nodebpy 0.2.0__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.
@@ -3,114 +3,128 @@ from typing import Literal
3
3
  import bpy
4
4
 
5
5
  from ..builder import NodeBuilder, SocketLinker
6
- from .types import (
7
- LINKABLE,
6
+ from ..types import (
8
7
  TYPE_INPUT_BOOLEAN,
9
8
  TYPE_INPUT_GEOMETRY,
10
9
  TYPE_INPUT_INT,
11
10
  TYPE_INPUT_MENU,
12
11
  TYPE_INPUT_STRING,
12
+ TYPE_INPUT_ROTATION,
13
+ TYPE_INPUT_COLOR,
13
14
  TYPE_INPUT_VALUE,
14
- _AttributeDataTypes,
15
- _AttributeDomains,
16
- _StoreNamedAttributeTypes,
15
+ TYPE_INPUT_VECTOR,
17
16
  )
18
17
 
19
18
 
20
- class DomainSize(NodeBuilder):
21
- """Retrieve the number of elements in a geometry for each attribute domain"""
19
+ class BlurAttribute(NodeBuilder):
20
+ """Mix attribute values of neighboring elements"""
22
21
 
23
- name = "GeometryNodeAttributeDomainSize"
24
- node: bpy.types.GeometryNodeAttributeDomainSize
22
+ _bl_idname = "GeometryNodeBlurAttribute"
23
+ node: bpy.types.GeometryNodeBlurAttribute
25
24
 
26
25
  def __init__(
27
26
  self,
28
- geometry: TYPE_INPUT_GEOMETRY = None,
27
+ value: TYPE_INPUT_VALUE = 0.0,
28
+ iterations: TYPE_INPUT_INT = 1,
29
+ weight: TYPE_INPUT_VALUE = 1.0,
29
30
  *,
30
- component: Literal[
31
- "MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"
32
- ] = "MESH",
31
+ data_type: Literal["FLOAT", "INT", "FLOAT_VECTOR", "FLOAT_COLOR"] = "FLOAT",
33
32
  ):
34
33
  super().__init__()
35
- key_args = {"Geometry": geometry}
36
- self.component = component
34
+ key_args = {"Value": value, "Iterations": iterations, "Weight": weight}
35
+ self.data_type = data_type
37
36
  self._establish_links(**key_args)
38
37
 
39
- @property
40
- def i_geometry(self) -> SocketLinker:
41
- """Input socket: Geometry"""
42
- return self._input("Geometry")
38
+ @classmethod
39
+ def float(
40
+ cls,
41
+ value: TYPE_INPUT_VALUE = 0.0,
42
+ iterations: TYPE_INPUT_INT = 1,
43
+ weight: TYPE_INPUT_VALUE = 1.0,
44
+ ) -> "BlurAttribute":
45
+ """Create Blur Attribute with operation 'Float'."""
46
+ return cls(data_type="FLOAT", value=value, iterations=iterations, weight=weight)
47
+
48
+ @classmethod
49
+ def integer(
50
+ cls,
51
+ value: TYPE_INPUT_INT = 0,
52
+ iterations: TYPE_INPUT_INT = 1,
53
+ weight: TYPE_INPUT_VALUE = 1.0,
54
+ ) -> "BlurAttribute":
55
+ """Create Blur Attribute with operation 'Integer'."""
56
+ return cls(data_type="INT", value=value, iterations=iterations, weight=weight)
57
+
58
+ @classmethod
59
+ def vector(
60
+ cls,
61
+ value: TYPE_INPUT_VECTOR = None,
62
+ iterations: TYPE_INPUT_INT = 1,
63
+ weight: TYPE_INPUT_VALUE = 1.0,
64
+ ) -> "BlurAttribute":
65
+ """Create Blur Attribute with operation 'Vector'."""
66
+ return cls(
67
+ data_type="FLOAT_VECTOR", value=value, iterations=iterations, weight=weight
68
+ )
69
+
70
+ @classmethod
71
+ def color(
72
+ cls,
73
+ value: TYPE_INPUT_COLOR = None,
74
+ iterations: TYPE_INPUT_INT = 1,
75
+ weight: TYPE_INPUT_VALUE = 1.0,
76
+ ) -> "BlurAttribute":
77
+ """Create Blur Attribute with operation 'Color'."""
78
+ return cls(
79
+ data_type="FLOAT_COLOR", value=value, iterations=iterations, weight=weight
80
+ )
43
81
 
44
82
  @property
45
- def o_point_count(self) -> SocketLinker:
46
- """Output socket: Point Count"""
47
- return self._output("Point Count")
83
+ def i_value(self) -> SocketLinker:
84
+ """Input socket: Value"""
85
+ return self._input("Value")
48
86
 
49
87
  @property
50
- def o_edge_count(self) -> SocketLinker:
51
- """Output socket: Edge Count"""
52
- return self._output("Edge Count")
88
+ def i_iterations(self) -> SocketLinker:
89
+ """Input socket: Iterations"""
90
+ return self._input("Iterations")
53
91
 
54
92
  @property
55
- def o_face_count(self) -> SocketLinker:
56
- """Output socket: Face Count"""
57
- return self._output("Face Count")
93
+ def i_weight(self) -> SocketLinker:
94
+ """Input socket: Weight"""
95
+ return self._input("Weight")
58
96
 
59
97
  @property
60
- def o_face_corner_count(self) -> SocketLinker:
61
- """Output socket: Face Corner Count"""
62
- return self._output("Face Corner Count")
98
+ def o_value(self) -> SocketLinker:
99
+ """Output socket: Value"""
100
+ return self._output("Value")
63
101
 
64
102
  @property
65
- def component(
66
- self,
67
- ) -> Literal["MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"]:
68
- return self.node.component
103
+ def data_type(self) -> Literal["FLOAT", "INT", "FLOAT_VECTOR", "FLOAT_COLOR"]:
104
+ return self.node.data_type
69
105
 
70
- @component.setter
71
- def component(
72
- self, value: Literal["MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"]
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"
81
- self.node.component = value
106
+ @data_type.setter
107
+ def data_type(self, value: Literal["FLOAT", "INT", "FLOAT_VECTOR", "FLOAT_COLOR"]):
108
+ self.node.data_type = value
82
109
 
83
110
 
84
- class AttributeStatistic(NodeBuilder):
85
- """Calculate statistics about a data set from a field evaluated on a geometry"""
111
+ class DomainSize(NodeBuilder):
112
+ """Retrieve the number of elements in a geometry for each attribute domain"""
86
113
 
87
- name = "GeometryNodeAttributeStatistic"
88
- node: bpy.types.GeometryNodeAttributeStatistic
114
+ _bl_idname = "GeometryNodeAttributeDomainSize"
115
+ node: bpy.types.GeometryNodeAttributeDomainSize
89
116
 
90
117
  def __init__(
91
118
  self,
92
119
  geometry: TYPE_INPUT_GEOMETRY = None,
93
- selection: TYPE_INPUT_BOOLEAN = True,
94
- attribute: LINKABLE = None,
95
120
  *,
96
- data_type: Literal[
97
- "FLOAT",
98
- "FLOAT_VECTOR",
99
- ] = "FLOAT",
100
- domain: Literal[
101
- "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
102
- ] = "POINT",
103
- **kwargs,
121
+ component: Literal[
122
+ "MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"
123
+ ] = "MESH",
104
124
  ):
105
125
  super().__init__()
106
- key_args = {
107
- "Geometry": geometry,
108
- "Selection": selection,
109
- "Attribute": attribute,
110
- }
111
- key_args.update(kwargs)
112
- self.data_type = data_type
113
- self.domain = domain
126
+ key_args = {"Geometry": geometry}
127
+ self.component = component
114
128
  self._establish_links(**key_args)
115
129
 
116
130
  @property
@@ -119,170 +133,68 @@ class AttributeStatistic(NodeBuilder):
119
133
  return self._input("Geometry")
120
134
 
121
135
  @property
122
- def i_selection(self) -> SocketLinker:
123
- """Input socket: Selection"""
124
- return self._input("Selection")
125
-
126
- @property
127
- def i_attribute(self) -> SocketLinker:
128
- """Input socket: Attribute"""
129
- return self._input("Attribute")
130
-
131
- @property
132
- def o_mean(self) -> SocketLinker:
133
- """Output socket: Mean"""
134
- return self._output("Mean")
135
-
136
- @property
137
- def o_median(self) -> SocketLinker:
138
- """Output socket: Median"""
139
- return self._output("Median")
140
-
141
- @property
142
- def o_sum(self) -> SocketLinker:
143
- """Output socket: Sum"""
144
- return self._output("Sum")
145
-
146
- @property
147
- def o_min(self) -> SocketLinker:
148
- """Output socket: Min"""
149
- return self._output("Min")
150
-
151
- @property
152
- def o_max(self) -> SocketLinker:
153
- """Output socket: Max"""
154
- return self._output("Max")
155
-
156
- @property
157
- def o_range(self) -> SocketLinker:
158
- """Output socket: Range"""
159
- return self._output("Range")
160
-
161
- @property
162
- def o_standard_deviation(self) -> SocketLinker:
163
- """Output socket: Standard Deviation"""
164
- return self._output("Standard Deviation")
165
-
166
- @property
167
- def o_variance(self) -> SocketLinker:
168
- """Output socket: Variance"""
169
- return self._output("Variance")
136
+ def o_point_count(self) -> SocketLinker:
137
+ """Output socket: Point Count"""
138
+ return self._output("Point Count")
170
139
 
171
140
  @property
172
- def data_type(
173
- self,
174
- ) -> Literal[
175
- "FLOAT",
176
- "FLOAT_VECTOR",
177
- ]:
178
- return self.node.data_type # type: ignore
179
-
180
- @data_type.setter
181
- def data_type(
182
- self,
183
- value: Literal[
184
- "FLOAT",
185
- "FLOAT_VECTOR",
186
- ],
187
- ):
188
- self.node.data_type = value
141
+ def o_edge_count(self) -> SocketLinker:
142
+ """Output socket: Edge Count"""
143
+ return self._output("Edge Count")
189
144
 
190
145
  @property
191
- def domain(
192
- self,
193
- ) -> _AttributeDomains:
194
- return self.node.domain
195
-
196
- @domain.setter
197
- def domain(
198
- self,
199
- value: _AttributeDomains,
200
- ):
201
- self.node.domain = value
202
-
203
-
204
- class BlurAttribute(NodeBuilder):
205
- """Mix attribute values of neighboring elements"""
206
-
207
- name = "GeometryNodeBlurAttribute"
208
- node: bpy.types.GeometryNodeBlurAttribute
209
-
210
- def __init__(
211
- self,
212
- value: LINKABLE = None,
213
- iterations: TYPE_INPUT_INT = 1,
214
- weight: TYPE_INPUT_VALUE = 1.0,
215
- *,
216
- data_type: Literal[
217
- "FLOAT",
218
- "INT",
219
- "FLOAT_VECTOR",
220
- "FLOAT_COLOR",
221
- ] = "FLOAT",
222
- ):
223
- super().__init__()
224
- key_args = {"Value": value, "Iterations": iterations, "Weight": weight}
225
- self.data_type = data_type
226
- self._establish_links(**key_args)
146
+ def o_face_count(self) -> SocketLinker:
147
+ """Output socket: Face Count"""
148
+ return self._output("Face Count")
227
149
 
228
150
  @property
229
- def i_value(self) -> SocketLinker:
230
- """Input socket: Value"""
231
- return self._input("Value")
151
+ def o_face_corner_count(self) -> SocketLinker:
152
+ """Output socket: Face Corner Count"""
153
+ return self._output("Face Corner Count")
232
154
 
233
155
  @property
234
- def i_iterations(self) -> SocketLinker:
235
- """Input socket: Iterations"""
236
- return self._input("Iterations")
156
+ def o_spline_count(self) -> SocketLinker:
157
+ """Output socket: Spline Count"""
158
+ return self._output("Spline Count")
237
159
 
238
160
  @property
239
- def i_weight(self) -> SocketLinker:
240
- """Input socket: Weight"""
241
- return self._input("Weight")
161
+ def o_instance_count(self) -> SocketLinker:
162
+ """Output socket: Instance Count"""
163
+ return self._output("Instance Count")
242
164
 
243
165
  @property
244
- def o_value(self) -> SocketLinker:
245
- """Output socket: Value"""
246
- return self._output("Value")
166
+ def o_layer_count(self) -> SocketLinker:
167
+ """Output socket: Layer Count"""
168
+ return self._output("Layer Count")
247
169
 
248
170
  @property
249
- def data_type(
171
+ def component(
250
172
  self,
251
- ) -> Literal[
252
- "FLOAT",
253
- "INT",
254
- "FLOAT_VECTOR",
255
- "FLOAT_COLOR",
256
- ]:
257
- return self.node.data_type # type: ignore
173
+ ) -> Literal["MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"]:
174
+ return self.node.component
258
175
 
259
- @data_type.setter
260
- def data_type(
261
- self,
262
- value: Literal[
263
- "FLOAT",
264
- "INT",
265
- "FLOAT_VECTOR",
266
- "FLOAT_COLOR",
267
- ],
176
+ @component.setter
177
+ def component(
178
+ self, value: Literal["MESH", "POINTCLOUD", "CURVE", "INSTANCES", "GREASEPENCIL"]
268
179
  ):
269
- self.node.data_type = value
180
+ self.node.component = value
270
181
 
271
182
 
272
183
  class RemoveNamedAttribute(NodeBuilder):
273
184
  """Delete an attribute with a specified name from a geometry. Typically used to optimize performance"""
274
185
 
275
- name = "GeometryNodeRemoveAttribute"
186
+ _bl_idname = "GeometryNodeRemoveAttribute"
276
187
  node: bpy.types.GeometryNodeRemoveAttribute
277
188
 
278
189
  def __init__(
279
190
  self,
280
191
  geometry: TYPE_INPUT_GEOMETRY = None,
281
- pattern_mode: Literal["Exact", "Wildcard"] | TYPE_INPUT_MENU = "Exact",
192
+ pattern_mode: TYPE_INPUT_MENU = "Exact",
282
193
  name: TYPE_INPUT_STRING = "",
283
194
  ):
284
195
  super().__init__()
285
196
  key_args = {"Geometry": geometry, "Pattern Mode": pattern_mode, "Name": name}
197
+
286
198
  self._establish_links(**key_args)
287
199
 
288
200
  @property
@@ -309,7 +221,7 @@ class RemoveNamedAttribute(NodeBuilder):
309
221
  class StoreNamedAttribute(NodeBuilder):
310
222
  """Store the result of a field on a geometry as an attribute with the specified name"""
311
223
 
312
- name = "GeometryNodeStoreNamedAttribute"
224
+ _bl_idname = "GeometryNodeStoreNamedAttribute"
313
225
  node: bpy.types.GeometryNodeStoreNamedAttribute
314
226
 
315
227
  def __init__(
@@ -317,10 +229,23 @@ class StoreNamedAttribute(NodeBuilder):
317
229
  geometry: TYPE_INPUT_GEOMETRY = None,
318
230
  selection: TYPE_INPUT_BOOLEAN = True,
319
231
  name: TYPE_INPUT_STRING = "",
320
- value: LINKABLE = None,
232
+ value: TYPE_INPUT_VALUE = 0.0,
321
233
  *,
322
- data_type: _StoreNamedAttributeTypes = "FLOAT",
323
- domain: _AttributeDomains = "POINT",
234
+ data_type: Literal[
235
+ "FLOAT",
236
+ "INT",
237
+ "BOOLEAN",
238
+ "FLOAT_VECTOR",
239
+ "FLOAT_COLOR",
240
+ "QUATERNION",
241
+ "FLOAT4X4",
242
+ "INT8",
243
+ "FLOAT2",
244
+ "BYTE_COLOR",
245
+ ] = "FLOAT",
246
+ domain: Literal[
247
+ "POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"
248
+ ] = "POINT",
324
249
  ):
325
250
  super().__init__()
326
251
  key_args = {
@@ -333,6 +258,210 @@ class StoreNamedAttribute(NodeBuilder):
333
258
  self.domain = domain
334
259
  self._establish_links(**key_args)
335
260
 
261
+ @classmethod
262
+ def float(
263
+ cls,
264
+ geometry: TYPE_INPUT_GEOMETRY = None,
265
+ selection: TYPE_INPUT_BOOLEAN = True,
266
+ name: TYPE_INPUT_STRING = "",
267
+ value: TYPE_INPUT_VALUE = 0.0,
268
+ ) -> "StoreNamedAttribute":
269
+ """Create Store Named Attribute with operation 'Float'."""
270
+ return cls(
271
+ data_type="FLOAT",
272
+ geometry=geometry,
273
+ selection=selection,
274
+ name=name,
275
+ value=value,
276
+ )
277
+
278
+ @classmethod
279
+ def integer(
280
+ cls,
281
+ geometry: TYPE_INPUT_GEOMETRY = None,
282
+ selection: TYPE_INPUT_BOOLEAN = True,
283
+ name: TYPE_INPUT_STRING = "",
284
+ value: TYPE_INPUT_INT = 0,
285
+ ) -> "StoreNamedAttribute":
286
+ """Create Store Named Attribute with operation 'Integer'."""
287
+ return cls(
288
+ data_type="INT",
289
+ geometry=geometry,
290
+ selection=selection,
291
+ name=name,
292
+ value=value,
293
+ )
294
+
295
+ @classmethod
296
+ def boolean(
297
+ cls,
298
+ geometry: TYPE_INPUT_GEOMETRY = None,
299
+ selection: TYPE_INPUT_BOOLEAN = True,
300
+ name: TYPE_INPUT_STRING = "",
301
+ value: TYPE_INPUT_BOOLEAN = False,
302
+ ) -> "StoreNamedAttribute":
303
+ """Create Store Named Attribute with operation 'Boolean'."""
304
+ return cls(
305
+ data_type="BOOLEAN",
306
+ geometry=geometry,
307
+ selection=selection,
308
+ name=name,
309
+ value=value,
310
+ )
311
+
312
+ @classmethod
313
+ def vector(
314
+ cls,
315
+ geometry: TYPE_INPUT_GEOMETRY = None,
316
+ selection: TYPE_INPUT_BOOLEAN = True,
317
+ name: TYPE_INPUT_STRING = "",
318
+ value: TYPE_INPUT_VECTOR = None,
319
+ ) -> "StoreNamedAttribute":
320
+ """Create Store Named Attribute with operation 'Vector'."""
321
+ return cls(
322
+ data_type="FLOAT_VECTOR",
323
+ geometry=geometry,
324
+ selection=selection,
325
+ name=name,
326
+ value=value,
327
+ )
328
+
329
+ @classmethod
330
+ def color(
331
+ cls,
332
+ geometry: TYPE_INPUT_GEOMETRY = None,
333
+ selection: TYPE_INPUT_BOOLEAN = True,
334
+ name: TYPE_INPUT_STRING = "",
335
+ value: TYPE_INPUT_COLOR = None,
336
+ ) -> "StoreNamedAttribute":
337
+ """Create Store Named Attribute with operation 'Color'."""
338
+ return cls(
339
+ data_type="FLOAT_COLOR",
340
+ geometry=geometry,
341
+ selection=selection,
342
+ name=name,
343
+ value=value,
344
+ )
345
+
346
+ @classmethod
347
+ def quaternion(
348
+ cls,
349
+ geometry: TYPE_INPUT_GEOMETRY = None,
350
+ selection: TYPE_INPUT_BOOLEAN = True,
351
+ name: TYPE_INPUT_STRING = "",
352
+ value: TYPE_INPUT_ROTATION = None,
353
+ ) -> "StoreNamedAttribute":
354
+ """Create Store Named Attribute with operation 'Quaternion'."""
355
+ return cls(
356
+ data_type="QUATERNION",
357
+ geometry=geometry,
358
+ selection=selection,
359
+ name=name,
360
+ value=value,
361
+ )
362
+
363
+ @classmethod
364
+ def point(
365
+ cls,
366
+ geometry: TYPE_INPUT_GEOMETRY = None,
367
+ selection: TYPE_INPUT_BOOLEAN = True,
368
+ name: TYPE_INPUT_STRING = "",
369
+ value: TYPE_INPUT_COLOR = None,
370
+ ) -> "StoreNamedAttribute":
371
+ """Create Store Named Attribute with operation 'Point'."""
372
+ return cls(
373
+ domain="POINT",
374
+ geometry=geometry,
375
+ selection=selection,
376
+ name=name,
377
+ value=value,
378
+ )
379
+
380
+ @classmethod
381
+ def edge(
382
+ cls,
383
+ geometry: TYPE_INPUT_GEOMETRY = None,
384
+ selection: TYPE_INPUT_BOOLEAN = True,
385
+ name: TYPE_INPUT_STRING = "",
386
+ value: TYPE_INPUT_COLOR = None,
387
+ ) -> "StoreNamedAttribute":
388
+ """Create Store Named Attribute with operation 'Edge'."""
389
+ return cls(
390
+ domain="EDGE",
391
+ geometry=geometry,
392
+ selection=selection,
393
+ name=name,
394
+ value=value,
395
+ )
396
+
397
+ @classmethod
398
+ def face(
399
+ cls,
400
+ geometry: TYPE_INPUT_GEOMETRY = None,
401
+ selection: TYPE_INPUT_BOOLEAN = True,
402
+ name: TYPE_INPUT_STRING = "",
403
+ value: TYPE_INPUT_COLOR = None,
404
+ ) -> "StoreNamedAttribute":
405
+ """Create Store Named Attribute with operation 'Face'."""
406
+ return cls(
407
+ domain="FACE",
408
+ geometry=geometry,
409
+ selection=selection,
410
+ name=name,
411
+ value=value,
412
+ )
413
+
414
+ @classmethod
415
+ def spline(
416
+ cls,
417
+ geometry: TYPE_INPUT_GEOMETRY = None,
418
+ selection: TYPE_INPUT_BOOLEAN = True,
419
+ name: TYPE_INPUT_STRING = "",
420
+ value: TYPE_INPUT_COLOR = None,
421
+ ) -> "StoreNamedAttribute":
422
+ """Create Store Named Attribute with operation 'Spline'."""
423
+ return cls(
424
+ domain="CURVE",
425
+ geometry=geometry,
426
+ selection=selection,
427
+ name=name,
428
+ value=value,
429
+ )
430
+
431
+ @classmethod
432
+ def instance(
433
+ cls,
434
+ geometry: TYPE_INPUT_GEOMETRY = None,
435
+ selection: TYPE_INPUT_BOOLEAN = True,
436
+ name: TYPE_INPUT_STRING = "",
437
+ value: TYPE_INPUT_COLOR = None,
438
+ ) -> "StoreNamedAttribute":
439
+ """Create Store Named Attribute with operation 'Instance'."""
440
+ return cls(
441
+ domain="INSTANCE",
442
+ geometry=geometry,
443
+ selection=selection,
444
+ name=name,
445
+ value=value,
446
+ )
447
+
448
+ @classmethod
449
+ def layer(
450
+ cls,
451
+ geometry: TYPE_INPUT_GEOMETRY = None,
452
+ selection: TYPE_INPUT_BOOLEAN = True,
453
+ name: TYPE_INPUT_STRING = "",
454
+ value: TYPE_INPUT_COLOR = None,
455
+ ) -> "StoreNamedAttribute":
456
+ """Create Store Named Attribute with operation 'Layer'."""
457
+ return cls(
458
+ domain="LAYER",
459
+ geometry=geometry,
460
+ selection=selection,
461
+ name=name,
462
+ value=value,
463
+ )
464
+
336
465
  @property
337
466
  def i_geometry(self) -> SocketLinker:
338
467
  """Input socket: Geometry"""
@@ -361,121 +490,47 @@ class StoreNamedAttribute(NodeBuilder):
361
490
  @property
362
491
  def data_type(
363
492
  self,
364
- ) -> _StoreNamedAttributeTypes:
365
- return self.node.data_type # type: ignore
493
+ ) -> Literal[
494
+ "FLOAT",
495
+ "INT",
496
+ "BOOLEAN",
497
+ "FLOAT_VECTOR",
498
+ "FLOAT_COLOR",
499
+ "QUATERNION",
500
+ "FLOAT4X4",
501
+ "INT8",
502
+ "FLOAT2",
503
+ "BYTE_COLOR",
504
+ ]:
505
+ return self.node.data_type
366
506
 
367
507
  @data_type.setter
368
508
  def data_type(
369
509
  self,
370
- value: _StoreNamedAttributeTypes,
510
+ value: Literal[
511
+ "FLOAT",
512
+ "INT",
513
+ "BOOLEAN",
514
+ "FLOAT_VECTOR",
515
+ "FLOAT_COLOR",
516
+ "QUATERNION",
517
+ "FLOAT4X4",
518
+ "INT8",
519
+ "FLOAT2",
520
+ "BYTE_COLOR",
521
+ ],
371
522
  ):
372
523
  self.node.data_type = value
373
524
 
374
525
  @property
375
526
  def domain(
376
527
  self,
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:
528
+ ) -> Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"]:
474
529
  return self.node.domain
475
530
 
476
531
  @domain.setter
477
532
  def domain(
478
533
  self,
479
- value: _AttributeDomains,
534
+ value: Literal["POINT", "EDGE", "FACE", "CORNER", "CURVE", "INSTANCE", "LAYER"],
480
535
  ):
481
536
  self.node.domain = value