rig-parts 1.5.2 → 1.5.3
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 +1 -1
- package/cli.ts +52 -29
- package/docs/AUTHORING.md +7 -5
- package/package.json +1 -1
- package/skills/rig-parts/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -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
|
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
|
@@ -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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
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` (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
|