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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { D as DoubleSide, a as Scene,
|
|
5
|
-
import { m as mergeViewportRenderSceneStates, v as validateJointOverrides, b as buildBaseJointValues, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../jointPose-
|
|
4
|
+
import { D as DoubleSide, a as Scene, bw as BoxGeometry, c1 as MeshStandardMaterial, a5 as BackSide, b2 as PointLight, M as Mesh, af as MeshBasicMaterial, cF as localAabbPlaneRelation, i as Vector2, cG as ShapeUtils, cH as analyzePhysicalConnectivity, h as Vector3, a0 as Matrix4, cI as Frustum, J as Box3, a1 as MathUtils, cJ as meshContactDataFor, cK as AabbSpatialIndex, cL as detectPhysicalContact, cM as resolveThicknessInspectionOptions, R as Raycaster, cN as thicknessColor, cO as thicknessClass, a6 as BufferAttribute, cE as initBackendForEvaluation, f as Color, b5 as COMPARISON_COLORS, aE as resolveForgeRenderStyle, bG as getRenderStylePreset, aD as setParamOverrides, bk as runScript, cp as scanProxyGridForBounds, cP as Group, b9 as shapeToGeometry, bl as MeshPhysicalMaterial, bD as AdditiveBlending, bJ as scanMaterialShellColor, cQ as createScanProxyGeometry, aU as LineBasicMaterial, bI as NormalBlending, bm as LineSegments, P as PerspectiveCamera, cm as DEFAULT_VIEW_CONFIG, bs as worldAuthorPlaneToLocal, cR as resolveSectionHatchMetrics, cv as buildGeometryComparisonPointCloud, ct as triangleSoupFromMeshes, O as OrthographicCamera, l as ShaderMaterial, bP as ZEBRA_STRIPE_FRAGMENT_SHADER, bQ as ZEBRA_STRIPE_VERTEX_SHADER, bK as ZEBRA_STRIPE_SOFTNESS, bL as ZEBRA_STRIPE_SCALE, bM as ZEBRA_LIGHT_COLOR, bN as ZEBRA_DARK_COLOR, bO as ZEBRA_ACCENT_COLOR, bE as geometryWithVisibleVertexColors, cS as intersectWithPlane, cT as setActiveBackend, W as WebGLRenderer, A as ACESFilmicToneMapping, d as SRGBColorSpace, cU as parseCameraCliSpec, cV as PMREMGenerator, aX as CanvasTexture, aY as Object3D, aZ as FogExp2, a_ as Fog, a$ as AmbientLight, b3 as DirectionalLight, b0 as HemisphereLight, aO as findJointAnimationClip, q as Plane, bT as SURFACE_FIELD_FRAGMENT_SHADER, bU as SURFACE_FIELD_VERTEX_SHADER, bS as scanMaterialLayerStyles, bR as SCAN_PROXY_LAYER_STYLES, aP as resolveJointAnimation, aQ as resolveJointViewValues, aT as BufferGeometry, cW as DEFAULT_ROUGHNESS_COLOR_SCALE, cX as PointsMaterial, cY as Points, b4 as heatPointsForSide, cZ as analyzeCollisionIntersections, c_ as serializeCollisionFinding, c$ as summarizeThicknessSamples, d0 as THICKNESS_GRADIENT_COLORS, d1 as THICKNESS_COLORS, d2 as DEFAULT_THICKNESS_COLOR_SCALE, b1 as SpotLight, c5 as CylinderGeometry, d3 as TorusGeometry, bW as CatmullRomCurve3, bX as TubeGeometry, cz as resolveScalarSceneSampleBudget, d4 as sampleColorScale, ba as buildComparisonHeatPatchGeometry, bb as EdgesGeometry, d5 as SphereGeometry, d6 as ConeGeometry, b6 as comparisonHeatDepthTest, b7 as comparisonHeatEdgeOpacity, b8 as comparisonHeatPatchOpacity, cC as comparisonCandidateContextOpacity, d7 as DEFAULT_COMPARISON_CANDIDATE_OPACITY } from "../backendInit-DbTkQN9J.js";
|
|
5
|
+
import { m as mergeViewportRenderSceneStates, v as validateJointOverrides, b as buildBaseJointValues, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../jointPose-AMvCywzS.js";
|
|
6
6
|
const CAD_MATERIAL_PROPS = {
|
|
7
7
|
color: 6003669,
|
|
8
8
|
metalness: 0.05,
|
|
@@ -1464,6 +1464,79 @@ function analyzeThicknessGeometry(sourceGeometry, rawOptions = {}, context = {})
|
|
|
1464
1464
|
warnings
|
|
1465
1465
|
};
|
|
1466
1466
|
}
|
|
1467
|
+
const DEFAULT_ROUGHNESS_INSPECTION_OPTIONS = {
|
|
1468
|
+
smoothAngleDeg: 5,
|
|
1469
|
+
sharpAngleDeg: 30,
|
|
1470
|
+
harshAngleDeg: 90,
|
|
1471
|
+
maxSamplesPerObject: 5e3
|
|
1472
|
+
};
|
|
1473
|
+
const ROUGHNESS_COLORS = {
|
|
1474
|
+
smooth: [62, 72, 84],
|
|
1475
|
+
moderate: [255, 214, 0],
|
|
1476
|
+
sharp: [255, 124, 34],
|
|
1477
|
+
harsh: [255, 42, 96]
|
|
1478
|
+
};
|
|
1479
|
+
function resolveRoughnessInspectionOptions(raw = {}) {
|
|
1480
|
+
const options = {
|
|
1481
|
+
smoothAngleDeg: raw.smoothAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.smoothAngleDeg,
|
|
1482
|
+
sharpAngleDeg: raw.sharpAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.sharpAngleDeg,
|
|
1483
|
+
harshAngleDeg: raw.harshAngleDeg ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.harshAngleDeg,
|
|
1484
|
+
maxSamplesPerObject: raw.maxSamplesPerObject ?? DEFAULT_ROUGHNESS_INSPECTION_OPTIONS.maxSamplesPerObject
|
|
1485
|
+
};
|
|
1486
|
+
if (!Number.isFinite(options.smoothAngleDeg) || options.smoothAngleDeg < 0) {
|
|
1487
|
+
throw new Error(`smoothAngleDeg must be a finite non-negative angle (got ${options.smoothAngleDeg}).`);
|
|
1488
|
+
}
|
|
1489
|
+
if (!Number.isFinite(options.sharpAngleDeg) || options.sharpAngleDeg <= options.smoothAngleDeg) {
|
|
1490
|
+
throw new Error(`sharpAngleDeg must be greater than smoothAngleDeg (got ${options.sharpAngleDeg}).`);
|
|
1491
|
+
}
|
|
1492
|
+
if (!Number.isFinite(options.harshAngleDeg) || options.harshAngleDeg <= options.sharpAngleDeg || options.harshAngleDeg > 180) {
|
|
1493
|
+
throw new Error(`harshAngleDeg must be greater than sharpAngleDeg and <= 180 (got ${options.harshAngleDeg}).`);
|
|
1494
|
+
}
|
|
1495
|
+
if (!Number.isFinite(options.maxSamplesPerObject) || options.maxSamplesPerObject <= 0) {
|
|
1496
|
+
throw new Error(`maxSamplesPerObject must be a positive finite number (got ${options.maxSamplesPerObject}).`);
|
|
1497
|
+
}
|
|
1498
|
+
return {
|
|
1499
|
+
...options,
|
|
1500
|
+
maxSamplesPerObject: Math.max(1, Math.floor(options.maxSamplesPerObject))
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
function roughnessClassForAngle(angleDeg, options) {
|
|
1504
|
+
if (angleDeg >= options.harshAngleDeg) return "harsh";
|
|
1505
|
+
if (angleDeg >= options.sharpAngleDeg) return "sharp";
|
|
1506
|
+
if (angleDeg >= options.smoothAngleDeg) return "moderate";
|
|
1507
|
+
return "smooth";
|
|
1508
|
+
}
|
|
1509
|
+
function roughnessScoreForAngle(angleDeg, options) {
|
|
1510
|
+
if (angleDeg < options.sharpAngleDeg) return 0;
|
|
1511
|
+
if (angleDeg < options.harshAngleDeg) {
|
|
1512
|
+
return MathUtils.lerp(0.48, 0.82, (angleDeg - options.sharpAngleDeg) / (options.harshAngleDeg - options.sharpAngleDeg));
|
|
1513
|
+
}
|
|
1514
|
+
return 1;
|
|
1515
|
+
}
|
|
1516
|
+
function roughnessColorForAngle(angleDeg, options) {
|
|
1517
|
+
const cls = roughnessClassForAngle(angleDeg, options);
|
|
1518
|
+
if (cls === "smooth" || cls === "harsh") return ROUGHNESS_COLORS[cls];
|
|
1519
|
+
if (cls === "moderate") {
|
|
1520
|
+
return lerpRgb(
|
|
1521
|
+
ROUGHNESS_COLORS.moderate,
|
|
1522
|
+
ROUGHNESS_COLORS.sharp,
|
|
1523
|
+
(angleDeg - options.smoothAngleDeg) / (options.sharpAngleDeg - options.smoothAngleDeg)
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1526
|
+
return lerpRgb(
|
|
1527
|
+
ROUGHNESS_COLORS.sharp,
|
|
1528
|
+
ROUGHNESS_COLORS.harsh,
|
|
1529
|
+
(angleDeg - options.sharpAngleDeg) / (options.harshAngleDeg - options.sharpAngleDeg)
|
|
1530
|
+
);
|
|
1531
|
+
}
|
|
1532
|
+
function lerpRgb(a, b, t) {
|
|
1533
|
+
const clamped = MathUtils.clamp(t, 0, 1);
|
|
1534
|
+
return [
|
|
1535
|
+
Math.round(MathUtils.lerp(a[0], b[0], clamped)),
|
|
1536
|
+
Math.round(MathUtils.lerp(a[1], b[1], clamped)),
|
|
1537
|
+
Math.round(MathUtils.lerp(a[2], b[2], clamped))
|
|
1538
|
+
];
|
|
1539
|
+
}
|
|
1467
1540
|
function emptyRoughnessSummary() {
|
|
1468
1541
|
return {
|
|
1469
1542
|
triangleCount: 0,
|
|
@@ -3602,7 +3675,7 @@ function bboxFromGeometry(geometry) {
|
|
|
3602
3675
|
max: bbox ? [bbox.max.x, bbox.max.y, bbox.max.z] : [0, 0, 0]
|
|
3603
3676
|
};
|
|
3604
3677
|
}
|
|
3605
|
-
function pointBuffersFromSamples(samples, offset = 0.025) {
|
|
3678
|
+
function pointBuffersFromSamples(samples, colorScale, offset = 0.025) {
|
|
3606
3679
|
const positions = new Float32Array(samples.length * 3);
|
|
3607
3680
|
const colors = new Float32Array(samples.length * 3);
|
|
3608
3681
|
samples.forEach((sample, index) => {
|
|
@@ -3610,9 +3683,16 @@ function pointBuffersFromSamples(samples, offset = 0.025) {
|
|
|
3610
3683
|
positions[base] = sample.position[0] + sample.normal[0] * offset;
|
|
3611
3684
|
positions[base + 1] = sample.position[1] + sample.normal[1] * offset;
|
|
3612
3685
|
positions[base + 2] = sample.position[2] + sample.normal[2] * offset;
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3686
|
+
if (colorScale && sample.value != null && Number.isFinite(sample.value)) {
|
|
3687
|
+
const [r, g, b] = sampleColorScale(colorScale, sample.value);
|
|
3688
|
+
colors[base] = r / 255;
|
|
3689
|
+
colors[base + 1] = g / 255;
|
|
3690
|
+
colors[base + 2] = b / 255;
|
|
3691
|
+
} else {
|
|
3692
|
+
colors[base] = sample.color[0] / 255;
|
|
3693
|
+
colors[base + 1] = sample.color[1] / 255;
|
|
3694
|
+
colors[base + 2] = sample.color[2] / 255;
|
|
3695
|
+
}
|
|
3616
3696
|
});
|
|
3617
3697
|
return { positions, colors };
|
|
3618
3698
|
}
|
|
@@ -3680,6 +3760,11 @@ function getSessionThicknessInspection(session, rawOptions) {
|
|
|
3680
3760
|
const byId = new Map(session.objects.map((obj) => [obj.id, obj]));
|
|
3681
3761
|
const warnings = [];
|
|
3682
3762
|
maybePushSceneSampleBudgetWarning(warnings, "Thickness", sampleBudget);
|
|
3763
|
+
const thicknessColorScale = {
|
|
3764
|
+
colormap: DEFAULT_THICKNESS_COLOR_SCALE.colormap,
|
|
3765
|
+
domainMin: options.colorMinThickness,
|
|
3766
|
+
domainMax: options.colorMaxThickness
|
|
3767
|
+
};
|
|
3683
3768
|
const objects = [];
|
|
3684
3769
|
const cloudObjects = [];
|
|
3685
3770
|
const points = [];
|
|
@@ -3727,7 +3812,7 @@ function getSessionThicknessInspection(session, rawOptions) {
|
|
|
3727
3812
|
...sample
|
|
3728
3813
|
});
|
|
3729
3814
|
});
|
|
3730
|
-
overlays.push({ renderable, ...pointBuffersFromSamples(analysis.pointSamples) });
|
|
3815
|
+
overlays.push({ renderable, ...pointBuffersFromSamples(analysis.pointSamples, thicknessColorScale) });
|
|
3731
3816
|
analysis.geometry.dispose();
|
|
3732
3817
|
});
|
|
3733
3818
|
const state = {
|
|
@@ -3750,7 +3835,10 @@ function getSessionThicknessInspection(session, rawOptions) {
|
|
|
3750
3835
|
objects,
|
|
3751
3836
|
warnings,
|
|
3752
3837
|
style: {
|
|
3838
|
+
// gradientColors is the legacy 'thickness-classic' rainbow, kept for
|
|
3839
|
+
// back-compat. colorScale is the truth the viewport/CLI now render with.
|
|
3753
3840
|
gradientColors: THICKNESS_GRADIENT_COLORS.map((color) => [...color]),
|
|
3841
|
+
colorScale: thicknessColorScale,
|
|
3754
3842
|
colorMinThickness: options.colorMinThickness,
|
|
3755
3843
|
colorMaxThickness: options.colorMaxThickness,
|
|
3756
3844
|
unknownColor: THICKNESS_COLORS.unknown
|
|
@@ -3783,8 +3871,22 @@ function getSessionRoughnessInspection(session, rawOptions) {
|
|
|
3783
3871
|
const cloudObjects = [];
|
|
3784
3872
|
const points = [];
|
|
3785
3873
|
const overlays = [];
|
|
3786
|
-
|
|
3874
|
+
let roughnessMin = Infinity;
|
|
3875
|
+
let roughnessMax = -Infinity;
|
|
3876
|
+
const analysesByIndex = [];
|
|
3877
|
+
session.renderables.forEach((renderable) => {
|
|
3787
3878
|
const analysis = analyzeRoughnessGeometry(renderable.solid.geometry, options);
|
|
3879
|
+
analysesByIndex.push(analysis);
|
|
3880
|
+
for (const sample of analysis.pointSamples) {
|
|
3881
|
+
if (sample.value != null && Number.isFinite(sample.value)) {
|
|
3882
|
+
if (sample.value < roughnessMin) roughnessMin = sample.value;
|
|
3883
|
+
if (sample.value > roughnessMax) roughnessMax = sample.value;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
});
|
|
3887
|
+
const roughnessColorScale = Number.isFinite(roughnessMin) && roughnessMax > roughnessMin ? { colormap: DEFAULT_ROUGHNESS_COLOR_SCALE.colormap, domainMin: roughnessMin, domainMax: roughnessMax } : DEFAULT_ROUGHNESS_COLOR_SCALE;
|
|
3888
|
+
session.renderables.forEach((renderable, index) => {
|
|
3889
|
+
const analysis = analysesByIndex[index];
|
|
3788
3890
|
const bbox = bboxFromGeometry(analysis.geometry);
|
|
3789
3891
|
const sourceObject = byId.get(renderable.id);
|
|
3790
3892
|
if (analysis.warnings.length > 0) {
|
|
@@ -3819,7 +3921,7 @@ function getSessionRoughnessInspection(session, rawOptions) {
|
|
|
3819
3921
|
...sample
|
|
3820
3922
|
});
|
|
3821
3923
|
});
|
|
3822
|
-
overlays.push({ renderable, ...pointBuffersFromSamples(analysis.pointSamples) });
|
|
3924
|
+
overlays.push({ renderable, ...pointBuffersFromSamples(analysis.pointSamples, roughnessColorScale) });
|
|
3823
3925
|
analysis.geometry.dispose();
|
|
3824
3926
|
});
|
|
3825
3927
|
const state = {
|
|
@@ -3842,6 +3944,9 @@ function getSessionRoughnessInspection(session, rawOptions) {
|
|
|
3842
3944
|
objects,
|
|
3843
3945
|
warnings,
|
|
3844
3946
|
style: {
|
|
3947
|
+
// Legacy class colors kept for back-compat; colorScale is the truth the
|
|
3948
|
+
// viewport/CLI now render with (continuous viridis over the data domain).
|
|
3949
|
+
colorScale: roughnessColorScale,
|
|
3845
3950
|
smoothColor: ROUGHNESS_COLORS.smooth,
|
|
3846
3951
|
moderateColor: ROUGHNESS_COLORS.moderate,
|
|
3847
3952
|
sharpColor: ROUGHNESS_COLORS.sharp,
|
package/dist/assets/{constructionHistoryWorker-CZ42Dksy.js → constructionHistoryWorker-PCwXrTDB.js}
RENAMED
|
@@ -11427,6 +11427,65 @@ function basisFuns(span, u2, degree, knots) {
|
|
|
11427
11427
|
}
|
|
11428
11428
|
return N;
|
|
11429
11429
|
}
|
|
11430
|
+
function basisFunsDeriv(span, u2, degree, knots, nDeriv) {
|
|
11431
|
+
const ndu = Array.from({ length: degree + 1 }, () => new Array(degree + 1).fill(0));
|
|
11432
|
+
const a2 = Array.from({ length: 2 }, () => new Array(degree + 1).fill(0));
|
|
11433
|
+
const left = new Array(degree + 1);
|
|
11434
|
+
const right = new Array(degree + 1);
|
|
11435
|
+
ndu[0][0] = 1;
|
|
11436
|
+
for (let j = 1; j <= degree; j++) {
|
|
11437
|
+
left[j] = u2 - knots[span + 1 - j];
|
|
11438
|
+
right[j] = knots[span + j] - u2;
|
|
11439
|
+
let saved = 0;
|
|
11440
|
+
for (let r2 = 0; r2 < j; r2++) {
|
|
11441
|
+
ndu[j][r2] = right[r2 + 1] + left[j - r2];
|
|
11442
|
+
const temp = ndu[j][r2] === 0 ? 0 : ndu[r2][j - 1] / ndu[j][r2];
|
|
11443
|
+
ndu[r2][j] = saved + right[r2 + 1] * temp;
|
|
11444
|
+
saved = left[j - r2] * temp;
|
|
11445
|
+
}
|
|
11446
|
+
ndu[j][j] = saved;
|
|
11447
|
+
}
|
|
11448
|
+
const ders = Array.from({ length: nDeriv + 1 }, () => new Array(degree + 1).fill(0));
|
|
11449
|
+
for (let j = 0; j <= degree; j++) {
|
|
11450
|
+
ders[0][j] = ndu[j][degree];
|
|
11451
|
+
}
|
|
11452
|
+
for (let r2 = 0; r2 <= degree; r2++) {
|
|
11453
|
+
let s1 = 0;
|
|
11454
|
+
let s2 = 1;
|
|
11455
|
+
a2[0][0] = 1;
|
|
11456
|
+
for (let k2 = 1; k2 <= nDeriv; k2++) {
|
|
11457
|
+
let d2 = 0;
|
|
11458
|
+
const rk = r2 - k2;
|
|
11459
|
+
const pk = degree - k2;
|
|
11460
|
+
if (r2 >= k2) {
|
|
11461
|
+
a2[s2][0] = ndu[pk + 1][rk] === 0 ? 0 : a2[s1][0] / ndu[pk + 1][rk];
|
|
11462
|
+
d2 = a2[s2][0] * ndu[rk][pk];
|
|
11463
|
+
}
|
|
11464
|
+
const j1 = rk >= -1 ? 1 : -rk;
|
|
11465
|
+
const j2 = r2 - 1 <= pk ? k2 - 1 : degree - r2;
|
|
11466
|
+
for (let j = j1; j <= j2; j++) {
|
|
11467
|
+
a2[s2][j] = ndu[pk + 1][rk + j] === 0 ? 0 : (a2[s1][j] - a2[s1][j - 1]) / ndu[pk + 1][rk + j];
|
|
11468
|
+
d2 += a2[s2][j] * ndu[rk + j][pk];
|
|
11469
|
+
}
|
|
11470
|
+
if (r2 <= pk) {
|
|
11471
|
+
a2[s2][k2] = ndu[pk + 1][r2] === 0 ? 0 : -a2[s1][k2 - 1] / ndu[pk + 1][r2];
|
|
11472
|
+
d2 += a2[s2][k2] * ndu[r2][pk];
|
|
11473
|
+
}
|
|
11474
|
+
ders[k2][r2] = d2;
|
|
11475
|
+
const tmp = s1;
|
|
11476
|
+
s1 = s2;
|
|
11477
|
+
s2 = tmp;
|
|
11478
|
+
}
|
|
11479
|
+
}
|
|
11480
|
+
let r = degree;
|
|
11481
|
+
for (let k2 = 1; k2 <= nDeriv; k2++) {
|
|
11482
|
+
for (let j = 0; j <= degree; j++) {
|
|
11483
|
+
ders[k2][j] *= r;
|
|
11484
|
+
}
|
|
11485
|
+
r *= degree - k2;
|
|
11486
|
+
}
|
|
11487
|
+
return ders;
|
|
11488
|
+
}
|
|
11430
11489
|
function deBoor3D(controlPoints, weights, knots, degree, u2) {
|
|
11431
11490
|
const n = controlPoints.length;
|
|
11432
11491
|
const span = findSpan(n, degree, u2, knots);
|
|
@@ -16863,7 +16922,7 @@ async function initTruckGeometryWasm() {
|
|
|
16863
16922
|
if (_initPromise$1) return _initPromise$1;
|
|
16864
16923
|
_initPromise$1 = (async () => {
|
|
16865
16924
|
try {
|
|
16866
|
-
const geometryModule = await import("./forgecad_geometry-
|
|
16925
|
+
const geometryModule = await import("./forgecad_geometry-CZ_IfuvA.js");
|
|
16867
16926
|
const isNode = isNodeRuntime();
|
|
16868
16927
|
if (isNode) {
|
|
16869
16928
|
const { readFileSync, existsSync } = await import("./__vite-browser-external-Dhvy_jtL.js");
|
|
@@ -17328,23 +17387,62 @@ class NurbsSurface {
|
|
|
17328
17387
|
return [wx / wSum, wy / wSum, wz / wSum];
|
|
17329
17388
|
}
|
|
17330
17389
|
/**
|
|
17331
|
-
* Evaluate the surface normal at (u, v)
|
|
17390
|
+
* Evaluate the surface unit normal at (u, v) from analytic first derivatives.
|
|
17391
|
+
*
|
|
17392
|
+
* Uses Algorithm A2.3 basis-function derivatives with the rational quotient
|
|
17393
|
+
* rule, so the normal is exact (no finite-difference epsilon, no error near
|
|
17394
|
+
* the boundary). Constant chain-rule factors from the parameter remap scale Su
|
|
17395
|
+
* and Sv positively and cancel under normalization, so they are omitted.
|
|
17332
17396
|
*/
|
|
17333
17397
|
normalAt(u2, v) {
|
|
17334
|
-
const
|
|
17335
|
-
const
|
|
17336
|
-
const
|
|
17337
|
-
const
|
|
17338
|
-
const pv = this.pointAt(u2, v1), pmv = this.pointAt(u2, v0);
|
|
17339
|
-
const du = [pu[0] - pmu[0], pu[1] - pmu[1], pu[2] - pmu[2]];
|
|
17340
|
-
const dv = [pv[0] - pmv[0], pv[1] - pmv[1], pv[2] - pmv[2]];
|
|
17341
|
-
const nx = du[1] * dv[2] - du[2] * dv[1];
|
|
17342
|
-
const ny = du[2] * dv[0] - du[0] * dv[2];
|
|
17343
|
-
const nz = du[0] * dv[1] - du[1] * dv[0];
|
|
17398
|
+
const { Su, Sv } = this.derivativesAt(u2, v);
|
|
17399
|
+
const nx = Su[1] * Sv[2] - Su[2] * Sv[1];
|
|
17400
|
+
const ny = Su[2] * Sv[0] - Su[0] * Sv[2];
|
|
17401
|
+
const nz = Su[0] * Sv[1] - Su[1] * Sv[0];
|
|
17344
17402
|
const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
|
17345
17403
|
if (len < 1e-12) return [0, 0, 1];
|
|
17346
17404
|
return [nx / len, ny / len, nz / len];
|
|
17347
17405
|
}
|
|
17406
|
+
/** Analytic first partial derivatives S_u, S_v (rational quotient rule). */
|
|
17407
|
+
derivativesAt(u2, v) {
|
|
17408
|
+
const uu = this.remapU(Math.max(0, Math.min(1, u2)));
|
|
17409
|
+
const vv = this.remapV(Math.max(0, Math.min(1, v)));
|
|
17410
|
+
const spanU = findSpan(this.nU, this.degreeU, uu, this.knotsU);
|
|
17411
|
+
const spanV = findSpan(this.nV, this.degreeV, vv, this.knotsV);
|
|
17412
|
+
const dU = basisFunsDeriv(spanU, uu, this.degreeU, this.knotsU, 1);
|
|
17413
|
+
const dV = basisFunsDeriv(spanV, vv, this.degreeV, this.knotsV, 1);
|
|
17414
|
+
const A = [0, 0, 0];
|
|
17415
|
+
const Au = [0, 0, 0];
|
|
17416
|
+
const Av = [0, 0, 0];
|
|
17417
|
+
let w2 = 0;
|
|
17418
|
+
let wu = 0;
|
|
17419
|
+
let wv = 0;
|
|
17420
|
+
for (let i = 0; i <= this.degreeU; i++) {
|
|
17421
|
+
const rowIdx = spanU - this.degreeU + i;
|
|
17422
|
+
for (let j = 0; j <= this.degreeV; j++) {
|
|
17423
|
+
const colIdx = spanV - this.degreeV + j;
|
|
17424
|
+
const weight = this.weightsGrid[rowIdx][colIdx];
|
|
17425
|
+
const pt = this.controlGrid[rowIdx][colIdx];
|
|
17426
|
+
const n00 = dU[0][i] * dV[0][j] * weight;
|
|
17427
|
+
const n10 = dU[1][i] * dV[0][j] * weight;
|
|
17428
|
+
const n01 = dU[0][i] * dV[1][j] * weight;
|
|
17429
|
+
w2 += n00;
|
|
17430
|
+
wu += n10;
|
|
17431
|
+
wv += n01;
|
|
17432
|
+
for (let c2 = 0; c2 < 3; c2++) {
|
|
17433
|
+
A[c2] += n00 * pt[c2];
|
|
17434
|
+
Au[c2] += n10 * pt[c2];
|
|
17435
|
+
Av[c2] += n01 * pt[c2];
|
|
17436
|
+
}
|
|
17437
|
+
}
|
|
17438
|
+
}
|
|
17439
|
+
if (w2 === 0) return { S: [0, 0, 0], Su: [0, 0, 0], Sv: [0, 0, 0] };
|
|
17440
|
+
const invW = 1 / w2;
|
|
17441
|
+
const S = [A[0] * invW, A[1] * invW, A[2] * invW];
|
|
17442
|
+
const Su = [(Au[0] - wu * S[0]) * invW, (Au[1] - wu * S[1]) * invW, (Au[2] - wu * S[2]) * invW];
|
|
17443
|
+
const Sv = [(Av[0] - wv * S[0]) * invW, (Av[1] - wv * S[1]) * invW, (Av[2] - wv * S[2]) * invW];
|
|
17444
|
+
return { S, Su, Sv };
|
|
17445
|
+
}
|
|
17348
17446
|
/**
|
|
17349
17447
|
* Tessellate the surface into a triangle mesh.
|
|
17350
17448
|
* Returns positions, normals, and triangle indices.
|
|
@@ -19656,6 +19754,20 @@ function fromSlicesSingleSliceHalfExtentForManifold(plan) {
|
|
|
19656
19754
|
}
|
|
19657
19755
|
return Math.max(1, radius + maxOffsetMagnitude + plan.boundsPadding + plan.edgeLength * 3);
|
|
19658
19756
|
}
|
|
19757
|
+
const BOOLEAN_OPERAND_NORMAL_SHARP_ANGLE_DEG = 60;
|
|
19758
|
+
function promoteBooleanOperandNormals(shapes) {
|
|
19759
|
+
let maxExtra = 0;
|
|
19760
|
+
for (const shape of shapes) maxExtra = Math.max(maxExtra, shape.numProp());
|
|
19761
|
+
if (maxExtra < 3) return { operands: shapes, created: [] };
|
|
19762
|
+
const created = [];
|
|
19763
|
+
const operands = shapes.map((shape) => {
|
|
19764
|
+
if (shape.numProp() >= 3) return shape;
|
|
19765
|
+
const promoted = shape.calculateNormals(0, BOOLEAN_OPERAND_NORMAL_SHARP_ANGLE_DEG);
|
|
19766
|
+
created.push(promoted);
|
|
19767
|
+
return promoted;
|
|
19768
|
+
});
|
|
19769
|
+
return { operands, created };
|
|
19770
|
+
}
|
|
19659
19771
|
function lowerShapeBooleanCompilePlan(plan, wasm) {
|
|
19660
19772
|
const shapes = plan.shapes.map((shape) => lowerShapeCompilePlanToManifold(shape, wasm));
|
|
19661
19773
|
if (shapes.length === 0) {
|
|
@@ -19664,16 +19776,18 @@ function lowerShapeBooleanCompilePlan(plan, wasm) {
|
|
|
19664
19776
|
if (shapes.length === 1) {
|
|
19665
19777
|
return shapes[0];
|
|
19666
19778
|
}
|
|
19779
|
+
const { operands, created } = promoteBooleanOperandNormals(shapes);
|
|
19667
19780
|
try {
|
|
19668
19781
|
switch (plan.op) {
|
|
19669
19782
|
case "union":
|
|
19670
|
-
return wasm.Manifold.union(
|
|
19783
|
+
return wasm.Manifold.union(operands);
|
|
19671
19784
|
case "difference":
|
|
19672
|
-
return wasm.Manifold.difference(
|
|
19785
|
+
return wasm.Manifold.difference(operands);
|
|
19673
19786
|
case "intersection":
|
|
19674
|
-
return wasm.Manifold.intersection(
|
|
19787
|
+
return wasm.Manifold.intersection(operands);
|
|
19675
19788
|
}
|
|
19676
19789
|
} finally {
|
|
19790
|
+
disposeWasmObjects(created);
|
|
19677
19791
|
disposeWasmObjects(shapes);
|
|
19678
19792
|
}
|
|
19679
19793
|
}
|
|
@@ -21023,12 +21137,16 @@ function lowerNurbsSurfaceToManifold(plan, wasm) {
|
|
|
21023
21137
|
const { positions, normals, indices } = surface.tessellate(res, res);
|
|
21024
21138
|
const thickness = plan.thickness;
|
|
21025
21139
|
const numVerts = positions.length;
|
|
21026
|
-
const
|
|
21027
|
-
for (const [x2, y2, z2] of positions) allPositions.push(x2, y2, z2);
|
|
21140
|
+
const vertProps = [];
|
|
21028
21141
|
for (let i = 0; i < numVerts; i++) {
|
|
21029
21142
|
const [x2, y2, z2] = positions[i];
|
|
21030
21143
|
const [nx, ny, nz] = normals[i];
|
|
21031
|
-
|
|
21144
|
+
vertProps.push(x2, y2, z2, nx, ny, nz);
|
|
21145
|
+
}
|
|
21146
|
+
for (let i = 0; i < numVerts; i++) {
|
|
21147
|
+
const [x2, y2, z2] = positions[i];
|
|
21148
|
+
const [nx, ny, nz] = normals[i];
|
|
21149
|
+
vertProps.push(x2 - nx * thickness, y2 - ny * thickness, z2 - nz * thickness, -nx, -ny, -nz);
|
|
21032
21150
|
}
|
|
21033
21151
|
const allIndices = [];
|
|
21034
21152
|
for (const idx of indices) allIndices.push(idx);
|
|
@@ -21053,11 +21171,12 @@ function lowerNurbsSurfaceToManifold(plan, wasm) {
|
|
|
21053
21171
|
allIndices.push(c2, c2 + numVerts, d2, d2, c2 + numVerts, d2 + numVerts);
|
|
21054
21172
|
}
|
|
21055
21173
|
const mesh = new wasm.Mesh({
|
|
21056
|
-
numProp:
|
|
21057
|
-
vertProperties: new Float32Array(
|
|
21174
|
+
numProp: 6,
|
|
21175
|
+
vertProperties: new Float32Array(vertProps),
|
|
21058
21176
|
triVerts: new Uint32Array(allIndices)
|
|
21059
21177
|
});
|
|
21060
21178
|
try {
|
|
21179
|
+
mesh.merge();
|
|
21061
21180
|
return new wasm.Manifold(mesh);
|
|
21062
21181
|
} finally {
|
|
21063
21182
|
disposeWasmObject(mesh);
|
|
@@ -37485,6 +37604,7 @@ const _TruckShapeBackend = class _TruckShapeBackend {
|
|
|
37485
37604
|
const payload = JSON.parse(getTruckGeometryWasm().geometry_mesh(this.getLiveHandle("getMesh()")));
|
|
37486
37605
|
const numTri = payload.triangles.length / 3;
|
|
37487
37606
|
const numVert = payload.positions.length / 3;
|
|
37607
|
+
const cornerNormals = payload.normals && payload.normals.length === numTri * 9 ? new Float32Array(payload.normals) : void 0;
|
|
37488
37608
|
this.resource.mesh = {
|
|
37489
37609
|
numProp: 3,
|
|
37490
37610
|
numTri,
|
|
@@ -37498,7 +37618,8 @@ const _TruckShapeBackend = class _TruckShapeBackend {
|
|
|
37498
37618
|
runTransform: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]),
|
|
37499
37619
|
faceID: new Int32Array(payload.face_ids),
|
|
37500
37620
|
faceIdNames: payload.face_id_names ?? [],
|
|
37501
|
-
halfedgeTangent: new Float32Array(0)
|
|
37621
|
+
halfedgeTangent: new Float32Array(0),
|
|
37622
|
+
cornerNormals
|
|
37502
37623
|
};
|
|
37503
37624
|
return this.resource.mesh;
|
|
37504
37625
|
}
|
|
@@ -38719,6 +38840,16 @@ function boundsInteriorOverlap(a2, b) {
|
|
|
38719
38840
|
const tolerance = 1e-8;
|
|
38720
38841
|
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;
|
|
38721
38842
|
}
|
|
38843
|
+
function boundsFaceOrInteriorOverlap(a2, b) {
|
|
38844
|
+
const tolerance = 1e-8;
|
|
38845
|
+
const overlaps = [
|
|
38846
|
+
Math.min(a2.max[0], b.max[0]) - Math.max(a2.min[0], b.min[0]),
|
|
38847
|
+
Math.min(a2.max[1], b.max[1]) - Math.max(a2.min[1], b.min[1]),
|
|
38848
|
+
Math.min(a2.max[2], b.max[2]) - Math.max(a2.min[2], b.min[2])
|
|
38849
|
+
];
|
|
38850
|
+
if (overlaps.some((overlap) => overlap < -tolerance)) return false;
|
|
38851
|
+
return overlaps.filter((overlap) => overlap <= tolerance).length <= 1;
|
|
38852
|
+
}
|
|
38722
38853
|
function boundsFromPoints(points) {
|
|
38723
38854
|
const first = points[0];
|
|
38724
38855
|
if (!first) return null;
|
|
@@ -38801,16 +38932,16 @@ function shapePlanBounds(plan) {
|
|
|
38801
38932
|
return null;
|
|
38802
38933
|
}
|
|
38803
38934
|
}
|
|
38804
|
-
function
|
|
38935
|
+
function hasPairwiseFaceOrInteriorBoundsOverlap(shapes) {
|
|
38805
38936
|
const bounds = shapes.map((shape) => shape.boundingBox());
|
|
38806
38937
|
for (let i = 0; i < bounds.length; i++) {
|
|
38807
38938
|
for (let j = i + 1; j < bounds.length; j++) {
|
|
38808
|
-
if (
|
|
38939
|
+
if (boundsFaceOrInteriorOverlap(bounds[i], bounds[j])) return true;
|
|
38809
38940
|
}
|
|
38810
38941
|
}
|
|
38811
38942
|
return false;
|
|
38812
38943
|
}
|
|
38813
|
-
function
|
|
38944
|
+
function faceOrInteriorOverlapComponents(shapes) {
|
|
38814
38945
|
const bounds = shapes.map((shape) => shape.boundingBox());
|
|
38815
38946
|
const visited = /* @__PURE__ */ new Set();
|
|
38816
38947
|
const components = [];
|
|
@@ -38824,7 +38955,7 @@ function interiorOverlapComponents(shapes) {
|
|
|
38824
38955
|
component.push(current);
|
|
38825
38956
|
for (let next = 0; next < shapes.length; next++) {
|
|
38826
38957
|
if (visited.has(next)) continue;
|
|
38827
|
-
if (
|
|
38958
|
+
if (boundsFaceOrInteriorOverlap(bounds[current], bounds[next])) {
|
|
38828
38959
|
visited.add(next);
|
|
38829
38960
|
queue.push(next);
|
|
38830
38961
|
}
|
|
@@ -38869,10 +39000,10 @@ function lowerGenericBooleanPlan(plan) {
|
|
|
38869
39000
|
let returned = null;
|
|
38870
39001
|
try {
|
|
38871
39002
|
if (plan.op === "union") {
|
|
38872
|
-
if (!
|
|
39003
|
+
if (!hasPairwiseFaceOrInteriorBoundsOverlap(shapes)) {
|
|
38873
39004
|
return null;
|
|
38874
39005
|
}
|
|
38875
|
-
const components =
|
|
39006
|
+
const components = faceOrInteriorOverlapComponents(shapes);
|
|
38876
39007
|
if (components.length > 1) {
|
|
38877
39008
|
returned = lowerClusteredUnion(shapes, components);
|
|
38878
39009
|
return returned;
|
|
@@ -39402,9 +39533,13 @@ function shapeHasClosedNativeTopology(shape) {
|
|
|
39402
39533
|
function normalizeTruckShapeForBooleanInput(shape) {
|
|
39403
39534
|
if (shapeHasClosedNativeTopology(shape)) return shape;
|
|
39404
39535
|
if (!meshHasRawBoundaryEdges(shape.getMesh())) return shape;
|
|
39405
|
-
|
|
39406
|
-
|
|
39407
|
-
|
|
39536
|
+
try {
|
|
39537
|
+
const normalized = normalizeFacetedTruckShape(shape);
|
|
39538
|
+
disposeShapeBackend(shape);
|
|
39539
|
+
return normalized;
|
|
39540
|
+
} catch {
|
|
39541
|
+
return shape;
|
|
39542
|
+
}
|
|
39408
39543
|
}
|
|
39409
39544
|
function lowerSdfPlan(plan) {
|
|
39410
39545
|
if (getUnsupportedSdfProgramReason(plan.tree) === void 0) {
|
|
@@ -41288,7 +41423,7 @@ function circleProfilePlan(radius, segments) {
|
|
|
41288
41423
|
}
|
|
41289
41424
|
function annulusProfilePlan(outerRadius, innerRadius, segments) {
|
|
41290
41425
|
const outer = Math.abs(outerRadius);
|
|
41291
|
-
const inner = Math.
|
|
41426
|
+
const inner = Math.max(0, innerRadius);
|
|
41292
41427
|
if (outer <= EXACT_PROFILE_EPS) return emptyProfilePlan();
|
|
41293
41428
|
if (inner <= EXACT_PROFILE_EPS) return circleProfilePlan(outer, segments);
|
|
41294
41429
|
return {
|
|
@@ -49960,7 +50095,7 @@ class Shape {
|
|
|
49960
50095
|
*
|
|
49961
50096
|
* Use `.color()` to set the base diffuse color; `.material()` controls how that color behaves
|
|
49962
50097
|
* under light (metalness, roughness, clearcoat) and can add emissive glow independent of
|
|
49963
|
-
* lighting.
|
|
50098
|
+
* lighting.
|
|
49964
50099
|
*
|
|
49965
50100
|
* **Example**
|
|
49966
50101
|
*
|
|
@@ -51493,7 +51628,8 @@ class FrozenShape extends Shape {
|
|
|
51493
51628
|
const EDGE_THRESHOLD_DOT = Math.cos(Math.PI / 180);
|
|
51494
51629
|
const SMOOTH_THRESHOLD_DOT = Math.cos(30 * Math.PI / 180);
|
|
51495
51630
|
function computeGeometryArrays(mesh, options = {}) {
|
|
51496
|
-
const { numProp, numTri: triCount, triVerts, vertProperties, vertNormals } = mesh;
|
|
51631
|
+
const { numProp, numTri: triCount, triVerts, vertProperties, vertNormals, cornerNormals } = mesh;
|
|
51632
|
+
const useCornerNormals = !!cornerNormals && cornerNormals.length === triCount * 9;
|
|
51497
51633
|
const positions = new Float32Array(triCount * 9);
|
|
51498
51634
|
const normals = new Float32Array(triCount * 9);
|
|
51499
51635
|
const faceNx = new Float32Array(triCount);
|
|
@@ -51525,7 +51661,9 @@ function computeGeometryArrays(mesh, options = {}) {
|
|
|
51525
51661
|
positions[o + 6] = cx;
|
|
51526
51662
|
positions[o + 7] = cy;
|
|
51527
51663
|
positions[o + 8] = cz;
|
|
51528
|
-
if (
|
|
51664
|
+
if (useCornerNormals) {
|
|
51665
|
+
for (let k2 = 0; k2 < 9; k2++) normals[o + k2] = cornerNormals[o + k2];
|
|
51666
|
+
} else if (vertNormals) {
|
|
51529
51667
|
normals[o] = vertNormals[i0 * 3];
|
|
51530
51668
|
normals[o + 1] = vertNormals[i0 * 3 + 1];
|
|
51531
51669
|
normals[o + 2] = vertNormals[i0 * 3 + 2];
|
|
@@ -51568,7 +51706,7 @@ function computeGeometryArrays(mesh, options = {}) {
|
|
|
51568
51706
|
faceNy[t] = fny;
|
|
51569
51707
|
faceNz[t] = fnz;
|
|
51570
51708
|
}
|
|
51571
|
-
if (!vertNormals && numProp < 6 && triCount > 0) {
|
|
51709
|
+
if (!useCornerNormals && !vertNormals && numProp < 6 && triCount > 0) {
|
|
51572
51710
|
computeAutoSmoothNormals(
|
|
51573
51711
|
triVerts,
|
|
51574
51712
|
vertProperties,
|
|
@@ -51755,7 +51893,8 @@ function shapeToGeometryFallback(shape) {
|
|
|
51755
51893
|
vertProperties: mesh.vertProperties,
|
|
51756
51894
|
mergeFromVert: mesh.mergeFromVert,
|
|
51757
51895
|
mergeToVert: mesh.mergeToVert,
|
|
51758
|
-
vertNormals
|
|
51896
|
+
vertNormals,
|
|
51897
|
+
cornerNormals: mesh.cornerNormals && mesh.cornerNormals.length === mesh.numTri * 9 ? mesh.cornerNormals : void 0
|
|
51759
51898
|
});
|
|
51760
51899
|
const solid = new BufferGeometry();
|
|
51761
51900
|
solid.setAttribute("position", new BufferAttribute(positions, 3));
|