zer0one-cinema 0.1.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.
- zer0one_cinema-0.1.0/LICENSE +21 -0
- zer0one_cinema-0.1.0/PKG-INFO +235 -0
- zer0one_cinema-0.1.0/README.md +198 -0
- zer0one_cinema-0.1.0/pyproject.toml +100 -0
- zer0one_cinema-0.1.0/setup.cfg +4 -0
- zer0one_cinema-0.1.0/tests/test_smoke.py +8 -0
- zer0one_cinema-0.1.0/zer0one_cinema/__init__.py +7 -0
- zer0one_cinema-0.1.0/zer0one_cinema/context.py +64 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/PKG-INFO +235 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/SOURCES.txt +12 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/dependency_links.txt +1 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/entry_points.txt +2 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/requires.txt +17 -0
- zer0one_cinema-0.1.0/zer0one_cinema.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 0xxCool
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zer0one-cinema
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic cinema-grade rendering automation for Blender: GLB in, movie out.
|
|
5
|
+
Author-email: ZER0ONELAB <michael@zer0one.codes>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://zer0onelab.com/cinema
|
|
8
|
+
Project-URL: Repository, https://github.com/0xxCool/zer0one-cinema
|
|
9
|
+
Project-URL: Issues, https://github.com/0xxCool/zer0one-cinema/issues
|
|
10
|
+
Keywords: blender,rendering,3d,cinema,automation,cycles,cli
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=1.26
|
|
22
|
+
Requires-Dist: pillow>=10.0
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Requires-Dist: click>=8.1
|
|
25
|
+
Requires-Dist: scikit-learn>=1.5
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
31
|
+
Requires-Dist: types-pyyaml; extra == "dev"
|
|
32
|
+
Requires-Dist: types-pillow; extra == "dev"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
35
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == "docs"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# zer0one-cinema
|
|
39
|
+
|
|
40
|
+
**Deterministic cinema-grade rendering automation for Blender.**
|
|
41
|
+
GLB in, movie out — no manual scene setup, no per-model tweaking, no subscription tools required.
|
|
42
|
+
|
|
43
|
+
> **Status:** v0.1 model-prep layer implemented, real-Blender verified on 2 vehicle GLBs.
|
|
44
|
+
> Follow [releases](https://github.com/0xxCool/zer0one-cinema/releases) or
|
|
45
|
+
> [zer0onelab.com/cinema](https://zer0onelab.com/cinema) for progress.
|
|
46
|
+
|
|
47
|
+
[](https://github.com/0xxCool/zer0one-cinema/actions/workflows/ci.yml)
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## The problem this solves
|
|
53
|
+
|
|
54
|
+
Take any 3D vehicle model from Sketchfab, throw it into Blender, run Cycles — you get a bland turntable. To get an *automotive-trailer look* (Ford v Ferrari, NfS Heat, Gran Turismo) you need:
|
|
55
|
+
|
|
56
|
+
- Wheels detected and rigged at their real rotation center (not the GLB's random origin)
|
|
57
|
+
- Body on the ground, not floating or sunk
|
|
58
|
+
- Lighting that flatters the paint (rim light for silhouette, key/fill balance)
|
|
59
|
+
- Camera framing that respects Rule-of-Thirds and doesn't clip parts of the car
|
|
60
|
+
- Post-processing (grading, DoF, motion blur, chromatic aberration, film grain)
|
|
61
|
+
- Verification that every rendered frame actually meets those standards
|
|
62
|
+
|
|
63
|
+
Today this takes a 3D artist several days of manual work per model. `zer0one-cinema` will do it in one CLI command:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
zocinema render my_car.glb --look studio_night_neon --camera push_in --output trailer.mp4
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**v0.1 ships the first stage of that pipeline** — deterministic model preparation:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
zocinema model-prep my_car.glb --output my_car_prepped.blend --report report.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The full render pipeline lands in v0.3.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Quickstart (v0.1)
|
|
80
|
+
|
|
81
|
+
Model-prep is a Blender-Python operation — it needs Blender 4.2+ installed. Full render
|
|
82
|
+
pipeline (v0.3+) will also work as a standalone pip install.
|
|
83
|
+
|
|
84
|
+
### 1. Install Blender 4.2 LTS
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Download the official tarball (avoid distro packages — many miss the Draco decoder)
|
|
88
|
+
wget https://download.blender.org/release/Blender4.2/blender-4.2.11-linux-x64.tar.xz
|
|
89
|
+
tar -xf blender-4.2.11-linux-x64.tar.xz -C ~/opt/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Install zer0one-cinema
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Into Blender's bundled Python:
|
|
96
|
+
~/opt/blender-4.2.11-linux-x64/4.2/python/bin/python3.11 -m pip install --user \
|
|
97
|
+
click numpy pillow pyyaml scikit-learn
|
|
98
|
+
|
|
99
|
+
# Clone the repo (PyPI upload will come with v0.1.0 release tag):
|
|
100
|
+
git clone https://github.com/0xxCool/zer0one-cinema ~/zer0one-cinema
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Prepare a GLB
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
BLENDER=~/opt/blender-4.2.11-linux-x64/blender
|
|
107
|
+
cd ~/zer0one-cinema
|
|
108
|
+
|
|
109
|
+
"$BLENDER" -b -P scripts/run_zocinema.py -- model-prep \
|
|
110
|
+
/path/to/car.glb \
|
|
111
|
+
--output out.blend \
|
|
112
|
+
--report report.json \
|
|
113
|
+
--seed 0
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Real example on `kenney_sedan.glb`** (part of our test-suite):
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
[1/7] Loading kenney_sedan.glb...
|
|
120
|
+
→ 5 meshes, 3184 vertices, 0.13s
|
|
121
|
+
[2/7] Ground-anchoring...
|
|
122
|
+
→ z_shift = 0.0000 m, moved 0 objects
|
|
123
|
+
[3/7] Detecting wheels...
|
|
124
|
+
→ 4 wheels: FL, FR, RL, RR (confidence 0.90)
|
|
125
|
+
[4/7] Re-origining wheels...
|
|
126
|
+
→ moved 0 origins, skipped 0 already-centered
|
|
127
|
+
[5/7] Building body group...
|
|
128
|
+
→ 1 body meshes (excluded 4 wheel + 0 env)
|
|
129
|
+
[6/7] Sanitizing materials...
|
|
130
|
+
→ 1 materials analyzed, 1 changed
|
|
131
|
+
[7/7] Saving out.blend...
|
|
132
|
+
✓ Done in 2.5s
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The output `.blend` file is fully-rigged: wheels have their origins at the axle
|
|
136
|
+
centers (so `wheel.rotation_euler.x -= radians(360)` spins them in place instead of
|
|
137
|
+
throwing them off the car), the body is grounded to z=0, materials are normalized
|
|
138
|
+
to sane PBR values (car-paint clearcoat, chrome metallic, etc.). Deterministic —
|
|
139
|
+
same GLB + same seed → byte-identical output.
|
|
140
|
+
|
|
141
|
+
**Read the report:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python3 -m json.tool report.json
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## What v0.1 supports
|
|
150
|
+
|
|
151
|
+
- **Wheel detection** for typical 4-wheeled cars, SUVs, trucks, monster-trucks (wheelbase-to-wheel-diameter ratio 0.03 – 0.50)
|
|
152
|
+
- **Ground anchor** — vehicle's lowest point placed at world z=0
|
|
153
|
+
- **Origin fix** — wheel object-origins moved to axle centers (so rotation animations work)
|
|
154
|
+
- **Body group** — non-wheel meshes grouped with a centroid for later body-roll/pitch animation
|
|
155
|
+
- **Material sanitize** — 12-class PBR classifier (car-paint, chrome, glass, tire, brake, carbon-fiber, headlight, taillight, rim-alloy, interior-plastic, leather-seat, unknown → default-plastic). Whitelist-based: unknowns pass through untouched. Hard fixes for the two most common Sketchfab bugs (emission accidentally set on body, alpha=0.99 instead of 1.0).
|
|
156
|
+
|
|
157
|
+
## What v0.1 does NOT support (yet)
|
|
158
|
+
|
|
159
|
+
- **Merged-mesh GLBs** — models exported as one giant mesh with no separate wheel objects. Common on old CAD-export or single-artist Sketchfab uploads (e.g. `khronos_toy_car.glb`). Sub-mesh splitting via connected-components arrives in v0.2.
|
|
160
|
+
- **Rendering** — v0.1 is model-prep only. Cinema-grade renders (Cycles + preset library) come in v0.3.
|
|
161
|
+
- **Preflight / verify** — automatic frame-QA is v0.2.
|
|
162
|
+
- **Non-vehicle models** — characters, architecture, product-vis need their own detection heuristics (v1.2+).
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Design principles
|
|
167
|
+
|
|
168
|
+
1. **Deterministic.** Same GLB + same preset → byte-identical output. K-Means uses `random_state=0, n_init=1` with lexicographically-sorted inputs.
|
|
169
|
+
2. **Open source.** MIT license. Core is free forever. Premium look library (v0.3+) is a separate paid add-on.
|
|
170
|
+
3. **No proprietary dependencies.** Blender / Python / numpy / scikit-learn / FFmpeg — no Adobe / Substance / KeyShot / Marmoset subscription required.
|
|
171
|
+
4. **Every frame verified.** The 6-gate cinema-grade verification framework (v0.2) runs on every render — bad frames are flagged, not shipped.
|
|
172
|
+
5. **Testable without Blender.** All model-prep modules work against pure-Python protocols (`MeshLike`, `MaterialLike`, `MutableObject`). Unit tests use numpy-only mocks — no `bpy` required. 140 tests in the current suite.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Architecture
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
GLB → Model-Prep → Preflight → Preset-Apply → Render → Post → Verify → Delivery
|
|
180
|
+
[v0.1 ✓] (v0.2) (v0.3) (v0.3) (v0.3) (v0.2) (v0.3)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Each stage is an independent Python package with a stable interface. Compose your own pipelines.
|
|
184
|
+
Full architecture: [docs/architecture.md](docs/architecture.md).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Roadmap
|
|
189
|
+
|
|
190
|
+
- **v0.1** ✓ — Model-Prep Core (wheel detection, origin fix, ground anchor, body group, material sanitize)
|
|
191
|
+
- **v0.2** — Preflight & Verify (test frame + 6-gate verification + auto-fix loop)
|
|
192
|
+
- **v0.3** — Preset Library (5 looks × 5 cameras) + Cycles rendering
|
|
193
|
+
- **v0.4** — CLI + Blender Addon + Docker Serverless
|
|
194
|
+
- **v0.5** — Public Launch (landing page + 3–5 case studies)
|
|
195
|
+
- **v1.0** — First customer case study live on zer0onelab.com
|
|
196
|
+
|
|
197
|
+
Full roadmap: [docs/roadmap.md](docs/roadmap.md).
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
git clone https://github.com/0xxCool/zer0one-cinema
|
|
205
|
+
cd zer0one-cinema
|
|
206
|
+
python3.11 -m venv .venv
|
|
207
|
+
source .venv/bin/activate
|
|
208
|
+
pip install -e ".[dev]"
|
|
209
|
+
pytest tests/ # 140 tests, ~5s
|
|
210
|
+
ruff check zer0one_cinema tests
|
|
211
|
+
mypy zer0one_cinema
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Real-Blender integration testing needs the runner script:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
~/opt/blender-4.2/blender -b -P scripts/run_zocinema.py -- \
|
|
218
|
+
model-prep tests/glb_fixtures/kenney_sedan.glb --output /tmp/out.blend
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Test-fixture GLBs (not in the repo — see [tests/glb_fixtures/README.md](tests/glb_fixtures/README.md) for reproduction).
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Contributing
|
|
226
|
+
|
|
227
|
+
Not accepting external contributions yet — waiting for v0.3 (public launch) to stabilize the interface. **Bug reports welcome** as GitHub Issues, especially for new GLB structures that the wheel-detection Stage 2 filter rejects (paste the output of `scripts/debug_candidates.py`).
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT — see [LICENSE](LICENSE).
|
|
232
|
+
|
|
233
|
+
## Who's behind this
|
|
234
|
+
|
|
235
|
+
Built by [ZER0ONELAB](https://zer0onelab.com) as part of our cloud-render platform for DACH studios doing brand work. If you need cinema-grade renders at scale without doing the engineering yourself, we're the delivery layer.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# zer0one-cinema
|
|
2
|
+
|
|
3
|
+
**Deterministic cinema-grade rendering automation for Blender.**
|
|
4
|
+
GLB in, movie out — no manual scene setup, no per-model tweaking, no subscription tools required.
|
|
5
|
+
|
|
6
|
+
> **Status:** v0.1 model-prep layer implemented, real-Blender verified on 2 vehicle GLBs.
|
|
7
|
+
> Follow [releases](https://github.com/0xxCool/zer0one-cinema/releases) or
|
|
8
|
+
> [zer0onelab.com/cinema](https://zer0onelab.com/cinema) for progress.
|
|
9
|
+
|
|
10
|
+
[](https://github.com/0xxCool/zer0one-cinema/actions/workflows/ci.yml)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## The problem this solves
|
|
16
|
+
|
|
17
|
+
Take any 3D vehicle model from Sketchfab, throw it into Blender, run Cycles — you get a bland turntable. To get an *automotive-trailer look* (Ford v Ferrari, NfS Heat, Gran Turismo) you need:
|
|
18
|
+
|
|
19
|
+
- Wheels detected and rigged at their real rotation center (not the GLB's random origin)
|
|
20
|
+
- Body on the ground, not floating or sunk
|
|
21
|
+
- Lighting that flatters the paint (rim light for silhouette, key/fill balance)
|
|
22
|
+
- Camera framing that respects Rule-of-Thirds and doesn't clip parts of the car
|
|
23
|
+
- Post-processing (grading, DoF, motion blur, chromatic aberration, film grain)
|
|
24
|
+
- Verification that every rendered frame actually meets those standards
|
|
25
|
+
|
|
26
|
+
Today this takes a 3D artist several days of manual work per model. `zer0one-cinema` will do it in one CLI command:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
zocinema render my_car.glb --look studio_night_neon --camera push_in --output trailer.mp4
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**v0.1 ships the first stage of that pipeline** — deterministic model preparation:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
zocinema model-prep my_car.glb --output my_car_prepped.blend --report report.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The full render pipeline lands in v0.3.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quickstart (v0.1)
|
|
43
|
+
|
|
44
|
+
Model-prep is a Blender-Python operation — it needs Blender 4.2+ installed. Full render
|
|
45
|
+
pipeline (v0.3+) will also work as a standalone pip install.
|
|
46
|
+
|
|
47
|
+
### 1. Install Blender 4.2 LTS
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Download the official tarball (avoid distro packages — many miss the Draco decoder)
|
|
51
|
+
wget https://download.blender.org/release/Blender4.2/blender-4.2.11-linux-x64.tar.xz
|
|
52
|
+
tar -xf blender-4.2.11-linux-x64.tar.xz -C ~/opt/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Install zer0one-cinema
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Into Blender's bundled Python:
|
|
59
|
+
~/opt/blender-4.2.11-linux-x64/4.2/python/bin/python3.11 -m pip install --user \
|
|
60
|
+
click numpy pillow pyyaml scikit-learn
|
|
61
|
+
|
|
62
|
+
# Clone the repo (PyPI upload will come with v0.1.0 release tag):
|
|
63
|
+
git clone https://github.com/0xxCool/zer0one-cinema ~/zer0one-cinema
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. Prepare a GLB
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
BLENDER=~/opt/blender-4.2.11-linux-x64/blender
|
|
70
|
+
cd ~/zer0one-cinema
|
|
71
|
+
|
|
72
|
+
"$BLENDER" -b -P scripts/run_zocinema.py -- model-prep \
|
|
73
|
+
/path/to/car.glb \
|
|
74
|
+
--output out.blend \
|
|
75
|
+
--report report.json \
|
|
76
|
+
--seed 0
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Real example on `kenney_sedan.glb`** (part of our test-suite):
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
[1/7] Loading kenney_sedan.glb...
|
|
83
|
+
→ 5 meshes, 3184 vertices, 0.13s
|
|
84
|
+
[2/7] Ground-anchoring...
|
|
85
|
+
→ z_shift = 0.0000 m, moved 0 objects
|
|
86
|
+
[3/7] Detecting wheels...
|
|
87
|
+
→ 4 wheels: FL, FR, RL, RR (confidence 0.90)
|
|
88
|
+
[4/7] Re-origining wheels...
|
|
89
|
+
→ moved 0 origins, skipped 0 already-centered
|
|
90
|
+
[5/7] Building body group...
|
|
91
|
+
→ 1 body meshes (excluded 4 wheel + 0 env)
|
|
92
|
+
[6/7] Sanitizing materials...
|
|
93
|
+
→ 1 materials analyzed, 1 changed
|
|
94
|
+
[7/7] Saving out.blend...
|
|
95
|
+
✓ Done in 2.5s
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The output `.blend` file is fully-rigged: wheels have their origins at the axle
|
|
99
|
+
centers (so `wheel.rotation_euler.x -= radians(360)` spins them in place instead of
|
|
100
|
+
throwing them off the car), the body is grounded to z=0, materials are normalized
|
|
101
|
+
to sane PBR values (car-paint clearcoat, chrome metallic, etc.). Deterministic —
|
|
102
|
+
same GLB + same seed → byte-identical output.
|
|
103
|
+
|
|
104
|
+
**Read the report:**
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
python3 -m json.tool report.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## What v0.1 supports
|
|
113
|
+
|
|
114
|
+
- **Wheel detection** for typical 4-wheeled cars, SUVs, trucks, monster-trucks (wheelbase-to-wheel-diameter ratio 0.03 – 0.50)
|
|
115
|
+
- **Ground anchor** — vehicle's lowest point placed at world z=0
|
|
116
|
+
- **Origin fix** — wheel object-origins moved to axle centers (so rotation animations work)
|
|
117
|
+
- **Body group** — non-wheel meshes grouped with a centroid for later body-roll/pitch animation
|
|
118
|
+
- **Material sanitize** — 12-class PBR classifier (car-paint, chrome, glass, tire, brake, carbon-fiber, headlight, taillight, rim-alloy, interior-plastic, leather-seat, unknown → default-plastic). Whitelist-based: unknowns pass through untouched. Hard fixes for the two most common Sketchfab bugs (emission accidentally set on body, alpha=0.99 instead of 1.0).
|
|
119
|
+
|
|
120
|
+
## What v0.1 does NOT support (yet)
|
|
121
|
+
|
|
122
|
+
- **Merged-mesh GLBs** — models exported as one giant mesh with no separate wheel objects. Common on old CAD-export or single-artist Sketchfab uploads (e.g. `khronos_toy_car.glb`). Sub-mesh splitting via connected-components arrives in v0.2.
|
|
123
|
+
- **Rendering** — v0.1 is model-prep only. Cinema-grade renders (Cycles + preset library) come in v0.3.
|
|
124
|
+
- **Preflight / verify** — automatic frame-QA is v0.2.
|
|
125
|
+
- **Non-vehicle models** — characters, architecture, product-vis need their own detection heuristics (v1.2+).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Design principles
|
|
130
|
+
|
|
131
|
+
1. **Deterministic.** Same GLB + same preset → byte-identical output. K-Means uses `random_state=0, n_init=1` with lexicographically-sorted inputs.
|
|
132
|
+
2. **Open source.** MIT license. Core is free forever. Premium look library (v0.3+) is a separate paid add-on.
|
|
133
|
+
3. **No proprietary dependencies.** Blender / Python / numpy / scikit-learn / FFmpeg — no Adobe / Substance / KeyShot / Marmoset subscription required.
|
|
134
|
+
4. **Every frame verified.** The 6-gate cinema-grade verification framework (v0.2) runs on every render — bad frames are flagged, not shipped.
|
|
135
|
+
5. **Testable without Blender.** All model-prep modules work against pure-Python protocols (`MeshLike`, `MaterialLike`, `MutableObject`). Unit tests use numpy-only mocks — no `bpy` required. 140 tests in the current suite.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Architecture
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
GLB → Model-Prep → Preflight → Preset-Apply → Render → Post → Verify → Delivery
|
|
143
|
+
[v0.1 ✓] (v0.2) (v0.3) (v0.3) (v0.3) (v0.2) (v0.3)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Each stage is an independent Python package with a stable interface. Compose your own pipelines.
|
|
147
|
+
Full architecture: [docs/architecture.md](docs/architecture.md).
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Roadmap
|
|
152
|
+
|
|
153
|
+
- **v0.1** ✓ — Model-Prep Core (wheel detection, origin fix, ground anchor, body group, material sanitize)
|
|
154
|
+
- **v0.2** — Preflight & Verify (test frame + 6-gate verification + auto-fix loop)
|
|
155
|
+
- **v0.3** — Preset Library (5 looks × 5 cameras) + Cycles rendering
|
|
156
|
+
- **v0.4** — CLI + Blender Addon + Docker Serverless
|
|
157
|
+
- **v0.5** — Public Launch (landing page + 3–5 case studies)
|
|
158
|
+
- **v1.0** — First customer case study live on zer0onelab.com
|
|
159
|
+
|
|
160
|
+
Full roadmap: [docs/roadmap.md](docs/roadmap.md).
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Development
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
git clone https://github.com/0xxCool/zer0one-cinema
|
|
168
|
+
cd zer0one-cinema
|
|
169
|
+
python3.11 -m venv .venv
|
|
170
|
+
source .venv/bin/activate
|
|
171
|
+
pip install -e ".[dev]"
|
|
172
|
+
pytest tests/ # 140 tests, ~5s
|
|
173
|
+
ruff check zer0one_cinema tests
|
|
174
|
+
mypy zer0one_cinema
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Real-Blender integration testing needs the runner script:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
~/opt/blender-4.2/blender -b -P scripts/run_zocinema.py -- \
|
|
181
|
+
model-prep tests/glb_fixtures/kenney_sedan.glb --output /tmp/out.blend
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Test-fixture GLBs (not in the repo — see [tests/glb_fixtures/README.md](tests/glb_fixtures/README.md) for reproduction).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Contributing
|
|
189
|
+
|
|
190
|
+
Not accepting external contributions yet — waiting for v0.3 (public launch) to stabilize the interface. **Bug reports welcome** as GitHub Issues, especially for new GLB structures that the wheel-detection Stage 2 filter rejects (paste the output of `scripts/debug_candidates.py`).
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT — see [LICENSE](LICENSE).
|
|
195
|
+
|
|
196
|
+
## Who's behind this
|
|
197
|
+
|
|
198
|
+
Built by [ZER0ONELAB](https://zer0onelab.com) as part of our cloud-render platform for DACH studios doing brand work. If you need cinema-grade renders at scale without doing the engineering yourself, we're the delivery layer.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "zer0one-cinema"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Deterministic cinema-grade rendering automation for Blender: GLB in, movie out."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [{ name = "ZER0ONELAB", email = "michael@zer0one.codes" }]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
keywords = ["blender", "rendering", "3d", "cinema", "automation", "cycles", "cli"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
16
|
+
"Intended Audience :: End Users/Desktop",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: Multimedia :: Graphics :: 3D Rendering",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"numpy>=1.26",
|
|
25
|
+
"pillow>=10.0",
|
|
26
|
+
"pyyaml>=6.0",
|
|
27
|
+
"click>=8.1",
|
|
28
|
+
"scikit-learn>=1.5",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest>=8.0",
|
|
34
|
+
"pytest-cov>=5.0",
|
|
35
|
+
"ruff>=0.5",
|
|
36
|
+
"mypy>=1.10",
|
|
37
|
+
"types-pyyaml",
|
|
38
|
+
"types-pillow",
|
|
39
|
+
]
|
|
40
|
+
docs = [
|
|
41
|
+
"mkdocs-material>=9.5",
|
|
42
|
+
"mkdocstrings[python]>=0.25",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
zocinema = "zer0one_cinema.cli:main"
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://zer0onelab.com/cinema"
|
|
50
|
+
Repository = "https://github.com/0xxCool/zer0one-cinema"
|
|
51
|
+
Issues = "https://github.com/0xxCool/zer0one-cinema/issues"
|
|
52
|
+
|
|
53
|
+
[tool.setuptools]
|
|
54
|
+
packages = ["zer0one_cinema"]
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.package-data]
|
|
57
|
+
zer0one_cinema = ["presets/**/*.yaml"]
|
|
58
|
+
|
|
59
|
+
[tool.ruff]
|
|
60
|
+
line-length = 100
|
|
61
|
+
target-version = "py311"
|
|
62
|
+
|
|
63
|
+
[tool.ruff.lint]
|
|
64
|
+
select = ["E", "F", "W", "I", "N", "UP", "B", "SIM", "C4", "PL"]
|
|
65
|
+
ignore = ["E501", "PLR0913"]
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint.per-file-ignores]
|
|
68
|
+
"tests/**/*.py" = ["PLR2004", "B017"] # assertions may use magic values + blind exceptions
|
|
69
|
+
"zer0one_cinema/model_prep/wheel_detect.py" = [
|
|
70
|
+
"PLC0415", # local sklearn import is intentional (lazy)
|
|
71
|
+
"PLR2004", # inline algorithm constants (min verts, half-of-2, etc.) — magic-value rule is noise here
|
|
72
|
+
]
|
|
73
|
+
"zer0one_cinema/model_prep/material_sanitize.py" = [
|
|
74
|
+
"PLR0911", # 3-pass classifier legitimately has many early-return branches
|
|
75
|
+
"PLR2004", # texture-signal thresholds are domain-specific, documented in research doc
|
|
76
|
+
]
|
|
77
|
+
"zer0one_cinema/model_prep/body_group.py" = [
|
|
78
|
+
"PLR0912", # multi-stage filter (wheel-filter → env-filter → aggregate) reads clearer inline
|
|
79
|
+
"PLR2004", # wheelbase-count threshold (2) is documented in-code
|
|
80
|
+
]
|
|
81
|
+
"zer0one_cinema/io/glb_loader.py" = [
|
|
82
|
+
"PLC0415", # deferred bpy import is intentional (keep core pure-python-importable)
|
|
83
|
+
]
|
|
84
|
+
"zer0one_cinema/cli/model_prep.py" = [
|
|
85
|
+
"PLC0415", # deferred bpy + adapter imports are intentional (CLI must import without bpy)
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
[tool.mypy]
|
|
89
|
+
python_version = "3.11"
|
|
90
|
+
strict = true
|
|
91
|
+
warn_return_any = true
|
|
92
|
+
|
|
93
|
+
[[tool.mypy.overrides]]
|
|
94
|
+
module = ["sklearn.*"]
|
|
95
|
+
ignore_missing_imports = true
|
|
96
|
+
|
|
97
|
+
[tool.pytest.ini_options]
|
|
98
|
+
testpaths = ["tests"]
|
|
99
|
+
python_files = ["test_*.py"]
|
|
100
|
+
addopts = "-v --strict-markers --cov=zer0one_cinema --cov-report=term-missing"
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Context and trace primitives for zer0one-cinema pipelines.
|
|
2
|
+
|
|
3
|
+
Every model-prep / preflight / render / verify module accepts a `Context`
|
|
4
|
+
and returns updates via `Context.log()`. The context is the single place
|
|
5
|
+
where pipeline state, config, seeds, and the append-only trace live.
|
|
6
|
+
|
|
7
|
+
The provenance hash makes runs reproducible for audit: same GLB + same
|
|
8
|
+
preset + same version + same seed → same hash → identical output.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from hashlib import sha256
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class TraceEntry:
|
|
20
|
+
"""One append-only entry in the pipeline trace."""
|
|
21
|
+
|
|
22
|
+
stage: str # e.g. "wheel_detect"
|
|
23
|
+
op: str # e.g. "clustered_4_wheels"
|
|
24
|
+
details: dict[str, Any] # JSON-serializable per convention
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class Context:
|
|
29
|
+
"""Mutable pipeline context, threaded through every stage.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
scene_ref: opaque handle to a Blender scene (None when running unit tests).
|
|
33
|
+
config: pipeline configuration (JSON-serializable), typically loaded from CLI + preset YAML.
|
|
34
|
+
trace: append-only operation log; used for rollback and audit reports.
|
|
35
|
+
seed: global RNG seed for deterministic runs.
|
|
36
|
+
version: package version (populated by CLI at startup).
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
scene_ref: object | None = None
|
|
40
|
+
config: dict[str, Any] = field(default_factory=dict)
|
|
41
|
+
trace: list[TraceEntry] = field(default_factory=list)
|
|
42
|
+
seed: int = 0
|
|
43
|
+
version: str = "0.0.1"
|
|
44
|
+
|
|
45
|
+
def log(self, stage: str, op: str, **details: Any) -> None:
|
|
46
|
+
"""Append a trace entry. Values must be JSON-serializable."""
|
|
47
|
+
self.trace.append(TraceEntry(stage=stage, op=op, details=details))
|
|
48
|
+
|
|
49
|
+
def provenance_hash(self, glb_sha256: str, preset_sha256: str) -> str:
|
|
50
|
+
"""Return the SHA-256 hash that identifies this run's inputs.
|
|
51
|
+
|
|
52
|
+
Same GLB + same preset + same package-version + same seed → same hash.
|
|
53
|
+
Recorded in every delivered `report.json`.
|
|
54
|
+
"""
|
|
55
|
+
h = sha256()
|
|
56
|
+
h.update(b"zer0one-cinema:v1\n")
|
|
57
|
+
h.update(glb_sha256.encode())
|
|
58
|
+
h.update(b"|")
|
|
59
|
+
h.update(preset_sha256.encode())
|
|
60
|
+
h.update(b"|")
|
|
61
|
+
h.update(self.version.encode())
|
|
62
|
+
h.update(b"|")
|
|
63
|
+
h.update(str(self.seed).encode())
|
|
64
|
+
return h.hexdigest()
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zer0one-cinema
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic cinema-grade rendering automation for Blender: GLB in, movie out.
|
|
5
|
+
Author-email: ZER0ONELAB <michael@zer0one.codes>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://zer0onelab.com/cinema
|
|
8
|
+
Project-URL: Repository, https://github.com/0xxCool/zer0one-cinema
|
|
9
|
+
Project-URL: Issues, https://github.com/0xxCool/zer0one-cinema/issues
|
|
10
|
+
Keywords: blender,rendering,3d,cinema,automation,cycles,cli
|
|
11
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=1.26
|
|
22
|
+
Requires-Dist: pillow>=10.0
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Requires-Dist: click>=8.1
|
|
25
|
+
Requires-Dist: scikit-learn>=1.5
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
31
|
+
Requires-Dist: types-pyyaml; extra == "dev"
|
|
32
|
+
Requires-Dist: types-pillow; extra == "dev"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
35
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == "docs"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# zer0one-cinema
|
|
39
|
+
|
|
40
|
+
**Deterministic cinema-grade rendering automation for Blender.**
|
|
41
|
+
GLB in, movie out — no manual scene setup, no per-model tweaking, no subscription tools required.
|
|
42
|
+
|
|
43
|
+
> **Status:** v0.1 model-prep layer implemented, real-Blender verified on 2 vehicle GLBs.
|
|
44
|
+
> Follow [releases](https://github.com/0xxCool/zer0one-cinema/releases) or
|
|
45
|
+
> [zer0onelab.com/cinema](https://zer0onelab.com/cinema) for progress.
|
|
46
|
+
|
|
47
|
+
[](https://github.com/0xxCool/zer0one-cinema/actions/workflows/ci.yml)
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## The problem this solves
|
|
53
|
+
|
|
54
|
+
Take any 3D vehicle model from Sketchfab, throw it into Blender, run Cycles — you get a bland turntable. To get an *automotive-trailer look* (Ford v Ferrari, NfS Heat, Gran Turismo) you need:
|
|
55
|
+
|
|
56
|
+
- Wheels detected and rigged at their real rotation center (not the GLB's random origin)
|
|
57
|
+
- Body on the ground, not floating or sunk
|
|
58
|
+
- Lighting that flatters the paint (rim light for silhouette, key/fill balance)
|
|
59
|
+
- Camera framing that respects Rule-of-Thirds and doesn't clip parts of the car
|
|
60
|
+
- Post-processing (grading, DoF, motion blur, chromatic aberration, film grain)
|
|
61
|
+
- Verification that every rendered frame actually meets those standards
|
|
62
|
+
|
|
63
|
+
Today this takes a 3D artist several days of manual work per model. `zer0one-cinema` will do it in one CLI command:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
zocinema render my_car.glb --look studio_night_neon --camera push_in --output trailer.mp4
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**v0.1 ships the first stage of that pipeline** — deterministic model preparation:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
zocinema model-prep my_car.glb --output my_car_prepped.blend --report report.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The full render pipeline lands in v0.3.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Quickstart (v0.1)
|
|
80
|
+
|
|
81
|
+
Model-prep is a Blender-Python operation — it needs Blender 4.2+ installed. Full render
|
|
82
|
+
pipeline (v0.3+) will also work as a standalone pip install.
|
|
83
|
+
|
|
84
|
+
### 1. Install Blender 4.2 LTS
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Download the official tarball (avoid distro packages — many miss the Draco decoder)
|
|
88
|
+
wget https://download.blender.org/release/Blender4.2/blender-4.2.11-linux-x64.tar.xz
|
|
89
|
+
tar -xf blender-4.2.11-linux-x64.tar.xz -C ~/opt/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Install zer0one-cinema
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Into Blender's bundled Python:
|
|
96
|
+
~/opt/blender-4.2.11-linux-x64/4.2/python/bin/python3.11 -m pip install --user \
|
|
97
|
+
click numpy pillow pyyaml scikit-learn
|
|
98
|
+
|
|
99
|
+
# Clone the repo (PyPI upload will come with v0.1.0 release tag):
|
|
100
|
+
git clone https://github.com/0xxCool/zer0one-cinema ~/zer0one-cinema
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Prepare a GLB
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
BLENDER=~/opt/blender-4.2.11-linux-x64/blender
|
|
107
|
+
cd ~/zer0one-cinema
|
|
108
|
+
|
|
109
|
+
"$BLENDER" -b -P scripts/run_zocinema.py -- model-prep \
|
|
110
|
+
/path/to/car.glb \
|
|
111
|
+
--output out.blend \
|
|
112
|
+
--report report.json \
|
|
113
|
+
--seed 0
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Real example on `kenney_sedan.glb`** (part of our test-suite):
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
[1/7] Loading kenney_sedan.glb...
|
|
120
|
+
→ 5 meshes, 3184 vertices, 0.13s
|
|
121
|
+
[2/7] Ground-anchoring...
|
|
122
|
+
→ z_shift = 0.0000 m, moved 0 objects
|
|
123
|
+
[3/7] Detecting wheels...
|
|
124
|
+
→ 4 wheels: FL, FR, RL, RR (confidence 0.90)
|
|
125
|
+
[4/7] Re-origining wheels...
|
|
126
|
+
→ moved 0 origins, skipped 0 already-centered
|
|
127
|
+
[5/7] Building body group...
|
|
128
|
+
→ 1 body meshes (excluded 4 wheel + 0 env)
|
|
129
|
+
[6/7] Sanitizing materials...
|
|
130
|
+
→ 1 materials analyzed, 1 changed
|
|
131
|
+
[7/7] Saving out.blend...
|
|
132
|
+
✓ Done in 2.5s
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The output `.blend` file is fully-rigged: wheels have their origins at the axle
|
|
136
|
+
centers (so `wheel.rotation_euler.x -= radians(360)` spins them in place instead of
|
|
137
|
+
throwing them off the car), the body is grounded to z=0, materials are normalized
|
|
138
|
+
to sane PBR values (car-paint clearcoat, chrome metallic, etc.). Deterministic —
|
|
139
|
+
same GLB + same seed → byte-identical output.
|
|
140
|
+
|
|
141
|
+
**Read the report:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python3 -m json.tool report.json
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## What v0.1 supports
|
|
150
|
+
|
|
151
|
+
- **Wheel detection** for typical 4-wheeled cars, SUVs, trucks, monster-trucks (wheelbase-to-wheel-diameter ratio 0.03 – 0.50)
|
|
152
|
+
- **Ground anchor** — vehicle's lowest point placed at world z=0
|
|
153
|
+
- **Origin fix** — wheel object-origins moved to axle centers (so rotation animations work)
|
|
154
|
+
- **Body group** — non-wheel meshes grouped with a centroid for later body-roll/pitch animation
|
|
155
|
+
- **Material sanitize** — 12-class PBR classifier (car-paint, chrome, glass, tire, brake, carbon-fiber, headlight, taillight, rim-alloy, interior-plastic, leather-seat, unknown → default-plastic). Whitelist-based: unknowns pass through untouched. Hard fixes for the two most common Sketchfab bugs (emission accidentally set on body, alpha=0.99 instead of 1.0).
|
|
156
|
+
|
|
157
|
+
## What v0.1 does NOT support (yet)
|
|
158
|
+
|
|
159
|
+
- **Merged-mesh GLBs** — models exported as one giant mesh with no separate wheel objects. Common on old CAD-export or single-artist Sketchfab uploads (e.g. `khronos_toy_car.glb`). Sub-mesh splitting via connected-components arrives in v0.2.
|
|
160
|
+
- **Rendering** — v0.1 is model-prep only. Cinema-grade renders (Cycles + preset library) come in v0.3.
|
|
161
|
+
- **Preflight / verify** — automatic frame-QA is v0.2.
|
|
162
|
+
- **Non-vehicle models** — characters, architecture, product-vis need their own detection heuristics (v1.2+).
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Design principles
|
|
167
|
+
|
|
168
|
+
1. **Deterministic.** Same GLB + same preset → byte-identical output. K-Means uses `random_state=0, n_init=1` with lexicographically-sorted inputs.
|
|
169
|
+
2. **Open source.** MIT license. Core is free forever. Premium look library (v0.3+) is a separate paid add-on.
|
|
170
|
+
3. **No proprietary dependencies.** Blender / Python / numpy / scikit-learn / FFmpeg — no Adobe / Substance / KeyShot / Marmoset subscription required.
|
|
171
|
+
4. **Every frame verified.** The 6-gate cinema-grade verification framework (v0.2) runs on every render — bad frames are flagged, not shipped.
|
|
172
|
+
5. **Testable without Blender.** All model-prep modules work against pure-Python protocols (`MeshLike`, `MaterialLike`, `MutableObject`). Unit tests use numpy-only mocks — no `bpy` required. 140 tests in the current suite.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Architecture
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
GLB → Model-Prep → Preflight → Preset-Apply → Render → Post → Verify → Delivery
|
|
180
|
+
[v0.1 ✓] (v0.2) (v0.3) (v0.3) (v0.3) (v0.2) (v0.3)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Each stage is an independent Python package with a stable interface. Compose your own pipelines.
|
|
184
|
+
Full architecture: [docs/architecture.md](docs/architecture.md).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Roadmap
|
|
189
|
+
|
|
190
|
+
- **v0.1** ✓ — Model-Prep Core (wheel detection, origin fix, ground anchor, body group, material sanitize)
|
|
191
|
+
- **v0.2** — Preflight & Verify (test frame + 6-gate verification + auto-fix loop)
|
|
192
|
+
- **v0.3** — Preset Library (5 looks × 5 cameras) + Cycles rendering
|
|
193
|
+
- **v0.4** — CLI + Blender Addon + Docker Serverless
|
|
194
|
+
- **v0.5** — Public Launch (landing page + 3–5 case studies)
|
|
195
|
+
- **v1.0** — First customer case study live on zer0onelab.com
|
|
196
|
+
|
|
197
|
+
Full roadmap: [docs/roadmap.md](docs/roadmap.md).
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
git clone https://github.com/0xxCool/zer0one-cinema
|
|
205
|
+
cd zer0one-cinema
|
|
206
|
+
python3.11 -m venv .venv
|
|
207
|
+
source .venv/bin/activate
|
|
208
|
+
pip install -e ".[dev]"
|
|
209
|
+
pytest tests/ # 140 tests, ~5s
|
|
210
|
+
ruff check zer0one_cinema tests
|
|
211
|
+
mypy zer0one_cinema
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Real-Blender integration testing needs the runner script:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
~/opt/blender-4.2/blender -b -P scripts/run_zocinema.py -- \
|
|
218
|
+
model-prep tests/glb_fixtures/kenney_sedan.glb --output /tmp/out.blend
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Test-fixture GLBs (not in the repo — see [tests/glb_fixtures/README.md](tests/glb_fixtures/README.md) for reproduction).
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Contributing
|
|
226
|
+
|
|
227
|
+
Not accepting external contributions yet — waiting for v0.3 (public launch) to stabilize the interface. **Bug reports welcome** as GitHub Issues, especially for new GLB structures that the wheel-detection Stage 2 filter rejects (paste the output of `scripts/debug_candidates.py`).
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT — see [LICENSE](LICENSE).
|
|
232
|
+
|
|
233
|
+
## Who's behind this
|
|
234
|
+
|
|
235
|
+
Built by [ZER0ONELAB](https://zer0onelab.com) as part of our cloud-render platform for DACH studios doing brand work. If you need cinema-grade renders at scale without doing the engineering yourself, we're the delivery layer.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
tests/test_smoke.py
|
|
5
|
+
zer0one_cinema/__init__.py
|
|
6
|
+
zer0one_cinema/context.py
|
|
7
|
+
zer0one_cinema.egg-info/PKG-INFO
|
|
8
|
+
zer0one_cinema.egg-info/SOURCES.txt
|
|
9
|
+
zer0one_cinema.egg-info/dependency_links.txt
|
|
10
|
+
zer0one_cinema.egg-info/entry_points.txt
|
|
11
|
+
zer0one_cinema.egg-info/requires.txt
|
|
12
|
+
zer0one_cinema.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
zer0one_cinema
|