rig-parts 1.5.4 → 1.5.5
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/NOTICE.md +23 -10
- package/README.md +51 -52
- package/docs/AUTHORING.md +114 -105
- package/docs/STABILITY.md +1 -1
- package/package.json +1 -1
- package/skills/rig-parts/SKILL.md +2 -2
package/NOTICE.md
CHANGED
|
@@ -96,16 +96,29 @@ ships none and downloads none, and the terms that govern an image they produce
|
|
|
96
96
|
are the terms of those models. A painting from any other source works the same
|
|
97
97
|
way.
|
|
98
98
|
|
|
99
|
-
The images this repository ships
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
[
|
|
99
|
+
The images this repository ships, and the public examples' paintings, were
|
|
100
|
+
generated with one of two checkpoints, with no LoRA; neither checkpoint is
|
|
101
|
+
redistributed.
|
|
102
|
+
|
|
103
|
+
- `assets/demo-*` and the `demo` example's painting (since issue #227):
|
|
104
|
+
`hassakuXLIllustrious_v13StyleA.safetensors`,
|
|
105
|
+
[Hassaku XL (Illustrious)](https://civitai.com/models/140272) v1.3 Style A, by
|
|
106
|
+
Ikena. Credit, as sharing it requires: *Painted with Hassaku XL (Illustrious)
|
|
107
|
+
v1.3 Style A by Ikena (https://civitai.com/models/140272), Fair AI Public
|
|
108
|
+
License 1.0-SD.* **[observed 2026-10-11]** The model page's version and licence
|
|
109
|
+
section reads "All Models using the Fair AI Public License 1.0-SD license", and
|
|
110
|
+
CivitAI's model API reported `allowCommercialUse: ["RentCivit", "Rent", "Image"]`,
|
|
111
|
+
`allowNoCredit: false`, `allowDerivatives: true` and `allowDifferentLicense: false`.
|
|
112
|
+
- `assets/sample-parts.png` and the `scarf`, `reference-sample` and `reference-demo`
|
|
113
|
+
paintings: `ponyDiffusionV6XL_v6StartWithThisOne.safetensors`,
|
|
114
|
+
[Pony Diffusion V6 XL](https://civitai.com/models/257749). **[observed
|
|
115
|
+
2026-09-27]** CivitAI's model API reported for it `allowCommercialUse: ["Image",
|
|
116
|
+
"RentCivit"]`, `allowNoCredit: false`, `allowDerivatives: true` and
|
|
117
|
+
`allowDifferentLicense: false`: generated images may be used commercially and
|
|
118
|
+
the model must be credited, which this line does.
|
|
119
|
+
|
|
120
|
+
The [parts-examples](https://github.com/rig-c/parts-examples) README records
|
|
121
|
+
both, beside each character's generation record.
|
|
109
122
|
|
|
110
123
|
## 4. Behaviour reimplemented, not code copied
|
|
111
124
|
|
package/README.md
CHANGED
|
@@ -14,57 +14,45 @@ input is silent.
|
|
|
14
14
|
## What you get
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-source.png" alt="The demo painting: a generated full-body character in a white and pink
|
|
17
|
+
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-source.png" alt="The demo painting: a generated full-body character in a white and pink idol dress with a layered skirt and long pink twin tails, standing with her arms held away from her body and her hands open" height="420" />
|
|
18
18
|
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-idle.png" alt="The same character rigged, breathing, blinking once and swaying her hair, sleeves and skirt in a four-second loop" height="420" />
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
21
|
<p align="center">
|
|
22
|
-
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-parts.png" alt="Contact sheet of the painting and the
|
|
22
|
+
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-parts.png" alt="Contact sheet of the painting and the 23 assembled parts it was split into: hair, sleeves, legs, boots, neck, skirt, bodice, earrings, hair ornaments, ears, face, brows, mouth and eyes" width="100%" />
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
<p align="center"><em>
|
|
26
|
-
The painting was generated for this repository with a public checkpoint (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
The painting was generated for this repository with a public checkpoint (Hassaku XL
|
|
27
|
+
(Illustrious) v1.3 Style A, by Ikena, Fair AI Public License 1.0-SD) and no LoRA, on a
|
|
28
|
+
pose that holds the hands apart, then given one hand-detailer pass; its generation
|
|
29
|
+
record, See-through layers and licence are in
|
|
30
|
+
<a href="https://github.com/rig-c/parts-examples">parts-examples</a>.
|
|
30
31
|
See-through ran twice, once on the whole figure and once on a square head crop.
|
|
31
|
-
Then one command: <code>rig-parts build --
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(a plan edit).
|
|
32
|
+
Then one command: <code>rig-parts build --loop</code>. The proposer's bones, meshes,
|
|
33
|
+
regions and motion were used as proposed but for one correction, written in the
|
|
34
|
+
config beside the values it replaced: the two outer skirt chains were moved out to
|
|
35
|
+
0.8 of the skirt's half-width (the proposal's, within 90 px of the centre of a skirt
|
|
36
|
+
449 px wide, swung it about its middle and failed <code>TIP_OVER_ROOT</code>, 0.442
|
|
37
|
+
against 1.4725; moved, 2.425). One input-stage edit: <code>hair_back</code> is taken
|
|
38
|
+
from the full run, because the twin tails leave the head crop sideways (a plan edit).
|
|
39
|
+
<code>check</code> printed, verbatim:<br/>
|
|
38
40
|
<code>50 assertions: 24 measured (24 passed, 0 failed), 26 skipped, 0 not in profile "spine-html"</code><br/>
|
|
39
41
|
<code>loop: idle 49 frame(s) at 12 fps, f0000 vs f0048 (t = 4s): max |d| 0 (0 required)</code><br/>
|
|
40
|
-
<code>seam: setup pose at
|
|
41
|
-
<code>pack: skeleton.png
|
|
42
|
-
<code
|
|
43
|
-
|
|
44
|
-
<code>near-white</code>, the reference implementation's rule, so the examples stay
|
|
45
|
-
comparable with it. The loop is <code>rig-parts loop --palette</code>'s indexed APNG, 48 frames at
|
|
46
|
-
12 fps, 1,706,719 bytes, one 256-entry palette at a measured error of max 57, mean 1.601
|
|
42
|
+
<code>seam: setup pose at 654x1216, scale 0.9438: mean |d| 0.147 (<= 1.0), 0 px over 40, 0.00 rig px (the count / s²; <= 50), 0 px over 80 (reported)</code><br/>
|
|
43
|
+
<code>pack: skeleton.png 1051x972, 23 region(s), 96.9% covered, padding 2, page edges free, shape polygon</code><br/>
|
|
44
|
+
The loop is <code>rig-parts loop --palette</code>'s indexed APNG, 48 frames at
|
|
45
|
+
12 fps, 827,857 bytes, one 256-entry palette at a measured error of max 65, mean 0.879
|
|
47
46
|
per channel over every frame (the lossless APNG beside it, the exactness record, is
|
|
48
|
-
|
|
49
|
-
closed eye: the blink holds for 0.084 s, one 12 fps frame rounded up
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
made the contact sheet.
|
|
47
|
+
5,832,634 bytes; the GIF, at the same error, 889,063). Frame 29 (2.417 s) is the
|
|
48
|
+
closed eye: the blink holds for 0.084 s, one 12 fps frame rounded up; the painting is
|
|
49
|
+
shown at half size, resampled and written by this package's PNG codec (nothing here
|
|
50
|
+
encodes JPEG). <code>rig-parts sheet</code> made the contact sheet. Its
|
|
51
|
+
<code>expected/</code> is this port's own build (<a href="examples/demo/README.md">examples/demo</a>).
|
|
54
52
|
</em></p>
|
|
55
53
|
|
|
56
|
-
<p align="center">
|
|
57
|
-
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/sample-parts.png" alt="Contact sheet of the sample character's painting and its 20 parts" width="560" />
|
|
58
|
-
</p>
|
|
59
|
-
|
|
60
54
|
<p align="center"><em>
|
|
61
|
-
The
|
|
62
|
-
built from its own proposal with no hand edit at all —
|
|
63
|
-
<code>seam: setup pose at 379x1216, scale 1.0116: mean |d| 0.204 (<= 1.0), 2 px over 40, 1.95 rig px (the count / s²; <= 50), 0 px over 80 (reported)</code>, loop max |d| 0.
|
|
64
|
-
</em></p>
|
|
65
|
-
|
|
66
|
-
<p align="center"><em>
|
|
67
|
-
The hanging element, <code>examples/scarf</code>: same checkpoint, no LoRA, a very long
|
|
55
|
+
The hanging element, <code>examples/scarf</code>: Pony Diffusion V6 XL, no LoRA, a very long
|
|
68
56
|
red scarf whose ends hang free, and the first character run through this pipeline
|
|
69
57
|
with its proposal used unedited — the only hand corrections are four
|
|
70
58
|
<code>assemble.patches</code>, each answering an <code>uncovered hole</code> line.
|
|
@@ -73,6 +61,15 @@ switched to the contour mode. It has no reference output: its <code>expected/</c
|
|
|
73
61
|
is this port's own build (<a href="examples/scarf/README.md">examples/scarf</a>).
|
|
74
62
|
</em></p>
|
|
75
63
|
|
|
64
|
+
<p align="center"><em>
|
|
65
|
+
Two more characters are tracked as fixtures and not shown:
|
|
66
|
+
<code>examples/reference-demo</code> and <code>examples/reference-sample</code>, the two
|
|
67
|
+
the reference implementation ran (published as <code>demo</code> and <code>sample</code>
|
|
68
|
+
until issue #227, which took the clasped-hands painting off display). Their
|
|
69
|
+
<code>expected/</code> is that implementation's own output, which the selftest holds
|
|
70
|
+
this port to.
|
|
71
|
+
</em></p>
|
|
72
|
+
|
|
76
73
|
## What it takes in
|
|
77
74
|
|
|
78
75
|
- **One painting** — a PNG of one character, front-facing, full body, taller than
|
|
@@ -102,7 +99,7 @@ page** (issue #2):
|
|
|
102
99
|
|
|
103
100
|
| path under `--out` | what |
|
|
104
101
|
| --- | --- |
|
|
105
|
-
| `check/build/skeleton.json`, `skeleton.atlas`, `skeleton.png` | **the artifact** — Spine 4.3 skeleton data and one packed page, written by `rigc build --pack --page-edges free --pack-shape polygon` and gated under `spine-html`, which holds every rule `spine` measures (on
|
|
102
|
+
| `check/build/skeleton.json`, `skeleton.atlas`, `skeleton.png` | **the artifact** — Spine 4.3 skeleton data and one packed page, written by `rigc build --pack --page-edges free --pack-shape polygon` and gated under `spine-html`, which holds every rule `spine` measures (on reference-demo, rigc 2.1.3 and 2.10.1: the 14 rules `validate --profile spine` measures are among the build's 24; 16 are not in `spine`) |
|
|
106
103
|
| `parts/*.png`, `parts.json`, `recomposite_rig.png`, `recomposite_error_rig.png` | the loose parts, each cropped to its alpha box; the record of where every part came from, how many of its pixels were re-taken from the painting, and the recomposite's uncovered holes with their boxes; the flat stack of parts; its error map — red where no part covers a pixel the painting has, blue where a part covers it in the wrong colour |
|
|
107
104
|
| `rig/` | `rig.json` and `motion.json` in rig-c's spec, `mesh_report.json`, the padded `images/` |
|
|
108
105
|
| `check/` | both gate files verbatim, the idle's frames and their `geometry.json` (skinned vertices per frame), `contact.png`, `motion_heat.png`, `check.json` (with `pack_mode`, the `--page-edges` and `--pack-shape` the page was packed under) |
|
|
@@ -110,7 +107,7 @@ page** (issue #2):
|
|
|
110
107
|
|
|
111
108
|
The last lines of a green build are the pack line, printed beside the Spine example
|
|
112
109
|
export's `spineboy.png` as a yardstick (a reference, not a bar), and the three
|
|
113
|
-
artifact paths — here for `examples/sample`:
|
|
110
|
+
artifact paths — here for `examples/reference-sample`:
|
|
114
111
|
|
|
115
112
|
```
|
|
116
113
|
build: PASS — the packed atlas is the artifact; parts/ and rig/ are the intermediates it was made from
|
|
@@ -121,7 +118,7 @@ build: PASS — the packed atlas is the artifact; parts/ and rig/ are the interm
|
|
|
121
118
|
```
|
|
122
119
|
|
|
123
120
|
The page's edges are free by default: rigc picks the least-area page the parts need,
|
|
124
|
-
not the next power of two. On the two examples, packed by rectangles, that is 967x1338
|
|
121
|
+
not the next power of two. On the two reference examples, packed by rectangles, that is 967x1338
|
|
125
122
|
and 479x1166, where a power-of-two page is 1024x2048 and 512x2048, and covered goes from 56.3 % to 91.2 % and
|
|
126
123
|
from 49.7 % to 93.4 %. The cost is the one rigc's help states: *"region attachments
|
|
127
124
|
sampling within 1 LSB of the loose build rather than exactly"*. Measured on both
|
|
@@ -192,8 +189,8 @@ head run on `st_input_head.png` is what gives the eyes more pixels
|
|
|
192
189
|
**See-through is required; ComfyUI is not.** The wrapper is one route among
|
|
193
190
|
four, and `rig-parts comfy` is only a convenience for that route: every
|
|
194
191
|
stage after See-through reads files, whichever route wrote them. On the two
|
|
195
|
-
|
|
196
|
-
`meta.json`, in [
|
|
192
|
+
reference examples each run took 171–199 s through the wrapper, and on the demo 179 s (each run's
|
|
193
|
+
`meta.json`, in [parts-examples](https://github.com/rig-c/parts-examples)).
|
|
197
194
|
|
|
198
195
|
### The two images See-through is fed: `inputs`
|
|
199
196
|
|
|
@@ -346,9 +343,9 @@ for each — a config fragment, the `check` lines it passes with, and its limit:
|
|
|
346
343
|
image; `check` measures the idle alone.
|
|
347
344
|
- [**A soft region driven by physics**](docs/AUTHORING.md#recipe-a-soft-region-driven-by-physics)
|
|
348
345
|
(a bust, the hips): a bone the config authors, a contour-mode region that hands it the patch,
|
|
349
|
-
and a `physics` constraint on it; `examples/sample` carries one. Under
|
|
346
|
+
and a `physics` constraint on it; `examples/reference-sample` carries one. Under its slow
|
|
350
347
|
4 s idle the bust moves at most 0.066 rig px and the hips not at all: the spring answers
|
|
351
|
-
faster keys on the body.
|
|
348
|
+
faster keys on the body. Its `hop`, a named animation keying only `hip`, moves the
|
|
352
349
|
bust up to 6.583 and the hips up to 4.432 rig px; the region's `band` caps how far a patch may
|
|
353
350
|
go before the texture-stretch ceiling, and `check` measures the idle alone.
|
|
354
351
|
|
|
@@ -357,15 +354,16 @@ for each — a config fragment, the `check` lines it passes with, and its limit:
|
|
|
357
354
|
`parts.json` splits each part's opaque pixels (`opaque_px`) into `visible_px` — no
|
|
358
355
|
later layer of its See-through run is opaque in front of them — and `occluded_px`,
|
|
359
356
|
and counts the visible ones whose colour was not taken from the painting
|
|
360
|
-
(`visible_not_projected_px`). On the
|
|
357
|
+
(`visible_not_projected_px`). On the four examples, from the totals of their
|
|
361
358
|
`expected/parts.json` (the default `--project core`; `scarf`'s painting patches are
|
|
362
359
|
whole painting pixels, so they count as taken):
|
|
363
360
|
|
|
364
361
|
| | opaque px | occluded | visible, not projected | taken from the painting |
|
|
365
362
|
| --- | --- | --- | --- | --- |
|
|
366
|
-
| `
|
|
367
|
-
| `demo` | 765,924 | 202,343 (26.4 %) | 75,626 (9.9 %) | 487,955 (63.7 %) |
|
|
363
|
+
| `demo` | 362,441 | 69,098 (19.1 %) | 67,164 (18.5 %) | 226,179 (62.4 %) |
|
|
368
364
|
| `scarf` | 283,813 | 78,503 (27.7 %) | 56,699 (20.0 %) | 148,611 (52.4 %) |
|
|
365
|
+
| `reference-sample` | 298,363 | 79,122 (26.5 %) | 35,979 (12.1 %) | 183,262 (61.4 %) |
|
|
366
|
+
| `reference-demo` | 765,924 | 202,343 (26.4 %) | 75,626 (9.9 %) | 487,955 (63.7 %) |
|
|
369
367
|
|
|
370
368
|
The occluded share is art the painting does not show — a back-hair layer, a neck, the
|
|
371
369
|
parts of an ear under the hair — and is See-through's synthesis by necessity; it is
|
|
@@ -373,18 +371,19 @@ what the decomposition is for. The visible-but-not-projected share is synthesis
|
|
|
373
371
|
the painting was there to be taken: a part too thin for the reference rule's 5x5
|
|
374
372
|
eroded core, an anti-aliased fringe below alpha 250, a rim beside a layer in front, a
|
|
375
373
|
pixel refused for drift. `--project visible` keeps the erosion only along a rim with a
|
|
376
|
-
layer in front, which takes that share to 22,476 (7.5 %) on `sample` and 49,672 (6.5 %)
|
|
377
|
-
on `demo` (from the `parts.json` of a `--project visible` build). On the eleven thin
|
|
374
|
+
layer in front, which takes that share to 22,476 (7.5 %) on `reference-sample` and 49,672 (6.5 %)
|
|
375
|
+
on `reference-demo` (from the `parts.json` of a `--project visible` build). On the eleven thin
|
|
378
376
|
head parts — brows, lashes, irises, eye whites, ears, mouth — it takes 296 of
|
|
379
|
-
`sample`'s 1,289 visible pixels where `core` takes 110, and 824 of `demo`'s 2,162
|
|
377
|
+
`reference-sample`'s 1,289 visible pixels where `core` takes 110, and 824 of `reference-demo`'s 2,162
|
|
380
378
|
where `core` takes 343. What neither rule takes is the fringe: a per-pixel
|
|
381
379
|
classification of those parts under `visible`, recorded with the change that added
|
|
382
|
-
the flag, puts 813 of `sample`'s 993 still-unprojected pixels and 879 of `demo`'s
|
|
380
|
+
the flag, puts 813 of `reference-sample`'s 993 still-unprojected pixels and 879 of `reference-demo`'s
|
|
383
381
|
1,338 below alpha 250. Where such a fringe keeps the stack off the painting and a part
|
|
384
382
|
beneath holds the pixel in the painting's colour, `assemble` clears it instead, and
|
|
385
383
|
the assemble line and `parts.json` say how many pixels, of which part, over which
|
|
386
384
|
(AUTHORING §5, *The fringe push-back*; the figures in this section were measured
|
|
387
|
-
before it, at v0.14.0
|
|
385
|
+
before it, at v0.14.0, but for the `demo` row, which is its `expected/parts.json`
|
|
386
|
+
as this port wrote it in issue #227).
|
|
388
387
|
|
|
389
388
|
## Requirements
|
|
390
389
|
|
package/docs/AUTHORING.md
CHANGED
|
@@ -6,12 +6,19 @@ the files it writes. Every refusal the tool prints names a rule, an object, the
|
|
|
6
6
|
value found and the value required — §6 maps each rule to the field or input that
|
|
7
7
|
has to change.
|
|
8
8
|
|
|
9
|
-
The worked example throughout is [`examples/sample`](../examples/sample): its
|
|
9
|
+
The worked example throughout is [`examples/reference-sample`](../examples/reference-sample): its
|
|
10
10
|
`config.json` is a complete, loading config, `proposal.json` is what the proposer
|
|
11
11
|
wrote for it, and `expected/` is what the reference implementation produced from
|
|
12
12
|
the same inputs — except `check.json`, which this port's `build` regenerates since
|
|
13
13
|
the reference has no judgement lines (§7). `bun run fetch-examples` puts its painting and See-through layers
|
|
14
|
-
into `examples/sample/inputs/`.
|
|
14
|
+
into `examples/reference-sample/inputs/`.
|
|
15
|
+
|
|
16
|
+
The examples' names: `reference-sample` and `reference-demo` are the two characters
|
|
17
|
+
the reference implementation ran (published as `sample` and `demo` until issue #227),
|
|
18
|
+
kept as fixtures because their `expected/` is that implementation's own output; every
|
|
19
|
+
figure this guide quotes for them was measured on them. `demo` is the painting the
|
|
20
|
+
README shows since issue #227 and `scarf` the hanging-element example; both have
|
|
21
|
+
`expected/` from this port's own build, and a figure quoted for them says so.
|
|
15
22
|
|
|
16
23
|
## 1. Prerequisites
|
|
17
24
|
|
|
@@ -244,8 +251,8 @@ box every rule scales by is derived from the head run's hair (`front hair`,
|
|
|
244
251
|
`back hair`: their highest top) and its `neck` (its top, and its centre x for the
|
|
245
252
|
axis): with `L` the span from the hair's top to the neck's top, the face is
|
|
246
253
|
1.067 `L` tall, its top 0.131 `L` below the hair's, its width 0.798 of its height.
|
|
247
|
-
Those ratios are the means of the two public examples (`demo` 1.073 / 0.105 /
|
|
248
|
-
0.820, `sample` 1.061 / 0.158 / 0.777) — a sample of two. On each example
|
|
254
|
+
Those ratios are the means of the two public examples (`reference-demo` 1.073 / 0.105 /
|
|
255
|
+
0.820, `reference-sample` 1.061 / 0.158 / 0.777) — a sample of two. On each example
|
|
249
256
|
re-assembled without its face, the derived box put `head` and `neck` within
|
|
250
257
|
5.0 px (0.038 face heights) of the with-face proposal's, `chest` and `hip` at
|
|
251
258
|
the same pixel. The first note says so —
|
|
@@ -270,7 +277,7 @@ Two rules read the figure rather than one tag, and each says so in a note:
|
|
|
270
277
|
0.8 of the shoulders — or `hip from 0.32 of figure height (no waist found: …)`,
|
|
271
278
|
naming why. Without `bottomwear` the hip is 0.32 of the figure height, as before
|
|
272
279
|
(`no bottomwear: hip from 0.32 of figure height`). Neither published example
|
|
273
|
-
meets either branch: their hips sit at 0.436 (`demo`) and 0.342 (`sample`) of
|
|
280
|
+
meets either branch: their hips sit at 0.436 (`reference-demo`) and 0.342 (`reference-sample`) of
|
|
274
281
|
their figures.
|
|
275
282
|
- **Clasped hands.** When every `handwear` part together is one blob (over
|
|
276
283
|
500 px) at most half the shoulders' width and centred within a quarter of it
|
|
@@ -289,7 +296,7 @@ sub-shape of the layer's **pendant rows** (the run of rows at the bottom narrowe
|
|
|
289
296
|
than 35 % of its widest row; the whole layer for `earwear` or a layer that is over
|
|
290
297
|
80 % pendant) that is at least **3×** as tall as wide, at least **0.2** of the
|
|
291
298
|
layer's height and at least **10** rows. On the public examples nothing is one: the
|
|
292
|
-
demo's hairpin pendant sub-shapes measure 0.54 and 0.89 tall-per-wide and its
|
|
299
|
+
reference-demo's hairpin pendant sub-shapes measure 0.54 and 0.89 tall-per-wide and its
|
|
293
300
|
earrings 1.04 and 1.08, so both proposals are unchanged. Every layer with strands
|
|
294
301
|
gets exactly one note carrying each strand's column centroid, first–last row and
|
|
295
302
|
width, and what became of it (two of the selftest's fixtures, PR12 and PR15):
|
|
@@ -323,7 +330,7 @@ the eyewhite's top with no art across its whole width, the lowest such row is pr
|
|
|
323
330
|
`motion.blink.still` on `head`, and the rows above it stop blinking; when it has none, the
|
|
324
331
|
note says so and nothing is cut — clear a row between the crease and the lash line in the
|
|
325
332
|
part, or leave the crease to blink. The cut has to be a clear row: two pieces cut through
|
|
326
|
-
art are each resampled against their own transparent edge, and on the demo example a cut
|
|
333
|
+
art are each resampled against their own transparent edge, and on the reference-demo example a cut
|
|
327
334
|
through its lash line changed 36 px of the setup-pose render (up to 7 levels, at render
|
|
328
335
|
scale 0.942) and up to 21 levels in the idle frames where the head rolls; a clear-row cut
|
|
329
336
|
changed none, at rest or rolled. The eye bone is not moved: scaling about the eyewhite's
|
|
@@ -442,23 +449,23 @@ crescent; the other four 1.5 or less). No cell refused overshoot, and along each
|
|
|
442
449
|
a margin passed every larger one passed — where the offset this replaced moved an acute corner
|
|
443
450
|
up to 4 × margin and closed the window from above. That is the generated shapes: on a real part
|
|
444
451
|
a larger margin can close a gap whose enclosed pocket lies further from the art than the bound,
|
|
445
|
-
which the overshoot check refuses (
|
|
452
|
+
which the overshoot check refuses (reference-demo's hairpin builds at margin 1 and refuses at 1.5, 2
|
|
446
453
|
and 3: 5.39 px). On the public examples at tolerance 1, margin 1, `stray` 4 and spacing = the
|
|
447
|
-
part's grid, 13 of the 14 mesh parts build; the 14th is
|
|
454
|
+
part's grid, 13 of the 14 mesh parts build; the 14th is reference-demo's earring, two pieces.
|
|
448
455
|
|
|
449
|
-
**When not to use it.** A part that is two pieces (
|
|
456
|
+
**When not to use it.** A part that is two pieces (reference-demo's earring: 411 and 358 px) — keep
|
|
450
457
|
the lattice, which bridges islands, or split the part. And a part nothing deforms locally: at
|
|
451
458
|
tolerance 1 the contour outline is dense, and on the examples' 13 parts the contour mesh used
|
|
452
|
-
more vertices than the lattice at the same spacing (demo 1785 against 1431, sample 974 against
|
|
453
|
-
852) while enclosing 5.8 and 9.8 times less transparent area (demo 25078 against 144782 px², sample
|
|
459
|
+
more vertices than the lattice at the same spacing (reference-demo 1785 against 1431, reference-sample 974 against
|
|
460
|
+
852) while enclosing 5.8 and 9.8 times less transparent area (reference-demo 25078 against 144782 px², reference-sample
|
|
454
461
|
6563 against 64445), with thinner triangles — smallest angles 2.46°–11.31° against the lattice's
|
|
455
|
-
12.09°–45° (#106). Switched, every part that builds:
|
|
456
|
-
`TEXTURE_STRETCH` 1.227 → 1.384, ceiling 1.927);
|
|
462
|
+
12.09°–45° (#106). Switched, every part that builds: reference-sample passes `check` (9 of 9;
|
|
463
|
+
`TEXTURE_STRETCH` 1.227 → 1.384, ceiling 1.927); reference-demo's gate is green but `check` refuses
|
|
457
464
|
`TEXTURE_STRETCH` on its back hair (2.535: an edge of a contour triangle squeezed to 0.394 of
|
|
458
465
|
its length in the idle), and with the back hair left on the lattice it passes 9 of 9 (1.388 →
|
|
459
466
|
1.68).
|
|
460
467
|
|
|
461
|
-
**Why
|
|
468
|
+
**Why reference-demo's back hair fails, and what passes** (issue #115). The squeezed edge is an
|
|
462
469
|
outline edge 2 px long, near the hair's tip, whose two ends sit either side of a step in the
|
|
463
470
|
weight field: one end keeps `hairback_l1` at 0.031, the other drops it, because a weight under
|
|
464
471
|
0.03 is dropped (`src/weights.ts`, the reference's `>= 0.03`). `hairback_l1` and `hairback_r2`
|
|
@@ -469,7 +476,7 @@ gives 1.316 on the contour mesh and 1.336 on the lattice: the lattice's 36 px ed
|
|
|
469
476
|
step, the outline's 2 px edges show it. Interior vertices cannot change it — an outline edge is
|
|
470
477
|
in every triangulation — so the background spacing does not move the figure (36, 24, 18 and
|
|
471
478
|
12 px all give 2.535). Raising `tolerance` to 1.5 removes every short edge across a step (the
|
|
472
|
-
shortest is then 8.2 px) and the part passes (1.345; with every buildable demo part switched,
|
|
479
|
+
shortest is then 8.2 px) and the part passes (1.345; with every buildable reference-demo part switched,
|
|
473
480
|
`check` passes 9 of 9 at 1.68), at 313 vertices against the lattice's 268 and 18155.5 px²
|
|
474
481
|
enclosed against 58346. The window is one value wide on this part: 1.25 keeps the same 2 px
|
|
475
482
|
edge (2.535) and 1.75 leaves art uncovered at margin 1. No other switched part of either
|
|
@@ -481,7 +488,7 @@ generated fixture of `tools/local_compare.ts` it reached a local shape error (0.
|
|
|
481
488
|
in #106, the same figures).
|
|
482
489
|
|
|
483
490
|
**On real parts the generated result did not carry over unchanged** (issues #107 and #110,
|
|
484
|
-
`bun tools/real_compare.ts --work <dir> --examples demo,sample --builds --sweep`, a declared test region on two demo
|
|
491
|
+
`bun tools/real_compare.ts --work <dir> --examples reference-demo,reference-sample --builds --sweep`, a declared test region on two reference-demo
|
|
485
492
|
parts — a place to measure, not a claim about the painting; the region spacing chosen by vertex
|
|
486
493
|
count alone). On `bottomwear` (a region of radius 65 px inside the part) the contour mesh passes
|
|
487
494
|
the same rule: 336 vertices against the lattice's 352, largest local shape error 1.535 px against
|
|
@@ -922,7 +929,7 @@ that crosses the region with no point of it inside to split at — is still stop
|
|
|
922
929
|
### Recipe: expressions and other named animations
|
|
923
930
|
|
|
924
931
|
The package proposes no expression and keys nothing but the idle; what it gives is a rig whose
|
|
925
|
-
face is bones (`eye_r`, `eye_l`, `brow_r`, `brow_l`, `mouth` on `sample`) and one door for
|
|
932
|
+
face is bones (`eye_r`, `eye_l`, `brow_r`, `brow_l`, `mouth` on `reference-sample`) and one door for
|
|
926
933
|
animations you write over them, `motion.animations_from` (the row above, issue #183). Write a
|
|
927
934
|
file in rig-c's motion-spec shape beside the config and name it:
|
|
928
935
|
|
|
@@ -941,8 +948,8 @@ file in rig-c's motion-spec shape beside the config and name it:
|
|
|
941
948
|
```
|
|
942
949
|
|
|
943
950
|
`build` writes `surprised` into `rig/motion.json` after `idle`, gates it with the rig, and
|
|
944
|
-
`check` names it on a line of its own (`examples/sample` carries one, `animations.json` with `hop`, the
|
|
945
|
-
recipe below). With exactly this file beside `examples/sample`'s config in its place,
|
|
951
|
+
`check` names it on a line of its own (`examples/reference-sample` carries one, `animations.json` with `hop`, the
|
|
952
|
+
recipe below). With exactly this file beside `examples/reference-sample`'s config in its place,
|
|
946
953
|
`build` printed (this tree, rig-c as `package.json` pins it):
|
|
947
954
|
|
|
948
955
|
```
|
|
@@ -963,7 +970,7 @@ passed rigc's gate and nothing else — no seam, stretch or hole bar has read it
|
|
|
963
970
|
|
|
964
971
|
A jiggle (a bust, the hips) is a patch of one part that lags behind the body. The package
|
|
965
972
|
proposes none and judges none; what it gives is the three pieces to build one, all in the
|
|
966
|
-
config. `examples/sample` carries a worked one (issue #183, PR #187), and its config is the
|
|
973
|
+
config. `examples/reference-sample` carries a worked one (issue #183, PR #187), and its config is the
|
|
967
974
|
fragment below, cut to the bust:
|
|
968
975
|
|
|
969
976
|
```jsonc
|
|
@@ -983,14 +990,14 @@ fragment below, cut to the bust:
|
|
|
983
990
|
bone and no constraint; it is yours, and nothing keys it — the constraint moves it.
|
|
984
991
|
- **A region in a `contour` (or `auto`) mesh** that hands the patch to that bone: weight 1
|
|
985
992
|
inside the shape, falling to 0 across `band` (*A contour mesh*, above). A `grid` mesh carries
|
|
986
|
-
no region, so the part moves from the lattice to the outline mode first; `sample` traced
|
|
993
|
+
no region, so the part moves from the lattice to the outline mode first; `reference-sample` traced
|
|
987
994
|
`topwear` at its former grid spacing (18) and `bottomwear` at 28. Place the shape on the
|
|
988
|
-
patch alone: on `sample` one circle at the hip centre reached the clasped hands, painted
|
|
995
|
+
patch alone: on `reference-sample` one circle at the hip centre reached the clasped hands, painted
|
|
989
996
|
inside `bottomwear`, so the hips are two side circles (`hip_r`, `hip_l`) on one bone.
|
|
990
997
|
- **A `physics` constraint** on that bone in `constraints`, in rig-c's shape; every field but
|
|
991
998
|
the bone is rigc's to accept.
|
|
992
999
|
|
|
993
|
-
`build` on `sample` as tracked (PR #187; the values above are the ones tuned for its `hop`, issue #183):
|
|
1000
|
+
`build` on `reference-sample` as tracked (PR #187; the values above are the ones tuned for its `hop`, issue #183):
|
|
994
1001
|
|
|
995
1002
|
```
|
|
996
1003
|
check: PASS; 9 of 9 bar(s) measured, 0 skipped
|
|
@@ -1004,7 +1011,7 @@ by whatever the spring is still doing; the bar is read off the same rig with eve
|
|
|
1004
1011
|
constraint left out, and the constraints left out are listed, reported and not judged
|
|
1005
1012
|
(`check.json`'s `loop_physics`, PR #184). It is not a measure of the jiggle.
|
|
1006
1013
|
|
|
1007
|
-
**Limits.** The idle drives the spring, and a slow idle barely moves it. Measured on `sample`
|
|
1014
|
+
**Limits.** The idle drives the spring, and a slow idle barely moves it. Measured on `reference-sample`
|
|
1008
1015
|
(PR #187, rig-c `render --geometry`, the physics build against the same build with
|
|
1009
1016
|
`constraints` removed): under its 4 s breath (`chest` `translatey` amplitude 1.3 px), the bust
|
|
1010
1017
|
moves at most 0.155 rig px (idle frame 3, t 0.25 s); the hips move 0.000 at all 49 frames,
|
|
@@ -1014,7 +1021,7 @@ frequency, about 0.2 px (PR #187, from the definition): no setting makes a 4 s b
|
|
|
1014
1021
|
jiggle (with the values tracked now, `bust_phys` inertia 0.25, strength 120, damping 0.92, the
|
|
1015
1022
|
idle moves the bust at most 0.066 rig px, idle frame 2). Faster keys on the parent bone — a hop,
|
|
1016
1023
|
a turn, in a named animation (the recipe above) or a consumer's own — are what the spring
|
|
1017
|
-
answers. `sample`'s `animations.json` holds one, `hop` (1 s: `hip` `translate` y down 5, up 24,
|
|
1024
|
+
answers. `reference-sample`'s `animations.json` holds one, `hop` (1 s: `hip` `translate` y down 5, up 24,
|
|
1018
1025
|
landing at -6 at 0.45 s, settling at 0.55 s; nothing keys the jiggle bones): rendered at 30 fps
|
|
1019
1026
|
against the same build without its constraints, the bust moves at most 6.583 rig px and the hips
|
|
1020
1027
|
(`hip_phys` inertia 0.2, strength 160, damping 0.88, mass 1.5) at most 4.432 (frame 13, the fall
|
|
@@ -1059,7 +1066,7 @@ not run through. Raising the bound is the author's choice, not the package's; mo
|
|
|
1059
1066
|
is the fix.
|
|
1060
1067
|
- **An added animation can move the idle's figures.** The render's viewport is fitted over
|
|
1061
1068
|
every animation, and the idle frames share it, so an animation that travels further than the
|
|
1062
|
-
idle redraws the idle at another size: adding `hop` to `sample` narrowed the idle render from
|
|
1069
|
+
idle redraws the idle at another size: adding `hop` to `reference-sample` narrowed the idle render from
|
|
1063
1070
|
201 to 198 px wide and moved `check.json`'s `BREATH_VISIBLE` `torso_heat_mean` from 7.8 to
|
|
1064
1071
|
7.705, every status unchanged, although `check` reads the idle alone.
|
|
1065
1072
|
|
|
@@ -1109,7 +1116,7 @@ full loader before its assemble stage writes anything.
|
|
|
1109
1116
|
5. **See-through, head run** (external), on that crop. See-through's own second,
|
|
1110
1117
|
head stage does not replace it: that stage's layers are pasted back at the full
|
|
1111
1118
|
run's scale on every route that was read (README *Getting See-through layers*),
|
|
1112
|
-
so the full run's eyes stay at its density — 22×13 px for
|
|
1119
|
+
so the full run's eyes stay at its density — 22×13 px for reference-demo's right eye
|
|
1113
1120
|
white at `resolution` 1024, against 60×38 px in the head run.
|
|
1114
1121
|
6. `rig-parts assemble --propose-plan --source … --full … --head … --config config.json`
|
|
1115
1122
|
→ paste `plan` and `extend_below_crop` into `config.assemble`. Config: the
|
|
@@ -1197,8 +1204,8 @@ proposal in as the steps above say (`RL01`); every step must exit 0.
|
|
|
1197
1204
|
| --- | --- | --- | --- |
|
|
1198
1205
|
| `layers` | the table, then the `WARN` lines | every tag the plan will need has opaque pixels; one `face` in the head run; `0 WARN line(s)` | a run whose layer PNG is not its box's size (`LAYERS_PNG_MATCHES_BBOX`); a `WARN PLAN_LAYER_…` line (§6, *Plausibility*) |
|
|
1199
1206
|
| `sheet` of both runs | the tile list (and the sheet, if you can see) | eyes, irises, lashes and brows as left/right pairs in the head run | a head box that cut off an ornament: move `head_box`, re-run the head crop |
|
|
1200
|
-
| `assemble` | one line per part, the `pixels:` totals (opaque = visible + occluded; taken; visible but not projected), then `recomposite vs source: mean \|d\|, within 8, error px > 40, uncovered error px`, then `uncovered holes (8-connected): N` and the largest five as `uncovered hole K: <px> px at x,y wxh (between "<part>" <px> px, …)`; and look at `render/recomposite_error_rig.png`. Between the part lines and the totals, one `cut: "<part>" opaque <n> = "<part>" <kept> + "<piece>" <taken> …` line per part an `assemble.cuts` entry cut (below; it ends `; under <n> px filled, <m> px left empty` when a cut of that part has `under`), then one `fringe pushed back: "<part>" <px> px, where the painting shows "<holder>" <px> px, …` line per part whose fringe was cleared (below) | on the examples: `sample` 0.83 / 98.0 % / 4,359 / 1,185, 259 holes, the largest 94 px; `demo` 2.34 / 95.8 % / 10,340 / 1,564, 453 holes, the largest 70 px (default rule) — many slivers along part edges, no hole a region could hide | one large hole: part of the figure is in no layer — a plan entry is missing, hair left the head crop sideways (
|
|
1201
|
-
| `propose` | `note:` lines, `LINT` lines, the `coverage` lines, `landmarks.png`, `basis.json` | no LINT line: every chain link lies on its mesh's art, and the hip is below the chest and the figure's top quarter; the `coverage:` summary says how many bones that verdict covers — a `not checked` bone was read by no check (its line says why), and a `ratio` or `fallback` bone in `basis.json` is a guess | a link off the art (a bone on the background) — move it onto the layer; `LINT hip at [x, y] is not below chest at [x, y]: …` or `LINT hip at [x, y] is above 0.25 of the figure height (figure y T..B, so hip y must be at least L): a hip at the shoulders` — move `hip` down to the waist (and `chest` between it and the neck); a `hanging strand … -- no chain proposed` note — that strand hangs stiff until you add a chain down the x and rows it names (§3); a `no blink: …` or `blink without brows: …` note — the idle will not blink (or its brows will not drop), because no part came from an `eyewhite` (or `eyebrow`) layer; the note names the tags looked for; a `no eyewhite part for eye_<s> …` note — the iris and lash parts it names ride `head` and do not blink, because no `eyewhite-<s>` part made that side's eye bone: take the eyewhite from the other run, or keep them on `head`; a `no face part: face box derived from …` note (always the first) — `head`, `neck` and every face-height scale come from a box guessed off the hair and neck (§3): check `head` and `neck` on `landmarks_head.png` and move them; when it adds `the blink shuts the eyes over no face part`, read `BLINK_NO_HOLE` after `check` — an eye with no face under it can open a hole (the `sample` with only its face removed: 587 px). Under `--keypoints`: the `lint rule set:` line first (joints, or screen and why), then the joint notes — `missing: the rule "…" placed bone X instead` is a bone still guessed; `not used — …` names why an arm's joints did not place its sleeve (for a wrist on no part, the nearest part and the `--wrist-snap` that would bind it); a `wrist snap: …` note is a wrist bound past 15 px by the flag — check that chain's tip on `landmarks.png`; a `one handwear part holds both wrists` note is two chains on one mesh — cut the part with `assemble.cuts` to separate them; `LINT chest at … is not between the neck joint …`, `LINT hip at … is not past chest …`, `LINT hip at … is nearer the neck joint …` and `LINT <chain><i> at … does not advance from <s>_shoulder toward <s>_wrist` are the joint-frame lines: move that bone between, past or along the joints they name |
|
|
1207
|
+
| `assemble` | one line per part, the `pixels:` totals (opaque = visible + occluded; taken; visible but not projected), then `recomposite vs source: mean \|d\|, within 8, error px > 40, uncovered error px`, then `uncovered holes (8-connected): N` and the largest five as `uncovered hole K: <px> px at x,y wxh (between "<part>" <px> px, …)`; and look at `render/recomposite_error_rig.png`. Between the part lines and the totals, one `cut: "<part>" opaque <n> = "<part>" <kept> + "<piece>" <taken> …` line per part an `assemble.cuts` entry cut (below; it ends `; under <n> px filled, <m> px left empty` when a cut of that part has `under`), then one `fringe pushed back: "<part>" <px> px, where the painting shows "<holder>" <px> px, …` line per part whose fringe was cleared (below) | on the examples: `reference-sample` 0.83 / 98.0 % / 4,359 / 1,185, 259 holes, the largest 94 px; `reference-demo` 2.34 / 95.8 % / 10,340 / 1,564, 453 holes, the largest 70 px (default rule) — many slivers along part edges, no hole a region could hide | one large hole: part of the figure is in no layer — a plan entry is missing, hair left the head crop sideways (reference-demo's `hair_back` is taken from the full run for that reason), or See-through split one garment into two and left the space between them in neither (a skirt as two trouser legs); the `between` parts say where. When neither run holds it at all, an `assemble.patches` entry cuts it from the painting (below) |
|
|
1208
|
+
| `propose` | `note:` lines, `LINT` lines, the `coverage` lines, `landmarks.png`, `basis.json` | no LINT line: every chain link lies on its mesh's art, and the hip is below the chest and the figure's top quarter; the `coverage:` summary says how many bones that verdict covers — a `not checked` bone was read by no check (its line says why), and a `ratio` or `fallback` bone in `basis.json` is a guess | a link off the art (a bone on the background) — move it onto the layer; `LINT hip at [x, y] is not below chest at [x, y]: …` or `LINT hip at [x, y] is above 0.25 of the figure height (figure y T..B, so hip y must be at least L): a hip at the shoulders` — move `hip` down to the waist (and `chest` between it and the neck); a `hanging strand … -- no chain proposed` note — that strand hangs stiff until you add a chain down the x and rows it names (§3); a `no blink: …` or `blink without brows: …` note — the idle will not blink (or its brows will not drop), because no part came from an `eyewhite` (or `eyebrow`) layer; the note names the tags looked for; a `no eyewhite part for eye_<s> …` note — the iris and lash parts it names ride `head` and do not blink, because no `eyewhite-<s>` part made that side's eye bone: take the eyewhite from the other run, or keep them on `head`; a `no face part: face box derived from …` note (always the first) — `head`, `neck` and every face-height scale come from a box guessed off the hair and neck (§3): check `head` and `neck` on `landmarks_head.png` and move them; when it adds `the blink shuts the eyes over no face part`, read `BLINK_NO_HOLE` after `check` — an eye with no face under it can open a hole (the `reference-sample` with only its face removed: 587 px). Under `--keypoints`: the `lint rule set:` line first (joints, or screen and why), then the joint notes — `missing: the rule "…" placed bone X instead` is a bone still guessed; `not used — …` names why an arm's joints did not place its sleeve (for a wrist on no part, the nearest part and the `--wrist-snap` that would bind it); a `wrist snap: …` note is a wrist bound past 15 px by the flag — check that chain's tip on `landmarks.png`; a `one handwear part holds both wrists` note is two chains on one mesh — cut the part with `assemble.cuts` to separate them; `LINT chest at … is not between the neck joint …`, `LINT hip at … is not past chest …`, `LINT hip at … is nearer the neck joint …` and `LINT <chain><i> at … does not advance from <s>_shoulder toward <s>_wrist` are the joint-frame lines: move that bone between, past or along the joints they name |
|
|
1202
1209
|
| `compare` | one line per pair (origin, parent, tip, length, direction — or SKIP and why), then the per-row summary, the unmapped bones of each side, `required:`, each side's roles and the `controls:` line | proposal against the config you corrected: the rows you changed and no others. Config against the `rig.json` `build` writes for it: measured on both examples, every origin within 6.19e-7 px (the rig's offsets are written to 6 places) and every chain link's tip and length within 4.99e-4 px (`length` is written to 3), printed to three places as `0.000` (a signed figure as `+0.000` or `-0.000`); `parent … is the right's ancestor at depth 2, <bone>_ctl between` for every keyed mesh bone, no `DIFFERENT` and no `NOT MAPPED` | `parent DIFFERENT: left a, right b` — a bone hangs from another parent than the other side's; `frames not related` — a rig with no stage (`skeleton.width`/`height`), two configs at different `rig_scale`: the distance rows SKIP, so declare the frame in a `--map` file if the author knows it; `FAIL STRUCTURE_REQUIRED_PRESENT` — a bone the map requires is missing through its pairs |
|
|
1203
1210
|
| `rig` (inside `build`) | one line per mesh: vertices, triangles, bones, influences, `cover`; the `bones` line; the `idle keys` line; then rigc's gate lines (with A15's declared SKIP under `--idle-keys direct`); in `rig.json`, each chain link's (or its `_ctl`'s) `length` and `rotation` | `cover 1.00000` on every mesh, both gate summaries `0 failed` (the compile and the packed pages); every link's `length` the distance to the next link and `rotation` its direction (Spine degrees, counter-clockwise, y up, local to the parent), every offset under it — a child bone's `x, y`, a weight's bind `x, y`, a region's `x, y` — in that turned frame, and a region on a link carrying `rotation` that turns it back upright. Nothing moved: `flattenRig` (`src/rig.ts`) turns every offset back and gives the unturned numbers | `RIG_LATTICE_ONE_LOOP`: change that mesh's `grid` |
|
|
1204
1211
|
| `check` (inside `build`) | the gate lines verbatim, the pack line, `loop:` (and `loop physics:` when the rig declares a physics constraint, §7), `seam:`, the six judgement lines, `RECOMPOSITE_HOLES` and, under `--source`, `SETUP_POSE_VS_SOURCE` (§7), `check.json`; the last line says how many of the nine bars measured and names the ones that said SKIP | `check: PASS; 9 of 9 bar(s) measured, 0 skipped` on the examples, and a judgement line SKIP only where the character lacks what it reads; on a rig spec with no `parts.json` or no `idle` (a merged rig, §7 *Measuring a rig rig-parts did not assemble*), PASS with the skipped bars named | `CHECK_SEAM_WITHIN_BAR` or `CHECK_LOOP_CLOSES` (§6) |
|
|
@@ -1214,25 +1221,27 @@ every frame (255 median-cut colours and one transparent entry, alpha graded per
|
|
|
1214
1221
|
entry, no dithering, filter None) — and is the small file to show. `idle.gif`
|
|
1215
1222
|
(`loop --out x.gif`) is the same median cut in a GIF. The indexed APNG and the GIF
|
|
1216
1223
|
print their palette error, per channel over R, G and B of every frame (and alpha's
|
|
1217
|
-
max for the APNG); a figure is a measurement of the file, not a bar. On the demo
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1224
|
+
max for the APNG); a figure is a measurement of the file, not a bar. On the demo
|
|
1225
|
+
(the README's animation since issue #227: `build --loop`, default flags, rig-c 2.33.0):
|
|
1226
|
+
5,832,634 B lossless, 827,857 B indexed and 889,063 B GIF, both palette files at
|
|
1227
|
+
max 65, mean 0.879 — the two share one quantiser, so their error is the same by
|
|
1228
|
+
construction and the size is the difference. On reference-demo with `--seam silhouette`
|
|
1229
|
+
(the README's animation until issue #227, rig-c 2.1.3, and 2.10.1 to the byte):
|
|
1230
|
+
13,645,503 B lossless, 1,706,719 B indexed and 1,812,288 B GIF at max 57, mean 1.601;
|
|
1231
|
+
with `--pack-shape rect` the same build writes 13,645,350, 1,706,520 and 1,812,238 B,
|
|
1232
|
+
and with `--page-edges pot --pack-shape rect` 13,645,519, 1,706,785 and 1,812,625 B,
|
|
1233
|
+
all at the same error (2.10.1 reproduces both). The loop shows the blink closed: the
|
|
1225
1234
|
eyes' hold is at least one 12 fps frame (below), so whatever `motion.blink.t` is, one
|
|
1226
1235
|
idle frame lands inside it, and `check.json`'s `BLINK_NO_HOLE.idle_frames_closed`
|
|
1227
|
-
names it — `[29]` on
|
|
1236
|
+
names it — `[29]` on the two reference examples and on the demo.
|
|
1228
1237
|
|
|
1229
1238
|
`--seam near-white` (the default) is the reference implementation's rule: where the
|
|
1230
1239
|
flat stack of parts differs from the painting by more than 60, the top part takes the
|
|
1231
1240
|
painting's colour — except where the painting is near-white, which protects the page
|
|
1232
1241
|
and also every white garment. `--seam silhouette` protects near-white pixels only
|
|
1233
|
-
outside the figure. On
|
|
1234
|
-
8,644 (`assemble`'s `error px > 40`, at v1.5.2); on
|
|
1235
|
-
(4,359 under both). At v0.14.0
|
|
1242
|
+
outside the figure. On reference-demo it lowers recomposite error pixels from 10,340 to
|
|
1243
|
+
8,644 (`assemble`'s `error px > 40`, at v1.5.2); on reference-sample it changes nothing
|
|
1244
|
+
(4,359 under both). At v0.14.0 reference-demo's were 11,050 and 9,540, and no check bar
|
|
1236
1245
|
changed. The default stays
|
|
1237
1246
|
the reference's so the examples stay comparable with it.
|
|
1238
1247
|
|
|
@@ -1253,8 +1262,8 @@ and a cleared bridge to opaque art is put back, so no part gains an island
|
|
|
1253
1262
|
(`CONTOUR_ONE_ISLAND` reads the islands it read before). `parts.json` records each part's cleared pixels by holder
|
|
1254
1263
|
(`fringe_pushed_back`), the counts in it are taken after, and the assemble line above
|
|
1255
1264
|
names them. On the examples (default flags, measured against the v0.14.0 build of
|
|
1256
|
-
the same inputs): `demo` 1,193 px over 16 parts, recomposite error pixels 11,050 →
|
|
1257
|
-
10,340; `sample` 276 px over 15 parts, 4,512 → 4,359; uncovered error pixels and
|
|
1265
|
+
the same inputs): `reference-demo` 1,193 px over 16 parts, recomposite error pixels 11,050 →
|
|
1266
|
+
10,340; `reference-sample` 276 px over 15 parts, 4,512 → 4,359; uncovered error pixels and
|
|
1258
1267
|
holes unchanged on both, `check` 9 of 9 on both. The `--project` comparison in
|
|
1259
1268
|
this section and the `SETUP_POSE_VS_SOURCE` example figures in §7 were measured
|
|
1260
1269
|
before it, at v0.14.0; the `--seam` figures above are v1.5.2's.
|
|
@@ -1272,10 +1281,10 @@ to 2.1.3's):
|
|
|
1272
1281
|
|
|
1273
1282
|
| build | page | covered | page opaque | page / figure |
|
|
1274
1283
|
| --- | --- | --- | --- | --- |
|
|
1275
|
-
| demo, `pot` | 1024x2048 | 56.3 % | 36.8 % | 2.651 |
|
|
1276
|
-
| demo, `free` | 967x1338 | 91.2 % | 59.7 % | 1.636 |
|
|
1277
|
-
| sample, `pot` | 512x2048 | 49.7 % | 28.7 % | 3.294 |
|
|
1278
|
-
| sample, `free` | 479x1166 | 93.4 % | 53.9 % | 1.755 |
|
|
1284
|
+
| reference-demo, `pot` | 1024x2048 | 56.3 % | 36.8 % | 2.651 |
|
|
1285
|
+
| reference-demo, `free` | 967x1338 | 91.2 % | 59.7 % | 1.636 |
|
|
1286
|
+
| reference-sample, `pot` | 512x2048 | 49.7 % | 28.7 % | 3.294 |
|
|
1287
|
+
| reference-sample, `free` | 479x1166 | 93.4 % | 53.9 % | 1.755 |
|
|
1279
1288
|
|
|
1280
1289
|
rigc's help states the cost: *"a smaller page, at the cost of region attachments
|
|
1281
1290
|
sampling within 1 LSB of the loose build rather than exactly"*. On these builds
|
|
@@ -1284,10 +1293,10 @@ in any channel:
|
|
|
1284
1293
|
|
|
1285
1294
|
| example | idle frames that differ | pixels that differ (all 49 frames) | max \|d\| |
|
|
1286
1295
|
| --- | --- | --- | --- |
|
|
1287
|
-
| demo | 49 of 49 | 2,373 | 1 |
|
|
1288
|
-
| sample | 49 of 49 | 651 | 1 |
|
|
1296
|
+
| reference-demo | 49 of 49 | 2,373 | 1 |
|
|
1297
|
+
| reference-sample | 49 of 49 | 651 | 1 |
|
|
1289
1298
|
|
|
1290
|
-
Only one check figure moved. It had no bar: sample's reported screen-space face
|
|
1299
|
+
Only one check figure moved. It had no bar: reference-sample's reported screen-space face
|
|
1291
1300
|
mean in `STILL_REGIONS_DARK`, 11.475 under `pot` and 11.472 under `free` (a pixel
|
|
1292
1301
|
figure the line no longer reports since issue #123; it reads geometry, which the page
|
|
1293
1302
|
does not enter). Every
|
|
@@ -1312,10 +1321,10 @@ both shapes and both edges (the full entry, spine-core 4.3.13 beside it),
|
|
|
1312
1321
|
|
|
1313
1322
|
| build | page | page area | covered | page opaque | page / figure |
|
|
1314
1323
|
| --- | --- | --- | --- | --- | --- |
|
|
1315
|
-
| demo, `rect` | 967x1338 | 1,293,846 | 91.2 % | 59.7 % | 1.636 |
|
|
1316
|
-
| demo, `polygon` | 922x1348 | 1,242,856 (−3.9 %) | 95.0 % | 62.1 % | 1.571 |
|
|
1317
|
-
| sample, `rect` | 479x1166 | 558,514 | 93.4 % | 53.9 % | 1.755 |
|
|
1318
|
-
| sample, `polygon` | 477x1151 | 549,027 (−1.7 %) | 95.0 % | 54.8 % | 1.725 |
|
|
1324
|
+
| reference-demo, `rect` | 967x1338 | 1,293,846 | 91.2 % | 59.7 % | 1.636 |
|
|
1325
|
+
| reference-demo, `polygon` | 922x1348 | 1,242,856 (−3.9 %) | 95.0 % | 62.1 % | 1.571 |
|
|
1326
|
+
| reference-sample, `rect` | 479x1166 | 558,514 | 93.4 % | 53.9 % | 1.755 |
|
|
1327
|
+
| reference-sample, `polygon` | 477x1151 | 549,027 (−1.7 %) | 95.0 % | 54.8 % | 1.725 |
|
|
1319
1328
|
|
|
1320
1329
|
Covered is Σ region rectangles over page area, as rigc prints it; under `polygon` the
|
|
1321
1330
|
rectangles may overlap where a hull leaves room, so it is not a union and can exceed
|
|
@@ -1328,8 +1337,8 @@ idle --fps 12 --max 640`, compared frame by frame, max over R, G, B and A):
|
|
|
1328
1337
|
|
|
1329
1338
|
| example | idle frames that differ | pixels that differ (all 49 frames) | max \|d\| |
|
|
1330
1339
|
| --- | --- | --- | --- |
|
|
1331
|
-
| demo | 49 of 49 | 2,594 | 1 |
|
|
1332
|
-
| sample | 49 of 49 | 740 | 1 |
|
|
1340
|
+
| reference-demo | 49 of 49 | 2,594 | 1 |
|
|
1341
|
+
| reference-sample | 49 of 49 | 740 | 1 |
|
|
1333
1342
|
|
|
1334
1343
|
That is the class `free` already costs (the table above, measured by the same
|
|
1335
1344
|
comparison), a little larger. No figure in `check.json` moved but `pack_mode`: every
|
|
@@ -1339,11 +1348,11 @@ they are byte-identical to rigc 2.0.3's `--page-edges free` build of the same ri
|
|
|
1339
1348
|
skeleton JSON differs only in its relative `images` path), and selftest `CK53` holds
|
|
1340
1349
|
`rect` to rigc's own rectangle page.
|
|
1341
1350
|
|
|
1342
|
-
The hull ceiling (rig-parts #58: hull area over rectangle area, 0.812 on demo and
|
|
1343
|
-
0.814 on sample) is not what the packer realises here: the hollows inside the meshes'
|
|
1351
|
+
The hull ceiling (rig-parts #58: hull area over rectangle area, 0.812 on reference-demo and
|
|
1352
|
+
0.814 on reference-sample) is not what the packer realises here: the hollows inside the meshes'
|
|
1344
1353
|
rectangles are worth only what fits into them. On the polygon pages, read off the
|
|
1345
|
-
atlas, demo's packed rectangles overlap in 21 pairs (17 a region attachment inside a
|
|
1346
|
-
mesh's rectangle, 4 a mesh inside another's) and sample's in 12 (10 and 2); no two
|
|
1354
|
+
atlas, reference-demo's packed rectangles overlap in 21 pairs (17 a region attachment inside a
|
|
1355
|
+
mesh's rectangle, 4 a mesh inside another's) and reference-sample's in 12 (10 and 2); no two
|
|
1347
1356
|
region attachments overlap. Meshes in place of regions would be rigc's stage 2 of
|
|
1348
1357
|
polygon packing (firejune/rigc#1093), which rigc measured and folded: on the three
|
|
1349
1358
|
production rigs most favourable to it, it adds 0.15 % of the rectangle area over
|
|
@@ -1356,7 +1365,7 @@ so a part a few pixels wide (a lash, a brow, an iris) takes none. `--project vis
|
|
|
1356
1365
|
keeps the erosion only along a rim where a later layer of the run is in front, and
|
|
1357
1366
|
takes every other top-most `alpha >= 250` pixel; neither rule takes a fringe pixel
|
|
1358
1367
|
(alpha below 250). On the examples it lowered the pixels that are visible but not
|
|
1359
|
-
projected from 36,227 to 22,476 (`sample`) and 76,801 to 49,672 (`demo`), recomposite
|
|
1368
|
+
projected from 36,227 to 22,476 (`reference-sample`) and 76,801 to 49,672 (`reference-demo`), recomposite
|
|
1360
1369
|
error pixels from 4,512 to 4,116 and 11,050 to 9,820, and the check seam from 0.207 to
|
|
1361
1370
|
0.206 and 0.326 to 0.325, with no other check figure changed. The default stays the
|
|
1362
1371
|
reference's so the examples stay comparable with it. `build` takes both flags.
|
|
@@ -1375,10 +1384,10 @@ drive M mesh attachment(s) totalling V vertices …`, which the stage prints; wi
|
|
|
1375
1384
|
mesh-driving bone keyed it declares nothing, because rigc refuses a declaration
|
|
1376
1385
|
that switches nothing off. The two write the same slots, skins and keys (`RG18`).
|
|
1377
1386
|
Measured on the examples with `bun tools/idle_cost.ts` (rig-parts #13): `direct`
|
|
1378
|
-
has 41 bones for
|
|
1387
|
+
has 41 bones for reference-demo's 72 and 32 for reference-sample's 56; every shown mesh moves on
|
|
1379
1388
|
every idle frame under both (8 of 8 and 6 of 6, so 0 a dirty-skip renderer could
|
|
1380
|
-
skip); the pose costs 14.8 against 15.3 us per frame (demo) and 8.3 against 8.8 us
|
|
1381
|
-
(sample), the difference all in `updateWorldTransform`; the rendered idle frames
|
|
1389
|
+
skip); the pose costs 14.8 against 15.3 us per frame (reference-demo) and 8.3 against 8.8 us
|
|
1390
|
+
(reference-sample), the difference all in `updateWorldTransform`; the rendered idle frames
|
|
1382
1391
|
differ by at most one level in a channel. The default stays `ctl`: the examples'
|
|
1383
1392
|
`expected/rig.json` and `motion.json` are the reference's output, and the
|
|
1384
1393
|
declaration is in the rig spec only, so `rigc validate <build> --profile spine-html`
|
|
@@ -1544,15 +1553,15 @@ above 8, the table's `opaque_px`), on the layer as read:
|
|
|
1544
1553
|
| `background` | the share of opaque pixels whose own colour (straight alpha) has a min channel above 235 — the seam rule's "near-white", applied to the layer |
|
|
1545
1554
|
| `area` | opaque pixels over the opaque pixels of the union of every **other** layer of the run ("the rest of the figure"); `-` when no other layer has any |
|
|
1546
1555
|
|
|
1547
|
-
Not over alpha above 0: See-through hazes whole canvases at alpha 1..8 (
|
|
1556
|
+
Not over alpha above 0: See-through hazes whole canvases at alpha 1..8 (reference-demo's
|
|
1548
1557
|
full-run face is 99.1 % translucent that way and 4.2 % over its opaque pixels). Not
|
|
1549
1558
|
over the whole union: a layer is part of it, so it could never be more than 1x.
|
|
1550
1559
|
|
|
1551
1560
|
| rule | crossed when | [observed] on the two examples' 116 layers (four runs) |
|
|
1552
1561
|
| --- | --- | --- |
|
|
1553
|
-
| `PLAN_LAYER_TRANSLUCENT` | judged, and `translucent` above 50 % | the most translucent judged layer is 17.8 % (sample, full run, `front hair`) |
|
|
1554
|
-
| `PLAN_LAYER_BACKGROUND` | judged, `background` above 50 %, and `translucent` above 25 % | the most background-coloured judged layer is 21.9 % (demo, head run, `topwear`, a white dress); of judged layers above 10 % background, the most translucent is 5.6 % (demo, full run, `handwear-r`) |
|
|
1555
|
-
| `PLAN_LAYER_OVERSIZED` | `area` above 4x | the largest is 1.681x (demo, head run, `back hair`, which fills the crop) |
|
|
1562
|
+
| `PLAN_LAYER_TRANSLUCENT` | judged, and `translucent` above 50 % | the most translucent judged layer is 17.8 % (reference-sample, full run, `front hair`) |
|
|
1563
|
+
| `PLAN_LAYER_BACKGROUND` | judged, `background` above 50 %, and `translucent` above 25 % | the most background-coloured judged layer is 21.9 % (reference-demo, head run, `topwear`, a white dress); of judged layers above 10 % background, the most translucent is 5.6 % (reference-demo, full run, `handwear-r`) |
|
|
1564
|
+
| `PLAN_LAYER_OVERSIZED` | `area` above 4x | the largest is 1.681x (reference-demo, head run, `back hair`, which fills the crop) |
|
|
1556
1565
|
|
|
1557
1566
|
**Judged** means `area` at least 0.05x (or `-`). The two colour rules skip smaller
|
|
1558
1567
|
layers on purpose: **[observed]** all 27 example layers of 150 px or more that are above
|
|
@@ -1749,7 +1758,7 @@ assemble*, at the end of this section):
|
|
|
1749
1758
|
- `gate_spine-html.txt`: every summary line `(N passed, 0 failed)` — the packed build
|
|
1750
1759
|
under the `spine-html` profile, gated once over the compile and once over the packed
|
|
1751
1760
|
pages on disk. There is no `spine` gate of its own: `spine-html` holds every rule
|
|
1752
|
-
`spine` measures (on
|
|
1761
|
+
`spine` measures (on reference-demo, rigc 1.5.1 and 2.0.3: `validate --profile spine`'s 14
|
|
1753
1762
|
measured rules are all among the build's 23, the 15 others not in `spine`; rigc
|
|
1754
1763
|
2.1.3 and 2.10.1: the same 14 among the build's 24, which adds
|
|
1755
1764
|
`A49_PACKED_FOOTPRINTS_DO_NOT_OVERLAP` on the packed pass, 16 not in `spine`; `CH09`
|
|
@@ -1760,19 +1769,19 @@ assemble*, at the end of this section):
|
|
|
1760
1769
|
prints and `check.json`'s `seam_frame_scale` holds (issue #216). The frame
|
|
1761
1770
|
holds s² pixels per rig pixel, so a stack that parts from the render over a
|
|
1762
1771
|
fixed area of the rig reads s² times as many frame pixels: on the public
|
|
1763
|
-
`sample` a part moved 2 rig px read 400, 891 and 1,560 frame px over 40 at
|
|
1764
|
-
s = 1.0, 1.5 and 2.0, and 400, 396 and 390 rig px;
|
|
1772
|
+
`reference-sample` a part moved 2 rig px read 400, 891 and 1,560 frame px over 40 at
|
|
1773
|
+
s = 1.0, 1.5 and 2.0, and 400, 396 and 390 rig px; reference-sample as built read
|
|
1765
1774
|
3, 3 and 7 frame px [measured, issue #216]. Divided by s² the bar reads the
|
|
1766
1775
|
same rig at every scale, and at s = 1 it is the reference's count. The mean
|
|
1767
1776
|
is a share of the frame and needs no such division (0.242, 0.188 and 0.226 on
|
|
1768
|
-
|
|
1777
|
+
reference-sample as built; 0.353, 0.305 and 0.340 with the part moved).
|
|
1769
1778
|
`seam_px_over_40` and `seam_px_over_80` stay frame pixels, and so does each
|
|
1770
1779
|
pair's count below. The bar reads one
|
|
1771
1780
|
frame, the setup-pose still, never the idle. When it fails (or when `check
|
|
1772
1781
|
--seam-pairs` asks, pass or fail), the pixels over 40 are split by the pair of
|
|
1773
1782
|
parts that answers for each (issue #202): the two parts drawn last among those
|
|
1774
1783
|
whose art (alpha above 0) lies in the 2x2 rig pixels the composite's bilinear
|
|
1775
|
-
sample reads for that frame pixel, lower first, `(no art)` standing in where
|
|
1784
|
+
reference-sample reads for that frame pixel, lower first, `(no art)` standing in where
|
|
1776
1785
|
fewer than two do. Each pair is a console line `seam pair <i> of <n>: "<a>" /
|
|
1777
1786
|
"<b>" at the setup pose: <count> px over 40 (<count> over 80), frame box x
|
|
1778
1787
|
<x0>..<x1>, y <y0>..<y1>, rig box …, picture seam/<i>_<a>_<b>.png` (in the
|
|
@@ -1818,8 +1827,8 @@ assemble*, at the end of this section):
|
|
|
1818
1827
|
`loop_max_diff`; they are reported, not judged. A rig with none is measured from the
|
|
1819
1828
|
idle render itself, exactly as before, and writes no such line or key.
|
|
1820
1829
|
|
|
1821
|
-
On the examples: `sample` 23/23, seam 0.207 with 0 pixels over 40, loop 0;
|
|
1822
|
-
`demo` (default rule) 23/23, seam 0.326 with 2 pixels over 40, loop 0.
|
|
1830
|
+
On the examples: `reference-sample` 23/23, seam 0.207 with 0 pixels over 40, loop 0;
|
|
1831
|
+
`reference-demo` (default rule) 23/23, seam 0.326 with 2 pixels over 40, loop 0.
|
|
1823
1832
|
|
|
1824
1833
|
A green gate cannot see a wrong animation, so `check` also writes six **judgement
|
|
1825
1834
|
lines** (issue #11; `TEXTURE_STRETCH`, issue #31), each a key of `check.json` and a console line
|
|
@@ -1836,10 +1845,10 @@ model itself fixes (a part on an unkeyed bone does not move, a lag is above 0, a
|
|
|
1836
1845
|
is 0 pixels) is that value, not a margin — and where the model's value is an error
|
|
1837
1846
|
the model fixes at "nothing moves" and the instrument reads exactly (the still regions,
|
|
1838
1847
|
from geometry since issue #123), the bar is the arithmetic's own rounding, derived, not
|
|
1839
|
-
measured. A bar is set once, from the figures of the day it was set, and is not chased: the torso floor 3.809 is half of sample's 7.618, which reads 7.617 since the chain links are turned (issue #73), a factor of 1.9997. The figures are this port's, measured on
|
|
1848
|
+
measured. A bar is set once, from the figures of the day it was set, and is not chased: the torso floor 3.809 is half of reference-sample's 7.618, which reads 7.617 since the chain links are turned (issue #73), a factor of 1.9997. The figures are this port's, measured on
|
|
1840
1849
|
the two examples [observed]:
|
|
1841
1850
|
|
|
1842
|
-
| line | measures | bar | `demo` | `sample` | SKIP when |
|
|
1851
|
+
| line | measures | bar | `reference-demo` | `reference-sample` | SKIP when |
|
|
1843
1852
|
| --- | --- | --- | --- | --- | --- |
|
|
1844
1853
|
| `BREATH_VISIBLE` | `topwear` parts rendered alone (`rigc render --slot`): heat mean over their box; `footwear` parts alone: heat max over theirs | torso mean ≥ 3.809; feet max ≤ 0 | 15.251; 0 | 7.617; 0 | no `topwear` or no `footwear` part |
|
|
1845
1854
|
| `BLINK_NO_HOLE` | the setup pose with every `scaley` track on the eyewhite slots' bones held at its closed value, against the setup pose, at full size: pixels in the eyewhite box that show the page where the open eye had art | 0 px | 0 | 0 | no `eyewhite` part, or no `scaley` track on its bones goes below its first key |
|
|
@@ -1856,27 +1865,27 @@ centroid of every pixel that was not the background; its fields were `root_px` a
|
|
|
1856
1865
|
mercy of which edge pixels the grid flips: over `--max` 620–660 the pixel figure
|
|
1857
1866
|
scattered around the exact one by up to 0.3 frame px whatever the travel [observed,
|
|
1858
1867
|
13 half-bands on the three examples and a variant], and every **root** half on every
|
|
1859
|
-
example travels 0.04–0.6 frame px, so the ratio's denominator was noise — sample's
|
|
1860
|
-
`bottomwear` read 4.187–6.849 over the sweep, demo's `sleeves` 2.960–6.503, and sample
|
|
1868
|
+
example travels 0.04–0.6 frame px, so the ratio's denominator was noise — reference-sample's
|
|
1869
|
+
`bottomwear` read 4.187–6.849 over the sweep, reference-demo's `sleeves` 2.960–6.503, and reference-sample
|
|
1861
1870
|
with its skirt amplitudes ×0.1 read 0.512–13.53, FAIL or PASS by the grid. The exact
|
|
1862
1871
|
reading of the same definition is the same at every size (4.007 on that skirt, a PASS).
|
|
1863
1872
|
The fields are now `root_rig_px` and `tip_rig_px`, rig px, beside `instrument:
|
|
1864
1873
|
"geometry"`, so an old and a new `check.json` are not read as one instrument. The bar
|
|
1865
|
-
is the one set from the pixel instrument (half of demo's `bottomwear` 2.945, by the
|
|
1866
|
-
rule above, not chased); demo's exact 3.222 clears it 2.19 times. The figures the two
|
|
1874
|
+
is the one set from the pixel instrument (half of reference-demo's `bottomwear` 2.945, by the
|
|
1875
|
+
rule above, not chased); reference-demo's exact 3.222 clears it 2.19 times. The figures the two
|
|
1867
1876
|
instruments give the examples, and `scarf` (whose `bottomwear` is tracked in contour
|
|
1868
1877
|
mode because its lattice fails the line — its README):
|
|
1869
1878
|
|
|
1870
1879
|
| part | pixel, `--max 640` (until #118) | geometry |
|
|
1871
1880
|
| --- | --- | --- |
|
|
1872
|
-
| `demo` `bottomwear`, `sleeves` | 2.990, 3.287 | 3.222, 4.721 |
|
|
1873
|
-
| `sample` `bottomwear`, `sleeves` | 4.396, 12.475 | 4.956, 11.830 |
|
|
1881
|
+
| `reference-demo` `bottomwear`, `sleeves` | 2.990, 3.287 | 3.222, 4.721 |
|
|
1882
|
+
| `reference-sample` `bottomwear`, `sleeves` | 4.396, 12.475 | 4.956, 11.830 |
|
|
1874
1883
|
| `scarf` `handwear_r`, `handwear_l` | 6.242, 5.558 | 6.683, 5.345 |
|
|
1875
1884
|
| `scarf` `bottomwear`, lattice / contour | 4.537 / 2.661 | 1.207 / 1.738 |
|
|
1876
1885
|
|
|
1877
1886
|
The part rendered alone at up to `--max 8000` — the motion spanning pixels — converges
|
|
1878
1887
|
on the geometric figure (`scarf`'s lattice `bottomwear` 1.337, 1.316, 1.285, 1.270 at
|
|
1879
|
-
1200, 2400, 4800, 8000), with one gap not explained: `sample`'s `bottomwear` tip reads
|
|
1888
|
+
1200, 2400, 4800, 8000), with one gap not explained: `reference-sample`'s `bottomwear` tip reads
|
|
1880
1889
|
2.342 rig px there against 2.596 from geometry, its root agreeing to 0.4 %.
|
|
1881
1890
|
|
|
1882
1891
|
**`STILL_REGIONS_DARK` is measured from geometry too, and its scope changed (issue #123).**
|
|
@@ -1889,8 +1898,8 @@ on the geometric figure (`scarf`'s lattice `bottomwear` 1.337, 1.316, 1.285, 1.2
|
|
|
1889
1898
|
|
|
1890
1899
|
Both were means of about one level, and both moved with the grid. Over `--max` 620–660
|
|
1891
1900
|
on the three examples:
|
|
1892
|
-
- demo read 1.03–1.16 times its calibration;
|
|
1893
|
-
- sample read 0.95–1.07;
|
|
1901
|
+
- reference-demo read 1.03–1.16 times its calibration;
|
|
1902
|
+
- reference-sample read 0.95–1.07;
|
|
1894
1903
|
- scarf read 0.99–1.38, with its head-frame mean between 1.350 and 1.869.
|
|
1895
1904
|
|
|
1896
1905
|
The feet half was a screen-space heat mean held to 3.244.
|
|
@@ -1902,7 +1911,7 @@ In all three examples `hair_front` is drawn over the face and weighted to `head`
|
|
|
1902
1911
|
bang bones. Its art swings into the face outline, relative to the head, on every idle
|
|
1903
1912
|
frame:
|
|
1904
1913
|
|
|
1905
|
-
| | `demo` | `sample` | `scarf` |
|
|
1914
|
+
| | `reference-demo` | `reference-sample` | `scarf` |
|
|
1906
1915
|
| --- | --- | --- | --- |
|
|
1907
1916
|
| deepest reach into the face | 2.816 rig px | 2.194 rig px | 2.479 rig px |
|
|
1908
1917
|
| most face area covered on one frame | 89.395 rig px² | 50.605 rig px² | 31.908 rig px² |
|
|
@@ -1960,7 +1969,7 @@ reported `crossing` depth is the only instrument for it.
|
|
|
1960
1969
|
**Before and after, the same builds, only `IDLE_MAX_PX` changed** (scratch copies of the
|
|
1961
1970
|
tree):
|
|
1962
1971
|
|
|
1963
|
-
| `--max` | before: face mean / calibration (ratio), feet mean, demo · sample · scarf | after: face `max_rig_px`, feet `max_rig_px`, all three |
|
|
1972
|
+
| `--max` | before: face mean / calibration (ratio), feet mean, reference-demo · reference-sample · scarf | after: face `max_rig_px`, feet `max_rig_px`, all three |
|
|
1964
1973
|
| --- | --- | --- |
|
|
1965
1974
|
| 620 | 1.283 / 1.196 (1.07), 1.504 · 0.933 / 0.900 (1.04), 0 · 1.350 / 1.360 (0.99), 0 | 4.202e-13, 0 · 4.418e-13, 0 · 4.224e-13, 0 |
|
|
1966
1975
|
| 640 | 1.328 / 1.145 (1.16), 1.619 · 0.898 / 0.897 (1.00), 0 · 1.869 / 1.352 (1.38), 0 | the same |
|
|
@@ -1978,7 +1987,7 @@ The selftest's planted cases (by hand):
|
|
|
1978
1987
|
|
|
1979
1988
|
After them, one **reported line** with no bar:
|
|
1980
1989
|
|
|
1981
|
-
| line | reports | bar | `demo` | `sample` | SKIP when |
|
|
1990
|
+
| line | reports | bar | `reference-demo` | `reference-sample` | SKIP when |
|
|
1982
1991
|
| --- | --- | --- | --- | --- | --- |
|
|
1983
1992
|
| `RECOMPOSITE_HOLES` | `parts.json`'s `recomposite` block (§5), read rather than measured: `error_px`, `uncovered_error_px`, `hole_count`, and the largest hole's `px`, `box` (`x,y wxh`) and `borders` (`<part> <px> px`) | none — status `REPORTED`, never FAIL, and `PASS` does not read it | 1,564 px in 453 holes; largest 70 px at 351,155 6x22, `hair_back` 53 px, `hair_front` 12 px | 1,185 px in 259 holes; largest 94 px at 479,412 7x34, `sleeves` 42 px, `topwear` 40 px, `bottomwear` 6 px | `parts.json` has no `recomposite` block (the reference's files) |
|
|
1984
1993
|
|
|
@@ -1996,16 +2005,16 @@ look at `recomposite_error_rig.png` when the largest hole is more than a sliver.
|
|
|
1996
2005
|
Under `--source <painting.png>`, a second reported line, also never a FAIL
|
|
1997
2006
|
(issue #77):
|
|
1998
2007
|
|
|
1999
|
-
| line | reports | bar | `demo` | `sample` | SKIP when |
|
|
2008
|
+
| line | reports | bar | `reference-demo` | `reference-sample` | SKIP when |
|
|
2000
2009
|
| --- | --- | --- | --- | --- | --- |
|
|
2001
2010
|
| `SETUP_POSE_VS_SOURCE` | the setup pose against the painting, by `assemble`'s own `measureRecomposite` over the stage's pixels — `mean_abs` and `within_share` (mean channel, within 8), `error_px` (max channel over 40), `uncovered_error_px` (of those, where the pose has alpha 128 or less), `hole_count` and the largest hole's box — with `painting_px`, `stage_px`, `render_px` and `render_scale` beside them. The painting is resampled onto the stage as assemble resamples it (lanczos3, alpha dropped). rigc renders onto an opaque grey, so the pose over white and its alpha are read off a second still of the same pose with every slot tinted black; both are carried onto the stage with the seam's map turned round (bilinear) | none — status `REPORTED`; assemble applies no bar to the figures it measures, so none is derived here | 3.146 / 93.43 % / 12,399 / 1,732, 518 holes, the largest 61 px at 351,157 6x20 (assemble's recomposite: 2.391 / 95.81 % / 11,050 / 1,564, 453) | 1.095 / 97.30 % / 5,348 / 1,239, 313 holes, the largest 88 px at 479,416 6x29 (assemble's: 0.835 / 97.95 % / 4,512 / 1,185, 259) | not written without `--source` |
|
|
2002
2011
|
|
|
2003
2012
|
The figures are assemble's by construction, not a second definition beside them;
|
|
2004
2013
|
what differs is what they are taken of — the pose rigc draws, not the flat stack —
|
|
2005
2014
|
and the gap between the two columns above is that drawing: the render's resampling at
|
|
2006
|
-
its scale (0.942 on
|
|
2015
|
+
its scale (0.942 on reference-demo, 1.012 on reference-sample) and the warp back onto the stage,
|
|
2007
2016
|
which soften every part edge by a pixel or two. It moves with the render's grid
|
|
2008
|
-
[observed,
|
|
2017
|
+
[observed, reference-demo's still rendered at four sizes: mean 2.663 at scale 1.0003, 3.091
|
|
2009
2018
|
at 1.0073, 3.146 at 0.942, 3.186 at 1.884], so compare the line with itself across
|
|
2010
2019
|
rigs or edits, and with `RECOMPOSITE_HOLES` for where a hole is, not digit for digit
|
|
2011
2020
|
with the recomposite. On the examples the line reads the same with and without
|
|
@@ -2035,11 +2044,11 @@ What each figure is, and is not:
|
|
|
2035
2044
|
chains of both examples are written the first way — so the reading folds a step into
|
|
2036
2045
|
(−¼, ¼] of a cycle and reports amplitudes unsigned. A lag of a quarter cycle or more
|
|
2037
2046
|
cannot be told from a lead. Tracks whose keys are not a sampled sine are listed as
|
|
2038
|
-
`unread`, and a keyed bone under a keyed ancestor of another period (
|
|
2047
|
+
`unread`, and a keyed bone under a keyed ancestor of another period (reference-demo's
|
|
2039
2048
|
tassel under the head) is listed in `other_period` and not compared.
|
|
2040
2049
|
- **Tip over root is a centroid, not a displacement.** Art entering or leaving a half
|
|
2041
2050
|
moves its centroid too. The halves' mean heat was the brief's first choice and was
|
|
2042
|
-
rejected: heat is texture times motion, and on
|
|
2051
|
+
rejected: heat is texture times motion, and on reference-demo's sleeves the lower half's
|
|
2043
2052
|
mean heat is 1.1 times the upper half's while its centroid travels 3.7 times as far.
|
|
2044
2053
|
The halves split the box across its rows, which assumes the part hangs — true of a
|
|
2045
2054
|
front-facing standing figure, the only input this tool takes.
|
|
@@ -2047,9 +2056,9 @@ What each figure is, and is not:
|
|
|
2047
2056
|
distorts a texture as much as stretch — an edge at half its rest length squeezes
|
|
2048
2057
|
the texels on it by the factor an edge at twice its length spreads them — so the
|
|
2049
2058
|
figure is max(ratio, 1/ratio), and on both examples the worst triangle is a
|
|
2050
|
-
compression (demo 0.720, sample 0.815). The ceiling rule is applied to the quantity
|
|
2059
|
+
compression (reference-demo 0.720, reference-sample 0.815). The ceiling rule is applied to the quantity
|
|
2051
2060
|
whose zero means "nothing happened", as it is for heat: for a ratio that is |ln r|,
|
|
2052
|
-
so twice demo's |ln 1.388| is ln(1.388²) = ln 1.926544 and sample clears it by 3.2
|
|
2061
|
+
so twice reference-demo's |ln 1.388| is ln(1.388²) = ln 1.926544 and reference-sample clears it by 3.2
|
|
2053
2062
|
times. Doubling the ratio itself (2.776) was rejected: its zero is not at 1, and it
|
|
2054
2063
|
passes an edge drawn at 2.7 times its rest length. The rest is the art's own
|
|
2055
2064
|
proportions — on both examples every rest edge equals its `uvs` edge times the
|
|
@@ -2080,7 +2089,7 @@ What each figure is, and is not:
|
|
|
2080
2089
|
its depth is reported per slot in `crossing`, which no bar reads.
|
|
2081
2090
|
- **The feet are measured in screen space.** They ride the root, which the idle does not
|
|
2082
2091
|
key, so the screen is their own frame.
|
|
2083
|
-
- Until #123 the feet half read the screen-space heat. On
|
|
2092
|
+
- Until #123 the feet half read the screen-space heat. On reference-demo the long skirt,
|
|
2084
2093
|
drawn under the shoes, swings beside them and lit their rim to 1.622.
|
|
2085
2094
|
- From the geometry, nothing drawn over the shoes enters them on any example, and
|
|
2086
2095
|
the shoes move exactly 0.
|
|
@@ -2116,7 +2125,7 @@ it reads is there, and says SKIP with the reason when it is not:
|
|
|
2116
2125
|
`PASS` reads every bar that measured, and the last console line says how many did:
|
|
2117
2126
|
`check: PASS; 1 of 9 bar(s) measured, 8 skipped (loop, seam, …)` is a rig whose gate is
|
|
2118
2127
|
green and nothing else was looked at. Without an idle no idle is rendered
|
|
2119
|
-
(`idle_frames/`, `contact.png` and `motion_heat.png` are not written).
|
|
2128
|
+
(`idle_frames/`, `contact.png` and `motion_heat.png` are not written). Reference-demo's own
|
|
2120
2129
|
rig directory, copied away from its `parts.json`, reads `4 of 9`: the gate, the loop,
|
|
2121
2130
|
`CHAIN_LAG` and `TEXTURE_STRETCH`.
|
|
2122
2131
|
|
|
@@ -2152,7 +2161,7 @@ What is composed:
|
|
|
2152
2161
|
|
|
2153
2162
|
- **Images are `<id>.<file>`, not `<id>:<file>`.** rig-c names an atlas region
|
|
2154
2163
|
by its PNG's basename, and an atlas region line that holds `:` is read as a
|
|
2155
|
-
`key: value` line: measured through rig-c 2.15.0 on
|
|
2164
|
+
`key: value` line: measured through rig-c 2.15.0 on reference-demo renamed
|
|
2156
2165
|
`demo:<name>` with images `demo:<file>`, `A07_ATLAS_TEXT_SHAPE` fails once per
|
|
2157
2166
|
region; with the images under a `demo/` folder the rig gates green but the region
|
|
2158
2167
|
keeps the bare basename, so two characters' `face` would collide. So the
|
|
@@ -2367,21 +2376,21 @@ is built (`CK83`–`CK85`, `RQ30`–`RQ35`).
|
|
|
2367
2376
|
|
|
2368
2377
|
## 8. What one character costs
|
|
2369
2378
|
|
|
2370
|
-
| step | sample | demo | source |
|
|
2379
|
+
| step | reference-sample | reference-demo | source |
|
|
2371
2380
|
| --- | --- | --- | --- |
|
|
2372
|
-
| painting (GPU) | 20.2 s | 18.3 s | `generation.json` `elapsed_s`, in [
|
|
2381
|
+
| painting (GPU) | 20.2 s | 18.3 s | `generation.json` `elapsed_s`, in [parts-examples](https://github.com/rig-c/parts-examples) |
|
|
2373
2382
|
| See-through full run (GPU) | 194.9 s | 198.5 s | `inputs/layers/full/meta.json` `elapsed_s` |
|
|
2374
2383
|
| See-through head run (GPU) | 170.9 s | 171.4 s | `inputs/layers/head/meta.json` `elapsed_s` |
|
|
2375
2384
|
| `build` (CPU, user + sys) | 14.6 s | 30.7 s | measured with `/usr/bin/time -p` on an Apple M4 machine under other load, rigc's child processes included; wall clock 12.7 s and 27.5 s |
|
|
2376
2385
|
|
|
2377
2386
|
About 6.5 minutes of GPU and under a minute of CPU per character, before any hand
|
|
2378
2387
|
correction. The GPU figures are one run each on one machine; the painting's figure
|
|
2379
|
-
excludes choosing among seeds (
|
|
2388
|
+
excludes choosing among seeds (reference-demo was chosen from eighteen candidates).
|
|
2380
2389
|
Since issue #33 `check` runs one more `rigc build` and one more idle render (the face
|
|
2381
2390
|
calibration, §7); the idle's `geometry.json` is the one issue #31 already writes. The `build` row
|
|
2382
2391
|
was not re-measured: A/B against the tree before that change, alternating on one
|
|
2383
2392
|
machine under a load average of 5 to 11, the difference in user + sys was +5.6 and
|
|
2384
|
-
+0.8 s on
|
|
2385
|
-
the load moves the same build by (the pre-change demo build alone took 43.6 to
|
|
2393
|
+
+0.8 s on reference-demo and +6.5 and −1.6 s on reference-sample over two rounds — inside what
|
|
2394
|
+
the load moves the same build by (the pre-change reference-demo build alone took 43.6 to
|
|
2386
2395
|
45.8 s there). Since issue #123 that build and render are gone again — the still regions read the
|
|
2387
2396
|
idle's geometry — and the `build` row was not re-measured for it either.
|
package/docs/STABILITY.md
CHANGED
|
@@ -231,7 +231,7 @@ the input and the machine. Measured: the evidence tools run every cell under a
|
|
|
231
231
|
rig-c 2.23.0 (the same document's quiet timing table, a remote WSL runner, pool,
|
|
232
232
|
load under 2); at rig-c 2.31.0 the whole rig stage of one automatic part, motion
|
|
233
233
|
gate and acceptance loop included, took 1.1 s to 61.6 s on the eight parts the
|
|
234
|
-
surveys switch, demo `bottomwear` the slowest at 12 gated builds, with a run-to-run
|
|
234
|
+
surveys switch, reference-demo `bottomwear` the slowest at 12 gated builds, with a run-to-run
|
|
235
235
|
spread of ±15 % on that part (pull request #152's paired exclusive timing, remote
|
|
236
236
|
20-core runner; the surveys print wall time to standard error, not into the
|
|
237
237
|
documents). On CI (`ubuntu-latest`), the last two green runs on `main` took 4 min
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.5",
|
|
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": {
|
|
@@ -125,7 +125,7 @@ it and the order as `scene.json` records it (AUTHORING §7, *Composing several
|
|
|
125
125
|
characters*).
|
|
126
126
|
|
|
127
127
|
`--seam silhouette` repairs more of the seam on white garments than the default
|
|
128
|
-
`near-white` (
|
|
128
|
+
`near-white` (reference-demo: 10,340 → 8,644 recomposite error pixels); the default is
|
|
129
129
|
the reference implementation's rule. `--project visible` lets thin visible parts
|
|
130
130
|
(lashes, brows, irises) take the painting's pixels, which the default `core` rule
|
|
131
131
|
erodes away. Name both rules you used in your report, and quote the assemble
|
|
@@ -159,7 +159,7 @@ leaves to you:
|
|
|
159
159
|
- An expression or any other named animation: AUTHORING §3, *Recipe: expressions and other
|
|
160
160
|
named animations* (`motion.animations_from`; built and gated with the rig, not measured).
|
|
161
161
|
- A jiggle (a bust, the hips): AUTHORING §3, *Recipe: a soft region driven by physics* (a
|
|
162
|
-
config-only bone, a `contour` region on it, a `physics` constraint; `examples/sample`
|
|
162
|
+
config-only bone, a `contour` region on it, a `physics` constraint; `examples/reference-sample`
|
|
163
163
|
carries one, and its slow idle barely moves it).
|
|
164
164
|
|
|
165
165
|
A `RIG_RIGC_GREEN` or `CHECK_RIGC_GREEN`
|