rig-parts 2.8.1 → 2.9.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 +1 -1
- package/cli.ts +42 -5
- package/docs/AUTHORING.md +177 -9
- package/docs/MIGRATION.md +20 -1
- package/docs/STABILITY.md +7 -1
- package/package.json +1 -1
- package/skills/rig-parts/SKILL.md +1 -1
- package/src/assemble.ts +32 -11
- package/src/build.ts +29 -7
- package/src/check.ts +162 -19
- package/src/coincide.ts +157 -0
- package/src/coincideio.ts +79 -0
- package/src/diffcomponents.ts +208 -0
- package/src/edgeresidual.ts +191 -0
- package/src/mesh.ts +29 -2
- package/src/meshdraft.ts +2 -27
- package/src/propose.ts +150 -5
- package/src/supportdomains.ts +76 -0
- package/tools/build-process.ts +31 -9
package/docs/MIGRATION.md
CHANGED
|
@@ -382,7 +382,7 @@ What to do, keeping every entry you tuned — one command, after `assemble` has
|
|
|
382
382
|
the split parts:
|
|
383
383
|
|
|
384
384
|
```
|
|
385
|
-
rig-parts propose --parts <work/rig> --source <painting> --out <dir> --write-config config.json --only-missing
|
|
385
|
+
rig-parts propose --parts <work/rig> --bust-landmarks bust-landmarks.json --source <painting> --out <dir> --write-config config.json --only-missing
|
|
386
386
|
```
|
|
387
387
|
|
|
388
388
|
For each part the config attaches by neither `meshes` nor `regions`, it adds what is
|
|
@@ -481,3 +481,22 @@ cohort to the actual PNG frame set through `readFrameSet` and `boneTrackOf`,
|
|
|
481
481
|
including unselected frames, before reading the worst pose. Identical static
|
|
482
482
|
ranges on a bone deduplicate; conflicting ranges are explicitly ambiguous,
|
|
483
483
|
never described as no declared range.
|
|
484
|
+
|
|
485
|
+
## Contour torso drafts (#986)
|
|
486
|
+
|
|
487
|
+
Fresh `propose` runs draft the chest-holding topwear as a contour mesh, including
|
|
488
|
+
`trunk_chest` when the figure layer is split into limbs. The drafted `proposal.json`
|
|
489
|
+
changes that mesh's mode and its explanatory notes. A torso on chains also declares
|
|
490
|
+
uncapped continuous influences (#991). Non-torso meshes retain their existing modes.
|
|
491
|
+
|
|
492
|
+
`--bust-landmarks <file>` declares `apex_r`, `apex_l` and optional `cleavage` in rig
|
|
493
|
+
pixels. With these landmarks, `proposal.json` also adds `contour.bust` and the two
|
|
494
|
+
chest-parented bones, `basis.json` records those bones, and the landmark overlays
|
|
495
|
+
show them. A chest-holding torso now refuses with `PROPOSE_BUST_INPUT` when neither
|
|
496
|
+
`--bust-landmarks` nor `--no-bust` is supplied. Runs that previously succeeded with
|
|
497
|
+
a missing-landmarks note must now declare the landmarks or give an explicit
|
|
498
|
+
`--no-bust "<reason>"`. Blank omission reasons are refused.
|
|
499
|
+
|
|
500
|
+
A config receiving these newly drafted sections, and builds made from it, have
|
|
501
|
+
changed mesh bytes. `--from-config` continues to read authored meshes unchanged.
|
|
502
|
+
See [AUTHORING.md](AUTHORING.md#drafting-the-chest-carrier) for the input contract.
|
package/docs/STABILITY.md
CHANGED
|
@@ -49,6 +49,7 @@ defaults are the help's too, and none is guessed from the art.
|
|
|
49
49
|
<!-- stable:commands -->
|
|
50
50
|
| command | flags |
|
|
51
51
|
| --- | --- |
|
|
52
|
+
| `diff-components` | `--stack`, `--painting`, `--parts`, `--floor`; optional `--threshold`, `--figure`; exactly one of `--out`, `--verify` (issue #1005; exhaustive native error inventory, with byte-bound reader) |
|
|
52
53
|
| `depth-prepare` | `--parts`, `--config`, `--out` (issue #897; separate numeric-depth recipe) |
|
|
53
54
|
| `depth-apply` | `--parts`, `--manifest`, `--config`, `--rig-config`, `--out` (issue #897; original character config is read-only) |
|
|
54
55
|
| `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; or a positional head run with `--full`, `--source`, `--config` together for `PLAN_HEAD_GARMENT_OVERLAP` (issue #826) |
|
|
@@ -58,7 +59,7 @@ defaults are the help's too, and none is guessed from the art.
|
|
|
58
59
|
| `comfy` | `seethrough`: `--image`, `--out`; optional `--resolution`, `--steps`, `--seed`, `--prefix`, `--offload`, `--no-offload`, `--lama`, `--nf4`, `--host`, `--wait`, `--timeout`, `--poll`, `--config` (See-through settings and optional depth block), `--depth-run` (`full` or `head`, required with the block) |
|
|
59
60
|
| `assemble` | `--propose-plan` with `--source`, `--full`, `--config`, optional `--head`, `--write-config` (must name `--config` itself, issue #356); or `--source`, `--full`, `--config`, `--out`, optional `--head` (without it, one run: issue #359), `--seam` (near-white, silhouette), `--project` (core, visible), `--alt` (repeatable `<name>=<source>:<full>[:<head>]`, issue #454), `--requirements` (source-bound cut-material evidence only when the file declares `cut_material`, issue #888) |
|
|
60
61
|
| `propose` | `--head-box` with `--full`, `--canvas`; optional `--no-back-hair`, `--write-config` (existing config, issue #356) |
|
|
61
|
-
| `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`), `--cloth` (a config whose `cloth` block is the recipe, issue #364; not with `--from-config`), `--write-config` (existing config for an ordinary proposal, issue #356; a new file with `--cloth`, issue #537; not with `--from-config` — additive: without it nothing `propose` writes changes), `--from` (the config the recipe is changed from, only with `--write-config`, issue #571 — additive: without it nothing `--write-config` writes changes), `--only-missing` (only with `--parts` and `--write-config`, not with `--cloth` or `--from-config`, issue #671 — additive: without it nothing `--write-config` writes changes) |
|
|
62
|
+
| `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`), `--cloth` (a config whose `cloth` block is the recipe, issue #364; not with `--from-config`), `--write-config` (existing config for an ordinary proposal, issue #356; a new file with `--cloth`, issue #537; not with `--from-config` — additive: without it nothing `propose` writes changes), `--from` (the config the recipe is changed from, only with `--write-config`, issue #571 — additive: without it nothing `--write-config` writes changes), `--only-missing` (only with `--parts` and `--write-config`, not with `--cloth` or `--from-config`, issue #671 — additive: without it nothing `--write-config` writes changes) `--bust-landmarks` (rig-pixel apex_r/apex_l and optional cleavage), or `--no-bust` (non-blank omission reason), one required when drafting a chest-holding torso, both incompatible with `--from-config` |
|
|
62
63
|
| `propose` | `--parts`, `--source`, `--out`, `--full`, `--head`, `--write-config` together: the [neck draft](AUTHORING.md#a-neck-that-moves-on-its-own) for an existing config with `turn.body` and one neck plan row; reassembles under `<out>/rig`, preserves the sampled turn and drafts a rigid neck unit (issue #826) |
|
|
63
64
|
| `compare` | `--left`, `--right`; optional `--map` |
|
|
64
65
|
| `rig` | `--config`, `--parts`, `--out`; optional `--idle-keys` (ctl, direct), `--page-edges` (pot, free), `--pack-shape` (rect, polygon) |
|
|
@@ -86,6 +87,10 @@ The [command reference](AUTHORING.md#command-reference) describes each mode;
|
|
|
86
87
|
[writing proposed config fields](AUTHORING.md#writing-proposed-config-fields)
|
|
87
88
|
records the existing-file and fresh-file destinations and byte-preservation rules.
|
|
88
89
|
|
|
90
|
+
`assemble --project visible` adds optional `edge_residuals.json` beside
|
|
91
|
+
`parts.json` (issue #999), a report-only front/back residual candidate sidecar.
|
|
92
|
+
Its observations add no acceptance bar to the existing outputs.
|
|
93
|
+
|
|
89
94
|
## The config contract
|
|
90
95
|
|
|
91
96
|
`src/config.ts` is the schema and the loader, and
|
|
@@ -256,6 +261,7 @@ every number) are AUTHORING §3's tables, and the loader refuses any other by na
|
|
|
256
261
|
| `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) |
|
|
257
262
|
| `rig/mesh_report.json` | `rig`, `build` | one row per mesh: `part`, `vertices`, `triangles`, `hull`, `bones` (the sorted names the attachment's weights bind in the written `rig.json`, in every mode — since 1.49.1 (issue #536) a rig with `turn` or `stops` names the twins and `<link>_d` bones there, where the row named the segment bones they replace: a fix of a wrong name, not a format change; a rig with neither writes the bytes it wrote), `max_influences`, `mean_influences`, `art_coverage`, then `grid` (a lattice); or `mode` "explicit" with `image_sha256` and `region_sha256` (the verified guards; counts and coverage are measured from the supplied mesh, no legacy generator report is adopted); `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` "influence" with `influence` (as declared), `reach` (`farthest`, `at`, `nearest`, `capped`, `widest`) and `lattice` (rig-c's `SegmentsLatticeReport`: `cols`, `rows`, `artCells`, `keptCells`, `passes`, `islands`) (issue #378); 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) |
|
|
258
263
|
| `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`, `environment` after it under `--environment` only (issue #538, additive: `path` as given, `sha256`, `steps`), `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 (issues #320, #363: `status`, `animations`, `fps`, `physics_left_out`, `folding` — each `animation`, `slot`, `attachment`, `frames`, `worst_frame`, `worst_triangles`, `triangles`, `physics_on`, `physics_off`, `physics_constraints`, `declared`, `line` — `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`), `SEAM_OVER_RANGE` after it when a limb record carries a `range` (issue #360: `status`, `frame_scale`, `physics_left_out`, `bar` — `mean`, `rig_px_over_40`, `level` — and `joints`, each `part`, `limb`, `segment`, `joint`, `bone`, `range`, `at`, `radius`, `under_px`, `status`, `poses` — each `degrees`, `status`, `mean`, `px_over_40`, `px_over_80`, `rig_px_over_40`, and `step_px` (`left`, `right`) only on a joint whose cap record carries `short_px` (issue #557, additive) — and `unread` on a joint not read), `SEAM_OVER_MOTION` after it when `parts.json` holds a limb segment or `--requirements` a `seam` (issue #493 retains existing pair warnings; issue #686 gates GAP on proven body-root pairs only (gap-only; mixed ghost remains INFO until rig-c/core#1555 supplies owners): `status` — `WARN`, `CLEAR`, `SKIP` or `FAIL` — `reason` on a SKIP only, `fps`, `floor`, `pairs` — each `pair`, `a`, `b`, `declared`, optional `root` (`limb`, `bone`, `parent`) on a proven body-root pair, and `unread` on a pair not read — `animations`, `warnings`, `rows` — each `pair`, `animation`, `status`, `drawn`, `banded`, `opens`, `px`, `max_px`, `under_floor`, and only on new-root rows stock `gapOpen` plus UNDER-owned `ghostA`/`ghostB` cells selected by resolved per-frame draw order gate their summed count against the unchanged strict one-cell floor on the original raw kind boxes (their union when both kinds contribute), never narrowed partition boxes, while `gapCovered` and OVER-owned ghost cells are excluded (issue #711); `cells` retains partition counts, UNDER owner and counted total, `worst` retains frame/count/cell/box, and `roots` retains status, mode `gap-open+under-ghost`, ghost_owner `resolved-draw-order`, pairs, failed, reason and optional unmeasured bindings; eligible candidates whose valid setup bands are all zero retain a named unmeasured root and SKIP bar, including when no pair is selected; measured root FAIL wins over SKIP, while measured PASS plus an unmeasured root remains SKIP; every eligible body drawing with stock setup `banded > 0` is selected, including both when a parent is shared; issue #708 resolves a body slot on its exact generated turn child to the same named carrier only after unique identity-bone/control/per-part-transform proof, without changing pair identity, setup selection or the direct-carrier path; setup-only observation preserves the authored motion and default drawing, root-free inputs add no setup compile/render, and no animation remains SKIP rather than a measured zero; existing internal pair warnings and their exits are unchanged; issue #941 adds optional `required` only under the requirements file's `seam_over_motion.required: true` — `status` (`PASS` or `FAIL`), `mode` `gap-open`, `bar_px` 0, `pairs` (each `pair`, `class` — `body-root`, `internal-joint` or `explicit` — `frames`, `background_frames`, `max_px`) and `failed` — and with it the key is written even when no pair is declared; issue #591 adds optional `worlds` on physics rigs with readable declared pairs and animations: `default` and `still`, each `wind`, `gravity`, `status` (`REPORTED` or `SKIP`), `reason` on SKIP, `dir` only when rendered (relative to check.json: `seam_motion/default` or `seam_motion/still`, the complete retained render with frames.json and each animation's raw seam.json), and `rows` — pair, animation, status, drawn, banded, `gap` and `ghost`, each `max_px` and `worst` only; worst carries `index`, `px`, `cell`, `box`. Per-frame hits stay in the raw sidecars. These raw reference readings add no bar or warning and leave the custom environment reading unchanged), `CLOTH_SETTLES` after it when the rig declares a physics constraint and has an idle (issue #501, a warning and not a bar: `status` — `WARN` or `CLEAR` — `fps`, `frames`, `duration`, `floor_rig_px_per_s`, `floor`, `levers`, `warnings`, `rows` — each `tip`, `root`, `links`, `point`, `settles_at`, `max_rig_px_per_s`, `min_rig_px_per_s`), `RECOMPOSITE_HOLES` (its first figure `declared_scene` when `parts.json` declares a scene), `SETUP_POSE_VS_SOURCE`, `WIND_BAND` after it under `--wind-band` only (issue #590, additive: `status` `"REPORTED"`, `spec` `"rig-parts-wind-band/1"`, `path` as given, `sha256`, `steady_wind_only` `true`, `gravity` `[0, 1]`, `min`, `max`, `step`, `steps`, `fps`, `animations`, `max_gap`, `max_ghost`, `holds_from`, `holds_to`, `pairs_holding_all`, and `pairs` — each `pair`, `a`, `b`, `holds_all`, `holds_from`, `holds_to`, `first_break_below`, `first_break_above`, `worst_gap`, `worst_ghost`, `steps`), `skipped`, `config` under `build` only (issue #607, additive: `path` as `--config` was typed, `sha256` of the bytes the build read; `check` and `compose` read no config and write none), a `requirements` block under `--requirements` (or `build`'s `config.requirements`) — `file` first from issue #556, additive: `path` as typed or declared, `sha256`, `keys` — and `PASS`; `check/build/skeleton.json`, `.atlas` and `.png` are the packed artifact rig-c writes. Missing stock partitions or resolved owner are named refusals, never zero. No whole-box exemption or consumer compositor remains; internal warnings and reference raw readings are unchanged. |
|
|
264
|
+
| `part_support_domains.json` | `assemble`, `build` | optional `rig-parts-support-domains/1` independent cut masks and unavailable reasons, with per-domain config-entry provenance and parts/PNG/payload digests; additive beside parts.json, whose bytes and PNGs are unchanged. Legacy output may omit it. `PART_SUPPORT_REPORT` reads pairs in the assembly placement frame and Unowned in actual setup, never as an acceptance gate. |
|
|
259
265
|
| `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 |
|
|
260
266
|
| the template `.psd` | `layers --template` | one empty layer per name `templateLayerNames` (`src/layers.ts`) holds, bottom first; the same canvas writes the same bytes |
|
|
261
267
|
| `proposal.json`, `render/landmarks*.png` | `propose` | the config's four rig sections, `constraints` with `--cloth` (issue #364: a physics constraint per tree link named `<bone>_physics`, a dangling end's `<bone>_translate`, and a skirt swing's transforms `<swing>_<tree>`), `turn` with `--full`/`--head`, `proposed_rig_scale` (issue #354), and `notes` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.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": {
|
|
@@ -86,7 +86,7 @@ under that.
|
|
|
86
86
|
5. `rig-parts assemble … --out work` — read the `uncovered hole` lines and look at
|
|
87
87
|
`work/render/recomposite_error_rig.png`; a large red hole between two parts is a
|
|
88
88
|
gap See-through left (a skirt split into two legs), fixed in the plan or the layers,
|
|
89
|
-
not in the rig. Then `rig-parts propose --parts work/rig
|
|
89
|
+
not in the rig. Then `rig-parts propose --parts work/rig --bust-landmarks bust-landmarks.json
|
|
90
90
|
--source <painting> --out work` → copy `bones`, `meshes`, `regions`, `limbs`,
|
|
91
91
|
`motion`, `constraints`, `turn`, `motion_seams`, `proposed_rig_scale` from `proposal.json` into the config, each it
|
|
92
92
|
wrote (`limbs` only with `--keypoints`, `constraints` only with `--cloth`, `turn`
|
package/src/assemble.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { edgePairResiduals, type EdgeResidualReport } from './edgeresidual.ts';
|
|
2
|
+
import type { SupportDomain } from './coincide.ts';
|
|
1
3
|
import { type SeamRule } from './seamrule.ts';
|
|
2
4
|
import { DEFAULT_GROUND, DEFAULT_PROJECT_RULE, type Ground, type ProjectRule } from './projectrule.ts';
|
|
3
5
|
import { paintingEdges, type PaintingEdgeSkips } from './paintingedges.ts';
|
|
@@ -2582,10 +2584,10 @@ export function visibilityCounts(object: string, part: Raster, visible: Mask, pr
|
|
|
2582
2584
|
*
|
|
2583
2585
|
* This is NOT in the reference. It is the input of `seamRule: 'silhouette'`.
|
|
2584
2586
|
*/
|
|
2585
|
-
export function figureSilhouette(srcr: Raster): Mask {
|
|
2587
|
+
export function figureSilhouette(srcr: Raster, painted = paintedFigure(srcr)): Mask {
|
|
2586
2588
|
const { width: W, height: H } = srcr;
|
|
2587
2589
|
const fig = newMask(W, H);
|
|
2588
|
-
fig.data.set(
|
|
2590
|
+
fig.data.set(painted);
|
|
2589
2591
|
const opened = dilate(dilate(erode(erode(fig, 3), 3), 3), 3);
|
|
2590
2592
|
return fillHoles(opened);
|
|
2591
2593
|
}
|
|
@@ -2628,9 +2630,8 @@ export function paintedFigure(srcr: Raster): Uint8Array {
|
|
|
2628
2630
|
* ground reads near 0; a ground of many colours, or a figure crossing the
|
|
2629
2631
|
* border, reads more.
|
|
2630
2632
|
*/
|
|
2631
|
-
export function groundRingShare(srcr: Raster): number {
|
|
2633
|
+
export function groundRingShare(srcr: Raster, painted = paintedFigure(srcr)): number {
|
|
2632
2634
|
const { width: W, height: H } = srcr;
|
|
2633
|
-
const painted = paintedFigure(srcr);
|
|
2634
2635
|
let ring = 0;
|
|
2635
2636
|
let figure = 0;
|
|
2636
2637
|
for (let y = 0; y < H; y++) {
|
|
@@ -3066,7 +3067,7 @@ export function recomposite(parts: PlacedPart[], W: number, H: number): Raster {
|
|
|
3066
3067
|
}
|
|
3067
3068
|
|
|
3068
3069
|
/** Per rig pixel: 1 where some part has alpha above `COVERED_ALPHA`. */
|
|
3069
|
-
function coveredMask(parts: PlacedPart[], W: number, H: number): Uint8Array {
|
|
3070
|
+
export function coveredMask(parts: PlacedPart[], W: number, H: number): Uint8Array {
|
|
3070
3071
|
const covered = new Uint8Array(W * H);
|
|
3071
3072
|
for (const { record: p, image } of parts) {
|
|
3072
3073
|
for (let y = 0; y < p.h; y++) for (let x = 0; x < p.w; x++) if (image.data[(y * p.w + x) * 4 + 3] > COVERED_ALPHA) covered[(p.y + y) * W + p.x + x] = 1;
|
|
@@ -3075,14 +3076,14 @@ function coveredMask(parts: PlacedPart[], W: number, H: number): Uint8Array {
|
|
|
3075
3076
|
}
|
|
3076
3077
|
|
|
3077
3078
|
/** Per rig pixel: 1 where the recomposite's max-channel difference from the painting is above `ERROR_LIMIT` — and, with `inside` (a scene, issue #242), the pixel is the figure's. */
|
|
3078
|
-
function errorMask(can: Raster, srcr: Raster, inside: Uint8Array | null = null): Uint8Array {
|
|
3079
|
+
export function errorMask(can: Raster, srcr: Raster, inside: Uint8Array | null = null, threshold = ERROR_LIMIT): Uint8Array {
|
|
3079
3080
|
const n = srcr.width * srcr.height;
|
|
3080
3081
|
const err = new Uint8Array(n);
|
|
3081
3082
|
for (let p = 0; p < n; p++) {
|
|
3082
3083
|
if (inside !== null && inside[p] === 0) continue;
|
|
3083
3084
|
let m = 0;
|
|
3084
3085
|
for (let c = 0; c < 3; c++) m = Math.max(m, Math.abs(can.data[p * 4 + c] - srcr.data[p * 4 + c]));
|
|
3085
|
-
if (m >
|
|
3086
|
+
if (m > threshold) err[p] = 1;
|
|
3086
3087
|
}
|
|
3087
3088
|
return err;
|
|
3088
3089
|
}
|
|
@@ -3127,7 +3128,7 @@ export function uncoveredHoles(can: Raster, srcr: Raster, parts: PlacedPart[], i
|
|
|
3127
3128
|
* parts hold counts for both). `uncoveredHoles` reads it at `COVERED_ALPHA`,
|
|
3128
3129
|
* `measurePinholes` (issue #944) at 0.
|
|
3129
3130
|
*/
|
|
3130
|
-
function holeBorders(parts: readonly PlacedPart[], cc: Components, s: Components['stats'][number], W: number, H: number, above: number): HoleBorder[] {
|
|
3131
|
+
export function holeBorders(parts: readonly PlacedPart[], cc: Components, s: Components['stats'][number], W: number, H: number, above: number): HoleBorder[] {
|
|
3131
3132
|
const borders: HoleBorder[] = [];
|
|
3132
3133
|
parts.forEach(({ record: p, image }) => {
|
|
3133
3134
|
let n = 0;
|
|
@@ -4597,6 +4598,8 @@ export function softOcclusionLine(r: SoftOcclusionReading): string {
|
|
|
4597
4598
|
}
|
|
4598
4599
|
|
|
4599
4600
|
export interface AssembleResult {
|
|
4601
|
+
/** Report-only residual candidates, present after the visible edge pass. */
|
|
4602
|
+
edgeResiduals?: EdgeResidualReport;
|
|
4600
4603
|
/** Report-only source re-take under actual soft front support (#825). */
|
|
4601
4604
|
softOcclusion?: SoftOcclusionReading[];
|
|
4602
4605
|
parts: PartsFile;
|
|
@@ -4613,6 +4616,10 @@ export interface AssembleResult {
|
|
|
4613
4616
|
/** Console-only source-edge support (#888); never serialized into parts.json. */
|
|
4614
4617
|
cutMaterial: MaterialRow[];
|
|
4615
4618
|
materialSources: MaterialSource[];
|
|
4619
|
+
/** Independent authored masks frozen before any art-dependent partition. */
|
|
4620
|
+
supportDomains: SupportDomain[];
|
|
4621
|
+
/** Transient native source observation reused by build, never serialized. */
|
|
4622
|
+
supportFigure?: Mask;
|
|
4616
4623
|
/** What each `config.limbs` limb cut, per part it took and per joint (`limbLines`); empty without limbs (issue #349). */
|
|
4617
4624
|
limbs: LimbCount[];
|
|
4618
4625
|
/** The full-run layers the plan does not take from the full run whose uncovered error holds a body (`uncoveredErrorLayers`); empty otherwise. */
|
|
@@ -4846,7 +4853,8 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
4846
4853
|
checkPlanAgainstRuns(sourcePlan, extend, full, head);
|
|
4847
4854
|
const { W, H } = frame;
|
|
4848
4855
|
const srcr = sourceInRig(source, W, H);
|
|
4849
|
-
const
|
|
4856
|
+
const supportPainted = paintedFigure(srcr);
|
|
4857
|
+
const groundShare = groundRingShare(srcr, supportPainted);
|
|
4850
4858
|
// Issue #359: a part's hidden-art layer is the under of a cut that names none — and, with one named, a refusal, since
|
|
4851
4859
|
// reading either would be a guess. Its uses are counted for `hiddenLines`.
|
|
4852
4860
|
const hiddenArt = hiddenArtByPart(plan, input.cuts, { full, head }, frame, input.resolution);
|
|
@@ -5002,6 +5010,9 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5002
5010
|
// most likely), and two cuts of one part that share a pixel would give it
|
|
5003
5011
|
// to both. Every pair is named.
|
|
5004
5012
|
const cutMasks = cuts.map((q) => pixelsInPolygon(q.polygon, W, H));
|
|
5013
|
+
const supportDomains: SupportDomain[] = cuts.map((cut, i) => ({ part: cut.into,
|
|
5014
|
+
mask: { width: W, height: H, data: cutMasks[i].data.slice() },
|
|
5015
|
+
provenance: { kind: 'cut-polygon', entry: `config.assemble.cuts[${i}].polygon` } }));
|
|
5005
5016
|
cuts.forEach((q, i) => {
|
|
5006
5017
|
const out = q.polygon.filter(([x, y]) => x > W || y > H);
|
|
5007
5018
|
if (out.length > 0) {
|
|
@@ -5139,7 +5150,7 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5139
5150
|
// Every Built owns its writer slice. No source-map lookup follows this
|
|
5140
5151
|
// last cut-layer build; drop originals before cut/limb working sets grow.
|
|
5141
5152
|
layerWriters.clear();
|
|
5142
|
-
const silhouette = seamRule === 'silhouette' || patches.some((q) => q.alpha === 'silhouette') ? figureSilhouette(srcr) : null;
|
|
5153
|
+
const silhouette = seamRule === 'silhouette' || patches.some((q) => q.alpha === 'silhouette') ? figureSilhouette(srcr, supportPainted) : null;
|
|
5143
5154
|
const cut = patches.map((q, i) => {
|
|
5144
5155
|
const c = cutPatch(q, srcr, silhouette);
|
|
5145
5156
|
if (c === null) {
|
|
@@ -5653,7 +5664,7 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5653
5664
|
return whole;
|
|
5654
5665
|
};
|
|
5655
5666
|
const e = paintingEdges(stack.map(onRig), srcr, {
|
|
5656
|
-
painted:
|
|
5667
|
+
painted: supportPainted,
|
|
5657
5668
|
...(input.ground === undefined ? {} : { ground: input.ground }),
|
|
5658
5669
|
editable: order.map((d) => !('patch' in d)),
|
|
5659
5670
|
keep: keepInOrder,
|
|
@@ -5835,6 +5846,13 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5835
5846
|
frame.headBottom,
|
|
5836
5847
|
bodyMinPx(frame),
|
|
5837
5848
|
);
|
|
5849
|
+
// This observation belongs to the source painting. Reuse the mask already
|
|
5850
|
+
// read for ground coverage without changing the assembly silhouette.
|
|
5851
|
+
let opaqueSource = true;
|
|
5852
|
+
for (let p = 3; p < source.data.length; p += 4) if (source.data[p] !== 255) { opaqueSource = false; break; }
|
|
5853
|
+
const supportSilhouette = opaqueSource ? silhouette ?? figureSilhouette(srcr, supportPainted) : null;
|
|
5854
|
+
const supportFigure = supportSilhouette === null ? undefined : newMask(W, H);
|
|
5855
|
+
if (supportFigure !== undefined && supportSilhouette !== null) for (let p = 0; p < supportPainted.length; p++) supportFigure.data[p] = supportSilhouette.data[p] & supportPainted[p];
|
|
5838
5856
|
return {
|
|
5839
5857
|
...(softOcclusion.length === 0 ? {} : { softOcclusion }),
|
|
5840
5858
|
parts: {
|
|
@@ -5851,6 +5869,7 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5851
5869
|
...(padRecord === null ? {} : { single_run_pad: padRecord }),
|
|
5852
5870
|
},
|
|
5853
5871
|
images: placed,
|
|
5872
|
+
...(projectRule === 'visible' ? { edgeResiduals: edgePairResiduals(placed.map(p => ({ name: p.record.name, x: p.record.x, y: p.record.y, image: p.image })), srcr, can, ERROR_LIMIT) } : {}),
|
|
5854
5873
|
...(registeredDepth.size === 0 ? {} : { depthReadings: ([['full', depthFullInput], ...(single ? [] : [['head', depthHeadInput]])] as Array<['full' | 'head', LayerSet]>).flatMap(([run, set]) => set.layers.flatMap(layer => layer.depthSheet === undefined ? [] : [{ from: `${run}:${layer.name}`, reading: layer.depthSheet.reading }])) }),
|
|
5855
5874
|
...(depthClamps.length === 0 ? {} : { depthClamps }),
|
|
5856
5875
|
recomposite: can,
|
|
@@ -5860,6 +5879,8 @@ export function assemble(input: AssembleInput): AssembleResult {
|
|
|
5860
5879
|
cuts: cutCounts,
|
|
5861
5880
|
cutMaterial: [...cutMaterial, ...lim.material],
|
|
5862
5881
|
materialSources: [...materialSources, ...lim.sources],
|
|
5882
|
+
supportDomains,
|
|
5883
|
+
...(supportFigure === undefined ? {} : { supportFigure }),
|
|
5863
5884
|
limbs: lim.counts,
|
|
5864
5885
|
uncovered,
|
|
5865
5886
|
holeKinds: kinds,
|
package/src/build.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { EDGE_RESIDUAL_FILE, edgeResidualLines } from './edgeresidual.ts';
|
|
2
|
+
import { SUPPORT_DOMAINS_FILE, writeSupportDomains } from './supportdomains.ts';
|
|
3
|
+
import { COINCIDE_LINE, supportLines } from './coincide.ts';
|
|
1
4
|
import { DEFAULT_SEAM_RULE } from './seamrule.ts';
|
|
2
5
|
import { DEFAULT_PROJECT_RULE } from './projectrule.ts';
|
|
3
6
|
import { EDGE_CONTRAST } from './paintingedges.ts';
|
|
@@ -338,6 +341,7 @@ export function assembleStage(input: AssembleStageInput, outs: AssembleOutputs,
|
|
|
338
341
|
// The early door: assemble runs before propose has drafted bones, meshes,
|
|
339
342
|
// regions and motion, so it requires only what it reads (issue #20).
|
|
340
343
|
const cfg = loadEarlyConfig(input.config, 'assemble');
|
|
344
|
+
const supportDeclarations = JSON.stringify(cfg.assemble.cuts ?? []);
|
|
341
345
|
const seam = input.seam ?? cfg.assemble.seam ?? DEFAULT_SEAM_RULE;
|
|
342
346
|
const project = input.project ?? cfg.assemble.project ?? DEFAULT_PROJECT_RULE;
|
|
343
347
|
const src = readSource(input.source);
|
|
@@ -793,6 +797,9 @@ export function assembleStage(input: AssembleStageInput, outs: AssembleOutputs,
|
|
|
793
797
|
mkdirSync(dirname(outs.recomposite), { recursive: true });
|
|
794
798
|
mkdirSync(dirname(outs.errorMap), { recursive: true });
|
|
795
799
|
writeParts(outs.partsJson, result.parts);
|
|
800
|
+
const residualPath = join(dirname(outs.partsJson), EDGE_RESIDUAL_FILE);
|
|
801
|
+
if (result.edgeResiduals === undefined) rmSync(residualPath, { force: true });
|
|
802
|
+
else writeFileSync(residualPath, JSON.stringify(result.edgeResiduals, null, 2) + '\n');
|
|
796
803
|
for (const { record, image, depthImage } of result.images) {
|
|
797
804
|
writePng(join(outs.partsDir, `${record.name}.png`), image);
|
|
798
805
|
if (depthImage !== undefined && record.depth !== undefined) writePng(join(outs.partsDir, record.depth.image), depthImage);
|
|
@@ -805,6 +812,7 @@ export function assembleStage(input: AssembleStageInput, outs: AssembleOutputs,
|
|
|
805
812
|
}
|
|
806
813
|
if (materialAsked) writeMaterialSources(outs.partsJson, outs.partsDir, result.parts, result.materialSources);
|
|
807
814
|
else rmSync(join(dirname(outs.partsJson), CUT_MATERIAL_SOURCES), { force: true });
|
|
815
|
+
writeSupportDomains(outs.partsJson, outs.partsDir, result.parts, result.supportDomains, supportDeclarations);
|
|
808
816
|
writePng(outs.recomposite, result.recomposite);
|
|
809
817
|
writePng(outs.errorMap, result.errorMap);
|
|
810
818
|
// Issue #242: under config.scene, the figure the recomposite was read inside, beside the recomposite.
|
|
@@ -822,6 +830,7 @@ export function assembleStage(input: AssembleStageInput, outs: AssembleOutputs,
|
|
|
822
830
|
// Issue #996: under a declared busy ground, what the two ground rules left.
|
|
823
831
|
if (fields.ground === 'busy') log(` busy ground (assemble.ground): ${e.skipped.mix} behind-side px left that are not a mix of the two reference colours, ${e.skipped.support} part px not raised outside the part's own support`);
|
|
824
832
|
}
|
|
833
|
+
if (result.edgeResiduals !== undefined) for (const line of edgeResidualLines(result.edgeResiduals)) log(line);
|
|
825
834
|
// Issue #359: one run, said, so a reader of the lines knows no head run was placed.
|
|
826
835
|
if (runs.single) log(` one run: ${input.full} holds the face (${SINGLE_RUN_FACE_TAGS.join(', ')}), so no head run is read; every part comes from the full run`);
|
|
827
836
|
// Issue #366: a file that is not the resolution square was padded to it; said, with where parts.json records it. None for a square file.
|
|
@@ -1665,6 +1674,10 @@ export interface CheckStageInput {
|
|
|
1665
1674
|
out: string;
|
|
1666
1675
|
/** The painting `--source` names (issue #77): adds the setup pose against it. */
|
|
1667
1676
|
source?: string;
|
|
1677
|
+
/** Internal build painting for the report only; does not enable source gates. */
|
|
1678
|
+
supportSource?: string;
|
|
1679
|
+
/** Transient source observation passed by assembly, never a public output. */
|
|
1680
|
+
supportFigure?: Mask;
|
|
1668
1681
|
/** The packed build's `--page-edges`; {@link DEFAULT_PAGE_EDGES} when absent. */
|
|
1669
1682
|
pageEdges?: PageEdges;
|
|
1670
1683
|
/** The packed build's `--pack-shape`; {@link DEFAULT_PACK_SHAPE} when absent. */
|
|
@@ -1826,9 +1839,12 @@ export function levelLines(line: LevelLine): string[] {
|
|
|
1826
1839
|
* own — its limb, its bone, and on a FAIL every other bone it is bound to.
|
|
1827
1840
|
*/
|
|
1828
1841
|
export function limbCheckLines(line: LimbLine): string[] {
|
|
1842
|
+
const carriers = line.parts.some(row => row.region_bones !== undefined)
|
|
1843
|
+
? 'its segment carrier or its declared contour region bones'
|
|
1844
|
+
: 'its one bone with weight 1 (a region on it, or a mesh weighted to it alone)';
|
|
1829
1845
|
return [
|
|
1830
|
-
`${LIMB_LINE}: ${line.status} — ${line.parts.length} limb part(s), each bound in rig.json to
|
|
1831
|
-
...line.parts.map((r) => `limb "${r.part}" (${r.limb}) on "${r.bone}": ${r.status}${r.others.length === 0 ? '' : `, also weighted to ${r.others.map((b) => `"${b}"`).join(', ')}`}`),
|
|
1846
|
+
`${LIMB_LINE}: ${line.status} — ${line.parts.length} limb part(s), each bound in rig.json to ${carriers}`,
|
|
1847
|
+
...line.parts.map((r) => `limb "${r.part}" (${r.limb}) on "${r.bone}": ${r.status}${r.region_bones === undefined ? '' : `, declared contour region bones [${r.region_bones.join(', ')}]`}${r.others.length === 0 ? '' : `, also weighted to ${r.others.map((b) => `"${b}"`).join(', ')}`}`),
|
|
1832
1848
|
];
|
|
1833
1849
|
}
|
|
1834
1850
|
|
|
@@ -1928,7 +1944,7 @@ export function checkStage(input: CheckStageInput, rigc: RigcRunner, bin: string
|
|
|
1928
1944
|
const entryLine = versionLines.find((l) => l.startsWith('entry:'));
|
|
1929
1945
|
log(` ${rigcIdentity(bin, v)}${entryLine === undefined ? '' : `; ${entryLine}`}`);
|
|
1930
1946
|
const mode: PackMode = { pageEdges: input.pageEdges ?? DEFAULT_PAGE_EDGES, packShape: input.packShape ?? DEFAULT_PACK_SHAPE };
|
|
1931
|
-
const r = runCheck(input.rig, input.out, rigc, input.parts, mode, input.source, input.requirements, input.seamPairs === true, input.keepStills === true, input.set, input.allSets === true, input.environment, input.requirementsAs, input.config, input.windBand, input.noExtremes === true);
|
|
1947
|
+
const r = runCheck(input.rig, input.out, rigc, input.parts, mode, input.source, input.requirements, input.seamPairs === true, input.keepStills === true, input.set, input.allSets === true, input.environment, input.requirementsAs, input.config, input.windBand, input.noExtremes === true, input.supportSource, input.supportFigure);
|
|
1932
1948
|
if (r.figures.environment !== undefined) log(` ${environmentLine(r.figures.environment)}`);
|
|
1933
1949
|
log(` gate rig-play (rigc ${packedBuildLabel(mode)}), verbatim:`);
|
|
1934
1950
|
for (const l of r.gateHtml) log(l);
|
|
@@ -1994,6 +2010,8 @@ export function checkStage(input: CheckStageInput, rigc: RigcRunner, bin: string
|
|
|
1994
2010
|
if (cutMaterial !== undefined) for (const line of materialLines(cutMaterial)) log(` ${line}`);
|
|
1995
2011
|
const artJoints = fig[ART_JOINT_LINE];
|
|
1996
2012
|
if (artJoints !== undefined) for (const line of artJointLines(artJoints)) log(` ${line}`);
|
|
2013
|
+
const partSupport = fig[COINCIDE_LINE];
|
|
2014
|
+
if (partSupport !== undefined) for (const line of supportLines(partSupport)) log(` ${line}`);
|
|
1997
2015
|
const setupPainting = fig[SETUP_PAINTING_LINE];
|
|
1998
2016
|
if (setupPainting !== undefined) for (const line of setupPaintingLines(setupPainting)) log(` ${line}`);
|
|
1999
2017
|
for (const line of boundaryColourLines(r.boundaryColour)) log(` ${line}`);
|
|
@@ -2368,9 +2386,9 @@ export function suppliedCheckFlag(flag: string): string | null {
|
|
|
2368
2386
|
* rig-c's launcher answers for; they are two fields so a caller can tell
|
|
2369
2387
|
* the stages' calls apart (the selftest counts them).
|
|
2370
2388
|
*/
|
|
2371
|
-
/** Stage implementations may run outside this process;
|
|
2389
|
+
/** Stage implementations may run outside this process; assembly may return its transient source observation; check returns its report. */
|
|
2372
2390
|
export interface BuildStages {
|
|
2373
|
-
assemble: (input: AssembleStageInput, outputs: AssembleOutputs, log: Log) => void;
|
|
2391
|
+
assemble: (input: AssembleStageInput, outputs: AssembleOutputs, log: Log) => { supportFigure?: Mask } | void;
|
|
2374
2392
|
rig: (input: RigStageInput, rigc: RigcRunner, scratch: string, log: Log) => void;
|
|
2375
2393
|
check: typeof checkStage;
|
|
2376
2394
|
}
|
|
@@ -2445,6 +2463,8 @@ export function build(input: BuildInput, run: BuildRunners, log: Log): BuildResu
|
|
|
2445
2463
|
for (const p of BUILD_OWNS) rmSync(join(out, p), { recursive: true, force: true });
|
|
2446
2464
|
// Optional source evidence is cleared separately; BUILD_OWNS is the legacy complete output tree.
|
|
2447
2465
|
rmSync(join(out, CUT_MATERIAL_SOURCES), { force: true });
|
|
2466
|
+
rmSync(join(out, EDGE_RESIDUAL_FILE), { force: true });
|
|
2467
|
+
rmSync(join(out, SUPPORT_DOMAINS_FILE), { force: true });
|
|
2448
2468
|
// Issue #242: the figure mask is written only under config.scene; one left by an earlier scene build is not this build's.
|
|
2449
2469
|
rmSync(join(out, FIGURE_MASK_FILE), { force: true });
|
|
2450
2470
|
// The idle-keys value is named only when it is not the default, so a build without the flag, or with the default, prints the line it printed before issue #95.
|
|
@@ -2455,6 +2475,7 @@ export function build(input: BuildInput, run: BuildRunners, log: Log): BuildResu
|
|
|
2455
2475
|
// Issue #978: the painting is handed to the check only when the requirements file declares setup_painting, which
|
|
2456
2476
|
// cannot be measured without it; a build without that declaration hands it nothing, as before, and writes the same bytes.
|
|
2457
2477
|
let paintingForCheck: string | null = null;
|
|
2478
|
+
let supportFigure: Mask | undefined;
|
|
2458
2479
|
try {
|
|
2459
2480
|
// build runs rig next, which needs the whole config, so the full loader is
|
|
2460
2481
|
// asked first: a config rig would refuse is refused before assemble writes
|
|
@@ -2474,11 +2495,12 @@ export function build(input: BuildInput, run: BuildRunners, log: Log): BuildResu
|
|
|
2474
2495
|
if (input.environment !== undefined) readCheckEnvironment(input.environment);
|
|
2475
2496
|
// And the steady-wind band spec (issue #590), as check reads it.
|
|
2476
2497
|
if (input.windBand !== undefined) readWindBand(input.windBand);
|
|
2477
|
-
stages.assemble(
|
|
2498
|
+
const assembled = stages.assemble(
|
|
2478
2499
|
{ source: input.source, full: input.full, head: input.head, config: input.config, seam, project, ...(req === null ? {} : { requirements: req.read }), ...(input.alts === undefined ? {} : { alts: input.alts }) },
|
|
2479
2500
|
{ partsJson: join(out, 'parts.json'), partsDir: join(out, 'parts'), recomposite: join(out, 'recomposite_rig.png'), errorMap: join(out, ERROR_MAP_FILE) },
|
|
2480
2501
|
prefixed('assemble'),
|
|
2481
2502
|
);
|
|
2503
|
+
supportFigure = assembled?.supportFigure;
|
|
2482
2504
|
} catch (err) {
|
|
2483
2505
|
return refused('assemble', err);
|
|
2484
2506
|
}
|
|
@@ -2491,7 +2513,7 @@ export function build(input: BuildInput, run: BuildRunners, log: Log): BuildResu
|
|
|
2491
2513
|
|
|
2492
2514
|
let report: CheckReport;
|
|
2493
2515
|
try {
|
|
2494
|
-
report = stages.check({ rig: join(out, 'rig'), parts: out, out: join(out, 'check'), pageEdges: input.pageEdges, packShape: input.packShape, ...(req === null ? {} : { requirements: req.read, requirementsAs: req.recorded }), ...(paintingForCheck === null ? {} : { source: paintingForCheck }), seamPairs: input.seamPairs === true, keepStills: input.keepStills === true, noExtremes: input.noExtremes === true, ...(input.set === undefined ? {} : { set: input.set }), allSets: input.allSets === true, ...(input.environment === undefined ? {} : { environment: input.environment }), ...(input.windBand === undefined ? {} : { windBand: input.windBand }), ...(configRecord === null ? {} : { config: configRecord }) }, run.check, run.checkBin, prefixed('check'));
|
|
2516
|
+
report = stages.check({ rig: join(out, 'rig'), parts: out, supportSource: input.source, ...(supportFigure === undefined ? {} : { supportFigure }), out: join(out, 'check'), pageEdges: input.pageEdges, packShape: input.packShape, ...(req === null ? {} : { requirements: req.read, requirementsAs: req.recorded }), ...(paintingForCheck === null ? {} : { source: paintingForCheck }), seamPairs: input.seamPairs === true, keepStills: input.keepStills === true, noExtremes: input.noExtremes === true, ...(input.set === undefined ? {} : { set: input.set }), allSets: input.allSets === true, ...(input.environment === undefined ? {} : { environment: input.environment }), ...(input.windBand === undefined ? {} : { windBand: input.windBand }), ...(configRecord === null ? {} : { config: configRecord }) }, run.check, run.checkBin, prefixed('check'));
|
|
2495
2517
|
} catch (err) {
|
|
2496
2518
|
return refused('check', err);
|
|
2497
2519
|
}
|