nodebpy 0.1.1__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nodebpy/builder.py +786 -316
- nodebpy/nodes/__init__.py +641 -10
- nodebpy/nodes/attribute.py +345 -389
- nodebpy/nodes/color.py +72 -0
- nodebpy/nodes/converter.py +3527 -0
- nodebpy/nodes/experimental.py +312 -0
- nodebpy/nodes/geometry.py +3677 -4717
- nodebpy/nodes/grid.py +1713 -0
- nodebpy/nodes/group.py +17 -0
- nodebpy/nodes/input.py +1821 -316
- nodebpy/nodes/interface.py +519 -0
- nodebpy/nodes/manual.py +2022 -0
- nodebpy/nodes/output.py +85 -0
- nodebpy/nodes/texture.py +930 -0
- nodebpy/nodes/vector.py +528 -0
- nodebpy/nodes/zone.py +442 -0
- nodebpy/screenshot.py +2 -1
- nodebpy/sockets.py +12 -12
- nodebpy/types.py +445 -0
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/METADATA +5 -5
- nodebpy-0.2.1.dist-info/RECORD +26 -0
- nodebpy/nodes/curve.py +0 -2006
- nodebpy/nodes/manually_specified.py +0 -1382
- nodebpy/nodes/mesh.py +0 -1408
- nodebpy/nodes/types.py +0 -119
- nodebpy/nodes/utilities.py +0 -2344
- nodebpy-0.1.1.dist-info/RECORD +0 -19
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/WHEEL +0 -0
- {nodebpy-0.1.1.dist-info → nodebpy-0.2.1.dist-info}/entry_points.txt +0 -0
nodebpy/nodes/grid.py
ADDED
|
@@ -0,0 +1,1713 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
import bpy
|
|
4
|
+
|
|
5
|
+
from ..builder import NodeBuilder, SocketLinker
|
|
6
|
+
from ..types import (
|
|
7
|
+
TYPE_INPUT_BOOLEAN,
|
|
8
|
+
TYPE_INPUT_GEOMETRY,
|
|
9
|
+
TYPE_INPUT_INT,
|
|
10
|
+
TYPE_INPUT_MENU,
|
|
11
|
+
TYPE_INPUT_STRING,
|
|
12
|
+
TYPE_INPUT_MATRIX,
|
|
13
|
+
TYPE_INPUT_VALUE,
|
|
14
|
+
TYPE_INPUT_VECTOR,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AdvectGrid(NodeBuilder):
|
|
19
|
+
"""Move grid values through a velocity field using numerical integration. Supports multiple integration schemes for different accuracy and performance trade-offs"""
|
|
20
|
+
|
|
21
|
+
_bl_idname = "GeometryNodeGridAdvect"
|
|
22
|
+
node: bpy.types.GeometryNodeGridAdvect
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
27
|
+
velocity: TYPE_INPUT_VECTOR = None,
|
|
28
|
+
time_step: TYPE_INPUT_VALUE = 1.0,
|
|
29
|
+
integration_scheme: TYPE_INPUT_MENU = "Runge-Kutta 3",
|
|
30
|
+
limiter: TYPE_INPUT_MENU = "Clamp",
|
|
31
|
+
*,
|
|
32
|
+
data_type: Literal["FLOAT", "INT", "VECTOR"] = "FLOAT",
|
|
33
|
+
):
|
|
34
|
+
super().__init__()
|
|
35
|
+
key_args = {
|
|
36
|
+
"Grid": grid,
|
|
37
|
+
"Velocity": velocity,
|
|
38
|
+
"Time Step": time_step,
|
|
39
|
+
"Integration Scheme": integration_scheme,
|
|
40
|
+
"Limiter": limiter,
|
|
41
|
+
}
|
|
42
|
+
self.data_type = data_type
|
|
43
|
+
self._establish_links(**key_args)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def float(
|
|
47
|
+
cls,
|
|
48
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
49
|
+
velocity: TYPE_INPUT_VECTOR = None,
|
|
50
|
+
time_step: TYPE_INPUT_VALUE = 1.0,
|
|
51
|
+
integration_scheme: TYPE_INPUT_MENU = "Runge-Kutta 3",
|
|
52
|
+
limiter: TYPE_INPUT_MENU = "Clamp",
|
|
53
|
+
) -> "AdvectGrid":
|
|
54
|
+
"""Create Advect Grid with operation 'Float'."""
|
|
55
|
+
return cls(
|
|
56
|
+
data_type="FLOAT",
|
|
57
|
+
grid=grid,
|
|
58
|
+
velocity=velocity,
|
|
59
|
+
time_step=time_step,
|
|
60
|
+
integration_scheme=integration_scheme,
|
|
61
|
+
limiter=limiter,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def integer(
|
|
66
|
+
cls,
|
|
67
|
+
grid: TYPE_INPUT_INT = 0,
|
|
68
|
+
velocity: TYPE_INPUT_VECTOR = None,
|
|
69
|
+
time_step: TYPE_INPUT_VALUE = 1.0,
|
|
70
|
+
integration_scheme: TYPE_INPUT_MENU = "Runge-Kutta 3",
|
|
71
|
+
limiter: TYPE_INPUT_MENU = "Clamp",
|
|
72
|
+
) -> "AdvectGrid":
|
|
73
|
+
"""Create Advect Grid with operation 'Integer'."""
|
|
74
|
+
return cls(
|
|
75
|
+
data_type="INT",
|
|
76
|
+
grid=grid,
|
|
77
|
+
velocity=velocity,
|
|
78
|
+
time_step=time_step,
|
|
79
|
+
integration_scheme=integration_scheme,
|
|
80
|
+
limiter=limiter,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def vector(
|
|
85
|
+
cls,
|
|
86
|
+
grid: TYPE_INPUT_VECTOR = None,
|
|
87
|
+
velocity: TYPE_INPUT_VECTOR = None,
|
|
88
|
+
time_step: TYPE_INPUT_VALUE = 1.0,
|
|
89
|
+
integration_scheme: TYPE_INPUT_MENU = "Runge-Kutta 3",
|
|
90
|
+
limiter: TYPE_INPUT_MENU = "Clamp",
|
|
91
|
+
) -> "AdvectGrid":
|
|
92
|
+
"""Create Advect Grid with operation 'Vector'."""
|
|
93
|
+
return cls(
|
|
94
|
+
data_type="VECTOR",
|
|
95
|
+
grid=grid,
|
|
96
|
+
velocity=velocity,
|
|
97
|
+
time_step=time_step,
|
|
98
|
+
integration_scheme=integration_scheme,
|
|
99
|
+
limiter=limiter,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def i_grid(self) -> SocketLinker:
|
|
104
|
+
"""Input socket: Grid"""
|
|
105
|
+
return self._input("Grid")
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def i_velocity(self) -> SocketLinker:
|
|
109
|
+
"""Input socket: Velocity"""
|
|
110
|
+
return self._input("Velocity")
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def i_time_step(self) -> SocketLinker:
|
|
114
|
+
"""Input socket: Time Step"""
|
|
115
|
+
return self._input("Time Step")
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def i_integration_scheme(self) -> SocketLinker:
|
|
119
|
+
"""Input socket: Integration Scheme"""
|
|
120
|
+
return self._input("Integration Scheme")
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def i_limiter(self) -> SocketLinker:
|
|
124
|
+
"""Input socket: Limiter"""
|
|
125
|
+
return self._input("Limiter")
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def o_grid(self) -> SocketLinker:
|
|
129
|
+
"""Output socket: Grid"""
|
|
130
|
+
return self._output("Grid")
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def data_type(self) -> Literal["FLOAT", "INT", "VECTOR"]:
|
|
134
|
+
return self.node.data_type
|
|
135
|
+
|
|
136
|
+
@data_type.setter
|
|
137
|
+
def data_type(self, value: Literal["FLOAT", "INT", "VECTOR"]):
|
|
138
|
+
self.node.data_type = value
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class DistributePointsInGrid(NodeBuilder):
|
|
142
|
+
"""Generate points inside a volume grid"""
|
|
143
|
+
|
|
144
|
+
_bl_idname = "GeometryNodeDistributePointsInGrid"
|
|
145
|
+
node: bpy.types.GeometryNodeDistributePointsInGrid
|
|
146
|
+
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
150
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
151
|
+
seed: TYPE_INPUT_INT = 0,
|
|
152
|
+
spacing: TYPE_INPUT_VECTOR = None,
|
|
153
|
+
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
154
|
+
*,
|
|
155
|
+
mode: Literal["DENSITY_RANDOM", "DENSITY_GRID"] = "DENSITY_RANDOM",
|
|
156
|
+
):
|
|
157
|
+
super().__init__()
|
|
158
|
+
key_args = {
|
|
159
|
+
"Grid": grid,
|
|
160
|
+
"Density": density,
|
|
161
|
+
"Seed": seed,
|
|
162
|
+
"Spacing": spacing,
|
|
163
|
+
"Threshold": threshold,
|
|
164
|
+
}
|
|
165
|
+
self.mode = mode
|
|
166
|
+
self._establish_links(**key_args)
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def i_grid(self) -> SocketLinker:
|
|
170
|
+
"""Input socket: Grid"""
|
|
171
|
+
return self._input("Grid")
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def i_density(self) -> SocketLinker:
|
|
175
|
+
"""Input socket: Density"""
|
|
176
|
+
return self._input("Density")
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def i_seed(self) -> SocketLinker:
|
|
180
|
+
"""Input socket: Seed"""
|
|
181
|
+
return self._input("Seed")
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def i_spacing(self) -> SocketLinker:
|
|
185
|
+
"""Input socket: Spacing"""
|
|
186
|
+
return self._input("Spacing")
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def i_threshold(self) -> SocketLinker:
|
|
190
|
+
"""Input socket: Threshold"""
|
|
191
|
+
return self._input("Threshold")
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def o_points(self) -> SocketLinker:
|
|
195
|
+
"""Output socket: Points"""
|
|
196
|
+
return self._output("Points")
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def mode(self) -> Literal["DENSITY_RANDOM", "DENSITY_GRID"]:
|
|
200
|
+
return self.node.mode
|
|
201
|
+
|
|
202
|
+
@mode.setter
|
|
203
|
+
def mode(self, value: Literal["DENSITY_RANDOM", "DENSITY_GRID"]):
|
|
204
|
+
self.node.mode = value
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class DistributePointsInVolume(NodeBuilder):
|
|
208
|
+
"""Generate points inside a volume"""
|
|
209
|
+
|
|
210
|
+
_bl_idname = "GeometryNodeDistributePointsInVolume"
|
|
211
|
+
node: bpy.types.GeometryNodeDistributePointsInVolume
|
|
212
|
+
|
|
213
|
+
def __init__(
|
|
214
|
+
self,
|
|
215
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
216
|
+
mode: TYPE_INPUT_MENU = "Random",
|
|
217
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
218
|
+
seed: TYPE_INPUT_INT = 0,
|
|
219
|
+
spacing: TYPE_INPUT_VECTOR = None,
|
|
220
|
+
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
221
|
+
):
|
|
222
|
+
super().__init__()
|
|
223
|
+
key_args = {
|
|
224
|
+
"Volume": volume,
|
|
225
|
+
"Mode": mode,
|
|
226
|
+
"Density": density,
|
|
227
|
+
"Seed": seed,
|
|
228
|
+
"Spacing": spacing,
|
|
229
|
+
"Threshold": threshold,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
self._establish_links(**key_args)
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def i_volume(self) -> SocketLinker:
|
|
236
|
+
"""Input socket: Volume"""
|
|
237
|
+
return self._input("Volume")
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def i_mode(self) -> SocketLinker:
|
|
241
|
+
"""Input socket: Mode"""
|
|
242
|
+
return self._input("Mode")
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def i_density(self) -> SocketLinker:
|
|
246
|
+
"""Input socket: Density"""
|
|
247
|
+
return self._input("Density")
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def i_seed(self) -> SocketLinker:
|
|
251
|
+
"""Input socket: Seed"""
|
|
252
|
+
return self._input("Seed")
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def i_spacing(self) -> SocketLinker:
|
|
256
|
+
"""Input socket: Spacing"""
|
|
257
|
+
return self._input("Spacing")
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def i_threshold(self) -> SocketLinker:
|
|
261
|
+
"""Input socket: Threshold"""
|
|
262
|
+
return self._input("Threshold")
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def o_points(self) -> SocketLinker:
|
|
266
|
+
"""Output socket: Points"""
|
|
267
|
+
return self._output("Points")
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class GetNamedGrid(NodeBuilder):
|
|
271
|
+
"""Get volume grid from a volume geometry with the specified name"""
|
|
272
|
+
|
|
273
|
+
_bl_idname = "GeometryNodeGetNamedGrid"
|
|
274
|
+
node: bpy.types.GeometryNodeGetNamedGrid
|
|
275
|
+
|
|
276
|
+
def __init__(
|
|
277
|
+
self,
|
|
278
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
279
|
+
name: TYPE_INPUT_STRING = "",
|
|
280
|
+
remove: TYPE_INPUT_BOOLEAN = True,
|
|
281
|
+
*,
|
|
282
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
283
|
+
):
|
|
284
|
+
super().__init__()
|
|
285
|
+
key_args = {"Volume": volume, "Name": name, "Remove": remove}
|
|
286
|
+
self.data_type = data_type
|
|
287
|
+
self._establish_links(**key_args)
|
|
288
|
+
|
|
289
|
+
@classmethod
|
|
290
|
+
def float(
|
|
291
|
+
cls,
|
|
292
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
293
|
+
name: TYPE_INPUT_STRING = "",
|
|
294
|
+
remove: TYPE_INPUT_BOOLEAN = True,
|
|
295
|
+
) -> "GetNamedGrid":
|
|
296
|
+
"""Create Get Named Grid with operation 'Float'."""
|
|
297
|
+
return cls(data_type="FLOAT", volume=volume, name=name, remove=remove)
|
|
298
|
+
|
|
299
|
+
@classmethod
|
|
300
|
+
def integer(
|
|
301
|
+
cls,
|
|
302
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
303
|
+
name: TYPE_INPUT_STRING = "",
|
|
304
|
+
remove: TYPE_INPUT_BOOLEAN = True,
|
|
305
|
+
) -> "GetNamedGrid":
|
|
306
|
+
"""Create Get Named Grid with operation 'Integer'."""
|
|
307
|
+
return cls(data_type="INT", volume=volume, name=name, remove=remove)
|
|
308
|
+
|
|
309
|
+
@classmethod
|
|
310
|
+
def boolean(
|
|
311
|
+
cls,
|
|
312
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
313
|
+
name: TYPE_INPUT_STRING = "",
|
|
314
|
+
remove: TYPE_INPUT_BOOLEAN = True,
|
|
315
|
+
) -> "GetNamedGrid":
|
|
316
|
+
"""Create Get Named Grid with operation 'Boolean'."""
|
|
317
|
+
return cls(data_type="BOOLEAN", volume=volume, name=name, remove=remove)
|
|
318
|
+
|
|
319
|
+
@classmethod
|
|
320
|
+
def vector(
|
|
321
|
+
cls,
|
|
322
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
323
|
+
name: TYPE_INPUT_STRING = "",
|
|
324
|
+
remove: TYPE_INPUT_BOOLEAN = True,
|
|
325
|
+
) -> "GetNamedGrid":
|
|
326
|
+
"""Create Get Named Grid with operation 'Vector'."""
|
|
327
|
+
return cls(data_type="VECTOR", volume=volume, name=name, remove=remove)
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def i_volume(self) -> SocketLinker:
|
|
331
|
+
"""Input socket: Volume"""
|
|
332
|
+
return self._input("Volume")
|
|
333
|
+
|
|
334
|
+
@property
|
|
335
|
+
def i_name(self) -> SocketLinker:
|
|
336
|
+
"""Input socket: Name"""
|
|
337
|
+
return self._input("Name")
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def i_remove(self) -> SocketLinker:
|
|
341
|
+
"""Input socket: Remove"""
|
|
342
|
+
return self._input("Remove")
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def o_volume(self) -> SocketLinker:
|
|
346
|
+
"""Output socket: Volume"""
|
|
347
|
+
return self._output("Volume")
|
|
348
|
+
|
|
349
|
+
@property
|
|
350
|
+
def o_grid(self) -> SocketLinker:
|
|
351
|
+
"""Output socket: Grid"""
|
|
352
|
+
return self._output("Grid")
|
|
353
|
+
|
|
354
|
+
@property
|
|
355
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
356
|
+
return self.node.data_type
|
|
357
|
+
|
|
358
|
+
@data_type.setter
|
|
359
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
360
|
+
self.node.data_type = value
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
class GridCurl(NodeBuilder):
|
|
364
|
+
"""Calculate the magnitude and direction of circulation of a directional vector grid"""
|
|
365
|
+
|
|
366
|
+
_bl_idname = "GeometryNodeGridCurl"
|
|
367
|
+
node: bpy.types.GeometryNodeGridCurl
|
|
368
|
+
|
|
369
|
+
def __init__(self, grid: TYPE_INPUT_VECTOR = None):
|
|
370
|
+
super().__init__()
|
|
371
|
+
key_args = {"Grid": grid}
|
|
372
|
+
|
|
373
|
+
self._establish_links(**key_args)
|
|
374
|
+
|
|
375
|
+
@property
|
|
376
|
+
def i_grid(self) -> SocketLinker:
|
|
377
|
+
"""Input socket: Grid"""
|
|
378
|
+
return self._input("Grid")
|
|
379
|
+
|
|
380
|
+
@property
|
|
381
|
+
def o_curl(self) -> SocketLinker:
|
|
382
|
+
"""Output socket: Curl"""
|
|
383
|
+
return self._output("Curl")
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
class GridDivergence(NodeBuilder):
|
|
387
|
+
"""Calculate the flow into and out of each point of a directional vector grid"""
|
|
388
|
+
|
|
389
|
+
_bl_idname = "GeometryNodeGridDivergence"
|
|
390
|
+
node: bpy.types.GeometryNodeGridDivergence
|
|
391
|
+
|
|
392
|
+
def __init__(self, grid: TYPE_INPUT_VECTOR = None):
|
|
393
|
+
super().__init__()
|
|
394
|
+
key_args = {"Grid": grid}
|
|
395
|
+
|
|
396
|
+
self._establish_links(**key_args)
|
|
397
|
+
|
|
398
|
+
@property
|
|
399
|
+
def i_grid(self) -> SocketLinker:
|
|
400
|
+
"""Input socket: Grid"""
|
|
401
|
+
return self._input("Grid")
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def o_divergence(self) -> SocketLinker:
|
|
405
|
+
"""Output socket: Divergence"""
|
|
406
|
+
return self._output("Divergence")
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class GridGradient(NodeBuilder):
|
|
410
|
+
"""Calculate the direction and magnitude of the change in values of a scalar grid"""
|
|
411
|
+
|
|
412
|
+
_bl_idname = "GeometryNodeGridGradient"
|
|
413
|
+
node: bpy.types.GeometryNodeGridGradient
|
|
414
|
+
|
|
415
|
+
def __init__(self, grid: TYPE_INPUT_VALUE = 0.0):
|
|
416
|
+
super().__init__()
|
|
417
|
+
key_args = {"Grid": grid}
|
|
418
|
+
|
|
419
|
+
self._establish_links(**key_args)
|
|
420
|
+
|
|
421
|
+
@property
|
|
422
|
+
def i_grid(self) -> SocketLinker:
|
|
423
|
+
"""Input socket: Grid"""
|
|
424
|
+
return self._input("Grid")
|
|
425
|
+
|
|
426
|
+
@property
|
|
427
|
+
def o_gradient(self) -> SocketLinker:
|
|
428
|
+
"""Output socket: Gradient"""
|
|
429
|
+
return self._output("Gradient")
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
class GridInfo(NodeBuilder):
|
|
433
|
+
"""Retrieve information about a volume grid"""
|
|
434
|
+
|
|
435
|
+
_bl_idname = "GeometryNodeGridInfo"
|
|
436
|
+
node: bpy.types.GeometryNodeGridInfo
|
|
437
|
+
|
|
438
|
+
def __init__(
|
|
439
|
+
self,
|
|
440
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
441
|
+
*,
|
|
442
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
443
|
+
):
|
|
444
|
+
super().__init__()
|
|
445
|
+
key_args = {"Grid": grid}
|
|
446
|
+
self.data_type = data_type
|
|
447
|
+
self._establish_links(**key_args)
|
|
448
|
+
|
|
449
|
+
@classmethod
|
|
450
|
+
def float(cls, grid: TYPE_INPUT_VALUE = 0.0) -> "GridInfo":
|
|
451
|
+
"""Create Grid Info with operation 'Float'."""
|
|
452
|
+
return cls(data_type="FLOAT", grid=grid)
|
|
453
|
+
|
|
454
|
+
@classmethod
|
|
455
|
+
def integer(cls, grid: TYPE_INPUT_INT = 0) -> "GridInfo":
|
|
456
|
+
"""Create Grid Info with operation 'Integer'."""
|
|
457
|
+
return cls(data_type="INT", grid=grid)
|
|
458
|
+
|
|
459
|
+
@classmethod
|
|
460
|
+
def boolean(cls, grid: TYPE_INPUT_BOOLEAN = False) -> "GridInfo":
|
|
461
|
+
"""Create Grid Info with operation 'Boolean'."""
|
|
462
|
+
return cls(data_type="BOOLEAN", grid=grid)
|
|
463
|
+
|
|
464
|
+
@classmethod
|
|
465
|
+
def vector(cls, grid: TYPE_INPUT_VECTOR = None) -> "GridInfo":
|
|
466
|
+
"""Create Grid Info with operation 'Vector'."""
|
|
467
|
+
return cls(data_type="VECTOR", grid=grid)
|
|
468
|
+
|
|
469
|
+
@property
|
|
470
|
+
def i_grid(self) -> SocketLinker:
|
|
471
|
+
"""Input socket: Grid"""
|
|
472
|
+
return self._input("Grid")
|
|
473
|
+
|
|
474
|
+
@property
|
|
475
|
+
def o_transform(self) -> SocketLinker:
|
|
476
|
+
"""Output socket: Transform"""
|
|
477
|
+
return self._output("Transform")
|
|
478
|
+
|
|
479
|
+
@property
|
|
480
|
+
def o_background_value(self) -> SocketLinker:
|
|
481
|
+
"""Output socket: Background Value"""
|
|
482
|
+
return self._output("Background Value")
|
|
483
|
+
|
|
484
|
+
@property
|
|
485
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
486
|
+
return self.node.data_type
|
|
487
|
+
|
|
488
|
+
@data_type.setter
|
|
489
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
490
|
+
self.node.data_type = value
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
class GridLaplacian(NodeBuilder):
|
|
494
|
+
"""Compute the divergence of the gradient of the input grid"""
|
|
495
|
+
|
|
496
|
+
_bl_idname = "GeometryNodeGridLaplacian"
|
|
497
|
+
node: bpy.types.GeometryNodeGridLaplacian
|
|
498
|
+
|
|
499
|
+
def __init__(self, grid: TYPE_INPUT_VALUE = 0.0):
|
|
500
|
+
super().__init__()
|
|
501
|
+
key_args = {"Grid": grid}
|
|
502
|
+
|
|
503
|
+
self._establish_links(**key_args)
|
|
504
|
+
|
|
505
|
+
@property
|
|
506
|
+
def i_grid(self) -> SocketLinker:
|
|
507
|
+
"""Input socket: Grid"""
|
|
508
|
+
return self._input("Grid")
|
|
509
|
+
|
|
510
|
+
@property
|
|
511
|
+
def o_laplacian(self) -> SocketLinker:
|
|
512
|
+
"""Output socket: Laplacian"""
|
|
513
|
+
return self._output("Laplacian")
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
class GridToMesh(NodeBuilder):
|
|
517
|
+
"""Generate a mesh on the "surface" of a volume grid"""
|
|
518
|
+
|
|
519
|
+
_bl_idname = "GeometryNodeGridToMesh"
|
|
520
|
+
node: bpy.types.GeometryNodeGridToMesh
|
|
521
|
+
|
|
522
|
+
def __init__(
|
|
523
|
+
self,
|
|
524
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
525
|
+
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
526
|
+
adaptivity: TYPE_INPUT_VALUE = 0.0,
|
|
527
|
+
):
|
|
528
|
+
super().__init__()
|
|
529
|
+
key_args = {"Grid": grid, "Threshold": threshold, "Adaptivity": adaptivity}
|
|
530
|
+
|
|
531
|
+
self._establish_links(**key_args)
|
|
532
|
+
|
|
533
|
+
@property
|
|
534
|
+
def i_grid(self) -> SocketLinker:
|
|
535
|
+
"""Input socket: Grid"""
|
|
536
|
+
return self._input("Grid")
|
|
537
|
+
|
|
538
|
+
@property
|
|
539
|
+
def i_threshold(self) -> SocketLinker:
|
|
540
|
+
"""Input socket: Threshold"""
|
|
541
|
+
return self._input("Threshold")
|
|
542
|
+
|
|
543
|
+
@property
|
|
544
|
+
def i_adaptivity(self) -> SocketLinker:
|
|
545
|
+
"""Input socket: Adaptivity"""
|
|
546
|
+
return self._input("Adaptivity")
|
|
547
|
+
|
|
548
|
+
@property
|
|
549
|
+
def o_mesh(self) -> SocketLinker:
|
|
550
|
+
"""Output socket: Mesh"""
|
|
551
|
+
return self._output("Mesh")
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
class MeshToDensityGrid(NodeBuilder):
|
|
555
|
+
"""Create a filled volume grid from a mesh"""
|
|
556
|
+
|
|
557
|
+
_bl_idname = "GeometryNodeMeshToDensityGrid"
|
|
558
|
+
node: bpy.types.GeometryNodeMeshToDensityGrid
|
|
559
|
+
|
|
560
|
+
def __init__(
|
|
561
|
+
self,
|
|
562
|
+
mesh: TYPE_INPUT_GEOMETRY = None,
|
|
563
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
564
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
565
|
+
gradient_width: TYPE_INPUT_VALUE = 0.2,
|
|
566
|
+
):
|
|
567
|
+
super().__init__()
|
|
568
|
+
key_args = {
|
|
569
|
+
"Mesh": mesh,
|
|
570
|
+
"Density": density,
|
|
571
|
+
"Voxel Size": voxel_size,
|
|
572
|
+
"Gradient Width": gradient_width,
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
self._establish_links(**key_args)
|
|
576
|
+
|
|
577
|
+
@property
|
|
578
|
+
def i_mesh(self) -> SocketLinker:
|
|
579
|
+
"""Input socket: Mesh"""
|
|
580
|
+
return self._input("Mesh")
|
|
581
|
+
|
|
582
|
+
@property
|
|
583
|
+
def i_density(self) -> SocketLinker:
|
|
584
|
+
"""Input socket: Density"""
|
|
585
|
+
return self._input("Density")
|
|
586
|
+
|
|
587
|
+
@property
|
|
588
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
589
|
+
"""Input socket: Voxel Size"""
|
|
590
|
+
return self._input("Voxel Size")
|
|
591
|
+
|
|
592
|
+
@property
|
|
593
|
+
def i_gradient_width(self) -> SocketLinker:
|
|
594
|
+
"""Input socket: Gradient Width"""
|
|
595
|
+
return self._input("Gradient Width")
|
|
596
|
+
|
|
597
|
+
@property
|
|
598
|
+
def o_density_grid(self) -> SocketLinker:
|
|
599
|
+
"""Output socket: Density Grid"""
|
|
600
|
+
return self._output("Density Grid")
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
class MeshToSDFGrid(NodeBuilder):
|
|
604
|
+
"""Create a signed distance volume grid from a mesh"""
|
|
605
|
+
|
|
606
|
+
_bl_idname = "GeometryNodeMeshToSDFGrid"
|
|
607
|
+
node: bpy.types.GeometryNodeMeshToSDFGrid
|
|
608
|
+
|
|
609
|
+
def __init__(
|
|
610
|
+
self,
|
|
611
|
+
mesh: TYPE_INPUT_GEOMETRY = None,
|
|
612
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
613
|
+
band_width: TYPE_INPUT_INT = 3,
|
|
614
|
+
):
|
|
615
|
+
super().__init__()
|
|
616
|
+
key_args = {"Mesh": mesh, "Voxel Size": voxel_size, "Band Width": band_width}
|
|
617
|
+
|
|
618
|
+
self._establish_links(**key_args)
|
|
619
|
+
|
|
620
|
+
@property
|
|
621
|
+
def i_mesh(self) -> SocketLinker:
|
|
622
|
+
"""Input socket: Mesh"""
|
|
623
|
+
return self._input("Mesh")
|
|
624
|
+
|
|
625
|
+
@property
|
|
626
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
627
|
+
"""Input socket: Voxel Size"""
|
|
628
|
+
return self._input("Voxel Size")
|
|
629
|
+
|
|
630
|
+
@property
|
|
631
|
+
def i_band_width(self) -> SocketLinker:
|
|
632
|
+
"""Input socket: Band Width"""
|
|
633
|
+
return self._input("Band Width")
|
|
634
|
+
|
|
635
|
+
@property
|
|
636
|
+
def o_sdf_grid(self) -> SocketLinker:
|
|
637
|
+
"""Output socket: SDF Grid"""
|
|
638
|
+
return self._output("SDF Grid")
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
class MeshToVolume(NodeBuilder):
|
|
642
|
+
"""Create a fog volume with the shape of the input mesh's surface"""
|
|
643
|
+
|
|
644
|
+
_bl_idname = "GeometryNodeMeshToVolume"
|
|
645
|
+
node: bpy.types.GeometryNodeMeshToVolume
|
|
646
|
+
|
|
647
|
+
def __init__(
|
|
648
|
+
self,
|
|
649
|
+
mesh: TYPE_INPUT_GEOMETRY = None,
|
|
650
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
651
|
+
resolution_mode: TYPE_INPUT_MENU = "Amount",
|
|
652
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
653
|
+
voxel_amount: TYPE_INPUT_VALUE = 64.0,
|
|
654
|
+
interior_band_width: TYPE_INPUT_VALUE = 0.2,
|
|
655
|
+
):
|
|
656
|
+
super().__init__()
|
|
657
|
+
key_args = {
|
|
658
|
+
"Mesh": mesh,
|
|
659
|
+
"Density": density,
|
|
660
|
+
"Resolution Mode": resolution_mode,
|
|
661
|
+
"Voxel Size": voxel_size,
|
|
662
|
+
"Voxel Amount": voxel_amount,
|
|
663
|
+
"Interior Band Width": interior_band_width,
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
self._establish_links(**key_args)
|
|
667
|
+
|
|
668
|
+
@property
|
|
669
|
+
def i_mesh(self) -> SocketLinker:
|
|
670
|
+
"""Input socket: Mesh"""
|
|
671
|
+
return self._input("Mesh")
|
|
672
|
+
|
|
673
|
+
@property
|
|
674
|
+
def i_density(self) -> SocketLinker:
|
|
675
|
+
"""Input socket: Density"""
|
|
676
|
+
return self._input("Density")
|
|
677
|
+
|
|
678
|
+
@property
|
|
679
|
+
def i_resolution_mode(self) -> SocketLinker:
|
|
680
|
+
"""Input socket: Resolution Mode"""
|
|
681
|
+
return self._input("Resolution Mode")
|
|
682
|
+
|
|
683
|
+
@property
|
|
684
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
685
|
+
"""Input socket: Voxel Size"""
|
|
686
|
+
return self._input("Voxel Size")
|
|
687
|
+
|
|
688
|
+
@property
|
|
689
|
+
def i_voxel_amount(self) -> SocketLinker:
|
|
690
|
+
"""Input socket: Voxel Amount"""
|
|
691
|
+
return self._input("Voxel Amount")
|
|
692
|
+
|
|
693
|
+
@property
|
|
694
|
+
def i_interior_band_width(self) -> SocketLinker:
|
|
695
|
+
"""Input socket: Interior Band Width"""
|
|
696
|
+
return self._input("Interior Band Width")
|
|
697
|
+
|
|
698
|
+
@property
|
|
699
|
+
def o_volume(self) -> SocketLinker:
|
|
700
|
+
"""Output socket: Volume"""
|
|
701
|
+
return self._output("Volume")
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
class PointsToSDFGrid(NodeBuilder):
|
|
705
|
+
"""Create a signed distance volume grid from points"""
|
|
706
|
+
|
|
707
|
+
_bl_idname = "GeometryNodePointsToSDFGrid"
|
|
708
|
+
node: bpy.types.GeometryNodePointsToSDFGrid
|
|
709
|
+
|
|
710
|
+
def __init__(
|
|
711
|
+
self,
|
|
712
|
+
points: TYPE_INPUT_GEOMETRY = None,
|
|
713
|
+
radius: TYPE_INPUT_VALUE = 0.5,
|
|
714
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
715
|
+
):
|
|
716
|
+
super().__init__()
|
|
717
|
+
key_args = {"Points": points, "Radius": radius, "Voxel Size": voxel_size}
|
|
718
|
+
|
|
719
|
+
self._establish_links(**key_args)
|
|
720
|
+
|
|
721
|
+
@property
|
|
722
|
+
def i_points(self) -> SocketLinker:
|
|
723
|
+
"""Input socket: Points"""
|
|
724
|
+
return self._input("Points")
|
|
725
|
+
|
|
726
|
+
@property
|
|
727
|
+
def i_radius(self) -> SocketLinker:
|
|
728
|
+
"""Input socket: Radius"""
|
|
729
|
+
return self._input("Radius")
|
|
730
|
+
|
|
731
|
+
@property
|
|
732
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
733
|
+
"""Input socket: Voxel Size"""
|
|
734
|
+
return self._input("Voxel Size")
|
|
735
|
+
|
|
736
|
+
@property
|
|
737
|
+
def o_sdf_grid(self) -> SocketLinker:
|
|
738
|
+
"""Output socket: SDF Grid"""
|
|
739
|
+
return self._output("SDF Grid")
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
class PointsToVolume(NodeBuilder):
|
|
743
|
+
"""Generate a fog volume sphere around every point"""
|
|
744
|
+
|
|
745
|
+
_bl_idname = "GeometryNodePointsToVolume"
|
|
746
|
+
node: bpy.types.GeometryNodePointsToVolume
|
|
747
|
+
|
|
748
|
+
def __init__(
|
|
749
|
+
self,
|
|
750
|
+
points: TYPE_INPUT_GEOMETRY = None,
|
|
751
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
752
|
+
resolution_mode: TYPE_INPUT_MENU = "Amount",
|
|
753
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
754
|
+
voxel_amount: TYPE_INPUT_VALUE = 64.0,
|
|
755
|
+
radius: TYPE_INPUT_VALUE = 0.5,
|
|
756
|
+
):
|
|
757
|
+
super().__init__()
|
|
758
|
+
key_args = {
|
|
759
|
+
"Points": points,
|
|
760
|
+
"Density": density,
|
|
761
|
+
"Resolution Mode": resolution_mode,
|
|
762
|
+
"Voxel Size": voxel_size,
|
|
763
|
+
"Voxel Amount": voxel_amount,
|
|
764
|
+
"Radius": radius,
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
self._establish_links(**key_args)
|
|
768
|
+
|
|
769
|
+
@property
|
|
770
|
+
def i_points(self) -> SocketLinker:
|
|
771
|
+
"""Input socket: Points"""
|
|
772
|
+
return self._input("Points")
|
|
773
|
+
|
|
774
|
+
@property
|
|
775
|
+
def i_density(self) -> SocketLinker:
|
|
776
|
+
"""Input socket: Density"""
|
|
777
|
+
return self._input("Density")
|
|
778
|
+
|
|
779
|
+
@property
|
|
780
|
+
def i_resolution_mode(self) -> SocketLinker:
|
|
781
|
+
"""Input socket: Resolution Mode"""
|
|
782
|
+
return self._input("Resolution Mode")
|
|
783
|
+
|
|
784
|
+
@property
|
|
785
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
786
|
+
"""Input socket: Voxel Size"""
|
|
787
|
+
return self._input("Voxel Size")
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def i_voxel_amount(self) -> SocketLinker:
|
|
791
|
+
"""Input socket: Voxel Amount"""
|
|
792
|
+
return self._input("Voxel Amount")
|
|
793
|
+
|
|
794
|
+
@property
|
|
795
|
+
def i_radius(self) -> SocketLinker:
|
|
796
|
+
"""Input socket: Radius"""
|
|
797
|
+
return self._input("Radius")
|
|
798
|
+
|
|
799
|
+
@property
|
|
800
|
+
def o_volume(self) -> SocketLinker:
|
|
801
|
+
"""Output socket: Volume"""
|
|
802
|
+
return self._output("Volume")
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
class PruneGrid(NodeBuilder):
|
|
806
|
+
"""Make the storage of a volume grid more efficient by collapsing data into tiles or inner nodes"""
|
|
807
|
+
|
|
808
|
+
_bl_idname = "GeometryNodeGridPrune"
|
|
809
|
+
node: bpy.types.GeometryNodeGridPrune
|
|
810
|
+
|
|
811
|
+
def __init__(
|
|
812
|
+
self,
|
|
813
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
814
|
+
mode: TYPE_INPUT_MENU = "Threshold",
|
|
815
|
+
threshold: TYPE_INPUT_VALUE = 0.01,
|
|
816
|
+
*,
|
|
817
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
818
|
+
):
|
|
819
|
+
super().__init__()
|
|
820
|
+
key_args = {"Grid": grid, "Mode": mode, "Threshold": threshold}
|
|
821
|
+
self.data_type = data_type
|
|
822
|
+
self._establish_links(**key_args)
|
|
823
|
+
|
|
824
|
+
@classmethod
|
|
825
|
+
def float(
|
|
826
|
+
cls,
|
|
827
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
828
|
+
mode: TYPE_INPUT_MENU = "Threshold",
|
|
829
|
+
threshold: TYPE_INPUT_VALUE = 0.01,
|
|
830
|
+
) -> "PruneGrid":
|
|
831
|
+
"""Create Prune Grid with operation 'Float'."""
|
|
832
|
+
return cls(data_type="FLOAT", grid=grid, mode=mode, threshold=threshold)
|
|
833
|
+
|
|
834
|
+
@classmethod
|
|
835
|
+
def integer(
|
|
836
|
+
cls,
|
|
837
|
+
grid: TYPE_INPUT_INT = 0,
|
|
838
|
+
mode: TYPE_INPUT_MENU = "Threshold",
|
|
839
|
+
threshold: TYPE_INPUT_INT = 0,
|
|
840
|
+
) -> "PruneGrid":
|
|
841
|
+
"""Create Prune Grid with operation 'Integer'."""
|
|
842
|
+
return cls(data_type="INT", grid=grid, mode=mode, threshold=threshold)
|
|
843
|
+
|
|
844
|
+
@classmethod
|
|
845
|
+
def boolean(
|
|
846
|
+
cls, grid: TYPE_INPUT_BOOLEAN = False, mode: TYPE_INPUT_MENU = "Threshold"
|
|
847
|
+
) -> "PruneGrid":
|
|
848
|
+
"""Create Prune Grid with operation 'Boolean'."""
|
|
849
|
+
return cls(data_type="BOOLEAN", grid=grid, mode=mode)
|
|
850
|
+
|
|
851
|
+
@classmethod
|
|
852
|
+
def vector(
|
|
853
|
+
cls,
|
|
854
|
+
grid: TYPE_INPUT_VECTOR = None,
|
|
855
|
+
mode: TYPE_INPUT_MENU = "Threshold",
|
|
856
|
+
threshold: TYPE_INPUT_VECTOR = None,
|
|
857
|
+
) -> "PruneGrid":
|
|
858
|
+
"""Create Prune Grid with operation 'Vector'."""
|
|
859
|
+
return cls(data_type="VECTOR", grid=grid, mode=mode, threshold=threshold)
|
|
860
|
+
|
|
861
|
+
@property
|
|
862
|
+
def i_grid(self) -> SocketLinker:
|
|
863
|
+
"""Input socket: Grid"""
|
|
864
|
+
return self._input("Grid")
|
|
865
|
+
|
|
866
|
+
@property
|
|
867
|
+
def i_mode(self) -> SocketLinker:
|
|
868
|
+
"""Input socket: Mode"""
|
|
869
|
+
return self._input("Mode")
|
|
870
|
+
|
|
871
|
+
@property
|
|
872
|
+
def i_threshold(self) -> SocketLinker:
|
|
873
|
+
"""Input socket: Threshold"""
|
|
874
|
+
return self._input("Threshold")
|
|
875
|
+
|
|
876
|
+
@property
|
|
877
|
+
def o_grid(self) -> SocketLinker:
|
|
878
|
+
"""Output socket: Grid"""
|
|
879
|
+
return self._output("Grid")
|
|
880
|
+
|
|
881
|
+
@property
|
|
882
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
883
|
+
return self.node.data_type
|
|
884
|
+
|
|
885
|
+
@data_type.setter
|
|
886
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
887
|
+
self.node.data_type = value
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
class SDFGridFillet(NodeBuilder):
|
|
891
|
+
"""Round off concave internal corners in a signed distance field. Only affects areas with negative principal curvature, creating smoother transitions between surfaces"""
|
|
892
|
+
|
|
893
|
+
_bl_idname = "GeometryNodeSDFGridFillet"
|
|
894
|
+
node: bpy.types.GeometryNodeSDFGridFillet
|
|
895
|
+
|
|
896
|
+
def __init__(
|
|
897
|
+
self,
|
|
898
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
899
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
900
|
+
):
|
|
901
|
+
super().__init__()
|
|
902
|
+
key_args = {"Grid": grid, "Iterations": iterations}
|
|
903
|
+
|
|
904
|
+
self._establish_links(**key_args)
|
|
905
|
+
|
|
906
|
+
@property
|
|
907
|
+
def i_grid(self) -> SocketLinker:
|
|
908
|
+
"""Input socket: Grid"""
|
|
909
|
+
return self._input("Grid")
|
|
910
|
+
|
|
911
|
+
@property
|
|
912
|
+
def i_iterations(self) -> SocketLinker:
|
|
913
|
+
"""Input socket: Iterations"""
|
|
914
|
+
return self._input("Iterations")
|
|
915
|
+
|
|
916
|
+
@property
|
|
917
|
+
def o_grid(self) -> SocketLinker:
|
|
918
|
+
"""Output socket: Grid"""
|
|
919
|
+
return self._output("Grid")
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
class SDFGridLaplacian(NodeBuilder):
|
|
923
|
+
"""Apply Laplacian flow smoothing to a signed distance field. Computationally efficient alternative to mean curvature flow, ideal when combined with SDF normalization"""
|
|
924
|
+
|
|
925
|
+
_bl_idname = "GeometryNodeSDFGridLaplacian"
|
|
926
|
+
node: bpy.types.GeometryNodeSDFGridLaplacian
|
|
927
|
+
|
|
928
|
+
def __init__(
|
|
929
|
+
self,
|
|
930
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
931
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
932
|
+
):
|
|
933
|
+
super().__init__()
|
|
934
|
+
key_args = {"Grid": grid, "Iterations": iterations}
|
|
935
|
+
|
|
936
|
+
self._establish_links(**key_args)
|
|
937
|
+
|
|
938
|
+
@property
|
|
939
|
+
def i_grid(self) -> SocketLinker:
|
|
940
|
+
"""Input socket: Grid"""
|
|
941
|
+
return self._input("Grid")
|
|
942
|
+
|
|
943
|
+
@property
|
|
944
|
+
def i_iterations(self) -> SocketLinker:
|
|
945
|
+
"""Input socket: Iterations"""
|
|
946
|
+
return self._input("Iterations")
|
|
947
|
+
|
|
948
|
+
@property
|
|
949
|
+
def o_grid(self) -> SocketLinker:
|
|
950
|
+
"""Output socket: Grid"""
|
|
951
|
+
return self._output("Grid")
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
class SDFGridMean(NodeBuilder):
|
|
955
|
+
"""Apply mean (box) filter smoothing to a signed distance field. Fast separable averaging filter for general smoothing of the distance field"""
|
|
956
|
+
|
|
957
|
+
_bl_idname = "GeometryNodeSDFGridMean"
|
|
958
|
+
node: bpy.types.GeometryNodeSDFGridMean
|
|
959
|
+
|
|
960
|
+
def __init__(
|
|
961
|
+
self,
|
|
962
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
963
|
+
width: TYPE_INPUT_INT = 1,
|
|
964
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
965
|
+
):
|
|
966
|
+
super().__init__()
|
|
967
|
+
key_args = {"Grid": grid, "Width": width, "Iterations": iterations}
|
|
968
|
+
|
|
969
|
+
self._establish_links(**key_args)
|
|
970
|
+
|
|
971
|
+
@property
|
|
972
|
+
def i_grid(self) -> SocketLinker:
|
|
973
|
+
"""Input socket: Grid"""
|
|
974
|
+
return self._input("Grid")
|
|
975
|
+
|
|
976
|
+
@property
|
|
977
|
+
def i_width(self) -> SocketLinker:
|
|
978
|
+
"""Input socket: Width"""
|
|
979
|
+
return self._input("Width")
|
|
980
|
+
|
|
981
|
+
@property
|
|
982
|
+
def i_iterations(self) -> SocketLinker:
|
|
983
|
+
"""Input socket: Iterations"""
|
|
984
|
+
return self._input("Iterations")
|
|
985
|
+
|
|
986
|
+
@property
|
|
987
|
+
def o_grid(self) -> SocketLinker:
|
|
988
|
+
"""Output socket: Grid"""
|
|
989
|
+
return self._output("Grid")
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
class SDFGridMeanCurvature(NodeBuilder):
|
|
993
|
+
"""Apply mean curvature flow smoothing to a signed distance field. Evolves the surface based on its mean curvature, naturally smoothing high-curvature regions more than flat areas"""
|
|
994
|
+
|
|
995
|
+
_bl_idname = "GeometryNodeSDFGridMeanCurvature"
|
|
996
|
+
node: bpy.types.GeometryNodeSDFGridMeanCurvature
|
|
997
|
+
|
|
998
|
+
def __init__(
|
|
999
|
+
self,
|
|
1000
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1001
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
1002
|
+
):
|
|
1003
|
+
super().__init__()
|
|
1004
|
+
key_args = {"Grid": grid, "Iterations": iterations}
|
|
1005
|
+
|
|
1006
|
+
self._establish_links(**key_args)
|
|
1007
|
+
|
|
1008
|
+
@property
|
|
1009
|
+
def i_grid(self) -> SocketLinker:
|
|
1010
|
+
"""Input socket: Grid"""
|
|
1011
|
+
return self._input("Grid")
|
|
1012
|
+
|
|
1013
|
+
@property
|
|
1014
|
+
def i_iterations(self) -> SocketLinker:
|
|
1015
|
+
"""Input socket: Iterations"""
|
|
1016
|
+
return self._input("Iterations")
|
|
1017
|
+
|
|
1018
|
+
@property
|
|
1019
|
+
def o_grid(self) -> SocketLinker:
|
|
1020
|
+
"""Output socket: Grid"""
|
|
1021
|
+
return self._output("Grid")
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
class SDFGridMedian(NodeBuilder):
|
|
1025
|
+
"""Apply median filter to a signed distance field. Reduces noise while preserving sharp features and edges in the distance field"""
|
|
1026
|
+
|
|
1027
|
+
_bl_idname = "GeometryNodeSDFGridMedian"
|
|
1028
|
+
node: bpy.types.GeometryNodeSDFGridMedian
|
|
1029
|
+
|
|
1030
|
+
def __init__(
|
|
1031
|
+
self,
|
|
1032
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1033
|
+
width: TYPE_INPUT_INT = 1,
|
|
1034
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
1035
|
+
):
|
|
1036
|
+
super().__init__()
|
|
1037
|
+
key_args = {"Grid": grid, "Width": width, "Iterations": iterations}
|
|
1038
|
+
|
|
1039
|
+
self._establish_links(**key_args)
|
|
1040
|
+
|
|
1041
|
+
@property
|
|
1042
|
+
def i_grid(self) -> SocketLinker:
|
|
1043
|
+
"""Input socket: Grid"""
|
|
1044
|
+
return self._input("Grid")
|
|
1045
|
+
|
|
1046
|
+
@property
|
|
1047
|
+
def i_width(self) -> SocketLinker:
|
|
1048
|
+
"""Input socket: Width"""
|
|
1049
|
+
return self._input("Width")
|
|
1050
|
+
|
|
1051
|
+
@property
|
|
1052
|
+
def i_iterations(self) -> SocketLinker:
|
|
1053
|
+
"""Input socket: Iterations"""
|
|
1054
|
+
return self._input("Iterations")
|
|
1055
|
+
|
|
1056
|
+
@property
|
|
1057
|
+
def o_grid(self) -> SocketLinker:
|
|
1058
|
+
"""Output socket: Grid"""
|
|
1059
|
+
return self._output("Grid")
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
class SDFGridOffset(NodeBuilder):
|
|
1063
|
+
"""Offset a signed distance field surface by a world-space distance. Dilates (positive) or erodes (negative) while maintaining the signed distance property"""
|
|
1064
|
+
|
|
1065
|
+
_bl_idname = "GeometryNodeSDFGridOffset"
|
|
1066
|
+
node: bpy.types.GeometryNodeSDFGridOffset
|
|
1067
|
+
|
|
1068
|
+
def __init__(
|
|
1069
|
+
self,
|
|
1070
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1071
|
+
distance: TYPE_INPUT_VALUE = 0.1,
|
|
1072
|
+
):
|
|
1073
|
+
super().__init__()
|
|
1074
|
+
key_args = {"Grid": grid, "Distance": distance}
|
|
1075
|
+
|
|
1076
|
+
self._establish_links(**key_args)
|
|
1077
|
+
|
|
1078
|
+
@property
|
|
1079
|
+
def i_grid(self) -> SocketLinker:
|
|
1080
|
+
"""Input socket: Grid"""
|
|
1081
|
+
return self._input("Grid")
|
|
1082
|
+
|
|
1083
|
+
@property
|
|
1084
|
+
def i_distance(self) -> SocketLinker:
|
|
1085
|
+
"""Input socket: Distance"""
|
|
1086
|
+
return self._input("Distance")
|
|
1087
|
+
|
|
1088
|
+
@property
|
|
1089
|
+
def o_grid(self) -> SocketLinker:
|
|
1090
|
+
"""Output socket: Grid"""
|
|
1091
|
+
return self._output("Grid")
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
class SampleGrid(NodeBuilder):
|
|
1095
|
+
"""Retrieve values from the specified volume grid"""
|
|
1096
|
+
|
|
1097
|
+
_bl_idname = "GeometryNodeSampleGrid"
|
|
1098
|
+
node: bpy.types.GeometryNodeSampleGrid
|
|
1099
|
+
|
|
1100
|
+
def __init__(
|
|
1101
|
+
self,
|
|
1102
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1103
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
1104
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
1105
|
+
*,
|
|
1106
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1107
|
+
):
|
|
1108
|
+
super().__init__()
|
|
1109
|
+
key_args = {"Grid": grid, "Position": position, "Interpolation": interpolation}
|
|
1110
|
+
self.data_type = data_type
|
|
1111
|
+
self._establish_links(**key_args)
|
|
1112
|
+
|
|
1113
|
+
@classmethod
|
|
1114
|
+
def float(
|
|
1115
|
+
cls,
|
|
1116
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1117
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
1118
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
1119
|
+
) -> "SampleGrid":
|
|
1120
|
+
"""Create Sample Grid with operation 'Float'."""
|
|
1121
|
+
return cls(
|
|
1122
|
+
data_type="FLOAT", grid=grid, position=position, interpolation=interpolation
|
|
1123
|
+
)
|
|
1124
|
+
|
|
1125
|
+
@classmethod
|
|
1126
|
+
def integer(
|
|
1127
|
+
cls,
|
|
1128
|
+
grid: TYPE_INPUT_INT = 0,
|
|
1129
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
1130
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
1131
|
+
) -> "SampleGrid":
|
|
1132
|
+
"""Create Sample Grid with operation 'Integer'."""
|
|
1133
|
+
return cls(
|
|
1134
|
+
data_type="INT", grid=grid, position=position, interpolation=interpolation
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
@classmethod
|
|
1138
|
+
def boolean(
|
|
1139
|
+
cls,
|
|
1140
|
+
grid: TYPE_INPUT_BOOLEAN = False,
|
|
1141
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
1142
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
1143
|
+
) -> "SampleGrid":
|
|
1144
|
+
"""Create Sample Grid with operation 'Boolean'."""
|
|
1145
|
+
return cls(
|
|
1146
|
+
data_type="BOOLEAN",
|
|
1147
|
+
grid=grid,
|
|
1148
|
+
position=position,
|
|
1149
|
+
interpolation=interpolation,
|
|
1150
|
+
)
|
|
1151
|
+
|
|
1152
|
+
@classmethod
|
|
1153
|
+
def vector(
|
|
1154
|
+
cls,
|
|
1155
|
+
grid: TYPE_INPUT_VECTOR = None,
|
|
1156
|
+
position: TYPE_INPUT_VECTOR = None,
|
|
1157
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
1158
|
+
) -> "SampleGrid":
|
|
1159
|
+
"""Create Sample Grid with operation 'Vector'."""
|
|
1160
|
+
return cls(
|
|
1161
|
+
data_type="VECTOR",
|
|
1162
|
+
grid=grid,
|
|
1163
|
+
position=position,
|
|
1164
|
+
interpolation=interpolation,
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
@property
|
|
1168
|
+
def i_grid(self) -> SocketLinker:
|
|
1169
|
+
"""Input socket: Grid"""
|
|
1170
|
+
return self._input("Grid")
|
|
1171
|
+
|
|
1172
|
+
@property
|
|
1173
|
+
def i_position(self) -> SocketLinker:
|
|
1174
|
+
"""Input socket: Position"""
|
|
1175
|
+
return self._input("Position")
|
|
1176
|
+
|
|
1177
|
+
@property
|
|
1178
|
+
def i_interpolation(self) -> SocketLinker:
|
|
1179
|
+
"""Input socket: Interpolation"""
|
|
1180
|
+
return self._input("Interpolation")
|
|
1181
|
+
|
|
1182
|
+
@property
|
|
1183
|
+
def o_value(self) -> SocketLinker:
|
|
1184
|
+
"""Output socket: Value"""
|
|
1185
|
+
return self._output("Value")
|
|
1186
|
+
|
|
1187
|
+
@property
|
|
1188
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1189
|
+
return self.node.data_type
|
|
1190
|
+
|
|
1191
|
+
@data_type.setter
|
|
1192
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1193
|
+
self.node.data_type = value
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
class SampleGridIndex(NodeBuilder):
|
|
1197
|
+
"""Retrieve volume grid values at specific voxels"""
|
|
1198
|
+
|
|
1199
|
+
_bl_idname = "GeometryNodeSampleGridIndex"
|
|
1200
|
+
node: bpy.types.GeometryNodeSampleGridIndex
|
|
1201
|
+
|
|
1202
|
+
def __init__(
|
|
1203
|
+
self,
|
|
1204
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1205
|
+
x: TYPE_INPUT_INT = 0,
|
|
1206
|
+
y: TYPE_INPUT_INT = 0,
|
|
1207
|
+
z: TYPE_INPUT_INT = 0,
|
|
1208
|
+
*,
|
|
1209
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1210
|
+
):
|
|
1211
|
+
super().__init__()
|
|
1212
|
+
key_args = {"Grid": grid, "X": x, "Y": y, "Z": z}
|
|
1213
|
+
self.data_type = data_type
|
|
1214
|
+
self._establish_links(**key_args)
|
|
1215
|
+
|
|
1216
|
+
@classmethod
|
|
1217
|
+
def float(
|
|
1218
|
+
cls,
|
|
1219
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1220
|
+
x: TYPE_INPUT_INT = 0,
|
|
1221
|
+
y: TYPE_INPUT_INT = 0,
|
|
1222
|
+
z: TYPE_INPUT_INT = 0,
|
|
1223
|
+
) -> "SampleGridIndex":
|
|
1224
|
+
"""Create Sample Grid Index with operation 'Float'."""
|
|
1225
|
+
return cls(data_type="FLOAT", grid=grid, x=x, y=y, z=z)
|
|
1226
|
+
|
|
1227
|
+
@classmethod
|
|
1228
|
+
def integer(
|
|
1229
|
+
cls,
|
|
1230
|
+
grid: TYPE_INPUT_INT = 0,
|
|
1231
|
+
x: TYPE_INPUT_INT = 0,
|
|
1232
|
+
y: TYPE_INPUT_INT = 0,
|
|
1233
|
+
z: TYPE_INPUT_INT = 0,
|
|
1234
|
+
) -> "SampleGridIndex":
|
|
1235
|
+
"""Create Sample Grid Index with operation 'Integer'."""
|
|
1236
|
+
return cls(data_type="INT", grid=grid, x=x, y=y, z=z)
|
|
1237
|
+
|
|
1238
|
+
@classmethod
|
|
1239
|
+
def boolean(
|
|
1240
|
+
cls,
|
|
1241
|
+
grid: TYPE_INPUT_BOOLEAN = False,
|
|
1242
|
+
x: TYPE_INPUT_INT = 0,
|
|
1243
|
+
y: TYPE_INPUT_INT = 0,
|
|
1244
|
+
z: TYPE_INPUT_INT = 0,
|
|
1245
|
+
) -> "SampleGridIndex":
|
|
1246
|
+
"""Create Sample Grid Index with operation 'Boolean'."""
|
|
1247
|
+
return cls(data_type="BOOLEAN", grid=grid, x=x, y=y, z=z)
|
|
1248
|
+
|
|
1249
|
+
@classmethod
|
|
1250
|
+
def vector(
|
|
1251
|
+
cls,
|
|
1252
|
+
grid: TYPE_INPUT_VECTOR = None,
|
|
1253
|
+
x: TYPE_INPUT_INT = 0,
|
|
1254
|
+
y: TYPE_INPUT_INT = 0,
|
|
1255
|
+
z: TYPE_INPUT_INT = 0,
|
|
1256
|
+
) -> "SampleGridIndex":
|
|
1257
|
+
"""Create Sample Grid Index with operation 'Vector'."""
|
|
1258
|
+
return cls(data_type="VECTOR", grid=grid, x=x, y=y, z=z)
|
|
1259
|
+
|
|
1260
|
+
@property
|
|
1261
|
+
def i_grid(self) -> SocketLinker:
|
|
1262
|
+
"""Input socket: Grid"""
|
|
1263
|
+
return self._input("Grid")
|
|
1264
|
+
|
|
1265
|
+
@property
|
|
1266
|
+
def i_x(self) -> SocketLinker:
|
|
1267
|
+
"""Input socket: X"""
|
|
1268
|
+
return self._input("X")
|
|
1269
|
+
|
|
1270
|
+
@property
|
|
1271
|
+
def i_y(self) -> SocketLinker:
|
|
1272
|
+
"""Input socket: Y"""
|
|
1273
|
+
return self._input("Y")
|
|
1274
|
+
|
|
1275
|
+
@property
|
|
1276
|
+
def i_z(self) -> SocketLinker:
|
|
1277
|
+
"""Input socket: Z"""
|
|
1278
|
+
return self._input("Z")
|
|
1279
|
+
|
|
1280
|
+
@property
|
|
1281
|
+
def o_value(self) -> SocketLinker:
|
|
1282
|
+
"""Output socket: Value"""
|
|
1283
|
+
return self._output("Value")
|
|
1284
|
+
|
|
1285
|
+
@property
|
|
1286
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1287
|
+
return self.node.data_type
|
|
1288
|
+
|
|
1289
|
+
@data_type.setter
|
|
1290
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1291
|
+
self.node.data_type = value
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
class SetGridBackground(NodeBuilder):
|
|
1295
|
+
"""Set the background value used for inactive voxels and tiles"""
|
|
1296
|
+
|
|
1297
|
+
_bl_idname = "GeometryNodeSetGridBackground"
|
|
1298
|
+
node: bpy.types.GeometryNodeSetGridBackground
|
|
1299
|
+
|
|
1300
|
+
def __init__(
|
|
1301
|
+
self,
|
|
1302
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1303
|
+
background: TYPE_INPUT_VALUE = 0.0,
|
|
1304
|
+
*,
|
|
1305
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1306
|
+
):
|
|
1307
|
+
super().__init__()
|
|
1308
|
+
key_args = {"Grid": grid, "Background": background}
|
|
1309
|
+
self.data_type = data_type
|
|
1310
|
+
self._establish_links(**key_args)
|
|
1311
|
+
|
|
1312
|
+
@classmethod
|
|
1313
|
+
def float(
|
|
1314
|
+
cls, grid: TYPE_INPUT_VALUE = 0.0, background: TYPE_INPUT_VALUE = 0.0
|
|
1315
|
+
) -> "SetGridBackground":
|
|
1316
|
+
"""Create Set Grid Background with operation 'Float'."""
|
|
1317
|
+
return cls(data_type="FLOAT", grid=grid, background=background)
|
|
1318
|
+
|
|
1319
|
+
@classmethod
|
|
1320
|
+
def integer(
|
|
1321
|
+
cls, grid: TYPE_INPUT_INT = 0, background: TYPE_INPUT_INT = 0
|
|
1322
|
+
) -> "SetGridBackground":
|
|
1323
|
+
"""Create Set Grid Background with operation 'Integer'."""
|
|
1324
|
+
return cls(data_type="INT", grid=grid, background=background)
|
|
1325
|
+
|
|
1326
|
+
@classmethod
|
|
1327
|
+
def boolean(
|
|
1328
|
+
cls, grid: TYPE_INPUT_BOOLEAN = False, background: TYPE_INPUT_BOOLEAN = False
|
|
1329
|
+
) -> "SetGridBackground":
|
|
1330
|
+
"""Create Set Grid Background with operation 'Boolean'."""
|
|
1331
|
+
return cls(data_type="BOOLEAN", grid=grid, background=background)
|
|
1332
|
+
|
|
1333
|
+
@classmethod
|
|
1334
|
+
def vector(
|
|
1335
|
+
cls, grid: TYPE_INPUT_VECTOR = None, background: TYPE_INPUT_VECTOR = None
|
|
1336
|
+
) -> "SetGridBackground":
|
|
1337
|
+
"""Create Set Grid Background with operation 'Vector'."""
|
|
1338
|
+
return cls(data_type="VECTOR", grid=grid, background=background)
|
|
1339
|
+
|
|
1340
|
+
@property
|
|
1341
|
+
def i_grid(self) -> SocketLinker:
|
|
1342
|
+
"""Input socket: Grid"""
|
|
1343
|
+
return self._input("Grid")
|
|
1344
|
+
|
|
1345
|
+
@property
|
|
1346
|
+
def i_background(self) -> SocketLinker:
|
|
1347
|
+
"""Input socket: Background"""
|
|
1348
|
+
return self._input("Background")
|
|
1349
|
+
|
|
1350
|
+
@property
|
|
1351
|
+
def o_grid(self) -> SocketLinker:
|
|
1352
|
+
"""Output socket: Grid"""
|
|
1353
|
+
return self._output("Grid")
|
|
1354
|
+
|
|
1355
|
+
@property
|
|
1356
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1357
|
+
return self.node.data_type
|
|
1358
|
+
|
|
1359
|
+
@data_type.setter
|
|
1360
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1361
|
+
self.node.data_type = value
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
class SetGridTransform(NodeBuilder):
|
|
1365
|
+
"""Set the transform for the grid from index space into object space."""
|
|
1366
|
+
|
|
1367
|
+
_bl_idname = "GeometryNodeSetGridTransform"
|
|
1368
|
+
node: bpy.types.GeometryNodeSetGridTransform
|
|
1369
|
+
|
|
1370
|
+
def __init__(
|
|
1371
|
+
self,
|
|
1372
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1373
|
+
transform: TYPE_INPUT_MATRIX = None,
|
|
1374
|
+
*,
|
|
1375
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1376
|
+
):
|
|
1377
|
+
super().__init__()
|
|
1378
|
+
key_args = {"Grid": grid, "Transform": transform}
|
|
1379
|
+
self.data_type = data_type
|
|
1380
|
+
self._establish_links(**key_args)
|
|
1381
|
+
|
|
1382
|
+
@classmethod
|
|
1383
|
+
def float(
|
|
1384
|
+
cls, grid: TYPE_INPUT_VALUE = 0.0, transform: TYPE_INPUT_MATRIX = None
|
|
1385
|
+
) -> "SetGridTransform":
|
|
1386
|
+
"""Create Set Grid Transform with operation 'Float'."""
|
|
1387
|
+
return cls(data_type="FLOAT", grid=grid, transform=transform)
|
|
1388
|
+
|
|
1389
|
+
@classmethod
|
|
1390
|
+
def integer(
|
|
1391
|
+
cls, grid: TYPE_INPUT_INT = 0, transform: TYPE_INPUT_MATRIX = None
|
|
1392
|
+
) -> "SetGridTransform":
|
|
1393
|
+
"""Create Set Grid Transform with operation 'Integer'."""
|
|
1394
|
+
return cls(data_type="INT", grid=grid, transform=transform)
|
|
1395
|
+
|
|
1396
|
+
@classmethod
|
|
1397
|
+
def boolean(
|
|
1398
|
+
cls, grid: TYPE_INPUT_BOOLEAN = False, transform: TYPE_INPUT_MATRIX = None
|
|
1399
|
+
) -> "SetGridTransform":
|
|
1400
|
+
"""Create Set Grid Transform with operation 'Boolean'."""
|
|
1401
|
+
return cls(data_type="BOOLEAN", grid=grid, transform=transform)
|
|
1402
|
+
|
|
1403
|
+
@classmethod
|
|
1404
|
+
def vector(
|
|
1405
|
+
cls, grid: TYPE_INPUT_VECTOR = None, transform: TYPE_INPUT_MATRIX = None
|
|
1406
|
+
) -> "SetGridTransform":
|
|
1407
|
+
"""Create Set Grid Transform with operation 'Vector'."""
|
|
1408
|
+
return cls(data_type="VECTOR", grid=grid, transform=transform)
|
|
1409
|
+
|
|
1410
|
+
@property
|
|
1411
|
+
def i_grid(self) -> SocketLinker:
|
|
1412
|
+
"""Input socket: Grid"""
|
|
1413
|
+
return self._input("Grid")
|
|
1414
|
+
|
|
1415
|
+
@property
|
|
1416
|
+
def i_transform(self) -> SocketLinker:
|
|
1417
|
+
"""Input socket: Transform"""
|
|
1418
|
+
return self._input("Transform")
|
|
1419
|
+
|
|
1420
|
+
@property
|
|
1421
|
+
def o_is_valid(self) -> SocketLinker:
|
|
1422
|
+
"""Output socket: Is Valid"""
|
|
1423
|
+
return self._output("Is Valid")
|
|
1424
|
+
|
|
1425
|
+
@property
|
|
1426
|
+
def o_grid(self) -> SocketLinker:
|
|
1427
|
+
"""Output socket: Grid"""
|
|
1428
|
+
return self._output("Grid")
|
|
1429
|
+
|
|
1430
|
+
@property
|
|
1431
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1432
|
+
return self.node.data_type
|
|
1433
|
+
|
|
1434
|
+
@data_type.setter
|
|
1435
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1436
|
+
self.node.data_type = value
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
class StoreNamedGrid(NodeBuilder):
|
|
1440
|
+
"""Store grid data in a volume geometry with the specified name"""
|
|
1441
|
+
|
|
1442
|
+
_bl_idname = "GeometryNodeStoreNamedGrid"
|
|
1443
|
+
node: bpy.types.GeometryNodeStoreNamedGrid
|
|
1444
|
+
|
|
1445
|
+
def __init__(
|
|
1446
|
+
self,
|
|
1447
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1448
|
+
name: TYPE_INPUT_STRING = "",
|
|
1449
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1450
|
+
*,
|
|
1451
|
+
data_type: Literal["BOOLEAN", "FLOAT", "INT", "VECTOR_FLOAT"] = "FLOAT",
|
|
1452
|
+
):
|
|
1453
|
+
super().__init__()
|
|
1454
|
+
key_args = {"Volume": volume, "Name": name, "Grid": grid}
|
|
1455
|
+
self.data_type = data_type
|
|
1456
|
+
self._establish_links(**key_args)
|
|
1457
|
+
|
|
1458
|
+
@classmethod
|
|
1459
|
+
def boolean(
|
|
1460
|
+
cls,
|
|
1461
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1462
|
+
name: TYPE_INPUT_STRING = "",
|
|
1463
|
+
grid: TYPE_INPUT_BOOLEAN = False,
|
|
1464
|
+
) -> "StoreNamedGrid":
|
|
1465
|
+
"""Create Store Named Grid with operation 'Boolean'."""
|
|
1466
|
+
return cls(data_type="BOOLEAN", volume=volume, name=name, grid=grid)
|
|
1467
|
+
|
|
1468
|
+
@classmethod
|
|
1469
|
+
def float(
|
|
1470
|
+
cls,
|
|
1471
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1472
|
+
name: TYPE_INPUT_STRING = "",
|
|
1473
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1474
|
+
) -> "StoreNamedGrid":
|
|
1475
|
+
"""Create Store Named Grid with operation 'Float'."""
|
|
1476
|
+
return cls(data_type="FLOAT", volume=volume, name=name, grid=grid)
|
|
1477
|
+
|
|
1478
|
+
@classmethod
|
|
1479
|
+
def integer(
|
|
1480
|
+
cls,
|
|
1481
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1482
|
+
name: TYPE_INPUT_STRING = "",
|
|
1483
|
+
grid: TYPE_INPUT_INT = 0,
|
|
1484
|
+
) -> "StoreNamedGrid":
|
|
1485
|
+
"""Create Store Named Grid with operation 'Integer'."""
|
|
1486
|
+
return cls(data_type="INT", volume=volume, name=name, grid=grid)
|
|
1487
|
+
|
|
1488
|
+
@classmethod
|
|
1489
|
+
def vector(
|
|
1490
|
+
cls,
|
|
1491
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1492
|
+
name: TYPE_INPUT_STRING = "",
|
|
1493
|
+
grid: TYPE_INPUT_VECTOR = None,
|
|
1494
|
+
) -> "StoreNamedGrid":
|
|
1495
|
+
"""Create Store Named Grid with operation 'Vector'."""
|
|
1496
|
+
return cls(data_type="VECTOR_FLOAT", volume=volume, name=name, grid=grid)
|
|
1497
|
+
|
|
1498
|
+
@property
|
|
1499
|
+
def i_volume(self) -> SocketLinker:
|
|
1500
|
+
"""Input socket: Volume"""
|
|
1501
|
+
return self._input("Volume")
|
|
1502
|
+
|
|
1503
|
+
@property
|
|
1504
|
+
def i_name(self) -> SocketLinker:
|
|
1505
|
+
"""Input socket: Name"""
|
|
1506
|
+
return self._input("Name")
|
|
1507
|
+
|
|
1508
|
+
@property
|
|
1509
|
+
def i_grid(self) -> SocketLinker:
|
|
1510
|
+
"""Input socket: Grid"""
|
|
1511
|
+
return self._input("Grid")
|
|
1512
|
+
|
|
1513
|
+
@property
|
|
1514
|
+
def o_volume(self) -> SocketLinker:
|
|
1515
|
+
"""Output socket: Volume"""
|
|
1516
|
+
return self._output("Volume")
|
|
1517
|
+
|
|
1518
|
+
@property
|
|
1519
|
+
def data_type(self) -> Literal["BOOLEAN", "FLOAT", "INT", "VECTOR_FLOAT"]:
|
|
1520
|
+
return self.node.data_type
|
|
1521
|
+
|
|
1522
|
+
@data_type.setter
|
|
1523
|
+
def data_type(self, value: Literal["BOOLEAN", "FLOAT", "INT", "VECTOR_FLOAT"]):
|
|
1524
|
+
self.node.data_type = value
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
class VolumeCube(NodeBuilder):
|
|
1528
|
+
"""Generate a dense volume with a field that controls the density at each grid voxel based on its position"""
|
|
1529
|
+
|
|
1530
|
+
_bl_idname = "GeometryNodeVolumeCube"
|
|
1531
|
+
node: bpy.types.GeometryNodeVolumeCube
|
|
1532
|
+
|
|
1533
|
+
def __init__(
|
|
1534
|
+
self,
|
|
1535
|
+
density: TYPE_INPUT_VALUE = 1.0,
|
|
1536
|
+
background: TYPE_INPUT_VALUE = 0.0,
|
|
1537
|
+
min: TYPE_INPUT_VECTOR = None,
|
|
1538
|
+
max: TYPE_INPUT_VECTOR = None,
|
|
1539
|
+
resolution_x: TYPE_INPUT_INT = 32,
|
|
1540
|
+
resolution_y: TYPE_INPUT_INT = 32,
|
|
1541
|
+
resolution_z: TYPE_INPUT_INT = 32,
|
|
1542
|
+
):
|
|
1543
|
+
super().__init__()
|
|
1544
|
+
key_args = {
|
|
1545
|
+
"Density": density,
|
|
1546
|
+
"Background": background,
|
|
1547
|
+
"Min": min,
|
|
1548
|
+
"Max": max,
|
|
1549
|
+
"Resolution X": resolution_x,
|
|
1550
|
+
"Resolution Y": resolution_y,
|
|
1551
|
+
"Resolution Z": resolution_z,
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
self._establish_links(**key_args)
|
|
1555
|
+
|
|
1556
|
+
@property
|
|
1557
|
+
def i_density(self) -> SocketLinker:
|
|
1558
|
+
"""Input socket: Density"""
|
|
1559
|
+
return self._input("Density")
|
|
1560
|
+
|
|
1561
|
+
@property
|
|
1562
|
+
def i_background(self) -> SocketLinker:
|
|
1563
|
+
"""Input socket: Background"""
|
|
1564
|
+
return self._input("Background")
|
|
1565
|
+
|
|
1566
|
+
@property
|
|
1567
|
+
def i_min(self) -> SocketLinker:
|
|
1568
|
+
"""Input socket: Min"""
|
|
1569
|
+
return self._input("Min")
|
|
1570
|
+
|
|
1571
|
+
@property
|
|
1572
|
+
def i_max(self) -> SocketLinker:
|
|
1573
|
+
"""Input socket: Max"""
|
|
1574
|
+
return self._input("Max")
|
|
1575
|
+
|
|
1576
|
+
@property
|
|
1577
|
+
def i_resolution_x(self) -> SocketLinker:
|
|
1578
|
+
"""Input socket: Resolution X"""
|
|
1579
|
+
return self._input("Resolution X")
|
|
1580
|
+
|
|
1581
|
+
@property
|
|
1582
|
+
def i_resolution_y(self) -> SocketLinker:
|
|
1583
|
+
"""Input socket: Resolution Y"""
|
|
1584
|
+
return self._input("Resolution Y")
|
|
1585
|
+
|
|
1586
|
+
@property
|
|
1587
|
+
def i_resolution_z(self) -> SocketLinker:
|
|
1588
|
+
"""Input socket: Resolution Z"""
|
|
1589
|
+
return self._input("Resolution Z")
|
|
1590
|
+
|
|
1591
|
+
@property
|
|
1592
|
+
def o_volume(self) -> SocketLinker:
|
|
1593
|
+
"""Output socket: Volume"""
|
|
1594
|
+
return self._output("Volume")
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
class VolumeToMesh(NodeBuilder):
|
|
1598
|
+
"""Generate a mesh on the "surface" of a volume"""
|
|
1599
|
+
|
|
1600
|
+
_bl_idname = "GeometryNodeVolumeToMesh"
|
|
1601
|
+
node: bpy.types.GeometryNodeVolumeToMesh
|
|
1602
|
+
|
|
1603
|
+
def __init__(
|
|
1604
|
+
self,
|
|
1605
|
+
volume: TYPE_INPUT_GEOMETRY = None,
|
|
1606
|
+
resolution_mode: TYPE_INPUT_MENU = "Grid",
|
|
1607
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
1608
|
+
voxel_amount: TYPE_INPUT_VALUE = 64.0,
|
|
1609
|
+
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
1610
|
+
adaptivity: TYPE_INPUT_VALUE = 0.0,
|
|
1611
|
+
):
|
|
1612
|
+
super().__init__()
|
|
1613
|
+
key_args = {
|
|
1614
|
+
"Volume": volume,
|
|
1615
|
+
"Resolution Mode": resolution_mode,
|
|
1616
|
+
"Voxel Size": voxel_size,
|
|
1617
|
+
"Voxel Amount": voxel_amount,
|
|
1618
|
+
"Threshold": threshold,
|
|
1619
|
+
"Adaptivity": adaptivity,
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
self._establish_links(**key_args)
|
|
1623
|
+
|
|
1624
|
+
@property
|
|
1625
|
+
def i_volume(self) -> SocketLinker:
|
|
1626
|
+
"""Input socket: Volume"""
|
|
1627
|
+
return self._input("Volume")
|
|
1628
|
+
|
|
1629
|
+
@property
|
|
1630
|
+
def i_resolution_mode(self) -> SocketLinker:
|
|
1631
|
+
"""Input socket: Resolution Mode"""
|
|
1632
|
+
return self._input("Resolution Mode")
|
|
1633
|
+
|
|
1634
|
+
@property
|
|
1635
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
1636
|
+
"""Input socket: Voxel Size"""
|
|
1637
|
+
return self._input("Voxel Size")
|
|
1638
|
+
|
|
1639
|
+
@property
|
|
1640
|
+
def i_voxel_amount(self) -> SocketLinker:
|
|
1641
|
+
"""Input socket: Voxel Amount"""
|
|
1642
|
+
return self._input("Voxel Amount")
|
|
1643
|
+
|
|
1644
|
+
@property
|
|
1645
|
+
def i_threshold(self) -> SocketLinker:
|
|
1646
|
+
"""Input socket: Threshold"""
|
|
1647
|
+
return self._input("Threshold")
|
|
1648
|
+
|
|
1649
|
+
@property
|
|
1650
|
+
def i_adaptivity(self) -> SocketLinker:
|
|
1651
|
+
"""Input socket: Adaptivity"""
|
|
1652
|
+
return self._input("Adaptivity")
|
|
1653
|
+
|
|
1654
|
+
@property
|
|
1655
|
+
def o_mesh(self) -> SocketLinker:
|
|
1656
|
+
"""Output socket: Mesh"""
|
|
1657
|
+
return self._output("Mesh")
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
class VoxelizeGrid(NodeBuilder):
|
|
1661
|
+
"""Remove sparseness from a volume grid by making the active tiles into voxels"""
|
|
1662
|
+
|
|
1663
|
+
_bl_idname = "GeometryNodeGridVoxelize"
|
|
1664
|
+
node: bpy.types.GeometryNodeGridVoxelize
|
|
1665
|
+
|
|
1666
|
+
def __init__(
|
|
1667
|
+
self,
|
|
1668
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1669
|
+
*,
|
|
1670
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1671
|
+
):
|
|
1672
|
+
super().__init__()
|
|
1673
|
+
key_args = {"Grid": grid}
|
|
1674
|
+
self.data_type = data_type
|
|
1675
|
+
self._establish_links(**key_args)
|
|
1676
|
+
|
|
1677
|
+
@classmethod
|
|
1678
|
+
def float(cls, grid: TYPE_INPUT_VALUE = 0.0) -> "VoxelizeGrid":
|
|
1679
|
+
"""Create Voxelize Grid with operation 'Float'."""
|
|
1680
|
+
return cls(data_type="FLOAT", grid=grid)
|
|
1681
|
+
|
|
1682
|
+
@classmethod
|
|
1683
|
+
def integer(cls, grid: TYPE_INPUT_INT = 0) -> "VoxelizeGrid":
|
|
1684
|
+
"""Create Voxelize Grid with operation 'Integer'."""
|
|
1685
|
+
return cls(data_type="INT", grid=grid)
|
|
1686
|
+
|
|
1687
|
+
@classmethod
|
|
1688
|
+
def boolean(cls, grid: TYPE_INPUT_BOOLEAN = False) -> "VoxelizeGrid":
|
|
1689
|
+
"""Create Voxelize Grid with operation 'Boolean'."""
|
|
1690
|
+
return cls(data_type="BOOLEAN", grid=grid)
|
|
1691
|
+
|
|
1692
|
+
@classmethod
|
|
1693
|
+
def vector(cls, grid: TYPE_INPUT_VECTOR = None) -> "VoxelizeGrid":
|
|
1694
|
+
"""Create Voxelize Grid with operation 'Vector'."""
|
|
1695
|
+
return cls(data_type="VECTOR", grid=grid)
|
|
1696
|
+
|
|
1697
|
+
@property
|
|
1698
|
+
def i_grid(self) -> SocketLinker:
|
|
1699
|
+
"""Input socket: Grid"""
|
|
1700
|
+
return self._input("Grid")
|
|
1701
|
+
|
|
1702
|
+
@property
|
|
1703
|
+
def o_grid(self) -> SocketLinker:
|
|
1704
|
+
"""Output socket: Grid"""
|
|
1705
|
+
return self._output("Grid")
|
|
1706
|
+
|
|
1707
|
+
@property
|
|
1708
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1709
|
+
return self.node.data_type
|
|
1710
|
+
|
|
1711
|
+
@data_type.setter
|
|
1712
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1713
|
+
self.node.data_type = value
|