rig-parts 2.0.2 → 2.0.4

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.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-38BDF8.svg?style=flat-square" alt="license" /></a>
9
9
  </p>
10
10
 
11
- # @rig-c/parts — CLI `rig-parts`
11
+ # @rig-c/parts
12
12
 
13
13
  **AI-authored 2D character rigs from one anime painting, verified before they
14
14
  are written.** rig-parts generates no images. The painting and See-through layers
@@ -507,6 +507,7 @@ the interface it holds.
507
507
 
508
508
  ## Depth-driven rigging
509
509
 
510
+ [docs/DEPTH.md](docs/DEPTH.md) is the feature page for a person: what a depth-driven turn gives you, the two stages that make the sheets, how to pick a painting and how to judge the result.
510
511
  See the [depth-driven rigging reference](docs/AUTHORING.md#depth-driven-rigging) for sampled head and body turns and unit-depth precedence.
511
512
 
512
513
  ### Per-layer depth input
package/docs/DEPTH.md ADDED
@@ -0,0 +1,250 @@
1
+ # Depth-driven rigging: a painted head that turns with volume
2
+
3
+ Move the pointer across the [head-turn demo](https://rig-c.org/demos/head-turn/)
4
+ and the painted head follows your gaze. The face comes forward, the hair falls
5
+ behind it, the ears keep their place behind the cheeks, and nothing reads as a
6
+ paper cut-out being tilted. That is what depth-driven rigging gives a rig this package
7
+ builds: a head (and, if you want, a body) that answers two dials, `yaw_dial`
8
+ and `pitch_dial`, with that sense of volume. The dials are values, not an
9
+ animation. You decide when they move and what moves them — a pointer, a
10
+ camera, a script — and the rig guarantees the picture holds together inside
11
+ the band it was built for.
12
+
13
+ This page is for a person deciding whether to try it, and then trying it. It
14
+ says what goes in, what each stage prints, how to pick a painting, how to judge
15
+ the result, and where the feature stops. The contract — every field, every
16
+ refusal, every number — stays in [AUTHORING](AUTHORING.md); this page links
17
+ there rather than repeating it.
18
+
19
+ ## The idea at a glance
20
+
21
+ A flat painting has no depth of its own, so the rig borrows some. Every part
22
+ that turns gets a **depth sheet**: a grey image the size of the part where each
23
+ pixel says how far forward that bit of paint sits. When the dial turns, each
24
+ point of the part slides sideways by its depth times the sine of the angle.
25
+ Near points move more, far points move less, and that difference is the
26
+ parallax your eye reads as a solid shape. Small features — eyes, mouth, brows —
27
+ move as one piece at one depth each, so they slide instead of warping. The back
28
+ hair shifts a little the other way, so the head reads as having a back.
29
+
30
+ Where do the sheets come from? From a depth model you run yourself, one part at
31
+ a time. The tools here carry no model, no weights and no downloads; they prepare
32
+ the inputs a model needs, and they turn what it returns into sheets a rig can
33
+ use. Three things we learned the hard way are built into that path:
34
+
35
+ - **One part at a time, on neutral grey.** A depth model shown the whole sheet
36
+ of parts reads it as one object and flattens everything. Shown one part on
37
+ grey, it gives that part its own shape.
38
+ - **The face is the exception.** Depth models misread painted faces — a fringe
39
+ shadow becomes a step in the forehead. So the face takes a *normal* map
40
+ instead, which the tool integrates into a height field and signs by
41
+ convexity (the middle of a face is nearer than its rim). That integration is
42
+ for the face only: it breaks on anything with an occlusion edge, like hair
43
+ strands or a collar.
44
+ - **The numbers that place a part are yours to declare.** A monocular model
45
+ gives relative shape, not scale. How far forward each part sits (its
46
+ `median`) and how deep its own shape is (its `relief`) are declared in rig
47
+ pixels, and the tool never guesses them.
48
+
49
+ See-through, the layer decomposition this package reads, also writes a per-layer
50
+ depth sheet, and a config can register those directly (`config.depth`,
51
+ [Per-layer depth sheets](AUTHORING.md#per-layer-depth-sheets-773)). In
52
+ side-by-side review, per-part maps from a depth model read better by eye than
53
+ a single map of the whole painting, which is why the per-part route below is
54
+ the one this page walks.
55
+
56
+ ## The steps, and what you will see
57
+
58
+ Depth sits between `assemble` and `rig`. You need an assembled build — a
59
+ `parts.json` and its `parts/` — and a character config whose `turn.roles`
60
+ names each part that turns and says what kind it is: `surface` for the parts
61
+ that bend with their sheet (the face, the hair), `unit` for features that move
62
+ as one piece, `rear` for what sits behind the head. A body group is declared
63
+ the same way under `turn.body.roles`. The roles, the dials and the grid the
64
+ surfaces are built on are in [AUTHORING §3, the `turn` row](AUTHORING.md#3-configjson-field-by-field).
65
+
66
+ ### 1. Prepare one inference image per part
67
+
68
+ Write a small recipe — a separate JSON file, not a field on the character
69
+ config — naming the parts you want sheets for, which group each belongs to,
70
+ and the medians and reliefs you declare for them:
71
+
72
+ ```json
73
+ {
74
+ "spec": "rig-parts-depth/1",
75
+ "prepare": {"longSide": 1024, "paddingFraction": 0.08, "padding": 4},
76
+ "groups": {"head": {"near": "white", "zScale": 30, "pivot": 15}},
77
+ "parts": {
78
+ "face": {"map": "face.json", "source": "normals", "frame": "input", "group": "head", "median": 21, "relief": 13},
79
+ "hair_front": {"map": "hair_front.json", "source": "depth", "frame": "input", "group": "head", "median": 21, "relief": 10},
80
+ "hair_back": {"map": "hair_back.json", "source": "depth", "frame": "input", "group": "head", "median": 15, "relief": 9}
81
+ },
82
+ "clear": []
83
+ }
84
+ ```
85
+
86
+ Every number there is an authored choice for one character, not a default; the
87
+ tool has none. Then:
88
+
89
+ ```sh
90
+ rig-parts depth-prepare --parts work/rig --config depth.json --out inference
91
+ ```
92
+
93
+ On the public `demo` example, assembled with its tracked config from the
94
+ painting and layers in [rig-c/examples](https://github.com/rig-c/examples),
95
+ that printed:
96
+
97
+ ```
98
+ depth-prepare: 3 part(s); manifest.json binds crop, padding and source/input hashes
99
+ ```
100
+
101
+ and wrote `inference/face.png`, `inference/hair_front.png`,
102
+ `inference/hair_back.png` — each part upscaled by a whole number until its long
103
+ side is at least the declared size, laid on grey with a margin — and
104
+ `inference/manifest.json`, which records the hashes of the parts, the recipe
105
+ and every image it wrote. That manifest is how the next stage knows the maps
106
+ belong to these parts and nothing moved in between.
107
+
108
+ ### 2. Run your depth model
109
+
110
+ This is your step, with your model, on your machine or wherever you run it.
111
+ Read `inference/<part>.png`, write one numeric map per part as JSON
112
+ (`rig-parts-map/1`: width, height, channels, and the raw floating-point values
113
+ row by row), the same size as the image you read. `"frame": "input"` in the
114
+ recipe is what says so, and the manifest binds it, so choose it before you
115
+ prepare. Scalar depth is one channel; the face's normals are three signed
116
+ channels in image axes. Save the model's actual numbers — a greyscale preview
117
+ has already thrown away the normalisation the next stage needs.
118
+
119
+ What we used: Depth Anything for the parts (V2 Large, and Depth Anything 3's
120
+ monocular model), and Lotus's normal model for the face. Any model that
121
+ returns a dense relative depth will do; the stage after this does not know
122
+ which one you ran. Model licences are the model's own and are not this
123
+ package's to restate — the site's [licensing page](https://rig-c.org/docs/licensing/)
124
+ says where each kind of term sits.
125
+
126
+ ### 3. Apply the maps as depth sheets
127
+
128
+ ```sh
129
+ rig-parts depth-apply --parts work/rig --manifest inference/manifest.json --config depth.json --rig-config config.json --out mapped
130
+ ```
131
+
132
+ For each part it normalises the map inside the part's opaque pixels, places it
133
+ at your declared median and relief, encodes it as a sheet in the group's
134
+ polarity and scale, extends it past the part's edge so there is no cliff at
135
+ the silhouette, and prints one line per part. On a one-part check fixture
136
+ (a synthetic disc, not a painting) the current code prints:
137
+
138
+ ```
139
+ depth-apply: face levels=30 clip=0 reliefRigPixels=10 sign=1
140
+ depth-apply: wrote registered parts, config.json and depth-report.json; run rig for the core gate
141
+ ```
142
+
143
+ `levels` is how many distinct grey levels the sheet uses, `clip` the share of
144
+ pixels that fell outside the group's scale (keep it at or near zero), and
145
+ `sign` the convexity sign the face integration chose. `mapped/` is a complete
146
+ assembled directory: the art unchanged, a `<part>_depth.png` beside each mapped
147
+ part, `parts.json` pointing at them, a copy of your config with the group
148
+ pivots written in, and `depth-report.json` with every number and hash. Nothing
149
+ in `work/rig` or your original config is touched. Any mismatch — a recipe edited
150
+ after prepare, a part that moved, a map of the wrong size, a part your
151
+ `turn.roles` does not name — is refused by name before a byte is written.
152
+
153
+ ### 4. Rig, and look
154
+
155
+ ```sh
156
+ rig-parts rig --parts mapped --config mapped/config.json --out compiled
157
+ ```
158
+
159
+ The rig stage is the ordinary one. With `turn.roles` declared it builds the
160
+ depth-sampled turn: `surface` parts become grids that bend with their sheets,
161
+ `unit` parts ride a carrier at their own depth, and the motion gains `turn` and
162
+ `tilt` animations driven by `yaw_dial` and `pitch_dial` (a body group adds
163
+ `body_yaw_dial`). On the check fixture above the compiled motion carried
164
+ `idle`, `tilt` and `turn`, and the bones `faceshift`, `face_surface`,
165
+ `yaw_dial` and `pitch_dial` beside the head. It also writes
166
+ `depth_sheets.json`, which names every sheet the build consumed. rig-c's gate
167
+ runs as always; nothing is written unless it passes. `check` and `build` go on
168
+ from here as they do for any rig.
169
+
170
+ **Try it today.** The `look` example in
171
+ [rig-c/examples](https://github.com/rig-c/examples/tree/main/look) is a complete
172
+ depth-driven head and body turn you can rebuild, with no model and no GPU. It
173
+ takes the See-through sheets route, so steps 1 to 3 are already done for you:
174
+
175
+ ```sh
176
+ rig-parts assemble --source painting.png --full layers/full --head layers/head --config config.json --out assembled
177
+ rig-parts rig --config config.json --parts assembled/rig --out candidate
178
+ rigc build --rig candidate/rig.json --motion candidate/motion.json --out built --profile rig-play --pack --page-edges free --pack-shape polygon
179
+ ```
180
+
181
+ The motion comes out with `turn`, `tilt` and `body_turn`, and the rig with
182
+ `yaw_dial`, `pitch_dial` and `body_dial`, so `look/config.json` is also a worked
183
+ `turn.roles` to start your own from. To try the per-part route, run
184
+ `depth-prepare` on `assembled/rig` with a recipe like the one above. From step 2
185
+ on, the maps are your model's.
186
+
187
+ ## Picking a painting, and judging what you get
188
+
189
+ **Start from an upright head.** Everything in [PAINTING](PAINTING.md) still
190
+ holds — front view, arms clear, plain background — and depth adds one more
191
+ requirement. The turn rotates the head about upright yaw and pitch axes, so a
192
+ painting whose head is already tilted gets a neck that breaks at the extremes.
193
+ That is an input failure, not a tool failure: pick a painting with the eye
194
+ line level. The rig stage warns by name (`RIG_TURN_HEAD_ROLL`) when the eye
195
+ line it reads is noticeably rolled; take the warning seriously
196
+ ([Head roll before a declared turn](AUTHORING.md#head-roll-before-a-declared-turn)).
197
+
198
+ **Judge it the way a person actually sees it.** Volume is read from gaze-like
199
+ motion — a pointer wandering irregularly in yaw and pitch at once — or from the
200
+ turn combined with a larger movement, such as an arm swinging. A dial swept
201
+ back and forth on its own reads flat, however good the sheets are, so do not
202
+ judge from a sweep or from the `turn` animation played straight through. Put
203
+ the build in a page where the pointer drives both dials; the adapters' look
204
+ example shows [how to bind a pointer to declared sliders](https://github.com/rig-c/adapters/blob/main/examples/look/README.md).
205
+ Separately, render the setup pose and both yaw endpoints and look at their
206
+ difference at native scale: that is where a tear, a clipped sheet or a feature
207
+ sliding off the face shows, and it is a check for defects, not for volume.
208
+
209
+ **Read the report before you read the render.** `depth-report.json` names each
210
+ part's relief, scale and clip fraction. A high clip fraction means the declared
211
+ numbers do not fit the group's scale; fix the recipe, not the render. Small
212
+ units — eyes, mouth, brows, ears — usually look best following the face surface
213
+ rather than carrying a sheet of their own: list them under `clear`, or give
214
+ them an explicit depth under the group's `unitDepths`. Which depth a unit ends
215
+ up using is spelled out in
216
+ [Unit depth precedence](AUTHORING.md#unit-depth-precedence).
217
+
218
+ ## What it will not do
219
+
220
+ - **Depth supplies no unseen drawing.** The rig has one painting. The turn is
221
+ rated for a band around the front view (by default ±15° yaw and ±12° pitch,
222
+ `turn.band`); past it the far cheek and the hidden ear are simply not there.
223
+ A wider turn needs a declared alternate drawing of the face
224
+ (`assemble.alternates`): the build indexes it in `sets.json` with the band's
225
+ threshold, and the player switches to it.
226
+ - **It is a projection, not a 3D head.** Points shift in the picture plane by
227
+ their depth; proportions stay the front view's. There is no lighting, no
228
+ silhouette change, no orbit.
229
+ - **It does not read depth itself.** No model ships here, and nothing here
230
+ estimates depth or judges a map's quality. The report measures the sheet it
231
+ wrote; whether the shape is right is still your eye's call.
232
+ - **It does not fix the input.** A tilted head, a map of the wrong size, a part
233
+ in two islands where normals were asked for — each is warned or refused by
234
+ name, and the remedy is upstream of these commands.
235
+
236
+ ## Where the contract is
237
+
238
+ - [Per-part provider maps](AUTHORING.md#per-part-provider-maps-897): the recipe
239
+ schema, the map format, the normalisation, the normal integration, and the
240
+ `DEPTH_*` refusal table.
241
+ - [Per-layer depth sheets](AUTHORING.md#per-layer-depth-sheets-773): registering
242
+ See-through's own sheets through `config.depth`, and the full surface and
243
+ blended-mesh contract.
244
+ - [`turn`](AUTHORING.md#3-configjson-field-by-field) in the config reference:
245
+ roles, dials, the surface grid and its triangle budget, the rated band.
246
+ - [Refusals](AUTHORING.md#6-refusals-the-rule-and-what-has-to-change): every
247
+ `FAIL` line ends with `(see rig-parts guide <RULE>)`, and that command prints
248
+ the rule's row.
249
+ - For what a turning face can and cannot do with one drawing, rig-c core's
250
+ [face construction guide](https://github.com/rig-c/core/blob/main/docs/FACE.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rig-parts",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "AI-authored 2D character parts from one anime painting and its See-through layer decomposition: measured parts, weighted-mesh rig specs, verified through rig-c before anything is written. A CLI for agents that cannot see the image.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,6 +46,7 @@
46
46
  "src",
47
47
  "workflows",
48
48
  "docs/AUTHORING.md",
49
+ "docs/DEPTH.md",
49
50
  "docs/MIGRATION.md",
50
51
  "docs/PAINTING.md",
51
52
  "docs/STABILITY.md",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rig-parts
3
- description: Turn one anime character painting and its See-through layer decomposition into a verified 2D character rig (Spine 4.3 skeleton data) — measured parts, weighted meshes, bone chains and a looping idle — with rig-parts, which gates everything through rig-c before it is written. Use for a request to rig or animate a single character painting, to check a painting before See-through (rig-parts painting), to run or read rig-parts layers, sheet, assemble, propose, rig, check, loop or build, or to write or fix a rig-parts config.json. Not for cutting art into parts by hand, for authoring a rig from loose PNGs (that is the rigc skill), for lip-sync or swapping a part's image, or for running See-through itself.
3
+ description: Turn one anime character painting and its See-through layer decomposition into a verified 2D character rig (Spine 4.3 skeleton data) — measured parts, weighted meshes, bone chains and a looping idle — with rig-parts, which gates everything through rig-c before it is written. Use for a request to rig or animate a single character painting, to check a painting before See-through (rig-parts painting), to run or read rig-parts layers, sheet, assemble, depth-prepare, depth-apply, propose, rig, check, loop or build, or to write or fix a rig-parts config.json. Not for cutting art into parts by hand, for authoring a rig from loose PNGs (that is the rigc skill), for lip-sync or swapping a part's image, or for running See-through itself.
4
4
  license: MIT
5
5
  compatibility: Requires Bun 1.4 or later (declared in engines.bun >=1.4.0; CI tests latest only). The tool is the npm package @rig-c/parts (npm i -D @rig-c/parts, or bun add -d @rig-c/parts), whose command is rig-parts; @rig-c/core (the rigc command) is installed with it. See-through is run separately.
6
6
  ---
@@ -74,7 +74,10 @@ under that.
74
74
  route; the optional `comfy seethrough` adapter only talks to a ComfyUI box.
75
75
  2. `rig-parts layers <full run>` — read the table. A `WARN PLAN_LAYER_…` line names
76
76
  a layer See-through invented (a translucent haze, or one out of proportion);
77
- the plan step leaves it out and says so in its `notes`.
77
+ the plan step leaves it out and says so in its `notes`. When an input carries no
78
+ depth (`depth_median: null` on every layer, or a PSD), `layers` prints one
79
+ `SKIP depth:` line (manifest order is then the draw order, and `propose --full`
80
+ or `--head` prints `turn: SKIP`) — report it as skipped, never as passed.
78
81
  3. `rig-parts propose --head-box --full <full run> --canvas <W>x<H>` → put
79
82
  `head_box` in the config, run `inputs` again (it now also writes
80
83
  `st_input_head.png`, the crop at that box), and run See-through on the crop.
@@ -142,6 +145,12 @@ under that.
142
145
  (add `--idle-keys direct` when step 6 said so).
143
146
  It stops at the first stage that refuses, printing that stage's lines under
144
147
  `[assemble]`, `[rig]` or `[check]`. Fix what the FAIL line names and build again.
148
+ When a declared head turn (`turn.depths` or `turn.roles`) has an absolute setup
149
+ eye-line roll above `18.485385` degrees, `rig` and `build` print
150
+ `WARN RIG_TURN_HEAD_ROLL` naming the face/eye parts, both eye bones, signed roll
151
+ and limit; it does not refuse the build or change emitted bytes — inspect the neck
152
+ at both yaw/pitch extremes before accepting the turn
153
+ ([Head roll before a declared turn](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#head-roll-before-a-declared-turn)).
145
154
  8. Read `out/check/check.json` — the six judgement lines the same way as the seam
146
155
  and the loop: a FAIL names the field to change (AUTHORING §6);
147
156
  `TEXTURE_STRETCH` names the worst mesh triangle (slot, triangle, vertices, edge,
@@ -178,6 +187,33 @@ nothing detects or separates people. Report the plate's provenance as you declar
178
187
  it and the order as `scene.json` records it (AUTHORING §7, *Composing several
179
188
  characters*).
180
189
 
190
+ Depth-driven 2.5D turns ([Depth-driven rigging](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#depth-driven-rigging)):
191
+ `depth_filename` is a legacy hint and activates nothing on its own. Declare
192
+ `config.depth` with positive finite `zScale` (`near: "black"` for See-through's
193
+ far-high sheets, or user fallbacks under `depth.full` / `depth.head`, and
194
+ `comfy seethrough --config <file> --depth-run <full|head>` when fetching from
195
+ ComfyUI; [Per-layer depth sheets](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#per-layer-depth-sheets-773)
196
+ and [Per-layer depth input](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#per-layer-depth-input)),
197
+ then map parts in `turn.roles` (head `yaw_dial`/`pitch_dial`) and `turn.body.roles`
198
+ (independent `body_yaw_dial` or `turn.body.slider`) as `"surface"` (grid or authored
199
+ weighted meshes; `auto` is refused by `CONFIG_TURN_SURFACE_AUTO`), `"unit"` or
200
+ `"rear"`. A `"unit"` part's depth resolves by `unitDepths.<part>` →
201
+ `unitDepths.<bone>` → primary surface sheet before the part's own sheet
202
+ ([Unit depth precedence](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#unit-depth-precedence)).
203
+ When depth comes from external per-part provider maps (`rig-parts-depth/1` recipe
204
+ and `rig-parts-map/1` float JSON maps, run after `assemble` and before `rig`), run
205
+ `rig-parts depth-prepare --parts <assembled> --config <depth.json> --out <inference>`
206
+ and `rig-parts depth-apply --parts <assembled> --manifest <manifest.json> --config <depth.json> --rig-config <config.json> --out <mapped>`;
207
+ non-empty output (`DEPTH_OUTPUT_EMPTY`), stale input bindings (`DEPTH_INPUT_BINDING`),
208
+ `authored-unit` provenance (`DEPTH_AUTHORED_UNIT_CONFLICT`), flat maps with nonzero
209
+ relief (`DEPTH_MAP_SPREAD`) and multi-island or non-convex normal maps
210
+ (`DEPTH_NORMAL_*`) are refused by name
211
+ ([Per-part provider maps](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#per-part-provider-maps-897)
212
+ and [Depth sheet refusals](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#depth-sheet-refusals-773)).
213
+
214
+ `assemble.seam` (`"near-white"` or `"silhouette"` in `config.json`, overridden by
215
+ `--seam`; [AUTHORING §3](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#3-configjson-field-by-field)
216
+ and [§5](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md#5-after-each-stage-what-to-read)):
181
217
  `--seam silhouette` repairs more of the seam on white garments than the default
182
218
  `near-white` (reference-demo: 10,340 → 8,644 recomposite error pixels); the default is
183
219
  the reference implementation's rule. `--project visible` lets thin visible parts