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.
Files changed (76) hide show
  1. procfunc/__init__.py +87 -0
  2. procfunc/color.py +57 -0
  3. procfunc/compute_graph/__init__.py +28 -0
  4. procfunc/compute_graph/compute_graph.py +115 -0
  5. procfunc/compute_graph/node.py +200 -0
  6. procfunc/compute_graph/operators_info.py +92 -0
  7. procfunc/compute_graph/proxy.py +173 -0
  8. procfunc/compute_graph/util.py +282 -0
  9. procfunc/context.py +115 -0
  10. procfunc/control.py +174 -0
  11. procfunc/nodes/__init__.py +66 -0
  12. procfunc/nodes/bindings_util.py +196 -0
  13. procfunc/nodes/bpy_node_info.py +280 -0
  14. procfunc/nodes/compositor.py +2242 -0
  15. procfunc/nodes/execute/construct_nodes.py +571 -0
  16. procfunc/nodes/execute/construct_special_cases.py +246 -0
  17. procfunc/nodes/execute/execute.py +548 -0
  18. procfunc/nodes/execute/infer_runtime_data_type.py +195 -0
  19. procfunc/nodes/execute/util.py +247 -0
  20. procfunc/nodes/func.py +1417 -0
  21. procfunc/nodes/geo.py +4240 -0
  22. procfunc/nodes/manifest.json +8769 -0
  23. procfunc/nodes/math.py +644 -0
  24. procfunc/nodes/node_function.py +160 -0
  25. procfunc/nodes/shader.py +2359 -0
  26. procfunc/nodes/types.py +347 -0
  27. procfunc/ops/__init__.py +35 -0
  28. procfunc/ops/_util.py +275 -0
  29. procfunc/ops/addons.py +59 -0
  30. procfunc/ops/attr.py +426 -0
  31. procfunc/ops/collection.py +90 -0
  32. procfunc/ops/curve.py +18 -0
  33. procfunc/ops/file.py +126 -0
  34. procfunc/ops/manifest.json +39149 -0
  35. procfunc/ops/mesh.py +1510 -0
  36. procfunc/ops/modifier.py +603 -0
  37. procfunc/ops/object.py +258 -0
  38. procfunc/ops/primitives/__init__.py +31 -0
  39. procfunc/ops/primitives/camera.py +45 -0
  40. procfunc/ops/primitives/curve.py +71 -0
  41. procfunc/ops/primitives/light.py +114 -0
  42. procfunc/ops/primitives/mesh.py +358 -0
  43. procfunc/ops/uv.py +271 -0
  44. procfunc/random.py +247 -0
  45. procfunc/tracer/__init__.py +43 -0
  46. procfunc/tracer/decorator.py +121 -0
  47. procfunc/tracer/patch.py +494 -0
  48. procfunc/tracer/proxy.py +127 -0
  49. procfunc/tracer/trace.py +222 -0
  50. procfunc/transforms/__init__.py +49 -0
  51. procfunc/transforms/cleanup.py +214 -0
  52. procfunc/transforms/convert.py +20 -0
  53. procfunc/transforms/distribution.py +191 -0
  54. procfunc/transforms/extract_materials.py +116 -0
  55. procfunc/transforms/infer_distribution.py +326 -0
  56. procfunc/transforms/parameters.py +15 -0
  57. procfunc/transforms/util.py +35 -0
  58. procfunc/transpiler/__init__.py +24 -0
  59. procfunc/transpiler/bpy_to_computegraph.py +1348 -0
  60. procfunc/transpiler/codegen.py +919 -0
  61. procfunc/transpiler/identifiers.py +595 -0
  62. procfunc/transpiler/main.py +299 -0
  63. procfunc/types.py +380 -0
  64. procfunc/util/__init__.py +0 -0
  65. procfunc/util/bpy_info.py +145 -0
  66. procfunc/util/camera.py +0 -0
  67. procfunc/util/keyframe.py +70 -0
  68. procfunc/util/log.py +96 -0
  69. procfunc/util/manifest.py +121 -0
  70. procfunc/util/pytree.py +343 -0
  71. procfunc/util/teardown.py +37 -0
  72. procfunc-0.30.0.dist-info/METADATA +120 -0
  73. procfunc-0.30.0.dist-info/RECORD +76 -0
  74. procfunc-0.30.0.dist-info/WHEEL +5 -0
  75. procfunc-0.30.0.dist-info/licenses/LICENSE.md +11 -0
  76. 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