armature-studio 0.2.1__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.
- armature_studio-0.2.1/LICENSE +21 -0
- armature_studio-0.2.1/PKG-INFO +135 -0
- armature_studio-0.2.1/README.md +241 -0
- armature_studio-0.2.1/README.pypi.md +85 -0
- armature_studio-0.2.1/pyproject.toml +54 -0
- armature_studio-0.2.1/setup.cfg +4 -0
- armature_studio-0.2.1/tests/test_aapose_convention.py +503 -0
- armature_studio-0.2.1/tests/test_assembly.py +280 -0
- armature_studio-0.2.1/tests/test_binding.py +179 -0
- armature_studio-0.2.1/tests/test_blender_conventions.py +130 -0
- armature_studio-0.2.1/tests/test_build_animate_payload.py +219 -0
- armature_studio-0.2.1/tests/test_build_camera_i2v_payload.py +498 -0
- armature_studio-0.2.1/tests/test_build_i2v_payload.py +325 -0
- armature_studio-0.2.1/tests/test_build_lora_arm_payload.py +234 -0
- armature_studio-0.2.1/tests/test_build_payload.py +278 -0
- armature_studio-0.2.1/tests/test_build_t2v_payload.py +173 -0
- armature_studio-0.2.1/tests/test_build_t2v_payload_a3.py +255 -0
- armature_studio-0.2.1/tests/test_cascade.py +357 -0
- armature_studio-0.2.1/tests/test_channels.py +147 -0
- armature_studio-0.2.1/tests/test_check_relift.py +69 -0
- armature_studio-0.2.1/tests/test_cli.py +112 -0
- armature_studio-0.2.1/tests/test_clipcompare.py +145 -0
- armature_studio-0.2.1/tests/test_clipstats.py +166 -0
- armature_studio-0.2.1/tests/test_composite_reference.py +195 -0
- armature_studio-0.2.1/tests/test_donor_gate.py +274 -0
- armature_studio-0.2.1/tests/test_e13_sheet.py +92 -0
- armature_studio-0.2.1/tests/test_extract_clip_frames.py +64 -0
- armature_studio-0.2.1/tests/test_fetch_run.py +40 -0
- armature_studio-0.2.1/tests/test_fit_reference.py +95 -0
- armature_studio-0.2.1/tests/test_floor_material.py +105 -0
- armature_studio-0.2.1/tests/test_framing.py +116 -0
- armature_studio-0.2.1/tests/test_gate_b.py +89 -0
- armature_studio-0.2.1/tests/test_gate_b_frames.py +95 -0
- armature_studio-0.2.1/tests/test_gate_g6.py +134 -0
- armature_studio-0.2.1/tests/test_gate_r.py +149 -0
- armature_studio-0.2.1/tests/test_gate_s.py +270 -0
- armature_studio-0.2.1/tests/test_gate_saved_graph.py +181 -0
- armature_studio-0.2.1/tests/test_gate_survives_optimize.py +191 -0
- armature_studio-0.2.1/tests/test_gates.py +212 -0
- armature_studio-0.2.1/tests/test_glb.py +107 -0
- armature_studio-0.2.1/tests/test_invert_frames.py +143 -0
- armature_studio-0.2.1/tests/test_joints.py +197 -0
- armature_studio-0.2.1/tests/test_landmarks.py +222 -0
- armature_studio-0.2.1/tests/test_lift_solve.py +545 -0
- armature_studio-0.2.1/tests/test_make_ab_clip.py +75 -0
- armature_studio-0.2.1/tests/test_make_crop_strip.py +41 -0
- armature_studio-0.2.1/tests/test_make_gate0_sheet.py +117 -0
- armature_studio-0.2.1/tests/test_make_hole_survey.py +234 -0
- armature_studio-0.2.1/tests/test_make_lift_sheet.py +69 -0
- armature_studio-0.2.1/tests/test_make_pick_sheet.py +219 -0
- armature_studio-0.2.1/tests/test_make_plate.py +250 -0
- armature_studio-0.2.1/tests/test_make_review_clip.py +25 -0
- armature_studio-0.2.1/tests/test_make_shotset_sheet.py +243 -0
- armature_studio-0.2.1/tests/test_make_startframe_sheet.py +94 -0
- armature_studio-0.2.1/tests/test_make_thesis_sheet.py +88 -0
- armature_studio-0.2.1/tests/test_make_zoom_sheet.py +37 -0
- armature_studio-0.2.1/tests/test_measure_smoothness.py +93 -0
- armature_studio-0.2.1/tests/test_measure_tracking.py +244 -0
- armature_studio-0.2.1/tests/test_openpose_convention.py +69 -0
- armature_studio-0.2.1/tests/test_ortho_convention.py +136 -0
- armature_studio-0.2.1/tests/test_pack_pose_pack.py +124 -0
- armature_studio-0.2.1/tests/test_parts.py +249 -0
- armature_studio-0.2.1/tests/test_pinned_camera.py +113 -0
- armature_studio-0.2.1/tests/test_pinned_framing.py +154 -0
- armature_studio-0.2.1/tests/test_plate_composite.py +102 -0
- armature_studio-0.2.1/tests/test_pngio.py +73 -0
- armature_studio-0.2.1/tests/test_posearc.py +143 -0
- armature_studio-0.2.1/tests/test_r2v_payload.py +340 -0
- armature_studio-0.2.1/tests/test_render_visibility.py +63 -0
- armature_studio-0.2.1/tests/test_resample.py +280 -0
- armature_studio-0.2.1/tests/test_rig_gates.py +279 -0
- armature_studio-0.2.1/tests/test_route_gates.py +722 -0
- armature_studio-0.2.1/tests/test_run_export.py +169 -0
- armature_studio-0.2.1/tests/test_sheet_compose.py +100 -0
- armature_studio-0.2.1/tests/test_shotspec.py +136 -0
- armature_studio-0.2.1/tests/test_sitelist.py +137 -0
- armature_studio-0.2.1/tests/test_startframe.py +501 -0
- armature_studio-0.2.1/tests/test_subject.py +88 -0
- armature_studio-0.2.1/tests/test_turnaround.py +302 -0
- armature_studio-0.2.1/tests/test_turnaround_ortho.py +425 -0
- armature_studio-0.2.1/tests/test_turnaround_pin.py +318 -0
- armature_studio-0.2.1/tests/test_walk.py +363 -0
- armature_studio-0.2.1/tools/armature_core/__init__.py +15 -0
- armature_studio-0.2.1/tools/armature_core/aapose.py +481 -0
- armature_studio-0.2.1/tools/armature_core/assembly.py +360 -0
- armature_studio-0.2.1/tools/armature_core/binding.py +148 -0
- armature_studio-0.2.1/tools/armature_core/blender_scene.py +497 -0
- armature_studio-0.2.1/tools/armature_core/channels.py +224 -0
- armature_studio-0.2.1/tools/armature_core/cli.py +141 -0
- armature_studio-0.2.1/tools/armature_core/clipcompare.py +111 -0
- armature_studio-0.2.1/tools/armature_core/clipstats.py +169 -0
- armature_studio-0.2.1/tools/armature_core/donor_gate.py +224 -0
- armature_studio-0.2.1/tools/armature_core/errors.py +230 -0
- armature_studio-0.2.1/tools/armature_core/framing.py +327 -0
- armature_studio-0.2.1/tools/armature_core/gates.py +593 -0
- armature_studio-0.2.1/tools/armature_core/glb.py +162 -0
- armature_studio-0.2.1/tools/armature_core/joints.py +235 -0
- armature_studio-0.2.1/tools/armature_core/landmarks.py +562 -0
- armature_studio-0.2.1/tools/armature_core/lift_solve.py +714 -0
- armature_studio-0.2.1/tools/armature_core/openpose.py +60 -0
- armature_studio-0.2.1/tools/armature_core/parts.py +354 -0
- armature_studio-0.2.1/tools/armature_core/pngio.py +85 -0
- armature_studio-0.2.1/tools/armature_core/posearc.py +159 -0
- armature_studio-0.2.1/tools/armature_core/resample.py +381 -0
- armature_studio-0.2.1/tools/armature_core/rig_gates.py +341 -0
- armature_studio-0.2.1/tools/armature_core/route_gates.py +1002 -0
- armature_studio-0.2.1/tools/armature_core/shotspec.py +234 -0
- armature_studio-0.2.1/tools/armature_core/sitelist.py +135 -0
- armature_studio-0.2.1/tools/armature_core/startframe.py +506 -0
- armature_studio-0.2.1/tools/armature_core/subject.py +64 -0
- armature_studio-0.2.1/tools/armature_core/turnaround.py +342 -0
- armature_studio-0.2.1/tools/armature_core/walk.py +640 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/PKG-INFO +135 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/SOURCES.txt +116 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/dependency_links.txt +1 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/entry_points.txt +2 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/requires.txt +4 -0
- armature_studio-0.2.1/tools/armature_studio.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcp-tool-shop
|
|
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,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: armature-studio
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Block the shot; the model shoots it — GLB-authored previz, control sequences and gates for video-diffusion generation.
|
|
5
|
+
Author-email: mcp-tool-shop <64996768+mcp-tool-shop@users.noreply.github.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 mcp-tool-shop
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://mcp-tool-shop-org.github.io/armature/
|
|
29
|
+
Project-URL: Repository, https://github.com/mcp-tool-shop-org/armature
|
|
30
|
+
Project-URL: Changelog, https://github.com/mcp-tool-shop-org/armature/blob/main/CHANGELOG.md
|
|
31
|
+
Project-URL: Issues, https://github.com/mcp-tool-shop-org/armature/issues
|
|
32
|
+
Keywords: previz,blender,video-diffusion,controlnet,turnaround,glb,character,animation,comfyui,sprite
|
|
33
|
+
Classifier: Development Status :: 4 - Beta
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
41
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
|
|
42
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
43
|
+
Requires-Python: >=3.10
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
License-File: LICENSE
|
|
46
|
+
Requires-Dist: numpy>=1.24
|
|
47
|
+
Provides-Extra: dev
|
|
48
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# armature
|
|
52
|
+
|
|
53
|
+
**You block the shot. The model shoots it.**
|
|
54
|
+
|
|
55
|
+
A video model can produce motion, light and life that no renderer can. It cannot be told
|
|
56
|
+
*who is on screen and where they are standing*. armature supplies exactly that: a canonical
|
|
57
|
+
character mesh is staged and animated in headless Blender, and the render becomes a per-frame
|
|
58
|
+
**control sequence** the video model must obey — so AI-generated video can carry one
|
|
59
|
+
persistent main character whose position and pose are known every frame.
|
|
60
|
+
|
|
61
|
+
**armature is image-to-video with a GLB instead of an image.** Everything spatial is
|
|
62
|
+
authored, and the model paints life over it. The deliverable is footage — film, cutscenes,
|
|
63
|
+
character poses and movement, any shot at all. A game is one consumer of that footage, never
|
|
64
|
+
the boundary of the tool.
|
|
65
|
+
|
|
66
|
+
## Install
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install armature-studio
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
armature check
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## What this package is
|
|
77
|
+
|
|
78
|
+
The installable package is `armature_core` — the measured pieces of the pipeline, every one
|
|
79
|
+
of which imports under a plain CPython:
|
|
80
|
+
|
|
81
|
+
- **Gates that raise.** `gates`, `route_gates`, `rig_gates`, `donor_gate` — predicates that
|
|
82
|
+
refuse a bad step *inside* the tool performing it, rather than warning beside it.
|
|
83
|
+
- **Framing and turnaround.** `framing`, `turnaround`, `startframe` — perspective and
|
|
84
|
+
orthographic camera solves, shared-scale shot-sets, silhouette extent, and the
|
|
85
|
+
frame-clearance checks that refuse a cropped subject.
|
|
86
|
+
- **Control channels.** `channels`, `openpose`, `aapose`, `landmarks`, `lift_solve` —
|
|
87
|
+
channel maths and pose conventions for driving a video model.
|
|
88
|
+
- **Rig and mesh.** `joints`, `binding`, `parts`, `posearc`, `walk`, `glb`.
|
|
89
|
+
- **Contracts and records.** `shotspec`, `subject`, `sitelist`, `assembly`, `clipstats`,
|
|
90
|
+
`clipcompare`, `pngio`, `errors`.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from armature_core import turnaround, framing
|
|
94
|
+
|
|
95
|
+
plan = turnaround.projection_plan(ortho=True, ortho_scale=1.1235359256161628)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## What this package is not
|
|
99
|
+
|
|
100
|
+
**The rendering scripts are not console entry points, deliberately.**
|
|
101
|
+
`render_turnaround.py`, `stage_render.py` and their siblings run inside **Blender's own
|
|
102
|
+
interpreter**:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
blender -b -P tools/render_turnaround.py -- --glb subject.glb --out renders --ortho
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A console script installed on your Python could not import `bpy` and would fail on its first
|
|
109
|
+
line, so shipping one would be a promise the package cannot keep. Those scripts live in the
|
|
110
|
+
repository, where the invocation that works is the one written down.
|
|
111
|
+
|
|
112
|
+
`armature_core.blender_scene` is the single module that imports `bpy`. It is packaged, and it
|
|
113
|
+
resolves only under Blender — `armature check` reports it as `needs-blender` rather than as a
|
|
114
|
+
defect.
|
|
115
|
+
|
|
116
|
+
## The discipline this comes from
|
|
117
|
+
|
|
118
|
+
armature is an experiment repository whose product is its record: a spec before the work, a
|
|
119
|
+
report after, a ruling last, and the Director's eye as the verdict of record. Metrics are
|
|
120
|
+
diagnostics and gate nothing on their own. Every generation records its model, payload, seed
|
|
121
|
+
and control hashes, because a recipe that does not reproduce its output is not a recipe. No
|
|
122
|
+
non-commercially-licensed model, weight or dependency enters the pipeline — anywhere,
|
|
123
|
+
including experiments.
|
|
124
|
+
|
|
125
|
+
- **Docs and handbook:** https://mcp-tool-shop-org.github.io/armature/
|
|
126
|
+
- **Repository and the full record:** https://github.com/mcp-tool-shop-org/armature
|
|
127
|
+
|
|
128
|
+
## Requirements
|
|
129
|
+
|
|
130
|
+
Python 3.10+ and numpy. Blender 5.x is required only for the rendering scripts in the
|
|
131
|
+
repository, not for this package.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/armature/readme.png" alt="armature — you block the shot, the model shoots it" width="820">
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://github.com/mcp-tool-shop-org/armature/actions/workflows/ci.yml"><img src="https://github.com/mcp-tool-shop-org/armature/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
|
|
12
|
+
<a href="https://mcp-tool-shop-org.github.io/armature/"><img src="https://img.shields.io/badge/Landing_Page-live-blue" alt="Landing Page"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
**You block the shot. The model shoots it.**
|
|
18
|
+
|
|
19
|
+
**[Landing page & handbook →](https://mcp-tool-shop-org.github.io/armature/)**
|
|
20
|
+
|
|
21
|
+
A video model can produce motion, light and life that no renderer can. It cannot be told *who
|
|
22
|
+
is on screen and where they are standing*. armature supplies exactly that: a canonical
|
|
23
|
+
character mesh is staged and animated in headless Blender, and the render becomes a per-frame
|
|
24
|
+
**control sequence** the video model must obey — so AI-generated video can carry one persistent
|
|
25
|
+
main character whose position and pose are known every frame.
|
|
26
|
+
|
|
27
|
+
**armature is image-to-video with a GLB instead of an image.** Everything spatial is authored,
|
|
28
|
+
and the model paints life over it. The deliverable is footage — film, cutscenes, character
|
|
29
|
+
poses and movement, any shot at all. A game is one consumer of that footage, never the
|
|
30
|
+
boundary of the tool.
|
|
31
|
+
|
|
32
|
+
Stage your character in Blender. Render the control sequence. Let the video model paint the life
|
|
33
|
+
over it. Structure comes from geometry you own; life comes from the model; identity is a named,
|
|
34
|
+
versioned thing that rides in the prompt and the reference stack — never an accident of a lucky
|
|
35
|
+
frame.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install armature-studio
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install -g @mcptoolshop/armature-studio # the same command, as a launcher
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
armature check
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The installable package is **`armature_core`** — the gates, the framing and turnaround solvers,
|
|
52
|
+
the shot-spec contract, the channel maths and the payload builders. Every one of them imports
|
|
53
|
+
under a plain CPython, which is what lets them be tested, and packaged, without Blender present.
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from armature_core import turnaround, framing
|
|
57
|
+
|
|
58
|
+
plan = turnaround.projection_plan(ortho=True, ortho_scale=1.1235359256161628)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**The rendering scripts are not console entry points, and that is deliberate.**
|
|
62
|
+
`render_turnaround.py`, `stage_render.py` and their siblings run inside **Blender's own
|
|
63
|
+
interpreter** — a console script on your Python could not import `bpy` and would fail on its
|
|
64
|
+
first line, so shipping one would be a promise the package cannot keep:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
blender -b -P tools/render_turnaround.py -- --glb subject.glb --out renders --ortho
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
They stay here in the repository, where the invocation that works is the one written down.
|
|
71
|
+
`armature_core.blender_scene` is the single module that imports `bpy`; `armature check` reports
|
|
72
|
+
it as `needs-blender` rather than as a defect.
|
|
73
|
+
|
|
74
|
+
The npm package is a **launcher, not a port**: re-implementing a threshold in a second language
|
|
75
|
+
is how a threshold drifts, so it forwards to the Python that holds the truth, and refuses —
|
|
76
|
+
loudly, non-zero, with the one command that fixes it — rather than installing anything on your
|
|
77
|
+
behalf.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## State: the thesis is measured at product level
|
|
82
|
+
|
|
83
|
+
Founded **2026-08-10**. Thirteen experiments closed and the thesis has moved from *under test*
|
|
84
|
+
to **measured at product level**: the character has danced on screen driven from his own rig
|
|
85
|
+
and free, a handed world holds to the last frame on two seeds (E12), and **identity now
|
|
86
|
+
survives a hosted, human-trained tier fed nothing but authored references** (E13) — all
|
|
87
|
+
judged by the Director's eye. The founding-arc audit is at
|
|
88
|
+
[docs/audit-first-arc.md](docs/audit-first-arc.md); the posture since 2026-08-12 is a learning
|
|
89
|
+
monorepo — experiments prove paths, no route is canon by momentum (CLAUDE.md).
|
|
90
|
+
|
|
91
|
+
| | |
|
|
92
|
+
|---|---|
|
|
93
|
+
| Experiments | **E01–E14 closed** (E05 withdrawn on a falsified premise) — the control arc (E01–E06) · rig repair + skeleton approval (E07) · **the first painted shot** (E08) · the clean-chain baseline (E09) · densified driving adopted (E10) · the no-control route, three waves to an instructive hard fail (E11) · **the free route gains a world** and the 6.0 / uni_pc baseline (E12) · **the composed route answers its question** (E13 — dispatched, halted at zero spend, repaired by a support arc, re-armed, run, and closed inside one date: identity holds at the Director's eye; reference grounds steer model-decided worlds) · **the LoRA scene-lever priced live** (E14 — the bake-off: both style LoRAs bind on the derivative weights; the character holds on `technically_color` and fails on the photo-real pair; the winner carries an unresolvable served-file tier and a credit obligation, both recorded) |
|
|
94
|
+
| Routes | **three, measured** — the **driven route** (rig-rendered AAPose sticks → Animate; proven at shot level, parked, and licence-clear for its unpark) · the **free route** (GLB-authored start frame → camera tier at the 6.0 / uni_pc baseline; identity holds unanchored, a handed world holds on two seeds, and the LoRA scene-lever is measured live — E14) · the **composed route** (authored references into a hosted identity-lock tier — graduated by E13: identity-locked, model-decided cinematography with worlds steered by what the references carry; disclosure note in its spec) |
|
|
95
|
+
| Spend | 22 probes in the founding arc at 4 credits each; the E08–E12 arc metered **0 credits** (GPU-hour billing) under per-experiment ceilings; **E13's four generations are the repo's first partner-credit spend, inside their pre-stated 424–844 bracket**; E14's two generations metered **0 partner credits** at a two-generation ceiling, reached exactly |
|
|
96
|
+
| Licence map | every adopted dependency carries a **retrieved licence document**; UNVERIFIED is treated as NO; routes through third-party tiers additionally carry **per-route disclosure** (Director-ruled 2026-08-12); the gate's stated purpose is publishing the studio's art |
|
|
97
|
+
| Tests | **1311 passing on the rig** (13 skips, measured 2026-08-15 at the v0.2.0 cut), under `-O` too; CI exercises what a runner honestly can — rig-local assets **skip visibly** |
|
|
98
|
+
| Status | **v0.2.1 released 2026-08-15** — the record becomes an installable toolkit: `armature_core` on PyPI as `armature-studio` and on npm as `@mcptoolshop/armature-studio`, published from a tag by OIDC with no long-lived token anywhere. The record is still the docs tree, and it is still complete |
|
|
99
|
+
|
|
100
|
+
### What is measured (the current arc)
|
|
101
|
+
|
|
102
|
+
- **Identity holds** — driven (E08: the face reads as the twin's through the shot) *and*
|
|
103
|
+
unanchored (E11 wave 1: every feature to the last frame with no reference, no clip-vision,
|
|
104
|
+
no driving signal). The Director's eye is the verdict of record on both.
|
|
105
|
+
- **The camera obeys explicit control to one pixel** on the camera-tier weights (E11 wave 3) —
|
|
106
|
+
and pushes in uncommanded without it (E11 wave 1).
|
|
107
|
+
- **Density moves the signal, not the performance** (E10) — resampling smooths steps 41 %,
|
|
108
|
+
the performance 8.6 %; adopted anyway by eye: more fps reads better.
|
|
109
|
+
- **A licence row is not a wiring claim** (E11 wave 2) — a mapped-Apache model and a graph that
|
|
110
|
+
never loaded it produced 65 frames of noise with every gate green. Gate PAIR now exists.
|
|
111
|
+
- **Scene composition is seed-volatile** (E10 / E11) — identical text re-composed the world
|
|
112
|
+
wholesale across seeds. **A scene claim needs two seeds before it is a property.**
|
|
113
|
+
- **A handed world holds** (E12) — a real room in the start frame survives to the last frame
|
|
114
|
+
on two seeds on the camera tier, one-variable-attributed to the start image by field diff.
|
|
115
|
+
The same tier handed a previz void held a void (E11 wave 3): worlds are authored, then kept.
|
|
116
|
+
- **The catalog's 6.0 / uni_pc is the camera tier's baseline** (E12) — the inherited
|
|
117
|
+
3.5 / euler premise fell to its own rung: at the catalog settings the same seeds that lost a
|
|
118
|
+
head and grew a limb hold the figure to f80. The cost is named — stronger adherence pushed
|
|
119
|
+
the **unscoped identity clause** onto the crowd on one seed of two; the subject-scoped
|
|
120
|
+
prompt is the promoted lever.
|
|
121
|
+
- **Identity survives a hosted tier fed only authored references** (E13) — on wan2.7's
|
|
122
|
+
reference-to-video, both arms, both seeds, the stylized wooden performer came through a
|
|
123
|
+
human-trained model as the same character at the Director's eye. Three blind predictions
|
|
124
|
+
across two seats expected the tier to overwrite non-human structure; none was right —
|
|
125
|
+
one-directional pessimism about these models is now written down as calibration doctrine.
|
|
126
|
+
- **Reference grounds steer model-decided worlds, and dominate seed chaos on that tier**
|
|
127
|
+
(E13) — grey plates begat a grey studio, a warm bar clip begat a warm interior, and both
|
|
128
|
+
seeds per arm agreed. Mechanism attribution (plate-bleed vs studio-default) honestly open
|
|
129
|
+
at four generations; a property-grade claim runs under the two-seed law in a designed
|
|
130
|
+
follow-up.
|
|
131
|
+
- **A constructed VIDEO reaches VIDEO sockets** (E13) — no upload path exists for clips, but
|
|
132
|
+
81 authored frames assembled in-graph (`CreateVideo`) were accepted at a reference-video
|
|
133
|
+
socket. Every VIDEO-typed input on the platform is in principle reachable from authored
|
|
134
|
+
frames.
|
|
135
|
+
|
|
136
|
+
### What is not
|
|
137
|
+
|
|
138
|
+
- **Arms and hands at speed.** Still failing at f80 on both seeds at both settings (E12).
|
|
139
|
+
The lever is re-scoped **presentation-first** — wrist and camera staging, from the
|
|
140
|
+
Director's own diagnosis on the GLB (the claw is a projection artifact, not mesh damage) —
|
|
141
|
+
with mesh surgery as the fallback, never the first move.
|
|
142
|
+
- **The camera claim on photographic worlds.** 0/81 horizon detections across all four E12
|
|
143
|
+
clips is a detector wanting a seam this world does not have — registered blind before
|
|
144
|
+
submission, never converted into a camera result. A **seam-free camera instrument** is owed
|
|
145
|
+
before any camera number is read on a real room.
|
|
146
|
+
- **The narration shelf** (consult #7): beat endpoints, per-chunk prompts, video-time area
|
|
147
|
+
conditioning, camera embeddings — adopted, licensed where needed, untested.
|
|
148
|
+
|
|
149
|
+
A negative answer remains a full success here — E11's hard fail bought three gates, two laws,
|
|
150
|
+
and the exact shape of the next work, and the roadmap said it would before any evidence arrived.
|
|
151
|
+
|
|
152
|
+
## How this repo works
|
|
153
|
+
|
|
154
|
+
- [CLAUDE.md](CLAUDE.md) — how to work here: the three roles, the rules each seat runs under,
|
|
155
|
+
and the non-negotiables (the license gate, bounded credits, identity is judged by eye).
|
|
156
|
+
- [docs/ROADMAP.md](docs/ROADMAP.md) — the whole build, session by session, with the drift
|
|
157
|
+
tripwires named in advance.
|
|
158
|
+
- `docs/experiments/` — every non-trivial change runs as a numbered experiment:
|
|
159
|
+
**spec before the work → report after → advisor ruling last.**
|
|
160
|
+
- `docs/license-map.md` — the verified commercial-use map. Nothing enters the pipeline without
|
|
161
|
+
a retrieved license document.
|
|
162
|
+
|
|
163
|
+
The method is inherited from [facet](../facet), where it was paid for: in facet's founding
|
|
164
|
+
session six inherited claims were falsified, each in minutes, because each sat next to runnable
|
|
165
|
+
code. armature is downstream of facet — facet cuts and paints the figure; armature stages and
|
|
166
|
+
performs it.
|
|
167
|
+
|
|
168
|
+
## Running it
|
|
169
|
+
|
|
170
|
+
There is nothing to install. This is a repository you clone and run — no package on any
|
|
171
|
+
registry, no service, no daemon. Every instrument is invoked directly:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
python tools/<name>.py --help # measurement, sheets, payload builders
|
|
175
|
+
blender -b -P tools/stage_render.py -- <args> # staging and render, headless only
|
|
176
|
+
pwsh -NoProfile -File .\verify.ps1 # tests, tests under -O, site build
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
| | |
|
|
180
|
+
|---|---|
|
|
181
|
+
| Platform | Windows 11 on the rig (Omen 45L, RTX 5090). The hermetic tests also run on `ubuntu-latest` in CI; Blender-dependent tests **skip visibly** where Blender is absent rather than passing silently |
|
|
182
|
+
| Python | 3.13+ — CI runs 3.13, the rig venv runs 3.14. Test dependencies are numpy, pillow, pytest, opencv (pinned to the rig's version, because the pose-raster tests assert byte-stable rasterization) and matplotlib |
|
|
183
|
+
| Blender | 5.2, headless only. A live GUI session produces artifacts with no recorded parameters, and a recipe that does not reproduce its output is not a recipe |
|
|
184
|
+
| Node | 22, for the site under `site/` only |
|
|
185
|
+
| Generation | runs on Comfy Cloud and is submitted by the operator; rendering and measurement run locally |
|
|
186
|
+
|
|
187
|
+
Absolute rig paths are baked into many tools and docs — they are not secrets, but they do
|
|
188
|
+
mean most instruments will not run unmodified on another machine.
|
|
189
|
+
|
|
190
|
+
## Standing rules that shape everything here
|
|
191
|
+
|
|
192
|
+
**No non-commercial models, ever — including in experiments.** CC-BY-NC, research-only and
|
|
193
|
+
academic-only licenses are banned outright. A conclusion drawn on a banned model is a
|
|
194
|
+
conclusion that has to be thrown away, so it never starts.
|
|
195
|
+
|
|
196
|
+
**Metrics are diagnostics; the Director judges.** Whether the figure on screen is the same
|
|
197
|
+
character is canon, and no metric approximates it. Every generating experiment builds a
|
|
198
|
+
**control | output | reference | provenance** sheet before a single number is quoted.
|
|
199
|
+
|
|
200
|
+
**Cloud credits are bounded before they are spent.** Spent credits have no undo, so every spec
|
|
201
|
+
states its ceiling per arm in advance.
|
|
202
|
+
|
|
203
|
+
**Routes disclose what rides with them** (the Director's ruling, 2026-08-12). Any route
|
|
204
|
+
through a third-party tier documents its providers' data-use and training posture, its
|
|
205
|
+
AI-content disclosure duties and its watermark policy, grounded in the licence map's fetched
|
|
206
|
+
documents. Fully-local routes state that nothing leaves the rig. A route without its
|
|
207
|
+
disclosure note is not complete — the first application rides E13's spec.
|
|
208
|
+
|
|
209
|
+
## Trust and threat model
|
|
210
|
+
|
|
211
|
+
The full policy is [SECURITY.md](SECURITY.md), measured against the tree rather than asserted.
|
|
212
|
+
The short form:
|
|
213
|
+
|
|
214
|
+
- **Data touched** — meshes, renders, videos, images and JSON on local disk, at paths you pass
|
|
215
|
+
on the command line, plus `docs/index/armature.db`, a SQLite index *derived* from this repo's
|
|
216
|
+
own markdown. Canonical assets are consumed read-only from sibling trees and never written to.
|
|
217
|
+
- **Data NOT touched** — no credentials of any kind: none are read, stored or transmitted, and
|
|
218
|
+
a sweep of every tracked file for provider-prefixed keys, tokens, private-key blocks and
|
|
219
|
+
inline secret assignments returns zero matches. **No telemetry, analytics or usage counting**
|
|
220
|
+
is collected or sent; there is no opt-out because there is nothing to opt out of.
|
|
221
|
+
- **Network egress** — no Python networking library is imported anywhere in `tools/` or
|
|
222
|
+
`tests/`. Two tools shell out to `curl.exe` to download the files listed in a dump *you*
|
|
223
|
+
paste in, from a generation *you* submitted. Nothing else here makes a network call.
|
|
224
|
+
- **Permissions** — ordinary user permissions. No elevation, no service installation, no
|
|
225
|
+
registry or system-settings writes.
|
|
226
|
+
- **The sharp edges, disclosed rather than claimed away** — file operations are not sandboxed;
|
|
227
|
+
a tool writes wherever its arguments say. Unexpected failures print a raw traceback.
|
|
228
|
+
Deliberate refusals do not: every gate raises a typed error carrying the measurement that
|
|
229
|
+
fired it, and **none of them is an `assert`** — the suite runs a second time under `-O` in CI
|
|
230
|
+
to prove they still raise.
|
|
231
|
+
- **Support status** — `main` is the only supported state. No release channel, no backport
|
|
232
|
+
policy, no SLA.
|
|
233
|
+
|
|
234
|
+
**Ship gate.** [SHIP_GATE.md](SHIP_GATE.md) carries the hard gates A–D as they actually stand,
|
|
235
|
+
with every line either checked with its evidence or skipped with the reason on its merits. The
|
|
236
|
+
soft-gate identity items are listed honestly, including the one still open.
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT — see [LICENSE](LICENSE). The license of any *model* used through this tool is a separate
|
|
241
|
+
question, tracked in `docs/license-map.md`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# armature
|
|
2
|
+
|
|
3
|
+
**You block the shot. The model shoots it.**
|
|
4
|
+
|
|
5
|
+
A video model can produce motion, light and life that no renderer can. It cannot be told
|
|
6
|
+
*who is on screen and where they are standing*. armature supplies exactly that: a canonical
|
|
7
|
+
character mesh is staged and animated in headless Blender, and the render becomes a per-frame
|
|
8
|
+
**control sequence** the video model must obey — so AI-generated video can carry one
|
|
9
|
+
persistent main character whose position and pose are known every frame.
|
|
10
|
+
|
|
11
|
+
**armature is image-to-video with a GLB instead of an image.** Everything spatial is
|
|
12
|
+
authored, and the model paints life over it. The deliverable is footage — film, cutscenes,
|
|
13
|
+
character poses and movement, any shot at all. A game is one consumer of that footage, never
|
|
14
|
+
the boundary of the tool.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install armature-studio
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
armature check
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## What this package is
|
|
27
|
+
|
|
28
|
+
The installable package is `armature_core` — the measured pieces of the pipeline, every one
|
|
29
|
+
of which imports under a plain CPython:
|
|
30
|
+
|
|
31
|
+
- **Gates that raise.** `gates`, `route_gates`, `rig_gates`, `donor_gate` — predicates that
|
|
32
|
+
refuse a bad step *inside* the tool performing it, rather than warning beside it.
|
|
33
|
+
- **Framing and turnaround.** `framing`, `turnaround`, `startframe` — perspective and
|
|
34
|
+
orthographic camera solves, shared-scale shot-sets, silhouette extent, and the
|
|
35
|
+
frame-clearance checks that refuse a cropped subject.
|
|
36
|
+
- **Control channels.** `channels`, `openpose`, `aapose`, `landmarks`, `lift_solve` —
|
|
37
|
+
channel maths and pose conventions for driving a video model.
|
|
38
|
+
- **Rig and mesh.** `joints`, `binding`, `parts`, `posearc`, `walk`, `glb`.
|
|
39
|
+
- **Contracts and records.** `shotspec`, `subject`, `sitelist`, `assembly`, `clipstats`,
|
|
40
|
+
`clipcompare`, `pngio`, `errors`.
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from armature_core import turnaround, framing
|
|
44
|
+
|
|
45
|
+
plan = turnaround.projection_plan(ortho=True, ortho_scale=1.1235359256161628)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## What this package is not
|
|
49
|
+
|
|
50
|
+
**The rendering scripts are not console entry points, deliberately.**
|
|
51
|
+
`render_turnaround.py`, `stage_render.py` and their siblings run inside **Blender's own
|
|
52
|
+
interpreter**:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
blender -b -P tools/render_turnaround.py -- --glb subject.glb --out renders --ortho
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A console script installed on your Python could not import `bpy` and would fail on its first
|
|
59
|
+
line, so shipping one would be a promise the package cannot keep. Those scripts live in the
|
|
60
|
+
repository, where the invocation that works is the one written down.
|
|
61
|
+
|
|
62
|
+
`armature_core.blender_scene` is the single module that imports `bpy`. It is packaged, and it
|
|
63
|
+
resolves only under Blender — `armature check` reports it as `needs-blender` rather than as a
|
|
64
|
+
defect.
|
|
65
|
+
|
|
66
|
+
## The discipline this comes from
|
|
67
|
+
|
|
68
|
+
armature is an experiment repository whose product is its record: a spec before the work, a
|
|
69
|
+
report after, a ruling last, and the Director's eye as the verdict of record. Metrics are
|
|
70
|
+
diagnostics and gate nothing on their own. Every generation records its model, payload, seed
|
|
71
|
+
and control hashes, because a recipe that does not reproduce its output is not a recipe. No
|
|
72
|
+
non-commercially-licensed model, weight or dependency enters the pipeline — anywhere,
|
|
73
|
+
including experiments.
|
|
74
|
+
|
|
75
|
+
- **Docs and handbook:** https://mcp-tool-shop-org.github.io/armature/
|
|
76
|
+
- **Repository and the full record:** https://github.com/mcp-tool-shop-org/armature
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
Python 3.10+ and numpy. Blender 5.x is required only for the rendering scripts in the
|
|
81
|
+
repository, not for this package.
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "armature-studio"
|
|
7
|
+
version = "0.2.1"
|
|
8
|
+
description = "Block the shot; the model shoots it — GLB-authored previz, control sequences and gates for video-diffusion generation."
|
|
9
|
+
readme = "README.pypi.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "mcp-tool-shop", email = "64996768+mcp-tool-shop@users.noreply.github.com" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"previz", "blender", "video-diffusion", "controlnet", "turnaround",
|
|
15
|
+
"glb", "character", "animation", "comfyui", "sprite",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Multimedia :: Graphics :: 3D Rendering",
|
|
27
|
+
# "Topic :: Scientific :: Image Processing" does not exist. PyPI rejected the first
|
|
28
|
+
# upload with a 400 on it, and `twine check` had passed — twine validates metadata
|
|
29
|
+
# structure, not classifier membership. The real one carries "/Engineering".
|
|
30
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
31
|
+
]
|
|
32
|
+
dependencies = ["numpy>=1.24"]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = ["pytest>=8.0"]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://mcp-tool-shop-org.github.io/armature/"
|
|
39
|
+
Repository = "https://github.com/mcp-tool-shop-org/armature"
|
|
40
|
+
Changelog = "https://github.com/mcp-tool-shop-org/armature/blob/main/CHANGELOG.md"
|
|
41
|
+
Issues = "https://github.com/mcp-tool-shop-org/armature/issues"
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
armature = "armature_core.cli:main"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools]
|
|
47
|
+
package-dir = { "" = "tools" }
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.packages.find]
|
|
50
|
+
where = ["tools"]
|
|
51
|
+
include = ["armature_core*"]
|
|
52
|
+
|
|
53
|
+
[tool.pytest.ini_options]
|
|
54
|
+
testpaths = ["tests"]
|