procfunc 0.35.1__tar.gz → 0.36.1__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.35.1/src/procfunc.egg-info → procfunc-0.36.1}/PKG-INFO +2 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/README.md +1 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/pyproject.toml +1 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/__init__.py +2 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/codegen/codegen.py +26 -17
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/codegen/repr.py +4 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/operators_info.py +12 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/context.py +16 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/control/__init__.py +7 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/__init__.py +2 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/color.py +16 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/compositor.py +227 -30
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/construct_special_cases.py +121 -31
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/construct_standard.py +2 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/infer_runtime_data_type.py +10 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/func.py +15 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/geo.py +200 -67
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/manifest.json +1107 -39
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/math.py +63 -19
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/shader.py +235 -18
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/texture.py +131 -28
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/types.py +18 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/util/bindings_util.py +1 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/util/bpy_node_info.py +0 -14
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/util/node_function.py +67 -7
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/_util.py +18 -13
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/addons.py +11 -6
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/curve.py +2 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/file.py +26 -14
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/manifest.json +43 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/mesh.py +6 -5
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/modifier.py +83 -14
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/object.py +1 -1
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/primitives/camera.py +3 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/primitives/curve.py +3 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/primitives/light.py +5 -4
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/primitives/mesh.py +21 -10
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/random.py +17 -17
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/tracer/trace.py +5 -6
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transpiler/bpy_to_computegraph.py +29 -158
- procfunc-0.36.1/src/procfunc/transpiler/parse_attrs.py +137 -0
- procfunc-0.36.1/src/procfunc/transpiler/parse_special_cases.py +467 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/teardown.py +8 -0
- {procfunc-0.35.1 → procfunc-0.36.1/src/procfunc.egg-info}/PKG-INFO +2 -2
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc.egg-info/SOURCES.txt +3 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_codegen.py +59 -0
- procfunc-0.36.1/tests/test_control.py +52 -0
- procfunc-0.36.1/tests/test_node_function.py +131 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_ops.py +166 -67
- procfunc-0.36.1/tests/test_random_mutation.py +92 -0
- procfunc-0.36.1/tests/test_teardown.py +99 -0
- procfunc-0.35.1/src/procfunc/transpiler/parse_special_cases.py +0 -158
- procfunc-0.35.1/tests/test_node_function.py +0 -28
- procfunc-0.35.1/tests/test_teardown.py +0 -51
- {procfunc-0.35.1 → procfunc-0.36.1}/LICENSE.md +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/setup.cfg +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/cli/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/cli/main.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/codegen/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/codegen/identifiers.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/color.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/compute_graph.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/node.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/proxy.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/compute_graph/util.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/construct_nodes.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/construct_operator.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/execute.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/realize.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/execute/util.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/nodes/util/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/attr.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/collection.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/primitives/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/ops/uv.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/tracer/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/tracer/decorator.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/tracer/patch.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/tracer/proxy.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/cleanup.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/convert.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/distribution.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/extract_materials.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/infer_distribution.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/parameters.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transforms/util.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transpiler/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transpiler/main.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/transpiler/parse_default_values.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/types.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/__init__.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/bpy_data.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/bpy_info.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/camera.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/keyframe.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/log.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/manifest.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc/util/pytree.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc.egg-info/dependency_links.txt +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc.egg-info/entry_points.txt +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc.egg-info/requires.txt +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/src/procfunc.egg-info/top_level.txt +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_asset.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_bpy_data_cleanup.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_cli_transpile.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_codegen_matrix.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_compute_graph.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_pytree.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_random.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_trace.py +0 -0
- {procfunc-0.35.1 → procfunc-0.36.1}/tests/test_transforms.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: procfunc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.36.1
|
|
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
|
|
@@ -37,7 +37,7 @@ Dynamic: license-file
|
|
|
37
37
|
|
|
38
38
|
This repository contains only the Primitives API, Transpiler and Tracer from our research paper.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Please see the infinigen2 [documentation](https://infinigen.cs.princeton.edu/docs/latest/) and [sourcecode](https://github.com/princeton-vl/infinigen/tree/3f58bb886bb1bda681d41240344fe3126ac0e9bd/src/infinigen2) to access the paper's library of new procedural generators
|
|
41
41
|
|
|
42
42
|
### Installation
|
|
43
43
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
This repository contains only the Primitives API, Transpiler and Tracer from our research paper.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Please see the infinigen2 [documentation](https://infinigen.cs.princeton.edu/docs/latest/) and [sourcecode](https://github.com/princeton-vl/infinigen/tree/3f58bb886bb1bda681d41240344fe3126ac0e9bd/src/infinigen2) to access the paper's library of new procedural generators
|
|
12
12
|
|
|
13
13
|
### Installation
|
|
14
14
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# ensure this gets imported first so that mathutils etc is available even if later modules dont import bpy
|
|
3
3
|
import bpy
|
|
4
4
|
|
|
5
|
-
__version__ = "0.
|
|
5
|
+
__version__ = "0.36.1"
|
|
6
6
|
|
|
7
7
|
from numpy.random import Generator as RNG
|
|
8
8
|
|
|
@@ -54,6 +54,7 @@ from .nodes import ProcNode, Shader, NodeDataType
|
|
|
54
54
|
from .tracer import trace, autowrap_module, add_search_scope
|
|
55
55
|
from .util.manifest import module_path
|
|
56
56
|
|
|
57
|
+
bpy.context.preferences.edit.use_global_undo = False
|
|
57
58
|
autowrap_module(random)
|
|
58
59
|
autowrap_module(color)
|
|
59
60
|
add_search_scope(nodes)
|
|
@@ -240,9 +240,12 @@ def _operator_call_operands(
|
|
|
240
240
|
|
|
241
241
|
operands = [bound.arguments[name] for name in operand_names]
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
operator_type = FUNCTIONS_TO_OPERATORS.get(node.func)
|
|
244
|
+
native_equality = operator_type in (OperatorType.EQUAL, OperatorType.NOT_EQUAL)
|
|
245
|
+
if (
|
|
246
|
+
template in _EPSILON_EQUALITY_TEMPLATES
|
|
247
|
+
and not native_equality
|
|
248
|
+
and not all(_is_exact_compare_operand(v) for v in operands)
|
|
246
249
|
):
|
|
247
250
|
return None
|
|
248
251
|
|
|
@@ -603,7 +606,8 @@ def _codegen_for_assignment(
|
|
|
603
606
|
def _expressions_scope_for_graph(
|
|
604
607
|
graph: cg.ComputeGraph,
|
|
605
608
|
scope_expressions: dict[int, str | list[str]],
|
|
606
|
-
|
|
609
|
+
fold_map: dict[int, bool],
|
|
610
|
+
) -> dict[int, str | list[str]]:
|
|
607
611
|
expressions: dict[int, str | list[str]] = {
|
|
608
612
|
**scope_expressions.copy(),
|
|
609
613
|
**_check_graph_input_names(graph, scope_expressions),
|
|
@@ -612,9 +616,6 @@ def _expressions_scope_for_graph(
|
|
|
612
616
|
# when we want to refer to a value, what string should we insert?
|
|
613
617
|
# - for most nodes: refer to a variable name
|
|
614
618
|
# - for inlined expressions: emplace a expression string
|
|
615
|
-
usages = cg.usages_per_node(graph)
|
|
616
|
-
fold_map = _expression_fold_map(graph, expressions, usages=usages)
|
|
617
|
-
|
|
618
619
|
node_names = identifiers.nodenames_from_fixed_and_infill(
|
|
619
620
|
graph,
|
|
620
621
|
fold_map=fold_map,
|
|
@@ -627,7 +628,7 @@ def _expressions_scope_for_graph(
|
|
|
627
628
|
raise ValueError(f"Scope and node names had overlap: {intersection=}")
|
|
628
629
|
expressions.update(node_names)
|
|
629
630
|
|
|
630
|
-
return expressions
|
|
631
|
+
return expressions
|
|
631
632
|
|
|
632
633
|
|
|
633
634
|
def _codegen_for_graph(
|
|
@@ -643,17 +644,13 @@ def _codegen_for_graph(
|
|
|
643
644
|
if add_version_comment:
|
|
644
645
|
code_lines.append(f"# Code generated by procfunc v{pf.__version__}")
|
|
645
646
|
|
|
646
|
-
|
|
647
|
+
usages = cg.usages_per_node(graph)
|
|
648
|
+
fold_map = _expression_fold_map(graph, scope_expressions, usages)
|
|
649
|
+
expressions = _expressions_scope_for_graph(graph, scope_expressions, fold_map)
|
|
647
650
|
_input_ids = set(id(node) for node in graph.inputs.values()) # noqa: F841
|
|
648
|
-
|
|
651
|
+
output_ids = {id(node) for node in graph.outputs.values()}
|
|
649
652
|
last_varname: str = ""
|
|
650
653
|
|
|
651
|
-
# Collect mutator call nodes so they emit as bare statements (no assignment)
|
|
652
|
-
mutator_call_ids = set()
|
|
653
|
-
for node in cg.traverse_depth_first(graph):
|
|
654
|
-
if isinstance(node, cg.MutatedArgumentNode):
|
|
655
|
-
mutator_call_ids.add(id(node.args[1]))
|
|
656
|
-
|
|
657
654
|
for node in cg.traverse_depth_first(graph):
|
|
658
655
|
if isinstance(node, cg.InputPlaceholderNode):
|
|
659
656
|
continue # arguments are defined in _codegen_graph_inputs
|
|
@@ -670,7 +667,17 @@ def _codegen_for_graph(
|
|
|
670
667
|
expressions[id(node)] = node_code
|
|
671
668
|
continue
|
|
672
669
|
|
|
673
|
-
|
|
670
|
+
node_usages = usages.get(id(node), [])
|
|
671
|
+
mutation_usages = [
|
|
672
|
+
usage
|
|
673
|
+
for usage in node_usages
|
|
674
|
+
if isinstance(usage, cg.MutatedArgumentNode) and usage.args[1] is node
|
|
675
|
+
]
|
|
676
|
+
if (
|
|
677
|
+
mutation_usages
|
|
678
|
+
and mutation_usages == node_usages
|
|
679
|
+
and id(node) not in output_ids
|
|
680
|
+
):
|
|
674
681
|
code_lines.extend(node_code if isinstance(node_code, list) else [node_code])
|
|
675
682
|
continue
|
|
676
683
|
|
|
@@ -713,6 +720,8 @@ def _resolve_func(func: Any) -> tuple[str | None, str]:
|
|
|
713
720
|
raise NotImplementedError(f"Unsupported function: {func}")
|
|
714
721
|
elif module == "builtins":
|
|
715
722
|
return None, func.__name__
|
|
723
|
+
elif module == "_operator":
|
|
724
|
+
return "import operator", f"operator.{func.__name__}"
|
|
716
725
|
elif module.startswith("procfunc."):
|
|
717
726
|
callsite = "pf." + module[len("procfunc.") :] + "." + func.__name__
|
|
718
727
|
importstring = "import procfunc as pf"
|
|
@@ -27,7 +27,8 @@ def repr_type(x: Any) -> str:
|
|
|
27
27
|
if origin is Union or origin is types.UnionType:
|
|
28
28
|
first_args = get_args(args[0])
|
|
29
29
|
if (
|
|
30
|
-
|
|
30
|
+
len(args) == 2
|
|
31
|
+
and get_origin(args[0]) is nt.ProcNode
|
|
31
32
|
and first_args
|
|
32
33
|
and first_args[0] is args[1]
|
|
33
34
|
):
|
|
@@ -82,6 +83,8 @@ def repr_value(value: Any) -> str:
|
|
|
82
83
|
|
|
83
84
|
if isinstance(value, np.random.Generator):
|
|
84
85
|
return "np.random.default_rng()"
|
|
86
|
+
elif get_origin(value) in (Union, types.UnionType, nt.ProcNode):
|
|
87
|
+
return repr_type(value)
|
|
85
88
|
elif isinstance(value, type):
|
|
86
89
|
return repr_type(value)
|
|
87
90
|
elif isinstance(value, np.ndarray):
|
|
@@ -7,6 +7,7 @@ class OperatorType(Enum):
|
|
|
7
7
|
SUB = "sub"
|
|
8
8
|
MUL = "mul"
|
|
9
9
|
DIV = "div"
|
|
10
|
+
FLOOR_DIV = "floordiv"
|
|
10
11
|
TRUEDIV = "truediv"
|
|
11
12
|
POW = "pow"
|
|
12
13
|
MOD = "mod"
|
|
@@ -17,6 +18,8 @@ class OperatorType(Enum):
|
|
|
17
18
|
EQUAL = "eq"
|
|
18
19
|
NOT_EQUAL = "ne"
|
|
19
20
|
NOT = "invert"
|
|
21
|
+
NEG = "neg"
|
|
22
|
+
POS = "pos"
|
|
20
23
|
LSHIFT = "lshift"
|
|
21
24
|
RSHIFT = "rshift"
|
|
22
25
|
BIT_AND = "and"
|
|
@@ -34,6 +37,7 @@ OPERATOR_TEMPLATES = {
|
|
|
34
37
|
OperatorType.SUB: "{} - {}",
|
|
35
38
|
OperatorType.MUL: "{} * {}",
|
|
36
39
|
OperatorType.DIV: "{} / {}",
|
|
40
|
+
OperatorType.FLOOR_DIV: "{} // {}",
|
|
37
41
|
OperatorType.POW: "{} ** {}",
|
|
38
42
|
OperatorType.MOD: "{} % {}",
|
|
39
43
|
OperatorType.LESS_THAN: "{} < {}",
|
|
@@ -42,6 +46,9 @@ OPERATOR_TEMPLATES = {
|
|
|
42
46
|
OperatorType.GREATER_THAN_EQUAL: "{} >= {}",
|
|
43
47
|
OperatorType.EQUAL: "{} == {}",
|
|
44
48
|
OperatorType.NOT_EQUAL: "{} != {}",
|
|
49
|
+
OperatorType.NOT: "~{}",
|
|
50
|
+
OperatorType.NEG: "-{}",
|
|
51
|
+
OperatorType.POS: "+{}",
|
|
45
52
|
OperatorType.VECTOR_PACK: "({}, {}, {})",
|
|
46
53
|
OperatorType.NOOP: "{}",
|
|
47
54
|
OperatorType.LSHIFT: "{} << {}",
|
|
@@ -57,6 +64,7 @@ OPERATORS_TO_FUNCTIONS = {
|
|
|
57
64
|
OperatorType.SUB: operator.sub,
|
|
58
65
|
OperatorType.MUL: operator.mul,
|
|
59
66
|
OperatorType.DIV: operator.truediv,
|
|
67
|
+
OperatorType.FLOOR_DIV: operator.floordiv,
|
|
60
68
|
OperatorType.MOD: operator.mod,
|
|
61
69
|
OperatorType.POW: operator.pow,
|
|
62
70
|
OperatorType.LESS_THAN: operator.lt,
|
|
@@ -65,6 +73,9 @@ OPERATORS_TO_FUNCTIONS = {
|
|
|
65
73
|
OperatorType.GREATER_THAN_EQUAL: operator.ge,
|
|
66
74
|
OperatorType.EQUAL: operator.eq,
|
|
67
75
|
OperatorType.NOT_EQUAL: operator.ne,
|
|
76
|
+
OperatorType.NOT: operator.invert,
|
|
77
|
+
OperatorType.NEG: operator.neg,
|
|
78
|
+
OperatorType.POS: operator.pos,
|
|
68
79
|
OperatorType.LSHIFT: operator.lshift,
|
|
69
80
|
OperatorType.RSHIFT: operator.rshift,
|
|
70
81
|
OperatorType.BIT_AND: operator.and_,
|
|
@@ -80,6 +91,7 @@ REFLECTABLE_OPERATORS = {
|
|
|
80
91
|
OperatorType.SUB,
|
|
81
92
|
OperatorType.MUL,
|
|
82
93
|
OperatorType.DIV,
|
|
94
|
+
OperatorType.FLOOR_DIV,
|
|
83
95
|
OperatorType.MOD,
|
|
84
96
|
OperatorType.POW,
|
|
85
97
|
OperatorType.LSHIFT,
|
|
@@ -19,6 +19,14 @@ class ProcfuncContext:
|
|
|
19
19
|
'ignore' silently returns an empty mesh, 'warn' logs a warning, 'throw' raises an error.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
+
warn_mode_transpile_dropped_attrs: Literal["ignore", "warn", "throw"]
|
|
23
|
+
"""
|
|
24
|
+
Controls behavior when transpiling a bpy node whose attributes carry render-affecting
|
|
25
|
+
state procfunc has no binding for, so the transpiled result would render differently
|
|
26
|
+
(e.g. a non-identity texture_mapping on a ShaderNodeTex* node).
|
|
27
|
+
'ignore' drops it silently, 'warn' logs a warning, 'throw' raises an error.
|
|
28
|
+
"""
|
|
29
|
+
|
|
22
30
|
record_node_definitions: bool = False
|
|
23
31
|
"""
|
|
24
32
|
Record the user-space file/line/function that constructed each ProcNode, used only to
|
|
@@ -34,10 +42,12 @@ class ProcfuncContext:
|
|
|
34
42
|
def set_strict(self):
|
|
35
43
|
"""Set all warning modes to 'throw'"""
|
|
36
44
|
self.warn_mode_empty_geonodes = "throw"
|
|
45
|
+
self.warn_mode_transpile_dropped_attrs = "throw"
|
|
37
46
|
|
|
38
47
|
def set_warn(self):
|
|
39
48
|
"""Set all warning modes to 'warn'"""
|
|
40
49
|
self.warn_mode_empty_geonodes = "warn"
|
|
50
|
+
self.warn_mode_transpile_dropped_attrs = "warn"
|
|
41
51
|
|
|
42
52
|
|
|
43
53
|
# Global context instance
|
|
@@ -47,9 +57,15 @@ warn_modes = ["ignore", "warn", "throw"]
|
|
|
47
57
|
_warn_mode_empty_geonodes = os.environ.get("PROCFUNC_WARN_MODE_EMPTY_GEONODES", "warn")
|
|
48
58
|
assert _warn_mode_empty_geonodes in warn_modes
|
|
49
59
|
|
|
60
|
+
_warn_mode_transpile_dropped_attrs = os.environ.get(
|
|
61
|
+
"PROCFUNC_WARN_MODE_TRANSPILE_DROPPED_ATTRS", "throw"
|
|
62
|
+
)
|
|
63
|
+
assert _warn_mode_transpile_dropped_attrs in warn_modes
|
|
64
|
+
|
|
50
65
|
globals = ProcfuncContext(
|
|
51
66
|
num_cpu_cores=int(os.environ.get("PROCFUNC_NUM_CPU_CORES", 0)),
|
|
52
67
|
warn_mode_empty_geonodes=_warn_mode_empty_geonodes, # type: ignore[invalid-assignment]
|
|
68
|
+
warn_mode_transpile_dropped_attrs=_warn_mode_transpile_dropped_attrs, # type: ignore[invalid-assignment]
|
|
53
69
|
current_trace_level=None,
|
|
54
70
|
record_node_definitions=os.environ.get("PROCFUNC_RECORD_NODE_DEFINITIONS", "0")
|
|
55
71
|
== "1",
|
|
@@ -33,6 +33,7 @@ def choice_idx(rng: np.random.Generator, weights: list[float]) -> int:
|
|
|
33
33
|
def _peekthrough_execute_all_choices(
|
|
34
34
|
choice_options: list[tuple[Callable[..., T], float]],
|
|
35
35
|
chosen_idx: int,
|
|
36
|
+
choice_rng: cg.Node,
|
|
36
37
|
args: tuple,
|
|
37
38
|
kwargs: dict,
|
|
38
39
|
) -> cg.Proxy:
|
|
@@ -43,6 +44,7 @@ def _peekthrough_execute_all_choices(
|
|
|
43
44
|
evald.append((res, weight))
|
|
44
45
|
|
|
45
46
|
new_kwargs = dict(
|
|
47
|
+
choice_rng=choice_rng,
|
|
46
48
|
choice_options=evald,
|
|
47
49
|
chosen_idx=chosen_idx,
|
|
48
50
|
)
|
|
@@ -67,6 +69,7 @@ class ChoiceResultProxy(cg.Proxy):
|
|
|
67
69
|
return _peekthrough_execute_all_choices(
|
|
68
70
|
self.node.kwargs["choice_options"],
|
|
69
71
|
self.node.kwargs["chosen_idx"],
|
|
72
|
+
self.node.kwargs["choice_rng"],
|
|
70
73
|
args,
|
|
71
74
|
kwargs,
|
|
72
75
|
)
|
|
@@ -92,13 +95,16 @@ def _choice_create_custom_tracer_wrapper(
|
|
|
92
95
|
@functools.wraps(choice)
|
|
93
96
|
def wrapper(
|
|
94
97
|
choice_rng: RngProxy,
|
|
95
|
-
choice_options: list[tuple[T, float]]
|
|
98
|
+
choice_options: list[tuple[T, float]],
|
|
96
99
|
chosen_idx: int | None = None,
|
|
97
100
|
):
|
|
98
101
|
choice_values, choice_weights = zip(*choice_options)
|
|
99
102
|
if chosen_idx is None:
|
|
100
103
|
chosen_idx = choice_idx(choice_rng.rng, choice_weights)
|
|
101
104
|
|
|
105
|
+
if patcher.trace_level < TraceLevel.RANDOM_CONTROL:
|
|
106
|
+
return choice_values[chosen_idx]
|
|
107
|
+
|
|
102
108
|
unwrapped_options = [
|
|
103
109
|
(pytree.PyTree(v).map(_unwrap_proxy).obj(), w) for v, w in choice_options
|
|
104
110
|
]
|
|
@@ -28,6 +28,7 @@ from .execute.execute import (
|
|
|
28
28
|
)
|
|
29
29
|
from .execute.util import NODE_OPERATOR_TABLE
|
|
30
30
|
from .types import (
|
|
31
|
+
HandleType,
|
|
31
32
|
ProcNode,
|
|
32
33
|
Shader,
|
|
33
34
|
SocketOrVal,
|
|
@@ -51,6 +52,7 @@ __all__ = [
|
|
|
51
52
|
"ProcNode",
|
|
52
53
|
"Shader",
|
|
53
54
|
"SocketOrVal",
|
|
55
|
+
"HandleType",
|
|
54
56
|
"NodeDataType",
|
|
55
57
|
"NodeGroupType",
|
|
56
58
|
"SocketType",
|
|
@@ -61,16 +61,31 @@ def rgb_curve(
|
|
|
61
61
|
fac: nt.SocketOrVal[float],
|
|
62
62
|
color: nt.SocketOrVal[pt.Color],
|
|
63
63
|
curves: list[np.ndarray] | np.ndarray | None = None,
|
|
64
|
+
handle_types: list[list[nt.HandleType]] | None = None,
|
|
65
|
+
use_clip: bool = True,
|
|
66
|
+
extend: Literal["HORIZONTAL", "EXTRAPOLATED"] = "EXTRAPOLATED",
|
|
67
|
+
clip_min: tuple[float, float] | None = None,
|
|
68
|
+
clip_max: tuple[float, float] | None = None,
|
|
64
69
|
) -> nt.ProcNode:
|
|
65
70
|
"""
|
|
66
71
|
Uses a RGBCurve Shader Node.
|
|
67
72
|
|
|
73
|
+
`handle_types[i]` contains the handles for the i-th curve, and
|
|
74
|
+
`handle_types[i][j]` is the handle type for `curves[i][j]`.
|
|
75
|
+
|
|
68
76
|
See: https://docs.blender.org/manual/en/4.2/render/shader_nodes/color/rgb_curves.html
|
|
69
77
|
"""
|
|
70
78
|
return nt.ProcNode.from_nodetype(
|
|
71
79
|
node_type="ShaderNodeRGBCurve",
|
|
72
80
|
inputs={"Fac": fac, "Color": color},
|
|
73
|
-
attrs={
|
|
81
|
+
attrs={
|
|
82
|
+
"curves": curves,
|
|
83
|
+
"handle_types": handle_types,
|
|
84
|
+
"use_clip": use_clip,
|
|
85
|
+
"extend": extend,
|
|
86
|
+
"clip_min": clip_min,
|
|
87
|
+
"clip_max": clip_max,
|
|
88
|
+
},
|
|
74
89
|
)
|
|
75
90
|
|
|
76
91
|
|