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.
- nodebpy/builder.py +19 -13
- nodebpy/nodes/__init__.py +352 -335
- nodebpy/nodes/attribute.py +362 -307
- nodebpy/nodes/color.py +30 -34
- nodebpy/nodes/converter.py +1987 -2978
- nodebpy/nodes/experimental.py +201 -203
- nodebpy/nodes/geometry.py +4189 -3644
- nodebpy/nodes/grid.py +932 -447
- nodebpy/nodes/group.py +7 -10
- nodebpy/nodes/input.py +1496 -1308
- nodebpy/nodes/interface.py +236 -117
- nodebpy/nodes/manual.py +2022 -0
- nodebpy/nodes/output.py +85 -0
- nodebpy/nodes/texture.py +867 -7
- nodebpy/nodes/vector.py +528 -0
- nodebpy/nodes/zone.py +7 -7
- nodebpy/{nodes/types.py → types.py} +14 -1
- {nodebpy-0.2.0.dist-info → nodebpy-0.2.1.dist-info}/METADATA +2 -2
- nodebpy-0.2.1.dist-info/RECORD +26 -0
- nodebpy/nodes/mesh.py +0 -17
- nodebpy-0.2.0.dist-info/RECORD +0 -25
- {nodebpy-0.2.0.dist-info → nodebpy-0.2.1.dist-info}/WHEEL +0 -0
- {nodebpy-0.2.0.dist-info → nodebpy-0.2.1.dist-info}/entry_points.txt +0 -0
nodebpy/nodes/grid.py
CHANGED
|
@@ -1,59 +1,103 @@
|
|
|
1
|
-
import
|
|
2
|
-
from typing_extensions import Literal
|
|
1
|
+
from typing import Literal
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import bpy
|
|
5
4
|
|
|
6
|
-
from
|
|
7
|
-
|
|
5
|
+
from ..builder import NodeBuilder, SocketLinker
|
|
6
|
+
from ..types import (
|
|
8
7
|
TYPE_INPUT_BOOLEAN,
|
|
9
8
|
TYPE_INPUT_GEOMETRY,
|
|
10
|
-
TYPE_INPUT_GRID,
|
|
11
9
|
TYPE_INPUT_INT,
|
|
10
|
+
TYPE_INPUT_MENU,
|
|
12
11
|
TYPE_INPUT_STRING,
|
|
12
|
+
TYPE_INPUT_MATRIX,
|
|
13
13
|
TYPE_INPUT_VALUE,
|
|
14
14
|
TYPE_INPUT_VECTOR,
|
|
15
|
-
_AdvectGridIntegration,
|
|
16
|
-
_GridDataTypes,
|
|
17
15
|
)
|
|
18
16
|
|
|
19
17
|
|
|
20
|
-
class
|
|
21
|
-
"""
|
|
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"""
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
node: bpy.types.
|
|
21
|
+
_bl_idname = "GeometryNodeGridAdvect"
|
|
22
|
+
node: bpy.types.GeometryNodeGridAdvect
|
|
25
23
|
|
|
26
24
|
def __init__(
|
|
27
25
|
self,
|
|
28
|
-
grid:
|
|
29
|
-
|
|
30
|
-
|
|
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",
|
|
31
33
|
):
|
|
32
34
|
super().__init__()
|
|
33
35
|
key_args = {
|
|
34
36
|
"Grid": grid,
|
|
37
|
+
"Velocity": velocity,
|
|
38
|
+
"Time Step": time_step,
|
|
39
|
+
"Integration Scheme": integration_scheme,
|
|
40
|
+
"Limiter": limiter,
|
|
35
41
|
}
|
|
36
|
-
self.
|
|
37
|
-
key_args.update(kwargs)
|
|
42
|
+
self.data_type = data_type
|
|
38
43
|
self._establish_links(**key_args)
|
|
39
44
|
|
|
40
45
|
@classmethod
|
|
41
|
-
def
|
|
46
|
+
def float(
|
|
42
47
|
cls,
|
|
43
|
-
grid:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
+
)
|
|
48
63
|
|
|
49
64
|
@classmethod
|
|
50
|
-
def
|
|
65
|
+
def integer(
|
|
51
66
|
cls,
|
|
52
|
-
grid:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
+
)
|
|
57
101
|
|
|
58
102
|
@property
|
|
59
103
|
def i_grid(self) -> SocketLinker:
|
|
@@ -61,66 +105,70 @@ class DistributePointsInGrid(NodeBuilder):
|
|
|
61
105
|
return self._input("Grid")
|
|
62
106
|
|
|
63
107
|
@property
|
|
64
|
-
def
|
|
65
|
-
"""Input socket:
|
|
66
|
-
return self._input("
|
|
108
|
+
def i_velocity(self) -> SocketLinker:
|
|
109
|
+
"""Input socket: Velocity"""
|
|
110
|
+
return self._input("Velocity")
|
|
67
111
|
|
|
68
112
|
@property
|
|
69
|
-
def
|
|
70
|
-
"""Input socket:
|
|
71
|
-
return self._input("
|
|
113
|
+
def i_time_step(self) -> SocketLinker:
|
|
114
|
+
"""Input socket: Time Step"""
|
|
115
|
+
return self._input("Time Step")
|
|
72
116
|
|
|
73
117
|
@property
|
|
74
|
-
def
|
|
75
|
-
"""
|
|
76
|
-
return self.
|
|
118
|
+
def i_integration_scheme(self) -> SocketLinker:
|
|
119
|
+
"""Input socket: Integration Scheme"""
|
|
120
|
+
return self._input("Integration Scheme")
|
|
77
121
|
|
|
78
122
|
@property
|
|
79
|
-
def
|
|
80
|
-
|
|
123
|
+
def i_limiter(self) -> SocketLinker:
|
|
124
|
+
"""Input socket: Limiter"""
|
|
125
|
+
return self._input("Limiter")
|
|
81
126
|
|
|
82
|
-
@
|
|
83
|
-
def
|
|
84
|
-
|
|
127
|
+
@property
|
|
128
|
+
def o_grid(self) -> SocketLinker:
|
|
129
|
+
"""Output socket: Grid"""
|
|
130
|
+
return self._output("Grid")
|
|
85
131
|
|
|
132
|
+
@property
|
|
133
|
+
def data_type(self) -> Literal["FLOAT", "INT", "VECTOR"]:
|
|
134
|
+
return self.node.data_type
|
|
86
135
|
|
|
87
|
-
|
|
88
|
-
|
|
136
|
+
@data_type.setter
|
|
137
|
+
def data_type(self, value: Literal["FLOAT", "INT", "VECTOR"]):
|
|
138
|
+
self.node.data_type = value
|
|
89
139
|
|
|
90
|
-
|
|
91
|
-
|
|
140
|
+
|
|
141
|
+
class DistributePointsInGrid(NodeBuilder):
|
|
142
|
+
"""Generate points inside a volume grid"""
|
|
143
|
+
|
|
144
|
+
_bl_idname = "GeometryNodeDistributePointsInGrid"
|
|
145
|
+
node: bpy.types.GeometryNodeDistributePointsInGrid
|
|
92
146
|
|
|
93
147
|
def __init__(
|
|
94
148
|
self,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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",
|
|
98
156
|
):
|
|
99
157
|
super().__init__()
|
|
100
158
|
key_args = {
|
|
101
|
-
"
|
|
102
|
-
"
|
|
159
|
+
"Grid": grid,
|
|
160
|
+
"Density": density,
|
|
161
|
+
"Seed": seed,
|
|
162
|
+
"Spacing": spacing,
|
|
163
|
+
"Threshold": threshold,
|
|
103
164
|
}
|
|
104
|
-
|
|
165
|
+
self.mode = mode
|
|
105
166
|
self._establish_links(**key_args)
|
|
106
167
|
|
|
107
|
-
@
|
|
108
|
-
def
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
density: TYPE_INPUT_VALUE = 1.0,
|
|
112
|
-
seed: TYPE_INPUT_INT = 0,
|
|
113
|
-
):
|
|
114
|
-
return cls(volume=volume, Density=density, Seed=seed, mode="Grid")
|
|
115
|
-
|
|
116
|
-
@classmethod
|
|
117
|
-
def random(
|
|
118
|
-
cls,
|
|
119
|
-
volume: TYPE_INPUT_GEOMETRY = None,
|
|
120
|
-
spacing: TYPE_INPUT_VECTOR = (0.3, 0.3, 0.3),
|
|
121
|
-
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
122
|
-
):
|
|
123
|
-
return cls(volume=volume, Space=spacing, Threshold=threshold, mode="Random")
|
|
168
|
+
@property
|
|
169
|
+
def i_grid(self) -> SocketLinker:
|
|
170
|
+
"""Input socket: Grid"""
|
|
171
|
+
return self._input("Grid")
|
|
124
172
|
|
|
125
173
|
@property
|
|
126
174
|
def i_density(self) -> SocketLinker:
|
|
@@ -147,122 +195,137 @@ class DistributePointsInVolume(NodeBuilder):
|
|
|
147
195
|
"""Output socket: Points"""
|
|
148
196
|
return self._output("Points")
|
|
149
197
|
|
|
198
|
+
@property
|
|
199
|
+
def mode(self) -> Literal["DENSITY_RANDOM", "DENSITY_GRID"]:
|
|
200
|
+
return self.node.mode
|
|
150
201
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
New socket items for field evaluation are first created from *args then **kwargs to give specific names to the items.
|
|
155
|
-
|
|
156
|
-
Data types are inferred automatically from the closest compatible data type.
|
|
202
|
+
@mode.setter
|
|
203
|
+
def mode(self, value: Literal["DENSITY_RANDOM", "DENSITY_GRID"]):
|
|
204
|
+
self.node.mode = value
|
|
157
205
|
|
|
158
|
-
Inputs:
|
|
159
|
-
-------
|
|
160
|
-
topology: LINKABLE
|
|
161
|
-
The grid which contains the topology to evaluate the different fields on.
|
|
162
|
-
data_type: _GridDataTypes = "FLOAT"
|
|
163
|
-
The data type of the grid to evaluate on. Possible values are "FLOAT", "INT", "VECTOR", "BOOLEAN".
|
|
164
|
-
*args: TYPE_INPUT_VALUE | TYPE_INPUT_VECTOR | TYPE_INPUT_INT | TYPE_INPUT_BOOLEAN
|
|
165
|
-
The fields to evaluate on the grid.
|
|
166
|
-
**kwargs: dict[str, TYPE_INPUT_VALUE | TYPE_INPUT_VECTOR | TYPE_INPUT_INT | TYPE_INPUT_GEOMETRY]
|
|
167
|
-
The key-value pairs of the fields to evaluate on the grid. Keys will be used as the name of the socket.
|
|
168
206
|
|
|
169
|
-
|
|
207
|
+
class DistributePointsInVolume(NodeBuilder):
|
|
208
|
+
"""Generate points inside a volume"""
|
|
170
209
|
|
|
171
|
-
|
|
172
|
-
node: bpy.types.
|
|
173
|
-
_socket_data_types = ("FLOAT", "VALUE", "INT", "VECTOR", "BOOLEAN")
|
|
174
|
-
_default_input_id = "Topology"
|
|
210
|
+
_bl_idname = "GeometryNodeDistributePointsInVolume"
|
|
211
|
+
node: bpy.types.GeometryNodeDistributePointsInVolume
|
|
175
212
|
|
|
176
213
|
def __init__(
|
|
177
214
|
self,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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,
|
|
182
221
|
):
|
|
183
222
|
super().__init__()
|
|
184
|
-
self.data_type = data_type
|
|
185
223
|
key_args = {
|
|
186
|
-
"
|
|
224
|
+
"Volume": volume,
|
|
225
|
+
"Mode": mode,
|
|
226
|
+
"Density": density,
|
|
227
|
+
"Seed": seed,
|
|
228
|
+
"Spacing": spacing,
|
|
229
|
+
"Threshold": threshold,
|
|
187
230
|
}
|
|
188
|
-
|
|
231
|
+
|
|
189
232
|
self._establish_links(**key_args)
|
|
190
233
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
default_value: float | int | str | None = None,
|
|
196
|
-
):
|
|
197
|
-
item = self.node.grid_items.new(socket_type=type, name=name)
|
|
198
|
-
if default_value is not None:
|
|
199
|
-
try:
|
|
200
|
-
self.node.inputs[item.name].default_value = default_value # type: ignore
|
|
201
|
-
except TypeError as e:
|
|
202
|
-
raise ValueError(
|
|
203
|
-
f"Invalid default value for {type}: {default_value}"
|
|
204
|
-
) from e
|
|
205
|
-
return self.node.inputs[item.name]
|
|
206
|
-
|
|
207
|
-
def capture(self, *args, **kwargs) -> list[SocketLinker]:
|
|
208
|
-
outputs = {
|
|
209
|
-
name: self.node.outputs[name] for name in self._add_inputs(*args, **kwargs)
|
|
210
|
-
}
|
|
234
|
+
@property
|
|
235
|
+
def i_volume(self) -> SocketLinker:
|
|
236
|
+
"""Input socket: Volume"""
|
|
237
|
+
return self._input("Volume")
|
|
211
238
|
|
|
212
|
-
|
|
239
|
+
@property
|
|
240
|
+
def i_mode(self) -> SocketLinker:
|
|
241
|
+
"""Input socket: Mode"""
|
|
242
|
+
return self._input("Mode")
|
|
213
243
|
|
|
214
244
|
@property
|
|
215
|
-
def
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
for item in self.node.grid_items
|
|
219
|
-
}
|
|
245
|
+
def i_density(self) -> SocketLinker:
|
|
246
|
+
"""Input socket: Density"""
|
|
247
|
+
return self._input("Density")
|
|
220
248
|
|
|
221
249
|
@property
|
|
222
|
-
def
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
for item in self.node.grid_items
|
|
226
|
-
}
|
|
250
|
+
def i_seed(self) -> SocketLinker:
|
|
251
|
+
"""Input socket: Seed"""
|
|
252
|
+
return self._input("Seed")
|
|
227
253
|
|
|
228
254
|
@property
|
|
229
|
-
def
|
|
230
|
-
"""Input socket:
|
|
231
|
-
return self._input("
|
|
255
|
+
def i_spacing(self) -> SocketLinker:
|
|
256
|
+
"""Input socket: Spacing"""
|
|
257
|
+
return self._input("Spacing")
|
|
232
258
|
|
|
233
259
|
@property
|
|
234
|
-
def
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return self.node.data_type # type: ignore
|
|
260
|
+
def i_threshold(self) -> SocketLinker:
|
|
261
|
+
"""Input socket: Threshold"""
|
|
262
|
+
return self._input("Threshold")
|
|
238
263
|
|
|
239
|
-
@
|
|
240
|
-
def
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
):
|
|
244
|
-
self.node.data_type = value
|
|
264
|
+
@property
|
|
265
|
+
def o_points(self) -> SocketLinker:
|
|
266
|
+
"""Output socket: Points"""
|
|
267
|
+
return self._output("Points")
|
|
245
268
|
|
|
246
269
|
|
|
247
270
|
class GetNamedGrid(NodeBuilder):
|
|
248
271
|
"""Get volume grid from a volume geometry with the specified name"""
|
|
249
272
|
|
|
250
|
-
|
|
273
|
+
_bl_idname = "GeometryNodeGetNamedGrid"
|
|
251
274
|
node: bpy.types.GeometryNodeGetNamedGrid
|
|
252
|
-
_default_input_id = "Volume"
|
|
253
275
|
|
|
254
276
|
def __init__(
|
|
255
277
|
self,
|
|
256
278
|
volume: TYPE_INPUT_GEOMETRY = None,
|
|
257
279
|
name: TYPE_INPUT_STRING = "",
|
|
258
280
|
remove: TYPE_INPUT_BOOLEAN = True,
|
|
259
|
-
|
|
281
|
+
*,
|
|
282
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
260
283
|
):
|
|
261
284
|
super().__init__()
|
|
262
285
|
key_args = {"Volume": volume, "Name": name, "Remove": remove}
|
|
263
286
|
self.data_type = data_type
|
|
264
287
|
self._establish_links(**key_args)
|
|
265
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
|
+
|
|
266
329
|
@property
|
|
267
330
|
def i_volume(self) -> SocketLinker:
|
|
268
331
|
"""Input socket: Volume"""
|
|
@@ -289,100 +352,24 @@ class GetNamedGrid(NodeBuilder):
|
|
|
289
352
|
return self._output("Grid")
|
|
290
353
|
|
|
291
354
|
@property
|
|
292
|
-
def data_type(
|
|
293
|
-
self
|
|
294
|
-
) -> _GridDataTypes:
|
|
295
|
-
return self.node.data_type # type: ignore
|
|
355
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
356
|
+
return self.node.data_type
|
|
296
357
|
|
|
297
358
|
@data_type.setter
|
|
298
|
-
def data_type(
|
|
299
|
-
self,
|
|
300
|
-
value: _GridDataTypes,
|
|
301
|
-
):
|
|
302
|
-
self.node.data_type = value
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
class AdvectGrid(NodeBuilder):
|
|
306
|
-
"""Move grid values through a velocity field using numerical integration. Supports multiple integration schemes for different accuracy and performance trade-offs"""
|
|
307
|
-
|
|
308
|
-
name = "GeometryNodeGridAdvect"
|
|
309
|
-
node: bpy.types.GeometryNodeGridAdvect
|
|
310
|
-
_socket_data_types = ["FLOAT", "VALUE", "INT", "VECTOR"]
|
|
311
|
-
|
|
312
|
-
def __init__(
|
|
313
|
-
self,
|
|
314
|
-
grid: TYPE_INPUT_VALUE = None,
|
|
315
|
-
velocity: TYPE_INPUT_VECTOR = None,
|
|
316
|
-
time_step: TYPE_INPUT_VALUE = 1.0,
|
|
317
|
-
*,
|
|
318
|
-
integration_scheme: _AdvectGridIntegration = "Runge-Kutta 3",
|
|
319
|
-
limiter: Literal["None", "Clamp", "Revert"] = "Clamp",
|
|
320
|
-
data_type: Literal["FLOAT", "INT", "VECTOR"] = "FLOAT",
|
|
321
|
-
):
|
|
322
|
-
super().__init__()
|
|
323
|
-
key_args = {
|
|
324
|
-
"Grid": grid,
|
|
325
|
-
"Velocity": velocity,
|
|
326
|
-
"Time Step": time_step,
|
|
327
|
-
"Integration Scheme": integration_scheme,
|
|
328
|
-
"Limiter": limiter,
|
|
329
|
-
}
|
|
330
|
-
self.data_type = data_type
|
|
331
|
-
self._establish_links(**key_args)
|
|
332
|
-
|
|
333
|
-
@property
|
|
334
|
-
def i_grid(self) -> SocketLinker:
|
|
335
|
-
"""Input socket: Grid"""
|
|
336
|
-
return self._input("Grid")
|
|
337
|
-
|
|
338
|
-
@property
|
|
339
|
-
def i_velocity(self) -> SocketLinker:
|
|
340
|
-
"""Input socket: Velocity"""
|
|
341
|
-
return self._input("Velocity")
|
|
342
|
-
|
|
343
|
-
@property
|
|
344
|
-
def i_time_step(self) -> SocketLinker:
|
|
345
|
-
"""Input socket: Time Step"""
|
|
346
|
-
return self._input("Time Step")
|
|
347
|
-
|
|
348
|
-
@property
|
|
349
|
-
def i_integration_scheme(self) -> SocketLinker:
|
|
350
|
-
"""Input socket: Integration Scheme"""
|
|
351
|
-
return self._input("Integration Scheme")
|
|
352
|
-
|
|
353
|
-
@property
|
|
354
|
-
def i_limiter(self) -> SocketLinker:
|
|
355
|
-
"""Input socket: Limiter"""
|
|
356
|
-
return self._input("Limiter")
|
|
357
|
-
|
|
358
|
-
@property
|
|
359
|
-
def o_grid(self) -> SocketLinker:
|
|
360
|
-
"""Output socket: Grid"""
|
|
361
|
-
return self._output("Grid")
|
|
362
|
-
|
|
363
|
-
@property
|
|
364
|
-
def data_type(
|
|
365
|
-
self,
|
|
366
|
-
) -> Literal["FLOAT", "INT", "VECTOR"]:
|
|
367
|
-
return self.node.data_type # type: ignore
|
|
368
|
-
|
|
369
|
-
@data_type.setter
|
|
370
|
-
def data_type(
|
|
371
|
-
self,
|
|
372
|
-
value: Literal["FLOAT", "INT", "VECTOR"],
|
|
373
|
-
):
|
|
359
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
374
360
|
self.node.data_type = value
|
|
375
361
|
|
|
376
362
|
|
|
377
363
|
class GridCurl(NodeBuilder):
|
|
378
364
|
"""Calculate the magnitude and direction of circulation of a directional vector grid"""
|
|
379
365
|
|
|
380
|
-
|
|
366
|
+
_bl_idname = "GeometryNodeGridCurl"
|
|
381
367
|
node: bpy.types.GeometryNodeGridCurl
|
|
382
368
|
|
|
383
369
|
def __init__(self, grid: TYPE_INPUT_VECTOR = None):
|
|
384
370
|
super().__init__()
|
|
385
371
|
key_args = {"Grid": grid}
|
|
372
|
+
|
|
386
373
|
self._establish_links(**key_args)
|
|
387
374
|
|
|
388
375
|
@property
|
|
@@ -399,12 +386,13 @@ class GridCurl(NodeBuilder):
|
|
|
399
386
|
class GridDivergence(NodeBuilder):
|
|
400
387
|
"""Calculate the flow into and out of each point of a directional vector grid"""
|
|
401
388
|
|
|
402
|
-
|
|
389
|
+
_bl_idname = "GeometryNodeGridDivergence"
|
|
403
390
|
node: bpy.types.GeometryNodeGridDivergence
|
|
404
391
|
|
|
405
392
|
def __init__(self, grid: TYPE_INPUT_VECTOR = None):
|
|
406
393
|
super().__init__()
|
|
407
394
|
key_args = {"Grid": grid}
|
|
395
|
+
|
|
408
396
|
self._establish_links(**key_args)
|
|
409
397
|
|
|
410
398
|
@property
|
|
@@ -421,12 +409,13 @@ class GridDivergence(NodeBuilder):
|
|
|
421
409
|
class GridGradient(NodeBuilder):
|
|
422
410
|
"""Calculate the direction and magnitude of the change in values of a scalar grid"""
|
|
423
411
|
|
|
424
|
-
|
|
412
|
+
_bl_idname = "GeometryNodeGridGradient"
|
|
425
413
|
node: bpy.types.GeometryNodeGridGradient
|
|
426
414
|
|
|
427
|
-
def __init__(self, grid: TYPE_INPUT_VALUE =
|
|
415
|
+
def __init__(self, grid: TYPE_INPUT_VALUE = 0.0):
|
|
428
416
|
super().__init__()
|
|
429
417
|
key_args = {"Grid": grid}
|
|
418
|
+
|
|
430
419
|
self._establish_links(**key_args)
|
|
431
420
|
|
|
432
421
|
@property
|
|
@@ -443,17 +432,40 @@ class GridGradient(NodeBuilder):
|
|
|
443
432
|
class GridInfo(NodeBuilder):
|
|
444
433
|
"""Retrieve information about a volume grid"""
|
|
445
434
|
|
|
446
|
-
|
|
435
|
+
_bl_idname = "GeometryNodeGridInfo"
|
|
447
436
|
node: bpy.types.GeometryNodeGridInfo
|
|
448
437
|
|
|
449
438
|
def __init__(
|
|
450
|
-
self,
|
|
439
|
+
self,
|
|
440
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
441
|
+
*,
|
|
442
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
451
443
|
):
|
|
452
444
|
super().__init__()
|
|
453
445
|
key_args = {"Grid": grid}
|
|
454
446
|
self.data_type = data_type
|
|
455
447
|
self._establish_links(**key_args)
|
|
456
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
|
+
|
|
457
469
|
@property
|
|
458
470
|
def i_grid(self) -> SocketLinker:
|
|
459
471
|
"""Input socket: Grid"""
|
|
@@ -470,28 +482,24 @@ class GridInfo(NodeBuilder):
|
|
|
470
482
|
return self._output("Background Value")
|
|
471
483
|
|
|
472
484
|
@property
|
|
473
|
-
def data_type(
|
|
474
|
-
self
|
|
475
|
-
) -> _GridDataTypes:
|
|
476
|
-
return self.node.data_type # type: ignore
|
|
485
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
486
|
+
return self.node.data_type
|
|
477
487
|
|
|
478
488
|
@data_type.setter
|
|
479
|
-
def data_type(
|
|
480
|
-
self,
|
|
481
|
-
value: _GridDataTypes,
|
|
482
|
-
):
|
|
489
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
483
490
|
self.node.data_type = value
|
|
484
491
|
|
|
485
492
|
|
|
486
493
|
class GridLaplacian(NodeBuilder):
|
|
487
494
|
"""Compute the divergence of the gradient of the input grid"""
|
|
488
495
|
|
|
489
|
-
|
|
496
|
+
_bl_idname = "GeometryNodeGridLaplacian"
|
|
490
497
|
node: bpy.types.GeometryNodeGridLaplacian
|
|
491
498
|
|
|
492
|
-
def __init__(self, grid: TYPE_INPUT_VALUE =
|
|
499
|
+
def __init__(self, grid: TYPE_INPUT_VALUE = 0.0):
|
|
493
500
|
super().__init__()
|
|
494
501
|
key_args = {"Grid": grid}
|
|
502
|
+
|
|
495
503
|
self._establish_links(**key_args)
|
|
496
504
|
|
|
497
505
|
@property
|
|
@@ -505,23 +513,21 @@ class GridLaplacian(NodeBuilder):
|
|
|
505
513
|
return self._output("Laplacian")
|
|
506
514
|
|
|
507
515
|
|
|
508
|
-
class
|
|
509
|
-
"""
|
|
516
|
+
class GridToMesh(NodeBuilder):
|
|
517
|
+
"""Generate a mesh on the "surface" of a volume grid"""
|
|
510
518
|
|
|
511
|
-
|
|
512
|
-
node: bpy.types.
|
|
519
|
+
_bl_idname = "GeometryNodeGridToMesh"
|
|
520
|
+
node: bpy.types.GeometryNodeGridToMesh
|
|
513
521
|
|
|
514
522
|
def __init__(
|
|
515
523
|
self,
|
|
516
|
-
grid:
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
threshold: TYPE_INPUT_VALUE = 0.01,
|
|
520
|
-
data_type: _GridDataTypes = "FLOAT",
|
|
524
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
525
|
+
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
526
|
+
adaptivity: TYPE_INPUT_VALUE = 0.0,
|
|
521
527
|
):
|
|
522
528
|
super().__init__()
|
|
523
|
-
key_args = {"Grid": grid, "
|
|
524
|
-
|
|
529
|
+
key_args = {"Grid": grid, "Threshold": threshold, "Adaptivity": adaptivity}
|
|
530
|
+
|
|
525
531
|
self._establish_links(**key_args)
|
|
526
532
|
|
|
527
533
|
@property
|
|
@@ -529,135 +535,266 @@ class PruneGrid(NodeBuilder):
|
|
|
529
535
|
"""Input socket: Grid"""
|
|
530
536
|
return self._input("Grid")
|
|
531
537
|
|
|
532
|
-
@property
|
|
533
|
-
def i_mode(self) -> SocketLinker:
|
|
534
|
-
"""Input socket: Mode"""
|
|
535
|
-
return self._input("Mode")
|
|
536
|
-
|
|
537
538
|
@property
|
|
538
539
|
def i_threshold(self) -> SocketLinker:
|
|
539
540
|
"""Input socket: Threshold"""
|
|
540
541
|
return self._input("Threshold")
|
|
541
542
|
|
|
542
543
|
@property
|
|
543
|
-
def
|
|
544
|
-
"""
|
|
545
|
-
return self.
|
|
544
|
+
def i_adaptivity(self) -> SocketLinker:
|
|
545
|
+
"""Input socket: Adaptivity"""
|
|
546
|
+
return self._input("Adaptivity")
|
|
546
547
|
|
|
547
548
|
@property
|
|
548
|
-
def
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
return self.node.data_type # type: ignore
|
|
549
|
+
def o_mesh(self) -> SocketLinker:
|
|
550
|
+
"""Output socket: Mesh"""
|
|
551
|
+
return self._output("Mesh")
|
|
552
552
|
|
|
553
|
-
|
|
554
|
-
|
|
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__(
|
|
555
561
|
self,
|
|
556
|
-
|
|
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,
|
|
557
566
|
):
|
|
558
|
-
|
|
567
|
+
super().__init__()
|
|
568
|
+
key_args = {
|
|
569
|
+
"Mesh": mesh,
|
|
570
|
+
"Density": density,
|
|
571
|
+
"Voxel Size": voxel_size,
|
|
572
|
+
"Gradient Width": gradient_width,
|
|
573
|
+
}
|
|
559
574
|
|
|
575
|
+
self._establish_links(**key_args)
|
|
560
576
|
|
|
561
|
-
|
|
562
|
-
|
|
577
|
+
@property
|
|
578
|
+
def i_mesh(self) -> SocketLinker:
|
|
579
|
+
"""Input socket: Mesh"""
|
|
580
|
+
return self._input("Mesh")
|
|
563
581
|
|
|
564
|
-
|
|
565
|
-
|
|
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
|
|
566
608
|
|
|
567
609
|
def __init__(
|
|
568
|
-
self,
|
|
610
|
+
self,
|
|
611
|
+
mesh: TYPE_INPUT_GEOMETRY = None,
|
|
612
|
+
voxel_size: TYPE_INPUT_VALUE = 0.3,
|
|
613
|
+
band_width: TYPE_INPUT_INT = 3,
|
|
569
614
|
):
|
|
570
615
|
super().__init__()
|
|
571
|
-
key_args = {"
|
|
572
|
-
|
|
616
|
+
key_args = {"Mesh": mesh, "Voxel Size": voxel_size, "Band Width": band_width}
|
|
617
|
+
|
|
573
618
|
self._establish_links(**key_args)
|
|
574
619
|
|
|
575
620
|
@property
|
|
576
|
-
def
|
|
577
|
-
"""Input socket:
|
|
578
|
-
return self._input("
|
|
621
|
+
def i_mesh(self) -> SocketLinker:
|
|
622
|
+
"""Input socket: Mesh"""
|
|
623
|
+
return self._input("Mesh")
|
|
579
624
|
|
|
580
625
|
@property
|
|
581
|
-
def
|
|
582
|
-
"""
|
|
583
|
-
return self.
|
|
626
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
627
|
+
"""Input socket: Voxel Size"""
|
|
628
|
+
return self._input("Voxel Size")
|
|
584
629
|
|
|
585
630
|
@property
|
|
586
|
-
def
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return self.node.data_type # type: ignore
|
|
631
|
+
def i_band_width(self) -> SocketLinker:
|
|
632
|
+
"""Input socket: Band Width"""
|
|
633
|
+
return self._input("Band Width")
|
|
590
634
|
|
|
591
|
-
@
|
|
592
|
-
def
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
):
|
|
596
|
-
self.node.data_type = value
|
|
635
|
+
@property
|
|
636
|
+
def o_sdf_grid(self) -> SocketLinker:
|
|
637
|
+
"""Output socket: SDF Grid"""
|
|
638
|
+
return self._output("SDF Grid")
|
|
597
639
|
|
|
598
640
|
|
|
599
|
-
class
|
|
600
|
-
"""
|
|
641
|
+
class MeshToVolume(NodeBuilder):
|
|
642
|
+
"""Create a fog volume with the shape of the input mesh's surface"""
|
|
601
643
|
|
|
602
|
-
|
|
603
|
-
node: bpy.types.
|
|
644
|
+
_bl_idname = "GeometryNodeMeshToVolume"
|
|
645
|
+
node: bpy.types.GeometryNodeMeshToVolume
|
|
604
646
|
|
|
605
647
|
def __init__(
|
|
606
648
|
self,
|
|
649
|
+
mesh: TYPE_INPUT_GEOMETRY = None,
|
|
607
650
|
density: TYPE_INPUT_VALUE = 1.0,
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
resolution_y: TYPE_INPUT_INT = 32,
|
|
613
|
-
resolution_z: TYPE_INPUT_INT = 32,
|
|
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,
|
|
614
655
|
):
|
|
615
656
|
super().__init__()
|
|
616
657
|
key_args = {
|
|
658
|
+
"Mesh": mesh,
|
|
617
659
|
"Density": density,
|
|
618
|
-
"
|
|
619
|
-
"
|
|
620
|
-
"
|
|
621
|
-
"
|
|
622
|
-
"Resolution Y": resolution_y,
|
|
623
|
-
"Resolution Z": resolution_z,
|
|
660
|
+
"Resolution Mode": resolution_mode,
|
|
661
|
+
"Voxel Size": voxel_size,
|
|
662
|
+
"Voxel Amount": voxel_amount,
|
|
663
|
+
"Interior Band Width": interior_band_width,
|
|
624
664
|
}
|
|
665
|
+
|
|
625
666
|
self._establish_links(**key_args)
|
|
626
667
|
|
|
668
|
+
@property
|
|
669
|
+
def i_mesh(self) -> SocketLinker:
|
|
670
|
+
"""Input socket: Mesh"""
|
|
671
|
+
return self._input("Mesh")
|
|
672
|
+
|
|
627
673
|
@property
|
|
628
674
|
def i_density(self) -> SocketLinker:
|
|
629
675
|
"""Input socket: Density"""
|
|
630
676
|
return self._input("Density")
|
|
631
677
|
|
|
632
678
|
@property
|
|
633
|
-
def
|
|
634
|
-
"""Input socket:
|
|
635
|
-
return self._input("
|
|
679
|
+
def i_resolution_mode(self) -> SocketLinker:
|
|
680
|
+
"""Input socket: Resolution Mode"""
|
|
681
|
+
return self._input("Resolution Mode")
|
|
636
682
|
|
|
637
683
|
@property
|
|
638
|
-
def
|
|
639
|
-
"""Input socket:
|
|
640
|
-
return self._input("
|
|
684
|
+
def i_voxel_size(self) -> SocketLinker:
|
|
685
|
+
"""Input socket: Voxel Size"""
|
|
686
|
+
return self._input("Voxel Size")
|
|
641
687
|
|
|
642
688
|
@property
|
|
643
|
-
def
|
|
644
|
-
"""Input socket:
|
|
645
|
-
return self._input("
|
|
689
|
+
def i_voxel_amount(self) -> SocketLinker:
|
|
690
|
+
"""Input socket: Voxel Amount"""
|
|
691
|
+
return self._input("Voxel Amount")
|
|
646
692
|
|
|
647
693
|
@property
|
|
648
|
-
def
|
|
649
|
-
"""Input socket:
|
|
650
|
-
return self._input("
|
|
694
|
+
def i_interior_band_width(self) -> SocketLinker:
|
|
695
|
+
"""Input socket: Interior Band Width"""
|
|
696
|
+
return self._input("Interior Band Width")
|
|
651
697
|
|
|
652
698
|
@property
|
|
653
|
-
def
|
|
654
|
-
"""
|
|
655
|
-
return self.
|
|
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)
|
|
656
720
|
|
|
657
721
|
@property
|
|
658
|
-
def
|
|
659
|
-
"""Input socket:
|
|
660
|
-
return self._input("
|
|
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")
|
|
661
798
|
|
|
662
799
|
@property
|
|
663
800
|
def o_volume(self) -> SocketLinker:
|
|
@@ -665,66 +802,76 @@ class VolumeCube(NodeBuilder):
|
|
|
665
802
|
return self._output("Volume")
|
|
666
803
|
|
|
667
804
|
|
|
668
|
-
class
|
|
669
|
-
"""
|
|
805
|
+
class PruneGrid(NodeBuilder):
|
|
806
|
+
"""Make the storage of a volume grid more efficient by collapsing data into tiles or inner nodes"""
|
|
670
807
|
|
|
671
|
-
|
|
672
|
-
node: bpy.types.
|
|
808
|
+
_bl_idname = "GeometryNodeGridPrune"
|
|
809
|
+
node: bpy.types.GeometryNodeGridPrune
|
|
673
810
|
|
|
674
811
|
def __init__(
|
|
675
|
-
self,
|
|
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",
|
|
676
818
|
):
|
|
677
819
|
super().__init__()
|
|
678
|
-
|
|
820
|
+
key_args = {"Grid": grid, "Mode": mode, "Threshold": threshold}
|
|
821
|
+
self.data_type = data_type
|
|
822
|
+
self._establish_links(**key_args)
|
|
679
823
|
|
|
680
824
|
@classmethod
|
|
681
|
-
def
|
|
825
|
+
def float(
|
|
682
826
|
cls,
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
node._link_from(arg, "Grid 2")
|
|
690
|
-
return node
|
|
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)
|
|
691
833
|
|
|
692
834
|
@classmethod
|
|
693
|
-
def
|
|
835
|
+
def integer(
|
|
694
836
|
cls,
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
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)
|
|
703
850
|
|
|
704
851
|
@classmethod
|
|
705
|
-
def
|
|
852
|
+
def vector(
|
|
706
853
|
cls,
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
return
|
|
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")
|
|
718
865
|
|
|
719
866
|
@property
|
|
720
|
-
def
|
|
721
|
-
"""Input socket:
|
|
722
|
-
return self._input("
|
|
867
|
+
def i_mode(self) -> SocketLinker:
|
|
868
|
+
"""Input socket: Mode"""
|
|
869
|
+
return self._input("Mode")
|
|
723
870
|
|
|
724
871
|
@property
|
|
725
|
-
def
|
|
726
|
-
"""Input socket:
|
|
727
|
-
return self._input("
|
|
872
|
+
def i_threshold(self) -> SocketLinker:
|
|
873
|
+
"""Input socket: Threshold"""
|
|
874
|
+
return self._input("Threshold")
|
|
728
875
|
|
|
729
876
|
@property
|
|
730
877
|
def o_grid(self) -> SocketLinker:
|
|
@@ -732,23 +879,28 @@ class SDFGridBoolean(NodeBuilder):
|
|
|
732
879
|
return self._output("Grid")
|
|
733
880
|
|
|
734
881
|
@property
|
|
735
|
-
def
|
|
736
|
-
return self.node.
|
|
882
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
883
|
+
return self.node.data_type
|
|
737
884
|
|
|
738
|
-
@
|
|
739
|
-
def
|
|
740
|
-
self.node.
|
|
885
|
+
@data_type.setter
|
|
886
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
887
|
+
self.node.data_type = value
|
|
741
888
|
|
|
742
889
|
|
|
743
890
|
class SDFGridFillet(NodeBuilder):
|
|
744
891
|
"""Round off concave internal corners in a signed distance field. Only affects areas with negative principal curvature, creating smoother transitions between surfaces"""
|
|
745
892
|
|
|
746
|
-
|
|
893
|
+
_bl_idname = "GeometryNodeSDFGridFillet"
|
|
747
894
|
node: bpy.types.GeometryNodeSDFGridFillet
|
|
748
895
|
|
|
749
|
-
def __init__(
|
|
896
|
+
def __init__(
|
|
897
|
+
self,
|
|
898
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
899
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
900
|
+
):
|
|
750
901
|
super().__init__()
|
|
751
902
|
key_args = {"Grid": grid, "Iterations": iterations}
|
|
903
|
+
|
|
752
904
|
self._establish_links(**key_args)
|
|
753
905
|
|
|
754
906
|
@property
|
|
@@ -770,12 +922,17 @@ class SDFGridFillet(NodeBuilder):
|
|
|
770
922
|
class SDFGridLaplacian(NodeBuilder):
|
|
771
923
|
"""Apply Laplacian flow smoothing to a signed distance field. Computationally efficient alternative to mean curvature flow, ideal when combined with SDF normalization"""
|
|
772
924
|
|
|
773
|
-
|
|
925
|
+
_bl_idname = "GeometryNodeSDFGridLaplacian"
|
|
774
926
|
node: bpy.types.GeometryNodeSDFGridLaplacian
|
|
775
927
|
|
|
776
|
-
def __init__(
|
|
928
|
+
def __init__(
|
|
929
|
+
self,
|
|
930
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
931
|
+
iterations: TYPE_INPUT_INT = 1,
|
|
932
|
+
):
|
|
777
933
|
super().__init__()
|
|
778
934
|
key_args = {"Grid": grid, "Iterations": iterations}
|
|
935
|
+
|
|
779
936
|
self._establish_links(**key_args)
|
|
780
937
|
|
|
781
938
|
@property
|
|
@@ -797,17 +954,18 @@ class SDFGridLaplacian(NodeBuilder):
|
|
|
797
954
|
class SDFGridMean(NodeBuilder):
|
|
798
955
|
"""Apply mean (box) filter smoothing to a signed distance field. Fast separable averaging filter for general smoothing of the distance field"""
|
|
799
956
|
|
|
800
|
-
|
|
957
|
+
_bl_idname = "GeometryNodeSDFGridMean"
|
|
801
958
|
node: bpy.types.GeometryNodeSDFGridMean
|
|
802
959
|
|
|
803
960
|
def __init__(
|
|
804
961
|
self,
|
|
805
|
-
grid: TYPE_INPUT_VALUE =
|
|
962
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
806
963
|
width: TYPE_INPUT_INT = 1,
|
|
807
964
|
iterations: TYPE_INPUT_INT = 1,
|
|
808
965
|
):
|
|
809
966
|
super().__init__()
|
|
810
967
|
key_args = {"Grid": grid, "Width": width, "Iterations": iterations}
|
|
968
|
+
|
|
811
969
|
self._establish_links(**key_args)
|
|
812
970
|
|
|
813
971
|
@property
|
|
@@ -834,16 +992,17 @@ class SDFGridMean(NodeBuilder):
|
|
|
834
992
|
class SDFGridMeanCurvature(NodeBuilder):
|
|
835
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"""
|
|
836
994
|
|
|
837
|
-
|
|
995
|
+
_bl_idname = "GeometryNodeSDFGridMeanCurvature"
|
|
838
996
|
node: bpy.types.GeometryNodeSDFGridMeanCurvature
|
|
839
997
|
|
|
840
998
|
def __init__(
|
|
841
999
|
self,
|
|
842
|
-
grid: TYPE_INPUT_VALUE =
|
|
1000
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
843
1001
|
iterations: TYPE_INPUT_INT = 1,
|
|
844
1002
|
):
|
|
845
1003
|
super().__init__()
|
|
846
1004
|
key_args = {"Grid": grid, "Iterations": iterations}
|
|
1005
|
+
|
|
847
1006
|
self._establish_links(**key_args)
|
|
848
1007
|
|
|
849
1008
|
@property
|
|
@@ -865,17 +1024,18 @@ class SDFGridMeanCurvature(NodeBuilder):
|
|
|
865
1024
|
class SDFGridMedian(NodeBuilder):
|
|
866
1025
|
"""Apply median filter to a signed distance field. Reduces noise while preserving sharp features and edges in the distance field"""
|
|
867
1026
|
|
|
868
|
-
|
|
1027
|
+
_bl_idname = "GeometryNodeSDFGridMedian"
|
|
869
1028
|
node: bpy.types.GeometryNodeSDFGridMedian
|
|
870
1029
|
|
|
871
1030
|
def __init__(
|
|
872
1031
|
self,
|
|
873
|
-
grid: TYPE_INPUT_VALUE =
|
|
1032
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
874
1033
|
width: TYPE_INPUT_INT = 1,
|
|
875
1034
|
iterations: TYPE_INPUT_INT = 1,
|
|
876
1035
|
):
|
|
877
1036
|
super().__init__()
|
|
878
1037
|
key_args = {"Grid": grid, "Width": width, "Iterations": iterations}
|
|
1038
|
+
|
|
879
1039
|
self._establish_links(**key_args)
|
|
880
1040
|
|
|
881
1041
|
@property
|
|
@@ -902,12 +1062,17 @@ class SDFGridMedian(NodeBuilder):
|
|
|
902
1062
|
class SDFGridOffset(NodeBuilder):
|
|
903
1063
|
"""Offset a signed distance field surface by a world-space distance. Dilates (positive) or erodes (negative) while maintaining the signed distance property"""
|
|
904
1064
|
|
|
905
|
-
|
|
1065
|
+
_bl_idname = "GeometryNodeSDFGridOffset"
|
|
906
1066
|
node: bpy.types.GeometryNodeSDFGridOffset
|
|
907
1067
|
|
|
908
|
-
def __init__(
|
|
1068
|
+
def __init__(
|
|
1069
|
+
self,
|
|
1070
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1071
|
+
distance: TYPE_INPUT_VALUE = 0.1,
|
|
1072
|
+
):
|
|
909
1073
|
super().__init__()
|
|
910
1074
|
key_args = {"Grid": grid, "Distance": distance}
|
|
1075
|
+
|
|
911
1076
|
self._establish_links(**key_args)
|
|
912
1077
|
|
|
913
1078
|
@property
|
|
@@ -929,23 +1094,76 @@ class SDFGridOffset(NodeBuilder):
|
|
|
929
1094
|
class SampleGrid(NodeBuilder):
|
|
930
1095
|
"""Retrieve values from the specified volume grid"""
|
|
931
1096
|
|
|
932
|
-
|
|
1097
|
+
_bl_idname = "GeometryNodeSampleGrid"
|
|
933
1098
|
node: bpy.types.GeometryNodeSampleGrid
|
|
934
1099
|
|
|
935
1100
|
def __init__(
|
|
936
1101
|
self,
|
|
937
|
-
grid: TYPE_INPUT_VALUE =
|
|
1102
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
938
1103
|
position: TYPE_INPUT_VECTOR = None,
|
|
939
|
-
interpolation:
|
|
940
|
-
| bpy.types.NodeSocketMenu = "Trilinear",
|
|
1104
|
+
interpolation: TYPE_INPUT_MENU = "Trilinear",
|
|
941
1105
|
*,
|
|
942
|
-
data_type:
|
|
1106
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
943
1107
|
):
|
|
944
1108
|
super().__init__()
|
|
945
1109
|
key_args = {"Grid": grid, "Position": position, "Interpolation": interpolation}
|
|
946
1110
|
self.data_type = data_type
|
|
947
1111
|
self._establish_links(**key_args)
|
|
948
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
|
+
|
|
949
1167
|
@property
|
|
950
1168
|
def i_grid(self) -> SocketLinker:
|
|
951
1169
|
"""Input socket: Grid"""
|
|
@@ -967,39 +1185,78 @@ class SampleGrid(NodeBuilder):
|
|
|
967
1185
|
return self._output("Value")
|
|
968
1186
|
|
|
969
1187
|
@property
|
|
970
|
-
def data_type(
|
|
971
|
-
self
|
|
972
|
-
) -> _GridDataTypes:
|
|
973
|
-
return self.node.data_type # type: ignore
|
|
1188
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1189
|
+
return self.node.data_type
|
|
974
1190
|
|
|
975
1191
|
@data_type.setter
|
|
976
|
-
def data_type(
|
|
977
|
-
self,
|
|
978
|
-
value: _GridDataTypes,
|
|
979
|
-
):
|
|
1192
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
980
1193
|
self.node.data_type = value
|
|
981
1194
|
|
|
982
1195
|
|
|
983
1196
|
class SampleGridIndex(NodeBuilder):
|
|
984
1197
|
"""Retrieve volume grid values at specific voxels"""
|
|
985
1198
|
|
|
986
|
-
|
|
1199
|
+
_bl_idname = "GeometryNodeSampleGridIndex"
|
|
987
1200
|
node: bpy.types.GeometryNodeSampleGridIndex
|
|
988
1201
|
|
|
989
1202
|
def __init__(
|
|
990
1203
|
self,
|
|
991
|
-
grid: TYPE_INPUT_VALUE =
|
|
1204
|
+
grid: TYPE_INPUT_VALUE = 0.0,
|
|
992
1205
|
x: TYPE_INPUT_INT = 0,
|
|
993
1206
|
y: TYPE_INPUT_INT = 0,
|
|
994
1207
|
z: TYPE_INPUT_INT = 0,
|
|
995
1208
|
*,
|
|
996
|
-
data_type:
|
|
1209
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
997
1210
|
):
|
|
998
1211
|
super().__init__()
|
|
999
1212
|
key_args = {"Grid": grid, "X": x, "Y": y, "Z": z}
|
|
1000
1213
|
self.data_type = data_type
|
|
1001
1214
|
self._establish_links(**key_args)
|
|
1002
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
|
+
|
|
1003
1260
|
@property
|
|
1004
1261
|
def i_grid(self) -> SocketLinker:
|
|
1005
1262
|
"""Input socket: Grid"""
|
|
@@ -1026,23 +1283,18 @@ class SampleGridIndex(NodeBuilder):
|
|
|
1026
1283
|
return self._output("Value")
|
|
1027
1284
|
|
|
1028
1285
|
@property
|
|
1029
|
-
def data_type(
|
|
1030
|
-
self
|
|
1031
|
-
) -> _GridDataTypes:
|
|
1032
|
-
return self.node.data_type # type: ignore
|
|
1286
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1287
|
+
return self.node.data_type
|
|
1033
1288
|
|
|
1034
1289
|
@data_type.setter
|
|
1035
|
-
def data_type(
|
|
1036
|
-
self,
|
|
1037
|
-
value: _GridDataTypes,
|
|
1038
|
-
):
|
|
1290
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1039
1291
|
self.node.data_type = value
|
|
1040
1292
|
|
|
1041
1293
|
|
|
1042
1294
|
class SetGridBackground(NodeBuilder):
|
|
1043
1295
|
"""Set the background value used for inactive voxels and tiles"""
|
|
1044
1296
|
|
|
1045
|
-
|
|
1297
|
+
_bl_idname = "GeometryNodeSetGridBackground"
|
|
1046
1298
|
node: bpy.types.GeometryNodeSetGridBackground
|
|
1047
1299
|
|
|
1048
1300
|
def __init__(
|
|
@@ -1050,13 +1302,41 @@ class SetGridBackground(NodeBuilder):
|
|
|
1050
1302
|
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1051
1303
|
background: TYPE_INPUT_VALUE = 0.0,
|
|
1052
1304
|
*,
|
|
1053
|
-
data_type:
|
|
1305
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1054
1306
|
):
|
|
1055
1307
|
super().__init__()
|
|
1056
1308
|
key_args = {"Grid": grid, "Background": background}
|
|
1057
1309
|
self.data_type = data_type
|
|
1058
1310
|
self._establish_links(**key_args)
|
|
1059
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
|
+
|
|
1060
1340
|
@property
|
|
1061
1341
|
def i_grid(self) -> SocketLinker:
|
|
1062
1342
|
"""Input socket: Grid"""
|
|
@@ -1073,37 +1353,60 @@ class SetGridBackground(NodeBuilder):
|
|
|
1073
1353
|
return self._output("Grid")
|
|
1074
1354
|
|
|
1075
1355
|
@property
|
|
1076
|
-
def data_type(
|
|
1077
|
-
self
|
|
1078
|
-
) -> _GridDataTypes:
|
|
1079
|
-
return self.node.data_type # type: ignore
|
|
1356
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1357
|
+
return self.node.data_type
|
|
1080
1358
|
|
|
1081
1359
|
@data_type.setter
|
|
1082
|
-
def data_type(
|
|
1083
|
-
self,
|
|
1084
|
-
value: _GridDataTypes,
|
|
1085
|
-
):
|
|
1360
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1086
1361
|
self.node.data_type = value
|
|
1087
1362
|
|
|
1088
1363
|
|
|
1089
1364
|
class SetGridTransform(NodeBuilder):
|
|
1090
1365
|
"""Set the transform for the grid from index space into object space."""
|
|
1091
1366
|
|
|
1092
|
-
|
|
1367
|
+
_bl_idname = "GeometryNodeSetGridTransform"
|
|
1093
1368
|
node: bpy.types.GeometryNodeSetGridTransform
|
|
1094
1369
|
|
|
1095
1370
|
def __init__(
|
|
1096
1371
|
self,
|
|
1097
1372
|
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1098
|
-
transform:
|
|
1373
|
+
transform: TYPE_INPUT_MATRIX = None,
|
|
1099
1374
|
*,
|
|
1100
|
-
data_type:
|
|
1375
|
+
data_type: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"] = "FLOAT",
|
|
1101
1376
|
):
|
|
1102
1377
|
super().__init__()
|
|
1103
1378
|
key_args = {"Grid": grid, "Transform": transform}
|
|
1104
1379
|
self.data_type = data_type
|
|
1105
1380
|
self._establish_links(**key_args)
|
|
1106
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
|
+
|
|
1107
1410
|
@property
|
|
1108
1411
|
def i_grid(self) -> SocketLinker:
|
|
1109
1412
|
"""Input socket: Grid"""
|
|
@@ -1125,23 +1428,18 @@ class SetGridTransform(NodeBuilder):
|
|
|
1125
1428
|
return self._output("Grid")
|
|
1126
1429
|
|
|
1127
1430
|
@property
|
|
1128
|
-
def data_type(
|
|
1129
|
-
self
|
|
1130
|
-
) -> _GridDataTypes:
|
|
1131
|
-
return self.node.data_type # type: ignore
|
|
1431
|
+
def data_type(self) -> Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]:
|
|
1432
|
+
return self.node.data_type
|
|
1132
1433
|
|
|
1133
1434
|
@data_type.setter
|
|
1134
|
-
def data_type(
|
|
1135
|
-
self,
|
|
1136
|
-
value: _GridDataTypes,
|
|
1137
|
-
):
|
|
1435
|
+
def data_type(self, value: Literal["FLOAT", "INT", "BOOLEAN", "VECTOR"]):
|
|
1138
1436
|
self.node.data_type = value
|
|
1139
1437
|
|
|
1140
1438
|
|
|
1141
1439
|
class StoreNamedGrid(NodeBuilder):
|
|
1142
1440
|
"""Store grid data in a volume geometry with the specified name"""
|
|
1143
1441
|
|
|
1144
|
-
|
|
1442
|
+
_bl_idname = "GeometryNodeStoreNamedGrid"
|
|
1145
1443
|
node: bpy.types.GeometryNodeStoreNamedGrid
|
|
1146
1444
|
|
|
1147
1445
|
def __init__(
|
|
@@ -1150,13 +1448,53 @@ class StoreNamedGrid(NodeBuilder):
|
|
|
1150
1448
|
name: TYPE_INPUT_STRING = "",
|
|
1151
1449
|
grid: TYPE_INPUT_VALUE = 0.0,
|
|
1152
1450
|
*,
|
|
1153
|
-
data_type: Literal["
|
|
1451
|
+
data_type: Literal["BOOLEAN", "FLOAT", "INT", "VECTOR_FLOAT"] = "FLOAT",
|
|
1154
1452
|
):
|
|
1155
1453
|
super().__init__()
|
|
1156
1454
|
key_args = {"Volume": volume, "Name": name, "Grid": grid}
|
|
1157
1455
|
self.data_type = data_type
|
|
1158
1456
|
self._establish_links(**key_args)
|
|
1159
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
|
+
|
|
1160
1498
|
@property
|
|
1161
1499
|
def i_volume(self) -> SocketLinker:
|
|
1162
1500
|
"""Input socket: Volume"""
|
|
@@ -1178,39 +1516,130 @@ class StoreNamedGrid(NodeBuilder):
|
|
|
1178
1516
|
return self._output("Volume")
|
|
1179
1517
|
|
|
1180
1518
|
@property
|
|
1181
|
-
def data_type(
|
|
1182
|
-
self
|
|
1183
|
-
) -> Literal["FLOAT", "VECTOR_FLOAT", "INT", "BOOLEAN"]:
|
|
1184
|
-
return self.node.data_type # type: ignore
|
|
1519
|
+
def data_type(self) -> Literal["BOOLEAN", "FLOAT", "INT", "VECTOR_FLOAT"]:
|
|
1520
|
+
return self.node.data_type
|
|
1185
1521
|
|
|
1186
1522
|
@data_type.setter
|
|
1187
|
-
def data_type(
|
|
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__(
|
|
1188
1534
|
self,
|
|
1189
|
-
|
|
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,
|
|
1190
1542
|
):
|
|
1191
|
-
|
|
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
|
+
}
|
|
1192
1553
|
|
|
1554
|
+
self._establish_links(**key_args)
|
|
1193
1555
|
|
|
1194
|
-
|
|
1195
|
-
|
|
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")
|
|
1196
1595
|
|
|
1197
|
-
|
|
1198
|
-
|
|
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
|
|
1199
1602
|
|
|
1200
1603
|
def __init__(
|
|
1201
1604
|
self,
|
|
1202
|
-
|
|
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,
|
|
1203
1609
|
threshold: TYPE_INPUT_VALUE = 0.1,
|
|
1204
1610
|
adaptivity: TYPE_INPUT_VALUE = 0.0,
|
|
1205
1611
|
):
|
|
1206
1612
|
super().__init__()
|
|
1207
|
-
key_args = {
|
|
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
|
+
|
|
1208
1622
|
self._establish_links(**key_args)
|
|
1209
1623
|
|
|
1210
1624
|
@property
|
|
1211
|
-
def
|
|
1212
|
-
"""Input socket:
|
|
1213
|
-
return self._input("
|
|
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")
|
|
1214
1643
|
|
|
1215
1644
|
@property
|
|
1216
1645
|
def i_threshold(self) -> SocketLinker:
|
|
@@ -1226,3 +1655,59 @@ class GridToMesh(NodeBuilder):
|
|
|
1226
1655
|
def o_mesh(self) -> SocketLinker:
|
|
1227
1656
|
"""Output socket: Mesh"""
|
|
1228
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
|