rig-parts 1.75.0 → 1.77.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/cli.ts +34 -3
- package/docs/AUTHORING.md +173 -28
- package/package.json +2 -1
- package/src/assemble.ts +171 -16
- package/src/build.ts +5 -0
- package/src/config.ts +8 -0
- package/src/configwrite.ts +14 -0
- package/src/neckdraft.ts +82 -0
- package/src/parts.ts +68 -5
- package/src/provenance.ts +106 -0
- package/tools/neck-propose.ts +39 -0
package/cli.ts
CHANGED
|
@@ -16,7 +16,8 @@ import { runBuildProcess, processRigcRunner as rigcRunner } from './tools/build-
|
|
|
16
16
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
17
17
|
import { tmpdir } from 'node:os';
|
|
18
18
|
import { basename, dirname, extname, join, resolve } from 'node:path';
|
|
19
|
-
import { DEFAULT_PROJECT_RULE, DEFAULT_SEAM_RULE, HOLES_LISTED, PROJECT_RULES, type ProjectRule, proposeFields, proposePlan, proposeSinglePlan, SEAM_RULES, type SeamRule } from './src/assemble.ts';
|
|
19
|
+
import { DEFAULT_PROJECT_RULE, DEFAULT_SEAM_RULE, headGarmentOverlaps, headGarmentWarning, HOLES_LISTED, PROJECT_RULES, type ProjectRule, proposeFields, proposePlan, proposeSinglePlan, SEAM_RULES, type SeamRule } from './src/assemble.ts';
|
|
20
|
+
import { proposeNeck } from './tools/neck-propose.ts';
|
|
20
21
|
import { parseAltArg } from './tools/alternate-cli.ts';
|
|
21
22
|
import { type AlternateCliInput, assembleStage, build, checkStage, ERROR_MAP_FILE, loopStage, readRuns, readSource, rigStage, suppliedCheckFlag } from './src/build.ts';
|
|
22
23
|
import { ACCEPTABLE_BARS, DEFAULT_PACK_SHAPE, DEFAULT_PAGE_EDGES, findRigc, PACK_SHAPES, rigcRunnerAt, type PackShape, PAGE_EDGES, type PageEdges, PARTS_HOME_SENTENCE, RIGC_GEOMETRY_VERSION, rigcRanClause, type RigcRunner, NO_PARTS_SENTENCE, SEAM_MEAN_BAR, SOURCE_SENTENCE, SEAM_PX_BAR, SEAM_PX_LEVEL, SPINEBOY_YARDSTICK, TEXTURE_STRETCH_CEILING } from './src/check.ts';
|
|
@@ -88,6 +89,11 @@ usage:
|
|
|
88
89
|
size is not its box, and anything else outside the input contract —
|
|
89
90
|
never a WARN.
|
|
90
91
|
|
|
92
|
+
rig-parts layers <head-run> --full <full-run> --source <painting.png> --config <config.json>
|
|
93
|
+
Read PLAN_HEAD_GARMENT_OVERLAP on planned head parts against full-run
|
|
94
|
+
garments registered into the declared crop. Alpha >=250, any overlap;
|
|
95
|
+
names part, garment, count, half-open head-canvas box and source remedy.
|
|
96
|
+
|
|
91
97
|
rig-parts layers --export <dir> <dir | layers.json | file.psd>
|
|
92
98
|
Print the table, then write the input as the wrapper form into <dir>
|
|
93
99
|
(absent or empty, LAYERS_EXPORT_DIR_EMPTY): layers.json and one RGBA PNG
|
|
@@ -203,6 +209,13 @@ usage:
|
|
|
203
209
|
or a layer with no depth is refused by name. Without either flag nothing
|
|
204
210
|
changes.
|
|
205
211
|
|
|
212
|
+
rig-parts propose … --full <run> --head <run> --write-config <existing.json>
|
|
213
|
+
When the target declares turn.body and one neck plan row, preserve its
|
|
214
|
+
sampled turn and authored rig, take a clean full-run neck, and draft one
|
|
215
|
+
rigid sibling unit under the body carrier. Reassembled art is written to
|
|
216
|
+
<out>/rig; depth comes from the existing scalar input, named in note:.
|
|
217
|
+
Missing depth, landmarks or clean source is refused, never invented.
|
|
218
|
+
|
|
206
219
|
rig-parts propose … [--grid-rule figure|part]
|
|
207
220
|
How each drafted lattice's spacing (meshes.<part>.grid) is chosen.
|
|
208
221
|
figure, the default: round(H / ${FIGURE_GRID_DIVISOR}) rig px for every lattice, H the
|
|
@@ -1051,7 +1064,7 @@ function printLayerTable(set: LayerSet): void {
|
|
|
1051
1064
|
* no row; `layers` takes one positional path beside its flags (issue #359).
|
|
1052
1065
|
*/
|
|
1053
1066
|
const TAKES = {
|
|
1054
|
-
layers: { valued: ['--export', '--template', '--canvas'], switches: [] },
|
|
1067
|
+
layers: { valued: ['--export', '--template', '--canvas', '--full', '--source', '--config'], switches: [] },
|
|
1055
1068
|
sheet: { valued: ['--source', '--layers', '--out', '--cell', '--cols'], switches: [] },
|
|
1056
1069
|
rig: { valued: ['--config', '--parts', '--out', '--idle-keys', '--page-edges', '--pack-shape'], switches: [] },
|
|
1057
1070
|
propose: { valued: ['--parts', '--source', '--out', '--from-config', '--compare', '--full', '--head', '--canvas', '--keypoints', '--person', '--wrist-snap', '--grid-rule', '--cloth', '--write-config', '--from'], switches: ['--head-box', '--no-back-hair', '--only-missing'] },
|
|
@@ -1109,7 +1122,7 @@ function cmdLayers(args: string[]): number {
|
|
|
1109
1122
|
}
|
|
1110
1123
|
const template = flags.get('--template');
|
|
1111
1124
|
if (template !== undefined) {
|
|
1112
|
-
if (flags.has('--export') || paths.length > 0) return usage(`--template writes a PSD and reads nothing; it takes --canvas only, and got ${[...[...flags.keys()].filter((f) => f !== '--template' && f !== '--canvas'), ...paths].join(', ')}`);
|
|
1125
|
+
if (flags.has('--export') || paths.length > 0 || ['--full', '--source', '--config'].some(f => flags.has(f))) return usage(`--template writes a PSD and reads nothing; it takes --canvas only, and got ${[...[...flags.keys()].filter((f) => f !== '--template' && f !== '--canvas'), ...paths].join(', ')}`);
|
|
1113
1126
|
const canvasArg = flags.get('--canvas');
|
|
1114
1127
|
if (canvasArg === undefined) return usage('--template needs --canvas <W>x<H>, the canvas size in px (with one run, a square of seethrough.resolution)');
|
|
1115
1128
|
const canvas = parseCanvas(canvasArg);
|
|
@@ -1127,6 +1140,14 @@ function cmdLayers(args: string[]): number {
|
|
|
1127
1140
|
try {
|
|
1128
1141
|
const set = readLayers(paths[0]);
|
|
1129
1142
|
printLayerTable(set);
|
|
1143
|
+
const context = ['--full', '--source', '--config'];
|
|
1144
|
+
if (context.some(f => flags.has(f))) {
|
|
1145
|
+
if (!context.every(f => flags.has(f))) return usage('layers crop overlap inspection requires --full, --source and --config together; the positional path is the head run');
|
|
1146
|
+
const full = readLayers(flags.get('--full')!), source = readSource(flags.get('--source')!);
|
|
1147
|
+
const cfg = loadEarlyConfig(flags.get('--config')!, 'assemble');
|
|
1148
|
+
const g = { sourceW: source.width, sourceH: source.height, ...proposeFields(cfg) };
|
|
1149
|
+
for (const w of headGarmentOverlaps(full, set, g, cfg.assemble.plan)) console.log(` ${headGarmentWarning(w)}`);
|
|
1150
|
+
}
|
|
1130
1151
|
const dir = flags.get('--export');
|
|
1131
1152
|
if (dir !== undefined) {
|
|
1132
1153
|
const w = exportLayers(set, dir);
|
|
@@ -1479,6 +1500,16 @@ function cmdPropose(args: string[]): number {
|
|
|
1479
1500
|
if (!existsSync(source)) {
|
|
1480
1501
|
throw new PartsError([{ code: 'PROPOSE_SOURCE_PRESENT', object: source, detail: 'no such file; the painting is drawn under the overlay' }]);
|
|
1481
1502
|
}
|
|
1503
|
+
if (target !== null && typeof target.raw === 'object' && target.raw !== null && 'turn' in target.raw) {
|
|
1504
|
+
const turn = target.raw.turn;
|
|
1505
|
+
if (typeof turn === 'object' && turn !== null && 'body' in turn && (loadEarlyConfig(target.path, 'assemble').assemble.plan.some(([, , tag]) => tag === 'neck'))) {
|
|
1506
|
+
const unsupported = [...flags.keys()].filter(f => !['--parts', '--source', '--out', '--full', '--head', '--write-config'].includes(f));
|
|
1507
|
+
if (unsupported.length > 0) throw new PartsError([{ code: 'PROPOSE_NECK_MODE', object: unsupported.join(', '), detail: 'cannot be combined with the authored sampled-turn neck draft; use --parts, --source, --out, --full, --head and --write-config only; run comparison or landmark drafting separately' }]);
|
|
1508
|
+
if (onlyMissing) throw new PartsError([{ code: 'PROPOSE_NECK_MODE', object: '--only-missing', detail: 'cannot replace an attached neck; omit --only-missing for the explicit sampled body-turn neck draft' }]);
|
|
1509
|
+
proposeNeck(target, { source, parts: partsDir, out, full: flags.get('--full'), head: flags.get('--head') });
|
|
1510
|
+
return EXIT_OK;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1482
1513
|
const P = readPartSet(partsDir);
|
|
1483
1514
|
const painting = readPng(source);
|
|
1484
1515
|
// Issue #75: the keypoint file, held to this painting's size and taken to rig px by the overlay's map.
|