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
nodebpy/nodes/attribute.py
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
Auto-generated Blender Geometry Node classes.
|
|
1
|
+
from typing import Literal
|
|
3
2
|
|
|
4
|
-
DO NOT EDIT THIS FILE MANUALLY.
|
|
5
|
-
This file is generated by molecularnodes/nodes/generator.py
|
|
6
|
-
|
|
7
|
-
To regenerate: Run generator.py from within Blender
|
|
8
|
-
|
|
9
|
-
KNOWN LIMITATIONS:
|
|
10
|
-
- Dynamic multi-input/output sockets are not yet supported
|
|
11
|
-
(these are the unnamed sockets that appear in the UI for nodes like
|
|
12
|
-
"Evaluate Closure", "Join Geometry", etc. that allow dragging in
|
|
13
|
-
multiple connections)
|
|
14
|
-
- TODO: Add support for dynamic socket creation
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from __future__ import annotations
|
|
18
3
|
import bpy
|
|
19
|
-
|
|
20
|
-
from ..builder import NodeBuilder,
|
|
21
|
-
from .types import
|
|
4
|
+
|
|
5
|
+
from ..builder import NodeBuilder, SocketLinker
|
|
6
|
+
from .types import (
|
|
7
|
+
LINKABLE,
|
|
8
|
+
TYPE_INPUT_BOOLEAN,
|
|
9
|
+
TYPE_INPUT_GEOMETRY,
|
|
10
|
+
TYPE_INPUT_INT,
|
|
11
|
+
TYPE_INPUT_MENU,
|
|
12
|
+
TYPE_INPUT_STRING,
|
|
13
|
+
TYPE_INPUT_VALUE,
|
|
14
|
+
_AttributeDataTypes,
|
|
15
|
+
_AttributeDomains,
|
|
16
|
+
_StoreNamedAttributeTypes,
|
|
17
|
+
)
|
|
22
18
|
|
|
23
19
|
|
|
24
20
|
class DomainSize(NodeBuilder):
|
|
@@ -29,40 +25,39 @@ class DomainSize(NodeBuilder):
|
|
|
29
25
|
|
|
30
26
|
def __init__(
|
|
31
27
|
self,
|
|
32
|
-
geometry:
|
|
28
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
29
|
+
*,
|
|
33
30
|
component: Literal[
|
|
34
31
|
"MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"
|
|
35
32
|
] = "MESH",
|
|
36
|
-
**kwargs,
|
|
37
33
|
):
|
|
38
34
|
super().__init__()
|
|
39
35
|
key_args = {"Geometry": geometry}
|
|
40
|
-
key_args.update(kwargs)
|
|
41
36
|
self.component = component
|
|
42
37
|
self._establish_links(**key_args)
|
|
43
38
|
|
|
44
39
|
@property
|
|
45
|
-
def i_geometry(self) ->
|
|
40
|
+
def i_geometry(self) -> SocketLinker:
|
|
46
41
|
"""Input socket: Geometry"""
|
|
47
42
|
return self._input("Geometry")
|
|
48
43
|
|
|
49
44
|
@property
|
|
50
|
-
def o_point_count(self) ->
|
|
45
|
+
def o_point_count(self) -> SocketLinker:
|
|
51
46
|
"""Output socket: Point Count"""
|
|
52
47
|
return self._output("Point Count")
|
|
53
48
|
|
|
54
49
|
@property
|
|
55
|
-
def o_edge_count(self) ->
|
|
50
|
+
def o_edge_count(self) -> SocketLinker:
|
|
56
51
|
"""Output socket: Edge Count"""
|
|
57
52
|
return self._output("Edge Count")
|
|
58
53
|
|
|
59
54
|
@property
|
|
60
|
-
def o_face_count(self) ->
|
|
55
|
+
def o_face_count(self) -> SocketLinker:
|
|
61
56
|
"""Output socket: Face Count"""
|
|
62
57
|
return self._output("Face Count")
|
|
63
58
|
|
|
64
59
|
@property
|
|
65
|
-
def o_face_corner_count(self) ->
|
|
60
|
+
def o_face_corner_count(self) -> SocketLinker:
|
|
66
61
|
"""Output socket: Face Corner Count"""
|
|
67
62
|
return self._output("Face Corner Count")
|
|
68
63
|
|
|
@@ -76,6 +71,13 @@ class DomainSize(NodeBuilder):
|
|
|
76
71
|
def component(
|
|
77
72
|
self, value: Literal["MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"]
|
|
78
73
|
):
|
|
74
|
+
match value:
|
|
75
|
+
case "MESH" | "POINTCLOUD" | "CURVE":
|
|
76
|
+
self._default_output_id = "Point Count"
|
|
77
|
+
case "INSTANCES":
|
|
78
|
+
self._default_output_id = "Instance Count"
|
|
79
|
+
case "GREASEPENCIL":
|
|
80
|
+
self._default_output_id = "Layer Count"
|
|
79
81
|
self.node.component = value
|
|
80
82
|
|
|
81
83
|
|
|
@@ -87,23 +89,13 @@ class AttributeStatistic(NodeBuilder):
|
|
|
87
89
|
|
|
88
90
|
def __init__(
|
|
89
91
|
self,
|
|
90
|
-
geometry:
|
|
92
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
91
93
|
selection: TYPE_INPUT_BOOLEAN = True,
|
|
92
|
-
attribute:
|
|
94
|
+
attribute: LINKABLE = None,
|
|
95
|
+
*,
|
|
93
96
|
data_type: Literal[
|
|
94
97
|
"FLOAT",
|
|
95
|
-
"INT",
|
|
96
|
-
"BOOLEAN",
|
|
97
98
|
"FLOAT_VECTOR",
|
|
98
|
-
"FLOAT_COLOR",
|
|
99
|
-
"QUATERNION",
|
|
100
|
-
"FLOAT4X4",
|
|
101
|
-
"STRING",
|
|
102
|
-
"INT8",
|
|
103
|
-
"INT16_2D",
|
|
104
|
-
"INT32_2D",
|
|
105
|
-
"FLOAT2",
|
|
106
|
-
"BYTE_COLOR",
|
|
107
99
|
] = "FLOAT",
|
|
108
100
|
domain: Literal[
|
|
109
101
|
"POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
|
|
@@ -122,57 +114,57 @@ class AttributeStatistic(NodeBuilder):
|
|
|
122
114
|
self._establish_links(**key_args)
|
|
123
115
|
|
|
124
116
|
@property
|
|
125
|
-
def i_geometry(self) ->
|
|
117
|
+
def i_geometry(self) -> SocketLinker:
|
|
126
118
|
"""Input socket: Geometry"""
|
|
127
119
|
return self._input("Geometry")
|
|
128
120
|
|
|
129
121
|
@property
|
|
130
|
-
def i_selection(self) ->
|
|
122
|
+
def i_selection(self) -> SocketLinker:
|
|
131
123
|
"""Input socket: Selection"""
|
|
132
124
|
return self._input("Selection")
|
|
133
125
|
|
|
134
126
|
@property
|
|
135
|
-
def i_attribute(self) ->
|
|
127
|
+
def i_attribute(self) -> SocketLinker:
|
|
136
128
|
"""Input socket: Attribute"""
|
|
137
129
|
return self._input("Attribute")
|
|
138
130
|
|
|
139
131
|
@property
|
|
140
|
-
def o_mean(self) ->
|
|
132
|
+
def o_mean(self) -> SocketLinker:
|
|
141
133
|
"""Output socket: Mean"""
|
|
142
134
|
return self._output("Mean")
|
|
143
135
|
|
|
144
136
|
@property
|
|
145
|
-
def o_median(self) ->
|
|
137
|
+
def o_median(self) -> SocketLinker:
|
|
146
138
|
"""Output socket: Median"""
|
|
147
139
|
return self._output("Median")
|
|
148
140
|
|
|
149
141
|
@property
|
|
150
|
-
def o_sum(self) ->
|
|
142
|
+
def o_sum(self) -> SocketLinker:
|
|
151
143
|
"""Output socket: Sum"""
|
|
152
144
|
return self._output("Sum")
|
|
153
145
|
|
|
154
146
|
@property
|
|
155
|
-
def o_min(self) ->
|
|
147
|
+
def o_min(self) -> SocketLinker:
|
|
156
148
|
"""Output socket: Min"""
|
|
157
149
|
return self._output("Min")
|
|
158
150
|
|
|
159
151
|
@property
|
|
160
|
-
def o_max(self) ->
|
|
152
|
+
def o_max(self) -> SocketLinker:
|
|
161
153
|
"""Output socket: Max"""
|
|
162
154
|
return self._output("Max")
|
|
163
155
|
|
|
164
156
|
@property
|
|
165
|
-
def o_range(self) ->
|
|
157
|
+
def o_range(self) -> SocketLinker:
|
|
166
158
|
"""Output socket: Range"""
|
|
167
159
|
return self._output("Range")
|
|
168
160
|
|
|
169
161
|
@property
|
|
170
|
-
def o_standard_deviation(self) ->
|
|
162
|
+
def o_standard_deviation(self) -> SocketLinker:
|
|
171
163
|
"""Output socket: Standard Deviation"""
|
|
172
164
|
return self._output("Standard Deviation")
|
|
173
165
|
|
|
174
166
|
@property
|
|
175
|
-
def o_variance(self) ->
|
|
167
|
+
def o_variance(self) -> SocketLinker:
|
|
176
168
|
"""Output socket: Variance"""
|
|
177
169
|
return self._output("Variance")
|
|
178
170
|
|
|
@@ -181,38 +173,16 @@ class AttributeStatistic(NodeBuilder):
|
|
|
181
173
|
self,
|
|
182
174
|
) -> Literal[
|
|
183
175
|
"FLOAT",
|
|
184
|
-
"INT",
|
|
185
|
-
"BOOLEAN",
|
|
186
176
|
"FLOAT_VECTOR",
|
|
187
|
-
"FLOAT_COLOR",
|
|
188
|
-
"QUATERNION",
|
|
189
|
-
"FLOAT4X4",
|
|
190
|
-
"STRING",
|
|
191
|
-
"INT8",
|
|
192
|
-
"INT16_2D",
|
|
193
|
-
"INT32_2D",
|
|
194
|
-
"FLOAT2",
|
|
195
|
-
"BYTE_COLOR",
|
|
196
177
|
]:
|
|
197
|
-
return self.node.data_type
|
|
178
|
+
return self.node.data_type # type: ignore
|
|
198
179
|
|
|
199
180
|
@data_type.setter
|
|
200
181
|
def data_type(
|
|
201
182
|
self,
|
|
202
183
|
value: Literal[
|
|
203
184
|
"FLOAT",
|
|
204
|
-
"INT",
|
|
205
|
-
"BOOLEAN",
|
|
206
185
|
"FLOAT_VECTOR",
|
|
207
|
-
"FLOAT_COLOR",
|
|
208
|
-
"QUATERNION",
|
|
209
|
-
"FLOAT4X4",
|
|
210
|
-
"STRING",
|
|
211
|
-
"INT8",
|
|
212
|
-
"INT16_2D",
|
|
213
|
-
"INT32_2D",
|
|
214
|
-
"FLOAT2",
|
|
215
|
-
"BYTE_COLOR",
|
|
216
186
|
],
|
|
217
187
|
):
|
|
218
188
|
self.node.data_type = value
|
|
@@ -220,13 +190,13 @@ class AttributeStatistic(NodeBuilder):
|
|
|
220
190
|
@property
|
|
221
191
|
def domain(
|
|
222
192
|
self,
|
|
223
|
-
) ->
|
|
193
|
+
) -> _AttributeDomains:
|
|
224
194
|
return self.node.domain
|
|
225
195
|
|
|
226
196
|
@domain.setter
|
|
227
197
|
def domain(
|
|
228
198
|
self,
|
|
229
|
-
value:
|
|
199
|
+
value: _AttributeDomains,
|
|
230
200
|
):
|
|
231
201
|
self.node.domain = value
|
|
232
202
|
|
|
@@ -239,49 +209,39 @@ class BlurAttribute(NodeBuilder):
|
|
|
239
209
|
|
|
240
210
|
def __init__(
|
|
241
211
|
self,
|
|
242
|
-
value:
|
|
243
|
-
iterations:
|
|
244
|
-
weight:
|
|
212
|
+
value: LINKABLE = None,
|
|
213
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
214
|
+
weight: TYPE_INPUT_VALUE = 1.0,
|
|
215
|
+
*,
|
|
245
216
|
data_type: Literal[
|
|
246
217
|
"FLOAT",
|
|
247
218
|
"INT",
|
|
248
|
-
"BOOLEAN",
|
|
249
219
|
"FLOAT_VECTOR",
|
|
250
220
|
"FLOAT_COLOR",
|
|
251
|
-
"QUATERNION",
|
|
252
|
-
"FLOAT4X4",
|
|
253
|
-
"STRING",
|
|
254
|
-
"INT8",
|
|
255
|
-
"INT16_2D",
|
|
256
|
-
"INT32_2D",
|
|
257
|
-
"FLOAT2",
|
|
258
|
-
"BYTE_COLOR",
|
|
259
221
|
] = "FLOAT",
|
|
260
|
-
**kwargs,
|
|
261
222
|
):
|
|
262
223
|
super().__init__()
|
|
263
224
|
key_args = {"Value": value, "Iterations": iterations, "Weight": weight}
|
|
264
|
-
key_args.update(kwargs)
|
|
265
225
|
self.data_type = data_type
|
|
266
226
|
self._establish_links(**key_args)
|
|
267
227
|
|
|
268
228
|
@property
|
|
269
|
-
def i_value(self) ->
|
|
229
|
+
def i_value(self) -> SocketLinker:
|
|
270
230
|
"""Input socket: Value"""
|
|
271
231
|
return self._input("Value")
|
|
272
232
|
|
|
273
233
|
@property
|
|
274
|
-
def i_iterations(self) ->
|
|
234
|
+
def i_iterations(self) -> SocketLinker:
|
|
275
235
|
"""Input socket: Iterations"""
|
|
276
236
|
return self._input("Iterations")
|
|
277
237
|
|
|
278
238
|
@property
|
|
279
|
-
def i_weight(self) ->
|
|
239
|
+
def i_weight(self) -> SocketLinker:
|
|
280
240
|
"""Input socket: Weight"""
|
|
281
241
|
return self._input("Weight")
|
|
282
242
|
|
|
283
243
|
@property
|
|
284
|
-
def o_value(self) ->
|
|
244
|
+
def o_value(self) -> SocketLinker:
|
|
285
245
|
"""Output socket: Value"""
|
|
286
246
|
return self._output("Value")
|
|
287
247
|
|
|
@@ -291,19 +251,10 @@ class BlurAttribute(NodeBuilder):
|
|
|
291
251
|
) -> Literal[
|
|
292
252
|
"FLOAT",
|
|
293
253
|
"INT",
|
|
294
|
-
"BOOLEAN",
|
|
295
254
|
"FLOAT_VECTOR",
|
|
296
255
|
"FLOAT_COLOR",
|
|
297
|
-
"QUATERNION",
|
|
298
|
-
"FLOAT4X4",
|
|
299
|
-
"STRING",
|
|
300
|
-
"INT8",
|
|
301
|
-
"INT16_2D",
|
|
302
|
-
"INT32_2D",
|
|
303
|
-
"FLOAT2",
|
|
304
|
-
"BYTE_COLOR",
|
|
305
256
|
]:
|
|
306
|
-
return self.node.data_type
|
|
257
|
+
return self.node.data_type # type: ignore
|
|
307
258
|
|
|
308
259
|
@data_type.setter
|
|
309
260
|
def data_type(
|
|
@@ -311,106 +262,8 @@ class BlurAttribute(NodeBuilder):
|
|
|
311
262
|
value: Literal[
|
|
312
263
|
"FLOAT",
|
|
313
264
|
"INT",
|
|
314
|
-
"BOOLEAN",
|
|
315
265
|
"FLOAT_VECTOR",
|
|
316
266
|
"FLOAT_COLOR",
|
|
317
|
-
"QUATERNION",
|
|
318
|
-
"FLOAT4X4",
|
|
319
|
-
"STRING",
|
|
320
|
-
"INT8",
|
|
321
|
-
"INT16_2D",
|
|
322
|
-
"INT32_2D",
|
|
323
|
-
"FLOAT2",
|
|
324
|
-
"BYTE_COLOR",
|
|
325
|
-
],
|
|
326
|
-
):
|
|
327
|
-
self.node.data_type = value
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
class NamedAttribute(NodeBuilder):
|
|
331
|
-
"""Retrieve the data of a specified attribute"""
|
|
332
|
-
|
|
333
|
-
name = "GeometryNodeInputNamedAttribute"
|
|
334
|
-
node: bpy.types.GeometryNodeInputNamedAttribute
|
|
335
|
-
|
|
336
|
-
def __init__(
|
|
337
|
-
self,
|
|
338
|
-
name: str | LINKABLE | None = "",
|
|
339
|
-
data_type: Literal[
|
|
340
|
-
"FLOAT",
|
|
341
|
-
"INT",
|
|
342
|
-
"BOOLEAN",
|
|
343
|
-
"FLOAT_VECTOR",
|
|
344
|
-
"FLOAT_COLOR",
|
|
345
|
-
"QUATERNION",
|
|
346
|
-
"FLOAT4X4",
|
|
347
|
-
"STRING",
|
|
348
|
-
"INT8",
|
|
349
|
-
"INT16_2D",
|
|
350
|
-
"INT32_2D",
|
|
351
|
-
"FLOAT2",
|
|
352
|
-
"BYTE_COLOR",
|
|
353
|
-
] = "FLOAT",
|
|
354
|
-
**kwargs,
|
|
355
|
-
):
|
|
356
|
-
super().__init__()
|
|
357
|
-
key_args = {"Name": name}
|
|
358
|
-
key_args.update(kwargs)
|
|
359
|
-
self.data_type = data_type
|
|
360
|
-
self._establish_links(**key_args)
|
|
361
|
-
|
|
362
|
-
@property
|
|
363
|
-
def i_name(self) -> bpy.types.NodeSocketString:
|
|
364
|
-
"""Input socket: Name"""
|
|
365
|
-
return self._input("Name")
|
|
366
|
-
|
|
367
|
-
@property
|
|
368
|
-
def o_attribute(self) -> bpy.types.NodeSocketFloat:
|
|
369
|
-
"""Output socket: Attribute"""
|
|
370
|
-
return self._output("Attribute")
|
|
371
|
-
|
|
372
|
-
@property
|
|
373
|
-
def o_exists(self) -> bpy.types.NodeSocketBool:
|
|
374
|
-
"""Output socket: Exists"""
|
|
375
|
-
return self._output("Exists")
|
|
376
|
-
|
|
377
|
-
@property
|
|
378
|
-
def data_type(
|
|
379
|
-
self,
|
|
380
|
-
) -> Literal[
|
|
381
|
-
"FLOAT",
|
|
382
|
-
"INT",
|
|
383
|
-
"BOOLEAN",
|
|
384
|
-
"FLOAT_VECTOR",
|
|
385
|
-
"FLOAT_COLOR",
|
|
386
|
-
"QUATERNION",
|
|
387
|
-
"FLOAT4X4",
|
|
388
|
-
"STRING",
|
|
389
|
-
"INT8",
|
|
390
|
-
"INT16_2D",
|
|
391
|
-
"INT32_2D",
|
|
392
|
-
"FLOAT2",
|
|
393
|
-
"BYTE_COLOR",
|
|
394
|
-
]:
|
|
395
|
-
return self.node.data_type
|
|
396
|
-
|
|
397
|
-
@data_type.setter
|
|
398
|
-
def data_type(
|
|
399
|
-
self,
|
|
400
|
-
value: Literal[
|
|
401
|
-
"FLOAT",
|
|
402
|
-
"INT",
|
|
403
|
-
"BOOLEAN",
|
|
404
|
-
"FLOAT_VECTOR",
|
|
405
|
-
"FLOAT_COLOR",
|
|
406
|
-
"QUATERNION",
|
|
407
|
-
"FLOAT4X4",
|
|
408
|
-
"STRING",
|
|
409
|
-
"INT8",
|
|
410
|
-
"INT16_2D",
|
|
411
|
-
"INT32_2D",
|
|
412
|
-
"FLOAT2",
|
|
413
|
-
"BYTE_COLOR",
|
|
414
267
|
],
|
|
415
268
|
):
|
|
416
269
|
self.node.data_type = value
|
|
@@ -424,34 +277,31 @@ class RemoveNamedAttribute(NodeBuilder):
|
|
|
424
277
|
|
|
425
278
|
def __init__(
|
|
426
279
|
self,
|
|
427
|
-
geometry:
|
|
428
|
-
pattern_mode:
|
|
429
|
-
name:
|
|
430
|
-
**kwargs,
|
|
280
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
281
|
+
pattern_mode: Literal["Exact", "Wildcard"] | TYPE_INPUT_MENU = "Exact",
|
|
282
|
+
name: TYPE_INPUT_STRING = "",
|
|
431
283
|
):
|
|
432
284
|
super().__init__()
|
|
433
285
|
key_args = {"Geometry": geometry, "Pattern Mode": pattern_mode, "Name": name}
|
|
434
|
-
key_args.update(kwargs)
|
|
435
|
-
|
|
436
286
|
self._establish_links(**key_args)
|
|
437
287
|
|
|
438
288
|
@property
|
|
439
|
-
def i_geometry(self) ->
|
|
289
|
+
def i_geometry(self) -> SocketLinker:
|
|
440
290
|
"""Input socket: Geometry"""
|
|
441
291
|
return self._input("Geometry")
|
|
442
292
|
|
|
443
293
|
@property
|
|
444
|
-
def i_pattern_mode(self) ->
|
|
294
|
+
def i_pattern_mode(self) -> SocketLinker:
|
|
445
295
|
"""Input socket: Pattern Mode"""
|
|
446
296
|
return self._input("Pattern Mode")
|
|
447
297
|
|
|
448
298
|
@property
|
|
449
|
-
def i_name(self) ->
|
|
299
|
+
def i_name(self) -> SocketLinker:
|
|
450
300
|
"""Input socket: Name"""
|
|
451
301
|
return self._input("Name")
|
|
452
302
|
|
|
453
303
|
@property
|
|
454
|
-
def o_geometry(self) ->
|
|
304
|
+
def o_geometry(self) -> SocketLinker:
|
|
455
305
|
"""Output socket: Geometry"""
|
|
456
306
|
return self._output("Geometry")
|
|
457
307
|
|
|
@@ -464,29 +314,13 @@ class StoreNamedAttribute(NodeBuilder):
|
|
|
464
314
|
|
|
465
315
|
def __init__(
|
|
466
316
|
self,
|
|
467
|
-
geometry:
|
|
317
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
468
318
|
selection: TYPE_INPUT_BOOLEAN = True,
|
|
469
|
-
name:
|
|
470
|
-
value:
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
"BOOLEAN",
|
|
475
|
-
"FLOAT_VECTOR",
|
|
476
|
-
"FLOAT_COLOR",
|
|
477
|
-
"QUATERNION",
|
|
478
|
-
"FLOAT4X4",
|
|
479
|
-
"STRING",
|
|
480
|
-
"INT8",
|
|
481
|
-
"INT16_2D",
|
|
482
|
-
"INT32_2D",
|
|
483
|
-
"FLOAT2",
|
|
484
|
-
"BYTE_COLOR",
|
|
485
|
-
] = "FLOAT",
|
|
486
|
-
domain: Literal[
|
|
487
|
-
"POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
|
|
488
|
-
] = "POINT",
|
|
489
|
-
**kwargs,
|
|
319
|
+
name: TYPE_INPUT_STRING = "",
|
|
320
|
+
value: LINKABLE = None,
|
|
321
|
+
*,
|
|
322
|
+
data_type: _StoreNamedAttributeTypes = "FLOAT",
|
|
323
|
+
domain: _AttributeDomains = "POINT",
|
|
490
324
|
):
|
|
491
325
|
super().__init__()
|
|
492
326
|
key_args = {
|
|
@@ -495,86 +329,153 @@ class StoreNamedAttribute(NodeBuilder):
|
|
|
495
329
|
"Name": name,
|
|
496
330
|
"Value": value,
|
|
497
331
|
}
|
|
498
|
-
key_args.update(kwargs)
|
|
499
332
|
self.data_type = data_type
|
|
500
333
|
self.domain = domain
|
|
501
334
|
self._establish_links(**key_args)
|
|
502
335
|
|
|
503
336
|
@property
|
|
504
|
-
def i_geometry(self) ->
|
|
337
|
+
def i_geometry(self) -> SocketLinker:
|
|
505
338
|
"""Input socket: Geometry"""
|
|
506
339
|
return self._input("Geometry")
|
|
507
340
|
|
|
508
341
|
@property
|
|
509
|
-
def i_selection(self) ->
|
|
342
|
+
def i_selection(self) -> SocketLinker:
|
|
510
343
|
"""Input socket: Selection"""
|
|
511
344
|
return self._input("Selection")
|
|
512
345
|
|
|
513
346
|
@property
|
|
514
|
-
def i_name(self) ->
|
|
347
|
+
def i_name(self) -> SocketLinker:
|
|
515
348
|
"""Input socket: Name"""
|
|
516
349
|
return self._input("Name")
|
|
517
350
|
|
|
518
351
|
@property
|
|
519
|
-
def i_value(self) ->
|
|
352
|
+
def i_value(self) -> SocketLinker:
|
|
520
353
|
"""Input socket: Value"""
|
|
521
354
|
return self._input("Value")
|
|
522
355
|
|
|
523
356
|
@property
|
|
524
|
-
def o_geometry(self) ->
|
|
357
|
+
def o_geometry(self) -> SocketLinker:
|
|
525
358
|
"""Output socket: Geometry"""
|
|
526
359
|
return self._output("Geometry")
|
|
527
360
|
|
|
528
361
|
@property
|
|
529
362
|
def data_type(
|
|
530
363
|
self,
|
|
531
|
-
) ->
|
|
532
|
-
|
|
533
|
-
"INT",
|
|
534
|
-
"BOOLEAN",
|
|
535
|
-
"FLOAT_VECTOR",
|
|
536
|
-
"FLOAT_COLOR",
|
|
537
|
-
"QUATERNION",
|
|
538
|
-
"FLOAT4X4",
|
|
539
|
-
"STRING",
|
|
540
|
-
"INT8",
|
|
541
|
-
"INT16_2D",
|
|
542
|
-
"INT32_2D",
|
|
543
|
-
"FLOAT2",
|
|
544
|
-
"BYTE_COLOR",
|
|
545
|
-
]:
|
|
546
|
-
return self.node.data_type
|
|
364
|
+
) -> _StoreNamedAttributeTypes:
|
|
365
|
+
return self.node.data_type # type: ignore
|
|
547
366
|
|
|
548
367
|
@data_type.setter
|
|
549
368
|
def data_type(
|
|
550
369
|
self,
|
|
551
|
-
value:
|
|
552
|
-
"FLOAT",
|
|
553
|
-
"INT",
|
|
554
|
-
"BOOLEAN",
|
|
555
|
-
"FLOAT_VECTOR",
|
|
556
|
-
"FLOAT_COLOR",
|
|
557
|
-
"QUATERNION",
|
|
558
|
-
"FLOAT4X4",
|
|
559
|
-
"STRING",
|
|
560
|
-
"INT8",
|
|
561
|
-
"INT16_2D",
|
|
562
|
-
"INT32_2D",
|
|
563
|
-
"FLOAT2",
|
|
564
|
-
"BYTE_COLOR",
|
|
565
|
-
],
|
|
370
|
+
value: _StoreNamedAttributeTypes,
|
|
566
371
|
):
|
|
567
372
|
self.node.data_type = value
|
|
568
373
|
|
|
569
374
|
@property
|
|
570
375
|
def domain(
|
|
571
376
|
self,
|
|
572
|
-
) ->
|
|
377
|
+
) -> _AttributeDomains:
|
|
378
|
+
return self.node.domain
|
|
379
|
+
|
|
380
|
+
@domain.setter
|
|
381
|
+
def domain(
|
|
382
|
+
self,
|
|
383
|
+
value: _AttributeDomains,
|
|
384
|
+
):
|
|
385
|
+
self.node.domain = value
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def _domain_capture_attribute(domain: _AttributeDomains):
|
|
389
|
+
@classmethod
|
|
390
|
+
def method(
|
|
391
|
+
cls,
|
|
392
|
+
*args: LINKABLE,
|
|
393
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
394
|
+
**kwargs,
|
|
395
|
+
) -> "CaptureAttribute":
|
|
396
|
+
"""Create an IndexSwitch node with a pre-set domain"""
|
|
397
|
+
return cls(*args, geometry=geometry, domain=domain, **kwargs)
|
|
398
|
+
|
|
399
|
+
return method
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class CaptureAttribute(NodeBuilder):
|
|
403
|
+
"""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"""
|
|
404
|
+
|
|
405
|
+
name = "GeometryNodeCaptureAttribute"
|
|
406
|
+
node: bpy.types.GeometryNodeCaptureAttribute
|
|
407
|
+
point = _domain_capture_attribute("POINT")
|
|
408
|
+
edge = _domain_capture_attribute("EDGE")
|
|
409
|
+
face = _domain_capture_attribute("FACE")
|
|
410
|
+
corner = _domain_capture_attribute("CORNER")
|
|
411
|
+
curve = _domain_capture_attribute("CURVE")
|
|
412
|
+
instance = _domain_capture_attribute("INSTANCE")
|
|
413
|
+
layer = _domain_capture_attribute("LAYER")
|
|
414
|
+
|
|
415
|
+
def __init__(
|
|
416
|
+
self,
|
|
417
|
+
*args: LINKABLE,
|
|
418
|
+
geometry: TYPE_INPUT_GEOMETRY = None,
|
|
419
|
+
domain: _AttributeDomains = "POINT",
|
|
420
|
+
**kwargs,
|
|
421
|
+
):
|
|
422
|
+
super().__init__()
|
|
423
|
+
key_args = {"Geometry": geometry}
|
|
424
|
+
self.domain = domain
|
|
425
|
+
key_args.update(self._add_inputs(*args, **kwargs)) # type: ignore
|
|
426
|
+
self._establish_links(**key_args)
|
|
427
|
+
|
|
428
|
+
def _add_socket(self, name: str, type: _AttributeDataTypes):
|
|
429
|
+
item = self.node.capture_items.new(socket_type=type, name=name)
|
|
430
|
+
return self.node.inputs[item.name]
|
|
431
|
+
|
|
432
|
+
def capture(self, value: LINKABLE) -> SocketLinker:
|
|
433
|
+
"""Capture the value to store in the attribute
|
|
434
|
+
|
|
435
|
+
Return the SocketLinker for the output socket
|
|
436
|
+
"""
|
|
437
|
+
# the _add_inputs returns a dictionary but we only want the first key
|
|
438
|
+
# because we are adding a single input
|
|
439
|
+
input_dict = self._add_inputs(value)
|
|
440
|
+
return SocketLinker(self.node.outputs[next(iter(input_dict))])
|
|
441
|
+
|
|
442
|
+
@property
|
|
443
|
+
def outputs(self) -> dict[str, SocketLinker]:
|
|
444
|
+
return {
|
|
445
|
+
item.name: SocketLinker(self.node.outputs[item.name])
|
|
446
|
+
for item in self.node.capture_items
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@property
|
|
450
|
+
def inputs(self) -> dict[str, SocketLinker]:
|
|
451
|
+
return {
|
|
452
|
+
item.name: SocketLinker(self.node.inputs[item.name])
|
|
453
|
+
for item in self.node.capture_items
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
@property
|
|
457
|
+
def _items(self) -> bpy.types.NodeGeometryCaptureAttributeItems:
|
|
458
|
+
return self.node.capture_items
|
|
459
|
+
|
|
460
|
+
@property
|
|
461
|
+
def i_geometry(self) -> SocketLinker:
|
|
462
|
+
"""Input socket: Geometry"""
|
|
463
|
+
return self._input("Geometry")
|
|
464
|
+
|
|
465
|
+
@property
|
|
466
|
+
def o_geometry(self) -> SocketLinker:
|
|
467
|
+
"""Output socket: Geometry"""
|
|
468
|
+
return self._output("Geometry")
|
|
469
|
+
|
|
470
|
+
@property
|
|
471
|
+
def domain(
|
|
472
|
+
self,
|
|
473
|
+
) -> _AttributeDomains:
|
|
573
474
|
return self.node.domain
|
|
574
475
|
|
|
575
476
|
@domain.setter
|
|
576
477
|
def domain(
|
|
577
478
|
self,
|
|
578
|
-
value:
|
|
479
|
+
value: _AttributeDomains,
|
|
579
480
|
):
|
|
580
481
|
self.node.domain = value
|