rig-parts 2.2.0 → 2.3.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/package.json +1 -1
- package/src/config.ts +8 -3
- package/src/rig.ts +6 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.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": {
|
package/src/config.ts
CHANGED
|
@@ -1305,8 +1305,6 @@ export interface CharacterConfig {
|
|
|
1305
1305
|
cloth?: ClothRecipes;
|
|
1306
1306
|
/** The `assemble.rig_scale` (`parts.json`'s `scale_rig_per_source`) `propose` drafted the rig sections at (issue #354): absent on a hand-authored config, held equal to `assemble.rig_scale` when present. */
|
|
1307
1307
|
proposed_rig_scale?: number;
|
|
1308
|
-
/** Alternate painting sets (issue #454): absent, no alternate sets are assembled or emitted. */
|
|
1309
|
-
alternates?: AlternateSetConfig[];
|
|
1310
1308
|
/**
|
|
1311
1309
|
* The requirements file the build's check reads (issue #556), a path relative
|
|
1312
1310
|
* to the config's directory: `build` reads it when no `--requirements` is
|
|
@@ -1649,7 +1647,14 @@ export interface AssembleConfig {
|
|
|
1649
1647
|
proposed_rig_scale?: number;
|
|
1650
1648
|
}
|
|
1651
1649
|
|
|
1652
|
-
|
|
1650
|
+
/**
|
|
1651
|
+
* The top-level sections `parseConfig` accepts in `config.json` (issue #948),
|
|
1652
|
+
* exported as a runtime tuple so a consumer does not read `src/config.ts` as text.
|
|
1653
|
+
*/
|
|
1654
|
+
export const CONFIG_SECTIONS = ['key', 'generation', 'seethrough', 'assemble', 'limbs', 'bones', 'meshes', 'regions', 'motion', 'constraints', 'stops', 'turn', 'scene', 'cloth', 'proposed_rig_scale', 'requirements', 'motion_seams', 'depth', 'waist'] as const;
|
|
1655
|
+
export type ConfigSection = (typeof CONFIG_SECTIONS)[number];
|
|
1656
|
+
|
|
1657
|
+
const TOP_KEYS = CONFIG_SECTIONS;
|
|
1653
1658
|
|
|
1654
1659
|
/**
|
|
1655
1660
|
* The one partial entry point. It validates exactly what its door requires —
|
package/src/rig.ts
CHANGED
|
@@ -1336,7 +1336,7 @@ export function buildWaistPairSource(
|
|
|
1336
1336
|
const CX = W / 2;
|
|
1337
1337
|
const byPart = new Map(parts.parts.map((p) => [p.name, p]));
|
|
1338
1338
|
|
|
1339
|
-
const configuredAlts = cfg.assemble.alternates ??
|
|
1339
|
+
const configuredAlts = cfg.assemble.alternates ?? [];
|
|
1340
1340
|
const anchorRegions = new Set(Object.keys(cfg.regions).filter(n => !(n in cfg.meshes)));
|
|
1341
1341
|
for (const a of configuredAlts) {
|
|
1342
1342
|
if (a.base_anchor === undefined) continue;
|
|
@@ -1354,7 +1354,7 @@ export function buildWaistPairSource(
|
|
|
1354
1354
|
if (JSON.stringify(configured === undefined ? null : orderedBaseAnchor(configured)) !== JSON.stringify(a.base_anchor === undefined ? null : orderedBaseAnchor(a.base_anchor))) fail('RIG_ALT_BASE_ANCHOR_MATCH_CONFIG', `alternate set "${a.name}" base_anchor`, 'config and parts.json declare different base anchors; re-run assemble before rig');
|
|
1355
1355
|
problems.push(...recordedFocusProblems(a, `parts.json alternate set "${a.name}".focus`, parts.rig_size, parts.scale_rig_per_source));
|
|
1356
1356
|
}
|
|
1357
|
-
for (const a of cfg.assemble.alternates ??
|
|
1357
|
+
for (const a of cfg.assemble.alternates ?? []) {
|
|
1358
1358
|
const record = parts.alternates?.find((p) => p.name === a.name);
|
|
1359
1359
|
if (a.base_anchor !== undefined && record === undefined) fail('RIG_ALT_BASE_ANCHOR_MATCH_CONFIG', `alternate set "${a.name}" base_anchor`, 'has no assembled set; re-run assemble before rig');
|
|
1360
1360
|
if ((a.focus !== undefined || record?.focus !== undefined)
|
|
@@ -1375,7 +1375,7 @@ export function buildWaistPairSource(
|
|
|
1375
1375
|
}
|
|
1376
1376
|
}
|
|
1377
1377
|
refuseIfAny(problems);
|
|
1378
|
-
for (const a of cfg.assemble.alternates ??
|
|
1378
|
+
for (const a of cfg.assemble.alternates ?? []) {
|
|
1379
1379
|
const record = parts.alternates?.find((p) => p.name === a.name);
|
|
1380
1380
|
if (a.tips === undefined) {
|
|
1381
1381
|
if (record?.tips !== undefined) {
|
|
@@ -2738,7 +2738,6 @@ export function buildWaistPairSource(
|
|
|
2738
2738
|
if (parts.alternates !== undefined && parts.alternates.length > 0) {
|
|
2739
2739
|
const setEntries: Record<string, AlternateSetMap> = {};
|
|
2740
2740
|
for (const [altIdx, alt] of parts.alternates.entries()) {
|
|
2741
|
-
const cfgAlt = cfg.alternates?.find((a) => a.name === alt.name);
|
|
2742
2741
|
for (const [bone, tip] of Object.entries(alt.tips ?? {})) {
|
|
2743
2742
|
if (bone === ROOT_BONE || !B.has(bone)) fail('RIG_NAME_RESOLVES', `parts.json alternates[${altIdx}].tips.${bone}`, `names "${bone}", which config.bones does not declare; re-run assemble with declared bone names`);
|
|
2744
2743
|
if (!Array.isArray(tip) || tip.length !== 2 || !tip.every((n) => typeof n === 'number' && Number.isFinite(n))) {
|
|
@@ -2753,8 +2752,8 @@ export function buildWaistPairSource(
|
|
|
2753
2752
|
}
|
|
2754
2753
|
const altFront = new Set(alt.front ?? []);
|
|
2755
2754
|
refuseIfAny(problems);
|
|
2756
|
-
const explicitDrawn = alt.drawn
|
|
2757
|
-
const isSubsetSet = alt.parts !== undefined
|
|
2755
|
+
const explicitDrawn = alt.drawn;
|
|
2756
|
+
const isSubsetSet = alt.parts !== undefined;
|
|
2758
2757
|
let coveredBones: Set<string> | null = null;
|
|
2759
2758
|
if (isSubsetSet) {
|
|
2760
2759
|
coveredBones = new Set<string>();
|
|
@@ -2776,7 +2775,7 @@ export function buildWaistPairSource(
|
|
|
2776
2775
|
if (explicitDrawn !== undefined) {
|
|
2777
2776
|
for (const boneName of Object.keys(explicitDrawn)) {
|
|
2778
2777
|
if (!B.has(boneName)) {
|
|
2779
|
-
fail('RIG_NAME_RESOLVES', `
|
|
2778
|
+
fail('RIG_NAME_RESOLVES', `parts.json alternates[${altIdx}].drawn.${boneName}`, `names the bone "${boneName}", which config.bones does not declare`);
|
|
2780
2779
|
} else if (coveredBones !== null && !coveredBones.has(boneName)) {
|
|
2781
2780
|
const coveredList = [...coveredBones].map((b) => `"${b}"`).join(', ') || 'none';
|
|
2782
2781
|
fail(
|