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.
- package/LICENSE +6 -4
- package/README.md +8 -4
- package/dist/assets/{AdminPage-DramHHDf.js → AdminPage-CDyGUinA.js} +2 -2
- package/dist/assets/{BenchmarkPage-Bjgkh5m9.js → BenchmarkPage-DfPMY_-d.js} +4 -15
- package/dist/assets/{BlogPage-n_HGP3Qm.js → BlogPage-kF0fkdJT.js} +2 -2
- package/dist/assets/{DocsPage-WCIkPmzC.js → DocsPage-B954L3YN.js} +9 -3
- package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
- package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
- package/dist/assets/{EmbedViewer-DEZKqdfW.js → EmbedViewer-C77B-TrF.js} +3 -3
- package/dist/assets/{LandingPageProofDriven-CeRIctuj.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
- package/dist/assets/LegalPage-BRlScr9A.css +91 -0
- package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
- package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
- package/dist/assets/{PricingPage-rIRa8p4Y.js → PricingPage-zWXkvlwl.js} +19 -19
- package/dist/assets/{SettingsPage-BqCUvEXM.js → SettingsPage-Bz0of4KQ.js} +2 -2
- package/dist/assets/app-CE3sYcV7.css +3890 -0
- package/dist/assets/{app-BUZqJvSO.js → app-D3kDkggg.js} +2305 -960
- package/dist/assets/cli/{render-lhGxj50Y.js → render-DSY3mMQa.js} +423 -30
- package/dist/assets/{constructionHistoryWorker-ipD1jcIv.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
- package/dist/assets/{evalWorker-CHXSe_-u.js → evalWorker-CU0Ke6DP.js} +7799 -4163
- package/dist/assets/{forgecad_geometry-BVnIeXMG.js → forgecad_geometry-Dgceylq9.js} +43 -1
- package/dist/assets/{forgecad_geometry_bg-DufhhCBV.wasm → forgecad_geometry_bg-dD4RNQF1.wasm} +0 -0
- package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
- package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
- package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
- package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
- package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
- package/dist/assets/{manifold-D1LZIHqn.js → manifold-BRI5prcH.js} +1 -1
- package/dist/assets/{manifold-C2fwoTgd.js → manifold-C-3h2M7p.js} +2 -2
- package/dist/assets/{manifold-BTkzxi9V.js → manifold-DNkrUWpA.js} +1 -1
- package/dist/assets/{reportWorker-Cq1qGmg0.js → reportWorker-CdBz5bNg.js} +7537 -10856
- package/dist/assets/{scalar-sampling-budget-D9Qv_UlJ.js → scalar-sampling-budget-wJF98aY9.js} +6943 -4345
- package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
- package/dist/assets/{renderSceneState-Dr0xPq1A.js → targets-B9sGB5nB.js} +27 -1
- package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/ai-native-cad.md +50 -0
- package/dist/docs-raw/AI/usage.md +9 -17
- package/dist/docs-raw/CLI.md +71 -21
- package/dist/docs-raw/component-model.md +27 -11
- package/dist/docs-raw/generated/assembly.md +301 -212
- package/dist/docs-raw/generated/concepts.md +238 -240
- package/dist/docs-raw/generated/core.md +283 -6
- package/dist/docs-raw/generated/curves.md +274 -361
- package/dist/docs-raw/generated/lib.md +7 -1
- package/dist/docs-raw/generated/output.md +19 -4
- package/dist/docs-raw/generated/runtime-names.md +41 -0
- package/dist/docs-raw/generated/sdf.md +31 -0
- package/dist/docs-raw/generated/sheet-metal.md +9 -0
- package/dist/docs-raw/generated/sketch.md +44 -1
- package/dist/docs-raw/generated/viewport.md +14 -6
- package/dist/docs-raw/guides/coordinate-system.md +20 -16
- package/dist/docs-raw/guides/geometry-conventions.md +2 -2
- package/dist/docs-raw/guides/inspection-bundles.md +2 -1
- package/dist/docs-raw/guides/joint-design.md +24 -0
- package/dist/docs-raw/guides/positioning.md +13 -3
- package/dist/docs-raw/legal/privacy.md +63 -0
- package/dist/docs-raw/legal/software-license.md +55 -0
- package/dist/docs-raw/legal/terms.md +87 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +3 -3
- package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
- package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
- package/dist/docs-raw/skills/forgecad-lld.md +1 -1
- package/dist/docs-raw/skills/forgecad-make-a-model.md +4 -4
- package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
- package/dist/docs-raw/skills/forgecad-project.md +1 -1
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +4 -4
- package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
- package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad.md +4 -3
- package/dist/index.html +40 -12
- package/dist/llms.txt +8 -0
- package/dist/site.webmanifest +1 -1
- package/dist/sitemap.xml +49 -13
- package/dist-cli/{check-compiler-LOXCPEOI.js → check-compiler-SDX5QIXI.js} +1 -2
- package/dist-cli/{check-query-propagation-BAKNVWXR.js → check-query-propagation-EAYEFT77.js} +1 -2
- package/dist-cli/{chunk-RY43WF46.js → chunk-N4O47JLF.js} +13772 -9938
- package/dist-cli/forgecad.js +2387 -899
- package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
- package/dist-skill/CONTEXT.md +1120 -724
- package/dist-skill/SKILL.md +3 -2
- package/dist-skill/docs/API/core/concepts.md +64 -1
- package/dist-skill/docs/CLI.md +71 -21
- package/dist-skill/docs/generated/assembly.md +277 -229
- package/dist-skill/docs/generated/core.md +283 -6
- package/dist-skill/docs/generated/curves.md +272 -362
- package/dist-skill/docs/generated/lib.md +7 -1
- package/dist-skill/docs/generated/output.md +19 -4
- package/dist-skill/docs/generated/runtime-names.md +41 -0
- package/dist-skill/docs/generated/sdf.md +31 -0
- package/dist-skill/docs/generated/sheet-metal.md +9 -0
- package/dist-skill/docs/generated/sketch.md +44 -2
- package/dist-skill/docs/generated/viewport.md +5 -90
- package/dist-skill/docs/guides/coordinate-system.md +20 -16
- package/dist-skill/docs/guides/geometry-conventions.md +2 -2
- package/dist-skill/docs/guides/inspection-bundles.md +2 -1
- package/dist-skill/docs/guides/joint-design.md +24 -0
- package/dist-skill/docs/guides/positioning.md +13 -3
- package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +2 -2
- package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
- package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +3 -3
- package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +3 -3
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
- package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
- package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
- package/examples/api/assembly-kinematics-limb.forge.js +116 -0
- package/examples/api/connector-frame-rig-chain.forge.js +102 -0
- package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
- package/examples/api/exact-surface-studio.forge.js +6 -8
- package/examples/api/helix-basics.forge.js +6 -6
- package/examples/api/lean-foundations/README.md +12 -0
- package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
- package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
- package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
- package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
- package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
- package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
- package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
- package/examples/api/route3d-elbow.forge.js +68 -0
- package/examples/api/transition-curves.forge.js +44 -15
- package/examples/api/y-blend-corner-showcase.forge.js +0 -2
- package/examples/generative/coral-vase.forge.js +1 -1
- package/examples/nurbs-tube.forge.js +1 -1
- package/package.json +14 -18
- package/dist/assets/EditorApp-CP9Za6tm.js +0 -13630
- package/dist/assets/app-CsHnaBWt.css +0 -1789
- package/dist/docs-raw/API/README.md +0 -16
- package/dist/docs-raw/API/core/concepts.md +0 -118
- package/dist/docs-raw/INDEX.md +0 -138
- package/dist/docs-raw/RELEASING.md +0 -87
- package/dist/docs-raw/agent-native-api.md +0 -27
- package/dist/docs-raw/beta-deployment.md +0 -304
- package/dist/docs-raw/beta-operations.md +0 -325
- package/dist/docs-raw/blueprint-first.md +0 -145
- package/dist/docs-raw/cli-monetization.md +0 -112
- package/dist/docs-raw/coding-best-practices.md +0 -120
- package/dist/docs-raw/coding.md +0 -340
- package/dist/docs-raw/deployment.md +0 -374
- package/dist/docs-raw/guides/skill-maintenance.md +0 -161
- package/dist/docs-raw/guides/surface-members.md +0 -82
- package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
- package/dist/docs-raw/internals/compiler.md +0 -307
- package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
- package/dist/docs-raw/internals/constraint-solver.md +0 -176
- package/dist/docs-raw/internals/shape-from-slices.md +0 -152
- package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
- package/dist/docs-raw/platform/admin.md +0 -45
- package/dist/docs-raw/platform/architecture.md +0 -82
- package/dist/docs-raw/platform/auth.md +0 -139
- package/dist/docs-raw/platform/email.md +0 -67
- package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
- package/dist/docs-raw/platform/observability.md +0 -197
- package/dist/docs-raw/platform/projects.md +0 -111
- package/dist/docs-raw/platform/sharing.md +0 -90
- package/dist/docs-raw/product/README.md +0 -39
- package/dist/docs-raw/product/api-as-product-language.md +0 -13
- package/dist/docs-raw/product/business-model.md +0 -15
- package/dist/docs-raw/product/competitive-positioning.md +0 -17
- package/dist/docs-raw/product/creative-manufacturing.md +0 -15
- package/dist/docs-raw/product/founder-story.md +0 -11
- package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
- package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
- package/dist/docs-raw/product/product-loop.md +0 -17
- package/dist/docs-raw/product/strategic-decisions.md +0 -22
- package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
- package/dist/docs-raw/product/user-segments.md +0 -15
- package/dist/docs-raw/product/vision.md +0 -26
- package/dist/docs-raw/rl-environments.md +0 -508
- package/dist/docs-raw/runbook.md +0 -611
- package/dist-cli/check-compiler-LOXCPEOI.js.map +0 -1
- package/dist-cli/check-query-propagation-BAKNVWXR.js.map +0 -1
- package/dist-cli/chunk-RY43WF46.js.map +0 -1
- package/dist-cli/forgecad.js.map +0 -1
- package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
- package/dist-cli/solver-46FFSK2U.js.map +0 -1
- package/dist-skill/SKILL-dev.md +0 -145
- package/dist-skill/docs-dev/API/core/concepts.md +0 -118
- package/dist-skill/docs-dev/CLI.md +0 -647
- package/dist-skill/docs-dev/agent-native-api.md +0 -27
- package/dist-skill/docs-dev/blueprint-first.md +0 -145
- package/dist-skill/docs-dev/coding-best-practices.md +0 -120
- package/dist-skill/docs-dev/coding.md +0 -340
- package/dist-skill/docs-dev/component-model.md +0 -164
- package/dist-skill/docs-dev/generated/assembly.md +0 -794
- package/dist-skill/docs-dev/generated/core.md +0 -2117
- package/dist-skill/docs-dev/generated/curves.md +0 -2583
- package/dist-skill/docs-dev/generated/lib.md +0 -169
- package/dist-skill/docs-dev/generated/output.md +0 -247
- package/dist-skill/docs-dev/generated/sdf.md +0 -446
- package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
- package/dist-skill/docs-dev/generated/sketch.md +0 -1811
- package/dist-skill/docs-dev/generated/viewport.md +0 -585
- package/dist-skill/docs-dev/generated/wood.md +0 -108
- package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
- package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
- package/dist-skill/docs-dev/guides/joint-design.md +0 -78
- package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs-dev/guides/positioning.md +0 -161
- package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
- package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
- package/dist-skill/docs-dev/internals/compiler.md +0 -307
- package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
- package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
- package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
- 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,
|
|
5
|
-
import { m as mergeViewportRenderSceneStates, p as parseRenderSceneCliSpec } from "../
|
|
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
|
|
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 ??
|
|
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
|
|
4949
|
+
const candidates = objectFocusCandidates(obj);
|
|
4587
4950
|
return focus.some((p) => {
|
|
4588
|
-
const pl = p
|
|
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(
|
|
4954
|
+
return candidates.some((candidate) => new RegExp(`^${regex}$`).test(candidate));
|
|
4592
4955
|
}
|
|
4593
|
-
return
|
|
4956
|
+
return candidates.includes(pl);
|
|
4594
4957
|
});
|
|
4595
4958
|
}
|
|
4596
4959
|
if (Array.isArray(hide)) {
|
|
4597
|
-
const
|
|
4960
|
+
const candidates = objectFocusCandidates(obj);
|
|
4598
4961
|
return !hide.some((p) => {
|
|
4599
|
-
const pl = p
|
|
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(
|
|
4965
|
+
return candidates.some((candidate) => new RegExp(`^${regex}$`).test(candidate));
|
|
4603
4966
|
}
|
|
4604
|
-
return
|
|
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 =
|
|
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 ??
|
|
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,
|