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,246 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import bpy
|
|
5
|
+
|
|
6
|
+
from procfunc import compute_graph as cg
|
|
7
|
+
from procfunc.nodes import bpy_node_info as bni
|
|
8
|
+
from procfunc.nodes import types as nt
|
|
9
|
+
|
|
10
|
+
from .util import assign_default_value
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def special_case_color_ramp(
|
|
16
|
+
bl_node: bpy.types.Node,
|
|
17
|
+
attrs: dict[str, Any],
|
|
18
|
+
**_kwargs,
|
|
19
|
+
):
|
|
20
|
+
color_ramp = bl_node.color_ramp # colorramp actually starts with 2 elements already
|
|
21
|
+
color_ramp.interpolation = attrs.pop("interpolation", "LINEAR")
|
|
22
|
+
color_ramp.color_mode = attrs.pop("color_mode", "RGB")
|
|
23
|
+
|
|
24
|
+
points = attrs.pop("points", None)
|
|
25
|
+
if points is None:
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
while len(color_ramp.elements) < len(points):
|
|
29
|
+
color_ramp.elements.new(0)
|
|
30
|
+
|
|
31
|
+
# Set positions and colors for all elements
|
|
32
|
+
for i, (position, color) in enumerate(points):
|
|
33
|
+
if i < len(color_ramp.elements):
|
|
34
|
+
color_ramp.elements[i].position = position
|
|
35
|
+
if len(color) == 3:
|
|
36
|
+
color_ramp.elements[i].color = (color[0], color[1], color[2], 1.0)
|
|
37
|
+
else:
|
|
38
|
+
color_ramp.elements[i].color = color
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def special_case_float_curve(
|
|
42
|
+
bl_node: bpy.types.Node,
|
|
43
|
+
attrs: dict[str, Any],
|
|
44
|
+
**_kwargs,
|
|
45
|
+
):
|
|
46
|
+
"""Handle float curve nodes with points attribute."""
|
|
47
|
+
points = attrs.pop("mapping", None)
|
|
48
|
+
|
|
49
|
+
handle_type = attrs.pop("handle_type", "AUTO")
|
|
50
|
+
if handle_type != "AUTO":
|
|
51
|
+
raise NotImplementedError(
|
|
52
|
+
f"handle_type={handle_type!r} is not yet supported, only 'AUTO' is implemented"
|
|
53
|
+
)
|
|
54
|
+
use_clip = attrs.pop("use_clip", True)
|
|
55
|
+
bl_node.mapping.use_clip = use_clip
|
|
56
|
+
|
|
57
|
+
if points is None:
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
curve = bl_node.mapping.curves[0]
|
|
61
|
+
|
|
62
|
+
# Add new points if needed (starts with 2 by default)
|
|
63
|
+
if len(points) > 2:
|
|
64
|
+
for _ in range(len(points) - 2):
|
|
65
|
+
curve.points.new(0, 0)
|
|
66
|
+
|
|
67
|
+
# Set positions for all points
|
|
68
|
+
for i, (x, y) in enumerate(points):
|
|
69
|
+
if i < len(curve.points):
|
|
70
|
+
curve.points[i].location = (x, y)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def special_case_rgb_curves(
|
|
74
|
+
bl_node: bpy.types.Node,
|
|
75
|
+
attrs: dict[str, Any],
|
|
76
|
+
**_kwargs,
|
|
77
|
+
):
|
|
78
|
+
"""Handle RGB curve nodes with points attribute."""
|
|
79
|
+
|
|
80
|
+
curves = attrs.pop("curves", None)
|
|
81
|
+
if curves is None:
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
for bl_curve, curve_np in zip(bl_node.mapping.curves, curves):
|
|
85
|
+
while len(bl_curve.points) < len(curve_np):
|
|
86
|
+
bl_curve.points.new(0, 0)
|
|
87
|
+
|
|
88
|
+
for i, (x, y) in enumerate(curve_np):
|
|
89
|
+
bl_curve.points[i].location = (x, y)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def special_case_vector_curves(
|
|
93
|
+
bl_node: bpy.types.Node,
|
|
94
|
+
attrs: dict[str, Any],
|
|
95
|
+
**_kwargs,
|
|
96
|
+
):
|
|
97
|
+
"""Handle vector curve nodes with points attribute."""
|
|
98
|
+
|
|
99
|
+
curves = attrs.pop("curves", None)
|
|
100
|
+
if curves is None:
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
for bl_curve, curve_np in zip(bl_node.mapping.curves, curves):
|
|
104
|
+
while len(bl_curve.points) < len(curve_np):
|
|
105
|
+
bl_curve.points.new(0, 0)
|
|
106
|
+
|
|
107
|
+
for i, (x, y) in enumerate(curve_np):
|
|
108
|
+
bl_curve.points[i].location = (x, y)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def special_case_file_output(
|
|
112
|
+
bl_node: bpy.types.Node,
|
|
113
|
+
attrs: dict[str, Any],
|
|
114
|
+
inputs: dict[str, Any],
|
|
115
|
+
**_kwargs,
|
|
116
|
+
):
|
|
117
|
+
assert bl_node.bl_idname == "CompositorNodeOutputFile"
|
|
118
|
+
|
|
119
|
+
bl_node.file_slots.clear()
|
|
120
|
+
for k in inputs.keys():
|
|
121
|
+
if k == 0 or k in attrs:
|
|
122
|
+
continue
|
|
123
|
+
bl_node.file_slots.new(k)
|
|
124
|
+
|
|
125
|
+
if file_format := attrs.pop("format", None):
|
|
126
|
+
for k, v in file_format.items():
|
|
127
|
+
setattr(bl_node.format, k, v)
|
|
128
|
+
|
|
129
|
+
if slot_paths := attrs.pop("slot_paths", None):
|
|
130
|
+
for k, v in slot_paths.items():
|
|
131
|
+
bl_node.file_slots[k].path = v
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def special_case_input(
|
|
135
|
+
node: nt.ProcNode,
|
|
136
|
+
node_tree: bpy.types.NodeTree,
|
|
137
|
+
bl_node: bpy.types.Node,
|
|
138
|
+
attrs: dict[str, Any],
|
|
139
|
+
**_kwargs,
|
|
140
|
+
):
|
|
141
|
+
raise NotImplementedError(f"{special_case_input.__name__} is not implemented")
|
|
142
|
+
|
|
143
|
+
# TODO node is actually a cg.Node
|
|
144
|
+
|
|
145
|
+
if node.type != nt.INPUT_NODE_TYPE:
|
|
146
|
+
raise ValueError(
|
|
147
|
+
f"{special_case_input.__name__} requires {nt.INPUT_NODE_TYPE!r}, got {node.type}"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
socket_types: list[nt.SocketType] = attrs.pop("socket_types")
|
|
151
|
+
defaults: list = attrs.pop("default_values")
|
|
152
|
+
|
|
153
|
+
output_sockets = node._output_sockets()
|
|
154
|
+
|
|
155
|
+
if output_sockets is None:
|
|
156
|
+
raise ValueError(f"{node=} has no output sockets")
|
|
157
|
+
|
|
158
|
+
for name, socket_type, default in zip(output_sockets, socket_types, defaults):
|
|
159
|
+
if name in node_tree.interface.items_tree:
|
|
160
|
+
raise ValueError(f"Socket {name} already exists in {node_tree.name}")
|
|
161
|
+
soc = node_tree.interface.new_socket(
|
|
162
|
+
name=name,
|
|
163
|
+
in_out="INPUT",
|
|
164
|
+
socket_type=socket_type.value,
|
|
165
|
+
)
|
|
166
|
+
data_type = nt.SOCKET_CLASS_TO_DATATYPE[socket_type.value]
|
|
167
|
+
assign_default_value(soc, default, data_type)
|
|
168
|
+
|
|
169
|
+
if name not in bl_node.outputs:
|
|
170
|
+
raise ValueError(f"Failed to add {name=} {socket_type=} to {bl_node.name=}")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def special_case_map_range(
|
|
174
|
+
attrs: dict[str, Any],
|
|
175
|
+
kwargs: dict[str, Any],
|
|
176
|
+
inputs: dict[str, Any],
|
|
177
|
+
**_kwargs,
|
|
178
|
+
):
|
|
179
|
+
if attrs["data_type"] == bni.NodeDataType.FLOAT_VECTOR.value:
|
|
180
|
+
assert "Value" in inputs, inputs
|
|
181
|
+
inputs["Vector"] = inputs.pop("Value")
|
|
182
|
+
kwargs["Vector"] = kwargs.pop("Value")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def special_case_capture_attribute(
|
|
186
|
+
bl_node: bpy.types.Node,
|
|
187
|
+
inputs: dict[str, Any],
|
|
188
|
+
kwargs: dict[str, Any],
|
|
189
|
+
**_kwargs,
|
|
190
|
+
):
|
|
191
|
+
for input_name, input_val in inputs.items():
|
|
192
|
+
if input_name == "Geometry":
|
|
193
|
+
continue
|
|
194
|
+
|
|
195
|
+
kwargval = kwargs.get(input_name)
|
|
196
|
+
if isinstance(kwargval, cg.Node) and (
|
|
197
|
+
annot := kwargval.metadata.get("known_value_type")
|
|
198
|
+
):
|
|
199
|
+
soc_type = bni.PYTHON_TYPE_TO_SOCKET_TYPE[annot]
|
|
200
|
+
data_type = bni.SOCKET_CLASS_TO_DATATYPE[soc_type.value]
|
|
201
|
+
elif isinstance(input_val, bpy.types.NodeSocket):
|
|
202
|
+
data_type = bni.SOCKET_CLASS_TO_DATATYPE[input_val.bl_idname]
|
|
203
|
+
elif type(input_val) in bni.PYTHON_TYPE_TO_SOCKET_TYPE:
|
|
204
|
+
soc_type = bni.PYTHON_TYPE_TO_SOCKET_TYPE[type(input_val)]
|
|
205
|
+
data_type = bni.SOCKET_CLASS_TO_DATATYPE[soc_type.value]
|
|
206
|
+
else:
|
|
207
|
+
raise ValueError(f"Could not determine data type for {input_val=}")
|
|
208
|
+
|
|
209
|
+
data_type = (
|
|
210
|
+
"VECTOR" # NodeDataType uses FLOAT_VECTOR here but that seems incorrect for CaptureAttribute??
|
|
211
|
+
if data_type == bni.NodeDataType.FLOAT_VECTOR
|
|
212
|
+
else data_type.value
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
bl_node.capture_items.new(data_type, name=input_name)
|
|
217
|
+
except Exception as e:
|
|
218
|
+
raise ValueError(
|
|
219
|
+
f"Could not add capture item {input_name=} {data_type} to {bl_node.name=}. "
|
|
220
|
+
f"{bl_node.capture_items.keys()=}. {e=}"
|
|
221
|
+
) from e
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def special_case_value_outputdefault(
|
|
225
|
+
bl_node: bpy.types.Node,
|
|
226
|
+
attrs: dict[str, Any],
|
|
227
|
+
**_kwargs,
|
|
228
|
+
):
|
|
229
|
+
value = attrs.pop("value", None)
|
|
230
|
+
if value is not None and hasattr(value, "__len__") and len(value) == 3:
|
|
231
|
+
value = (*value, 1.0)
|
|
232
|
+
bl_node.outputs[0].default_value = value
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
NODE_SPECIAL_CASES = {
|
|
236
|
+
"ShaderNodeValToRGB": special_case_color_ramp,
|
|
237
|
+
"ShaderNodeFloatCurve": special_case_float_curve,
|
|
238
|
+
"ShaderNodeMapRange": special_case_map_range,
|
|
239
|
+
"ShaderNodeRGBCurve": special_case_rgb_curves,
|
|
240
|
+
"ShaderNodeVectorCurve": special_case_vector_curves,
|
|
241
|
+
"CompositorNodeOutputFile": special_case_file_output,
|
|
242
|
+
nt.INPUT_NODE_TYPE: special_case_input,
|
|
243
|
+
"GeometryNodeCaptureAttribute": special_case_capture_attribute,
|
|
244
|
+
"ShaderNodeValue": special_case_value_outputdefault,
|
|
245
|
+
"ShaderNodeRGB": special_case_value_outputdefault,
|
|
246
|
+
}
|