procfunc 0.30.0__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.
- procfunc/__init__.py +87 -0
- procfunc/color.py +57 -0
- procfunc/compute_graph/__init__.py +28 -0
- procfunc/compute_graph/compute_graph.py +115 -0
- procfunc/compute_graph/node.py +200 -0
- procfunc/compute_graph/operators_info.py +92 -0
- procfunc/compute_graph/proxy.py +173 -0
- procfunc/compute_graph/util.py +282 -0
- procfunc/context.py +115 -0
- procfunc/control.py +174 -0
- procfunc/nodes/__init__.py +66 -0
- procfunc/nodes/bindings_util.py +196 -0
- procfunc/nodes/bpy_node_info.py +280 -0
- procfunc/nodes/compositor.py +2242 -0
- procfunc/nodes/execute/construct_nodes.py +571 -0
- procfunc/nodes/execute/construct_special_cases.py +246 -0
- procfunc/nodes/execute/execute.py +548 -0
- procfunc/nodes/execute/infer_runtime_data_type.py +195 -0
- procfunc/nodes/execute/util.py +247 -0
- procfunc/nodes/func.py +1417 -0
- procfunc/nodes/geo.py +4240 -0
- procfunc/nodes/manifest.json +8769 -0
- procfunc/nodes/math.py +644 -0
- procfunc/nodes/node_function.py +160 -0
- procfunc/nodes/shader.py +2359 -0
- procfunc/nodes/types.py +347 -0
- procfunc/ops/__init__.py +35 -0
- procfunc/ops/_util.py +275 -0
- procfunc/ops/addons.py +59 -0
- procfunc/ops/attr.py +426 -0
- procfunc/ops/collection.py +90 -0
- procfunc/ops/curve.py +18 -0
- procfunc/ops/file.py +126 -0
- procfunc/ops/manifest.json +39149 -0
- procfunc/ops/mesh.py +1510 -0
- procfunc/ops/modifier.py +603 -0
- procfunc/ops/object.py +258 -0
- procfunc/ops/primitives/__init__.py +31 -0
- procfunc/ops/primitives/camera.py +45 -0
- procfunc/ops/primitives/curve.py +71 -0
- procfunc/ops/primitives/light.py +114 -0
- procfunc/ops/primitives/mesh.py +358 -0
- procfunc/ops/uv.py +271 -0
- procfunc/random.py +247 -0
- procfunc/tracer/__init__.py +43 -0
- procfunc/tracer/decorator.py +121 -0
- procfunc/tracer/patch.py +494 -0
- procfunc/tracer/proxy.py +127 -0
- procfunc/tracer/trace.py +222 -0
- procfunc/transforms/__init__.py +49 -0
- procfunc/transforms/cleanup.py +214 -0
- procfunc/transforms/convert.py +20 -0
- procfunc/transforms/distribution.py +191 -0
- procfunc/transforms/extract_materials.py +116 -0
- procfunc/transforms/infer_distribution.py +326 -0
- procfunc/transforms/parameters.py +15 -0
- procfunc/transforms/util.py +35 -0
- procfunc/transpiler/__init__.py +24 -0
- procfunc/transpiler/bpy_to_computegraph.py +1348 -0
- procfunc/transpiler/codegen.py +919 -0
- procfunc/transpiler/identifiers.py +595 -0
- procfunc/transpiler/main.py +299 -0
- procfunc/types.py +380 -0
- procfunc/util/__init__.py +0 -0
- procfunc/util/bpy_info.py +145 -0
- procfunc/util/camera.py +0 -0
- procfunc/util/keyframe.py +70 -0
- procfunc/util/log.py +96 -0
- procfunc/util/manifest.py +121 -0
- procfunc/util/pytree.py +343 -0
- procfunc/util/teardown.py +37 -0
- procfunc-0.30.0.dist-info/METADATA +120 -0
- procfunc-0.30.0.dist-info/RECORD +76 -0
- procfunc-0.30.0.dist-info/WHEEL +5 -0
- procfunc-0.30.0.dist-info/licenses/LICENSE.md +11 -0
- procfunc-0.30.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import inspect
|
|
3
|
+
import logging
|
|
4
|
+
from types import UnionType
|
|
5
|
+
from typing import Any, Callable, Union, get_args, get_origin
|
|
6
|
+
|
|
7
|
+
import procfunc as pf
|
|
8
|
+
from procfunc import compute_graph as cg
|
|
9
|
+
from procfunc.compute_graph.node import normalize_args_to_kwargs
|
|
10
|
+
from procfunc.nodes import types as nt
|
|
11
|
+
from procfunc.tracer import TraceLevel, register_trace_target
|
|
12
|
+
from procfunc.util import pytree
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _find_procnode_type(t: type) -> type | None:
|
|
18
|
+
origin = get_origin(t)
|
|
19
|
+
if origin is nt.ProcNode:
|
|
20
|
+
args = get_args(t)
|
|
21
|
+
return args[0] if args else None
|
|
22
|
+
elif origin in (Union, UnionType):
|
|
23
|
+
for a in get_args(t):
|
|
24
|
+
res = _find_procnode_type(a)
|
|
25
|
+
if res is not None:
|
|
26
|
+
return res
|
|
27
|
+
return None
|
|
28
|
+
else:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _procnode_placeholder(func: Callable, k: str, v: inspect.Parameter):
|
|
33
|
+
if v.annotation is None:
|
|
34
|
+
raise TypeError(
|
|
35
|
+
f"{func.__name} had argument {k:!r} with non type annotation. "
|
|
36
|
+
f"All @{node_function.__name__} arguments must have a type annotation."
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
value_type = _find_procnode_type(v.annotation)
|
|
40
|
+
if value_type is None and v.annotation is nt.ProcNode:
|
|
41
|
+
value_type = nt.Geometry
|
|
42
|
+
if value_type is None:
|
|
43
|
+
raise TypeError(
|
|
44
|
+
f"{func.__name__} had argument {k} with {v.annotation=} which is not allowed - "
|
|
45
|
+
f"all func annotations must contain a ProcNode to be used with @{node_function.__name__}"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
node = cg.InputPlaceholderNode(
|
|
49
|
+
name=k, default_value=v.default, metadata={"known_value_type": value_type}
|
|
50
|
+
)
|
|
51
|
+
logger.debug(
|
|
52
|
+
f"Using known_value_type={value_type} for {node=} for {k=} {v.default=}"
|
|
53
|
+
)
|
|
54
|
+
node = nt.ProcNode(node)
|
|
55
|
+
return node
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _execute_procnode_func_to_computegraph(func: Callable):
|
|
59
|
+
sig = inspect.signature(func)
|
|
60
|
+
input_placeholders = {
|
|
61
|
+
k: _procnode_placeholder(func, k, v) for k, v in sig.parameters.items()
|
|
62
|
+
}
|
|
63
|
+
result = func(**input_placeholders)
|
|
64
|
+
|
|
65
|
+
def _unwrap(x):
|
|
66
|
+
if isinstance(x, nt.ProcNode):
|
|
67
|
+
return x.item()
|
|
68
|
+
return x
|
|
69
|
+
|
|
70
|
+
inp_pt = pytree.PyTree(input_placeholders).map(_unwrap)
|
|
71
|
+
out_pt = pytree.PyTree(result).map(_unwrap)
|
|
72
|
+
graph = cg.ComputeGraph(
|
|
73
|
+
inputs=inp_pt,
|
|
74
|
+
outputs=out_pt,
|
|
75
|
+
name=func.__name__,
|
|
76
|
+
metadata={},
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
value_types = {
|
|
80
|
+
k: v.metadata.get("known_value_type", None) for k, v in graph.inputs.items()
|
|
81
|
+
}
|
|
82
|
+
if any(v is None for v in value_types.values()):
|
|
83
|
+
raise ValueError(
|
|
84
|
+
f"Subgraph {func.__name__} has inputs with no known value type: {value_types}"
|
|
85
|
+
)
|
|
86
|
+
graph.metadata["known_value_types"] = value_types
|
|
87
|
+
|
|
88
|
+
return graph
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _preprocess_procnode_call_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]:
|
|
92
|
+
result = {}
|
|
93
|
+
for k, v in kwargs.items():
|
|
94
|
+
match v:
|
|
95
|
+
case nt.ProcNode():
|
|
96
|
+
result[k] = v.item()
|
|
97
|
+
case pf.MeshObject() | pf.CurveObject():
|
|
98
|
+
result[k] = pf.nodes.geo.object_info(v).geometry.item()
|
|
99
|
+
case dict():
|
|
100
|
+
result[k] = _preprocess_procnode_call_kwargs(v)
|
|
101
|
+
case _:
|
|
102
|
+
result[k] = v
|
|
103
|
+
return result
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _subgraph_call_procnode(func: Callable, subgraph: cg.ComputeGraph, *args, **kwargs):
|
|
107
|
+
args, kwargs = normalize_args_to_kwargs(func, args, kwargs)
|
|
108
|
+
kwargs_unwrap = _preprocess_procnode_call_kwargs(kwargs)
|
|
109
|
+
node = cg.SubgraphCallNode(subgraph=subgraph, args=args, kwargs=kwargs_unwrap)
|
|
110
|
+
|
|
111
|
+
output_socket_names = list(subgraph.outputs.names(nocontainer_name="result"))
|
|
112
|
+
logger.debug(f"Created {func.__name__} with {output_socket_names=}")
|
|
113
|
+
call_node = nt.ProcNode(node)
|
|
114
|
+
|
|
115
|
+
if len(output_socket_names) == 1:
|
|
116
|
+
return call_node
|
|
117
|
+
|
|
118
|
+
sig = inspect.signature(func)
|
|
119
|
+
return_type = sig.return_annotation
|
|
120
|
+
|
|
121
|
+
subgraph_outputs = subgraph.outputs.dict()
|
|
122
|
+
outputs = {}
|
|
123
|
+
for k in output_socket_names:
|
|
124
|
+
# dont add non-None values where the original was None
|
|
125
|
+
if subgraph_outputs[k] is not None:
|
|
126
|
+
outputs[k] = call_node._output_socket(k)
|
|
127
|
+
else:
|
|
128
|
+
outputs[k] = None
|
|
129
|
+
outputs = {k: v for k, v in outputs.items() if v is not None}
|
|
130
|
+
return return_type(**outputs)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def node_function(func: Callable):
|
|
134
|
+
@functools.wraps(func)
|
|
135
|
+
def node_function_wrapper(*args, **kwargs):
|
|
136
|
+
subgraph = _execute_procnode_func_to_computegraph(func)
|
|
137
|
+
subgraph.metadata["operations"] = [
|
|
138
|
+
(node_function, {"func": func}),
|
|
139
|
+
]
|
|
140
|
+
subgraph.metadata["bpy_cached_impls"] = {}
|
|
141
|
+
|
|
142
|
+
return _subgraph_call_procnode(func, subgraph, *args, **kwargs)
|
|
143
|
+
|
|
144
|
+
register_trace_target(
|
|
145
|
+
node_function_wrapper,
|
|
146
|
+
trace_level=TraceLevel.NODEGROUPS,
|
|
147
|
+
allow_exec=False,
|
|
148
|
+
custom_trace_wrapper_create=None,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return node_function_wrapper
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def node_function_dynamic(func: Callable):
|
|
155
|
+
@functools.wraps(func)
|
|
156
|
+
def node_function_wrapper(*args, **kwargs):
|
|
157
|
+
subgraph = _execute_procnode_func_to_computegraph(func)
|
|
158
|
+
return _subgraph_call_procnode(func, subgraph, *args, **kwargs)
|
|
159
|
+
|
|
160
|
+
return node_function_wrapper
|