@rig-c/parts 1.16.0 → 1.18.0
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 +8 -3
- package/cli.ts +191 -24
- package/docs/AUTHORING.md +381 -21
- package/docs/MIGRATION.md +52 -0
- package/docs/PAINTING.md +172 -0
- package/docs/STABILITY.md +14 -9
- package/package.json +2 -1
- package/skills/rig-parts/SKILL.md +31 -2
- package/src/assemble.ts +642 -41
- package/src/autoamplitude.ts +23 -3
- package/src/autoenvelope.ts +17 -5
- package/src/build.ts +109 -13
- package/src/check.ts +632 -11
- package/src/config.ts +185 -8
- package/src/inputs.ts +11 -1
- package/src/layers.ts +231 -18
- package/src/limbs.ts +188 -0
- package/src/paintcheck.ts +250 -0
- package/src/parts.ts +167 -6
- package/src/propose.ts +148 -108
- package/src/rig.ts +43 -8
- package/src/tags.ts +47 -0
package/docs/MIGRATION.md
CHANGED
|
@@ -210,3 +210,55 @@ no declared form changed.
|
|
|
210
210
|
What to do: nothing for a config without `contour.bridges`. A part that declares it and
|
|
211
211
|
holds a faint island no longer draws that island; if those pixels matter, keep the
|
|
212
212
|
lattice for that part.
|
|
213
|
+
|
|
214
|
+
## After 1.17.0: an artist's own file
|
|
215
|
+
|
|
216
|
+
Issue #359 makes an artist's layered PSD an input in its own right (AUTHORING §4,
|
|
217
|
+
*For artists* and *The correction loop*). Nothing a config already builds changes:
|
|
218
|
+
every new form was refused or a usage error before, so no byte any existing build
|
|
219
|
+
writes moves (the selftest's existing controls and the examples' `expected/` are
|
|
220
|
+
unchanged by it).
|
|
221
|
+
|
|
222
|
+
| change | before | after |
|
|
223
|
+
| --- | --- | --- |
|
|
224
|
+
| `assemble`, `--propose-plan` and `build` without `--head` | a usage error (exit 2) | one run: the full run must hold `face`, `eyewhite-r` and `eyewhite-l`, painted (`ASSEMBLE_SINGLE_RUN_FACE`); every row takes `"full"` (`ASSEMBLE_SINGLE_RUN_PLAN`); no `seethrough.head_box` (`ASSEMBLE_SINGLE_RUN_HEAD_BOX`) |
|
|
225
|
+
| `propose --full`/`--head` over runs with no depth on any part's layer (a PSD) | refused, `PROPOSE_TURN_DEPTH_PRESENT` on every part (exit 1) | no `turn`, one note `turn: SKIP — <runs> carry no depth_median …`, the proposal written (exit 0); a run where some parts' layers carry a depth and others do not is still refused part by part, and the detail now says so |
|
|
226
|
+
| a wrapper `layers.json` with `depth_median: null` | refused, `LAYERS_FIELD_PRESENT` | `null` on every drawn layer reads in the manifest's order; a mix is `LAYERS_DEPTH_ALL_OR_NONE` |
|
|
227
|
+
| a layer named `<layer>:hidden` | refused, `LAYERS_TAG_KNOWN` | a hidden-art layer, listed apart and never drawn; read as a cut's `under` and a limb segment's cap where the config names no file (`ASSEMBLE_HIDDEN_ONE_SOURCE` when it names one too) |
|
|
228
|
+
| `layers` on a PSD, or on a manifest with no depth | the table | the table and one `SKIP depth:` line naming the file |
|
|
229
|
+
| `parts.json`, a limb segment's `cap` | `image_px` with a cap file | `image_layer` after `image_px` when the image was a hidden-art layer |
|
|
230
|
+
|
|
231
|
+
What to do: nothing. A consumer that matched `PROPOSE_TURN_DEPTH_PRESENT` to detect a
|
|
232
|
+
PSD run reads the `turn: SKIP` note instead.
|
|
233
|
+
|
|
234
|
+
Issue #366 lets that one run be a file that is not square (AUTHORING §4, *For
|
|
235
|
+
artists*: the canvas). Two-run builds and a square file at `seethrough.resolution`
|
|
236
|
+
are read exactly as before — no `single_run_pad` block, no `padded:` line, the same
|
|
237
|
+
bytes (the selftest's existing single-run controls and the examples' `expected/` are
|
|
238
|
+
unchanged by it).
|
|
239
|
+
|
|
240
|
+
| change | before | after |
|
|
241
|
+
| --- | --- | --- |
|
|
242
|
+
| one run whose file is not the `resolution` square, no side above it | refused, `ASSEMBLE_RUN_CANVAS` | padded to the square, centred (the odd pixel right or bottom), and assembled in the file's pixels; `parts.json` ends with `single_run_pad` (`file_size`, `side`, `left`, `top`) and `assemble` prints a `padded:` line under `one run:` |
|
|
243
|
+
| one run whose file has a side above `resolution` | refused, `ASSEMBLE_RUN_CANVAS` | still refused by that code; the detail now says padding cannot shrink a file and names the resolution that would hold it |
|
|
244
|
+
| one run with a painting of another size than the file | read: the run mapped onto the painting at the painting's scale | refused, `ASSEMBLE_SINGLE_RUN_SOURCE` — §4 already required the same size |
|
|
245
|
+
| a `parts.json` with `single_run_pad` | refused, `PARTS_KEY_KNOWN` | read; a block that is not the centring, or disagrees with `rig_size`, is `PARTS_SINGLE_RUN_PAD` |
|
|
246
|
+
|
|
247
|
+
What to do: nothing, unless a single-run painting was not the file's own size — pass
|
|
248
|
+
the file flattened.
|
|
249
|
+
|
|
250
|
+
### And a check before See-through (`painting`, issue #350)
|
|
251
|
+
|
|
252
|
+
A new command, `rig-parts painting --keypoints <k.json> [--person <id>]
|
|
253
|
+
<painting.png>`, reads a painting against its body-18 joints before See-through runs
|
|
254
|
+
and refuses what a rig cannot be cut from (arms against the body, hands together,
|
|
255
|
+
legs without a gap, a joint off the figure, a background that is not plain;
|
|
256
|
+
[PAINTING.md](PAINTING.md)). It reads the keypoint file `propose --keypoints` reads
|
|
257
|
+
and writes nothing; no other command changed, and no byte any build writes moves.
|
|
258
|
+
|
|
259
|
+
| change | before | after |
|
|
260
|
+
| --- | --- | --- |
|
|
261
|
+
| `rig-parts painting` | a usage error, `unknown command` (exit 2) | the check: exit 0 PASS, 1 with a `FAIL PAINTING_…` line per refusal |
|
|
262
|
+
| the README's input bullet for the painting | one sentence | the requirements, linked to `docs/PAINTING.md`, which ships in the package |
|
|
263
|
+
|
|
264
|
+
What to do: nothing. Run `painting` on a new painting before See-through.
|
package/docs/PAINTING.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# The painting: what makes one riggable
|
|
2
|
+
|
|
3
|
+
rig-parts starts from one painting of one character. Making that painting is
|
|
4
|
+
yours — on your own GPU, with any generator, or by hand — and this package runs
|
|
5
|
+
no model. But a painting the pipeline cannot rig fails late: a sleeve layer that
|
|
6
|
+
holds the torso, a leg chain that drags the other leg, a dance clip that tears.
|
|
7
|
+
This page lists what the painting must be, why the pipeline needs each thing, and
|
|
8
|
+
what breaks without it; gives one generation recipe as a starting point; says how
|
|
9
|
+
to paint alternate art for a limb; and describes `rig-parts painting`, the check
|
|
10
|
+
that reads the painting before See-through runs on it.
|
|
11
|
+
|
|
12
|
+
There are two ways in:
|
|
13
|
+
|
|
14
|
+
- **A generated painting**, decomposed by [See-through](https://github.com/shitagaki-lab/see-through)
|
|
15
|
+
into layers. Everything below is about this route.
|
|
16
|
+
- **An artist's own layered file** (a PSD, one layer per part): [AUTHORING §4,
|
|
17
|
+
*For artists*](AUTHORING.md#for-artists-your-own-layered-file-issue-359) and
|
|
18
|
+
*The correction loop*. The requirements below still hold for the figure — a
|
|
19
|
+
limb the artist draws against the body is as hard to move — but there is no
|
|
20
|
+
See-through step to fail, and an artist can paint what a joint hides as a
|
|
21
|
+
`<layer>:hidden` layer.
|
|
22
|
+
|
|
23
|
+
For the environment that makes a painting (an NVIDIA GPU, an Apple Silicon Mac, or
|
|
24
|
+
none), see [rig-c/getting-started](https://github.com/rig-c/getting-started).
|
|
25
|
+
|
|
26
|
+
## The requirements
|
|
27
|
+
|
|
28
|
+
Each requirement says what the pipeline needs, what fails without it, and whether
|
|
29
|
+
`rig-parts painting` reads it (and under which rule) or only an eye can.
|
|
30
|
+
|
|
31
|
+
| requirement | why the pipeline needs it | what fails without it | read by |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| **Front view** | the proposer and the keypoint file read the subject's right on the image's left of a figure facing the viewer, and the eyes, the blink and the head turn are drafted from a face toward the viewer | a back view has no face part for `propose` to draft from (`PROPOSE_FACE_PRESENT`, or the face-less fallback its first note names) | an eye |
|
|
34
|
+
| **Full body, inside the frame** | the figure's height is the proposer's yardstick, and the feet carry the leg chain's last link | a cropped foot is a leg with no ankle; a figure touching the edge reads as background that is not plain | `PAINTING_BACKGROUND_PLAIN` |
|
|
35
|
+
| **Arms clear of the body** (an A-pose: arms down and out, a gap under each arm) | See-through separates what it can see; an arm with background round it becomes its own `handwear` and sleeve layers | an arm painted against the side is cut into a layer that holds part of the torso, and no rotation of its bone can swing it clear without dragging the torso's pixels | `PAINTING_ARM_CLEAR`: a gap on the line from each wrist to the hip of its side |
|
|
36
|
+
| **Hands apart and open** | each hand is a part on its own arm's chain; open fingers read as a hand at a thumbnail | clasped or touching hands are one `handwear` layer, split only by an `assemble.cuts` polygon drawn by hand; and the clasped hands the README showed until issue #227 did not read as hands above a thumbnail (`examples/demo/README.md`) | `PAINTING_HANDS_APART`: a gap on the line between the wrists. Hands that meet close a loop of arms round the torso, so both arms are refused with them |
|
|
37
|
+
| **Legs apart, with a visible gap** | the leg chain needs the legs painted apart (two legs that touch are one column See-through cannot split), and limbs are cut at their joints (#349, AUTHORING §3, *Limbs*), so each knee must be its own | legs that touch at the knee or the ankle come back as one `legwear` silhouette, a cut at the knee takes the other leg's pixels, and a step drags both | `PAINTING_LEGS_APART`: a gap on the line between the knees and on the line between the ankles |
|
|
38
|
+
| **Feet facing front** | a foot seen from the front stays inside its leg's column, below the ankle the leg chain ends at | not measured in this repository; read the leg parts on the `sheet` | an eye (body-18 has no foot points) |
|
|
39
|
+
| **A plain light background** | See-through and `assemble` read near-white as background (every channel above 235, the one test the assemble rim and the layer plausibility figures share) | scenery, a floor, a cast shadow, a gradient or a vignette is read as more figure — a layer of haze (`PLAN_LAYER_BACKGROUND`), or pixels that belong to no part | `PAINTING_BACKGROUND_PLAIN`: every border pixel near-white or unpainted |
|
|
40
|
+
| **Nothing held, no prop across a limb** | each part rides one bone; a prop belongs to no tag See-through knows | a held object joins the hands (`PAINTING_HANDS_APART`) or lands in a hand or garment layer and moves with the wrong bone | partly: a prop that joins the hands is `PAINTING_HANDS_APART`; anything else, an eye |
|
|
41
|
+
| **Clothing that leaves the joints unoccluded** | limbs are cut at the elbow and the knee (#349); each lower part carries a cap painted from what the joint hides | long sleeves and tights are fine; a cape over the elbows, a wide skirt over the knees or a forearm in front of the skirt's flare puts two parts' pixels on one joint. `assemble` names the missing cap pixels in its `limb cap:` lines | partly: a skirt over the knees is `PAINTING_LEGS_APART`, a forearm across a skirt is `PAINTING_ARM_CLEAR`; a cape over an elbow, an eye |
|
|
42
|
+
| **Resolution and aspect** | See-through runs on a square (`inputs` pads the painting white to a square of its longer side) at `seethrough.resolution` (1024 by default), and a second run on a crop round the head, because the eyes of a full-figure run are too small to separate. A standing figure is taller than wide; `comfy paint` writes twice its latent (832x1216 → 1664x2432) | a landscape painting is padded above and below and spends See-through's square on white; a small painting leaves the head crop too few pixels for the eyes | an eye; `inputs` refuses a translucent painting (`INPUTS_PAINTING_OPAQUE`) and a head box off it |
|
|
43
|
+
|
|
44
|
+
**One painting, one character.** The keypoint file may hold several people, and
|
|
45
|
+
`--person` names the one checked; the pipeline rigs one.
|
|
46
|
+
|
|
47
|
+
## The check: `rig-parts painting`
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
rig-parts painting --keypoints <keypoints.json> [--person <id>] <painting.png>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
It runs on the CPU, before See-through, on the painting and its body-18 joints:
|
|
54
|
+
the same keypoint file `propose --keypoints` reads (AUTHORING §3, *A posed
|
|
55
|
+
figure*), from any estimator or written by hand, measured on this painting (its
|
|
56
|
+
`width` and `height` are the painting's, `KEYPOINTS_IMAGE_SIZE`). It writes
|
|
57
|
+
nothing. It prints the figure, every joint and every gap with its count, then
|
|
58
|
+
`PASS` and exit 0, or a `FAIL` line per refusal and exit 1. Each `FAIL` line ends
|
|
59
|
+
with `(see rig-parts guide <RULE>)`, which prints the rule's row in
|
|
60
|
+
[AUTHORING §6](AUTHORING.md#6-refusals-the-rule-and-what-has-to-change).
|
|
61
|
+
|
|
62
|
+
What it reads, each a definition with no tuned number:
|
|
63
|
+
|
|
64
|
+
- **Ground** — a pixel the package already calls background: alpha 8 or less
|
|
65
|
+
(unpainted, the layer reader's cut), or every colour channel above 235
|
|
66
|
+
(near-white, the assemble stage's and the plausibility figures' test).
|
|
67
|
+
- **Background** — the ground that reaches the edge: ground 4-connected to ground
|
|
68
|
+
on the border. A white blouse inside its line art is ground but not background,
|
|
69
|
+
so it is figure.
|
|
70
|
+
- **Figure** — everything that is not background.
|
|
71
|
+
- **A gap** between two joints — at least one background pixel on the straight
|
|
72
|
+
line between them, sampled once per pixel the line crosses.
|
|
73
|
+
|
|
74
|
+
The rules: `PAINTING_BACKGROUND_PLAIN` (every border pixel is ground),
|
|
75
|
+
`PAINTING_JOINTS_STATED` (the wrists, hips, knees and ankles are `observed` with a
|
|
76
|
+
position), `PAINTING_JOINT_ON_FIGURE` (every observed joint's pixel is figure),
|
|
77
|
+
`PAINTING_ARM_CLEAR`, `PAINTING_HANDS_APART` and `PAINTING_LEGS_APART` (the gaps in
|
|
78
|
+
the table above).
|
|
79
|
+
|
|
80
|
+
What it does not read: a front view, the feet, a prop that does not join the
|
|
81
|
+
hands, a cape over an elbow, the hands' fingers, the face. A green `painting` says
|
|
82
|
+
the joints and the silhouette hold the requirements it reads, not that the
|
|
83
|
+
painting is good. A shadow or a floor enclosed by the background is figure to it;
|
|
84
|
+
the border rule sees it only where it reaches the edge.
|
|
85
|
+
|
|
86
|
+
## A recipe that is one way, not the only way
|
|
87
|
+
|
|
88
|
+
Anyone with a different generator reads the requirements above, not this. This
|
|
89
|
+
is the `generation` block of the public `demo` example (`examples/demo/config.json`,
|
|
90
|
+
with its pose file `examples/demo/pose.json`), which `rig-parts comfy paint`
|
|
91
|
+
painted, with three changes: its character's words in `identity` and `costume`
|
|
92
|
+
are placeholders, and the words its idol costume needed in `negative_extra`
|
|
93
|
+
("microphone, holding microphone, stage, stage lights") are left out; its full record — the candidates, the seed choice and a hand-detailer
|
|
94
|
+
pass `comfy paint` does not run — is in
|
|
95
|
+
[parts-examples](https://github.com/rig-c/parts-examples):
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
"generation": {
|
|
99
|
+
"checkpoint": "hassakuXLIllustrious_v13StyleA.safetensors",
|
|
100
|
+
"loras": [],
|
|
101
|
+
"trigger": "",
|
|
102
|
+
"identity": "1girl, solo, adult woman, <your character's hair, eyes, accessories>",
|
|
103
|
+
"sampler": { "steps": 30, "cfg": 6.0, "sampler": "euler_ancestral", "scheduler": "normal" },
|
|
104
|
+
"costume": "<the costume>, fully clothed, empty hands",
|
|
105
|
+
"negative_extra": "revealing clothes, bare shoulders, off shoulder, 2girls, multiple girls, holding, bag, weapon, clouds, cloud, sun, sky, sky background, grey background, blue background, gradient background, scenery, outdoors, from behind, back view, back of head, facing away, vignette, beige background, brown background, dark background, black background, spotlight, lighting gradient, flat color, cel shading, monochrome, lineart",
|
|
106
|
+
"pose": "full body, head to toe, entire body in frame, front view, facing viewer, looking at viewer, standing, arms away from body, hands apart away from skirt, open hands, relaxed fingers, relaxed pose, gentle smile, feet visible, shoes",
|
|
107
|
+
"style": "anime illustration, detailed, soft shading, (white background:1.3), simple background, plain background",
|
|
108
|
+
"negative_pose": "cropped, out of frame, cut off feet, close-up, portrait, upper body, from side, profile, sitting, kneeling, dynamic pose, arms raised, hand on face, contact shadow, cast shadow, floor, multiple views, reference sheet",
|
|
109
|
+
"latent": [832, 1216],
|
|
110
|
+
"seed": 71006,
|
|
111
|
+
"control": { "skeleton": "pose.json", "strength": 0.8, "end_percent": 0.7 }
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Put your character in the two placeholders, and negate what its costume invites.
|
|
116
|
+
What each part does:
|
|
117
|
+
|
|
118
|
+
- **The checkpoint** is public: [Hassaku XL (Illustrious)](https://civitai.com/models/140272)
|
|
119
|
+
v1.3 Style A, no LoRA. `scarf` and the two reference examples used
|
|
120
|
+
[Pony Diffusion V6 XL](https://civitai.com/models/257749) with the same sampler.
|
|
121
|
+
- **The control skeleton** is what holds the pose; a pose asked for in words
|
|
122
|
+
alone is one the sampler is free to ignore (`src/skeleton.ts`). `comfy paint`
|
|
123
|
+
draws it as OpenPose body-18 in the annotator's own style and applies it through
|
|
124
|
+
`controlnet-openpose-sdxl-1.0` at strength 0.8, ending at 0.7 of the steps. The
|
|
125
|
+
two built-ins are `stand_sides` (arms nearly straight down at the sides) and
|
|
126
|
+
`stand_clasp` (hands clasped at the waist), neither an A-pose; `pose.json` is a
|
|
127
|
+
pose file (issue #198) with the arms held out: the wrists at (206, 590) and
|
|
128
|
+
(626, 590) on the 832x1216 canvas, the shoulders at (340, 272) and (492, 272).
|
|
129
|
+
A pose file carries no words, so `generation.pose` is required beside it.
|
|
130
|
+
- **The pose words** repeat what the skeleton asks — arms away, hands apart and
|
|
131
|
+
open — and the **negatives** refuse what breaks a rig: a held object, a
|
|
132
|
+
background that is not plain, a back or side view, a crop, a cast shadow or a
|
|
133
|
+
floor.
|
|
134
|
+
- **The seed** is chosen by looking: the demo's was the best of sixteen candidates,
|
|
135
|
+
read at the hands; generate several and run `rig-parts painting` on each.
|
|
136
|
+
|
|
137
|
+
What this recipe did not hold, measured: on the demo painting itself, with joints
|
|
138
|
+
read by eye, `rig-parts painting` refuses both arms (the forearms cross the
|
|
139
|
+
skirt's flare) and the legs at the knees and the ankles (the pose file's knees
|
|
140
|
+
and ankles are the built-ins', close together, and the thighhighs touch). So
|
|
141
|
+
change the two things it did not ask for, and check the result: move the pose
|
|
142
|
+
file's knees and ankles apart and add leg words ("legs apart") to `pose`, and keep
|
|
143
|
+
a skirt short or narrow enough that the forearms hang clear of it. How far apart
|
|
144
|
+
holds a gap on a given checkpoint is not measured here; `painting` is the
|
|
145
|
+
instrument that says.
|
|
146
|
+
|
|
147
|
+
## Alternate art for a limb
|
|
148
|
+
|
|
149
|
+
A rig plays its base art in every pose; where a limb turns somewhere the base art
|
|
150
|
+
cannot follow (behind the head, toward the camera), the mesh folds.
|
|
151
|
+
[rig-c/pose#6](https://github.com/rig-c/pose/issues/6) lets `rig-pose retarget`
|
|
152
|
+
switch to an alternate drawing of the limb for those spans, and its report's
|
|
153
|
+
`uncovered` list names every fold no alternate covers — that list is the answer
|
|
154
|
+
to *which* angles to paint.
|
|
155
|
+
|
|
156
|
+
To paint one without the character drifting, repaint only the limb:
|
|
157
|
+
|
|
158
|
+
1. **Start from the base painting**, not from a new generation: the face, the
|
|
159
|
+
costume and the colours stay the base painting's pixels.
|
|
160
|
+
2. **Inpaint with a mask along the old and the new limb**: the region the limb
|
|
161
|
+
leaves and the region it moves into, from the shoulder (or hip) down. Keep the
|
|
162
|
+
face out of the mask.
|
|
163
|
+
3. **Use the key skeleton as the control**: the body-18 pose the alternate depicts,
|
|
164
|
+
in the painting's space — the same skeleton the pose map's `alternates` entry
|
|
165
|
+
records — drawn the way `comfy paint` draws a pose file.
|
|
166
|
+
4. **Run See-through on the result and take the limb's layers** (the sleeve, the
|
|
167
|
+
hand); the rest of that run is discarded. The base rig's other parts stay the
|
|
168
|
+
base painting's.
|
|
169
|
+
|
|
170
|
+
`comfy paint` does not run an inpainting graph; the demo's hand-detailer pass is
|
|
171
|
+
the same idea at hand scale (a masked repaint on the same checkpoint, recorded
|
|
172
|
+
beside its painting in parts-examples).
|
package/docs/STABILITY.md
CHANGED
|
@@ -46,21 +46,22 @@ defaults are the help's too, and none is guessed from the art.
|
|
|
46
46
|
<!-- stable:commands -->
|
|
47
47
|
| command | flags |
|
|
48
48
|
| --- | --- |
|
|
49
|
-
| `layers` | one positional path: a wrapper directory, a `layers.json` or a `.psd` |
|
|
49
|
+
| `layers` | one positional path: a wrapper directory, a `layers.json` or a `.psd`; with it, optional `--export` (a directory to write the wrapper form into, issue #359); or `--template` with `--canvas` and no path |
|
|
50
50
|
| `sheet` | `--source`, `--layers` (repeatable), `--out`; optional `--cell`, `--cols` |
|
|
51
51
|
| `inputs` | `--source`, `--config`, `--out` |
|
|
52
52
|
| `comfy` | `paint`: `--config`, `--out`; optional `--seeds`, `--seed0`, `--host`, `--wait`, `--timeout`, `--poll` |
|
|
53
53
|
| `comfy` | `seethrough`: `--image`, `--out`; optional `--resolution`, `--steps`, `--seed`, `--prefix`, `--offload`, `--lama`, `--nf4`, `--host`, `--wait`, `--timeout`, `--poll` |
|
|
54
|
-
| `assemble` | `--propose-plan` with `--source`, `--full`, `--
|
|
54
|
+
| `assemble` | `--propose-plan` with `--source`, `--full`, `--config`, optional `--head`; or `--source`, `--full`, `--config`, `--out`, optional `--head` (without it, one run: issue #359), `--seam` (near-white, silhouette), `--project` (core, visible) |
|
|
55
55
|
| `propose` | `--head-box` with `--full`, `--canvas` |
|
|
56
56
|
| `propose` | `--parts`, `--source`, `--out`; optional `--compare` or `--from-config` (one of them), `--keypoints`, `--person` and `--wrist-snap` (each with `--keypoints`), `--full`, `--head` (the turn control's depths; not with `--from-config`), `--grid-rule` (`figure` or `part`, the drafted lattice's spacing; not with `--from-config`) |
|
|
57
57
|
| `compare` | `--left`, `--right`; optional `--map` |
|
|
58
58
|
| `rig` | `--config`, `--parts`, `--out`; optional `--idle-keys` (ctl, direct), `--page-edges` (pot, free), `--pack-shape` (rect, polygon) |
|
|
59
59
|
| `check` | `--rig`, `--out`; optional `--parts`, `--source`, `--page-edges`, `--pack-shape`, `--requirements`, `--seam-pairs`, `--keep-stills` |
|
|
60
60
|
| `loop` | `--frames`, `--out`; optional `--palette` |
|
|
61
|
-
| `build` | `--config`, `--source`, `--full`, `--
|
|
61
|
+
| `build` | `--config`, `--source`, `--full`, `--out`; optional `--head` (as for `assemble`), `--seam`, `--project`, `--page-edges`, `--pack-shape`, `--loop`, `--lead-in`, `--requirements`, `--idle-keys`, `--seam-pairs`, `--keep-stills` |
|
|
62
62
|
| `compose` | `--scene`, `--out`; optional `--requirements`, `--accept` |
|
|
63
63
|
| `mesh-draft` | `--config`, `--parts`, `--out`; optional `--requirements`, `--idle-keys` (ctl, direct), `--page-edges` (pot, free), `--pack-shape` (rect, polygon), `--more-triangles` |
|
|
64
|
+
| `painting` | one positional path, the painting; `--keypoints`; optional `--person` |
|
|
64
65
|
| `guide` | one positional argument: a rule name, `§<n>`, `§<n>.<m>` or `§<n>.<m>.<k>` |
|
|
65
66
|
| (none) | `--version`, `--help` |
|
|
66
67
|
<!-- /stable:commands -->
|
|
@@ -111,7 +112,7 @@ The fields, object by object (a bold path is where the object sits; `<part>` is
|
|
|
111
112
|
part name, `[i]` an entry of a list):
|
|
112
113
|
|
|
113
114
|
<!-- stable:config -->
|
|
114
|
-
- **config** — required by the full loader, in front of rig and build: `key`, `assemble`, `bones`, `meshes`, `regions`, `motion`; optional: `generation`, `seethrough`, `constraints`, `turn`, `scene`
|
|
115
|
+
- **config** — required by the full loader, in front of rig and build: `key`, `assemble`, `bones`, `meshes`, `regions`, `motion`; optional: `generation`, `seethrough`, `limbs`, `constraints`, `turn`, `scene`
|
|
115
116
|
- **generation** — required: `checkpoint`, `loras`, `trigger`, `identity`, `sampler`, `costume`, `negative_extra`, `style`, `negative_pose`, `latent`, `seed`; optional: `pose`, `control`
|
|
116
117
|
- **generation.loras[i]** — required: `name`, `strength`; optional: `strength_clip`
|
|
117
118
|
- **generation.sampler** — required: `steps`, `cfg`, `sampler`, `scheduler`
|
|
@@ -124,7 +125,9 @@ part name, `[i]` an entry of a list):
|
|
|
124
125
|
- **assemble.patches[i].draw**, when an object — required: `before`
|
|
125
126
|
- **assemble.cuts[i]** — required: `from`, `into`, `polygon`, `draw`, `overlap`; optional: `under`
|
|
126
127
|
- **assemble.cuts[i].draw**, when an object — required: `before`
|
|
127
|
-
- **
|
|
128
|
+
- **limbs.<limb>** — required: `segments` (issue #349)
|
|
129
|
+
- **limbs.<limb>.segments[i]** — required: `part`, `from`, `bone`; required below a joint (i > 0): `joint`; optional below a joint: `range`, `cap`
|
|
130
|
+
- **bones[i]**, a single bone — required: `name`, `parent`, `at`; optional: `tip`, `inherit`
|
|
128
131
|
- **bones[i]**, a chain — required: `chain`, `parent`, `points`, `tip`
|
|
129
132
|
- **meshes.<part>** — exactly one of `grid`, `contour`, `auto`; required in every mode: `r`, `segments`; optional in every mode: `exponent`, `rule`; optional with `contour` or `auto`: `ribs`; optional with `grid` or `contour`: `influences` (issue #284; beside `auto` it is refused, CONFIG_INFLUENCES_MODE); optional with `grid`: `stray` (issue #303; beside `contour` or `auto` it is refused, CONFIG_STRAY_MODE)
|
|
130
133
|
- **meshes.<part>.influences** — optional, at least one: `maxInfluences` (a whole number, 1 or more, or null for no cap), `floor` ("cut" or "continuous")
|
|
@@ -154,7 +157,7 @@ part name, `[i]` an entry of a list):
|
|
|
154
157
|
- **turn** — required: `pivot`, `depths`
|
|
155
158
|
- **turn.depths.<part>** — a See-through depth
|
|
156
159
|
- **scene** — no field (`{}`; a record or an annotation only)
|
|
157
|
-
- **proposal.json**, the file propose writes — `bones`, `meshes`, `regions`, `motion` under the rules above, `turn` with `--full`/`--head`, and `notes`
|
|
160
|
+
- **proposal.json**, the file propose writes — `bones`, `meshes`, `regions`, `limbs` under `--keypoints` where an arm or a leg is drafted from its joints (issue #349), `motion` under the rules above, `turn` with `--full`/`--head`, and `notes`
|
|
158
161
|
<!-- /stable:config -->
|
|
159
162
|
|
|
160
163
|
`TY14` holds the set of field names in backticks above to the set of names the
|
|
@@ -171,10 +174,12 @@ every number) are AUTHORING §3's tables, and the loader refuses any other by na
|
|
|
171
174
|
|
|
172
175
|
| file | written by | what is stable |
|
|
173
176
|
| --- | --- | --- |
|
|
174
|
-
| `parts.json`, `parts/<name>.png` | `assemble`, `build` | one record per part: `from` (`<run>:<tag>` with a See-through v3 tag, `<run>:author:<label>` for a layer the author made — issue #256, read by no role rule — or `painting:<name>` for a patch), `cut_from` on a cut's piece only (the plan part it was cut from, issue #230), the box `x`, `y`, `w`, `h` (rig px), the pixel counts `src/parts.ts` documents (`opaque_px`, `visible_px`, `occluded_px`, `projected_core_px`, `source_px_taken`, `visible_not_projected_px`, `refused_drift_px`, `merged_px`, `seam_override_px`, and `fringe_pushed_back` when not empty); `rig_size`, `scale_rig_per_source`, `ghost_px`, `recomposite`, and `scene` (`figure_alpha_above`, `figure_px`, `figure_mask`) under `config.scene` only, with the figure's mask `figure_rig.png` beside the recomposite (issue #242) |
|
|
175
|
-
| `rig/rig.json`, `rig/motion.json`, `rig/images/` | `rig`, `build`, `compose` | rig-c's rig spec and motion spec, `spec` `rigc-rig/1` and `rigc-motion/1`: the format is rig-c's, and this package writes only what rig-c's parser accepts |
|
|
177
|
+
| `parts.json`, `parts/<name>.png` | `assemble`, `build` | one record per part: `from` (`<run>:<tag>` with a See-through v3 tag, `<run>:author:<label>` for a layer the author made — issue #256, read by no role rule — or `painting:<name>` for a patch), `cut_from` on a cut's piece only (the plan part it was cut from, issue #230), `limb` on a limb segment's part only (issue #349: `name`, `segment`, `of`, `bone`, and below a joint `joint` and `cap` — `at`, `width`, `radius`, `box`, `layer_px`, `image_px` with a cap image, `image_layer` after it when that image was a hidden-art layer — issue #359, `<run>:<layer>:hidden` — `missing_px`), the box `x`, `y`, `w`, `h` (rig px), the pixel counts `src/parts.ts` documents (`opaque_px`, `visible_px`, `occluded_px`, `projected_core_px`, `source_px_taken`, `visible_not_projected_px`, `refused_drift_px`, `merged_px`, `seam_override_px`, and `fringe_pushed_back` when not empty); `rig_size`, `scale_rig_per_source`, `ghost_px`, `recomposite`, and `scene` (`figure_alpha_above`, `figure_px`, `figure_mask`) under `config.scene` only, with the figure's mask `figure_rig.png` beside the recomposite (issue #242); `single_run_pad` (`file_size`, `side`, `left`, `top`) last, only for one run whose file is not the `seethrough.resolution` square (issue #366) |
|
|
178
|
+
| `rig/rig.json`, `rig/motion.json`, `rig/images/` | `rig`, `build`, `compose` | rig-c's rig spec and motion spec, `spec` `rigc-rig/1` and `rigc-motion/1`: the format is rig-c's, and this package writes only what rig-c's parser accepts; a bone carries `inherit` only where config.bones declares one, rig-c's mode name as written (issue #348) |
|
|
176
179
|
| `rig/mesh_report.json` | `rig`, `build` | one row per mesh: `part`, `vertices`, `triangles`, `hull`, `bones`, `max_influences`, `mean_influences`, `art_coverage`, then `grid` (a lattice); `mode` "contour" with `params`, `contour`, `regions` (`params.maxEdge` and `contour.outlineCut` only when the mesh declares `contour.maxEdge`; `params.bridges` and `contour.bridges` — `islands`, `units`, `joins`, and `faint` only when an island was left out as faint — only when it declares `contour.bridges`); or `mode` "auto" with `settings`, `source`, `result`, `residuals`, `worst_residual`, `worst_region`, `motion_amplitude`, `termination`, `weights`, `regions`, `deformation`, `quality_report` (rig-c's `mesh-quality-report/1` document whole), `motion_report`, and, only when they apply, `stray_cleared` (after `source`, when `source.stray` is declared), `skinning_residual` and `replay` (`AutoMeshReport` in `src/rig.ts`); in every mode, `exponent` when the mesh declares one (after `grid`, or after `mode`); `influences`, as declared, when a lattice or contour mesh declares it (after `exponent`, or where `exponent` would be); `stray` and `stray_cleared` when a lattice mesh declares `stray` (after `influences`, or where `influences` would be); `ribs` when a contour or auto mesh declares them (after `exponent`, or after `mode`), and then `contour.ribs` (`source.contour.ribs` in the automatic mode) |
|
|
177
|
-
| `check/check.json` and the rest of `check/` | `check`, `build`, `compose` | the reference's fields in its order (`gate_spine_html_green`, `rigc_entry`, `pack_mode`, `loop_max_diff`, the seam figures — `seam_mean`, `seam_px_over_40`, `seam_px_over_80` and, from issue #216, `seam_frame_scale`, the frame scale the bar divides the count by), `loop_physics` after `loop_max_diff` when the rig declares a physics constraint, `seam_border` after the seam figures when `parts.json` declares a scene (issue #242), `seam_pairs` after the seam figures when the seam bar fails or `--seam-pairs` asks (each row's picture under `check/seam/`; `--keep-stills` leaves the setup-pose still and its `frames.json` under `check/setup_still/`), then the judgement lines (`BREATH_VISIBLE`, `BLINK_NO_HOLE`, `CHAIN_LAG`, `TIP_OVER_ROOT`, `STILL_REGIONS_DARK`, `TEXTURE_STRETCH`), `ANIMATIONS_DO_NOT_FOLD` after them when `motion.json` holds an animation, the idle included — on every rig with an idle since issue #333 (issue #320: `status`, `animations`, `fps`, `physics_left_out`, `folding`, `folding_undeclared`, `declared_not_folding`, `bar`), `RECOMPOSITE_HOLES` (its first figure `declared_scene` when `parts.json` declares a scene), `SETUP_POSE_VS_SOURCE`, `skipped`, a `requirements` block under `--requirements`, and `PASS`; `check/build/skeleton.json`, `.atlas` and `.png` are the packed artifact rig-c writes |
|
|
180
|
+
| `check/check.json` and the rest of `check/` | `check`, `build`, `compose` | the reference's fields in its order (`gate_spine_html_green`, `rigc_entry`, `pack_mode`, `loop_max_diff`, the seam figures — `seam_mean`, `seam_px_over_40`, `seam_px_over_80` and, from issue #216, `seam_frame_scale`, the frame scale the bar divides the count by), `loop_physics` after `loop_max_diff` when the rig declares a physics constraint, `seam_border` after the seam figures when `parts.json` declares a scene (issue #242), `seam_pairs` after the seam figures when the seam bar fails or `--seam-pairs` asks (each row's picture under `check/seam/`; `--keep-stills` leaves the setup-pose still and its `frames.json` under `check/setup_still/`), then the judgement lines (`BREATH_VISIBLE`, `BLINK_NO_HOLE`, `CHAIN_LAG`, `TIP_OVER_ROOT`, `STILL_REGIONS_DARK`, `TEXTURE_STRETCH`), `ANIMATIONS_DO_NOT_FOLD` after them when `motion.json` holds an animation, the idle included — on every rig with an idle since issue #333 (issue #320: `status`, `animations`, `fps`, `physics_left_out`, `folding`, `folding_undeclared`, `declared_not_folding`, `bar`), `FEET_STAY_LEVEL` after it when a `footwear` part rides a bone that hangs from another and `motion.json` holds an animation (issue #348: `status`, `reason` on a SKIP only, `animations`, `fps`, `physics_left_out`, `bar_degrees`, `bar`, `feet` — each `part`, `bone`, `hangs_from`, `status`, `frames_posed`, `worst`), `LIMB_ONE_BONE` after it (and after `STRESS_OFF_CHAIN` where that is written) when `parts.json` holds a limb segment's part (issue #349: `status`, `parts` — each `part`, `limb`, `bone`, `status`, `others`), `RECOMPOSITE_HOLES` (its first figure `declared_scene` when `parts.json` declares a scene), `SETUP_POSE_VS_SOURCE`, `skipped`, a `requirements` block under `--requirements`, and `PASS`; `check/build/skeleton.json`, `.atlas` and `.png` are the packed artifact rig-c writes |
|
|
181
|
+
| `layers.json`, `<index>_<name>.png` | `layers --export` | the wrapper form `layers` reads (issue #359): `width`, `height`, then `layers` — each `name`, `filename`, `left`, `top`, `right`, `bottom`, `depth_median` (the input's own; `null` for a PSD, the manifest's order then being the draw order) — drawn layers in draw order, then the hidden-art layers; a PNG's name is its index and its layer's name, and the manifest, not the file name, says which layer it is |
|
|
182
|
+
| the template `.psd` | `layers --template` | one empty layer per name `templateLayerNames` (`src/layers.ts`) holds, bottom first; the same canvas writes the same bytes |
|
|
178
183
|
| `proposal.json`, `render/landmarks*.png` | `propose` | the config's four rig sections, `turn` with `--full`/`--head`, and `notes` |
|
|
179
184
|
| `basis.json` | `propose` | spec `spine-parts-basis/1` |
|
|
180
185
|
| `config.json`, `mesh_draft.json` | `mesh-draft` | `config.json` is the config read, byte for byte, but for each drafted part's `meshes` entry; `mesh_draft.json` is spec `rig-parts-mesh-draft/1`: `rules`, `lattice_check`, `draft_check`, `figure_overdraw`, and per lattice part `part`, `mode`, `lattice`, `candidate` (with `bridges` — `units`, `joins` of `span` and `area_px2`, `area_px2`, `overdraw`, and `faint` only when an island was left out as faint — only when the candidate is a bridged one, issue #326), `delta` (under `--more-triangles` only), `readings`, `gate` (each line's `reading`, `pass`, `text`, `margin`), `note`; and `not_compared` (issue #307), only when the config holds an `auto` or `contour` entry: per such entry, in config order, `part`, `mode` and `note` — the part was neither drafted nor compared, and a config of lattices alone writes no such key |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rig-c/parts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
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": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"workflows",
|
|
44
44
|
"docs/AUTHORING.md",
|
|
45
45
|
"docs/MIGRATION.md",
|
|
46
|
+
"docs/PAINTING.md",
|
|
46
47
|
"docs/STABILITY.md",
|
|
47
48
|
"skills",
|
|
48
49
|
"NOTICE.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 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, 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.2 or later. 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 is installed with it. See-through is run separately.
|
|
6
6
|
---
|
|
@@ -58,6 +58,15 @@ under that.
|
|
|
58
58
|
|
|
59
59
|
## The loop
|
|
60
60
|
|
|
61
|
+
0. Before See-through, check the painting: `rig-parts painting --keypoints
|
|
62
|
+
<k.json> <painting.png>` with the figure's body-18 joints (the file
|
|
63
|
+
`propose --keypoints` reads, from an estimator or the painting — never a joint
|
|
64
|
+
you guessed). A `FAIL PAINTING_…` line names what a rig cannot be cut from —
|
|
65
|
+
an arm against the body, hands together, legs with no gap, a joint off the
|
|
66
|
+
figure, a background that is not plain — and the fix is a new painting, not a
|
|
67
|
+
config field. `docs/PAINTING.md` lists every requirement, the ones only an eye
|
|
68
|
+
reads (front view, feet, a cape over an elbow), and one generation recipe;
|
|
69
|
+
report those as not checked.
|
|
61
70
|
1. `rig-parts inputs --source <painting> --config config.json --out <dir>` writes
|
|
62
71
|
`st_input_full.png`, the painting on a white square. The config needs only `key`,
|
|
63
72
|
`seethrough` and `assemble.rig_scale` at this point. Run See-through on it — any
|
|
@@ -93,7 +102,9 @@ under that.
|
|
|
93
102
|
an arm raised, seated in a skirt that does not start at the hip: add
|
|
94
103
|
`--keypoints <file>` (body-18 joints in painting px, each observed, occluded
|
|
95
104
|
or missing; AUTHORING §3, *A posed figure*) so the neck, hip, chest and
|
|
96
|
-
sleeves follow the pose and LINT reads the joints, not screen y.
|
|
105
|
+
sleeves follow the pose and LINT reads the joints, not screen y. Each arm and
|
|
106
|
+
leg it places comes back as `limbs` (AUTHORING §3, *Limbs*): paste it, assemble
|
|
107
|
+
again, and read each `limb cap:` line for the pixels a cap is missing. A clean
|
|
97
108
|
LINT does not show a seated hip is right; the overlay does. Never write a joint you did not get from an
|
|
98
109
|
estimator or the painting: say `missing` and let the rule stand in.
|
|
99
110
|
6. Correct against `render/landmarks.png` and `note:` lines; a
|
|
@@ -112,6 +123,7 @@ under that.
|
|
|
112
123
|
(rigc refuses the pair the link's control splits, and the line names the flag
|
|
113
124
|
on the command that ran; AUTHORING §3).
|
|
114
125
|
7. `rig-parts build --config … --source … --full … --head … --out out --loop`
|
|
126
|
+
(no `--head` for an artist's own file, below)
|
|
115
127
|
(add `--idle-keys direct` when step 6 said so).
|
|
116
128
|
It stops at the first stage that refuses, printing that stage's lines under
|
|
117
129
|
`[assemble]`, `[rig]` or `[check]`. Fix what the FAIL line names and build again.
|
|
@@ -125,6 +137,23 @@ under that.
|
|
|
125
137
|
last: `check/build/skeleton.json`, `skeleton.atlas` and the packed page. Report
|
|
126
138
|
them with the pack line and the check figures verbatim.
|
|
127
139
|
|
|
140
|
+
An artist's own layered PSD (issue #359; AUTHORING §4, *For artists*): one run,
|
|
141
|
+
no See-through, no `--head` and no `head_box` in the config. The file must hold
|
|
142
|
+
`face`, `eyewhite-r` and `eyewhite-l`, painted (`ASSEMBLE_SINGLE_RUN_FACE`
|
|
143
|
+
otherwise); its stacking is the draw order and it carries no depth, so `layers`
|
|
144
|
+
prints `SKIP depth:` and the turn draft says `turn: SKIP` — report those as
|
|
145
|
+
skipped, never as passed. `rig-parts layers --template art.psd --canvas <W>x<H>`
|
|
146
|
+
writes the empty layers an artist paints into. A layer named `<layer>:hidden` is
|
|
147
|
+
that layer's art where something covers it (the forearm under a sleeve): read as a
|
|
148
|
+
cut's `under` and a limb segment's cap, never drawn; a `hidden art:` line names
|
|
149
|
+
what read it. To correct a parse, `rig-parts layers --export work art.psd` writes
|
|
150
|
+
the same layers as `layers.json` and one PNG each; move pixels between the PNGs
|
|
151
|
+
(grow a PNG and its box in `layers.json` together), then pass `--full work` and
|
|
152
|
+
read `recomposite vs source` and the error map again (AUTHORING §4, *The
|
|
153
|
+
correction loop*). A patch in the wrong layer shows as error only where the
|
|
154
|
+
painting is near-white; elsewhere it shows as `drift=`/`seam=` on the part drawn
|
|
155
|
+
over it.
|
|
156
|
+
|
|
128
157
|
Several characters in one rig: build each one green on its own, then
|
|
129
158
|
`rig-parts compose --scene scene.json --out scene` (spec `spine-parts-scene/1`:
|
|
130
159
|
the canvas, each character's `build` and `offset`, an optional plate with its
|