@rig-c/parts 0.0.0-stage → 1.5.4
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/LICENSE +21 -0
- package/NOTICE.md +134 -0
- package/README.md +433 -2
- package/bin/rig-parts.cjs +43 -0
- package/cli.ts +1240 -0
- package/docs/AUTHORING.md +2387 -0
- package/docs/MIGRATION.md +150 -0
- package/docs/STABILITY.md +262 -0
- package/package.json +70 -4
- package/skills/rig-parts/SKILL.md +167 -0
- package/src/apng.ts +381 -0
- package/src/assemble.ts +2259 -0
- package/src/autoamplitude.ts +194 -0
- package/src/autoenvelope.ts +404 -0
- package/src/automesh.ts +585 -0
- package/src/automotion.ts +447 -0
- package/src/autoreplay.ts +516 -0
- package/src/build.ts +1240 -0
- package/src/check.ts +2942 -0
- package/src/comfy/client.ts +245 -0
- package/src/comfy/index.ts +19 -0
- package/src/comfy/painting.ts +136 -0
- package/src/comfy/seethrough.ts +171 -0
- package/src/config.ts +2283 -0
- package/src/contour.ts +1901 -0
- package/src/coords.ts +26 -0
- package/src/diagnostics.ts +198 -0
- package/src/errors.ts +39 -0
- package/src/gif.ts +213 -0
- package/src/graphs.ts +302 -0
- package/src/headbox.ts +173 -0
- package/src/heat.ts +313 -0
- package/src/inputs.ts +100 -0
- package/src/instruments.ts +1145 -0
- package/src/keypoints.ts +296 -0
- package/src/layers.ts +598 -0
- package/src/localweights.ts +217 -0
- package/src/mesh.ts +362 -0
- package/src/motion.ts +311 -0
- package/src/palette.ts +208 -0
- package/src/parts.ts +410 -0
- package/src/propose.ts +2540 -0
- package/src/pyfmt.ts +135 -0
- package/src/raster/blur.ts +80 -0
- package/src/raster/components.ts +165 -0
- package/src/raster/composite.ts +81 -0
- package/src/raster/index.ts +9 -0
- package/src/raster/morph.ts +116 -0
- package/src/raster/png.ts +82 -0
- package/src/raster/poly.ts +166 -0
- package/src/raster/resize.ts +301 -0
- package/src/raster/types.ts +89 -0
- package/src/raster/warp.ts +121 -0
- package/src/requirements.ts +1240 -0
- package/src/rig.ts +1440 -0
- package/src/round.ts +62 -0
- package/src/scene.ts +1414 -0
- package/src/sheet.ts +128 -0
- package/src/skeleton.ts +400 -0
- package/src/structure.ts +858 -0
- package/src/tags.ts +121 -0
- package/src/weights.ts +124 -0
- package/workflows/seethrough.json +68 -0
package/src/round.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rounding the way the reference implementation rounds.
|
|
3
|
+
*
|
|
4
|
+
* The rig stage writes every coordinate, weight, uv and key value rounded to a
|
|
5
|
+
* fixed number of decimals, and the reference did that with Python's
|
|
6
|
+
* `round(x, n)` and NumPy's `np.round` — both of which round the EXACT binary
|
|
7
|
+
* value of `x` to the nearest n-decimal number and break an exact tie to the
|
|
8
|
+
* even digit. JavaScript has no such call: `Math.round` breaks ties upward,
|
|
9
|
+
* and `Number.prototype.toFixed` rounds the exact value correctly but breaks an
|
|
10
|
+
* exact tie away from zero. So this file is `toFixed` plus the one case where
|
|
11
|
+
* the two disagree.
|
|
12
|
+
*
|
|
13
|
+
* ⭐ The case is not hypothetical. A uv is `x / w` rounded to 6 decimals, and
|
|
14
|
+
* for `x = 1, w = 128` that is exactly 0.0078125 — a tie at the sixth decimal,
|
|
15
|
+
* which Python writes as 0.007812 and a naive port as 0.007813. Ties happen
|
|
16
|
+
* exactly when `x` is a dyadic rational whose lowest set bit is 2^-(n+1): then
|
|
17
|
+
* `x * 2 * 10^n` is an odd integer (`5^n` and the odd mantissa stay odd), and
|
|
18
|
+
* for no other double.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** The exponent of the lowest set bit of a finite non-zero double: `x = m * 2^e` with `m` an odd integer. */
|
|
22
|
+
function lowestBitExponent(x: number): number {
|
|
23
|
+
let y = Math.abs(x);
|
|
24
|
+
let e = 0;
|
|
25
|
+
// Doubling and halving a double are exact while it stays normal, and a
|
|
26
|
+
// finite double becomes an integer after at most 1074 doublings.
|
|
27
|
+
while (!Number.isInteger(y)) {
|
|
28
|
+
y *= 2;
|
|
29
|
+
e--;
|
|
30
|
+
}
|
|
31
|
+
while (y % 2 === 0) {
|
|
32
|
+
y /= 2;
|
|
33
|
+
e++;
|
|
34
|
+
}
|
|
35
|
+
return e;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** `round(x, n)` as Python 3 computes it for a float: correctly rounded, exact ties to even. */
|
|
39
|
+
export function pyRound(x: number, n: number): number {
|
|
40
|
+
if (!Number.isFinite(x) || x === 0) return x;
|
|
41
|
+
if (Math.abs(x) >= 1e21) return x;
|
|
42
|
+
const fixed = x.toFixed(n);
|
|
43
|
+
if (lowestBitExponent(x) !== -(n + 1)) return Number(fixed);
|
|
44
|
+
// An exact tie: toFixed went away from zero. Keep it when that digit is even,
|
|
45
|
+
// otherwise step one unit back toward zero.
|
|
46
|
+
const negative = fixed.startsWith('-');
|
|
47
|
+
const digits = fixed.replace('-', '').replace('.', '');
|
|
48
|
+
const last = Number(digits[digits.length - 1]);
|
|
49
|
+
if (last % 2 === 0) return Number(fixed);
|
|
50
|
+
const down = (BigInt(digits) - 1n).toString().padStart(n + 1, '0');
|
|
51
|
+
const text = n === 0 ? down : `${down.slice(0, down.length - n)}.${down.slice(down.length - n)}`;
|
|
52
|
+
return Number(`${negative ? '-' : ''}${text}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** `np.rint` / `round(np.float64)`: to the nearest integer, exact halves to even. */
|
|
56
|
+
export function rint(x: number): number {
|
|
57
|
+
const f = Math.floor(x);
|
|
58
|
+
const frac = x - f;
|
|
59
|
+
if (frac < 0.5) return f;
|
|
60
|
+
if (frac > 0.5) return f + 1;
|
|
61
|
+
return f % 2 === 0 ? f : f + 1;
|
|
62
|
+
}
|