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,343 @@
1
+ import logging
2
+ from dataclasses import dataclass
3
+ from typing import Any, Callable, Generic, Iterator, TypeVar
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ """
8
+ A minimal pytree pack/unpack implementation inspired by JAX's docs.
9
+ """
10
+
11
+
12
+ @dataclass
13
+ class PyTreeDef:
14
+ container: type | None
15
+ items: list["PyTreeDef"]
16
+ aux: Any
17
+
18
+
19
+ @dataclass
20
+ class RegisteredPyTreeContainer:
21
+ flatten_func: Callable[[Any], tuple[list[Any], Any]]
22
+ unflatten_func: Callable[[list[Any], Any], Any]
23
+ names_func: Callable[[Any], list[str]]
24
+
25
+
26
+ _registered_pytree_containers: dict[type, RegisteredPyTreeContainer] = {}
27
+
28
+
29
+ TRegister = TypeVar("TRegister")
30
+
31
+
32
+ def register_pytree_container(
33
+ container: type,
34
+ flatten_func: Callable[[TRegister], tuple[list[Any], Any]],
35
+ unflatten_func: Callable[[list[Any], Any], TRegister],
36
+ names_func: Callable[[TRegister], list[str]],
37
+ ):
38
+ _registered_pytree_containers[container] = RegisteredPyTreeContainer(
39
+ flatten_func,
40
+ unflatten_func,
41
+ names_func,
42
+ )
43
+
44
+
45
+ def _tuple_flatten(obj: tuple) -> tuple[list[Any], Any]:
46
+ return list(obj), None
47
+
48
+
49
+ def _tuple_unflatten(objs: list[Any], spec: Any) -> tuple:
50
+ return tuple(objs)
51
+
52
+
53
+ def _list_flatten(obj: list) -> tuple[list[Any], Any]:
54
+ return obj, None
55
+
56
+
57
+ def _list_unflatten(objs: list[Any], spec: Any) -> list:
58
+ return objs
59
+
60
+
61
+ def _dict_flatten(obj: dict) -> tuple[list[Any], Any]:
62
+ return list(obj.values()), obj.keys()
63
+
64
+
65
+ def _dict_unflatten(objs: list[Any], spec: Any) -> dict:
66
+ return dict(zip(spec, objs))
67
+
68
+
69
+ def _namedtuple_flatten(obj: tuple) -> tuple[list[Any], Any]:
70
+ return list(obj), list(obj._fields)
71
+
72
+
73
+ def _namedtuple_unflatten(objs: list[Any], spec: Any) -> tuple:
74
+ return spec.container(*objs)
75
+
76
+
77
+ def _namedtuple_names(obj: tuple) -> list[str]:
78
+ return list(obj._fields)
79
+
80
+
81
+ register_pytree_container(
82
+ list,
83
+ flatten_func=lambda x: (x, None),
84
+ unflatten_func=lambda x, spec: x,
85
+ names_func=lambda x: [str(i) for i in range(len(x))],
86
+ )
87
+ register_pytree_container(
88
+ dict,
89
+ flatten_func=lambda x: (list(x.values()), x.keys()),
90
+ unflatten_func=lambda x, spec: dict(zip(spec.aux, x)),
91
+ names_func=lambda x: list(x.keys()),
92
+ )
93
+ register_pytree_container(
94
+ tuple,
95
+ flatten_func=lambda x: (list(x), None),
96
+ unflatten_func=lambda x, spec: tuple(x),
97
+ names_func=lambda x: [str(i) for i in range(len(x))],
98
+ )
99
+
100
+ NAMEDTUPLE_CONTAINER = RegisteredPyTreeContainer(
101
+ flatten_func=_namedtuple_flatten,
102
+ unflatten_func=_namedtuple_unflatten,
103
+ names_func=_namedtuple_names,
104
+ )
105
+
106
+
107
+ def is_type_namedtuple(obj: type) -> bool:
108
+ return issubclass(obj, tuple) and obj is not tuple
109
+
110
+
111
+ def is_obj_namedtuple(obj: Any) -> bool:
112
+ # theres no good way to check isinstance namedtuple
113
+ # namedtuple is a function not a type, and the returntype is only a subclass of tuple
114
+ return is_type_namedtuple(type(obj)) and hasattr(obj, "_fields")
115
+
116
+
117
+ def flatten(obj: Any) -> tuple[list[Any], PyTreeDef]:
118
+ registered_pytree_container = _registered_pytree_containers.get(type(obj))
119
+
120
+ if registered_pytree_container is not None:
121
+ flatten_func = registered_pytree_container.flatten_func
122
+ elif is_obj_namedtuple(obj):
123
+ flatten_func = _namedtuple_flatten
124
+ else:
125
+ return [obj], PyTreeDef(None, [], None)
126
+
127
+ children, aux = flatten_func(obj)
128
+
129
+ child_items = []
130
+ spec_items = []
131
+ for child in children:
132
+ child_objs, child_spec = flatten(child)
133
+ child_items.extend(child_objs)
134
+ spec_items.append(child_spec)
135
+
136
+ return child_items, PyTreeDef(type(obj), spec_items, aux)
137
+
138
+
139
+ def _get_container_funcs(container_type: type) -> RegisteredPyTreeContainer:
140
+ rec = _registered_pytree_containers.get(container_type)
141
+ if is_type_namedtuple(container_type):
142
+ return NAMEDTUPLE_CONTAINER
143
+ elif rec is None:
144
+ return None
145
+ else:
146
+ return rec
147
+
148
+
149
+ def _unflatten_iterative(
150
+ children: Iterator[Any],
151
+ spec: PyTreeDef,
152
+ ) -> Any:
153
+ if spec.container is None:
154
+ return next(children)
155
+
156
+ container_spec = _get_container_funcs(spec.container)
157
+ if container_spec is None:
158
+ assert len(children) == 1
159
+ return next(children)
160
+
161
+ real_children = []
162
+ for child_spec in spec.items:
163
+ child = _unflatten_iterative(children, child_spec)
164
+ real_children.append(child)
165
+
166
+ return container_spec.unflatten_func(real_children, spec)
167
+
168
+
169
+ def unflatten(children: list[Any], spec: PyTreeDef, start_idx: int = 0) -> Any:
170
+ return _unflatten_iterative(iter(children), spec)
171
+
172
+
173
+ def _compute_pytree_obj_names(
174
+ obj: Any, separator: str = "_", nocontainer_name: str = ""
175
+ ) -> Iterator[str]:
176
+ container_spec = _get_container_funcs(type(obj))
177
+ if container_spec is None:
178
+ yield nocontainer_name
179
+ return
180
+ names = container_spec.names_func(obj)
181
+ children = container_spec.flatten_func(obj)[0]
182
+
183
+ for parentname, child in zip(names, children):
184
+ for childname in _compute_pytree_obj_names(child, separator):
185
+ yield (parentname + separator + childname if childname else parentname)
186
+
187
+
188
+ TItem = TypeVar("TItem")
189
+ TChildren = TypeVar("TChildren")
190
+ TChildrenNew = TypeVar("TChildrenNew")
191
+
192
+
193
+ class PyTree(Generic[TItem, TChildren]):
194
+ """
195
+ Data-structure for trees of python objects.Any
196
+
197
+ Pytrees support flattening and unflattening, similar to Jax
198
+
199
+ However, we additionally require that every registered pytree container provides names for each child.
200
+ """
201
+
202
+ def __init__(self, obj: TItem):
203
+ flat = flatten(obj)
204
+ self.children: list[TChildren] = flat[0]
205
+ self.spec: PyTreeDef = flat[1]
206
+
207
+ def __repr__(self):
208
+ return f"PyTree({self.spec!r}, len(children)={len(self.children)})"
209
+
210
+ def obj(self) -> TItem:
211
+ """Get the original object used to construct this PyTree"""
212
+
213
+ return unflatten(self.children, self.spec)
214
+
215
+ def dict(self) -> dict[str, TChildren]:
216
+ res = {}
217
+ for name, child in self.items():
218
+ if name in res:
219
+ existing = res[name]
220
+ raise ValueError(
221
+ f"pytree to dict had duplicate key {name} for {existing=} and {child=}"
222
+ )
223
+ res[name] = child
224
+ return res
225
+
226
+ def values(self) -> Iterator[TChildren]:
227
+ return iter(self.children)
228
+
229
+ def names(self, separator: str = "_", nocontainer_name: str = "") -> Iterator[str]:
230
+ return _compute_pytree_obj_names(self.obj(), separator, nocontainer_name)
231
+
232
+ def items(
233
+ self, separator: str = "_", nocontainer_name: str = ""
234
+ ) -> Iterator[tuple[str, TChildren]]:
235
+ names = self.names(separator=separator, nocontainer_name=nocontainer_name)
236
+ return iter(zip(names, self.children))
237
+
238
+ def __len__(self) -> int:
239
+ return len(self.children)
240
+
241
+ @classmethod
242
+ def from_values(
243
+ cls, children: list[TChildren], spec: PyTreeDef
244
+ ) -> "PyTree[TItem, TChildren]":
245
+ return cls(unflatten(children, spec))
246
+
247
+ @classmethod
248
+ def from_children_spec(
249
+ cls, children: list[TChildren], spec: PyTreeDef
250
+ ) -> "PyTree[TItem, TChildren]":
251
+ res = PyTree(None)
252
+ res.children = children
253
+ res.spec = spec
254
+ return res
255
+
256
+ def map(
257
+ self, fn: Callable[[TChildren], TChildrenNew]
258
+ ) -> "PyTree[TItem, TChildrenNew]":
259
+ children = [fn(child) for child in self.children]
260
+ return self.from_values(children, self.spec)
261
+
262
+ def map_items(
263
+ self, fn: Callable[[str, TChildren], TChildrenNew]
264
+ ) -> "PyTree[TItem, TChildrenNew]":
265
+ children = [fn(name, child) for name, child in self.items()]
266
+ return self.from_values(children, self.spec)
267
+
268
+ def is_single(self) -> bool:
269
+ return self.spec.container is None
270
+
271
+ def toplevel_type(self) -> type:
272
+ return self.spec.container
273
+
274
+ def children_one_level(self) -> list[Any]:
275
+ obj = self.obj()
276
+
277
+ container_funcs = _get_container_funcs(self.spec.container)
278
+
279
+ child_objs = container_funcs.flatten_func(obj)[0]
280
+ new_children = []
281
+ for child_obj, child_spec in zip(child_objs, self.spec.items):
282
+ if child_spec.container is not None:
283
+ child_tree = PyTree(child_obj)
284
+ new_children.append(child_tree)
285
+ else:
286
+ new_children.append(child_obj)
287
+
288
+ return new_children
289
+
290
+ def unflatten_one_level(
291
+ self,
292
+ ) -> TItem:
293
+ container_funcs = _get_container_funcs(self.spec.container)
294
+ return container_funcs.unflatten_func(self.children_one_level(), self.spec)
295
+
296
+ def value(self) -> TItem:
297
+ return unflatten(self.children, self.spec)
298
+
299
+
300
+ def repr_tree_to_str(
301
+ tree: PyTree[Any, str] | str,
302
+ type_namer: Callable[[type], str] | None = None,
303
+ ) -> str:
304
+ if type_namer is None:
305
+
306
+ def type_namer(t):
307
+ return t.__name__
308
+
309
+ if isinstance(tree, str):
310
+ return tree
311
+
312
+ if tree.spec.container is None or tree.spec.container is type(None):
313
+ assert len(tree.children) == 1, tree.children
314
+ assert isinstance(tree.children[0], str)
315
+ return tree.children[0]
316
+
317
+ children = tree.children_one_level()
318
+ childreprs = [repr_tree_to_str(child, type_namer) for child in children]
319
+
320
+ if tree.spec.container is list:
321
+ return f"[{', '.join(childreprs)}]"
322
+ elif tree.spec.container is dict:
323
+ keys = list(tree.unflatten_one_level().keys())
324
+ return (
325
+ "{" + ", ".join(f"{repr(k)}: {v}" for k, v in zip(keys, childreprs)) + "}"
326
+ )
327
+ elif tree.spec.container is tuple:
328
+ return f"({', '.join(childreprs)})"
329
+ elif is_type_namedtuple(tree.spec.container):
330
+ return f"{type_namer(tree.spec.container)}({', '.join(childreprs)})"
331
+ elif tree.spec.container in _registered_pytree_containers:
332
+ container_funcs = _registered_pytree_containers[tree.spec.container]
333
+ names = container_funcs.names_func(None)
334
+ return f"{type_namer(tree.spec.container)}({', '.join(f'{n}={v}' for n, v in zip(names, childreprs))})"
335
+ else:
336
+ raise ValueError(f"Unsupported container type {tree.spec.container}")
337
+
338
+
339
+ __all__ = [
340
+ "flatten",
341
+ "unflatten",
342
+ "PyTree",
343
+ ]
@@ -0,0 +1,37 @@
1
+ """Helpers to exit without triggering bpy's C-level teardown segfault.
2
+
3
+ bpy's cleanup segfaults (SIGSEGV / exit code 139) during normal Python
4
+ shutdown. ``os._exit`` skips Python teardown and atexit handlers, avoiding
5
+ the crash while preserving the real exit code.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import traceback
11
+ from contextlib import contextmanager
12
+
13
+
14
+ def exit_skipping_teardown(code: int = 0):
15
+ sys.stdout.flush()
16
+ sys.stderr.flush()
17
+ os._exit(code)
18
+
19
+
20
+ @contextmanager
21
+ def skip_teardown_on_exit():
22
+ """Run a block and unconditionally ``os._exit`` when it finishes.
23
+
24
+ Catches ``SystemExit``, unhandled exceptions, and normal return;
25
+ translates each into an ``os._exit`` with the appropriate code so
26
+ bpy's teardown is skipped. Unhandled exceptions are printed with the
27
+ standard Python traceback format to stderr before exiting, matching
28
+ what you'd see from a natural crash.
29
+ """
30
+ try:
31
+ yield
32
+ except SystemExit as e:
33
+ exit_skipping_teardown(e.code if isinstance(e.code, int) else 1)
34
+ except BaseException:
35
+ traceback.print_exc()
36
+ exit_skipping_teardown(1)
37
+ exit_skipping_teardown(0)
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: procfunc
3
+ Version: 0.30.0
4
+ Summary: A framework for compositional procedural generation
5
+ License-Expression: BSD-3-Clause
6
+ Project-URL: Homepage, https://github.com/princeton-vl/procfunc
7
+ Project-URL: Repository, https://github.com/princeton-vl/procfunc
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE.md
11
+ Requires-Dist: bpy==4.2.0
12
+ Requires-Dist: numpy<2
13
+ Requires-Dist: pandas
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest; extra == "dev"
16
+ Requires-Dist: pytest-xdist; extra == "dev"
17
+ Requires-Dist: ruff<0.16,>=0.15; extra == "dev"
18
+ Requires-Dist: ty; extra == "dev"
19
+ Provides-Extra: docs
20
+ Requires-Dist: sphinx; extra == "docs"
21
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
22
+ Dynamic: license-file
23
+
24
+ # ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python
25
+
26
+ [**Documentation**](#documentation)
27
+ | [**Research Paper**](#paper)
28
+ | [**Documentation**](#paper)
29
+ | [**Transpiling**](#transpile-a-blender-file-to-procfunc-code)
30
+ | [**Experiments**](#experiments)
31
+ | [**Contributing**](#contributing)
32
+
33
+ This repository contains only the Primitives API, Transpiler and Tracer from our research paper.
34
+
35
+ The pre-made procedural generators are coming soon as part of [infinigen](https://github.com/princeton-vl/infinigen).
36
+
37
+ ### Installation
38
+
39
+ Use [uv](https://docs.astral.sh/uv/getting-started/installation/) or your favorite package manager to install procfunc via pip:
40
+ ```bash
41
+ uv pip install procfunc
42
+ ```
43
+
44
+ Note: ProcFunc depends on `bpy==4.2.0` which then requires Python==3.11.x. Other version are not yet supported.
45
+
46
+ Since we have not yet reached [semver 1.0.0](https://semver.org/) we have not yet finalized procfunc's interface.
47
+ In the meantime, each 0.X.0 may introduce interface changes. Please pin `uv add procfunc<0.XX` where X is the current version.
48
+
49
+ ### Usage
50
+
51
+ See [procfunc.readthedocs.io](https://procfunc.readthedocs.io) for available functions
52
+
53
+ Please create Github Issues for any bugs or unclear interfaces!
54
+
55
+ ##### Transpile a blender file to ProcFunc code
56
+
57
+ <p float="left">
58
+ <img src="examples/transpile_simple_chair/blender_screenshot.png" height="200" />
59
+ <img src="examples/transpile_simple_chair/code_screenshot.png" height="200" />
60
+ </p>
61
+
62
+ Convert a Blender geometry node tree into procfunc Python code by downloading our example blend and executing the transpiler:
63
+ ```bash
64
+ wget https://raw.githubusercontent.com/princeton-vl/procfunc/main/examples/transpile_simple_chair/simple_chair.blend
65
+ uv run python -m procfunc.transpiler.main simple_chair.blend --node_trees simple_chair --output transpiled_code.py
66
+ ```
67
+
68
+ See the expected output in [`examples/transpile_simple_chair/transpiled_code.py`](examples/transpile_simple_chair/transpiled_code.py).
69
+ To use the code, you can add `pf.ops.file.save_blend("test.blend")` to the end of it, then open the generated blender file.
70
+ You can also open and edit the blender geonodes prior to transpiling in order to generate different procfunc code.
71
+
72
+ ### Paper
73
+
74
+ If you find procfunc useful, please cite our paper:
75
+ ```
76
+ @misc{raistrick2026procfunc,
77
+ title={ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python},
78
+ author={Alexander Raistrick and Karhan Kayan and Jack Nugent and David Yan and Lingjie Mei and Meenal Parakh and Hongyu Wen and Dylan Li and Yiming Zuo and Erich Liang and Jia Deng},
79
+ year={2026},
80
+ eprint={2604.26943},
81
+ archivePrefix={arXiv},
82
+ primaryClass={cs.CV},
83
+ url={https://arxiv.org/abs/2604.26943},
84
+ }
85
+ ```
86
+
87
+ ### Experiments
88
+
89
+ See [experiments/EXPERIMENTS.md](experiments/EXPERIMENTS.md)
90
+
91
+ NOTE: experiments are only intended to be correct when using the `experiments` branch, which will not see major updates.
92
+
93
+ ### Contributing
94
+
95
+ Please create an issue for any proposed features to discuss them before implementing.
96
+
97
+ ##### Developer Installation
98
+ ```bash
99
+ git clone git@github.com:princeton-vl/procfunc.git
100
+ cd procfunc
101
+ uv venv
102
+ uv pip install -e ".[dev]"
103
+ ```
104
+
105
+ ##### Tools
106
+
107
+ ```bash
108
+ uv run ruff format
109
+ uv run ruff check --fix
110
+ uv run pytest
111
+ make docs
112
+ ```
113
+
114
+ ##### Todos / Sharp Edges
115
+
116
+ Add optional support for bpy==4.x and 5.x and maybe 3.6, all under the same procfunc interface.
117
+
118
+ pf.ops is missing some blender functions and arguments, especially returning "selection" masks for some cases.
119
+
120
+ Assets like pf.MeshObject and pf.Material are not currently cleaned up upon going out of scope
@@ -0,0 +1,76 @@
1
+ procfunc/__init__.py,sha256=-hCx5Edtijw2i3wXYWlqqPZ58VUH2LKwSzGBcJvnoYU,1826
2
+ procfunc/color.py,sha256=oae7WRSU3J0Tz-fC_NYX8_qMSvcu2nAoAY4cGILOAyU,1175
3
+ procfunc/context.py,sha256=51td0Vkpyyjjh9SgLMcAycS9KdNdC6J0ipCFGU7FkEs,4233
4
+ procfunc/control.py,sha256=ZmBHEnIdd1hmFSr_nXLznkhfZrO-nUUY2DnlRD1Ow0I,5138
5
+ procfunc/random.py,sha256=1N4GT_PLIUcI0OGLqYH3cIddHm2rLrTgX16sXVr7rzg,4776
6
+ procfunc/types.py,sha256=tupPzIj2oih5pBvfm_KrvBA0W9TbuGiXi3sFP5sayJY,10592
7
+ procfunc/compute_graph/__init__.py,sha256=sMDY97qqaIkDd0EHxXMIuMEbfptSu7caUYV8A4pRxPU,621
8
+ procfunc/compute_graph/compute_graph.py,sha256=UEKxNnwtT8W9pS95mRkAdcYDJo0rbEJ7o9c4B41s3YQ,3675
9
+ procfunc/compute_graph/node.py,sha256=-2DYDiDhrFdWQZQufCFeWvHhjHyCRJA00pTVUbLeYvU,6065
10
+ procfunc/compute_graph/operators_info.py,sha256=GGYXQgae8PBgLQSiD2ICxqlZsfVwj5bA_bfKl7zSIDg,2448
11
+ procfunc/compute_graph/proxy.py,sha256=68H-CHlTZumhN6hUMqCUfXVohRYxi3QfmDdWIvO0mRc,5145
12
+ procfunc/compute_graph/util.py,sha256=6Lvp5M9ryCjP2M0BfT3wuxYjCn1R0d2vCLPwSVXyW8w,7886
13
+ procfunc/nodes/__init__.py,sha256=l3O5TqL5URZlST7ojdG3Uxgb076n_aDZDFkNZvXgXO4,1592
14
+ procfunc/nodes/bindings_util.py,sha256=YFmqwoIccs9iB7sxJaE7-92PeqRV2jP72oXrXU7i1p4,6727
15
+ procfunc/nodes/bpy_node_info.py,sha256=TrrT6_uac8pD69rTrvPUOGo6TPgAFeW6nz4frO3liIU,8225
16
+ procfunc/nodes/compositor.py,sha256=G-yOGOUAIagIVKQW5BNCE3PNkaj_zc-ZCZBrY9lhJn8,64784
17
+ procfunc/nodes/func.py,sha256=guPkyhRHT6IDJP-IoJA0KRz7t_4nd_Q0s5IqnscZQyc,41021
18
+ procfunc/nodes/geo.py,sha256=GMRfNt7wCyAwfml_JggEPKcMSU10wRNMtyvXNJfJwaM,129731
19
+ procfunc/nodes/manifest.json,sha256=w33_d5NdbgnxSdK5qINDGxutCAVveayUFUA4YrueGOY,224587
20
+ procfunc/nodes/math.py,sha256=-sVHfCgF_gOHEqA8yS-1lM5lpXR2FslRMpDJXxWSq7Y,18566
21
+ procfunc/nodes/node_function.py,sha256=158JoMW8trrVLskHin1L1tI2Bf_PMWvEmPjn2aohGV0,5195
22
+ procfunc/nodes/shader.py,sha256=gR4Qp09vSpCLB95t7lC9-QmVzFlJvCRjWLoNo_18S2s,73564
23
+ procfunc/nodes/types.py,sha256=dfj3-l4sBvAAxRcjYvoNfUM5l0lRlZ_goJO5XplH0RY,11529
24
+ procfunc/nodes/execute/construct_nodes.py,sha256=oq5Ju75t-voAXO4maix2WlZ14UDKsBS8TB9I_D61qE0,20083
25
+ procfunc/nodes/execute/construct_special_cases.py,sha256=kXfA8Uo3iKJHmeUpHM14njBT_bxB0wxTAEHjKO4ZcRQ,7668
26
+ procfunc/nodes/execute/execute.py,sha256=tnbzpKiVClrGBg1tXYFdOgZOyiufK7z_wG_z8NjrC2U,17143
27
+ procfunc/nodes/execute/infer_runtime_data_type.py,sha256=C1L5C7d2ZdFzYVXeN1MXPPkmRycaRf6cCQMDudAxKTc,6572
28
+ procfunc/nodes/execute/util.py,sha256=2BZKxUCZb9vzoE7vVWwlXmgXzauXPRH2s0ZvjXzJ4OI,8644
29
+ procfunc/ops/__init__.py,sha256=XwD9FIArPEkJ38CEdx2GvVCnXriCmEo7RJ9sT-d_fV0,580
30
+ procfunc/ops/_util.py,sha256=QcBZJ470n9ZV6YWSpj8P4u8_25MbGwpb7r6Ta8m2fpU,8018
31
+ procfunc/ops/addons.py,sha256=z1tlA9GqsBkldQib8EvFC1JaKHn3YqtD5b7WMBoux9k,1906
32
+ procfunc/ops/attr.py,sha256=Q7r9Jj7dBxHAUz74V3dG4sEghw7Y-Y08_-YhargOP7E,13383
33
+ procfunc/ops/collection.py,sha256=zwLBxvE_D7FqGf_Dq0pSto2dUeUaww_io8zciB8m6vs,2560
34
+ procfunc/ops/curve.py,sha256=LXCN_ANEcCawjC2Som4BcMEQXigFqlIjDWrBIlek3_U,400
35
+ procfunc/ops/file.py,sha256=e5DTwVDY0BueGI_3pp1Dhr0Ki_V55W6P5OedAYowrW4,3631
36
+ procfunc/ops/manifest.json,sha256=ZRAwPd6077ndNdeLDNVZbgMzuTr7vaTITx_OfM-ADU4,1099302
37
+ procfunc/ops/mesh.py,sha256=eiqpdJaayVRV-ubKPbc0YN-CC18yaUoHGG9vwexkAaA,42716
38
+ procfunc/ops/modifier.py,sha256=IdPL5_FyiUg5N-qZwEsN8oOggCzxDQi4kI3yv3oiCFU,15688
39
+ procfunc/ops/object.py,sha256=sZ6icCXd-uybMMFeniZVM6yuVzJ_LyTLnFJCIlPtsBU,7173
40
+ procfunc/ops/uv.py,sha256=xRYmPIxoyBQvg2InwQcE_sKrQilYrbTVjdtsYDUxu2k,8514
41
+ procfunc/ops/primitives/__init__.py,sha256=0HWtXy2nsAeeVVV-uV-vOFHwsJ1n4Nhwq_iChB4Fxxg,492
42
+ procfunc/ops/primitives/camera.py,sha256=X3hNwvVkCMVZyXp-qIGlJAUbFip3WsL-P4TK64bKY3Y,1246
43
+ procfunc/ops/primitives/curve.py,sha256=AptzFWxqgGS_xhVmy0n18pZtZ9lzLZvPhpTQxiTsEeQ,2279
44
+ procfunc/ops/primitives/light.py,sha256=v6AL48m6TVz_vQD0qFBZhA0PO1QNAZEkEOfX91B_a4Q,3651
45
+ procfunc/ops/primitives/mesh.py,sha256=tuPZ6jMW7hejIrIRnaSxF6X-Wah8-eDTwvDEPbV2Zxk,10019
46
+ procfunc/tracer/__init__.py,sha256=m1XdoNp37CKHhgAkuC_Kh_IFUI4uhhj8K_5W9rsaEdQ,798
47
+ procfunc/tracer/decorator.py,sha256=gjdHuSe68-_y4kUxqRYi3_OXx0o0rPNx08Pb-S9AV3c,3806
48
+ procfunc/tracer/patch.py,sha256=PzTPjpdhuk9USndCoAjGzeVFFVBP7k9YOyUcXaJQARI,17051
49
+ procfunc/tracer/proxy.py,sha256=BQMyLuLsHs0p5Qhf1bEvtmEYGfMMAKnbE7UmJ1jBe9c,3664
50
+ procfunc/tracer/trace.py,sha256=tRCQOSfv35PMYA8ZjXpocz-gEb_XOY4ivu58duXfE3E,6074
51
+ procfunc/transforms/__init__.py,sha256=5OPkJFds2qNz3tydQxbY-bst7M_6wD_uqSSSErOQ25c,1243
52
+ procfunc/transforms/cleanup.py,sha256=aoilB72ZCkfa_0Q41PNC_P3ZeeziqMFVVCMdBp6tfso,6629
53
+ procfunc/transforms/convert.py,sha256=YdQEQp9qK6l9o7qGWPPHm4hFeJXgIaWNUkhHLjFCl2s,779
54
+ procfunc/transforms/distribution.py,sha256=kB85-XrLBDKb7MnYpjd816wLUinbrv77cVYLQLInZyE,6586
55
+ procfunc/transforms/extract_materials.py,sha256=hPjYoS5qghvKx75CcBcKVtyZOL07ukukkdFodDUThtM,3768
56
+ procfunc/transforms/infer_distribution.py,sha256=-AZP_H5YIU2sIn9nvasenrsQcrBKlGa3dCZTyz9aEGY,10642
57
+ procfunc/transforms/parameters.py,sha256=wRKzCKH6FKZTLRdrt8X9GN2JAOJH_r5V7H98eo72h_8,432
58
+ procfunc/transforms/util.py,sha256=D4fdLn0TfLmyLzosLnvyk7ElUKuHW2rVMJ_ytQmrwhk,1127
59
+ procfunc/transpiler/__init__.py,sha256=V_SvwphTm01awck4afJkI8v1jwbm66DR9jEZAEjpGyQ,451
60
+ procfunc/transpiler/bpy_to_computegraph.py,sha256=T-fOpRJYz_iVrH-9mC6w3Z5nKSRrTUcs5xkWqSgyBZ0,45369
61
+ procfunc/transpiler/codegen.py,sha256=HxIpcdaic-TusZ7NSKW4bIhOTXeRa_wIneKYgi9oa8k,30793
62
+ procfunc/transpiler/identifiers.py,sha256=F14q_tz2Mzl6HvdL5hoqVloyYY9dcyE1U9DXh-I30Lg,18715
63
+ procfunc/transpiler/main.py,sha256=eDlct7T-ad6gbncbr7zrjQdW8OyflR5FmWg13HBSP_8,8938
64
+ procfunc/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ procfunc/util/bpy_info.py,sha256=z2mRLgmYJalnBOXVJRjmbCf3HtDPa0sfdaG2FWUBDzA,3616
66
+ procfunc/util/camera.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ procfunc/util/keyframe.py,sha256=BkzvwlblstIR_HweCLnqbunnxyQKwbR83rf6W62E6Eo,2234
68
+ procfunc/util/log.py,sha256=Z8_FG0sLrbS6FP1GHuup4ZCdK01wLfkjCARz8t1xEjw,2513
69
+ procfunc/util/manifest.py,sha256=gHcwd6XA3SEsqTzds_9EK74DZY1RpZ1mqv6Z1Pc0Vt8,3857
70
+ procfunc/util/pytree.py,sha256=xz9rBQdYZWBpKG7jNirawnr3dE1O8pFEECk4EcMB3m4,10163
71
+ procfunc/util/teardown.py,sha256=tw9wxZxBdLvhf4v8PIiimKGR4vjH7IFpb2MIEllASAo,1151
72
+ procfunc-0.30.0.dist-info/licenses/LICENSE.md,sha256=rbHE2JmP9dBt-KDoOW-L6ezvPDvpKzlk5z3UNTngySk,1468
73
+ procfunc-0.30.0.dist-info/METADATA,sha256=hDaoy4V82m5fPy23rwjIqtH34KilKE9-jAw0OorSPRU,4383
74
+ procfunc-0.30.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
75
+ procfunc-0.30.0.dist-info/top_level.txt,sha256=VDI0XXM5U6uKHLV036b2k7PYhYEBNFtHuM5WyUp2RWU,9
76
+ procfunc-0.30.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,11 @@
1
+ Copyright 2026 Princeton University
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ procfunc