procfunc 0.33.0__tar.gz → 0.33.2__tar.gz
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.
- {procfunc-0.33.0/src/procfunc.egg-info → procfunc-0.33.2}/PKG-INFO +2 -2
- {procfunc-0.33.0 → procfunc-0.33.2}/README.md +1 -1
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/__init__.py +1 -1
- procfunc-0.33.2/src/procfunc/cli/__init__.py +3 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/color.py +4 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/util.py +96 -14
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/color.py +4 -4
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/func.py +21 -2
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/geo.py +6 -4
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/math.py +70 -2
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/texture.py +11 -1
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/attr.py +6 -3
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/extract_materials.py +38 -16
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transpiler/bpy_to_computegraph.py +18 -8
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transpiler/parse_special_cases.py +13 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/bpy_info.py +19 -15
- {procfunc-0.33.0 → procfunc-0.33.2/src/procfunc.egg-info}/PKG-INFO +2 -2
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_ops.py +28 -0
- procfunc-0.33.0/src/procfunc/cli/__init__.py +0 -3
- {procfunc-0.33.0 → procfunc-0.33.2}/LICENSE.md +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/pyproject.toml +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/setup.cfg +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/cli/main.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/codegen/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/codegen/codegen.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/codegen/identifiers.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/codegen/repr.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/compute_graph.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/node.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/operators_info.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/compute_graph/proxy.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/context.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/control/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/compositor.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/construct_nodes.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/construct_operator.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/construct_special_cases.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/construct_standard.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/execute.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/infer_runtime_data_type.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/realize.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/execute/util.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/manifest.json +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/shader.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/types.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/util/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/util/bindings_util.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/util/bpy_node_info.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/nodes/util/node_function.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/_util.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/addons.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/collection.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/curve.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/file.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/manifest.json +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/mesh.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/modifier.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/object.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/primitives/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/primitives/camera.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/primitives/curve.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/primitives/light.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/primitives/mesh.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/ops/uv.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/random.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/tracer/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/tracer/decorator.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/tracer/patch.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/tracer/proxy.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/tracer/trace.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/cleanup.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/convert.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/distribution.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/infer_distribution.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/parameters.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transforms/util.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transpiler/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transpiler/main.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/transpiler/parse_default_values.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/types.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/__init__.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/bpy_data.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/camera.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/keyframe.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/log.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/manifest.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/pytree.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc/util/teardown.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc.egg-info/SOURCES.txt +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc.egg-info/dependency_links.txt +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc.egg-info/entry_points.txt +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc.egg-info/requires.txt +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/src/procfunc.egg-info/top_level.txt +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_asset.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_bpy_data_cleanup.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_cli_transpile.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_codegen.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_codegen_matrix.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_compute_graph.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_node_function.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_pytree.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_random.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_trace.py +0 -0
- {procfunc-0.33.0 → procfunc-0.33.2}/tests/test_transforms.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: procfunc
|
|
3
|
-
Version: 0.33.
|
|
3
|
+
Version: 0.33.2
|
|
4
4
|
Summary: Function-Oriented Abstractions for Procedural 3D Generation in Python
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
Project-URL: Homepage, https://github.com/princeton-vl/procfunc
|
|
@@ -24,7 +24,7 @@ Dynamic: license-file
|
|
|
24
24
|
|
|
25
25
|
# ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python
|
|
26
26
|
|
|
27
|
-
[**Documentation**](
|
|
27
|
+
[**Documentation**](https://procfunc.readthedocs.io)
|
|
28
28
|
| [**Research Paper**](https://arxiv.org/abs/2604.26943)
|
|
29
29
|
| [**Transpiling**](#transpile-a-blender-file-to-procfunc-code)
|
|
30
30
|
| [**Experiments**](#experiments)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python
|
|
2
2
|
|
|
3
|
-
[**Documentation**](
|
|
3
|
+
[**Documentation**](https://procfunc.readthedocs.io)
|
|
4
4
|
| [**Research Paper**](https://arxiv.org/abs/2604.26943)
|
|
5
5
|
| [**Transpiling**](#transpile-a-blender-file-to-procfunc-code)
|
|
6
6
|
| [**Experiments**](#experiments)
|
|
@@ -10,6 +10,8 @@ def hsv_color(
|
|
|
10
10
|
saturation: float | None = None,
|
|
11
11
|
value: float | None = None,
|
|
12
12
|
) -> t.Color:
|
|
13
|
+
if hsv is None and (hue is None or saturation is None or value is None):
|
|
14
|
+
raise ValueError("provide hsv=... or all of hue/saturation/value")
|
|
13
15
|
color = t.Color()
|
|
14
16
|
if hsv is not None:
|
|
15
17
|
color.hsv = hsv
|
|
@@ -27,6 +29,8 @@ def rgb_color(
|
|
|
27
29
|
b: float | None = None,
|
|
28
30
|
rgb: np.ndarray | None = None,
|
|
29
31
|
) -> t.Color:
|
|
32
|
+
if rgb is None and (r is None or g is None or b is None):
|
|
33
|
+
raise ValueError("provide rgb=... or all of r/g/b")
|
|
30
34
|
color = t.Color()
|
|
31
35
|
if rgb is not None:
|
|
32
36
|
color.r, color.g, color.b = rgb
|
|
@@ -3,10 +3,21 @@ import logging
|
|
|
3
3
|
from collections import defaultdict, deque
|
|
4
4
|
from typing import Any, Callable, Generator, Literal, TypeVar
|
|
5
5
|
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
6
8
|
from procfunc.util import pytree
|
|
7
9
|
|
|
8
10
|
from .compute_graph import ComputeGraph
|
|
9
|
-
from .node import
|
|
11
|
+
from .node import (
|
|
12
|
+
ConstantNode,
|
|
13
|
+
FunctionCallNode,
|
|
14
|
+
GetAttributeNode,
|
|
15
|
+
InputPlaceholderNode,
|
|
16
|
+
MethodCallNode,
|
|
17
|
+
Node,
|
|
18
|
+
ProceduralNode,
|
|
19
|
+
SubgraphCallNode,
|
|
20
|
+
)
|
|
10
21
|
|
|
11
22
|
logger = logging.getLogger(__name__)
|
|
12
23
|
|
|
@@ -40,6 +51,7 @@ def traverse_breadth_first(
|
|
|
40
51
|
|
|
41
52
|
visited = set()
|
|
42
53
|
frontier = deque((None, name, node) for name, node in graph.outputs.items())
|
|
54
|
+
visited.update(id(node) for _, _, node in frontier)
|
|
43
55
|
# logger.debug(f"{traverse_breadth_first.__name__} {graph.name} {len(frontier)=}")
|
|
44
56
|
|
|
45
57
|
def res(parent, name, child):
|
|
@@ -61,10 +73,6 @@ def traverse_breadth_first(
|
|
|
61
73
|
if not isinstance(node, Node):
|
|
62
74
|
continue
|
|
63
75
|
|
|
64
|
-
if id(node) in visited:
|
|
65
|
-
continue
|
|
66
|
-
visited.add(id(node))
|
|
67
|
-
|
|
68
76
|
yield res(parent, name, node)
|
|
69
77
|
|
|
70
78
|
children = list(pytree.PyTree(node.args).items()) + list(
|
|
@@ -75,6 +83,7 @@ def traverse_breadth_first(
|
|
|
75
83
|
continue
|
|
76
84
|
if id(arg) in visited:
|
|
77
85
|
continue
|
|
86
|
+
visited.add(id(arg))
|
|
78
87
|
frontier.append((node, key, arg))
|
|
79
88
|
|
|
80
89
|
|
|
@@ -201,22 +210,95 @@ def usages_per_node(
|
|
|
201
210
|
return dict(usages)
|
|
202
211
|
|
|
203
212
|
|
|
204
|
-
def
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
def _value_equal(a: Any, b: Any) -> bool:
|
|
214
|
+
"""Array-safe equality for non-node values (constants, attrs, defaults)."""
|
|
215
|
+
if a is b:
|
|
216
|
+
return True
|
|
217
|
+
if isinstance(a, np.ndarray) or isinstance(b, np.ndarray):
|
|
218
|
+
return np.array_equal(a, b)
|
|
219
|
+
if isinstance(a, dict) and isinstance(b, dict):
|
|
220
|
+
return a.keys() == b.keys() and all(_value_equal(a[k], b[k]) for k in a)
|
|
221
|
+
if isinstance(a, (list, tuple)) and isinstance(b, (list, tuple)):
|
|
222
|
+
return (
|
|
223
|
+
type(a) is type(b)
|
|
224
|
+
and len(a) == len(b)
|
|
225
|
+
and all(_value_equal(x, y) for x, y in zip(a, b))
|
|
226
|
+
)
|
|
227
|
+
try:
|
|
228
|
+
return bool(a == b)
|
|
229
|
+
except (ValueError, TypeError):
|
|
230
|
+
return False
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _args_equal(a: Any, b: Any, memo: dict[tuple[int, int], bool]) -> bool:
|
|
234
|
+
"""Structural equality of an args/kwargs tree: same container shape, with
|
|
235
|
+
node-valued leaves compared recursively and other leaves by value."""
|
|
236
|
+
tree_a = pytree.PyTree(a)
|
|
237
|
+
tree_b = pytree.PyTree(b)
|
|
238
|
+
if tree_a.spec != tree_b.spec:
|
|
208
239
|
return False
|
|
209
|
-
for
|
|
210
|
-
|
|
240
|
+
for leaf_a, leaf_b in zip(tree_a.values(), tree_b.values()):
|
|
241
|
+
a_is_node = isinstance(leaf_a, Node)
|
|
242
|
+
b_is_node = isinstance(leaf_b, Node)
|
|
243
|
+
if a_is_node != b_is_node:
|
|
211
244
|
return False
|
|
212
|
-
if
|
|
213
|
-
if not
|
|
245
|
+
if a_is_node:
|
|
246
|
+
if not _nodes_equal(leaf_a, leaf_b, memo):
|
|
214
247
|
return False
|
|
215
|
-
elif
|
|
248
|
+
elif not _value_equal(leaf_a, leaf_b):
|
|
216
249
|
return False
|
|
217
250
|
return True
|
|
218
251
|
|
|
219
252
|
|
|
253
|
+
def _nodes_equal(node1: Node, node2: Node, memo: dict[tuple[int, int], bool]) -> bool:
|
|
254
|
+
if node1 is node2:
|
|
255
|
+
return True
|
|
256
|
+
if type(node1) is not type(node2):
|
|
257
|
+
return False
|
|
258
|
+
|
|
259
|
+
key = (id(node1), id(node2))
|
|
260
|
+
cached = memo.get(key)
|
|
261
|
+
if cached is not None:
|
|
262
|
+
return cached
|
|
263
|
+
memo[key] = True # optimistic, breaks cycles in shared DAGs
|
|
264
|
+
|
|
265
|
+
result = True
|
|
266
|
+
if isinstance(node1, SubgraphCallNode):
|
|
267
|
+
result = graph_nodes_equal(node1.subgraph, node2.subgraph)
|
|
268
|
+
if result and isinstance(node1, FunctionCallNode):
|
|
269
|
+
result = node1.func is node2.func
|
|
270
|
+
if result and isinstance(node1, MethodCallNode):
|
|
271
|
+
result = node1.method_name == node2.method_name
|
|
272
|
+
if result and isinstance(node1, GetAttributeNode):
|
|
273
|
+
result = node1.attribute_name == node2.attribute_name
|
|
274
|
+
if result and isinstance(node1, ProceduralNode):
|
|
275
|
+
result = node1.node_type == node2.node_type and _value_equal(
|
|
276
|
+
node1.attrs, node2.attrs
|
|
277
|
+
)
|
|
278
|
+
if result and isinstance(node1, ConstantNode):
|
|
279
|
+
result = _value_equal(node1.value, node2.value)
|
|
280
|
+
if result and isinstance(node1, InputPlaceholderNode):
|
|
281
|
+
result = node1.input_name == node2.input_name and _value_equal(
|
|
282
|
+
node1.default_value, node2.default_value
|
|
283
|
+
)
|
|
284
|
+
if result:
|
|
285
|
+
result = _args_equal(node1.args, node2.args, memo) and _args_equal(
|
|
286
|
+
node1.kwargs, node2.kwargs, memo
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
memo[key] = result
|
|
290
|
+
return result
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def graph_nodes_equal(graph1: ComputeGraph, graph2: ComputeGraph) -> bool:
|
|
294
|
+
nodes1 = list(traverse_depth_first(graph1))
|
|
295
|
+
nodes2 = list(traverse_depth_first(graph2))
|
|
296
|
+
if len(nodes1) != len(nodes2):
|
|
297
|
+
return False
|
|
298
|
+
memo: dict[tuple[int, int], bool] = {}
|
|
299
|
+
return all(_nodes_equal(node1, node2, memo) for node1, node2 in zip(nodes1, nodes2))
|
|
300
|
+
|
|
301
|
+
|
|
220
302
|
def transform_nodetree(
|
|
221
303
|
root: Node,
|
|
222
304
|
transform_fn: Callable[[Node], Any],
|
|
@@ -39,7 +39,7 @@ def mix_rgb(
|
|
|
39
39
|
clamp_factor: bool = True,
|
|
40
40
|
) -> nt.ProcNode[pt.Color]:
|
|
41
41
|
"""
|
|
42
|
-
Uses a Mix Node with
|
|
42
|
+
Uses a Mix Shader Node with data_type='RGBA'.
|
|
43
43
|
|
|
44
44
|
NOTE: separated from float/vector mix() due to extra arguments
|
|
45
45
|
|
|
@@ -80,7 +80,7 @@ def combine_rgb(
|
|
|
80
80
|
blue: nt.SocketOrVal[float] = 0.0,
|
|
81
81
|
) -> nt.ProcNode[pt.Color]:
|
|
82
82
|
"""
|
|
83
|
-
Uses a CombineColor Shader Node.
|
|
83
|
+
Uses a CombineColor Shader Node in RGB mode.
|
|
84
84
|
|
|
85
85
|
See: https://docs.blender.org/manual/en/4.2/render/shader_nodes/converter/combine_color.html
|
|
86
86
|
"""
|
|
@@ -97,7 +97,7 @@ def combine_hsv(
|
|
|
97
97
|
value: nt.SocketOrVal[float] = 0.0,
|
|
98
98
|
) -> nt.ProcNode[pt.Color]:
|
|
99
99
|
"""
|
|
100
|
-
Uses a CombineColor Shader Node.
|
|
100
|
+
Uses a CombineColor Shader Node in HSV mode.
|
|
101
101
|
|
|
102
102
|
See: https://docs.blender.org/manual/en/4.2/render/shader_nodes/converter/combine_color.html
|
|
103
103
|
"""
|
|
@@ -115,7 +115,7 @@ def combine_hsl(
|
|
|
115
115
|
lightness: nt.SocketOrVal[float] = 0.0,
|
|
116
116
|
) -> nt.ProcNode[pt.Color]:
|
|
117
117
|
"""
|
|
118
|
-
Uses a
|
|
118
|
+
Uses a CombineColor Shader Node in HSL mode.
|
|
119
119
|
|
|
120
120
|
See: https://docs.blender.org/manual/en/4.2/render/shader_nodes/converter/combine_color.html
|
|
121
121
|
"""
|
|
@@ -92,6 +92,7 @@ def boolean_or(
|
|
|
92
92
|
a: nt.SocketOrVal[bool],
|
|
93
93
|
b: nt.SocketOrVal[bool],
|
|
94
94
|
) -> nt.ProcNode[bool]:
|
|
95
|
+
"""Uses a BooleanMath Function Node with operation='OR'."""
|
|
95
96
|
return nt.ProcNode.from_nodetype(
|
|
96
97
|
node_type="FunctionNodeBooleanMath",
|
|
97
98
|
inputs={("Boolean", 0): a, ("Boolean", 1): b},
|
|
@@ -103,6 +104,7 @@ def boolean_and(
|
|
|
103
104
|
a: nt.SocketOrVal[bool],
|
|
104
105
|
b: nt.SocketOrVal[bool],
|
|
105
106
|
) -> nt.ProcNode[bool]:
|
|
107
|
+
"""Uses a BooleanMath Function Node with operation='AND'."""
|
|
106
108
|
return nt.ProcNode.from_nodetype(
|
|
107
109
|
node_type="FunctionNodeBooleanMath",
|
|
108
110
|
inputs={("Boolean", 0): a, ("Boolean", 1): b},
|
|
@@ -114,6 +116,7 @@ def boolean_xor(
|
|
|
114
116
|
a: nt.SocketOrVal[bool],
|
|
115
117
|
b: nt.SocketOrVal[bool],
|
|
116
118
|
) -> nt.ProcNode[bool]:
|
|
119
|
+
"""Uses a BooleanMath Function Node with operation='XOR'."""
|
|
117
120
|
return nt.ProcNode.from_nodetype(
|
|
118
121
|
node_type="FunctionNodeBooleanMath",
|
|
119
122
|
inputs={("Boolean", 0): a, ("Boolean", 1): b},
|
|
@@ -125,7 +128,7 @@ def boolean_not(
|
|
|
125
128
|
a: nt.SocketOrVal[bool],
|
|
126
129
|
) -> nt.ProcNode[bool]:
|
|
127
130
|
"""
|
|
128
|
-
Uses a
|
|
131
|
+
Uses a BooleanMath Function Node with operation='NOT'.
|
|
129
132
|
|
|
130
133
|
See: https://docs.blender.org/manual/en/4.2/modeling/geometry_nodes/utilities/math/boolean_math.html
|
|
131
134
|
"""
|
|
@@ -275,6 +278,7 @@ def less_than(
|
|
|
275
278
|
a: TCompareNumeric,
|
|
276
279
|
b: TCompareNumeric,
|
|
277
280
|
) -> nt.ProcNode[bool]:
|
|
281
|
+
"""Uses a Compare Function Node with operation='LESS_THAN'."""
|
|
278
282
|
return _compare(a, b, operation="LESS_THAN")
|
|
279
283
|
|
|
280
284
|
|
|
@@ -282,6 +286,7 @@ def less_equal(
|
|
|
282
286
|
a: TCompareNumeric,
|
|
283
287
|
b: TCompareNumeric,
|
|
284
288
|
) -> nt.ProcNode[bool]:
|
|
289
|
+
"""Uses a Compare Function Node with operation='LESS_EQUAL'."""
|
|
285
290
|
return _compare(a, b, operation="LESS_EQUAL")
|
|
286
291
|
|
|
287
292
|
|
|
@@ -289,6 +294,7 @@ def greater_than(
|
|
|
289
294
|
a: TCompareNumeric,
|
|
290
295
|
b: TCompareNumeric,
|
|
291
296
|
) -> nt.ProcNode[bool]:
|
|
297
|
+
"""Uses a Compare Function Node with operation='GREATER_THAN'."""
|
|
292
298
|
return _compare(a, b, operation="GREATER_THAN")
|
|
293
299
|
|
|
294
300
|
|
|
@@ -296,6 +302,7 @@ def greater_equal(
|
|
|
296
302
|
a: TCompareNumeric,
|
|
297
303
|
b: TCompareNumeric,
|
|
298
304
|
) -> nt.ProcNode[bool]:
|
|
305
|
+
"""Uses a Compare Function Node with operation='GREATER_EQUAL'."""
|
|
299
306
|
return _compare(a, b, operation="GREATER_EQUAL")
|
|
300
307
|
|
|
301
308
|
|
|
@@ -311,6 +318,7 @@ def equal(
|
|
|
311
318
|
b: TCompareEqual,
|
|
312
319
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
313
320
|
) -> nt.ProcNode[bool]:
|
|
321
|
+
"""Uses a Compare Function Node with operation='EQUAL'."""
|
|
314
322
|
return _compare(a, b, epsilon, operation="EQUAL")
|
|
315
323
|
|
|
316
324
|
|
|
@@ -319,6 +327,7 @@ def not_equal(
|
|
|
319
327
|
b: TCompareEqual,
|
|
320
328
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
321
329
|
) -> nt.ProcNode[bool]:
|
|
330
|
+
"""Uses a Compare Function Node with operation='NOT_EQUAL'."""
|
|
322
331
|
return _compare(a, b, epsilon, operation="NOT_EQUAL")
|
|
323
332
|
|
|
324
333
|
|
|
@@ -332,6 +341,7 @@ def vector_elementwise_less_than(
|
|
|
332
341
|
a: nt.SocketOrVal[pt.Vector],
|
|
333
342
|
b: nt.SocketOrVal[pt.Vector],
|
|
334
343
|
) -> nt.ProcNode[bool]:
|
|
344
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='LESS_THAN'."""
|
|
335
345
|
return _compare(a, b, operation="LESS_THAN", data_type=NodeDataType.FLOAT_VECTOR)
|
|
336
346
|
|
|
337
347
|
|
|
@@ -339,6 +349,7 @@ def vector_elementwise_less_equal(
|
|
|
339
349
|
a: nt.SocketOrVal[pt.Vector],
|
|
340
350
|
b: nt.SocketOrVal[pt.Vector],
|
|
341
351
|
) -> nt.ProcNode[bool]:
|
|
352
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='LESS_EQUAL'."""
|
|
342
353
|
return _compare(a, b, operation="LESS_EQUAL", data_type=NodeDataType.FLOAT_VECTOR)
|
|
343
354
|
|
|
344
355
|
|
|
@@ -346,6 +357,7 @@ def vector_elementwise_greater_than(
|
|
|
346
357
|
a: nt.SocketOrVal[pt.Vector],
|
|
347
358
|
b: nt.SocketOrVal[pt.Vector],
|
|
348
359
|
) -> nt.ProcNode[bool]:
|
|
360
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='GREATER_THAN'."""
|
|
349
361
|
return _compare(a, b, operation="GREATER_THAN", data_type=NodeDataType.FLOAT_VECTOR)
|
|
350
362
|
|
|
351
363
|
|
|
@@ -353,6 +365,7 @@ def vector_elementwise_greater_equal(
|
|
|
353
365
|
a: nt.SocketOrVal[pt.Vector],
|
|
354
366
|
b: nt.SocketOrVal[pt.Vector],
|
|
355
367
|
) -> nt.ProcNode[bool]:
|
|
368
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='GREATER_EQUAL'."""
|
|
356
369
|
return _compare(
|
|
357
370
|
a, b, operation="GREATER_EQUAL", data_type=NodeDataType.FLOAT_VECTOR
|
|
358
371
|
)
|
|
@@ -363,6 +376,7 @@ def vector_elementwise_equal(
|
|
|
363
376
|
b: nt.SocketOrVal[pt.Vector],
|
|
364
377
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
365
378
|
) -> nt.ProcNode[bool]:
|
|
379
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='EQUAL'."""
|
|
366
380
|
return _compare(
|
|
367
381
|
a, b, epsilon, operation="EQUAL", data_type=NodeDataType.FLOAT_VECTOR
|
|
368
382
|
)
|
|
@@ -373,6 +387,7 @@ def vector_elementwise_not_equal(
|
|
|
373
387
|
b: nt.SocketOrVal[pt.Vector],
|
|
374
388
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
375
389
|
) -> nt.ProcNode[bool]:
|
|
390
|
+
"""Uses a Compare Function Node with data_type='VECTOR', mode='ELEMENT', operation='NOT_EQUAL'."""
|
|
376
391
|
return _compare(
|
|
377
392
|
a, b, epsilon, operation="NOT_EQUAL", data_type=NodeDataType.FLOAT_VECTOR
|
|
378
393
|
)
|
|
@@ -383,6 +398,7 @@ def color_equal(
|
|
|
383
398
|
b: nt.SocketOrVal[pt.Color],
|
|
384
399
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
385
400
|
) -> nt.ProcNode[bool]:
|
|
401
|
+
"""Uses a Compare Function Node with data_type='RGBA', operation='EQUAL'."""
|
|
386
402
|
return _compare(a, b, epsilon, operation="EQUAL", data_type=NodeDataType.RGBA)
|
|
387
403
|
|
|
388
404
|
|
|
@@ -391,6 +407,7 @@ def color_not_equal(
|
|
|
391
407
|
b: nt.SocketOrVal[pt.Color],
|
|
392
408
|
epsilon: nt.SocketOrVal[float] = COMPARE_EPSILON_DEFAULT,
|
|
393
409
|
) -> nt.ProcNode[bool]:
|
|
410
|
+
"""Uses a Compare Function Node with data_type='RGBA', operation='NOT_EQUAL'."""
|
|
394
411
|
return _compare(a, b, epsilon, operation="NOT_EQUAL", data_type=NodeDataType.RGBA)
|
|
395
412
|
|
|
396
413
|
|
|
@@ -398,6 +415,7 @@ def color_brighter(
|
|
|
398
415
|
a: nt.SocketOrVal[pt.Color],
|
|
399
416
|
b: nt.SocketOrVal[pt.Color],
|
|
400
417
|
) -> nt.ProcNode[bool]:
|
|
418
|
+
"""Uses a Compare Function Node with data_type='RGBA', operation='BRIGHTER'."""
|
|
401
419
|
return _compare(a, b, operation="BRIGHTER", data_type=NodeDataType.RGBA)
|
|
402
420
|
|
|
403
421
|
|
|
@@ -405,6 +423,7 @@ def color_darker(
|
|
|
405
423
|
a: nt.SocketOrVal[pt.Color],
|
|
406
424
|
b: nt.SocketOrVal[pt.Color],
|
|
407
425
|
) -> nt.ProcNode[bool]:
|
|
426
|
+
"""Uses a Compare Function Node with data_type='RGBA', operation='DARKER'."""
|
|
408
427
|
return _compare(a, b, operation="DARKER", data_type=NodeDataType.RGBA)
|
|
409
428
|
|
|
410
429
|
|
|
@@ -693,7 +712,7 @@ def random_boolean(
|
|
|
693
712
|
seed: nt.SocketOrVal[int] = 0,
|
|
694
713
|
) -> nt.ProcNode[bool]:
|
|
695
714
|
"""
|
|
696
|
-
Uses a
|
|
715
|
+
Uses a RandomValue Function Node with data_type='BOOLEAN'.
|
|
697
716
|
"""
|
|
698
717
|
return nt.ProcNode.from_nodetype(
|
|
699
718
|
node_type="FunctionNodeRandomValue",
|
|
@@ -622,7 +622,7 @@ def curve_line(
|
|
|
622
622
|
end: nt.SocketOrVal[nt.pt.Vector],
|
|
623
623
|
) -> nt.ProcNode[pt.CurveObject]:
|
|
624
624
|
"""
|
|
625
|
-
Uses a CurvePrimitiveLine Geometry Node.
|
|
625
|
+
Uses a CurvePrimitiveLine Geometry Node in POINTS mode.
|
|
626
626
|
|
|
627
627
|
See: https://docs.blender.org/manual/en/4.2/modeling/geometry_nodes/curve/primitives/curve_line.html
|
|
628
628
|
"""
|
|
@@ -639,7 +639,7 @@ def curve_line_from_direction(
|
|
|
639
639
|
length: nt.SocketOrVal[float] = 1.0,
|
|
640
640
|
) -> nt.ProcNode[pt.CurveObject]:
|
|
641
641
|
"""
|
|
642
|
-
Uses a
|
|
642
|
+
Uses a CurvePrimitiveLine Geometry Node in DIRECTION mode.
|
|
643
643
|
|
|
644
644
|
See: https://docs.blender.org/manual/en/4.2/modeling/geometry_nodes/curve/primitives/curve_line.html
|
|
645
645
|
"""
|
|
@@ -2633,6 +2633,7 @@ def mesh_line_from_endpoints(
|
|
|
2633
2633
|
count: nt.SocketOrVal[int] = 10,
|
|
2634
2634
|
count_mode: Literal["TOTAL", "RESOLUTION"] = "TOTAL",
|
|
2635
2635
|
) -> nt.ProcNode[pt.MeshObject]:
|
|
2636
|
+
"""Uses a MeshLine Geometry Node with mode='END_POINTS'."""
|
|
2636
2637
|
return nt.ProcNode.from_nodetype(
|
|
2637
2638
|
node_type="GeometryNodeMeshLine",
|
|
2638
2639
|
inputs={
|
|
@@ -3227,7 +3228,7 @@ def sample_curve(
|
|
|
3227
3228
|
data_type: NodeDataType | RuntimeResolveDataType | None = None,
|
|
3228
3229
|
) -> SampleCurveResult:
|
|
3229
3230
|
"""
|
|
3230
|
-
Uses a SampleCurve Geometry Node.
|
|
3231
|
+
Uses a SampleCurve Geometry Node with FACTOR mode.
|
|
3231
3232
|
|
|
3232
3233
|
See: https://docs.blender.org/manual/en/4.2/modeling/geometry_nodes/curve/sample/sample_curve.html
|
|
3233
3234
|
"""
|
|
@@ -4306,7 +4307,7 @@ def transform(
|
|
|
4306
4307
|
scale: nt.SocketOrVal[pt.Vector] = (1, 1, 1),
|
|
4307
4308
|
) -> nt.ProcNode[TMeshOrCurve]:
|
|
4308
4309
|
"""
|
|
4309
|
-
Uses a Transform Geometry Node.
|
|
4310
|
+
Uses a Transform Geometry Node with mode='COMPONENTS'.
|
|
4310
4311
|
|
|
4311
4312
|
See: https://docs.blender.org/manual/en/4.2/modeling/geometry_nodes/geometry/operations/transform_geometry.html
|
|
4312
4313
|
"""
|
|
@@ -4326,6 +4327,7 @@ def transform_by_matrix(
|
|
|
4326
4327
|
geometry: nt.ProcNode[TMeshOrCurve],
|
|
4327
4328
|
matrix: nt.SocketOrVal[pt.Matrix],
|
|
4328
4329
|
):
|
|
4330
|
+
"""Uses a Transform Geometry Node with mode='MATRIX'."""
|
|
4329
4331
|
return nt.ProcNode.from_nodetype(
|
|
4330
4332
|
node_type="GeometryNodeTransform",
|
|
4331
4333
|
inputs={
|