forgecad 0.9.14 → 0.9.16

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 (239) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-eWGs2K6H.js → AdminPage-CXvls4-J.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-CTrLKfpo.js → BenchmarkPage-B27zk8xL.js} +4 -15
  5. package/dist/assets/{BlogPage-5nPesyds.js → BlogPage-CMAVvgQL.js} +2 -2
  6. package/dist/assets/{DocsPage-C4Y3nbYc.js → DocsPage-knf4I4h7.js} +9 -3
  7. package/dist/assets/EditorApp-BHMQlJ-D.js +14686 -0
  8. package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-BpjZgzk0.css} +846 -0
  9. package/dist/assets/{EmbedViewer-C8fB4n5U.js → EmbedViewer-D7ZGlFjx.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-jSz0LaMM.js → LandingPageProofDriven-CnevhTE8.js} +36 -38
  11. package/dist/assets/LegalPage-BPTUmqeg.js +39 -0
  12. package/dist/assets/LegalPage-BRlScr9A.css +91 -0
  13. package/dist/assets/{PricingPage-B83B90zh.js → PricingPage-B0D4goG_.js} +19 -19
  14. package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
  15. package/dist/assets/{SettingsPage-DY889pcu.js → SettingsPage-CFF-UgjI.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-bEww1ic4.js → app-T0pDcSX4.js} +3382 -1069
  18. package/dist/assets/cli/{render-Cho2uKG_.js → render-C5pcIISc.js} +477 -29
  19. package/dist/assets/{constructionHistoryWorker-HYwzJY4m.js → constructionHistoryWorker-Ba2Hm58b.js} +928 -243
  20. package/dist/assets/{evalWorker-CjQwJSE-.js → evalWorker-vkx310U2.js} +8883 -6040
  21. package/dist/assets/{forgecad_geometry-CH2nvuLA.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/forgecad_geometry_bg-dD4RNQF1.wasm +0 -0
  23. package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-BuTJDVX6.js} +1179 -273
  24. package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
  25. package/dist/assets/{targets-D6PWsv6X.js → jointPose-B_Cgedn9.js} +71 -3
  26. package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
  27. package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
  28. package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
  29. package/dist/assets/{manifold-rmfAcdwF.js → manifold-BWgsjmAM.js} +1 -1
  30. package/dist/assets/{manifold-uRzgk5O8.js → manifold-D6IFSkhH.js} +2 -2
  31. package/dist/assets/{manifold-CG9Fokx-.js → manifold-rZexZI0G.js} +1 -1
  32. package/dist/assets/{reportWorker-4cW_ZpoS.js → reportWorker-0AGij1Ru.js} +8659 -12771
  33. package/dist/assets/{scalar-sampling-budget-CfDiFvh7.js → scalar-sampling-budget-J5cuzxT1.js} +8050 -6203
  34. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-Vl4Wxa1y.js} +50 -6
  35. package/dist/assets/{solver-DuJAO8S6.js → solver-BZ9LPTHs.js} +1 -1
  36. package/dist/assets/solver_bg-DAHZJ_rw.wasm +0 -0
  37. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  38. package/dist/cli/render.html +1 -1
  39. package/dist/docs/index.html +2 -2
  40. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  41. package/dist/docs-raw/AI/usage.md +5 -12
  42. package/dist/docs-raw/CLI.md +34 -10
  43. package/dist/docs-raw/component-model.md +27 -11
  44. package/dist/docs-raw/generated/assembly.md +374 -187
  45. package/dist/docs-raw/generated/concepts.md +245 -237
  46. package/dist/docs-raw/generated/core.md +283 -6
  47. package/dist/docs-raw/generated/curves.md +274 -361
  48. package/dist/docs-raw/generated/lib.md +9 -19
  49. package/dist/docs-raw/generated/output.md +29 -4
  50. package/dist/docs-raw/generated/runtime-names.md +49 -0
  51. package/dist/docs-raw/generated/sdf.md +31 -0
  52. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  53. package/dist/docs-raw/generated/sketch.md +44 -1
  54. package/dist/docs-raw/generated/viewport.md +11 -3
  55. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  56. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  57. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  58. package/dist/docs-raw/guides/joint-design.md +24 -0
  59. package/dist/docs-raw/guides/positioning.md +13 -3
  60. package/dist/docs-raw/legal/privacy.md +63 -0
  61. package/dist/docs-raw/legal/software-license.md +55 -0
  62. package/dist/docs-raw/legal/terms.md +87 -0
  63. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +1 -1
  64. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  66. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  68. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  69. package/dist/docs-raw/skills/forgecad-make-a-model.md +40 -39
  70. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  71. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  72. package/dist/docs-raw/skills/forgecad-project.md +3 -1
  73. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +1 -1
  74. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  75. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  76. package/dist/docs-raw/skills/forgecad.md +4 -3
  77. package/dist/docs-raw/welcome.md +2 -0
  78. package/dist/index.html +40 -12
  79. package/dist/llms.txt +8 -0
  80. package/dist/site.webmanifest +1 -1
  81. package/dist/sitemap.xml +49 -13
  82. package/dist-cli/{check-compiler-U5SOPN7X.js → check-compiler-SYQ2PWOB.js} +1 -2
  83. package/dist-cli/{check-query-propagation-XOKNSSYU.js → check-query-propagation-HIAGV62W.js} +1 -2
  84. package/dist-cli/{chunk-EXWGNL6K.js → chunk-SPZE3DUY.js} +20659 -17930
  85. package/dist-cli/forgecad.js +3568 -1250
  86. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  87. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  88. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  89. package/dist-cli/solver_bg.wasm +0 -0
  90. package/dist-skill/CONTEXT.md +1192 -725
  91. package/dist-skill/SKILL.md +3 -2
  92. package/dist-skill/docs/API/core/concepts.md +64 -1
  93. package/dist-skill/docs/CLI.md +34 -10
  94. package/dist-skill/docs/generated/assembly.md +339 -213
  95. package/dist-skill/docs/generated/core.md +283 -6
  96. package/dist-skill/docs/generated/curves.md +272 -362
  97. package/dist-skill/docs/generated/lib.md +9 -19
  98. package/dist-skill/docs/generated/output.md +29 -4
  99. package/dist-skill/docs/generated/runtime-names.md +40 -0
  100. package/dist-skill/docs/generated/sdf.md +31 -0
  101. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  102. package/dist-skill/docs/generated/sketch.md +44 -2
  103. package/dist-skill/docs/generated/viewport.md +2 -87
  104. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  105. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  106. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  107. package/dist-skill/docs/guides/joint-design.md +24 -0
  108. package/dist-skill/docs/guides/positioning.md +13 -3
  109. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  110. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  111. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  112. package/dist-skill/library/forgecad-make-a-model/SKILL.md +39 -38
  113. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  114. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  115. package/dist-skill/library/forgecad-project/SKILL.md +2 -0
  116. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  117. package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
  118. package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
  119. package/examples/api/assembly-kinematics-limb.forge.js +116 -0
  120. package/examples/api/connector-frame-rig-chain.forge.js +102 -0
  121. package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
  122. package/examples/api/exact-surface-studio.forge.js +6 -8
  123. package/examples/api/helix-basics.forge.js +8 -8
  124. package/examples/api/lean-foundations/README.md +12 -0
  125. package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
  126. package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
  127. package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
  128. package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
  129. package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
  130. package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
  131. package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
  132. package/examples/api/route3d-elbow.forge.js +71 -0
  133. package/examples/api/transition-curves.forge.js +44 -15
  134. package/examples/api/variable-sweep-test.forge.js +3 -1
  135. package/examples/api/y-blend-corner-showcase.forge.js +0 -2
  136. package/examples/generative/coral-vase.forge.js +1 -1
  137. package/examples/nurbs-tube.forge.js +1 -1
  138. package/package.json +17 -13
  139. package/dist/assets/EditorApp-lXv53A1m.js +0 -13610
  140. package/dist/assets/app-CsHnaBWt.css +0 -1789
  141. package/dist/assets/forgecad_geometry_bg-C5_E9Oa9.wasm +0 -0
  142. package/dist/assets/solver_bg-CWvv4lnN.wasm +0 -0
  143. package/dist/docs-raw/API/README.md +0 -16
  144. package/dist/docs-raw/API/core/concepts.md +0 -118
  145. package/dist/docs-raw/INDEX.md +0 -138
  146. package/dist/docs-raw/RELEASING.md +0 -87
  147. package/dist/docs-raw/agent-native-api.md +0 -27
  148. package/dist/docs-raw/beta-deployment.md +0 -304
  149. package/dist/docs-raw/beta-operations.md +0 -325
  150. package/dist/docs-raw/blueprint-first.md +0 -145
  151. package/dist/docs-raw/cli-monetization.md +0 -112
  152. package/dist/docs-raw/coding-best-practices.md +0 -120
  153. package/dist/docs-raw/coding.md +0 -340
  154. package/dist/docs-raw/deployment.md +0 -374
  155. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  156. package/dist/docs-raw/guides/surface-members.md +0 -82
  157. package/dist/docs-raw/harbor-cli.md +0 -854
  158. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  159. package/dist/docs-raw/internals/compiler.md +0 -307
  160. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  161. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  162. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  163. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  164. package/dist/docs-raw/platform/admin.md +0 -45
  165. package/dist/docs-raw/platform/architecture.md +0 -82
  166. package/dist/docs-raw/platform/auth.md +0 -139
  167. package/dist/docs-raw/platform/email.md +0 -67
  168. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  169. package/dist/docs-raw/platform/observability.md +0 -197
  170. package/dist/docs-raw/platform/projects.md +0 -111
  171. package/dist/docs-raw/platform/sharing.md +0 -90
  172. package/dist/docs-raw/product/README.md +0 -39
  173. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  174. package/dist/docs-raw/product/business-model.md +0 -15
  175. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  176. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  177. package/dist/docs-raw/product/founder-story.md +0 -11
  178. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  179. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  180. package/dist/docs-raw/product/product-loop.md +0 -17
  181. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  182. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  183. package/dist/docs-raw/product/user-segments.md +0 -15
  184. package/dist/docs-raw/product/vision.md +0 -26
  185. package/dist/docs-raw/rl-environments.md +0 -350
  186. package/dist/docs-raw/runbook.md +0 -611
  187. package/dist-cli/check-compiler-U5SOPN7X.js.map +0 -1
  188. package/dist-cli/check-query-propagation-XOKNSSYU.js.map +0 -1
  189. package/dist-cli/chunk-EXWGNL6K.js.map +0 -1
  190. package/dist-cli/forgecad.js.map +0 -1
  191. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  192. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  193. package/dist-skill/SKILL-dev.md +0 -145
  194. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  195. package/dist-skill/docs-dev/CLI.md +0 -677
  196. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  197. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  198. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  199. package/dist-skill/docs-dev/coding.md +0 -340
  200. package/dist-skill/docs-dev/component-model.md +0 -164
  201. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  202. package/dist-skill/docs-dev/generated/core.md +0 -2117
  203. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  204. package/dist-skill/docs-dev/generated/lib.md +0 -169
  205. package/dist-skill/docs-dev/generated/output.md +0 -247
  206. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  207. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  208. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  209. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  210. package/dist-skill/docs-dev/generated/wood.md +0 -108
  211. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  212. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  213. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  214. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  215. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  216. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  217. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  218. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  219. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  220. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  221. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  222. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  223. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
  224. package/examples/api/bolted-service-cover.forge.js +0 -17
  225. package/examples/api/cable-gland-anchor.forge.js +0 -14
  226. package/examples/api/captured-cartridge-guide.forge.js +0 -14
  227. package/examples/api/captured-linear-slide.forge.js +0 -13
  228. package/examples/api/clevis-pin-joint.forge.js +0 -13
  229. package/examples/api/datum-enclosure.forge.js +0 -16
  230. package/examples/api/hose-barb-port.forge.js +0 -14
  231. package/examples/api/knuckled-hinge-assembly.forge.js +0 -15
  232. package/examples/api/living-hinge-cover.forge.js +0 -14
  233. package/examples/api/pcb-terminal-block.forge.js +0 -22
  234. package/examples/api/pinned-lever-pivot-stack.forge.js +0 -14
  235. package/examples/api/retained-shaft-knob-stack.forge.js +0 -15
  236. package/examples/api/routed-tube-clip.forge.js +0 -15
  237. package/examples/api/seated-bearing-stack.forge.js +0 -30
  238. package/examples/api/snap-latch-cover.forge.js +0 -14
  239. 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, cB as initSolverWasm, cA as initKernel, S as Scene, cC as BoxGeometry, bR as MeshStandardMaterial, a4 as BackSide, b3 as PointLight, M as Mesh, aa as MeshBasicMaterial, cD as localAabbPlaneRelation, h as Vector2, cE as ShapeUtils, cF as analyzePhysicalConnectivity, g as Vector3, $ as Matrix4, cG as Frustum, G as Box3, a0 as MathUtils, cH as meshContactDataFor, cI as AabbSpatialIndex, cJ as detectPhysicalContact, cK as resolveThicknessInspectionOptions, R as Raycaster, cL as thicknessColor, cM as thicknessClass, aX as BufferAttribute, cN as roughnessClassForAngle, cO as resolveRoughnessInspectionOptions, cP as roughnessColorForAngle, cQ as roughnessScoreForAngle, cR as activateBackend, e as Color, b6 as COMPARISON_COLORS, aF as resolveForgeRenderStyle, bt as getRenderStylePreset, ax as setParamOverrides, bh as runScript, cl as scanProxyGridForBounds, cS as Group, ba as shapeToGeometry, bi as MeshPhysicalMaterial, bw as NormalBlending, cT as createScanProxyGeometry, bv as AdditiveBlending, aK as LineBasicMaterial, bj as LineSegments, aJ as BufferGeometry, P as PerspectiveCamera, bo as worldAuthorPlaneToLocal, cU as resolveSectionHatchMetrics, ct as buildGeometryComparisonPointCloud, cr as triangleSoupFromMeshes, O as OrthographicCamera, k as ShaderMaterial, bC as ZEBRA_STRIPE_FRAGMENT_SHADER, bD as ZEBRA_STRIPE_VERTEX_SHADER, bx as ZEBRA_STRIPE_SOFTNESS, by as ZEBRA_STRIPE_SCALE, bz as ZEBRA_LIGHT_COLOR, bA as ZEBRA_DARK_COLOR, bB as ZEBRA_ACCENT_COLOR, bs as geometryWithVisibleVertexColors, cV as intersectWithPlane, cW as setActiveBackend, W as WebGLRenderer, A as ACESFilmicToneMapping, c as SRGBColorSpace, cX as parseCameraCliSpec, cY as PMREMGenerator, aY as CanvasTexture, aZ as Object3D, a_ as FogExp2, a$ as Fog, b0 as AmbientLight, b4 as DirectionalLight, b1 as HemisphereLight, cd as findJointAnimationClip, p as Plane, bF as SURFACE_FIELD_FRAGMENT_SHADER, bG as SURFACE_FIELD_VERTEX_SHADER, bE as SCAN_PROXY_LAYER_STYLES, Y as Vector4, bU as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bT as buildSdfRaymarchFragmentShader, ce as resolveJointAnimation, cf as resolveJointViewValues, bL as ROUGHNESS_COLORS, cZ as PointsMaterial, c_ as Points, b5 as heatPointsForSide, c$ as analyzeCollisionIntersections, d0 as serializeCollisionFinding, d1 as summarizeThicknessSamples, bN as THICKNESS_COLORS, b2 as SpotLight, cx as resolveScalarSceneSampleBudget, bb as buildComparisonHeatPatchGeometry, bc as EdgesGeometry, b7 as comparisonHeatDepthTest, b8 as comparisonHeatEdgeOpacity, b9 as comparisonHeatPatchOpacity, cz as comparisonCandidateContextOpacity, d2 as DEFAULT_COMPARISON_CANDIDATE_OPACITY } from "../scalar-sampling-budget-CfDiFvh7.js";
5
- import { m as mergeViewportRenderSceneStates, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../targets-D6PWsv6X.js";
4
+ import { D as DoubleSide, cC as initSolverWasm, cB as initKernel, S as Scene, cD as BoxGeometry, bU 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, cl 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, ci as DEFAULT_VIEW_CONFIG, bs as worldAuthorPlaneToLocal, cV as resolveSectionHatchMetrics, ct as buildGeometryComparisonPointCloud, cr 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, bX as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bW 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, bO as THICKNESS_GRADIENT_COLORS, d3 as THICKNESS_COLORS, b6 as SpotLight, b$ as CylinderGeometry, d4 as TorusGeometry, bM as CatmullRomCurve3, bN as TubeGeometry, cx as resolveScalarSceneSampleBudget, bf as buildComparisonHeatPatchGeometry, bg as EdgesGeometry, d5 as SphereGeometry, d6 as ConeGeometry, bb as comparisonHeatDepthTest, bc as comparisonHeatEdgeOpacity, bd as comparisonHeatPatchOpacity, cz as comparisonCandidateContextOpacity, d7 as DEFAULT_COMPARISON_CANDIDATE_OPACITY } from "../scalar-sampling-budget-J5cuzxT1.js";
5
+ import { m as mergeViewportRenderSceneStates, v as validateJointOverrides, b as buildBaseJointValues, p as parseRenderSceneCliSpec, g as getSceneObjectTreePath } from "../jointPose-B_Cgedn9.js";
6
6
  const CAD_MATERIAL_PROPS = {
7
7
  color: 6003669,
8
8
  metalness: 0.05,
@@ -1110,6 +1110,92 @@ ${body}
1110
1110
  pathCount
1111
1111
  };
1112
1112
  }
1113
+ class DisjointSet {
1114
+ constructor(size) {
1115
+ __publicField(this, "parent");
1116
+ __publicField(this, "rank");
1117
+ this.parent = Array.from({ length: size }, (_, index) => index);
1118
+ this.rank = Array.from({ length: size }, () => 0);
1119
+ }
1120
+ find(index) {
1121
+ const parent = this.parent[index];
1122
+ if (parent === index) return index;
1123
+ const root = this.find(parent);
1124
+ this.parent[index] = root;
1125
+ return root;
1126
+ }
1127
+ union(a, b) {
1128
+ const rootA = this.find(a);
1129
+ const rootB = this.find(b);
1130
+ if (rootA === rootB) return;
1131
+ if (this.rank[rootA] < this.rank[rootB]) {
1132
+ this.parent[rootA] = rootB;
1133
+ } else if (this.rank[rootA] > this.rank[rootB]) {
1134
+ this.parent[rootB] = rootA;
1135
+ } else {
1136
+ this.parent[rootB] = rootA;
1137
+ this.rank[rootA] += 1;
1138
+ }
1139
+ }
1140
+ }
1141
+ function connectedCoplanarSurfacePatches(triangles) {
1142
+ const snap = surfacePatchSnap(triangles);
1143
+ const planeKeys = triangles.map((triangle) => planeKey(triangle, snap));
1144
+ const edgeOwners = /* @__PURE__ */ new Map();
1145
+ const sets = new DisjointSet(triangles.length);
1146
+ triangles.forEach((triangle, index) => {
1147
+ for (const key of triangleEdgeKeys(triangle, snap)) {
1148
+ const owners = edgeOwners.get(key);
1149
+ if (owners) {
1150
+ for (const owner of owners) {
1151
+ if (planeKeys[owner] === planeKeys[index]) sets.union(owner, index);
1152
+ }
1153
+ owners.push(index);
1154
+ } else {
1155
+ edgeOwners.set(key, [index]);
1156
+ }
1157
+ }
1158
+ });
1159
+ const patchByRoot = /* @__PURE__ */ new Map();
1160
+ triangles.forEach((triangle, index) => {
1161
+ const root = sets.find(index);
1162
+ const patch = patchByRoot.get(root) ?? { triangleIndexes: [], area: 0 };
1163
+ patch.triangleIndexes.push(index);
1164
+ patch.area += triangle.area;
1165
+ patchByRoot.set(root, patch);
1166
+ });
1167
+ return [...patchByRoot.values()];
1168
+ }
1169
+ function surfacePatchSnap(triangles) {
1170
+ const bounds = new Box3();
1171
+ for (const triangle of triangles) {
1172
+ bounds.expandByPoint(triangle.a);
1173
+ bounds.expandByPoint(triangle.b);
1174
+ bounds.expandByPoint(triangle.c);
1175
+ }
1176
+ const size = bounds.getSize(new Vector3());
1177
+ return Math.max(1e-6, size.length() * 1e-8);
1178
+ }
1179
+ function planeKey(triangle, snap) {
1180
+ const normalSnap = 1e-6;
1181
+ const distance = triangle.normal.dot(triangle.a);
1182
+ return [
1183
+ Math.round(triangle.normal.x / normalSnap),
1184
+ Math.round(triangle.normal.y / normalSnap),
1185
+ Math.round(triangle.normal.z / normalSnap),
1186
+ Math.round(distance / snap)
1187
+ ].join(",");
1188
+ }
1189
+ function triangleEdgeKeys(triangle, snap) {
1190
+ const vertices = [vertexKey$2(triangle.a, snap), vertexKey$2(triangle.b, snap), vertexKey$2(triangle.c, snap)];
1191
+ return [edgeKey$1(vertices[0], vertices[1]), edgeKey$1(vertices[1], vertices[2]), edgeKey$1(vertices[2], vertices[0])];
1192
+ }
1193
+ function vertexKey$2(point, snap) {
1194
+ return `${Math.round(point.x / snap)},${Math.round(point.y / snap)},${Math.round(point.z / snap)}`;
1195
+ }
1196
+ function edgeKey$1(a, b) {
1197
+ return a < b ? `${a}|${b}` : `${b}|${a}`;
1198
+ }
1113
1199
  const MIN_TRIANGLE_AREA = 1e-12;
1114
1200
  const R2_ALPHA = 0.7548776662466927;
1115
1201
  const R2_BETA = 0.5698402909980532;
@@ -1162,7 +1248,7 @@ function allocateAreaSampleCounts(triangles, maxSamples) {
1162
1248
  return counts;
1163
1249
  }
1164
1250
  function sampleSurfaceTriangles(triangles, maxSamples) {
1165
- const counts = allocateAreaSampleCounts(triangles, maxSamples);
1251
+ const counts = allocateSurfacePatchSampleCounts(triangles, maxSamples);
1166
1252
  const samples = [];
1167
1253
  const position = new Vector3();
1168
1254
  let sampleIndex = 0;
@@ -1187,6 +1273,35 @@ function sampleSurfaceTriangles(triangles, maxSamples) {
1187
1273
  });
1188
1274
  return samples;
1189
1275
  }
1276
+ function allocateSurfacePatchSampleCounts(triangles, maxSamples) {
1277
+ const counts = new Array(triangles.length).fill(0);
1278
+ if (triangles.length === 0) return counts;
1279
+ const patches = connectedCoplanarSurfacePatches(triangles);
1280
+ const patchCounts = allocateAreaSampleCounts(
1281
+ patches.map((patch, index) => {
1282
+ var _a, _b, _c, _d;
1283
+ return {
1284
+ index,
1285
+ a: ((_a = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _a.a) ?? new Vector3(),
1286
+ b: ((_b = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _b.b) ?? new Vector3(),
1287
+ c: ((_c = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _c.c) ?? new Vector3(),
1288
+ normal: ((_d = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _d.normal) ?? new Vector3(0, 0, 1),
1289
+ area: patch.area
1290
+ };
1291
+ }),
1292
+ maxSamples
1293
+ );
1294
+ patches.forEach((patch, patchIndex) => {
1295
+ const patchBudget = patchCounts[patchIndex] ?? 0;
1296
+ if (patchBudget <= 0) return;
1297
+ const patchTriangles = patch.triangleIndexes.map((index) => triangles[index]);
1298
+ const localCounts = allocateAreaSampleCounts(patchTriangles, patchBudget);
1299
+ patch.triangleIndexes.forEach((triangleIndex, localIndex) => {
1300
+ counts[triangleIndex] += localCounts[localIndex] ?? 0;
1301
+ });
1302
+ });
1303
+ return counts;
1304
+ }
1190
1305
  function totalSurfaceArea(triangles) {
1191
1306
  return triangles.reduce((sum, triangle) => sum + triangle.area, 0);
1192
1307
  }
@@ -1767,6 +1882,10 @@ const exportCtx = exportCanvas.getContext("2d");
1767
1882
  const DEFAULT_BACKGROUND = 2434342;
1768
1883
  const DEFAULT_PITCH_DEG = 18;
1769
1884
  const DEFAULT_FIXED_DIR = new Vector3(0, -1, 0.32).normalize();
1885
+ const RIG_SHADOW_COLOR = [6, 10, 18];
1886
+ const RIG_LINK_COLOR = [20, 220, 255];
1887
+ const RIG_PART_LINK_COLOR = [174, 255, 92];
1888
+ const RIG_HIDDEN_LINK_COLOR = [116, 136, 148];
1770
1889
  const ORTHO_BASE_SIZE = 960;
1771
1890
  const CAPTURE_RUNTIME_CAPABILITIES = {
1772
1891
  version: 3,
@@ -2790,6 +2909,314 @@ function renderCurrentMask(session) {
2790
2909
  });
2791
2910
  }
2792
2911
  }
2912
+ function tupleFromVector(value) {
2913
+ return [Number(value.x.toFixed(6)), Number(value.y.toFixed(6)), Number(value.z.toFixed(6))];
2914
+ }
2915
+ function isFiniteVector(value) {
2916
+ return Number.isFinite(value.x) && Number.isFinite(value.y) && Number.isFinite(value.z);
2917
+ }
2918
+ function clampRadius(value, min, max) {
2919
+ return MathUtils.clamp(value, min, max);
2920
+ }
2921
+ function rigObjectMatchesChild(renderable, child) {
2922
+ return renderable.name === child || renderable.groupName === child;
2923
+ }
2924
+ function rigChildCenter(session, child) {
2925
+ const bounds = new Box3();
2926
+ let hasBounds = false;
2927
+ for (const renderable of session.renderables) {
2928
+ if (!rigObjectMatchesChild(renderable, child)) continue;
2929
+ renderable.root.updateMatrixWorld(true);
2930
+ const objectBounds = new Box3().setFromObject(renderable.root);
2931
+ if (!objectBounds.isEmpty()) {
2932
+ bounds.union(objectBounds);
2933
+ hasBounds = true;
2934
+ }
2935
+ }
2936
+ if (!hasBounds) return null;
2937
+ const center = bounds.getCenter(new Vector3());
2938
+ return isFiniteVector(center) ? center : null;
2939
+ }
2940
+ function resolveRigArcReferenceDirection(axisWorld) {
2941
+ const candidates = [new Vector3(0, 0, 1), new Vector3(0, 1, 0), new Vector3(1, 0, 0)];
2942
+ for (const candidate of candidates) {
2943
+ const projected = candidate.clone().addScaledVector(axisWorld, -candidate.dot(axisWorld));
2944
+ if (projected.lengthSq() > 1e-8) return projected.normalize();
2945
+ }
2946
+ return new Vector3(1, 0, 0);
2947
+ }
2948
+ function resolveRigVisualArcAngleDeg(valueDeg, visualLimitDeg) {
2949
+ if (!Number.isFinite(valueDeg)) return 0;
2950
+ const limit = MathUtils.clamp(visualLimitDeg, 0, 360);
2951
+ if (limit <= 1e-8) return 0;
2952
+ if (Math.abs(valueDeg) <= 360) return MathUtils.clamp(valueDeg, -limit, limit);
2953
+ return MathUtils.clamp(valueDeg % 360, -limit, limit);
2954
+ }
2955
+ function addRigCylinder(group, start, end, radius, color, opacity, renderOrder) {
2956
+ const direction = end.clone().sub(start);
2957
+ const length = direction.length();
2958
+ if (length <= 1e-6) return null;
2959
+ direction.multiplyScalar(1 / length);
2960
+ const geometry = new CylinderGeometry(radius, radius, length, 18);
2961
+ const material = new MeshBasicMaterial({
2962
+ color: Array.isArray(color) ? colorHex(color) : color,
2963
+ transparent: opacity < 1,
2964
+ opacity,
2965
+ depthTest: false,
2966
+ depthWrite: false,
2967
+ blending: AdditiveBlending,
2968
+ toneMapped: false
2969
+ });
2970
+ const mesh = new Mesh(geometry, material);
2971
+ mesh.position.copy(start).add(end).multiplyScalar(0.5);
2972
+ mesh.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction);
2973
+ mesh.renderOrder = renderOrder;
2974
+ group.add(mesh);
2975
+ return mesh;
2976
+ }
2977
+ function addRigSphere(group, position, radius, color, renderOrder) {
2978
+ const mesh = new Mesh(
2979
+ new SphereGeometry(radius, 18, 18),
2980
+ new MeshBasicMaterial({ color, depthTest: false, toneMapped: false })
2981
+ );
2982
+ mesh.position.copy(position);
2983
+ mesh.renderOrder = renderOrder;
2984
+ group.add(mesh);
2985
+ }
2986
+ function addRigCone(group, position, direction, radius, length, color) {
2987
+ if (direction.lengthSq() <= 1e-8) return;
2988
+ const mesh = new Mesh(
2989
+ new ConeGeometry(radius, length, 18),
2990
+ new MeshBasicMaterial({ color, depthTest: false, toneMapped: false })
2991
+ );
2992
+ mesh.position.copy(position);
2993
+ mesh.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction.clone().normalize());
2994
+ mesh.renderOrder = 96;
2995
+ group.add(mesh);
2996
+ }
2997
+ function addRigJointVisual(group, entry, config, axisLength, hidden) {
2998
+ const pivot = new Vector3(...entry.pivot);
2999
+ const axis = new Vector3(...entry.axis).normalize();
3000
+ const axisColor = hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.axisColor;
3001
+ const arcColor = hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.arcColor;
3002
+ const coreColor = hidden ? "#d7e7ee" : config.axisCoreColor;
3003
+ const zeroColor = hidden ? "#aebbc4" : config.zeroColor;
3004
+ const length = axisLength * (hidden ? 0.78 : 1);
3005
+ const axisRadius = clampRadius(length * config.axisLineRadiusScale, config.axisLineRadiusMin, config.axisLineRadiusMax);
3006
+ const spokeRadius = clampRadius(length * config.spokeLineRadiusScale, config.spokeLineRadiusMin, config.spokeLineRadiusMax);
3007
+ const arcLineRadius = clampRadius(length * config.arcLineRadiusScale, config.arcLineRadiusMin, config.arcLineRadiusMax);
3008
+ const dotRadius = Math.max(config.axisDotRadiusMin, length * config.axisDotRadiusScale);
3009
+ const arrowRadius = Math.max(config.axisArrowRadiusMin, length * config.axisArrowRadiusScale);
3010
+ const arrowLength = Math.max(config.axisArrowLengthMin, length * config.axisArrowLengthScale);
3011
+ const axisStart = pivot.clone().addScaledVector(axis, -length * 0.5);
3012
+ const axisEnd = pivot.clone().addScaledVector(axis, length * 0.5);
3013
+ addRigCylinder(group, axisStart, axisEnd, axisRadius, axisColor, hidden ? 0.55 : 0.98, 95);
3014
+ addRigSphere(group, pivot, dotRadius, coreColor, 96);
3015
+ addRigCone(
3016
+ group,
3017
+ axisEnd.clone().addScaledVector(axis, arrowLength * config.axisArrowOffsetFactor),
3018
+ axis,
3019
+ arrowRadius,
3020
+ arrowLength,
3021
+ axisColor
3022
+ );
3023
+ const ringRadius = Math.max(config.arcRadiusMin, length * config.arcRadiusScale);
3024
+ const ring = new Mesh(
3025
+ new TorusGeometry(ringRadius, arcLineRadius * 0.78, 10, 72),
3026
+ new MeshBasicMaterial({
3027
+ color: hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.axisColor,
3028
+ transparent: true,
3029
+ opacity: hidden ? 0.34 : 0.58,
3030
+ depthTest: false,
3031
+ depthWrite: false,
3032
+ blending: AdditiveBlending,
3033
+ toneMapped: false
3034
+ })
3035
+ );
3036
+ ring.position.copy(pivot);
3037
+ ring.quaternion.setFromUnitVectors(new Vector3(0, 0, 1), axis);
3038
+ ring.renderOrder = 92;
3039
+ group.add(ring);
3040
+ if (entry.type !== "revolute") return;
3041
+ const arcStartDirection = resolveRigArcReferenceDirection(axis);
3042
+ const arcAngleRad = MathUtils.degToRad(resolveRigVisualArcAngleDeg(entry.value, config.arcVisualLimitDeg));
3043
+ const arcStartPoint = pivot.clone().addScaledVector(arcStartDirection, ringRadius);
3044
+ const arcEndDirection = arcStartDirection.clone().applyAxisAngle(axis, arcAngleRad);
3045
+ const arcEndPoint = pivot.clone().addScaledVector(arcEndDirection, ringRadius);
3046
+ addRigCylinder(group, pivot, arcStartPoint, spokeRadius, zeroColor, hidden ? 0.45 : 0.9, 97);
3047
+ addRigCylinder(group, pivot, arcEndPoint, spokeRadius, arcColor, hidden ? 0.5 : 0.96, 97);
3048
+ addRigSphere(group, arcStartPoint, Math.max(config.arcDotRadiusMin, length * config.arcDotRadiusScale), zeroColor, 98);
3049
+ addRigSphere(group, arcEndPoint, Math.max(config.arcDotRadiusMin, length * config.arcDotRadiusScale), arcColor, 98);
3050
+ if (Math.abs(arcAngleRad) > 1e-4) {
3051
+ const visualDeg = MathUtils.radToDeg(Math.abs(arcAngleRad));
3052
+ const steps = Math.max(config.arcMinSteps, Math.ceil(visualDeg / config.arcStepDeg));
3053
+ const points = [];
3054
+ for (let i = 0; i <= steps; i += 1) {
3055
+ const direction = arcStartDirection.clone().applyAxisAngle(axis, arcAngleRad * (i / steps));
3056
+ points.push(pivot.clone().addScaledVector(direction, ringRadius));
3057
+ }
3058
+ const curve = new CatmullRomCurve3(points, false, "centripetal");
3059
+ const tubeSegments = Math.max(config.arcTubeSegmentsMin, Math.ceil(points.length * config.arcTubeSegmentsFactor));
3060
+ const tube = new Mesh(
3061
+ new TubeGeometry(curve, tubeSegments, arcLineRadius, config.arcTubeRadialSegments, false),
3062
+ new MeshBasicMaterial({
3063
+ color: arcColor,
3064
+ transparent: true,
3065
+ opacity: hidden ? 0.5 : 0.98,
3066
+ depthTest: false,
3067
+ depthWrite: false,
3068
+ blending: AdditiveBlending,
3069
+ toneMapped: false
3070
+ })
3071
+ );
3072
+ tube.renderOrder = 98;
3073
+ group.add(tube);
3074
+ }
3075
+ }
3076
+ function buildRigSceneGroup(session) {
3077
+ var _a;
3078
+ const group = new Group();
3079
+ const config = session.jointOverlayConfig;
3080
+ const bbox = new Box3(new Vector3(...session.bbox.min), new Vector3(...session.bbox.max));
3081
+ const diagonal = Math.max(1, bbox.getSize(new Vector3()).length());
3082
+ const axisLength = Math.max(config.axisLengthMin, diagonal * config.axisLengthScale);
3083
+ const animatedValues = resolveJointAnimation(session.selectedAnimation, 0, session.baseJointValues);
3084
+ const effectiveJointValues = resolveJointViewValues(session.joints, session.jointCouplings, animatedValues);
3085
+ const jointMatrices = computeJointNodeMatrices(session.joints, effectiveJointValues);
3086
+ const joints = [];
3087
+ const links = [];
3088
+ const jointByChild = /* @__PURE__ */ new Map();
3089
+ for (let index = 0; index < session.joints.length; index += 1) {
3090
+ const joint = session.joints[index];
3091
+ const parentMatrix = joint.parent ? ((_a = jointMatrices.get(joint.parent)) == null ? void 0 : _a.clone()) ?? new Matrix4() : new Matrix4();
3092
+ const axisLocal = new Vector3(joint.axis[0], joint.axis[1], joint.axis[2]).normalize();
3093
+ const axisWorld = axisLocal.clone().transformDirection(parentMatrix);
3094
+ if (axisWorld.lengthSq() <= 1e-8) axisWorld.copy(axisLocal);
3095
+ axisWorld.normalize();
3096
+ if (axisWorld.lengthSq() <= 1e-8 || !isFiniteVector(axisWorld)) continue;
3097
+ const pivotWorld = new Vector3(joint.pivot[0], joint.pivot[1], joint.pivot[2]).applyMatrix4(parentMatrix);
3098
+ if (!isFiniteVector(pivotWorld)) continue;
3099
+ const rawValue = effectiveJointValues[joint.name] ?? joint.defaultValue;
3100
+ const entry = {
3101
+ index,
3102
+ name: joint.name,
3103
+ type: joint.type,
3104
+ child: joint.child,
3105
+ ...joint.parent ? { parent: joint.parent } : {},
3106
+ hidden: joint.hidden === true,
3107
+ value: Number.isFinite(rawValue) ? rawValue : joint.defaultValue,
3108
+ pivot: tupleFromVector(pivotWorld),
3109
+ axis: tupleFromVector(axisWorld)
3110
+ };
3111
+ joints.push(entry);
3112
+ jointByChild.set(joint.child, entry);
3113
+ }
3114
+ const pushLink = (entry, kind, start, end) => {
3115
+ if (!start || !end || !isFiniteVector(start) || !isFiniteVector(end)) return;
3116
+ if (start.distanceToSquared(end) <= 1e-6) return;
3117
+ const id = `${entry.name}:${kind}`;
3118
+ links.push({
3119
+ id,
3120
+ kind,
3121
+ joint: entry.name,
3122
+ hidden: entry.hidden,
3123
+ start: tupleFromVector(start),
3124
+ end: tupleFromVector(end)
3125
+ });
3126
+ };
3127
+ for (const entry of joints) {
3128
+ const pivot = new Vector3(...entry.pivot);
3129
+ const parent = entry.parent ? jointByChild.get(entry.parent) : null;
3130
+ pushLink(entry, "hierarchy", parent ? new Vector3(...parent.pivot) : null, pivot);
3131
+ pushLink(entry, "part", pivot, rigChildCenter(session, entry.child));
3132
+ }
3133
+ const hierarchyRadius = clampRadius(axisLength * 0.013, 0.55, 2.4);
3134
+ const partRadius = clampRadius(axisLength * 8e-3, 0.34, 1.45);
3135
+ for (const link of links) {
3136
+ addRigCylinder(
3137
+ group,
3138
+ new Vector3(...link.start),
3139
+ new Vector3(...link.end),
3140
+ link.kind === "hierarchy" ? hierarchyRadius : partRadius,
3141
+ link.hidden ? RIG_HIDDEN_LINK_COLOR : link.kind === "hierarchy" ? RIG_LINK_COLOR : RIG_PART_LINK_COLOR,
3142
+ link.hidden ? 0.36 : link.kind === "hierarchy" ? 0.82 : 0.58,
3143
+ 88
3144
+ );
3145
+ }
3146
+ if (config.enabled) {
3147
+ for (const joint of joints) {
3148
+ addRigJointVisual(group, joint, config, axisLength, joint.hidden);
3149
+ }
3150
+ }
3151
+ return {
3152
+ group,
3153
+ report: {
3154
+ method: "rig-skeleton-shadow-v1",
3155
+ objectCount: session.renderables.length,
3156
+ jointCount: joints.length,
3157
+ linkCount: links.length,
3158
+ hiddenJointCount: joints.filter((joint) => joint.hidden).length,
3159
+ joints,
3160
+ links,
3161
+ palette: {
3162
+ shadow: RIG_SHADOW_COLOR,
3163
+ hierarchyLink: RIG_LINK_COLOR,
3164
+ partLink: RIG_PART_LINK_COLOR,
3165
+ hiddenLink: RIG_HIDDEN_LINK_COLOR
3166
+ }
3167
+ }
3168
+ };
3169
+ }
3170
+ function renderCurrentRig(session) {
3171
+ const r = getRenderer(session.size, session.pixelRatio);
3172
+ const { group, report } = buildRigSceneGroup(session);
3173
+ const replacements = session.renderables.map((renderable) => {
3174
+ var _a, _b;
3175
+ const material = new MeshBasicMaterial({
3176
+ color: colorHex(RIG_SHADOW_COLOR),
3177
+ transparent: true,
3178
+ opacity: 0.16,
3179
+ side: DoubleSide,
3180
+ depthWrite: false,
3181
+ toneMapped: false,
3182
+ clippingPlanes: renderable.solidMaterial.clippingPlanes
3183
+ });
3184
+ const previous = {
3185
+ solidVisible: renderable.solid.visible,
3186
+ wireVisible: renderable.wire.visible,
3187
+ shellVisible: (_a = renderable.shell) == null ? void 0 : _a.visible,
3188
+ scanProxyVisible: (_b = renderable.scanProxy) == null ? void 0 : _b.visible,
3189
+ material: renderable.solid.material,
3190
+ replacement: material
3191
+ };
3192
+ renderable.solid.material = material;
3193
+ renderable.solid.visible = true;
3194
+ renderable.wire.visible = false;
3195
+ if (renderable.shell) renderable.shell.visible = false;
3196
+ if (renderable.scanProxy) renderable.scanProxy.visible = false;
3197
+ return { renderable, previous };
3198
+ });
3199
+ session.scene.add(group);
3200
+ try {
3201
+ const png = withTemporarySceneBackground(session, new Color(132105), () => {
3202
+ updateSdfRaymarchUniforms(session);
3203
+ r.render(session.scene, session.camera);
3204
+ return captureRenderedPng(session.size);
3205
+ });
3206
+ return { png, report };
3207
+ } finally {
3208
+ session.scene.remove(group);
3209
+ disposeObjectTree(group);
3210
+ replacements.forEach(({ renderable, previous }) => {
3211
+ renderable.solid.material = previous.material;
3212
+ renderable.solid.visible = previous.solidVisible;
3213
+ renderable.wire.visible = previous.wireVisible;
3214
+ if (renderable.shell && previous.shellVisible !== void 0) renderable.shell.visible = previous.shellVisible;
3215
+ if (renderable.scanProxy && previous.scanProxyVisible !== void 0) renderable.scanProxy.visible = previous.scanProxyVisible;
3216
+ previous.replacement.dispose();
3217
+ });
3218
+ }
3219
+ }
2793
3220
  function analyzeSessionConnectivity(session) {
2794
3221
  if (!session.physicalConnectivity) {
2795
3222
  session.physicalConnectivity = analyzePhysicalConnectivity(session.connectivityEntries);
@@ -3442,10 +3869,9 @@ function getSessionThicknessInspection(session, rawOptions) {
3442
3869
  objects,
3443
3870
  warnings,
3444
3871
  style: {
3445
- criticalColor: THICKNESS_COLORS.critical,
3446
- warningColor: THICKNESS_COLORS.warning,
3447
- okColor: THICKNESS_COLORS.ok,
3448
- thickColor: THICKNESS_COLORS.thick,
3872
+ gradientColors: THICKNESS_GRADIENT_COLORS.map((color) => [...color]),
3873
+ colorMinThickness: options.colorMinThickness,
3874
+ colorMaxThickness: options.colorMaxThickness,
3449
3875
  unknownColor: THICKNESS_COLORS.unknown
3450
3876
  }
3451
3877
  }
@@ -3792,9 +4218,6 @@ function addRenderStyleLights(scene, style) {
3792
4218
  new HemisphereLight(new Color(lights.hemisphereSky), new Color(lights.hemisphereGround), lights.hemisphereIntensity)
3793
4219
  );
3794
4220
  }
3795
- function fieldKindUniform(kind) {
3796
- return kind === "hybrid" ? 1 : 0;
3797
- }
3798
4221
  function createSurfaceFieldMaterial({
3799
4222
  field,
3800
4223
  objectColor,
@@ -3808,7 +4231,6 @@ function createSurfaceFieldMaterial({
3808
4231
  uAccentColor: { value: new Color(field.accentColor) },
3809
4232
  uBaseColor: { value: new Color(field.baseColor) },
3810
4233
  uDarkColor: { value: new Color(field.darkColor) },
3811
- uFieldKind: { value: fieldKindUniform(field.kind) },
3812
4234
  uFieldScale: { value: fieldScale },
3813
4235
  uGlow: { value: field.glow },
3814
4236
  uLineColor: { value: new Color(field.lineColor) },
@@ -4434,13 +4856,6 @@ function buildCameraRig(center, distance, _maxDim, spec, fovDeg = 45) {
4434
4856
  orbitBasePitchDeg: Number.isFinite(orbitBasePitchDeg) ? orbitBasePitchDeg : DEFAULT_PITCH_DEG
4435
4857
  };
4436
4858
  }
4437
- function buildBaseJointValues(joints) {
4438
- const out = {};
4439
- joints.forEach((joint) => {
4440
- out[joint.name] = joint.defaultValue;
4441
- });
4442
- return out;
4443
- }
4444
4859
  function resolveRequestedSceneState(opts) {
4445
4860
  let sceneState = (opts == null ? void 0 : opts.sceneState) ?? null;
4446
4861
  if (opts == null ? void 0 : opts.sceneSpec) {
@@ -4465,8 +4880,8 @@ function resolveRenderableJointNodeName(obj, joints) {
4465
4880
  }
4466
4881
  function applyObjectTransforms(session, animationProgress) {
4467
4882
  const animatedValues = resolveJointAnimation(session.selectedAnimation, animationProgress ?? 0, session.baseJointValues);
4468
- const effectiveJointValues = resolveJointViewValues(session.joints, session.jointCouplings, animatedValues);
4469
- const jointMatrices = computeJointNodeMatrices(session.joints, effectiveJointValues);
4883
+ const effectiveJointValues = resolveJointViewValues(session.transformJoints, session.transformJointCouplings, animatedValues);
4884
+ const jointMatrices = computeJointNodeMatrices(session.transformJoints, effectiveJointValues);
4470
4885
  const objectMatrices = /* @__PURE__ */ new Map();
4471
4886
  session.renderables.forEach((renderable) => {
4472
4887
  var _a;
@@ -4693,7 +5108,7 @@ Available renderable objects: ${available}`;
4693
5108
  return "No visible renderable objects found.";
4694
5109
  }
4695
5110
  function createSession(code, opts) {
4696
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
5111
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
4697
5112
  const size = (opts == null ? void 0 : opts.size) ?? 1024;
4698
5113
  const pixelRatio = (opts == null ? void 0 : opts.pixelRatio) ?? 1;
4699
5114
  const debug = createCaptureDebugLogger(opts == null ? void 0 : opts.debug);
@@ -4706,6 +5121,12 @@ function createSession(code, opts) {
4706
5121
  });
4707
5122
  const r = getRenderer(size, pixelRatio);
4708
5123
  const renderStyle = resolveForgeRenderStyle(opts == null ? void 0 : opts.renderStyle);
5124
+ if (renderStyle === "matrix") {
5125
+ return {
5126
+ ok: false,
5127
+ error: "Matrix render style is only supported in the interactive viewport; CLI rendering does not support the glyph volume yet."
5128
+ };
5129
+ }
4709
5130
  const renderStylePreset = getRenderStylePreset(renderStyle);
4710
5131
  let requestedSceneState = null;
4711
5132
  try {
@@ -4719,6 +5140,7 @@ function createSession(code, opts) {
4719
5140
  const result = runScript(code, (opts == null ? void 0 : opts.fileName) || "main.forge.js", (opts == null ? void 0 : opts.allFiles) || {}, {
4720
5141
  quality: (opts == null ? void 0 : opts.quality) ?? "high",
4721
5142
  readBinaryFile: binaryFileMapReader(opts == null ? void 0 : opts.binaryFiles),
5143
+ assemblyState: opts == null ? void 0 : opts.jointOverrides,
4722
5144
  debug: (opts == null ? void 0 : opts.debug) ? (phase, detail) => debug(`runScript:${phase}`, detail) : void 0
4723
5145
  });
4724
5146
  debug("session:runScript:end", {
@@ -4875,8 +5297,15 @@ function createSession(code, opts) {
4875
5297
  }
4876
5298
  const joints = ((_e = result.jointsView) == null ? void 0 : _e.enabled) === false ? [] : ((_f = result.jointsView) == null ? void 0 : _f.joints) ?? [];
4877
5299
  const jointCouplings = ((_g = result.jointsView) == null ? void 0 : _g.enabled) === false ? [] : ((_h = result.jointsView) == null ? void 0 : _h.couplings) ?? [];
4878
- const animationClips = ((_i = result.jointsView) == null ? void 0 : _i.enabled) === false ? [] : ((_j = result.jointsView) == null ? void 0 : _j.animations) ?? [];
4879
- const defaultAnimation = ((_k = result.jointsView) == null ? void 0 : _k.defaultAnimation) ?? null;
5300
+ try {
5301
+ validateJointOverrides(result.jointsView, (opts == null ? void 0 : opts.jointOverrides) ?? {});
5302
+ } catch (err) {
5303
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
5304
+ }
5305
+ const transformJoints = ((_i = result.jointsView) == null ? void 0 : _i.motionSource) === "assembly" ? [] : joints;
5306
+ const transformJointCouplings = ((_j = result.jointsView) == null ? void 0 : _j.motionSource) === "assembly" ? [] : jointCouplings;
5307
+ const animationClips = ((_k = result.jointsView) == null ? void 0 : _k.enabled) === false ? [] : ((_l = result.jointsView) == null ? void 0 : _l.animations) ?? [];
5308
+ const defaultAnimation = ((_m = result.jointsView) == null ? void 0 : _m.defaultAnimation) ?? null;
4880
5309
  let selectedAnimation;
4881
5310
  let sweep = null;
4882
5311
  let cutawayBase = null;
@@ -4952,8 +5381,8 @@ function createSession(code, opts) {
4952
5381
  id: obj.source.id,
4953
5382
  name: objectLabel,
4954
5383
  ms: Number((performance.now() - geometryStart).toFixed(1)),
4955
- triangles: Math.floor((((_l = geo.solid.getAttribute("position")) == null ? void 0 : _l.count) ?? 0) / 3),
4956
- edgeSegments: Math.floor((((_m = geo.edges.getAttribute("position")) == null ? void 0 : _m.count) ?? 0) / 2)
5384
+ triangles: Math.floor((((_n = geo.solid.getAttribute("position")) == null ? void 0 : _n.count) ?? 0) / 3),
5385
+ edgeSegments: Math.floor((((_o = geo.edges.getAttribute("position")) == null ? void 0 : _o.count) ?? 0) / 2)
4957
5386
  });
4958
5387
  const materialDefaults = renderStylePreset.material;
4959
5388
  const surfaceField = renderStylePreset.surfaceField;
@@ -5109,7 +5538,7 @@ function createSession(code, opts) {
5109
5538
  ...scanProxy ? { scanProxy } : {},
5110
5539
  solidMaterial,
5111
5540
  wireMaterial,
5112
- jointNodeName: resolveRenderableJointNodeName(obj.source, joints),
5541
+ jointNodeName: resolveRenderableJointNodeName(obj.source, transformJoints),
5113
5542
  sourceColor: obj.color ?? "#5b9bd5",
5114
5543
  opacity: obj.opacity,
5115
5544
  sectionMesh,
@@ -5128,7 +5557,7 @@ function createSession(code, opts) {
5128
5557
  { bodyShape: () => new EmptyInspectionShape() }
5129
5558
  ) : null;
5130
5559
  const connectivityEntries = (connectivityBodyInput == null ? void 0 : connectivityBodyInput.entries) ?? [];
5131
- const groundOffset = Number.isFinite((_n = sceneConfig == null ? void 0 : sceneConfig.ground) == null ? void 0 : _n.offset) ? sceneConfig.ground.offset : 0;
5560
+ const groundOffset = Number.isFinite((_p = sceneConfig == null ? void 0 : sceneConfig.ground) == null ? void 0 : _p.offset) ? sceneConfig.ground.offset : 0;
5132
5561
  const floatingGroundZ = bbox.min[2] - groundOffset;
5133
5562
  let sceneConfigCameraState = null;
5134
5563
  if ((sceneConfig == null ? void 0 : sceneConfig.camera) && !(requestedSceneState == null ? void 0 : requestedSceneState.camera)) {
@@ -5157,7 +5586,7 @@ function createSession(code, opts) {
5157
5586
  } : null;
5158
5587
  const cameraSpec = sceneConfigCameraState && (opts == null ? void 0 : opts.capture) === "section-sweep" ? fitCameraStateToBounds(sceneConfigCameraState, bbox, cameraFov) : (requestedSceneState == null ? void 0 : requestedSceneState.camera) ?? cutawayCameraState ?? sceneConfigCameraState;
5159
5588
  const cameraRig = buildCameraRig(center, distance, maxDim, cameraSpec, cameraFov);
5160
- const explicitCameraFov = (cameraSpec == null ? void 0 : cameraSpec.fov) ?? ((_o = sceneConfig == null ? void 0 : sceneConfig.camera) == null ? void 0 : _o.fov);
5589
+ const explicitCameraFov = (cameraSpec == null ? void 0 : cameraSpec.fov) ?? ((_q = sceneConfig == null ? void 0 : sceneConfig.camera) == null ? void 0 : _q.fov);
5161
5590
  if (explicitCameraFov && cameraRig.camera instanceof PerspectiveCamera) {
5162
5591
  cameraRig.camera.fov = explicitCameraFov;
5163
5592
  cameraRig.camera.updateProjectionMatrix();
@@ -5190,11 +5619,14 @@ function createSession(code, opts) {
5190
5619
  roughnessInspection: null,
5191
5620
  joints,
5192
5621
  jointCouplings,
5622
+ transformJoints,
5623
+ transformJointCouplings,
5624
+ jointOverlayConfig: ((_r = result.viewConfig) == null ? void 0 : _r.jointOverlay) ?? DEFAULT_VIEW_CONFIG.jointOverlay,
5193
5625
  animationClips,
5194
5626
  defaultAnimation,
5195
5627
  selectedAnimation,
5196
5628
  availableCutPlaneNames: availableCutPlanes.map((cp) => cp.name),
5197
- baseJointValues: buildBaseJointValues(joints),
5629
+ baseJointValues: buildBaseJointValues(transformJoints, (opts == null ? void 0 : opts.jointOverrides) ?? {}),
5198
5630
  fixedCameraState: cameraRig.fixedCameraState,
5199
5631
  orbitTarget: cameraRig.orbitTarget,
5200
5632
  orbitRadius: cameraRig.orbitRadius,
@@ -5261,6 +5693,7 @@ window.__forgeRender = async (code, opts) => {
5261
5693
  focus: opts == null ? void 0 : opts.focus,
5262
5694
  hide: opts == null ? void 0 : opts.hide,
5263
5695
  paramOverrides: opts == null ? void 0 : opts.paramOverrides,
5696
+ jointOverrides: opts == null ? void 0 : opts.jointOverrides,
5264
5697
  renderStyle: opts == null ? void 0 : opts.renderStyle,
5265
5698
  scanGranularity: opts == null ? void 0 : opts.scanGranularity,
5266
5699
  respectAuthoredSceneStyle: opts == null ? void 0 : opts.respectAuthoredSceneStyle,
@@ -5336,6 +5769,7 @@ window.__forgeRender = async (code, opts) => {
5336
5769
  const depthRenders = {};
5337
5770
  const normalRenders = {};
5338
5771
  const zebraRenders = {};
5772
+ const rigRenders = {};
5339
5773
  const maskRenders = {};
5340
5774
  const connectivityRenders = {};
5341
5775
  const floatingRenders = {};
@@ -5348,6 +5782,7 @@ window.__forgeRender = async (code, opts) => {
5348
5782
  let connectivityReport = null;
5349
5783
  let floatingReport = null;
5350
5784
  let distanceReport = null;
5785
+ let rigReport = null;
5351
5786
  const comparisonViewStats = {};
5352
5787
  let comparisonPointCloud = null;
5353
5788
  let collisionReport = null;
@@ -5423,6 +5858,13 @@ window.__forgeRender = async (code, opts) => {
5423
5858
  zebraRenders[label] = renderCurrentZebra(session);
5424
5859
  await markChannelViewDone("zebra", label);
5425
5860
  }
5861
+ if (requestedChannels.has("rig")) {
5862
+ await markChannelViewStart("rig", label);
5863
+ const rig = renderCurrentRig(session);
5864
+ rigRenders[label] = rig.png;
5865
+ rigReport = rig.report;
5866
+ await markChannelViewDone("rig", label);
5867
+ }
5426
5868
  if (requestedChannels.has("roughness")) {
5427
5869
  await markChannelViewStart("roughness", label);
5428
5870
  const roughness = renderCurrentRoughness(session, opts == null ? void 0 : opts.roughness);
@@ -5518,6 +5960,12 @@ window.__forgeRender = async (code, opts) => {
5518
5960
  depth: depthRenders,
5519
5961
  normals: normalRenders,
5520
5962
  zebra: zebraRenders,
5963
+ rig: rigReport ? {
5964
+ ...rigReport,
5965
+ views: rigRenders
5966
+ } : {
5967
+ views: rigRenders
5968
+ },
5521
5969
  roughness: roughnessReport ? {
5522
5970
  ...roughnessReport,
5523
5971
  pointCloud: roughnessPointCloud,