nodebpy 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nodebpy/builder.py +770 -306
- nodebpy/nodes/__init__.py +623 -9
- nodebpy/nodes/attribute.py +174 -273
- nodebpy/nodes/color.py +76 -0
- nodebpy/nodes/converter.py +4518 -0
- nodebpy/nodes/experimental.py +314 -0
- nodebpy/nodes/geometry.py +3665 -5250
- nodebpy/nodes/grid.py +1228 -0
- nodebpy/nodes/group.py +20 -0
- nodebpy/nodes/input.py +1571 -254
- nodebpy/nodes/interface.py +400 -0
- nodebpy/nodes/mesh.py +0 -1391
- nodebpy/nodes/texture.py +70 -0
- nodebpy/nodes/types.py +319 -6
- nodebpy/nodes/vector.py +0 -0
- nodebpy/nodes/zone.py +442 -0
- nodebpy/screenshot.py +2 -1
- nodebpy/sockets.py +12 -12
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.0.dist-info}/METADATA +4 -4
- nodebpy-0.2.0.dist-info/RECORD +25 -0
- nodebpy/nodes/curve.py +0 -2006
- nodebpy/nodes/manually_specified.py +0 -1382
- nodebpy/nodes/utilities.py +0 -2344
- nodebpy-0.1.1.dist-info/RECORD +0 -19
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.0.dist-info}/WHEEL +0 -0
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,1382 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Some of the nodes need to be manually specified because they are a bit tricky to generate automatically.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
|
|
7
|
-
import bpy
|
|
8
|
-
from bpy.types import NodeSocketFloat, NodeSocketVector
|
|
9
|
-
from typing import Iterable, Literal
|
|
10
|
-
|
|
11
|
-
from ..builder import (
|
|
12
|
-
NodeBuilder,
|
|
13
|
-
NodeSocket,
|
|
14
|
-
source_socket,
|
|
15
|
-
SocketLinker,
|
|
16
|
-
)
|
|
17
|
-
from . import types
|
|
18
|
-
from .types import LINKABLE, TYPE_INPUT_BOOLEAN, TYPE_INPUT_VECTOR, _AttributeDomains
|
|
19
|
-
|
|
20
|
-
_RANDOM_VALUE_DATA_TYPES = Literal["FLOAT", "INT", "BOOLEAN", "FLOAT_VECTOR"]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Vector(NodeBuilder):
|
|
24
|
-
"""Provide a vector value that can be connected to other nodes in the tree"""
|
|
25
|
-
|
|
26
|
-
name = "FunctionNodeInputVector"
|
|
27
|
-
node: bpy.types.FunctionNodeInputVector
|
|
28
|
-
|
|
29
|
-
def __init__(self, vector: list[float, float, float] | None = (0, 0, 0), **kwargs):
|
|
30
|
-
super().__init__()
|
|
31
|
-
key_args = kwargs
|
|
32
|
-
self.vector = vector
|
|
33
|
-
self._establish_links(**key_args)
|
|
34
|
-
|
|
35
|
-
@property
|
|
36
|
-
def o_vector(self) -> bpy.types.NodeSocketVector:
|
|
37
|
-
"""Output socket: Vector"""
|
|
38
|
-
return self._output("Vector")
|
|
39
|
-
|
|
40
|
-
@property
|
|
41
|
-
def vector(self) -> list[float, float, float]:
|
|
42
|
-
return self.node.vector
|
|
43
|
-
|
|
44
|
-
@vector.setter
|
|
45
|
-
def vector(self, value: list[float, float, float]):
|
|
46
|
-
self.node.vector = value
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class RandomValue(NodeBuilder):
|
|
50
|
-
"""Random Value node"""
|
|
51
|
-
|
|
52
|
-
name = "FunctionNodeRandomValue"
|
|
53
|
-
node: bpy.types.FunctionNodeRandomValue
|
|
54
|
-
_default_input_id = "ID"
|
|
55
|
-
|
|
56
|
-
def __init__(
|
|
57
|
-
self,
|
|
58
|
-
data_type: _RANDOM_VALUE_DATA_TYPES,
|
|
59
|
-
id: int | LINKABLE | None = None,
|
|
60
|
-
seed: int | LINKABLE | None = None,
|
|
61
|
-
**kwargs,
|
|
62
|
-
):
|
|
63
|
-
super().__init__()
|
|
64
|
-
self.node.data_type = data_type
|
|
65
|
-
key_args = {
|
|
66
|
-
"ID": id,
|
|
67
|
-
"Seed": seed,
|
|
68
|
-
}
|
|
69
|
-
key_args.update(kwargs)
|
|
70
|
-
|
|
71
|
-
self._establish_links(**key_args)
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
def data_type(self) -> _RANDOM_VALUE_DATA_TYPES:
|
|
75
|
-
return self.node.data_type # type: ignore
|
|
76
|
-
|
|
77
|
-
@data_type.setter
|
|
78
|
-
def data_type(self, value: _RANDOM_VALUE_DATA_TYPES):
|
|
79
|
-
self.node.data_type = value
|
|
80
|
-
|
|
81
|
-
@property
|
|
82
|
-
def o_value(self) -> NodeSocket:
|
|
83
|
-
"""Output socket: Value"""
|
|
84
|
-
match self.data_type:
|
|
85
|
-
case "FLOAT":
|
|
86
|
-
return self._output("Value_001")
|
|
87
|
-
case "INT":
|
|
88
|
-
return self._output("Value_002")
|
|
89
|
-
case "BOOLEAN":
|
|
90
|
-
return self._output("Value_003")
|
|
91
|
-
case "FLOAT_VECTOR":
|
|
92
|
-
return self._output("Value")
|
|
93
|
-
|
|
94
|
-
def i_min(self) -> NodeSocket:
|
|
95
|
-
"""Input socket: Minimum"""
|
|
96
|
-
match self.data_type:
|
|
97
|
-
case "FLOAT":
|
|
98
|
-
return self._input("Min_001")
|
|
99
|
-
case "INT":
|
|
100
|
-
return self._input("Min_002")
|
|
101
|
-
case "BOOLEAN":
|
|
102
|
-
raise ValueError(
|
|
103
|
-
"Boolean data type does not support minimum value, use 'Probability'"
|
|
104
|
-
)
|
|
105
|
-
case "FLOAT_VECTOR":
|
|
106
|
-
return self._input("Min")
|
|
107
|
-
|
|
108
|
-
def i_max(self) -> NodeSocket:
|
|
109
|
-
"""Input socket: Maximum"""
|
|
110
|
-
match self.data_type:
|
|
111
|
-
case "FLOAT":
|
|
112
|
-
return self._input("Max_001")
|
|
113
|
-
case "INT":
|
|
114
|
-
return self._input("Max_002")
|
|
115
|
-
case "BOOLEAN":
|
|
116
|
-
raise ValueError(
|
|
117
|
-
"Boolean data type does not support maximum value, use 'Probability'"
|
|
118
|
-
)
|
|
119
|
-
case "FLOAT_VECTOR":
|
|
120
|
-
return self._input("Max")
|
|
121
|
-
|
|
122
|
-
def i_probability(self) -> NodeSocket:
|
|
123
|
-
"""Input socket: Probability"""
|
|
124
|
-
if self.data_type != "BOOLEAN":
|
|
125
|
-
raise ValueError(
|
|
126
|
-
f"Probability socket is only supported for boolean data types, not for data type: {self.data_type}"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
return self._input("Probability")
|
|
130
|
-
|
|
131
|
-
@classmethod
|
|
132
|
-
def float(
|
|
133
|
-
cls,
|
|
134
|
-
min: float | LINKABLE = 0.0,
|
|
135
|
-
max: float | LINKABLE = 1.0,
|
|
136
|
-
id: int | LINKABLE | None = None,
|
|
137
|
-
seed: int | LINKABLE = 1,
|
|
138
|
-
) -> NodeBuilder:
|
|
139
|
-
buidler = cls(Min_001=min, Max_001=max, id=id, seed=seed, data_type="FLOAT")
|
|
140
|
-
buidler._default_output_id = "Value_001"
|
|
141
|
-
return buidler
|
|
142
|
-
|
|
143
|
-
@classmethod
|
|
144
|
-
def integer(
|
|
145
|
-
cls,
|
|
146
|
-
min: int | LINKABLE = 0,
|
|
147
|
-
max: int | LINKABLE = 1,
|
|
148
|
-
id: int | LINKABLE | None = None,
|
|
149
|
-
seed: int | LINKABLE = 1,
|
|
150
|
-
) -> NodeBuilder:
|
|
151
|
-
buidler = cls(Min_002=min, Max_002=max, id=id, seed=seed, data_type="INT")
|
|
152
|
-
buidler._default_output_id = "Value_002"
|
|
153
|
-
return buidler
|
|
154
|
-
|
|
155
|
-
@classmethod
|
|
156
|
-
def boolean(
|
|
157
|
-
cls,
|
|
158
|
-
probability: float | LINKABLE = 0.5,
|
|
159
|
-
id: int | LINKABLE | None = None,
|
|
160
|
-
seed: int | LINKABLE = 1,
|
|
161
|
-
) -> NodeBuilder:
|
|
162
|
-
builder = cls(Probability=probability, id=id, seed=seed, data_type="BOOLEAN")
|
|
163
|
-
builder._default_output_id = "Value_003"
|
|
164
|
-
return builder
|
|
165
|
-
|
|
166
|
-
@classmethod
|
|
167
|
-
def vector(
|
|
168
|
-
cls,
|
|
169
|
-
min: tuple[float, float, float] | list[float] | LINKABLE = (0.0, 0.0, 0.0),
|
|
170
|
-
max: tuple[float, float, float] | list[float] | LINKABLE = (1.0, 1.0, 1.0),
|
|
171
|
-
id: int | LINKABLE | None = None,
|
|
172
|
-
seed: int | LINKABLE = 1,
|
|
173
|
-
) -> NodeBuilder:
|
|
174
|
-
buidler = cls(Min=min, Max=max, id=id, seed=seed, data_type="FLOAT_VECTOR")
|
|
175
|
-
buidler._default_output_id = "Value"
|
|
176
|
-
return buidler
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
class SeparateXYZ(NodeBuilder):
|
|
180
|
-
"""Split a vector into its X, Y, and Z components"""
|
|
181
|
-
|
|
182
|
-
name = "ShaderNodeSeparateXYZ"
|
|
183
|
-
node: bpy.types.ShaderNodeSeparateXYZ # type: ignore
|
|
184
|
-
|
|
185
|
-
def __init__(self, vector: TYPE_INPUT_VECTOR | None = None):
|
|
186
|
-
super().__init__()
|
|
187
|
-
self._establish_links(**{"Vector": vector})
|
|
188
|
-
|
|
189
|
-
@property
|
|
190
|
-
def i_vector(self) -> NodeSocket:
|
|
191
|
-
"""Input socket: Vector"""
|
|
192
|
-
return self._input("Vector")
|
|
193
|
-
|
|
194
|
-
@property
|
|
195
|
-
def o_x(self) -> NodeSocket:
|
|
196
|
-
"""Output socket: X"""
|
|
197
|
-
return self._output("X")
|
|
198
|
-
|
|
199
|
-
@property
|
|
200
|
-
def o_y(self) -> NodeSocket:
|
|
201
|
-
"""Output socket: Y"""
|
|
202
|
-
return self._output("Y")
|
|
203
|
-
|
|
204
|
-
@property
|
|
205
|
-
def o_z(self) -> NodeSocket:
|
|
206
|
-
"""Output socket: Z"""
|
|
207
|
-
return self._output("Z")
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
class CombineXYZ(NodeBuilder):
|
|
211
|
-
"""Create a vector from X, Y, and Z components"""
|
|
212
|
-
|
|
213
|
-
name = "ShaderNodeCombineXYZ"
|
|
214
|
-
node: bpy.types.ShaderNodeCombineXYZ # type: ignore
|
|
215
|
-
|
|
216
|
-
def __init__(
|
|
217
|
-
self,
|
|
218
|
-
x: float | LINKABLE = 0.0,
|
|
219
|
-
y: float | LINKABLE = 0.0,
|
|
220
|
-
z: float | LINKABLE = 0.0,
|
|
221
|
-
):
|
|
222
|
-
super().__init__()
|
|
223
|
-
self._establish_links(**{"X": x, "Y": y, "Z": z})
|
|
224
|
-
|
|
225
|
-
@property
|
|
226
|
-
def o_vector(self) -> NodeSocket:
|
|
227
|
-
"""Output socket: Vector"""
|
|
228
|
-
return self._output("Vector")
|
|
229
|
-
|
|
230
|
-
@property
|
|
231
|
-
def i_x(self) -> NodeSocket:
|
|
232
|
-
"""Input socket: X"""
|
|
233
|
-
return self._input("X")
|
|
234
|
-
|
|
235
|
-
@property
|
|
236
|
-
def i_y(self) -> NodeSocket:
|
|
237
|
-
"""Input socket: Y"""
|
|
238
|
-
return self._input("Y")
|
|
239
|
-
|
|
240
|
-
@property
|
|
241
|
-
def i_z(self) -> NodeSocket:
|
|
242
|
-
"""Input socket: Z"""
|
|
243
|
-
return self._input("Z")
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
_MIX_VALUE_DATA_TYPES = Literal["FLOAT", "VECTOR", "COLOR", "ROTATION"]
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class Mix(NodeBuilder):
|
|
250
|
-
"""Mix values by a factor"""
|
|
251
|
-
|
|
252
|
-
name = "ShaderNodeMix"
|
|
253
|
-
node: bpy.types.ShaderNodeMix # type: ignore
|
|
254
|
-
|
|
255
|
-
def __init__(
|
|
256
|
-
self,
|
|
257
|
-
data_type: _MIX_VALUE_DATA_TYPES = "FLOAT",
|
|
258
|
-
**kwargs,
|
|
259
|
-
):
|
|
260
|
-
super().__init__()
|
|
261
|
-
self._default_input_id = f"A_{data_type.title()}"
|
|
262
|
-
self._default_output_id = f"Result_{data_type.title()}"
|
|
263
|
-
self.node.data_type = "RGBA" if data_type == "COLOR" else data_type
|
|
264
|
-
key_args = {}
|
|
265
|
-
key_args.update(kwargs)
|
|
266
|
-
self._establish_links(**key_args)
|
|
267
|
-
|
|
268
|
-
@property
|
|
269
|
-
def data_type(self) -> str:
|
|
270
|
-
return self.node.data_type
|
|
271
|
-
|
|
272
|
-
@data_type.setter
|
|
273
|
-
def data_type(self, value: _MIX_VALUE_DATA_TYPES):
|
|
274
|
-
self.node.data_type = value # type: ignore
|
|
275
|
-
|
|
276
|
-
@property
|
|
277
|
-
def factor_mode(self) -> Literal["UNIFORM", "NON_UNIFORM"]:
|
|
278
|
-
return self.node.factor_mode
|
|
279
|
-
|
|
280
|
-
@factor_mode.setter
|
|
281
|
-
def factor_mode(self, value: Literal["NON_UNIFORM", "UNIFORM"]):
|
|
282
|
-
self.node.factor_mode = value
|
|
283
|
-
|
|
284
|
-
@property
|
|
285
|
-
def o_result(self) -> NodeSocket:
|
|
286
|
-
"""Output socket: Result"""
|
|
287
|
-
return self._default_output_socket
|
|
288
|
-
|
|
289
|
-
@property
|
|
290
|
-
def i_factor(self) -> NodeSocket:
|
|
291
|
-
"""Input socket: Factor"""
|
|
292
|
-
match self.data_type:
|
|
293
|
-
case "FLOAT":
|
|
294
|
-
name = "Factor_Float"
|
|
295
|
-
case "VECTOR":
|
|
296
|
-
name = (
|
|
297
|
-
"Factor_Float" if self.factor_mode == "UNIFORM" else "Factor_Vector"
|
|
298
|
-
)
|
|
299
|
-
case "RGBA":
|
|
300
|
-
name = "Factor_Color"
|
|
301
|
-
case "ROTATION":
|
|
302
|
-
name = "Factor_Rotation"
|
|
303
|
-
case _:
|
|
304
|
-
raise ValueError(f"Unsupported data type: {self.data_type}")
|
|
305
|
-
|
|
306
|
-
idx = self._input_idx(name)
|
|
307
|
-
return self.node.inputs[idx]
|
|
308
|
-
|
|
309
|
-
@property
|
|
310
|
-
def i_value_a(self) -> NodeSocket:
|
|
311
|
-
"""Input socket: Value A"""
|
|
312
|
-
type_name = "Color" if self.data_type == "RGBA" else self.data_type
|
|
313
|
-
name = f"A_{type_name}"
|
|
314
|
-
idx = self._input_idx(name)
|
|
315
|
-
return self.node.inputs[idx]
|
|
316
|
-
|
|
317
|
-
@property
|
|
318
|
-
def i_value_b(self) -> NodeSocket:
|
|
319
|
-
"""Input socket: Value B"""
|
|
320
|
-
type_name = "Color" if self.data_type == "RGBA" else self.data_type
|
|
321
|
-
name = f"B_{type_name}"
|
|
322
|
-
idx = self._input_idx(name)
|
|
323
|
-
return self.node.inputs[idx]
|
|
324
|
-
|
|
325
|
-
@classmethod
|
|
326
|
-
def float(
|
|
327
|
-
cls,
|
|
328
|
-
factor: float | LINKABLE = 0.5,
|
|
329
|
-
a: float | LINKABLE = 0.0,
|
|
330
|
-
b: float | LINKABLE = 0.0,
|
|
331
|
-
clamp_factor: bool | LINKABLE = True,
|
|
332
|
-
) -> Mix:
|
|
333
|
-
builder = cls(
|
|
334
|
-
Factor_Float=factor,
|
|
335
|
-
A_Float=a,
|
|
336
|
-
B_Float=b,
|
|
337
|
-
data_type="COLOR",
|
|
338
|
-
)
|
|
339
|
-
builder.node.clamp_factor = clamp_factor
|
|
340
|
-
return builder
|
|
341
|
-
|
|
342
|
-
@classmethod
|
|
343
|
-
def vector(
|
|
344
|
-
cls,
|
|
345
|
-
factor: float | LINKABLE = 0.5,
|
|
346
|
-
a: tuple[float, float, float] | list[float] | LINKABLE = (0.0, 0.0, 0.0),
|
|
347
|
-
b: tuple[float, float, float] | list[float] | LINKABLE = (1.0, 1.0, 1.0),
|
|
348
|
-
clamp_factor: bool = True,
|
|
349
|
-
factor_mode: Literal["UNIFORM", "NON_UNIFORM"] = "UNIFORM",
|
|
350
|
-
) -> Mix:
|
|
351
|
-
match factor_mode:
|
|
352
|
-
case "UNIFORM":
|
|
353
|
-
builder = cls(
|
|
354
|
-
Factor_Float=factor,
|
|
355
|
-
A_Vector=a,
|
|
356
|
-
B_Vector=b,
|
|
357
|
-
data_type="VECTOR",
|
|
358
|
-
)
|
|
359
|
-
case "NON_UNIFORM":
|
|
360
|
-
builder = cls(
|
|
361
|
-
Factor_Vector=factor,
|
|
362
|
-
A_Vector=a,
|
|
363
|
-
B_Vector=b,
|
|
364
|
-
data_type="VECTOR",
|
|
365
|
-
)
|
|
366
|
-
|
|
367
|
-
builder.node.clamp_factor = clamp_factor
|
|
368
|
-
return builder
|
|
369
|
-
|
|
370
|
-
@classmethod
|
|
371
|
-
def color(
|
|
372
|
-
cls,
|
|
373
|
-
factor: float | LINKABLE = 0.5,
|
|
374
|
-
a: tuple[float, float, float] | list[float] | LINKABLE = (0.0, 0.0, 0.0),
|
|
375
|
-
b: tuple[float, float, float] | list[float] | LINKABLE = (1.0, 1.0, 1.0),
|
|
376
|
-
blend_type: str = "add",
|
|
377
|
-
clamp_factor: bool = True,
|
|
378
|
-
clamp_result: bool = True,
|
|
379
|
-
) -> Mix:
|
|
380
|
-
builder = cls(
|
|
381
|
-
Factor_Float=factor,
|
|
382
|
-
A_Color=a,
|
|
383
|
-
B_Color=b,
|
|
384
|
-
data_type="COLOR",
|
|
385
|
-
)
|
|
386
|
-
builder.node.blend_type = blend_type.capitalize()
|
|
387
|
-
builder.node.clamp_factor = clamp_factor
|
|
388
|
-
builder.node.clamp_result = clamp_result
|
|
389
|
-
return builder
|
|
390
|
-
|
|
391
|
-
@classmethod
|
|
392
|
-
def rotation(
|
|
393
|
-
cls,
|
|
394
|
-
a: tuple[float, float, float, float] | list[float] | LINKABLE | None = None,
|
|
395
|
-
b: tuple[float, float, float, float] | list[float] | LINKABLE | None = None,
|
|
396
|
-
factor: float | LINKABLE = 0.5,
|
|
397
|
-
clamp_factor: bool = True,
|
|
398
|
-
) -> Mix:
|
|
399
|
-
builder = cls(
|
|
400
|
-
Factor_Float=factor,
|
|
401
|
-
A_Rotation=a,
|
|
402
|
-
B_Rotation=b,
|
|
403
|
-
data_type="ROTATION",
|
|
404
|
-
)
|
|
405
|
-
builder.node.clamp_factor = clamp_factor
|
|
406
|
-
return builder
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
_AttributeDataTypes = Literal[
|
|
410
|
-
"FLOAT", "INT", "BOOLEAN", "VECTOR", "RGBA", "ROTATION", "MATRIX"
|
|
411
|
-
]
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
class CaptureAttribute(NodeBuilder):
|
|
415
|
-
"""Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation"""
|
|
416
|
-
|
|
417
|
-
name = "GeometryNodeCaptureAttribute"
|
|
418
|
-
node: bpy.types.GeometryNodeCaptureAttribute
|
|
419
|
-
|
|
420
|
-
def __init__(
|
|
421
|
-
self,
|
|
422
|
-
geometry: LINKABLE = None,
|
|
423
|
-
domain: _AttributeDomains = "POINT",
|
|
424
|
-
**kwargs,
|
|
425
|
-
):
|
|
426
|
-
super().__init__()
|
|
427
|
-
key_args = {"Geometry": geometry}
|
|
428
|
-
key_args.update(kwargs)
|
|
429
|
-
self.domain = domain
|
|
430
|
-
self._establish_links(**key_args)
|
|
431
|
-
|
|
432
|
-
def capture(
|
|
433
|
-
self,
|
|
434
|
-
value: LINKABLE,
|
|
435
|
-
name: str | None = None,
|
|
436
|
-
data_type: _AttributeDataTypes | None = None,
|
|
437
|
-
):
|
|
438
|
-
"""Capture the value to store in the attribute"""
|
|
439
|
-
source = source_socket(value)
|
|
440
|
-
if name is None:
|
|
441
|
-
name = source.name
|
|
442
|
-
if data_type is None:
|
|
443
|
-
data_type = source.type # type: ignore
|
|
444
|
-
|
|
445
|
-
item = self._add_item(name, data_type) # type: ignore
|
|
446
|
-
self._establish_links(**{item.name: value})
|
|
447
|
-
return SocketLinker(self.node.outputs[item.name])
|
|
448
|
-
|
|
449
|
-
def _add_item(
|
|
450
|
-
self, name: str, data_type: _AttributeDataTypes = "FLOAT"
|
|
451
|
-
) -> bpy.types.NodeGeometryCaptureAttributeItem:
|
|
452
|
-
"""Add a new output socket to capture additional attributes"""
|
|
453
|
-
return self._items.new(data_type, name)
|
|
454
|
-
|
|
455
|
-
@property
|
|
456
|
-
def _items(self) -> bpy.types.NodeGeometryCaptureAttributeItems:
|
|
457
|
-
return self.node.capture_items
|
|
458
|
-
|
|
459
|
-
@property
|
|
460
|
-
def i_geometry(self) -> NodeSocket:
|
|
461
|
-
"""Input socket: Geometry"""
|
|
462
|
-
return self._input("Geometry")
|
|
463
|
-
|
|
464
|
-
@property
|
|
465
|
-
def o_geometry(self) -> NodeSocket:
|
|
466
|
-
"""Output socket: Geometry"""
|
|
467
|
-
return self._output("Geometry")
|
|
468
|
-
|
|
469
|
-
@property
|
|
470
|
-
def domain(
|
|
471
|
-
self,
|
|
472
|
-
) -> _AttributeDomains:
|
|
473
|
-
return self.node.domain
|
|
474
|
-
|
|
475
|
-
@domain.setter
|
|
476
|
-
def domain(
|
|
477
|
-
self,
|
|
478
|
-
value: _AttributeDomains,
|
|
479
|
-
):
|
|
480
|
-
self.node.domain = value
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
class JoinGeometry(NodeBuilder):
|
|
484
|
-
"""Merge separately generated geometries into a single one"""
|
|
485
|
-
|
|
486
|
-
name = "GeometryNodeJoinGeometry"
|
|
487
|
-
node: bpy.types.GeometryNodeJoinGeometry
|
|
488
|
-
|
|
489
|
-
def __init__(self, geometry: NodeBuilder | Iterable[NodeBuilder] | None = None):
|
|
490
|
-
super().__init__()
|
|
491
|
-
if geometry is None:
|
|
492
|
-
return
|
|
493
|
-
elif isinstance(geometry, NodeBuilder):
|
|
494
|
-
geometry = [geometry]
|
|
495
|
-
for source in reversed(geometry):
|
|
496
|
-
self.link_from(source, self)
|
|
497
|
-
|
|
498
|
-
@property
|
|
499
|
-
def i_geometry(self) -> NodeSocket:
|
|
500
|
-
"""Input socket: Geometry"""
|
|
501
|
-
return self._input("Geometry")
|
|
502
|
-
|
|
503
|
-
@property
|
|
504
|
-
def o_geometry(self) -> NodeSocket:
|
|
505
|
-
"""Output socket: Geometry"""
|
|
506
|
-
return self._output("Geometry")
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
class Math(NodeBuilder):
|
|
510
|
-
"""Perform math operations"""
|
|
511
|
-
|
|
512
|
-
name = "ShaderNodeMath"
|
|
513
|
-
node: bpy.types.ShaderNodeMath # type: ignore
|
|
514
|
-
|
|
515
|
-
def __init__(
|
|
516
|
-
self,
|
|
517
|
-
operation: types.NodeMathItems = "ADD",
|
|
518
|
-
use_clamp: bool = False,
|
|
519
|
-
**kwargs,
|
|
520
|
-
):
|
|
521
|
-
super().__init__()
|
|
522
|
-
self.operation = operation
|
|
523
|
-
self.use_clamp = use_clamp
|
|
524
|
-
self._establish_links(**kwargs)
|
|
525
|
-
|
|
526
|
-
@property
|
|
527
|
-
def operation(self) -> types.NodeMathItems:
|
|
528
|
-
return self.node.operation
|
|
529
|
-
|
|
530
|
-
@operation.setter
|
|
531
|
-
def operation(self, value: types.NodeMathItems):
|
|
532
|
-
self.node.operation = value
|
|
533
|
-
|
|
534
|
-
@property
|
|
535
|
-
def use_clamp(self) -> bool:
|
|
536
|
-
return self.node.use_clamp
|
|
537
|
-
|
|
538
|
-
@use_clamp.setter
|
|
539
|
-
def use_clamp(self, value: bool):
|
|
540
|
-
self.node.use_clamp = value
|
|
541
|
-
|
|
542
|
-
@property
|
|
543
|
-
def o_value(self) -> NodeSocketFloat:
|
|
544
|
-
return self._output("Value") # type: ignore
|
|
545
|
-
|
|
546
|
-
def _input(self, identifier: str) -> NodeSocketFloat:
|
|
547
|
-
return self._input(identifier)
|
|
548
|
-
|
|
549
|
-
@property
|
|
550
|
-
def i_value(self) -> NodeSocketFloat:
|
|
551
|
-
return self._input("Value")
|
|
552
|
-
|
|
553
|
-
@property
|
|
554
|
-
def i_value_001(self) -> NodeSocketFloat:
|
|
555
|
-
return self._input("Value_001")
|
|
556
|
-
|
|
557
|
-
@property
|
|
558
|
-
def i_value_002(self) -> NodeSocketFloat:
|
|
559
|
-
return self._input("Value_002")
|
|
560
|
-
|
|
561
|
-
@classmethod
|
|
562
|
-
def add(
|
|
563
|
-
cls,
|
|
564
|
-
a: float | LINKABLE = 0.5,
|
|
565
|
-
b: float | LINKABLE = 0.5,
|
|
566
|
-
) -> "Math":
|
|
567
|
-
"""Create Math with operation of `a + b`."""
|
|
568
|
-
return cls(operation="ADD", Value=a, Value_001=b)
|
|
569
|
-
|
|
570
|
-
@classmethod
|
|
571
|
-
def subtract(
|
|
572
|
-
cls,
|
|
573
|
-
a: float | LINKABLE = 0.5,
|
|
574
|
-
b: float | LINKABLE = 0.5,
|
|
575
|
-
) -> "Math":
|
|
576
|
-
"""Create Math with operation of `a - b`."""
|
|
577
|
-
return cls(operation="SUBTRACT", Value=a, Value_001=b)
|
|
578
|
-
|
|
579
|
-
@classmethod
|
|
580
|
-
def multiply(
|
|
581
|
-
cls,
|
|
582
|
-
a: float | LINKABLE = 0.5,
|
|
583
|
-
b: float | LINKABLE = 0.5,
|
|
584
|
-
) -> "Math":
|
|
585
|
-
"""Create Math with operation of `a * b`."""
|
|
586
|
-
return cls(operation="MULTIPLY", Value=a, Value_001=b)
|
|
587
|
-
|
|
588
|
-
@classmethod
|
|
589
|
-
def divide(
|
|
590
|
-
cls,
|
|
591
|
-
a: float | LINKABLE = 0.5,
|
|
592
|
-
b: float | LINKABLE = 0.5,
|
|
593
|
-
) -> "Math":
|
|
594
|
-
"""Create Math with operation of `a / b`."""
|
|
595
|
-
return cls(operation="DIVIDE", Value=a, Value_001=b)
|
|
596
|
-
|
|
597
|
-
@classmethod
|
|
598
|
-
def multiply_add(
|
|
599
|
-
cls,
|
|
600
|
-
a: float | LINKABLE = 0.5,
|
|
601
|
-
b: float | LINKABLE = 0.5,
|
|
602
|
-
c: float | LINKABLE = 0.5,
|
|
603
|
-
) -> "Math":
|
|
604
|
-
"""Create Math with operation `a * b + c`."""
|
|
605
|
-
return cls(operation="MULTIPLY_ADD", Value=a, Value_001=b, value_002=c)
|
|
606
|
-
|
|
607
|
-
@classmethod
|
|
608
|
-
def power(
|
|
609
|
-
cls,
|
|
610
|
-
base: float | LINKABLE = 0.5,
|
|
611
|
-
exponent: float | LINKABLE = 0.5,
|
|
612
|
-
) -> "Math":
|
|
613
|
-
"""Create Math with operation `base ** exponent`."""
|
|
614
|
-
return cls(operation="POWER", Value=base, Value_001=exponent)
|
|
615
|
-
|
|
616
|
-
@classmethod
|
|
617
|
-
def logarithm(
|
|
618
|
-
cls,
|
|
619
|
-
value: float | LINKABLE = 0.5,
|
|
620
|
-
base: float | LINKABLE = 0.5,
|
|
621
|
-
) -> "Math":
|
|
622
|
-
"""Create Math with operation `log(value, base)`."""
|
|
623
|
-
return cls(operation="LOGARITHM", Value=value, Value_001=base)
|
|
624
|
-
|
|
625
|
-
@classmethod
|
|
626
|
-
def sqrt(
|
|
627
|
-
cls,
|
|
628
|
-
value: float | LINKABLE = 0.5,
|
|
629
|
-
) -> "Math":
|
|
630
|
-
"""Create Math with operation `sqrt(value)`."""
|
|
631
|
-
return cls(operation="SQRT", Value=value)
|
|
632
|
-
|
|
633
|
-
@classmethod
|
|
634
|
-
def inverse_sqrt(
|
|
635
|
-
cls,
|
|
636
|
-
value: float | LINKABLE = 0.5,
|
|
637
|
-
) -> "Math":
|
|
638
|
-
"""Create Math with operation `inverse_sqrt(value)`."""
|
|
639
|
-
return cls(operation="INVERSE_SQRT", Value=value)
|
|
640
|
-
|
|
641
|
-
@classmethod
|
|
642
|
-
def absolute(
|
|
643
|
-
cls,
|
|
644
|
-
value: float | LINKABLE = 0.5,
|
|
645
|
-
) -> "Math":
|
|
646
|
-
"""Create Math with operation `abs(value)`."""
|
|
647
|
-
return cls(operation="ABSOLUTE", Value=value)
|
|
648
|
-
|
|
649
|
-
@classmethod
|
|
650
|
-
def exponent(
|
|
651
|
-
cls,
|
|
652
|
-
value: float | LINKABLE = 0.5,
|
|
653
|
-
) -> "Math":
|
|
654
|
-
"""Create Math with operation `exp(value)`."""
|
|
655
|
-
return cls(operation="EXPONENT", Value=value)
|
|
656
|
-
|
|
657
|
-
@classmethod
|
|
658
|
-
def minimum(
|
|
659
|
-
cls,
|
|
660
|
-
a: float | LINKABLE = 0.5,
|
|
661
|
-
b: float | LINKABLE = 0.5,
|
|
662
|
-
) -> "Math":
|
|
663
|
-
"""Create Math with operation `min(a, b)`."""
|
|
664
|
-
return cls(operation="MINIMUM", Value=a, Value_001=b)
|
|
665
|
-
|
|
666
|
-
@classmethod
|
|
667
|
-
def maximum(
|
|
668
|
-
cls,
|
|
669
|
-
a: float | LINKABLE = 0.5,
|
|
670
|
-
b: float | LINKABLE = 0.5,
|
|
671
|
-
) -> "Math":
|
|
672
|
-
"""Create Math with operation `max(a, b)`."""
|
|
673
|
-
return cls(operation="MAXIMUM", Value=a, Value_001=b)
|
|
674
|
-
|
|
675
|
-
@classmethod
|
|
676
|
-
def less_than(
|
|
677
|
-
cls,
|
|
678
|
-
value: float | LINKABLE = 0.5,
|
|
679
|
-
threshold: float | LINKABLE = 0.5,
|
|
680
|
-
) -> "Math":
|
|
681
|
-
"""Create Math with operation `value < threshold` returning 1 or 0."""
|
|
682
|
-
return cls(operation="LESS_THAN", Value=value, Value_001=threshold)
|
|
683
|
-
|
|
684
|
-
@classmethod
|
|
685
|
-
def greater_than(
|
|
686
|
-
cls,
|
|
687
|
-
value: float | LINKABLE = 0.5,
|
|
688
|
-
threshold: float | LINKABLE = 0.5,
|
|
689
|
-
) -> "Math":
|
|
690
|
-
"""Create Math with operation `value > threshold` returning 1 or 0."""
|
|
691
|
-
return cls(operation="GREATER_THAN", Value=value, Value_001=threshold)
|
|
692
|
-
|
|
693
|
-
@classmethod
|
|
694
|
-
def sign(
|
|
695
|
-
cls,
|
|
696
|
-
value: float | LINKABLE = 0.5,
|
|
697
|
-
) -> "Math":
|
|
698
|
-
"""Create Math with operation `sign(value)` returning -1, 0, or 1."""
|
|
699
|
-
return cls(operation="SIGN", Value=value)
|
|
700
|
-
|
|
701
|
-
@classmethod
|
|
702
|
-
def compare(
|
|
703
|
-
cls,
|
|
704
|
-
a: float | LINKABLE = 0.5,
|
|
705
|
-
b: float | LINKABLE = 0.5,
|
|
706
|
-
epsilon: float | LINKABLE = 0.5,
|
|
707
|
-
) -> "Math":
|
|
708
|
-
"""Create Math with operation `compare(a, b, epsilon)` returning -1, 0, or 1."""
|
|
709
|
-
return cls(operation="COMPARE", Value=a, Value_001=b, value_002=epsilon)
|
|
710
|
-
|
|
711
|
-
@classmethod
|
|
712
|
-
def smooth_min(
|
|
713
|
-
cls,
|
|
714
|
-
a: float | LINKABLE = 0.5,
|
|
715
|
-
b: float | LINKABLE = 0.5,
|
|
716
|
-
distance: float | LINKABLE = 0.5,
|
|
717
|
-
) -> "Math":
|
|
718
|
-
"""Create Math with operation `smooth_min(a, b, distance)`."""
|
|
719
|
-
return cls(operation="SMOOTH_MIN", Value=a, Value_001=b, value_002=distance)
|
|
720
|
-
|
|
721
|
-
@classmethod
|
|
722
|
-
def smooth_max_(
|
|
723
|
-
cls,
|
|
724
|
-
a: float | LINKABLE = 0.5,
|
|
725
|
-
b: float | LINKABLE = 0.5,
|
|
726
|
-
distance: float | LINKABLE = 0.5,
|
|
727
|
-
) -> "Math":
|
|
728
|
-
"""Create Math with operation `smooth_max(a, b, distance)`."""
|
|
729
|
-
return cls(operation="SMOOTH_MAX", Value=a, Value_001=b, value_002=distance)
|
|
730
|
-
|
|
731
|
-
@classmethod
|
|
732
|
-
def round(
|
|
733
|
-
cls,
|
|
734
|
-
value: float | LINKABLE = 0.5,
|
|
735
|
-
) -> "Math":
|
|
736
|
-
"""Round A to the nearest integer. Round up if 0.5 or greater."""
|
|
737
|
-
return cls(operation="ROUND", Value=value)
|
|
738
|
-
|
|
739
|
-
@classmethod
|
|
740
|
-
def floor(
|
|
741
|
-
cls,
|
|
742
|
-
value: float | LINKABLE = 0.5,
|
|
743
|
-
) -> "Math":
|
|
744
|
-
"""The largest integer smaller than or equal to `value`"""
|
|
745
|
-
return cls(operation="FLOOR", Value=value)
|
|
746
|
-
|
|
747
|
-
@classmethod
|
|
748
|
-
def ceil(
|
|
749
|
-
cls,
|
|
750
|
-
value: float | LINKABLE = 0.5,
|
|
751
|
-
) -> "Math":
|
|
752
|
-
"""The smallest integer greater than or equal to `value`"""
|
|
753
|
-
return cls(operation="CEIL", Value=value)
|
|
754
|
-
|
|
755
|
-
@classmethod
|
|
756
|
-
def truncate(
|
|
757
|
-
cls,
|
|
758
|
-
value: float | LINKABLE = 0.5,
|
|
759
|
-
) -> "Math":
|
|
760
|
-
"""The integer part of `value` removing the fractional part"""
|
|
761
|
-
return cls(operation="TRUNC", Value=value)
|
|
762
|
-
|
|
763
|
-
@classmethod
|
|
764
|
-
def fraction(
|
|
765
|
-
cls,
|
|
766
|
-
value: float | LINKABLE = 0.5,
|
|
767
|
-
) -> "Math":
|
|
768
|
-
"""The fractional part of `value`"""
|
|
769
|
-
return cls(operation="FRACT", Value=value)
|
|
770
|
-
|
|
771
|
-
@classmethod
|
|
772
|
-
def truncated_modulo(
|
|
773
|
-
cls,
|
|
774
|
-
a: float | LINKABLE = 0.5,
|
|
775
|
-
b: float | LINKABLE = 0.5,
|
|
776
|
-
) -> "Math":
|
|
777
|
-
"""The remained of truncated division using fmod(a, b)"""
|
|
778
|
-
return cls(operation="MODULO", Value=a, Value_001=b)
|
|
779
|
-
|
|
780
|
-
@classmethod
|
|
781
|
-
def floored_modulo(
|
|
782
|
-
cls,
|
|
783
|
-
a: float | LINKABLE = 0.5,
|
|
784
|
-
b: float | LINKABLE = 0.5,
|
|
785
|
-
) -> "Math":
|
|
786
|
-
"""The remained of floored division"""
|
|
787
|
-
return cls(operation="FLOORED_MODULO", Value=a, Value_001=b)
|
|
788
|
-
|
|
789
|
-
@classmethod
|
|
790
|
-
def wrap(
|
|
791
|
-
cls,
|
|
792
|
-
value: float | LINKABLE = 0.5,
|
|
793
|
-
max: float | LINKABLE = 0.5,
|
|
794
|
-
min: float | LINKABLE = 0.5,
|
|
795
|
-
) -> "Math":
|
|
796
|
-
"""Wrap value to range, wrap(value, max, min)"""
|
|
797
|
-
return cls(operation="WRAP", Value=value, Value_001=max, value_002=min)
|
|
798
|
-
|
|
799
|
-
@classmethod
|
|
800
|
-
def snap(
|
|
801
|
-
cls,
|
|
802
|
-
value: float | LINKABLE = 0.5,
|
|
803
|
-
increment: float | LINKABLE = 0.5,
|
|
804
|
-
) -> "Math":
|
|
805
|
-
"""Snap to increment of `snap(value, increment)`"""
|
|
806
|
-
return cls(operation="SNAP", Value=value, Value_001=increment)
|
|
807
|
-
|
|
808
|
-
@classmethod
|
|
809
|
-
def ping_pong(
|
|
810
|
-
cls,
|
|
811
|
-
value: float | LINKABLE = 0.5,
|
|
812
|
-
scale: float | LINKABLE = 0.5,
|
|
813
|
-
) -> "Math":
|
|
814
|
-
"""Wraps a value and reverses every other cycle"""
|
|
815
|
-
return cls(operation="PINGPONG", Value=value, Value_001=scale)
|
|
816
|
-
|
|
817
|
-
@classmethod
|
|
818
|
-
def sine(
|
|
819
|
-
cls,
|
|
820
|
-
value: float | LINKABLE = 0.5,
|
|
821
|
-
) -> "Math":
|
|
822
|
-
"""Create Math with operation 'sin(value)'."""
|
|
823
|
-
return cls(operation="SINE", Value=value)
|
|
824
|
-
|
|
825
|
-
@classmethod
|
|
826
|
-
def cosine(
|
|
827
|
-
cls,
|
|
828
|
-
value: float | LINKABLE = 0.5,
|
|
829
|
-
) -> "Math":
|
|
830
|
-
"""Create Math with operation 'cos(value)'."""
|
|
831
|
-
return cls(operation="COSINE", Value=value)
|
|
832
|
-
|
|
833
|
-
@classmethod
|
|
834
|
-
def tangent(
|
|
835
|
-
cls,
|
|
836
|
-
value: float | LINKABLE = 0.5,
|
|
837
|
-
) -> "Math":
|
|
838
|
-
"""Create Math with operation 'tan(value)'."""
|
|
839
|
-
return cls(operation="TANGENT", Value=value)
|
|
840
|
-
|
|
841
|
-
@classmethod
|
|
842
|
-
def arcsine(
|
|
843
|
-
cls,
|
|
844
|
-
value: float | LINKABLE = 0.5,
|
|
845
|
-
) -> "Math":
|
|
846
|
-
"""Create Math with operation `arcsin(value)'."""
|
|
847
|
-
return cls(operation="ARCSINE", Value=value)
|
|
848
|
-
|
|
849
|
-
@classmethod
|
|
850
|
-
def arccosine(
|
|
851
|
-
cls,
|
|
852
|
-
value: float | LINKABLE = 0.5,
|
|
853
|
-
) -> "Math":
|
|
854
|
-
"""Create Math with operation 'arccos(value)'."""
|
|
855
|
-
return cls(operation="ARCCOSINE", Value=value)
|
|
856
|
-
|
|
857
|
-
@classmethod
|
|
858
|
-
def arctangent(
|
|
859
|
-
cls,
|
|
860
|
-
value: float | LINKABLE = 0.5,
|
|
861
|
-
) -> "Math":
|
|
862
|
-
"""Create Math with operation 'arctan(value)'."""
|
|
863
|
-
return cls(operation="ARCTANGENT", Value=value)
|
|
864
|
-
|
|
865
|
-
@classmethod
|
|
866
|
-
def arctan2(
|
|
867
|
-
cls,
|
|
868
|
-
a: float | LINKABLE = 0.5,
|
|
869
|
-
b: float | LINKABLE = 0.5,
|
|
870
|
-
) -> "Math":
|
|
871
|
-
"""Create Math with operation 'arctan(a / b)'."""
|
|
872
|
-
return cls(operation="ARCTAN2", Value=a, Value_001=b)
|
|
873
|
-
|
|
874
|
-
@classmethod
|
|
875
|
-
def sinh(
|
|
876
|
-
cls,
|
|
877
|
-
value: float | LINKABLE = 0.5,
|
|
878
|
-
) -> "Math":
|
|
879
|
-
"""Create Math with operation `sinh(value)`."""
|
|
880
|
-
return cls(operation="SINH", Value=value)
|
|
881
|
-
|
|
882
|
-
@classmethod
|
|
883
|
-
def cosh(
|
|
884
|
-
cls,
|
|
885
|
-
value: float | LINKABLE = 0.5,
|
|
886
|
-
) -> "Math":
|
|
887
|
-
"""Create Math with operation `cosh(value)`."""
|
|
888
|
-
return cls(operation="COSH", Value=value)
|
|
889
|
-
|
|
890
|
-
@classmethod
|
|
891
|
-
def tanh(
|
|
892
|
-
cls,
|
|
893
|
-
value: float | LINKABLE = 0.5,
|
|
894
|
-
) -> "Math":
|
|
895
|
-
"""Create Math with operation `tanh(value)`."""
|
|
896
|
-
return cls(operation="TANH", Value=value)
|
|
897
|
-
|
|
898
|
-
@classmethod
|
|
899
|
-
def radians(
|
|
900
|
-
cls,
|
|
901
|
-
degrees: float | LINKABLE = 0.5,
|
|
902
|
-
) -> "Math":
|
|
903
|
-
"""Create Math with operation `radians(degrees)`."""
|
|
904
|
-
return cls(operation="RADIANS", Value=degrees)
|
|
905
|
-
|
|
906
|
-
@classmethod
|
|
907
|
-
def degrees(
|
|
908
|
-
cls,
|
|
909
|
-
radians: float | LINKABLE = 0.5,
|
|
910
|
-
) -> "Math":
|
|
911
|
-
"""Create Math with operation 'To Degrees'."""
|
|
912
|
-
return cls(operation="DEGREES", Value=radians)
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
class BooleanMath(NodeBuilder):
|
|
916
|
-
"""Boolean Math node"""
|
|
917
|
-
|
|
918
|
-
name = "FunctionNodeBooleanMath"
|
|
919
|
-
node: bpy.types.FunctionNodeBooleanMath
|
|
920
|
-
|
|
921
|
-
def __init__(self, operation: types.NodeBooleanMathItems = "AND", **kwargs):
|
|
922
|
-
super().__init__()
|
|
923
|
-
self.operator = operation
|
|
924
|
-
self._establish_links(**kwargs)
|
|
925
|
-
|
|
926
|
-
@property
|
|
927
|
-
def operation(self) -> types.NodeBooleanMathItems:
|
|
928
|
-
return self.node.operation
|
|
929
|
-
|
|
930
|
-
@operation.setter
|
|
931
|
-
def operation(self, value: types.NodeBooleanMathItems):
|
|
932
|
-
self.node.operation = value
|
|
933
|
-
|
|
934
|
-
@property
|
|
935
|
-
def i_boolean(self) -> bpy.types.NodeSocketBool:
|
|
936
|
-
return self._input("Boolean") # type: ignore
|
|
937
|
-
|
|
938
|
-
@property
|
|
939
|
-
def i_boolean_001(self) -> bpy.types.NodeSocketBool:
|
|
940
|
-
return self._input("Boolean_001") # type: ignore
|
|
941
|
-
|
|
942
|
-
@property
|
|
943
|
-
def o_boolean(self) -> bpy.types.NodeSocketBool:
|
|
944
|
-
return self._output("Boolean") # type: ignore
|
|
945
|
-
|
|
946
|
-
@classmethod
|
|
947
|
-
def l_and(
|
|
948
|
-
cls,
|
|
949
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
950
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
951
|
-
) -> "BooleanMath":
|
|
952
|
-
"""Create Boolean Math with operation 'AND'."""
|
|
953
|
-
return cls(operation="AND", Boolean=boolean, Boolean_001=boolean_001)
|
|
954
|
-
|
|
955
|
-
@classmethod
|
|
956
|
-
def l_or(
|
|
957
|
-
cls,
|
|
958
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
959
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
960
|
-
) -> "BooleanMath":
|
|
961
|
-
"""Create Boolean Math with operation 'OR'."""
|
|
962
|
-
return cls(operation="OR", Boolean=boolean, Boolean_001=boolean_001)
|
|
963
|
-
|
|
964
|
-
@classmethod
|
|
965
|
-
def l_not(cls, boolean: TYPE_INPUT_BOOLEAN = False) -> "BooleanMath":
|
|
966
|
-
"""Create Boolean Math with operation 'NOT'."""
|
|
967
|
-
return cls(operation="NOT", Boolean=boolean)
|
|
968
|
-
|
|
969
|
-
@classmethod
|
|
970
|
-
def l_not_and(
|
|
971
|
-
cls,
|
|
972
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
973
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
974
|
-
) -> "BooleanMath":
|
|
975
|
-
"""Create Boolean Math with operation 'NAND'."""
|
|
976
|
-
return cls(operation="NAND", Boolean=boolean, Boolean_001=boolean_001)
|
|
977
|
-
|
|
978
|
-
@classmethod
|
|
979
|
-
def l_nor(
|
|
980
|
-
cls,
|
|
981
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
982
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
983
|
-
) -> "BooleanMath":
|
|
984
|
-
"""Create Boolean Math with operation 'NOR'."""
|
|
985
|
-
return cls(operation="NOR", Boolean=boolean, Boolean_001=boolean_001)
|
|
986
|
-
|
|
987
|
-
@classmethod
|
|
988
|
-
def l_equal(
|
|
989
|
-
cls,
|
|
990
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
991
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
992
|
-
) -> "BooleanMath":
|
|
993
|
-
"""Create Boolean Math with operation 'XNOR'."""
|
|
994
|
-
return cls(operation="XNOR", Boolean=boolean, Boolean_001=boolean_001)
|
|
995
|
-
|
|
996
|
-
@classmethod
|
|
997
|
-
def l_not_equal(
|
|
998
|
-
cls,
|
|
999
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
1000
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
1001
|
-
) -> "BooleanMath":
|
|
1002
|
-
"""Create Boolean Math with operation 'XOR'."""
|
|
1003
|
-
return cls(operation="XOR", Boolean=boolean, Boolean_001=boolean_001)
|
|
1004
|
-
|
|
1005
|
-
@classmethod
|
|
1006
|
-
def l_imply(
|
|
1007
|
-
cls,
|
|
1008
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
1009
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
1010
|
-
) -> "BooleanMath":
|
|
1011
|
-
"""Create Boolean Math with operation 'IMPLY'."""
|
|
1012
|
-
return cls(operation="IMPLY", Boolean=boolean, Boolean_001=boolean_001)
|
|
1013
|
-
|
|
1014
|
-
@classmethod
|
|
1015
|
-
def l_subtract(
|
|
1016
|
-
cls,
|
|
1017
|
-
boolean: TYPE_INPUT_BOOLEAN = False,
|
|
1018
|
-
boolean_001: TYPE_INPUT_BOOLEAN = False,
|
|
1019
|
-
) -> "BooleanMath":
|
|
1020
|
-
"""Create Boolean Math with operation 'NIMPLY'."""
|
|
1021
|
-
return cls(operation="NIMPLY", Boolean=boolean, Boolean_001=boolean_001)
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
_VectorMathOperations = Literal[
|
|
1025
|
-
"ADD",
|
|
1026
|
-
"SUBTRACT",
|
|
1027
|
-
"MULTIPLY",
|
|
1028
|
-
"DIVIDE",
|
|
1029
|
-
"MULTIPLY_ADD",
|
|
1030
|
-
"CROSS_PRODUCT",
|
|
1031
|
-
"PROJECT",
|
|
1032
|
-
"REFLECT",
|
|
1033
|
-
"REFRACT",
|
|
1034
|
-
"FACEFORWARD",
|
|
1035
|
-
"DOT_PRODUCT",
|
|
1036
|
-
"DISTANCE",
|
|
1037
|
-
"LENGTH",
|
|
1038
|
-
"SCALE",
|
|
1039
|
-
"NORMALIZE",
|
|
1040
|
-
"ABSOLUTE",
|
|
1041
|
-
"POWER",
|
|
1042
|
-
"SIGN",
|
|
1043
|
-
"MINIMUM",
|
|
1044
|
-
"MAXIMUM",
|
|
1045
|
-
"FLOOR",
|
|
1046
|
-
"CEIL",
|
|
1047
|
-
"FRACTION",
|
|
1048
|
-
"MODULO",
|
|
1049
|
-
"WRAP",
|
|
1050
|
-
"SNAP",
|
|
1051
|
-
"SINE",
|
|
1052
|
-
"COSINE",
|
|
1053
|
-
"TANGENT",
|
|
1054
|
-
]
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
class VectorMath(NodeBuilder):
|
|
1058
|
-
"""Perform vector math operation"""
|
|
1059
|
-
|
|
1060
|
-
name = "ShaderNodeVectorMath"
|
|
1061
|
-
node: bpy.types.ShaderNodeVectorMath
|
|
1062
|
-
|
|
1063
|
-
def __init__(
|
|
1064
|
-
self,
|
|
1065
|
-
operation: _VectorMathOperations = "ADD",
|
|
1066
|
-
**kwargs,
|
|
1067
|
-
):
|
|
1068
|
-
super().__init__()
|
|
1069
|
-
self.operation = operation
|
|
1070
|
-
self._establish_links(**kwargs)
|
|
1071
|
-
|
|
1072
|
-
@property
|
|
1073
|
-
def i_vector(self) -> bpy.types.NodeSocketVector:
|
|
1074
|
-
"""Input socket: Vector"""
|
|
1075
|
-
return self._input("Vector")
|
|
1076
|
-
|
|
1077
|
-
@property
|
|
1078
|
-
def i_vector_001(self) -> bpy.types.NodeSocketVector:
|
|
1079
|
-
"""Input socket: Vector"""
|
|
1080
|
-
return self._input("Vector_001")
|
|
1081
|
-
|
|
1082
|
-
@property
|
|
1083
|
-
def o_vector(self) -> bpy.types.NodeSocketVector:
|
|
1084
|
-
"""Output socket: Vector"""
|
|
1085
|
-
if self.operation in {"DOT_PRODUCT", "DISTANCE", "LENGTH"}:
|
|
1086
|
-
raise RuntimeError(
|
|
1087
|
-
f"Output 'Vector' is not available for operation '{self.operation}'"
|
|
1088
|
-
)
|
|
1089
|
-
return self._output("Vector")
|
|
1090
|
-
|
|
1091
|
-
def o_value(self) -> bpy.types.NodeSocketFloat:
|
|
1092
|
-
"""Output socket: Value"""
|
|
1093
|
-
if self.operation not in {"DOT_PRODUCT", "DISTANCE", "LENGTH"}:
|
|
1094
|
-
raise RuntimeError(
|
|
1095
|
-
f"Output 'Value' is not available for operation '{self.operation}'"
|
|
1096
|
-
)
|
|
1097
|
-
return self._output("Value")
|
|
1098
|
-
|
|
1099
|
-
@property
|
|
1100
|
-
def _default_output_socket(self) -> NodeSocketFloat | NodeSocketVector:
|
|
1101
|
-
match self.operation:
|
|
1102
|
-
case "DOT_PRODUCT" | "DISTANCE" | "LENGTH":
|
|
1103
|
-
return self.o_value
|
|
1104
|
-
case _:
|
|
1105
|
-
return self.o_vector
|
|
1106
|
-
|
|
1107
|
-
@property
|
|
1108
|
-
def operation(
|
|
1109
|
-
self,
|
|
1110
|
-
) -> _VectorMathOperations:
|
|
1111
|
-
return self.node.operation
|
|
1112
|
-
|
|
1113
|
-
@operation.setter
|
|
1114
|
-
def operation(
|
|
1115
|
-
self,
|
|
1116
|
-
value: _VectorMathOperations,
|
|
1117
|
-
):
|
|
1118
|
-
self.node.operation = value
|
|
1119
|
-
|
|
1120
|
-
@classmethod
|
|
1121
|
-
def add(
|
|
1122
|
-
cls,
|
|
1123
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1124
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1125
|
-
) -> "VectorMath":
|
|
1126
|
-
"""Create Vector Math with operation `a + b`."""
|
|
1127
|
-
return cls(operation="ADD", Vector=a, Vector_001=b)
|
|
1128
|
-
|
|
1129
|
-
@classmethod
|
|
1130
|
-
def subtract(
|
|
1131
|
-
cls,
|
|
1132
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1133
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1134
|
-
) -> "VectorMath":
|
|
1135
|
-
"""Create Vector Math with operation `a - b`."""
|
|
1136
|
-
return cls(operation="SUBTRACT", Vector=a, Vector_001=b)
|
|
1137
|
-
|
|
1138
|
-
@classmethod
|
|
1139
|
-
def multiply(
|
|
1140
|
-
cls,
|
|
1141
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1142
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1143
|
-
) -> "VectorMath":
|
|
1144
|
-
"""Create Vector Math with operation `a * b` element-wise."""
|
|
1145
|
-
return cls(operation="MULTIPLY", Vector=a, Vector_001=b)
|
|
1146
|
-
|
|
1147
|
-
@classmethod
|
|
1148
|
-
def divide(
|
|
1149
|
-
cls,
|
|
1150
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1151
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1152
|
-
) -> "VectorMath":
|
|
1153
|
-
"""Create Vector Math with operation 'Divide'."""
|
|
1154
|
-
return cls(operation="DIVIDE", Vector=a, Vector_001=b)
|
|
1155
|
-
|
|
1156
|
-
@classmethod
|
|
1157
|
-
def multiply_add(
|
|
1158
|
-
cls,
|
|
1159
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1160
|
-
multiplier: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1161
|
-
addend: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1162
|
-
) -> "VectorMath":
|
|
1163
|
-
"""Create Vector Math with operation 'Multiply Add'."""
|
|
1164
|
-
return cls(
|
|
1165
|
-
operation="MULTIPLY_ADD",
|
|
1166
|
-
Vector=vector,
|
|
1167
|
-
Vector_001=multiplier,
|
|
1168
|
-
Vector_002=addend,
|
|
1169
|
-
)
|
|
1170
|
-
|
|
1171
|
-
@classmethod
|
|
1172
|
-
def cross_product(
|
|
1173
|
-
cls,
|
|
1174
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1175
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1176
|
-
) -> "VectorMath":
|
|
1177
|
-
"""Create Vector Math with operation 'Cross Product'."""
|
|
1178
|
-
return cls(operation="CROSS_PRODUCT", Vector=a, Vector_001=b)
|
|
1179
|
-
|
|
1180
|
-
@classmethod
|
|
1181
|
-
def project(
|
|
1182
|
-
cls,
|
|
1183
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1184
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1185
|
-
) -> "VectorMath":
|
|
1186
|
-
"""Project A onto B."""
|
|
1187
|
-
return cls(operation="PROJECT", Vector=a, Vector_001=b)
|
|
1188
|
-
|
|
1189
|
-
@classmethod
|
|
1190
|
-
def reflect(
|
|
1191
|
-
cls,
|
|
1192
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1193
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1194
|
-
) -> "VectorMath":
|
|
1195
|
-
"""Reflect A around the normal B. B does not need to be normalized."""
|
|
1196
|
-
return cls(operation="REFLECT", Vector=a, Vector_001=b)
|
|
1197
|
-
|
|
1198
|
-
@classmethod
|
|
1199
|
-
def refract(
|
|
1200
|
-
cls,
|
|
1201
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1202
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1203
|
-
ior: LINKABLE | float = 1.0,
|
|
1204
|
-
) -> "VectorMath":
|
|
1205
|
-
"""For a given incident vector and surface normal (b) with an index of refraction (ior), return the refraction vector"""
|
|
1206
|
-
return cls(operation="REFRACT", Vector=a, Vector_001=b, Scale=ior)
|
|
1207
|
-
|
|
1208
|
-
@classmethod
|
|
1209
|
-
def face_forward(
|
|
1210
|
-
cls,
|
|
1211
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1212
|
-
incidence: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1213
|
-
reference: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1214
|
-
) -> "VectorMath":
|
|
1215
|
-
"""Orients a vector to face away from a surface (incidence) defined by it's normal (reference)"""
|
|
1216
|
-
return cls(
|
|
1217
|
-
operation="FACEFORWARD",
|
|
1218
|
-
Vector=vector,
|
|
1219
|
-
Vector_001=incidence,
|
|
1220
|
-
Vector_002=reference,
|
|
1221
|
-
)
|
|
1222
|
-
|
|
1223
|
-
@classmethod
|
|
1224
|
-
def dot_product(
|
|
1225
|
-
cls,
|
|
1226
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1227
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1228
|
-
) -> "VectorMath":
|
|
1229
|
-
"""Create Vector Math with operation 'Dot Product'."""
|
|
1230
|
-
return cls(operation="DOT_PRODUCT", Vector=a, Vector_001=b)
|
|
1231
|
-
|
|
1232
|
-
@classmethod
|
|
1233
|
-
def distance(
|
|
1234
|
-
cls,
|
|
1235
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1236
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1237
|
-
) -> "VectorMath":
|
|
1238
|
-
"""Create Vector Math with operation 'Distance'."""
|
|
1239
|
-
return cls(operation="DISTANCE", Vector=a, Vector_001=b)
|
|
1240
|
-
|
|
1241
|
-
@classmethod
|
|
1242
|
-
def length(
|
|
1243
|
-
cls,
|
|
1244
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1245
|
-
) -> "VectorMath":
|
|
1246
|
-
"""Create Vector Math with operation 'Length'."""
|
|
1247
|
-
return cls(operation="LENGTH", Vector=vector)
|
|
1248
|
-
|
|
1249
|
-
@classmethod
|
|
1250
|
-
def scale(
|
|
1251
|
-
cls,
|
|
1252
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1253
|
-
scale: LINKABLE | float = 1.0,
|
|
1254
|
-
) -> "VectorMath":
|
|
1255
|
-
"""Create Vector Math with operation 'Scale'."""
|
|
1256
|
-
return cls(operation="SCALE", Vector=vector, Scale=scale)
|
|
1257
|
-
|
|
1258
|
-
@classmethod
|
|
1259
|
-
def normalize(
|
|
1260
|
-
cls,
|
|
1261
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1262
|
-
) -> "VectorMath":
|
|
1263
|
-
"""Create Vector Math with operation 'Normalize'."""
|
|
1264
|
-
return cls(operation="NORMALIZE", Vector=vector)
|
|
1265
|
-
|
|
1266
|
-
@classmethod
|
|
1267
|
-
def absolute(
|
|
1268
|
-
cls,
|
|
1269
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1270
|
-
) -> "VectorMath":
|
|
1271
|
-
"""Create Vector Math with operation 'Absolute'."""
|
|
1272
|
-
return cls(operation="ABSOLUTE", Vector=vector)
|
|
1273
|
-
|
|
1274
|
-
@classmethod
|
|
1275
|
-
def power(
|
|
1276
|
-
cls,
|
|
1277
|
-
base: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1278
|
-
exponent: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1279
|
-
) -> "VectorMath":
|
|
1280
|
-
"""Create Vector Math with operation 'Power'."""
|
|
1281
|
-
return cls(operation="POWER", Vector=base, Vector_001=exponent)
|
|
1282
|
-
|
|
1283
|
-
@classmethod
|
|
1284
|
-
def sign(
|
|
1285
|
-
cls,
|
|
1286
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1287
|
-
) -> "VectorMath":
|
|
1288
|
-
"""Create Vector Math with operation 'Sign'."""
|
|
1289
|
-
return cls(operation="SIGN", Vector=vector)
|
|
1290
|
-
|
|
1291
|
-
@classmethod
|
|
1292
|
-
def minimum(
|
|
1293
|
-
cls,
|
|
1294
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1295
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1296
|
-
) -> "VectorMath":
|
|
1297
|
-
"""Create Vector Math with operation 'Minimum'."""
|
|
1298
|
-
return cls(operation="MINIMUM", Vector=a, Vector_001=b)
|
|
1299
|
-
|
|
1300
|
-
@classmethod
|
|
1301
|
-
def maximum(
|
|
1302
|
-
cls,
|
|
1303
|
-
a: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1304
|
-
b: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1305
|
-
) -> "VectorMath":
|
|
1306
|
-
"""Create Vector Math with operation 'Maximum'."""
|
|
1307
|
-
return cls(operation="MAXIMUM", Vector=a, Vector_001=b)
|
|
1308
|
-
|
|
1309
|
-
@classmethod
|
|
1310
|
-
def floor(
|
|
1311
|
-
cls,
|
|
1312
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1313
|
-
) -> "VectorMath":
|
|
1314
|
-
"""Create Vector Math with operation 'Floor'."""
|
|
1315
|
-
return cls(operation="FLOOR", Vector=vector)
|
|
1316
|
-
|
|
1317
|
-
@classmethod
|
|
1318
|
-
def ceil(
|
|
1319
|
-
cls,
|
|
1320
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1321
|
-
) -> "VectorMath":
|
|
1322
|
-
"""Create Vector Math with operation 'Ceil'."""
|
|
1323
|
-
return cls(operation="CEIL", Vector=vector)
|
|
1324
|
-
|
|
1325
|
-
@classmethod
|
|
1326
|
-
def fraction(
|
|
1327
|
-
cls,
|
|
1328
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1329
|
-
) -> "VectorMath":
|
|
1330
|
-
"""Create Vector Math with operation 'Fraction'."""
|
|
1331
|
-
return cls(operation="FRACTION", Vector=vector)
|
|
1332
|
-
|
|
1333
|
-
@classmethod
|
|
1334
|
-
def modulo(
|
|
1335
|
-
cls,
|
|
1336
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1337
|
-
) -> "VectorMath":
|
|
1338
|
-
"""Create Vector Math with operation 'Modulo'."""
|
|
1339
|
-
return cls(operation="MODULO", Vector=vector)
|
|
1340
|
-
|
|
1341
|
-
@classmethod
|
|
1342
|
-
def wrap(
|
|
1343
|
-
cls,
|
|
1344
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1345
|
-
min: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1346
|
-
max: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1347
|
-
) -> "VectorMath":
|
|
1348
|
-
"""Create Vector Math with operation 'Wrap'."""
|
|
1349
|
-
return cls(operation="WRAP", Vector=vector, Vector_001=min, Vector_002=max)
|
|
1350
|
-
|
|
1351
|
-
@classmethod
|
|
1352
|
-
def snap(
|
|
1353
|
-
cls,
|
|
1354
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1355
|
-
increment: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1356
|
-
) -> "VectorMath":
|
|
1357
|
-
"""Create Vector Math with operation 'Snap'."""
|
|
1358
|
-
return cls(operation="SNAP", Vector=vector, Vector_001=increment)
|
|
1359
|
-
|
|
1360
|
-
@classmethod
|
|
1361
|
-
def sine(
|
|
1362
|
-
cls,
|
|
1363
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1364
|
-
) -> "VectorMath":
|
|
1365
|
-
"""Create Vector Math with operation 'Sine'."""
|
|
1366
|
-
return cls(operation="SINE", Vector=vector)
|
|
1367
|
-
|
|
1368
|
-
@classmethod
|
|
1369
|
-
def cosine(
|
|
1370
|
-
cls,
|
|
1371
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1372
|
-
) -> "VectorMath":
|
|
1373
|
-
"""Create Vector Math with operation 'Cosine'."""
|
|
1374
|
-
return cls(operation="COSINE", Vector=vector)
|
|
1375
|
-
|
|
1376
|
-
@classmethod
|
|
1377
|
-
def tangent(
|
|
1378
|
-
cls,
|
|
1379
|
-
vector: TYPE_INPUT_VECTOR = [0.0, 0.0, 0.0],
|
|
1380
|
-
) -> "VectorMath":
|
|
1381
|
-
"""Create Vector Math with operation 'Tangent'."""
|
|
1382
|
-
return cls(operation="TANGENT", Vector=vector)
|