forgecad 0.10.2 → 0.10.3
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 +7 -6
- package/dist/assets/{AdminPage-CHY6ZN-p.js → AdminPage-CK7ObBz3.js} +1 -1
- package/dist/assets/{BenchmarkPage-BcRT5iGN.js → BenchmarkPage-Ds7Z2doN.js} +1 -1
- package/dist/assets/{BlogPage-BssBbnb-.js → BlogPage-DlPbpt6A.js} +1 -1
- package/dist/assets/{DocsPage-DsvdiRNK.js → DocsPage-vZb3b3Y0.js} +9 -14
- package/dist/assets/{EditorApp-BpjZgzk0.css → EditorApp-C5f24ZN9.css} +8 -0
- package/dist/assets/{EditorApp-Bfd3jbtC.js → EditorApp-HLoKfe15.js} +141 -12
- package/dist/assets/{EmbedViewer-D5t8WamV.js → EmbedViewer--KnqBKrJ.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-DbN7o-Be.js → LandingPageProofDriven-C_LssmnA.js} +1 -1
- package/dist/assets/{LegalPage-DNGrrY0p.js → LegalPage-DGsyo4n1.js} +1 -1
- package/dist/assets/{PricingPage-Nczr3pRz.js → PricingPage-BOE27B-R.js} +1 -1
- package/dist/assets/{SettingsPage-DZlyu4d4.js → SettingsPage-f47cnk39.js} +1 -1
- package/dist/assets/{app-C9ct2hRD.js → app-D6ccu2Xx.js} +6854 -7373
- package/dist/assets/{backendInit-ymjonyQp.js → backendInit-DbTkQN9J.js} +2557 -809
- package/dist/assets/cli/{render-B_0lQwKU.js → render-BsngirjC.js} +114 -9
- package/dist/assets/{constructionHistoryWorker-CZ42Dksy.js → constructionHistoryWorker-PCwXrTDB.js} +175 -36
- package/dist/assets/{evalWorker-C2pm8LHP.js → evalWorker-CS63PfZu.js} +1125 -447
- package/dist/assets/{forgecad_geometry-BlMtqluF.js → forgecad_geometry-CZ_IfuvA.js} +1 -9
- package/dist/assets/{forgecad_geometry_bg-BllP_WiL.wasm → forgecad_geometry_bg-C3rQHfwg.wasm} +0 -0
- package/dist/assets/{inspectWorker-D5T5VbfK.js → inspectWorker-Y4cOzNyA.js} +4345 -373
- package/dist/assets/{jointPose-4r8ed8_5.js → jointPose-AMvCywzS.js} +1 -1
- package/dist/assets/{manifold-C4r6B-XY.js → manifold-CBry38ly.js} +2 -2
- package/dist/assets/{manifold-5PP1eGLN.js → manifold-Crd_F2qx.js} +1 -1
- package/dist/assets/{manifold-DjBkyIc8.js → manifold-k2kRcc85.js} +1 -1
- package/dist/assets/{reportWorker-CwenM7wB.js → reportWorker-CWvn0CEv.js} +1095 -400
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/usage.md +2 -4
- package/dist/docs-raw/CLI.md +9 -7
- package/dist/docs-raw/README.md +1 -1
- package/dist/docs-raw/component-model.md +1 -1
- package/dist/docs-raw/generated/assembly.md +1 -1
- package/dist/docs-raw/generated/concepts.md +5 -3
- package/dist/docs-raw/generated/core.md +70 -1
- package/dist/docs-raw/generated/curves.md +8 -1
- package/dist/docs-raw/generated/output.md +0 -64
- package/dist/docs-raw/generated/runtime-names.md +6 -6
- package/dist/docs-raw/generated/viewport.md +3 -12
- package/dist/docs-raw/guides/inspection-bundles.md +1 -1
- package/dist/docs-raw/simulation-workflow.md +58 -0
- package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
- package/dist/docs-raw/skills/forgecad-image-replicator.md +2 -2
- package/dist/docs-raw/skills/forgecad-mujoco-verify.md +78 -0
- package/dist/docs-raw/skills/forgecad-spec-by-walking-through-it.md +145 -0
- package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad.md +24 -24
- package/dist/docs-raw/skills/index.md +2 -3
- package/dist/index.html +1 -1
- package/dist/sitemap.xml +15 -15
- package/dist-cli/{check-compiler-SP7FAL7R.js → check-compiler-HPF2T2FS.js} +1 -1
- package/dist-cli/{check-query-propagation-BRLSHP22.js → check-query-propagation-HYSLTXAB.js} +1 -1
- package/dist-cli/{chunk-RQQ42YCP.js → chunk-WLUKAW3H.js} +1025 -158
- package/dist-cli/forgecad.js +2621 -232
- package/dist-cli/{forgecad_geometry-7TVSNVUB.js → forgecad_geometry-2IMYCUWW.js} +0 -8
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +85 -73
- package/dist-skill/SKILL.md +1 -1
- package/dist-skill/docs/CLI.md +9 -7
- package/dist-skill/docs/generated/assembly.md +1 -1
- package/dist-skill/docs/generated/core.md +70 -1
- package/dist-skill/docs/generated/curves.md +8 -1
- package/dist-skill/docs/generated/output.md +0 -64
- package/dist-skill/docs/generated/runtime-names.md +6 -6
- package/dist-skill/docs/generated/viewport.md +3 -12
- package/dist-skill/docs/guides/inspection-bundles.md +1 -1
- package/dist-skill/library/README.md +2 -3
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +1 -1
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +2 -2
- package/dist-skill/library/forgecad-mujoco-verify/SKILL.md +66 -0
- package/dist-skill/library/forgecad-mujoco-verify/scripts/mujoco_verify.py +385 -0
- package/dist-skill/library/forgecad-spec-by-walking-through-it/SKILL.md +132 -0
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +1 -1
- package/dist-skill/website/skills/forgecad-blockout-model.md +1 -1
- package/dist-skill/website/skills/forgecad-image-replicator.md +2 -2
- package/dist-skill/website/skills/forgecad-mujoco-verify.md +78 -0
- package/dist-skill/website/skills/forgecad-spec-by-walking-through-it.md +145 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +1 -1
- package/dist-skill/website/skills/forgecad.md +24 -24
- package/dist-skill/website/skills/index.md +2 -3
- package/examples/analysis/clearance-fit.forge.js +31 -0
- package/examples/analysis/lever-arm-actuator.forge.js +43 -0
- package/examples/analysis/tipping-tripod.forge.js +35 -0
- package/examples/products/sportscar.forge.js +77 -0
- package/package.json +1 -3
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +0 -101
- package/dist/docs-raw/skills/forgecad-lld.md +0 -41
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +0 -63
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +0 -94
- package/dist-skill/library/forgecad-lld/SKILL.md +0 -34
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +0 -50
- package/dist-skill/website/skills/forgecad-high-level-spec.md +0 -101
- package/dist-skill/website/skills/forgecad-lld.md +0 -41
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +0 -63
- /package/dist-skill/library/{forgecad-prepare-prompt → forgecad-spec-by-walking-through-it}/references/default-profiles.md +0 -0
- /package/dist-skill/library/{forgecad-prepare-prompt → forgecad-spec-by-walking-through-it}/references/master-prompt.md +0 -0
|
@@ -3268,20 +3268,20 @@ function flatKnotsToKnotsMults(flatKnots) {
|
|
|
3268
3268
|
return { knots, mults };
|
|
3269
3269
|
}
|
|
3270
3270
|
const KNOT_EPSILON = 1e-10;
|
|
3271
|
-
function sameKnot(a2, b) {
|
|
3271
|
+
function sameKnot$1(a2, b) {
|
|
3272
3272
|
return Math.abs(a2 - b) <= KNOT_EPSILON;
|
|
3273
3273
|
}
|
|
3274
|
-
function knotMultiplicity(knots, u2) {
|
|
3275
|
-
return knots.reduce((count, knot) => count + (sameKnot(knot, u2) ? 1 : 0), 0);
|
|
3274
|
+
function knotMultiplicity$1(knots, u2) {
|
|
3275
|
+
return knots.reduce((count, knot) => count + (sameKnot$1(knot, u2) ? 1 : 0), 0);
|
|
3276
3276
|
}
|
|
3277
3277
|
function firstKnotIndex(knots, u2) {
|
|
3278
|
-
const index2 = knots.findIndex((knot) => sameKnot(knot, u2));
|
|
3278
|
+
const index2 = knots.findIndex((knot) => sameKnot$1(knot, u2));
|
|
3279
3279
|
if (index2 < 0) throw new Error(`NURBS subdomain extraction could not find boundary knot ${u2}.`);
|
|
3280
3280
|
return index2;
|
|
3281
3281
|
}
|
|
3282
3282
|
function lastKnotIndex(knots, u2) {
|
|
3283
3283
|
for (let index2 = knots.length - 1; index2 >= 0; index2 -= 1) {
|
|
3284
|
-
if (sameKnot(knots[index2], u2)) return index2;
|
|
3284
|
+
if (sameKnot$1(knots[index2], u2)) return index2;
|
|
3285
3285
|
}
|
|
3286
3286
|
throw new Error(`NURBS subdomain extraction could not find boundary knot ${u2}.`);
|
|
3287
3287
|
}
|
|
@@ -3294,7 +3294,7 @@ function insertKnotOnceHomogeneous(points, knots, degree, u2) {
|
|
|
3294
3294
|
const lastPoint = count - 1;
|
|
3295
3295
|
const lastKnot = knots.length - 1;
|
|
3296
3296
|
const span = findSpan(count, degree, u2, knots);
|
|
3297
|
-
const multiplicity = knotMultiplicity(knots, u2);
|
|
3297
|
+
const multiplicity = knotMultiplicity$1(knots, u2);
|
|
3298
3298
|
if (multiplicity >= degree) {
|
|
3299
3299
|
throw new Error(`NURBS subdomain extraction cannot insert knot ${u2}: multiplicity ${multiplicity} already reaches degree ${degree}.`);
|
|
3300
3300
|
}
|
|
@@ -3318,7 +3318,7 @@ function insertKnotOnceHomogeneous(points, knots, degree, u2) {
|
|
|
3318
3318
|
function insertBoundaryToMultiplicity(points, knots, degree, u2, targetMultiplicity) {
|
|
3319
3319
|
let refinedPoints = points;
|
|
3320
3320
|
let refinedKnots = knots;
|
|
3321
|
-
while (knotMultiplicity(refinedKnots, u2) < targetMultiplicity) {
|
|
3321
|
+
while (knotMultiplicity$1(refinedKnots, u2) < targetMultiplicity) {
|
|
3322
3322
|
const refined = insertKnotOnceHomogeneous(refinedPoints, refinedKnots, degree, u2);
|
|
3323
3323
|
refinedPoints = refined.points;
|
|
3324
3324
|
refinedKnots = refined.knots;
|
|
@@ -3338,8 +3338,8 @@ function extractNurbsCurveSubdomain(controlPoints, weights, knots, degree, uStar
|
|
|
3338
3338
|
}
|
|
3339
3339
|
const activeStart = knots[degree];
|
|
3340
3340
|
const activeEnd = knots[controlPoints.length];
|
|
3341
|
-
const start = sameKnot(uStart, activeStart) ? activeStart : sameKnot(uStart, activeEnd) ? activeEnd : uStart;
|
|
3342
|
-
const end = sameKnot(uEnd, activeEnd) ? activeEnd : sameKnot(uEnd, activeStart) ? activeStart : uEnd;
|
|
3341
|
+
const start = sameKnot$1(uStart, activeStart) ? activeStart : sameKnot$1(uStart, activeEnd) ? activeEnd : uStart;
|
|
3342
|
+
const end = sameKnot$1(uEnd, activeEnd) ? activeEnd : sameKnot$1(uEnd, activeStart) ? activeStart : uEnd;
|
|
3343
3343
|
if (start < activeStart - KNOT_EPSILON || end > activeEnd + KNOT_EPSILON) {
|
|
3344
3344
|
throw new Error(`NURBS subdomain [${uStart}, ${uEnd}] must stay inside active knot domain [${activeStart}, ${activeEnd}].`);
|
|
3345
3345
|
}
|
|
@@ -10242,7 +10242,7 @@ async function initTruckGeometryWasm() {
|
|
|
10242
10242
|
if (_initPromise$2) return _initPromise$2;
|
|
10243
10243
|
_initPromise$2 = (async () => {
|
|
10244
10244
|
try {
|
|
10245
|
-
const geometryModule = await __vitePreload(() => import("./forgecad_geometry-
|
|
10245
|
+
const geometryModule = await __vitePreload(() => import("./forgecad_geometry-CZ_IfuvA.js"), true ? [] : void 0);
|
|
10246
10246
|
const isNode = isNodeRuntime();
|
|
10247
10247
|
if (isNode) {
|
|
10248
10248
|
const { readFileSync, existsSync } = await __vitePreload(async () => {
|
|
@@ -11170,23 +11170,62 @@ class NurbsSurface {
|
|
|
11170
11170
|
return [wx / wSum, wy / wSum, wz / wSum];
|
|
11171
11171
|
}
|
|
11172
11172
|
/**
|
|
11173
|
-
* Evaluate the surface normal at (u, v)
|
|
11173
|
+
* Evaluate the surface unit normal at (u, v) from analytic first derivatives.
|
|
11174
|
+
*
|
|
11175
|
+
* Uses Algorithm A2.3 basis-function derivatives with the rational quotient
|
|
11176
|
+
* rule, so the normal is exact (no finite-difference epsilon, no error near
|
|
11177
|
+
* the boundary). Constant chain-rule factors from the parameter remap scale Su
|
|
11178
|
+
* and Sv positively and cancel under normalization, so they are omitted.
|
|
11174
11179
|
*/
|
|
11175
11180
|
normalAt(u2, v) {
|
|
11176
|
-
const
|
|
11177
|
-
const
|
|
11178
|
-
const
|
|
11179
|
-
const
|
|
11180
|
-
const pv = this.pointAt(u2, v1), pmv = this.pointAt(u2, v0);
|
|
11181
|
-
const du = [pu[0] - pmu[0], pu[1] - pmu[1], pu[2] - pmu[2]];
|
|
11182
|
-
const dv = [pv[0] - pmv[0], pv[1] - pmv[1], pv[2] - pmv[2]];
|
|
11183
|
-
const nx = du[1] * dv[2] - du[2] * dv[1];
|
|
11184
|
-
const ny = du[2] * dv[0] - du[0] * dv[2];
|
|
11185
|
-
const nz = du[0] * dv[1] - du[1] * dv[0];
|
|
11181
|
+
const { Su, Sv } = this.derivativesAt(u2, v);
|
|
11182
|
+
const nx = Su[1] * Sv[2] - Su[2] * Sv[1];
|
|
11183
|
+
const ny = Su[2] * Sv[0] - Su[0] * Sv[2];
|
|
11184
|
+
const nz = Su[0] * Sv[1] - Su[1] * Sv[0];
|
|
11186
11185
|
const len2 = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
|
11187
11186
|
if (len2 < 1e-12) return [0, 0, 1];
|
|
11188
11187
|
return [nx / len2, ny / len2, nz / len2];
|
|
11189
11188
|
}
|
|
11189
|
+
/** Analytic first partial derivatives S_u, S_v (rational quotient rule). */
|
|
11190
|
+
derivativesAt(u2, v) {
|
|
11191
|
+
const uu = this.remapU(Math.max(0, Math.min(1, u2)));
|
|
11192
|
+
const vv = this.remapV(Math.max(0, Math.min(1, v)));
|
|
11193
|
+
const spanU = findSpan(this.nU, this.degreeU, uu, this.knotsU);
|
|
11194
|
+
const spanV = findSpan(this.nV, this.degreeV, vv, this.knotsV);
|
|
11195
|
+
const dU = basisFunsDeriv(spanU, uu, this.degreeU, this.knotsU, 1);
|
|
11196
|
+
const dV = basisFunsDeriv(spanV, vv, this.degreeV, this.knotsV, 1);
|
|
11197
|
+
const A = [0, 0, 0];
|
|
11198
|
+
const Au = [0, 0, 0];
|
|
11199
|
+
const Av = [0, 0, 0];
|
|
11200
|
+
let w2 = 0;
|
|
11201
|
+
let wu = 0;
|
|
11202
|
+
let wv = 0;
|
|
11203
|
+
for (let i = 0; i <= this.degreeU; i++) {
|
|
11204
|
+
const rowIdx = spanU - this.degreeU + i;
|
|
11205
|
+
for (let j = 0; j <= this.degreeV; j++) {
|
|
11206
|
+
const colIdx = spanV - this.degreeV + j;
|
|
11207
|
+
const weight = this.weightsGrid[rowIdx][colIdx];
|
|
11208
|
+
const pt = this.controlGrid[rowIdx][colIdx];
|
|
11209
|
+
const n00 = dU[0][i] * dV[0][j] * weight;
|
|
11210
|
+
const n10 = dU[1][i] * dV[0][j] * weight;
|
|
11211
|
+
const n01 = dU[0][i] * dV[1][j] * weight;
|
|
11212
|
+
w2 += n00;
|
|
11213
|
+
wu += n10;
|
|
11214
|
+
wv += n01;
|
|
11215
|
+
for (let c2 = 0; c2 < 3; c2++) {
|
|
11216
|
+
A[c2] += n00 * pt[c2];
|
|
11217
|
+
Au[c2] += n10 * pt[c2];
|
|
11218
|
+
Av[c2] += n01 * pt[c2];
|
|
11219
|
+
}
|
|
11220
|
+
}
|
|
11221
|
+
}
|
|
11222
|
+
if (w2 === 0) return { S: [0, 0, 0], Su: [0, 0, 0], Sv: [0, 0, 0] };
|
|
11223
|
+
const invW = 1 / w2;
|
|
11224
|
+
const S = [A[0] * invW, A[1] * invW, A[2] * invW];
|
|
11225
|
+
const Su = [(Au[0] - wu * S[0]) * invW, (Au[1] - wu * S[1]) * invW, (Au[2] - wu * S[2]) * invW];
|
|
11226
|
+
const Sv = [(Av[0] - wv * S[0]) * invW, (Av[1] - wv * S[1]) * invW, (Av[2] - wv * S[2]) * invW];
|
|
11227
|
+
return { S, Su, Sv };
|
|
11228
|
+
}
|
|
11190
11229
|
/**
|
|
11191
11230
|
* Tessellate the surface into a triangle mesh.
|
|
11192
11231
|
* Returns positions, normals, and triangle indices.
|
|
@@ -12557,7 +12596,7 @@ function maxQuadDeviation(rings, heights, colA, colB) {
|
|
|
12557
12596
|
const b = [rings[i][colB][0], rings[i][colB][1], heights[i]];
|
|
12558
12597
|
const c2 = [rings[i + 1][colB][0], rings[i + 1][colB][1], heights[i + 1]];
|
|
12559
12598
|
const d2 = [rings[i + 1][colA][0], rings[i + 1][colA][1], heights[i + 1]];
|
|
12560
|
-
const n = cross3$7(sub3$
|
|
12599
|
+
const n = cross3$7(sub3$7(b, a2), sub3$7(d2, a2));
|
|
12561
12600
|
const len2 = Math.hypot(n[0], n[1], n[2]);
|
|
12562
12601
|
if (len2 < 1e-12) continue;
|
|
12563
12602
|
const deviation = Math.abs((n[0] * (c2[0] - a2[0]) + n[1] * (c2[1] - a2[1]) + n[2] * (c2[2] - a2[2])) / len2);
|
|
@@ -12833,15 +12872,15 @@ function buildSpanRows(rings, heights) {
|
|
|
12833
12872
|
function stationTangent(stations, t, i, j) {
|
|
12834
12873
|
const R = stations.length;
|
|
12835
12874
|
if (i === 0) {
|
|
12836
|
-
return scale3$2(sub3$
|
|
12875
|
+
return scale3$2(sub3$7(stations[1][j], stations[0][j]), 1 / (t[1] - t[0]));
|
|
12837
12876
|
}
|
|
12838
12877
|
if (i === R - 1) {
|
|
12839
|
-
return scale3$2(sub3$
|
|
12878
|
+
return scale3$2(sub3$7(stations[R - 1][j], stations[R - 2][j]), 1 / (t[R - 1] - t[R - 2]));
|
|
12840
12879
|
}
|
|
12841
12880
|
const hPrev = t[i] - t[i - 1];
|
|
12842
12881
|
const hNext = t[i + 1] - t[i];
|
|
12843
|
-
const dPrev = scale3$2(sub3$
|
|
12844
|
-
const dNext = scale3$2(sub3$
|
|
12882
|
+
const dPrev = scale3$2(sub3$7(stations[i][j], stations[i - 1][j]), 1 / hPrev);
|
|
12883
|
+
const dNext = scale3$2(sub3$7(stations[i + 1][j], stations[i][j]), 1 / hNext);
|
|
12845
12884
|
return scale3$2(add3$2(scale3$2(dPrev, hNext), scale3$2(dNext, hPrev)), 1 / (hPrev + hNext));
|
|
12846
12885
|
}
|
|
12847
12886
|
function hermite(p0, m0, p1, m1, h, u2) {
|
|
@@ -12897,12 +12936,12 @@ function stitchSingleLoopLoft(loops, heights, wasm, options) {
|
|
|
12897
12936
|
const curr = points[j];
|
|
12898
12937
|
const next = points[(j + 1) % N];
|
|
12899
12938
|
if (cornerSet.has(j)) {
|
|
12900
|
-
const nFwd = surfaceNormal(sub3$
|
|
12901
|
-
const nBwd = surfaceNormal(sub3$
|
|
12939
|
+
const nFwd = surfaceNormal(sub3$7(next, curr), tangents[j]);
|
|
12940
|
+
const nBwd = surfaceNormal(sub3$7(curr, prev), tangents[j]);
|
|
12902
12941
|
fwd[j] = pushVert(curr, nFwd);
|
|
12903
12942
|
bwd[j] = pushVert(curr, nBwd);
|
|
12904
12943
|
} else {
|
|
12905
|
-
const idx = pushVert(curr, surfaceNormal(sub3$
|
|
12944
|
+
const idx = pushVert(curr, surfaceNormal(sub3$7(next, prev), tangents[j]));
|
|
12906
12945
|
fwd[j] = idx;
|
|
12907
12946
|
bwd[j] = idx;
|
|
12908
12947
|
}
|
|
@@ -12963,7 +13002,7 @@ function surfaceNormal(chord, span) {
|
|
|
12963
13002
|
}
|
|
12964
13003
|
return [n[0] / len2, n[1] / len2, n[2] / len2];
|
|
12965
13004
|
}
|
|
12966
|
-
function sub3$
|
|
13005
|
+
function sub3$7(a2, b) {
|
|
12967
13006
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
12968
13007
|
}
|
|
12969
13008
|
function add3$2(a2, b) {
|
|
@@ -12990,7 +13029,7 @@ async function initManifoldWasm() {
|
|
|
12990
13029
|
if (_wasm) return _wasm;
|
|
12991
13030
|
performance.mark("manifold:start");
|
|
12992
13031
|
const Module = (await __vitePreload(async () => {
|
|
12993
|
-
const { default: __vite_default__ } = await import("./manifold-
|
|
13032
|
+
const { default: __vite_default__ } = await import("./manifold-CBry38ly.js");
|
|
12994
13033
|
return { default: __vite_default__ };
|
|
12995
13034
|
}, true ? [] : void 0)).default;
|
|
12996
13035
|
performance.mark("manifold:imported");
|
|
@@ -13617,6 +13656,20 @@ function fromSlicesSingleSliceHalfExtentForManifold(plan) {
|
|
|
13617
13656
|
}
|
|
13618
13657
|
return Math.max(1, radius + maxOffsetMagnitude + plan.boundsPadding + plan.edgeLength * 3);
|
|
13619
13658
|
}
|
|
13659
|
+
const BOOLEAN_OPERAND_NORMAL_SHARP_ANGLE_DEG = 60;
|
|
13660
|
+
function promoteBooleanOperandNormals(shapes) {
|
|
13661
|
+
let maxExtra = 0;
|
|
13662
|
+
for (const shape of shapes) maxExtra = Math.max(maxExtra, shape.numProp());
|
|
13663
|
+
if (maxExtra < 3) return { operands: shapes, created: [] };
|
|
13664
|
+
const created = [];
|
|
13665
|
+
const operands = shapes.map((shape) => {
|
|
13666
|
+
if (shape.numProp() >= 3) return shape;
|
|
13667
|
+
const promoted = shape.calculateNormals(0, BOOLEAN_OPERAND_NORMAL_SHARP_ANGLE_DEG);
|
|
13668
|
+
created.push(promoted);
|
|
13669
|
+
return promoted;
|
|
13670
|
+
});
|
|
13671
|
+
return { operands, created };
|
|
13672
|
+
}
|
|
13620
13673
|
function lowerShapeBooleanCompilePlan(plan, wasm) {
|
|
13621
13674
|
const shapes = plan.shapes.map((shape) => lowerShapeCompilePlanToManifold(shape, wasm));
|
|
13622
13675
|
if (shapes.length === 0) {
|
|
@@ -13625,16 +13678,18 @@ function lowerShapeBooleanCompilePlan(plan, wasm) {
|
|
|
13625
13678
|
if (shapes.length === 1) {
|
|
13626
13679
|
return shapes[0];
|
|
13627
13680
|
}
|
|
13681
|
+
const { operands, created } = promoteBooleanOperandNormals(shapes);
|
|
13628
13682
|
try {
|
|
13629
13683
|
switch (plan.op) {
|
|
13630
13684
|
case "union":
|
|
13631
|
-
return wasm.Manifold.union(
|
|
13685
|
+
return wasm.Manifold.union(operands);
|
|
13632
13686
|
case "difference":
|
|
13633
|
-
return wasm.Manifold.difference(
|
|
13687
|
+
return wasm.Manifold.difference(operands);
|
|
13634
13688
|
case "intersection":
|
|
13635
|
-
return wasm.Manifold.intersection(
|
|
13689
|
+
return wasm.Manifold.intersection(operands);
|
|
13636
13690
|
}
|
|
13637
13691
|
} finally {
|
|
13692
|
+
disposeWasmObjects(created);
|
|
13638
13693
|
disposeWasmObjects(shapes);
|
|
13639
13694
|
}
|
|
13640
13695
|
}
|
|
@@ -14984,12 +15039,16 @@ function lowerNurbsSurfaceToManifold(plan, wasm) {
|
|
|
14984
15039
|
const { positions, normals, indices } = surface.tessellate(res, res);
|
|
14985
15040
|
const thickness = plan.thickness;
|
|
14986
15041
|
const numVerts = positions.length;
|
|
14987
|
-
const
|
|
14988
|
-
for (const [x2, y2, z2] of positions) allPositions.push(x2, y2, z2);
|
|
15042
|
+
const vertProps = [];
|
|
14989
15043
|
for (let i = 0; i < numVerts; i++) {
|
|
14990
15044
|
const [x2, y2, z2] = positions[i];
|
|
14991
15045
|
const [nx, ny, nz] = normals[i];
|
|
14992
|
-
|
|
15046
|
+
vertProps.push(x2, y2, z2, nx, ny, nz);
|
|
15047
|
+
}
|
|
15048
|
+
for (let i = 0; i < numVerts; i++) {
|
|
15049
|
+
const [x2, y2, z2] = positions[i];
|
|
15050
|
+
const [nx, ny, nz] = normals[i];
|
|
15051
|
+
vertProps.push(x2 - nx * thickness, y2 - ny * thickness, z2 - nz * thickness, -nx, -ny, -nz);
|
|
14993
15052
|
}
|
|
14994
15053
|
const allIndices = [];
|
|
14995
15054
|
for (const idx of indices) allIndices.push(idx);
|
|
@@ -15014,11 +15073,12 @@ function lowerNurbsSurfaceToManifold(plan, wasm) {
|
|
|
15014
15073
|
allIndices.push(c2, c2 + numVerts, d2, d2, c2 + numVerts, d2 + numVerts);
|
|
15015
15074
|
}
|
|
15016
15075
|
const mesh = new wasm.Mesh({
|
|
15017
|
-
numProp:
|
|
15018
|
-
vertProperties: new Float32Array(
|
|
15076
|
+
numProp: 6,
|
|
15077
|
+
vertProperties: new Float32Array(vertProps),
|
|
15019
15078
|
triVerts: new Uint32Array(allIndices)
|
|
15020
15079
|
});
|
|
15021
15080
|
try {
|
|
15081
|
+
mesh.merge();
|
|
15022
15082
|
return new wasm.Manifold(mesh);
|
|
15023
15083
|
} finally {
|
|
15024
15084
|
disposeWasmObject(mesh);
|
|
@@ -59626,7 +59686,7 @@ function uvInsideTrim(uv, trim) {
|
|
|
59626
59686
|
function add3$1(a2, b) {
|
|
59627
59687
|
return [a2[0] + b[0], a2[1] + b[1], a2[2] + b[2]];
|
|
59628
59688
|
}
|
|
59629
|
-
function sub3$
|
|
59689
|
+
function sub3$6(a2, b) {
|
|
59630
59690
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
59631
59691
|
}
|
|
59632
59692
|
function scale3$1(v, scale2) {
|
|
@@ -59672,7 +59732,7 @@ function resamplePolyline$1(points, count) {
|
|
|
59672
59732
|
if (points.length === 1 || count <= 1) return [points[0]];
|
|
59673
59733
|
const cumulative = [0];
|
|
59674
59734
|
for (let index2 = 1; index2 < points.length; index2 += 1) {
|
|
59675
|
-
cumulative.push(cumulative[index2 - 1] + Math.hypot(...sub3$
|
|
59735
|
+
cumulative.push(cumulative[index2 - 1] + Math.hypot(...sub3$6(points[index2], points[index2 - 1])));
|
|
59676
59736
|
}
|
|
59677
59737
|
const total = cumulative[cumulative.length - 1];
|
|
59678
59738
|
if (total <= 1e-12) return Array.from({ length: count }, () => points[0]);
|
|
@@ -59833,7 +59893,7 @@ function computeGridNormals(positions, indices) {
|
|
|
59833
59893
|
const a2 = positions[indices[index2]];
|
|
59834
59894
|
const b = positions[indices[index2 + 1]];
|
|
59835
59895
|
const c2 = positions[indices[index2 + 2]];
|
|
59836
|
-
const normal2 = cross3$5(sub3$
|
|
59896
|
+
const normal2 = cross3$5(sub3$6(b, a2), sub3$6(c2, a2));
|
|
59837
59897
|
for (const vertexIndex of [indices[index2], indices[index2 + 1], indices[index2 + 2]]) {
|
|
59838
59898
|
normals[vertexIndex][0] += normal2[0];
|
|
59839
59899
|
normals[vertexIndex][1] += normal2[1];
|
|
@@ -59926,16 +59986,16 @@ function planarProjectionFrame(points, context) {
|
|
|
59926
59986
|
const tolerance = pointTolerance(points) * 100;
|
|
59927
59987
|
const uSource = points.find((point2) => distance3$1(point2, origin) > tolerance);
|
|
59928
59988
|
if (!uSource) throw new Error(`${context} boundary loop collapsed to one point.`);
|
|
59929
|
-
const u2 = normalize3$4(sub3$
|
|
59989
|
+
const u2 = normalize3$4(sub3$6(uSource, origin), `${context} u axis`);
|
|
59930
59990
|
const v = cross3$5(normal2, u2);
|
|
59931
|
-
const maxPlaneError = points.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$
|
|
59991
|
+
const maxPlaneError = points.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$6(point2, origin), normal2))), 0);
|
|
59932
59992
|
if (maxPlaneError > tolerance) throw new Error(`${context} boundary loop must be planar for sampled SDF triangulation.`);
|
|
59933
59993
|
return { origin, u: u2, v, tolerance };
|
|
59934
59994
|
}
|
|
59935
59995
|
function meshFromPlanarBoundaryLoop(loop, context) {
|
|
59936
59996
|
const frame = planarProjectionFrame(loop, context);
|
|
59937
59997
|
const projected = loop.map((point2) => {
|
|
59938
|
-
const relative = sub3$
|
|
59998
|
+
const relative = sub3$6(point2, frame.origin);
|
|
59939
59999
|
return new Vector2(dot3$7(relative, frame.u), dot3$7(relative, frame.v));
|
|
59940
60000
|
});
|
|
59941
60001
|
const triangles = ShapeUtils.triangulateShape(projected, []);
|
|
@@ -59944,7 +60004,7 @@ function meshFromPlanarBoundaryLoop(loop, context) {
|
|
|
59944
60004
|
const indices = [];
|
|
59945
60005
|
for (const triangle of triangles) {
|
|
59946
60006
|
const [a2, b, c2] = triangle;
|
|
59947
|
-
const areaNormal = cross3$5(sub3$
|
|
60007
|
+
const areaNormal = cross3$5(sub3$6(positions[b], positions[a2]), sub3$6(positions[c2], positions[a2]));
|
|
59948
60008
|
if (Math.hypot(...areaNormal) > frame.tolerance * frame.tolerance) indices.push(a2, b, c2);
|
|
59949
60009
|
}
|
|
59950
60010
|
if (indices.length === 0) throw new Error(`${context} boundary loop collapsed to zero area.`);
|
|
@@ -68462,7 +68522,7 @@ function reconstructSdfBackendFromMesh(mesh) {
|
|
|
68462
68522
|
return wrapSdfMeshShapeBackend(boundsFromMeshBackend(runtimeMesh, edgeLength2), runtimeMesh);
|
|
68463
68523
|
}
|
|
68464
68524
|
const EPS$d = 1e-8;
|
|
68465
|
-
function sub3$
|
|
68525
|
+
function sub3$5(a2, b) {
|
|
68466
68526
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
68467
68527
|
}
|
|
68468
68528
|
function unit(v, context) {
|
|
@@ -68485,13 +68545,13 @@ function loopNormal(points) {
|
|
|
68485
68545
|
}
|
|
68486
68546
|
function firstEdgeDirection(points, filePath, context) {
|
|
68487
68547
|
for (let index2 = 0; index2 < points.length; index2 += 1) {
|
|
68488
|
-
const edge = sub3$
|
|
68548
|
+
const edge = sub3$5(points[(index2 + 1) % points.length], points[index2]);
|
|
68489
68549
|
if (Math.hypot(edge[0], edge[1], edge[2]) > EPS$d) return unit(edge, context);
|
|
68490
68550
|
}
|
|
68491
68551
|
failStepImport(filePath, `${context} face loop has no non-zero edges.`);
|
|
68492
68552
|
}
|
|
68493
68553
|
function project(point2, origin, u2, v) {
|
|
68494
|
-
const local = sub3$
|
|
68554
|
+
const local = sub3$5(point2, origin);
|
|
68495
68555
|
return new Vector2(dot3$7(local, u2), dot3$7(local, v));
|
|
68496
68556
|
}
|
|
68497
68557
|
function triangulateStepFace(face, filePath) {
|
|
@@ -68515,7 +68575,7 @@ function triangulateStepFace(face, filePath) {
|
|
|
68515
68575
|
const a2 = allPoints[ia];
|
|
68516
68576
|
const b = allPoints[ib];
|
|
68517
68577
|
const c2 = allPoints[ic];
|
|
68518
|
-
const triNormal = cross3$5(sub3$
|
|
68578
|
+
const triNormal = cross3$5(sub3$5(b, a2), sub3$5(c2, a2));
|
|
68519
68579
|
if (Math.hypot(triNormal[0], triNormal[1], triNormal[2]) <= EPS$d) {
|
|
68520
68580
|
failStepImport(filePath, `${face.context} triangulates to a degenerate triangle.`);
|
|
68521
68581
|
}
|
|
@@ -69557,7 +69617,7 @@ function angleDistance(a2, b) {
|
|
|
69557
69617
|
return Math.abs(normalizeAngleDelta(a2 - b));
|
|
69558
69618
|
}
|
|
69559
69619
|
function torusMajorAngle(frame, point2, context) {
|
|
69560
|
-
const local = sub3$
|
|
69620
|
+
const local = sub3$4(point2, frame.origin);
|
|
69561
69621
|
const x2 = dot3$7(local, frame.xAxis);
|
|
69562
69622
|
const y2 = dot3$7(local, frame.yAxis);
|
|
69563
69623
|
if (Math.hypot(x2, y2) <= 1e-12) throw new Error(`${context} torus major angle is degenerate.`);
|
|
@@ -69573,11 +69633,11 @@ function torusRadialDirection(frame, u2) {
|
|
|
69573
69633
|
function torusTubeAngle(frame, majorRadius, u2, point2) {
|
|
69574
69634
|
const radial = torusRadialDirection(frame, u2);
|
|
69575
69635
|
const tubeCenter = addScaled$2(frame.origin, radial, majorRadius);
|
|
69576
|
-
const local = sub3$
|
|
69636
|
+
const local = sub3$4(point2, tubeCenter);
|
|
69577
69637
|
return Math.atan2(dot3$7(local, frame.axis), dot3$7(local, radial));
|
|
69578
69638
|
}
|
|
69579
69639
|
function rotateAroundAxis(point2, axis, angle) {
|
|
69580
|
-
const local = sub3$
|
|
69640
|
+
const local = sub3$4(point2, axis.origin);
|
|
69581
69641
|
const cos2 = Math.cos(angle);
|
|
69582
69642
|
const sin2 = Math.sin(angle);
|
|
69583
69643
|
const cross4 = cross3$5(axis.axis, local);
|
|
@@ -69589,12 +69649,12 @@ function rotateAroundAxis(point2, axis, angle) {
|
|
|
69589
69649
|
];
|
|
69590
69650
|
}
|
|
69591
69651
|
function distanceFromAxis(point2, axis) {
|
|
69592
|
-
const local = sub3$
|
|
69652
|
+
const local = sub3$4(point2, axis.origin);
|
|
69593
69653
|
const axial = dot3$7(local, axis.axis);
|
|
69594
69654
|
return Math.hypot(local[0] - axis.axis[0] * axial, local[1] - axis.axis[1] * axial, local[2] - axis.axis[2] * axial);
|
|
69595
69655
|
}
|
|
69596
69656
|
function radialFromAxis(frame, point2, context) {
|
|
69597
|
-
const local = sub3$
|
|
69657
|
+
const local = sub3$4(point2, frame.origin);
|
|
69598
69658
|
const axial = dot3$7(local, frame.axis);
|
|
69599
69659
|
const radialVector = [local[0] - frame.axis[0] * axial, local[1] - frame.axis[1] * axial, local[2] - frame.axis[2] * axial];
|
|
69600
69660
|
return { axial, radial: Math.hypot(radialVector[0], radialVector[1], radialVector[2]), direction: normalize3$4(radialVector, context) };
|
|
@@ -69663,9 +69723,9 @@ function triangulateBoundedLinearSurfaceOfRevolution(records, curveId, axis, loo
|
|
|
69663
69723
|
return triangulateBoundedLineCurveSurfaceOfRevolution(line2, axis, loop, sameSense, filePath, context);
|
|
69664
69724
|
}
|
|
69665
69725
|
function triangulateBoundedLineCurveSurfaceOfRevolution(line2, axis, loop, sameSense, filePath, context) {
|
|
69666
|
-
const startAxial = dot3$7(sub3$
|
|
69726
|
+
const startAxial = dot3$7(sub3$4(line2.point, axis.origin), axis.axis);
|
|
69667
69727
|
const end = linePoint(line2, 1);
|
|
69668
|
-
const endAxial = dot3$7(sub3$
|
|
69728
|
+
const endAxial = dot3$7(sub3$4(end, axis.origin), axis.axis);
|
|
69669
69729
|
const axialSpan = endAxial - startAxial;
|
|
69670
69730
|
if (Math.abs(axialSpan) <= 1e-8)
|
|
69671
69731
|
failStepImport(filePath, `${context} bounded SURFACE_OF_REVOLUTION LINE profile must change along the revolution axis.`);
|
|
@@ -69694,7 +69754,7 @@ function trimmedLineCurveForSurfaceOfRevolution(records, curve, filePath, contex
|
|
|
69694
69754
|
const sameSense = stepBoolean(curve.args[4], `TRIMMED_CURVE #${curve.id} sense agreement`);
|
|
69695
69755
|
const point2 = sameSense ? start : end;
|
|
69696
69756
|
const target = sameSense ? end : start;
|
|
69697
|
-
const delta = sub3$
|
|
69757
|
+
const delta = sub3$4(target, point2);
|
|
69698
69758
|
const magnitude = Math.hypot(delta[0], delta[1], delta[2]);
|
|
69699
69759
|
if (magnitude <= 1e-10) failStepImport(filePath, `${context} TRIMMED_CURVE LINE profile has zero length.`);
|
|
69700
69760
|
return {
|
|
@@ -69705,10 +69765,10 @@ function trimmedLineCurveForSurfaceOfRevolution(records, curve, filePath, contex
|
|
|
69705
69765
|
}
|
|
69706
69766
|
function revolvedCircleTorus(records, curveId, axis, filePath, context) {
|
|
69707
69767
|
const circle2 = resolveCircle(records, curveId, filePath);
|
|
69708
|
-
const centerOffset = sub3$
|
|
69768
|
+
const centerOffset = sub3$4(circle2.frame.origin, axis.origin);
|
|
69709
69769
|
const axial = dot3$7(centerOffset, axis.axis);
|
|
69710
69770
|
const axisPoint = addScaled$2(axis.origin, axis.axis, axial);
|
|
69711
|
-
const radial = sub3$
|
|
69771
|
+
const radial = sub3$4(circle2.frame.origin, axisPoint);
|
|
69712
69772
|
const majorRadius = Math.hypot(radial[0], radial[1], radial[2]);
|
|
69713
69773
|
if (majorRadius <= 1e-8) failStepImport(filePath, `${context} SURFACE_OF_REVOLUTION circle profile is centered on the axis.`);
|
|
69714
69774
|
if (majorRadius <= circle2.radius)
|
|
@@ -69720,7 +69780,7 @@ function revolvedCircleTorus(records, curveId, axis, filePath, context) {
|
|
|
69720
69780
|
return { frame, majorRadius, minorRadius: circle2.radius };
|
|
69721
69781
|
}
|
|
69722
69782
|
function revolutionAngle(frame, point2, filePath, context) {
|
|
69723
|
-
const local = sub3$
|
|
69783
|
+
const local = sub3$4(point2, frame.origin);
|
|
69724
69784
|
const x2 = dot3$7(local, frame.xAxis);
|
|
69725
69785
|
const y2 = dot3$7(local, frame.yAxis);
|
|
69726
69786
|
if (Math.hypot(x2, y2) <= 1e-12) failStepImport(filePath, `${context} major angle is degenerate.`);
|
|
@@ -69762,10 +69822,10 @@ function orientRevolvedProfileTriangles(triangles, frame, axis, profileCenter, p
|
|
|
69762
69822
|
];
|
|
69763
69823
|
const angle = revolutionAngle(frame, sample, filePath, "SURFACE_OF_REVOLUTION");
|
|
69764
69824
|
const center = rotateAroundAxis(profileCenter, axis, normalizeAngleDelta(angle - profileAngle));
|
|
69765
|
-
const outward = sub3$
|
|
69825
|
+
const outward = sub3$4(sample, center);
|
|
69766
69826
|
if (Math.hypot(outward[0], outward[1], outward[2]) <= 1e-12)
|
|
69767
69827
|
failStepImport(filePath, "SURFACE_OF_REVOLUTION sample hit degenerate profile centerline.");
|
|
69768
|
-
const normal2 = cross3$5(sub3$
|
|
69828
|
+
const normal2 = cross3$5(sub3$4(triangle[1], triangle[0]), sub3$4(triangle[2], triangle[0]));
|
|
69769
69829
|
const outwardFacing = dot3$7(normal2, outward) >= 0;
|
|
69770
69830
|
return sameSense === outwardFacing ? triangle : reverseTriangle(triangle);
|
|
69771
69831
|
});
|
|
@@ -69849,7 +69909,7 @@ function triangulateBoundedToroidalTubeSegment(frame, majorRadius, minorRadius,
|
|
|
69849
69909
|
const loop = compactLoops[loopIndex];
|
|
69850
69910
|
const majorAngle = majorAngles[loopIndex];
|
|
69851
69911
|
for (const point2 of loop) {
|
|
69852
|
-
const local = sub3$
|
|
69912
|
+
const local = sub3$4(point2, frame.origin);
|
|
69853
69913
|
const x2 = dot3$7(local, frame.xAxis);
|
|
69854
69914
|
const y2 = dot3$7(local, frame.yAxis);
|
|
69855
69915
|
const radialLength = Math.hypot(x2, y2);
|
|
@@ -70384,7 +70444,7 @@ function triangulateClosedVBSplineSurfaceBand(surface, loops, sameSense, filePat
|
|
|
70384
70444
|
}
|
|
70385
70445
|
return orientBridgeTriangles(triangles, centroid(a2.points), centroid(b.points), sameSense);
|
|
70386
70446
|
}
|
|
70387
|
-
function sub3$
|
|
70447
|
+
function sub3$4(a2, b) {
|
|
70388
70448
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
70389
70449
|
}
|
|
70390
70450
|
function newellNormal(points) {
|
|
@@ -70423,9 +70483,9 @@ function triangulateBoundedSphericalCap(frame, radius, loop, sameSense, filePath
|
|
|
70423
70483
|
}
|
|
70424
70484
|
const boundaryCenter = centroid(boundary);
|
|
70425
70485
|
const capDirection = normalize3$4(newellNormal(boundary), `${context} bounded SPHERICAL_SURFACE boundary normal`);
|
|
70426
|
-
const maxPlaneError = boundary.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$
|
|
70486
|
+
const maxPlaneError = boundary.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$4(point2, boundaryCenter), capDirection))), 0);
|
|
70427
70487
|
if (maxPlaneError > tolerance) failStepImport(filePath, `${context} bounded SPHERICAL_SURFACE boundary loop is not planar.`);
|
|
70428
|
-
const boundaryDirections = boundary.map((point2) => normalize3$4(sub3$
|
|
70488
|
+
const boundaryDirections = boundary.map((point2) => normalize3$4(sub3$4(point2, frame.origin), `${context} bounded SPHERICAL_SURFACE point`));
|
|
70429
70489
|
const maxAngle = boundaryDirections.reduce((max2, direction2) => Math.max(max2, Math.acos(clamp$8(dot3$7(direction2, capDirection), -1, 1))), 0);
|
|
70430
70490
|
if (Math.PI - maxAngle <= 1e-6) failStepImport(filePath, `${context} bounded SPHERICAL_SURFACE cap is degenerate.`);
|
|
70431
70491
|
const radialSegments = Math.max(4, Math.ceil(maxAngle / (Math.PI / 24)));
|
|
@@ -70464,17 +70524,17 @@ function sphericalLoopInfo(frame, radius, loop, filePath, context) {
|
|
|
70464
70524
|
}
|
|
70465
70525
|
const center = centroid(points);
|
|
70466
70526
|
const normal2 = normalize3$4(newellNormal(points), `${context} bounded SPHERICAL_SURFACE boundary normal`);
|
|
70467
|
-
const maxPlaneError = points.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$
|
|
70527
|
+
const maxPlaneError = points.reduce((max2, point2) => Math.max(max2, Math.abs(dot3$7(sub3$4(point2, center), normal2))), 0);
|
|
70468
70528
|
if (maxPlaneError > tolerance) failStepImport(filePath, `${context} bounded SPHERICAL_SURFACE boundary loop is not planar.`);
|
|
70469
70529
|
return { points, center, normal: normal2 };
|
|
70470
70530
|
}
|
|
70471
70531
|
function triangulateBoundedSphericalBand(frame, radius, loops, sameSense, filePath, context) {
|
|
70472
70532
|
if (loops.length !== 2) failStepImport(filePath, `${context} bounded SPHERICAL_SURFACE band supports exactly two loops right now.`);
|
|
70473
70533
|
const [aInfo, bInfo] = loops.map((loop) => sphericalLoopInfo(frame, radius, loop, filePath, context));
|
|
70474
|
-
const axis = normalize3$4(sub3$
|
|
70534
|
+
const axis = normalize3$4(sub3$4(bInfo.center, aInfo.center), `${context} bounded SPHERICAL_SURFACE band axis`);
|
|
70475
70535
|
const tolerance = Math.max(1e-5, radius * 1e-4);
|
|
70476
70536
|
const axisPointError = (point2) => {
|
|
70477
|
-
const local = sub3$
|
|
70537
|
+
const local = sub3$4(point2, frame.origin);
|
|
70478
70538
|
const projected = addScaled$2(frame.origin, axis, dot3$7(local, axis));
|
|
70479
70539
|
return Math.hypot(point2[0] - projected[0], point2[1] - projected[1], point2[2] - projected[2]);
|
|
70480
70540
|
};
|
|
@@ -70483,12 +70543,12 @@ function triangulateBoundedSphericalBand(frame, radius, loops, sameSense, filePa
|
|
|
70483
70543
|
const count = Math.max(aInfo.points.length, bInfo.points.length, 8);
|
|
70484
70544
|
const aLoop = resampleClosedLoop(aInfo.points, count);
|
|
70485
70545
|
let bLoop = resampleClosedLoop(bInfo.points, count);
|
|
70486
|
-
const rawX = sub3$
|
|
70546
|
+
const rawX = sub3$4(aLoop[0], aInfo.center);
|
|
70487
70547
|
const xProjection = dot3$7(rawX, axis);
|
|
70488
70548
|
const xAxis = normalize3$4([rawX[0] - axis[0] * xProjection, rawX[1] - axis[1] * xProjection, rawX[2] - axis[2] * xProjection], context);
|
|
70489
70549
|
const yAxis = cross3$5(axis, xAxis);
|
|
70490
70550
|
const loopAngle = (point2, center) => {
|
|
70491
|
-
const local = sub3$
|
|
70551
|
+
const local = sub3$4(point2, center);
|
|
70492
70552
|
return Math.atan2(dot3$7(local, yAxis), dot3$7(local, xAxis));
|
|
70493
70553
|
};
|
|
70494
70554
|
const rotateLoop = (loop, center, targetAngle) => {
|
|
@@ -70509,8 +70569,8 @@ function triangulateBoundedSphericalBand(frame, radius, loops, sameSense, filePa
|
|
|
70509
70569
|
const reversed = rotateLoop([...bLoop].reverse(), bInfo.center, aAngles[0]);
|
|
70510
70570
|
bLoop = sequenceMismatch(forward) <= sequenceMismatch(reversed) ? forward : reversed;
|
|
70511
70571
|
const angularSpan = aLoop.reduce((max2, point2, index2) => {
|
|
70512
|
-
const aDirection = normalize3$4(sub3$
|
|
70513
|
-
const bDirection = normalize3$4(sub3$
|
|
70572
|
+
const aDirection = normalize3$4(sub3$4(point2, frame.origin), `${context} bounded SPHERICAL_SURFACE band point`);
|
|
70573
|
+
const bDirection = normalize3$4(sub3$4(bLoop[index2], frame.origin), `${context} bounded SPHERICAL_SURFACE band point`);
|
|
70514
70574
|
return Math.max(max2, Math.acos(clamp$8(dot3$7(aDirection, bDirection), -1, 1)));
|
|
70515
70575
|
}, 0);
|
|
70516
70576
|
if (angularSpan <= 1e-6) failStepImport(filePath, `${context} bounded SPHERICAL_SURFACE band has zero angular span.`);
|
|
@@ -70520,8 +70580,8 @@ function triangulateBoundedSphericalBand(frame, radius, loops, sameSense, filePa
|
|
|
70520
70580
|
const t = ringIndex / radialSegments;
|
|
70521
70581
|
rings.push(
|
|
70522
70582
|
aLoop.map((point2, index2) => {
|
|
70523
|
-
const aDirection = normalize3$4(sub3$
|
|
70524
|
-
const bDirection = normalize3$4(sub3$
|
|
70583
|
+
const aDirection = normalize3$4(sub3$4(point2, frame.origin), `${context} bounded SPHERICAL_SURFACE band point`);
|
|
70584
|
+
const bDirection = normalize3$4(sub3$4(bLoop[index2], frame.origin), `${context} bounded SPHERICAL_SURFACE band point`);
|
|
70525
70585
|
return addScaled$2(frame.origin, slerpUnit(aDirection, bDirection, t), radius);
|
|
70526
70586
|
})
|
|
70527
70587
|
);
|
|
@@ -72570,14 +72630,14 @@ function cross$7(a2, b) {
|
|
|
72570
72630
|
function isFiniteNumber$1(value) {
|
|
72571
72631
|
return typeof value === "number" && Number.isFinite(value);
|
|
72572
72632
|
}
|
|
72573
|
-
function isVec3$
|
|
72633
|
+
function isVec3$3(value) {
|
|
72574
72634
|
return Array.isArray(value) && value.length === 3 && value.every(isFiniteNumber$1);
|
|
72575
72635
|
}
|
|
72576
72636
|
function isVec2(value) {
|
|
72577
72637
|
return Array.isArray(value) && value.length === 2 && value.every(isFiniteNumber$1);
|
|
72578
72638
|
}
|
|
72579
72639
|
function isRuledRails(value) {
|
|
72580
|
-
return Array.isArray(value) && value.length === 2 && value.every((rail2) => Array.isArray(rail2) && rail2.length === 2 && rail2.every(isVec3$
|
|
72640
|
+
return Array.isArray(value) && value.length === 2 && value.every((rail2) => Array.isArray(rail2) && rail2.length === 2 && rail2.every(isVec3$3));
|
|
72581
72641
|
}
|
|
72582
72642
|
function axisSpan(face, axis) {
|
|
72583
72643
|
if (face.vertices.length === 0) return 0;
|
|
@@ -72594,14 +72654,14 @@ function isRationalWeights(weights) {
|
|
|
72594
72654
|
return Boolean(weights == null ? void 0 : weights.some((row) => row.some((weight) => Math.abs(weight - 1) > 1e-9)));
|
|
72595
72655
|
}
|
|
72596
72656
|
function explicitGeometrySurface(geometry, face) {
|
|
72597
|
-
if ("Plane" in geometry && isVec3$
|
|
72657
|
+
if ("Plane" in geometry && isVec3$3(geometry.Plane.normal)) {
|
|
72598
72658
|
return { kind: "plane", normal: normalizeVec3$3(geometry.Plane.normal) };
|
|
72599
72659
|
}
|
|
72600
72660
|
if ("AnalyticCylinder" in geometry) {
|
|
72601
72661
|
const origin = geometry.AnalyticCylinder.axis_origin;
|
|
72602
72662
|
const axis = geometry.AnalyticCylinder.axis_direction;
|
|
72603
72663
|
const radius = geometry.AnalyticCylinder.radius;
|
|
72604
|
-
if (isVec3$
|
|
72664
|
+
if (isVec3$3(origin) && isVec3$3(axis) && isFiniteNumber$1(radius) && radius > 0) {
|
|
72605
72665
|
const normalizedAxis = normalizeVec3$3(axis);
|
|
72606
72666
|
return { kind: "cylinder", origin, axis: normalizedAxis, radius, height: axisSpan(face, normalizedAxis) };
|
|
72607
72667
|
}
|
|
@@ -72611,7 +72671,7 @@ function explicitGeometrySurface(geometry, face) {
|
|
|
72611
72671
|
const axis = geometry.AnalyticCone.axis_direction;
|
|
72612
72672
|
const radiusBottom = geometry.AnalyticCone.radius_start;
|
|
72613
72673
|
const radiusTop = geometry.AnalyticCone.radius_end;
|
|
72614
|
-
if (isVec3$
|
|
72674
|
+
if (isVec3$3(origin) && isVec3$3(axis) && isFiniteNumber$1(radiusBottom) && isFiniteNumber$1(radiusTop)) {
|
|
72615
72675
|
const normalizedAxis = normalizeVec3$3(axis);
|
|
72616
72676
|
return {
|
|
72617
72677
|
kind: "cone",
|
|
@@ -72626,7 +72686,7 @@ function explicitGeometrySurface(geometry, face) {
|
|
|
72626
72686
|
if ("AnalyticSphere" in geometry) {
|
|
72627
72687
|
const center = geometry.AnalyticSphere.center;
|
|
72628
72688
|
const radius = geometry.AnalyticSphere.radius;
|
|
72629
|
-
if (isVec3$
|
|
72689
|
+
if (isVec3$3(center) && isFiniteNumber$1(radius) && radius > 0) {
|
|
72630
72690
|
return { kind: "sphere", center, radius };
|
|
72631
72691
|
}
|
|
72632
72692
|
}
|
|
@@ -72635,7 +72695,7 @@ function explicitGeometrySurface(geometry, face) {
|
|
|
72635
72695
|
const axis = geometry.AnalyticTorus.axis;
|
|
72636
72696
|
const majorRadius = geometry.AnalyticTorus.major_radius;
|
|
72637
72697
|
const minorRadius = geometry.AnalyticTorus.minor_radius;
|
|
72638
|
-
if (isVec3$
|
|
72698
|
+
if (isVec3$3(center) && isVec3$3(axis) && isFiniteNumber$1(majorRadius) && isFiniteNumber$1(minorRadius) && majorRadius > 0 && minorRadius > 0) {
|
|
72639
72699
|
return { kind: "torus", center, axis: normalizeVec3$3(axis), majorRadius, minorRadius };
|
|
72640
72700
|
}
|
|
72641
72701
|
}
|
|
@@ -72733,7 +72793,7 @@ function explicitEdgeCurve(geometry, faceName) {
|
|
|
72733
72793
|
const center = (_a3 = geometry.CircularArc) == null ? void 0 : _a3.center;
|
|
72734
72794
|
const axis = (_b3 = geometry.CircularArc) == null ? void 0 : _b3.axis;
|
|
72735
72795
|
const radius = (_c2 = geometry.CircularArc) == null ? void 0 : _c2.radius;
|
|
72736
|
-
if (center !== void 0 && axis !== void 0 && radius !== void 0 && isVec3$
|
|
72796
|
+
if (center !== void 0 && axis !== void 0 && radius !== void 0 && isVec3$3(center) && isVec3$3(axis) && isFiniteNumber$1(radius) && radius > 0) {
|
|
72737
72797
|
return {
|
|
72738
72798
|
kind: "circle",
|
|
72739
72799
|
center,
|
|
@@ -72744,7 +72804,7 @@ function explicitEdgeCurve(geometry, faceName) {
|
|
|
72744
72804
|
}
|
|
72745
72805
|
const start = (_d2 = geometry.Line) == null ? void 0 : _d2.start;
|
|
72746
72806
|
const end = (_e2 = geometry.Line) == null ? void 0 : _e2.end;
|
|
72747
|
-
if (isVec3$
|
|
72807
|
+
if (isVec3$3(start) && isVec3$3(end)) return makeLineEdgeCurve(start, end, faceName);
|
|
72748
72808
|
const polyline = geometry.PolylineUv;
|
|
72749
72809
|
if (polyline && Array.isArray(polyline.points)) {
|
|
72750
72810
|
const points = polyline.points.filter(isVec2);
|
|
@@ -73089,7 +73149,7 @@ function topologyPayloadToTopology(payload) {
|
|
|
73089
73149
|
if (explicitEdge.visual === false) continue;
|
|
73090
73150
|
const start = explicitVertices[explicitEdge.vertices[0]];
|
|
73091
73151
|
const end = explicitVertices[explicitEdge.vertices[1]];
|
|
73092
|
-
if (!isVec3$
|
|
73152
|
+
if (!isVec3$3(start) || !isVec3$3(end)) continue;
|
|
73093
73153
|
const key2 = edgeKey(start, end);
|
|
73094
73154
|
if (seenEdges.has(key2)) continue;
|
|
73095
73155
|
seenEdges.set(key2, edges.size);
|
|
@@ -73253,6 +73313,7 @@ const _TruckShapeBackend = class _TruckShapeBackend {
|
|
|
73253
73313
|
const payload = JSON.parse(getTruckGeometryWasm().geometry_mesh(this.getLiveHandle("getMesh()")));
|
|
73254
73314
|
const numTri = payload.triangles.length / 3;
|
|
73255
73315
|
const numVert = payload.positions.length / 3;
|
|
73316
|
+
const cornerNormals = payload.normals && payload.normals.length === numTri * 9 ? new Float32Array(payload.normals) : void 0;
|
|
73256
73317
|
this.resource.mesh = {
|
|
73257
73318
|
numProp: 3,
|
|
73258
73319
|
numTri,
|
|
@@ -73266,7 +73327,8 @@ const _TruckShapeBackend = class _TruckShapeBackend {
|
|
|
73266
73327
|
runTransform: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]),
|
|
73267
73328
|
faceID: new Int32Array(payload.face_ids),
|
|
73268
73329
|
faceIdNames: payload.face_id_names ?? [],
|
|
73269
|
-
halfedgeTangent: new Float32Array(0)
|
|
73330
|
+
halfedgeTangent: new Float32Array(0),
|
|
73331
|
+
cornerNormals
|
|
73270
73332
|
};
|
|
73271
73333
|
return this.resource.mesh;
|
|
73272
73334
|
}
|
|
@@ -74487,6 +74549,16 @@ function boundsInteriorOverlap(a2, b) {
|
|
|
74487
74549
|
const tolerance = 1e-8;
|
|
74488
74550
|
return Math.min(a2.max[0], b.max[0]) - Math.max(a2.min[0], b.min[0]) > tolerance && Math.min(a2.max[1], b.max[1]) - Math.max(a2.min[1], b.min[1]) > tolerance && Math.min(a2.max[2], b.max[2]) - Math.max(a2.min[2], b.min[2]) > tolerance;
|
|
74489
74551
|
}
|
|
74552
|
+
function boundsFaceOrInteriorOverlap(a2, b) {
|
|
74553
|
+
const tolerance = 1e-8;
|
|
74554
|
+
const overlaps = [
|
|
74555
|
+
Math.min(a2.max[0], b.max[0]) - Math.max(a2.min[0], b.min[0]),
|
|
74556
|
+
Math.min(a2.max[1], b.max[1]) - Math.max(a2.min[1], b.min[1]),
|
|
74557
|
+
Math.min(a2.max[2], b.max[2]) - Math.max(a2.min[2], b.min[2])
|
|
74558
|
+
];
|
|
74559
|
+
if (overlaps.some((overlap) => overlap < -tolerance)) return false;
|
|
74560
|
+
return overlaps.filter((overlap) => overlap <= tolerance).length <= 1;
|
|
74561
|
+
}
|
|
74490
74562
|
function boundsFromPoints(points) {
|
|
74491
74563
|
const first = points[0];
|
|
74492
74564
|
if (!first) return null;
|
|
@@ -74569,16 +74641,16 @@ function shapePlanBounds(plan) {
|
|
|
74569
74641
|
return null;
|
|
74570
74642
|
}
|
|
74571
74643
|
}
|
|
74572
|
-
function
|
|
74644
|
+
function hasPairwiseFaceOrInteriorBoundsOverlap(shapes) {
|
|
74573
74645
|
const bounds = shapes.map((shape) => shape.boundingBox());
|
|
74574
74646
|
for (let i = 0; i < bounds.length; i++) {
|
|
74575
74647
|
for (let j = i + 1; j < bounds.length; j++) {
|
|
74576
|
-
if (
|
|
74648
|
+
if (boundsFaceOrInteriorOverlap(bounds[i], bounds[j])) return true;
|
|
74577
74649
|
}
|
|
74578
74650
|
}
|
|
74579
74651
|
return false;
|
|
74580
74652
|
}
|
|
74581
|
-
function
|
|
74653
|
+
function faceOrInteriorOverlapComponents(shapes) {
|
|
74582
74654
|
const bounds = shapes.map((shape) => shape.boundingBox());
|
|
74583
74655
|
const visited = /* @__PURE__ */ new Set();
|
|
74584
74656
|
const components = [];
|
|
@@ -74592,7 +74664,7 @@ function interiorOverlapComponents(shapes) {
|
|
|
74592
74664
|
component.push(current);
|
|
74593
74665
|
for (let next = 0; next < shapes.length; next++) {
|
|
74594
74666
|
if (visited.has(next)) continue;
|
|
74595
|
-
if (
|
|
74667
|
+
if (boundsFaceOrInteriorOverlap(bounds[current], bounds[next])) {
|
|
74596
74668
|
visited.add(next);
|
|
74597
74669
|
queue.push(next);
|
|
74598
74670
|
}
|
|
@@ -74637,10 +74709,10 @@ function lowerGenericBooleanPlan(plan) {
|
|
|
74637
74709
|
let returned = null;
|
|
74638
74710
|
try {
|
|
74639
74711
|
if (plan.op === "union") {
|
|
74640
|
-
if (!
|
|
74712
|
+
if (!hasPairwiseFaceOrInteriorBoundsOverlap(shapes)) {
|
|
74641
74713
|
return null;
|
|
74642
74714
|
}
|
|
74643
|
-
const components =
|
|
74715
|
+
const components = faceOrInteriorOverlapComponents(shapes);
|
|
74644
74716
|
if (components.length > 1) {
|
|
74645
74717
|
returned = lowerClusteredUnion(shapes, components);
|
|
74646
74718
|
return returned;
|
|
@@ -75170,9 +75242,13 @@ function shapeHasClosedNativeTopology(shape) {
|
|
|
75170
75242
|
function normalizeTruckShapeForBooleanInput(shape) {
|
|
75171
75243
|
if (shapeHasClosedNativeTopology(shape)) return shape;
|
|
75172
75244
|
if (!meshHasRawBoundaryEdges(shape.getMesh())) return shape;
|
|
75173
|
-
|
|
75174
|
-
|
|
75175
|
-
|
|
75245
|
+
try {
|
|
75246
|
+
const normalized = normalizeFacetedTruckShape(shape);
|
|
75247
|
+
disposeShapeBackend(shape);
|
|
75248
|
+
return normalized;
|
|
75249
|
+
} catch {
|
|
75250
|
+
return shape;
|
|
75251
|
+
}
|
|
75176
75252
|
}
|
|
75177
75253
|
function lowerSdfPlan(plan) {
|
|
75178
75254
|
if (getUnsupportedSdfProgramReason(plan.tree) === void 0) {
|
|
@@ -77056,7 +77132,7 @@ function circleProfilePlan(radius, segments) {
|
|
|
77056
77132
|
}
|
|
77057
77133
|
function annulusProfilePlan(outerRadius, innerRadius, segments) {
|
|
77058
77134
|
const outer = Math.abs(outerRadius);
|
|
77059
|
-
const inner = Math.
|
|
77135
|
+
const inner = Math.max(0, innerRadius);
|
|
77060
77136
|
if (outer <= EXACT_PROFILE_EPS) return emptyProfilePlan();
|
|
77061
77137
|
if (inner <= EXACT_PROFILE_EPS) return circleProfilePlan(outer, segments);
|
|
77062
77138
|
return {
|
|
@@ -82015,11 +82091,11 @@ function requireFiniteVec3$3(v, label) {
|
|
|
82015
82091
|
}
|
|
82016
82092
|
return [x2, y2, z2];
|
|
82017
82093
|
}
|
|
82018
|
-
function len3$
|
|
82094
|
+
function len3$3(v) {
|
|
82019
82095
|
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
82020
82096
|
}
|
|
82021
82097
|
function normalize3$3(v) {
|
|
82022
|
-
const l = len3$
|
|
82098
|
+
const l = len3$3(v);
|
|
82023
82099
|
if (l < 1e-10) throw new Error("Cannot normalize zero-length vector");
|
|
82024
82100
|
return [v[0] / l, v[1] / l, v[2] / l];
|
|
82025
82101
|
}
|
|
@@ -82029,7 +82105,7 @@ function dot3$5(a2, b) {
|
|
|
82029
82105
|
function cross3$2(a2, b) {
|
|
82030
82106
|
return [a2[1] * b[2] - a2[2] * b[1], a2[2] * b[0] - a2[0] * b[2], a2[0] * b[1] - a2[1] * b[0]];
|
|
82031
82107
|
}
|
|
82032
|
-
function sub3$
|
|
82108
|
+
function sub3$3(a2, b) {
|
|
82033
82109
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
82034
82110
|
}
|
|
82035
82111
|
function negate3$1(v) {
|
|
@@ -82052,7 +82128,7 @@ function normalizePortInput(input) {
|
|
|
82052
82128
|
const end = requireFiniteVec3$3(input.end, "port end");
|
|
82053
82129
|
origin = [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2, (start[2] + end[2]) / 2];
|
|
82054
82130
|
const dir = [end[0] - start[0], end[1] - start[1], end[2] - start[2]];
|
|
82055
|
-
const dirLen = len3$
|
|
82131
|
+
const dirLen = len3$3(dir);
|
|
82056
82132
|
if (dirLen < 1e-10) {
|
|
82057
82133
|
throw new Error("Port start and end must not be the same point");
|
|
82058
82134
|
}
|
|
@@ -82063,7 +82139,7 @@ function normalizePortInput(input) {
|
|
|
82063
82139
|
} else if (hasOriginAxis) {
|
|
82064
82140
|
origin = requireFiniteVec3$3(input.origin, "port origin");
|
|
82065
82141
|
const rawAxis = requireFiniteVec3$3(input.axis, "port axis");
|
|
82066
|
-
if (len3$
|
|
82142
|
+
if (len3$3(rawAxis) < 1e-10) {
|
|
82067
82143
|
throw new Error("Port axis must be non-zero");
|
|
82068
82144
|
}
|
|
82069
82145
|
axis = normalize3$3(rawAxis);
|
|
@@ -82079,12 +82155,12 @@ function normalizePortInput(input) {
|
|
|
82079
82155
|
let up;
|
|
82080
82156
|
if (input.up != null) {
|
|
82081
82157
|
const rawUp = requireFiniteVec3$3(input.up, "port up");
|
|
82082
|
-
if (len3$
|
|
82158
|
+
if (len3$3(rawUp) < 1e-10) {
|
|
82083
82159
|
throw new Error("Port up vector must be non-zero");
|
|
82084
82160
|
}
|
|
82085
82161
|
const proj = dot3$5(rawUp, axis);
|
|
82086
82162
|
const ortho = [rawUp[0] - proj * axis[0], rawUp[1] - proj * axis[1], rawUp[2] - proj * axis[2]];
|
|
82087
|
-
if (len3$
|
|
82163
|
+
if (len3$3(ortho) < 1e-10) {
|
|
82088
82164
|
throw new Error("Port up vector must not be parallel to axis");
|
|
82089
82165
|
}
|
|
82090
82166
|
up = normalize3$3(ortho);
|
|
@@ -82148,8 +82224,8 @@ function transformPort(port, matrix) {
|
|
|
82148
82224
|
const newOrigin = tx.point(port.origin);
|
|
82149
82225
|
const rawAxis = tx.vector(port.axis);
|
|
82150
82226
|
const rawUp = tx.vector(port.up);
|
|
82151
|
-
const axisLen = len3$
|
|
82152
|
-
const upLen = len3$
|
|
82227
|
+
const axisLen = len3$3(rawAxis);
|
|
82228
|
+
const upLen = len3$3(rawUp);
|
|
82153
82229
|
const out = {
|
|
82154
82230
|
origin: newOrigin,
|
|
82155
82231
|
axis: axisLen > 1e-10 ? normalize3$3(rawAxis) : port.axis,
|
|
@@ -82201,7 +82277,7 @@ function computeConnectFrame(childBase, childPort, parentPort, _flip, childAlign
|
|
|
82201
82277
|
r10 * cI[0] + r11 * cI[1] + r12 * cI[2],
|
|
82202
82278
|
r20 * cI[0] + r21 * cI[1] + r22 * cI[2]
|
|
82203
82279
|
];
|
|
82204
|
-
const t = sub3$
|
|
82280
|
+
const t = sub3$3(pOrigin, rcI);
|
|
82205
82281
|
const frame = Transform.from([r00, r10, r20, 0, r01, r11, r21, 0, r02, r12, r22, 0, t[0], t[1], t[2], 1]);
|
|
82206
82282
|
const axis = cAxis;
|
|
82207
82283
|
return { frame, axis };
|
|
@@ -82286,18 +82362,18 @@ function validateConnectorMatch(selfName, selfPort, targetName, targetPort, forc
|
|
|
82286
82362
|
}
|
|
82287
82363
|
}
|
|
82288
82364
|
}
|
|
82289
|
-
function len3$
|
|
82365
|
+
function len3$2(v) {
|
|
82290
82366
|
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
82291
82367
|
}
|
|
82292
82368
|
function normalize3$2(v) {
|
|
82293
|
-
const l = len3$
|
|
82369
|
+
const l = len3$2(v);
|
|
82294
82370
|
if (l < 1e-10) throw new Error("Cannot normalize zero-length vector");
|
|
82295
82371
|
return [v[0] / l, v[1] / l, v[2] / l];
|
|
82296
82372
|
}
|
|
82297
82373
|
function cross3$1(a2, b) {
|
|
82298
82374
|
return [a2[1] * b[2] - a2[2] * b[1], a2[2] * b[0] - a2[0] * b[2], a2[0] * b[1] - a2[1] * b[0]];
|
|
82299
82375
|
}
|
|
82300
|
-
function sub3$
|
|
82376
|
+
function sub3$2(a2, b) {
|
|
82301
82377
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
82302
82378
|
}
|
|
82303
82379
|
function negate3(v) {
|
|
@@ -82320,7 +82396,7 @@ function alignmentMatrix(childOrigin, childAxis, childUp, parentOrigin, parentAx
|
|
|
82320
82396
|
r10 * childOrigin[0] + r11 * childOrigin[1] + r12 * childOrigin[2],
|
|
82321
82397
|
r20 * childOrigin[0] + r21 * childOrigin[1] + r22 * childOrigin[2]
|
|
82322
82398
|
];
|
|
82323
|
-
const t = sub3$
|
|
82399
|
+
const t = sub3$2(parentOrigin, rc);
|
|
82324
82400
|
return Transform.from([r00, r10, r20, 0, r01, r11, r21, 0, r02, r12, r22, 0, t[0], t[1], t[2], 1]);
|
|
82325
82401
|
}
|
|
82326
82402
|
function computeSinglePairAlignment(childPort, targetPort) {
|
|
@@ -82359,8 +82435,8 @@ function computeMultiPairAlignment(pairs, childPorts, targetPorts, tolerance = 0
|
|
|
82359
82435
|
[0, 0, 0]
|
|
82360
82436
|
];
|
|
82361
82437
|
for (const p2 of pairs) {
|
|
82362
|
-
const s = sub3$
|
|
82363
|
-
const t2 = sub3$
|
|
82438
|
+
const s = sub3$2(p2.childOrigin, srcCentroid);
|
|
82439
|
+
const t2 = sub3$2(p2.targetOrigin, tgtCentroid);
|
|
82364
82440
|
for (let i = 0; i < 3; i++) {
|
|
82365
82441
|
for (let j = 0; j < 3; j++) {
|
|
82366
82442
|
h[i][j] += s[i] * t2[j];
|
|
@@ -82373,7 +82449,7 @@ function computeMultiPairAlignment(pairs, childPorts, targetPorts, tolerance = 0
|
|
|
82373
82449
|
R[1][0] * srcCentroid[0] + R[1][1] * srcCentroid[1] + R[1][2] * srcCentroid[2],
|
|
82374
82450
|
R[2][0] * srcCentroid[0] + R[2][1] * srcCentroid[1] + R[2][2] * srcCentroid[2]
|
|
82375
82451
|
];
|
|
82376
|
-
const t = sub3$
|
|
82452
|
+
const t = sub3$2(tgtCentroid, rSrc);
|
|
82377
82453
|
const transform = Transform.from([
|
|
82378
82454
|
R[0][0],
|
|
82379
82455
|
R[1][0],
|
|
@@ -82395,8 +82471,8 @@ function computeMultiPairAlignment(pairs, childPorts, targetPorts, tolerance = 0
|
|
|
82395
82471
|
const residuals = [];
|
|
82396
82472
|
for (const p2 of pairs) {
|
|
82397
82473
|
const transformed = transform.point(p2.childOrigin);
|
|
82398
|
-
const diff = sub3$
|
|
82399
|
-
residuals.push(len3$
|
|
82474
|
+
const diff = sub3$2(transformed, p2.targetOrigin);
|
|
82475
|
+
residuals.push(len3$2(diff));
|
|
82400
82476
|
}
|
|
82401
82477
|
const maxResidual = Math.max(...residuals);
|
|
82402
82478
|
if (maxResidual > tolerance) {
|
|
@@ -82596,8 +82672,8 @@ function getConnectorDistance(ports, nameA, nameB) {
|
|
|
82596
82672
|
const b = ports[nameB];
|
|
82597
82673
|
if (!a2) throw new Error(`connectorDistance: unknown connector "${nameA}"`);
|
|
82598
82674
|
if (!b) throw new Error(`connectorDistance: unknown connector "${nameB}"`);
|
|
82599
|
-
const d2 = sub3$
|
|
82600
|
-
return len3$
|
|
82675
|
+
const d2 = sub3$2(a2.origin, b.origin);
|
|
82676
|
+
return len3$2(d2);
|
|
82601
82677
|
}
|
|
82602
82678
|
function getConnectorMeasurements(ports, name) {
|
|
82603
82679
|
const p2 = ports[name];
|
|
@@ -87839,8 +87915,7 @@ function sculptLook(preset = "gallery") {
|
|
|
87839
87915
|
{ type: "directional", position: [90, -110, 150], color: "#ffffff", intensity: 1.4 },
|
|
87840
87916
|
{ type: "directional", position: [-120, 70, 80], color: "#dcecff", intensity: 0.65 },
|
|
87841
87917
|
{ type: "hemisphere", skyColor: "#d9edff", groundColor: "#f0e6d4", intensity: 0.45 }
|
|
87842
|
-
]
|
|
87843
|
-
postProcessing: { toneMappingExposure: 1.12, vignette: { darkness: 0.16, offset: 0.6 } }
|
|
87918
|
+
]
|
|
87844
87919
|
};
|
|
87845
87920
|
case "candy-shop":
|
|
87846
87921
|
return {
|
|
@@ -87851,8 +87926,7 @@ function sculptLook(preset = "gallery") {
|
|
|
87851
87926
|
{ type: "point", position: [70, -60, 90], color: "#ff8ac8", intensity: 2.2, distance: 280, decay: 1.2 },
|
|
87852
87927
|
{ type: "point", position: [-85, 80, 70], color: "#70e1ff", intensity: 1.8, distance: 260, decay: 1.4 },
|
|
87853
87928
|
{ type: "directional", position: [30, -80, 140], color: "#fff6dd", intensity: 0.9 }
|
|
87854
|
-
]
|
|
87855
|
-
postProcessing: { toneMappingExposure: 1.25, bloom: { intensity: 0.35, threshold: 0.78, radius: 0.45 } }
|
|
87929
|
+
]
|
|
87856
87930
|
};
|
|
87857
87931
|
case "midnight":
|
|
87858
87932
|
return {
|
|
@@ -87864,8 +87938,7 @@ function sculptLook(preset = "gallery") {
|
|
|
87864
87938
|
{ type: "point", position: [-90, 70, 50], color: "#ff7ac8", intensity: 1.4, distance: 300, decay: 1.3 },
|
|
87865
87939
|
{ type: "directional", position: [30, -30, 160], color: "#d7e9ff", intensity: 0.65 }
|
|
87866
87940
|
],
|
|
87867
|
-
fog: { color: "#060814", near: 180, far: 520 }
|
|
87868
|
-
postProcessing: { toneMappingExposure: 1.35, bloom: { intensity: 0.65, threshold: 0.65, radius: 0.6 } }
|
|
87941
|
+
fog: { color: "#060814", near: 180, far: 520 }
|
|
87869
87942
|
};
|
|
87870
87943
|
case "workbench":
|
|
87871
87944
|
return {
|
|
@@ -87876,8 +87949,7 @@ function sculptLook(preset = "gallery") {
|
|
|
87876
87949
|
{ type: "directional", position: [80, -100, 130], color: "#fff5df", intensity: 1.25 },
|
|
87877
87950
|
{ type: "hemisphere", skyColor: "#eef6ff", groundColor: "#d8d0c0", intensity: 0.35 }
|
|
87878
87951
|
],
|
|
87879
|
-
ground: { visible: true, color: "#d8d4ca", offset: 1, receiveShadow: true }
|
|
87880
|
-
postProcessing: { toneMappingExposure: 1.05 }
|
|
87952
|
+
ground: { visible: true, color: "#d8d4ca", offset: 1, receiveShadow: true }
|
|
87881
87953
|
};
|
|
87882
87954
|
default:
|
|
87883
87955
|
return {
|
|
@@ -87888,8 +87960,7 @@ function sculptLook(preset = "gallery") {
|
|
|
87888
87960
|
{ type: "directional", position: [110, -130, 150], color: "#ffffff", intensity: 1.5 },
|
|
87889
87961
|
{ type: "directional", position: [-90, 80, 90], color: "#b8d8ff", intensity: 0.55 },
|
|
87890
87962
|
{ type: "hemisphere", skyColor: "#ddefff", groundColor: "#e8e2d8", intensity: 0.45 }
|
|
87891
|
-
]
|
|
87892
|
-
postProcessing: { toneMappingExposure: 1.18, vignette: { darkness: 0.18, offset: 0.55 } }
|
|
87963
|
+
]
|
|
87893
87964
|
};
|
|
87894
87965
|
}
|
|
87895
87966
|
}
|
|
@@ -89700,7 +89771,7 @@ class Shape2 {
|
|
|
89700
89771
|
*
|
|
89701
89772
|
* Use `.color()` to set the base diffuse color; `.material()` controls how that color behaves
|
|
89702
89773
|
* under light (metalness, roughness, clearcoat) and can add emissive glow independent of
|
|
89703
|
-
* lighting.
|
|
89774
|
+
* lighting.
|
|
89704
89775
|
*
|
|
89705
89776
|
* **Example**
|
|
89706
89777
|
*
|
|
@@ -92096,14 +92167,14 @@ function dot3$3(a2, b) {
|
|
|
92096
92167
|
function cross3(a2, b) {
|
|
92097
92168
|
return [a2[1] * b[2] - a2[2] * b[1], a2[2] * b[0] - a2[0] * b[2], a2[0] * b[1] - a2[1] * b[0]];
|
|
92098
92169
|
}
|
|
92099
|
-
function sub3(a2, b) {
|
|
92170
|
+
function sub3$1(a2, b) {
|
|
92100
92171
|
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
92101
92172
|
}
|
|
92102
|
-
function len3(v) {
|
|
92173
|
+
function len3$1(v) {
|
|
92103
92174
|
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
92104
92175
|
}
|
|
92105
92176
|
function normalize3$1(v) {
|
|
92106
|
-
const l = len3(v);
|
|
92177
|
+
const l = len3$1(v);
|
|
92107
92178
|
if (l < EPS$9) return [0, 0, 0];
|
|
92108
92179
|
return [v[0] / l, v[1] / l, v[2] / l];
|
|
92109
92180
|
}
|
|
@@ -92115,7 +92186,7 @@ const alignDef = {
|
|
|
92115
92186
|
const faceB = ctx.worldFace(constraint.refB.bodyId, constraint.refB.featureName);
|
|
92116
92187
|
const n1 = faceA.normal;
|
|
92117
92188
|
const n2 = faceB.normal;
|
|
92118
|
-
const delta = sub3(faceB.center, faceA.center);
|
|
92189
|
+
const delta = sub3$1(faceB.center, faceA.center);
|
|
92119
92190
|
const parallel = dot3$3(n1, n2) - 1;
|
|
92120
92191
|
const normalDist = dot3$3(delta, n1);
|
|
92121
92192
|
const cx = n1[1] * n2[2] - n1[2] * n2[1];
|
|
@@ -92158,7 +92229,7 @@ const concentricDef = {
|
|
|
92158
92229
|
const axisA = ctx.worldAxis(constraint.refA.bodyId, constraint.refA.featureName);
|
|
92159
92230
|
const axisB = ctx.worldAxis(constraint.refB.bodyId, constraint.refB.featureName);
|
|
92160
92231
|
const dirCross = cross3(axisA.direction, axisB.direction);
|
|
92161
|
-
const delta = sub3(axisB.origin, axisA.origin);
|
|
92232
|
+
const delta = sub3$1(axisB.origin, axisA.origin);
|
|
92162
92233
|
const offsetCross = cross3(delta, axisA.direction);
|
|
92163
92234
|
const pickTwo = (v) => {
|
|
92164
92235
|
const ax = Math.abs(v[0]);
|
|
@@ -92182,9 +92253,9 @@ const faceDistanceDef = {
|
|
|
92182
92253
|
const distance2 = constraint.value ?? 0;
|
|
92183
92254
|
const n1 = faceA.normal;
|
|
92184
92255
|
const n2 = faceB.normal;
|
|
92185
|
-
const delta = sub3(faceB.center, faceA.center);
|
|
92256
|
+
const delta = sub3$1(faceB.center, faceA.center);
|
|
92186
92257
|
const antiParallel = dot3$3(n1, n2) + 1;
|
|
92187
|
-
const crossMag = len3(cross3(n1, n2));
|
|
92258
|
+
const crossMag = len3$1(cross3(n1, n2));
|
|
92188
92259
|
const signedDist = dot3$3(delta, n1) - distance2;
|
|
92189
92260
|
return [antiParallel, crossMag, signedDist];
|
|
92190
92261
|
}
|
|
@@ -92204,7 +92275,7 @@ const flushDef = {
|
|
|
92204
92275
|
const faceB = ctx.worldFace(constraint.refB.bodyId, constraint.refB.featureName);
|
|
92205
92276
|
const n1 = faceA.normal;
|
|
92206
92277
|
const n2 = faceB.normal;
|
|
92207
|
-
const delta = sub3(faceB.center, faceA.center);
|
|
92278
|
+
const delta = sub3$1(faceB.center, faceA.center);
|
|
92208
92279
|
const antiParallel = dot3$3(n1, n2) + 1;
|
|
92209
92280
|
const normalDist = dot3$3(delta, n1);
|
|
92210
92281
|
const cx = n1[1] * n2[2] - n1[2] * n2[1];
|
|
@@ -92244,7 +92315,7 @@ const pointOnAxisDef = {
|
|
|
92244
92315
|
residual(constraint, ctx) {
|
|
92245
92316
|
const point2 = ctx.worldPoint(constraint.refA.bodyId, constraint.refA.featureName);
|
|
92246
92317
|
const axis = ctx.worldAxis(constraint.refB.bodyId, constraint.refB.featureName);
|
|
92247
|
-
const delta = sub3(point2, axis.origin);
|
|
92318
|
+
const delta = sub3$1(point2, axis.origin);
|
|
92248
92319
|
const c2 = cross3(delta, axis.direction);
|
|
92249
92320
|
const ax = Math.abs(c2[0]);
|
|
92250
92321
|
const ay = Math.abs(c2[1]);
|
|
@@ -92260,7 +92331,7 @@ const pointOnFaceDef = {
|
|
|
92260
92331
|
residual(constraint, ctx) {
|
|
92261
92332
|
const point2 = ctx.worldPoint(constraint.refA.bodyId, constraint.refA.featureName);
|
|
92262
92333
|
const face = ctx.worldFace(constraint.refB.bodyId, constraint.refB.featureName);
|
|
92263
|
-
const delta = sub3(point2, face.center);
|
|
92334
|
+
const delta = sub3$1(point2, face.center);
|
|
92264
92335
|
return [dot3$3(delta, face.normal)];
|
|
92265
92336
|
}
|
|
92266
92337
|
};
|
|
@@ -92809,7 +92880,7 @@ function runWithForgeValidationPolicy(policy, fn) {
|
|
|
92809
92880
|
}
|
|
92810
92881
|
let _collected$8 = null;
|
|
92811
92882
|
const isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
92812
|
-
const isVec3$
|
|
92883
|
+
const isVec3$2 = (value) => Array.isArray(value) && value.length === 3 && isFiniteNumber(value[0]) && isFiniteNumber(value[1]) && isFiniteNumber(value[2]);
|
|
92813
92884
|
const normalizeAxis = (axis) => {
|
|
92814
92885
|
const len2 = Math.hypot(axis[0], axis[1], axis[2]);
|
|
92815
92886
|
if (len2 <= 1e-8) throw new Error("jointsView joint axis must be non-zero");
|
|
@@ -92844,10 +92915,10 @@ const normalizeJoint = (joint2) => {
|
|
|
92844
92915
|
throw new Error(`jointsView joint "${name}" type must be "revolute" or "prismatic"`);
|
|
92845
92916
|
}
|
|
92846
92917
|
const axisRaw = joint2.axis ?? [0, 0, 1];
|
|
92847
|
-
if (!isVec3$
|
|
92918
|
+
if (!isVec3$2(axisRaw)) throw new Error(`jointsView joint "${name}" axis must be [x, y, z]`);
|
|
92848
92919
|
const axis = normalizeAxis([axisRaw[0], axisRaw[1], axisRaw[2]]);
|
|
92849
92920
|
const pivotRaw = joint2.pivot ?? [0, 0, 0];
|
|
92850
|
-
if (!isVec3$
|
|
92921
|
+
if (!isVec3$2(pivotRaw)) throw new Error(`jointsView joint "${name}" pivot must be [x, y, z]`);
|
|
92851
92922
|
const pivot = [pivotRaw[0], pivotRaw[1], pivotRaw[2]];
|
|
92852
92923
|
if (joint2.min !== void 0 && !isFiniteNumber(joint2.min)) {
|
|
92853
92924
|
throw new Error(`jointsView joint "${name}" min must be a finite number`);
|
|
@@ -93097,8 +93168,8 @@ const clampJointValue$1 = (joint2, value) => {
|
|
|
93097
93168
|
};
|
|
93098
93169
|
function resolveJointViewValues(joints, couplings = [], baseValues = {}, options = {}) {
|
|
93099
93170
|
const shouldClamp = options.clamp ?? false;
|
|
93100
|
-
const
|
|
93101
|
-
joints.forEach((joint2) =>
|
|
93171
|
+
const jointByName = /* @__PURE__ */ new Map();
|
|
93172
|
+
joints.forEach((joint2) => jointByName.set(joint2.name, joint2));
|
|
93102
93173
|
const couplingByJoint = /* @__PURE__ */ new Map();
|
|
93103
93174
|
couplings.forEach((coupling) => couplingByJoint.set(coupling.joint, coupling));
|
|
93104
93175
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -93106,7 +93177,7 @@ function resolveJointViewValues(joints, couplings = [], baseValues = {}, options
|
|
|
93106
93177
|
const resolveValue = (jointName) => {
|
|
93107
93178
|
const cached = cache.get(jointName);
|
|
93108
93179
|
if (cached !== void 0) return cached;
|
|
93109
|
-
const joint2 =
|
|
93180
|
+
const joint2 = jointByName.get(jointName);
|
|
93110
93181
|
if (!joint2) return 0;
|
|
93111
93182
|
if (resolving.has(jointName)) {
|
|
93112
93183
|
const cycleFallback = baseValues[jointName] ?? joint2.defaultValue;
|
|
@@ -93809,7 +93880,7 @@ function deriveExplodeHintsFromMates(constraints, result, bodies, ctx) {
|
|
|
93809
93880
|
const posA = result.transforms.get(c2.refA.bodyId);
|
|
93810
93881
|
const posB = result.transforms.get(c2.refB.bodyId);
|
|
93811
93882
|
if (posA && posB) {
|
|
93812
|
-
const raw = sub3(bodyA.grounded ? posB.position : posA.position, bodyA.grounded ? posA.position : posB.position);
|
|
93883
|
+
const raw = sub3$1(bodyA.grounded ? posB.position : posA.position, bodyA.grounded ? posA.position : posB.position);
|
|
93813
93884
|
dir = normalize3$1(raw);
|
|
93814
93885
|
}
|
|
93815
93886
|
break;
|
|
@@ -94335,8 +94406,8 @@ class Assembly {
|
|
|
94335
94406
|
*
|
|
94336
94407
|
* Use this after adding physical parts and joints. Robot-body profiles require
|
|
94337
94408
|
* `rootPart`; asset profiles can describe one-part or multi-part physical assets.
|
|
94338
|
-
* URDF/SDF exporters and `forgecad check simready` read this
|
|
94339
|
-
*
|
|
94409
|
+
* URDF/SDF/MJCF/USD exporters and `forgecad check simready` read this
|
|
94410
|
+
* contract directly from the returned assembly.
|
|
94340
94411
|
*
|
|
94341
94412
|
* @category Assembly
|
|
94342
94413
|
*/
|
|
@@ -103450,7 +103521,7 @@ function beltDrive(options) {
|
|
|
103450
103521
|
}
|
|
103451
103522
|
const GEAR_META_KEY = Symbol.for("forgecad.library.gearMeta");
|
|
103452
103523
|
const EPSILON$1 = 1e-9;
|
|
103453
|
-
function clamp01$
|
|
103524
|
+
function clamp01$4(value) {
|
|
103454
103525
|
return Math.max(-1, Math.min(1, value));
|
|
103455
103526
|
}
|
|
103456
103527
|
function isFinitePositive(value) {
|
|
@@ -103470,7 +103541,7 @@ function addArcPoints(target, radius, startAngle, endAngle, steps, includeStart
|
|
|
103470
103541
|
}
|
|
103471
103542
|
}
|
|
103472
103543
|
function flankAngleAtRadius(radius, baseRadius, halfThicknessAtPitch, pressureAngleRad) {
|
|
103473
|
-
const alphaAtRadius = Math.acos(clamp01$
|
|
103544
|
+
const alphaAtRadius = Math.acos(clamp01$4(baseRadius / Math.max(radius, baseRadius)));
|
|
103474
103545
|
return halfThicknessAtPitch + involuteFn(pressureAngleRad) - involuteFn(alphaAtRadius);
|
|
103475
103546
|
}
|
|
103476
103547
|
function addRootFilletPoints(target, rootRadius, filletRadius, flankAngle, sign2, fromFlank, steps) {
|
|
@@ -104590,7 +104661,7 @@ function gearPair(options) {
|
|
|
104590
104661
|
message: `Center distance ${centerDistance.toFixed(4)} exceeds addendum reach ${addendumReach.toFixed(4)} (no mesh contact)`
|
|
104591
104662
|
});
|
|
104592
104663
|
}
|
|
104593
|
-
const cosWorking = clamp01$
|
|
104664
|
+
const cosWorking = clamp01$4(baseSum / Math.max(centerDistance, EPSILON$1));
|
|
104594
104665
|
const alphaWorking = Math.acos(cosWorking);
|
|
104595
104666
|
const basePitch = Math.PI * module * Math.cos(alpha);
|
|
104596
104667
|
const pathLength = Math.sqrt(Math.max(0, pinion.meta.outerRadius ** 2 - pinion.meta.baseRadius ** 2)) + Math.sqrt(Math.max(0, gear.meta.outerRadius ** 2 - gear.meta.baseRadius ** 2)) - centerDistance * Math.sin(alphaWorking);
|
|
@@ -105503,7 +105574,8 @@ class FrozenShape extends Shape2 {
|
|
|
105503
105574
|
const EDGE_THRESHOLD_DOT = Math.cos(Math.PI / 180);
|
|
105504
105575
|
const SMOOTH_THRESHOLD_DOT = Math.cos(30 * Math.PI / 180);
|
|
105505
105576
|
function computeGeometryArrays(mesh, options = {}) {
|
|
105506
|
-
const { numProp, numTri: triCount, triVerts, vertProperties, vertNormals } = mesh;
|
|
105577
|
+
const { numProp, numTri: triCount, triVerts, vertProperties, vertNormals, cornerNormals } = mesh;
|
|
105578
|
+
const useCornerNormals = !!cornerNormals && cornerNormals.length === triCount * 9;
|
|
105507
105579
|
const positions = new Float32Array(triCount * 9);
|
|
105508
105580
|
const normals = new Float32Array(triCount * 9);
|
|
105509
105581
|
const faceNx = new Float32Array(triCount);
|
|
@@ -105535,7 +105607,9 @@ function computeGeometryArrays(mesh, options = {}) {
|
|
|
105535
105607
|
positions[o + 6] = cx;
|
|
105536
105608
|
positions[o + 7] = cy;
|
|
105537
105609
|
positions[o + 8] = cz;
|
|
105538
|
-
if (
|
|
105610
|
+
if (useCornerNormals) {
|
|
105611
|
+
for (let k2 = 0; k2 < 9; k2++) normals[o + k2] = cornerNormals[o + k2];
|
|
105612
|
+
} else if (vertNormals) {
|
|
105539
105613
|
normals[o] = vertNormals[i0 * 3];
|
|
105540
105614
|
normals[o + 1] = vertNormals[i0 * 3 + 1];
|
|
105541
105615
|
normals[o + 2] = vertNormals[i0 * 3 + 2];
|
|
@@ -105578,7 +105652,7 @@ function computeGeometryArrays(mesh, options = {}) {
|
|
|
105578
105652
|
faceNy[t] = fny;
|
|
105579
105653
|
faceNz[t] = fnz;
|
|
105580
105654
|
}
|
|
105581
|
-
if (!vertNormals && numProp < 6 && triCount > 0) {
|
|
105655
|
+
if (!useCornerNormals && !vertNormals && numProp < 6 && triCount > 0) {
|
|
105582
105656
|
computeAutoSmoothNormals(
|
|
105583
105657
|
triVerts,
|
|
105584
105658
|
vertProperties,
|
|
@@ -105776,7 +105850,8 @@ function shapeToGeometryFallback(shape) {
|
|
|
105776
105850
|
vertProperties: mesh.vertProperties,
|
|
105777
105851
|
mergeFromVert: mesh.mergeFromVert,
|
|
105778
105852
|
mergeToVert: mesh.mergeToVert,
|
|
105779
|
-
vertNormals
|
|
105853
|
+
vertNormals,
|
|
105854
|
+
cornerNormals: mesh.cornerNormals && mesh.cornerNormals.length === mesh.numTri * 9 ? mesh.cornerNormals : void 0
|
|
105780
105855
|
});
|
|
105781
105856
|
const solid = new BufferGeometry();
|
|
105782
105857
|
solid.setAttribute("position", new BufferAttribute(positions, 3));
|
|
@@ -105806,26 +105881,26 @@ function getPendingShapeHighlights() {
|
|
|
105806
105881
|
function resetPendingShapeHighlights() {
|
|
105807
105882
|
pendingShapeHighlights = [];
|
|
105808
105883
|
}
|
|
105809
|
-
function isVec3(v) {
|
|
105884
|
+
function isVec3$1(v) {
|
|
105810
105885
|
return Array.isArray(v) && v.length === 3 && typeof v[0] === "number" && typeof v[1] === "number" && typeof v[2] === "number";
|
|
105811
105886
|
}
|
|
105812
105887
|
function isEdgePair(v) {
|
|
105813
|
-
return Array.isArray(v) && v.length === 2 && isVec3(v[0]) && isVec3(v[1]);
|
|
105888
|
+
return Array.isArray(v) && v.length === 2 && isVec3$1(v[0]) && isVec3$1(v[1]);
|
|
105814
105889
|
}
|
|
105815
105890
|
function isPlaneSpec(v) {
|
|
105816
105891
|
if (typeof v !== "object" || v === null) return false;
|
|
105817
105892
|
const obj = v;
|
|
105818
|
-
return isVec3(obj.normal) && (typeof obj.offset === "number" || isVec3(obj.point));
|
|
105893
|
+
return isVec3$1(obj.normal) && (typeof obj.offset === "number" || isVec3$1(obj.point));
|
|
105819
105894
|
}
|
|
105820
105895
|
function isFaceRef$1(v) {
|
|
105821
105896
|
if (typeof v !== "object" || v === null) return false;
|
|
105822
105897
|
const obj = v;
|
|
105823
|
-
return isVec3(obj.normal) && isVec3(obj.center) && typeof obj.name === "string";
|
|
105898
|
+
return isVec3$1(obj.normal) && isVec3$1(obj.center) && typeof obj.name === "string";
|
|
105824
105899
|
}
|
|
105825
105900
|
function isEdgeRef(v) {
|
|
105826
105901
|
if (typeof v !== "object" || v === null) return false;
|
|
105827
105902
|
const obj = v;
|
|
105828
|
-
return isVec3(obj.start) && isVec3(obj.end) && typeof obj.name === "string";
|
|
105903
|
+
return isVec3$1(obj.start) && isVec3$1(obj.end) && typeof obj.name === "string";
|
|
105829
105904
|
}
|
|
105830
105905
|
function requireFiniteVec3(v, name) {
|
|
105831
105906
|
for (let i = 0; i < 3; i++) {
|
|
@@ -105864,7 +105939,7 @@ function highlight(target, opts) {
|
|
|
105864
105939
|
});
|
|
105865
105940
|
return;
|
|
105866
105941
|
}
|
|
105867
|
-
if (isVec3(target)) {
|
|
105942
|
+
if (isVec3$1(target)) {
|
|
105868
105943
|
requireFiniteVec3(target, "point");
|
|
105869
105944
|
collectedDebugHighlights3D.push({
|
|
105870
105945
|
kind: "point",
|
|
@@ -106958,7 +107033,7 @@ function resolveForgeRenderStyle(value) {
|
|
|
106958
107033
|
function getRenderStylePreset(style) {
|
|
106959
107034
|
return PRESETS[resolveForgeRenderStyle(style)];
|
|
106960
107035
|
}
|
|
106961
|
-
function clamp01$
|
|
107036
|
+
function clamp01$3(value) {
|
|
106962
107037
|
return Math.max(0, Math.min(1, value));
|
|
106963
107038
|
}
|
|
106964
107039
|
function applyMaterial(shape, preset) {
|
|
@@ -106980,7 +107055,7 @@ const materials = {
|
|
|
106980
107055
|
clearPolycarbonate(options = {}) {
|
|
106981
107056
|
return {
|
|
106982
107057
|
color: options.tint ?? "#bdefff",
|
|
106983
|
-
material: { opacity: clamp01$
|
|
107058
|
+
material: { opacity: clamp01$3(options.opacity ?? 0.34), roughness: 0.08, metalness: 0, clearcoat: 1, clearcoatRoughness: 0.03 }
|
|
106984
107059
|
};
|
|
106985
107060
|
},
|
|
106986
107061
|
/** Brushed steel-like material for trim, soleplates, and hardware. */
|
|
@@ -107457,31 +107532,6 @@ function validateFog(fog, label) {
|
|
|
107457
107532
|
if (fog.density !== void 0) out.density = requireFinite$5(fog.density, `${label}.density`);
|
|
107458
107533
|
return out;
|
|
107459
107534
|
}
|
|
107460
|
-
function validatePostProcessing(pp, label) {
|
|
107461
|
-
const out = {};
|
|
107462
|
-
if (pp.bloom !== void 0) {
|
|
107463
|
-
if (!pp.bloom || typeof pp.bloom !== "object") throw new Error(`${label}.bloom must be an object`);
|
|
107464
|
-
out.bloom = {};
|
|
107465
|
-
if (pp.bloom.intensity !== void 0) out.bloom.intensity = requireFinite$5(pp.bloom.intensity, `${label}.bloom.intensity`);
|
|
107466
|
-
if (pp.bloom.threshold !== void 0) out.bloom.threshold = requireFinite$5(pp.bloom.threshold, `${label}.bloom.threshold`);
|
|
107467
|
-
if (pp.bloom.radius !== void 0) out.bloom.radius = requireFinite$5(pp.bloom.radius, `${label}.bloom.radius`);
|
|
107468
|
-
}
|
|
107469
|
-
if (pp.vignette !== void 0) {
|
|
107470
|
-
if (!pp.vignette || typeof pp.vignette !== "object") throw new Error(`${label}.vignette must be an object`);
|
|
107471
|
-
out.vignette = {};
|
|
107472
|
-
if (pp.vignette.darkness !== void 0) out.vignette.darkness = requireFinite$5(pp.vignette.darkness, `${label}.vignette.darkness`);
|
|
107473
|
-
if (pp.vignette.offset !== void 0) out.vignette.offset = requireFinite$5(pp.vignette.offset, `${label}.vignette.offset`);
|
|
107474
|
-
}
|
|
107475
|
-
if (pp.grain !== void 0) {
|
|
107476
|
-
if (!pp.grain || typeof pp.grain !== "object") throw new Error(`${label}.grain must be an object`);
|
|
107477
|
-
out.grain = {};
|
|
107478
|
-
if (pp.grain.intensity !== void 0) out.grain.intensity = requireFinite$5(pp.grain.intensity, `${label}.grain.intensity`);
|
|
107479
|
-
}
|
|
107480
|
-
if (pp.toneMappingExposure !== void 0) {
|
|
107481
|
-
out.toneMappingExposure = requireFinite$5(pp.toneMappingExposure, `${label}.toneMappingExposure`);
|
|
107482
|
-
}
|
|
107483
|
-
return out;
|
|
107484
|
-
}
|
|
107485
107535
|
function validateGround(ground, label) {
|
|
107486
107536
|
const out = {};
|
|
107487
107537
|
if (ground.visible !== void 0) {
|
|
@@ -107563,7 +107613,6 @@ function scene(options) {
|
|
|
107563
107613
|
lights: null,
|
|
107564
107614
|
environment: null,
|
|
107565
107615
|
fog: null,
|
|
107566
|
-
postProcessing: null,
|
|
107567
107616
|
ground: null,
|
|
107568
107617
|
capture: null
|
|
107569
107618
|
};
|
|
@@ -107603,12 +107652,9 @@ function scene(options) {
|
|
|
107603
107652
|
}
|
|
107604
107653
|
current.fog = validateFog(options.fog, "scene.fog");
|
|
107605
107654
|
}
|
|
107606
|
-
|
|
107607
|
-
|
|
107608
|
-
|
|
107609
|
-
}
|
|
107610
|
-
const validated = validatePostProcessing(options.postProcessing, "scene.postProcessing");
|
|
107611
|
-
current.postProcessing = current.postProcessing ? { ...current.postProcessing, ...validated } : validated;
|
|
107655
|
+
const disabledPostProcessing = options.postProcessing;
|
|
107656
|
+
if (disabledPostProcessing !== void 0) {
|
|
107657
|
+
console.warn("scene.postProcessing is disabled for now while the browser post-processing path is being rebuilt.");
|
|
107612
107658
|
}
|
|
107613
107659
|
if (options.ground !== void 0) {
|
|
107614
107660
|
if (!options.ground || typeof options.ground !== "object") {
|
|
@@ -107768,8 +107814,7 @@ function scenePreset(name) {
|
|
|
107768
107814
|
{ type: "hemisphere", skyColor: "#ffffff", groundColor: "#d5d9de", intensity: 0.75 },
|
|
107769
107815
|
{ type: "directional", position: [90, -120, 180], color: "#ffffff", intensity: 1.8, castShadow: true },
|
|
107770
107816
|
{ type: "directional", position: [-140, 100, 80], color: "#dfe9ff", intensity: 0.55 }
|
|
107771
|
-
]
|
|
107772
|
-
postProcessing: { toneMappingExposure: 1.08 }
|
|
107817
|
+
]
|
|
107773
107818
|
});
|
|
107774
107819
|
return;
|
|
107775
107820
|
}
|
|
@@ -108011,8 +108056,8 @@ function shapeBoundsCenter(shape) {
|
|
|
108011
108056
|
];
|
|
108012
108057
|
}
|
|
108013
108058
|
class ProductSurfaceRef {
|
|
108014
|
-
constructor(
|
|
108015
|
-
this.skin =
|
|
108059
|
+
constructor(skin2, query, name) {
|
|
108060
|
+
this.skin = skin2;
|
|
108016
108061
|
this.query = query;
|
|
108017
108062
|
this.name = name;
|
|
108018
108063
|
}
|
|
@@ -108529,8 +108574,8 @@ class ProductHandleBuilder {
|
|
|
108529
108574
|
}
|
|
108530
108575
|
}
|
|
108531
108576
|
class ProductSurfaceBuilder {
|
|
108532
|
-
constructor(
|
|
108533
|
-
this.skin =
|
|
108577
|
+
constructor(skin2, side) {
|
|
108578
|
+
this.skin = skin2;
|
|
108534
108579
|
this.side = side;
|
|
108535
108580
|
}
|
|
108536
108581
|
/** Create a ref on this skin side. */
|
|
@@ -108598,9 +108643,9 @@ class ProductRibbonBuilder {
|
|
|
108598
108643
|
* ProductSkin.frame(), so the ribbon bends along the selected side as station width/depth changes.
|
|
108599
108644
|
* All query path points must stay on one side; split side transitions into separate ribbons.
|
|
108600
108645
|
*/
|
|
108601
|
-
on(
|
|
108646
|
+
on(skin2, points, options = {}) {
|
|
108602
108647
|
if (points.length < 2) throw new Error("Product.ribbon().on(skin, points) requires at least two path points");
|
|
108603
|
-
this.skinValue =
|
|
108648
|
+
this.skinValue = skin2;
|
|
108604
108649
|
this.queryPath = resolvePathQueries(points);
|
|
108605
108650
|
this.refPath = [];
|
|
108606
108651
|
return this.applyOptions(options);
|
|
@@ -108723,7 +108768,7 @@ class ProductRibbonBuilder {
|
|
|
108723
108768
|
const localT = scaled - segment;
|
|
108724
108769
|
return interpolateQuery(this.queryPath[segment], this.queryPath[segment + 1], localT);
|
|
108725
108770
|
}
|
|
108726
|
-
buildSkinGrid(
|
|
108771
|
+
buildSkinGrid(skin2, path2) {
|
|
108727
108772
|
if (path2.length < 2) throw new Error("Product.ribbon().on(skin, points) must be called before .build()");
|
|
108728
108773
|
const side = normalizedSide(path2[0].side);
|
|
108729
108774
|
if (side === "front" || side === "rear") {
|
|
@@ -108742,7 +108787,7 @@ class ProductRibbonBuilder {
|
|
|
108742
108787
|
for (let i = 0; i < this.samplesValue; i += 1) {
|
|
108743
108788
|
const along = this.samplesValue === 1 ? 0 : i / (this.samplesValue - 1);
|
|
108744
108789
|
const center = this.samplePathQuery(along);
|
|
108745
|
-
const station =
|
|
108790
|
+
const station = skin2.stationAt(center.v ?? 0.5);
|
|
108746
108791
|
const span = sideSpan(side, station.width, station.depth);
|
|
108747
108792
|
for (let j = 0; j < this.widthSamplesValue; j += 1) {
|
|
108748
108793
|
const across = this.widthSamplesValue === 1 ? 0 : j / (this.widthSamplesValue - 1) - 0.5;
|
|
@@ -108759,13 +108804,13 @@ class ProductRibbonBuilder {
|
|
|
108759
108804
|
u: u2,
|
|
108760
108805
|
offset: (center.offset ?? 0) + this.offsetValue + this.thicknessValue
|
|
108761
108806
|
};
|
|
108762
|
-
rows[j].push(
|
|
108807
|
+
rows[j].push(skin2.frame(query).point);
|
|
108763
108808
|
}
|
|
108764
108809
|
}
|
|
108765
108810
|
return {
|
|
108766
108811
|
grid: rows,
|
|
108767
108812
|
diagnostics: this.makeDiagnostics({
|
|
108768
|
-
skin:
|
|
108813
|
+
skin: skin2.name,
|
|
108769
108814
|
side,
|
|
108770
108815
|
pathPointCount: path2.length,
|
|
108771
108816
|
clampedUCount,
|
|
@@ -108922,16 +108967,16 @@ const Product = {
|
|
|
108922
108967
|
return scaleProfileTo(sketch, width, depth);
|
|
108923
108968
|
},
|
|
108924
108969
|
/** Create an ad-hoc ProductSurfaceRef from a skin and side/u/v query. */
|
|
108925
|
-
ref(
|
|
108926
|
-
return new ProductSurfaceRef(
|
|
108970
|
+
ref(skin2, query) {
|
|
108971
|
+
return new ProductSurfaceRef(skin2, query);
|
|
108927
108972
|
},
|
|
108928
108973
|
/**
|
|
108929
108974
|
* Create a fluent surface helper for refs and conformal features on one side of a skin.
|
|
108930
108975
|
*
|
|
108931
108976
|
* Equivalent to skin.surface(side), useful when writing in Product.* namespace style.
|
|
108932
108977
|
*/
|
|
108933
|
-
surface(
|
|
108934
|
-
return
|
|
108978
|
+
surface(skin2, side) {
|
|
108979
|
+
return skin2.surface(side);
|
|
108935
108980
|
},
|
|
108936
108981
|
/** Start a panel feature builder. */
|
|
108937
108982
|
panel(name) {
|
|
@@ -109400,9 +109445,9 @@ function coordinateOnSide(coordinate, side, label) {
|
|
|
109400
109445
|
return { ...coordinate, kind: "productSkin", side };
|
|
109401
109446
|
}
|
|
109402
109447
|
class ProductSkinCarrier {
|
|
109403
|
-
constructor(
|
|
109448
|
+
constructor(skin2, name = skin2.name, sideValue2, offsetValue = 0) {
|
|
109404
109449
|
__publicField(this, "kind", "productSkin");
|
|
109405
|
-
this.skin =
|
|
109450
|
+
this.skin = skin2;
|
|
109406
109451
|
this.name = name;
|
|
109407
109452
|
this.sideValue = sideValue2;
|
|
109408
109453
|
this.offsetValue = offsetValue;
|
|
@@ -112336,8 +112381,8 @@ const Carrier = {
|
|
|
112336
112381
|
return new PlaneCarrier(name);
|
|
112337
112382
|
},
|
|
112338
112383
|
/** Adapt an existing ProductSkin into the general surface-member carrier protocol. */
|
|
112339
|
-
productSkin(
|
|
112340
|
-
return new ProductSkinCarrier(
|
|
112384
|
+
productSkin(skin2) {
|
|
112385
|
+
return new ProductSkinCarrier(skin2);
|
|
112341
112386
|
},
|
|
112342
112387
|
/** Reserved stub for future parameterized mesh carriers; arbitrary mesh parameterization is not implemented yet. */
|
|
112343
112388
|
mesh(name) {
|
|
@@ -112501,206 +112546,6 @@ ${xrefPos}
|
|
|
112501
112546
|
return encoder.encode(parts.join(""));
|
|
112502
112547
|
}
|
|
112503
112548
|
}
|
|
112504
|
-
let _collectedRobotExport = null;
|
|
112505
|
-
function cloneLinkOptions(input) {
|
|
112506
|
-
if (!input) return {};
|
|
112507
|
-
return Object.fromEntries(Object.entries(input).map(([name, opts]) => [name, { ...opts }]));
|
|
112508
|
-
}
|
|
112509
|
-
function cloneJointOptions(input) {
|
|
112510
|
-
if (!input) return {};
|
|
112511
|
-
return Object.fromEntries(Object.entries(input).map(([name, opts]) => [name, { ...opts }]));
|
|
112512
|
-
}
|
|
112513
|
-
function cloneDiffDrive(input) {
|
|
112514
|
-
if (!input) return void 0;
|
|
112515
|
-
return {
|
|
112516
|
-
...input,
|
|
112517
|
-
leftJoints: [...input.leftJoints],
|
|
112518
|
-
rightJoints: [...input.rightJoints]
|
|
112519
|
-
};
|
|
112520
|
-
}
|
|
112521
|
-
function cloneJointStatePublisher(input) {
|
|
112522
|
-
if (!input) return void 0;
|
|
112523
|
-
return {
|
|
112524
|
-
...input,
|
|
112525
|
-
joints: input.joints ? [...input.joints] : void 0
|
|
112526
|
-
};
|
|
112527
|
-
}
|
|
112528
|
-
function cloneWorld(input) {
|
|
112529
|
-
if (!input) return null;
|
|
112530
|
-
return {
|
|
112531
|
-
...input,
|
|
112532
|
-
spawnPose: input.spawnPose ? [...input.spawnPose] : void 0,
|
|
112533
|
-
keyboardTeleop: input.keyboardTeleop ? { ...input.keyboardTeleop } : void 0
|
|
112534
|
-
};
|
|
112535
|
-
}
|
|
112536
|
-
function assertFinite(value, label) {
|
|
112537
|
-
if (value !== void 0 && !Number.isFinite(value)) {
|
|
112538
|
-
throw new Error(`${label} must be finite`);
|
|
112539
|
-
}
|
|
112540
|
-
}
|
|
112541
|
-
function metadataNumber(value) {
|
|
112542
|
-
return typeof value === "number" ? value : void 0;
|
|
112543
|
-
}
|
|
112544
|
-
function metadataCollision(value) {
|
|
112545
|
-
return value === "none" || value === "visual" || value === "box" || value === "convex" ? value : void 0;
|
|
112546
|
-
}
|
|
112547
|
-
function colliderCollision(collider2) {
|
|
112548
|
-
if (!collider2) return void 0;
|
|
112549
|
-
if (collider2.mode === "box") return "box";
|
|
112550
|
-
if (collider2.mode === "visual") return "visual";
|
|
112551
|
-
return collider2.mode;
|
|
112552
|
-
}
|
|
112553
|
-
function velocityDriveEffort(drive) {
|
|
112554
|
-
return (drive == null ? void 0 : drive.kind) === "velocity" ? drive.maxTorqueNm : void 0;
|
|
112555
|
-
}
|
|
112556
|
-
function velocityDriveVelocityDegS(drive) {
|
|
112557
|
-
return (drive == null ? void 0 : drive.kind) === "velocity" ? drive.maxSpeedRpm * 6 : void 0;
|
|
112558
|
-
}
|
|
112559
|
-
function driveDamping(drive) {
|
|
112560
|
-
return drive == null ? void 0 : drive.damping;
|
|
112561
|
-
}
|
|
112562
|
-
function driveFriction(drive) {
|
|
112563
|
-
return drive == null ? void 0 : drive.friction;
|
|
112564
|
-
}
|
|
112565
|
-
function jointByName(assembly2) {
|
|
112566
|
-
return new Map(assembly2.joints.map((joint2) => [joint2.name, joint2]));
|
|
112567
|
-
}
|
|
112568
|
-
function diffDriveFromControllers(controllers) {
|
|
112569
|
-
if (!controllers) return void 0;
|
|
112570
|
-
const diffDrives = controllers.filter((controller) => controller.kind === "diffDrive");
|
|
112571
|
-
if (diffDrives.length > 1) {
|
|
112572
|
-
throw new Error("assembly.withSimulation(...) currently supports one Sim.controller.diffDrive(...) controller");
|
|
112573
|
-
}
|
|
112574
|
-
const diffDrive2 = diffDrives[0];
|
|
112575
|
-
return diffDrive2 ? {
|
|
112576
|
-
leftJoints: [...diffDrive2.leftJoints],
|
|
112577
|
-
rightJoints: [...diffDrive2.rightJoints],
|
|
112578
|
-
wheelSeparationMm: diffDrive2.wheelSeparationMm,
|
|
112579
|
-
wheelRadiusMm: diffDrive2.wheelRadiusMm,
|
|
112580
|
-
topic: diffDrive2.topic,
|
|
112581
|
-
odomTopic: diffDrive2.odomTopic,
|
|
112582
|
-
tfTopic: diffDrive2.tfTopic,
|
|
112583
|
-
frameId: diffDrive2.frameId,
|
|
112584
|
-
odomFrameId: diffDrive2.odomFrameId,
|
|
112585
|
-
maxLinearVelocity: diffDrive2.maxLinearVelocity,
|
|
112586
|
-
maxAngularVelocity: diffDrive2.maxAngularVelocity,
|
|
112587
|
-
linearAcceleration: diffDrive2.linearAcceleration,
|
|
112588
|
-
angularAcceleration: diffDrive2.angularAcceleration
|
|
112589
|
-
} : void 0;
|
|
112590
|
-
}
|
|
112591
|
-
function resetRobotExport() {
|
|
112592
|
-
_collectedRobotExport = null;
|
|
112593
|
-
}
|
|
112594
|
-
function getCollectedRobotExport() {
|
|
112595
|
-
return _collectedRobotExport;
|
|
112596
|
-
}
|
|
112597
|
-
function collectSimulationModel(assemblyInput, options = {}) {
|
|
112598
|
-
var _a3, _b3, _c2, _d2, _e2, _f3, _g2, _h2, _i2;
|
|
112599
|
-
const assembly2 = typeof assemblyInput.describe === "function" ? assemblyInput.describe() : assemblyInput;
|
|
112600
|
-
const partNames = new Set(assembly2.parts.map((part) => part.name));
|
|
112601
|
-
const joints = jointByName(assembly2);
|
|
112602
|
-
const links = cloneLinkOptions(options.links);
|
|
112603
|
-
for (const part of assembly2.parts) {
|
|
112604
|
-
const fromSim = part.sim;
|
|
112605
|
-
const fromMaterialDensity = (_a3 = fromSim == null ? void 0 : fromSim.material) == null ? void 0 : _a3.densityKgM3;
|
|
112606
|
-
const current = links[part.name] ?? {};
|
|
112607
|
-
const next = {
|
|
112608
|
-
massKg: current.massKg ?? (fromSim == null ? void 0 : fromSim.massKg) ?? metadataNumber((_b3 = part.metadata) == null ? void 0 : _b3.massKg),
|
|
112609
|
-
densityKgM3: current.densityKgM3 ?? (fromSim == null ? void 0 : fromSim.densityKgM3) ?? fromMaterialDensity ?? metadataNumber((_c2 = part.metadata) == null ? void 0 : _c2.densityKgM3),
|
|
112610
|
-
collision: current.collision ?? colliderCollision(fromSim == null ? void 0 : fromSim.collider) ?? metadataCollision((_d2 = part.metadata) == null ? void 0 : _d2.collision)
|
|
112611
|
-
};
|
|
112612
|
-
if (next.massKg !== void 0 || next.densityKgM3 !== void 0 || next.collision !== void 0) {
|
|
112613
|
-
links[part.name] = next;
|
|
112614
|
-
}
|
|
112615
|
-
}
|
|
112616
|
-
for (const [partName, link] of Object.entries(links)) {
|
|
112617
|
-
if (!partNames.has(partName)) throw new Error(`simulation model references unknown link "${partName}"`);
|
|
112618
|
-
assertFinite(link.massKg, `simulation model link "${partName}" massKg`);
|
|
112619
|
-
assertFinite(link.densityKgM3, `simulation model link "${partName}" densityKgM3`);
|
|
112620
|
-
}
|
|
112621
|
-
const jointOpts = cloneJointOptions(options.joints);
|
|
112622
|
-
for (const joint2 of assembly2.joints) {
|
|
112623
|
-
const drive = (_e2 = joint2.sim) == null ? void 0 : _e2.drive;
|
|
112624
|
-
const current = jointOpts[joint2.name] ?? {};
|
|
112625
|
-
const next = {
|
|
112626
|
-
effort: current.effort ?? velocityDriveEffort(drive) ?? joint2.effort,
|
|
112627
|
-
velocity: current.velocity ?? velocityDriveVelocityDegS(drive) ?? joint2.velocity,
|
|
112628
|
-
damping: current.damping ?? driveDamping(drive) ?? joint2.damping,
|
|
112629
|
-
friction: current.friction ?? driveFriction(drive) ?? joint2.friction
|
|
112630
|
-
};
|
|
112631
|
-
if (next.effort !== void 0 || next.velocity !== void 0 || next.damping !== void 0 || next.friction !== void 0) {
|
|
112632
|
-
jointOpts[joint2.name] = next;
|
|
112633
|
-
}
|
|
112634
|
-
}
|
|
112635
|
-
for (const [jointName, joint2] of Object.entries(jointOpts)) {
|
|
112636
|
-
if (!joints.has(jointName)) throw new Error(`simulation model references unknown joint "${jointName}"`);
|
|
112637
|
-
assertFinite(joint2.effort, `simulation model joint "${jointName}" effort`);
|
|
112638
|
-
assertFinite(joint2.velocity, `simulation model joint "${jointName}" velocity`);
|
|
112639
|
-
assertFinite(joint2.damping, `simulation model joint "${jointName}" damping`);
|
|
112640
|
-
assertFinite(joint2.friction, `simulation model joint "${jointName}" friction`);
|
|
112641
|
-
}
|
|
112642
|
-
const simulation = cloneSimAssemblySimulation(assembly2.sim) ?? null;
|
|
112643
|
-
const simulationDiffDrive = diffDriveFromControllers(simulation == null ? void 0 : simulation.controllers);
|
|
112644
|
-
const diffDrive2 = cloneDiffDrive((_f3 = options.plugins) == null ? void 0 : _f3.diffDrive) ?? simulationDiffDrive;
|
|
112645
|
-
if (diffDrive2) {
|
|
112646
|
-
if (diffDrive2.leftJoints.length === 0 || diffDrive2.rightJoints.length === 0) {
|
|
112647
|
-
throw new Error("simulation model diffDrive requires at least one left joint and one right joint");
|
|
112648
|
-
}
|
|
112649
|
-
assertFinite(diffDrive2.wheelSeparationMm, "simulation model diffDrive wheelSeparationMm");
|
|
112650
|
-
assertFinite(diffDrive2.wheelRadiusMm, "simulation model diffDrive wheelRadiusMm");
|
|
112651
|
-
if (diffDrive2.wheelSeparationMm <= 0 || diffDrive2.wheelRadiusMm <= 0) {
|
|
112652
|
-
throw new Error("simulation model diffDrive wheel separation and radius must be > 0");
|
|
112653
|
-
}
|
|
112654
|
-
[...diffDrive2.leftJoints, ...diffDrive2.rightJoints].forEach((jointName) => {
|
|
112655
|
-
const joint2 = joints.get(jointName);
|
|
112656
|
-
if (!joint2) throw new Error(`simulation model diffDrive references unknown joint "${jointName}"`);
|
|
112657
|
-
if (joint2.type !== "revolute") {
|
|
112658
|
-
throw new Error(`simulation model diffDrive joint "${jointName}" must be revolute`);
|
|
112659
|
-
}
|
|
112660
|
-
});
|
|
112661
|
-
}
|
|
112662
|
-
const jointStatePublisher = cloneJointStatePublisher((_g2 = options.plugins) == null ? void 0 : _g2.jointStatePublisher);
|
|
112663
|
-
if (jointStatePublisher == null ? void 0 : jointStatePublisher.joints) {
|
|
112664
|
-
jointStatePublisher.joints.forEach((jointName) => {
|
|
112665
|
-
if (!joints.has(jointName)) {
|
|
112666
|
-
throw new Error(`simulation model jointStatePublisher references unknown joint "${jointName}"`);
|
|
112667
|
-
}
|
|
112668
|
-
});
|
|
112669
|
-
}
|
|
112670
|
-
const world = cloneWorld(options.world);
|
|
112671
|
-
if (world == null ? void 0 : world.spawnPose) {
|
|
112672
|
-
world.spawnPose.forEach((value, index2) => assertFinite(value, `simulation model world spawnPose[${index2}]`));
|
|
112673
|
-
}
|
|
112674
|
-
assertFinite((_h2 = world == null ? void 0 : world.keyboardTeleop) == null ? void 0 : _h2.linearStep, "simulation model world keyboardTeleop.linearStep");
|
|
112675
|
-
assertFinite((_i2 = world == null ? void 0 : world.keyboardTeleop) == null ? void 0 : _i2.angularStep, "simulation model world keyboardTeleop.angularStep");
|
|
112676
|
-
return {
|
|
112677
|
-
modelName: (options.modelName ?? assembly2.name ?? "ForgeCAD Simulation").trim() || "ForgeCAD Simulation",
|
|
112678
|
-
assembly: assembly2,
|
|
112679
|
-
simulation,
|
|
112680
|
-
source: options.source ?? "assembly",
|
|
112681
|
-
state: { ...options.state ?? {} },
|
|
112682
|
-
static: options.static ?? false,
|
|
112683
|
-
selfCollide: options.selfCollide ?? false,
|
|
112684
|
-
allowAutoDisable: options.allowAutoDisable ?? true,
|
|
112685
|
-
links,
|
|
112686
|
-
joints: jointOpts,
|
|
112687
|
-
plugins: {
|
|
112688
|
-
diffDrive: diffDrive2,
|
|
112689
|
-
jointStatePublisher
|
|
112690
|
-
},
|
|
112691
|
-
world
|
|
112692
|
-
};
|
|
112693
|
-
}
|
|
112694
|
-
function robotExport(options) {
|
|
112695
|
-
if (!options || typeof options !== "object") {
|
|
112696
|
-
throw new Error("robotExport(...) expects an options object");
|
|
112697
|
-
}
|
|
112698
|
-
if (!options.assembly || typeof options.assembly.describe !== "function") {
|
|
112699
|
-
throw new Error("robotExport(...) requires an assembly");
|
|
112700
|
-
}
|
|
112701
|
-
_collectedRobotExport = collectSimulationModel(options.assembly, { ...options, source: "robotExport" });
|
|
112702
|
-
return _collectedRobotExport;
|
|
112703
|
-
}
|
|
112704
112549
|
class Point2D {
|
|
112705
112550
|
constructor(x2, y2) {
|
|
112706
112551
|
this.x = x2;
|
|
@@ -134990,6 +134835,847 @@ function getSketchWorldMatrix(sketch) {
|
|
|
134990
134835
|
Sketch.prototype.onFace = function(parentOrFace, faceOrOpts, maybeOpts = {}) {
|
|
134991
134836
|
return sketchOnFace(this, parentOrFace, faceOrOpts, maybeOpts);
|
|
134992
134837
|
};
|
|
134838
|
+
const KNOT_EPS = 1e-10;
|
|
134839
|
+
const KNOT_MERGE_EPS = 1e-7;
|
|
134840
|
+
function sameKnot(a2, b) {
|
|
134841
|
+
return Math.abs(a2 - b) <= KNOT_EPS;
|
|
134842
|
+
}
|
|
134843
|
+
function knotMultiplicity(knots, u2) {
|
|
134844
|
+
let count = 0;
|
|
134845
|
+
for (const k2 of knots) if (sameKnot(k2, u2)) count++;
|
|
134846
|
+
return count;
|
|
134847
|
+
}
|
|
134848
|
+
function computeParamsCentripetal(points, alpha = 0.5) {
|
|
134849
|
+
const n = points.length;
|
|
134850
|
+
const params = new Array(n).fill(0);
|
|
134851
|
+
const seg = new Array(n).fill(0);
|
|
134852
|
+
let total = 0;
|
|
134853
|
+
for (let k2 = 1; k2 < n; k2++) {
|
|
134854
|
+
const dx = points[k2][0] - points[k2 - 1][0];
|
|
134855
|
+
const dy = points[k2][1] - points[k2 - 1][1];
|
|
134856
|
+
const dz = points[k2][2] - points[k2 - 1][2];
|
|
134857
|
+
seg[k2] = Math.hypot(dx, dy, dz) ** alpha;
|
|
134858
|
+
total += seg[k2];
|
|
134859
|
+
}
|
|
134860
|
+
if (total === 0) {
|
|
134861
|
+
for (let k2 = 0; k2 < n; k2++) params[k2] = n > 1 ? k2 / (n - 1) : 0;
|
|
134862
|
+
return params;
|
|
134863
|
+
}
|
|
134864
|
+
let acc = 0;
|
|
134865
|
+
for (let k2 = 1; k2 < n - 1; k2++) {
|
|
134866
|
+
acc += seg[k2];
|
|
134867
|
+
params[k2] = acc / total;
|
|
134868
|
+
}
|
|
134869
|
+
params[n - 1] = 1;
|
|
134870
|
+
return params;
|
|
134871
|
+
}
|
|
134872
|
+
function knotsFromParamsAveraging(params, degree) {
|
|
134873
|
+
const n = params.length - 1;
|
|
134874
|
+
const m2 = n + degree + 1;
|
|
134875
|
+
const knots = new Array(m2 + 1).fill(0);
|
|
134876
|
+
for (let i = m2 - degree; i <= m2; i++) knots[i] = 1;
|
|
134877
|
+
for (let j = 1; j <= n - degree; j++) {
|
|
134878
|
+
let s = 0;
|
|
134879
|
+
for (let i = j; i <= j + degree - 1; i++) s += params[i];
|
|
134880
|
+
knots[j + degree] = s / degree;
|
|
134881
|
+
}
|
|
134882
|
+
return knots;
|
|
134883
|
+
}
|
|
134884
|
+
function solveLinear(A, B2) {
|
|
134885
|
+
const n = A.length;
|
|
134886
|
+
const k2 = B2[0].length;
|
|
134887
|
+
const M = A.map((row, i) => [...row, ...B2[i]]);
|
|
134888
|
+
for (let col = 0; col < n; col++) {
|
|
134889
|
+
let piv = col;
|
|
134890
|
+
for (let r = col + 1; r < n; r++) if (Math.abs(M[r][col]) > Math.abs(M[piv][col])) piv = r;
|
|
134891
|
+
if (Math.abs(M[piv][col]) < 1e-14) throw new Error(`Singular interpolation matrix at column ${col}.`);
|
|
134892
|
+
[M[col], M[piv]] = [M[piv], M[col]];
|
|
134893
|
+
const inv = 1 / M[col][col];
|
|
134894
|
+
for (let j = col; j < n + k2; j++) M[col][j] *= inv;
|
|
134895
|
+
for (let r = 0; r < n; r++) {
|
|
134896
|
+
if (r === col) continue;
|
|
134897
|
+
const f3 = M[r][col];
|
|
134898
|
+
if (f3 === 0) continue;
|
|
134899
|
+
for (let j = col; j < n + k2; j++) M[r][j] -= f3 * M[col][j];
|
|
134900
|
+
}
|
|
134901
|
+
}
|
|
134902
|
+
return Array.from({ length: n }, (_2, i) => M[i].slice(n));
|
|
134903
|
+
}
|
|
134904
|
+
function globalCurveInterp(points, degree, paramsIn) {
|
|
134905
|
+
const last = points.length - 1;
|
|
134906
|
+
if (last < degree) throw new Error(`Curve interpolation needs at least ${degree + 1} points, got ${points.length}.`);
|
|
134907
|
+
const params = paramsIn ? paramsIn.slice() : computeParamsCentripetal(points, 0.5);
|
|
134908
|
+
const knots = knotsFromParamsAveraging(params, degree);
|
|
134909
|
+
const count = last + 1;
|
|
134910
|
+
const N = Array.from({ length: count }, () => new Array(count).fill(0));
|
|
134911
|
+
for (let i = 0; i <= last; i++) {
|
|
134912
|
+
const span = findSpan(count, degree, params[i], knots);
|
|
134913
|
+
const basis = basisFuns(span, params[i], degree, knots);
|
|
134914
|
+
for (let j = 0; j <= degree; j++) N[i][span - degree + j] = basis[j];
|
|
134915
|
+
}
|
|
134916
|
+
const Q = points.map((p2) => [p2[0], p2[1], p2[2]]);
|
|
134917
|
+
const cps = solveLinear(N, Q);
|
|
134918
|
+
return { cps, knots, degree };
|
|
134919
|
+
}
|
|
134920
|
+
function insertKnotCurve(cps, knots, degree, u2) {
|
|
134921
|
+
const n = cps.length;
|
|
134922
|
+
const span = findSpan(n, degree, u2, knots);
|
|
134923
|
+
const mult = knotMultiplicity(knots, u2);
|
|
134924
|
+
if (mult >= degree) return { cps: cps.slice(), knots: knots.slice() };
|
|
134925
|
+
const newCps = new Array(n + 1);
|
|
134926
|
+
const newKnots = new Array(knots.length + 1);
|
|
134927
|
+
for (let i = 0; i <= span; i++) newKnots[i] = knots[i];
|
|
134928
|
+
newKnots[span + 1] = u2;
|
|
134929
|
+
for (let i = span + 1; i < knots.length; i++) newKnots[i + 1] = knots[i];
|
|
134930
|
+
for (let i = 0; i <= span - degree; i++) newCps[i] = [...cps[i]];
|
|
134931
|
+
for (let i = span - mult; i < n; i++) newCps[i + 1] = [...cps[i]];
|
|
134932
|
+
for (let i = span - degree + 1; i <= span - mult; i++) {
|
|
134933
|
+
const denom = knots[i + degree] - knots[i];
|
|
134934
|
+
const alpha = denom === 0 ? 0 : (u2 - knots[i]) / denom;
|
|
134935
|
+
const a2 = cps[i - 1];
|
|
134936
|
+
const b = cps[i];
|
|
134937
|
+
newCps[i] = [(1 - alpha) * a2[0] + alpha * b[0], (1 - alpha) * a2[1] + alpha * b[1], (1 - alpha) * a2[2] + alpha * b[2]];
|
|
134938
|
+
}
|
|
134939
|
+
return { cps: newCps, knots: newKnots };
|
|
134940
|
+
}
|
|
134941
|
+
function interiorKnotBuckets(kv, mergeEps = KNOT_MERGE_EPS) {
|
|
134942
|
+
const buckets = [];
|
|
134943
|
+
for (const k2 of kv) {
|
|
134944
|
+
if (k2 <= KNOT_EPS || k2 >= 1 - KNOT_EPS) continue;
|
|
134945
|
+
const b = buckets.find((x2) => Math.abs(x2.value - k2) <= mergeEps);
|
|
134946
|
+
if (b) b.mult++;
|
|
134947
|
+
else buckets.push({ value: k2, mult: 1 });
|
|
134948
|
+
}
|
|
134949
|
+
return buckets;
|
|
134950
|
+
}
|
|
134951
|
+
function mergeKnotVectors(knotVectors, degree, mergeEps = KNOT_MERGE_EPS) {
|
|
134952
|
+
const merged = [];
|
|
134953
|
+
for (const kv of knotVectors) {
|
|
134954
|
+
for (const { value, mult } of interiorKnotBuckets(kv, mergeEps)) {
|
|
134955
|
+
const b = merged.find((x2) => Math.abs(x2.value - value) <= mergeEps);
|
|
134956
|
+
if (b) b.mult = Math.max(b.mult, mult);
|
|
134957
|
+
else merged.push({ value, mult });
|
|
134958
|
+
}
|
|
134959
|
+
}
|
|
134960
|
+
merged.sort((a2, b) => a2.value - b.value);
|
|
134961
|
+
const out = [];
|
|
134962
|
+
for (let i = 0; i <= degree; i++) out.push(0);
|
|
134963
|
+
for (const { value, mult } of merged) for (let i = 0; i < mult; i++) out.push(value);
|
|
134964
|
+
for (let i = 0; i <= degree; i++) out.push(1);
|
|
134965
|
+
return out;
|
|
134966
|
+
}
|
|
134967
|
+
function refineKnotsToTarget(cps, knots, degree, targetKnots, mergeEps = KNOT_MERGE_EPS) {
|
|
134968
|
+
let curCps = cps.map((p2) => [...p2]);
|
|
134969
|
+
let curKnots = knots.slice();
|
|
134970
|
+
for (const { value, mult } of interiorKnotBuckets(targetKnots, mergeEps)) {
|
|
134971
|
+
const curMult = () => curKnots.reduce((c2, k2) => c2 + (Math.abs(k2 - value) <= mergeEps ? 1 : 0), 0);
|
|
134972
|
+
let guard = 0;
|
|
134973
|
+
while (curMult() < mult) {
|
|
134974
|
+
const r = insertKnotCurve(curCps, curKnots, degree, value);
|
|
134975
|
+
if (r.cps.length === curCps.length) break;
|
|
134976
|
+
curCps = r.cps;
|
|
134977
|
+
curKnots = r.knots;
|
|
134978
|
+
if (++guard > degree + 2) break;
|
|
134979
|
+
}
|
|
134980
|
+
}
|
|
134981
|
+
return { cps: curCps, knots: curKnots };
|
|
134982
|
+
}
|
|
134983
|
+
function binomial(a2, b) {
|
|
134984
|
+
if (b < 0 || b > a2) return 0;
|
|
134985
|
+
let r = 1;
|
|
134986
|
+
for (let i = 0; i < b; i++) r = r * (a2 - i) / (i + 1);
|
|
134987
|
+
return r;
|
|
134988
|
+
}
|
|
134989
|
+
function bezierElevate(bez, p2, t) {
|
|
134990
|
+
const m2 = p2 + t;
|
|
134991
|
+
const out = [];
|
|
134992
|
+
for (let i = 0; i <= m2; i++) {
|
|
134993
|
+
const acc = [0, 0, 0];
|
|
134994
|
+
const lo = Math.max(0, i - t);
|
|
134995
|
+
const hi = Math.min(p2, i);
|
|
134996
|
+
for (let j = lo; j <= hi; j++) {
|
|
134997
|
+
const w2 = binomial(p2, j) * binomial(t, i - j) / binomial(m2, i);
|
|
134998
|
+
acc[0] += w2 * bez[j][0];
|
|
134999
|
+
acc[1] += w2 * bez[j][1];
|
|
135000
|
+
acc[2] += w2 * bez[j][2];
|
|
135001
|
+
}
|
|
135002
|
+
out.push(acc);
|
|
135003
|
+
}
|
|
135004
|
+
return out;
|
|
135005
|
+
}
|
|
135006
|
+
function elevateCurveDegree(cps, knots, degree, targetDegree) {
|
|
135007
|
+
if (targetDegree === degree) return { cps: cps.map((p2) => [...p2]), knots: knots.slice(), degree };
|
|
135008
|
+
if (targetDegree < degree) throw new Error("Degree reduction is not supported.");
|
|
135009
|
+
const t = targetDegree - degree;
|
|
135010
|
+
let curCps = cps.map((p2) => [...p2]);
|
|
135011
|
+
let curKnots = knots.slice();
|
|
135012
|
+
const breaks = interiorKnotBuckets(curKnots).map((b) => b.value);
|
|
135013
|
+
for (const v of breaks) {
|
|
135014
|
+
let guard = 0;
|
|
135015
|
+
while (knotMultiplicity(curKnots, v) < degree) {
|
|
135016
|
+
const r = insertKnotCurve(curCps, curKnots, degree, v);
|
|
135017
|
+
curCps = r.cps;
|
|
135018
|
+
curKnots = r.knots;
|
|
135019
|
+
if (++guard > degree + 2) break;
|
|
135020
|
+
}
|
|
135021
|
+
}
|
|
135022
|
+
const segVals = [0, ...breaks.slice().sort((a2, b) => a2 - b), 1];
|
|
135023
|
+
const nSeg = segVals.length - 1;
|
|
135024
|
+
const newCps = [];
|
|
135025
|
+
for (let s = 0; s < nSeg; s++) {
|
|
135026
|
+
const bez = curCps.slice(s * degree, s * degree + degree + 1);
|
|
135027
|
+
const elevated = bezierElevate(bez, degree, t);
|
|
135028
|
+
if (s === 0) newCps.push(...elevated);
|
|
135029
|
+
else newCps.push(...elevated.slice(1));
|
|
135030
|
+
}
|
|
135031
|
+
const newKnots = [];
|
|
135032
|
+
for (let i = 0; i <= targetDegree; i++) newKnots.push(0);
|
|
135033
|
+
for (let s = 1; s < nSeg; s++) for (let i = 0; i < targetDegree; i++) newKnots.push(segVals[s]);
|
|
135034
|
+
for (let i = 0; i <= targetDegree; i++) newKnots.push(1);
|
|
135035
|
+
if (newKnots.length !== newCps.length + targetDegree + 1) {
|
|
135036
|
+
throw new Error(
|
|
135037
|
+
`Degree elevation produced inconsistent knots (${newKnots.length}) for ${newCps.length} control points at degree ${targetDegree}.`
|
|
135038
|
+
);
|
|
135039
|
+
}
|
|
135040
|
+
return { cps: newCps, knots: newKnots, degree: targetDegree };
|
|
135041
|
+
}
|
|
135042
|
+
function unifyCurves(curves) {
|
|
135043
|
+
const targetDeg = Math.max(...curves.map((c2) => c2.degree));
|
|
135044
|
+
const elevated = curves.map((c2) => elevateCurveDegree(c2.cps, c2.knots, c2.degree, targetDeg));
|
|
135045
|
+
const common2 = mergeKnotVectors(
|
|
135046
|
+
elevated.map((c2) => c2.knots),
|
|
135047
|
+
targetDeg
|
|
135048
|
+
);
|
|
135049
|
+
const refined = elevated.map((c2) => refineKnotsToTarget(c2.cps, c2.knots, targetDeg, common2));
|
|
135050
|
+
const ncp = common2.length - targetDeg - 1;
|
|
135051
|
+
for (const r of refined) {
|
|
135052
|
+
if (r.cps.length !== ncp) throw new Error(`Curve unification produced ${r.cps.length} control points, expected ${ncp}.`);
|
|
135053
|
+
}
|
|
135054
|
+
return { degree: targetDeg, knots: common2, curves: refined.map((r) => r.cps) };
|
|
135055
|
+
}
|
|
135056
|
+
function transpose(g2) {
|
|
135057
|
+
const out = [];
|
|
135058
|
+
for (let j = 0; j < g2[0].length; j++) {
|
|
135059
|
+
const row = [];
|
|
135060
|
+
for (let i = 0; i < g2.length; i++) row.push(g2[i][j]);
|
|
135061
|
+
out.push(row);
|
|
135062
|
+
}
|
|
135063
|
+
return out;
|
|
135064
|
+
}
|
|
135065
|
+
function skin(curveCps, spanParams, spanDegree) {
|
|
135066
|
+
const ncp = curveCps[0].length;
|
|
135067
|
+
const cols = [];
|
|
135068
|
+
for (let j = 0; j < ncp; j++) {
|
|
135069
|
+
const pts = curveCps.map((row) => row[j]);
|
|
135070
|
+
cols.push(globalCurveInterp(pts, spanDegree, spanParams).cps);
|
|
135071
|
+
}
|
|
135072
|
+
const spanCp = cols[0].length;
|
|
135073
|
+
const grid = [];
|
|
135074
|
+
for (let s = 0; s < spanCp; s++) {
|
|
135075
|
+
const row = [];
|
|
135076
|
+
for (let j = 0; j < ncp; j++) row.push(cols[j][s]);
|
|
135077
|
+
grid.push(row);
|
|
135078
|
+
}
|
|
135079
|
+
const spanKnots = knotsFromParamsAveraging(spanParams, spanDegree);
|
|
135080
|
+
return { grid, spanKnots };
|
|
135081
|
+
}
|
|
135082
|
+
function tensorInterp(gridPts, uParams, vParams, degreeU, degreeV) {
|
|
135083
|
+
const rowInterp = gridPts.map((rowPts) => globalCurveInterp(rowPts, degreeV, vParams));
|
|
135084
|
+
const knotsV = rowInterp[0].knots;
|
|
135085
|
+
const ncpV = rowInterp[0].cps.length;
|
|
135086
|
+
const cols = [];
|
|
135087
|
+
for (let j = 0; j < ncpV; j++) {
|
|
135088
|
+
const pts = rowInterp.map((ri) => ri.cps[j]);
|
|
135089
|
+
cols.push(globalCurveInterp(pts, degreeU, uParams));
|
|
135090
|
+
}
|
|
135091
|
+
const knotsU = cols[0].knots;
|
|
135092
|
+
const cpU = cols[0].cps.length;
|
|
135093
|
+
const grid = [];
|
|
135094
|
+
for (let i = 0; i < cpU; i++) {
|
|
135095
|
+
const row = [];
|
|
135096
|
+
for (let j = 0; j < ncpV; j++) row.push(cols[j].cps[i]);
|
|
135097
|
+
grid.push(row);
|
|
135098
|
+
}
|
|
135099
|
+
return { grid, knotsU, knotsV };
|
|
135100
|
+
}
|
|
135101
|
+
function refineSurface(surf, targetKnotsU, targetKnotsV) {
|
|
135102
|
+
const { grid, knotsU, knotsV, degreeU, degreeV } = surf;
|
|
135103
|
+
const rows = grid.map((row) => refineKnotsToTarget(row, knotsV, degreeV, targetKnotsV).cps);
|
|
135104
|
+
const ncpV = rows[0].length;
|
|
135105
|
+
const cols = [];
|
|
135106
|
+
for (let j = 0; j < ncpV; j++) {
|
|
135107
|
+
const colPts = rows.map((r) => r[j]);
|
|
135108
|
+
cols.push(refineKnotsToTarget(colPts, knotsU, degreeU, targetKnotsU).cps);
|
|
135109
|
+
}
|
|
135110
|
+
const cpU = cols[0].length;
|
|
135111
|
+
const out = [];
|
|
135112
|
+
for (let i = 0; i < cpU; i++) {
|
|
135113
|
+
const row = [];
|
|
135114
|
+
for (let j = 0; j < ncpV; j++) row.push(cols[j][i]);
|
|
135115
|
+
out.push(row);
|
|
135116
|
+
}
|
|
135117
|
+
return { grid: out, knotsU: targetKnotsU, knotsV: targetKnotsV, degreeU, degreeV };
|
|
135118
|
+
}
|
|
135119
|
+
function averageParams(polylines, alpha = 0.5) {
|
|
135120
|
+
const count = polylines[0].length;
|
|
135121
|
+
const acc = new Array(count).fill(0);
|
|
135122
|
+
for (const pl of polylines) {
|
|
135123
|
+
const p2 = computeParamsCentripetal(pl, alpha);
|
|
135124
|
+
for (let i = 0; i < count; i++) acc[i] += p2[i];
|
|
135125
|
+
}
|
|
135126
|
+
return acc.map((s) => s / polylines.length);
|
|
135127
|
+
}
|
|
135128
|
+
function gordonGridParams(gridPts) {
|
|
135129
|
+
const rows = gridPts;
|
|
135130
|
+
const cols = gridPts[0].map((_2, l) => gridPts.map((r) => r[l]));
|
|
135131
|
+
return { vParams: averageParams(rows, 0.5), uParams: averageParams(cols, 0.5) };
|
|
135132
|
+
}
|
|
135133
|
+
function buildGordonFromGrid(gridPts, degreeU = 3, degreeV = 3) {
|
|
135134
|
+
const m2 = gridPts.length - 1;
|
|
135135
|
+
const n = gridPts[0].length - 1;
|
|
135136
|
+
if (m2 < 1 || n < 1) throw new Error("A Gordon surface needs at least a 2x2 curve network.");
|
|
135137
|
+
if (m2 < degreeU) degreeU = m2;
|
|
135138
|
+
if (n < degreeV) degreeV = n;
|
|
135139
|
+
const rows = gridPts;
|
|
135140
|
+
const cols = gridPts[0].map((_2, l) => gridPts.map((r) => r[l]));
|
|
135141
|
+
const { uParams, vParams } = gordonGridParams(gridPts);
|
|
135142
|
+
const uCurves = rows.map((rowPts) => globalCurveInterp(rowPts, degreeV, vParams));
|
|
135143
|
+
const vCurves = cols.map((colPts) => globalCurveInterp(colPts, degreeU, uParams));
|
|
135144
|
+
const uFam = unifyCurves(uCurves);
|
|
135145
|
+
const vFam = unifyCurves(vCurves);
|
|
135146
|
+
const Lu = skin(uFam.curves, uParams, degreeU);
|
|
135147
|
+
const LvRaw = skin(vFam.curves, vParams, degreeV);
|
|
135148
|
+
const Lv = { grid: transpose(LvRaw.grid), knotsU: vFam.knots, knotsV: LvRaw.spanKnots };
|
|
135149
|
+
const T = tensorInterp(gridPts, uParams, vParams, degreeU, degreeV);
|
|
135150
|
+
const knotsU = mergeKnotVectors([Lu.spanKnots, Lv.knotsU, T.knotsU], degreeU);
|
|
135151
|
+
const knotsV = mergeKnotVectors([uFam.knots, Lv.knotsV, T.knotsV], degreeV);
|
|
135152
|
+
const LuS = refineSurface({ grid: Lu.grid, knotsU: Lu.spanKnots, knotsV: uFam.knots, degreeU, degreeV }, knotsU, knotsV);
|
|
135153
|
+
const LvS = refineSurface({ grid: Lv.grid, knotsU: Lv.knotsU, knotsV: Lv.knotsV, degreeU, degreeV }, knotsU, knotsV);
|
|
135154
|
+
const TS = refineSurface({ grid: T.grid, knotsU: T.knotsU, knotsV: T.knotsV, degreeU, degreeV }, knotsU, knotsV);
|
|
135155
|
+
const nuc = LuS.grid.length;
|
|
135156
|
+
const nvc = LuS.grid[0].length;
|
|
135157
|
+
if (LvS.grid.length !== nuc || TS.grid.length !== nuc || LvS.grid[0].length !== nvc || TS.grid[0].length !== nvc) {
|
|
135158
|
+
throw new Error(
|
|
135159
|
+
`Gordon blend grid mismatch: Lu ${nuc}x${nvc}, Lv ${LvS.grid.length}x${LvS.grid[0].length}, T ${TS.grid.length}x${TS.grid[0].length}.`
|
|
135160
|
+
);
|
|
135161
|
+
}
|
|
135162
|
+
const grid = [];
|
|
135163
|
+
for (let i = 0; i < nuc; i++) {
|
|
135164
|
+
const row = [];
|
|
135165
|
+
for (let j = 0; j < nvc; j++) {
|
|
135166
|
+
const a2 = LuS.grid[i][j];
|
|
135167
|
+
const b = LvS.grid[i][j];
|
|
135168
|
+
const c2 = TS.grid[i][j];
|
|
135169
|
+
row.push([a2[0] + b[0] - c2[0], a2[1] + b[1] - c2[1], a2[2] + b[2] - c2[2]]);
|
|
135170
|
+
}
|
|
135171
|
+
grid.push(row);
|
|
135172
|
+
}
|
|
135173
|
+
return { grid, knotsU, knotsV, degreeU, degreeV };
|
|
135174
|
+
}
|
|
135175
|
+
function evalSurface(surf, u2, v) {
|
|
135176
|
+
const { grid, knotsU, knotsV, degreeU, degreeV } = surf;
|
|
135177
|
+
const nu = grid.length;
|
|
135178
|
+
const nv = grid[0].length;
|
|
135179
|
+
const su = findSpan(nu, degreeU, u2, knotsU);
|
|
135180
|
+
const sv = findSpan(nv, degreeV, v, knotsV);
|
|
135181
|
+
const Nu = basisFuns(su, u2, degreeU, knotsU);
|
|
135182
|
+
const Nv = basisFuns(sv, v, degreeV, knotsV);
|
|
135183
|
+
const out = [0, 0, 0];
|
|
135184
|
+
for (let i = 0; i <= degreeU; i++) {
|
|
135185
|
+
const ui = su - degreeU + i;
|
|
135186
|
+
for (let j = 0; j <= degreeV; j++) {
|
|
135187
|
+
const vj = sv - degreeV + j;
|
|
135188
|
+
const w2 = Nu[i] * Nv[j];
|
|
135189
|
+
const p2 = grid[ui][vj];
|
|
135190
|
+
out[0] += w2 * p2[0];
|
|
135191
|
+
out[1] += w2 * p2[1];
|
|
135192
|
+
out[2] += w2 * p2[2];
|
|
135193
|
+
}
|
|
135194
|
+
}
|
|
135195
|
+
return out;
|
|
135196
|
+
}
|
|
135197
|
+
function evalSurfaceJet(surf, u2, v) {
|
|
135198
|
+
const { grid, knotsU, knotsV, degreeU, degreeV } = surf;
|
|
135199
|
+
const nu = grid.length;
|
|
135200
|
+
const nv = grid[0].length;
|
|
135201
|
+
const su = findSpan(nu, degreeU, u2, knotsU);
|
|
135202
|
+
const sv = findSpan(nv, degreeV, v, knotsV);
|
|
135203
|
+
const dU = basisFunsDeriv(su, u2, degreeU, knotsU, 2);
|
|
135204
|
+
const dV = basisFunsDeriv(sv, v, degreeV, knotsV, 2);
|
|
135205
|
+
const S = [0, 0, 0];
|
|
135206
|
+
const Su = [0, 0, 0];
|
|
135207
|
+
const Sv = [0, 0, 0];
|
|
135208
|
+
const Suu = [0, 0, 0];
|
|
135209
|
+
const Suv = [0, 0, 0];
|
|
135210
|
+
const Svv = [0, 0, 0];
|
|
135211
|
+
for (let i = 0; i <= degreeU; i++) {
|
|
135212
|
+
const ui = su - degreeU + i;
|
|
135213
|
+
for (let j = 0; j <= degreeV; j++) {
|
|
135214
|
+
const vj = sv - degreeV + j;
|
|
135215
|
+
const p2 = grid[ui][vj];
|
|
135216
|
+
const w00 = dU[0][i] * dV[0][j];
|
|
135217
|
+
const w10 = dU[1][i] * dV[0][j];
|
|
135218
|
+
const w01 = dU[0][i] * dV[1][j];
|
|
135219
|
+
const w20 = dU[2][i] * dV[0][j];
|
|
135220
|
+
const w11 = dU[1][i] * dV[1][j];
|
|
135221
|
+
const w02 = dU[0][i] * dV[2][j];
|
|
135222
|
+
for (let c2 = 0; c2 < 3; c2++) {
|
|
135223
|
+
S[c2] += w00 * p2[c2];
|
|
135224
|
+
Su[c2] += w10 * p2[c2];
|
|
135225
|
+
Sv[c2] += w01 * p2[c2];
|
|
135226
|
+
Suu[c2] += w20 * p2[c2];
|
|
135227
|
+
Suv[c2] += w11 * p2[c2];
|
|
135228
|
+
Svv[c2] += w02 * p2[c2];
|
|
135229
|
+
}
|
|
135230
|
+
}
|
|
135231
|
+
}
|
|
135232
|
+
let nx = Su[1] * Sv[2] - Su[2] * Sv[1];
|
|
135233
|
+
let ny = Su[2] * Sv[0] - Su[0] * Sv[2];
|
|
135234
|
+
let nz = Su[0] * Sv[1] - Su[1] * Sv[0];
|
|
135235
|
+
const len2 = Math.hypot(nx, ny, nz) || 1;
|
|
135236
|
+
nx /= len2;
|
|
135237
|
+
ny /= len2;
|
|
135238
|
+
nz /= len2;
|
|
135239
|
+
return { S, Su, Sv, Suu, Suv, Svv, normal: [nx, ny, nz] };
|
|
135240
|
+
}
|
|
135241
|
+
function surfaceCurvature(jet) {
|
|
135242
|
+
const { Su, Sv, Suu, Suv, Svv, normal: normal2 } = jet;
|
|
135243
|
+
const E = Su[0] * Su[0] + Su[1] * Su[1] + Su[2] * Su[2];
|
|
135244
|
+
const F = Su[0] * Sv[0] + Su[1] * Sv[1] + Su[2] * Sv[2];
|
|
135245
|
+
const G = Sv[0] * Sv[0] + Sv[1] * Sv[1] + Sv[2] * Sv[2];
|
|
135246
|
+
const e = Suu[0] * normal2[0] + Suu[1] * normal2[1] + Suu[2] * normal2[2];
|
|
135247
|
+
const f3 = Suv[0] * normal2[0] + Suv[1] * normal2[1] + Suv[2] * normal2[2];
|
|
135248
|
+
const g2 = Svv[0] * normal2[0] + Svv[1] * normal2[1] + Svv[2] * normal2[2];
|
|
135249
|
+
const denom = E * G - F * F;
|
|
135250
|
+
if (Math.abs(denom) < 1e-20) return { k1: 0, k2: 0, K: 0, H: 0 };
|
|
135251
|
+
const K = (e * g2 - f3 * f3) / denom;
|
|
135252
|
+
const H = (e * G - 2 * f3 * F + g2 * E) / (2 * denom);
|
|
135253
|
+
const disc = Math.max(0, H * H - K);
|
|
135254
|
+
const root = Math.sqrt(disc);
|
|
135255
|
+
return { k1: H + root, k2: H - root, K, H };
|
|
135256
|
+
}
|
|
135257
|
+
function isVec3(v) {
|
|
135258
|
+
return Array.isArray(v) && v.length === 3 && typeof v[0] === "number" && typeof v[1] === "number" && typeof v[2] === "number";
|
|
135259
|
+
}
|
|
135260
|
+
function requireFiniteVec(p2, label) {
|
|
135261
|
+
for (let i = 0; i < 3; i++)
|
|
135262
|
+
if (!Number.isFinite(p2[i])) throw new Error(`Surface.Net: ${label} component ${i} must be finite, got ${p2[i]}`);
|
|
135263
|
+
return [p2[0], p2[1], p2[2]];
|
|
135264
|
+
}
|
|
135265
|
+
function toSampler(input, label) {
|
|
135266
|
+
if (input instanceof NurbsCurve3D) {
|
|
135267
|
+
return (t) => input.pointAt(t);
|
|
135268
|
+
}
|
|
135269
|
+
if (Array.isArray(input) && input.length > 0 && isVec3(input[0])) {
|
|
135270
|
+
const pts = input.map((p2, i) => requireFiniteVec(p2, `${label}[${i}]`));
|
|
135271
|
+
if (pts.length < 2) throw new Error(`Surface.Net: ${label} needs at least 2 points.`);
|
|
135272
|
+
if (pts.length === 2) {
|
|
135273
|
+
const [a2, b] = pts;
|
|
135274
|
+
return (t) => [a2[0] + (b[0] - a2[0]) * t, a2[1] + (b[1] - a2[1]) * t, a2[2] + (b[2] - a2[2]) * t];
|
|
135275
|
+
}
|
|
135276
|
+
const curve = globalCurveInterp(pts, Math.min(3, pts.length - 1));
|
|
135277
|
+
const nc = new NurbsCurve3D(curve.cps, { degree: curve.degree, knots: curve.knots });
|
|
135278
|
+
return (t) => nc.pointAt(t);
|
|
135279
|
+
}
|
|
135280
|
+
throw new Error(`Surface.Net: ${label} must be a Curve.Fit/Curve.Nurbs value or an array of [x,y,z] points.`);
|
|
135281
|
+
}
|
|
135282
|
+
function sampleCurve(sampler, count) {
|
|
135283
|
+
const out = [];
|
|
135284
|
+
for (let i = 0; i < count; i++) out.push(sampler(i / (count - 1)));
|
|
135285
|
+
return out;
|
|
135286
|
+
}
|
|
135287
|
+
const DEFAULT_THICKEN_RESOLUTION = 48;
|
|
135288
|
+
class Sheet {
|
|
135289
|
+
constructor(surface) {
|
|
135290
|
+
this.surface = surface;
|
|
135291
|
+
}
|
|
135292
|
+
/** Edge naming follows parameter direction (documented): front=v0, rear=v1, left=u0, right=u1. */
|
|
135293
|
+
get frontEdge() {
|
|
135294
|
+
return { sheet: this, fixed: "v", value: 0 };
|
|
135295
|
+
}
|
|
135296
|
+
get rearEdge() {
|
|
135297
|
+
return { sheet: this, fixed: "v", value: 1 };
|
|
135298
|
+
}
|
|
135299
|
+
get leftEdge() {
|
|
135300
|
+
return { sheet: this, fixed: "u", value: 0 };
|
|
135301
|
+
}
|
|
135302
|
+
get rightEdge() {
|
|
135303
|
+
return { sheet: this, fixed: "u", value: 1 };
|
|
135304
|
+
}
|
|
135305
|
+
pointAt(u2, v) {
|
|
135306
|
+
return evalSurface(this.surface, clamp01$2(u2), clamp01$2(v));
|
|
135307
|
+
}
|
|
135308
|
+
normalAt(u2, v) {
|
|
135309
|
+
return evalSurfaceJet(this.surface, clamp01$2(u2), clamp01$2(v)).normal;
|
|
135310
|
+
}
|
|
135311
|
+
curvatureAt(u2, v) {
|
|
135312
|
+
return surfaceCurvature(evalSurfaceJet(this.surface, clamp01$2(u2), clamp01$2(v)));
|
|
135313
|
+
}
|
|
135314
|
+
/** Largest principal curvature magnitude over a sampling grid (for offset safety). */
|
|
135315
|
+
maxAbsPrincipalCurvature(samples = 9) {
|
|
135316
|
+
let maxK = 0;
|
|
135317
|
+
for (let i = 0; i <= samples; i++) {
|
|
135318
|
+
for (let j = 0; j <= samples; j++) {
|
|
135319
|
+
const c2 = this.curvatureAt(i / samples, j / samples);
|
|
135320
|
+
maxK = Math.max(maxK, Math.abs(c2.k1), Math.abs(c2.k2));
|
|
135321
|
+
}
|
|
135322
|
+
}
|
|
135323
|
+
return maxK;
|
|
135324
|
+
}
|
|
135325
|
+
/**
|
|
135326
|
+
* Offset the sheet along its analytic normals into a watertight solid shell of
|
|
135327
|
+
* the given wall thickness. Throws if the wall would self-intersect on a
|
|
135328
|
+
* concave region (no silent degenerate solid).
|
|
135329
|
+
*/
|
|
135330
|
+
thicken(wall, options = {}) {
|
|
135331
|
+
if (!Number.isFinite(wall) || wall <= 0) throw new Error(`Sheet.thicken: wall must be a positive finite number, got ${wall}`);
|
|
135332
|
+
const maxK = this.maxAbsPrincipalCurvature();
|
|
135333
|
+
if (wall * maxK >= 1) {
|
|
135334
|
+
throw new Error(
|
|
135335
|
+
`Sheet.thicken: wall ${wall} exceeds the minimum radius of curvature (1/${maxK.toFixed(4)} = ${(1 / maxK).toFixed(3)}). The offset surface would self-intersect. Reduce the wall thickness or relax the curvature.`
|
|
135336
|
+
);
|
|
135337
|
+
}
|
|
135338
|
+
const resolution = options.resolution ?? DEFAULT_THICKEN_RESOLUTION;
|
|
135339
|
+
return nurbsSurface(this.surface.grid, {
|
|
135340
|
+
degreeU: this.surface.degreeU,
|
|
135341
|
+
degreeV: this.surface.degreeV,
|
|
135342
|
+
knotsU: this.surface.knotsU,
|
|
135343
|
+
knotsV: this.surface.knotsV,
|
|
135344
|
+
thickness: wall,
|
|
135345
|
+
resolution
|
|
135346
|
+
});
|
|
135347
|
+
}
|
|
135348
|
+
/** Per-edge continuity match against a neighbor (returns a NEW Sheet). */
|
|
135349
|
+
matchEdge(edge) {
|
|
135350
|
+
if (edge.sheet !== this) throw new Error("Sheet.matchEdge: the edge must belong to this sheet.");
|
|
135351
|
+
return new MatchEdgeBuilder(this, edge);
|
|
135352
|
+
}
|
|
135353
|
+
}
|
|
135354
|
+
function clamp01$2(t) {
|
|
135355
|
+
return t < 0 ? 0 : t > 1 ? 1 : t;
|
|
135356
|
+
}
|
|
135357
|
+
class CurveNetBuilder {
|
|
135358
|
+
constructor() {
|
|
135359
|
+
__publicField(this, "lengthwiseCurves", []);
|
|
135360
|
+
__publicField(this, "crosswiseCurves", []);
|
|
135361
|
+
__publicField(this, "railCurves", []);
|
|
135362
|
+
__publicField(this, "cageGrid", null);
|
|
135363
|
+
__publicField(this, "degU");
|
|
135364
|
+
__publicField(this, "degV");
|
|
135365
|
+
__publicField(this, "built", null);
|
|
135366
|
+
}
|
|
135367
|
+
lengthwise(...curves) {
|
|
135368
|
+
this.lengthwiseCurves = curves;
|
|
135369
|
+
this.built = null;
|
|
135370
|
+
return this;
|
|
135371
|
+
}
|
|
135372
|
+
crosswise(...curves) {
|
|
135373
|
+
this.crosswiseCurves = curves;
|
|
135374
|
+
this.built = null;
|
|
135375
|
+
return this;
|
|
135376
|
+
}
|
|
135377
|
+
alongRails(railA, railB) {
|
|
135378
|
+
this.railCurves = [railA, railB];
|
|
135379
|
+
this.built = null;
|
|
135380
|
+
return this;
|
|
135381
|
+
}
|
|
135382
|
+
sections(...curves) {
|
|
135383
|
+
this.crosswiseCurves = curves;
|
|
135384
|
+
this.built = null;
|
|
135385
|
+
return this;
|
|
135386
|
+
}
|
|
135387
|
+
cage(grid) {
|
|
135388
|
+
if (!Array.isArray(grid) || grid.length < 2 || !Array.isArray(grid[0]) || grid[0].length < 2) {
|
|
135389
|
+
throw new Error("Surface.Net().cage: grid must be at least a 2x2 array of [x,y,z] points.");
|
|
135390
|
+
}
|
|
135391
|
+
const cols = grid[0].length;
|
|
135392
|
+
this.cageGrid = grid.map((row, k2) => {
|
|
135393
|
+
if (row.length !== cols) throw new Error(`Surface.Net().cage: row ${k2} has ${row.length} points, expected ${cols}.`);
|
|
135394
|
+
return row.map((p2, l) => requireFiniteVec(p2, `cage[${k2}][${l}]`));
|
|
135395
|
+
});
|
|
135396
|
+
this.built = null;
|
|
135397
|
+
return this;
|
|
135398
|
+
}
|
|
135399
|
+
degree(u2, v) {
|
|
135400
|
+
if (!Number.isInteger(u2) || u2 < 1) throw new Error(`Surface.Net().degree: degree must be a positive integer, got ${u2}`);
|
|
135401
|
+
this.degU = u2;
|
|
135402
|
+
this.degV = v === void 0 ? u2 : v;
|
|
135403
|
+
if (v !== void 0 && (!Number.isInteger(v) || v < 1))
|
|
135404
|
+
throw new Error(`Surface.Net().degree: degree must be a positive integer, got ${v}`);
|
|
135405
|
+
this.built = null;
|
|
135406
|
+
return this;
|
|
135407
|
+
}
|
|
135408
|
+
/** Build (once) and return the Sheet. */
|
|
135409
|
+
toSheet() {
|
|
135410
|
+
if (this.built) return this.built;
|
|
135411
|
+
const grid = this.buildGrid();
|
|
135412
|
+
const m2 = grid.length - 1;
|
|
135413
|
+
const n = grid[0].length - 1;
|
|
135414
|
+
const degreeU = Math.max(1, Math.min(this.degU ?? 3, m2));
|
|
135415
|
+
const degreeV = Math.max(1, Math.min(this.degV ?? 3, n));
|
|
135416
|
+
const surface = buildGordonFromGrid(grid, degreeU, degreeV);
|
|
135417
|
+
this.built = new Sheet(surface);
|
|
135418
|
+
return this.built;
|
|
135419
|
+
}
|
|
135420
|
+
buildGrid() {
|
|
135421
|
+
if (this.cageGrid) return this.cageGrid;
|
|
135422
|
+
const lengthwise = this.railCurves.length > 0 ? this.railCurves : this.lengthwiseCurves;
|
|
135423
|
+
const crosswise = this.crosswiseCurves;
|
|
135424
|
+
const SAMPLES = 17;
|
|
135425
|
+
if (lengthwise.length >= 2) {
|
|
135426
|
+
const samplers = lengthwise.map((c2, l) => toSampler(c2, `lengthwise[${l}]`));
|
|
135427
|
+
const grid = [];
|
|
135428
|
+
for (let i = 0; i < SAMPLES; i++) {
|
|
135429
|
+
const u2 = i / (SAMPLES - 1);
|
|
135430
|
+
grid.push(samplers.map((s) => s(u2)));
|
|
135431
|
+
}
|
|
135432
|
+
return grid;
|
|
135433
|
+
}
|
|
135434
|
+
if (crosswise.length >= 2) {
|
|
135435
|
+
const samplers = crosswise.map((c2, k2) => toSampler(c2, `crosswise[${k2}]`));
|
|
135436
|
+
const grid = [];
|
|
135437
|
+
for (const s of samplers) grid.push(sampleCurve(s, SAMPLES));
|
|
135438
|
+
return grid;
|
|
135439
|
+
}
|
|
135440
|
+
throw new Error(
|
|
135441
|
+
"Surface.Net: provide a .cage(grid), or a family of at least 2 curves via .lengthwise(...) / .crosswise(...) / .alongRails(a,b).sections(...). Intersecting two independent hand-drawn families is not available yet — supply the denser family or a cage."
|
|
135442
|
+
);
|
|
135443
|
+
}
|
|
135444
|
+
// ── Sheet delegation (build on first access) ──────────────────────────────
|
|
135445
|
+
get frontEdge() {
|
|
135446
|
+
return this.toSheet().frontEdge;
|
|
135447
|
+
}
|
|
135448
|
+
get rearEdge() {
|
|
135449
|
+
return this.toSheet().rearEdge;
|
|
135450
|
+
}
|
|
135451
|
+
get leftEdge() {
|
|
135452
|
+
return this.toSheet().leftEdge;
|
|
135453
|
+
}
|
|
135454
|
+
get rightEdge() {
|
|
135455
|
+
return this.toSheet().rightEdge;
|
|
135456
|
+
}
|
|
135457
|
+
get surface() {
|
|
135458
|
+
return this.toSheet().surface;
|
|
135459
|
+
}
|
|
135460
|
+
pointAt(u2, v) {
|
|
135461
|
+
return this.toSheet().pointAt(u2, v);
|
|
135462
|
+
}
|
|
135463
|
+
normalAt(u2, v) {
|
|
135464
|
+
return this.toSheet().normalAt(u2, v);
|
|
135465
|
+
}
|
|
135466
|
+
curvatureAt(u2, v) {
|
|
135467
|
+
return this.toSheet().curvatureAt(u2, v);
|
|
135468
|
+
}
|
|
135469
|
+
thicken(wall, options) {
|
|
135470
|
+
return this.toSheet().thicken(wall, options);
|
|
135471
|
+
}
|
|
135472
|
+
matchEdge(edge) {
|
|
135473
|
+
return this.toSheet().matchEdge(edge);
|
|
135474
|
+
}
|
|
135475
|
+
}
|
|
135476
|
+
function createCurveNet() {
|
|
135477
|
+
return new CurveNetBuilder();
|
|
135478
|
+
}
|
|
135479
|
+
class MatchEdgeBuilder {
|
|
135480
|
+
constructor(sheet, edge) {
|
|
135481
|
+
this.sheet = sheet;
|
|
135482
|
+
this.edge = edge;
|
|
135483
|
+
}
|
|
135484
|
+
toG0(neighbor) {
|
|
135485
|
+
return applyEdgeMatch(this.sheet, this.edge, neighbor, 0);
|
|
135486
|
+
}
|
|
135487
|
+
toG1(neighbor) {
|
|
135488
|
+
return applyEdgeMatch(this.sheet, this.edge, neighbor, 1);
|
|
135489
|
+
}
|
|
135490
|
+
toG2(neighbor) {
|
|
135491
|
+
return applyEdgeMatch(this.sheet, this.edge, neighbor, 2);
|
|
135492
|
+
}
|
|
135493
|
+
}
|
|
135494
|
+
function boundaryRows(surf, fixed, value, depth) {
|
|
135495
|
+
const rows = [];
|
|
135496
|
+
if (fixed === "u") {
|
|
135497
|
+
const nU = surf.grid.length;
|
|
135498
|
+
for (let d2 = 0; d2 <= depth; d2++) {
|
|
135499
|
+
const i = value === 0 ? d2 : nU - 1 - d2;
|
|
135500
|
+
rows.push(surf.grid[i].map((p2) => [p2[0], p2[1], p2[2]]));
|
|
135501
|
+
}
|
|
135502
|
+
} else {
|
|
135503
|
+
const nV = surf.grid[0].length;
|
|
135504
|
+
for (let d2 = 0; d2 <= depth; d2++) {
|
|
135505
|
+
const j = value === 0 ? d2 : nV - 1 - d2;
|
|
135506
|
+
rows.push(surf.grid.map((p2) => [p2[j][0], p2[j][1], p2[j][2]]));
|
|
135507
|
+
}
|
|
135508
|
+
}
|
|
135509
|
+
return rows;
|
|
135510
|
+
}
|
|
135511
|
+
function setBoundaryRow(surf, fixed, value, depth, row) {
|
|
135512
|
+
if (fixed === "u") {
|
|
135513
|
+
const nU = surf.grid.length;
|
|
135514
|
+
const i = value === 0 ? depth : nU - 1 - depth;
|
|
135515
|
+
for (let l = 0; l < surf.grid[i].length; l++) surf.grid[i][l] = [row[l][0], row[l][1], row[l][2]];
|
|
135516
|
+
} else {
|
|
135517
|
+
const nV = surf.grid[0].length;
|
|
135518
|
+
const j = value === 0 ? depth : nV - 1 - depth;
|
|
135519
|
+
for (let k2 = 0; k2 < surf.grid.length; k2++) surf.grid[k2][j] = [row[k2][0], row[k2][1], row[k2][2]];
|
|
135520
|
+
}
|
|
135521
|
+
}
|
|
135522
|
+
function cloneSurface(surf) {
|
|
135523
|
+
return {
|
|
135524
|
+
grid: surf.grid.map((row) => row.map((p2) => [p2[0], p2[1], p2[2]])),
|
|
135525
|
+
knotsU: [...surf.knotsU],
|
|
135526
|
+
knotsV: [...surf.knotsV],
|
|
135527
|
+
degreeU: surf.degreeU,
|
|
135528
|
+
degreeV: surf.degreeV
|
|
135529
|
+
};
|
|
135530
|
+
}
|
|
135531
|
+
function applyEdgeMatch(sheet, edge, neighbor, order) {
|
|
135532
|
+
const result = cloneSurface(sheet.surface);
|
|
135533
|
+
const my = boundaryRows(result, edge.fixed, edge.value, order);
|
|
135534
|
+
const their = boundaryRows(neighbor.sheet.surface, neighbor.fixed, neighbor.value, order);
|
|
135535
|
+
if (my[0].length !== their[0].length) {
|
|
135536
|
+
throw new Error(
|
|
135537
|
+
`Sheet.matchEdge: edge control-point counts differ (${my[0].length} vs ${their[0].length}). Both sheets must share section sampling along the matched edge for continuity.`
|
|
135538
|
+
);
|
|
135539
|
+
}
|
|
135540
|
+
const len2 = my[0].length;
|
|
135541
|
+
const b0 = their[0].map((p2) => [p2[0], p2[1], p2[2]]);
|
|
135542
|
+
setBoundaryRow(result, edge.fixed, edge.value, 0, b0);
|
|
135543
|
+
if (order === 0) return new Sheet(result);
|
|
135544
|
+
const b1 = [];
|
|
135545
|
+
for (let i = 0; i < len2; i++) {
|
|
135546
|
+
const p0 = their[0][i];
|
|
135547
|
+
const p1 = their[1][i];
|
|
135548
|
+
b1.push([2 * p0[0] - p1[0], 2 * p0[1] - p1[1], 2 * p0[2] - p1[2]]);
|
|
135549
|
+
}
|
|
135550
|
+
setBoundaryRow(result, edge.fixed, edge.value, 1, b1);
|
|
135551
|
+
if (order === 1) return new Sheet(result);
|
|
135552
|
+
const b22 = [];
|
|
135553
|
+
for (let i = 0; i < len2; i++) {
|
|
135554
|
+
const p0 = their[0][i];
|
|
135555
|
+
const p1 = their[1][i];
|
|
135556
|
+
const p2 = their[2][i];
|
|
135557
|
+
b22.push([3 * p0[0] - 3 * p1[0] + p2[0], 3 * p0[1] - 3 * p1[1] + p2[1], 3 * p0[2] - 3 * p1[2] + p2[2]]);
|
|
135558
|
+
}
|
|
135559
|
+
setBoundaryRow(result, edge.fixed, edge.value, 2, b22);
|
|
135560
|
+
return new Sheet(result);
|
|
135561
|
+
}
|
|
135562
|
+
function edgeJet(edge, t) {
|
|
135563
|
+
const surf = edge.sheet.surface;
|
|
135564
|
+
if (edge.fixed === "u") {
|
|
135565
|
+
const j2 = evalSurfaceJet(surf, edge.value, clamp01$2(t));
|
|
135566
|
+
return { point: j2.S, cross: j2.Su, cross2: j2.Suu };
|
|
135567
|
+
}
|
|
135568
|
+
const j = evalSurfaceJet(surf, clamp01$2(t), edge.value);
|
|
135569
|
+
return { point: j.S, cross: j.Sv, cross2: j.Svv };
|
|
135570
|
+
}
|
|
135571
|
+
function sub3(a2, b) {
|
|
135572
|
+
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
135573
|
+
}
|
|
135574
|
+
function len3(a2) {
|
|
135575
|
+
return Math.hypot(a2[0], a2[1], a2[2]);
|
|
135576
|
+
}
|
|
135577
|
+
function unit3(a2) {
|
|
135578
|
+
const l = len3(a2) || 1;
|
|
135579
|
+
return [a2[0] / l, a2[1] / l, a2[2] / l];
|
|
135580
|
+
}
|
|
135581
|
+
function edgeMatchReport(edgeA, edgeB, samples = 24) {
|
|
135582
|
+
let maxPositionGap = 0;
|
|
135583
|
+
let maxTangentAngleDeg = 0;
|
|
135584
|
+
let maxCurvatureRelErr = 0;
|
|
135585
|
+
for (let i = 0; i <= samples; i++) {
|
|
135586
|
+
const t = i / samples;
|
|
135587
|
+
const a2 = edgeJet(edgeA, t);
|
|
135588
|
+
const b = edgeJet(edgeB, t);
|
|
135589
|
+
maxPositionGap = Math.max(maxPositionGap, len3(sub3(a2.point, b.point)));
|
|
135590
|
+
const ua = unit3(a2.cross);
|
|
135591
|
+
const ub = unit3(b.cross);
|
|
135592
|
+
const dot2 = Math.max(-1, Math.min(1, ua[0] * ub[0] + ua[1] * ub[1] + ua[2] * ub[2]));
|
|
135593
|
+
const angle = Math.acos(Math.abs(dot2)) * 180 / Math.PI;
|
|
135594
|
+
maxTangentAngleDeg = Math.max(maxTangentAngleDeg, angle);
|
|
135595
|
+
const la = len3(a2.cross) ** 2 || 1;
|
|
135596
|
+
const lb = len3(b.cross) ** 2 || 1;
|
|
135597
|
+
const ka = (a2.cross2[0] * ua[0] + a2.cross2[1] * ua[1] + a2.cross2[2] * ua[2]) / la;
|
|
135598
|
+
const kb = (b.cross2[0] * ub[0] + b.cross2[1] * ub[1] + b.cross2[2] * ub[2]) / lb;
|
|
135599
|
+
maxCurvatureRelErr = Math.max(maxCurvatureRelErr, Math.abs(ka - kb) / (Math.abs(ka) + Math.abs(kb) + 1e-9));
|
|
135600
|
+
}
|
|
135601
|
+
return { maxPositionGap, maxTangentAngleDeg, maxCurvatureRelErr };
|
|
135602
|
+
}
|
|
135603
|
+
function bridgeBetween(edgeA, edgeB) {
|
|
135604
|
+
return new BridgeBuilder(edgeA, edgeB);
|
|
135605
|
+
}
|
|
135606
|
+
class BridgeBuilder {
|
|
135607
|
+
constructor(edgeA, edgeB) {
|
|
135608
|
+
__publicField(this, "bulgeA", 0.5);
|
|
135609
|
+
__publicField(this, "bulgeB", 0.5);
|
|
135610
|
+
this.edgeA = edgeA;
|
|
135611
|
+
this.edgeB = edgeB;
|
|
135612
|
+
}
|
|
135613
|
+
/** Tune the influence of each side (Rhino-style bulge). */
|
|
135614
|
+
bulge(a2, b) {
|
|
135615
|
+
if (!Number.isFinite(a2) || !Number.isFinite(b)) throw new Error("Surfaces.bridge.bulge: both factors must be finite.");
|
|
135616
|
+
this.bulgeA = a2;
|
|
135617
|
+
this.bulgeB = b;
|
|
135618
|
+
return this;
|
|
135619
|
+
}
|
|
135620
|
+
g0() {
|
|
135621
|
+
return this.build(0);
|
|
135622
|
+
}
|
|
135623
|
+
g1() {
|
|
135624
|
+
return this.build(1);
|
|
135625
|
+
}
|
|
135626
|
+
g2() {
|
|
135627
|
+
return this.build(2);
|
|
135628
|
+
}
|
|
135629
|
+
build(order) {
|
|
135630
|
+
const SAMPLES = 21;
|
|
135631
|
+
const CROSS = 11;
|
|
135632
|
+
const cage = [];
|
|
135633
|
+
for (let i = 0; i < SAMPLES; i++) {
|
|
135634
|
+
const t = i / (SAMPLES - 1);
|
|
135635
|
+
const a2 = edgeJet(this.edgeA, t);
|
|
135636
|
+
const b = edgeJet(this.edgeB, t);
|
|
135637
|
+
const chord = len3(sub3(b.point, a2.point));
|
|
135638
|
+
const toward = unit3(sub3(b.point, a2.point));
|
|
135639
|
+
const tA = orientToward(unit3(a2.cross), toward);
|
|
135640
|
+
const tB = orientToward(unit3(b.cross), [-toward[0], -toward[1], -toward[2]]);
|
|
135641
|
+
const poles = bridgePoles(a2.point, b.point, tA, tB, chord, this.bulgeA, this.bulgeB, order);
|
|
135642
|
+
const row = [];
|
|
135643
|
+
for (let c2 = 0; c2 < CROSS; c2++) row.push(deCasteljau(poles, c2 / (CROSS - 1)));
|
|
135644
|
+
cage.push(row);
|
|
135645
|
+
}
|
|
135646
|
+
return new CurveNetBuilder().cage(cage).degree(Math.min(3, SAMPLES - 1), Math.min(2 * order + 1 || 1, CROSS - 1)).toSheet();
|
|
135647
|
+
}
|
|
135648
|
+
}
|
|
135649
|
+
function orientToward(v, toward) {
|
|
135650
|
+
const dot2 = v[0] * toward[0] + v[1] * toward[1] + v[2] * toward[2];
|
|
135651
|
+
return dot2 < 0 ? [-v[0], -v[1], -v[2]] : v;
|
|
135652
|
+
}
|
|
135653
|
+
function bridgePoles(a2, b, tA, tB, chord, bulgeA, bulgeB, order) {
|
|
135654
|
+
if (order === 0) return [a2, b];
|
|
135655
|
+
const dA = chord * bulgeA / (order === 1 ? 3 : 5);
|
|
135656
|
+
const dB = chord * bulgeB / (order === 1 ? 3 : 5);
|
|
135657
|
+
const a1 = [a2[0] + tA[0] * dA, a2[1] + tA[1] * dA, a2[2] + tA[2] * dA];
|
|
135658
|
+
const b1 = [b[0] + tB[0] * dB, b[1] + tB[1] * dB, b[2] + tB[2] * dB];
|
|
135659
|
+
if (order === 1) return [a2, a1, b1, b];
|
|
135660
|
+
const a22 = [a1[0] + tA[0] * dA, a1[1] + tA[1] * dA, a1[2] + tA[2] * dA];
|
|
135661
|
+
const b22 = [b1[0] + tB[0] * dB, b1[1] + tB[1] * dB, b1[2] + tB[2] * dB];
|
|
135662
|
+
return [a2, a1, a22, b22, b1, b];
|
|
135663
|
+
}
|
|
135664
|
+
function deCasteljau(poles, s) {
|
|
135665
|
+
let pts = poles.map((p2) => [p2[0], p2[1], p2[2]]);
|
|
135666
|
+
while (pts.length > 1) {
|
|
135667
|
+
const next = [];
|
|
135668
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
135669
|
+
next.push([
|
|
135670
|
+
pts[i][0] + (pts[i + 1][0] - pts[i][0]) * s,
|
|
135671
|
+
pts[i][1] + (pts[i + 1][1] - pts[i][1]) * s,
|
|
135672
|
+
pts[i][2] + (pts[i + 1][2] - pts[i][2]) * s
|
|
135673
|
+
]);
|
|
135674
|
+
}
|
|
135675
|
+
pts = next;
|
|
135676
|
+
}
|
|
135677
|
+
return pts[0];
|
|
135678
|
+
}
|
|
134993
135679
|
const CORNER_Y_ALPHA_ISSUE_URL = "https://github.com/KoStard/forgecad-private/issues/162";
|
|
134994
135680
|
function isVec3Array(value) {
|
|
134995
135681
|
return Array.isArray(value) && (value.length === 0 || Array.isArray(value[0]));
|
|
@@ -136381,7 +137067,16 @@ const Surface = {
|
|
|
136381
137067
|
"Surface.MatchEdge",
|
|
136382
137068
|
"Surface.Match()",
|
|
136383
137069
|
(shape, options) => Surface.Match(shape, options)
|
|
136384
|
-
)
|
|
137070
|
+
),
|
|
137071
|
+
/**
|
|
137072
|
+
* Begin a curve-network (Gordon) surface — the class-A keystone. Chain
|
|
137073
|
+
* `.lengthwise(...)/.crosswise(...)` (or `.alongRails(a,b).sections(...)`, or
|
|
137074
|
+
* `.cage(grid)`), then `.thicken(wall)` to get a solid Shape. Returns a fluent
|
|
137075
|
+
* `Sheet` builder with analytic point/normal/curvature queries and named edges.
|
|
137076
|
+
*/
|
|
137077
|
+
Net() {
|
|
137078
|
+
return createCurveNet();
|
|
137079
|
+
}
|
|
136385
137080
|
};
|
|
136386
137081
|
const Blend = {
|
|
136387
137082
|
Edge(options) {
|
|
@@ -136401,6 +137096,14 @@ const Blend = {
|
|
|
136401
137096
|
Surface(options) {
|
|
136402
137097
|
return Surface.Fill(options);
|
|
136403
137098
|
},
|
|
137099
|
+
/**
|
|
137100
|
+
* Build a transition strip between two `Surface.Net` sheet edges. Chain
|
|
137101
|
+
* `.bulge(a, b)` then `.g0()/.g1()/.g2()` for the continuity order. Returns a
|
|
137102
|
+
* `Sheet`; verify the seam with `Analysis.EdgeMatch`.
|
|
137103
|
+
*/
|
|
137104
|
+
Bridge(edgeA, edgeB) {
|
|
137105
|
+
return bridgeBetween(edgeA, edgeB);
|
|
137106
|
+
},
|
|
136404
137107
|
/**
|
|
136405
137108
|
* @alpha
|
|
136406
137109
|
* Current implementation uses continuity-controlled edge fillets on solid edges.
|
|
@@ -136435,6 +137138,14 @@ const Analysis = {
|
|
|
136435
137138
|
SurfaceContinuity(shape, options = {}) {
|
|
136436
137139
|
return evaluateEdgeContinuityReport(shape, options, "Analysis.SurfaceContinuity()");
|
|
136437
137140
|
},
|
|
137141
|
+
/**
|
|
137142
|
+
* Measure G0/G1/G2 agreement between two `Surface.Net` sheet edges: worst
|
|
137143
|
+
* position gap, cross-boundary tangent angle (0 = G1), and normal-curvature
|
|
137144
|
+
* mismatch (0 = G2). The reflection/fairness check for matched panel seams.
|
|
137145
|
+
*/
|
|
137146
|
+
EdgeMatch(edgeA, edgeB, options = {}) {
|
|
137147
|
+
return edgeMatchReport(edgeA, edgeB, options.samples);
|
|
137148
|
+
},
|
|
136438
137149
|
CurvatureComb(input, options = {}) {
|
|
136439
137150
|
if (input instanceof NurbsCurve3D) {
|
|
136440
137151
|
const count = Math.max(8, options.samples ?? 32);
|
|
@@ -140329,22 +141040,10 @@ function roundNum(n, digits = 4) {
|
|
|
140329
141040
|
return Number.isFinite(n) ? n.toFixed(digits).replace(/\.?0+$/, "") : String(n);
|
|
140330
141041
|
}
|
|
140331
141042
|
const COLLISION_OVERLAP_VOLUME_TOLERANCE = 1e-6;
|
|
140332
|
-
function meshDerivedManifoldBackend(shape) {
|
|
140333
|
-
const mesh = getShapeRuntimeBackend(shape).getMesh();
|
|
140334
|
-
return reconstructBackendFromMesh({
|
|
140335
|
-
numProp: mesh.numProp,
|
|
140336
|
-
triVerts: mesh.triVerts,
|
|
140337
|
-
vertProperties: mesh.vertProperties,
|
|
140338
|
-
mergeFromVert: mesh.mergeFromVert ?? new Uint32Array(),
|
|
140339
|
-
mergeToVert: mesh.mergeToVert ?? new Uint32Array()
|
|
140340
|
-
});
|
|
140341
|
-
}
|
|
140342
141043
|
function backendForMinGap(shape) {
|
|
140343
141044
|
const backend = getShapeRuntimeBackend(shape);
|
|
140344
141045
|
if (isManifoldCapableBackend(backend)) return { kind: "manifold", backend, method: "exact", dispose: false };
|
|
140345
|
-
|
|
140346
|
-
return { kind: "mesh", backend, method: "mesh-derived", dispose: false };
|
|
140347
|
-
return { kind: "manifold", backend: meshDerivedManifoldBackend(shape), method: "mesh-derived", dispose: true };
|
|
141046
|
+
return { kind: "mesh", backend, method: "mesh-derived", dispose: false };
|
|
140348
141047
|
}
|
|
140349
141048
|
function meshHasPointInsideSdf(source, target) {
|
|
140350
141049
|
const mesh = source.getMesh();
|
|
@@ -141600,7 +142299,6 @@ function resetExecutionSession(logs) {
|
|
|
141600
142299
|
resetHighlights();
|
|
141601
142300
|
resetBom();
|
|
141602
142301
|
resetSheetStock();
|
|
141603
|
-
resetRobotExport();
|
|
141604
142302
|
resetCutPlanes();
|
|
141605
142303
|
resetRenderLabels();
|
|
141606
142304
|
resetCameraTrajectory();
|
|
@@ -141683,7 +142381,6 @@ function collectSuccessfulExecutionSnapshot(args) {
|
|
|
141683
142381
|
jointsView: getCollectedJointsView(),
|
|
141684
142382
|
viewConfig: getCollectedViewConfig(),
|
|
141685
142383
|
sceneConfig: getCollectedScene(),
|
|
141686
|
-
robotExport: getCollectedRobotExport(),
|
|
141687
142384
|
quality: args.quality,
|
|
141688
142385
|
logs: args.logs.slice(),
|
|
141689
142386
|
verifications: getCollectedVerifications(),
|
|
@@ -141708,7 +142405,6 @@ function collectFailedExecutionSnapshot(args) {
|
|
|
141708
142405
|
jointsView: getCollectedJointsView(),
|
|
141709
142406
|
viewConfig: getCollectedViewConfig(),
|
|
141710
142407
|
sceneConfig: getCollectedScene(),
|
|
141711
|
-
robotExport: getCollectedRobotExport(),
|
|
141712
142408
|
quality: args.quality,
|
|
141713
142409
|
logs: args.logs.slice(),
|
|
141714
142410
|
verifications: getCollectedVerifications(),
|
|
@@ -355208,7 +355904,6 @@ function executeFile(code, fileName, allFiles, visited, scope = {}, options, exe
|
|
|
355208
355904
|
sketchToDxf,
|
|
355209
355905
|
bom,
|
|
355210
355906
|
sheetStock,
|
|
355211
|
-
robotExport,
|
|
355212
355907
|
Sim,
|
|
355213
355908
|
group,
|
|
355214
355909
|
ShapeGroup,
|
|
@@ -356075,6 +356770,1135 @@ function pointFromProjectedTriangle(u2, v, a2, normal2, uAxis, vAxis, dropAxis,
|
|
|
356075
356770
|
const dropped = axisValue(a2, dropAxis) - (axisValue(normal2, uAxis) * (u2 - axisValue(a2, uAxis)) + axisValue(normal2, vAxis) * (v - axisValue(a2, vAxis))) / axisValue(normal2, dropAxis);
|
|
356076
356771
|
setAxisValue(target, dropAxis, dropped);
|
|
356077
356772
|
}
|
|
356773
|
+
const VIRIDIS_256 = [
|
|
356774
|
+
[68, 1, 84],
|
|
356775
|
+
[68, 2, 86],
|
|
356776
|
+
[69, 4, 87],
|
|
356777
|
+
[69, 5, 89],
|
|
356778
|
+
[70, 7, 90],
|
|
356779
|
+
[70, 8, 92],
|
|
356780
|
+
[70, 10, 93],
|
|
356781
|
+
[70, 11, 94],
|
|
356782
|
+
[71, 13, 96],
|
|
356783
|
+
[71, 14, 97],
|
|
356784
|
+
[71, 16, 99],
|
|
356785
|
+
[71, 17, 100],
|
|
356786
|
+
[71, 19, 101],
|
|
356787
|
+
[72, 20, 103],
|
|
356788
|
+
[72, 22, 104],
|
|
356789
|
+
[72, 23, 105],
|
|
356790
|
+
[72, 24, 106],
|
|
356791
|
+
[72, 26, 108],
|
|
356792
|
+
[72, 27, 109],
|
|
356793
|
+
[72, 28, 110],
|
|
356794
|
+
[72, 29, 111],
|
|
356795
|
+
[72, 31, 112],
|
|
356796
|
+
[72, 32, 113],
|
|
356797
|
+
[72, 33, 115],
|
|
356798
|
+
[72, 35, 116],
|
|
356799
|
+
[72, 36, 117],
|
|
356800
|
+
[72, 37, 118],
|
|
356801
|
+
[72, 38, 119],
|
|
356802
|
+
[72, 40, 120],
|
|
356803
|
+
[72, 41, 121],
|
|
356804
|
+
[71, 42, 122],
|
|
356805
|
+
[71, 44, 122],
|
|
356806
|
+
[71, 45, 123],
|
|
356807
|
+
[71, 46, 124],
|
|
356808
|
+
[71, 47, 125],
|
|
356809
|
+
[70, 48, 126],
|
|
356810
|
+
[70, 50, 126],
|
|
356811
|
+
[70, 51, 127],
|
|
356812
|
+
[70, 52, 128],
|
|
356813
|
+
[69, 53, 129],
|
|
356814
|
+
[69, 55, 129],
|
|
356815
|
+
[69, 56, 130],
|
|
356816
|
+
[68, 57, 131],
|
|
356817
|
+
[68, 58, 131],
|
|
356818
|
+
[68, 59, 132],
|
|
356819
|
+
[67, 61, 132],
|
|
356820
|
+
[67, 62, 133],
|
|
356821
|
+
[66, 63, 133],
|
|
356822
|
+
[66, 64, 134],
|
|
356823
|
+
[66, 65, 134],
|
|
356824
|
+
[65, 66, 135],
|
|
356825
|
+
[65, 68, 135],
|
|
356826
|
+
[64, 69, 136],
|
|
356827
|
+
[64, 70, 136],
|
|
356828
|
+
[63, 71, 136],
|
|
356829
|
+
[63, 72, 137],
|
|
356830
|
+
[62, 73, 137],
|
|
356831
|
+
[62, 74, 137],
|
|
356832
|
+
[62, 76, 138],
|
|
356833
|
+
[61, 77, 138],
|
|
356834
|
+
[61, 78, 138],
|
|
356835
|
+
[60, 79, 138],
|
|
356836
|
+
[60, 80, 139],
|
|
356837
|
+
[59, 81, 139],
|
|
356838
|
+
[59, 82, 139],
|
|
356839
|
+
[58, 83, 139],
|
|
356840
|
+
[58, 84, 140],
|
|
356841
|
+
[57, 85, 140],
|
|
356842
|
+
[57, 86, 140],
|
|
356843
|
+
[56, 88, 140],
|
|
356844
|
+
[56, 89, 140],
|
|
356845
|
+
[55, 90, 140],
|
|
356846
|
+
[55, 91, 141],
|
|
356847
|
+
[54, 92, 141],
|
|
356848
|
+
[54, 93, 141],
|
|
356849
|
+
[53, 94, 141],
|
|
356850
|
+
[53, 95, 141],
|
|
356851
|
+
[52, 96, 141],
|
|
356852
|
+
[52, 97, 141],
|
|
356853
|
+
[51, 98, 141],
|
|
356854
|
+
[51, 99, 141],
|
|
356855
|
+
[50, 100, 142],
|
|
356856
|
+
[50, 101, 142],
|
|
356857
|
+
[49, 102, 142],
|
|
356858
|
+
[49, 103, 142],
|
|
356859
|
+
[49, 104, 142],
|
|
356860
|
+
[48, 105, 142],
|
|
356861
|
+
[48, 106, 142],
|
|
356862
|
+
[47, 107, 142],
|
|
356863
|
+
[47, 108, 142],
|
|
356864
|
+
[46, 109, 142],
|
|
356865
|
+
[46, 110, 142],
|
|
356866
|
+
[46, 111, 142],
|
|
356867
|
+
[45, 112, 142],
|
|
356868
|
+
[45, 113, 142],
|
|
356869
|
+
[44, 113, 142],
|
|
356870
|
+
[44, 114, 142],
|
|
356871
|
+
[44, 115, 142],
|
|
356872
|
+
[43, 116, 142],
|
|
356873
|
+
[43, 117, 142],
|
|
356874
|
+
[42, 118, 142],
|
|
356875
|
+
[42, 119, 142],
|
|
356876
|
+
[42, 120, 142],
|
|
356877
|
+
[41, 121, 142],
|
|
356878
|
+
[41, 122, 142],
|
|
356879
|
+
[41, 123, 142],
|
|
356880
|
+
[40, 124, 142],
|
|
356881
|
+
[40, 125, 142],
|
|
356882
|
+
[39, 126, 142],
|
|
356883
|
+
[39, 127, 142],
|
|
356884
|
+
[39, 128, 142],
|
|
356885
|
+
[38, 129, 142],
|
|
356886
|
+
[38, 130, 142],
|
|
356887
|
+
[38, 130, 142],
|
|
356888
|
+
[37, 131, 142],
|
|
356889
|
+
[37, 132, 142],
|
|
356890
|
+
[37, 133, 142],
|
|
356891
|
+
[36, 134, 142],
|
|
356892
|
+
[36, 135, 142],
|
|
356893
|
+
[35, 136, 142],
|
|
356894
|
+
[35, 137, 142],
|
|
356895
|
+
[35, 138, 141],
|
|
356896
|
+
[34, 139, 141],
|
|
356897
|
+
[34, 140, 141],
|
|
356898
|
+
[34, 141, 141],
|
|
356899
|
+
[33, 142, 141],
|
|
356900
|
+
[33, 143, 141],
|
|
356901
|
+
[33, 144, 141],
|
|
356902
|
+
[33, 145, 140],
|
|
356903
|
+
[32, 146, 140],
|
|
356904
|
+
[32, 146, 140],
|
|
356905
|
+
[32, 147, 140],
|
|
356906
|
+
[31, 148, 140],
|
|
356907
|
+
[31, 149, 139],
|
|
356908
|
+
[31, 150, 139],
|
|
356909
|
+
[31, 151, 139],
|
|
356910
|
+
[31, 152, 139],
|
|
356911
|
+
[31, 153, 138],
|
|
356912
|
+
[31, 154, 138],
|
|
356913
|
+
[30, 155, 138],
|
|
356914
|
+
[30, 156, 137],
|
|
356915
|
+
[30, 157, 137],
|
|
356916
|
+
[31, 158, 137],
|
|
356917
|
+
[31, 159, 136],
|
|
356918
|
+
[31, 160, 136],
|
|
356919
|
+
[31, 161, 136],
|
|
356920
|
+
[31, 161, 135],
|
|
356921
|
+
[31, 162, 135],
|
|
356922
|
+
[32, 163, 134],
|
|
356923
|
+
[32, 164, 134],
|
|
356924
|
+
[33, 165, 133],
|
|
356925
|
+
[33, 166, 133],
|
|
356926
|
+
[34, 167, 133],
|
|
356927
|
+
[34, 168, 132],
|
|
356928
|
+
[35, 169, 131],
|
|
356929
|
+
[36, 170, 131],
|
|
356930
|
+
[37, 171, 130],
|
|
356931
|
+
[37, 172, 130],
|
|
356932
|
+
[38, 173, 129],
|
|
356933
|
+
[39, 173, 129],
|
|
356934
|
+
[40, 174, 128],
|
|
356935
|
+
[41, 175, 127],
|
|
356936
|
+
[42, 176, 127],
|
|
356937
|
+
[44, 177, 126],
|
|
356938
|
+
[45, 178, 125],
|
|
356939
|
+
[46, 179, 124],
|
|
356940
|
+
[47, 180, 124],
|
|
356941
|
+
[49, 181, 123],
|
|
356942
|
+
[50, 182, 122],
|
|
356943
|
+
[52, 182, 121],
|
|
356944
|
+
[53, 183, 121],
|
|
356945
|
+
[55, 184, 120],
|
|
356946
|
+
[56, 185, 119],
|
|
356947
|
+
[58, 186, 118],
|
|
356948
|
+
[59, 187, 117],
|
|
356949
|
+
[61, 188, 116],
|
|
356950
|
+
[63, 188, 115],
|
|
356951
|
+
[64, 189, 114],
|
|
356952
|
+
[66, 190, 113],
|
|
356953
|
+
[68, 191, 112],
|
|
356954
|
+
[70, 192, 111],
|
|
356955
|
+
[72, 193, 110],
|
|
356956
|
+
[74, 193, 109],
|
|
356957
|
+
[76, 194, 108],
|
|
356958
|
+
[78, 195, 107],
|
|
356959
|
+
[80, 196, 106],
|
|
356960
|
+
[82, 197, 105],
|
|
356961
|
+
[84, 197, 104],
|
|
356962
|
+
[86, 198, 103],
|
|
356963
|
+
[88, 199, 101],
|
|
356964
|
+
[90, 200, 100],
|
|
356965
|
+
[92, 200, 99],
|
|
356966
|
+
[94, 201, 98],
|
|
356967
|
+
[96, 202, 96],
|
|
356968
|
+
[99, 203, 95],
|
|
356969
|
+
[101, 203, 94],
|
|
356970
|
+
[103, 204, 92],
|
|
356971
|
+
[105, 205, 91],
|
|
356972
|
+
[108, 205, 90],
|
|
356973
|
+
[110, 206, 88],
|
|
356974
|
+
[112, 207, 87],
|
|
356975
|
+
[115, 208, 86],
|
|
356976
|
+
[117, 208, 84],
|
|
356977
|
+
[119, 209, 83],
|
|
356978
|
+
[122, 209, 81],
|
|
356979
|
+
[124, 210, 80],
|
|
356980
|
+
[127, 211, 78],
|
|
356981
|
+
[129, 211, 77],
|
|
356982
|
+
[132, 212, 75],
|
|
356983
|
+
[134, 213, 73],
|
|
356984
|
+
[137, 213, 72],
|
|
356985
|
+
[139, 214, 70],
|
|
356986
|
+
[142, 214, 69],
|
|
356987
|
+
[144, 215, 67],
|
|
356988
|
+
[147, 215, 65],
|
|
356989
|
+
[149, 216, 64],
|
|
356990
|
+
[152, 216, 62],
|
|
356991
|
+
[155, 217, 60],
|
|
356992
|
+
[157, 217, 59],
|
|
356993
|
+
[160, 218, 57],
|
|
356994
|
+
[162, 218, 55],
|
|
356995
|
+
[165, 219, 54],
|
|
356996
|
+
[168, 219, 52],
|
|
356997
|
+
[170, 220, 50],
|
|
356998
|
+
[173, 220, 48],
|
|
356999
|
+
[176, 221, 47],
|
|
357000
|
+
[178, 221, 45],
|
|
357001
|
+
[181, 222, 43],
|
|
357002
|
+
[184, 222, 41],
|
|
357003
|
+
[186, 222, 40],
|
|
357004
|
+
[189, 223, 38],
|
|
357005
|
+
[192, 223, 37],
|
|
357006
|
+
[194, 223, 35],
|
|
357007
|
+
[197, 224, 33],
|
|
357008
|
+
[200, 224, 32],
|
|
357009
|
+
[202, 225, 31],
|
|
357010
|
+
[205, 225, 29],
|
|
357011
|
+
[208, 225, 28],
|
|
357012
|
+
[210, 226, 27],
|
|
357013
|
+
[213, 226, 26],
|
|
357014
|
+
[216, 226, 25],
|
|
357015
|
+
[218, 227, 25],
|
|
357016
|
+
[221, 227, 24],
|
|
357017
|
+
[223, 227, 24],
|
|
357018
|
+
[226, 228, 24],
|
|
357019
|
+
[229, 228, 25],
|
|
357020
|
+
[231, 228, 25],
|
|
357021
|
+
[234, 229, 26],
|
|
357022
|
+
[236, 229, 27],
|
|
357023
|
+
[239, 229, 28],
|
|
357024
|
+
[241, 229, 29],
|
|
357025
|
+
[244, 230, 30],
|
|
357026
|
+
[246, 230, 32],
|
|
357027
|
+
[248, 230, 33],
|
|
357028
|
+
[251, 231, 35],
|
|
357029
|
+
[253, 231, 37]
|
|
357030
|
+
];
|
|
357031
|
+
const INFERNO_256 = [
|
|
357032
|
+
[0, 0, 4],
|
|
357033
|
+
[1, 0, 5],
|
|
357034
|
+
[1, 1, 6],
|
|
357035
|
+
[1, 1, 8],
|
|
357036
|
+
[2, 1, 10],
|
|
357037
|
+
[2, 2, 12],
|
|
357038
|
+
[2, 2, 14],
|
|
357039
|
+
[3, 2, 16],
|
|
357040
|
+
[4, 3, 18],
|
|
357041
|
+
[4, 3, 20],
|
|
357042
|
+
[5, 4, 23],
|
|
357043
|
+
[6, 4, 25],
|
|
357044
|
+
[7, 5, 27],
|
|
357045
|
+
[8, 5, 29],
|
|
357046
|
+
[9, 6, 31],
|
|
357047
|
+
[10, 7, 34],
|
|
357048
|
+
[11, 7, 36],
|
|
357049
|
+
[12, 8, 38],
|
|
357050
|
+
[13, 8, 41],
|
|
357051
|
+
[14, 9, 43],
|
|
357052
|
+
[16, 9, 45],
|
|
357053
|
+
[17, 10, 48],
|
|
357054
|
+
[18, 10, 50],
|
|
357055
|
+
[20, 11, 52],
|
|
357056
|
+
[21, 11, 55],
|
|
357057
|
+
[22, 11, 57],
|
|
357058
|
+
[24, 12, 60],
|
|
357059
|
+
[25, 12, 62],
|
|
357060
|
+
[27, 12, 65],
|
|
357061
|
+
[28, 12, 67],
|
|
357062
|
+
[30, 12, 69],
|
|
357063
|
+
[31, 12, 72],
|
|
357064
|
+
[33, 12, 74],
|
|
357065
|
+
[35, 12, 76],
|
|
357066
|
+
[36, 12, 79],
|
|
357067
|
+
[38, 12, 81],
|
|
357068
|
+
[40, 11, 83],
|
|
357069
|
+
[41, 11, 85],
|
|
357070
|
+
[43, 11, 87],
|
|
357071
|
+
[45, 11, 89],
|
|
357072
|
+
[47, 10, 91],
|
|
357073
|
+
[49, 10, 92],
|
|
357074
|
+
[50, 10, 94],
|
|
357075
|
+
[52, 10, 95],
|
|
357076
|
+
[54, 9, 97],
|
|
357077
|
+
[56, 9, 98],
|
|
357078
|
+
[57, 9, 99],
|
|
357079
|
+
[59, 9, 100],
|
|
357080
|
+
[61, 9, 101],
|
|
357081
|
+
[62, 9, 102],
|
|
357082
|
+
[64, 10, 103],
|
|
357083
|
+
[66, 10, 104],
|
|
357084
|
+
[68, 10, 104],
|
|
357085
|
+
[69, 10, 105],
|
|
357086
|
+
[71, 11, 106],
|
|
357087
|
+
[73, 11, 106],
|
|
357088
|
+
[74, 12, 107],
|
|
357089
|
+
[76, 12, 107],
|
|
357090
|
+
[77, 13, 108],
|
|
357091
|
+
[79, 13, 108],
|
|
357092
|
+
[81, 14, 108],
|
|
357093
|
+
[82, 14, 109],
|
|
357094
|
+
[84, 15, 109],
|
|
357095
|
+
[85, 15, 109],
|
|
357096
|
+
[87, 16, 110],
|
|
357097
|
+
[89, 16, 110],
|
|
357098
|
+
[90, 17, 110],
|
|
357099
|
+
[92, 18, 110],
|
|
357100
|
+
[93, 18, 110],
|
|
357101
|
+
[95, 19, 110],
|
|
357102
|
+
[97, 19, 110],
|
|
357103
|
+
[98, 20, 110],
|
|
357104
|
+
[100, 21, 110],
|
|
357105
|
+
[101, 21, 110],
|
|
357106
|
+
[103, 22, 110],
|
|
357107
|
+
[105, 22, 110],
|
|
357108
|
+
[106, 23, 110],
|
|
357109
|
+
[108, 24, 110],
|
|
357110
|
+
[109, 24, 110],
|
|
357111
|
+
[111, 25, 110],
|
|
357112
|
+
[113, 25, 110],
|
|
357113
|
+
[114, 26, 110],
|
|
357114
|
+
[116, 26, 110],
|
|
357115
|
+
[117, 27, 110],
|
|
357116
|
+
[119, 28, 109],
|
|
357117
|
+
[120, 28, 109],
|
|
357118
|
+
[122, 29, 109],
|
|
357119
|
+
[124, 29, 109],
|
|
357120
|
+
[125, 30, 109],
|
|
357121
|
+
[127, 30, 108],
|
|
357122
|
+
[128, 31, 108],
|
|
357123
|
+
[130, 32, 108],
|
|
357124
|
+
[132, 32, 107],
|
|
357125
|
+
[133, 33, 107],
|
|
357126
|
+
[135, 33, 107],
|
|
357127
|
+
[136, 34, 106],
|
|
357128
|
+
[138, 34, 106],
|
|
357129
|
+
[140, 35, 105],
|
|
357130
|
+
[141, 35, 105],
|
|
357131
|
+
[143, 36, 105],
|
|
357132
|
+
[144, 37, 104],
|
|
357133
|
+
[146, 37, 104],
|
|
357134
|
+
[147, 38, 103],
|
|
357135
|
+
[149, 38, 103],
|
|
357136
|
+
[151, 39, 102],
|
|
357137
|
+
[152, 39, 102],
|
|
357138
|
+
[154, 40, 101],
|
|
357139
|
+
[155, 41, 100],
|
|
357140
|
+
[157, 41, 100],
|
|
357141
|
+
[159, 42, 99],
|
|
357142
|
+
[160, 42, 99],
|
|
357143
|
+
[162, 43, 98],
|
|
357144
|
+
[163, 44, 97],
|
|
357145
|
+
[165, 44, 96],
|
|
357146
|
+
[166, 45, 96],
|
|
357147
|
+
[168, 46, 95],
|
|
357148
|
+
[169, 46, 94],
|
|
357149
|
+
[171, 47, 94],
|
|
357150
|
+
[173, 48, 93],
|
|
357151
|
+
[174, 48, 92],
|
|
357152
|
+
[176, 49, 91],
|
|
357153
|
+
[177, 50, 90],
|
|
357154
|
+
[179, 50, 90],
|
|
357155
|
+
[180, 51, 89],
|
|
357156
|
+
[182, 52, 88],
|
|
357157
|
+
[183, 53, 87],
|
|
357158
|
+
[185, 53, 86],
|
|
357159
|
+
[186, 54, 85],
|
|
357160
|
+
[188, 55, 84],
|
|
357161
|
+
[189, 56, 83],
|
|
357162
|
+
[191, 57, 82],
|
|
357163
|
+
[192, 58, 81],
|
|
357164
|
+
[193, 58, 80],
|
|
357165
|
+
[195, 59, 79],
|
|
357166
|
+
[196, 60, 78],
|
|
357167
|
+
[198, 61, 77],
|
|
357168
|
+
[199, 62, 76],
|
|
357169
|
+
[200, 63, 75],
|
|
357170
|
+
[202, 64, 74],
|
|
357171
|
+
[203, 65, 73],
|
|
357172
|
+
[204, 66, 72],
|
|
357173
|
+
[206, 67, 71],
|
|
357174
|
+
[207, 68, 70],
|
|
357175
|
+
[208, 69, 69],
|
|
357176
|
+
[210, 70, 68],
|
|
357177
|
+
[211, 71, 67],
|
|
357178
|
+
[212, 72, 66],
|
|
357179
|
+
[213, 74, 65],
|
|
357180
|
+
[215, 75, 63],
|
|
357181
|
+
[216, 76, 62],
|
|
357182
|
+
[217, 77, 61],
|
|
357183
|
+
[218, 78, 60],
|
|
357184
|
+
[219, 80, 59],
|
|
357185
|
+
[221, 81, 58],
|
|
357186
|
+
[222, 82, 56],
|
|
357187
|
+
[223, 83, 55],
|
|
357188
|
+
[224, 85, 54],
|
|
357189
|
+
[225, 86, 53],
|
|
357190
|
+
[226, 87, 52],
|
|
357191
|
+
[227, 89, 51],
|
|
357192
|
+
[228, 90, 49],
|
|
357193
|
+
[229, 92, 48],
|
|
357194
|
+
[230, 93, 47],
|
|
357195
|
+
[231, 94, 46],
|
|
357196
|
+
[232, 96, 45],
|
|
357197
|
+
[233, 97, 43],
|
|
357198
|
+
[234, 99, 42],
|
|
357199
|
+
[235, 100, 41],
|
|
357200
|
+
[235, 102, 40],
|
|
357201
|
+
[236, 103, 38],
|
|
357202
|
+
[237, 105, 37],
|
|
357203
|
+
[238, 106, 36],
|
|
357204
|
+
[239, 108, 35],
|
|
357205
|
+
[239, 110, 33],
|
|
357206
|
+
[240, 111, 32],
|
|
357207
|
+
[241, 113, 31],
|
|
357208
|
+
[241, 115, 29],
|
|
357209
|
+
[242, 116, 28],
|
|
357210
|
+
[243, 118, 27],
|
|
357211
|
+
[243, 120, 25],
|
|
357212
|
+
[244, 121, 24],
|
|
357213
|
+
[245, 123, 23],
|
|
357214
|
+
[245, 125, 21],
|
|
357215
|
+
[246, 126, 20],
|
|
357216
|
+
[246, 128, 19],
|
|
357217
|
+
[247, 130, 18],
|
|
357218
|
+
[247, 132, 16],
|
|
357219
|
+
[248, 133, 15],
|
|
357220
|
+
[248, 135, 14],
|
|
357221
|
+
[248, 137, 12],
|
|
357222
|
+
[249, 139, 11],
|
|
357223
|
+
[249, 140, 10],
|
|
357224
|
+
[249, 142, 9],
|
|
357225
|
+
[250, 144, 8],
|
|
357226
|
+
[250, 146, 7],
|
|
357227
|
+
[250, 148, 7],
|
|
357228
|
+
[251, 150, 6],
|
|
357229
|
+
[251, 151, 6],
|
|
357230
|
+
[251, 153, 6],
|
|
357231
|
+
[251, 155, 6],
|
|
357232
|
+
[251, 157, 7],
|
|
357233
|
+
[252, 159, 7],
|
|
357234
|
+
[252, 161, 8],
|
|
357235
|
+
[252, 163, 9],
|
|
357236
|
+
[252, 165, 10],
|
|
357237
|
+
[252, 166, 12],
|
|
357238
|
+
[252, 168, 13],
|
|
357239
|
+
[252, 170, 15],
|
|
357240
|
+
[252, 172, 17],
|
|
357241
|
+
[252, 174, 18],
|
|
357242
|
+
[252, 176, 20],
|
|
357243
|
+
[252, 178, 22],
|
|
357244
|
+
[252, 180, 24],
|
|
357245
|
+
[251, 182, 26],
|
|
357246
|
+
[251, 184, 29],
|
|
357247
|
+
[251, 186, 31],
|
|
357248
|
+
[251, 188, 33],
|
|
357249
|
+
[251, 190, 35],
|
|
357250
|
+
[250, 192, 38],
|
|
357251
|
+
[250, 194, 40],
|
|
357252
|
+
[250, 196, 42],
|
|
357253
|
+
[250, 198, 45],
|
|
357254
|
+
[249, 199, 47],
|
|
357255
|
+
[249, 201, 50],
|
|
357256
|
+
[249, 203, 53],
|
|
357257
|
+
[248, 205, 55],
|
|
357258
|
+
[248, 207, 58],
|
|
357259
|
+
[247, 209, 61],
|
|
357260
|
+
[247, 211, 64],
|
|
357261
|
+
[246, 213, 67],
|
|
357262
|
+
[246, 215, 70],
|
|
357263
|
+
[245, 217, 73],
|
|
357264
|
+
[245, 219, 76],
|
|
357265
|
+
[244, 221, 79],
|
|
357266
|
+
[244, 223, 83],
|
|
357267
|
+
[244, 225, 86],
|
|
357268
|
+
[243, 227, 90],
|
|
357269
|
+
[243, 229, 93],
|
|
357270
|
+
[242, 230, 97],
|
|
357271
|
+
[242, 232, 101],
|
|
357272
|
+
[242, 234, 105],
|
|
357273
|
+
[241, 236, 109],
|
|
357274
|
+
[241, 237, 113],
|
|
357275
|
+
[241, 239, 117],
|
|
357276
|
+
[241, 241, 121],
|
|
357277
|
+
[242, 242, 125],
|
|
357278
|
+
[242, 244, 130],
|
|
357279
|
+
[243, 245, 134],
|
|
357280
|
+
[243, 246, 138],
|
|
357281
|
+
[244, 248, 142],
|
|
357282
|
+
[245, 249, 146],
|
|
357283
|
+
[246, 250, 150],
|
|
357284
|
+
[248, 251, 154],
|
|
357285
|
+
[249, 252, 157],
|
|
357286
|
+
[250, 253, 161],
|
|
357287
|
+
[252, 255, 164]
|
|
357288
|
+
];
|
|
357289
|
+
const TURBO_256 = [
|
|
357290
|
+
[48, 18, 59],
|
|
357291
|
+
[50, 21, 67],
|
|
357292
|
+
[51, 24, 74],
|
|
357293
|
+
[52, 27, 81],
|
|
357294
|
+
[53, 30, 88],
|
|
357295
|
+
[54, 33, 95],
|
|
357296
|
+
[55, 36, 102],
|
|
357297
|
+
[56, 39, 109],
|
|
357298
|
+
[57, 42, 115],
|
|
357299
|
+
[58, 45, 121],
|
|
357300
|
+
[59, 47, 128],
|
|
357301
|
+
[60, 50, 134],
|
|
357302
|
+
[61, 53, 139],
|
|
357303
|
+
[62, 56, 145],
|
|
357304
|
+
[63, 59, 151],
|
|
357305
|
+
[63, 62, 156],
|
|
357306
|
+
[64, 64, 162],
|
|
357307
|
+
[65, 67, 167],
|
|
357308
|
+
[65, 70, 172],
|
|
357309
|
+
[66, 73, 177],
|
|
357310
|
+
[66, 75, 181],
|
|
357311
|
+
[67, 78, 186],
|
|
357312
|
+
[68, 81, 191],
|
|
357313
|
+
[68, 84, 195],
|
|
357314
|
+
[68, 86, 199],
|
|
357315
|
+
[69, 89, 203],
|
|
357316
|
+
[69, 92, 207],
|
|
357317
|
+
[69, 94, 211],
|
|
357318
|
+
[70, 97, 214],
|
|
357319
|
+
[70, 100, 218],
|
|
357320
|
+
[70, 102, 221],
|
|
357321
|
+
[70, 105, 224],
|
|
357322
|
+
[70, 107, 227],
|
|
357323
|
+
[71, 110, 230],
|
|
357324
|
+
[71, 113, 233],
|
|
357325
|
+
[71, 115, 235],
|
|
357326
|
+
[71, 118, 238],
|
|
357327
|
+
[71, 120, 240],
|
|
357328
|
+
[71, 123, 242],
|
|
357329
|
+
[70, 125, 244],
|
|
357330
|
+
[70, 128, 246],
|
|
357331
|
+
[70, 130, 248],
|
|
357332
|
+
[70, 133, 250],
|
|
357333
|
+
[70, 135, 251],
|
|
357334
|
+
[69, 138, 252],
|
|
357335
|
+
[69, 140, 253],
|
|
357336
|
+
[68, 143, 254],
|
|
357337
|
+
[67, 145, 254],
|
|
357338
|
+
[66, 148, 255],
|
|
357339
|
+
[65, 150, 255],
|
|
357340
|
+
[64, 153, 255],
|
|
357341
|
+
[62, 155, 254],
|
|
357342
|
+
[61, 158, 254],
|
|
357343
|
+
[59, 160, 253],
|
|
357344
|
+
[58, 163, 252],
|
|
357345
|
+
[56, 165, 251],
|
|
357346
|
+
[55, 168, 250],
|
|
357347
|
+
[53, 171, 248],
|
|
357348
|
+
[51, 173, 247],
|
|
357349
|
+
[49, 175, 245],
|
|
357350
|
+
[47, 178, 244],
|
|
357351
|
+
[46, 180, 242],
|
|
357352
|
+
[44, 183, 240],
|
|
357353
|
+
[42, 185, 238],
|
|
357354
|
+
[40, 188, 235],
|
|
357355
|
+
[39, 190, 233],
|
|
357356
|
+
[37, 192, 231],
|
|
357357
|
+
[35, 195, 228],
|
|
357358
|
+
[34, 197, 226],
|
|
357359
|
+
[32, 199, 223],
|
|
357360
|
+
[31, 201, 221],
|
|
357361
|
+
[30, 203, 218],
|
|
357362
|
+
[28, 205, 216],
|
|
357363
|
+
[27, 208, 213],
|
|
357364
|
+
[26, 210, 210],
|
|
357365
|
+
[26, 212, 208],
|
|
357366
|
+
[25, 213, 205],
|
|
357367
|
+
[24, 215, 202],
|
|
357368
|
+
[24, 217, 200],
|
|
357369
|
+
[24, 219, 197],
|
|
357370
|
+
[24, 221, 194],
|
|
357371
|
+
[24, 222, 192],
|
|
357372
|
+
[24, 224, 189],
|
|
357373
|
+
[25, 226, 187],
|
|
357374
|
+
[25, 227, 185],
|
|
357375
|
+
[26, 228, 182],
|
|
357376
|
+
[28, 230, 180],
|
|
357377
|
+
[29, 231, 178],
|
|
357378
|
+
[31, 233, 175],
|
|
357379
|
+
[32, 234, 172],
|
|
357380
|
+
[34, 235, 170],
|
|
357381
|
+
[37, 236, 167],
|
|
357382
|
+
[39, 238, 164],
|
|
357383
|
+
[42, 239, 161],
|
|
357384
|
+
[44, 240, 158],
|
|
357385
|
+
[47, 241, 155],
|
|
357386
|
+
[50, 242, 152],
|
|
357387
|
+
[53, 243, 148],
|
|
357388
|
+
[56, 244, 145],
|
|
357389
|
+
[60, 245, 142],
|
|
357390
|
+
[63, 246, 138],
|
|
357391
|
+
[67, 247, 135],
|
|
357392
|
+
[70, 248, 132],
|
|
357393
|
+
[74, 248, 128],
|
|
357394
|
+
[78, 249, 125],
|
|
357395
|
+
[82, 250, 122],
|
|
357396
|
+
[85, 250, 118],
|
|
357397
|
+
[89, 251, 115],
|
|
357398
|
+
[93, 252, 111],
|
|
357399
|
+
[97, 252, 108],
|
|
357400
|
+
[101, 253, 105],
|
|
357401
|
+
[105, 253, 102],
|
|
357402
|
+
[109, 254, 98],
|
|
357403
|
+
[113, 254, 95],
|
|
357404
|
+
[117, 254, 92],
|
|
357405
|
+
[121, 254, 89],
|
|
357406
|
+
[125, 255, 86],
|
|
357407
|
+
[128, 255, 83],
|
|
357408
|
+
[132, 255, 81],
|
|
357409
|
+
[136, 255, 78],
|
|
357410
|
+
[139, 255, 75],
|
|
357411
|
+
[143, 255, 73],
|
|
357412
|
+
[146, 255, 71],
|
|
357413
|
+
[150, 254, 68],
|
|
357414
|
+
[153, 254, 66],
|
|
357415
|
+
[156, 254, 64],
|
|
357416
|
+
[159, 253, 63],
|
|
357417
|
+
[161, 253, 61],
|
|
357418
|
+
[164, 252, 60],
|
|
357419
|
+
[167, 252, 58],
|
|
357420
|
+
[169, 251, 57],
|
|
357421
|
+
[172, 251, 56],
|
|
357422
|
+
[175, 250, 55],
|
|
357423
|
+
[177, 249, 54],
|
|
357424
|
+
[180, 248, 54],
|
|
357425
|
+
[183, 247, 53],
|
|
357426
|
+
[185, 246, 53],
|
|
357427
|
+
[188, 245, 52],
|
|
357428
|
+
[190, 244, 52],
|
|
357429
|
+
[193, 243, 52],
|
|
357430
|
+
[195, 241, 52],
|
|
357431
|
+
[198, 240, 52],
|
|
357432
|
+
[200, 239, 52],
|
|
357433
|
+
[203, 237, 52],
|
|
357434
|
+
[205, 236, 52],
|
|
357435
|
+
[208, 234, 52],
|
|
357436
|
+
[210, 233, 53],
|
|
357437
|
+
[212, 231, 53],
|
|
357438
|
+
[215, 229, 53],
|
|
357439
|
+
[217, 228, 54],
|
|
357440
|
+
[219, 226, 54],
|
|
357441
|
+
[221, 224, 55],
|
|
357442
|
+
[223, 223, 55],
|
|
357443
|
+
[225, 221, 55],
|
|
357444
|
+
[227, 219, 56],
|
|
357445
|
+
[229, 217, 56],
|
|
357446
|
+
[231, 215, 57],
|
|
357447
|
+
[233, 213, 57],
|
|
357448
|
+
[235, 211, 57],
|
|
357449
|
+
[236, 209, 58],
|
|
357450
|
+
[238, 207, 58],
|
|
357451
|
+
[239, 205, 58],
|
|
357452
|
+
[241, 203, 58],
|
|
357453
|
+
[242, 201, 58],
|
|
357454
|
+
[244, 199, 58],
|
|
357455
|
+
[245, 197, 58],
|
|
357456
|
+
[246, 195, 58],
|
|
357457
|
+
[247, 193, 58],
|
|
357458
|
+
[248, 190, 57],
|
|
357459
|
+
[249, 188, 57],
|
|
357460
|
+
[250, 186, 57],
|
|
357461
|
+
[251, 184, 56],
|
|
357462
|
+
[251, 182, 55],
|
|
357463
|
+
[252, 179, 54],
|
|
357464
|
+
[252, 177, 54],
|
|
357465
|
+
[253, 174, 53],
|
|
357466
|
+
[253, 172, 52],
|
|
357467
|
+
[254, 169, 51],
|
|
357468
|
+
[254, 167, 50],
|
|
357469
|
+
[254, 164, 49],
|
|
357470
|
+
[254, 161, 48],
|
|
357471
|
+
[254, 158, 47],
|
|
357472
|
+
[254, 155, 45],
|
|
357473
|
+
[254, 153, 44],
|
|
357474
|
+
[254, 150, 43],
|
|
357475
|
+
[254, 147, 42],
|
|
357476
|
+
[254, 144, 41],
|
|
357477
|
+
[253, 141, 39],
|
|
357478
|
+
[253, 138, 38],
|
|
357479
|
+
[252, 135, 37],
|
|
357480
|
+
[252, 132, 35],
|
|
357481
|
+
[251, 129, 34],
|
|
357482
|
+
[251, 126, 33],
|
|
357483
|
+
[250, 123, 31],
|
|
357484
|
+
[249, 120, 30],
|
|
357485
|
+
[249, 117, 29],
|
|
357486
|
+
[248, 114, 28],
|
|
357487
|
+
[247, 111, 26],
|
|
357488
|
+
[246, 108, 25],
|
|
357489
|
+
[245, 105, 24],
|
|
357490
|
+
[244, 102, 23],
|
|
357491
|
+
[243, 99, 21],
|
|
357492
|
+
[242, 96, 20],
|
|
357493
|
+
[241, 93, 19],
|
|
357494
|
+
[240, 91, 18],
|
|
357495
|
+
[239, 88, 17],
|
|
357496
|
+
[237, 85, 16],
|
|
357497
|
+
[236, 83, 15],
|
|
357498
|
+
[235, 80, 14],
|
|
357499
|
+
[234, 78, 13],
|
|
357500
|
+
[232, 75, 12],
|
|
357501
|
+
[231, 73, 12],
|
|
357502
|
+
[229, 71, 11],
|
|
357503
|
+
[228, 69, 10],
|
|
357504
|
+
[226, 67, 10],
|
|
357505
|
+
[225, 65, 9],
|
|
357506
|
+
[223, 63, 8],
|
|
357507
|
+
[221, 61, 8],
|
|
357508
|
+
[220, 59, 7],
|
|
357509
|
+
[218, 57, 7],
|
|
357510
|
+
[216, 55, 6],
|
|
357511
|
+
[214, 53, 6],
|
|
357512
|
+
[212, 51, 5],
|
|
357513
|
+
[210, 49, 5],
|
|
357514
|
+
[208, 47, 5],
|
|
357515
|
+
[206, 45, 4],
|
|
357516
|
+
[204, 43, 4],
|
|
357517
|
+
[202, 42, 4],
|
|
357518
|
+
[200, 40, 3],
|
|
357519
|
+
[197, 38, 3],
|
|
357520
|
+
[195, 37, 3],
|
|
357521
|
+
[193, 35, 2],
|
|
357522
|
+
[190, 33, 2],
|
|
357523
|
+
[188, 32, 2],
|
|
357524
|
+
[185, 30, 2],
|
|
357525
|
+
[183, 29, 2],
|
|
357526
|
+
[180, 27, 1],
|
|
357527
|
+
[178, 26, 1],
|
|
357528
|
+
[175, 24, 1],
|
|
357529
|
+
[172, 23, 1],
|
|
357530
|
+
[169, 22, 1],
|
|
357531
|
+
[167, 20, 1],
|
|
357532
|
+
[164, 19, 1],
|
|
357533
|
+
[161, 18, 1],
|
|
357534
|
+
[158, 16, 1],
|
|
357535
|
+
[155, 15, 1],
|
|
357536
|
+
[152, 14, 1],
|
|
357537
|
+
[149, 13, 1],
|
|
357538
|
+
[146, 11, 1],
|
|
357539
|
+
[142, 10, 1],
|
|
357540
|
+
[139, 9, 2],
|
|
357541
|
+
[136, 8, 2],
|
|
357542
|
+
[133, 7, 2],
|
|
357543
|
+
[129, 6, 2],
|
|
357544
|
+
[126, 5, 2],
|
|
357545
|
+
[122, 4, 3]
|
|
357546
|
+
];
|
|
357547
|
+
const COOLWARM_256 = [
|
|
357548
|
+
[59, 76, 192],
|
|
357549
|
+
[60, 78, 194],
|
|
357550
|
+
[61, 80, 195],
|
|
357551
|
+
[62, 81, 197],
|
|
357552
|
+
[63, 83, 198],
|
|
357553
|
+
[64, 85, 200],
|
|
357554
|
+
[66, 87, 201],
|
|
357555
|
+
[67, 88, 203],
|
|
357556
|
+
[68, 90, 204],
|
|
357557
|
+
[69, 92, 206],
|
|
357558
|
+
[70, 94, 207],
|
|
357559
|
+
[72, 95, 209],
|
|
357560
|
+
[73, 97, 210],
|
|
357561
|
+
[74, 99, 211],
|
|
357562
|
+
[75, 100, 213],
|
|
357563
|
+
[76, 102, 214],
|
|
357564
|
+
[78, 104, 216],
|
|
357565
|
+
[79, 105, 217],
|
|
357566
|
+
[80, 107, 218],
|
|
357567
|
+
[81, 109, 219],
|
|
357568
|
+
[83, 110, 221],
|
|
357569
|
+
[84, 112, 222],
|
|
357570
|
+
[85, 114, 223],
|
|
357571
|
+
[86, 115, 224],
|
|
357572
|
+
[88, 117, 225],
|
|
357573
|
+
[89, 119, 227],
|
|
357574
|
+
[90, 120, 228],
|
|
357575
|
+
[91, 122, 229],
|
|
357576
|
+
[93, 124, 230],
|
|
357577
|
+
[94, 125, 231],
|
|
357578
|
+
[95, 127, 232],
|
|
357579
|
+
[97, 128, 233],
|
|
357580
|
+
[98, 130, 234],
|
|
357581
|
+
[99, 132, 235],
|
|
357582
|
+
[100, 133, 236],
|
|
357583
|
+
[102, 135, 237],
|
|
357584
|
+
[103, 136, 238],
|
|
357585
|
+
[104, 138, 239],
|
|
357586
|
+
[106, 139, 239],
|
|
357587
|
+
[107, 141, 240],
|
|
357588
|
+
[108, 143, 241],
|
|
357589
|
+
[110, 144, 242],
|
|
357590
|
+
[111, 146, 243],
|
|
357591
|
+
[112, 147, 243],
|
|
357592
|
+
[114, 149, 244],
|
|
357593
|
+
[115, 150, 245],
|
|
357594
|
+
[117, 151, 246],
|
|
357595
|
+
[118, 153, 246],
|
|
357596
|
+
[119, 154, 247],
|
|
357597
|
+
[121, 156, 248],
|
|
357598
|
+
[122, 157, 248],
|
|
357599
|
+
[123, 159, 249],
|
|
357600
|
+
[125, 160, 249],
|
|
357601
|
+
[126, 161, 250],
|
|
357602
|
+
[128, 163, 250],
|
|
357603
|
+
[129, 164, 251],
|
|
357604
|
+
[130, 166, 251],
|
|
357605
|
+
[132, 167, 252],
|
|
357606
|
+
[133, 168, 252],
|
|
357607
|
+
[134, 169, 252],
|
|
357608
|
+
[136, 171, 253],
|
|
357609
|
+
[137, 172, 253],
|
|
357610
|
+
[139, 173, 253],
|
|
357611
|
+
[140, 175, 254],
|
|
357612
|
+
[141, 176, 254],
|
|
357613
|
+
[143, 177, 254],
|
|
357614
|
+
[144, 178, 254],
|
|
357615
|
+
[146, 180, 254],
|
|
357616
|
+
[147, 181, 254],
|
|
357617
|
+
[148, 182, 255],
|
|
357618
|
+
[150, 183, 255],
|
|
357619
|
+
[151, 184, 255],
|
|
357620
|
+
[152, 185, 255],
|
|
357621
|
+
[154, 187, 255],
|
|
357622
|
+
[155, 188, 255],
|
|
357623
|
+
[157, 189, 255],
|
|
357624
|
+
[158, 190, 255],
|
|
357625
|
+
[159, 191, 255],
|
|
357626
|
+
[161, 192, 255],
|
|
357627
|
+
[162, 193, 255],
|
|
357628
|
+
[163, 194, 254],
|
|
357629
|
+
[165, 195, 254],
|
|
357630
|
+
[166, 196, 254],
|
|
357631
|
+
[167, 197, 254],
|
|
357632
|
+
[169, 198, 253],
|
|
357633
|
+
[170, 199, 253],
|
|
357634
|
+
[171, 200, 253],
|
|
357635
|
+
[173, 201, 253],
|
|
357636
|
+
[174, 201, 252],
|
|
357637
|
+
[175, 202, 252],
|
|
357638
|
+
[177, 203, 252],
|
|
357639
|
+
[178, 204, 251],
|
|
357640
|
+
[179, 205, 251],
|
|
357641
|
+
[181, 205, 250],
|
|
357642
|
+
[182, 206, 250],
|
|
357643
|
+
[183, 207, 249],
|
|
357644
|
+
[185, 208, 249],
|
|
357645
|
+
[186, 208, 248],
|
|
357646
|
+
[187, 209, 248],
|
|
357647
|
+
[188, 210, 247],
|
|
357648
|
+
[190, 210, 246],
|
|
357649
|
+
[191, 211, 246],
|
|
357650
|
+
[192, 212, 245],
|
|
357651
|
+
[193, 212, 244],
|
|
357652
|
+
[195, 213, 244],
|
|
357653
|
+
[196, 213, 243],
|
|
357654
|
+
[197, 214, 242],
|
|
357655
|
+
[198, 214, 241],
|
|
357656
|
+
[199, 215, 240],
|
|
357657
|
+
[201, 215, 240],
|
|
357658
|
+
[202, 216, 239],
|
|
357659
|
+
[203, 216, 238],
|
|
357660
|
+
[204, 217, 237],
|
|
357661
|
+
[205, 217, 236],
|
|
357662
|
+
[206, 218, 235],
|
|
357663
|
+
[207, 218, 234],
|
|
357664
|
+
[209, 218, 233],
|
|
357665
|
+
[210, 219, 232],
|
|
357666
|
+
[211, 219, 231],
|
|
357667
|
+
[212, 219, 230],
|
|
357668
|
+
[213, 219, 229],
|
|
357669
|
+
[214, 220, 228],
|
|
357670
|
+
[215, 220, 227],
|
|
357671
|
+
[216, 220, 226],
|
|
357672
|
+
[217, 220, 225],
|
|
357673
|
+
[218, 220, 224],
|
|
357674
|
+
[219, 220, 222],
|
|
357675
|
+
[220, 221, 221],
|
|
357676
|
+
[221, 220, 220],
|
|
357677
|
+
[222, 220, 219],
|
|
357678
|
+
[223, 219, 217],
|
|
357679
|
+
[224, 219, 216],
|
|
357680
|
+
[225, 218, 214],
|
|
357681
|
+
[226, 218, 213],
|
|
357682
|
+
[227, 217, 211],
|
|
357683
|
+
[228, 217, 210],
|
|
357684
|
+
[229, 216, 209],
|
|
357685
|
+
[230, 215, 207],
|
|
357686
|
+
[231, 215, 206],
|
|
357687
|
+
[232, 214, 204],
|
|
357688
|
+
[233, 213, 203],
|
|
357689
|
+
[234, 213, 201],
|
|
357690
|
+
[234, 212, 200],
|
|
357691
|
+
[235, 211, 198],
|
|
357692
|
+
[236, 211, 197],
|
|
357693
|
+
[237, 210, 195],
|
|
357694
|
+
[237, 209, 194],
|
|
357695
|
+
[238, 208, 192],
|
|
357696
|
+
[239, 207, 191],
|
|
357697
|
+
[239, 206, 189],
|
|
357698
|
+
[240, 205, 187],
|
|
357699
|
+
[241, 205, 186],
|
|
357700
|
+
[241, 204, 184],
|
|
357701
|
+
[242, 203, 183],
|
|
357702
|
+
[242, 202, 181],
|
|
357703
|
+
[242, 201, 180],
|
|
357704
|
+
[243, 200, 178],
|
|
357705
|
+
[243, 199, 177],
|
|
357706
|
+
[244, 198, 175],
|
|
357707
|
+
[244, 197, 173],
|
|
357708
|
+
[245, 196, 172],
|
|
357709
|
+
[245, 194, 170],
|
|
357710
|
+
[245, 193, 169],
|
|
357711
|
+
[245, 192, 167],
|
|
357712
|
+
[246, 191, 166],
|
|
357713
|
+
[246, 190, 164],
|
|
357714
|
+
[246, 189, 162],
|
|
357715
|
+
[247, 188, 161],
|
|
357716
|
+
[247, 186, 159],
|
|
357717
|
+
[247, 185, 158],
|
|
357718
|
+
[247, 184, 156],
|
|
357719
|
+
[247, 183, 155],
|
|
357720
|
+
[247, 181, 153],
|
|
357721
|
+
[247, 180, 151],
|
|
357722
|
+
[247, 179, 150],
|
|
357723
|
+
[247, 177, 148],
|
|
357724
|
+
[247, 176, 147],
|
|
357725
|
+
[247, 175, 145],
|
|
357726
|
+
[247, 173, 144],
|
|
357727
|
+
[247, 172, 142],
|
|
357728
|
+
[247, 170, 140],
|
|
357729
|
+
[247, 169, 139],
|
|
357730
|
+
[247, 168, 137],
|
|
357731
|
+
[247, 166, 136],
|
|
357732
|
+
[246, 165, 134],
|
|
357733
|
+
[246, 163, 133],
|
|
357734
|
+
[246, 162, 131],
|
|
357735
|
+
[245, 160, 129],
|
|
357736
|
+
[245, 159, 128],
|
|
357737
|
+
[245, 157, 126],
|
|
357738
|
+
[245, 156, 125],
|
|
357739
|
+
[244, 154, 123],
|
|
357740
|
+
[244, 152, 122],
|
|
357741
|
+
[243, 151, 120],
|
|
357742
|
+
[243, 149, 119],
|
|
357743
|
+
[243, 148, 117],
|
|
357744
|
+
[242, 146, 116],
|
|
357745
|
+
[242, 144, 114],
|
|
357746
|
+
[241, 143, 113],
|
|
357747
|
+
[241, 141, 111],
|
|
357748
|
+
[240, 139, 110],
|
|
357749
|
+
[240, 138, 108],
|
|
357750
|
+
[239, 136, 107],
|
|
357751
|
+
[238, 134, 105],
|
|
357752
|
+
[238, 132, 104],
|
|
357753
|
+
[237, 131, 102],
|
|
357754
|
+
[236, 129, 101],
|
|
357755
|
+
[236, 127, 99],
|
|
357756
|
+
[235, 125, 98],
|
|
357757
|
+
[234, 123, 96],
|
|
357758
|
+
[233, 122, 95],
|
|
357759
|
+
[233, 120, 93],
|
|
357760
|
+
[232, 118, 92],
|
|
357761
|
+
[231, 116, 91],
|
|
357762
|
+
[230, 114, 89],
|
|
357763
|
+
[229, 112, 88],
|
|
357764
|
+
[228, 110, 86],
|
|
357765
|
+
[227, 108, 85],
|
|
357766
|
+
[227, 107, 84],
|
|
357767
|
+
[226, 105, 82],
|
|
357768
|
+
[225, 103, 81],
|
|
357769
|
+
[224, 101, 79],
|
|
357770
|
+
[223, 99, 78],
|
|
357771
|
+
[222, 97, 77],
|
|
357772
|
+
[221, 95, 75],
|
|
357773
|
+
[220, 93, 74],
|
|
357774
|
+
[218, 90, 73],
|
|
357775
|
+
[217, 88, 71],
|
|
357776
|
+
[216, 86, 70],
|
|
357777
|
+
[215, 84, 69],
|
|
357778
|
+
[214, 82, 68],
|
|
357779
|
+
[213, 80, 66],
|
|
357780
|
+
[212, 78, 65],
|
|
357781
|
+
[210, 75, 64],
|
|
357782
|
+
[209, 73, 63],
|
|
357783
|
+
[208, 71, 61],
|
|
357784
|
+
[207, 69, 60],
|
|
357785
|
+
[205, 66, 59],
|
|
357786
|
+
[204, 64, 58],
|
|
357787
|
+
[203, 62, 56],
|
|
357788
|
+
[202, 59, 55],
|
|
357789
|
+
[200, 56, 54],
|
|
357790
|
+
[199, 54, 53],
|
|
357791
|
+
[197, 51, 52],
|
|
357792
|
+
[196, 48, 50],
|
|
357793
|
+
[195, 46, 49],
|
|
357794
|
+
[193, 43, 48],
|
|
357795
|
+
[192, 40, 47],
|
|
357796
|
+
[190, 36, 46],
|
|
357797
|
+
[189, 31, 45],
|
|
357798
|
+
[187, 27, 44],
|
|
357799
|
+
[186, 22, 43],
|
|
357800
|
+
[184, 18, 42],
|
|
357801
|
+
[183, 13, 40],
|
|
357802
|
+
[181, 9, 39],
|
|
357803
|
+
[180, 4, 38]
|
|
357804
|
+
];
|
|
357805
|
+
const COLOR_SCALE_LUT_SIZE = 256;
|
|
357806
|
+
const THICKNESS_CLASSIC_STOPS = [
|
|
357807
|
+
[255, 28, 28],
|
|
357808
|
+
[255, 222, 0],
|
|
357809
|
+
[60, 220, 90],
|
|
357810
|
+
[70, 145, 255]
|
|
357811
|
+
];
|
|
357812
|
+
const COLORMAP_STOPS = {
|
|
357813
|
+
viridis: VIRIDIS_256,
|
|
357814
|
+
inferno: INFERNO_256,
|
|
357815
|
+
turbo: TURBO_256,
|
|
357816
|
+
coolwarm: COOLWARM_256,
|
|
357817
|
+
grayscale: [[0, 0, 0], [255, 255, 255]],
|
|
357818
|
+
"thickness-classic": THICKNESS_CLASSIC_STOPS
|
|
357819
|
+
};
|
|
357820
|
+
const COLORMAP_LABELS = {
|
|
357821
|
+
viridis: "Viridis",
|
|
357822
|
+
inferno: "Inferno",
|
|
357823
|
+
turbo: "Turbo",
|
|
357824
|
+
coolwarm: "Cool–Warm",
|
|
357825
|
+
grayscale: "Grayscale",
|
|
357826
|
+
"thickness-classic": "Thickness (classic)"
|
|
357827
|
+
};
|
|
357828
|
+
const COLORMAP_OPTIONS = [
|
|
357829
|
+
{ name: "viridis", label: COLORMAP_LABELS.viridis },
|
|
357830
|
+
{ name: "inferno", label: COLORMAP_LABELS.inferno },
|
|
357831
|
+
{ name: "turbo", label: COLORMAP_LABELS.turbo },
|
|
357832
|
+
{ name: "coolwarm", label: COLORMAP_LABELS.coolwarm },
|
|
357833
|
+
{ name: "grayscale", label: COLORMAP_LABELS.grayscale },
|
|
357834
|
+
{ name: "thickness-classic", label: COLORMAP_LABELS["thickness-classic"] }
|
|
357835
|
+
];
|
|
357836
|
+
function clamp01$1(t) {
|
|
357837
|
+
if (t <= 0) return 0;
|
|
357838
|
+
if (t >= 1) return 1;
|
|
357839
|
+
return t;
|
|
357840
|
+
}
|
|
357841
|
+
function sampleStops(stops, t) {
|
|
357842
|
+
const clamped = clamp01$1(t);
|
|
357843
|
+
const scaled = clamped * (stops.length - 1);
|
|
357844
|
+
const leftIndex = Math.min(stops.length - 2, Math.floor(scaled));
|
|
357845
|
+
const frac = scaled - leftIndex;
|
|
357846
|
+
const left = stops[leftIndex];
|
|
357847
|
+
const right = stops[leftIndex + 1];
|
|
357848
|
+
return [
|
|
357849
|
+
Math.round(left[0] + (right[0] - left[0]) * frac),
|
|
357850
|
+
Math.round(left[1] + (right[1] - left[1]) * frac),
|
|
357851
|
+
Math.round(left[2] + (right[2] - left[2]) * frac)
|
|
357852
|
+
];
|
|
357853
|
+
}
|
|
357854
|
+
function resolveStops(name) {
|
|
357855
|
+
const stops = COLORMAP_STOPS[name];
|
|
357856
|
+
if (!stops) {
|
|
357857
|
+
throw new Error(`Unknown colormap '${String(name)}'. Valid names: ${COLORMAP_OPTIONS.map((o) => o.name).join(", ")}.`);
|
|
357858
|
+
}
|
|
357859
|
+
return stops;
|
|
357860
|
+
}
|
|
357861
|
+
const DEFAULT_COLORMAP = "viridis";
|
|
357862
|
+
function resolveColormapName(value) {
|
|
357863
|
+
return typeof value === "string" && value in COLORMAP_STOPS ? value : DEFAULT_COLORMAP;
|
|
357864
|
+
}
|
|
357865
|
+
function colorScaleHexStops(name, n = 8) {
|
|
357866
|
+
const count = Math.max(2, Math.floor(n));
|
|
357867
|
+
const stops = resolveStops(name);
|
|
357868
|
+
const out = [];
|
|
357869
|
+
for (let i = 0; i < count; i++) {
|
|
357870
|
+
const [r, g2, b] = sampleStops(stops, i / (count - 1));
|
|
357871
|
+
out.push(`#${(1 << 24 | r << 16 | g2 << 8 | b).toString(16).slice(1)}`);
|
|
357872
|
+
}
|
|
357873
|
+
return out;
|
|
357874
|
+
}
|
|
357875
|
+
function colorScaleLUT(name) {
|
|
357876
|
+
const stops = resolveStops(name);
|
|
357877
|
+
const lut = new Uint8Array(COLOR_SCALE_LUT_SIZE * 4);
|
|
357878
|
+
for (let i = 0; i < COLOR_SCALE_LUT_SIZE; i++) {
|
|
357879
|
+
const [r, g2, b] = sampleStops(stops, i / (COLOR_SCALE_LUT_SIZE - 1));
|
|
357880
|
+
const o = i * 4;
|
|
357881
|
+
lut[o] = r;
|
|
357882
|
+
lut[o + 1] = g2;
|
|
357883
|
+
lut[o + 2] = b;
|
|
357884
|
+
lut[o + 3] = 255;
|
|
357885
|
+
}
|
|
357886
|
+
return lut;
|
|
357887
|
+
}
|
|
357888
|
+
function sampleColorScale(scale2, value) {
|
|
357889
|
+
const stops = resolveStops(scale2.colormap);
|
|
357890
|
+
const span = scale2.domainMax - scale2.domainMin;
|
|
357891
|
+
const t = span > 0 ? (value - scale2.domainMin) / span : 0;
|
|
357892
|
+
return sampleStops(stops, Number.isFinite(t) ? t : 0);
|
|
357893
|
+
}
|
|
357894
|
+
const DEFAULT_THICKNESS_COLOR_SCALE = {
|
|
357895
|
+
colormap: "viridis"
|
|
357896
|
+
};
|
|
357897
|
+
const DEFAULT_ROUGHNESS_COLOR_SCALE = {
|
|
357898
|
+
colormap: "viridis",
|
|
357899
|
+
domainMin: 0,
|
|
357900
|
+
domainMax: 1
|
|
357901
|
+
};
|
|
356078
357902
|
const MIN_PATCH_TRIANGLES = 1;
|
|
356079
357903
|
function finitePoint(point2) {
|
|
356080
357904
|
return point2.point.every((value) => Number.isFinite(value));
|
|
@@ -356198,6 +358022,121 @@ const formatPerformanceCount = (value) => INTEGER_FORMATTER.format(Math.max(0, M
|
|
|
356198
358022
|
const waitForAnimationFrame = () => new Promise((resolve) => {
|
|
356199
358023
|
requestAnimationFrame(() => resolve());
|
|
356200
358024
|
});
|
|
358025
|
+
const VECTOR_KEYS = /* @__PURE__ */ new Set(["pos", "position", "target", "lookat", "aim", "up"]);
|
|
358026
|
+
const roundNumber = (value, digits) => {
|
|
358027
|
+
const scale2 = 10 ** digits;
|
|
358028
|
+
return Math.round(value * scale2) / scale2;
|
|
358029
|
+
};
|
|
358030
|
+
const isFiniteTuple3 = (value) => Array.isArray(value) && value.length === 3 && value.every((entry) => typeof entry === "number" && Number.isFinite(entry));
|
|
358031
|
+
function parseViewportCameraState(value) {
|
|
358032
|
+
if (!value || typeof value !== "object") return null;
|
|
358033
|
+
const candidate = value;
|
|
358034
|
+
if (candidate.projectionMode !== "perspective" && candidate.projectionMode !== "orthographic") return null;
|
|
358035
|
+
if (!isFiniteTuple3(candidate.position)) return null;
|
|
358036
|
+
if (!isFiniteTuple3(candidate.target)) return null;
|
|
358037
|
+
if (!isFiniteTuple3(candidate.up)) return null;
|
|
358038
|
+
if (candidate.fov !== void 0 && (!Number.isFinite(candidate.fov) || candidate.fov <= 0 || candidate.fov >= 180)) {
|
|
358039
|
+
return null;
|
|
358040
|
+
}
|
|
358041
|
+
if (candidate.orthoZoom !== void 0 && (!Number.isFinite(candidate.orthoZoom) || candidate.orthoZoom <= 0)) {
|
|
358042
|
+
return null;
|
|
358043
|
+
}
|
|
358044
|
+
const parsed = {
|
|
358045
|
+
projectionMode: candidate.projectionMode,
|
|
358046
|
+
position: candidate.position,
|
|
358047
|
+
target: candidate.target,
|
|
358048
|
+
up: candidate.up
|
|
358049
|
+
};
|
|
358050
|
+
if (candidate.fov !== void 0) parsed.fov = candidate.fov;
|
|
358051
|
+
if (candidate.orthoZoom !== void 0) parsed.orthoZoom = candidate.orthoZoom;
|
|
358052
|
+
return parsed;
|
|
358053
|
+
}
|
|
358054
|
+
function parseVector(name, raw) {
|
|
358055
|
+
const parts = raw.split(",").map((entry) => Number.parseFloat(entry.trim()));
|
|
358056
|
+
if (parts.length !== 3 || parts.some((entry) => !Number.isFinite(entry))) {
|
|
358057
|
+
throw new Error(`Camera ${name} must be three comma-separated numbers.`);
|
|
358058
|
+
}
|
|
358059
|
+
return [parts[0], parts[1], parts[2]];
|
|
358060
|
+
}
|
|
358061
|
+
function parseCameraCliSpec(input) {
|
|
358062
|
+
const trimmed = input.trim();
|
|
358063
|
+
if (!trimmed) {
|
|
358064
|
+
throw new Error("Camera spec cannot be empty.");
|
|
358065
|
+
}
|
|
358066
|
+
if (trimmed.startsWith("{")) {
|
|
358067
|
+
const parsed2 = parseViewportCameraState(JSON.parse(trimmed));
|
|
358068
|
+
if (!parsed2) {
|
|
358069
|
+
throw new Error("Camera JSON does not match the expected shape.");
|
|
358070
|
+
}
|
|
358071
|
+
return parsed2;
|
|
358072
|
+
}
|
|
358073
|
+
const parsed = {};
|
|
358074
|
+
const segments = trimmed.split(";").map((segment) => segment.trim()).filter(Boolean);
|
|
358075
|
+
if (segments.length === 0) {
|
|
358076
|
+
throw new Error("Camera spec cannot be empty.");
|
|
358077
|
+
}
|
|
358078
|
+
for (const segment of segments) {
|
|
358079
|
+
const eqIndex = segment.indexOf("=");
|
|
358080
|
+
if (eqIndex === -1) {
|
|
358081
|
+
throw new Error(`Invalid camera segment "${segment}". Expected key=value.`);
|
|
358082
|
+
}
|
|
358083
|
+
const rawKey = segment.slice(0, eqIndex).trim().toLowerCase();
|
|
358084
|
+
const rawValue = segment.slice(eqIndex + 1).trim();
|
|
358085
|
+
if (!rawValue) {
|
|
358086
|
+
throw new Error(`Camera segment "${segment}" is missing a value.`);
|
|
358087
|
+
}
|
|
358088
|
+
if (rawKey === "proj" || rawKey === "projection" || rawKey === "projectionmode") {
|
|
358089
|
+
if (rawValue !== "perspective" && rawValue !== "orthographic") {
|
|
358090
|
+
throw new Error(`Camera projection must be "perspective" or "orthographic" (got "${rawValue}").`);
|
|
358091
|
+
}
|
|
358092
|
+
parsed.projectionMode = rawValue;
|
|
358093
|
+
continue;
|
|
358094
|
+
}
|
|
358095
|
+
if (rawKey === "zoom" || rawKey === "orthozoom") {
|
|
358096
|
+
const zoom = Number.parseFloat(rawValue);
|
|
358097
|
+
if (!Number.isFinite(zoom) || zoom <= 0) {
|
|
358098
|
+
throw new Error(`Camera zoom must be a positive number (got "${rawValue}").`);
|
|
358099
|
+
}
|
|
358100
|
+
parsed.orthoZoom = zoom;
|
|
358101
|
+
continue;
|
|
358102
|
+
}
|
|
358103
|
+
if (rawKey === "fov") {
|
|
358104
|
+
const fov2 = Number.parseFloat(rawValue);
|
|
358105
|
+
if (!Number.isFinite(fov2) || fov2 <= 0 || fov2 >= 180) {
|
|
358106
|
+
throw new Error(`Camera fov must be between 0 and 180 degrees (got "${rawValue}").`);
|
|
358107
|
+
}
|
|
358108
|
+
parsed.fov = fov2;
|
|
358109
|
+
continue;
|
|
358110
|
+
}
|
|
358111
|
+
if (VECTOR_KEYS.has(rawKey)) {
|
|
358112
|
+
const vector = parseVector(rawKey, rawValue);
|
|
358113
|
+
if (rawKey === "pos" || rawKey === "position") parsed.position = vector;
|
|
358114
|
+
if (rawKey === "target" || rawKey === "lookat" || rawKey === "aim") parsed.target = vector;
|
|
358115
|
+
if (rawKey === "up") parsed.up = vector;
|
|
358116
|
+
continue;
|
|
358117
|
+
}
|
|
358118
|
+
throw new Error(`Unknown camera key "${rawKey}".`);
|
|
358119
|
+
}
|
|
358120
|
+
const finalized = parseViewportCameraState({
|
|
358121
|
+
projectionMode: parsed.projectionMode ?? "perspective",
|
|
358122
|
+
position: parsed.position,
|
|
358123
|
+
target: parsed.target,
|
|
358124
|
+
up: parsed.up ?? [0, 0, 1],
|
|
358125
|
+
fov: parsed.fov,
|
|
358126
|
+
orthoZoom: parsed.orthoZoom
|
|
358127
|
+
});
|
|
358128
|
+
if (!finalized) {
|
|
358129
|
+
throw new Error("Camera spec must include position, target, and up vectors.");
|
|
358130
|
+
}
|
|
358131
|
+
return finalized;
|
|
358132
|
+
}
|
|
358133
|
+
function getCameraForwardVector(state, digits = 3) {
|
|
358134
|
+
const dx = state.target[0] - state.position[0];
|
|
358135
|
+
const dy = state.target[1] - state.position[1];
|
|
358136
|
+
const dz = state.target[2] - state.position[2];
|
|
358137
|
+
const length4 = Math.hypot(dx, dy, dz) || 1;
|
|
358138
|
+
return [roundNumber(dx / length4, digits), roundNumber(dy / length4, digits), roundNumber(dz / length4, digits)];
|
|
358139
|
+
}
|
|
356201
358140
|
const SURFACE_FIELD_VERTEX_SHADER = `
|
|
356202
358141
|
#include <common>
|
|
356203
358142
|
#include <logdepthbuf_pars_vertex>
|
|
@@ -356506,79 +358445,6 @@ function localAabbPlaneRelation(min2, max2, plane, eps = 1e-7) {
|
|
|
356506
358445
|
if (minDistance > -eps) return "positive";
|
|
356507
358446
|
return "crossing";
|
|
356508
358447
|
}
|
|
356509
|
-
const DEFAULT_ROUGHNESS_INSPECTION_OPTIONS = {
|
|
356510
|
-
smoothAngleDeg: 5,
|
|
356511
|
-
sharpAngleDeg: 30,
|
|
356512
|
-
harshAngleDeg: 90,
|
|
356513
|
-
maxSamplesPerObject: 5e3
|
|
356514
|
-
};
|
|
356515
|
-
const ROUGHNESS_COLORS = {
|
|
356516
|
-
smooth: [62, 72, 84],
|
|
356517
|
-
moderate: [255, 214, 0],
|
|
356518
|
-
sharp: [255, 124, 34],
|
|
356519
|
-
harsh: [255, 42, 96]
|
|
356520
|
-
};
|
|
356521
|
-
function resolveRoughnessInspectionOptions(raw = {}) {
|
|
356522
|
-
const options = {
|
|
356523
|
-
smoothAngleDeg: raw.smoothAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.smoothAngleDeg,
|
|
356524
|
-
sharpAngleDeg: raw.sharpAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.sharpAngleDeg,
|
|
356525
|
-
harshAngleDeg: raw.harshAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.harshAngleDeg,
|
|
356526
|
-
maxSamplesPerObject: raw.maxSamplesPerObject ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.maxSamplesPerObject
|
|
356527
|
-
};
|
|
356528
|
-
if (!Number.isFinite(options.smoothAngleDeg) || options.smoothAngleDeg < 0) {
|
|
356529
|
-
throw new Error(`smoothAngleDeg must be a finite non-negative angle (got ${options.smoothAngleDeg}).`);
|
|
356530
|
-
}
|
|
356531
|
-
if (!Number.isFinite(options.sharpAngleDeg) || options.sharpAngleDeg <= options.smoothAngleDeg) {
|
|
356532
|
-
throw new Error(`sharpAngleDeg must be greater than smoothAngleDeg (got ${options.sharpAngleDeg}).`);
|
|
356533
|
-
}
|
|
356534
|
-
if (!Number.isFinite(options.harshAngleDeg) || options.harshAngleDeg <= options.sharpAngleDeg || options.harshAngleDeg > 180) {
|
|
356535
|
-
throw new Error(`harshAngleDeg must be greater than sharpAngleDeg and <= 180 (got ${options.harshAngleDeg}).`);
|
|
356536
|
-
}
|
|
356537
|
-
if (!Number.isFinite(options.maxSamplesPerObject) || options.maxSamplesPerObject <= 0) {
|
|
356538
|
-
throw new Error(`maxSamplesPerObject must be a positive finite number (got ${options.maxSamplesPerObject}).`);
|
|
356539
|
-
}
|
|
356540
|
-
return {
|
|
356541
|
-
...options,
|
|
356542
|
-
maxSamplesPerObject: Math.max(1, Math.floor(options.maxSamplesPerObject))
|
|
356543
|
-
};
|
|
356544
|
-
}
|
|
356545
|
-
function roughnessClassForAngle(angleDeg, options) {
|
|
356546
|
-
if (angleDeg >= options.harshAngleDeg) return "harsh";
|
|
356547
|
-
if (angleDeg >= options.sharpAngleDeg) return "sharp";
|
|
356548
|
-
if (angleDeg >= options.smoothAngleDeg) return "moderate";
|
|
356549
|
-
return "smooth";
|
|
356550
|
-
}
|
|
356551
|
-
function roughnessScoreForAngle(angleDeg, options) {
|
|
356552
|
-
if (angleDeg < options.sharpAngleDeg) return 0;
|
|
356553
|
-
if (angleDeg < options.harshAngleDeg) {
|
|
356554
|
-
return MathUtils.lerp(0.48, 0.82, (angleDeg - options.sharpAngleDeg) / (options.harshAngleDeg - options.sharpAngleDeg));
|
|
356555
|
-
}
|
|
356556
|
-
return 1;
|
|
356557
|
-
}
|
|
356558
|
-
function roughnessColorForAngle(angleDeg, options) {
|
|
356559
|
-
const cls = roughnessClassForAngle(angleDeg, options);
|
|
356560
|
-
if (cls === "smooth" || cls === "harsh") return ROUGHNESS_COLORS[cls];
|
|
356561
|
-
if (cls === "moderate") {
|
|
356562
|
-
return lerpRgb(
|
|
356563
|
-
ROUGHNESS_COLORS.moderate,
|
|
356564
|
-
ROUGHNESS_COLORS.sharp,
|
|
356565
|
-
(angleDeg - options.smoothAngleDeg) / (options.sharpAngleDeg - options.smoothAngleDeg)
|
|
356566
|
-
);
|
|
356567
|
-
}
|
|
356568
|
-
return lerpRgb(
|
|
356569
|
-
ROUGHNESS_COLORS.sharp,
|
|
356570
|
-
ROUGHNESS_COLORS.harsh,
|
|
356571
|
-
(angleDeg - options.sharpAngleDeg) / (options.harshAngleDeg - options.sharpAngleDeg)
|
|
356572
|
-
);
|
|
356573
|
-
}
|
|
356574
|
-
function lerpRgb(a2, b, t) {
|
|
356575
|
-
const clamped = MathUtils.clamp(t, 0, 1);
|
|
356576
|
-
return [
|
|
356577
|
-
Math.round(MathUtils.lerp(a2[0], b[0], clamped)),
|
|
356578
|
-
Math.round(MathUtils.lerp(a2[1], b[1], clamped)),
|
|
356579
|
-
Math.round(MathUtils.lerp(a2[2], b[2], clamped))
|
|
356580
|
-
];
|
|
356581
|
-
}
|
|
356582
358448
|
const DEFAULT_LEAF_SIZE = 8;
|
|
356583
358449
|
function cloneVec3$2(value) {
|
|
356584
358450
|
return [value[0], value[1], value[2]];
|
|
@@ -357368,121 +359234,6 @@ function summarizeThicknessSamples(samples, options) {
|
|
|
357368
359234
|
unresolvedAreaPercent: percent(unresolvedArea, totalArea)
|
|
357369
359235
|
};
|
|
357370
359236
|
}
|
|
357371
|
-
const VECTOR_KEYS = /* @__PURE__ */ new Set(["pos", "position", "target", "lookat", "aim", "up"]);
|
|
357372
|
-
const roundNumber = (value, digits) => {
|
|
357373
|
-
const scale2 = 10 ** digits;
|
|
357374
|
-
return Math.round(value * scale2) / scale2;
|
|
357375
|
-
};
|
|
357376
|
-
const isFiniteTuple3 = (value) => Array.isArray(value) && value.length === 3 && value.every((entry) => typeof entry === "number" && Number.isFinite(entry));
|
|
357377
|
-
function parseViewportCameraState(value) {
|
|
357378
|
-
if (!value || typeof value !== "object") return null;
|
|
357379
|
-
const candidate = value;
|
|
357380
|
-
if (candidate.projectionMode !== "perspective" && candidate.projectionMode !== "orthographic") return null;
|
|
357381
|
-
if (!isFiniteTuple3(candidate.position)) return null;
|
|
357382
|
-
if (!isFiniteTuple3(candidate.target)) return null;
|
|
357383
|
-
if (!isFiniteTuple3(candidate.up)) return null;
|
|
357384
|
-
if (candidate.fov !== void 0 && (!Number.isFinite(candidate.fov) || candidate.fov <= 0 || candidate.fov >= 180)) {
|
|
357385
|
-
return null;
|
|
357386
|
-
}
|
|
357387
|
-
if (candidate.orthoZoom !== void 0 && (!Number.isFinite(candidate.orthoZoom) || candidate.orthoZoom <= 0)) {
|
|
357388
|
-
return null;
|
|
357389
|
-
}
|
|
357390
|
-
const parsed = {
|
|
357391
|
-
projectionMode: candidate.projectionMode,
|
|
357392
|
-
position: candidate.position,
|
|
357393
|
-
target: candidate.target,
|
|
357394
|
-
up: candidate.up
|
|
357395
|
-
};
|
|
357396
|
-
if (candidate.fov !== void 0) parsed.fov = candidate.fov;
|
|
357397
|
-
if (candidate.orthoZoom !== void 0) parsed.orthoZoom = candidate.orthoZoom;
|
|
357398
|
-
return parsed;
|
|
357399
|
-
}
|
|
357400
|
-
function parseVector(name, raw) {
|
|
357401
|
-
const parts = raw.split(",").map((entry) => Number.parseFloat(entry.trim()));
|
|
357402
|
-
if (parts.length !== 3 || parts.some((entry) => !Number.isFinite(entry))) {
|
|
357403
|
-
throw new Error(`Camera ${name} must be three comma-separated numbers.`);
|
|
357404
|
-
}
|
|
357405
|
-
return [parts[0], parts[1], parts[2]];
|
|
357406
|
-
}
|
|
357407
|
-
function parseCameraCliSpec(input) {
|
|
357408
|
-
const trimmed = input.trim();
|
|
357409
|
-
if (!trimmed) {
|
|
357410
|
-
throw new Error("Camera spec cannot be empty.");
|
|
357411
|
-
}
|
|
357412
|
-
if (trimmed.startsWith("{")) {
|
|
357413
|
-
const parsed2 = parseViewportCameraState(JSON.parse(trimmed));
|
|
357414
|
-
if (!parsed2) {
|
|
357415
|
-
throw new Error("Camera JSON does not match the expected shape.");
|
|
357416
|
-
}
|
|
357417
|
-
return parsed2;
|
|
357418
|
-
}
|
|
357419
|
-
const parsed = {};
|
|
357420
|
-
const segments = trimmed.split(";").map((segment) => segment.trim()).filter(Boolean);
|
|
357421
|
-
if (segments.length === 0) {
|
|
357422
|
-
throw new Error("Camera spec cannot be empty.");
|
|
357423
|
-
}
|
|
357424
|
-
for (const segment of segments) {
|
|
357425
|
-
const eqIndex = segment.indexOf("=");
|
|
357426
|
-
if (eqIndex === -1) {
|
|
357427
|
-
throw new Error(`Invalid camera segment "${segment}". Expected key=value.`);
|
|
357428
|
-
}
|
|
357429
|
-
const rawKey = segment.slice(0, eqIndex).trim().toLowerCase();
|
|
357430
|
-
const rawValue = segment.slice(eqIndex + 1).trim();
|
|
357431
|
-
if (!rawValue) {
|
|
357432
|
-
throw new Error(`Camera segment "${segment}" is missing a value.`);
|
|
357433
|
-
}
|
|
357434
|
-
if (rawKey === "proj" || rawKey === "projection" || rawKey === "projectionmode") {
|
|
357435
|
-
if (rawValue !== "perspective" && rawValue !== "orthographic") {
|
|
357436
|
-
throw new Error(`Camera projection must be "perspective" or "orthographic" (got "${rawValue}").`);
|
|
357437
|
-
}
|
|
357438
|
-
parsed.projectionMode = rawValue;
|
|
357439
|
-
continue;
|
|
357440
|
-
}
|
|
357441
|
-
if (rawKey === "zoom" || rawKey === "orthozoom") {
|
|
357442
|
-
const zoom = Number.parseFloat(rawValue);
|
|
357443
|
-
if (!Number.isFinite(zoom) || zoom <= 0) {
|
|
357444
|
-
throw new Error(`Camera zoom must be a positive number (got "${rawValue}").`);
|
|
357445
|
-
}
|
|
357446
|
-
parsed.orthoZoom = zoom;
|
|
357447
|
-
continue;
|
|
357448
|
-
}
|
|
357449
|
-
if (rawKey === "fov") {
|
|
357450
|
-
const fov2 = Number.parseFloat(rawValue);
|
|
357451
|
-
if (!Number.isFinite(fov2) || fov2 <= 0 || fov2 >= 180) {
|
|
357452
|
-
throw new Error(`Camera fov must be between 0 and 180 degrees (got "${rawValue}").`);
|
|
357453
|
-
}
|
|
357454
|
-
parsed.fov = fov2;
|
|
357455
|
-
continue;
|
|
357456
|
-
}
|
|
357457
|
-
if (VECTOR_KEYS.has(rawKey)) {
|
|
357458
|
-
const vector = parseVector(rawKey, rawValue);
|
|
357459
|
-
if (rawKey === "pos" || rawKey === "position") parsed.position = vector;
|
|
357460
|
-
if (rawKey === "target" || rawKey === "lookat" || rawKey === "aim") parsed.target = vector;
|
|
357461
|
-
if (rawKey === "up") parsed.up = vector;
|
|
357462
|
-
continue;
|
|
357463
|
-
}
|
|
357464
|
-
throw new Error(`Unknown camera key "${rawKey}".`);
|
|
357465
|
-
}
|
|
357466
|
-
const finalized = parseViewportCameraState({
|
|
357467
|
-
projectionMode: parsed.projectionMode ?? "perspective",
|
|
357468
|
-
position: parsed.position,
|
|
357469
|
-
target: parsed.target,
|
|
357470
|
-
up: parsed.up ?? [0, 0, 1],
|
|
357471
|
-
fov: parsed.fov,
|
|
357472
|
-
orthoZoom: parsed.orthoZoom
|
|
357473
|
-
});
|
|
357474
|
-
if (!finalized) {
|
|
357475
|
-
throw new Error("Camera spec must include position, target, and up vectors.");
|
|
357476
|
-
}
|
|
357477
|
-
return finalized;
|
|
357478
|
-
}
|
|
357479
|
-
function getCameraForwardVector(state, digits = 3) {
|
|
357480
|
-
const dx = state.target[0] - state.position[0];
|
|
357481
|
-
const dy = state.target[1] - state.position[1];
|
|
357482
|
-
const dz = state.target[2] - state.position[2];
|
|
357483
|
-
const length4 = Math.hypot(dx, dy, dz) || 1;
|
|
357484
|
-
return [roundNumber(dx / length4, digits), roundNumber(dy / length4, digits), roundNumber(dz / length4, digits)];
|
|
357485
|
-
}
|
|
357486
359237
|
const SECTION_EXPLORER_PLANE_NAME = "__section_explorer__";
|
|
357487
359238
|
function resolveSectionHatchMetrics(geometry) {
|
|
357488
359239
|
const planeUv = geometry.getAttribute("planeUv");
|
|
@@ -359219,88 +360970,88 @@ export {
|
|
|
359219
360970
|
Vector4 as Z,
|
|
359220
360971
|
__vitePreload as _,
|
|
359221
360972
|
Scene as a,
|
|
359222
|
-
|
|
360973
|
+
AmbientLight as a$,
|
|
359223
360974
|
Matrix4 as a0,
|
|
359224
360975
|
MathUtils as a1,
|
|
359225
360976
|
Uniform as a2,
|
|
359226
360977
|
WebGLRenderTarget as a3,
|
|
359227
360978
|
DepthTexture as a4,
|
|
359228
360979
|
BackSide as a5,
|
|
359229
|
-
|
|
359230
|
-
|
|
359231
|
-
|
|
359232
|
-
|
|
359233
|
-
|
|
359234
|
-
|
|
359235
|
-
|
|
359236
|
-
|
|
359237
|
-
|
|
359238
|
-
|
|
359239
|
-
|
|
359240
|
-
|
|
359241
|
-
|
|
359242
|
-
|
|
359243
|
-
|
|
359244
|
-
|
|
359245
|
-
|
|
359246
|
-
|
|
359247
|
-
|
|
359248
|
-
|
|
359249
|
-
|
|
359250
|
-
|
|
359251
|
-
|
|
359252
|
-
|
|
359253
|
-
|
|
359254
|
-
|
|
359255
|
-
|
|
359256
|
-
|
|
359257
|
-
|
|
359258
|
-
|
|
359259
|
-
|
|
359260
|
-
|
|
359261
|
-
|
|
359262
|
-
|
|
359263
|
-
|
|
359264
|
-
|
|
359265
|
-
|
|
359266
|
-
|
|
359267
|
-
|
|
359268
|
-
|
|
359269
|
-
|
|
359270
|
-
|
|
359271
|
-
|
|
359272
|
-
|
|
359273
|
-
|
|
359274
|
-
|
|
359275
|
-
|
|
359276
|
-
|
|
359277
|
-
|
|
359278
|
-
|
|
359279
|
-
|
|
359280
|
-
|
|
359281
|
-
|
|
359282
|
-
|
|
359283
|
-
|
|
359284
|
-
|
|
359285
|
-
|
|
360980
|
+
BufferAttribute as a6,
|
|
360981
|
+
Triangle as a7,
|
|
360982
|
+
FrontSide as a8,
|
|
360983
|
+
BatchedMesh as a9,
|
|
360984
|
+
setShapePortsInternal as aA,
|
|
360985
|
+
markShapePortsUsed as aB,
|
|
360986
|
+
resolveColormapName as aC,
|
|
360987
|
+
setParamOverrides as aD,
|
|
360988
|
+
resolveForgeRenderStyle as aE,
|
|
360989
|
+
DEFAULT_ACTIVE_BACKEND as aF,
|
|
360990
|
+
isConstraintSketch as aG,
|
|
360991
|
+
updateConstraintValue as aH,
|
|
360992
|
+
linearizeMultiObjectSteps as aI,
|
|
360993
|
+
getShapeCompilePlan as aJ,
|
|
360994
|
+
SCAN_PROXY_GRANULARITY_DEFAULT as aK,
|
|
360995
|
+
publishSolverWasmRunDebug as aL,
|
|
360996
|
+
resolveForgeQualityPreset as aM,
|
|
360997
|
+
SCAN_PROXY_MATRIX_GRANULARITY_MAX as aN,
|
|
360998
|
+
findJointAnimationClip as aO,
|
|
360999
|
+
resolveJointAnimation as aP,
|
|
361000
|
+
resolveJointViewValues as aQ,
|
|
361001
|
+
resolveImportPath as aR,
|
|
361002
|
+
resolveScanProxyGranularity as aS,
|
|
361003
|
+
BufferGeometry as aT,
|
|
361004
|
+
LineBasicMaterial as aU,
|
|
361005
|
+
Line as aV,
|
|
361006
|
+
LineDashedMaterial as aW,
|
|
361007
|
+
CanvasTexture as aX,
|
|
361008
|
+
Object3D as aY,
|
|
361009
|
+
FogExp2 as aZ,
|
|
361010
|
+
Fog as a_,
|
|
361011
|
+
ClampToEdgeWrapping as aa,
|
|
361012
|
+
PlaneGeometry as ab,
|
|
361013
|
+
UVMapping as ac,
|
|
361014
|
+
DataTexture as ad,
|
|
361015
|
+
Texture as ae,
|
|
361016
|
+
MeshBasicMaterial as af,
|
|
361017
|
+
IntType as ag,
|
|
361018
|
+
ShortType as ah,
|
|
361019
|
+
ByteType as ai,
|
|
361020
|
+
UnsignedIntType as aj,
|
|
361021
|
+
Loader as ak,
|
|
361022
|
+
LoadingManager as al,
|
|
361023
|
+
LinearMipMapLinearFilter as am,
|
|
361024
|
+
FileLoader as an,
|
|
361025
|
+
NoBlending as ao,
|
|
361026
|
+
CubeReflectionMapping as ap,
|
|
361027
|
+
EquirectangularReflectionMapping as aq,
|
|
361028
|
+
CubeTextureLoader as ar,
|
|
361029
|
+
WebGLCubeRenderTarget as as,
|
|
361030
|
+
ConstraintSketch as at,
|
|
361031
|
+
setSketchPlacement3D as au,
|
|
361032
|
+
Sketch as av,
|
|
361033
|
+
PROFILE_BACKEND_MARKER as aw,
|
|
361034
|
+
FrozenShape as ax,
|
|
361035
|
+
setShapeCompilePlan as ay,
|
|
361036
|
+
hasAnyPorts as az,
|
|
359286
361037
|
PCFSoftShadowMap as b,
|
|
359287
|
-
|
|
359288
|
-
|
|
359289
|
-
|
|
359290
|
-
|
|
359291
|
-
|
|
359292
|
-
|
|
359293
|
-
|
|
359294
|
-
|
|
359295
|
-
|
|
359296
|
-
|
|
359297
|
-
|
|
359298
|
-
|
|
359299
|
-
|
|
359300
|
-
|
|
359301
|
-
|
|
359302
|
-
|
|
359303
|
-
|
|
361038
|
+
formatPerformanceCount as b$,
|
|
361039
|
+
HemisphereLight as b0,
|
|
361040
|
+
SpotLight as b1,
|
|
361041
|
+
PointLight as b2,
|
|
361042
|
+
DirectionalLight as b3,
|
|
361043
|
+
heatPointsForSide as b4,
|
|
361044
|
+
COMPARISON_COLORS as b5,
|
|
361045
|
+
comparisonHeatDepthTest as b6,
|
|
361046
|
+
comparisonHeatEdgeOpacity as b7,
|
|
361047
|
+
comparisonHeatPatchOpacity as b8,
|
|
361048
|
+
shapeToGeometry as b9,
|
|
361049
|
+
scanProxySourceBytes as bA,
|
|
361050
|
+
disposeScanProxyGeometry as bB,
|
|
361051
|
+
scanProxyGeometryFromPayload as bC,
|
|
361052
|
+
AdditiveBlending as bD,
|
|
361053
|
+
geometryWithVisibleVertexColors as bE,
|
|
361054
|
+
colorScaleLUT as bF,
|
|
359304
361055
|
getRenderStylePreset as bG,
|
|
359305
361056
|
SCAN_RENDER_COLORS as bH,
|
|
359306
361057
|
NormalBlending as bI,
|
|
@@ -359319,121 +361070,118 @@ export {
|
|
|
359319
361070
|
WORLD_UP as bV,
|
|
359320
361071
|
CatmullRomCurve3 as bW,
|
|
359321
361072
|
TubeGeometry as bX,
|
|
359322
|
-
|
|
359323
|
-
|
|
359324
|
-
|
|
359325
|
-
|
|
359326
|
-
|
|
359327
|
-
|
|
359328
|
-
|
|
359329
|
-
|
|
359330
|
-
|
|
359331
|
-
|
|
359332
|
-
|
|
359333
|
-
|
|
359334
|
-
|
|
359335
|
-
|
|
359336
|
-
|
|
359337
|
-
|
|
359338
|
-
|
|
359339
|
-
|
|
359340
|
-
|
|
359341
|
-
|
|
359342
|
-
|
|
359343
|
-
|
|
359344
|
-
|
|
359345
|
-
|
|
359346
|
-
|
|
359347
|
-
|
|
359348
|
-
|
|
359349
|
-
|
|
359350
|
-
|
|
361073
|
+
DEFAULT_COLORMAP as bY,
|
|
361074
|
+
colorScaleHexStops as bZ,
|
|
361075
|
+
PERFORMANCE_SAMPLE_INTERVAL_SEC as b_,
|
|
361076
|
+
buildComparisonHeatPatchGeometry as ba,
|
|
361077
|
+
EdgesGeometry as bb,
|
|
361078
|
+
buildShapeFromCompilePlan as bc,
|
|
361079
|
+
VIEWPORT_CAMERA_STORAGE_KEY as bd,
|
|
361080
|
+
parseViewportCameraState as be,
|
|
361081
|
+
getKernelFaceNameForTriangle as bf,
|
|
361082
|
+
OBJECT_CONTEXT_MENU_MARGIN as bg,
|
|
361083
|
+
buildVisibleHistoryStacks as bh,
|
|
361084
|
+
sketchToSvg as bi,
|
|
361085
|
+
sketchToDxf as bj,
|
|
361086
|
+
runScript as bk,
|
|
361087
|
+
MeshPhysicalMaterial as bl,
|
|
361088
|
+
LineSegments as bm,
|
|
361089
|
+
findDesignTraceNodeForConstructionStep as bn,
|
|
361090
|
+
formatDesignTraceAnchor as bo,
|
|
361091
|
+
waitForAnimationFrame as bp,
|
|
361092
|
+
selectBuildLedgerNodes as bq,
|
|
361093
|
+
NoColorSpace as br,
|
|
361094
|
+
worldAuthorPlaneToLocal as bs,
|
|
361095
|
+
compileSdfProgramEvaluator3 as bt,
|
|
361096
|
+
SDF_LINEAR_OUTPUT_COLOR_GLSL as bu,
|
|
361097
|
+
GLSL3 as bv,
|
|
361098
|
+
BoxGeometry as bw,
|
|
361099
|
+
Data3DTexture as bx,
|
|
361100
|
+
buildSdfRaymarchFragmentShader as by,
|
|
361101
|
+
SDF_RAYMARCH_PROXY_VERTEX_SHADER as bz,
|
|
359351
361102
|
PCFShadowMap as c,
|
|
359352
|
-
|
|
359353
|
-
|
|
359354
|
-
|
|
359355
|
-
|
|
359356
|
-
|
|
359357
|
-
|
|
359358
|
-
|
|
359359
|
-
|
|
359360
|
-
|
|
359361
|
-
|
|
359362
|
-
|
|
359363
|
-
|
|
359364
|
-
|
|
359365
|
-
|
|
359366
|
-
|
|
359367
|
-
|
|
359368
|
-
|
|
359369
|
-
|
|
359370
|
-
|
|
359371
|
-
|
|
359372
|
-
|
|
359373
|
-
|
|
359374
|
-
|
|
359375
|
-
|
|
359376
|
-
|
|
359377
|
-
|
|
359378
|
-
|
|
359379
|
-
|
|
359380
|
-
|
|
359381
|
-
|
|
359382
|
-
|
|
359383
|
-
|
|
359384
|
-
|
|
359385
|
-
|
|
359386
|
-
|
|
359387
|
-
|
|
359388
|
-
|
|
359389
|
-
|
|
359390
|
-
|
|
359391
|
-
|
|
359392
|
-
|
|
359393
|
-
|
|
359394
|
-
|
|
359395
|
-
|
|
359396
|
-
|
|
359397
|
-
|
|
359398
|
-
|
|
359399
|
-
|
|
359400
|
-
|
|
359401
|
-
|
|
359402
|
-
|
|
359403
|
-
|
|
359404
|
-
|
|
359405
|
-
|
|
359406
|
-
|
|
359407
|
-
|
|
359408
|
-
|
|
359409
|
-
|
|
359410
|
-
|
|
359411
|
-
|
|
359412
|
-
|
|
359413
|
-
|
|
359414
|
-
|
|
359415
|
-
|
|
361103
|
+
summarizeThicknessSamples as c$,
|
|
361104
|
+
NON_TEXT_INPUT_TYPES as c0,
|
|
361105
|
+
MeshStandardMaterial as c1,
|
|
361106
|
+
Shape$1 as c2,
|
|
361107
|
+
ShapeGeometry as c3,
|
|
361108
|
+
ShaderLib as c4,
|
|
361109
|
+
CylinderGeometry as c5,
|
|
361110
|
+
createResolvedExplodeConfig as c6,
|
|
361111
|
+
explodeBoundsCenter as c7,
|
|
361112
|
+
explodeMergeBounds as c8,
|
|
361113
|
+
resolveExplodeDirective as c9,
|
|
361114
|
+
FOCUS_MODE_DIM_OPACITY as cA,
|
|
361115
|
+
DEFAULT_THICKNESS_INSPECTION_OPTIONS as cB,
|
|
361116
|
+
comparisonCandidateContextOpacity as cC,
|
|
361117
|
+
Matrix3 as cD,
|
|
361118
|
+
initBackendForEvaluation as cE,
|
|
361119
|
+
localAabbPlaneRelation as cF,
|
|
361120
|
+
ShapeUtils as cG,
|
|
361121
|
+
analyzePhysicalConnectivity as cH,
|
|
361122
|
+
Frustum as cI,
|
|
361123
|
+
meshContactDataFor as cJ,
|
|
361124
|
+
AabbSpatialIndex as cK,
|
|
361125
|
+
detectPhysicalContact as cL,
|
|
361126
|
+
resolveThicknessInspectionOptions as cM,
|
|
361127
|
+
thicknessColor as cN,
|
|
361128
|
+
thicknessClass as cO,
|
|
361129
|
+
Group as cP,
|
|
361130
|
+
createScanProxyGeometry as cQ,
|
|
361131
|
+
resolveSectionHatchMetrics as cR,
|
|
361132
|
+
intersectWithPlane as cS,
|
|
361133
|
+
setActiveBackend as cT,
|
|
361134
|
+
parseCameraCliSpec as cU,
|
|
361135
|
+
PMREMGenerator as cV,
|
|
361136
|
+
DEFAULT_ROUGHNESS_COLOR_SCALE as cW,
|
|
361137
|
+
PointsMaterial as cX,
|
|
361138
|
+
Points$1 as cY,
|
|
361139
|
+
analyzeCollisionIntersections as cZ,
|
|
361140
|
+
serializeCollisionFinding as c_,
|
|
361141
|
+
computeExplodeMotion as ca,
|
|
361142
|
+
getSketchWorldMatrix as cb,
|
|
361143
|
+
explodeAdd as cc,
|
|
361144
|
+
hasExplodeOverride as cd,
|
|
361145
|
+
resolveExplodeLocalFanDirection as ce,
|
|
361146
|
+
explodeMul as cf,
|
|
361147
|
+
explodeLeafFanStage as cg,
|
|
361148
|
+
normalizeCutPlane as ch,
|
|
361149
|
+
toClippingPlane as ci,
|
|
361150
|
+
isObjectExcludedFromCutPlane as cj,
|
|
361151
|
+
getShapePorts as ck,
|
|
361152
|
+
getShapeUsedPorts as cl,
|
|
361153
|
+
DEFAULT_VIEW_CONFIG as cm,
|
|
361154
|
+
SECTION_EXPLORER_PLANE_NAME as cn,
|
|
361155
|
+
ZERO_OFFSET as co,
|
|
361156
|
+
scanProxyGridForBounds as cp,
|
|
361157
|
+
IDENTITY_MATRIX as cq,
|
|
361158
|
+
OBJECT_CONTEXT_MENU_WIDTH as cr,
|
|
361159
|
+
OBJECT_CONTEXT_MENU_HEIGHT as cs,
|
|
361160
|
+
triangleSoupFromMeshes as ct,
|
|
361161
|
+
compareTriangleSoups as cu,
|
|
361162
|
+
buildGeometryComparisonPointCloud as cv,
|
|
361163
|
+
aabbOverlaps as cw,
|
|
361164
|
+
aabbOverlapVolume as cx,
|
|
361165
|
+
DEFAULT_COLLISION_INSPECTION_OPTIONS as cy,
|
|
361166
|
+
resolveScalarSceneSampleBudget as cz,
|
|
359416
361167
|
SRGBColorSpace as d,
|
|
359417
|
-
|
|
359418
|
-
|
|
359419
|
-
|
|
359420
|
-
|
|
359421
|
-
|
|
359422
|
-
|
|
359423
|
-
|
|
359424
|
-
|
|
359425
|
-
|
|
359426
|
-
|
|
359427
|
-
|
|
359428
|
-
|
|
359429
|
-
|
|
359430
|
-
|
|
359431
|
-
|
|
359432
|
-
|
|
359433
|
-
|
|
359434
|
-
SCAN_PROXY_GRANULARITY_MAX as dh,
|
|
359435
|
-
SCAN_PROXY_GRANULARITY_MIN as di,
|
|
359436
|
-
__viteBrowserExternal$1 as dj,
|
|
361168
|
+
THICKNESS_GRADIENT_COLORS as d0,
|
|
361169
|
+
THICKNESS_COLORS as d1,
|
|
361170
|
+
DEFAULT_THICKNESS_COLOR_SCALE as d2,
|
|
361171
|
+
TorusGeometry as d3,
|
|
361172
|
+
sampleColorScale as d4,
|
|
361173
|
+
SphereGeometry as d5,
|
|
361174
|
+
ConeGeometry as d6,
|
|
361175
|
+
DEFAULT_COMPARISON_CANDIDATE_OPACITY as d7,
|
|
361176
|
+
computeCuttingLayout as d8,
|
|
361177
|
+
generateCuttingLayoutPdf as d9,
|
|
361178
|
+
buildDesignTraceNeighborhood as da,
|
|
361179
|
+
getCameraForwardVector as db,
|
|
361180
|
+
RENDER_STYLE_OPTIONS as dc,
|
|
361181
|
+
SCAN_PROXY_GRANULARITY_MAX as dd,
|
|
361182
|
+
SCAN_PROXY_GRANULARITY_MIN as de,
|
|
361183
|
+
COLORMAP_OPTIONS as df,
|
|
361184
|
+
__viteBrowserExternal$1 as dg,
|
|
359437
361185
|
Layers as e,
|
|
359438
361186
|
Color as f,
|
|
359439
361187
|
RGBAFormat as g,
|