nodebpy 0.1.1__py3-none-any.whl → 0.2.1__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 +786 -316
- nodebpy/nodes/__init__.py +641 -10
- nodebpy/nodes/attribute.py +345 -389
- nodebpy/nodes/color.py +72 -0
- nodebpy/nodes/converter.py +3527 -0
- nodebpy/nodes/experimental.py +312 -0
- nodebpy/nodes/geometry.py +3677 -4717
- nodebpy/nodes/grid.py +1713 -0
- nodebpy/nodes/group.py +17 -0
- nodebpy/nodes/input.py +1821 -316
- nodebpy/nodes/interface.py +519 -0
- nodebpy/nodes/manual.py +2022 -0
- nodebpy/nodes/output.py +85 -0
- nodebpy/nodes/texture.py +930 -0
- nodebpy/nodes/vector.py +528 -0
- nodebpy/nodes/zone.py +442 -0
- nodebpy/screenshot.py +2 -1
- nodebpy/sockets.py +12 -12
- nodebpy/types.py +445 -0
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/METADATA +5 -5
- nodebpy-0.2.1.dist-info/RECORD +26 -0
- nodebpy/nodes/curve.py +0 -2006
- nodebpy/nodes/manually_specified.py +0 -1382
- nodebpy/nodes/mesh.py +0 -1408
- nodebpy/nodes/types.py +0 -119
- nodebpy/nodes/utilities.py +0 -2344
- nodebpy-0.1.1.dist-info/RECORD +0 -19
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/WHEEL +0 -0
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,3527 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
import bpy
|
|
4
|
+
|
|
5
|
+
from ..builder import NodeBuilder, SocketLinker
|
|
6
|
+
from ..types import (
|
|
7
|
+
TYPE_INPUT_BOOLEAN,
|
|
8
|
+
TYPE_INPUT_GEOMETRY,
|
|
9
|
+
TYPE_INPUT_INT,
|
|
10
|
+
TYPE_INPUT_MENU,
|
|
11
|
+
TYPE_INPUT_STRING,
|
|
12
|
+
TYPE_INPUT_ROTATION,
|
|
13
|
+
TYPE_INPUT_COLOR,
|
|
14
|
+
TYPE_INPUT_MATRIX,
|
|
15
|
+
TYPE_INPUT_BUNDLE,
|
|
16
|
+
TYPE_INPUT_CLOSURE,
|
|
17
|
+
TYPE_INPUT_OBJECT,
|
|
18
|
+
TYPE_INPUT_COLLECTION,
|
|
19
|
+
TYPE_INPUT_IMAGE,
|
|
20
|
+
TYPE_INPUT_MATERIAL,
|
|
21
|
+
TYPE_INPUT_VALUE,
|
|
22
|
+
TYPE_INPUT_VECTOR,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AlignRotationToVector(NodeBuilder):
|
|
27
|
+
"""Orient a rotation along the given direction"""
|
|
28
|
+
|
|
29
|
+
_bl_idname = "FunctionNodeAlignRotationToVector"
|
|
30
|
+
node: bpy.types.FunctionNodeAlignRotationToVector
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
rotation: TYPE_INPUT_ROTATION = None,
|
|
35
|
+
factor: TYPE_INPUT_VALUE = 1.0,
|
|
36
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
37
|
+
*,
|
|
38
|
+
axis: Literal["X", "Y", "Z"] = "Z",
|
|
39
|
+
pivot_axis: Literal["AUTO", "X", "Y", "Z"] = "AUTO",
|
|
40
|
+
):
|
|
41
|
+
super().__init__()
|
|
42
|
+
key_args = {"Rotation": rotation, "Factor": factor, "Vector": vector}
|
|
43
|
+
self.axis = axis
|
|
44
|
+
self.pivot_axis = pivot_axis
|
|
45
|
+
self._establish_links(**key_args)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def i_rotation(self) -> SocketLinker:
|
|
49
|
+
"""Input socket: Rotation"""
|
|
50
|
+
return self._input("Rotation")
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def i_factor(self) -> SocketLinker:
|
|
54
|
+
"""Input socket: Factor"""
|
|
55
|
+
return self._input("Factor")
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def i_vector(self) -> SocketLinker:
|
|
59
|
+
"""Input socket: Vector"""
|
|
60
|
+
return self._input("Vector")
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def o_rotation(self) -> SocketLinker:
|
|
64
|
+
"""Output socket: Rotation"""
|
|
65
|
+
return self._output("Rotation")
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def axis(self) -> Literal["X", "Y", "Z"]:
|
|
69
|
+
return self.node.axis
|
|
70
|
+
|
|
71
|
+
@axis.setter
|
|
72
|
+
def axis(self, value: Literal["X", "Y", "Z"]):
|
|
73
|
+
self.node.axis = value
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def pivot_axis(self) -> Literal["AUTO", "X", "Y", "Z"]:
|
|
77
|
+
return self.node.pivot_axis
|
|
78
|
+
|
|
79
|
+
@pivot_axis.setter
|
|
80
|
+
def pivot_axis(self, value: Literal["AUTO", "X", "Y", "Z"]):
|
|
81
|
+
self.node.pivot_axis = value
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AxesToRotation(NodeBuilder):
|
|
85
|
+
"""Create a rotation from a primary and (ideally orthogonal) secondary axis"""
|
|
86
|
+
|
|
87
|
+
_bl_idname = "FunctionNodeAxesToRotation"
|
|
88
|
+
node: bpy.types.FunctionNodeAxesToRotation
|
|
89
|
+
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
primary_axis: TYPE_INPUT_VECTOR = None,
|
|
93
|
+
secondary_axis: TYPE_INPUT_VECTOR = None,
|
|
94
|
+
*,
|
|
95
|
+
primary: Literal["X", "Y", "Z"] = "Z",
|
|
96
|
+
secondary: Literal["X", "Y", "Z"] = "X",
|
|
97
|
+
):
|
|
98
|
+
super().__init__()
|
|
99
|
+
key_args = {"Primary Axis": primary_axis, "Secondary Axis": secondary_axis}
|
|
100
|
+
self.primary_axis = primary_axis
|
|
101
|
+
self.secondary_axis = secondary_axis
|
|
102
|
+
self._establish_links(**key_args)
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def i_primary_axis(self) -> SocketLinker:
|
|
106
|
+
"""Input socket: Primary Axis"""
|
|
107
|
+
return self._input("Primary Axis")
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def i_secondary_axis(self) -> SocketLinker:
|
|
111
|
+
"""Input socket: Secondary Axis"""
|
|
112
|
+
return self._input("Secondary Axis")
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def o_rotation(self) -> SocketLinker:
|
|
116
|
+
"""Output socket: Rotation"""
|
|
117
|
+
return self._output("Rotation")
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def primary(self) -> Literal["X", "Y", "Z"]:
|
|
121
|
+
return self.node.primary_axis
|
|
122
|
+
|
|
123
|
+
@primary.setter
|
|
124
|
+
def primary(self, value: Literal["X", "Y", "Z"]):
|
|
125
|
+
self.node.primary_axis = value
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def secondary(self) -> Literal["X", "Y", "Z"]:
|
|
129
|
+
return self.node.secondary_axis
|
|
130
|
+
|
|
131
|
+
@secondary.setter
|
|
132
|
+
def secondary(self, value: Literal["X", "Y", "Z"]):
|
|
133
|
+
self.node.secondary_axis = value
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class AxisAngleToRotation(NodeBuilder):
|
|
137
|
+
"""Build a rotation from an axis and a rotation around that axis"""
|
|
138
|
+
|
|
139
|
+
_bl_idname = "FunctionNodeAxisAngleToRotation"
|
|
140
|
+
node: bpy.types.FunctionNodeAxisAngleToRotation
|
|
141
|
+
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
axis: TYPE_INPUT_VECTOR = None,
|
|
145
|
+
angle: TYPE_INPUT_VALUE = 0.0,
|
|
146
|
+
):
|
|
147
|
+
super().__init__()
|
|
148
|
+
key_args = {"Axis": axis, "Angle": angle}
|
|
149
|
+
|
|
150
|
+
self._establish_links(**key_args)
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def i_axis(self) -> SocketLinker:
|
|
154
|
+
"""Input socket: Axis"""
|
|
155
|
+
return self._input("Axis")
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def i_angle(self) -> SocketLinker:
|
|
159
|
+
"""Input socket: Angle"""
|
|
160
|
+
return self._input("Angle")
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def o_rotation(self) -> SocketLinker:
|
|
164
|
+
"""Output socket: Rotation"""
|
|
165
|
+
return self._output("Rotation")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class BitMath(NodeBuilder):
|
|
169
|
+
"""Perform bitwise operations on 32-bit integers"""
|
|
170
|
+
|
|
171
|
+
_bl_idname = "FunctionNodeBitMath"
|
|
172
|
+
node: bpy.types.FunctionNodeBitMath
|
|
173
|
+
|
|
174
|
+
def __init__(
|
|
175
|
+
self,
|
|
176
|
+
a: TYPE_INPUT_INT = 0,
|
|
177
|
+
b: TYPE_INPUT_INT = 0,
|
|
178
|
+
shift: TYPE_INPUT_INT = 0,
|
|
179
|
+
*,
|
|
180
|
+
operation: Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"] = "AND",
|
|
181
|
+
):
|
|
182
|
+
super().__init__()
|
|
183
|
+
key_args = {"A": a, "B": b, "Shift": shift}
|
|
184
|
+
self.operation = operation
|
|
185
|
+
self._establish_links(**key_args)
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def l_and(cls, a: TYPE_INPUT_INT = 0, b: TYPE_INPUT_INT = 0) -> "BitMath":
|
|
189
|
+
"""Create Bit Math with operation 'And'."""
|
|
190
|
+
return cls(operation="AND", a=a, b=b)
|
|
191
|
+
|
|
192
|
+
@classmethod
|
|
193
|
+
def l_or(cls, a: TYPE_INPUT_INT = 0, b: TYPE_INPUT_INT = 0) -> "BitMath":
|
|
194
|
+
"""Create Bit Math with operation 'Or'."""
|
|
195
|
+
return cls(operation="OR", a=a, b=b)
|
|
196
|
+
|
|
197
|
+
@classmethod
|
|
198
|
+
def l_not(cls, a: TYPE_INPUT_INT = 0) -> "BitMath":
|
|
199
|
+
"""Create Bit Math with operation 'Not'."""
|
|
200
|
+
return cls(operation="NOT", a=a)
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def shift(cls, a: TYPE_INPUT_INT = 0, shift: TYPE_INPUT_INT = 0) -> "BitMath":
|
|
204
|
+
"""Create Bit Math with operation 'Shift'."""
|
|
205
|
+
return cls(operation="SHIFT", a=a, shift=shift)
|
|
206
|
+
|
|
207
|
+
@classmethod
|
|
208
|
+
def rotate(cls, a: TYPE_INPUT_INT = 0, shift: TYPE_INPUT_INT = 0) -> "BitMath":
|
|
209
|
+
"""Create Bit Math with operation 'Rotate'."""
|
|
210
|
+
return cls(operation="ROTATE", a=a, shift=shift)
|
|
211
|
+
|
|
212
|
+
@property
|
|
213
|
+
def i_a(self) -> SocketLinker:
|
|
214
|
+
"""Input socket: A"""
|
|
215
|
+
return self._input("A")
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def i_b(self) -> SocketLinker:
|
|
219
|
+
"""Input socket: B"""
|
|
220
|
+
return self._input("B")
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
def i_shift(self) -> SocketLinker:
|
|
224
|
+
"""Input socket: Shift"""
|
|
225
|
+
return self._input("Shift")
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def o_value(self) -> SocketLinker:
|
|
229
|
+
"""Output socket: Value"""
|
|
230
|
+
return self._output("Value")
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def operation(self) -> Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"]:
|
|
234
|
+
return self.node.operation
|
|
235
|
+
|
|
236
|
+
@operation.setter
|
|
237
|
+
def operation(self, value: Literal["AND", "OR", "XOR", "NOT", "SHIFT", "ROTATE"]):
|
|
238
|
+
self.node.operation = value
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class Blackbody(NodeBuilder):
|
|
242
|
+
"""Convert a blackbody temperature to an RGB value"""
|
|
243
|
+
|
|
244
|
+
_bl_idname = "ShaderNodeBlackbody"
|
|
245
|
+
node: bpy.types.ShaderNodeBlackbody
|
|
246
|
+
|
|
247
|
+
def __init__(self, temperature: TYPE_INPUT_VALUE = 6500.0):
|
|
248
|
+
super().__init__()
|
|
249
|
+
key_args = {"Temperature": temperature}
|
|
250
|
+
|
|
251
|
+
self._establish_links(**key_args)
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def i_temperature(self) -> SocketLinker:
|
|
255
|
+
"""Input socket: Temperature"""
|
|
256
|
+
return self._input("Temperature")
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def o_color(self) -> SocketLinker:
|
|
260
|
+
"""Output socket: Color"""
|
|
261
|
+
return self._output("Color")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class BooleanMath(NodeBuilder):
|
|
265
|
+
"""Perform a logical operation on the given boolean inputs"""
|
|
266
|
+
|
|
267
|
+
_bl_idname = "FunctionNodeBooleanMath"
|
|
268
|
+
node: bpy.types.FunctionNodeBooleanMath
|
|
269
|
+
|
|
270
|
+
def __init__(
|
|
271
|
+
self,
|
|
272
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
273
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
274
|
+
*,
|
|
275
|
+
operation: Literal[
|
|
276
|
+
"AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"
|
|
277
|
+
] = "AND",
|
|
278
|
+
):
|
|
279
|
+
super().__init__()
|
|
280
|
+
key_args = {"Boolean": boolean, "Boolean_001": boolean_001}
|
|
281
|
+
self.operation = operation
|
|
282
|
+
self._establish_links(**key_args)
|
|
283
|
+
|
|
284
|
+
@classmethod
|
|
285
|
+
def l_and(
|
|
286
|
+
cls,
|
|
287
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
288
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
289
|
+
) -> "BooleanMath":
|
|
290
|
+
"""Create Boolean Math with operation 'And'."""
|
|
291
|
+
return cls(operation="AND", boolean=boolean, boolean_001=boolean_001)
|
|
292
|
+
|
|
293
|
+
@classmethod
|
|
294
|
+
def l_or(
|
|
295
|
+
cls,
|
|
296
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
297
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
298
|
+
) -> "BooleanMath":
|
|
299
|
+
"""Create Boolean Math with operation 'Or'."""
|
|
300
|
+
return cls(operation="OR", boolean=boolean, boolean_001=boolean_001)
|
|
301
|
+
|
|
302
|
+
@classmethod
|
|
303
|
+
def l_not(cls, boolean: TYPE_INPUT_BOOLEAN = False) -> "BooleanMath":
|
|
304
|
+
"""Create Boolean Math with operation 'Not'."""
|
|
305
|
+
return cls(operation="NOT", boolean=boolean)
|
|
306
|
+
|
|
307
|
+
@classmethod
|
|
308
|
+
def nor(
|
|
309
|
+
cls,
|
|
310
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
311
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
312
|
+
) -> "BooleanMath":
|
|
313
|
+
"""Create Boolean Math with operation 'Nor'."""
|
|
314
|
+
return cls(operation="NOR", boolean=boolean, boolean_001=boolean_001)
|
|
315
|
+
|
|
316
|
+
@classmethod
|
|
317
|
+
def equal(
|
|
318
|
+
cls,
|
|
319
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
320
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
321
|
+
) -> "BooleanMath":
|
|
322
|
+
"""Create Boolean Math with operation 'Equal'."""
|
|
323
|
+
return cls(operation="XNOR", boolean=boolean, boolean_001=boolean_001)
|
|
324
|
+
|
|
325
|
+
@classmethod
|
|
326
|
+
def imply(
|
|
327
|
+
cls,
|
|
328
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
329
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
330
|
+
) -> "BooleanMath":
|
|
331
|
+
"""Create Boolean Math with operation 'Imply'."""
|
|
332
|
+
return cls(operation="IMPLY", boolean=boolean, boolean_001=boolean_001)
|
|
333
|
+
|
|
334
|
+
@classmethod
|
|
335
|
+
def subtract(
|
|
336
|
+
cls,
|
|
337
|
+
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
338
|
+
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
339
|
+
) -> "BooleanMath":
|
|
340
|
+
"""Create Boolean Math with operation 'Subtract'."""
|
|
341
|
+
return cls(operation="NIMPLY", boolean=boolean, boolean_001=boolean_001)
|
|
342
|
+
|
|
343
|
+
@property
|
|
344
|
+
def i_boolean(self) -> SocketLinker:
|
|
345
|
+
"""Input socket: Boolean"""
|
|
346
|
+
return self._input("Boolean")
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def i_boolean_001(self) -> SocketLinker:
|
|
350
|
+
"""Input socket: Boolean"""
|
|
351
|
+
return self._input("Boolean_001")
|
|
352
|
+
|
|
353
|
+
@property
|
|
354
|
+
def o_boolean(self) -> SocketLinker:
|
|
355
|
+
"""Output socket: Boolean"""
|
|
356
|
+
return self._output("Boolean")
|
|
357
|
+
|
|
358
|
+
@property
|
|
359
|
+
def operation(
|
|
360
|
+
self,
|
|
361
|
+
) -> Literal["AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"]:
|
|
362
|
+
return self.node.operation
|
|
363
|
+
|
|
364
|
+
@operation.setter
|
|
365
|
+
def operation(
|
|
366
|
+
self,
|
|
367
|
+
value: Literal[
|
|
368
|
+
"AND", "OR", "NOT", "NAND", "NOR", "XNOR", "XOR", "IMPLY", "NIMPLY"
|
|
369
|
+
],
|
|
370
|
+
):
|
|
371
|
+
self.node.operation = value
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
class Clamp(NodeBuilder):
|
|
375
|
+
"""Clamp a value between a minimum and a maximum"""
|
|
376
|
+
|
|
377
|
+
_bl_idname = "ShaderNodeClamp"
|
|
378
|
+
node: bpy.types.ShaderNodeClamp
|
|
379
|
+
|
|
380
|
+
def __init__(
|
|
381
|
+
self,
|
|
382
|
+
value: TYPE_INPUT_VALUE = 1.0,
|
|
383
|
+
min: TYPE_INPUT_VALUE = 0.0,
|
|
384
|
+
max: TYPE_INPUT_VALUE = 1.0,
|
|
385
|
+
*,
|
|
386
|
+
clamp_type: Literal["MINMAX", "RANGE"] = "MINMAX",
|
|
387
|
+
):
|
|
388
|
+
super().__init__()
|
|
389
|
+
key_args = {"Value": value, "Min": min, "Max": max}
|
|
390
|
+
self.clamp_type = clamp_type
|
|
391
|
+
self._establish_links(**key_args)
|
|
392
|
+
|
|
393
|
+
@property
|
|
394
|
+
def i_value(self) -> SocketLinker:
|
|
395
|
+
"""Input socket: Value"""
|
|
396
|
+
return self._input("Value")
|
|
397
|
+
|
|
398
|
+
@property
|
|
399
|
+
def i_min(self) -> SocketLinker:
|
|
400
|
+
"""Input socket: Min"""
|
|
401
|
+
return self._input("Min")
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def i_max(self) -> SocketLinker:
|
|
405
|
+
"""Input socket: Max"""
|
|
406
|
+
return self._input("Max")
|
|
407
|
+
|
|
408
|
+
@property
|
|
409
|
+
def o_result(self) -> SocketLinker:
|
|
410
|
+
"""Output socket: Result"""
|
|
411
|
+
return self._output("Result")
|
|
412
|
+
|
|
413
|
+
@property
|
|
414
|
+
def clamp_type(self) -> Literal["MINMAX", "RANGE"]:
|
|
415
|
+
return self.node.clamp_type
|
|
416
|
+
|
|
417
|
+
@clamp_type.setter
|
|
418
|
+
def clamp_type(self, value: Literal["MINMAX", "RANGE"]):
|
|
419
|
+
self.node.clamp_type = value
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
class ColorRamp(NodeBuilder):
|
|
423
|
+
"""Map values to colors with the use of a gradient"""
|
|
424
|
+
|
|
425
|
+
_bl_idname = "ShaderNodeValToRGB"
|
|
426
|
+
node: bpy.types.ShaderNodeValToRGB
|
|
427
|
+
|
|
428
|
+
def __init__(self, fac: TYPE_INPUT_VALUE = 0.5):
|
|
429
|
+
super().__init__()
|
|
430
|
+
key_args = {"Fac": fac}
|
|
431
|
+
|
|
432
|
+
self._establish_links(**key_args)
|
|
433
|
+
|
|
434
|
+
@property
|
|
435
|
+
def i_fac(self) -> SocketLinker:
|
|
436
|
+
"""Input socket: Factor"""
|
|
437
|
+
return self._input("Fac")
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
def o_color(self) -> SocketLinker:
|
|
441
|
+
"""Output socket: Color"""
|
|
442
|
+
return self._output("Color")
|
|
443
|
+
|
|
444
|
+
@property
|
|
445
|
+
def o_alpha(self) -> SocketLinker:
|
|
446
|
+
"""Output socket: Alpha"""
|
|
447
|
+
return self._output("Alpha")
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
class CombineBundle(NodeBuilder):
|
|
451
|
+
"""Combine multiple socket values into one."""
|
|
452
|
+
|
|
453
|
+
_bl_idname = "NodeCombineBundle"
|
|
454
|
+
node: bpy.types.Node
|
|
455
|
+
|
|
456
|
+
def __init__(self, define_signature: bool = False):
|
|
457
|
+
super().__init__()
|
|
458
|
+
key_args = {}
|
|
459
|
+
self.define_signature = define_signature
|
|
460
|
+
self._establish_links(**key_args)
|
|
461
|
+
|
|
462
|
+
@property
|
|
463
|
+
def o_bundle(self) -> SocketLinker:
|
|
464
|
+
"""Output socket: Bundle"""
|
|
465
|
+
return self._output("Bundle")
|
|
466
|
+
|
|
467
|
+
@property
|
|
468
|
+
def define_signature(self) -> bool:
|
|
469
|
+
return self.node.define_signature
|
|
470
|
+
|
|
471
|
+
@define_signature.setter
|
|
472
|
+
def define_signature(self, value: bool):
|
|
473
|
+
self.node.define_signature = value
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class CombineColor(NodeBuilder):
|
|
477
|
+
"""Combine four channels into a single color, based on a particular color model"""
|
|
478
|
+
|
|
479
|
+
_bl_idname = "FunctionNodeCombineColor"
|
|
480
|
+
node: bpy.types.FunctionNodeCombineColor
|
|
481
|
+
|
|
482
|
+
def __init__(
|
|
483
|
+
self,
|
|
484
|
+
red: TYPE_INPUT_VALUE = 0.0,
|
|
485
|
+
green: TYPE_INPUT_VALUE = 0.0,
|
|
486
|
+
blue: TYPE_INPUT_VALUE = 0.0,
|
|
487
|
+
alpha: TYPE_INPUT_VALUE = 1.0,
|
|
488
|
+
*,
|
|
489
|
+
mode: Literal["RGB", "HSV", "HSL"] = "RGB",
|
|
490
|
+
):
|
|
491
|
+
super().__init__()
|
|
492
|
+
key_args = {"Red": red, "Green": green, "Blue": blue, "Alpha": alpha}
|
|
493
|
+
self.mode = mode
|
|
494
|
+
self._establish_links(**key_args)
|
|
495
|
+
|
|
496
|
+
@property
|
|
497
|
+
def i_red(self) -> SocketLinker:
|
|
498
|
+
"""Input socket: Red"""
|
|
499
|
+
return self._input("Red")
|
|
500
|
+
|
|
501
|
+
@property
|
|
502
|
+
def i_green(self) -> SocketLinker:
|
|
503
|
+
"""Input socket: Green"""
|
|
504
|
+
return self._input("Green")
|
|
505
|
+
|
|
506
|
+
@property
|
|
507
|
+
def i_blue(self) -> SocketLinker:
|
|
508
|
+
"""Input socket: Blue"""
|
|
509
|
+
return self._input("Blue")
|
|
510
|
+
|
|
511
|
+
@property
|
|
512
|
+
def i_alpha(self) -> SocketLinker:
|
|
513
|
+
"""Input socket: Alpha"""
|
|
514
|
+
return self._input("Alpha")
|
|
515
|
+
|
|
516
|
+
@property
|
|
517
|
+
def o_color(self) -> SocketLinker:
|
|
518
|
+
"""Output socket: Color"""
|
|
519
|
+
return self._output("Color")
|
|
520
|
+
|
|
521
|
+
@property
|
|
522
|
+
def mode(self) -> Literal["RGB", "HSV", "HSL"]:
|
|
523
|
+
return self.node.mode
|
|
524
|
+
|
|
525
|
+
@mode.setter
|
|
526
|
+
def mode(self, value: Literal["RGB", "HSV", "HSL"]):
|
|
527
|
+
self.node.mode = value
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
class CombineMatrix(NodeBuilder):
|
|
531
|
+
"""Construct a 4x4 matrix from its individual values"""
|
|
532
|
+
|
|
533
|
+
_bl_idname = "FunctionNodeCombineMatrix"
|
|
534
|
+
node: bpy.types.FunctionNodeCombineMatrix
|
|
535
|
+
|
|
536
|
+
def __init__(
|
|
537
|
+
self,
|
|
538
|
+
column_1_row_1: TYPE_INPUT_VALUE = 1.0,
|
|
539
|
+
column_1_row_2: TYPE_INPUT_VALUE = 0.0,
|
|
540
|
+
column_1_row_3: TYPE_INPUT_VALUE = 0.0,
|
|
541
|
+
column_1_row_4: TYPE_INPUT_VALUE = 0.0,
|
|
542
|
+
column_2_row_1: TYPE_INPUT_VALUE = 0.0,
|
|
543
|
+
column_2_row_2: TYPE_INPUT_VALUE = 1.0,
|
|
544
|
+
column_2_row_3: TYPE_INPUT_VALUE = 0.0,
|
|
545
|
+
column_2_row_4: TYPE_INPUT_VALUE = 0.0,
|
|
546
|
+
column_3_row_1: TYPE_INPUT_VALUE = 0.0,
|
|
547
|
+
column_3_row_2: TYPE_INPUT_VALUE = 0.0,
|
|
548
|
+
column_3_row_3: TYPE_INPUT_VALUE = 1.0,
|
|
549
|
+
column_3_row_4: TYPE_INPUT_VALUE = 0.0,
|
|
550
|
+
column_4_row_1: TYPE_INPUT_VALUE = 0.0,
|
|
551
|
+
column_4_row_2: TYPE_INPUT_VALUE = 0.0,
|
|
552
|
+
column_4_row_3: TYPE_INPUT_VALUE = 0.0,
|
|
553
|
+
column_4_row_4: TYPE_INPUT_VALUE = 1.0,
|
|
554
|
+
):
|
|
555
|
+
super().__init__()
|
|
556
|
+
key_args = {
|
|
557
|
+
"Column 1 Row 1": column_1_row_1,
|
|
558
|
+
"Column 1 Row 2": column_1_row_2,
|
|
559
|
+
"Column 1 Row 3": column_1_row_3,
|
|
560
|
+
"Column 1 Row 4": column_1_row_4,
|
|
561
|
+
"Column 2 Row 1": column_2_row_1,
|
|
562
|
+
"Column 2 Row 2": column_2_row_2,
|
|
563
|
+
"Column 2 Row 3": column_2_row_3,
|
|
564
|
+
"Column 2 Row 4": column_2_row_4,
|
|
565
|
+
"Column 3 Row 1": column_3_row_1,
|
|
566
|
+
"Column 3 Row 2": column_3_row_2,
|
|
567
|
+
"Column 3 Row 3": column_3_row_3,
|
|
568
|
+
"Column 3 Row 4": column_3_row_4,
|
|
569
|
+
"Column 4 Row 1": column_4_row_1,
|
|
570
|
+
"Column 4 Row 2": column_4_row_2,
|
|
571
|
+
"Column 4 Row 3": column_4_row_3,
|
|
572
|
+
"Column 4 Row 4": column_4_row_4,
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
self._establish_links(**key_args)
|
|
576
|
+
|
|
577
|
+
@property
|
|
578
|
+
def i_column_1_row_1(self) -> SocketLinker:
|
|
579
|
+
"""Input socket: Column 1 Row 1"""
|
|
580
|
+
return self._input("Column 1 Row 1")
|
|
581
|
+
|
|
582
|
+
@property
|
|
583
|
+
def i_column_1_row_2(self) -> SocketLinker:
|
|
584
|
+
"""Input socket: Column 1 Row 2"""
|
|
585
|
+
return self._input("Column 1 Row 2")
|
|
586
|
+
|
|
587
|
+
@property
|
|
588
|
+
def i_column_1_row_3(self) -> SocketLinker:
|
|
589
|
+
"""Input socket: Column 1 Row 3"""
|
|
590
|
+
return self._input("Column 1 Row 3")
|
|
591
|
+
|
|
592
|
+
@property
|
|
593
|
+
def i_column_1_row_4(self) -> SocketLinker:
|
|
594
|
+
"""Input socket: Column 1 Row 4"""
|
|
595
|
+
return self._input("Column 1 Row 4")
|
|
596
|
+
|
|
597
|
+
@property
|
|
598
|
+
def i_column_2_row_1(self) -> SocketLinker:
|
|
599
|
+
"""Input socket: Column 2 Row 1"""
|
|
600
|
+
return self._input("Column 2 Row 1")
|
|
601
|
+
|
|
602
|
+
@property
|
|
603
|
+
def i_column_2_row_2(self) -> SocketLinker:
|
|
604
|
+
"""Input socket: Column 2 Row 2"""
|
|
605
|
+
return self._input("Column 2 Row 2")
|
|
606
|
+
|
|
607
|
+
@property
|
|
608
|
+
def i_column_2_row_3(self) -> SocketLinker:
|
|
609
|
+
"""Input socket: Column 2 Row 3"""
|
|
610
|
+
return self._input("Column 2 Row 3")
|
|
611
|
+
|
|
612
|
+
@property
|
|
613
|
+
def i_column_2_row_4(self) -> SocketLinker:
|
|
614
|
+
"""Input socket: Column 2 Row 4"""
|
|
615
|
+
return self._input("Column 2 Row 4")
|
|
616
|
+
|
|
617
|
+
@property
|
|
618
|
+
def i_column_3_row_1(self) -> SocketLinker:
|
|
619
|
+
"""Input socket: Column 3 Row 1"""
|
|
620
|
+
return self._input("Column 3 Row 1")
|
|
621
|
+
|
|
622
|
+
@property
|
|
623
|
+
def i_column_3_row_2(self) -> SocketLinker:
|
|
624
|
+
"""Input socket: Column 3 Row 2"""
|
|
625
|
+
return self._input("Column 3 Row 2")
|
|
626
|
+
|
|
627
|
+
@property
|
|
628
|
+
def i_column_3_row_3(self) -> SocketLinker:
|
|
629
|
+
"""Input socket: Column 3 Row 3"""
|
|
630
|
+
return self._input("Column 3 Row 3")
|
|
631
|
+
|
|
632
|
+
@property
|
|
633
|
+
def i_column_3_row_4(self) -> SocketLinker:
|
|
634
|
+
"""Input socket: Column 3 Row 4"""
|
|
635
|
+
return self._input("Column 3 Row 4")
|
|
636
|
+
|
|
637
|
+
@property
|
|
638
|
+
def i_column_4_row_1(self) -> SocketLinker:
|
|
639
|
+
"""Input socket: Column 4 Row 1"""
|
|
640
|
+
return self._input("Column 4 Row 1")
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
def i_column_4_row_2(self) -> SocketLinker:
|
|
644
|
+
"""Input socket: Column 4 Row 2"""
|
|
645
|
+
return self._input("Column 4 Row 2")
|
|
646
|
+
|
|
647
|
+
@property
|
|
648
|
+
def i_column_4_row_3(self) -> SocketLinker:
|
|
649
|
+
"""Input socket: Column 4 Row 3"""
|
|
650
|
+
return self._input("Column 4 Row 3")
|
|
651
|
+
|
|
652
|
+
@property
|
|
653
|
+
def i_column_4_row_4(self) -> SocketLinker:
|
|
654
|
+
"""Input socket: Column 4 Row 4"""
|
|
655
|
+
return self._input("Column 4 Row 4")
|
|
656
|
+
|
|
657
|
+
@property
|
|
658
|
+
def o_matrix(self) -> SocketLinker:
|
|
659
|
+
"""Output socket: Matrix"""
|
|
660
|
+
return self._output("Matrix")
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
class CombineTransform(NodeBuilder):
|
|
664
|
+
"""Combine a translation vector, a rotation, and a scale vector into a transformation matrix"""
|
|
665
|
+
|
|
666
|
+
_bl_idname = "FunctionNodeCombineTransform"
|
|
667
|
+
node: bpy.types.FunctionNodeCombineTransform
|
|
668
|
+
|
|
669
|
+
def __init__(
|
|
670
|
+
self,
|
|
671
|
+
translation: TYPE_INPUT_VECTOR = None,
|
|
672
|
+
rotation: TYPE_INPUT_ROTATION = None,
|
|
673
|
+
scale: TYPE_INPUT_VECTOR = None,
|
|
674
|
+
):
|
|
675
|
+
super().__init__()
|
|
676
|
+
key_args = {"Translation": translation, "Rotation": rotation, "Scale": scale}
|
|
677
|
+
|
|
678
|
+
self._establish_links(**key_args)
|
|
679
|
+
|
|
680
|
+
@property
|
|
681
|
+
def i_translation(self) -> SocketLinker:
|
|
682
|
+
"""Input socket: Translation"""
|
|
683
|
+
return self._input("Translation")
|
|
684
|
+
|
|
685
|
+
@property
|
|
686
|
+
def i_rotation(self) -> SocketLinker:
|
|
687
|
+
"""Input socket: Rotation"""
|
|
688
|
+
return self._input("Rotation")
|
|
689
|
+
|
|
690
|
+
@property
|
|
691
|
+
def i_scale(self) -> SocketLinker:
|
|
692
|
+
"""Input socket: Scale"""
|
|
693
|
+
return self._input("Scale")
|
|
694
|
+
|
|
695
|
+
@property
|
|
696
|
+
def o_transform(self) -> SocketLinker:
|
|
697
|
+
"""Output socket: Transform"""
|
|
698
|
+
return self._output("Transform")
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
class CombineXYZ(NodeBuilder):
|
|
702
|
+
"""Create a vector from X, Y, and Z components"""
|
|
703
|
+
|
|
704
|
+
_bl_idname = "ShaderNodeCombineXYZ"
|
|
705
|
+
node: bpy.types.ShaderNodeCombineXYZ
|
|
706
|
+
|
|
707
|
+
def __init__(
|
|
708
|
+
self,
|
|
709
|
+
x: TYPE_INPUT_VALUE = 0.0,
|
|
710
|
+
y: TYPE_INPUT_VALUE = 0.0,
|
|
711
|
+
z: TYPE_INPUT_VALUE = 0.0,
|
|
712
|
+
):
|
|
713
|
+
super().__init__()
|
|
714
|
+
key_args = {"X": x, "Y": y, "Z": z}
|
|
715
|
+
|
|
716
|
+
self._establish_links(**key_args)
|
|
717
|
+
|
|
718
|
+
@property
|
|
719
|
+
def i_x(self) -> SocketLinker:
|
|
720
|
+
"""Input socket: X"""
|
|
721
|
+
return self._input("X")
|
|
722
|
+
|
|
723
|
+
@property
|
|
724
|
+
def i_y(self) -> SocketLinker:
|
|
725
|
+
"""Input socket: Y"""
|
|
726
|
+
return self._input("Y")
|
|
727
|
+
|
|
728
|
+
@property
|
|
729
|
+
def i_z(self) -> SocketLinker:
|
|
730
|
+
"""Input socket: Z"""
|
|
731
|
+
return self._input("Z")
|
|
732
|
+
|
|
733
|
+
@property
|
|
734
|
+
def o_vector(self) -> SocketLinker:
|
|
735
|
+
"""Output socket: Vector"""
|
|
736
|
+
return self._output("Vector")
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
class EulerToRotation(NodeBuilder):
|
|
740
|
+
"""Build a rotation from separate angles around each axis"""
|
|
741
|
+
|
|
742
|
+
_bl_idname = "FunctionNodeEulerToRotation"
|
|
743
|
+
node: bpy.types.FunctionNodeEulerToRotation
|
|
744
|
+
|
|
745
|
+
def __init__(self, euler: TYPE_INPUT_VECTOR = None):
|
|
746
|
+
super().__init__()
|
|
747
|
+
key_args = {"Euler": euler}
|
|
748
|
+
|
|
749
|
+
self._establish_links(**key_args)
|
|
750
|
+
|
|
751
|
+
@property
|
|
752
|
+
def i_euler(self) -> SocketLinker:
|
|
753
|
+
"""Input socket: Euler"""
|
|
754
|
+
return self._input("Euler")
|
|
755
|
+
|
|
756
|
+
@property
|
|
757
|
+
def o_rotation(self) -> SocketLinker:
|
|
758
|
+
"""Output socket: Rotation"""
|
|
759
|
+
return self._output("Rotation")
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
class FindInString(NodeBuilder):
|
|
763
|
+
"""Find the number of times a given string occurs in another string and the position of the first match"""
|
|
764
|
+
|
|
765
|
+
_bl_idname = "FunctionNodeFindInString"
|
|
766
|
+
node: bpy.types.FunctionNodeFindInString
|
|
767
|
+
|
|
768
|
+
def __init__(
|
|
769
|
+
self,
|
|
770
|
+
string: TYPE_INPUT_STRING = "",
|
|
771
|
+
search: TYPE_INPUT_STRING = "",
|
|
772
|
+
):
|
|
773
|
+
super().__init__()
|
|
774
|
+
key_args = {"String": string, "Search": search}
|
|
775
|
+
|
|
776
|
+
self._establish_links(**key_args)
|
|
777
|
+
|
|
778
|
+
@property
|
|
779
|
+
def i_string(self) -> SocketLinker:
|
|
780
|
+
"""Input socket: String"""
|
|
781
|
+
return self._input("String")
|
|
782
|
+
|
|
783
|
+
@property
|
|
784
|
+
def i_search(self) -> SocketLinker:
|
|
785
|
+
"""Input socket: Search"""
|
|
786
|
+
return self._input("Search")
|
|
787
|
+
|
|
788
|
+
@property
|
|
789
|
+
def o_first_found(self) -> SocketLinker:
|
|
790
|
+
"""Output socket: First Found"""
|
|
791
|
+
return self._output("First Found")
|
|
792
|
+
|
|
793
|
+
@property
|
|
794
|
+
def o_count(self) -> SocketLinker:
|
|
795
|
+
"""Output socket: Count"""
|
|
796
|
+
return self._output("Count")
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
class FloatCurve(NodeBuilder):
|
|
800
|
+
"""Map an input float to a curve and outputs a float value"""
|
|
801
|
+
|
|
802
|
+
_bl_idname = "ShaderNodeFloatCurve"
|
|
803
|
+
node: bpy.types.ShaderNodeFloatCurve
|
|
804
|
+
|
|
805
|
+
def __init__(
|
|
806
|
+
self,
|
|
807
|
+
factor: TYPE_INPUT_VALUE = 1.0,
|
|
808
|
+
value: TYPE_INPUT_VALUE = 1.0,
|
|
809
|
+
):
|
|
810
|
+
super().__init__()
|
|
811
|
+
key_args = {"Factor": factor, "Value": value}
|
|
812
|
+
|
|
813
|
+
self._establish_links(**key_args)
|
|
814
|
+
|
|
815
|
+
@property
|
|
816
|
+
def i_factor(self) -> SocketLinker:
|
|
817
|
+
"""Input socket: Factor"""
|
|
818
|
+
return self._input("Factor")
|
|
819
|
+
|
|
820
|
+
@property
|
|
821
|
+
def i_value(self) -> SocketLinker:
|
|
822
|
+
"""Input socket: Value"""
|
|
823
|
+
return self._input("Value")
|
|
824
|
+
|
|
825
|
+
@property
|
|
826
|
+
def o_value(self) -> SocketLinker:
|
|
827
|
+
"""Output socket: Value"""
|
|
828
|
+
return self._output("Value")
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
class FloatToInteger(NodeBuilder):
|
|
832
|
+
"""Convert the given floating-point number to an integer, with a choice of methods"""
|
|
833
|
+
|
|
834
|
+
_bl_idname = "FunctionNodeFloatToInt"
|
|
835
|
+
node: bpy.types.FunctionNodeFloatToInt
|
|
836
|
+
|
|
837
|
+
def __init__(
|
|
838
|
+
self,
|
|
839
|
+
float: TYPE_INPUT_VALUE = 0.0,
|
|
840
|
+
*,
|
|
841
|
+
rounding_mode: Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"] = "ROUND",
|
|
842
|
+
):
|
|
843
|
+
super().__init__()
|
|
844
|
+
key_args = {"Float": float}
|
|
845
|
+
self.rounding_mode = rounding_mode
|
|
846
|
+
self._establish_links(**key_args)
|
|
847
|
+
|
|
848
|
+
@property
|
|
849
|
+
def i_float(self) -> SocketLinker:
|
|
850
|
+
"""Input socket: Float"""
|
|
851
|
+
return self._input("Float")
|
|
852
|
+
|
|
853
|
+
@property
|
|
854
|
+
def o_integer(self) -> SocketLinker:
|
|
855
|
+
"""Output socket: Integer"""
|
|
856
|
+
return self._output("Integer")
|
|
857
|
+
|
|
858
|
+
@property
|
|
859
|
+
def rounding_mode(self) -> Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"]:
|
|
860
|
+
return self.node.rounding_mode
|
|
861
|
+
|
|
862
|
+
@rounding_mode.setter
|
|
863
|
+
def rounding_mode(self, value: Literal["ROUND", "FLOOR", "CEILING", "TRUNCATE"]):
|
|
864
|
+
self.node.rounding_mode = value
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
class HashValue(NodeBuilder):
|
|
868
|
+
"""Generate a randomized integer using the given input value as a seed"""
|
|
869
|
+
|
|
870
|
+
_bl_idname = "FunctionNodeHashValue"
|
|
871
|
+
node: bpy.types.FunctionNodeHashValue
|
|
872
|
+
|
|
873
|
+
def __init__(
|
|
874
|
+
self,
|
|
875
|
+
value: TYPE_INPUT_INT = 0,
|
|
876
|
+
seed: TYPE_INPUT_INT = 0,
|
|
877
|
+
*,
|
|
878
|
+
data_type: Literal[
|
|
879
|
+
"FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"
|
|
880
|
+
] = "INT",
|
|
881
|
+
):
|
|
882
|
+
super().__init__()
|
|
883
|
+
key_args = {"Value": value, "Seed": seed}
|
|
884
|
+
self.data_type = data_type
|
|
885
|
+
self._establish_links(**key_args)
|
|
886
|
+
|
|
887
|
+
@classmethod
|
|
888
|
+
def float(
|
|
889
|
+
cls, value: TYPE_INPUT_VALUE = 0.0, seed: TYPE_INPUT_INT = 0
|
|
890
|
+
) -> "HashValue":
|
|
891
|
+
"""Create Hash Value with operation 'Float'."""
|
|
892
|
+
return cls(data_type="FLOAT", value=value, seed=seed)
|
|
893
|
+
|
|
894
|
+
@classmethod
|
|
895
|
+
def integer(
|
|
896
|
+
cls, value: TYPE_INPUT_INT = 0, seed: TYPE_INPUT_INT = 0
|
|
897
|
+
) -> "HashValue":
|
|
898
|
+
"""Create Hash Value with operation 'Integer'."""
|
|
899
|
+
return cls(data_type="INT", value=value, seed=seed)
|
|
900
|
+
|
|
901
|
+
@classmethod
|
|
902
|
+
def vector(
|
|
903
|
+
cls, value: TYPE_INPUT_VECTOR = None, seed: TYPE_INPUT_INT = 0
|
|
904
|
+
) -> "HashValue":
|
|
905
|
+
"""Create Hash Value with operation 'Vector'."""
|
|
906
|
+
return cls(data_type="VECTOR", value=value, seed=seed)
|
|
907
|
+
|
|
908
|
+
@classmethod
|
|
909
|
+
def color(
|
|
910
|
+
cls, value: TYPE_INPUT_COLOR = None, seed: TYPE_INPUT_INT = 0
|
|
911
|
+
) -> "HashValue":
|
|
912
|
+
"""Create Hash Value with operation 'Color'."""
|
|
913
|
+
return cls(data_type="RGBA", value=value, seed=seed)
|
|
914
|
+
|
|
915
|
+
@classmethod
|
|
916
|
+
def rotation(
|
|
917
|
+
cls, value: TYPE_INPUT_ROTATION = None, seed: TYPE_INPUT_INT = 0
|
|
918
|
+
) -> "HashValue":
|
|
919
|
+
"""Create Hash Value with operation 'Rotation'."""
|
|
920
|
+
return cls(data_type="ROTATION", value=value, seed=seed)
|
|
921
|
+
|
|
922
|
+
@classmethod
|
|
923
|
+
def matrix(
|
|
924
|
+
cls, value: TYPE_INPUT_MATRIX = None, seed: TYPE_INPUT_INT = 0
|
|
925
|
+
) -> "HashValue":
|
|
926
|
+
"""Create Hash Value with operation 'Matrix'."""
|
|
927
|
+
return cls(data_type="MATRIX", value=value, seed=seed)
|
|
928
|
+
|
|
929
|
+
@classmethod
|
|
930
|
+
def string(
|
|
931
|
+
cls, value: TYPE_INPUT_STRING = "", seed: TYPE_INPUT_INT = 0
|
|
932
|
+
) -> "HashValue":
|
|
933
|
+
"""Create Hash Value with operation 'String'."""
|
|
934
|
+
return cls(data_type="STRING", value=value, seed=seed)
|
|
935
|
+
|
|
936
|
+
@property
|
|
937
|
+
def i_value(self) -> SocketLinker:
|
|
938
|
+
"""Input socket: Value"""
|
|
939
|
+
return self._input("Value")
|
|
940
|
+
|
|
941
|
+
@property
|
|
942
|
+
def i_seed(self) -> SocketLinker:
|
|
943
|
+
"""Input socket: Seed"""
|
|
944
|
+
return self._input("Seed")
|
|
945
|
+
|
|
946
|
+
@property
|
|
947
|
+
def o_hash(self) -> SocketLinker:
|
|
948
|
+
"""Output socket: Hash"""
|
|
949
|
+
return self._output("Hash")
|
|
950
|
+
|
|
951
|
+
@property
|
|
952
|
+
def data_type(
|
|
953
|
+
self,
|
|
954
|
+
) -> Literal["FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"]:
|
|
955
|
+
return self.node.data_type
|
|
956
|
+
|
|
957
|
+
@data_type.setter
|
|
958
|
+
def data_type(
|
|
959
|
+
self,
|
|
960
|
+
value: Literal[
|
|
961
|
+
"FLOAT", "INT", "VECTOR", "RGBA", "ROTATION", "MATRIX", "STRING"
|
|
962
|
+
],
|
|
963
|
+
):
|
|
964
|
+
self.node.data_type = value
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
class IndexOfNearest(NodeBuilder):
|
|
968
|
+
"""Find the nearest element in a group. Similar to the "Sample Nearest" node"""
|
|
969
|
+
|
|
970
|
+
_bl_idname = "GeometryNodeIndexOfNearest"
|
|
971
|
+
node: bpy.types.GeometryNodeIndexOfNearest
|
|
972
|
+
|
|
973
|
+
def __init__(
|
|
974
|
+
self,
|
|
975
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
976
|
+
group_id: TYPE_INPUT_INT = 0,
|
|
977
|
+
):
|
|
978
|
+
super().__init__()
|
|
979
|
+
key_args = {"Position": position, "Group ID": group_id}
|
|
980
|
+
|
|
981
|
+
self._establish_links(**key_args)
|
|
982
|
+
|
|
983
|
+
@property
|
|
984
|
+
def i_position(self) -> SocketLinker:
|
|
985
|
+
"""Input socket: Position"""
|
|
986
|
+
return self._input("Position")
|
|
987
|
+
|
|
988
|
+
@property
|
|
989
|
+
def i_group_id(self) -> SocketLinker:
|
|
990
|
+
"""Input socket: Group ID"""
|
|
991
|
+
return self._input("Group ID")
|
|
992
|
+
|
|
993
|
+
@property
|
|
994
|
+
def o_index(self) -> SocketLinker:
|
|
995
|
+
"""Output socket: Index"""
|
|
996
|
+
return self._output("Index")
|
|
997
|
+
|
|
998
|
+
@property
|
|
999
|
+
def o_has_neighbor(self) -> SocketLinker:
|
|
1000
|
+
"""Output socket: Has Neighbor"""
|
|
1001
|
+
return self._output("Has Neighbor")
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
class IntegerMath(NodeBuilder):
|
|
1005
|
+
"""Perform various math operations on the given integer inputs"""
|
|
1006
|
+
|
|
1007
|
+
_bl_idname = "FunctionNodeIntegerMath"
|
|
1008
|
+
node: bpy.types.FunctionNodeIntegerMath
|
|
1009
|
+
|
|
1010
|
+
def __init__(
|
|
1011
|
+
self,
|
|
1012
|
+
value: TYPE_INPUT_INT = 0,
|
|
1013
|
+
value_001: TYPE_INPUT_INT = 0,
|
|
1014
|
+
value_002: TYPE_INPUT_INT = 0,
|
|
1015
|
+
*,
|
|
1016
|
+
operation: Literal[
|
|
1017
|
+
"ADD",
|
|
1018
|
+
"SUBTRACT",
|
|
1019
|
+
"MULTIPLY",
|
|
1020
|
+
"DIVIDE",
|
|
1021
|
+
"MULTIPLY_ADD",
|
|
1022
|
+
"ABSOLUTE",
|
|
1023
|
+
"NEGATE",
|
|
1024
|
+
"POWER",
|
|
1025
|
+
"MINIMUM",
|
|
1026
|
+
"MAXIMUM",
|
|
1027
|
+
"SIGN",
|
|
1028
|
+
"DIVIDE_ROUND",
|
|
1029
|
+
"DIVIDE_FLOOR",
|
|
1030
|
+
"DIVIDE_CEIL",
|
|
1031
|
+
"FLOORED_MODULO",
|
|
1032
|
+
"MODULO",
|
|
1033
|
+
"GCD",
|
|
1034
|
+
"LCM",
|
|
1035
|
+
] = "ADD",
|
|
1036
|
+
):
|
|
1037
|
+
super().__init__()
|
|
1038
|
+
key_args = {"Value": value, "Value_001": value_001, "Value_002": value_002}
|
|
1039
|
+
self.operation = operation
|
|
1040
|
+
self._establish_links(**key_args)
|
|
1041
|
+
|
|
1042
|
+
@classmethod
|
|
1043
|
+
def add(
|
|
1044
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1045
|
+
) -> "IntegerMath":
|
|
1046
|
+
"""Create Integer Math with operation 'Add'."""
|
|
1047
|
+
return cls(operation="ADD", value=value, value_001=value_001)
|
|
1048
|
+
|
|
1049
|
+
@classmethod
|
|
1050
|
+
def subtract(
|
|
1051
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1052
|
+
) -> "IntegerMath":
|
|
1053
|
+
"""Create Integer Math with operation 'Subtract'."""
|
|
1054
|
+
return cls(operation="SUBTRACT", value=value, value_001=value_001)
|
|
1055
|
+
|
|
1056
|
+
@classmethod
|
|
1057
|
+
def multiply(
|
|
1058
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1059
|
+
) -> "IntegerMath":
|
|
1060
|
+
"""Create Integer Math with operation 'Multiply'."""
|
|
1061
|
+
return cls(operation="MULTIPLY", value=value, value_001=value_001)
|
|
1062
|
+
|
|
1063
|
+
@classmethod
|
|
1064
|
+
def divide(
|
|
1065
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1066
|
+
) -> "IntegerMath":
|
|
1067
|
+
"""Create Integer Math with operation 'Divide'."""
|
|
1068
|
+
return cls(operation="DIVIDE", value=value, value_001=value_001)
|
|
1069
|
+
|
|
1070
|
+
@classmethod
|
|
1071
|
+
def absolute(cls, value: TYPE_INPUT_INT = 0) -> "IntegerMath":
|
|
1072
|
+
"""Create Integer Math with operation 'Absolute'."""
|
|
1073
|
+
return cls(operation="ABSOLUTE", value=value)
|
|
1074
|
+
|
|
1075
|
+
@classmethod
|
|
1076
|
+
def negate(cls, value: TYPE_INPUT_INT = 0) -> "IntegerMath":
|
|
1077
|
+
"""Create Integer Math with operation 'Negate'."""
|
|
1078
|
+
return cls(operation="NEGATE", value=value)
|
|
1079
|
+
|
|
1080
|
+
@classmethod
|
|
1081
|
+
def power(
|
|
1082
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1083
|
+
) -> "IntegerMath":
|
|
1084
|
+
"""Create Integer Math with operation 'Power'."""
|
|
1085
|
+
return cls(operation="POWER", value=value, value_001=value_001)
|
|
1086
|
+
|
|
1087
|
+
@classmethod
|
|
1088
|
+
def minimum(
|
|
1089
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1090
|
+
) -> "IntegerMath":
|
|
1091
|
+
"""Create Integer Math with operation 'Minimum'."""
|
|
1092
|
+
return cls(operation="MINIMUM", value=value, value_001=value_001)
|
|
1093
|
+
|
|
1094
|
+
@classmethod
|
|
1095
|
+
def maximum(
|
|
1096
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1097
|
+
) -> "IntegerMath":
|
|
1098
|
+
"""Create Integer Math with operation 'Maximum'."""
|
|
1099
|
+
return cls(operation="MAXIMUM", value=value, value_001=value_001)
|
|
1100
|
+
|
|
1101
|
+
@classmethod
|
|
1102
|
+
def sign(cls, value: TYPE_INPUT_INT = 0) -> "IntegerMath":
|
|
1103
|
+
"""Create Integer Math with operation 'Sign'."""
|
|
1104
|
+
return cls(operation="SIGN", value=value)
|
|
1105
|
+
|
|
1106
|
+
@classmethod
|
|
1107
|
+
def modulo(
|
|
1108
|
+
cls, value: TYPE_INPUT_INT = 0, value_001: TYPE_INPUT_INT = 0
|
|
1109
|
+
) -> "IntegerMath":
|
|
1110
|
+
"""Create Integer Math with operation 'Modulo'."""
|
|
1111
|
+
return cls(operation="MODULO", value=value, value_001=value_001)
|
|
1112
|
+
|
|
1113
|
+
@property
|
|
1114
|
+
def i_value(self) -> SocketLinker:
|
|
1115
|
+
"""Input socket: Value"""
|
|
1116
|
+
return self._input("Value")
|
|
1117
|
+
|
|
1118
|
+
@property
|
|
1119
|
+
def i_value_001(self) -> SocketLinker:
|
|
1120
|
+
"""Input socket: Value"""
|
|
1121
|
+
return self._input("Value_001")
|
|
1122
|
+
|
|
1123
|
+
@property
|
|
1124
|
+
def i_value_002(self) -> SocketLinker:
|
|
1125
|
+
"""Input socket: Value"""
|
|
1126
|
+
return self._input("Value_002")
|
|
1127
|
+
|
|
1128
|
+
@property
|
|
1129
|
+
def o_value(self) -> SocketLinker:
|
|
1130
|
+
"""Output socket: Value"""
|
|
1131
|
+
return self._output("Value")
|
|
1132
|
+
|
|
1133
|
+
@property
|
|
1134
|
+
def operation(
|
|
1135
|
+
self,
|
|
1136
|
+
) -> Literal[
|
|
1137
|
+
"ADD",
|
|
1138
|
+
"SUBTRACT",
|
|
1139
|
+
"MULTIPLY",
|
|
1140
|
+
"DIVIDE",
|
|
1141
|
+
"MULTIPLY_ADD",
|
|
1142
|
+
"ABSOLUTE",
|
|
1143
|
+
"NEGATE",
|
|
1144
|
+
"POWER",
|
|
1145
|
+
"MINIMUM",
|
|
1146
|
+
"MAXIMUM",
|
|
1147
|
+
"SIGN",
|
|
1148
|
+
"DIVIDE_ROUND",
|
|
1149
|
+
"DIVIDE_FLOOR",
|
|
1150
|
+
"DIVIDE_CEIL",
|
|
1151
|
+
"FLOORED_MODULO",
|
|
1152
|
+
"MODULO",
|
|
1153
|
+
"GCD",
|
|
1154
|
+
"LCM",
|
|
1155
|
+
]:
|
|
1156
|
+
return self.node.operation
|
|
1157
|
+
|
|
1158
|
+
@operation.setter
|
|
1159
|
+
def operation(
|
|
1160
|
+
self,
|
|
1161
|
+
value: Literal[
|
|
1162
|
+
"ADD",
|
|
1163
|
+
"SUBTRACT",
|
|
1164
|
+
"MULTIPLY",
|
|
1165
|
+
"DIVIDE",
|
|
1166
|
+
"MULTIPLY_ADD",
|
|
1167
|
+
"ABSOLUTE",
|
|
1168
|
+
"NEGATE",
|
|
1169
|
+
"POWER",
|
|
1170
|
+
"MINIMUM",
|
|
1171
|
+
"MAXIMUM",
|
|
1172
|
+
"SIGN",
|
|
1173
|
+
"DIVIDE_ROUND",
|
|
1174
|
+
"DIVIDE_FLOOR",
|
|
1175
|
+
"DIVIDE_CEIL",
|
|
1176
|
+
"FLOORED_MODULO",
|
|
1177
|
+
"MODULO",
|
|
1178
|
+
"GCD",
|
|
1179
|
+
"LCM",
|
|
1180
|
+
],
|
|
1181
|
+
):
|
|
1182
|
+
self.node.operation = value
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
class InvertMatrix(NodeBuilder):
|
|
1186
|
+
"""Compute the inverse of the given matrix, if one exists"""
|
|
1187
|
+
|
|
1188
|
+
_bl_idname = "FunctionNodeInvertMatrix"
|
|
1189
|
+
node: bpy.types.FunctionNodeInvertMatrix
|
|
1190
|
+
|
|
1191
|
+
def __init__(self, matrix: TYPE_INPUT_MATRIX = None):
|
|
1192
|
+
super().__init__()
|
|
1193
|
+
key_args = {"Matrix": matrix}
|
|
1194
|
+
|
|
1195
|
+
self._establish_links(**key_args)
|
|
1196
|
+
|
|
1197
|
+
@property
|
|
1198
|
+
def i_matrix(self) -> SocketLinker:
|
|
1199
|
+
"""Input socket: Matrix"""
|
|
1200
|
+
return self._input("Matrix")
|
|
1201
|
+
|
|
1202
|
+
@property
|
|
1203
|
+
def o_matrix(self) -> SocketLinker:
|
|
1204
|
+
"""Output socket: Matrix"""
|
|
1205
|
+
return self._output("Matrix")
|
|
1206
|
+
|
|
1207
|
+
@property
|
|
1208
|
+
def o_invertible(self) -> SocketLinker:
|
|
1209
|
+
"""Output socket: Invertible"""
|
|
1210
|
+
return self._output("Invertible")
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
class InvertRotation(NodeBuilder):
|
|
1214
|
+
"""Compute the inverse of the given rotation"""
|
|
1215
|
+
|
|
1216
|
+
_bl_idname = "FunctionNodeInvertRotation"
|
|
1217
|
+
node: bpy.types.FunctionNodeInvertRotation
|
|
1218
|
+
|
|
1219
|
+
def __init__(self, rotation: TYPE_INPUT_ROTATION = None):
|
|
1220
|
+
super().__init__()
|
|
1221
|
+
key_args = {"Rotation": rotation}
|
|
1222
|
+
|
|
1223
|
+
self._establish_links(**key_args)
|
|
1224
|
+
|
|
1225
|
+
@property
|
|
1226
|
+
def i_rotation(self) -> SocketLinker:
|
|
1227
|
+
"""Input socket: Rotation"""
|
|
1228
|
+
return self._input("Rotation")
|
|
1229
|
+
|
|
1230
|
+
@property
|
|
1231
|
+
def o_rotation(self) -> SocketLinker:
|
|
1232
|
+
"""Output socket: Rotation"""
|
|
1233
|
+
return self._output("Rotation")
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
class JoinBundle(NodeBuilder):
|
|
1237
|
+
"""Join multiple bundles together"""
|
|
1238
|
+
|
|
1239
|
+
_bl_idname = "NodeJoinBundle"
|
|
1240
|
+
node: bpy.types.Node
|
|
1241
|
+
|
|
1242
|
+
def __init__(self, bundle: TYPE_INPUT_BUNDLE = None):
|
|
1243
|
+
super().__init__()
|
|
1244
|
+
key_args = {"Bundle": bundle}
|
|
1245
|
+
|
|
1246
|
+
self._establish_links(**key_args)
|
|
1247
|
+
|
|
1248
|
+
@property
|
|
1249
|
+
def i_bundle(self) -> SocketLinker:
|
|
1250
|
+
"""Input socket: Bundle"""
|
|
1251
|
+
return self._input("Bundle")
|
|
1252
|
+
|
|
1253
|
+
@property
|
|
1254
|
+
def o_bundle(self) -> SocketLinker:
|
|
1255
|
+
"""Output socket: Bundle"""
|
|
1256
|
+
return self._output("Bundle")
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
class MapRange(NodeBuilder):
|
|
1260
|
+
"""Remap a value from a range to a target range"""
|
|
1261
|
+
|
|
1262
|
+
_bl_idname = "ShaderNodeMapRange"
|
|
1263
|
+
node: bpy.types.ShaderNodeMapRange
|
|
1264
|
+
|
|
1265
|
+
def __init__(
|
|
1266
|
+
self,
|
|
1267
|
+
value: TYPE_INPUT_VALUE = 1.0,
|
|
1268
|
+
from_min: TYPE_INPUT_VALUE = 0.0,
|
|
1269
|
+
from_max: TYPE_INPUT_VALUE = 1.0,
|
|
1270
|
+
to_min: TYPE_INPUT_VALUE = 0.0,
|
|
1271
|
+
to_max: TYPE_INPUT_VALUE = 1.0,
|
|
1272
|
+
steps: TYPE_INPUT_VALUE = 4.0,
|
|
1273
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
1274
|
+
from_min_float3: TYPE_INPUT_VECTOR = None,
|
|
1275
|
+
from_max_float3: TYPE_INPUT_VECTOR = None,
|
|
1276
|
+
to_min_float3: TYPE_INPUT_VECTOR = None,
|
|
1277
|
+
to_max_float3: TYPE_INPUT_VECTOR = None,
|
|
1278
|
+
steps_float3: TYPE_INPUT_VECTOR = None,
|
|
1279
|
+
*,
|
|
1280
|
+
clamp: bool = False,
|
|
1281
|
+
interpolation_type: Literal[
|
|
1282
|
+
"LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"
|
|
1283
|
+
] = "LINEAR",
|
|
1284
|
+
data_type: Literal["FLOAT", "FLOAT_VECTOR"] = "FLOAT",
|
|
1285
|
+
):
|
|
1286
|
+
super().__init__()
|
|
1287
|
+
key_args = {
|
|
1288
|
+
"Value": value,
|
|
1289
|
+
"From Min": from_min,
|
|
1290
|
+
"From Max": from_max,
|
|
1291
|
+
"To Min": to_min,
|
|
1292
|
+
"To Max": to_max,
|
|
1293
|
+
"Steps": steps,
|
|
1294
|
+
"Vector": vector,
|
|
1295
|
+
"From_Min_FLOAT3": from_min_float3,
|
|
1296
|
+
"From_Max_FLOAT3": from_max_float3,
|
|
1297
|
+
"To_Min_FLOAT3": to_min_float3,
|
|
1298
|
+
"To_Max_FLOAT3": to_max_float3,
|
|
1299
|
+
"Steps_FLOAT3": steps_float3,
|
|
1300
|
+
}
|
|
1301
|
+
self.clamp = clamp
|
|
1302
|
+
self.interpolation_type = interpolation_type
|
|
1303
|
+
self.data_type = data_type
|
|
1304
|
+
self._establish_links(**key_args)
|
|
1305
|
+
|
|
1306
|
+
@classmethod
|
|
1307
|
+
def float(
|
|
1308
|
+
cls,
|
|
1309
|
+
value: TYPE_INPUT_VALUE = 1.0,
|
|
1310
|
+
from_min: TYPE_INPUT_VALUE = 0.0,
|
|
1311
|
+
from_max: TYPE_INPUT_VALUE = 1.0,
|
|
1312
|
+
to_min: TYPE_INPUT_VALUE = 0.0,
|
|
1313
|
+
to_max: TYPE_INPUT_VALUE = 1.0,
|
|
1314
|
+
) -> "MapRange":
|
|
1315
|
+
"""Create Map Range with operation 'Float'."""
|
|
1316
|
+
return cls(
|
|
1317
|
+
data_type="FLOAT",
|
|
1318
|
+
value=value,
|
|
1319
|
+
from_min=from_min,
|
|
1320
|
+
from_max=from_max,
|
|
1321
|
+
to_min=to_min,
|
|
1322
|
+
to_max=to_max,
|
|
1323
|
+
)
|
|
1324
|
+
|
|
1325
|
+
@classmethod
|
|
1326
|
+
def vector(
|
|
1327
|
+
cls,
|
|
1328
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
1329
|
+
from_min3: TYPE_INPUT_VECTOR = None,
|
|
1330
|
+
from_max3: TYPE_INPUT_VECTOR = None,
|
|
1331
|
+
to_min3: TYPE_INPUT_VECTOR = None,
|
|
1332
|
+
to_max3: TYPE_INPUT_VECTOR = None,
|
|
1333
|
+
) -> "MapRange":
|
|
1334
|
+
"""Create Map Range with operation 'Vector'."""
|
|
1335
|
+
return cls(
|
|
1336
|
+
data_type="FLOAT_VECTOR",
|
|
1337
|
+
vector=vector,
|
|
1338
|
+
from_min_float3=from_min3,
|
|
1339
|
+
from_max_float3=from_max3,
|
|
1340
|
+
to_min_float3=to_min3,
|
|
1341
|
+
to_max_float3=to_max3,
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
@property
|
|
1345
|
+
def i_value(self) -> SocketLinker:
|
|
1346
|
+
"""Input socket: Value"""
|
|
1347
|
+
return self._input("Value")
|
|
1348
|
+
|
|
1349
|
+
@property
|
|
1350
|
+
def i_from_min(self) -> SocketLinker:
|
|
1351
|
+
"""Input socket: From Min"""
|
|
1352
|
+
return self._input("From Min")
|
|
1353
|
+
|
|
1354
|
+
@property
|
|
1355
|
+
def i_from_max(self) -> SocketLinker:
|
|
1356
|
+
"""Input socket: From Max"""
|
|
1357
|
+
return self._input("From Max")
|
|
1358
|
+
|
|
1359
|
+
@property
|
|
1360
|
+
def i_to_min(self) -> SocketLinker:
|
|
1361
|
+
"""Input socket: To Min"""
|
|
1362
|
+
return self._input("To Min")
|
|
1363
|
+
|
|
1364
|
+
@property
|
|
1365
|
+
def i_to_max(self) -> SocketLinker:
|
|
1366
|
+
"""Input socket: To Max"""
|
|
1367
|
+
return self._input("To Max")
|
|
1368
|
+
|
|
1369
|
+
@property
|
|
1370
|
+
def i_steps(self) -> SocketLinker:
|
|
1371
|
+
"""Input socket: Steps"""
|
|
1372
|
+
return self._input("Steps")
|
|
1373
|
+
|
|
1374
|
+
@property
|
|
1375
|
+
def i_vector(self) -> SocketLinker:
|
|
1376
|
+
"""Input socket: Vector"""
|
|
1377
|
+
return self._input("Vector")
|
|
1378
|
+
|
|
1379
|
+
@property
|
|
1380
|
+
def i_from_min_float3(self) -> SocketLinker:
|
|
1381
|
+
"""Input socket: From Min"""
|
|
1382
|
+
return self._input("From_Min_FLOAT3")
|
|
1383
|
+
|
|
1384
|
+
@property
|
|
1385
|
+
def i_from_max_float3(self) -> SocketLinker:
|
|
1386
|
+
"""Input socket: From Max"""
|
|
1387
|
+
return self._input("From_Max_FLOAT3")
|
|
1388
|
+
|
|
1389
|
+
@property
|
|
1390
|
+
def i_to_min_float3(self) -> SocketLinker:
|
|
1391
|
+
"""Input socket: To Min"""
|
|
1392
|
+
return self._input("To_Min_FLOAT3")
|
|
1393
|
+
|
|
1394
|
+
@property
|
|
1395
|
+
def i_to_max_float3(self) -> SocketLinker:
|
|
1396
|
+
"""Input socket: To Max"""
|
|
1397
|
+
return self._input("To_Max_FLOAT3")
|
|
1398
|
+
|
|
1399
|
+
@property
|
|
1400
|
+
def i_steps_float3(self) -> SocketLinker:
|
|
1401
|
+
"""Input socket: Steps"""
|
|
1402
|
+
return self._input("Steps_FLOAT3")
|
|
1403
|
+
|
|
1404
|
+
@property
|
|
1405
|
+
def o_result(self) -> SocketLinker:
|
|
1406
|
+
"""Output socket: Result"""
|
|
1407
|
+
return self._output("Result")
|
|
1408
|
+
|
|
1409
|
+
@property
|
|
1410
|
+
def o_vector(self) -> SocketLinker:
|
|
1411
|
+
"""Output socket: Vector"""
|
|
1412
|
+
return self._output("Vector")
|
|
1413
|
+
|
|
1414
|
+
@property
|
|
1415
|
+
def clamp(self) -> bool:
|
|
1416
|
+
return self.node.clamp
|
|
1417
|
+
|
|
1418
|
+
@clamp.setter
|
|
1419
|
+
def clamp(self, value: bool):
|
|
1420
|
+
self.node.clamp = value
|
|
1421
|
+
|
|
1422
|
+
@property
|
|
1423
|
+
def interpolation_type(
|
|
1424
|
+
self,
|
|
1425
|
+
) -> Literal["LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"]:
|
|
1426
|
+
return self.node.interpolation_type
|
|
1427
|
+
|
|
1428
|
+
@interpolation_type.setter
|
|
1429
|
+
def interpolation_type(
|
|
1430
|
+
self, value: Literal["LINEAR", "STEPPED", "SMOOTHSTEP", "SMOOTHERSTEP"]
|
|
1431
|
+
):
|
|
1432
|
+
self.node.interpolation_type = value
|
|
1433
|
+
|
|
1434
|
+
@property
|
|
1435
|
+
def data_type(self) -> Literal["FLOAT", "FLOAT_VECTOR"]:
|
|
1436
|
+
return self.node.data_type
|
|
1437
|
+
|
|
1438
|
+
@data_type.setter
|
|
1439
|
+
def data_type(self, value: Literal["FLOAT", "FLOAT_VECTOR"]):
|
|
1440
|
+
self.node.data_type = value
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
class MatchString(NodeBuilder):
|
|
1444
|
+
"""Check if a given string exists within another string"""
|
|
1445
|
+
|
|
1446
|
+
_bl_idname = "FunctionNodeMatchString"
|
|
1447
|
+
node: bpy.types.FunctionNodeMatchString
|
|
1448
|
+
|
|
1449
|
+
def __init__(
|
|
1450
|
+
self,
|
|
1451
|
+
string: TYPE_INPUT_STRING = "",
|
|
1452
|
+
operation: TYPE_INPUT_MENU = "Starts With",
|
|
1453
|
+
key: TYPE_INPUT_STRING = "",
|
|
1454
|
+
):
|
|
1455
|
+
super().__init__()
|
|
1456
|
+
key_args = {"String": string, "Operation": operation, "Key": key}
|
|
1457
|
+
|
|
1458
|
+
self._establish_links(**key_args)
|
|
1459
|
+
|
|
1460
|
+
@property
|
|
1461
|
+
def i_string(self) -> SocketLinker:
|
|
1462
|
+
"""Input socket: String"""
|
|
1463
|
+
return self._input("String")
|
|
1464
|
+
|
|
1465
|
+
@property
|
|
1466
|
+
def i_operation(self) -> SocketLinker:
|
|
1467
|
+
"""Input socket: Operation"""
|
|
1468
|
+
return self._input("Operation")
|
|
1469
|
+
|
|
1470
|
+
@property
|
|
1471
|
+
def i_key(self) -> SocketLinker:
|
|
1472
|
+
"""Input socket: Key"""
|
|
1473
|
+
return self._input("Key")
|
|
1474
|
+
|
|
1475
|
+
@property
|
|
1476
|
+
def o_result(self) -> SocketLinker:
|
|
1477
|
+
"""Output socket: Result"""
|
|
1478
|
+
return self._output("Result")
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
class Math(NodeBuilder):
|
|
1482
|
+
"""Perform math operations"""
|
|
1483
|
+
|
|
1484
|
+
_bl_idname = "ShaderNodeMath"
|
|
1485
|
+
node: bpy.types.ShaderNodeMath
|
|
1486
|
+
|
|
1487
|
+
def __init__(
|
|
1488
|
+
self,
|
|
1489
|
+
value: TYPE_INPUT_VALUE = 0.5,
|
|
1490
|
+
value_001: TYPE_INPUT_VALUE = 0.5,
|
|
1491
|
+
value_002: TYPE_INPUT_VALUE = 0.5,
|
|
1492
|
+
*,
|
|
1493
|
+
operation: Literal[
|
|
1494
|
+
"ADD",
|
|
1495
|
+
"SUBTRACT",
|
|
1496
|
+
"MULTIPLY",
|
|
1497
|
+
"DIVIDE",
|
|
1498
|
+
"MULTIPLY_ADD",
|
|
1499
|
+
"POWER",
|
|
1500
|
+
"LOGARITHM",
|
|
1501
|
+
"SQRT",
|
|
1502
|
+
"INVERSE_SQRT",
|
|
1503
|
+
"ABSOLUTE",
|
|
1504
|
+
"EXPONENT",
|
|
1505
|
+
"MINIMUM",
|
|
1506
|
+
"MAXIMUM",
|
|
1507
|
+
"LESS_THAN",
|
|
1508
|
+
"GREATER_THAN",
|
|
1509
|
+
"SIGN",
|
|
1510
|
+
"COMPARE",
|
|
1511
|
+
"SMOOTH_MIN",
|
|
1512
|
+
"SMOOTH_MAX",
|
|
1513
|
+
"ROUND",
|
|
1514
|
+
"FLOOR",
|
|
1515
|
+
"CEIL",
|
|
1516
|
+
"TRUNC",
|
|
1517
|
+
"FRACT",
|
|
1518
|
+
"MODULO",
|
|
1519
|
+
"FLOORED_MODULO",
|
|
1520
|
+
"WRAP",
|
|
1521
|
+
"SNAP",
|
|
1522
|
+
"PINGPONG",
|
|
1523
|
+
"SINE",
|
|
1524
|
+
"COSINE",
|
|
1525
|
+
"TANGENT",
|
|
1526
|
+
"ARCSINE",
|
|
1527
|
+
"ARCCOSINE",
|
|
1528
|
+
"ARCTANGENT",
|
|
1529
|
+
"ARCTAN2",
|
|
1530
|
+
"SINH",
|
|
1531
|
+
"COSH",
|
|
1532
|
+
"TANH",
|
|
1533
|
+
"RADIANS",
|
|
1534
|
+
"DEGREES",
|
|
1535
|
+
] = "ADD",
|
|
1536
|
+
use_clamp: bool = False,
|
|
1537
|
+
):
|
|
1538
|
+
super().__init__()
|
|
1539
|
+
key_args = {"Value": value, "Value_001": value_001, "Value_002": value_002}
|
|
1540
|
+
self.operation = operation
|
|
1541
|
+
self.use_clamp = use_clamp
|
|
1542
|
+
self._establish_links(**key_args)
|
|
1543
|
+
|
|
1544
|
+
@classmethod
|
|
1545
|
+
def add(
|
|
1546
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1547
|
+
) -> "Math":
|
|
1548
|
+
"""Create Math with operation 'Add'."""
|
|
1549
|
+
return cls(operation="ADD", value=value, value_001=value_001)
|
|
1550
|
+
|
|
1551
|
+
@classmethod
|
|
1552
|
+
def subtract(
|
|
1553
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1554
|
+
) -> "Math":
|
|
1555
|
+
"""Create Math with operation 'Subtract'."""
|
|
1556
|
+
return cls(operation="SUBTRACT", value=value, value_001=value_001)
|
|
1557
|
+
|
|
1558
|
+
@classmethod
|
|
1559
|
+
def multiply(
|
|
1560
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1561
|
+
) -> "Math":
|
|
1562
|
+
"""Create Math with operation 'Multiply'."""
|
|
1563
|
+
return cls(operation="MULTIPLY", value=value, value_001=value_001)
|
|
1564
|
+
|
|
1565
|
+
@classmethod
|
|
1566
|
+
def divide(
|
|
1567
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1568
|
+
) -> "Math":
|
|
1569
|
+
"""Create Math with operation 'Divide'."""
|
|
1570
|
+
return cls(operation="DIVIDE", value=value, value_001=value_001)
|
|
1571
|
+
|
|
1572
|
+
@classmethod
|
|
1573
|
+
def power(
|
|
1574
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1575
|
+
) -> "Math":
|
|
1576
|
+
"""Create Math with operation 'Power'."""
|
|
1577
|
+
return cls(operation="POWER", value=value, value_001=value_001)
|
|
1578
|
+
|
|
1579
|
+
@classmethod
|
|
1580
|
+
def logarithm(
|
|
1581
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1582
|
+
) -> "Math":
|
|
1583
|
+
"""Create Math with operation 'Logarithm'."""
|
|
1584
|
+
return cls(operation="LOGARITHM", value=value, value_001=value_001)
|
|
1585
|
+
|
|
1586
|
+
@classmethod
|
|
1587
|
+
def absolute(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1588
|
+
"""Create Math with operation 'Absolute'."""
|
|
1589
|
+
return cls(operation="ABSOLUTE", value=value)
|
|
1590
|
+
|
|
1591
|
+
@classmethod
|
|
1592
|
+
def exponent(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1593
|
+
"""Create Math with operation 'Exponent'."""
|
|
1594
|
+
return cls(operation="EXPONENT", value=value)
|
|
1595
|
+
|
|
1596
|
+
@classmethod
|
|
1597
|
+
def minimum(
|
|
1598
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1599
|
+
) -> "Math":
|
|
1600
|
+
"""Create Math with operation 'Minimum'."""
|
|
1601
|
+
return cls(operation="MINIMUM", value=value, value_001=value_001)
|
|
1602
|
+
|
|
1603
|
+
@classmethod
|
|
1604
|
+
def maximum(
|
|
1605
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1606
|
+
) -> "Math":
|
|
1607
|
+
"""Create Math with operation 'Maximum'."""
|
|
1608
|
+
return cls(operation="MAXIMUM", value=value, value_001=value_001)
|
|
1609
|
+
|
|
1610
|
+
@classmethod
|
|
1611
|
+
def sign(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1612
|
+
"""Create Math with operation 'Sign'."""
|
|
1613
|
+
return cls(operation="SIGN", value=value)
|
|
1614
|
+
|
|
1615
|
+
@classmethod
|
|
1616
|
+
def compare(
|
|
1617
|
+
cls,
|
|
1618
|
+
value: TYPE_INPUT_VALUE = 0.5,
|
|
1619
|
+
value_001: TYPE_INPUT_VALUE = 0.5,
|
|
1620
|
+
value_002: TYPE_INPUT_VALUE = 0.5,
|
|
1621
|
+
) -> "Math":
|
|
1622
|
+
"""Create Math with operation 'Compare'."""
|
|
1623
|
+
return cls(
|
|
1624
|
+
operation="COMPARE", value=value, value_001=value_001, value_002=value_002
|
|
1625
|
+
)
|
|
1626
|
+
|
|
1627
|
+
@classmethod
|
|
1628
|
+
def round(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1629
|
+
"""Create Math with operation 'Round'."""
|
|
1630
|
+
return cls(operation="ROUND", value=value)
|
|
1631
|
+
|
|
1632
|
+
@classmethod
|
|
1633
|
+
def floor(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1634
|
+
"""Create Math with operation 'Floor'."""
|
|
1635
|
+
return cls(operation="FLOOR", value=value)
|
|
1636
|
+
|
|
1637
|
+
@classmethod
|
|
1638
|
+
def ceil(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1639
|
+
"""Create Math with operation 'Ceil'."""
|
|
1640
|
+
return cls(operation="CEIL", value=value)
|
|
1641
|
+
|
|
1642
|
+
@classmethod
|
|
1643
|
+
def truncate(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1644
|
+
"""Create Math with operation 'Truncate'."""
|
|
1645
|
+
return cls(operation="TRUNC", value=value)
|
|
1646
|
+
|
|
1647
|
+
@classmethod
|
|
1648
|
+
def fraction(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1649
|
+
"""Create Math with operation 'Fraction'."""
|
|
1650
|
+
return cls(operation="FRACT", value=value)
|
|
1651
|
+
|
|
1652
|
+
@classmethod
|
|
1653
|
+
def wrap(
|
|
1654
|
+
cls,
|
|
1655
|
+
value: TYPE_INPUT_VALUE = 0.5,
|
|
1656
|
+
value_001: TYPE_INPUT_VALUE = 0.5,
|
|
1657
|
+
value_002: TYPE_INPUT_VALUE = 0.5,
|
|
1658
|
+
) -> "Math":
|
|
1659
|
+
"""Create Math with operation 'Wrap'."""
|
|
1660
|
+
return cls(
|
|
1661
|
+
operation="WRAP", value=value, value_001=value_001, value_002=value_002
|
|
1662
|
+
)
|
|
1663
|
+
|
|
1664
|
+
@classmethod
|
|
1665
|
+
def snap(
|
|
1666
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1667
|
+
) -> "Math":
|
|
1668
|
+
"""Create Math with operation 'Snap'."""
|
|
1669
|
+
return cls(operation="SNAP", value=value, value_001=value_001)
|
|
1670
|
+
|
|
1671
|
+
@classmethod
|
|
1672
|
+
def sine(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1673
|
+
"""Create Math with operation 'Sine'."""
|
|
1674
|
+
return cls(operation="SINE", value=value)
|
|
1675
|
+
|
|
1676
|
+
@classmethod
|
|
1677
|
+
def cosine(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1678
|
+
"""Create Math with operation 'Cosine'."""
|
|
1679
|
+
return cls(operation="COSINE", value=value)
|
|
1680
|
+
|
|
1681
|
+
@classmethod
|
|
1682
|
+
def tangent(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1683
|
+
"""Create Math with operation 'Tangent'."""
|
|
1684
|
+
return cls(operation="TANGENT", value=value)
|
|
1685
|
+
|
|
1686
|
+
@classmethod
|
|
1687
|
+
def arcsine(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1688
|
+
"""Create Math with operation 'Arcsine'."""
|
|
1689
|
+
return cls(operation="ARCSINE", value=value)
|
|
1690
|
+
|
|
1691
|
+
@classmethod
|
|
1692
|
+
def arccosine(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1693
|
+
"""Create Math with operation 'Arccosine'."""
|
|
1694
|
+
return cls(operation="ARCCOSINE", value=value)
|
|
1695
|
+
|
|
1696
|
+
@classmethod
|
|
1697
|
+
def arctangent(cls, value: TYPE_INPUT_VALUE = 0.5) -> "Math":
|
|
1698
|
+
"""Create Math with operation 'Arctangent'."""
|
|
1699
|
+
return cls(operation="ARCTANGENT", value=value)
|
|
1700
|
+
|
|
1701
|
+
@classmethod
|
|
1702
|
+
def arctan2(
|
|
1703
|
+
cls, value: TYPE_INPUT_VALUE = 0.5, value_001: TYPE_INPUT_VALUE = 0.5
|
|
1704
|
+
) -> "Math":
|
|
1705
|
+
"""Create Math with operation 'Arctan2'."""
|
|
1706
|
+
return cls(operation="ARCTAN2", value=value, value_001=value_001)
|
|
1707
|
+
|
|
1708
|
+
@property
|
|
1709
|
+
def i_value(self) -> SocketLinker:
|
|
1710
|
+
"""Input socket: Value"""
|
|
1711
|
+
return self._input("Value")
|
|
1712
|
+
|
|
1713
|
+
@property
|
|
1714
|
+
def i_value_001(self) -> SocketLinker:
|
|
1715
|
+
"""Input socket: Value"""
|
|
1716
|
+
return self._input("Value_001")
|
|
1717
|
+
|
|
1718
|
+
@property
|
|
1719
|
+
def i_value_002(self) -> SocketLinker:
|
|
1720
|
+
"""Input socket: Value"""
|
|
1721
|
+
return self._input("Value_002")
|
|
1722
|
+
|
|
1723
|
+
@property
|
|
1724
|
+
def o_value(self) -> SocketLinker:
|
|
1725
|
+
"""Output socket: Value"""
|
|
1726
|
+
return self._output("Value")
|
|
1727
|
+
|
|
1728
|
+
@property
|
|
1729
|
+
def operation(
|
|
1730
|
+
self,
|
|
1731
|
+
) -> Literal[
|
|
1732
|
+
"ADD",
|
|
1733
|
+
"SUBTRACT",
|
|
1734
|
+
"MULTIPLY",
|
|
1735
|
+
"DIVIDE",
|
|
1736
|
+
"MULTIPLY_ADD",
|
|
1737
|
+
"POWER",
|
|
1738
|
+
"LOGARITHM",
|
|
1739
|
+
"SQRT",
|
|
1740
|
+
"INVERSE_SQRT",
|
|
1741
|
+
"ABSOLUTE",
|
|
1742
|
+
"EXPONENT",
|
|
1743
|
+
"MINIMUM",
|
|
1744
|
+
"MAXIMUM",
|
|
1745
|
+
"LESS_THAN",
|
|
1746
|
+
"GREATER_THAN",
|
|
1747
|
+
"SIGN",
|
|
1748
|
+
"COMPARE",
|
|
1749
|
+
"SMOOTH_MIN",
|
|
1750
|
+
"SMOOTH_MAX",
|
|
1751
|
+
"ROUND",
|
|
1752
|
+
"FLOOR",
|
|
1753
|
+
"CEIL",
|
|
1754
|
+
"TRUNC",
|
|
1755
|
+
"FRACT",
|
|
1756
|
+
"MODULO",
|
|
1757
|
+
"FLOORED_MODULO",
|
|
1758
|
+
"WRAP",
|
|
1759
|
+
"SNAP",
|
|
1760
|
+
"PINGPONG",
|
|
1761
|
+
"SINE",
|
|
1762
|
+
"COSINE",
|
|
1763
|
+
"TANGENT",
|
|
1764
|
+
"ARCSINE",
|
|
1765
|
+
"ARCCOSINE",
|
|
1766
|
+
"ARCTANGENT",
|
|
1767
|
+
"ARCTAN2",
|
|
1768
|
+
"SINH",
|
|
1769
|
+
"COSH",
|
|
1770
|
+
"TANH",
|
|
1771
|
+
"RADIANS",
|
|
1772
|
+
"DEGREES",
|
|
1773
|
+
]:
|
|
1774
|
+
return self.node.operation
|
|
1775
|
+
|
|
1776
|
+
@operation.setter
|
|
1777
|
+
def operation(
|
|
1778
|
+
self,
|
|
1779
|
+
value: Literal[
|
|
1780
|
+
"ADD",
|
|
1781
|
+
"SUBTRACT",
|
|
1782
|
+
"MULTIPLY",
|
|
1783
|
+
"DIVIDE",
|
|
1784
|
+
"MULTIPLY_ADD",
|
|
1785
|
+
"POWER",
|
|
1786
|
+
"LOGARITHM",
|
|
1787
|
+
"SQRT",
|
|
1788
|
+
"INVERSE_SQRT",
|
|
1789
|
+
"ABSOLUTE",
|
|
1790
|
+
"EXPONENT",
|
|
1791
|
+
"MINIMUM",
|
|
1792
|
+
"MAXIMUM",
|
|
1793
|
+
"LESS_THAN",
|
|
1794
|
+
"GREATER_THAN",
|
|
1795
|
+
"SIGN",
|
|
1796
|
+
"COMPARE",
|
|
1797
|
+
"SMOOTH_MIN",
|
|
1798
|
+
"SMOOTH_MAX",
|
|
1799
|
+
"ROUND",
|
|
1800
|
+
"FLOOR",
|
|
1801
|
+
"CEIL",
|
|
1802
|
+
"TRUNC",
|
|
1803
|
+
"FRACT",
|
|
1804
|
+
"MODULO",
|
|
1805
|
+
"FLOORED_MODULO",
|
|
1806
|
+
"WRAP",
|
|
1807
|
+
"SNAP",
|
|
1808
|
+
"PINGPONG",
|
|
1809
|
+
"SINE",
|
|
1810
|
+
"COSINE",
|
|
1811
|
+
"TANGENT",
|
|
1812
|
+
"ARCSINE",
|
|
1813
|
+
"ARCCOSINE",
|
|
1814
|
+
"ARCTANGENT",
|
|
1815
|
+
"ARCTAN2",
|
|
1816
|
+
"SINH",
|
|
1817
|
+
"COSH",
|
|
1818
|
+
"TANH",
|
|
1819
|
+
"RADIANS",
|
|
1820
|
+
"DEGREES",
|
|
1821
|
+
],
|
|
1822
|
+
):
|
|
1823
|
+
self.node.operation = value
|
|
1824
|
+
|
|
1825
|
+
@property
|
|
1826
|
+
def use_clamp(self) -> bool:
|
|
1827
|
+
return self.node.use_clamp
|
|
1828
|
+
|
|
1829
|
+
@use_clamp.setter
|
|
1830
|
+
def use_clamp(self, value: bool):
|
|
1831
|
+
self.node.use_clamp = value
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
class MatrixDeterminant(NodeBuilder):
|
|
1835
|
+
"""Compute the determinant of the given matrix"""
|
|
1836
|
+
|
|
1837
|
+
_bl_idname = "FunctionNodeMatrixDeterminant"
|
|
1838
|
+
node: bpy.types.FunctionNodeMatrixDeterminant
|
|
1839
|
+
|
|
1840
|
+
def __init__(self, matrix: TYPE_INPUT_MATRIX = None):
|
|
1841
|
+
super().__init__()
|
|
1842
|
+
key_args = {"Matrix": matrix}
|
|
1843
|
+
|
|
1844
|
+
self._establish_links(**key_args)
|
|
1845
|
+
|
|
1846
|
+
@property
|
|
1847
|
+
def i_matrix(self) -> SocketLinker:
|
|
1848
|
+
"""Input socket: Matrix"""
|
|
1849
|
+
return self._input("Matrix")
|
|
1850
|
+
|
|
1851
|
+
@property
|
|
1852
|
+
def o_determinant(self) -> SocketLinker:
|
|
1853
|
+
"""Output socket: Determinant"""
|
|
1854
|
+
return self._output("Determinant")
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
class Mix(NodeBuilder):
|
|
1858
|
+
"""Mix values by a factor"""
|
|
1859
|
+
|
|
1860
|
+
_bl_idname = "ShaderNodeMix"
|
|
1861
|
+
node: bpy.types.ShaderNodeMix
|
|
1862
|
+
|
|
1863
|
+
def __init__(
|
|
1864
|
+
self,
|
|
1865
|
+
factor_float: TYPE_INPUT_VALUE = 0.5,
|
|
1866
|
+
factor_vector: TYPE_INPUT_VECTOR = None,
|
|
1867
|
+
a_float: TYPE_INPUT_VALUE = 0.0,
|
|
1868
|
+
b_float: TYPE_INPUT_VALUE = 0.0,
|
|
1869
|
+
a_vector: TYPE_INPUT_VECTOR = None,
|
|
1870
|
+
b_vector: TYPE_INPUT_VECTOR = None,
|
|
1871
|
+
a_color: TYPE_INPUT_COLOR = None,
|
|
1872
|
+
b_color: TYPE_INPUT_COLOR = None,
|
|
1873
|
+
a_rotation: TYPE_INPUT_ROTATION = None,
|
|
1874
|
+
b_rotation: TYPE_INPUT_ROTATION = None,
|
|
1875
|
+
*,
|
|
1876
|
+
data_type: Literal["FLOAT", "VECTOR", "RGBA", "ROTATION"] = "FLOAT",
|
|
1877
|
+
factor_mode: Literal["UNIFORM", "NON_UNIFORM"] = "UNIFORM",
|
|
1878
|
+
blend_type: Literal[
|
|
1879
|
+
"MIX",
|
|
1880
|
+
"DARKEN",
|
|
1881
|
+
"MULTIPLY",
|
|
1882
|
+
"BURN",
|
|
1883
|
+
"LIGHTEN",
|
|
1884
|
+
"SCREEN",
|
|
1885
|
+
"DODGE",
|
|
1886
|
+
"ADD",
|
|
1887
|
+
"OVERLAY",
|
|
1888
|
+
"SOFT_LIGHT",
|
|
1889
|
+
"LINEAR_LIGHT",
|
|
1890
|
+
"DIFFERENCE",
|
|
1891
|
+
"EXCLUSION",
|
|
1892
|
+
"SUBTRACT",
|
|
1893
|
+
"DIVIDE",
|
|
1894
|
+
"HUE",
|
|
1895
|
+
"SATURATION",
|
|
1896
|
+
"COLOR",
|
|
1897
|
+
"VALUE",
|
|
1898
|
+
] = "MIX",
|
|
1899
|
+
clamp_factor: bool = False,
|
|
1900
|
+
clamp_result: bool = False,
|
|
1901
|
+
):
|
|
1902
|
+
super().__init__()
|
|
1903
|
+
key_args = {
|
|
1904
|
+
"Factor_Float": factor_float,
|
|
1905
|
+
"Factor_Vector": factor_vector,
|
|
1906
|
+
"A_Float": a_float,
|
|
1907
|
+
"B_Float": b_float,
|
|
1908
|
+
"A_Vector": a_vector,
|
|
1909
|
+
"B_Vector": b_vector,
|
|
1910
|
+
"A_Color": a_color,
|
|
1911
|
+
"B_Color": b_color,
|
|
1912
|
+
"A_Rotation": a_rotation,
|
|
1913
|
+
"B_Rotation": b_rotation,
|
|
1914
|
+
}
|
|
1915
|
+
self.data_type = data_type
|
|
1916
|
+
self.factor_mode = factor_mode
|
|
1917
|
+
self.blend_type = blend_type
|
|
1918
|
+
self.clamp_factor = clamp_factor
|
|
1919
|
+
self.clamp_result = clamp_result
|
|
1920
|
+
self._establish_links(**key_args)
|
|
1921
|
+
|
|
1922
|
+
@classmethod
|
|
1923
|
+
def float(
|
|
1924
|
+
cls,
|
|
1925
|
+
factor: TYPE_INPUT_VALUE = 0.5,
|
|
1926
|
+
a: TYPE_INPUT_VALUE = 0.0,
|
|
1927
|
+
b: TYPE_INPUT_VALUE = 0.0,
|
|
1928
|
+
) -> "Mix":
|
|
1929
|
+
"""Create Mix with operation 'Float'."""
|
|
1930
|
+
return cls(data_type="FLOAT", factor_float=factor, a_float=a, b_float=b)
|
|
1931
|
+
|
|
1932
|
+
@classmethod
|
|
1933
|
+
def vector(
|
|
1934
|
+
cls,
|
|
1935
|
+
factor: TYPE_INPUT_VALUE = 0.5,
|
|
1936
|
+
a: TYPE_INPUT_VECTOR = None,
|
|
1937
|
+
b: TYPE_INPUT_VECTOR = None,
|
|
1938
|
+
) -> "Mix":
|
|
1939
|
+
"""Create Mix with operation 'Vector'."""
|
|
1940
|
+
return cls(data_type="VECTOR", factor_float=factor, a_vector=a, b_vector=b)
|
|
1941
|
+
|
|
1942
|
+
@classmethod
|
|
1943
|
+
def color(
|
|
1944
|
+
cls,
|
|
1945
|
+
factor: TYPE_INPUT_VALUE = 0.5,
|
|
1946
|
+
a_color: TYPE_INPUT_COLOR = None,
|
|
1947
|
+
b_color: TYPE_INPUT_COLOR = None,
|
|
1948
|
+
) -> "Mix":
|
|
1949
|
+
"""Create Mix with operation 'Color'."""
|
|
1950
|
+
return cls(
|
|
1951
|
+
data_type="RGBA", factor_float=factor, a_color=a_color, b_color=b_color
|
|
1952
|
+
)
|
|
1953
|
+
|
|
1954
|
+
@classmethod
|
|
1955
|
+
def rotation(
|
|
1956
|
+
cls,
|
|
1957
|
+
factor: TYPE_INPUT_VALUE = 0.5,
|
|
1958
|
+
a_rotation: TYPE_INPUT_ROTATION = None,
|
|
1959
|
+
b_rotation: TYPE_INPUT_ROTATION = None,
|
|
1960
|
+
) -> "Mix":
|
|
1961
|
+
"""Create Mix with operation 'Rotation'."""
|
|
1962
|
+
return cls(
|
|
1963
|
+
data_type="ROTATION",
|
|
1964
|
+
factor_float=factor,
|
|
1965
|
+
a_rotation=a_rotation,
|
|
1966
|
+
b_rotation=b_rotation,
|
|
1967
|
+
)
|
|
1968
|
+
|
|
1969
|
+
@property
|
|
1970
|
+
def i_factor_float(self) -> SocketLinker:
|
|
1971
|
+
"""Input socket: Factor"""
|
|
1972
|
+
return self._input("Factor_Float")
|
|
1973
|
+
|
|
1974
|
+
@property
|
|
1975
|
+
def i_factor_vector(self) -> SocketLinker:
|
|
1976
|
+
"""Input socket: Factor"""
|
|
1977
|
+
return self._input("Factor_Vector")
|
|
1978
|
+
|
|
1979
|
+
@property
|
|
1980
|
+
def i_a_float(self) -> SocketLinker:
|
|
1981
|
+
"""Input socket: A"""
|
|
1982
|
+
return self._input("A_Float")
|
|
1983
|
+
|
|
1984
|
+
@property
|
|
1985
|
+
def i_b_float(self) -> SocketLinker:
|
|
1986
|
+
"""Input socket: B"""
|
|
1987
|
+
return self._input("B_Float")
|
|
1988
|
+
|
|
1989
|
+
@property
|
|
1990
|
+
def i_a_vector(self) -> SocketLinker:
|
|
1991
|
+
"""Input socket: A"""
|
|
1992
|
+
return self._input("A_Vector")
|
|
1993
|
+
|
|
1994
|
+
@property
|
|
1995
|
+
def i_b_vector(self) -> SocketLinker:
|
|
1996
|
+
"""Input socket: B"""
|
|
1997
|
+
return self._input("B_Vector")
|
|
1998
|
+
|
|
1999
|
+
@property
|
|
2000
|
+
def i_a_color(self) -> SocketLinker:
|
|
2001
|
+
"""Input socket: A"""
|
|
2002
|
+
return self._input("A_Color")
|
|
2003
|
+
|
|
2004
|
+
@property
|
|
2005
|
+
def i_b_color(self) -> SocketLinker:
|
|
2006
|
+
"""Input socket: B"""
|
|
2007
|
+
return self._input("B_Color")
|
|
2008
|
+
|
|
2009
|
+
@property
|
|
2010
|
+
def i_a_rotation(self) -> SocketLinker:
|
|
2011
|
+
"""Input socket: A"""
|
|
2012
|
+
return self._input("A_Rotation")
|
|
2013
|
+
|
|
2014
|
+
@property
|
|
2015
|
+
def i_b_rotation(self) -> SocketLinker:
|
|
2016
|
+
"""Input socket: B"""
|
|
2017
|
+
return self._input("B_Rotation")
|
|
2018
|
+
|
|
2019
|
+
@property
|
|
2020
|
+
def o_result_float(self) -> SocketLinker:
|
|
2021
|
+
"""Output socket: Result"""
|
|
2022
|
+
return self._output("Result_Float")
|
|
2023
|
+
|
|
2024
|
+
@property
|
|
2025
|
+
def o_result_vector(self) -> SocketLinker:
|
|
2026
|
+
"""Output socket: Result"""
|
|
2027
|
+
return self._output("Result_Vector")
|
|
2028
|
+
|
|
2029
|
+
@property
|
|
2030
|
+
def o_result_color(self) -> SocketLinker:
|
|
2031
|
+
"""Output socket: Result"""
|
|
2032
|
+
return self._output("Result_Color")
|
|
2033
|
+
|
|
2034
|
+
@property
|
|
2035
|
+
def o_result_rotation(self) -> SocketLinker:
|
|
2036
|
+
"""Output socket: Result"""
|
|
2037
|
+
return self._output("Result_Rotation")
|
|
2038
|
+
|
|
2039
|
+
@property
|
|
2040
|
+
def data_type(self) -> Literal["FLOAT", "VECTOR", "RGBA", "ROTATION"]:
|
|
2041
|
+
return self.node.data_type
|
|
2042
|
+
|
|
2043
|
+
@data_type.setter
|
|
2044
|
+
def data_type(self, value: Literal["FLOAT", "VECTOR", "RGBA", "ROTATION"]):
|
|
2045
|
+
self.node.data_type = value
|
|
2046
|
+
|
|
2047
|
+
@property
|
|
2048
|
+
def factor_mode(self) -> Literal["UNIFORM", "NON_UNIFORM"]:
|
|
2049
|
+
return self.node.factor_mode
|
|
2050
|
+
|
|
2051
|
+
@factor_mode.setter
|
|
2052
|
+
def factor_mode(self, value: Literal["UNIFORM", "NON_UNIFORM"]):
|
|
2053
|
+
self.node.factor_mode = value
|
|
2054
|
+
|
|
2055
|
+
@property
|
|
2056
|
+
def blend_type(
|
|
2057
|
+
self,
|
|
2058
|
+
) -> Literal[
|
|
2059
|
+
"MIX",
|
|
2060
|
+
"DARKEN",
|
|
2061
|
+
"MULTIPLY",
|
|
2062
|
+
"BURN",
|
|
2063
|
+
"LIGHTEN",
|
|
2064
|
+
"SCREEN",
|
|
2065
|
+
"DODGE",
|
|
2066
|
+
"ADD",
|
|
2067
|
+
"OVERLAY",
|
|
2068
|
+
"SOFT_LIGHT",
|
|
2069
|
+
"LINEAR_LIGHT",
|
|
2070
|
+
"DIFFERENCE",
|
|
2071
|
+
"EXCLUSION",
|
|
2072
|
+
"SUBTRACT",
|
|
2073
|
+
"DIVIDE",
|
|
2074
|
+
"HUE",
|
|
2075
|
+
"SATURATION",
|
|
2076
|
+
"COLOR",
|
|
2077
|
+
"VALUE",
|
|
2078
|
+
]:
|
|
2079
|
+
return self.node.blend_type
|
|
2080
|
+
|
|
2081
|
+
@blend_type.setter
|
|
2082
|
+
def blend_type(
|
|
2083
|
+
self,
|
|
2084
|
+
value: Literal[
|
|
2085
|
+
"MIX",
|
|
2086
|
+
"DARKEN",
|
|
2087
|
+
"MULTIPLY",
|
|
2088
|
+
"BURN",
|
|
2089
|
+
"LIGHTEN",
|
|
2090
|
+
"SCREEN",
|
|
2091
|
+
"DODGE",
|
|
2092
|
+
"ADD",
|
|
2093
|
+
"OVERLAY",
|
|
2094
|
+
"SOFT_LIGHT",
|
|
2095
|
+
"LINEAR_LIGHT",
|
|
2096
|
+
"DIFFERENCE",
|
|
2097
|
+
"EXCLUSION",
|
|
2098
|
+
"SUBTRACT",
|
|
2099
|
+
"DIVIDE",
|
|
2100
|
+
"HUE",
|
|
2101
|
+
"SATURATION",
|
|
2102
|
+
"COLOR",
|
|
2103
|
+
"VALUE",
|
|
2104
|
+
],
|
|
2105
|
+
):
|
|
2106
|
+
self.node.blend_type = value
|
|
2107
|
+
|
|
2108
|
+
@property
|
|
2109
|
+
def clamp_factor(self) -> bool:
|
|
2110
|
+
return self.node.clamp_factor
|
|
2111
|
+
|
|
2112
|
+
@clamp_factor.setter
|
|
2113
|
+
def clamp_factor(self, value: bool):
|
|
2114
|
+
self.node.clamp_factor = value
|
|
2115
|
+
|
|
2116
|
+
@property
|
|
2117
|
+
def clamp_result(self) -> bool:
|
|
2118
|
+
return self.node.clamp_result
|
|
2119
|
+
|
|
2120
|
+
@clamp_result.setter
|
|
2121
|
+
def clamp_result(self, value: bool):
|
|
2122
|
+
self.node.clamp_result = value
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
class MultiplyMatrices(NodeBuilder):
|
|
2126
|
+
"""Perform a matrix multiplication on two input matrices"""
|
|
2127
|
+
|
|
2128
|
+
_bl_idname = "FunctionNodeMatrixMultiply"
|
|
2129
|
+
node: bpy.types.FunctionNodeMatrixMultiply
|
|
2130
|
+
|
|
2131
|
+
def __init__(
|
|
2132
|
+
self,
|
|
2133
|
+
matrix: TYPE_INPUT_MATRIX = None,
|
|
2134
|
+
matrix_001: TYPE_INPUT_MATRIX = None,
|
|
2135
|
+
):
|
|
2136
|
+
super().__init__()
|
|
2137
|
+
key_args = {"Matrix": matrix, "Matrix_001": matrix_001}
|
|
2138
|
+
|
|
2139
|
+
self._establish_links(**key_args)
|
|
2140
|
+
|
|
2141
|
+
@property
|
|
2142
|
+
def i_matrix(self) -> SocketLinker:
|
|
2143
|
+
"""Input socket: Matrix"""
|
|
2144
|
+
return self._input("Matrix")
|
|
2145
|
+
|
|
2146
|
+
@property
|
|
2147
|
+
def i_matrix_001(self) -> SocketLinker:
|
|
2148
|
+
"""Input socket: Matrix"""
|
|
2149
|
+
return self._input("Matrix_001")
|
|
2150
|
+
|
|
2151
|
+
@property
|
|
2152
|
+
def o_matrix(self) -> SocketLinker:
|
|
2153
|
+
"""Output socket: Matrix"""
|
|
2154
|
+
return self._output("Matrix")
|
|
2155
|
+
|
|
2156
|
+
|
|
2157
|
+
class PackUVIslands(NodeBuilder):
|
|
2158
|
+
"""Scale islands of a UV map and move them so they fill the UV space as much as possible"""
|
|
2159
|
+
|
|
2160
|
+
_bl_idname = "GeometryNodeUVPackIslands"
|
|
2161
|
+
node: bpy.types.GeometryNodeUVPackIslands
|
|
2162
|
+
|
|
2163
|
+
def __init__(
|
|
2164
|
+
self,
|
|
2165
|
+
uv: TYPE_INPUT_VECTOR = None,
|
|
2166
|
+
selection: TYPE_INPUT_BOOLEAN = True,
|
|
2167
|
+
margin: TYPE_INPUT_VALUE = 0.001,
|
|
2168
|
+
rotate: TYPE_INPUT_BOOLEAN = True,
|
|
2169
|
+
method: TYPE_INPUT_MENU = "Bounding Box",
|
|
2170
|
+
):
|
|
2171
|
+
super().__init__()
|
|
2172
|
+
key_args = {
|
|
2173
|
+
"UV": uv,
|
|
2174
|
+
"Selection": selection,
|
|
2175
|
+
"Margin": margin,
|
|
2176
|
+
"Rotate": rotate,
|
|
2177
|
+
"Method": method,
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
self._establish_links(**key_args)
|
|
2181
|
+
|
|
2182
|
+
@property
|
|
2183
|
+
def i_uv(self) -> SocketLinker:
|
|
2184
|
+
"""Input socket: UV"""
|
|
2185
|
+
return self._input("UV")
|
|
2186
|
+
|
|
2187
|
+
@property
|
|
2188
|
+
def i_selection(self) -> SocketLinker:
|
|
2189
|
+
"""Input socket: Selection"""
|
|
2190
|
+
return self._input("Selection")
|
|
2191
|
+
|
|
2192
|
+
@property
|
|
2193
|
+
def i_margin(self) -> SocketLinker:
|
|
2194
|
+
"""Input socket: Margin"""
|
|
2195
|
+
return self._input("Margin")
|
|
2196
|
+
|
|
2197
|
+
@property
|
|
2198
|
+
def i_rotate(self) -> SocketLinker:
|
|
2199
|
+
"""Input socket: Rotate"""
|
|
2200
|
+
return self._input("Rotate")
|
|
2201
|
+
|
|
2202
|
+
@property
|
|
2203
|
+
def i_method(self) -> SocketLinker:
|
|
2204
|
+
"""Input socket: Method"""
|
|
2205
|
+
return self._input("Method")
|
|
2206
|
+
|
|
2207
|
+
@property
|
|
2208
|
+
def o_uv(self) -> SocketLinker:
|
|
2209
|
+
"""Output socket: UV"""
|
|
2210
|
+
return self._output("UV")
|
|
2211
|
+
|
|
2212
|
+
|
|
2213
|
+
class ProjectPoint(NodeBuilder):
|
|
2214
|
+
"""Project a point using a matrix, using location, rotation, scale, and perspective divide"""
|
|
2215
|
+
|
|
2216
|
+
_bl_idname = "FunctionNodeProjectPoint"
|
|
2217
|
+
node: bpy.types.FunctionNodeProjectPoint
|
|
2218
|
+
|
|
2219
|
+
def __init__(
|
|
2220
|
+
self,
|
|
2221
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
2222
|
+
transform: TYPE_INPUT_MATRIX = None,
|
|
2223
|
+
):
|
|
2224
|
+
super().__init__()
|
|
2225
|
+
key_args = {"Vector": vector, "Transform": transform}
|
|
2226
|
+
|
|
2227
|
+
self._establish_links(**key_args)
|
|
2228
|
+
|
|
2229
|
+
@property
|
|
2230
|
+
def i_vector(self) -> SocketLinker:
|
|
2231
|
+
"""Input socket: Vector"""
|
|
2232
|
+
return self._input("Vector")
|
|
2233
|
+
|
|
2234
|
+
@property
|
|
2235
|
+
def i_transform(self) -> SocketLinker:
|
|
2236
|
+
"""Input socket: Transform"""
|
|
2237
|
+
return self._input("Transform")
|
|
2238
|
+
|
|
2239
|
+
@property
|
|
2240
|
+
def o_vector(self) -> SocketLinker:
|
|
2241
|
+
"""Output socket: Vector"""
|
|
2242
|
+
return self._output("Vector")
|
|
2243
|
+
|
|
2244
|
+
|
|
2245
|
+
class QuaternionToRotation(NodeBuilder):
|
|
2246
|
+
"""Build a rotation from quaternion components"""
|
|
2247
|
+
|
|
2248
|
+
_bl_idname = "FunctionNodeQuaternionToRotation"
|
|
2249
|
+
node: bpy.types.FunctionNodeQuaternionToRotation
|
|
2250
|
+
|
|
2251
|
+
def __init__(
|
|
2252
|
+
self,
|
|
2253
|
+
w: TYPE_INPUT_VALUE = 1.0,
|
|
2254
|
+
x: TYPE_INPUT_VALUE = 0.0,
|
|
2255
|
+
y: TYPE_INPUT_VALUE = 0.0,
|
|
2256
|
+
z: TYPE_INPUT_VALUE = 0.0,
|
|
2257
|
+
):
|
|
2258
|
+
super().__init__()
|
|
2259
|
+
key_args = {"W": w, "X": x, "Y": y, "Z": z}
|
|
2260
|
+
|
|
2261
|
+
self._establish_links(**key_args)
|
|
2262
|
+
|
|
2263
|
+
@property
|
|
2264
|
+
def i_w(self) -> SocketLinker:
|
|
2265
|
+
"""Input socket: W"""
|
|
2266
|
+
return self._input("W")
|
|
2267
|
+
|
|
2268
|
+
@property
|
|
2269
|
+
def i_x(self) -> SocketLinker:
|
|
2270
|
+
"""Input socket: X"""
|
|
2271
|
+
return self._input("X")
|
|
2272
|
+
|
|
2273
|
+
@property
|
|
2274
|
+
def i_y(self) -> SocketLinker:
|
|
2275
|
+
"""Input socket: Y"""
|
|
2276
|
+
return self._input("Y")
|
|
2277
|
+
|
|
2278
|
+
@property
|
|
2279
|
+
def i_z(self) -> SocketLinker:
|
|
2280
|
+
"""Input socket: Z"""
|
|
2281
|
+
return self._input("Z")
|
|
2282
|
+
|
|
2283
|
+
@property
|
|
2284
|
+
def o_rotation(self) -> SocketLinker:
|
|
2285
|
+
"""Output socket: Rotation"""
|
|
2286
|
+
return self._output("Rotation")
|
|
2287
|
+
|
|
2288
|
+
|
|
2289
|
+
class RandomValue(NodeBuilder):
|
|
2290
|
+
"""Output a randomized value"""
|
|
2291
|
+
|
|
2292
|
+
_bl_idname = "FunctionNodeRandomValue"
|
|
2293
|
+
node: bpy.types.FunctionNodeRandomValue
|
|
2294
|
+
|
|
2295
|
+
def __init__(
|
|
2296
|
+
self,
|
|
2297
|
+
min: TYPE_INPUT_VECTOR = None,
|
|
2298
|
+
max: TYPE_INPUT_VECTOR = None,
|
|
2299
|
+
min_001: TYPE_INPUT_VALUE = 0.0,
|
|
2300
|
+
max_001: TYPE_INPUT_VALUE = 1.0,
|
|
2301
|
+
min_002: TYPE_INPUT_INT = 0,
|
|
2302
|
+
max_002: TYPE_INPUT_INT = 100,
|
|
2303
|
+
probability: TYPE_INPUT_VALUE = 0.5,
|
|
2304
|
+
id: TYPE_INPUT_INT = 0,
|
|
2305
|
+
seed: TYPE_INPUT_INT = 0,
|
|
2306
|
+
*,
|
|
2307
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"] = "FLOAT",
|
|
2308
|
+
):
|
|
2309
|
+
super().__init__()
|
|
2310
|
+
key_args = {
|
|
2311
|
+
"Min": min,
|
|
2312
|
+
"Max": max,
|
|
2313
|
+
"Min_001": min_001,
|
|
2314
|
+
"Max_001": max_001,
|
|
2315
|
+
"Min_002": min_002,
|
|
2316
|
+
"Max_002": max_002,
|
|
2317
|
+
"Probability": probability,
|
|
2318
|
+
"ID": id,
|
|
2319
|
+
"Seed": seed,
|
|
2320
|
+
}
|
|
2321
|
+
self.data_type = data_type
|
|
2322
|
+
self._establish_links(**key_args)
|
|
2323
|
+
|
|
2324
|
+
@classmethod
|
|
2325
|
+
def float(
|
|
2326
|
+
cls,
|
|
2327
|
+
min: TYPE_INPUT_VALUE = 0.0,
|
|
2328
|
+
max: TYPE_INPUT_VALUE = 1.0,
|
|
2329
|
+
id: TYPE_INPUT_INT = 0,
|
|
2330
|
+
seed: TYPE_INPUT_INT = 0,
|
|
2331
|
+
) -> "RandomValue":
|
|
2332
|
+
"""Create Random Value with operation 'Float'."""
|
|
2333
|
+
return cls(data_type="FLOAT", min_001=min, max_001=max, id=id, seed=seed)
|
|
2334
|
+
|
|
2335
|
+
@classmethod
|
|
2336
|
+
def integer(
|
|
2337
|
+
cls,
|
|
2338
|
+
min: TYPE_INPUT_INT = 0,
|
|
2339
|
+
max: TYPE_INPUT_INT = 100,
|
|
2340
|
+
id: TYPE_INPUT_INT = 0,
|
|
2341
|
+
seed: TYPE_INPUT_INT = 0,
|
|
2342
|
+
) -> "RandomValue":
|
|
2343
|
+
"""Create Random Value with operation 'Integer'."""
|
|
2344
|
+
return cls(data_type="INT", min_002=min, max_002=max, id=id, seed=seed)
|
|
2345
|
+
|
|
2346
|
+
@classmethod
|
|
2347
|
+
def boolean(
|
|
2348
|
+
cls,
|
|
2349
|
+
probability: TYPE_INPUT_VALUE = 0.5,
|
|
2350
|
+
id: TYPE_INPUT_INT = 0,
|
|
2351
|
+
seed: TYPE_INPUT_INT = 0,
|
|
2352
|
+
) -> "RandomValue":
|
|
2353
|
+
"""Create Random Value with operation 'Boolean'."""
|
|
2354
|
+
return cls(data_type="BOOLEAN", probability=probability, id=id, seed=seed)
|
|
2355
|
+
|
|
2356
|
+
@classmethod
|
|
2357
|
+
def vector(
|
|
2358
|
+
cls,
|
|
2359
|
+
min: TYPE_INPUT_VECTOR = None,
|
|
2360
|
+
max: TYPE_INPUT_VECTOR = None,
|
|
2361
|
+
id: TYPE_INPUT_INT = 0,
|
|
2362
|
+
seed: TYPE_INPUT_INT = 0,
|
|
2363
|
+
) -> "RandomValue":
|
|
2364
|
+
"""Create Random Value with operation 'Vector'."""
|
|
2365
|
+
return cls(data_type="FLOAT_VECTOR", min=min, max=max, id=id, seed=seed)
|
|
2366
|
+
|
|
2367
|
+
@property
|
|
2368
|
+
def i_min(self) -> SocketLinker:
|
|
2369
|
+
"""Input socket: Min"""
|
|
2370
|
+
return self._input("Min")
|
|
2371
|
+
|
|
2372
|
+
@property
|
|
2373
|
+
def i_max(self) -> SocketLinker:
|
|
2374
|
+
"""Input socket: Max"""
|
|
2375
|
+
return self._input("Max")
|
|
2376
|
+
|
|
2377
|
+
@property
|
|
2378
|
+
def i_min_001(self) -> SocketLinker:
|
|
2379
|
+
"""Input socket: Min"""
|
|
2380
|
+
return self._input("Min_001")
|
|
2381
|
+
|
|
2382
|
+
@property
|
|
2383
|
+
def i_max_001(self) -> SocketLinker:
|
|
2384
|
+
"""Input socket: Max"""
|
|
2385
|
+
return self._input("Max_001")
|
|
2386
|
+
|
|
2387
|
+
@property
|
|
2388
|
+
def i_min_002(self) -> SocketLinker:
|
|
2389
|
+
"""Input socket: Min"""
|
|
2390
|
+
return self._input("Min_002")
|
|
2391
|
+
|
|
2392
|
+
@property
|
|
2393
|
+
def i_max_002(self) -> SocketLinker:
|
|
2394
|
+
"""Input socket: Max"""
|
|
2395
|
+
return self._input("Max_002")
|
|
2396
|
+
|
|
2397
|
+
@property
|
|
2398
|
+
def i_probability(self) -> SocketLinker:
|
|
2399
|
+
"""Input socket: Probability"""
|
|
2400
|
+
return self._input("Probability")
|
|
2401
|
+
|
|
2402
|
+
@property
|
|
2403
|
+
def i_id(self) -> SocketLinker:
|
|
2404
|
+
"""Input socket: ID"""
|
|
2405
|
+
return self._input("ID")
|
|
2406
|
+
|
|
2407
|
+
@property
|
|
2408
|
+
def i_seed(self) -> SocketLinker:
|
|
2409
|
+
"""Input socket: Seed"""
|
|
2410
|
+
return self._input("Seed")
|
|
2411
|
+
|
|
2412
|
+
@property
|
|
2413
|
+
def o_value(self) -> SocketLinker:
|
|
2414
|
+
"""Output socket: Value"""
|
|
2415
|
+
return self._output("Value")
|
|
2416
|
+
|
|
2417
|
+
@property
|
|
2418
|
+
def o_value_001(self) -> SocketLinker:
|
|
2419
|
+
"""Output socket: Value"""
|
|
2420
|
+
return self._output("Value_001")
|
|
2421
|
+
|
|
2422
|
+
@property
|
|
2423
|
+
def o_value_002(self) -> SocketLinker:
|
|
2424
|
+
"""Output socket: Value"""
|
|
2425
|
+
return self._output("Value_002")
|
|
2426
|
+
|
|
2427
|
+
@property
|
|
2428
|
+
def o_value_003(self) -> SocketLinker:
|
|
2429
|
+
"""Output socket: Value"""
|
|
2430
|
+
return self._output("Value_003")
|
|
2431
|
+
|
|
2432
|
+
@property
|
|
2433
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"]:
|
|
2434
|
+
return self.node.data_type
|
|
2435
|
+
|
|
2436
|
+
@data_type.setter
|
|
2437
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"]):
|
|
2438
|
+
self.node.data_type = value
|
|
2439
|
+
|
|
2440
|
+
|
|
2441
|
+
class ReplaceString(NodeBuilder):
|
|
2442
|
+
"""Replace a given string segment with another"""
|
|
2443
|
+
|
|
2444
|
+
_bl_idname = "FunctionNodeReplaceString"
|
|
2445
|
+
node: bpy.types.FunctionNodeReplaceString
|
|
2446
|
+
|
|
2447
|
+
def __init__(
|
|
2448
|
+
self,
|
|
2449
|
+
string: TYPE_INPUT_STRING = "",
|
|
2450
|
+
find: TYPE_INPUT_STRING = "",
|
|
2451
|
+
replace: TYPE_INPUT_STRING = "",
|
|
2452
|
+
):
|
|
2453
|
+
super().__init__()
|
|
2454
|
+
key_args = {"String": string, "Find": find, "Replace": replace}
|
|
2455
|
+
|
|
2456
|
+
self._establish_links(**key_args)
|
|
2457
|
+
|
|
2458
|
+
@property
|
|
2459
|
+
def i_string(self) -> SocketLinker:
|
|
2460
|
+
"""Input socket: String"""
|
|
2461
|
+
return self._input("String")
|
|
2462
|
+
|
|
2463
|
+
@property
|
|
2464
|
+
def i_find(self) -> SocketLinker:
|
|
2465
|
+
"""Input socket: Find"""
|
|
2466
|
+
return self._input("Find")
|
|
2467
|
+
|
|
2468
|
+
@property
|
|
2469
|
+
def i_replace(self) -> SocketLinker:
|
|
2470
|
+
"""Input socket: Replace"""
|
|
2471
|
+
return self._input("Replace")
|
|
2472
|
+
|
|
2473
|
+
@property
|
|
2474
|
+
def o_string(self) -> SocketLinker:
|
|
2475
|
+
"""Output socket: String"""
|
|
2476
|
+
return self._output("String")
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
class RotateEuler(NodeBuilder):
|
|
2480
|
+
"""Apply a secondary Euler rotation to a given Euler rotation"""
|
|
2481
|
+
|
|
2482
|
+
_bl_idname = "FunctionNodeRotateEuler"
|
|
2483
|
+
node: bpy.types.FunctionNodeRotateEuler
|
|
2484
|
+
|
|
2485
|
+
def __init__(
|
|
2486
|
+
self,
|
|
2487
|
+
rotation: TYPE_INPUT_VECTOR = None,
|
|
2488
|
+
rotate_by: TYPE_INPUT_VECTOR = None,
|
|
2489
|
+
axis: TYPE_INPUT_VECTOR = None,
|
|
2490
|
+
angle: TYPE_INPUT_VALUE = 0.0,
|
|
2491
|
+
*,
|
|
2492
|
+
rotation_type: Literal["AXIS_ANGLE", "EULER"] = "EULER",
|
|
2493
|
+
space: Literal["OBJECT", "LOCAL"] = "OBJECT",
|
|
2494
|
+
):
|
|
2495
|
+
super().__init__()
|
|
2496
|
+
key_args = {
|
|
2497
|
+
"Rotation": rotation,
|
|
2498
|
+
"Rotate By": rotate_by,
|
|
2499
|
+
"Axis": axis,
|
|
2500
|
+
"Angle": angle,
|
|
2501
|
+
}
|
|
2502
|
+
self.rotation_type = rotation_type
|
|
2503
|
+
self.space = space
|
|
2504
|
+
self._establish_links(**key_args)
|
|
2505
|
+
|
|
2506
|
+
@property
|
|
2507
|
+
def i_rotation(self) -> SocketLinker:
|
|
2508
|
+
"""Input socket: Rotation"""
|
|
2509
|
+
return self._input("Rotation")
|
|
2510
|
+
|
|
2511
|
+
@property
|
|
2512
|
+
def i_rotate_by(self) -> SocketLinker:
|
|
2513
|
+
"""Input socket: Rotate By"""
|
|
2514
|
+
return self._input("Rotate By")
|
|
2515
|
+
|
|
2516
|
+
@property
|
|
2517
|
+
def i_axis(self) -> SocketLinker:
|
|
2518
|
+
"""Input socket: Axis"""
|
|
2519
|
+
return self._input("Axis")
|
|
2520
|
+
|
|
2521
|
+
@property
|
|
2522
|
+
def i_angle(self) -> SocketLinker:
|
|
2523
|
+
"""Input socket: Angle"""
|
|
2524
|
+
return self._input("Angle")
|
|
2525
|
+
|
|
2526
|
+
@property
|
|
2527
|
+
def o_rotation(self) -> SocketLinker:
|
|
2528
|
+
"""Output socket: Rotation"""
|
|
2529
|
+
return self._output("Rotation")
|
|
2530
|
+
|
|
2531
|
+
@property
|
|
2532
|
+
def rotation_type(self) -> Literal["AXIS_ANGLE", "EULER"]:
|
|
2533
|
+
return self.node.rotation_type
|
|
2534
|
+
|
|
2535
|
+
@rotation_type.setter
|
|
2536
|
+
def rotation_type(self, value: Literal["AXIS_ANGLE", "EULER"]):
|
|
2537
|
+
self.node.rotation_type = value
|
|
2538
|
+
|
|
2539
|
+
@property
|
|
2540
|
+
def space(self) -> Literal["OBJECT", "LOCAL"]:
|
|
2541
|
+
return self.node.space
|
|
2542
|
+
|
|
2543
|
+
@space.setter
|
|
2544
|
+
def space(self, value: Literal["OBJECT", "LOCAL"]):
|
|
2545
|
+
self.node.space = value
|
|
2546
|
+
|
|
2547
|
+
|
|
2548
|
+
class RotateRotation(NodeBuilder):
|
|
2549
|
+
"""Apply a secondary rotation to a given rotation value"""
|
|
2550
|
+
|
|
2551
|
+
_bl_idname = "FunctionNodeRotateRotation"
|
|
2552
|
+
node: bpy.types.FunctionNodeRotateRotation
|
|
2553
|
+
|
|
2554
|
+
def __init__(
|
|
2555
|
+
self,
|
|
2556
|
+
rotation: TYPE_INPUT_ROTATION = None,
|
|
2557
|
+
rotate_by: TYPE_INPUT_ROTATION = None,
|
|
2558
|
+
*,
|
|
2559
|
+
rotation_space: Literal["GLOBAL", "LOCAL"] = "GLOBAL",
|
|
2560
|
+
):
|
|
2561
|
+
super().__init__()
|
|
2562
|
+
key_args = {"Rotation": rotation, "Rotate By": rotate_by}
|
|
2563
|
+
self.rotation_space = rotation_space
|
|
2564
|
+
self._establish_links(**key_args)
|
|
2565
|
+
|
|
2566
|
+
@property
|
|
2567
|
+
def i_rotation(self) -> SocketLinker:
|
|
2568
|
+
"""Input socket: Rotation"""
|
|
2569
|
+
return self._input("Rotation")
|
|
2570
|
+
|
|
2571
|
+
@property
|
|
2572
|
+
def i_rotate_by(self) -> SocketLinker:
|
|
2573
|
+
"""Input socket: Rotate By"""
|
|
2574
|
+
return self._input("Rotate By")
|
|
2575
|
+
|
|
2576
|
+
@property
|
|
2577
|
+
def o_rotation(self) -> SocketLinker:
|
|
2578
|
+
"""Output socket: Rotation"""
|
|
2579
|
+
return self._output("Rotation")
|
|
2580
|
+
|
|
2581
|
+
@property
|
|
2582
|
+
def rotation_space(self) -> Literal["GLOBAL", "LOCAL"]:
|
|
2583
|
+
return self.node.rotation_space
|
|
2584
|
+
|
|
2585
|
+
@rotation_space.setter
|
|
2586
|
+
def rotation_space(self, value: Literal["GLOBAL", "LOCAL"]):
|
|
2587
|
+
self.node.rotation_space = value
|
|
2588
|
+
|
|
2589
|
+
|
|
2590
|
+
class RotateVector(NodeBuilder):
|
|
2591
|
+
"""Apply a rotation to a given vector"""
|
|
2592
|
+
|
|
2593
|
+
_bl_idname = "FunctionNodeRotateVector"
|
|
2594
|
+
node: bpy.types.FunctionNodeRotateVector
|
|
2595
|
+
|
|
2596
|
+
def __init__(
|
|
2597
|
+
self,
|
|
2598
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
2599
|
+
rotation: TYPE_INPUT_ROTATION = None,
|
|
2600
|
+
):
|
|
2601
|
+
super().__init__()
|
|
2602
|
+
key_args = {"Vector": vector, "Rotation": rotation}
|
|
2603
|
+
|
|
2604
|
+
self._establish_links(**key_args)
|
|
2605
|
+
|
|
2606
|
+
@property
|
|
2607
|
+
def i_vector(self) -> SocketLinker:
|
|
2608
|
+
"""Input socket: Vector"""
|
|
2609
|
+
return self._input("Vector")
|
|
2610
|
+
|
|
2611
|
+
@property
|
|
2612
|
+
def i_rotation(self) -> SocketLinker:
|
|
2613
|
+
"""Input socket: Rotation"""
|
|
2614
|
+
return self._input("Rotation")
|
|
2615
|
+
|
|
2616
|
+
@property
|
|
2617
|
+
def o_vector(self) -> SocketLinker:
|
|
2618
|
+
"""Output socket: Vector"""
|
|
2619
|
+
return self._output("Vector")
|
|
2620
|
+
|
|
2621
|
+
|
|
2622
|
+
class RotationToAxisAngle(NodeBuilder):
|
|
2623
|
+
"""Convert a rotation to axis angle components"""
|
|
2624
|
+
|
|
2625
|
+
_bl_idname = "FunctionNodeRotationToAxisAngle"
|
|
2626
|
+
node: bpy.types.FunctionNodeRotationToAxisAngle
|
|
2627
|
+
|
|
2628
|
+
def __init__(self, rotation: TYPE_INPUT_ROTATION = None):
|
|
2629
|
+
super().__init__()
|
|
2630
|
+
key_args = {"Rotation": rotation}
|
|
2631
|
+
|
|
2632
|
+
self._establish_links(**key_args)
|
|
2633
|
+
|
|
2634
|
+
@property
|
|
2635
|
+
def i_rotation(self) -> SocketLinker:
|
|
2636
|
+
"""Input socket: Rotation"""
|
|
2637
|
+
return self._input("Rotation")
|
|
2638
|
+
|
|
2639
|
+
@property
|
|
2640
|
+
def o_axis(self) -> SocketLinker:
|
|
2641
|
+
"""Output socket: Axis"""
|
|
2642
|
+
return self._output("Axis")
|
|
2643
|
+
|
|
2644
|
+
@property
|
|
2645
|
+
def o_angle(self) -> SocketLinker:
|
|
2646
|
+
"""Output socket: Angle"""
|
|
2647
|
+
return self._output("Angle")
|
|
2648
|
+
|
|
2649
|
+
|
|
2650
|
+
class RotationToEuler(NodeBuilder):
|
|
2651
|
+
"""Convert a standard rotation value to an Euler rotation"""
|
|
2652
|
+
|
|
2653
|
+
_bl_idname = "FunctionNodeRotationToEuler"
|
|
2654
|
+
node: bpy.types.FunctionNodeRotationToEuler
|
|
2655
|
+
|
|
2656
|
+
def __init__(self, rotation: TYPE_INPUT_ROTATION = None):
|
|
2657
|
+
super().__init__()
|
|
2658
|
+
key_args = {"Rotation": rotation}
|
|
2659
|
+
|
|
2660
|
+
self._establish_links(**key_args)
|
|
2661
|
+
|
|
2662
|
+
@property
|
|
2663
|
+
def i_rotation(self) -> SocketLinker:
|
|
2664
|
+
"""Input socket: Rotation"""
|
|
2665
|
+
return self._input("Rotation")
|
|
2666
|
+
|
|
2667
|
+
@property
|
|
2668
|
+
def o_euler(self) -> SocketLinker:
|
|
2669
|
+
"""Output socket: Euler"""
|
|
2670
|
+
return self._output("Euler")
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
class RotationToQuaternion(NodeBuilder):
|
|
2674
|
+
"""Retrieve the quaternion components representing a rotation"""
|
|
2675
|
+
|
|
2676
|
+
_bl_idname = "FunctionNodeRotationToQuaternion"
|
|
2677
|
+
node: bpy.types.FunctionNodeRotationToQuaternion
|
|
2678
|
+
|
|
2679
|
+
def __init__(self, rotation: TYPE_INPUT_ROTATION = None):
|
|
2680
|
+
super().__init__()
|
|
2681
|
+
key_args = {"Rotation": rotation}
|
|
2682
|
+
|
|
2683
|
+
self._establish_links(**key_args)
|
|
2684
|
+
|
|
2685
|
+
@property
|
|
2686
|
+
def i_rotation(self) -> SocketLinker:
|
|
2687
|
+
"""Input socket: Rotation"""
|
|
2688
|
+
return self._input("Rotation")
|
|
2689
|
+
|
|
2690
|
+
@property
|
|
2691
|
+
def o_w(self) -> SocketLinker:
|
|
2692
|
+
"""Output socket: W"""
|
|
2693
|
+
return self._output("W")
|
|
2694
|
+
|
|
2695
|
+
@property
|
|
2696
|
+
def o_x(self) -> SocketLinker:
|
|
2697
|
+
"""Output socket: X"""
|
|
2698
|
+
return self._output("X")
|
|
2699
|
+
|
|
2700
|
+
@property
|
|
2701
|
+
def o_y(self) -> SocketLinker:
|
|
2702
|
+
"""Output socket: Y"""
|
|
2703
|
+
return self._output("Y")
|
|
2704
|
+
|
|
2705
|
+
@property
|
|
2706
|
+
def o_z(self) -> SocketLinker:
|
|
2707
|
+
"""Output socket: Z"""
|
|
2708
|
+
return self._output("Z")
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
class SeparateBundle(NodeBuilder):
|
|
2712
|
+
"""Split a bundle into multiple sockets."""
|
|
2713
|
+
|
|
2714
|
+
_bl_idname = "NodeSeparateBundle"
|
|
2715
|
+
node: bpy.types.Node
|
|
2716
|
+
|
|
2717
|
+
def __init__(
|
|
2718
|
+
self,
|
|
2719
|
+
bundle: TYPE_INPUT_BUNDLE = None,
|
|
2720
|
+
*,
|
|
2721
|
+
define_signature: bool = False,
|
|
2722
|
+
):
|
|
2723
|
+
super().__init__()
|
|
2724
|
+
key_args = {"Bundle": bundle}
|
|
2725
|
+
self.define_signature = define_signature
|
|
2726
|
+
self._establish_links(**key_args)
|
|
2727
|
+
|
|
2728
|
+
@property
|
|
2729
|
+
def i_bundle(self) -> SocketLinker:
|
|
2730
|
+
"""Input socket: Bundle"""
|
|
2731
|
+
return self._input("Bundle")
|
|
2732
|
+
|
|
2733
|
+
@property
|
|
2734
|
+
def define_signature(self) -> bool:
|
|
2735
|
+
return self.node.define_signature
|
|
2736
|
+
|
|
2737
|
+
@define_signature.setter
|
|
2738
|
+
def define_signature(self, value: bool):
|
|
2739
|
+
self.node.define_signature = value
|
|
2740
|
+
|
|
2741
|
+
|
|
2742
|
+
class SeparateColor(NodeBuilder):
|
|
2743
|
+
"""Split a color into separate channels, based on a particular color model"""
|
|
2744
|
+
|
|
2745
|
+
_bl_idname = "FunctionNodeSeparateColor"
|
|
2746
|
+
node: bpy.types.FunctionNodeSeparateColor
|
|
2747
|
+
|
|
2748
|
+
def __init__(
|
|
2749
|
+
self,
|
|
2750
|
+
color: TYPE_INPUT_COLOR = None,
|
|
2751
|
+
*,
|
|
2752
|
+
mode: Literal["RGB", "HSV", "HSL"] = "RGB",
|
|
2753
|
+
):
|
|
2754
|
+
super().__init__()
|
|
2755
|
+
key_args = {"Color": color}
|
|
2756
|
+
self.mode = mode
|
|
2757
|
+
self._establish_links(**key_args)
|
|
2758
|
+
|
|
2759
|
+
@property
|
|
2760
|
+
def i_color(self) -> SocketLinker:
|
|
2761
|
+
"""Input socket: Color"""
|
|
2762
|
+
return self._input("Color")
|
|
2763
|
+
|
|
2764
|
+
@property
|
|
2765
|
+
def o_red(self) -> SocketLinker:
|
|
2766
|
+
"""Output socket: Red"""
|
|
2767
|
+
return self._output("Red")
|
|
2768
|
+
|
|
2769
|
+
@property
|
|
2770
|
+
def o_green(self) -> SocketLinker:
|
|
2771
|
+
"""Output socket: Green"""
|
|
2772
|
+
return self._output("Green")
|
|
2773
|
+
|
|
2774
|
+
@property
|
|
2775
|
+
def o_blue(self) -> SocketLinker:
|
|
2776
|
+
"""Output socket: Blue"""
|
|
2777
|
+
return self._output("Blue")
|
|
2778
|
+
|
|
2779
|
+
@property
|
|
2780
|
+
def o_alpha(self) -> SocketLinker:
|
|
2781
|
+
"""Output socket: Alpha"""
|
|
2782
|
+
return self._output("Alpha")
|
|
2783
|
+
|
|
2784
|
+
@property
|
|
2785
|
+
def mode(self) -> Literal["RGB", "HSV", "HSL"]:
|
|
2786
|
+
return self.node.mode
|
|
2787
|
+
|
|
2788
|
+
@mode.setter
|
|
2789
|
+
def mode(self, value: Literal["RGB", "HSV", "HSL"]):
|
|
2790
|
+
self.node.mode = value
|
|
2791
|
+
|
|
2792
|
+
|
|
2793
|
+
class SeparateMatrix(NodeBuilder):
|
|
2794
|
+
"""Split a 4x4 matrix into its individual values"""
|
|
2795
|
+
|
|
2796
|
+
_bl_idname = "FunctionNodeSeparateMatrix"
|
|
2797
|
+
node: bpy.types.FunctionNodeSeparateMatrix
|
|
2798
|
+
|
|
2799
|
+
def __init__(self, matrix: TYPE_INPUT_MATRIX = None):
|
|
2800
|
+
super().__init__()
|
|
2801
|
+
key_args = {"Matrix": matrix}
|
|
2802
|
+
|
|
2803
|
+
self._establish_links(**key_args)
|
|
2804
|
+
|
|
2805
|
+
@property
|
|
2806
|
+
def i_matrix(self) -> SocketLinker:
|
|
2807
|
+
"""Input socket: Matrix"""
|
|
2808
|
+
return self._input("Matrix")
|
|
2809
|
+
|
|
2810
|
+
@property
|
|
2811
|
+
def o_column_1_row_1(self) -> SocketLinker:
|
|
2812
|
+
"""Output socket: Column 1 Row 1"""
|
|
2813
|
+
return self._output("Column 1 Row 1")
|
|
2814
|
+
|
|
2815
|
+
@property
|
|
2816
|
+
def o_column_1_row_2(self) -> SocketLinker:
|
|
2817
|
+
"""Output socket: Column 1 Row 2"""
|
|
2818
|
+
return self._output("Column 1 Row 2")
|
|
2819
|
+
|
|
2820
|
+
@property
|
|
2821
|
+
def o_column_1_row_3(self) -> SocketLinker:
|
|
2822
|
+
"""Output socket: Column 1 Row 3"""
|
|
2823
|
+
return self._output("Column 1 Row 3")
|
|
2824
|
+
|
|
2825
|
+
@property
|
|
2826
|
+
def o_column_1_row_4(self) -> SocketLinker:
|
|
2827
|
+
"""Output socket: Column 1 Row 4"""
|
|
2828
|
+
return self._output("Column 1 Row 4")
|
|
2829
|
+
|
|
2830
|
+
@property
|
|
2831
|
+
def o_column_2_row_1(self) -> SocketLinker:
|
|
2832
|
+
"""Output socket: Column 2 Row 1"""
|
|
2833
|
+
return self._output("Column 2 Row 1")
|
|
2834
|
+
|
|
2835
|
+
@property
|
|
2836
|
+
def o_column_2_row_2(self) -> SocketLinker:
|
|
2837
|
+
"""Output socket: Column 2 Row 2"""
|
|
2838
|
+
return self._output("Column 2 Row 2")
|
|
2839
|
+
|
|
2840
|
+
@property
|
|
2841
|
+
def o_column_2_row_3(self) -> SocketLinker:
|
|
2842
|
+
"""Output socket: Column 2 Row 3"""
|
|
2843
|
+
return self._output("Column 2 Row 3")
|
|
2844
|
+
|
|
2845
|
+
@property
|
|
2846
|
+
def o_column_2_row_4(self) -> SocketLinker:
|
|
2847
|
+
"""Output socket: Column 2 Row 4"""
|
|
2848
|
+
return self._output("Column 2 Row 4")
|
|
2849
|
+
|
|
2850
|
+
@property
|
|
2851
|
+
def o_column_3_row_1(self) -> SocketLinker:
|
|
2852
|
+
"""Output socket: Column 3 Row 1"""
|
|
2853
|
+
return self._output("Column 3 Row 1")
|
|
2854
|
+
|
|
2855
|
+
@property
|
|
2856
|
+
def o_column_3_row_2(self) -> SocketLinker:
|
|
2857
|
+
"""Output socket: Column 3 Row 2"""
|
|
2858
|
+
return self._output("Column 3 Row 2")
|
|
2859
|
+
|
|
2860
|
+
@property
|
|
2861
|
+
def o_column_3_row_3(self) -> SocketLinker:
|
|
2862
|
+
"""Output socket: Column 3 Row 3"""
|
|
2863
|
+
return self._output("Column 3 Row 3")
|
|
2864
|
+
|
|
2865
|
+
@property
|
|
2866
|
+
def o_column_3_row_4(self) -> SocketLinker:
|
|
2867
|
+
"""Output socket: Column 3 Row 4"""
|
|
2868
|
+
return self._output("Column 3 Row 4")
|
|
2869
|
+
|
|
2870
|
+
@property
|
|
2871
|
+
def o_column_4_row_1(self) -> SocketLinker:
|
|
2872
|
+
"""Output socket: Column 4 Row 1"""
|
|
2873
|
+
return self._output("Column 4 Row 1")
|
|
2874
|
+
|
|
2875
|
+
@property
|
|
2876
|
+
def o_column_4_row_2(self) -> SocketLinker:
|
|
2877
|
+
"""Output socket: Column 4 Row 2"""
|
|
2878
|
+
return self._output("Column 4 Row 2")
|
|
2879
|
+
|
|
2880
|
+
@property
|
|
2881
|
+
def o_column_4_row_3(self) -> SocketLinker:
|
|
2882
|
+
"""Output socket: Column 4 Row 3"""
|
|
2883
|
+
return self._output("Column 4 Row 3")
|
|
2884
|
+
|
|
2885
|
+
@property
|
|
2886
|
+
def o_column_4_row_4(self) -> SocketLinker:
|
|
2887
|
+
"""Output socket: Column 4 Row 4"""
|
|
2888
|
+
return self._output("Column 4 Row 4")
|
|
2889
|
+
|
|
2890
|
+
|
|
2891
|
+
class SeparateTransform(NodeBuilder):
|
|
2892
|
+
"""Split a transformation matrix into a translation vector, a rotation, and a scale vector"""
|
|
2893
|
+
|
|
2894
|
+
_bl_idname = "FunctionNodeSeparateTransform"
|
|
2895
|
+
node: bpy.types.FunctionNodeSeparateTransform
|
|
2896
|
+
|
|
2897
|
+
def __init__(self, transform: TYPE_INPUT_MATRIX = None):
|
|
2898
|
+
super().__init__()
|
|
2899
|
+
key_args = {"Transform": transform}
|
|
2900
|
+
|
|
2901
|
+
self._establish_links(**key_args)
|
|
2902
|
+
|
|
2903
|
+
@property
|
|
2904
|
+
def i_transform(self) -> SocketLinker:
|
|
2905
|
+
"""Input socket: Transform"""
|
|
2906
|
+
return self._input("Transform")
|
|
2907
|
+
|
|
2908
|
+
@property
|
|
2909
|
+
def o_translation(self) -> SocketLinker:
|
|
2910
|
+
"""Output socket: Translation"""
|
|
2911
|
+
return self._output("Translation")
|
|
2912
|
+
|
|
2913
|
+
@property
|
|
2914
|
+
def o_rotation(self) -> SocketLinker:
|
|
2915
|
+
"""Output socket: Rotation"""
|
|
2916
|
+
return self._output("Rotation")
|
|
2917
|
+
|
|
2918
|
+
@property
|
|
2919
|
+
def o_scale(self) -> SocketLinker:
|
|
2920
|
+
"""Output socket: Scale"""
|
|
2921
|
+
return self._output("Scale")
|
|
2922
|
+
|
|
2923
|
+
|
|
2924
|
+
class SeparateXYZ(NodeBuilder):
|
|
2925
|
+
"""Split a vector into its X, Y, and Z components"""
|
|
2926
|
+
|
|
2927
|
+
_bl_idname = "ShaderNodeSeparateXYZ"
|
|
2928
|
+
node: bpy.types.ShaderNodeSeparateXYZ
|
|
2929
|
+
|
|
2930
|
+
def __init__(self, vector: TYPE_INPUT_VECTOR = None):
|
|
2931
|
+
super().__init__()
|
|
2932
|
+
key_args = {"Vector": vector}
|
|
2933
|
+
|
|
2934
|
+
self._establish_links(**key_args)
|
|
2935
|
+
|
|
2936
|
+
@property
|
|
2937
|
+
def i_vector(self) -> SocketLinker:
|
|
2938
|
+
"""Input socket: Vector"""
|
|
2939
|
+
return self._input("Vector")
|
|
2940
|
+
|
|
2941
|
+
@property
|
|
2942
|
+
def o_x(self) -> SocketLinker:
|
|
2943
|
+
"""Output socket: X"""
|
|
2944
|
+
return self._output("X")
|
|
2945
|
+
|
|
2946
|
+
@property
|
|
2947
|
+
def o_y(self) -> SocketLinker:
|
|
2948
|
+
"""Output socket: Y"""
|
|
2949
|
+
return self._output("Y")
|
|
2950
|
+
|
|
2951
|
+
@property
|
|
2952
|
+
def o_z(self) -> SocketLinker:
|
|
2953
|
+
"""Output socket: Z"""
|
|
2954
|
+
return self._output("Z")
|
|
2955
|
+
|
|
2956
|
+
|
|
2957
|
+
class SliceString(NodeBuilder):
|
|
2958
|
+
"""Extract a string segment from a larger string"""
|
|
2959
|
+
|
|
2960
|
+
_bl_idname = "FunctionNodeSliceString"
|
|
2961
|
+
node: bpy.types.FunctionNodeSliceString
|
|
2962
|
+
|
|
2963
|
+
def __init__(
|
|
2964
|
+
self,
|
|
2965
|
+
string: TYPE_INPUT_STRING = "",
|
|
2966
|
+
position: TYPE_INPUT_INT = 0,
|
|
2967
|
+
length: TYPE_INPUT_INT = 10,
|
|
2968
|
+
):
|
|
2969
|
+
super().__init__()
|
|
2970
|
+
key_args = {"String": string, "Position": position, "Length": length}
|
|
2971
|
+
|
|
2972
|
+
self._establish_links(**key_args)
|
|
2973
|
+
|
|
2974
|
+
@property
|
|
2975
|
+
def i_string(self) -> SocketLinker:
|
|
2976
|
+
"""Input socket: String"""
|
|
2977
|
+
return self._input("String")
|
|
2978
|
+
|
|
2979
|
+
@property
|
|
2980
|
+
def i_position(self) -> SocketLinker:
|
|
2981
|
+
"""Input socket: Position"""
|
|
2982
|
+
return self._input("Position")
|
|
2983
|
+
|
|
2984
|
+
@property
|
|
2985
|
+
def i_length(self) -> SocketLinker:
|
|
2986
|
+
"""Input socket: Length"""
|
|
2987
|
+
return self._input("Length")
|
|
2988
|
+
|
|
2989
|
+
@property
|
|
2990
|
+
def o_string(self) -> SocketLinker:
|
|
2991
|
+
"""Output socket: String"""
|
|
2992
|
+
return self._output("String")
|
|
2993
|
+
|
|
2994
|
+
|
|
2995
|
+
class StringLength(NodeBuilder):
|
|
2996
|
+
"""Output the number of characters in the given string"""
|
|
2997
|
+
|
|
2998
|
+
_bl_idname = "FunctionNodeStringLength"
|
|
2999
|
+
node: bpy.types.FunctionNodeStringLength
|
|
3000
|
+
|
|
3001
|
+
def __init__(self, string: TYPE_INPUT_STRING = ""):
|
|
3002
|
+
super().__init__()
|
|
3003
|
+
key_args = {"String": string}
|
|
3004
|
+
|
|
3005
|
+
self._establish_links(**key_args)
|
|
3006
|
+
|
|
3007
|
+
@property
|
|
3008
|
+
def i_string(self) -> SocketLinker:
|
|
3009
|
+
"""Input socket: String"""
|
|
3010
|
+
return self._input("String")
|
|
3011
|
+
|
|
3012
|
+
@property
|
|
3013
|
+
def o_length(self) -> SocketLinker:
|
|
3014
|
+
"""Output socket: Length"""
|
|
3015
|
+
return self._output("Length")
|
|
3016
|
+
|
|
3017
|
+
|
|
3018
|
+
class StringToValue(NodeBuilder):
|
|
3019
|
+
"""Derive a numeric value from a given string representation"""
|
|
3020
|
+
|
|
3021
|
+
_bl_idname = "FunctionNodeStringToValue"
|
|
3022
|
+
node: bpy.types.FunctionNodeStringToValue
|
|
3023
|
+
|
|
3024
|
+
def __init__(
|
|
3025
|
+
self,
|
|
3026
|
+
string: TYPE_INPUT_STRING = "",
|
|
3027
|
+
*,
|
|
3028
|
+
data_type: Literal["FLOAT", "INT"] = "FLOAT",
|
|
3029
|
+
):
|
|
3030
|
+
super().__init__()
|
|
3031
|
+
key_args = {"String": string}
|
|
3032
|
+
self.data_type = data_type
|
|
3033
|
+
self._establish_links(**key_args)
|
|
3034
|
+
|
|
3035
|
+
@classmethod
|
|
3036
|
+
def float(cls, string: TYPE_INPUT_STRING = "") -> "StringToValue":
|
|
3037
|
+
"""Create String to Value with operation 'Float'."""
|
|
3038
|
+
return cls(data_type="FLOAT", string=string)
|
|
3039
|
+
|
|
3040
|
+
@classmethod
|
|
3041
|
+
def integer(cls, string: TYPE_INPUT_STRING = "") -> "StringToValue":
|
|
3042
|
+
"""Create String to Value with operation 'Integer'."""
|
|
3043
|
+
return cls(data_type="INT", string=string)
|
|
3044
|
+
|
|
3045
|
+
@property
|
|
3046
|
+
def i_string(self) -> SocketLinker:
|
|
3047
|
+
"""Input socket: String"""
|
|
3048
|
+
return self._input("String")
|
|
3049
|
+
|
|
3050
|
+
@property
|
|
3051
|
+
def o_value(self) -> SocketLinker:
|
|
3052
|
+
"""Output socket: Value"""
|
|
3053
|
+
return self._output("Value")
|
|
3054
|
+
|
|
3055
|
+
@property
|
|
3056
|
+
def o_length(self) -> SocketLinker:
|
|
3057
|
+
"""Output socket: Length"""
|
|
3058
|
+
return self._output("Length")
|
|
3059
|
+
|
|
3060
|
+
@property
|
|
3061
|
+
def data_type(self) -> Literal["FLOAT", "INT"]:
|
|
3062
|
+
return self.node.data_type
|
|
3063
|
+
|
|
3064
|
+
@data_type.setter
|
|
3065
|
+
def data_type(self, value: Literal["FLOAT", "INT"]):
|
|
3066
|
+
self.node.data_type = value
|
|
3067
|
+
|
|
3068
|
+
|
|
3069
|
+
class Switch(NodeBuilder):
|
|
3070
|
+
"""Switch between two inputs"""
|
|
3071
|
+
|
|
3072
|
+
_bl_idname = "GeometryNodeSwitch"
|
|
3073
|
+
node: bpy.types.GeometryNodeSwitch
|
|
3074
|
+
|
|
3075
|
+
def __init__(
|
|
3076
|
+
self,
|
|
3077
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3078
|
+
false: TYPE_INPUT_GEOMETRY = None,
|
|
3079
|
+
true: TYPE_INPUT_GEOMETRY = None,
|
|
3080
|
+
*,
|
|
3081
|
+
input_type: Literal[
|
|
3082
|
+
"FLOAT",
|
|
3083
|
+
"INT",
|
|
3084
|
+
"BOOLEAN",
|
|
3085
|
+
"VECTOR",
|
|
3086
|
+
"RGBA",
|
|
3087
|
+
"ROTATION",
|
|
3088
|
+
"MATRIX",
|
|
3089
|
+
"STRING",
|
|
3090
|
+
"MENU",
|
|
3091
|
+
"OBJECT",
|
|
3092
|
+
"IMAGE",
|
|
3093
|
+
"GEOMETRY",
|
|
3094
|
+
"COLLECTION",
|
|
3095
|
+
"MATERIAL",
|
|
3096
|
+
"BUNDLE",
|
|
3097
|
+
"CLOSURE",
|
|
3098
|
+
] = "GEOMETRY",
|
|
3099
|
+
):
|
|
3100
|
+
super().__init__()
|
|
3101
|
+
key_args = {"Switch": switch, "False": false, "True": true}
|
|
3102
|
+
self.input_type = input_type
|
|
3103
|
+
self._establish_links(**key_args)
|
|
3104
|
+
|
|
3105
|
+
@classmethod
|
|
3106
|
+
def float(
|
|
3107
|
+
cls,
|
|
3108
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3109
|
+
false: TYPE_INPUT_VALUE = 0.0,
|
|
3110
|
+
true: TYPE_INPUT_VALUE = 0.0,
|
|
3111
|
+
) -> "Switch":
|
|
3112
|
+
"""Create Switch with operation 'Float'."""
|
|
3113
|
+
return cls(input_type="FLOAT", switch=switch, false=false, true=true)
|
|
3114
|
+
|
|
3115
|
+
@classmethod
|
|
3116
|
+
def integer(
|
|
3117
|
+
cls,
|
|
3118
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3119
|
+
false: TYPE_INPUT_INT = 0,
|
|
3120
|
+
true: TYPE_INPUT_INT = 0,
|
|
3121
|
+
) -> "Switch":
|
|
3122
|
+
"""Create Switch with operation 'Integer'."""
|
|
3123
|
+
return cls(input_type="INT", switch=switch, false=false, true=true)
|
|
3124
|
+
|
|
3125
|
+
@classmethod
|
|
3126
|
+
def boolean(
|
|
3127
|
+
cls,
|
|
3128
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3129
|
+
false: TYPE_INPUT_BOOLEAN = False,
|
|
3130
|
+
true: TYPE_INPUT_BOOLEAN = False,
|
|
3131
|
+
) -> "Switch":
|
|
3132
|
+
"""Create Switch with operation 'Boolean'."""
|
|
3133
|
+
return cls(input_type="BOOLEAN", switch=switch, false=false, true=true)
|
|
3134
|
+
|
|
3135
|
+
@classmethod
|
|
3136
|
+
def vector(
|
|
3137
|
+
cls,
|
|
3138
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3139
|
+
false: TYPE_INPUT_VECTOR = None,
|
|
3140
|
+
true: TYPE_INPUT_VECTOR = None,
|
|
3141
|
+
) -> "Switch":
|
|
3142
|
+
"""Create Switch with operation 'Vector'."""
|
|
3143
|
+
return cls(input_type="VECTOR", switch=switch, false=false, true=true)
|
|
3144
|
+
|
|
3145
|
+
@classmethod
|
|
3146
|
+
def color(
|
|
3147
|
+
cls,
|
|
3148
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3149
|
+
false: TYPE_INPUT_COLOR = None,
|
|
3150
|
+
true: TYPE_INPUT_COLOR = None,
|
|
3151
|
+
) -> "Switch":
|
|
3152
|
+
"""Create Switch with operation 'Color'."""
|
|
3153
|
+
return cls(input_type="RGBA", switch=switch, false=false, true=true)
|
|
3154
|
+
|
|
3155
|
+
@classmethod
|
|
3156
|
+
def rotation(
|
|
3157
|
+
cls,
|
|
3158
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3159
|
+
false: TYPE_INPUT_ROTATION = None,
|
|
3160
|
+
true: TYPE_INPUT_ROTATION = None,
|
|
3161
|
+
) -> "Switch":
|
|
3162
|
+
"""Create Switch with operation 'Rotation'."""
|
|
3163
|
+
return cls(input_type="ROTATION", switch=switch, false=false, true=true)
|
|
3164
|
+
|
|
3165
|
+
@classmethod
|
|
3166
|
+
def matrix(
|
|
3167
|
+
cls,
|
|
3168
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3169
|
+
false: TYPE_INPUT_MATRIX = None,
|
|
3170
|
+
true: TYPE_INPUT_MATRIX = None,
|
|
3171
|
+
) -> "Switch":
|
|
3172
|
+
"""Create Switch with operation 'Matrix'."""
|
|
3173
|
+
return cls(input_type="MATRIX", switch=switch, false=false, true=true)
|
|
3174
|
+
|
|
3175
|
+
@classmethod
|
|
3176
|
+
def string(
|
|
3177
|
+
cls,
|
|
3178
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3179
|
+
false: TYPE_INPUT_STRING = "",
|
|
3180
|
+
true: TYPE_INPUT_STRING = "",
|
|
3181
|
+
) -> "Switch":
|
|
3182
|
+
"""Create Switch with operation 'String'."""
|
|
3183
|
+
return cls(input_type="STRING", switch=switch, false=false, true=true)
|
|
3184
|
+
|
|
3185
|
+
@classmethod
|
|
3186
|
+
def menu(
|
|
3187
|
+
cls,
|
|
3188
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3189
|
+
false: TYPE_INPUT_MENU = "",
|
|
3190
|
+
true: TYPE_INPUT_MENU = "",
|
|
3191
|
+
) -> "Switch":
|
|
3192
|
+
"""Create Switch with operation 'Menu'."""
|
|
3193
|
+
return cls(input_type="MENU", switch=switch, false=false, true=true)
|
|
3194
|
+
|
|
3195
|
+
@classmethod
|
|
3196
|
+
def object(
|
|
3197
|
+
cls,
|
|
3198
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3199
|
+
false: TYPE_INPUT_OBJECT = None,
|
|
3200
|
+
true: TYPE_INPUT_OBJECT = None,
|
|
3201
|
+
) -> "Switch":
|
|
3202
|
+
"""Create Switch with operation 'Object'."""
|
|
3203
|
+
return cls(input_type="OBJECT", switch=switch, false=false, true=true)
|
|
3204
|
+
|
|
3205
|
+
@classmethod
|
|
3206
|
+
def image(
|
|
3207
|
+
cls,
|
|
3208
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3209
|
+
false: TYPE_INPUT_IMAGE = None,
|
|
3210
|
+
true: TYPE_INPUT_IMAGE = None,
|
|
3211
|
+
) -> "Switch":
|
|
3212
|
+
"""Create Switch with operation 'Image'."""
|
|
3213
|
+
return cls(input_type="IMAGE", switch=switch, false=false, true=true)
|
|
3214
|
+
|
|
3215
|
+
@classmethod
|
|
3216
|
+
def geometry(
|
|
3217
|
+
cls,
|
|
3218
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3219
|
+
false: TYPE_INPUT_GEOMETRY = None,
|
|
3220
|
+
true: TYPE_INPUT_GEOMETRY = None,
|
|
3221
|
+
) -> "Switch":
|
|
3222
|
+
"""Create Switch with operation 'Geometry'."""
|
|
3223
|
+
return cls(input_type="GEOMETRY", switch=switch, false=false, true=true)
|
|
3224
|
+
|
|
3225
|
+
@classmethod
|
|
3226
|
+
def collection(
|
|
3227
|
+
cls,
|
|
3228
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3229
|
+
false: TYPE_INPUT_COLLECTION = None,
|
|
3230
|
+
true: TYPE_INPUT_COLLECTION = None,
|
|
3231
|
+
) -> "Switch":
|
|
3232
|
+
"""Create Switch with operation 'Collection'."""
|
|
3233
|
+
return cls(input_type="COLLECTION", switch=switch, false=false, true=true)
|
|
3234
|
+
|
|
3235
|
+
@classmethod
|
|
3236
|
+
def material(
|
|
3237
|
+
cls,
|
|
3238
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3239
|
+
false: TYPE_INPUT_MATERIAL = None,
|
|
3240
|
+
true: TYPE_INPUT_MATERIAL = None,
|
|
3241
|
+
) -> "Switch":
|
|
3242
|
+
"""Create Switch with operation 'Material'."""
|
|
3243
|
+
return cls(input_type="MATERIAL", switch=switch, false=false, true=true)
|
|
3244
|
+
|
|
3245
|
+
@classmethod
|
|
3246
|
+
def bundle(
|
|
3247
|
+
cls,
|
|
3248
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3249
|
+
false: TYPE_INPUT_BUNDLE = None,
|
|
3250
|
+
true: TYPE_INPUT_BUNDLE = None,
|
|
3251
|
+
) -> "Switch":
|
|
3252
|
+
"""Create Switch with operation 'Bundle'."""
|
|
3253
|
+
return cls(input_type="BUNDLE", switch=switch, false=false, true=true)
|
|
3254
|
+
|
|
3255
|
+
@classmethod
|
|
3256
|
+
def closure(
|
|
3257
|
+
cls,
|
|
3258
|
+
switch: TYPE_INPUT_BOOLEAN = False,
|
|
3259
|
+
false: TYPE_INPUT_CLOSURE = None,
|
|
3260
|
+
true: TYPE_INPUT_CLOSURE = None,
|
|
3261
|
+
) -> "Switch":
|
|
3262
|
+
"""Create Switch with operation 'Closure'."""
|
|
3263
|
+
return cls(input_type="CLOSURE", switch=switch, false=false, true=true)
|
|
3264
|
+
|
|
3265
|
+
@property
|
|
3266
|
+
def i_switch(self) -> SocketLinker:
|
|
3267
|
+
"""Input socket: Switch"""
|
|
3268
|
+
return self._input("Switch")
|
|
3269
|
+
|
|
3270
|
+
@property
|
|
3271
|
+
def i_false(self) -> SocketLinker:
|
|
3272
|
+
"""Input socket: False"""
|
|
3273
|
+
return self._input("False")
|
|
3274
|
+
|
|
3275
|
+
@property
|
|
3276
|
+
def i_true(self) -> SocketLinker:
|
|
3277
|
+
"""Input socket: True"""
|
|
3278
|
+
return self._input("True")
|
|
3279
|
+
|
|
3280
|
+
@property
|
|
3281
|
+
def o_output(self) -> SocketLinker:
|
|
3282
|
+
"""Output socket: Output"""
|
|
3283
|
+
return self._output("Output")
|
|
3284
|
+
|
|
3285
|
+
@property
|
|
3286
|
+
def input_type(
|
|
3287
|
+
self,
|
|
3288
|
+
) -> Literal[
|
|
3289
|
+
"FLOAT",
|
|
3290
|
+
"INT",
|
|
3291
|
+
"BOOLEAN",
|
|
3292
|
+
"VECTOR",
|
|
3293
|
+
"RGBA",
|
|
3294
|
+
"ROTATION",
|
|
3295
|
+
"MATRIX",
|
|
3296
|
+
"STRING",
|
|
3297
|
+
"MENU",
|
|
3298
|
+
"OBJECT",
|
|
3299
|
+
"IMAGE",
|
|
3300
|
+
"GEOMETRY",
|
|
3301
|
+
"COLLECTION",
|
|
3302
|
+
"MATERIAL",
|
|
3303
|
+
"BUNDLE",
|
|
3304
|
+
"CLOSURE",
|
|
3305
|
+
]:
|
|
3306
|
+
return self.node.input_type
|
|
3307
|
+
|
|
3308
|
+
@input_type.setter
|
|
3309
|
+
def input_type(
|
|
3310
|
+
self,
|
|
3311
|
+
value: Literal[
|
|
3312
|
+
"FLOAT",
|
|
3313
|
+
"INT",
|
|
3314
|
+
"BOOLEAN",
|
|
3315
|
+
"VECTOR",
|
|
3316
|
+
"RGBA",
|
|
3317
|
+
"ROTATION",
|
|
3318
|
+
"MATRIX",
|
|
3319
|
+
"STRING",
|
|
3320
|
+
"MENU",
|
|
3321
|
+
"OBJECT",
|
|
3322
|
+
"IMAGE",
|
|
3323
|
+
"GEOMETRY",
|
|
3324
|
+
"COLLECTION",
|
|
3325
|
+
"MATERIAL",
|
|
3326
|
+
"BUNDLE",
|
|
3327
|
+
"CLOSURE",
|
|
3328
|
+
],
|
|
3329
|
+
):
|
|
3330
|
+
self.node.input_type = value
|
|
3331
|
+
|
|
3332
|
+
|
|
3333
|
+
class TransformDirection(NodeBuilder):
|
|
3334
|
+
"""Apply a transformation matrix (excluding translation) to the given vector"""
|
|
3335
|
+
|
|
3336
|
+
_bl_idname = "FunctionNodeTransformDirection"
|
|
3337
|
+
node: bpy.types.FunctionNodeTransformDirection
|
|
3338
|
+
|
|
3339
|
+
def __init__(
|
|
3340
|
+
self,
|
|
3341
|
+
direction: TYPE_INPUT_VECTOR = None,
|
|
3342
|
+
transform: TYPE_INPUT_MATRIX = None,
|
|
3343
|
+
):
|
|
3344
|
+
super().__init__()
|
|
3345
|
+
key_args = {"Direction": direction, "Transform": transform}
|
|
3346
|
+
|
|
3347
|
+
self._establish_links(**key_args)
|
|
3348
|
+
|
|
3349
|
+
@property
|
|
3350
|
+
def i_direction(self) -> SocketLinker:
|
|
3351
|
+
"""Input socket: Direction"""
|
|
3352
|
+
return self._input("Direction")
|
|
3353
|
+
|
|
3354
|
+
@property
|
|
3355
|
+
def i_transform(self) -> SocketLinker:
|
|
3356
|
+
"""Input socket: Transform"""
|
|
3357
|
+
return self._input("Transform")
|
|
3358
|
+
|
|
3359
|
+
@property
|
|
3360
|
+
def o_direction(self) -> SocketLinker:
|
|
3361
|
+
"""Output socket: Direction"""
|
|
3362
|
+
return self._output("Direction")
|
|
3363
|
+
|
|
3364
|
+
|
|
3365
|
+
class TransformPoint(NodeBuilder):
|
|
3366
|
+
"""Apply a transformation matrix to the given vector"""
|
|
3367
|
+
|
|
3368
|
+
_bl_idname = "FunctionNodeTransformPoint"
|
|
3369
|
+
node: bpy.types.FunctionNodeTransformPoint
|
|
3370
|
+
|
|
3371
|
+
def __init__(
|
|
3372
|
+
self,
|
|
3373
|
+
vector: TYPE_INPUT_VECTOR = None,
|
|
3374
|
+
transform: TYPE_INPUT_MATRIX = None,
|
|
3375
|
+
):
|
|
3376
|
+
super().__init__()
|
|
3377
|
+
key_args = {"Vector": vector, "Transform": transform}
|
|
3378
|
+
|
|
3379
|
+
self._establish_links(**key_args)
|
|
3380
|
+
|
|
3381
|
+
@property
|
|
3382
|
+
def i_vector(self) -> SocketLinker:
|
|
3383
|
+
"""Input socket: Vector"""
|
|
3384
|
+
return self._input("Vector")
|
|
3385
|
+
|
|
3386
|
+
@property
|
|
3387
|
+
def i_transform(self) -> SocketLinker:
|
|
3388
|
+
"""Input socket: Transform"""
|
|
3389
|
+
return self._input("Transform")
|
|
3390
|
+
|
|
3391
|
+
@property
|
|
3392
|
+
def o_vector(self) -> SocketLinker:
|
|
3393
|
+
"""Output socket: Vector"""
|
|
3394
|
+
return self._output("Vector")
|
|
3395
|
+
|
|
3396
|
+
|
|
3397
|
+
class TransposeMatrix(NodeBuilder):
|
|
3398
|
+
"""Flip a matrix over its diagonal, turning columns into rows and vice-versa"""
|
|
3399
|
+
|
|
3400
|
+
_bl_idname = "FunctionNodeTransposeMatrix"
|
|
3401
|
+
node: bpy.types.FunctionNodeTransposeMatrix
|
|
3402
|
+
|
|
3403
|
+
def __init__(self, matrix: TYPE_INPUT_MATRIX = None):
|
|
3404
|
+
super().__init__()
|
|
3405
|
+
key_args = {"Matrix": matrix}
|
|
3406
|
+
|
|
3407
|
+
self._establish_links(**key_args)
|
|
3408
|
+
|
|
3409
|
+
@property
|
|
3410
|
+
def i_matrix(self) -> SocketLinker:
|
|
3411
|
+
"""Input socket: Matrix"""
|
|
3412
|
+
return self._input("Matrix")
|
|
3413
|
+
|
|
3414
|
+
@property
|
|
3415
|
+
def o_matrix(self) -> SocketLinker:
|
|
3416
|
+
"""Output socket: Matrix"""
|
|
3417
|
+
return self._output("Matrix")
|
|
3418
|
+
|
|
3419
|
+
|
|
3420
|
+
class UVUnwrap(NodeBuilder):
|
|
3421
|
+
"""Generate a UV map based on seam edges"""
|
|
3422
|
+
|
|
3423
|
+
_bl_idname = "GeometryNodeUVUnwrap"
|
|
3424
|
+
node: bpy.types.GeometryNodeUVUnwrap
|
|
3425
|
+
|
|
3426
|
+
def __init__(
|
|
3427
|
+
self,
|
|
3428
|
+
selection: TYPE_INPUT_BOOLEAN = True,
|
|
3429
|
+
seam: TYPE_INPUT_BOOLEAN = False,
|
|
3430
|
+
margin: TYPE_INPUT_VALUE = 0.001,
|
|
3431
|
+
fill_holes: TYPE_INPUT_BOOLEAN = True,
|
|
3432
|
+
method: TYPE_INPUT_MENU = "Angle Based",
|
|
3433
|
+
):
|
|
3434
|
+
super().__init__()
|
|
3435
|
+
key_args = {
|
|
3436
|
+
"Selection": selection,
|
|
3437
|
+
"Seam": seam,
|
|
3438
|
+
"Margin": margin,
|
|
3439
|
+
"Fill Holes": fill_holes,
|
|
3440
|
+
"Method": method,
|
|
3441
|
+
}
|
|
3442
|
+
|
|
3443
|
+
self._establish_links(**key_args)
|
|
3444
|
+
|
|
3445
|
+
@property
|
|
3446
|
+
def i_selection(self) -> SocketLinker:
|
|
3447
|
+
"""Input socket: Selection"""
|
|
3448
|
+
return self._input("Selection")
|
|
3449
|
+
|
|
3450
|
+
@property
|
|
3451
|
+
def i_seam(self) -> SocketLinker:
|
|
3452
|
+
"""Input socket: Seam"""
|
|
3453
|
+
return self._input("Seam")
|
|
3454
|
+
|
|
3455
|
+
@property
|
|
3456
|
+
def i_margin(self) -> SocketLinker:
|
|
3457
|
+
"""Input socket: Margin"""
|
|
3458
|
+
return self._input("Margin")
|
|
3459
|
+
|
|
3460
|
+
@property
|
|
3461
|
+
def i_fill_holes(self) -> SocketLinker:
|
|
3462
|
+
"""Input socket: Fill Holes"""
|
|
3463
|
+
return self._input("Fill Holes")
|
|
3464
|
+
|
|
3465
|
+
@property
|
|
3466
|
+
def i_method(self) -> SocketLinker:
|
|
3467
|
+
"""Input socket: Method"""
|
|
3468
|
+
return self._input("Method")
|
|
3469
|
+
|
|
3470
|
+
@property
|
|
3471
|
+
def o_uv(self) -> SocketLinker:
|
|
3472
|
+
"""Output socket: UV"""
|
|
3473
|
+
return self._output("UV")
|
|
3474
|
+
|
|
3475
|
+
|
|
3476
|
+
class ValueToString(NodeBuilder):
|
|
3477
|
+
"""Generate a string representation of the given input value"""
|
|
3478
|
+
|
|
3479
|
+
_bl_idname = "FunctionNodeValueToString"
|
|
3480
|
+
node: bpy.types.FunctionNodeValueToString
|
|
3481
|
+
|
|
3482
|
+
def __init__(
|
|
3483
|
+
self,
|
|
3484
|
+
value: TYPE_INPUT_VALUE = 0.0,
|
|
3485
|
+
decimals: TYPE_INPUT_INT = 0,
|
|
3486
|
+
*,
|
|
3487
|
+
data_type: Literal["FLOAT", "INT"] = "FLOAT",
|
|
3488
|
+
):
|
|
3489
|
+
super().__init__()
|
|
3490
|
+
key_args = {"Value": value, "Decimals": decimals}
|
|
3491
|
+
self.data_type = data_type
|
|
3492
|
+
self._establish_links(**key_args)
|
|
3493
|
+
|
|
3494
|
+
@classmethod
|
|
3495
|
+
def float(
|
|
3496
|
+
cls, value: TYPE_INPUT_VALUE = 0.0, decimals: TYPE_INPUT_INT = 0
|
|
3497
|
+
) -> "ValueToString":
|
|
3498
|
+
"""Create Value to String with operation 'Float'."""
|
|
3499
|
+
return cls(data_type="FLOAT", value=value, decimals=decimals)
|
|
3500
|
+
|
|
3501
|
+
@classmethod
|
|
3502
|
+
def integer(cls, value: TYPE_INPUT_INT = 0) -> "ValueToString":
|
|
3503
|
+
"""Create Value to String with operation 'Integer'."""
|
|
3504
|
+
return cls(data_type="INT", value=value)
|
|
3505
|
+
|
|
3506
|
+
@property
|
|
3507
|
+
def i_value(self) -> SocketLinker:
|
|
3508
|
+
"""Input socket: Value"""
|
|
3509
|
+
return self._input("Value")
|
|
3510
|
+
|
|
3511
|
+
@property
|
|
3512
|
+
def i_decimals(self) -> SocketLinker:
|
|
3513
|
+
"""Input socket: Decimals"""
|
|
3514
|
+
return self._input("Decimals")
|
|
3515
|
+
|
|
3516
|
+
@property
|
|
3517
|
+
def o_string(self) -> SocketLinker:
|
|
3518
|
+
"""Output socket: String"""
|
|
3519
|
+
return self._output("String")
|
|
3520
|
+
|
|
3521
|
+
@property
|
|
3522
|
+
def data_type(self) -> Literal["FLOAT", "INT"]:
|
|
3523
|
+
return self.node.data_type
|
|
3524
|
+
|
|
3525
|
+
@data_type.setter
|
|
3526
|
+
def data_type(self, value: Literal["FLOAT", "INT"]):
|
|
3527
|
+
self.node.data_type = value
|