rig-parts 2.9.0 → 2.9.1
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/paintingedges.ts +11 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.1",
|
|
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/paintingedges.ts
CHANGED
|
@@ -78,6 +78,9 @@ import { type Mask, newMask, type Raster, RasterError } from './raster/types.ts'
|
|
|
78
78
|
* part, BEHIND is made opaque there in `Cb` (in the painting's own colour
|
|
79
79
|
* where FRONT's alpha is 0), so the flat composite at p is the painting, the
|
|
80
80
|
* rim stays FRONT's, and BEHIND's hidden surface past the window is untouched.
|
|
81
|
+
* Where BEHIND already has alpha at least {@link EDGE_OWNER_ALPHA}, its own
|
|
82
|
+
* pre-step RGB is the fill colour. FRONT is unmixed against that same colour,
|
|
83
|
+
* including the clamping error calculation, to preserve the pair's composite.
|
|
81
84
|
*
|
|
82
85
|
* A pixel is left as it was — and counted, by reason — when a part drawn in
|
|
83
86
|
* front of FRONT, or between BEHIND and FRONT, has alpha above
|
|
@@ -491,11 +494,16 @@ export function paintingEdges(parts: Raster[], srcr: Raster, options: PaintingEd
|
|
|
491
494
|
decisions.forEach((q, k) => {
|
|
492
495
|
const s = q.p * 4;
|
|
493
496
|
const P = [srcr.data[s], srcr.data[s + 1], srcr.data[s + 2]];
|
|
494
|
-
|
|
497
|
+
// An existing BEHIND surface keeps its own colour. Unmix FRONT against
|
|
498
|
+
// that same surface so the pair still reconstructs the painting.
|
|
499
|
+
const cb = q.behind >= 0 && parts[q.behind].data[s + 3] >= EDGE_OWNER_ALPHA
|
|
500
|
+
? [parts[q.behind].data[s], parts[q.behind].data[s + 1], parts[q.behind].data[s + 2]]
|
|
501
|
+
: q.cb;
|
|
502
|
+
const unmixAt = (c: number, a: number): number => Math.min(255, Math.max(0, Math.round(cb[c] + ((P[c] - cb[c]) * 255) / a)));
|
|
495
503
|
// FRONT's colour is clamped to 0..255, so a pixel the two colours cannot mix at that coverage (a painted line darker or
|
|
496
504
|
// lighter than both) would miss the painting: FRONT's coverage rises to the least that brings the composite within half
|
|
497
505
|
// the contrast floor of it (at full coverage it is the painting).
|
|
498
|
-
const miss = (a: number): number => Math.max(...[0, 1, 2].map((c) => Math.abs(Math.round((unmixAt(c, a) * a +
|
|
506
|
+
const miss = (a: number): number => Math.max(...[0, 1, 2].map((c) => Math.abs(Math.round((unmixAt(c, a) * a + cb[c] * (255 - a)) / 255) - P[c])));
|
|
499
507
|
let alpha = alphaOf[k];
|
|
500
508
|
if (alpha > 0 && alpha < 255) while (alpha < 255 && 2 * miss(alpha) > EDGE_CONTRAST) alpha++;
|
|
501
509
|
if (alpha >= 255 - OPAQUE_ALPHA_ABOVE) alpha = 255;
|
|
@@ -512,7 +520,7 @@ export function paintingEdges(parts: Raster[], srcr: Raster, options: PaintingEd
|
|
|
512
520
|
else plan(q.front, q.p, unmix(0), unmix(1), unmix(2), alpha);
|
|
513
521
|
if (q.behind >= 0 && alpha < 255) {
|
|
514
522
|
if (alpha === 0) plan(q.behind, q.p, P[0], P[1], P[2], 255);
|
|
515
|
-
else plan(q.behind, q.p,
|
|
523
|
+
else plan(q.behind, q.p, cb[0], cb[1], cb[2], 255);
|
|
516
524
|
fills[q.behind].set(q.p, q.front);
|
|
517
525
|
}
|
|
518
526
|
});
|