nodebpy 0.3.0__py3-none-any.whl → 0.3.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.
@@ -14,7 +14,9 @@ from ..types import (
14
14
 
15
15
 
16
16
  class DialGizmo(NodeBuilder):
17
- """Show a dial gizmo in the viewport for a value"""
17
+ """
18
+ Show a dial gizmo in the viewport for a value
19
+ """
18
20
 
19
21
  _bl_idname = "GeometryNodeGizmoDial"
20
22
  node: bpy.types.GeometryNodeGizmoDial
@@ -80,7 +82,9 @@ class DialGizmo(NodeBuilder):
80
82
 
81
83
 
82
84
  class EnableOutput(NodeBuilder):
83
- """Either pass through the input value or output the fallback value"""
85
+ """
86
+ Either pass through the input value or output the fallback value
87
+ """
84
88
 
85
89
  _bl_idname = "NodeEnableOutput"
86
90
  node: bpy.types.Node
@@ -258,7 +262,9 @@ class EnableOutput(NodeBuilder):
258
262
 
259
263
 
260
264
  class GroupInput(NodeBuilder):
261
- """Expose connected data from inside a node group as inputs to its interface"""
265
+ """
266
+ Expose connected data from inside a node group as inputs to its interface
267
+ """
262
268
 
263
269
  _bl_idname = "NodeGroupInput"
264
270
  node: bpy.types.Node
@@ -271,7 +277,9 @@ class GroupInput(NodeBuilder):
271
277
 
272
278
 
273
279
  class GroupOutput(NodeBuilder):
274
- """Output data from inside of a node group"""
280
+ """
281
+ Output data from inside of a node group
282
+ """
275
283
 
276
284
  _bl_idname = "NodeGroupOutput"
277
285
  node: bpy.types.Node
@@ -292,7 +300,9 @@ class GroupOutput(NodeBuilder):
292
300
 
293
301
 
294
302
  class LinearGizmo(NodeBuilder):
295
- """Show a linear gizmo in the viewport for a value"""
303
+ """
304
+ Show a linear gizmo in the viewport for a value
305
+ """
296
306
 
297
307
  _bl_idname = "GeometryNodeGizmoLinear"
298
308
  node: bpy.types.GeometryNodeGizmoLinear
@@ -350,7 +360,9 @@ class LinearGizmo(NodeBuilder):
350
360
 
351
361
 
352
362
  class TransformGizmo(NodeBuilder):
353
- """Show a transform gizmo in the viewport"""
363
+ """
364
+ Show a transform gizmo in the viewport
365
+ """
354
366
 
355
367
  _bl_idname = "GeometryNodeGizmoTransform"
356
368
  node: bpy.types.GeometryNodeGizmoTransform
@@ -478,7 +490,9 @@ class TransformGizmo(NodeBuilder):
478
490
 
479
491
 
480
492
  class Warning(NodeBuilder):
481
- """Create custom warnings in node groups"""
493
+ """
494
+ Create custom warnings in node groups
495
+ """
482
496
 
483
497
  _bl_idname = "GeometryNodeWarning"
484
498
  node: bpy.types.GeometryNodeWarning
nodebpy/nodes/manual.py CHANGED
@@ -35,6 +35,9 @@ from ..types import (
35
35
  _is_default_value,
36
36
  )
37
37
  from .zone import (
38
+ ForEachGeometryElementInput,
39
+ ForEachGeometryElementOutput,
40
+ ForEachGeometryElementZone,
38
41
  RepeatInput,
39
42
  RepeatOutput,
40
43
  RepeatZone,
@@ -50,6 +53,9 @@ __all__ = (
50
53
  "SimulationInput",
51
54
  "SimulationOutput",
52
55
  "SimulationZone",
56
+ "ForEachGeometryElementInput",
57
+ "ForEachGeometryElementOutput",
58
+ "ForEachGeometryElementZone",
53
59
  "GeometryToInstance",
54
60
  "SDFGridBoolean",
55
61
  #
@@ -64,12 +70,6 @@ __all__ = (
64
70
  "Bake",
65
71
  "JoinStrings",
66
72
  "GeometryToInstance",
67
- "RepeatInput",
68
- "RepeatOutput",
69
- "RepeatZone",
70
- "SimulationInput",
71
- "SimulationOutput",
72
- "SimulationZone",
73
73
  "FormatString",
74
74
  "Value",
75
75
  "AccumulateField",
nodebpy/nodes/output.py CHANGED
@@ -6,7 +6,9 @@ from ..builder import NodeBuilder
6
6
 
7
7
 
8
8
  class Viewer(NodeBuilder):
9
- """Display the input data in the Spreadsheet Editor"""
9
+ """
10
+ Display the input data in the Spreadsheet Editor
11
+ """
10
12
 
11
13
  _bl_idname = "GeometryNodeViewer"
12
14
  node: bpy.types.GeometryNodeViewer
@@ -44,6 +46,11 @@ class Viewer(NodeBuilder):
44
46
  """Create Viewer with operation 'Face'."""
45
47
  return cls(domain="FACE")
46
48
 
49
+ @classmethod
50
+ def face_corner(cls) -> "Viewer":
51
+ """Create Viewer with operation 'Face Corner'."""
52
+ return cls(domain="CORNER")
53
+
47
54
  @classmethod
48
55
  def spline(cls) -> "Viewer":
49
56
  """Create Viewer with operation 'Spline'."""
nodebpy/nodes/texture.py CHANGED
@@ -13,7 +13,9 @@ from ..types import (
13
13
 
14
14
 
15
15
  class BrickTexture(NodeBuilder):
16
- """Generate a procedural texture producing bricks"""
16
+ """
17
+ Generate a procedural texture producing bricks
18
+ """
17
19
 
18
20
  _bl_idname = "ShaderNodeTexBrick"
19
21
  node: bpy.types.ShaderNodeTexBrick
@@ -149,7 +151,9 @@ class BrickTexture(NodeBuilder):
149
151
 
150
152
 
151
153
  class CheckerTexture(NodeBuilder):
152
- """Generate a checkerboard texture"""
154
+ """
155
+ Generate a checkerboard texture
156
+ """
153
157
 
154
158
  _bl_idname = "ShaderNodeTexChecker"
155
159
  node: bpy.types.ShaderNodeTexChecker
@@ -203,7 +207,9 @@ class CheckerTexture(NodeBuilder):
203
207
 
204
208
 
205
209
  class GaborTexture(NodeBuilder):
206
- """Generate Gabor noise"""
210
+ """
211
+ Generate Gabor noise
212
+ """
207
213
 
208
214
  _bl_idname = "ShaderNodeTexGabor"
209
215
  node: bpy.types.ShaderNodeTexGabor
@@ -286,7 +292,9 @@ class GaborTexture(NodeBuilder):
286
292
 
287
293
 
288
294
  class GradientTexture(NodeBuilder):
289
- """Generate interpolated color and intensity values based on the input vector"""
295
+ """
296
+ Generate interpolated color and intensity values based on the input vector
297
+ """
290
298
 
291
299
  _bl_idname = "ShaderNodeTexGradient"
292
300
  node: bpy.types.ShaderNodeTexGradient
@@ -356,7 +364,9 @@ class GradientTexture(NodeBuilder):
356
364
 
357
365
 
358
366
  class ImageTexture(NodeBuilder):
359
- """Sample values from an image texture"""
367
+ """
368
+ Sample values from an image texture
369
+ """
360
370
 
361
371
  _bl_idname = "GeometryNodeImageTexture"
362
372
  node: bpy.types.GeometryNodeImageTexture
@@ -419,7 +429,9 @@ class ImageTexture(NodeBuilder):
419
429
 
420
430
 
421
431
  class MagicTexture(NodeBuilder):
422
- """Generate a psychedelic color texture"""
432
+ """
433
+ Generate a psychedelic color texture
434
+ """
423
435
 
424
436
  _bl_idname = "ShaderNodeTexMagic"
425
437
  node: bpy.types.ShaderNodeTexMagic
@@ -472,7 +484,9 @@ class MagicTexture(NodeBuilder):
472
484
 
473
485
 
474
486
  class NoiseTexture(NodeBuilder):
475
- """Generate fractal Perlin noise"""
487
+ """
488
+ Generate fractal Perlin noise
489
+ """
476
490
 
477
491
  _bl_idname = "ShaderNodeTexNoise"
478
492
  node: bpy.types.ShaderNodeTexNoise
@@ -614,7 +628,9 @@ class NoiseTexture(NodeBuilder):
614
628
 
615
629
 
616
630
  class VoronoiTexture(NodeBuilder):
617
- """Generate Worley noise based on the distance to random points. Typically used to generate textures such as stones, water, or biological cells"""
631
+ """
632
+ Generate Worley noise based on the distance to random points. Typically used to generate textures such as stones, water, or biological cells
633
+ """
618
634
 
619
635
  _bl_idname = "ShaderNodeTexVoronoi"
620
636
  node: bpy.types.ShaderNodeTexVoronoi
@@ -769,7 +785,9 @@ class VoronoiTexture(NodeBuilder):
769
785
 
770
786
 
771
787
  class WaveTexture(NodeBuilder):
772
- """Generate procedural bands or rings with noise"""
788
+ """
789
+ Generate procedural bands or rings with noise
790
+ """
773
791
 
774
792
  _bl_idname = "ShaderNodeTexWave"
775
793
  node: bpy.types.ShaderNodeTexWave
@@ -884,7 +902,9 @@ class WaveTexture(NodeBuilder):
884
902
 
885
903
 
886
904
  class WhiteNoiseTexture(NodeBuilder):
887
- """Calculate a random value or color based on an input seed"""
905
+ """
906
+ Calculate a random value or color based on an input seed
907
+ """
888
908
 
889
909
  _bl_idname = "ShaderNodeTexWhiteNoise"
890
910
  node: bpy.types.ShaderNodeTexWhiteNoise
nodebpy/nodes/vector.py CHANGED
@@ -10,7 +10,9 @@ from ..types import (
10
10
 
11
11
 
12
12
  class RadialTiling(NodeBuilder):
13
- """Transform Coordinate System for Radial Tiling"""
13
+ """
14
+ Transform Coordinate System for Radial Tiling
15
+ """
14
16
 
15
17
  _bl_idname = "ShaderNodeRadialTiling"
16
18
  node: bpy.types.ShaderNodeRadialTiling
@@ -73,7 +75,9 @@ class RadialTiling(NodeBuilder):
73
75
 
74
76
 
75
77
  class VectorCurves(NodeBuilder):
76
- """Map input vector components with curves"""
78
+ """
79
+ Map input vector components with curves
80
+ """
77
81
 
78
82
  _bl_idname = "ShaderNodeVectorCurve"
79
83
  node: bpy.types.ShaderNodeVectorCurve
@@ -105,7 +109,9 @@ class VectorCurves(NodeBuilder):
105
109
 
106
110
 
107
111
  class VectorMath(NodeBuilder):
108
- """Perform vector math operation"""
112
+ """
113
+ Perform vector math operation
114
+ """
109
115
 
110
116
  _bl_idname = "ShaderNodeVectorMath"
111
117
  node: bpy.types.ShaderNodeVectorMath
@@ -187,6 +193,28 @@ class VectorMath(NodeBuilder):
187
193
  """Create Vector Math with operation 'Divide'."""
188
194
  return cls(operation="DIVIDE", vector=vector, vector_001=vector_001)
189
195
 
196
+ @classmethod
197
+ def multiply_add(
198
+ cls,
199
+ vector: TYPE_INPUT_VECTOR = None,
200
+ vector_001: TYPE_INPUT_VECTOR = None,
201
+ vector_002: TYPE_INPUT_VECTOR = None,
202
+ ) -> "VectorMath":
203
+ """Create Vector Math with operation 'Multiply Add'."""
204
+ return cls(
205
+ operation="MULTIPLY_ADD",
206
+ vector=vector,
207
+ vector_001=vector_001,
208
+ vector_002=vector_002,
209
+ )
210
+
211
+ @classmethod
212
+ def cross_product(
213
+ cls, vector: TYPE_INPUT_VECTOR = None, vector_001: TYPE_INPUT_VECTOR = None
214
+ ) -> "VectorMath":
215
+ """Create Vector Math with operation 'Cross Product'."""
216
+ return cls(operation="CROSS_PRODUCT", vector=vector, vector_001=vector_001)
217
+
190
218
  @classmethod
191
219
  def project(
192
220
  cls, vector: TYPE_INPUT_VECTOR = None, vector_001: TYPE_INPUT_VECTOR = None
@@ -228,6 +256,13 @@ class VectorMath(NodeBuilder):
228
256
  vector_002=vector_002,
229
257
  )
230
258
 
259
+ @classmethod
260
+ def dot_product(
261
+ cls, vector: TYPE_INPUT_VECTOR = None, vector_001: TYPE_INPUT_VECTOR = None
262
+ ) -> "VectorMath":
263
+ """Create Vector Math with operation 'Dot Product'."""
264
+ return cls(operation="DOT_PRODUCT", vector=vector, vector_001=vector_001)
265
+
231
266
  @classmethod
232
267
  def distance(
233
268
  cls, vector: TYPE_INPUT_VECTOR = None, vector_001: TYPE_INPUT_VECTOR = None
@@ -447,7 +482,9 @@ class VectorMath(NodeBuilder):
447
482
 
448
483
 
449
484
  class VectorRotate(NodeBuilder):
450
- """Rotate a vector around a pivot point (center)"""
485
+ """
486
+ Rotate a vector around a pivot point (center)
487
+ """
451
488
 
452
489
  _bl_idname = "ShaderNodeVectorRotate"
453
490
  node: bpy.types.ShaderNodeVectorRotate
nodebpy/nodes/zone.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Literal
2
+ from typing import Iterable
3
3
 
4
4
  import bpy
5
5
 
@@ -16,8 +16,6 @@ from ..types import (
16
16
 
17
17
 
18
18
  class BaseZone(DynamicInputsMixin, NodeBuilder, ABC):
19
- _items_attribute: Literal["state_items", "repeat_items"]
20
-
21
19
  @property
22
20
  @abstractmethod
23
21
  def _items_node(
@@ -72,7 +70,11 @@ class BaseZoneInput(BaseZone, NodeBuilder, ABC):
72
70
  @property
73
71
  def output(
74
72
  self,
75
- ) -> bpy.types.GeometryNodeSimulationOutput | bpy.types.GeometryNodeRepeatOutput:
73
+ ) -> (
74
+ bpy.types.GeometryNodeSimulationOutput
75
+ | bpy.types.GeometryNodeRepeatOutput
76
+ | bpy.types.GeometryNodeForeachGeometryElementOutput
77
+ ):
76
78
  return self.node.paired_output # type: ignore
77
79
 
78
80
  def _add_socket(self, name: str, type: _BakeDataTypes):
@@ -99,7 +101,6 @@ class BaseZoneOutput(BaseZone, NodeBuilder, ABC):
99
101
 
100
102
 
101
103
  class BaseSimulationZone(BaseZone):
102
- _items_attribute = "state_items"
103
104
  _socket_data_types = (
104
105
  "VALUE",
105
106
  "INT",
@@ -168,7 +169,6 @@ class SimulationZone:
168
169
 
169
170
 
170
171
  class BaseRepeatZone(BaseZone):
171
- _items_attribute = "repeat_items"
172
172
  _socket_data_types = (
173
173
  "FLOAT",
174
174
  "INT",
@@ -208,12 +208,6 @@ class RepeatInput(BaseRepeatZone, BaseZoneInput):
208
208
  """Output socket: Iteration"""
209
209
  return self._output("Iteration")
210
210
 
211
- @property
212
- def output_node(self) -> bpy.types.GeometryNodeRepeatOutput:
213
- zone_output = self.node.paired_output # type: ignore
214
- assert zone_output is not None
215
- return zone_output # type: ignore
216
-
217
211
 
218
212
  class RepeatOutput(BaseRepeatZone, BaseZoneOutput):
219
213
  """Repeat Output node"""
@@ -253,25 +247,78 @@ class RepeatZone:
253
247
  return self.i, self.input, self.output
254
248
 
255
249
 
256
- class ForEachGeometryElementInput(NodeBuilder):
250
+ class ForEachGeometryElementZone:
251
+ def __init__(
252
+ self,
253
+ geometry: TYPE_INPUT_GEOMETRY = None,
254
+ selection: TYPE_INPUT_BOOLEAN = True,
255
+ *,
256
+ domain: _AttributeDomains = "POINT",
257
+ ):
258
+ self.input = ForEachGeometryElementInput()
259
+ self.output = ForEachGeometryElementOutput()
260
+ self.input.node.pair_with_output(self.output.node)
261
+ self.output.domain = domain
262
+ self.input._establish_links(Geometry=geometry, Selection=selection)
263
+
264
+ @property
265
+ def index(self) -> SocketLinker:
266
+ return self.input.o_index
267
+
268
+ def __getitem__(self, index: int):
269
+ match index:
270
+ case 0:
271
+ return self.input
272
+ case 1:
273
+ return self.output
274
+ case _:
275
+ raise IndexError("ForEachZone has only two items")
276
+
277
+
278
+ class ForEachGeometryElementInput(BaseZoneInput):
257
279
  """For Each Geometry Element Input node"""
258
280
 
281
+ _socket_data_types = (
282
+ "VALUE",
283
+ "INT",
284
+ "BOOLEAN",
285
+ "VECTOR",
286
+ "RGBA",
287
+ "ROTATION",
288
+ "MATRIX",
289
+ "MENU",
290
+ )
291
+ _type_map = {"VALUE": "FLOAT"}
292
+
259
293
  _bl_idname = "GeometryNodeForeachGeometryElementInput"
260
294
  node: bpy.types.GeometryNodeForeachGeometryElementInput
261
295
 
262
296
  def __init__(
263
- self,
264
- geometry: TYPE_INPUT_GEOMETRY = None,
265
- selection: TYPE_INPUT_BOOLEAN = True,
266
- extend: LINKABLE | None = None,
267
- **kwargs,
297
+ self, geometry: TYPE_INPUT_GEOMETRY = None, selection: TYPE_INPUT_BOOLEAN = True
268
298
  ):
269
299
  super().__init__()
270
- key_args = {"Geometry": geometry, "Selection": selection, "__extend__": extend}
271
- key_args.update(kwargs)
272
-
300
+ key_args = {"Geometry": geometry, "Selection": selection}
273
301
  self._establish_links(**key_args)
274
302
 
303
+ def capture(
304
+ self, value: LINKABLE, domain: _AttributeDomains = "POINT"
305
+ ) -> SocketLinker:
306
+ """Capture something as an input to the simulation"""
307
+ item_dict = self._add_inputs(value)
308
+ self._establish_links(**item_dict)
309
+ new_output_idx = [o.identifier for o in self.node.outputs].index(
310
+ "__extend__"
311
+ ) - 1
312
+ print(f"{new_output_idx=}")
313
+ output = self.node.outputs[new_output_idx]
314
+ print(f"{output=} {output.type=}")
315
+
316
+ return SocketLinker(output)
317
+
318
+ @property
319
+ def items(self) -> bpy.types.NodeGeometryForeachGeometryElementInputItems:
320
+ return self.output.input_items
321
+
275
322
  @property
276
323
  def i_geometry(self) -> SocketLinker:
277
324
  """Input socket: Geometry"""
@@ -282,113 +329,100 @@ class ForEachGeometryElementInput(NodeBuilder):
282
329
  """Input socket: Selection"""
283
330
  return self._input("Selection")
284
331
 
285
- @property
286
- def i_input_socket(self) -> SocketLinker:
287
- """Input socket:"""
288
- return self._input("__extend__")
289
-
290
332
  @property
291
333
  def o_index(self) -> SocketLinker:
292
334
  """Output socket: Index"""
293
335
  return self._output("Index")
294
336
 
295
- @property
296
- def o_input_socket(self) -> SocketLinker:
297
- """Output socket:"""
298
- return self._output("__extend__")
299
-
300
337
 
301
- class ForEachGeometryElementOutput(NodeBuilder):
338
+ class ForEachGeometryElementOutput(BaseZoneOutput):
302
339
  """For Each Geometry Element Output node"""
303
340
 
341
+ _socket_data_types = [
342
+ "VALUE",
343
+ "INT",
344
+ "BOOLEAN",
345
+ "VECTOR",
346
+ "RGBA",
347
+ "ROTATION",
348
+ "MATRIX",
349
+ ]
350
+ _type_map = {"VALUE": "FLOAT"}
351
+
304
352
  _bl_idname = "GeometryNodeForeachGeometryElementOutput"
305
353
  node: bpy.types.GeometryNodeForeachGeometryElementOutput
306
354
 
307
355
  def __init__(
308
356
  self,
309
- extend_main: LINKABLE | None = None,
310
- generation_0: LINKABLE = None,
311
- extend_generation: LINKABLE | None = None,
312
- active_input_index: int = 0,
313
- active_generation_index: int = 0,
314
- active_main_index: int = 0,
315
357
  domain: _AttributeDomains = "POINT",
316
- inspection_index: int = 0,
317
358
  **kwargs,
318
359
  ):
319
360
  super().__init__()
320
- key_args = {
321
- "__extend__main": extend_main,
322
- "Generation_0": generation_0,
323
- "__extend__generation": extend_generation,
324
- }
361
+ key_args = {}
325
362
  key_args.update(kwargs)
326
- self.active_input_index = active_input_index
327
- self.active_generation_index = active_generation_index
328
- self.active_main_index = active_main_index
329
363
  self.domain = domain
330
- self.inspection_index = inspection_index
331
364
  self._establish_links(**key_args)
332
365
 
333
366
  @property
334
- def i_input_socket(self) -> SocketLinker:
335
- """Input socket:"""
336
- return self._input("__extend__main")
367
+ def items(self) -> bpy.types.NodeGeometryForeachGeometryElementMainItems:
368
+ return self.node.main_items
369
+
370
+ @property
371
+ def items_generated(
372
+ self,
373
+ ) -> bpy.types.NodeGeometryForeachGeometryElementGenerationItems:
374
+ return self.node.generation_items
375
+
376
+ def _latest(
377
+ self, suffix: str, sockets: Iterable[bpy.types.NodeSocket]
378
+ ) -> bpy.types.NodeSocket:
379
+ idx = [o.identifier for o in sockets].index(f"__extend__{suffix}") - 1
380
+ return sockets[idx]
381
+
382
+ def capture(
383
+ self, value: LINKABLE, domain: _AttributeDomains = "POINT"
384
+ ) -> SocketLinker:
385
+ """Capture something as an input to the simulation"""
386
+ item_dict = self._add_inputs(value)
387
+ self._establish_links(**item_dict)
388
+ return SocketLinker(self._latest("main", self.node.outputs))
389
+
390
+ def capture_generated(self, value: LINKABLE) -> SocketLinker:
391
+ self._socket_data_types = self._socket_data_types + ["GEOMETRY"]
392
+ self._add_socket = self._add_socket_generated
393
+ item_dict = self._add_inputs(value)
394
+ self._establish_links(**item_dict)
395
+ self._socket_data_types = list(
396
+ [x for x in self._socket_data_types if x != "GEOMETRY"]
397
+ )
398
+ self._add_socket = self._add_socket_main
399
+ return SocketLinker(self._latest("generation", self.node.outputs))
400
+
401
+ def _add_socket_main(self, name: str, type: _BakeDataTypes):
402
+ """Add a socket to the zone"""
403
+ _ = self.items.new(type, name)
404
+ return self._latest("main", self.node.inputs)
405
+
406
+ def _add_socket_generated(self, name: str, type: _BakeDataTypes):
407
+ """Add a socket to the zone"""
408
+ _ = self.items_generated.new(type, name)
409
+ return self._latest("generation", self.node.inputs)
337
410
 
338
411
  @property
339
412
  def i_geometry(self) -> SocketLinker:
340
413
  """Input socket: Geometry"""
341
414
  return self._input("Generation_0")
342
415
 
343
- @property
344
- def i_extend_generation(self) -> SocketLinker:
345
- """Input socket:"""
346
- return self._input("__extend__generation")
347
-
348
416
  @property
349
417
  def o_geometry(self) -> SocketLinker:
350
418
  """Output socket: Geometry"""
351
419
  return self._output("Geometry")
352
420
 
353
421
  @property
354
- def o_input_socket(self) -> SocketLinker:
355
- """Output socket:"""
356
- return self._output("__extend__main")
357
-
358
- @property
359
- def o_generation_0(self) -> SocketLinker:
422
+ def o_generation(self) -> SocketLinker:
360
423
  """Output socket: Geometry"""
361
424
  return self._output("Generation_0")
362
425
 
363
- @property
364
- def o_extend_generation(self) -> SocketLinker:
365
- """Output socket:"""
366
- return self._output("__extend__generation")
367
-
368
- @property
369
- def active_input_index(self) -> int:
370
- return self.node.active_input_index
371
-
372
- @active_input_index.setter
373
- def active_input_index(self, value: int):
374
- self.node.active_input_index = value
375
-
376
- @property
377
- def active_generation_index(self) -> int:
378
- return self.node.active_generation_index
379
-
380
- @active_generation_index.setter
381
- def active_generation_index(self, value: int):
382
- self.node.active_generation_index = value
383
-
384
- @property
385
- def active_main_index(self) -> int:
386
- return self.node.active_main_index
387
-
388
- @active_main_index.setter
389
- def active_main_index(self, value: int):
390
- self.node.active_main_index = value
391
-
392
426
  @property
393
427
  def domain(
394
428
  self,
@@ -401,11 +435,3 @@ class ForEachGeometryElementOutput(NodeBuilder):
401
435
  value: _AttributeDomains,
402
436
  ):
403
437
  self.node.domain = value
404
-
405
- @property
406
- def inspection_index(self) -> int:
407
- return self.node.inspection_index
408
-
409
- @inspection_index.setter
410
- def inspection_index(self, value: int):
411
- self.node.inspection_index = value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nodebpy
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Build nodes in Blender with code
5
5
  Author: Brady Johnston
6
6
  Author-email: Brady Johnston <brady.johnston@me.com>
@@ -158,3 +158,13 @@ actually build.
158
158
  - `TransformGeometry.matrix(CombineTrasnsform(translation=(0, 0, 1))`
159
159
  - `TransformGeoemtry.components(translation=(0, 0, 1))`
160
160
  - `TransformGeometry(translation=(0, 0, 1))`
161
+
162
+ ## Building
163
+
164
+ Most node classes are generated automatically with this. The nodes in
165
+ `nodes/manual.py` are currently manually specified due to varying
166
+ complexities of particular nodes (usually lergacy).
167
+
168
+ ``` bash
169
+ uv run generate.py && ruff format && ruff check --fix --unsafe-fixes
170
+ ```