forgecad 0.9.15 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/assets/{AdminPage-CDyGUinA.js → AdminPage-DwYHz72L.js} +1 -1
  2. package/dist/assets/{BenchmarkPage-DfPMY_-d.js → BenchmarkPage-a9_f-1US.js} +1 -1
  3. package/dist/assets/{BlogPage-kF0fkdJT.js → BlogPage-DodHpvmf.js} +1 -1
  4. package/dist/assets/{DocsPage-B954L3YN.js → DocsPage-B5LePEuj.js} +8 -858
  5. package/dist/assets/{EditorApp-CuDLxKqL.css → EditorApp-BpjZgzk0.css} +148 -0
  6. package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
  7. package/dist/assets/{EmbedViewer-C77B-TrF.js → EmbedViewer-DdEHGUMU.js} +2 -2
  8. package/dist/assets/{LandingPageProofDriven-Cr6fXMDj.js → LandingPageProofDriven-yhhOodbf.js} +2 -2
  9. package/dist/assets/{LegalPage-Dzklqmmg.js → LegalPage-5RbKRGYK.js} +1 -1
  10. package/dist/assets/{PricingPage-zWXkvlwl.js → PricingPage-E3Rma7aV.js} +1 -1
  11. package/dist/assets/{SettingsPage-Bz0of4KQ.js → SettingsPage-BJZcM97j.js} +1 -1
  12. package/dist/assets/{app-D3kDkggg.js → app-DSYrDg0V.js} +1846 -352
  13. package/dist/assets/cli/{render-DSY3mMQa.js → render-ZMHR9HkV.js} +161 -70
  14. package/dist/assets/{constructionHistoryWorker-gpDo-uH2.js → constructionHistoryWorker-AwMMWSxg.js} +1104 -349
  15. package/dist/assets/{evalWorker-CU0Ke6DP.js → evalWorker-DbNs7Dkp.js} +5155 -3772
  16. package/dist/assets/{inspectWorker-COyp8XXA.js → inspectWorker-CZsCFtQT.js} +1415 -439
  17. package/dist/assets/{targets-B9sGB5nB.js → jointPose-DO6mnXn_.js} +71 -3
  18. package/dist/assets/{manifold-DNkrUWpA.js → manifold-BGlQBBH9.js} +1 -1
  19. package/dist/assets/{manifold-BRI5prcH.js → manifold-BU-tJwQh.js} +1 -1
  20. package/dist/assets/{manifold-C-3h2M7p.js → manifold-fy2MV7K1.js} +2 -2
  21. package/dist/assets/{reportWorker-CdBz5bNg.js → reportWorker-DO6hcQbh.js} +8474 -4549
  22. package/dist/assets/{scalar-sampling-budget-wJF98aY9.js → scalar-sampling-budget-o90NSNmF.js} +5347 -3906
  23. package/dist/assets/{scanProxyWorker-B-9VbLIs.js → scanProxyWorker-2GtDLk-R.js} +19 -6
  24. package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
  25. package/dist/cli/render.html +1 -1
  26. package/dist/docs/index.html +3 -3
  27. package/dist/docs-raw/AI/usage.md +3 -1
  28. package/dist/docs-raw/CLI.md +65 -239
  29. package/dist/docs-raw/README.md +6 -0
  30. package/dist/docs-raw/component-model.md +17 -150
  31. package/dist/docs-raw/generated/assembly.md +159 -520
  32. package/dist/docs-raw/generated/concepts.md +245 -3491
  33. package/dist/docs-raw/generated/core.md +277 -1251
  34. package/dist/docs-raw/generated/curves.md +387 -1608
  35. package/dist/docs-raw/generated/legacy.md +162 -0
  36. package/dist/docs-raw/generated/lib.md +238 -112
  37. package/dist/docs-raw/generated/output.md +51 -76
  38. package/dist/docs-raw/generated/runtime-names.md +30 -22
  39. package/dist/docs-raw/generated/sdf.md +68 -284
  40. package/dist/docs-raw/generated/sheet-metal.md +68 -335
  41. package/dist/docs-raw/generated/sketch.md +240 -1161
  42. package/dist/docs-raw/generated/viewport.md +75 -316
  43. package/dist/docs-raw/generated/wood.md +21 -49
  44. package/dist/docs-raw/guides/coordinate-system.md +4 -42
  45. package/dist/docs-raw/guides/inspection-bundles.md +44 -442
  46. package/dist/docs-raw/guides/joint-design.md +18 -79
  47. package/dist/docs-raw/guides/positioning.md +21 -143
  48. package/dist/docs-raw/guides/scene-presentation.md +89 -0
  49. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
  50. package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
  51. package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
  52. package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
  53. package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
  54. package/dist/docs-raw/skills/forgecad-lld.md +19 -113
  55. package/dist/docs-raw/skills/forgecad-make-a-model.md +113 -532
  56. package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
  57. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
  58. package/dist/docs-raw/skills/forgecad-project.md +13 -129
  59. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
  60. package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
  61. package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
  62. package/dist/docs-raw/skills/forgecad.md +19 -18
  63. package/dist/docs-raw/skills/index.md +2 -0
  64. package/dist/docs-raw/welcome.md +4 -2
  65. package/dist/index.html +1 -1
  66. package/dist/llms.txt +1 -2
  67. package/dist/sitemap.xml +13 -13
  68. package/dist-cli/{check-compiler-SDX5QIXI.js → check-compiler-JTVBITCR.js} +1 -1
  69. package/dist-cli/{check-query-propagation-EAYEFT77.js → check-query-propagation-3FFLSMVN.js} +1 -1
  70. package/dist-cli/{chunk-N4O47JLF.js → chunk-OAN5T4XD.js} +5722 -4287
  71. package/dist-cli/forgecad.js +2195 -656
  72. package/dist-skill/CONTEXT.md +1778 -7912
  73. package/dist-skill/SKILL.md +15 -15
  74. package/dist-skill/docs/API/core/concepts.md +27 -157
  75. package/dist-skill/docs/CLI.md +65 -239
  76. package/dist-skill/docs/generated/assembly.md +160 -493
  77. package/dist-skill/docs/generated/core.md +277 -1251
  78. package/dist-skill/docs/generated/curves.md +387 -1609
  79. package/dist-skill/docs/generated/lib.md +238 -112
  80. package/dist-skill/docs/generated/output.md +51 -76
  81. package/dist-skill/docs/generated/runtime-names.md +16 -22
  82. package/dist-skill/docs/generated/sdf.md +68 -284
  83. package/dist-skill/docs/generated/sheet-metal.md +68 -335
  84. package/dist-skill/docs/generated/sketch.md +240 -1160
  85. package/dist-skill/docs/generated/viewport.md +75 -223
  86. package/dist-skill/docs/generated/wood.md +21 -49
  87. package/dist-skill/docs/guides/coordinate-system.md +4 -42
  88. package/dist-skill/docs/guides/inspection-bundles.md +44 -442
  89. package/dist-skill/docs/guides/joint-design.md +18 -79
  90. package/dist-skill/docs/guides/positioning.md +21 -143
  91. package/dist-skill/docs/guides/scene-presentation.md +89 -0
  92. package/dist-skill/docs/guides/surface-members.md +26 -0
  93. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
  94. package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
  95. package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
  96. package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
  97. package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
  98. package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
  99. package/dist-skill/library/forgecad-make-a-model/SKILL.md +111 -532
  100. package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
  101. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
  102. package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
  103. package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
  104. package/dist-skill/library/forgecad-project/SKILL.md +13 -131
  105. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
  106. package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
  107. package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
  108. package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
  109. package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
  110. package/dist-skill/website/skills/forgecad-component-model.md +53 -0
  111. package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
  112. package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
  113. package/dist-skill/website/skills/forgecad-lld.md +41 -0
  114. package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
  115. package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
  116. package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
  117. package/dist-skill/website/skills/forgecad-project.md +26 -0
  118. package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
  119. package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
  120. package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
  121. package/dist-skill/website/skills/forgecad.md +122 -0
  122. package/dist-skill/website/skills/index.md +26 -0
  123. package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
  124. package/examples/api/conformal-product-ribbon.forge.js +1 -1
  125. package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
  126. package/examples/api/extrude-options.forge.js +4 -2
  127. package/examples/api/field-loft-drive-tip.forge.js +40 -0
  128. package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
  129. package/examples/api/helix-basics.forge.js +2 -2
  130. package/examples/api/highlight-debug.forge.js +10 -10
  131. package/examples/api/mesh-import-slats.forge.js +1 -1
  132. package/examples/api/real-product-curves.forge.js +1 -1
  133. package/examples/api/route3d-elbow.forge.js +3 -0
  134. package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
  135. package/examples/api/sdf-shapes.forge.js +2 -5
  136. package/examples/api/sketch-rounding-strategies.forge.js +6 -6
  137. package/examples/api/surface-member-bottle-cage.forge.js +3 -3
  138. package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
  139. package/examples/api/surface-member-razor-inlay.forge.js +1 -1
  140. package/examples/api/variable-sweep-test.forge.js +4 -2
  141. package/examples/mechanical/airplane-propeller.forge.js +74 -39
  142. package/examples/nurbs-surface.forge.js +1 -1
  143. package/examples/products/iphone.forge.js +1 -1
  144. package/package.json +4 -1
  145. package/dist/assets/EditorApp-Beb-IZ0y.js +0 -14014
  146. package/dist/docs-raw/guides/geometry-conventions.md +0 -52
  147. package/dist/docs-raw/guides/modeling-recipes.md +0 -78
  148. package/dist-skill/docs/guides/geometry-conventions.md +0 -52
  149. package/dist-skill/docs/guides/modeling-recipes.md +0 -78
  150. package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
  151. package/examples/api/bolted-service-cover.forge.js +0 -17
  152. package/examples/api/cable-gland-anchor.forge.js +0 -14
  153. package/examples/api/captured-cartridge-guide.forge.js +0 -14
  154. package/examples/api/captured-linear-slide.forge.js +0 -13
  155. package/examples/api/clevis-pin-joint.forge.js +0 -13
  156. package/examples/api/datum-enclosure.forge.js +0 -16
  157. package/examples/api/hose-barb-port.forge.js +0 -14
  158. package/examples/api/knuckled-hinge-assembly.forge.js +0 -15
  159. package/examples/api/living-hinge-cover.forge.js +0 -14
  160. package/examples/api/pcb-terminal-block.forge.js +0 -22
  161. package/examples/api/pinned-lever-pivot-stack.forge.js +0 -14
  162. package/examples/api/retained-shaft-knob-stack.forge.js +0 -15
  163. package/examples/api/routed-tube-clip.forge.js +0 -15
  164. package/examples/api/seated-bearing-stack.forge.js +0 -30
  165. package/examples/api/snap-latch-cover.forge.js +0 -14
  166. package/examples/api/thumb-screw-clamp.forge.js +0 -15
@@ -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, cC as initSolverWasm, cB as initKernel, S as Scene, cD as BoxGeometry, bV as MeshStandardMaterial, a4 as BackSide, b7 as PointLight, M as Mesh, aa as MeshBasicMaterial, cE as localAabbPlaneRelation, h as Vector2, cF as ShapeUtils, cG as analyzePhysicalConnectivity, g as Vector3, $ as Matrix4, cH as Frustum, G as Box3, a0 as MathUtils, cI as meshContactDataFor, cJ as AabbSpatialIndex, cK as detectPhysicalContact, cL as resolveThicknessInspectionOptions, R as Raycaster, cM as thicknessColor, cN as thicknessClass, a$ as BufferAttribute, cO as roughnessClassForAngle, cP as resolveRoughnessInspectionOptions, cQ as roughnessColorForAngle, cR as roughnessScoreForAngle, cS as activateBackend, e as Color, ba as COMPARISON_COLORS, ay as resolveForgeRenderStyle, by as getRenderStylePreset, ax as setParamOverrides, bl as runScript, cm as scanProxyGridForBounds, cT as Group, be as shapeToGeometry, bm as MeshPhysicalMaterial, bA as NormalBlending, cU as createScanProxyGeometry, bw as AdditiveBlending, aO as LineBasicMaterial, bn as LineSegments, aN as BufferGeometry, P as PerspectiveCamera, cj as DEFAULT_VIEW_CONFIG, bs as worldAuthorPlaneToLocal, cV as resolveSectionHatchMetrics, cu as buildGeometryComparisonPointCloud, cs as triangleSoupFromMeshes, O as OrthographicCamera, k as ShaderMaterial, bG as ZEBRA_STRIPE_FRAGMENT_SHADER, bH as ZEBRA_STRIPE_VERTEX_SHADER, bB as ZEBRA_STRIPE_SOFTNESS, bC as ZEBRA_STRIPE_SCALE, bD as ZEBRA_LIGHT_COLOR, bE as ZEBRA_DARK_COLOR, bF as ZEBRA_ACCENT_COLOR, bx as geometryWithVisibleVertexColors, cW as intersectWithPlane, cX as setActiveBackend, W as WebGLRenderer, A as ACESFilmicToneMapping, c as SRGBColorSpace, cY as parseCameraCliSpec, cZ as PMREMGenerator, b0 as CanvasTexture, b1 as Object3D, b2 as FogExp2, b3 as Fog, b4 as AmbientLight, b8 as DirectionalLight, b5 as HemisphereLight, aI as findJointAnimationClip, p as Plane, bJ as SURFACE_FIELD_FRAGMENT_SHADER, bK as SURFACE_FIELD_VERTEX_SHADER, bI as SCAN_PROXY_LAYER_STYLES, Y as Vector4, bY as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bX as buildSdfRaymarchFragmentShader, aJ as resolveJointAnimation, aK as resolveJointViewValues, bP as ROUGHNESS_COLORS, c_ as PointsMaterial, c$ as Points, b9 as heatPointsForSide, d0 as analyzeCollisionIntersections, d1 as serializeCollisionFinding, d2 as summarizeThicknessSamples, bR as THICKNESS_COLORS, b6 as SpotLight, c0 as CylinderGeometry, d3 as TorusGeometry, bM as CatmullRomCurve3, bN as TubeGeometry, cy as resolveScalarSceneSampleBudget, bf as buildComparisonHeatPatchGeometry, bg as EdgesGeometry, d4 as SphereGeometry, d5 as ConeGeometry, bb as comparisonHeatDepthTest, bc as comparisonHeatEdgeOpacity, bd as comparisonHeatPatchOpacity, cA as comparisonCandidateContextOpacity, d6 as DEFAULT_COMPARISON_CANDIDATE_OPACITY } from "../scalar-sampling-budget-wJF98aY9.js";
5
- import { m as mergeViewportRenderSceneStates, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../targets-B9sGB5nB.js";
4
+ import { D as DoubleSide, cE as initSolverWasm, cD as initKernel, S as Scene, cF as BoxGeometry, bW as MeshStandardMaterial, a4 as BackSide, b7 as PointLight, M as Mesh, aa as MeshBasicMaterial, cG as localAabbPlaneRelation, h as Vector2, cH as ShapeUtils, cI as analyzePhysicalConnectivity, g as Vector3, $ as Matrix4, cJ as Frustum, G as Box3, a0 as MathUtils, cK as meshContactDataFor, cL as AabbSpatialIndex, cM as detectPhysicalContact, cN as resolveThicknessInspectionOptions, R as Raycaster, cO as thicknessColor, cP as thicknessClass, a$ as BufferAttribute, cQ as roughnessClassForAngle, cR as resolveRoughnessInspectionOptions, cS as roughnessColorForAngle, cT as roughnessScoreForAngle, cU as activateBackend, e as Color, ba as COMPARISON_COLORS, ay as resolveForgeRenderStyle, by as getRenderStylePreset, ax as setParamOverrides, bl as runScript, cn as scanProxyGridForBounds, cV as Group, be as shapeToGeometry, bm as MeshPhysicalMaterial, bw as AdditiveBlending, bB as scanMaterialShellColor, cW as createScanProxyGeometry, aO as LineBasicMaterial, bA as NormalBlending, bn as LineSegments, aN as BufferGeometry, P as PerspectiveCamera, ck as DEFAULT_VIEW_CONFIG, bs as worldAuthorPlaneToLocal, cX as resolveSectionHatchMetrics, cv as buildGeometryComparisonPointCloud, ct as triangleSoupFromMeshes, O as OrthographicCamera, k as ShaderMaterial, bH as ZEBRA_STRIPE_FRAGMENT_SHADER, bI as ZEBRA_STRIPE_VERTEX_SHADER, bC as ZEBRA_STRIPE_SOFTNESS, bD as ZEBRA_STRIPE_SCALE, bE as ZEBRA_LIGHT_COLOR, bF as ZEBRA_DARK_COLOR, bG as ZEBRA_ACCENT_COLOR, bx as geometryWithVisibleVertexColors, cY as intersectWithPlane, cZ as setActiveBackend, W as WebGLRenderer, A as ACESFilmicToneMapping, c as SRGBColorSpace, c_ as parseCameraCliSpec, c$ as PMREMGenerator, b0 as CanvasTexture, b1 as Object3D, b2 as FogExp2, b3 as Fog, b4 as AmbientLight, b8 as DirectionalLight, b5 as HemisphereLight, aI as findJointAnimationClip, p as Plane, bL as SURFACE_FIELD_FRAGMENT_SHADER, bM as SURFACE_FIELD_VERTEX_SHADER, bK as scanMaterialLayerStyles, bJ as SCAN_PROXY_LAYER_STYLES, Y as Vector4, bZ as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bY as buildSdfRaymarchFragmentShader, aJ as resolveJointAnimation, aK as resolveJointViewValues, bR as ROUGHNESS_COLORS, d0 as PointsMaterial, d1 as Points, b9 as heatPointsForSide, d2 as analyzeCollisionIntersections, d3 as serializeCollisionFinding, d4 as summarizeThicknessSamples, bQ as THICKNESS_GRADIENT_COLORS, d5 as THICKNESS_COLORS, b6 as SpotLight, c1 as CylinderGeometry, d6 as TorusGeometry, bO as CatmullRomCurve3, bP as TubeGeometry, cz as resolveScalarSceneSampleBudget, bf as buildComparisonHeatPatchGeometry, bg as EdgesGeometry, d7 as SphereGeometry, d8 as ConeGeometry, bb as comparisonHeatDepthTest, bc as comparisonHeatEdgeOpacity, bd as comparisonHeatPatchOpacity, cB as comparisonCandidateContextOpacity, d9 as DEFAULT_COMPARISON_CANDIDATE_OPACITY } from "../scalar-sampling-budget-o90NSNmF.js";
5
+ import { m as mergeViewportRenderSceneStates, v as validateJointOverrides, b as buildBaseJointValues, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../jointPose-DO6mnXn_.js";
6
6
  const CAD_MATERIAL_PROPS = {
7
7
  color: 6003669,
8
8
  metalness: 0.05,
@@ -754,6 +754,9 @@ function analyzeCameraFraming(camera, objects) {
754
754
  fullyOutOfFrame
755
755
  };
756
756
  }
757
+ function selectRenderSceneBoundsEntries(entries) {
758
+ return entries.filter((entry) => entry.visible);
759
+ }
757
760
  const DEFAULT_CONTACT_TOLERANCE = 0.05;
758
761
  const DEFAULT_BED_TOLERANCE = 0.05;
759
762
  const DEFAULT_GROUND_Z = 0;
@@ -1110,6 +1113,92 @@ ${body}
1110
1113
  pathCount
1111
1114
  };
1112
1115
  }
1116
+ class DisjointSet {
1117
+ constructor(size) {
1118
+ __publicField(this, "parent");
1119
+ __publicField(this, "rank");
1120
+ this.parent = Array.from({ length: size }, (_, index) => index);
1121
+ this.rank = Array.from({ length: size }, () => 0);
1122
+ }
1123
+ find(index) {
1124
+ const parent = this.parent[index];
1125
+ if (parent === index) return index;
1126
+ const root = this.find(parent);
1127
+ this.parent[index] = root;
1128
+ return root;
1129
+ }
1130
+ union(a, b) {
1131
+ const rootA = this.find(a);
1132
+ const rootB = this.find(b);
1133
+ if (rootA === rootB) return;
1134
+ if (this.rank[rootA] < this.rank[rootB]) {
1135
+ this.parent[rootA] = rootB;
1136
+ } else if (this.rank[rootA] > this.rank[rootB]) {
1137
+ this.parent[rootB] = rootA;
1138
+ } else {
1139
+ this.parent[rootB] = rootA;
1140
+ this.rank[rootA] += 1;
1141
+ }
1142
+ }
1143
+ }
1144
+ function connectedCoplanarSurfacePatches(triangles) {
1145
+ const snap = surfacePatchSnap(triangles);
1146
+ const planeKeys = triangles.map((triangle) => planeKey(triangle, snap));
1147
+ const edgeOwners = /* @__PURE__ */ new Map();
1148
+ const sets = new DisjointSet(triangles.length);
1149
+ triangles.forEach((triangle, index) => {
1150
+ for (const key of triangleEdgeKeys(triangle, snap)) {
1151
+ const owners = edgeOwners.get(key);
1152
+ if (owners) {
1153
+ for (const owner of owners) {
1154
+ if (planeKeys[owner] === planeKeys[index]) sets.union(owner, index);
1155
+ }
1156
+ owners.push(index);
1157
+ } else {
1158
+ edgeOwners.set(key, [index]);
1159
+ }
1160
+ }
1161
+ });
1162
+ const patchByRoot = /* @__PURE__ */ new Map();
1163
+ triangles.forEach((triangle, index) => {
1164
+ const root = sets.find(index);
1165
+ const patch = patchByRoot.get(root) ?? { triangleIndexes: [], area: 0 };
1166
+ patch.triangleIndexes.push(index);
1167
+ patch.area += triangle.area;
1168
+ patchByRoot.set(root, patch);
1169
+ });
1170
+ return [...patchByRoot.values()];
1171
+ }
1172
+ function surfacePatchSnap(triangles) {
1173
+ const bounds = new Box3();
1174
+ for (const triangle of triangles) {
1175
+ bounds.expandByPoint(triangle.a);
1176
+ bounds.expandByPoint(triangle.b);
1177
+ bounds.expandByPoint(triangle.c);
1178
+ }
1179
+ const size = bounds.getSize(new Vector3());
1180
+ return Math.max(1e-6, size.length() * 1e-8);
1181
+ }
1182
+ function planeKey(triangle, snap) {
1183
+ const normalSnap = 1e-6;
1184
+ const distance = triangle.normal.dot(triangle.a);
1185
+ return [
1186
+ Math.round(triangle.normal.x / normalSnap),
1187
+ Math.round(triangle.normal.y / normalSnap),
1188
+ Math.round(triangle.normal.z / normalSnap),
1189
+ Math.round(distance / snap)
1190
+ ].join(",");
1191
+ }
1192
+ function triangleEdgeKeys(triangle, snap) {
1193
+ const vertices = [vertexKey$2(triangle.a, snap), vertexKey$2(triangle.b, snap), vertexKey$2(triangle.c, snap)];
1194
+ return [edgeKey$1(vertices[0], vertices[1]), edgeKey$1(vertices[1], vertices[2]), edgeKey$1(vertices[2], vertices[0])];
1195
+ }
1196
+ function vertexKey$2(point, snap) {
1197
+ return `${Math.round(point.x / snap)},${Math.round(point.y / snap)},${Math.round(point.z / snap)}`;
1198
+ }
1199
+ function edgeKey$1(a, b) {
1200
+ return a < b ? `${a}|${b}` : `${b}|${a}`;
1201
+ }
1113
1202
  const MIN_TRIANGLE_AREA = 1e-12;
1114
1203
  const R2_ALPHA = 0.7548776662466927;
1115
1204
  const R2_BETA = 0.5698402909980532;
@@ -1162,7 +1251,7 @@ function allocateAreaSampleCounts(triangles, maxSamples) {
1162
1251
  return counts;
1163
1252
  }
1164
1253
  function sampleSurfaceTriangles(triangles, maxSamples) {
1165
- const counts = allocateAreaSampleCounts(triangles, maxSamples);
1254
+ const counts = allocateSurfacePatchSampleCounts(triangles, maxSamples);
1166
1255
  const samples = [];
1167
1256
  const position = new Vector3();
1168
1257
  let sampleIndex = 0;
@@ -1187,6 +1276,35 @@ function sampleSurfaceTriangles(triangles, maxSamples) {
1187
1276
  });
1188
1277
  return samples;
1189
1278
  }
1279
+ function allocateSurfacePatchSampleCounts(triangles, maxSamples) {
1280
+ const counts = new Array(triangles.length).fill(0);
1281
+ if (triangles.length === 0) return counts;
1282
+ const patches = connectedCoplanarSurfacePatches(triangles);
1283
+ const patchCounts = allocateAreaSampleCounts(
1284
+ patches.map((patch, index) => {
1285
+ var _a, _b, _c, _d;
1286
+ return {
1287
+ index,
1288
+ a: ((_a = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _a.a) ?? new Vector3(),
1289
+ b: ((_b = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _b.b) ?? new Vector3(),
1290
+ c: ((_c = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _c.c) ?? new Vector3(),
1291
+ normal: ((_d = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _d.normal) ?? new Vector3(0, 0, 1),
1292
+ area: patch.area
1293
+ };
1294
+ }),
1295
+ maxSamples
1296
+ );
1297
+ patches.forEach((patch, patchIndex) => {
1298
+ const patchBudget = patchCounts[patchIndex] ?? 0;
1299
+ if (patchBudget <= 0) return;
1300
+ const patchTriangles = patch.triangleIndexes.map((index) => triangles[index]);
1301
+ const localCounts = allocateAreaSampleCounts(patchTriangles, patchBudget);
1302
+ patch.triangleIndexes.forEach((triangleIndex, localIndex) => {
1303
+ counts[triangleIndex] += localCounts[localIndex] ?? 0;
1304
+ });
1305
+ });
1306
+ return counts;
1307
+ }
1190
1308
  function totalSurfaceArea(triangles) {
1191
1309
  return triangles.reduce((sum, triangle) => sum + triangle.area, 0);
1192
1310
  }
@@ -2189,7 +2307,7 @@ function directCadKindForPath(path) {
2189
2307
  return null;
2190
2308
  }
2191
2309
  function directCadReferenceCode(path, kind) {
2192
- const fn = kind === "step" ? "importStep" : "importMesh";
2310
+ const fn = kind === "step" ? "Import.step" : "Import.mesh";
2193
2311
  const name = pathBasename(path);
2194
2312
  return [`const imported = ${fn}(${JSON.stringify(path)});`, `return [{ name: ${JSON.stringify(name)}, shape: imported }];`].join("\n");
2195
2313
  }
@@ -3754,10 +3872,9 @@ function getSessionThicknessInspection(session, rawOptions) {
3754
3872
  objects,
3755
3873
  warnings,
3756
3874
  style: {
3757
- criticalColor: THICKNESS_COLORS.critical,
3758
- warningColor: THICKNESS_COLORS.warning,
3759
- okColor: THICKNESS_COLORS.ok,
3760
- thickColor: THICKNESS_COLORS.thick,
3875
+ gradientColors: THICKNESS_GRADIENT_COLORS.map((color) => [...color]),
3876
+ colorMinThickness: options.colorMinThickness,
3877
+ colorMaxThickness: options.colorMaxThickness,
3761
3878
  unknownColor: THICKNESS_COLORS.unknown
3762
3879
  }
3763
3880
  }
@@ -4134,18 +4251,15 @@ function createSurfaceFieldMaterial({
4134
4251
  function createScanProxyMaterial({
4135
4252
  color,
4136
4253
  opacity,
4137
- clippingPlanes,
4138
- wireframe = false,
4139
- additiveWire = true
4254
+ clippingPlanes
4140
4255
  }) {
4141
4256
  return new MeshBasicMaterial({
4142
4257
  color,
4143
4258
  transparent: true,
4144
4259
  opacity,
4145
- wireframe,
4146
4260
  side: DoubleSide,
4147
4261
  depthWrite: false,
4148
- blending: wireframe && additiveWire ? AdditiveBlending : NormalBlending,
4262
+ blending: AdditiveBlending,
4149
4263
  toneMapped: false,
4150
4264
  clippingPlanes
4151
4265
  });
@@ -4153,32 +4267,20 @@ function createScanProxyMaterial({
4153
4267
  function createScanProxyGroup(proxy, clippingPlanes, objectColor) {
4154
4268
  const group = new Group();
4155
4269
  group.userData = { scanProxyTelemetry: proxy.telemetry };
4156
- const additiveWire = objectColor === void 0;
4157
- for (const layer of SCAN_PROXY_LAYER_STYLES) {
4270
+ const layers = objectColor ? scanMaterialLayerStyles(objectColor) : SCAN_PROXY_LAYER_STYLES;
4271
+ for (const layer of layers) {
4158
4272
  const geometry = proxy.geometries[layer.material];
4159
4273
  if (!geometry) continue;
4160
4274
  const fill = new Mesh(
4161
4275
  geometry,
4162
4276
  createScanProxyMaterial({
4163
- color: objectColor ?? layer.color,
4164
- opacity: layer.fillOpacity,
4277
+ color: layer.color,
4278
+ opacity: Math.min(0.1, layer.fillOpacity * 0.2),
4165
4279
  clippingPlanes
4166
4280
  })
4167
4281
  );
4168
4282
  fill.raycast = () => null;
4169
4283
  group.add(fill);
4170
- const wire = new Mesh(
4171
- geometry,
4172
- createScanProxyMaterial({
4173
- color: objectColor ?? layer.color,
4174
- opacity: layer.wireOpacity,
4175
- wireframe: true,
4176
- additiveWire,
4177
- clippingPlanes
4178
- })
4179
- );
4180
- wire.raycast = () => null;
4181
- group.add(wire);
4182
4284
  }
4183
4285
  return group;
4184
4286
  }
@@ -4742,13 +4844,6 @@ function buildCameraRig(center, distance, _maxDim, spec, fovDeg = 45) {
4742
4844
  orbitBasePitchDeg: Number.isFinite(orbitBasePitchDeg) ? orbitBasePitchDeg : DEFAULT_PITCH_DEG
4743
4845
  };
4744
4846
  }
4745
- function buildBaseJointValues(joints) {
4746
- const out = {};
4747
- joints.forEach((joint) => {
4748
- out[joint.name] = joint.defaultValue;
4749
- });
4750
- return out;
4751
- }
4752
4847
  function resolveRequestedSceneState(opts) {
4753
4848
  let sceneState = (opts == null ? void 0 : opts.sceneState) ?? null;
4754
4849
  if (opts == null ? void 0 : opts.sceneSpec) {
@@ -4773,8 +4868,8 @@ function resolveRenderableJointNodeName(obj, joints) {
4773
4868
  }
4774
4869
  function applyObjectTransforms(session, animationProgress) {
4775
4870
  const animatedValues = resolveJointAnimation(session.selectedAnimation, animationProgress ?? 0, session.baseJointValues);
4776
- const effectiveJointValues = resolveJointViewValues(session.joints, session.jointCouplings, animatedValues);
4777
- const jointMatrices = computeJointNodeMatrices(session.joints, effectiveJointValues);
4871
+ const effectiveJointValues = resolveJointViewValues(session.transformJoints, session.transformJointCouplings, animatedValues);
4872
+ const jointMatrices = computeJointNodeMatrices(session.transformJoints, effectiveJointValues);
4778
4873
  const objectMatrices = /* @__PURE__ */ new Map();
4779
4874
  session.renderables.forEach((renderable) => {
4780
4875
  var _a;
@@ -5001,7 +5096,7 @@ Available renderable objects: ${available}`;
5001
5096
  return "No visible renderable objects found.";
5002
5097
  }
5003
5098
  function createSession(code, opts) {
5004
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
5099
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
5005
5100
  const size = (opts == null ? void 0 : opts.size) ?? 1024;
5006
5101
  const pixelRatio = (opts == null ? void 0 : opts.pixelRatio) ?? 1;
5007
5102
  const debug = createCaptureDebugLogger(opts == null ? void 0 : opts.debug);
@@ -5033,6 +5128,7 @@ function createSession(code, opts) {
5033
5128
  const result = runScript(code, (opts == null ? void 0 : opts.fileName) || "main.forge.js", (opts == null ? void 0 : opts.allFiles) || {}, {
5034
5129
  quality: (opts == null ? void 0 : opts.quality) ?? "high",
5035
5130
  readBinaryFile: binaryFileMapReader(opts == null ? void 0 : opts.binaryFiles),
5131
+ assemblyState: opts == null ? void 0 : opts.jointOverrides,
5036
5132
  debug: (opts == null ? void 0 : opts.debug) ? (phase, detail) => debug(`runScript:${phase}`, detail) : void 0
5037
5133
  });
5038
5134
  debug("session:runScript:end", {
@@ -5073,7 +5169,7 @@ function createSession(code, opts) {
5073
5169
  shapeObjects: visibleObjs.filter((entry) => entry.shape != null).length,
5074
5170
  sdfObjects: visibleObjs.filter((entry) => entry.sdf != null).length
5075
5171
  });
5076
- const boundsObjs = visibleObjs.length > 0 ? visibleObjs : objs;
5172
+ const boundsObjs = selectRenderSceneBoundsEntries(objs);
5077
5173
  const objectVisibility = new Map(objs.map((entry) => [entry.source.id, entry.visible]));
5078
5174
  const objectRenderability = new Set(objs.map((entry) => entry.source.id));
5079
5175
  const sceneObjects = result.objects.map((obj) => ({
@@ -5189,8 +5285,15 @@ function createSession(code, opts) {
5189
5285
  }
5190
5286
  const joints = ((_e = result.jointsView) == null ? void 0 : _e.enabled) === false ? [] : ((_f = result.jointsView) == null ? void 0 : _f.joints) ?? [];
5191
5287
  const jointCouplings = ((_g = result.jointsView) == null ? void 0 : _g.enabled) === false ? [] : ((_h = result.jointsView) == null ? void 0 : _h.couplings) ?? [];
5192
- const animationClips = ((_i = result.jointsView) == null ? void 0 : _i.enabled) === false ? [] : ((_j = result.jointsView) == null ? void 0 : _j.animations) ?? [];
5193
- const defaultAnimation = ((_k = result.jointsView) == null ? void 0 : _k.defaultAnimation) ?? null;
5288
+ try {
5289
+ validateJointOverrides(result.jointsView, (opts == null ? void 0 : opts.jointOverrides) ?? {});
5290
+ } catch (err) {
5291
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
5292
+ }
5293
+ const transformJoints = ((_i = result.jointsView) == null ? void 0 : _i.motionSource) === "assembly" ? [] : joints;
5294
+ const transformJointCouplings = ((_j = result.jointsView) == null ? void 0 : _j.motionSource) === "assembly" ? [] : jointCouplings;
5295
+ const animationClips = ((_k = result.jointsView) == null ? void 0 : _k.enabled) === false ? [] : ((_l = result.jointsView) == null ? void 0 : _l.animations) ?? [];
5296
+ const defaultAnimation = ((_m = result.jointsView) == null ? void 0 : _m.defaultAnimation) ?? null;
5194
5297
  let selectedAnimation;
5195
5298
  let sweep = null;
5196
5299
  let cutawayBase = null;
@@ -5266,8 +5369,8 @@ function createSession(code, opts) {
5266
5369
  id: obj.source.id,
5267
5370
  name: objectLabel,
5268
5371
  ms: Number((performance.now() - geometryStart).toFixed(1)),
5269
- triangles: Math.floor((((_l = geo.solid.getAttribute("position")) == null ? void 0 : _l.count) ?? 0) / 3),
5270
- edgeSegments: Math.floor((((_m = geo.edges.getAttribute("position")) == null ? void 0 : _m.count) ?? 0) / 2)
5372
+ triangles: Math.floor((((_n = geo.solid.getAttribute("position")) == null ? void 0 : _n.count) ?? 0) / 3),
5373
+ edgeSegments: Math.floor((((_o = geo.edges.getAttribute("position")) == null ? void 0 : _o.count) ?? 0) / 2)
5271
5374
  });
5272
5375
  const materialDefaults = renderStylePreset.material;
5273
5376
  const surfaceField = renderStylePreset.surfaceField;
@@ -5298,12 +5401,12 @@ function createSession(code, opts) {
5298
5401
  ...(mp == null ? void 0 : mp.wireframe) && { wireframe: true }
5299
5402
  };
5300
5403
  solidMaterial = isScanRenderStyle ? new MeshBasicMaterial({
5301
- color: objectColor,
5404
+ color: scanMaterialShellColor(objectColor),
5302
5405
  transparent: true,
5303
- opacity: 0.16,
5406
+ opacity: 0.08,
5304
5407
  side: DoubleSide,
5305
5408
  depthWrite: false,
5306
- blending: NormalBlending,
5409
+ blending: AdditiveBlending,
5307
5410
  toneMapped: false,
5308
5411
  clippingPlanes: applicableCutPlanes
5309
5412
  }) : surfaceField.enabled ? createSurfaceFieldMaterial({
@@ -5341,22 +5444,7 @@ function createSession(code, opts) {
5341
5444
  });
5342
5445
  }
5343
5446
  }
5344
- if (isScanRenderStyle && !scanProxy) {
5345
- shell = new Mesh(
5346
- geo.solid,
5347
- new MeshBasicMaterial({
5348
- color: objectColor,
5349
- transparent: true,
5350
- opacity: 0.08,
5351
- side: BackSide,
5352
- depthWrite: false,
5353
- blending: NormalBlending,
5354
- clippingPlanes: applicableCutPlanes
5355
- })
5356
- );
5357
- shell.scale.setScalar(0.992);
5358
- shell.raycast = () => null;
5359
- } else if (hasAuthoredTransparency && renderStylePreset.glassShell.enabled) {
5447
+ if (!isScanRenderStyle && hasAuthoredTransparency && renderStylePreset.glassShell.enabled) {
5360
5448
  shell = new Mesh(
5361
5449
  geo.solid,
5362
5450
  new MeshBasicMaterial({
@@ -5374,9 +5462,9 @@ function createSession(code, opts) {
5374
5462
  }
5375
5463
  wireMaterial = new LineBasicMaterial({
5376
5464
  ...EDGE_MATERIAL_PROPS,
5377
- color: isScanRenderStyle ? objectColor : parseColor(renderStylePreset.edge.color, EDGE_MATERIAL_PROPS.color),
5465
+ color: parseColor(renderStylePreset.edge.color, EDGE_MATERIAL_PROPS.color),
5378
5466
  transparent: true,
5379
- opacity: isScanRenderStyle ? 0.62 : Math.min(1, renderStylePreset.edge.opacity * Math.max(0.35, obj.opacity) + 0.1),
5467
+ opacity: isScanRenderStyle ? 0 : Math.min(1, renderStylePreset.edge.opacity * Math.max(0.35, obj.opacity) + 0.1),
5380
5468
  depthWrite: false,
5381
5469
  blending: NormalBlending,
5382
5470
  clippingPlanes: applicableCutPlanes
@@ -5423,7 +5511,7 @@ function createSession(code, opts) {
5423
5511
  ...scanProxy ? { scanProxy } : {},
5424
5512
  solidMaterial,
5425
5513
  wireMaterial,
5426
- jointNodeName: resolveRenderableJointNodeName(obj.source, joints),
5514
+ jointNodeName: resolveRenderableJointNodeName(obj.source, transformJoints),
5427
5515
  sourceColor: obj.color ?? "#5b9bd5",
5428
5516
  opacity: obj.opacity,
5429
5517
  sectionMesh,
@@ -5442,7 +5530,7 @@ function createSession(code, opts) {
5442
5530
  { bodyShape: () => new EmptyInspectionShape() }
5443
5531
  ) : null;
5444
5532
  const connectivityEntries = (connectivityBodyInput == null ? void 0 : connectivityBodyInput.entries) ?? [];
5445
- const groundOffset = Number.isFinite((_n = sceneConfig == null ? void 0 : sceneConfig.ground) == null ? void 0 : _n.offset) ? sceneConfig.ground.offset : 0;
5533
+ const groundOffset = Number.isFinite((_p = sceneConfig == null ? void 0 : sceneConfig.ground) == null ? void 0 : _p.offset) ? sceneConfig.ground.offset : 0;
5446
5534
  const floatingGroundZ = bbox.min[2] - groundOffset;
5447
5535
  let sceneConfigCameraState = null;
5448
5536
  if ((sceneConfig == null ? void 0 : sceneConfig.camera) && !(requestedSceneState == null ? void 0 : requestedSceneState.camera)) {
@@ -5471,7 +5559,7 @@ function createSession(code, opts) {
5471
5559
  } : null;
5472
5560
  const cameraSpec = sceneConfigCameraState && (opts == null ? void 0 : opts.capture) === "section-sweep" ? fitCameraStateToBounds(sceneConfigCameraState, bbox, cameraFov) : (requestedSceneState == null ? void 0 : requestedSceneState.camera) ?? cutawayCameraState ?? sceneConfigCameraState;
5473
5561
  const cameraRig = buildCameraRig(center, distance, maxDim, cameraSpec, cameraFov);
5474
- const explicitCameraFov = (cameraSpec == null ? void 0 : cameraSpec.fov) ?? ((_o = sceneConfig == null ? void 0 : sceneConfig.camera) == null ? void 0 : _o.fov);
5562
+ const explicitCameraFov = (cameraSpec == null ? void 0 : cameraSpec.fov) ?? ((_q = sceneConfig == null ? void 0 : sceneConfig.camera) == null ? void 0 : _q.fov);
5475
5563
  if (explicitCameraFov && cameraRig.camera instanceof PerspectiveCamera) {
5476
5564
  cameraRig.camera.fov = explicitCameraFov;
5477
5565
  cameraRig.camera.updateProjectionMatrix();
@@ -5504,12 +5592,14 @@ function createSession(code, opts) {
5504
5592
  roughnessInspection: null,
5505
5593
  joints,
5506
5594
  jointCouplings,
5507
- jointOverlayConfig: ((_p = result.viewConfig) == null ? void 0 : _p.jointOverlay) ?? DEFAULT_VIEW_CONFIG.jointOverlay,
5595
+ transformJoints,
5596
+ transformJointCouplings,
5597
+ jointOverlayConfig: ((_r = result.viewConfig) == null ? void 0 : _r.jointOverlay) ?? DEFAULT_VIEW_CONFIG.jointOverlay,
5508
5598
  animationClips,
5509
5599
  defaultAnimation,
5510
5600
  selectedAnimation,
5511
5601
  availableCutPlaneNames: availableCutPlanes.map((cp) => cp.name),
5512
- baseJointValues: buildBaseJointValues(joints),
5602
+ baseJointValues: buildBaseJointValues(transformJoints, (opts == null ? void 0 : opts.jointOverrides) ?? {}),
5513
5603
  fixedCameraState: cameraRig.fixedCameraState,
5514
5604
  orbitTarget: cameraRig.orbitTarget,
5515
5605
  orbitRadius: cameraRig.orbitRadius,
@@ -5576,6 +5666,7 @@ window.__forgeRender = async (code, opts) => {
5576
5666
  focus: opts == null ? void 0 : opts.focus,
5577
5667
  hide: opts == null ? void 0 : opts.hide,
5578
5668
  paramOverrides: opts == null ? void 0 : opts.paramOverrides,
5669
+ jointOverrides: opts == null ? void 0 : opts.jointOverrides,
5579
5670
  renderStyle: opts == null ? void 0 : opts.renderStyle,
5580
5671
  scanGranularity: opts == null ? void 0 : opts.scanGranularity,
5581
5672
  respectAuthoredSceneStyle: opts == null ? void 0 : opts.respectAuthoredSceneStyle,