forgecad 0.9.13 → 0.9.15

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 (216) hide show
  1. package/LICENSE +6 -4
  2. package/README.md +8 -4
  3. package/dist/assets/{AdminPage-DramHHDf.js → AdminPage-CDyGUinA.js} +2 -2
  4. package/dist/assets/{BenchmarkPage-Bjgkh5m9.js → BenchmarkPage-DfPMY_-d.js} +4 -15
  5. package/dist/assets/{BlogPage-n_HGP3Qm.js → BlogPage-kF0fkdJT.js} +2 -2
  6. package/dist/assets/{DocsPage-WCIkPmzC.js → DocsPage-B954L3YN.js} +9 -3
  7. package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
  8. package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
  9. package/dist/assets/{EmbedViewer-DEZKqdfW.js → EmbedViewer-C77B-TrF.js} +3 -3
  10. package/dist/assets/{LandingPageProofDriven-CeRIctuj.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
  11. package/dist/assets/LegalPage-BRlScr9A.css +91 -0
  12. package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
  13. package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
  14. package/dist/assets/{PricingPage-rIRa8p4Y.js → PricingPage-zWXkvlwl.js} +19 -19
  15. package/dist/assets/{SettingsPage-BqCUvEXM.js → SettingsPage-Bz0of4KQ.js} +2 -2
  16. package/dist/assets/app-CE3sYcV7.css +3890 -0
  17. package/dist/assets/{app-BUZqJvSO.js → app-D3kDkggg.js} +2305 -960
  18. package/dist/assets/cli/{render-lhGxj50Y.js → render-DSY3mMQa.js} +423 -30
  19. package/dist/assets/{constructionHistoryWorker-ipD1jcIv.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
  20. package/dist/assets/{evalWorker-CHXSe_-u.js → evalWorker-CU0Ke6DP.js} +7799 -4163
  21. package/dist/assets/{forgecad_geometry-BVnIeXMG.js → forgecad_geometry-Dgceylq9.js} +43 -1
  22. package/dist/assets/{forgecad_geometry_bg-DufhhCBV.wasm → forgecad_geometry_bg-dD4RNQF1.wasm} +0 -0
  23. package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
  24. package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
  25. package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
  26. package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
  27. package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
  28. package/dist/assets/{manifold-D1LZIHqn.js → manifold-BRI5prcH.js} +1 -1
  29. package/dist/assets/{manifold-C2fwoTgd.js → manifold-C-3h2M7p.js} +2 -2
  30. package/dist/assets/{manifold-BTkzxi9V.js → manifold-DNkrUWpA.js} +1 -1
  31. package/dist/assets/{reportWorker-Cq1qGmg0.js → reportWorker-CdBz5bNg.js} +7537 -10856
  32. package/dist/assets/{scalar-sampling-budget-D9Qv_UlJ.js → scalar-sampling-budget-wJF98aY9.js} +6943 -4345
  33. package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
  34. package/dist/assets/{renderSceneState-Dr0xPq1A.js → targets-B9sGB5nB.js} +27 -1
  35. package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
  36. package/dist/cli/render.html +1 -1
  37. package/dist/docs/index.html +2 -2
  38. package/dist/docs-raw/AI/ai-native-cad.md +50 -0
  39. package/dist/docs-raw/AI/usage.md +9 -17
  40. package/dist/docs-raw/CLI.md +71 -21
  41. package/dist/docs-raw/component-model.md +27 -11
  42. package/dist/docs-raw/generated/assembly.md +301 -212
  43. package/dist/docs-raw/generated/concepts.md +238 -240
  44. package/dist/docs-raw/generated/core.md +283 -6
  45. package/dist/docs-raw/generated/curves.md +274 -361
  46. package/dist/docs-raw/generated/lib.md +7 -1
  47. package/dist/docs-raw/generated/output.md +19 -4
  48. package/dist/docs-raw/generated/runtime-names.md +41 -0
  49. package/dist/docs-raw/generated/sdf.md +31 -0
  50. package/dist/docs-raw/generated/sheet-metal.md +9 -0
  51. package/dist/docs-raw/generated/sketch.md +44 -1
  52. package/dist/docs-raw/generated/viewport.md +14 -6
  53. package/dist/docs-raw/guides/coordinate-system.md +20 -16
  54. package/dist/docs-raw/guides/geometry-conventions.md +2 -2
  55. package/dist/docs-raw/guides/inspection-bundles.md +2 -1
  56. package/dist/docs-raw/guides/joint-design.md +24 -0
  57. package/dist/docs-raw/guides/positioning.md +13 -3
  58. package/dist/docs-raw/legal/privacy.md +63 -0
  59. package/dist/docs-raw/legal/software-license.md +55 -0
  60. package/dist/docs-raw/legal/terms.md +87 -0
  61. package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +3 -3
  62. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
  63. package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
  64. package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
  65. package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
  66. package/dist/docs-raw/skills/forgecad-lld.md +1 -1
  67. package/dist/docs-raw/skills/forgecad-make-a-model.md +4 -4
  68. package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
  69. package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
  70. package/dist/docs-raw/skills/forgecad-project.md +1 -1
  71. package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +4 -4
  72. package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
  73. package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
  74. package/dist/docs-raw/skills/forgecad.md +4 -3
  75. package/dist/index.html +40 -12
  76. package/dist/llms.txt +8 -0
  77. package/dist/site.webmanifest +1 -1
  78. package/dist/sitemap.xml +49 -13
  79. package/dist-cli/{check-compiler-LOXCPEOI.js → check-compiler-SDX5QIXI.js} +1 -2
  80. package/dist-cli/{check-query-propagation-BAKNVWXR.js → check-query-propagation-EAYEFT77.js} +1 -2
  81. package/dist-cli/{chunk-RY43WF46.js → chunk-N4O47JLF.js} +13772 -9938
  82. package/dist-cli/forgecad.js +2387 -899
  83. package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
  84. package/dist-cli/forgecad_geometry_bg.wasm +0 -0
  85. package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
  86. package/dist-skill/CONTEXT.md +1120 -724
  87. package/dist-skill/SKILL.md +3 -2
  88. package/dist-skill/docs/API/core/concepts.md +64 -1
  89. package/dist-skill/docs/CLI.md +71 -21
  90. package/dist-skill/docs/generated/assembly.md +277 -229
  91. package/dist-skill/docs/generated/core.md +283 -6
  92. package/dist-skill/docs/generated/curves.md +272 -362
  93. package/dist-skill/docs/generated/lib.md +7 -1
  94. package/dist-skill/docs/generated/output.md +19 -4
  95. package/dist-skill/docs/generated/runtime-names.md +41 -0
  96. package/dist-skill/docs/generated/sdf.md +31 -0
  97. package/dist-skill/docs/generated/sheet-metal.md +9 -0
  98. package/dist-skill/docs/generated/sketch.md +44 -2
  99. package/dist-skill/docs/generated/viewport.md +5 -90
  100. package/dist-skill/docs/guides/coordinate-system.md +20 -16
  101. package/dist-skill/docs/guides/geometry-conventions.md +2 -2
  102. package/dist-skill/docs/guides/inspection-bundles.md +2 -1
  103. package/dist-skill/docs/guides/joint-design.md +24 -0
  104. package/dist-skill/docs/guides/positioning.md +13 -3
  105. package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +2 -2
  106. package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
  107. package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
  108. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
  109. package/dist-skill/library/forgecad-make-a-model/SKILL.md +3 -3
  110. package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
  111. package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
  112. package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +3 -3
  113. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  114. package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
  115. package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
  116. package/examples/api/assembly-kinematics-limb.forge.js +116 -0
  117. package/examples/api/connector-frame-rig-chain.forge.js +102 -0
  118. package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
  119. package/examples/api/exact-surface-studio.forge.js +6 -8
  120. package/examples/api/helix-basics.forge.js +6 -6
  121. package/examples/api/lean-foundations/README.md +12 -0
  122. package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
  123. package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
  124. package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
  125. package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
  126. package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
  127. package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
  128. package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
  129. package/examples/api/route3d-elbow.forge.js +68 -0
  130. package/examples/api/transition-curves.forge.js +44 -15
  131. package/examples/api/y-blend-corner-showcase.forge.js +0 -2
  132. package/examples/generative/coral-vase.forge.js +1 -1
  133. package/examples/nurbs-tube.forge.js +1 -1
  134. package/package.json +14 -18
  135. package/dist/assets/EditorApp-CP9Za6tm.js +0 -13630
  136. package/dist/assets/app-CsHnaBWt.css +0 -1789
  137. package/dist/docs-raw/API/README.md +0 -16
  138. package/dist/docs-raw/API/core/concepts.md +0 -118
  139. package/dist/docs-raw/INDEX.md +0 -138
  140. package/dist/docs-raw/RELEASING.md +0 -87
  141. package/dist/docs-raw/agent-native-api.md +0 -27
  142. package/dist/docs-raw/beta-deployment.md +0 -304
  143. package/dist/docs-raw/beta-operations.md +0 -325
  144. package/dist/docs-raw/blueprint-first.md +0 -145
  145. package/dist/docs-raw/cli-monetization.md +0 -112
  146. package/dist/docs-raw/coding-best-practices.md +0 -120
  147. package/dist/docs-raw/coding.md +0 -340
  148. package/dist/docs-raw/deployment.md +0 -374
  149. package/dist/docs-raw/guides/skill-maintenance.md +0 -161
  150. package/dist/docs-raw/guides/surface-members.md +0 -82
  151. package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
  152. package/dist/docs-raw/internals/compiler.md +0 -307
  153. package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
  154. package/dist/docs-raw/internals/constraint-solver.md +0 -176
  155. package/dist/docs-raw/internals/shape-from-slices.md +0 -152
  156. package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
  157. package/dist/docs-raw/platform/admin.md +0 -45
  158. package/dist/docs-raw/platform/architecture.md +0 -82
  159. package/dist/docs-raw/platform/auth.md +0 -139
  160. package/dist/docs-raw/platform/email.md +0 -67
  161. package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
  162. package/dist/docs-raw/platform/observability.md +0 -197
  163. package/dist/docs-raw/platform/projects.md +0 -111
  164. package/dist/docs-raw/platform/sharing.md +0 -90
  165. package/dist/docs-raw/product/README.md +0 -39
  166. package/dist/docs-raw/product/api-as-product-language.md +0 -13
  167. package/dist/docs-raw/product/business-model.md +0 -15
  168. package/dist/docs-raw/product/competitive-positioning.md +0 -17
  169. package/dist/docs-raw/product/creative-manufacturing.md +0 -15
  170. package/dist/docs-raw/product/founder-story.md +0 -11
  171. package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
  172. package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
  173. package/dist/docs-raw/product/product-loop.md +0 -17
  174. package/dist/docs-raw/product/strategic-decisions.md +0 -22
  175. package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
  176. package/dist/docs-raw/product/user-segments.md +0 -15
  177. package/dist/docs-raw/product/vision.md +0 -26
  178. package/dist/docs-raw/rl-environments.md +0 -508
  179. package/dist/docs-raw/runbook.md +0 -611
  180. package/dist-cli/check-compiler-LOXCPEOI.js.map +0 -1
  181. package/dist-cli/check-query-propagation-BAKNVWXR.js.map +0 -1
  182. package/dist-cli/chunk-RY43WF46.js.map +0 -1
  183. package/dist-cli/forgecad.js.map +0 -1
  184. package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
  185. package/dist-cli/solver-46FFSK2U.js.map +0 -1
  186. package/dist-skill/SKILL-dev.md +0 -145
  187. package/dist-skill/docs-dev/API/core/concepts.md +0 -118
  188. package/dist-skill/docs-dev/CLI.md +0 -647
  189. package/dist-skill/docs-dev/agent-native-api.md +0 -27
  190. package/dist-skill/docs-dev/blueprint-first.md +0 -145
  191. package/dist-skill/docs-dev/coding-best-practices.md +0 -120
  192. package/dist-skill/docs-dev/coding.md +0 -340
  193. package/dist-skill/docs-dev/component-model.md +0 -164
  194. package/dist-skill/docs-dev/generated/assembly.md +0 -794
  195. package/dist-skill/docs-dev/generated/core.md +0 -2117
  196. package/dist-skill/docs-dev/generated/curves.md +0 -2583
  197. package/dist-skill/docs-dev/generated/lib.md +0 -169
  198. package/dist-skill/docs-dev/generated/output.md +0 -247
  199. package/dist-skill/docs-dev/generated/sdf.md +0 -446
  200. package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
  201. package/dist-skill/docs-dev/generated/sketch.md +0 -1811
  202. package/dist-skill/docs-dev/generated/viewport.md +0 -585
  203. package/dist-skill/docs-dev/generated/wood.md +0 -108
  204. package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
  205. package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
  206. package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
  207. package/dist-skill/docs-dev/guides/joint-design.md +0 -78
  208. package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
  209. package/dist-skill/docs-dev/guides/positioning.md +0 -161
  210. package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
  211. package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
  212. package/dist-skill/docs-dev/internals/compiler.md +0 -307
  213. package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
  214. package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
  215. package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
  216. package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
@@ -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, $ as Matrix4, cG as Frustum, G as Box3, g as Vector3, 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, a0 as MathUtils, 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-D9Qv_UlJ.js";
5
- import { m as mergeViewportRenderSceneStates, p as parseRenderSceneCliSpec } from "../renderSceneState-Dr0xPq1A.js";
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";
6
6
  const CAD_MATERIAL_PROPS = {
7
7
  color: 6003669,
8
8
  metalness: 0.05,
@@ -648,6 +648,8 @@ function analyzeDistanceInspection(entries, rawOptions = {}) {
648
648
  warnings: [...connectivity.warnings]
649
649
  };
650
650
  }
651
+ const DEFAULT_PERSPECTIVE_FIT_MARGIN = 1.1;
652
+ const DEFAULT_MIN_CAMERA_DISTANCE = 1;
651
653
  function bboxCorners$1(bbox) {
652
654
  const [minX, minY, minZ] = bbox.min;
653
655
  const [maxX, maxY, maxZ] = bbox.max;
@@ -662,9 +664,59 @@ function bboxCorners$1(bbox) {
662
664
  new Vector3(maxX, maxY, maxZ)
663
665
  ];
664
666
  }
667
+ function bboxCenter(bbox) {
668
+ return new Vector3((bbox.min[0] + bbox.max[0]) * 0.5, (bbox.min[1] + bbox.max[1]) * 0.5, (bbox.min[2] + bbox.max[2]) * 0.5);
669
+ }
670
+ function finitePositive(value, label) {
671
+ if (!Number.isFinite(value) || value <= 0) {
672
+ throw new Error(`${label} must be a positive finite number.`);
673
+ }
674
+ return value;
675
+ }
676
+ function cameraRightFor(backward, up) {
677
+ const normalizedUp = up.lengthSq() > 1e-8 ? up.clone().normalize() : new Vector3(0, 0, 1);
678
+ let right = new Vector3().crossVectors(normalizedUp, backward);
679
+ if (right.lengthSq() > 1e-8) return right.normalize();
680
+ const fallbackUp = Math.abs(backward.z) > 0.92 ? new Vector3(0, 1, 0) : new Vector3(0, 0, 1);
681
+ right = new Vector3().crossVectors(fallbackUp, backward);
682
+ if (right.lengthSq() > 1e-8) return right.normalize();
683
+ return new Vector3(1, 0, 0);
684
+ }
665
685
  function objectBox(input) {
666
686
  return new Box3(new Vector3(...input.bbox.min), new Vector3(...input.bbox.max));
667
687
  }
688
+ function perspectiveCameraDistanceForBounds(bbox, directionFromTargetToCamera, options) {
689
+ const backward = new Vector3(...directionFromTargetToCamera);
690
+ if (backward.lengthSq() <= 1e-8) {
691
+ throw new Error("directionFromTargetToCamera must be a non-zero vector.");
692
+ }
693
+ backward.normalize();
694
+ const fovDeg = finitePositive(options.fovDeg, "fovDeg");
695
+ if (fovDeg >= 180) {
696
+ throw new Error("fovDeg must be less than 180 degrees.");
697
+ }
698
+ const aspect = finitePositive(options.aspect ?? 1, "aspect");
699
+ const margin = finitePositive(options.margin ?? DEFAULT_PERSPECTIVE_FIT_MARGIN, "margin");
700
+ const minDistance = finitePositive(options.minDistance ?? DEFAULT_MIN_CAMERA_DISTANCE, "minDistance");
701
+ const tanHalfVerticalFov = Math.tan(MathUtils.degToRad(fovDeg) * 0.5);
702
+ const tanHalfHorizontalFov = tanHalfVerticalFov * aspect;
703
+ const right = cameraRightFor(backward, new Vector3(...options.up ?? [0, 0, 1]));
704
+ const screenUp = new Vector3().crossVectors(backward, right).normalize();
705
+ const center = bboxCenter(bbox);
706
+ let requiredDistance = minDistance;
707
+ for (const corner of bboxCorners$1(bbox)) {
708
+ const offset = corner.sub(center);
709
+ const depthOffset = offset.dot(backward);
710
+ const horizontalOffset = Math.abs(offset.dot(right));
711
+ const verticalOffset = Math.abs(offset.dot(screenUp));
712
+ requiredDistance = Math.max(
713
+ requiredDistance,
714
+ horizontalOffset * margin / tanHalfHorizontalFov + depthOffset,
715
+ verticalOffset * margin / tanHalfVerticalFov + depthOffset
716
+ );
717
+ }
718
+ return requiredDistance;
719
+ }
668
720
  function cameraFrustum(camera) {
669
721
  camera.updateMatrixWorld(true);
670
722
  if ("updateProjectionMatrix" in camera && typeof camera.updateProjectionMatrix === "function") {
@@ -1715,6 +1767,10 @@ const exportCtx = exportCanvas.getContext("2d");
1715
1767
  const DEFAULT_BACKGROUND = 2434342;
1716
1768
  const DEFAULT_PITCH_DEG = 18;
1717
1769
  const DEFAULT_FIXED_DIR = new Vector3(0, -1, 0.32).normalize();
1770
+ const RIG_SHADOW_COLOR = [6, 10, 18];
1771
+ const RIG_LINK_COLOR = [20, 220, 255];
1772
+ const RIG_PART_LINK_COLOR = [174, 255, 92];
1773
+ const RIG_HIDDEN_LINK_COLOR = [116, 136, 148];
1718
1774
  const ORTHO_BASE_SIZE = 960;
1719
1775
  const CAPTURE_RUNTIME_CAPABILITIES = {
1720
1776
  version: 3,
@@ -2035,7 +2091,12 @@ function updateSdfRaymarchUniforms(session) {
2035
2091
  }
2036
2092
  function applyDirectionCamera(session, dir, distanceOverride) {
2037
2093
  const d = normalizeCameraDirection(dir);
2038
- const dist = distanceOverride ?? session.distance;
2094
+ const fov = session.camera instanceof PerspectiveCamera ? session.camera.fov : 45;
2095
+ const dist = distanceOverride ?? perspectiveCameraDistanceForBounds(session.bbox, d, {
2096
+ fovDeg: fov,
2097
+ aspect: session.camera instanceof PerspectiveCamera ? session.camera.aspect : 1,
2098
+ up: [0, 0, 1]
2099
+ });
2039
2100
  session.camera.position.set(session.center.x + d[0] * dist, session.center.y + d[1] * dist, session.center.z + d[2] * dist);
2040
2101
  session.camera.up.set(0, 0, 1);
2041
2102
  session.camera.lookAt(session.center);
@@ -2199,15 +2260,15 @@ function mergeBounds(a, b) {
2199
2260
  function boundsCenter(bounds) {
2200
2261
  return new Vector3((bounds.min[0] + bounds.max[0]) / 2, (bounds.min[1] + bounds.max[1]) / 2, (bounds.min[2] + bounds.max[2]) / 2);
2201
2262
  }
2202
- function boundsMaxDim(bounds) {
2203
- return Math.max(1, bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2]);
2204
- }
2205
2263
  function applyDirectionCameraToBounds(session, bounds, dir, distanceOverride) {
2206
2264
  const d = normalizeCameraDirection(dir);
2207
2265
  const center = boundsCenter(bounds);
2208
- const maxDim = boundsMaxDim(bounds);
2209
2266
  const fov = session.camera instanceof PerspectiveCamera ? session.camera.fov : 45;
2210
- const dist = distanceOverride ?? maxDim / (2 * Math.tan(fov * Math.PI / 360)) * 1.6;
2267
+ const dist = distanceOverride ?? perspectiveCameraDistanceForBounds(bounds, d, {
2268
+ fovDeg: fov,
2269
+ aspect: session.camera instanceof PerspectiveCamera ? session.camera.aspect : 1,
2270
+ up: [0, 0, 1]
2271
+ });
2211
2272
  session.camera.position.set(center.x + d[0] * dist, center.y + d[1] * dist, center.z + d[2] * dist);
2212
2273
  session.camera.up.set(0, 0, 1);
2213
2274
  session.camera.lookAt(center);
@@ -2733,6 +2794,314 @@ function renderCurrentMask(session) {
2733
2794
  });
2734
2795
  }
2735
2796
  }
2797
+ function tupleFromVector(value) {
2798
+ return [Number(value.x.toFixed(6)), Number(value.y.toFixed(6)), Number(value.z.toFixed(6))];
2799
+ }
2800
+ function isFiniteVector(value) {
2801
+ return Number.isFinite(value.x) && Number.isFinite(value.y) && Number.isFinite(value.z);
2802
+ }
2803
+ function clampRadius(value, min, max) {
2804
+ return MathUtils.clamp(value, min, max);
2805
+ }
2806
+ function rigObjectMatchesChild(renderable, child) {
2807
+ return renderable.name === child || renderable.groupName === child;
2808
+ }
2809
+ function rigChildCenter(session, child) {
2810
+ const bounds = new Box3();
2811
+ let hasBounds = false;
2812
+ for (const renderable of session.renderables) {
2813
+ if (!rigObjectMatchesChild(renderable, child)) continue;
2814
+ renderable.root.updateMatrixWorld(true);
2815
+ const objectBounds = new Box3().setFromObject(renderable.root);
2816
+ if (!objectBounds.isEmpty()) {
2817
+ bounds.union(objectBounds);
2818
+ hasBounds = true;
2819
+ }
2820
+ }
2821
+ if (!hasBounds) return null;
2822
+ const center = bounds.getCenter(new Vector3());
2823
+ return isFiniteVector(center) ? center : null;
2824
+ }
2825
+ function resolveRigArcReferenceDirection(axisWorld) {
2826
+ const candidates = [new Vector3(0, 0, 1), new Vector3(0, 1, 0), new Vector3(1, 0, 0)];
2827
+ for (const candidate of candidates) {
2828
+ const projected = candidate.clone().addScaledVector(axisWorld, -candidate.dot(axisWorld));
2829
+ if (projected.lengthSq() > 1e-8) return projected.normalize();
2830
+ }
2831
+ return new Vector3(1, 0, 0);
2832
+ }
2833
+ function resolveRigVisualArcAngleDeg(valueDeg, visualLimitDeg) {
2834
+ if (!Number.isFinite(valueDeg)) return 0;
2835
+ const limit = MathUtils.clamp(visualLimitDeg, 0, 360);
2836
+ if (limit <= 1e-8) return 0;
2837
+ if (Math.abs(valueDeg) <= 360) return MathUtils.clamp(valueDeg, -limit, limit);
2838
+ return MathUtils.clamp(valueDeg % 360, -limit, limit);
2839
+ }
2840
+ function addRigCylinder(group, start, end, radius, color, opacity, renderOrder) {
2841
+ const direction = end.clone().sub(start);
2842
+ const length = direction.length();
2843
+ if (length <= 1e-6) return null;
2844
+ direction.multiplyScalar(1 / length);
2845
+ const geometry = new CylinderGeometry(radius, radius, length, 18);
2846
+ const material = new MeshBasicMaterial({
2847
+ color: Array.isArray(color) ? colorHex(color) : color,
2848
+ transparent: opacity < 1,
2849
+ opacity,
2850
+ depthTest: false,
2851
+ depthWrite: false,
2852
+ blending: AdditiveBlending,
2853
+ toneMapped: false
2854
+ });
2855
+ const mesh = new Mesh(geometry, material);
2856
+ mesh.position.copy(start).add(end).multiplyScalar(0.5);
2857
+ mesh.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction);
2858
+ mesh.renderOrder = renderOrder;
2859
+ group.add(mesh);
2860
+ return mesh;
2861
+ }
2862
+ function addRigSphere(group, position, radius, color, renderOrder) {
2863
+ const mesh = new Mesh(
2864
+ new SphereGeometry(radius, 18, 18),
2865
+ new MeshBasicMaterial({ color, depthTest: false, toneMapped: false })
2866
+ );
2867
+ mesh.position.copy(position);
2868
+ mesh.renderOrder = renderOrder;
2869
+ group.add(mesh);
2870
+ }
2871
+ function addRigCone(group, position, direction, radius, length, color) {
2872
+ if (direction.lengthSq() <= 1e-8) return;
2873
+ const mesh = new Mesh(
2874
+ new ConeGeometry(radius, length, 18),
2875
+ new MeshBasicMaterial({ color, depthTest: false, toneMapped: false })
2876
+ );
2877
+ mesh.position.copy(position);
2878
+ mesh.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction.clone().normalize());
2879
+ mesh.renderOrder = 96;
2880
+ group.add(mesh);
2881
+ }
2882
+ function addRigJointVisual(group, entry, config, axisLength, hidden) {
2883
+ const pivot = new Vector3(...entry.pivot);
2884
+ const axis = new Vector3(...entry.axis).normalize();
2885
+ const axisColor = hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.axisColor;
2886
+ const arcColor = hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.arcColor;
2887
+ const coreColor = hidden ? "#d7e7ee" : config.axisCoreColor;
2888
+ const zeroColor = hidden ? "#aebbc4" : config.zeroColor;
2889
+ const length = axisLength * (hidden ? 0.78 : 1);
2890
+ const axisRadius = clampRadius(length * config.axisLineRadiusScale, config.axisLineRadiusMin, config.axisLineRadiusMax);
2891
+ const spokeRadius = clampRadius(length * config.spokeLineRadiusScale, config.spokeLineRadiusMin, config.spokeLineRadiusMax);
2892
+ const arcLineRadius = clampRadius(length * config.arcLineRadiusScale, config.arcLineRadiusMin, config.arcLineRadiusMax);
2893
+ const dotRadius = Math.max(config.axisDotRadiusMin, length * config.axisDotRadiusScale);
2894
+ const arrowRadius = Math.max(config.axisArrowRadiusMin, length * config.axisArrowRadiusScale);
2895
+ const arrowLength = Math.max(config.axisArrowLengthMin, length * config.axisArrowLengthScale);
2896
+ const axisStart = pivot.clone().addScaledVector(axis, -length * 0.5);
2897
+ const axisEnd = pivot.clone().addScaledVector(axis, length * 0.5);
2898
+ addRigCylinder(group, axisStart, axisEnd, axisRadius, axisColor, hidden ? 0.55 : 0.98, 95);
2899
+ addRigSphere(group, pivot, dotRadius, coreColor, 96);
2900
+ addRigCone(
2901
+ group,
2902
+ axisEnd.clone().addScaledVector(axis, arrowLength * config.axisArrowOffsetFactor),
2903
+ axis,
2904
+ arrowRadius,
2905
+ arrowLength,
2906
+ axisColor
2907
+ );
2908
+ const ringRadius = Math.max(config.arcRadiusMin, length * config.arcRadiusScale);
2909
+ const ring = new Mesh(
2910
+ new TorusGeometry(ringRadius, arcLineRadius * 0.78, 10, 72),
2911
+ new MeshBasicMaterial({
2912
+ color: hidden ? colorHex(RIG_HIDDEN_LINK_COLOR) : config.axisColor,
2913
+ transparent: true,
2914
+ opacity: hidden ? 0.34 : 0.58,
2915
+ depthTest: false,
2916
+ depthWrite: false,
2917
+ blending: AdditiveBlending,
2918
+ toneMapped: false
2919
+ })
2920
+ );
2921
+ ring.position.copy(pivot);
2922
+ ring.quaternion.setFromUnitVectors(new Vector3(0, 0, 1), axis);
2923
+ ring.renderOrder = 92;
2924
+ group.add(ring);
2925
+ if (entry.type !== "revolute") return;
2926
+ const arcStartDirection = resolveRigArcReferenceDirection(axis);
2927
+ const arcAngleRad = MathUtils.degToRad(resolveRigVisualArcAngleDeg(entry.value, config.arcVisualLimitDeg));
2928
+ const arcStartPoint = pivot.clone().addScaledVector(arcStartDirection, ringRadius);
2929
+ const arcEndDirection = arcStartDirection.clone().applyAxisAngle(axis, arcAngleRad);
2930
+ const arcEndPoint = pivot.clone().addScaledVector(arcEndDirection, ringRadius);
2931
+ addRigCylinder(group, pivot, arcStartPoint, spokeRadius, zeroColor, hidden ? 0.45 : 0.9, 97);
2932
+ addRigCylinder(group, pivot, arcEndPoint, spokeRadius, arcColor, hidden ? 0.5 : 0.96, 97);
2933
+ addRigSphere(group, arcStartPoint, Math.max(config.arcDotRadiusMin, length * config.arcDotRadiusScale), zeroColor, 98);
2934
+ addRigSphere(group, arcEndPoint, Math.max(config.arcDotRadiusMin, length * config.arcDotRadiusScale), arcColor, 98);
2935
+ if (Math.abs(arcAngleRad) > 1e-4) {
2936
+ const visualDeg = MathUtils.radToDeg(Math.abs(arcAngleRad));
2937
+ const steps = Math.max(config.arcMinSteps, Math.ceil(visualDeg / config.arcStepDeg));
2938
+ const points = [];
2939
+ for (let i = 0; i <= steps; i += 1) {
2940
+ const direction = arcStartDirection.clone().applyAxisAngle(axis, arcAngleRad * (i / steps));
2941
+ points.push(pivot.clone().addScaledVector(direction, ringRadius));
2942
+ }
2943
+ const curve = new CatmullRomCurve3(points, false, "centripetal");
2944
+ const tubeSegments = Math.max(config.arcTubeSegmentsMin, Math.ceil(points.length * config.arcTubeSegmentsFactor));
2945
+ const tube = new Mesh(
2946
+ new TubeGeometry(curve, tubeSegments, arcLineRadius, config.arcTubeRadialSegments, false),
2947
+ new MeshBasicMaterial({
2948
+ color: arcColor,
2949
+ transparent: true,
2950
+ opacity: hidden ? 0.5 : 0.98,
2951
+ depthTest: false,
2952
+ depthWrite: false,
2953
+ blending: AdditiveBlending,
2954
+ toneMapped: false
2955
+ })
2956
+ );
2957
+ tube.renderOrder = 98;
2958
+ group.add(tube);
2959
+ }
2960
+ }
2961
+ function buildRigSceneGroup(session) {
2962
+ var _a;
2963
+ const group = new Group();
2964
+ const config = session.jointOverlayConfig;
2965
+ const bbox = new Box3(new Vector3(...session.bbox.min), new Vector3(...session.bbox.max));
2966
+ const diagonal = Math.max(1, bbox.getSize(new Vector3()).length());
2967
+ const axisLength = Math.max(config.axisLengthMin, diagonal * config.axisLengthScale);
2968
+ const animatedValues = resolveJointAnimation(session.selectedAnimation, 0, session.baseJointValues);
2969
+ const effectiveJointValues = resolveJointViewValues(session.joints, session.jointCouplings, animatedValues);
2970
+ const jointMatrices = computeJointNodeMatrices(session.joints, effectiveJointValues);
2971
+ const joints = [];
2972
+ const links = [];
2973
+ const jointByChild = /* @__PURE__ */ new Map();
2974
+ for (let index = 0; index < session.joints.length; index += 1) {
2975
+ const joint = session.joints[index];
2976
+ const parentMatrix = joint.parent ? ((_a = jointMatrices.get(joint.parent)) == null ? void 0 : _a.clone()) ?? new Matrix4() : new Matrix4();
2977
+ const axisLocal = new Vector3(joint.axis[0], joint.axis[1], joint.axis[2]).normalize();
2978
+ const axisWorld = axisLocal.clone().transformDirection(parentMatrix);
2979
+ if (axisWorld.lengthSq() <= 1e-8) axisWorld.copy(axisLocal);
2980
+ axisWorld.normalize();
2981
+ if (axisWorld.lengthSq() <= 1e-8 || !isFiniteVector(axisWorld)) continue;
2982
+ const pivotWorld = new Vector3(joint.pivot[0], joint.pivot[1], joint.pivot[2]).applyMatrix4(parentMatrix);
2983
+ if (!isFiniteVector(pivotWorld)) continue;
2984
+ const rawValue = effectiveJointValues[joint.name] ?? joint.defaultValue;
2985
+ const entry = {
2986
+ index,
2987
+ name: joint.name,
2988
+ type: joint.type,
2989
+ child: joint.child,
2990
+ ...joint.parent ? { parent: joint.parent } : {},
2991
+ hidden: joint.hidden === true,
2992
+ value: Number.isFinite(rawValue) ? rawValue : joint.defaultValue,
2993
+ pivot: tupleFromVector(pivotWorld),
2994
+ axis: tupleFromVector(axisWorld)
2995
+ };
2996
+ joints.push(entry);
2997
+ jointByChild.set(joint.child, entry);
2998
+ }
2999
+ const pushLink = (entry, kind, start, end) => {
3000
+ if (!start || !end || !isFiniteVector(start) || !isFiniteVector(end)) return;
3001
+ if (start.distanceToSquared(end) <= 1e-6) return;
3002
+ const id = `${entry.name}:${kind}`;
3003
+ links.push({
3004
+ id,
3005
+ kind,
3006
+ joint: entry.name,
3007
+ hidden: entry.hidden,
3008
+ start: tupleFromVector(start),
3009
+ end: tupleFromVector(end)
3010
+ });
3011
+ };
3012
+ for (const entry of joints) {
3013
+ const pivot = new Vector3(...entry.pivot);
3014
+ const parent = entry.parent ? jointByChild.get(entry.parent) : null;
3015
+ pushLink(entry, "hierarchy", parent ? new Vector3(...parent.pivot) : null, pivot);
3016
+ pushLink(entry, "part", pivot, rigChildCenter(session, entry.child));
3017
+ }
3018
+ const hierarchyRadius = clampRadius(axisLength * 0.013, 0.55, 2.4);
3019
+ const partRadius = clampRadius(axisLength * 8e-3, 0.34, 1.45);
3020
+ for (const link of links) {
3021
+ addRigCylinder(
3022
+ group,
3023
+ new Vector3(...link.start),
3024
+ new Vector3(...link.end),
3025
+ link.kind === "hierarchy" ? hierarchyRadius : partRadius,
3026
+ link.hidden ? RIG_HIDDEN_LINK_COLOR : link.kind === "hierarchy" ? RIG_LINK_COLOR : RIG_PART_LINK_COLOR,
3027
+ link.hidden ? 0.36 : link.kind === "hierarchy" ? 0.82 : 0.58,
3028
+ 88
3029
+ );
3030
+ }
3031
+ if (config.enabled) {
3032
+ for (const joint of joints) {
3033
+ addRigJointVisual(group, joint, config, axisLength, joint.hidden);
3034
+ }
3035
+ }
3036
+ return {
3037
+ group,
3038
+ report: {
3039
+ method: "rig-skeleton-shadow-v1",
3040
+ objectCount: session.renderables.length,
3041
+ jointCount: joints.length,
3042
+ linkCount: links.length,
3043
+ hiddenJointCount: joints.filter((joint) => joint.hidden).length,
3044
+ joints,
3045
+ links,
3046
+ palette: {
3047
+ shadow: RIG_SHADOW_COLOR,
3048
+ hierarchyLink: RIG_LINK_COLOR,
3049
+ partLink: RIG_PART_LINK_COLOR,
3050
+ hiddenLink: RIG_HIDDEN_LINK_COLOR
3051
+ }
3052
+ }
3053
+ };
3054
+ }
3055
+ function renderCurrentRig(session) {
3056
+ const r = getRenderer(session.size, session.pixelRatio);
3057
+ const { group, report } = buildRigSceneGroup(session);
3058
+ const replacements = session.renderables.map((renderable) => {
3059
+ var _a, _b;
3060
+ const material = new MeshBasicMaterial({
3061
+ color: colorHex(RIG_SHADOW_COLOR),
3062
+ transparent: true,
3063
+ opacity: 0.16,
3064
+ side: DoubleSide,
3065
+ depthWrite: false,
3066
+ toneMapped: false,
3067
+ clippingPlanes: renderable.solidMaterial.clippingPlanes
3068
+ });
3069
+ const previous = {
3070
+ solidVisible: renderable.solid.visible,
3071
+ wireVisible: renderable.wire.visible,
3072
+ shellVisible: (_a = renderable.shell) == null ? void 0 : _a.visible,
3073
+ scanProxyVisible: (_b = renderable.scanProxy) == null ? void 0 : _b.visible,
3074
+ material: renderable.solid.material,
3075
+ replacement: material
3076
+ };
3077
+ renderable.solid.material = material;
3078
+ renderable.solid.visible = true;
3079
+ renderable.wire.visible = false;
3080
+ if (renderable.shell) renderable.shell.visible = false;
3081
+ if (renderable.scanProxy) renderable.scanProxy.visible = false;
3082
+ return { renderable, previous };
3083
+ });
3084
+ session.scene.add(group);
3085
+ try {
3086
+ const png = withTemporarySceneBackground(session, new Color(132105), () => {
3087
+ updateSdfRaymarchUniforms(session);
3088
+ r.render(session.scene, session.camera);
3089
+ return captureRenderedPng(session.size);
3090
+ });
3091
+ return { png, report };
3092
+ } finally {
3093
+ session.scene.remove(group);
3094
+ disposeObjectTree(group);
3095
+ replacements.forEach(({ renderable, previous }) => {
3096
+ renderable.solid.material = previous.material;
3097
+ renderable.solid.visible = previous.solidVisible;
3098
+ renderable.wire.visible = previous.wireVisible;
3099
+ if (renderable.shell && previous.shellVisible !== void 0) renderable.shell.visible = previous.shellVisible;
3100
+ if (renderable.scanProxy && previous.scanProxyVisible !== void 0) renderable.scanProxy.visible = previous.scanProxyVisible;
3101
+ previous.replacement.dispose();
3102
+ });
3103
+ }
3104
+ }
2736
3105
  function analyzeSessionConnectivity(session) {
2737
3106
  if (!session.physicalConnectivity) {
2738
3107
  session.physicalConnectivity = analyzePhysicalConnectivity(session.connectivityEntries);
@@ -3735,9 +4104,6 @@ function addRenderStyleLights(scene, style) {
3735
4104
  new HemisphereLight(new Color(lights.hemisphereSky), new Color(lights.hemisphereGround), lights.hemisphereIntensity)
3736
4105
  );
3737
4106
  }
3738
- function fieldKindUniform(kind) {
3739
- return kind === "hybrid" ? 1 : 0;
3740
- }
3741
4107
  function createSurfaceFieldMaterial({
3742
4108
  field,
3743
4109
  objectColor,
@@ -3751,7 +4117,6 @@ function createSurfaceFieldMaterial({
3751
4117
  uAccentColor: { value: new Color(field.accentColor) },
3752
4118
  uBaseColor: { value: new Color(field.baseColor) },
3753
4119
  uDarkColor: { value: new Color(field.darkColor) },
3754
- uFieldKind: { value: fieldKindUniform(field.kind) },
3755
4120
  uFieldScale: { value: fieldScale },
3756
4121
  uGlow: { value: field.glow },
3757
4122
  uLineColor: { value: new Color(field.lineColor) },
@@ -3800,7 +4165,6 @@ function createScanProxyGroup(proxy, clippingPlanes, objectColor) {
3800
4165
  clippingPlanes
3801
4166
  })
3802
4167
  );
3803
- fill.renderOrder = layer.fillOrder;
3804
4168
  fill.raycast = () => null;
3805
4169
  group.add(fill);
3806
4170
  const wire = new Mesh(
@@ -3813,7 +4177,6 @@ function createScanProxyGroup(proxy, clippingPlanes, objectColor) {
3813
4177
  clippingPlanes
3814
4178
  })
3815
4179
  );
3816
- wire.renderOrder = layer.wireOrder;
3817
4180
  wire.raycast = () => null;
3818
4181
  group.add(wire);
3819
4182
  }
@@ -4583,29 +4946,37 @@ function destroyCaptureSession() {
4583
4946
  function isFocusVisible(obj, focus, hide) {
4584
4947
  if (focus === "no-mocks") return !obj.mock;
4585
4948
  if (Array.isArray(focus)) {
4586
- const lower = obj.name.toLowerCase();
4949
+ const candidates = objectFocusCandidates(obj);
4587
4950
  return focus.some((p) => {
4588
- const pl = p.toLowerCase();
4951
+ const pl = normalizeFocusCandidate(p);
4589
4952
  if (pl.includes("*") || pl.includes("?")) {
4590
4953
  const regex = pl.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
4591
- return new RegExp(`^${regex}$`).test(lower);
4954
+ return candidates.some((candidate) => new RegExp(`^${regex}$`).test(candidate));
4592
4955
  }
4593
- return lower === pl;
4956
+ return candidates.includes(pl);
4594
4957
  });
4595
4958
  }
4596
4959
  if (Array.isArray(hide)) {
4597
- const lower = obj.name.toLowerCase();
4960
+ const candidates = objectFocusCandidates(obj);
4598
4961
  return !hide.some((p) => {
4599
- const pl = p.toLowerCase();
4962
+ const pl = normalizeFocusCandidate(p);
4600
4963
  if (pl.includes("*") || pl.includes("?")) {
4601
4964
  const regex = pl.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
4602
- return new RegExp(`^${regex}$`).test(lower);
4965
+ return candidates.some((candidate) => new RegExp(`^${regex}$`).test(candidate));
4603
4966
  }
4604
- return lower === pl;
4967
+ return candidates.includes(pl);
4605
4968
  });
4606
4969
  }
4607
4970
  return true;
4608
4971
  }
4972
+ function normalizeFocusCandidate(value) {
4973
+ return value.trim().replace(/\\/g, "/").replace(/\s*\/\s*/g, "/").replace(/\s*\.\s*/g, ".").toLowerCase();
4974
+ }
4975
+ function objectFocusCandidates(obj) {
4976
+ const treePath = getSceneObjectTreePath(obj);
4977
+ const candidates = [obj.id, obj.name, treePath.join("/"), treePath.join("."), obj.groupName ?? ""];
4978
+ return candidates.map(normalizeFocusCandidate).filter(Boolean);
4979
+ }
4609
4980
  function availableRenderableObjectNames(entries) {
4610
4981
  return entries.map((entry) => entry.source.name).join(", ") || "(none)";
4611
4982
  }
@@ -4630,7 +5001,7 @@ Available renderable objects: ${available}`;
4630
5001
  return "No visible renderable objects found.";
4631
5002
  }
4632
5003
  function createSession(code, opts) {
4633
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
5004
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
4634
5005
  const size = (opts == null ? void 0 : opts.size) ?? 1024;
4635
5006
  const pixelRatio = (opts == null ? void 0 : opts.pixelRatio) ?? 1;
4636
5007
  const debug = createCaptureDebugLogger(opts == null ? void 0 : opts.debug);
@@ -4643,6 +5014,12 @@ function createSession(code, opts) {
4643
5014
  });
4644
5015
  const r = getRenderer(size, pixelRatio);
4645
5016
  const renderStyle = resolveForgeRenderStyle(opts == null ? void 0 : opts.renderStyle);
5017
+ if (renderStyle === "matrix") {
5018
+ return {
5019
+ ok: false,
5020
+ error: "Matrix render style is only supported in the interactive viewport; CLI rendering does not support the glyph volume yet."
5021
+ };
5022
+ }
4646
5023
  const renderStylePreset = getRenderStylePreset(renderStyle);
4647
5024
  let requestedSceneState = null;
4648
5025
  try {
@@ -4779,7 +5156,9 @@ function createSession(code, opts) {
4779
5156
  const surfaceFieldScale = maxDim / 5;
4780
5157
  const scanProxyGrid = scanProxyGridForBounds(bb, opts == null ? void 0 : opts.scanGranularity);
4781
5158
  const fov = 45;
4782
- const distance = maxDim / (2 * Math.tan(fov * Math.PI / 360)) * 1.6;
5159
+ const distance = perspectiveCameraDistanceForBounds(bbox, [DEFAULT_FIXED_DIR.x, DEFAULT_FIXED_DIR.y, DEFAULT_FIXED_DIR.z], {
5160
+ fovDeg: fov
5161
+ });
4783
5162
  const cameraFov = ((_c = requestedSceneState == null ? void 0 : requestedSceneState.camera) == null ? void 0 : _c.fov) ?? ((_d = sceneConfig == null ? void 0 : sceneConfig.camera) == null ? void 0 : _d.fov) ?? fov;
4784
5163
  try {
4785
5164
  if (opts == null ? void 0 : opts.cameraToken) {
@@ -4791,7 +5170,10 @@ function createSession(code, opts) {
4791
5170
  }
4792
5171
  const parsed = parseCameraToken(opts.cameraToken);
4793
5172
  const dir = normalizeCameraDirection(parsed.dir);
4794
- const tokenDistance = parsed.distance ?? distance;
5173
+ const tokenDistance = parsed.distance ?? perspectiveCameraDistanceForBounds(bbox, dir, {
5174
+ fovDeg: cameraFov,
5175
+ up: [0, 0, 1]
5176
+ });
4795
5177
  requestedSceneState = mergeViewportRenderSceneStates(requestedSceneState, {
4796
5178
  camera: {
4797
5179
  projectionMode: "perspective",
@@ -4959,9 +5341,6 @@ function createSession(code, opts) {
4959
5341
  });
4960
5342
  }
4961
5343
  }
4962
- if (isScanRenderStyle) {
4963
- solid.renderOrder = 2;
4964
- }
4965
5344
  if (isScanRenderStyle && !scanProxy) {
4966
5345
  shell = new Mesh(
4967
5346
  geo.solid,
@@ -4976,7 +5355,6 @@ function createSession(code, opts) {
4976
5355
  })
4977
5356
  );
4978
5357
  shell.scale.setScalar(0.992);
4979
- shell.renderOrder = 1;
4980
5358
  shell.raycast = () => null;
4981
5359
  } else if (hasAuthoredTransparency && renderStylePreset.glassShell.enabled) {
4982
5360
  shell = new Mesh(
@@ -5004,7 +5382,6 @@ function createSession(code, opts) {
5004
5382
  clippingPlanes: applicableCutPlanes
5005
5383
  });
5006
5384
  wire = new LineSegments(geo.edges, wireMaterial);
5007
- if (isScanRenderStyle) wire.renderOrder = 3;
5008
5385
  sectionMesh = sweep ? buildSectionMeshPayload(obj.source.id, obj.shape, debug, objectLabel) : null;
5009
5386
  } else if (obj.sdf) {
5010
5387
  const sdfStart = performance.now();
@@ -5127,6 +5504,7 @@ function createSession(code, opts) {
5127
5504
  roughnessInspection: null,
5128
5505
  joints,
5129
5506
  jointCouplings,
5507
+ jointOverlayConfig: ((_p = result.viewConfig) == null ? void 0 : _p.jointOverlay) ?? DEFAULT_VIEW_CONFIG.jointOverlay,
5130
5508
  animationClips,
5131
5509
  defaultAnimation,
5132
5510
  selectedAnimation,
@@ -5273,6 +5651,7 @@ window.__forgeRender = async (code, opts) => {
5273
5651
  const depthRenders = {};
5274
5652
  const normalRenders = {};
5275
5653
  const zebraRenders = {};
5654
+ const rigRenders = {};
5276
5655
  const maskRenders = {};
5277
5656
  const connectivityRenders = {};
5278
5657
  const floatingRenders = {};
@@ -5285,6 +5664,7 @@ window.__forgeRender = async (code, opts) => {
5285
5664
  let connectivityReport = null;
5286
5665
  let floatingReport = null;
5287
5666
  let distanceReport = null;
5667
+ let rigReport = null;
5288
5668
  const comparisonViewStats = {};
5289
5669
  let comparisonPointCloud = null;
5290
5670
  let collisionReport = null;
@@ -5360,6 +5740,13 @@ window.__forgeRender = async (code, opts) => {
5360
5740
  zebraRenders[label] = renderCurrentZebra(session);
5361
5741
  await markChannelViewDone("zebra", label);
5362
5742
  }
5743
+ if (requestedChannels.has("rig")) {
5744
+ await markChannelViewStart("rig", label);
5745
+ const rig = renderCurrentRig(session);
5746
+ rigRenders[label] = rig.png;
5747
+ rigReport = rig.report;
5748
+ await markChannelViewDone("rig", label);
5749
+ }
5363
5750
  if (requestedChannels.has("roughness")) {
5364
5751
  await markChannelViewStart("roughness", label);
5365
5752
  const roughness = renderCurrentRoughness(session, opts == null ? void 0 : opts.roughness);
@@ -5455,6 +5842,12 @@ window.__forgeRender = async (code, opts) => {
5455
5842
  depth: depthRenders,
5456
5843
  normals: normalRenders,
5457
5844
  zebra: zebraRenders,
5845
+ rig: rigReport ? {
5846
+ ...rigReport,
5847
+ views: rigRenders
5848
+ } : {
5849
+ views: rigRenders
5850
+ },
5458
5851
  roughness: roughnessReport ? {
5459
5852
  ...roughnessReport,
5460
5853
  pointCloud: roughnessPointCloud,