procfunc 0.30.0__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.30.0/LICENSE.md +11 -0
- procfunc-0.30.0/PKG-INFO +120 -0
- procfunc-0.30.0/README.md +97 -0
- procfunc-0.30.0/pyproject.toml +67 -0
- procfunc-0.30.0/setup.cfg +4 -0
- procfunc-0.30.0/src/procfunc/__init__.py +87 -0
- procfunc-0.30.0/src/procfunc/color.py +57 -0
- procfunc-0.30.0/src/procfunc/compute_graph/__init__.py +28 -0
- procfunc-0.30.0/src/procfunc/compute_graph/compute_graph.py +115 -0
- procfunc-0.30.0/src/procfunc/compute_graph/node.py +200 -0
- procfunc-0.30.0/src/procfunc/compute_graph/operators_info.py +92 -0
- procfunc-0.30.0/src/procfunc/compute_graph/proxy.py +173 -0
- procfunc-0.30.0/src/procfunc/compute_graph/util.py +282 -0
- procfunc-0.30.0/src/procfunc/context.py +115 -0
- procfunc-0.30.0/src/procfunc/control.py +174 -0
- procfunc-0.30.0/src/procfunc/nodes/__init__.py +66 -0
- procfunc-0.30.0/src/procfunc/nodes/bindings_util.py +196 -0
- procfunc-0.30.0/src/procfunc/nodes/bpy_node_info.py +280 -0
- procfunc-0.30.0/src/procfunc/nodes/compositor.py +2242 -0
- procfunc-0.30.0/src/procfunc/nodes/execute/construct_nodes.py +571 -0
- procfunc-0.30.0/src/procfunc/nodes/execute/construct_special_cases.py +246 -0
- procfunc-0.30.0/src/procfunc/nodes/execute/execute.py +548 -0
- procfunc-0.30.0/src/procfunc/nodes/execute/infer_runtime_data_type.py +195 -0
- procfunc-0.30.0/src/procfunc/nodes/execute/util.py +247 -0
- procfunc-0.30.0/src/procfunc/nodes/func.py +1417 -0
- procfunc-0.30.0/src/procfunc/nodes/geo.py +4240 -0
- procfunc-0.30.0/src/procfunc/nodes/manifest.json +8769 -0
- procfunc-0.30.0/src/procfunc/nodes/math.py +644 -0
- procfunc-0.30.0/src/procfunc/nodes/node_function.py +160 -0
- procfunc-0.30.0/src/procfunc/nodes/shader.py +2359 -0
- procfunc-0.30.0/src/procfunc/nodes/types.py +347 -0
- procfunc-0.30.0/src/procfunc/ops/__init__.py +35 -0
- procfunc-0.30.0/src/procfunc/ops/_util.py +275 -0
- procfunc-0.30.0/src/procfunc/ops/addons.py +59 -0
- procfunc-0.30.0/src/procfunc/ops/attr.py +426 -0
- procfunc-0.30.0/src/procfunc/ops/collection.py +90 -0
- procfunc-0.30.0/src/procfunc/ops/curve.py +18 -0
- procfunc-0.30.0/src/procfunc/ops/file.py +126 -0
- procfunc-0.30.0/src/procfunc/ops/manifest.json +39149 -0
- procfunc-0.30.0/src/procfunc/ops/mesh.py +1510 -0
- procfunc-0.30.0/src/procfunc/ops/modifier.py +603 -0
- procfunc-0.30.0/src/procfunc/ops/object.py +258 -0
- procfunc-0.30.0/src/procfunc/ops/primitives/__init__.py +31 -0
- procfunc-0.30.0/src/procfunc/ops/primitives/camera.py +45 -0
- procfunc-0.30.0/src/procfunc/ops/primitives/curve.py +71 -0
- procfunc-0.30.0/src/procfunc/ops/primitives/light.py +114 -0
- procfunc-0.30.0/src/procfunc/ops/primitives/mesh.py +358 -0
- procfunc-0.30.0/src/procfunc/ops/uv.py +271 -0
- procfunc-0.30.0/src/procfunc/random.py +247 -0
- procfunc-0.30.0/src/procfunc/tracer/__init__.py +43 -0
- procfunc-0.30.0/src/procfunc/tracer/decorator.py +121 -0
- procfunc-0.30.0/src/procfunc/tracer/patch.py +494 -0
- procfunc-0.30.0/src/procfunc/tracer/proxy.py +127 -0
- procfunc-0.30.0/src/procfunc/tracer/trace.py +222 -0
- procfunc-0.30.0/src/procfunc/transforms/__init__.py +49 -0
- procfunc-0.30.0/src/procfunc/transforms/cleanup.py +214 -0
- procfunc-0.30.0/src/procfunc/transforms/convert.py +20 -0
- procfunc-0.30.0/src/procfunc/transforms/distribution.py +191 -0
- procfunc-0.30.0/src/procfunc/transforms/extract_materials.py +116 -0
- procfunc-0.30.0/src/procfunc/transforms/infer_distribution.py +326 -0
- procfunc-0.30.0/src/procfunc/transforms/parameters.py +15 -0
- procfunc-0.30.0/src/procfunc/transforms/util.py +35 -0
- procfunc-0.30.0/src/procfunc/transpiler/__init__.py +24 -0
- procfunc-0.30.0/src/procfunc/transpiler/bpy_to_computegraph.py +1348 -0
- procfunc-0.30.0/src/procfunc/transpiler/codegen.py +919 -0
- procfunc-0.30.0/src/procfunc/transpiler/identifiers.py +595 -0
- procfunc-0.30.0/src/procfunc/transpiler/main.py +299 -0
- procfunc-0.30.0/src/procfunc/types.py +380 -0
- procfunc-0.30.0/src/procfunc/util/__init__.py +0 -0
- procfunc-0.30.0/src/procfunc/util/bpy_info.py +145 -0
- procfunc-0.30.0/src/procfunc/util/camera.py +0 -0
- procfunc-0.30.0/src/procfunc/util/keyframe.py +70 -0
- procfunc-0.30.0/src/procfunc/util/log.py +96 -0
- procfunc-0.30.0/src/procfunc/util/manifest.py +121 -0
- procfunc-0.30.0/src/procfunc/util/pytree.py +343 -0
- procfunc-0.30.0/src/procfunc/util/teardown.py +37 -0
- procfunc-0.30.0/src/procfunc.egg-info/PKG-INFO +120 -0
- procfunc-0.30.0/src/procfunc.egg-info/SOURCES.txt +85 -0
- procfunc-0.30.0/src/procfunc.egg-info/dependency_links.txt +1 -0
- procfunc-0.30.0/src/procfunc.egg-info/requires.txt +13 -0
- procfunc-0.30.0/src/procfunc.egg-info/top_level.txt +1 -0
- procfunc-0.30.0/tests/test_asset.py +228 -0
- procfunc-0.30.0/tests/test_compute_graph.py +63 -0
- procfunc-0.30.0/tests/test_dedup_names.py +18 -0
- procfunc-0.30.0/tests/test_ops.py +480 -0
- procfunc-0.30.0/tests/test_pytree.py +45 -0
- procfunc-0.30.0/tests/test_trace.py +142 -0
|
@@ -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.
|
procfunc-0.30.0/PKG-INFO
ADDED
|
@@ -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,97 @@
|
|
|
1
|
+
# ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python
|
|
2
|
+
|
|
3
|
+
[**Documentation**](#documentation)
|
|
4
|
+
| [**Research Paper**](#paper)
|
|
5
|
+
| [**Documentation**](#paper)
|
|
6
|
+
| [**Transpiling**](#transpile-a-blender-file-to-procfunc-code)
|
|
7
|
+
| [**Experiments**](#experiments)
|
|
8
|
+
| [**Contributing**](#contributing)
|
|
9
|
+
|
|
10
|
+
This repository contains only the Primitives API, Transpiler and Tracer from our research paper.
|
|
11
|
+
|
|
12
|
+
The pre-made procedural generators are coming soon as part of [infinigen](https://github.com/princeton-vl/infinigen).
|
|
13
|
+
|
|
14
|
+
### Installation
|
|
15
|
+
|
|
16
|
+
Use [uv](https://docs.astral.sh/uv/getting-started/installation/) or your favorite package manager to install procfunc via pip:
|
|
17
|
+
```bash
|
|
18
|
+
uv pip install procfunc
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Note: ProcFunc depends on `bpy==4.2.0` which then requires Python==3.11.x. Other version are not yet supported.
|
|
22
|
+
|
|
23
|
+
Since we have not yet reached [semver 1.0.0](https://semver.org/) we have not yet finalized procfunc's interface.
|
|
24
|
+
In the meantime, each 0.X.0 may introduce interface changes. Please pin `uv add procfunc<0.XX` where X is the current version.
|
|
25
|
+
|
|
26
|
+
### Usage
|
|
27
|
+
|
|
28
|
+
See [procfunc.readthedocs.io](https://procfunc.readthedocs.io) for available functions
|
|
29
|
+
|
|
30
|
+
Please create Github Issues for any bugs or unclear interfaces!
|
|
31
|
+
|
|
32
|
+
##### Transpile a blender file to ProcFunc code
|
|
33
|
+
|
|
34
|
+
<p float="left">
|
|
35
|
+
<img src="examples/transpile_simple_chair/blender_screenshot.png" height="200" />
|
|
36
|
+
<img src="examples/transpile_simple_chair/code_screenshot.png" height="200" />
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
Convert a Blender geometry node tree into procfunc Python code by downloading our example blend and executing the transpiler:
|
|
40
|
+
```bash
|
|
41
|
+
wget https://raw.githubusercontent.com/princeton-vl/procfunc/main/examples/transpile_simple_chair/simple_chair.blend
|
|
42
|
+
uv run python -m procfunc.transpiler.main simple_chair.blend --node_trees simple_chair --output transpiled_code.py
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See the expected output in [`examples/transpile_simple_chair/transpiled_code.py`](examples/transpile_simple_chair/transpiled_code.py).
|
|
46
|
+
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.
|
|
47
|
+
You can also open and edit the blender geonodes prior to transpiling in order to generate different procfunc code.
|
|
48
|
+
|
|
49
|
+
### Paper
|
|
50
|
+
|
|
51
|
+
If you find procfunc useful, please cite our paper:
|
|
52
|
+
```
|
|
53
|
+
@misc{raistrick2026procfunc,
|
|
54
|
+
title={ProcFunc: Function-Oriented Abstractions for Procedural 3D Generation in Python},
|
|
55
|
+
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},
|
|
56
|
+
year={2026},
|
|
57
|
+
eprint={2604.26943},
|
|
58
|
+
archivePrefix={arXiv},
|
|
59
|
+
primaryClass={cs.CV},
|
|
60
|
+
url={https://arxiv.org/abs/2604.26943},
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Experiments
|
|
65
|
+
|
|
66
|
+
See [experiments/EXPERIMENTS.md](experiments/EXPERIMENTS.md)
|
|
67
|
+
|
|
68
|
+
NOTE: experiments are only intended to be correct when using the `experiments` branch, which will not see major updates.
|
|
69
|
+
|
|
70
|
+
### Contributing
|
|
71
|
+
|
|
72
|
+
Please create an issue for any proposed features to discuss them before implementing.
|
|
73
|
+
|
|
74
|
+
##### Developer Installation
|
|
75
|
+
```bash
|
|
76
|
+
git clone git@github.com:princeton-vl/procfunc.git
|
|
77
|
+
cd procfunc
|
|
78
|
+
uv venv
|
|
79
|
+
uv pip install -e ".[dev]"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
##### Tools
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv run ruff format
|
|
86
|
+
uv run ruff check --fix
|
|
87
|
+
uv run pytest
|
|
88
|
+
make docs
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
##### Todos / Sharp Edges
|
|
92
|
+
|
|
93
|
+
Add optional support for bpy==4.x and 5.x and maybe 3.6, all under the same procfunc interface.
|
|
94
|
+
|
|
95
|
+
pf.ops is missing some blender functions and arguments, especially returning "selection" masks for some cases.
|
|
96
|
+
|
|
97
|
+
Assets like pf.MeshObject and pf.Material are not currently cleaned up upon going out of scope
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "procfunc"
|
|
7
|
+
version = "0.30.0"
|
|
8
|
+
description = "A framework for compositional procedural generation"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "BSD-3-Clause"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"bpy==4.2.0",
|
|
14
|
+
"numpy<2",
|
|
15
|
+
"pandas",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://github.com/princeton-vl/procfunc"
|
|
20
|
+
Repository = "https://github.com/princeton-vl/procfunc"
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
dev = [
|
|
24
|
+
"pytest",
|
|
25
|
+
"pytest-xdist",
|
|
26
|
+
"ruff>=0.15,<0.16",
|
|
27
|
+
"ty"
|
|
28
|
+
]
|
|
29
|
+
docs = [
|
|
30
|
+
"sphinx",
|
|
31
|
+
"sphinx-rtd-theme",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["src"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.package-data]
|
|
38
|
+
procfunc = ["**/*.json"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = "tests"
|
|
42
|
+
|
|
43
|
+
[tool.ruff]
|
|
44
|
+
exclude = ["examples", "experiments"]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
|
|
48
|
+
select = [
|
|
49
|
+
"E",
|
|
50
|
+
"I",
|
|
51
|
+
"F",
|
|
52
|
+
"S102", # no exec(),
|
|
53
|
+
"TID251", # custom banned imports
|
|
54
|
+
"TID252", # relative imports only allowed for siblings
|
|
55
|
+
|
|
56
|
+
]
|
|
57
|
+
ignore = [
|
|
58
|
+
"E501", # over-length lines, formatter should handle it
|
|
59
|
+
"E741", # ambigous variable name
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint.per-file-ignores]
|
|
63
|
+
"__init__.py" = ["F401"]
|
|
64
|
+
|
|
65
|
+
[tool.ty.rules]
|
|
66
|
+
unresolved-import = "ignore"
|
|
67
|
+
unresolved-attribute = "ignore"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ruff: noqa: I001, F401
|
|
2
|
+
# ensure this gets imported first so that mathutils etc is available even if later modules dont import bpy
|
|
3
|
+
import bpy
|
|
4
|
+
|
|
5
|
+
__version__ = "0.30.0"
|
|
6
|
+
|
|
7
|
+
from numpy.random import Generator as RNG
|
|
8
|
+
|
|
9
|
+
# ensure these are always imported first and in the right order
|
|
10
|
+
import bpy as _bpy
|
|
11
|
+
import mathutils as _mu
|
|
12
|
+
|
|
13
|
+
from . import (
|
|
14
|
+
compute_graph,
|
|
15
|
+
control,
|
|
16
|
+
nodes,
|
|
17
|
+
ops,
|
|
18
|
+
random,
|
|
19
|
+
tracer,
|
|
20
|
+
util,
|
|
21
|
+
context,
|
|
22
|
+
color,
|
|
23
|
+
transforms,
|
|
24
|
+
)
|
|
25
|
+
from .types import (
|
|
26
|
+
Vector,
|
|
27
|
+
Color,
|
|
28
|
+
Euler,
|
|
29
|
+
Quaternion,
|
|
30
|
+
Matrix,
|
|
31
|
+
BVHTree,
|
|
32
|
+
Object,
|
|
33
|
+
CameraObject,
|
|
34
|
+
MeshObject,
|
|
35
|
+
CurveObject,
|
|
36
|
+
VolumeObject,
|
|
37
|
+
EmptyObject,
|
|
38
|
+
ArmatureObject,
|
|
39
|
+
HairObject,
|
|
40
|
+
LatticeObject,
|
|
41
|
+
LightObject,
|
|
42
|
+
LightProbeObject,
|
|
43
|
+
MetaObject,
|
|
44
|
+
Material,
|
|
45
|
+
Texture,
|
|
46
|
+
Collection,
|
|
47
|
+
Image,
|
|
48
|
+
ViewLayer,
|
|
49
|
+
Asset,
|
|
50
|
+
World,
|
|
51
|
+
)
|
|
52
|
+
from .nodes import ProcNode, Shader, NodeDataType
|
|
53
|
+
from .tracer import trace, autowrap_module, add_search_scope
|
|
54
|
+
from .util.manifest import module_path
|
|
55
|
+
|
|
56
|
+
autowrap_module(random)
|
|
57
|
+
autowrap_module(color)
|
|
58
|
+
add_search_scope(nodes)
|
|
59
|
+
add_search_scope(ops)
|
|
60
|
+
|
|
61
|
+
__all__ = [
|
|
62
|
+
# Subpackages
|
|
63
|
+
"compute_graph",
|
|
64
|
+
"control",
|
|
65
|
+
"context",
|
|
66
|
+
"color",
|
|
67
|
+
"nodes",
|
|
68
|
+
"ops",
|
|
69
|
+
"random",
|
|
70
|
+
"tracer",
|
|
71
|
+
"transforms",
|
|
72
|
+
"util",
|
|
73
|
+
# Node graph primitives
|
|
74
|
+
"ProcNode",
|
|
75
|
+
"Shader",
|
|
76
|
+
"NodeDataType",
|
|
77
|
+
# Tracing entrypoints
|
|
78
|
+
"trace",
|
|
79
|
+
# Utilities
|
|
80
|
+
"RNG",
|
|
81
|
+
"module_path",
|
|
82
|
+
# NOTE: Blender wrapper types (Object, MeshObject, Material, Texture, ...)
|
|
83
|
+
# are re-exported above for convenience but live in procfunc.types — see
|
|
84
|
+
# that page for documentation. Blender/mathutils re-exports (Vector, Color,
|
|
85
|
+
# Euler, Quaternion, Matrix, BVHTree, NodeGroup, Scene, ViewLayer) are
|
|
86
|
+
# likewise kept importable but documented upstream by Blender.
|
|
87
|
+
]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from procfunc import types as t
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def hsv_color(
|
|
7
|
+
hsv: np.ndarray | tuple | None = None,
|
|
8
|
+
*,
|
|
9
|
+
hue: float | None = None,
|
|
10
|
+
saturation: float | None = None,
|
|
11
|
+
value: float | None = None,
|
|
12
|
+
) -> t.Color:
|
|
13
|
+
color = t.Color()
|
|
14
|
+
if hsv is not None:
|
|
15
|
+
color.hsv = hsv
|
|
16
|
+
else:
|
|
17
|
+
color.hsv = (hue, saturation, value)
|
|
18
|
+
return color
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
hsv_to_rgba = hsv_color
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def rgb_color(
|
|
25
|
+
r: float | None = None,
|
|
26
|
+
g: float | None = None,
|
|
27
|
+
b: float | None = None,
|
|
28
|
+
rgb: np.ndarray | None = None,
|
|
29
|
+
) -> t.Color:
|
|
30
|
+
color = t.Color()
|
|
31
|
+
if rgb is not None:
|
|
32
|
+
color.r, color.g, color.b = rgb
|
|
33
|
+
else:
|
|
34
|
+
color.r, color.g, color.b = r, g, b
|
|
35
|
+
return color
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _srgb_to_linearrgb(c):
|
|
39
|
+
if c < 0:
|
|
40
|
+
return 0
|
|
41
|
+
elif c < 0.04045:
|
|
42
|
+
return c / 12.92
|
|
43
|
+
else:
|
|
44
|
+
return ((c + 0.055) / 1.055) ** 2.4
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _hex_to_rgb(h: int, alpha: float = 1):
|
|
48
|
+
r = (h & 0xFF0000) >> 16
|
|
49
|
+
g = (h & 0x00FF00) >> 8
|
|
50
|
+
b = h & 0x0000FF
|
|
51
|
+
return tuple([_srgb_to_linearrgb(c / 0xFF) for c in (r, g, b)])
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def hex_color(h: int, alpha: float = 1):
|
|
55
|
+
c = t.Color()
|
|
56
|
+
c.r, c.g, c.b = _hex_to_rgb(h, alpha)
|
|
57
|
+
return c
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .compute_graph import (
|
|
2
|
+
ComputeGraph,
|
|
3
|
+
)
|
|
4
|
+
from .node import (
|
|
5
|
+
ConstantNode,
|
|
6
|
+
FunctionCallNode,
|
|
7
|
+
GetAttributeNode,
|
|
8
|
+
InputPlaceholderNode,
|
|
9
|
+
MethodCallNode,
|
|
10
|
+
MutatedArgumentNode,
|
|
11
|
+
Node,
|
|
12
|
+
ProceduralNode,
|
|
13
|
+
SubgraphCallNode,
|
|
14
|
+
normalize_args_to_kwargs,
|
|
15
|
+
)
|
|
16
|
+
from .operators_info import OperatorType
|
|
17
|
+
from .proxy import AttributeProxy, Proxy
|
|
18
|
+
from .util import (
|
|
19
|
+
LiteralConstant,
|
|
20
|
+
graph_nodes_equal,
|
|
21
|
+
transform_compute_graph,
|
|
22
|
+
transform_nodetree,
|
|
23
|
+
traverse_breadth_first,
|
|
24
|
+
traverse_depth_first,
|
|
25
|
+
traverse_depth_first_node,
|
|
26
|
+
traverse_nested_graphs,
|
|
27
|
+
usages_per_node,
|
|
28
|
+
)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import logging
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from procfunc.util.pytree import PyTree
|
|
7
|
+
|
|
8
|
+
from .node import Node
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _evaluate_node(node: Node) -> Any:
|
|
14
|
+
if node.result is not None:
|
|
15
|
+
return node.result
|
|
16
|
+
|
|
17
|
+
for arg in itertools.chain(node.args, node.kwargs.values()):
|
|
18
|
+
if isinstance(arg, Node):
|
|
19
|
+
arg.result = _evaluate_node(arg)
|
|
20
|
+
|
|
21
|
+
arg_eval, kwarg_eval = node.inputs.map(
|
|
22
|
+
lambda x: x.result if isinstance(x, Node) else x
|
|
23
|
+
).obj()
|
|
24
|
+
|
|
25
|
+
# match node:
|
|
26
|
+
# case cg.FunctionCallNode:
|
|
27
|
+
# return node.func(*arg_vals, **kwarg_vals)
|
|
28
|
+
# case cg.PlaceholderNode:
|
|
29
|
+
# raise NotImplementedError(
|
|
30
|
+
# f"Placeholder {node!r} or '<unnamed>'} should not be evaluated - "
|
|
31
|
+
# "its .result should be populated in advance"
|
|
32
|
+
# )
|
|
33
|
+
# case cg.MutatedArgumentNode:
|
|
34
|
+
# # Evaluate the mutation call first (for side effects), then return the original object
|
|
35
|
+
# mutation_call_node = node.args[1]
|
|
36
|
+
# _evaluate_node(mutation_call_node)
|
|
37
|
+
# return (
|
|
38
|
+
# node.args[0].result if isinstance(node.args[0], Node) else node.args[0]
|
|
39
|
+
# )
|
|
40
|
+
# case _:
|
|
41
|
+
# raise NotImplementedError(f"Unsupported node operation: {node.kind}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _clear_node_results(node: Node):
|
|
45
|
+
node.result = None
|
|
46
|
+
for arg in itertools.chain(node.args, node.kwargs.values()):
|
|
47
|
+
if isinstance(arg, Node) and arg.result is not None:
|
|
48
|
+
_clear_node_results(arg)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class ComputeGraph:
|
|
53
|
+
inputs: PyTree[Any, Node]
|
|
54
|
+
outputs: PyTree[Any, Node]
|
|
55
|
+
name: str
|
|
56
|
+
metadata: dict[str, Any]
|
|
57
|
+
|
|
58
|
+
def __post_init__(self):
|
|
59
|
+
# input_names = set(self.inputs.names())
|
|
60
|
+
# if len(input_names) != len(set(input_names)):
|
|
61
|
+
# raise ValueError(f"Input names had duplicates: {input_names}")
|
|
62
|
+
|
|
63
|
+
# output_names = set(self.outputs.names())
|
|
64
|
+
# if len(output_names) != len(set(output_names)):
|
|
65
|
+
# raise ValueError(f"Output names had duplicates: {output_names}")
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
def __repr__(self):
|
|
69
|
+
return f"{self.__class__.__name__}({self.name!r})"
|
|
70
|
+
|
|
71
|
+
def clear_values(self):
|
|
72
|
+
for node in self.outputs.values():
|
|
73
|
+
_clear_node_results(node)
|
|
74
|
+
|
|
75
|
+
def __call__(
|
|
76
|
+
self,
|
|
77
|
+
*args,
|
|
78
|
+
allow_clear: bool = True,
|
|
79
|
+
**kwargs,
|
|
80
|
+
):
|
|
81
|
+
"""
|
|
82
|
+
Execute the compute graph. If this graph came from a tracer,
|
|
83
|
+
this should be exactly equivelant to executing the original python function.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
raise NotImplementedError("Not implemented")
|
|
87
|
+
|
|
88
|
+
if len(args) != len(self.inputs):
|
|
89
|
+
raise ValueError(f"Expected {len(self.inputs)} arguments, got {len(args)}")
|
|
90
|
+
|
|
91
|
+
if allow_clear:
|
|
92
|
+
self.clear_values()
|
|
93
|
+
|
|
94
|
+
extra_kwargs = self.kwarg_nodes.keys() - kwargs.keys()
|
|
95
|
+
if extra_kwargs:
|
|
96
|
+
raise ValueError(
|
|
97
|
+
f"{self.__class__.__name__} {self.name!r} got unexpected keyword arguments: {extra_kwargs}"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
missing_kwargs = kwargs.keys() - self.kwarg_nodes.keys()
|
|
101
|
+
if missing_kwargs:
|
|
102
|
+
raise ValueError(
|
|
103
|
+
f"{self.__class__.__name__} {self.name!r} had missing keyword arguments: {missing_kwargs}"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
for arg, arg_node in zip(args, self.arg_nodes):
|
|
107
|
+
arg_node.result = arg
|
|
108
|
+
|
|
109
|
+
for k, v in kwargs.items():
|
|
110
|
+
self.kwarg_nodes[k].result = v
|
|
111
|
+
|
|
112
|
+
for node in self.outputs.values():
|
|
113
|
+
_evaluate_node(node)
|
|
114
|
+
|
|
115
|
+
return {name: node.result for name, node in self.outputs.items()}
|