rig-parts 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +1 -1
- package/README.md +17 -15
- package/cli.ts +52 -29
- package/docs/AUTHORING.md +8 -6
- package/docs/MIGRATION.md +22 -9
- package/package.json +4 -4
- package/skills/rig-parts/SKILL.md +4 -4
package/NOTICE.md
CHANGED
|
@@ -69,7 +69,7 @@ only as a development dependency, and an install of rig-c gates a build with
|
|
|
69
69
|
its own validator. rig-parts does not install it either; it is this repository's
|
|
70
70
|
development dependency, at the version rig-c develops against, for the round
|
|
71
71
|
trip in the selftest and CI and the selftest's posing oracle.
|
|
72
|
-
rig-c's [NOTICE.md](https://github.com/
|
|
72
|
+
rig-c's [NOTICE.md](https://github.com/rig-c/core/blob/main/NOTICE.md)
|
|
73
73
|
sets out the chain in full; briefly, as a restatement of Esoteric Software's
|
|
74
74
|
terms and not a term of this project:
|
|
75
75
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
are written.** rig-parts takes a single character painting and the layers
|
|
5
5
|
[See-through](https://github.com/shitagaki-lab/see-through) decomposed it into,
|
|
6
6
|
merges them into measured rig-space parts, authors weighted meshes, bone chains
|
|
7
|
-
and a looping idle over them in [rig-c](https://github.com/
|
|
7
|
+
and a looping idle over them in [rig-c](https://github.com/rig-c/core)'s
|
|
8
8
|
spec, and hands that spec to rig-c to compile, gate, pack, render and check.
|
|
9
9
|
It is built for agents that cannot see the image: every stage prints named,
|
|
10
10
|
numeric findings, a refusal names the object, the value found and the value
|
|
@@ -14,12 +14,12 @@ input is silent.
|
|
|
14
14
|
## What you get
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<img src="https://raw.githubusercontent.com/
|
|
18
|
-
<img src="https://raw.githubusercontent.com/
|
|
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 frilled dress with long pink twin tails, standing with her hands clasped" height="420" />
|
|
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/
|
|
22
|
+
<img src="https://raw.githubusercontent.com/rig-c/parts/main/assets/demo-parts.png" alt="Contact sheet of the painting and the 22 assembled parts it was split into: hair, dress, sleeves, shoes, face, eyes, brows, mouth and ornaments" width="100%" />
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
<p align="center"><em>
|
|
@@ -40,7 +40,7 @@ is taken from the full run, because the twin tails leave the head crop sideways
|
|
|
40
40
|
<code>seam: setup pose at 714x1216, scale 0.9422: mean |d| 0.234 (<= 1.0), 2 px over 40, 2.25 rig px (the count / s²; <= 50), 0 px over 80 (reported)</code><br/>
|
|
41
41
|
<code>pack: skeleton.png 922x1348, 22 region(s), 94.9% covered, padding 2, page edges free, shape polygon</code><br/>
|
|
42
42
|
<code>--seam silhouette</code> repaired the navy blobs the default rule leaves on the white
|
|
43
|
-
blouse (recomposite error pixels
|
|
43
|
+
blouse (recomposite error pixels 10,340 → 8,644); the default stays
|
|
44
44
|
<code>near-white</code>, the reference implementation's rule, so the examples stay
|
|
45
45
|
comparable with it. The loop is <code>rig-parts loop --palette</code>'s indexed APNG, 48 frames at
|
|
46
46
|
12 fps, 1,706,719 bytes, one 256-entry palette at a measured error of max 57, mean 1.601
|
|
@@ -54,7 +54,7 @@ made the contact sheet.
|
|
|
54
54
|
</em></p>
|
|
55
55
|
|
|
56
56
|
<p align="center">
|
|
57
|
-
<img src="https://raw.githubusercontent.com/
|
|
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
58
|
</p>
|
|
59
59
|
|
|
60
60
|
<p align="center"><em>
|
|
@@ -148,9 +148,9 @@ atlas written by anything else would have no oracle behind it.
|
|
|
148
148
|
|
|
149
149
|
| stage | tool | what it owns |
|
|
150
150
|
| --- | --- | --- |
|
|
151
|
-
| painting + See-through layers → parts and specs | **rig-parts** | the merge of two runs, the measurements, the rig spec and motion spec |
|
|
152
|
-
| specs → Spine skeleton data | **[rig-c](https://github.com/
|
|
153
|
-
| skeleton data → a page | **[rig-play](https://github.com/
|
|
151
|
+
| painting + See-through layers → parts and specs | **rig-parts** (npm `@rig-c/parts`) | the merge of two runs, the measurements, the rig spec and motion spec |
|
|
152
|
+
| specs → Spine skeleton data | **[rig-c](https://github.com/rig-c/core)** (npm `rig-c`) | compile, the gate (rigc's own validator in an install; the round trip through `spine-core` where the runtime is beside it, as in this repository's CI), the named assertions, the packer, the renderer |
|
|
153
|
+
| skeleton data → a page | **[rig-play](https://github.com/rig-c/play)** (npm `@rig-c/play`; formerly spine-html), a sibling project | a DOM renderer; rigc's `spine-html` profile is its policy, and every build here is gated under that profile as well as under `spine` |
|
|
154
154
|
|
|
155
155
|
rig-parts never writes Spine data itself. Everything on disk under `check/build/`
|
|
156
156
|
was written by rig-c after its own gate passed.
|
|
@@ -388,15 +388,17 @@ before it, at v0.14.0).
|
|
|
388
388
|
|
|
389
389
|
## Requirements
|
|
390
390
|
|
|
391
|
-
[Bun](https://bun.sh) 1.2 or later. `npm
|
|
392
|
-
`rig-parts` command
|
|
393
|
-
on `PATH`.
|
|
391
|
+
[Bun](https://bun.sh) 1.2 or later. `npm i -D @rig-c/parts` installs the
|
|
392
|
+
`rig-parts` command (`npm install -g @rig-c/parts` puts it on `PATH`); it hands off
|
|
393
|
+
to Bun and says so in one sentence if Bun is not on `PATH`. **`@rig-c/parts` is the
|
|
394
|
+
package's name; versions 1.0.0-rc.1 to 1.5.3 were published as `rig-parts`, and
|
|
395
|
+
versions up to 0.16.0
|
|
394
396
|
as `spine-parts`, its former name**, and the install keeps a `spine-parts` command
|
|
395
397
|
beside `rig-parts` for the transition, the same launcher under both names. On npm
|
|
396
|
-
|
|
398
|
+
both former names stay published beside `@rig-c/parts` at every version, as aliases
|
|
397
399
|
carrying the same files with only the `name` in `package.json` changed, so a
|
|
398
|
-
project that depends on
|
|
399
|
-
install names
|
|
400
|
+
project that depends on either keeps receiving every release; a new
|
|
401
|
+
install names `@rig-c/parts` ([RELEASING.md](RELEASING.md), *The registry side*). rig-c
|
|
400
402
|
comes with it as a dependency. No Spine runtime does: since
|
|
401
403
|
rig-c 2.0 the installed `rigc` gates every build with its own validator over the
|
|
402
404
|
compiled model document, and `rigc --version` says `entry: cli_core.ts —
|
package/cli.ts
CHANGED
|
@@ -550,6 +550,39 @@ function printLayerTable(set: LayerSet): void {
|
|
|
550
550
|
console.log(` ${warned} WARN line(s)`);
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
+
/**
|
|
554
|
+
* Every flag each command takes: `valued` flags carry a value, `switches` are bare. Each parser reads its row to
|
|
555
|
+
* decide what it accepts, and {@link notTaken} prints the same row in the unknown-flag refusal, so the refusal
|
|
556
|
+
* lists exactly the flags the parser accepts (CL26). `layers` takes one positional path and no flag, so it has no row.
|
|
557
|
+
*/
|
|
558
|
+
const TAKES = {
|
|
559
|
+
sheet: { valued: ['--source', '--layers', '--out', '--cell', '--cols'], switches: [] },
|
|
560
|
+
rig: { valued: ['--config', '--parts', '--out', '--idle-keys', '--page-edges', '--pack-shape'], switches: [] },
|
|
561
|
+
propose: { valued: ['--parts', '--source', '--out', '--from-config', '--compare', '--full', '--canvas', '--keypoints', '--person', '--wrist-snap'], switches: ['--head-box'] },
|
|
562
|
+
compare: { valued: ['--left', '--right', '--map'], switches: [] },
|
|
563
|
+
check: { valued: ['--rig', '--out', '--parts', '--source', '--page-edges', '--pack-shape', '--requirements'], switches: ['--seam-pairs', '--keep-stills'] },
|
|
564
|
+
loop: { valued: ['--frames', '--out'], switches: ['--palette'] },
|
|
565
|
+
assemble: { valued: ['--source', '--full', '--head', '--config', '--out', '--seam', '--project'], switches: ['--propose-plan'] },
|
|
566
|
+
'comfy seethrough': { valued: ['--image', '--out', '--resolution', '--steps', '--seed', '--prefix', '--host', '--wait', '--timeout', '--poll'], switches: ['--offload', '--lama', '--nf4'] },
|
|
567
|
+
'comfy paint': { valued: ['--config', '--out', '--seeds', '--seed0', '--host', '--wait', '--timeout', '--poll'], switches: [] },
|
|
568
|
+
inputs: { valued: ['--source', '--config', '--out'], switches: [] },
|
|
569
|
+
build: { valued: ['--config', '--source', '--full', '--head', '--out', '--seam', '--project', '--page-edges', '--pack-shape', '--requirements', '--idle-keys'], switches: ['--loop'] },
|
|
570
|
+
compose: { valued: ['--scene', '--out', '--requirements', '--accept'], switches: [] },
|
|
571
|
+
} as const satisfies Record<string, { valued: readonly string[]; switches: readonly string[] }>;
|
|
572
|
+
|
|
573
|
+
type Command = keyof typeof TAKES;
|
|
574
|
+
|
|
575
|
+
/** Whether `command` takes `flag` as a valued flag, read off its {@link TAKES} row. */
|
|
576
|
+
function takesValued(command: Command, flag: string): boolean {
|
|
577
|
+
return (TAKES[command].valued as readonly string[]).includes(flag);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/** The unknown-flag refusal: the flag, and every flag the command's {@link TAKES} row holds, valued then bare. */
|
|
581
|
+
function notTaken(command: Command, flag: string): string {
|
|
582
|
+
const row = TAKES[command];
|
|
583
|
+
return `${command} does not take "${flag}"; it takes ${[...row.valued, ...row.switches].join(', ')}`;
|
|
584
|
+
}
|
|
585
|
+
|
|
553
586
|
function cmdLayers(args: string[]): number {
|
|
554
587
|
if (args.length !== 1) return usage(`layers takes one path; got ${args.length}`);
|
|
555
588
|
try {
|
|
@@ -569,7 +602,7 @@ function cmdSheet(args: string[]): number {
|
|
|
569
602
|
for (let i = 0; i < args.length; i++) {
|
|
570
603
|
const flag = args[i];
|
|
571
604
|
const value = args[i + 1];
|
|
572
|
-
if (!
|
|
605
|
+
if (!takesValued('sheet', flag)) return usage(notTaken('sheet', flag));
|
|
573
606
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
574
607
|
i++;
|
|
575
608
|
if (flag === '--source') source = value;
|
|
@@ -639,7 +672,7 @@ function cmdRig(args: string[]): number {
|
|
|
639
672
|
for (let i = 0; i < args.length; i++) {
|
|
640
673
|
const flag = args[i];
|
|
641
674
|
const value = args[i + 1];
|
|
642
|
-
if (!
|
|
675
|
+
if (!takesValued('rig', flag)) return usage(notTaken('rig', flag));
|
|
643
676
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
644
677
|
i++;
|
|
645
678
|
if (flag === '--config') config = value;
|
|
@@ -699,18 +732,17 @@ function rigcRunner(bin: string): RigcRunner {
|
|
|
699
732
|
};
|
|
700
733
|
}
|
|
701
734
|
|
|
702
|
-
/**
|
|
703
|
-
function flags(args: string[],
|
|
735
|
+
/** The command's valued flags as `--flag value` pairs, each one its {@link TAKES} row holds; `required` must all be given. Its bare switches are taken out by the caller before this reads the rest. A string is a usage error. */
|
|
736
|
+
function flags(args: string[], command: Command, required: readonly string[]): Map<string, string> | string {
|
|
704
737
|
const got = new Map<string, string>();
|
|
705
|
-
const all = [...known, ...optional];
|
|
706
738
|
for (let i = 0; i < args.length; i += 2) {
|
|
707
739
|
const flag = args[i];
|
|
708
|
-
if (!
|
|
740
|
+
if (!takesValued(command, flag)) return notTaken(command, flag);
|
|
709
741
|
if (args[i + 1] === undefined) return `${flag} needs a value`;
|
|
710
742
|
if (got.has(flag)) return `${flag} is given twice`;
|
|
711
743
|
got.set(flag, args[i + 1]);
|
|
712
744
|
}
|
|
713
|
-
for (const k of
|
|
745
|
+
for (const k of required) if (!got.has(k)) return `${command} needs ${k} <value>`;
|
|
714
746
|
return got;
|
|
715
747
|
}
|
|
716
748
|
|
|
@@ -722,10 +754,8 @@ function cmdCheck(args: string[]): number {
|
|
|
722
754
|
if (keepStills > 1) return usage('--keep-stills is given twice');
|
|
723
755
|
const f = flags(
|
|
724
756
|
args.filter((a) => a !== '--seam-pairs' && a !== '--keep-stills'),
|
|
725
|
-
['--rig', '--out'],
|
|
726
757
|
'check',
|
|
727
|
-
['--
|
|
728
|
-
['--seam-pairs', '--keep-stills'],
|
|
758
|
+
['--rig', '--out'],
|
|
729
759
|
);
|
|
730
760
|
if (typeof f === 'string') return usage(f);
|
|
731
761
|
const rig = f.get('--rig') as string;
|
|
@@ -775,14 +805,13 @@ function printLint(P: PartSet, spec: { bones: CharacterConfig['bones']; meshes:
|
|
|
775
805
|
function cmdPropose(args: string[]): number {
|
|
776
806
|
const flags = new Map<string, string>();
|
|
777
807
|
let headBox = false;
|
|
778
|
-
const valued = ['--parts', '--source', '--out', '--from-config', '--compare', '--full', '--canvas', '--keypoints', '--person', '--wrist-snap'];
|
|
779
808
|
for (let i = 0; i < args.length; i++) {
|
|
780
809
|
const flag = args[i];
|
|
781
810
|
if (flag === '--head-box') {
|
|
782
811
|
headBox = true;
|
|
783
812
|
continue;
|
|
784
813
|
}
|
|
785
|
-
if (!
|
|
814
|
+
if (!takesValued('propose', flag)) return usage(notTaken('propose', flag));
|
|
786
815
|
const value = args[i + 1];
|
|
787
816
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
788
817
|
if (flags.has(flag)) return usage(`${flag} is given twice`);
|
|
@@ -880,10 +909,9 @@ function cmdPropose(args: string[]): number {
|
|
|
880
909
|
|
|
881
910
|
function cmdCompare(args: string[]): number {
|
|
882
911
|
const flags = new Map<string, string>();
|
|
883
|
-
const valued = ['--left', '--right', '--map'];
|
|
884
912
|
for (let i = 0; i < args.length; i++) {
|
|
885
913
|
const flag = args[i];
|
|
886
|
-
if (!
|
|
914
|
+
if (!takesValued('compare', flag)) return usage(notTaken('compare', flag));
|
|
887
915
|
const value = args[i + 1];
|
|
888
916
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
889
917
|
if (flags.has(flag)) return usage(`${flag} is given twice`);
|
|
@@ -912,8 +940,8 @@ function cmdLoop(args: string[]): number {
|
|
|
912
940
|
if (palettes > 1) return usage('--palette is given twice');
|
|
913
941
|
const f = flags(
|
|
914
942
|
args.filter((a) => a !== '--palette'),
|
|
915
|
-
['--frames', '--out'],
|
|
916
943
|
'loop',
|
|
944
|
+
['--frames', '--out'],
|
|
917
945
|
);
|
|
918
946
|
if (typeof f === 'string') return usage(f);
|
|
919
947
|
const out = f.get('--out') as string;
|
|
@@ -932,14 +960,13 @@ function cmdLoop(args: string[]): number {
|
|
|
932
960
|
function cmdAssemble(args: string[]): number {
|
|
933
961
|
const flags = new Map<string, string>();
|
|
934
962
|
let propose = false;
|
|
935
|
-
const valued = ['--source', '--full', '--head', '--config', '--out', '--seam', '--project'];
|
|
936
963
|
for (let i = 0; i < args.length; i++) {
|
|
937
964
|
const flag = args[i];
|
|
938
965
|
if (flag === '--propose-plan') {
|
|
939
966
|
propose = true;
|
|
940
967
|
continue;
|
|
941
968
|
}
|
|
942
|
-
if (!
|
|
969
|
+
if (!takesValued('assemble', flag)) return usage(notTaken('assemble', flag));
|
|
943
970
|
const value = args[i + 1];
|
|
944
971
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
945
972
|
if (flags.has(flag)) return usage(`${flag} is given twice`);
|
|
@@ -975,8 +1002,9 @@ function cmdAssemble(args: string[]): number {
|
|
|
975
1002
|
}
|
|
976
1003
|
}
|
|
977
1004
|
|
|
978
|
-
/** Parse `--flag value` pairs and bare `--switch`es; a string is a usage error. */
|
|
979
|
-
function comfyFlags(args: string[],
|
|
1005
|
+
/** Parse `--flag value` pairs and bare `--switch`es, as the command's {@link TAKES} row names them; a string is a usage error. */
|
|
1006
|
+
function comfyFlags(args: string[], command: 'comfy seethrough' | 'comfy paint'): { v: Map<string, string>; on: Set<string> } | string {
|
|
1007
|
+
const switches: readonly string[] = TAKES[command].switches;
|
|
980
1008
|
const v = new Map<string, string>();
|
|
981
1009
|
const on = new Set<string>();
|
|
982
1010
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -986,7 +1014,7 @@ function comfyFlags(args: string[], valued: readonly string[], switches: readonl
|
|
|
986
1014
|
on.add(flag);
|
|
987
1015
|
continue;
|
|
988
1016
|
}
|
|
989
|
-
if (!
|
|
1017
|
+
if (!takesValued(command, flag)) return notTaken(command, flag);
|
|
990
1018
|
const value = args[i + 1];
|
|
991
1019
|
if (value === undefined) return `${flag} needs a value`;
|
|
992
1020
|
if (v.has(flag)) return `${flag} is given twice`;
|
|
@@ -1012,14 +1040,10 @@ function secondsFlag(v: Map<string, string>, flag: string, fallback: number): nu
|
|
|
1012
1040
|
return Number.isFinite(n) && n > 0 ? n : `${flag} ${raw} is not a number of seconds above 0`;
|
|
1013
1041
|
}
|
|
1014
1042
|
|
|
1015
|
-
const COMFY_TIMING = ['--host', '--wait', '--timeout', '--poll'] as const;
|
|
1016
|
-
|
|
1017
1043
|
async function cmdComfy(args: string[]): Promise<number> {
|
|
1018
1044
|
const [sub, ...rest] = args;
|
|
1019
1045
|
if (sub !== 'seethrough' && sub !== 'paint') return usage(`comfy takes seethrough or paint; got ${sub === undefined ? 'nothing' : `"${sub}"`}`);
|
|
1020
|
-
const
|
|
1021
|
-
const switches = sub === 'seethrough' ? ['--offload', '--lama', '--nf4'] : [];
|
|
1022
|
-
const f = comfyFlags(rest, valued, switches, `comfy ${sub}`);
|
|
1046
|
+
const f = comfyFlags(rest, `comfy ${sub}`);
|
|
1023
1047
|
if (typeof f === 'string') return usage(f);
|
|
1024
1048
|
const { v, on } = f;
|
|
1025
1049
|
const wait = secondsFlag(v, '--wait', 1800);
|
|
@@ -1082,7 +1106,7 @@ async function cmdComfy(args: string[]): Promise<number> {
|
|
|
1082
1106
|
}
|
|
1083
1107
|
|
|
1084
1108
|
function cmdInputs(args: string[]): number {
|
|
1085
|
-
const f = flags(args, ['--source', '--config', '--out']
|
|
1109
|
+
const f = flags(args, 'inputs', ['--source', '--config', '--out']);
|
|
1086
1110
|
if (typeof f === 'string') return usage(f);
|
|
1087
1111
|
const source = f.get('--source') as string;
|
|
1088
1112
|
const out = f.get('--out') as string;
|
|
@@ -1114,7 +1138,6 @@ function cmdInputs(args: string[]): number {
|
|
|
1114
1138
|
function cmdBuild(args: string[]): number {
|
|
1115
1139
|
const flags = new Map<string, string>();
|
|
1116
1140
|
let loop = false;
|
|
1117
|
-
const valued = ['--config', '--source', '--full', '--head', '--out', '--seam', '--project', '--page-edges', '--pack-shape', '--requirements', '--idle-keys'];
|
|
1118
1141
|
for (let i = 0; i < args.length; i++) {
|
|
1119
1142
|
const flag = args[i];
|
|
1120
1143
|
if (flag === '--loop') {
|
|
@@ -1122,7 +1145,7 @@ function cmdBuild(args: string[]): number {
|
|
|
1122
1145
|
loop = true;
|
|
1123
1146
|
continue;
|
|
1124
1147
|
}
|
|
1125
|
-
if (!
|
|
1148
|
+
if (!takesValued('build', flag)) return usage(notTaken('build', flag));
|
|
1126
1149
|
const value = args[i + 1];
|
|
1127
1150
|
if (value === undefined) return usage(`${flag} needs a value`);
|
|
1128
1151
|
if (flags.has(flag)) return usage(`${flag} is given twice`);
|
|
@@ -1161,7 +1184,7 @@ function cmdBuild(args: string[]): number {
|
|
|
1161
1184
|
}
|
|
1162
1185
|
|
|
1163
1186
|
function cmdCompose(args: string[]): number {
|
|
1164
|
-
const f = flags(args,
|
|
1187
|
+
const f = flags(args, 'compose', ['--scene', '--out']);
|
|
1165
1188
|
if (typeof f === 'string') return usage(f);
|
|
1166
1189
|
let bin: string;
|
|
1167
1190
|
try {
|
package/docs/AUTHORING.md
CHANGED
|
@@ -17,7 +17,7 @@ into `examples/sample/inputs/`.
|
|
|
17
17
|
|
|
18
18
|
| what | why | how |
|
|
19
19
|
| --- | --- | --- |
|
|
20
|
-
| [Bun](https://bun.sh) 1.2 or later | rig-parts and rig-c are Bun programs | `npm install -g rig-parts` installs the command; it says so if Bun is missing |
|
|
20
|
+
| [Bun](https://bun.sh) 1.2 or later | rig-parts and rig-c are Bun programs | `npm install -g @rig-c/parts` installs the command; it says so if Bun is missing |
|
|
21
21
|
| [rig-c](https://www.npmjs.com/package/rig-c) | compiles, gates, packs and renders every rig; rig-parts writes no Spine data itself | installed with rig-parts as a dependency (`node_modules/.bin/rigc`); with no Spine runtime beside it, it gates with its own validator, and `rigc --version` says `entry: cli_core.ts` |
|
|
22
22
|
| [See-through](https://github.com/shitagaki-lab/see-through), somewhere | the layer decomposition is the input | any route in README *Getting See-through layers*; it runs twice per character, outside this tool |
|
|
23
23
|
| a GPU, wherever See-through runs | See-through is a diffusion model | nothing in rig-parts itself uses a GPU |
|
|
@@ -1230,8 +1230,10 @@ names it — `[29]` on both examples.
|
|
|
1230
1230
|
flat stack of parts differs from the painting by more than 60, the top part takes the
|
|
1231
1231
|
painting's colour — except where the painting is near-white, which protects the page
|
|
1232
1232
|
and also every white garment. `--seam silhouette` protects near-white pixels only
|
|
1233
|
-
outside the figure. On the demo it
|
|
1234
|
-
|
|
1233
|
+
outside the figure. On the demo it lowers recomposite error pixels from 10,340 to
|
|
1234
|
+
8,644 (`assemble`'s `error px > 40`, at v1.5.2); on the sample it changes nothing
|
|
1235
|
+
(4,359 under both). At v0.14.0 the demo's were 11,050 and 9,540, and no check bar
|
|
1236
|
+
changed. The default stays
|
|
1235
1237
|
the reference's so the examples stay comparable with it.
|
|
1236
1238
|
|
|
1237
1239
|
**The fringe push-back** (issue #119; under either seam rule, no flag). Both places
|
|
@@ -1253,9 +1255,9 @@ and a cleared bridge to opaque art is put back, so no part gains an island
|
|
|
1253
1255
|
names them. On the examples (default flags, measured against the v0.14.0 build of
|
|
1254
1256
|
the same inputs): `demo` 1,193 px over 16 parts, recomposite error pixels 11,050 →
|
|
1255
1257
|
10,340; `sample` 276 px over 15 parts, 4,512 → 4,359; uncovered error pixels and
|
|
1256
|
-
holes unchanged on both, `check` 9 of 9 on both. The `--
|
|
1257
|
-
|
|
1258
|
-
|
|
1258
|
+
holes unchanged on both, `check` 9 of 9 on both. The `--project` comparison in
|
|
1259
|
+
this section and the `SETUP_POSE_VS_SOURCE` example figures in §7 were measured
|
|
1260
|
+
before it, at v0.14.0; the `--seam` figures above are v1.5.2's.
|
|
1259
1261
|
|
|
1260
1262
|
**Page edges.** `rig`, `check` and `build` pack through `rigc build --pack
|
|
1261
1263
|
--page-edges <v>`, and hand the value to rigc verbatim. The default is `free`,
|
package/docs/MIGRATION.md
CHANGED
|
@@ -9,14 +9,14 @@ from the pull request that measured it.
|
|
|
9
9
|
|
|
10
10
|
## In one paragraph
|
|
11
11
|
|
|
12
|
-
Install
|
|
13
|
-
config
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
reference (#169).
|
|
12
|
+
Install `@rig-c/parts` (the package's name after 1.5.3; *After 1.5.3* below). A
|
|
13
|
+
config that built on 0.16.0 loads and builds unchanged: every config change since is
|
|
14
|
+
a new, opt-in field inside a new mesh mode. The bytes a config without that mode
|
|
15
|
+
builds moved once, by a declared exception (every mesh triangle's vertex order,
|
|
16
|
+
#133); apart from it, each change since 0.16.0 that touched the code was measured
|
|
17
|
+
against the tree before it on the three public examples' builds, and moved no byte
|
|
18
|
+
of them. Inside the automatic mode, one change after the candidate moves declared
|
|
19
|
+
bytes, named in *Since 1.0.0-rc.1*: the skinning envelope's reference (#169).
|
|
20
20
|
|
|
21
21
|
## From 0.16.0 to 1.0.0-rc.1
|
|
22
22
|
|
|
@@ -31,7 +31,7 @@ reference (#169).
|
|
|
31
31
|
| spec ids of the files authors write and this package writes | `spine-parts-requirements/1`, `spine-parts-scene/1`, `spine-parts-keypoints/1`, `spine-parts-bonemap/1`, `spine-parts-basis/1`, `spine-parts-scene-report/1` | unchanged: they name a file format, not the tool, so a file written before the rename still reads |
|
|
32
32
|
| public examples repository | `spine-parts-examples` | unchanged (it keeps the name it was published under) |
|
|
33
33
|
|
|
34
|
-
What to do: install with `npm install -g rig-parts` and write `rig-parts` in scripts.
|
|
34
|
+
What to do: install with `npm install -g @rig-c/parts` and write `rig-parts` in scripts.
|
|
35
35
|
A script or a dependant that names the alias `spine-parts` keeps working and keeps
|
|
36
36
|
receiving every release; how long the alias stays is RELEASING.md's *The alias stays
|
|
37
37
|
until its retirement questions have written answers*. No build output carries the
|
|
@@ -135,3 +135,16 @@ What to do: nothing for a config without `auto`. A config under `auto` that decl
|
|
|
135
135
|
`motion.residual` may write a different mesh than 1.0.0-rc.1 did, as above; a
|
|
136
136
|
consumer that compares builds byte for byte with 1.0.0-rc.1 expects that move and
|
|
137
137
|
nothing else.
|
|
138
|
+
|
|
139
|
+
## After 1.5.3: the scoped name
|
|
140
|
+
|
|
141
|
+
| | 1.0.0 to 1.5.3 | after 1.5.3 |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| npm package | `rig-parts` | `@rig-c/parts`; `rig-parts` and the alias `spine-parts` are published beside it at every version as aliases, the same files with only the `name` in `package.json` changed |
|
|
144
|
+
| command | `rig-parts`, and the alias `spine-parts` on the same launcher | unchanged |
|
|
145
|
+
| repository | `firejune/rig-parts` (GitHub redirects it) | `rig-c/parts`, beside `rig-c/core` (npm `rig-c`) and `rig-c/play` |
|
|
146
|
+
| spec ids, the config, the bytes a build writes | | unchanged |
|
|
147
|
+
|
|
148
|
+
What to do: install with `npm i -D @rig-c/parts` (or `npm install -g @rig-c/parts`);
|
|
149
|
+
command lines do not change. A dependant that names `rig-parts` keeps receiving
|
|
150
|
+
every release under it (#222).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "AI-authored 2D character parts from one anime painting and its See-through layer decomposition: measured parts, weighted-mesh rig specs, verified through rig-c before anything is written. A CLI for agents that cannot see the image.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"author": "firejune",
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
|
17
|
-
"url": "https://github.com/
|
|
17
|
+
"url": "https://github.com/rig-c/parts.git"
|
|
18
18
|
},
|
|
19
|
-
"homepage": "https://github.com/
|
|
20
|
-
"bugs": "https://github.com/
|
|
19
|
+
"homepage": "https://github.com/rig-c/parts#readme",
|
|
20
|
+
"bugs": "https://github.com/rig-c/parts/issues",
|
|
21
21
|
"keywords": [
|
|
22
22
|
"spine",
|
|
23
23
|
"spine2d",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: rig-parts
|
|
3
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.
|
|
4
4
|
license: MIT
|
|
5
|
-
compatibility: Requires Bun 1.2 or later. The tool is the npm package rig-parts (
|
|
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
|
---
|
|
7
7
|
|
|
8
8
|
# rig-parts — a painting to a Spine rig, for agents
|
|
@@ -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` (the demo:
|
|
128
|
+
`near-white` (the 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
|
|
@@ -150,9 +150,9 @@ share is synthesis where the painting was there to be taken.
|
|
|
150
150
|
|
|
151
151
|
## Where to read next
|
|
152
152
|
|
|
153
|
-
[docs/AUTHORING.md](https://github.com/
|
|
153
|
+
[docs/AUTHORING.md](https://github.com/rig-c/parts/blob/main/docs/AUTHORING.md)
|
|
154
154
|
first — every config field, the command order, what to read after each stage, every
|
|
155
|
-
refusal. It is in the installed package at `node_modules
|
|
155
|
+
refusal. It is in the installed package at `node_modules/@rig-c/parts/docs/AUTHORING.md`,
|
|
156
156
|
the copy that matches the version you run. Two recipes there cover what this package
|
|
157
157
|
leaves to you:
|
|
158
158
|
|