nodebpy 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nodebpy/builder.py +193 -411
- nodebpy/nodes/__init__.py +352 -335
- nodebpy/nodes/attribute.py +362 -307
- nodebpy/nodes/color.py +30 -34
- nodebpy/nodes/converter.py +1987 -2978
- nodebpy/nodes/experimental.py +201 -203
- nodebpy/nodes/geometry.py +4189 -3644
- nodebpy/nodes/grid.py +932 -447
- nodebpy/nodes/group.py +7 -10
- nodebpy/nodes/input.py +1496 -1308
- nodebpy/nodes/interface.py +236 -117
- nodebpy/nodes/manual.py +2051 -0
- nodebpy/nodes/output.py +85 -0
- nodebpy/nodes/texture.py +867 -7
- nodebpy/nodes/vector.py +528 -0
- nodebpy/nodes/zone.py +88 -119
- nodebpy/{nodes/types.py → types.py} +15 -2
- {nodebpy-0.2.0.dist-info → nodebpy-0.3.0.dist-info}/METADATA +5 -5
- nodebpy-0.3.0.dist-info/RECORD +26 -0
- nodebpy/nodes/mesh.py +0 -17
- nodebpy-0.2.0.dist-info/RECORD +0 -25
- {nodebpy-0.2.0.dist-info → nodebpy-0.3.0.dist-info}/WHEEL +0 -0
- {nodebpy-0.2.0.dist-info → nodebpy-0.3.0.dist-info}/entry_points.txt +0 -0
nodebpy/nodes/texture.py
CHANGED
|
@@ -1,15 +1,364 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from typing import Literal
|
|
3
2
|
|
|
4
3
|
import bpy
|
|
5
|
-
|
|
6
|
-
from
|
|
4
|
+
|
|
5
|
+
from ..builder import NodeBuilder, SocketLinker
|
|
6
|
+
from ..types import (
|
|
7
|
+
TYPE_INPUT_INT,
|
|
8
|
+
TYPE_INPUT_COLOR,
|
|
9
|
+
TYPE_INPUT_IMAGE,
|
|
10
|
+
TYPE_INPUT_VALUE,
|
|
11
|
+
TYPE_INPUT_VECTOR,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BrickTexture(NodeBuilder):
|
|
16
|
+
"""Generate a procedural texture producing bricks"""
|
|
17
|
+
|
|
18
|
+
_bl_idname = "ShaderNodeTexBrick"
|
|
19
|
+
node: bpy.types.ShaderNodeTexBrick
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
24
|
+
color1: TYPE_INPUT_COLOR = None,
|
|
25
|
+
color2: TYPE_INPUT_COLOR = None,
|
|
26
|
+
mortar: TYPE_INPUT_COLOR = None,
|
|
27
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
28
|
+
mortar_size: TYPE_INPUT_VALUE = 0.02,
|
|
29
|
+
mortar_smooth: TYPE_INPUT_VALUE = 0.1,
|
|
30
|
+
bias: TYPE_INPUT_VALUE = 0.0,
|
|
31
|
+
brick_width: TYPE_INPUT_VALUE = 0.5,
|
|
32
|
+
row_height: TYPE_INPUT_VALUE = 0.25,
|
|
33
|
+
*,
|
|
34
|
+
offset_frequency: int = 2,
|
|
35
|
+
squash_frequency: int = 2,
|
|
36
|
+
offset: float = 0.5,
|
|
37
|
+
squash: float = 1.0,
|
|
38
|
+
):
|
|
39
|
+
super().__init__()
|
|
40
|
+
key_args = {
|
|
41
|
+
"Vector": vector,
|
|
42
|
+
"Color1": color1,
|
|
43
|
+
"Color2": color2,
|
|
44
|
+
"Mortar": mortar,
|
|
45
|
+
"Scale": scale,
|
|
46
|
+
"Mortar Size": mortar_size,
|
|
47
|
+
"Mortar Smooth": mortar_smooth,
|
|
48
|
+
"Bias": bias,
|
|
49
|
+
"Brick Width": brick_width,
|
|
50
|
+
"Row Height": row_height,
|
|
51
|
+
}
|
|
52
|
+
self.offset_frequency = offset_frequency
|
|
53
|
+
self.squash_frequency = squash_frequency
|
|
54
|
+
self.offset = offset
|
|
55
|
+
self.squash = squash
|
|
56
|
+
self._establish_links(**key_args)
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def i_vector(self) -> SocketLinker:
|
|
60
|
+
"""Input socket: Vector"""
|
|
61
|
+
return self._input("Vector")
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def i_color1(self) -> SocketLinker:
|
|
65
|
+
"""Input socket: Color1"""
|
|
66
|
+
return self._input("Color1")
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def i_color2(self) -> SocketLinker:
|
|
70
|
+
"""Input socket: Color2"""
|
|
71
|
+
return self._input("Color2")
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def i_mortar(self) -> SocketLinker:
|
|
75
|
+
"""Input socket: Mortar"""
|
|
76
|
+
return self._input("Mortar")
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def i_scale(self) -> SocketLinker:
|
|
80
|
+
"""Input socket: Scale"""
|
|
81
|
+
return self._input("Scale")
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def i_mortar_size(self) -> SocketLinker:
|
|
85
|
+
"""Input socket: Mortar Size"""
|
|
86
|
+
return self._input("Mortar Size")
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def i_mortar_smooth(self) -> SocketLinker:
|
|
90
|
+
"""Input socket: Mortar Smooth"""
|
|
91
|
+
return self._input("Mortar Smooth")
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def i_bias(self) -> SocketLinker:
|
|
95
|
+
"""Input socket: Bias"""
|
|
96
|
+
return self._input("Bias")
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def i_brick_width(self) -> SocketLinker:
|
|
100
|
+
"""Input socket: Brick Width"""
|
|
101
|
+
return self._input("Brick Width")
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def i_row_height(self) -> SocketLinker:
|
|
105
|
+
"""Input socket: Row Height"""
|
|
106
|
+
return self._input("Row Height")
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def o_color(self) -> SocketLinker:
|
|
110
|
+
"""Output socket: Color"""
|
|
111
|
+
return self._output("Color")
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def o_fac(self) -> SocketLinker:
|
|
115
|
+
"""Output socket: Factor"""
|
|
116
|
+
return self._output("Fac")
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def offset_frequency(self) -> int:
|
|
120
|
+
return self.node.offset_frequency
|
|
121
|
+
|
|
122
|
+
@offset_frequency.setter
|
|
123
|
+
def offset_frequency(self, value: int):
|
|
124
|
+
self.node.offset_frequency = value
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def squash_frequency(self) -> int:
|
|
128
|
+
return self.node.squash_frequency
|
|
129
|
+
|
|
130
|
+
@squash_frequency.setter
|
|
131
|
+
def squash_frequency(self, value: int):
|
|
132
|
+
self.node.squash_frequency = value
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def offset(self) -> float:
|
|
136
|
+
return self.node.offset
|
|
137
|
+
|
|
138
|
+
@offset.setter
|
|
139
|
+
def offset(self, value: float):
|
|
140
|
+
self.node.offset = value
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def squash(self) -> float:
|
|
144
|
+
return self.node.squash
|
|
145
|
+
|
|
146
|
+
@squash.setter
|
|
147
|
+
def squash(self, value: float):
|
|
148
|
+
self.node.squash = value
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class CheckerTexture(NodeBuilder):
|
|
152
|
+
"""Generate a checkerboard texture"""
|
|
153
|
+
|
|
154
|
+
_bl_idname = "ShaderNodeTexChecker"
|
|
155
|
+
node: bpy.types.ShaderNodeTexChecker
|
|
156
|
+
|
|
157
|
+
def __init__(
|
|
158
|
+
self,
|
|
159
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
160
|
+
color1: TYPE_INPUT_COLOR = None,
|
|
161
|
+
color2: TYPE_INPUT_COLOR = None,
|
|
162
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
163
|
+
):
|
|
164
|
+
super().__init__()
|
|
165
|
+
key_args = {
|
|
166
|
+
"Vector": vector,
|
|
167
|
+
"Color1": color1,
|
|
168
|
+
"Color2": color2,
|
|
169
|
+
"Scale": scale,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
self._establish_links(**key_args)
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def i_vector(self) -> SocketLinker:
|
|
176
|
+
"""Input socket: Vector"""
|
|
177
|
+
return self._input("Vector")
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def i_color1(self) -> SocketLinker:
|
|
181
|
+
"""Input socket: Color1"""
|
|
182
|
+
return self._input("Color1")
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def i_color2(self) -> SocketLinker:
|
|
186
|
+
"""Input socket: Color2"""
|
|
187
|
+
return self._input("Color2")
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def i_scale(self) -> SocketLinker:
|
|
191
|
+
"""Input socket: Scale"""
|
|
192
|
+
return self._input("Scale")
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def o_color(self) -> SocketLinker:
|
|
196
|
+
"""Output socket: Color"""
|
|
197
|
+
return self._output("Color")
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def o_fac(self) -> SocketLinker:
|
|
201
|
+
"""Output socket: Factor"""
|
|
202
|
+
return self._output("Fac")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class GaborTexture(NodeBuilder):
|
|
206
|
+
"""Generate Gabor noise"""
|
|
207
|
+
|
|
208
|
+
_bl_idname = "ShaderNodeTexGabor"
|
|
209
|
+
node: bpy.types.ShaderNodeTexGabor
|
|
210
|
+
|
|
211
|
+
def __init__(
|
|
212
|
+
self,
|
|
213
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
214
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
215
|
+
frequency: TYPE_INPUT_VALUE = 2.0,
|
|
216
|
+
anisotropy: TYPE_INPUT_VALUE = 1.0,
|
|
217
|
+
orientation_2d: TYPE_INPUT_VALUE = 0.7854,
|
|
218
|
+
orientation_3d: TYPE_INPUT_VECTOR = None,
|
|
219
|
+
*,
|
|
220
|
+
gabor_type: Literal["2D", "3D"] = "2D",
|
|
221
|
+
):
|
|
222
|
+
super().__init__()
|
|
223
|
+
key_args = {
|
|
224
|
+
"Vector": vector,
|
|
225
|
+
"Scale": scale,
|
|
226
|
+
"Frequency": frequency,
|
|
227
|
+
"Anisotropy": anisotropy,
|
|
228
|
+
"Orientation 2D": orientation_2d,
|
|
229
|
+
"Orientation 3D": orientation_3d,
|
|
230
|
+
}
|
|
231
|
+
self.gabor_type = gabor_type
|
|
232
|
+
self._establish_links(**key_args)
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def i_vector(self) -> SocketLinker:
|
|
236
|
+
"""Input socket: Vector"""
|
|
237
|
+
return self._input("Vector")
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def i_scale(self) -> SocketLinker:
|
|
241
|
+
"""Input socket: Scale"""
|
|
242
|
+
return self._input("Scale")
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def i_frequency(self) -> SocketLinker:
|
|
246
|
+
"""Input socket: Frequency"""
|
|
247
|
+
return self._input("Frequency")
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def i_anisotropy(self) -> SocketLinker:
|
|
251
|
+
"""Input socket: Anisotropy"""
|
|
252
|
+
return self._input("Anisotropy")
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def i_orientation_2d(self) -> SocketLinker:
|
|
256
|
+
"""Input socket: Orientation"""
|
|
257
|
+
return self._input("Orientation 2D")
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def i_orientation_3d(self) -> SocketLinker:
|
|
261
|
+
"""Input socket: Orientation"""
|
|
262
|
+
return self._input("Orientation 3D")
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def o_value(self) -> SocketLinker:
|
|
266
|
+
"""Output socket: Value"""
|
|
267
|
+
return self._output("Value")
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def o_phase(self) -> SocketLinker:
|
|
271
|
+
"""Output socket: Phase"""
|
|
272
|
+
return self._output("Phase")
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def o_intensity(self) -> SocketLinker:
|
|
276
|
+
"""Output socket: Intensity"""
|
|
277
|
+
return self._output("Intensity")
|
|
278
|
+
|
|
279
|
+
@property
|
|
280
|
+
def gabor_type(self) -> Literal["2D", "3D"]:
|
|
281
|
+
return self.node.gabor_type
|
|
282
|
+
|
|
283
|
+
@gabor_type.setter
|
|
284
|
+
def gabor_type(self, value: Literal["2D", "3D"]):
|
|
285
|
+
self.node.gabor_type = value
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class GradientTexture(NodeBuilder):
|
|
289
|
+
"""Generate interpolated color and intensity values based on the input vector"""
|
|
290
|
+
|
|
291
|
+
_bl_idname = "ShaderNodeTexGradient"
|
|
292
|
+
node: bpy.types.ShaderNodeTexGradient
|
|
293
|
+
|
|
294
|
+
def __init__(
|
|
295
|
+
self,
|
|
296
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
297
|
+
*,
|
|
298
|
+
gradient_type: Literal[
|
|
299
|
+
"LINEAR",
|
|
300
|
+
"QUADRATIC",
|
|
301
|
+
"EASING",
|
|
302
|
+
"DIAGONAL",
|
|
303
|
+
"SPHERICAL",
|
|
304
|
+
"QUADRATIC_SPHERE",
|
|
305
|
+
"RADIAL",
|
|
306
|
+
] = "LINEAR",
|
|
307
|
+
):
|
|
308
|
+
super().__init__()
|
|
309
|
+
key_args = {"Vector": vector}
|
|
310
|
+
self.gradient_type = gradient_type
|
|
311
|
+
self._establish_links(**key_args)
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def i_vector(self) -> SocketLinker:
|
|
315
|
+
"""Input socket: Vector"""
|
|
316
|
+
return self._input("Vector")
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def o_color(self) -> SocketLinker:
|
|
320
|
+
"""Output socket: Color"""
|
|
321
|
+
return self._output("Color")
|
|
322
|
+
|
|
323
|
+
@property
|
|
324
|
+
def o_fac(self) -> SocketLinker:
|
|
325
|
+
"""Output socket: Factor"""
|
|
326
|
+
return self._output("Fac")
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def gradient_type(
|
|
330
|
+
self,
|
|
331
|
+
) -> Literal[
|
|
332
|
+
"LINEAR",
|
|
333
|
+
"QUADRATIC",
|
|
334
|
+
"EASING",
|
|
335
|
+
"DIAGONAL",
|
|
336
|
+
"SPHERICAL",
|
|
337
|
+
"QUADRATIC_SPHERE",
|
|
338
|
+
"RADIAL",
|
|
339
|
+
]:
|
|
340
|
+
return self.node.gradient_type
|
|
341
|
+
|
|
342
|
+
@gradient_type.setter
|
|
343
|
+
def gradient_type(
|
|
344
|
+
self,
|
|
345
|
+
value: Literal[
|
|
346
|
+
"LINEAR",
|
|
347
|
+
"QUADRATIC",
|
|
348
|
+
"EASING",
|
|
349
|
+
"DIAGONAL",
|
|
350
|
+
"SPHERICAL",
|
|
351
|
+
"QUADRATIC_SPHERE",
|
|
352
|
+
"RADIAL",
|
|
353
|
+
],
|
|
354
|
+
):
|
|
355
|
+
self.node.gradient_type = value
|
|
7
356
|
|
|
8
357
|
|
|
9
358
|
class ImageTexture(NodeBuilder):
|
|
10
359
|
"""Sample values from an image texture"""
|
|
11
360
|
|
|
12
|
-
|
|
361
|
+
_bl_idname = "GeometryNodeImageTexture"
|
|
13
362
|
node: bpy.types.GeometryNodeImageTexture
|
|
14
363
|
|
|
15
364
|
def __init__(
|
|
@@ -17,13 +366,12 @@ class ImageTexture(NodeBuilder):
|
|
|
17
366
|
image: TYPE_INPUT_IMAGE = None,
|
|
18
367
|
vector: TYPE_INPUT_VECTOR = None,
|
|
19
368
|
frame: TYPE_INPUT_INT = 0,
|
|
369
|
+
*,
|
|
20
370
|
interpolation: Literal["Linear", "Closest", "Cubic"] = "Linear",
|
|
21
371
|
extension: Literal["REPEAT", "EXTEND", "CLIP", "MIRROR"] = "REPEAT",
|
|
22
|
-
**kwargs,
|
|
23
372
|
):
|
|
24
373
|
super().__init__()
|
|
25
374
|
key_args = {"Image": image, "Vector": vector, "Frame": frame}
|
|
26
|
-
key_args.update(kwargs)
|
|
27
375
|
self.interpolation = interpolation
|
|
28
376
|
self.extension = extension
|
|
29
377
|
self._establish_links(**key_args)
|
|
@@ -68,3 +416,515 @@ class ImageTexture(NodeBuilder):
|
|
|
68
416
|
@extension.setter
|
|
69
417
|
def extension(self, value: Literal["REPEAT", "EXTEND", "CLIP", "MIRROR"]):
|
|
70
418
|
self.node.extension = value
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
class MagicTexture(NodeBuilder):
|
|
422
|
+
"""Generate a psychedelic color texture"""
|
|
423
|
+
|
|
424
|
+
_bl_idname = "ShaderNodeTexMagic"
|
|
425
|
+
node: bpy.types.ShaderNodeTexMagic
|
|
426
|
+
|
|
427
|
+
def __init__(
|
|
428
|
+
self,
|
|
429
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
430
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
431
|
+
distortion: TYPE_INPUT_VALUE = 1.0,
|
|
432
|
+
*,
|
|
433
|
+
turbulence_depth: int = 0,
|
|
434
|
+
):
|
|
435
|
+
super().__init__()
|
|
436
|
+
key_args = {"Vector": vector, "Scale": scale, "Distortion": distortion}
|
|
437
|
+
self.turbulence_depth = turbulence_depth
|
|
438
|
+
self._establish_links(**key_args)
|
|
439
|
+
|
|
440
|
+
@property
|
|
441
|
+
def i_vector(self) -> SocketLinker:
|
|
442
|
+
"""Input socket: Vector"""
|
|
443
|
+
return self._input("Vector")
|
|
444
|
+
|
|
445
|
+
@property
|
|
446
|
+
def i_scale(self) -> SocketLinker:
|
|
447
|
+
"""Input socket: Scale"""
|
|
448
|
+
return self._input("Scale")
|
|
449
|
+
|
|
450
|
+
@property
|
|
451
|
+
def i_distortion(self) -> SocketLinker:
|
|
452
|
+
"""Input socket: Distortion"""
|
|
453
|
+
return self._input("Distortion")
|
|
454
|
+
|
|
455
|
+
@property
|
|
456
|
+
def o_color(self) -> SocketLinker:
|
|
457
|
+
"""Output socket: Color"""
|
|
458
|
+
return self._output("Color")
|
|
459
|
+
|
|
460
|
+
@property
|
|
461
|
+
def o_fac(self) -> SocketLinker:
|
|
462
|
+
"""Output socket: Factor"""
|
|
463
|
+
return self._output("Fac")
|
|
464
|
+
|
|
465
|
+
@property
|
|
466
|
+
def turbulence_depth(self) -> int:
|
|
467
|
+
return self.node.turbulence_depth
|
|
468
|
+
|
|
469
|
+
@turbulence_depth.setter
|
|
470
|
+
def turbulence_depth(self, value: int):
|
|
471
|
+
self.node.turbulence_depth = value
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
class NoiseTexture(NodeBuilder):
|
|
475
|
+
"""Generate fractal Perlin noise"""
|
|
476
|
+
|
|
477
|
+
_bl_idname = "ShaderNodeTexNoise"
|
|
478
|
+
node: bpy.types.ShaderNodeTexNoise
|
|
479
|
+
|
|
480
|
+
def __init__(
|
|
481
|
+
self,
|
|
482
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
483
|
+
w: TYPE_INPUT_VALUE = 0.0,
|
|
484
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
485
|
+
detail: TYPE_INPUT_VALUE = 2.0,
|
|
486
|
+
roughness: TYPE_INPUT_VALUE = 0.5,
|
|
487
|
+
lacunarity: TYPE_INPUT_VALUE = 2.0,
|
|
488
|
+
offset: TYPE_INPUT_VALUE = 0.0,
|
|
489
|
+
gain: TYPE_INPUT_VALUE = 1.0,
|
|
490
|
+
distortion: TYPE_INPUT_VALUE = 0.0,
|
|
491
|
+
*,
|
|
492
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] = "3D",
|
|
493
|
+
noise_type: Literal[
|
|
494
|
+
"MULTIFRACTAL",
|
|
495
|
+
"RIDGED_MULTIFRACTAL",
|
|
496
|
+
"HYBRID_MULTIFRACTAL",
|
|
497
|
+
"FBM",
|
|
498
|
+
"HETERO_TERRAIN",
|
|
499
|
+
] = "FBM",
|
|
500
|
+
normalize: bool = False,
|
|
501
|
+
):
|
|
502
|
+
super().__init__()
|
|
503
|
+
key_args = {
|
|
504
|
+
"Vector": vector,
|
|
505
|
+
"W": w,
|
|
506
|
+
"Scale": scale,
|
|
507
|
+
"Detail": detail,
|
|
508
|
+
"Roughness": roughness,
|
|
509
|
+
"Lacunarity": lacunarity,
|
|
510
|
+
"Offset": offset,
|
|
511
|
+
"Gain": gain,
|
|
512
|
+
"Distortion": distortion,
|
|
513
|
+
}
|
|
514
|
+
self.noise_dimensions = noise_dimensions
|
|
515
|
+
self.noise_type = noise_type
|
|
516
|
+
self.normalize = normalize
|
|
517
|
+
self._establish_links(**key_args)
|
|
518
|
+
|
|
519
|
+
@property
|
|
520
|
+
def i_vector(self) -> SocketLinker:
|
|
521
|
+
"""Input socket: Vector"""
|
|
522
|
+
return self._input("Vector")
|
|
523
|
+
|
|
524
|
+
@property
|
|
525
|
+
def i_w(self) -> SocketLinker:
|
|
526
|
+
"""Input socket: W"""
|
|
527
|
+
return self._input("W")
|
|
528
|
+
|
|
529
|
+
@property
|
|
530
|
+
def i_scale(self) -> SocketLinker:
|
|
531
|
+
"""Input socket: Scale"""
|
|
532
|
+
return self._input("Scale")
|
|
533
|
+
|
|
534
|
+
@property
|
|
535
|
+
def i_detail(self) -> SocketLinker:
|
|
536
|
+
"""Input socket: Detail"""
|
|
537
|
+
return self._input("Detail")
|
|
538
|
+
|
|
539
|
+
@property
|
|
540
|
+
def i_roughness(self) -> SocketLinker:
|
|
541
|
+
"""Input socket: Roughness"""
|
|
542
|
+
return self._input("Roughness")
|
|
543
|
+
|
|
544
|
+
@property
|
|
545
|
+
def i_lacunarity(self) -> SocketLinker:
|
|
546
|
+
"""Input socket: Lacunarity"""
|
|
547
|
+
return self._input("Lacunarity")
|
|
548
|
+
|
|
549
|
+
@property
|
|
550
|
+
def i_offset(self) -> SocketLinker:
|
|
551
|
+
"""Input socket: Offset"""
|
|
552
|
+
return self._input("Offset")
|
|
553
|
+
|
|
554
|
+
@property
|
|
555
|
+
def i_gain(self) -> SocketLinker:
|
|
556
|
+
"""Input socket: Gain"""
|
|
557
|
+
return self._input("Gain")
|
|
558
|
+
|
|
559
|
+
@property
|
|
560
|
+
def i_distortion(self) -> SocketLinker:
|
|
561
|
+
"""Input socket: Distortion"""
|
|
562
|
+
return self._input("Distortion")
|
|
563
|
+
|
|
564
|
+
@property
|
|
565
|
+
def o_fac(self) -> SocketLinker:
|
|
566
|
+
"""Output socket: Factor"""
|
|
567
|
+
return self._output("Fac")
|
|
568
|
+
|
|
569
|
+
@property
|
|
570
|
+
def o_color(self) -> SocketLinker:
|
|
571
|
+
"""Output socket: Color"""
|
|
572
|
+
return self._output("Color")
|
|
573
|
+
|
|
574
|
+
@property
|
|
575
|
+
def noise_dimensions(self) -> Literal["1D", "2D", "3D", "4D"]:
|
|
576
|
+
return self.node.noise_dimensions
|
|
577
|
+
|
|
578
|
+
@noise_dimensions.setter
|
|
579
|
+
def noise_dimensions(self, value: Literal["1D", "2D", "3D", "4D"]):
|
|
580
|
+
self.node.noise_dimensions = value
|
|
581
|
+
|
|
582
|
+
@property
|
|
583
|
+
def noise_type(
|
|
584
|
+
self,
|
|
585
|
+
) -> Literal[
|
|
586
|
+
"MULTIFRACTAL",
|
|
587
|
+
"RIDGED_MULTIFRACTAL",
|
|
588
|
+
"HYBRID_MULTIFRACTAL",
|
|
589
|
+
"FBM",
|
|
590
|
+
"HETERO_TERRAIN",
|
|
591
|
+
]:
|
|
592
|
+
return self.node.noise_type
|
|
593
|
+
|
|
594
|
+
@noise_type.setter
|
|
595
|
+
def noise_type(
|
|
596
|
+
self,
|
|
597
|
+
value: Literal[
|
|
598
|
+
"MULTIFRACTAL",
|
|
599
|
+
"RIDGED_MULTIFRACTAL",
|
|
600
|
+
"HYBRID_MULTIFRACTAL",
|
|
601
|
+
"FBM",
|
|
602
|
+
"HETERO_TERRAIN",
|
|
603
|
+
],
|
|
604
|
+
):
|
|
605
|
+
self.node.noise_type = value
|
|
606
|
+
|
|
607
|
+
@property
|
|
608
|
+
def normalize(self) -> bool:
|
|
609
|
+
return self.node.normalize
|
|
610
|
+
|
|
611
|
+
@normalize.setter
|
|
612
|
+
def normalize(self, value: bool):
|
|
613
|
+
self.node.normalize = value
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
class VoronoiTexture(NodeBuilder):
|
|
617
|
+
"""Generate Worley noise based on the distance to random points. Typically used to generate textures such as stones, water, or biological cells"""
|
|
618
|
+
|
|
619
|
+
_bl_idname = "ShaderNodeTexVoronoi"
|
|
620
|
+
node: bpy.types.ShaderNodeTexVoronoi
|
|
621
|
+
|
|
622
|
+
def __init__(
|
|
623
|
+
self,
|
|
624
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
625
|
+
w: TYPE_INPUT_VALUE = 0.0,
|
|
626
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
627
|
+
detail: TYPE_INPUT_VALUE = 0.0,
|
|
628
|
+
roughness: TYPE_INPUT_VALUE = 0.5,
|
|
629
|
+
lacunarity: TYPE_INPUT_VALUE = 2.0,
|
|
630
|
+
smoothness: TYPE_INPUT_VALUE = 1.0,
|
|
631
|
+
exponent: TYPE_INPUT_VALUE = 0.5,
|
|
632
|
+
randomness: TYPE_INPUT_VALUE = 1.0,
|
|
633
|
+
*,
|
|
634
|
+
voronoi_dimensions: Literal["1D", "2D", "3D", "4D"] = "3D",
|
|
635
|
+
distance: Literal[
|
|
636
|
+
"EUCLIDEAN", "MANHATTAN", "CHEBYCHEV", "MINKOWSKI"
|
|
637
|
+
] = "EUCLIDEAN",
|
|
638
|
+
feature: Literal[
|
|
639
|
+
"F1", "F2", "SMOOTH_F1", "DISTANCE_TO_EDGE", "N_SPHERE_RADIUS"
|
|
640
|
+
] = "F1",
|
|
641
|
+
normalize: bool = False,
|
|
642
|
+
):
|
|
643
|
+
super().__init__()
|
|
644
|
+
key_args = {
|
|
645
|
+
"Vector": vector,
|
|
646
|
+
"W": w,
|
|
647
|
+
"Scale": scale,
|
|
648
|
+
"Detail": detail,
|
|
649
|
+
"Roughness": roughness,
|
|
650
|
+
"Lacunarity": lacunarity,
|
|
651
|
+
"Smoothness": smoothness,
|
|
652
|
+
"Exponent": exponent,
|
|
653
|
+
"Randomness": randomness,
|
|
654
|
+
}
|
|
655
|
+
self.voronoi_dimensions = voronoi_dimensions
|
|
656
|
+
self.distance = distance
|
|
657
|
+
self.feature = feature
|
|
658
|
+
self.normalize = normalize
|
|
659
|
+
self._establish_links(**key_args)
|
|
660
|
+
|
|
661
|
+
@property
|
|
662
|
+
def i_vector(self) -> SocketLinker:
|
|
663
|
+
"""Input socket: Vector"""
|
|
664
|
+
return self._input("Vector")
|
|
665
|
+
|
|
666
|
+
@property
|
|
667
|
+
def i_w(self) -> SocketLinker:
|
|
668
|
+
"""Input socket: W"""
|
|
669
|
+
return self._input("W")
|
|
670
|
+
|
|
671
|
+
@property
|
|
672
|
+
def i_scale(self) -> SocketLinker:
|
|
673
|
+
"""Input socket: Scale"""
|
|
674
|
+
return self._input("Scale")
|
|
675
|
+
|
|
676
|
+
@property
|
|
677
|
+
def i_detail(self) -> SocketLinker:
|
|
678
|
+
"""Input socket: Detail"""
|
|
679
|
+
return self._input("Detail")
|
|
680
|
+
|
|
681
|
+
@property
|
|
682
|
+
def i_roughness(self) -> SocketLinker:
|
|
683
|
+
"""Input socket: Roughness"""
|
|
684
|
+
return self._input("Roughness")
|
|
685
|
+
|
|
686
|
+
@property
|
|
687
|
+
def i_lacunarity(self) -> SocketLinker:
|
|
688
|
+
"""Input socket: Lacunarity"""
|
|
689
|
+
return self._input("Lacunarity")
|
|
690
|
+
|
|
691
|
+
@property
|
|
692
|
+
def i_smoothness(self) -> SocketLinker:
|
|
693
|
+
"""Input socket: Smoothness"""
|
|
694
|
+
return self._input("Smoothness")
|
|
695
|
+
|
|
696
|
+
@property
|
|
697
|
+
def i_exponent(self) -> SocketLinker:
|
|
698
|
+
"""Input socket: Exponent"""
|
|
699
|
+
return self._input("Exponent")
|
|
700
|
+
|
|
701
|
+
@property
|
|
702
|
+
def i_randomness(self) -> SocketLinker:
|
|
703
|
+
"""Input socket: Randomness"""
|
|
704
|
+
return self._input("Randomness")
|
|
705
|
+
|
|
706
|
+
@property
|
|
707
|
+
def o_distance(self) -> SocketLinker:
|
|
708
|
+
"""Output socket: Distance"""
|
|
709
|
+
return self._output("Distance")
|
|
710
|
+
|
|
711
|
+
@property
|
|
712
|
+
def o_color(self) -> SocketLinker:
|
|
713
|
+
"""Output socket: Color"""
|
|
714
|
+
return self._output("Color")
|
|
715
|
+
|
|
716
|
+
@property
|
|
717
|
+
def o_position(self) -> SocketLinker:
|
|
718
|
+
"""Output socket: Position"""
|
|
719
|
+
return self._output("Position")
|
|
720
|
+
|
|
721
|
+
@property
|
|
722
|
+
def o_w(self) -> SocketLinker:
|
|
723
|
+
"""Output socket: W"""
|
|
724
|
+
return self._output("W")
|
|
725
|
+
|
|
726
|
+
@property
|
|
727
|
+
def o_radius(self) -> SocketLinker:
|
|
728
|
+
"""Output socket: Radius"""
|
|
729
|
+
return self._output("Radius")
|
|
730
|
+
|
|
731
|
+
@property
|
|
732
|
+
def voronoi_dimensions(self) -> Literal["1D", "2D", "3D", "4D"]:
|
|
733
|
+
return self.node.voronoi_dimensions
|
|
734
|
+
|
|
735
|
+
@voronoi_dimensions.setter
|
|
736
|
+
def voronoi_dimensions(self, value: Literal["1D", "2D", "3D", "4D"]):
|
|
737
|
+
self.node.voronoi_dimensions = value
|
|
738
|
+
|
|
739
|
+
@property
|
|
740
|
+
def distance(self) -> Literal["EUCLIDEAN", "MANHATTAN", "CHEBYCHEV", "MINKOWSKI"]:
|
|
741
|
+
return self.node.distance
|
|
742
|
+
|
|
743
|
+
@distance.setter
|
|
744
|
+
def distance(
|
|
745
|
+
self, value: Literal["EUCLIDEAN", "MANHATTAN", "CHEBYCHEV", "MINKOWSKI"]
|
|
746
|
+
):
|
|
747
|
+
self.node.distance = value
|
|
748
|
+
|
|
749
|
+
@property
|
|
750
|
+
def feature(
|
|
751
|
+
self,
|
|
752
|
+
) -> Literal["F1", "F2", "SMOOTH_F1", "DISTANCE_TO_EDGE", "N_SPHERE_RADIUS"]:
|
|
753
|
+
return self.node.feature
|
|
754
|
+
|
|
755
|
+
@feature.setter
|
|
756
|
+
def feature(
|
|
757
|
+
self,
|
|
758
|
+
value: Literal["F1", "F2", "SMOOTH_F1", "DISTANCE_TO_EDGE", "N_SPHERE_RADIUS"],
|
|
759
|
+
):
|
|
760
|
+
self.node.feature = value
|
|
761
|
+
|
|
762
|
+
@property
|
|
763
|
+
def normalize(self) -> bool:
|
|
764
|
+
return self.node.normalize
|
|
765
|
+
|
|
766
|
+
@normalize.setter
|
|
767
|
+
def normalize(self, value: bool):
|
|
768
|
+
self.node.normalize = value
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
class WaveTexture(NodeBuilder):
|
|
772
|
+
"""Generate procedural bands or rings with noise"""
|
|
773
|
+
|
|
774
|
+
_bl_idname = "ShaderNodeTexWave"
|
|
775
|
+
node: bpy.types.ShaderNodeTexWave
|
|
776
|
+
|
|
777
|
+
def __init__(
|
|
778
|
+
self,
|
|
779
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
780
|
+
scale: TYPE_INPUT_VALUE = 5.0,
|
|
781
|
+
distortion: TYPE_INPUT_VALUE = 0.0,
|
|
782
|
+
detail: TYPE_INPUT_VALUE = 2.0,
|
|
783
|
+
detail_scale: TYPE_INPUT_VALUE = 1.0,
|
|
784
|
+
detail_roughness: TYPE_INPUT_VALUE = 0.5,
|
|
785
|
+
phase_offset: TYPE_INPUT_VALUE = 0.0,
|
|
786
|
+
*,
|
|
787
|
+
wave_type: Literal["BANDS", "RINGS"] = "BANDS",
|
|
788
|
+
bands_direction: Literal["X", "Y", "Z", "DIAGONAL"] = "X",
|
|
789
|
+
rings_direction: Literal["X", "Y", "Z", "SPHERICAL"] = "X",
|
|
790
|
+
wave_profile: Literal["SIN", "SAW", "TRI"] = "SIN",
|
|
791
|
+
):
|
|
792
|
+
super().__init__()
|
|
793
|
+
key_args = {
|
|
794
|
+
"Vector": vector,
|
|
795
|
+
"Scale": scale,
|
|
796
|
+
"Distortion": distortion,
|
|
797
|
+
"Detail": detail,
|
|
798
|
+
"Detail Scale": detail_scale,
|
|
799
|
+
"Detail Roughness": detail_roughness,
|
|
800
|
+
"Phase Offset": phase_offset,
|
|
801
|
+
}
|
|
802
|
+
self.wave_type = wave_type
|
|
803
|
+
self.bands_direction = bands_direction
|
|
804
|
+
self.rings_direction = rings_direction
|
|
805
|
+
self.wave_profile = wave_profile
|
|
806
|
+
self._establish_links(**key_args)
|
|
807
|
+
|
|
808
|
+
@property
|
|
809
|
+
def i_vector(self) -> SocketLinker:
|
|
810
|
+
"""Input socket: Vector"""
|
|
811
|
+
return self._input("Vector")
|
|
812
|
+
|
|
813
|
+
@property
|
|
814
|
+
def i_scale(self) -> SocketLinker:
|
|
815
|
+
"""Input socket: Scale"""
|
|
816
|
+
return self._input("Scale")
|
|
817
|
+
|
|
818
|
+
@property
|
|
819
|
+
def i_distortion(self) -> SocketLinker:
|
|
820
|
+
"""Input socket: Distortion"""
|
|
821
|
+
return self._input("Distortion")
|
|
822
|
+
|
|
823
|
+
@property
|
|
824
|
+
def i_detail(self) -> SocketLinker:
|
|
825
|
+
"""Input socket: Detail"""
|
|
826
|
+
return self._input("Detail")
|
|
827
|
+
|
|
828
|
+
@property
|
|
829
|
+
def i_detail_scale(self) -> SocketLinker:
|
|
830
|
+
"""Input socket: Detail Scale"""
|
|
831
|
+
return self._input("Detail Scale")
|
|
832
|
+
|
|
833
|
+
@property
|
|
834
|
+
def i_detail_roughness(self) -> SocketLinker:
|
|
835
|
+
"""Input socket: Detail Roughness"""
|
|
836
|
+
return self._input("Detail Roughness")
|
|
837
|
+
|
|
838
|
+
@property
|
|
839
|
+
def i_phase_offset(self) -> SocketLinker:
|
|
840
|
+
"""Input socket: Phase Offset"""
|
|
841
|
+
return self._input("Phase Offset")
|
|
842
|
+
|
|
843
|
+
@property
|
|
844
|
+
def o_color(self) -> SocketLinker:
|
|
845
|
+
"""Output socket: Color"""
|
|
846
|
+
return self._output("Color")
|
|
847
|
+
|
|
848
|
+
@property
|
|
849
|
+
def o_fac(self) -> SocketLinker:
|
|
850
|
+
"""Output socket: Factor"""
|
|
851
|
+
return self._output("Fac")
|
|
852
|
+
|
|
853
|
+
@property
|
|
854
|
+
def wave_type(self) -> Literal["BANDS", "RINGS"]:
|
|
855
|
+
return self.node.wave_type
|
|
856
|
+
|
|
857
|
+
@wave_type.setter
|
|
858
|
+
def wave_type(self, value: Literal["BANDS", "RINGS"]):
|
|
859
|
+
self.node.wave_type = value
|
|
860
|
+
|
|
861
|
+
@property
|
|
862
|
+
def bands_direction(self) -> Literal["X", "Y", "Z", "DIAGONAL"]:
|
|
863
|
+
return self.node.bands_direction
|
|
864
|
+
|
|
865
|
+
@bands_direction.setter
|
|
866
|
+
def bands_direction(self, value: Literal["X", "Y", "Z", "DIAGONAL"]):
|
|
867
|
+
self.node.bands_direction = value
|
|
868
|
+
|
|
869
|
+
@property
|
|
870
|
+
def rings_direction(self) -> Literal["X", "Y", "Z", "SPHERICAL"]:
|
|
871
|
+
return self.node.rings_direction
|
|
872
|
+
|
|
873
|
+
@rings_direction.setter
|
|
874
|
+
def rings_direction(self, value: Literal["X", "Y", "Z", "SPHERICAL"]):
|
|
875
|
+
self.node.rings_direction = value
|
|
876
|
+
|
|
877
|
+
@property
|
|
878
|
+
def wave_profile(self) -> Literal["SIN", "SAW", "TRI"]:
|
|
879
|
+
return self.node.wave_profile
|
|
880
|
+
|
|
881
|
+
@wave_profile.setter
|
|
882
|
+
def wave_profile(self, value: Literal["SIN", "SAW", "TRI"]):
|
|
883
|
+
self.node.wave_profile = value
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
class WhiteNoiseTexture(NodeBuilder):
|
|
887
|
+
"""Calculate a random value or color based on an input seed"""
|
|
888
|
+
|
|
889
|
+
_bl_idname = "ShaderNodeTexWhiteNoise"
|
|
890
|
+
node: bpy.types.ShaderNodeTexWhiteNoise
|
|
891
|
+
|
|
892
|
+
def __init__(
|
|
893
|
+
self,
|
|
894
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
895
|
+
w: TYPE_INPUT_VALUE = 0.0,
|
|
896
|
+
*,
|
|
897
|
+
noise_dimensions: Literal["1D", "2D", "3D", "4D"] = "3D",
|
|
898
|
+
):
|
|
899
|
+
super().__init__()
|
|
900
|
+
key_args = {"Vector": vector, "W": w}
|
|
901
|
+
self.noise_dimensions = noise_dimensions
|
|
902
|
+
self._establish_links(**key_args)
|
|
903
|
+
|
|
904
|
+
@property
|
|
905
|
+
def i_vector(self) -> SocketLinker:
|
|
906
|
+
"""Input socket: Vector"""
|
|
907
|
+
return self._input("Vector")
|
|
908
|
+
|
|
909
|
+
@property
|
|
910
|
+
def i_w(self) -> SocketLinker:
|
|
911
|
+
"""Input socket: W"""
|
|
912
|
+
return self._input("W")
|
|
913
|
+
|
|
914
|
+
@property
|
|
915
|
+
def o_value(self) -> SocketLinker:
|
|
916
|
+
"""Output socket: Value"""
|
|
917
|
+
return self._output("Value")
|
|
918
|
+
|
|
919
|
+
@property
|
|
920
|
+
def o_color(self) -> SocketLinker:
|
|
921
|
+
"""Output socket: Color"""
|
|
922
|
+
return self._output("Color")
|
|
923
|
+
|
|
924
|
+
@property
|
|
925
|
+
def noise_dimensions(self) -> Literal["1D", "2D", "3D", "4D"]:
|
|
926
|
+
return self.node.noise_dimensions
|
|
927
|
+
|
|
928
|
+
@noise_dimensions.setter
|
|
929
|
+
def noise_dimensions(self, value: Literal["1D", "2D", "3D", "4D"]):
|
|
930
|
+
self.node.noise_dimensions = value
|