forgecad 0.9.7 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/assets/{AdminPage-DX0mpSZT.js → AdminPage-CNEvQM7c.js} +1 -1
- package/dist/assets/{BlogPage-CI_P0_Pf.js → BlogPage-Cc41PP4d.js} +1 -1
- package/dist/assets/{DocsPage-DLhIIZyJ.js → DocsPage-9U1hGjrg.js} +2 -2
- package/dist/assets/{EditorApp-DfFT2Dn8.css → EditorApp-D11wL4Qn.css} +51 -0
- package/dist/assets/{EditorApp-BujZvuwX.js → EditorApp-DnddQvBt.js} +151 -9
- package/dist/assets/{EmbedViewer-0S0qXKog.js → EmbedViewer-B2lhWTcd.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-O_yMtAri.js → LandingPageProofDriven-CFet-l3o.js} +1 -1
- package/dist/assets/{PricingPage-DGkX3Ahr.js → PricingPage-CPm8mQx3.js} +1 -1
- package/dist/assets/{SettingsPage-DBsqTB_y.js → SettingsPage-BarZonVZ.js} +1 -1
- package/dist/assets/__vite-browser-external-Dhvy_jtL.js +4 -0
- package/dist/assets/{app-BE2nD6Yz.js → app-BjSEB4sY.js} +1006 -526
- package/dist/assets/cli/{render-iP9qh475.js → render-CXVrHY8q.js} +647 -481
- package/dist/assets/constructionHistoryWorker-z9_LGiRd.js +42984 -0
- package/dist/assets/{evalWorker-Ds5U4xtN.js → evalWorker-CtO7GsJR.js} +42 -9
- package/dist/assets/{inspectWorker-Dll4eVyD.js → inspectWorker-BZ2CkQZr.js} +785 -111
- package/dist/assets/{manifold-DjYsd7A_.js → manifold-BRdhoQy5.js} +2 -2
- package/dist/assets/{manifold-sJ-axdXM.js → manifold-BVi4_OeB.js} +1 -1
- package/dist/assets/manifold-Cp_dCC7i.js +3018 -0
- package/dist/assets/{manifold-Bk26ViCr.js → manifold-DAzn2Fsa.js} +1 -1
- package/dist/assets/{renderSceneState-Bngp5MrQ.js → renderSceneState-CWO8rHlt.js} +1 -1
- package/dist/assets/{reportWorker-CU8RZ4O0.js → reportWorker-Bz9tGiHb.js} +42 -9
- package/dist/assets/{sectionPlaneMath-BdTjyVfs.js → scalar-sampling-budget-Bmewod18.js} +1339 -215
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +1 -1
- package/dist/docs-raw/CLI.md +10 -10
- package/dist/docs-raw/coding-best-practices.md +1 -1
- package/dist/docs-raw/guides/inspection-bundles.md +77 -19
- package/dist/docs-raw/guides/skill-maintenance.md +1 -1
- package/dist/docs-raw/runbook.md +2 -2
- package/dist/docs-raw/skills/forgecad-make-a-model.md +11 -0
- package/dist/docs-raw/skills/forgecad-render-inspect.md +12 -6
- package/dist/docs-raw/skills/index.md +1 -1
- package/dist/index.html +1 -1
- package/dist/sitemap.xml +6 -6
- package/dist-cli/forgecad.js +596 -354
- package/dist-cli/forgecad.js.map +1 -1
- package/dist-skill/CONTEXT.md +77 -19
- package/dist-skill/docs/CLI.md +10 -10
- package/dist-skill/docs/guides/inspection-bundles.md +77 -19
- package/dist-skill/docs-dev/CLI.md +10 -10
- package/dist-skill/docs-dev/coding-best-practices.md +1 -1
- package/dist-skill/docs-dev/guides/inspection-bundles.md +77 -19
- package/dist-skill/docs-dev/guides/skill-maintenance.md +1 -1
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +11 -0
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +12 -6
- package/package.json +6 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/EditorApp-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/EditorApp-D11wL4Qn.css","assets/landing-proof-driven-B7_RpP79.css","assets/PricingPage-BMedqFef.css"])))=>i.map(i=>d[i]);
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
var _a2;
|
|
6
6
|
import { c as create, j as jsxRuntimeExports, r as reactExports, a as createWithEqualityFn, R as React, T as Tb, s as schedulerExports, b as clientExports, d as reactDomExports, u as useParams, e as useSearchParams, f as useNavigate, L as Link, B as BrowserRouter, g as Routes, h as Route, N as Navigate } from "./vendor-react-Da3A2QmU.js";
|
|
7
|
-
import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as DEFAULT_ACTIVE_BACKEND, az as isConstraintSketch, aA as updateConstraintValue, aB as getShapeCompilePlan, aC as resolveForgeRenderStyle, aD as publishSolverWasmRunDebug, aE as resolveForgeQualityPreset, aF as resolveImportPath, aG as BufferGeometry, aH as LineBasicMaterial, aI as Line$1, aJ as LineDashedMaterial, aK as DepthStencilFormat, aL as UnsignedInt248Type, aM as MeshNormalMaterial, aN as NearestFilter, aO as BasicDepthPacking, aP as EventDispatcher$1, aQ as NoColorSpace, aR as FrontSide, aS as Material, aT as AlwaysDepth, aU as BufferAttribute, aV as CanvasTexture, aW as Object3D, aX as FogExp2, aY as Fog, aZ as AmbientLight, a_ as HemisphereLight, a$ as SpotLight, b0 as PointLight, b1 as DirectionalLight, b2 as analyzeCollisionIntersections, b3 as shapeToGeometry, b4 as buildShapeFromCompilePlan, b5 as sketchToSvg, b6 as sketchToDxf, b7 as runScript, b8 as MeshPhysicalMaterial, b9 as LineSegments, ba as
|
|
7
|
+
import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as DEFAULT_ACTIVE_BACKEND, az as isConstraintSketch, aA as updateConstraintValue, aB as getShapeCompilePlan, aC as resolveForgeRenderStyle, aD as publishSolverWasmRunDebug, aE as resolveForgeQualityPreset, aF as resolveImportPath, aG as BufferGeometry, aH as LineBasicMaterial, aI as Line$1, aJ as LineDashedMaterial, aK as DepthStencilFormat, aL as UnsignedInt248Type, aM as MeshNormalMaterial, aN as NearestFilter, aO as BasicDepthPacking, aP as EventDispatcher$1, aQ as NoColorSpace, aR as FrontSide, aS as Material, aT as AlwaysDepth, aU as BufferAttribute, aV as CanvasTexture, aW as Object3D, aX as FogExp2, aY as Fog, aZ as AmbientLight, a_ as HemisphereLight, a$ as SpotLight, b0 as PointLight, b1 as DirectionalLight, b2 as analyzeCollisionIntersections, b3 as shapeToGeometry, b4 as buildShapeFromCompilePlan, b5 as sketchToSvg, b6 as sketchToDxf, b7 as runScript, b8 as MeshPhysicalMaterial, b9 as LineSegments, ba as geometryWithVisibleVertexColors, bb as getRenderStylePreset, bc as AdditiveBlending, bd as ZEBRA_STRIPE_SOFTNESS, be as ZEBRA_STRIPE_SCALE, bf as ZEBRA_LIGHT_COLOR, bg as ZEBRA_DARK_COLOR, bh as ZEBRA_ACCENT_COLOR, bi as ZEBRA_STRIPE_FRAGMENT_SHADER, bj as ZEBRA_STRIPE_VERTEX_SHADER, bk as SURFACE_FIELD_FRAGMENT_SHADER, bl as SURFACE_FIELD_VERTEX_SHADER, bm as CatmullRomCurve3, bn as TubeGeometry, bo as ROUGHNESS_COLORS, bp as DEFAULT_ROUGHNESS_INSPECTION_OPTIONS, bq as DEFAULT_THICKNESS_INSPECTION_OPTIONS, br as THICKNESS_COLORS, bs as MeshStandardMaterial, bt as compileSdfNode3, bu as buildSdfRaymarchFragmentShader, bv as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bw as Shape, bx as ShapeGeometry, by as ShaderLib, bz as CylinderGeometry, bA as parseViewportCameraState, bB as createResolvedExplodeConfig, bC as explodeBoundsCenter, bD as explodeMergeBounds, bE as resolveExplodeDirective, bF as computeExplodeMotion, bG as getSketchWorldMatrix, bH as explodeAdd, bI as hasExplodeOverride, bJ as resolveExplodeLocalFanDirection, bK as explodeMul, bL as explodeLeafFanStage, bM as normalizeCutPlane, bN as toClippingPlane, bO as findJointAnimationClip, bP as resolveJointAnimation, bQ as resolveJointViewValues, bR as getShapePorts, bS as getShapeUsedPorts, bT as DEFAULT_VIEW_CONFIG, bU as getKernelFaceNameForTriangle, bV as resolveScalarSceneSampleBudget, bW as initKernel, bX as initSolverWasm } from "./scalar-sampling-budget-Bmewod18.js";
|
|
8
8
|
function getCsrfToken() {
|
|
9
9
|
const match = document.cookie.match(/(?:^|;\s*)fc-csrf-token=([^;]+)/);
|
|
10
10
|
return match == null ? void 0 : match[1];
|
|
@@ -14909,24 +14909,24 @@ const formatAnimationSpeed = (speed) => {
|
|
|
14909
14909
|
const safeSpeed = clampAnimationSpeed(speed);
|
|
14910
14910
|
return safeSpeed < 0.1 ? safeSpeed.toFixed(3) : safeSpeed.toFixed(2);
|
|
14911
14911
|
};
|
|
14912
|
-
const fmt$
|
|
14912
|
+
const fmt$2 = (n) => (Math.round(n * 1e3) / 1e3).toString();
|
|
14913
14913
|
function planLabel(plan) {
|
|
14914
14914
|
var _a3;
|
|
14915
14915
|
switch (plan.kind) {
|
|
14916
14916
|
case "box":
|
|
14917
|
-
return `Box ${fmt$
|
|
14917
|
+
return `Box ${fmt$2(plan.x)} × ${fmt$2(plan.y)} × ${fmt$2(plan.z)}`;
|
|
14918
14918
|
case "cylinder": {
|
|
14919
|
-
const rLabel = plan.radiusTop !== void 0 && plan.radiusTop !== plan.radius ? `r=${fmt$
|
|
14920
|
-
return `Cylinder ${rLabel} h=${fmt$
|
|
14919
|
+
const rLabel = plan.radiusTop !== void 0 && plan.radiusTop !== plan.radius ? `r=${fmt$2(plan.radius)}→${fmt$2(plan.radiusTop)}` : `r=${fmt$2(plan.radius)}`;
|
|
14920
|
+
return `Cylinder ${rLabel} h=${fmt$2(plan.height)}`;
|
|
14921
14921
|
}
|
|
14922
14922
|
case "sphere":
|
|
14923
|
-
return `Sphere r=${fmt$
|
|
14923
|
+
return `Sphere r=${fmt$2(plan.radius)}`;
|
|
14924
14924
|
case "torus":
|
|
14925
|
-
return `Torus R=${fmt$
|
|
14925
|
+
return `Torus R=${fmt$2(plan.majorRadius)} r=${fmt$2(plan.minorRadius)}`;
|
|
14926
14926
|
case "extrude":
|
|
14927
|
-
return `Extrude h=${fmt$
|
|
14927
|
+
return `Extrude h=${fmt$2(plan.height)}`;
|
|
14928
14928
|
case "revolve":
|
|
14929
|
-
return `Revolve ${fmt$
|
|
14929
|
+
return `Revolve ${fmt$2(plan.degrees)}°`;
|
|
14930
14930
|
case "loft":
|
|
14931
14931
|
return `Loft (${plan.profiles.length} profiles)`;
|
|
14932
14932
|
case "sweep":
|
|
@@ -14940,17 +14940,17 @@ function planLabel(plan) {
|
|
|
14940
14940
|
case "queryOwner":
|
|
14941
14941
|
return planLabel(plan.base);
|
|
14942
14942
|
case "fillet":
|
|
14943
|
-
return `Fillet r=${fmt$
|
|
14943
|
+
return `Fillet r=${fmt$2(plan.radius)}`;
|
|
14944
14944
|
case "filletEdges":
|
|
14945
|
-
return `Fillet r=${fmt$
|
|
14945
|
+
return `Fillet r=${fmt$2(plan.radius)}`;
|
|
14946
14946
|
case "cornerYBlend":
|
|
14947
|
-
return `Y-corner blend r=${fmt$
|
|
14947
|
+
return `Y-corner blend r=${fmt$2(plan.radius)}`;
|
|
14948
14948
|
case "chamfer":
|
|
14949
|
-
return `Chamfer ${fmt$
|
|
14949
|
+
return `Chamfer ${fmt$2(plan.size)}`;
|
|
14950
14950
|
case "chamferEdges":
|
|
14951
|
-
return `Chamfer ${fmt$
|
|
14951
|
+
return `Chamfer ${fmt$2(plan.size)}`;
|
|
14952
14952
|
case "shell":
|
|
14953
|
-
return `Shell t=${fmt$
|
|
14953
|
+
return `Shell t=${fmt$2(plan.thickness)}`;
|
|
14954
14954
|
case "hole":
|
|
14955
14955
|
return "Hole";
|
|
14956
14956
|
case "cut":
|
|
@@ -14960,9 +14960,9 @@ function planLabel(plan) {
|
|
|
14960
14960
|
case "sheetMetal":
|
|
14961
14961
|
return "Sheet Metal";
|
|
14962
14962
|
case "draft":
|
|
14963
|
-
return `Draft ${fmt$
|
|
14963
|
+
return `Draft ${fmt$2(plan.angleDeg)}°`;
|
|
14964
14964
|
case "offsetSolid":
|
|
14965
|
-
return `Offset ${fmt$
|
|
14965
|
+
return `Offset ${fmt$2(plan.thickness)}`;
|
|
14966
14966
|
case "importedMesh":
|
|
14967
14967
|
return `Import ${plan.filePath.split("/").pop() ?? "mesh"}`;
|
|
14968
14968
|
case "sdf":
|
|
@@ -14978,9 +14978,9 @@ function planLabel(plan) {
|
|
|
14978
14978
|
case "surfaceSew":
|
|
14979
14979
|
return `Surface Sew (${plan.shapes.length} sheets)`;
|
|
14980
14980
|
case "surfaceExtend":
|
|
14981
|
-
return `Surface Extend ${fmt$
|
|
14981
|
+
return `Surface Extend ${fmt$2(plan.length)}`;
|
|
14982
14982
|
case "surfaceThicken":
|
|
14983
|
-
return `Thicken ${fmt$
|
|
14983
|
+
return `Thicken ${fmt$2(plan.thickness)}`;
|
|
14984
14984
|
case "importedStep":
|
|
14985
14985
|
return `STEP Import (${plan.filePath})`;
|
|
14986
14986
|
}
|
|
@@ -15021,9 +15021,6 @@ function stableJsonStringify(value) {
|
|
|
15021
15021
|
function shapeCompilePlanCacheKey(plan) {
|
|
15022
15022
|
return `${SHAPE_COMPILE_PLAN_CACHE_KEY_VERSION}:${stableJsonStringify(plan)}`;
|
|
15023
15023
|
}
|
|
15024
|
-
function constructionStepGeometryCacheKey(step) {
|
|
15025
|
-
return step.cumulativePlanCacheKey;
|
|
15026
|
-
}
|
|
15027
15024
|
function makeConstructionStep(step) {
|
|
15028
15025
|
const planCacheKey = shapeCompilePlanCacheKey(step.plan);
|
|
15029
15026
|
return {
|
|
@@ -15849,13 +15846,11 @@ function triggerDownload(blob, filename) {
|
|
|
15849
15846
|
URL.revokeObjectURL(url2);
|
|
15850
15847
|
}
|
|
15851
15848
|
const INIT_TIMEOUT_MS = 12e4;
|
|
15852
|
-
const RUN_TIMEOUT_MS = 3e4;
|
|
15853
|
-
const EXPORT_TIMEOUT_MS = 3e5;
|
|
15854
15849
|
const CRASH_COOLDOWN_MS = 2e3;
|
|
15855
15850
|
class EvalWorkerClient {
|
|
15856
15851
|
constructor(workerFactory = () => new Worker(new URL(
|
|
15857
15852
|
/* @vite-ignore */
|
|
15858
|
-
"/assets/evalWorker-
|
|
15853
|
+
"/assets/evalWorker-CtO7GsJR.js",
|
|
15859
15854
|
import.meta.url
|
|
15860
15855
|
), { type: "module" })) {
|
|
15861
15856
|
__publicField(this, "worker", null);
|
|
@@ -15867,8 +15862,7 @@ class EvalWorkerClient {
|
|
|
15867
15862
|
__publicField(this, "pendingFaceInfo", /* @__PURE__ */ new Map());
|
|
15868
15863
|
__publicField(this, "pendingExportExact", /* @__PURE__ */ new Map());
|
|
15869
15864
|
__publicField(this, "pendingExportMesh", /* @__PURE__ */ new Map());
|
|
15870
|
-
__publicField(this, "
|
|
15871
|
-
__publicField(this, "exportTimeoutId", null);
|
|
15865
|
+
__publicField(this, "initTimeoutId", null);
|
|
15872
15866
|
/** Timestamp of the last worker crash — used to enforce a cooldown before respawning. */
|
|
15873
15867
|
__publicField(this, "lastCrashTime", 0);
|
|
15874
15868
|
__publicField(this, "activeRunSeq", null);
|
|
@@ -15894,16 +15888,12 @@ class EvalWorkerClient {
|
|
|
15894
15888
|
const { data } = event;
|
|
15895
15889
|
if (data.type === "progress") {
|
|
15896
15890
|
if (data.payload.phase === "export-evaluating" || data.payload.phase === "export-writing") {
|
|
15897
|
-
this.resetExportTimeout();
|
|
15898
15891
|
return;
|
|
15899
15892
|
}
|
|
15900
15893
|
if (data.payload.seq !== this.activeRunSeq) return;
|
|
15901
15894
|
(_a3 = this.onProgress) == null ? void 0 : _a3.call(this, data.payload.phase);
|
|
15902
15895
|
if (data.payload.phase === "evaluating") {
|
|
15903
|
-
this.
|
|
15904
|
-
this.runTimeoutId = setTimeout(() => {
|
|
15905
|
-
this.killWorker(`Script execution timed out after ${RUN_TIMEOUT_MS / 1e3}s`);
|
|
15906
|
-
}, RUN_TIMEOUT_MS);
|
|
15896
|
+
this.clearInitTimeout();
|
|
15907
15897
|
}
|
|
15908
15898
|
return;
|
|
15909
15899
|
}
|
|
@@ -15915,7 +15905,7 @@ class EvalWorkerClient {
|
|
|
15915
15905
|
if (data.type === "run-success" || data.type === "run-error") {
|
|
15916
15906
|
const req = this.pendingRuns.get(data.payload.seq);
|
|
15917
15907
|
if (!req) return;
|
|
15918
|
-
this.
|
|
15908
|
+
this.clearInitTimeout();
|
|
15919
15909
|
this.clearActiveRun(data.payload.seq);
|
|
15920
15910
|
this.pendingRuns.delete(data.payload.seq);
|
|
15921
15911
|
if (data.type === "run-success") {
|
|
@@ -15942,7 +15932,6 @@ class EvalWorkerClient {
|
|
|
15942
15932
|
return;
|
|
15943
15933
|
}
|
|
15944
15934
|
if (data.type === "export-exact-success" || data.type === "export-exact-error") {
|
|
15945
|
-
this.clearExportTimeout();
|
|
15946
15935
|
const req = this.pendingExportExact.get(data.payload.reqId);
|
|
15947
15936
|
if (!req) return;
|
|
15948
15937
|
this.pendingExportExact.delete(data.payload.reqId);
|
|
@@ -15954,7 +15943,6 @@ class EvalWorkerClient {
|
|
|
15954
15943
|
return;
|
|
15955
15944
|
}
|
|
15956
15945
|
if (data.type === "export-mesh-success" || data.type === "export-mesh-error") {
|
|
15957
|
-
this.clearExportTimeout();
|
|
15958
15946
|
const req = this.pendingExportMesh.get(data.payload.reqId);
|
|
15959
15947
|
if (!req) return;
|
|
15960
15948
|
this.pendingExportMesh.delete(data.payload.reqId);
|
|
@@ -15966,8 +15954,7 @@ class EvalWorkerClient {
|
|
|
15966
15954
|
}
|
|
15967
15955
|
};
|
|
15968
15956
|
this.worker.onerror = (event) => {
|
|
15969
|
-
this.
|
|
15970
|
-
this.clearExportTimeout();
|
|
15957
|
+
this.clearInitTimeout();
|
|
15971
15958
|
this.clearActiveRun();
|
|
15972
15959
|
this.lastCrashTime = Date.now();
|
|
15973
15960
|
const err = new Error(event.message || "Eval worker crashed");
|
|
@@ -15985,28 +15972,12 @@ class EvalWorkerClient {
|
|
|
15985
15972
|
};
|
|
15986
15973
|
return this.worker;
|
|
15987
15974
|
}
|
|
15988
|
-
|
|
15989
|
-
if (this.
|
|
15990
|
-
clearTimeout(this.
|
|
15991
|
-
this.
|
|
15992
|
-
}
|
|
15993
|
-
}
|
|
15994
|
-
clearExportTimeout() {
|
|
15995
|
-
if (this.exportTimeoutId !== null) {
|
|
15996
|
-
clearTimeout(this.exportTimeoutId);
|
|
15997
|
-
this.exportTimeoutId = null;
|
|
15975
|
+
clearInitTimeout() {
|
|
15976
|
+
if (this.initTimeoutId !== null) {
|
|
15977
|
+
clearTimeout(this.initTimeoutId);
|
|
15978
|
+
this.initTimeoutId = null;
|
|
15998
15979
|
}
|
|
15999
15980
|
}
|
|
16000
|
-
resetExportTimeout() {
|
|
16001
|
-
this.clearExportTimeout();
|
|
16002
|
-
this.exportTimeoutId = setTimeout(() => {
|
|
16003
|
-
const err = new Error(`Export timed out after ${EXPORT_TIMEOUT_MS / 1e3}s`);
|
|
16004
|
-
for (const req of this.pendingExportExact.values()) req.reject(err);
|
|
16005
|
-
for (const req of this.pendingExportMesh.values()) req.reject(err);
|
|
16006
|
-
this.pendingExportExact.clear();
|
|
16007
|
-
this.pendingExportMesh.clear();
|
|
16008
|
-
}, EXPORT_TIMEOUT_MS);
|
|
16009
|
-
}
|
|
16010
15981
|
clearActiveRun(seq) {
|
|
16011
15982
|
if (seq !== void 0 && this.activeRunSeq !== seq) return;
|
|
16012
15983
|
this.activeRunSeq = null;
|
|
@@ -16020,8 +15991,7 @@ class EvalWorkerClient {
|
|
|
16020
15991
|
*/
|
|
16021
15992
|
replaceWorkerForSupersedingRun() {
|
|
16022
15993
|
console.info("[evalWorkerClient] Superseded eval run — replacing worker");
|
|
16023
|
-
this.
|
|
16024
|
-
this.clearExportTimeout();
|
|
15994
|
+
this.clearInitTimeout();
|
|
16025
15995
|
this.clearActiveRun();
|
|
16026
15996
|
this.workerWasmHeap = null;
|
|
16027
15997
|
if (this.worker) {
|
|
@@ -16045,8 +16015,7 @@ class EvalWorkerClient {
|
|
|
16045
16015
|
*/
|
|
16046
16016
|
killWorker(reason, failureMessage = reason) {
|
|
16047
16017
|
console.warn(`[evalWorkerClient] ${reason} — terminating worker`);
|
|
16048
|
-
this.
|
|
16049
|
-
this.clearExportTimeout();
|
|
16018
|
+
this.clearInitTimeout();
|
|
16050
16019
|
this.clearActiveRun();
|
|
16051
16020
|
this.lastCrashTime = Date.now();
|
|
16052
16021
|
this.workerWasmHeap = null;
|
|
@@ -16068,7 +16037,7 @@ class EvalWorkerClient {
|
|
|
16068
16037
|
/** Post a run request to the worker and arm the init timeout. */
|
|
16069
16038
|
startRun(seq, options) {
|
|
16070
16039
|
this.activeRunSeq = seq;
|
|
16071
|
-
this.
|
|
16040
|
+
this.initTimeoutId = setTimeout(() => {
|
|
16072
16041
|
this.killWorker(`Kernel initialization timed out after ${INIT_TIMEOUT_MS / 1e3}s`);
|
|
16073
16042
|
}, INIT_TIMEOUT_MS);
|
|
16074
16043
|
const request = { type: "run", payload: { seq, ...options } };
|
|
@@ -16080,7 +16049,7 @@ class EvalWorkerClient {
|
|
|
16080
16049
|
* block the newer request. Only the latest run's result is resolved.
|
|
16081
16050
|
*
|
|
16082
16051
|
* A generous init timeout (120s) covers WASM loading. Once the worker signals
|
|
16083
|
-
* 'evaluating',
|
|
16052
|
+
* 'evaluating', the run is allowed to continue until it completes or is superseded.
|
|
16084
16053
|
*/
|
|
16085
16054
|
run(options) {
|
|
16086
16055
|
if (this.shouldReplaceWorkerForSupersedingRun()) {
|
|
@@ -16088,7 +16057,7 @@ class EvalWorkerClient {
|
|
|
16088
16057
|
} else {
|
|
16089
16058
|
for (const req of this.pendingRuns.values()) req.reject(new Error("cancelled"));
|
|
16090
16059
|
this.pendingRuns.clear();
|
|
16091
|
-
this.
|
|
16060
|
+
this.clearInitTimeout();
|
|
16092
16061
|
}
|
|
16093
16062
|
const seq = ++this.seq;
|
|
16094
16063
|
const msSinceCrash = Date.now() - this.lastCrashTime;
|
|
@@ -16122,7 +16091,6 @@ class EvalWorkerClient {
|
|
|
16122
16091
|
/**
|
|
16123
16092
|
* Export exact geometry (STEP/BREP) using live OCCT shapes in the worker.
|
|
16124
16093
|
* Includes script context so the worker can re-evaluate if needed.
|
|
16125
|
-
* Uses a generous 5-minute timeout that resets on each progress phase.
|
|
16126
16094
|
*/
|
|
16127
16095
|
exportExact(format, scriptContext) {
|
|
16128
16096
|
const reqId = ++this.exportExactReqId;
|
|
@@ -16134,7 +16102,6 @@ class EvalWorkerClient {
|
|
|
16134
16102
|
},
|
|
16135
16103
|
reject
|
|
16136
16104
|
});
|
|
16137
|
-
this.resetExportTimeout();
|
|
16138
16105
|
const request = {
|
|
16139
16106
|
type: "export-exact",
|
|
16140
16107
|
payload: { reqId, format, ...scriptContext }
|
|
@@ -16156,7 +16123,6 @@ class EvalWorkerClient {
|
|
|
16156
16123
|
},
|
|
16157
16124
|
reject
|
|
16158
16125
|
});
|
|
16159
|
-
this.resetExportTimeout();
|
|
16160
16126
|
const request = {
|
|
16161
16127
|
type: "export-mesh",
|
|
16162
16128
|
payload: { reqId, format, ...scriptContext }
|
|
@@ -16170,8 +16136,7 @@ class EvalWorkerClient {
|
|
|
16170
16136
|
this.worker.postMessage({ type: "set-project", payload: { projectId } });
|
|
16171
16137
|
}
|
|
16172
16138
|
terminate() {
|
|
16173
|
-
this.
|
|
16174
|
-
this.clearExportTimeout();
|
|
16139
|
+
this.clearInitTimeout();
|
|
16175
16140
|
this.clearActiveRun();
|
|
16176
16141
|
this.workerWasmHeap = null;
|
|
16177
16142
|
this.lastWorkerFailure = null;
|
|
@@ -17323,11 +17288,48 @@ const VIEW_PREFERENCES_KEY = "fc-view-preferences-v1";
|
|
|
17323
17288
|
const INSPECT_POINT_SAMPLE_COUNT_MIN = 100;
|
|
17324
17289
|
const INSPECT_POINT_SAMPLE_COUNT_MAX = 1e4;
|
|
17325
17290
|
const DEFAULT_INSPECT_POINT_SAMPLE_COUNT = 2e3;
|
|
17291
|
+
const DEFAULT_MANUAL_SCENE_SETTINGS = {
|
|
17292
|
+
enabled: false,
|
|
17293
|
+
backgroundColor: "#f6f7f8",
|
|
17294
|
+
groundVisible: true,
|
|
17295
|
+
groundColor: "#eef0f2",
|
|
17296
|
+
ambientIntensity: 0.3,
|
|
17297
|
+
keyIntensity: 1.45,
|
|
17298
|
+
fillIntensity: 0.55,
|
|
17299
|
+
rimIntensity: 0.2,
|
|
17300
|
+
environmentIntensity: 0.9
|
|
17301
|
+
};
|
|
17326
17302
|
const resolveInspectPointSampleCount = (value) => {
|
|
17327
17303
|
const numeric = typeof value === "number" ? value : Number(value);
|
|
17328
17304
|
if (!Number.isFinite(numeric)) return DEFAULT_INSPECT_POINT_SAMPLE_COUNT;
|
|
17329
17305
|
return Math.max(INSPECT_POINT_SAMPLE_COUNT_MIN, Math.min(INSPECT_POINT_SAMPLE_COUNT_MAX, Math.round(numeric)));
|
|
17330
17306
|
};
|
|
17307
|
+
const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i;
|
|
17308
|
+
const resolveHexColor = (value, fallback) => {
|
|
17309
|
+
return typeof value === "string" && HEX_COLOR_RE.test(value) ? value : fallback;
|
|
17310
|
+
};
|
|
17311
|
+
const resolveClampedNumber = (value, fallback, min, max2) => {
|
|
17312
|
+
const numeric = typeof value === "number" ? value : Number(value);
|
|
17313
|
+
if (!Number.isFinite(numeric)) return fallback;
|
|
17314
|
+
return Math.max(min, Math.min(max2, numeric));
|
|
17315
|
+
};
|
|
17316
|
+
const resolveManualSceneSettings = (value) => {
|
|
17317
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17318
|
+
return DEFAULT_MANUAL_SCENE_SETTINGS;
|
|
17319
|
+
}
|
|
17320
|
+
const raw = value;
|
|
17321
|
+
return {
|
|
17322
|
+
enabled: typeof raw.enabled === "boolean" ? raw.enabled : DEFAULT_MANUAL_SCENE_SETTINGS.enabled,
|
|
17323
|
+
backgroundColor: resolveHexColor(raw.backgroundColor, DEFAULT_MANUAL_SCENE_SETTINGS.backgroundColor),
|
|
17324
|
+
groundVisible: typeof raw.groundVisible === "boolean" ? raw.groundVisible : DEFAULT_MANUAL_SCENE_SETTINGS.groundVisible,
|
|
17325
|
+
groundColor: resolveHexColor(raw.groundColor, DEFAULT_MANUAL_SCENE_SETTINGS.groundColor),
|
|
17326
|
+
ambientIntensity: resolveClampedNumber(raw.ambientIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.ambientIntensity, 0, 3),
|
|
17327
|
+
keyIntensity: resolveClampedNumber(raw.keyIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.keyIntensity, 0, 5),
|
|
17328
|
+
fillIntensity: resolveClampedNumber(raw.fillIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.fillIntensity, 0, 3),
|
|
17329
|
+
rimIntensity: resolveClampedNumber(raw.rimIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.rimIntensity, 0, 3),
|
|
17330
|
+
environmentIntensity: resolveClampedNumber(raw.environmentIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.environmentIntensity, 0, 3)
|
|
17331
|
+
};
|
|
17332
|
+
};
|
|
17331
17333
|
const readViewPreferences = () => {
|
|
17332
17334
|
if (typeof window === "undefined") return {};
|
|
17333
17335
|
try {
|
|
@@ -17439,7 +17441,10 @@ const INITIAL_SAVED = {};
|
|
|
17439
17441
|
const VIEW_INSPECT_CHANNELS = /* @__PURE__ */ new Set([
|
|
17440
17442
|
"none",
|
|
17441
17443
|
"mask",
|
|
17444
|
+
"normals",
|
|
17445
|
+
"zebra",
|
|
17442
17446
|
"connectivity",
|
|
17447
|
+
"floating",
|
|
17443
17448
|
"distance",
|
|
17444
17449
|
"collisions",
|
|
17445
17450
|
"thickness",
|
|
@@ -18210,6 +18215,16 @@ Switch to LOCAL mode or wait for the server to recover.`,
|
|
|
18210
18215
|
writeViewPreferences({ renderMode: mode });
|
|
18211
18216
|
set({ renderMode: mode });
|
|
18212
18217
|
},
|
|
18218
|
+
manualScene: resolveManualSceneSettings(initialViewPreferences.manualScene),
|
|
18219
|
+
setManualScene: (patch) => set((state2) => {
|
|
18220
|
+
const next = resolveManualSceneSettings({ ...state2.manualScene, ...patch });
|
|
18221
|
+
writeViewPreferences({ manualScene: next });
|
|
18222
|
+
return { manualScene: next };
|
|
18223
|
+
}),
|
|
18224
|
+
resetManualScene: () => {
|
|
18225
|
+
writeViewPreferences({ manualScene: DEFAULT_MANUAL_SCENE_SETTINGS });
|
|
18226
|
+
set({ manualScene: DEFAULT_MANUAL_SCENE_SETTINGS });
|
|
18227
|
+
},
|
|
18213
18228
|
inspectChannel: resolveViewInspectChannel(initialViewPreferences.inspectChannel),
|
|
18214
18229
|
setInspectChannel: (channel) => {
|
|
18215
18230
|
const next = resolveViewInspectChannel(channel);
|
|
@@ -18234,11 +18249,16 @@ Switch to LOCAL mode or wait for the server to recover.`,
|
|
|
18234
18249
|
set({ projectionMode: mode });
|
|
18235
18250
|
},
|
|
18236
18251
|
gridEnabled: initialViewPreferences.gridEnabled ?? true,
|
|
18252
|
+
axesVisible: initialViewPreferences.axesVisible ?? true,
|
|
18237
18253
|
gridSize: initialViewPreferences.gridSize ?? 10,
|
|
18238
18254
|
setGridEnabled: (enabled) => {
|
|
18239
18255
|
writeViewPreferences({ gridEnabled: enabled });
|
|
18240
18256
|
set({ gridEnabled: enabled });
|
|
18241
18257
|
},
|
|
18258
|
+
setAxesVisible: (visible) => {
|
|
18259
|
+
writeViewPreferences({ axesVisible: visible });
|
|
18260
|
+
set({ axesVisible: visible });
|
|
18261
|
+
},
|
|
18242
18262
|
setGridSize: (size) => {
|
|
18243
18263
|
writeViewPreferences({ gridSize: size });
|
|
18244
18264
|
set({ gridSize: size });
|
|
@@ -19021,7 +19041,7 @@ useAuthStore.subscribe((state2) => {
|
|
|
19021
19041
|
function roundCoord(v) {
|
|
19022
19042
|
return Math.round(v * 10) / 10;
|
|
19023
19043
|
}
|
|
19024
|
-
function fmt(v) {
|
|
19044
|
+
function fmt$1(v) {
|
|
19025
19045
|
const r2 = roundCoord(v);
|
|
19026
19046
|
return Number.isInteger(r2) ? String(r2) : r2.toFixed(1);
|
|
19027
19047
|
}
|
|
@@ -19040,13 +19060,13 @@ function generateSketchCode(session) {
|
|
|
19040
19060
|
return lines.join("\n");
|
|
19041
19061
|
}
|
|
19042
19062
|
function pointStatement(varName, x, y) {
|
|
19043
|
-
return `const ${varName} = sk.point(${fmt(x)}, ${fmt(y)});`;
|
|
19063
|
+
return `const ${varName} = sk.point(${fmt$1(x)}, ${fmt$1(y)});`;
|
|
19044
19064
|
}
|
|
19045
19065
|
function lineStatement(varName, startVar, endVar) {
|
|
19046
19066
|
return `const ${varName} = sk.line(${startVar}, ${endVar});`;
|
|
19047
19067
|
}
|
|
19048
19068
|
function circleStatement(varName, centerVar, radius) {
|
|
19049
|
-
return `const ${varName} = sk.circle(${centerVar}, ${fmt(radius)});`;
|
|
19069
|
+
return `const ${varName} = sk.circle(${centerVar}, ${fmt$1(radius)});`;
|
|
19050
19070
|
}
|
|
19051
19071
|
function arcStatement(varName, centerVar, startVar, endVar) {
|
|
19052
19072
|
return `const ${varName} = sk.arcByCenter(${centerVar}, ${startVar}, ${endVar});`;
|
|
@@ -19056,7 +19076,7 @@ const CONSTRAINT_API_MAP = {
|
|
|
19056
19076
|
};
|
|
19057
19077
|
function constraintStatement(type, ...args) {
|
|
19058
19078
|
const apiName = CONSTRAINT_API_MAP[type] ?? type;
|
|
19059
|
-
const fmtArgs = args.map((a2) => typeof a2 === "number" ? fmt(a2) : a2).join(", ");
|
|
19079
|
+
const fmtArgs = args.map((a2) => typeof a2 === "number" ? fmt$1(a2) : a2).join(", ");
|
|
19060
19080
|
return `sk.${apiName}(${fmtArgs});`;
|
|
19061
19081
|
}
|
|
19062
19082
|
function isConstraintTool(tool) {
|
|
@@ -26737,12 +26757,12 @@ function SceneEffects({ config }) {
|
|
|
26737
26757
|
/* @__PURE__ */ jsxRuntimeExports.jsx(dt$1, { children: effects })
|
|
26738
26758
|
] });
|
|
26739
26759
|
}
|
|
26740
|
-
function ScenePostProcessing({ config }) {
|
|
26760
|
+
function ScenePostProcessing({ config, interactivePreview }) {
|
|
26741
26761
|
const pp = config.postProcessing;
|
|
26742
26762
|
if (!pp) return null;
|
|
26743
26763
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
26744
26764
|
pp.toneMappingExposure !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneExposure, { exposure: pp.toneMappingExposure }),
|
|
26745
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SceneEffects, { config })
|
|
26765
|
+
!interactivePreview && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneEffects, { config })
|
|
26746
26766
|
] });
|
|
26747
26767
|
}
|
|
26748
26768
|
function SceneEnvironment({ config }) {
|
|
@@ -26757,9 +26777,9 @@ function SceneEnvironment({ config }) {
|
|
|
26757
26777
|
}
|
|
26758
26778
|
);
|
|
26759
26779
|
}
|
|
26760
|
-
function SceneGround({ config, modelBoundsMinZ }) {
|
|
26780
|
+
function SceneGround({ config, modelBoundsMinZ, hidden }) {
|
|
26761
26781
|
const ground = config.ground;
|
|
26762
|
-
if (!ground || ground.visible === false) return null;
|
|
26782
|
+
if (hidden || !ground || ground.visible === false) return null;
|
|
26763
26783
|
const offset = ground.offset ?? 0;
|
|
26764
26784
|
const height = (modelBoundsMinZ ?? 0) - offset;
|
|
26765
26785
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("mesh", { position: [0, 0, height], receiveShadow: ground.receiveShadow ?? false, children: [
|
|
@@ -26769,8 +26789,10 @@ function SceneGround({ config, modelBoundsMinZ }) {
|
|
|
26769
26789
|
}
|
|
26770
26790
|
function SceneConfigurator({
|
|
26771
26791
|
config,
|
|
26792
|
+
interactivePreview = false,
|
|
26772
26793
|
controlsRef,
|
|
26773
26794
|
modelBoundsMinZ,
|
|
26795
|
+
hideGround = false,
|
|
26774
26796
|
onDefaultLightsOverridden,
|
|
26775
26797
|
onDefaultEnvironmentOverridden
|
|
26776
26798
|
}) {
|
|
@@ -26785,11 +26807,11 @@ function SceneConfigurator({
|
|
|
26785
26807
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
26786
26808
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SceneBackground, { config }),
|
|
26787
26809
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SceneCamera, { config, controlsRef }),
|
|
26788
|
-
config.lights && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneLights, { lights: config.lights }),
|
|
26810
|
+
!interactivePreview && config.lights && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneLights, { lights: config.lights }),
|
|
26789
26811
|
config.fog && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneFog, { fog: config.fog }),
|
|
26790
|
-
config.environment && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneEnvironment, { config }),
|
|
26791
|
-
config.ground && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneGround, { config, modelBoundsMinZ }),
|
|
26792
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ScenePostProcessing, { config })
|
|
26812
|
+
!interactivePreview && config.environment && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneEnvironment, { config }),
|
|
26813
|
+
config.ground && /* @__PURE__ */ jsxRuntimeExports.jsx(SceneGround, { config, modelBoundsMinZ, hidden: hideGround }),
|
|
26814
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScenePostProcessing, { config, interactivePreview })
|
|
26793
26815
|
] });
|
|
26794
26816
|
}
|
|
26795
26817
|
function ClippingManager({ active }) {
|
|
@@ -26799,9 +26821,45 @@ function ClippingManager({ active }) {
|
|
|
26799
26821
|
}, [gl, active]);
|
|
26800
26822
|
return null;
|
|
26801
26823
|
}
|
|
26824
|
+
function matrixToCollisionMat4(matrix) {
|
|
26825
|
+
if (!matrix) return void 0;
|
|
26826
|
+
const e2 = matrix.elements;
|
|
26827
|
+
return [e2[0], e2[1], e2[2], e2[3], e2[4], e2[5], e2[6], e2[7], e2[8], e2[9], e2[10], e2[11], e2[12], e2[13], e2[14], e2[15]];
|
|
26828
|
+
}
|
|
26829
|
+
function buildViewportCollisionEntries(objects, objectSettings, objectMatrices) {
|
|
26830
|
+
const entries = [];
|
|
26831
|
+
objects.forEach((obj) => {
|
|
26832
|
+
var _a3;
|
|
26833
|
+
if (!obj.shape) return;
|
|
26834
|
+
if (((_a3 = objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) return;
|
|
26835
|
+
try {
|
|
26836
|
+
const bb = obj.shape.boundingBox();
|
|
26837
|
+
entries.push({
|
|
26838
|
+
id: obj.id,
|
|
26839
|
+
name: obj.name,
|
|
26840
|
+
shape: obj.shape,
|
|
26841
|
+
min: [bb.min[0], bb.min[1], bb.min[2]],
|
|
26842
|
+
max: [bb.max[0], bb.max[1], bb.max[2]],
|
|
26843
|
+
transform: matrixToCollisionMat4(objectMatrices[obj.id]),
|
|
26844
|
+
groupName: obj.groupName,
|
|
26845
|
+
treePath: obj.treePath,
|
|
26846
|
+
mock: obj.mock
|
|
26847
|
+
});
|
|
26848
|
+
} catch {
|
|
26849
|
+
}
|
|
26850
|
+
});
|
|
26851
|
+
return entries;
|
|
26852
|
+
}
|
|
26853
|
+
function analyzeViewportCollisions(objects, objectSettings, objectMatrices) {
|
|
26854
|
+
return analyzeCollisionIntersections(buildViewportCollisionEntries(objects, objectSettings, objectMatrices), {
|
|
26855
|
+
includeBBoxCandidates: false
|
|
26856
|
+
});
|
|
26857
|
+
}
|
|
26802
26858
|
const COLLISION_SOURCE_OPACITY = 0.22;
|
|
26803
26859
|
const COLLISION_SOURCE_COLOR = [180, 200, 220];
|
|
26804
26860
|
const COLLISION_HIGHLIGHT_COLOR = [255, 68, 16];
|
|
26861
|
+
const FLOATING_HIGHLIGHT_COLOR = [255, 68, 16];
|
|
26862
|
+
const FLOATING_CONTEXT_COLOR = [38, 49, 58];
|
|
26805
26863
|
const COLLISION_PALETTE = [
|
|
26806
26864
|
COLLISION_HIGHLIGHT_COLOR,
|
|
26807
26865
|
[0, 204, 255],
|
|
@@ -26838,6 +26896,10 @@ const MASK_PALETTE = [
|
|
|
26838
26896
|
[0, 0, 128],
|
|
26839
26897
|
[128, 128, 128]
|
|
26840
26898
|
];
|
|
26899
|
+
const DISTANCE_NEAR_COLOR = [66, 220, 120];
|
|
26900
|
+
const DISTANCE_MID_COLOR = [255, 214, 0];
|
|
26901
|
+
const DISTANCE_FAR_COLOR = [255, 68, 16];
|
|
26902
|
+
const DISTANCE_UNKNOWN_COLOR = [128, 128, 128];
|
|
26841
26903
|
function rgbToHex(color2) {
|
|
26842
26904
|
return `#${color2.map((value) => value.toString(16).padStart(2, "0")).join("")}`;
|
|
26843
26905
|
}
|
|
@@ -26850,48 +26912,13 @@ function maskColorForIndex(index) {
|
|
|
26850
26912
|
function collisionColorForIndex(index) {
|
|
26851
26913
|
return rgbToHex(COLLISION_PALETTE[(index - 1) % COLLISION_PALETTE.length]);
|
|
26852
26914
|
}
|
|
26853
|
-
const MAX_VIEWPORT_COLLISION_CANDIDATES = 200;
|
|
26854
|
-
const MAX_VIEWPORT_COLLISION_MS = 1e3;
|
|
26855
|
-
function matrixToCollisionMat4(matrix) {
|
|
26856
|
-
if (!matrix) return void 0;
|
|
26857
|
-
const e2 = matrix.elements;
|
|
26858
|
-
return [e2[0], e2[1], e2[2], e2[3], e2[4], e2[5], e2[6], e2[7], e2[8], e2[9], e2[10], e2[11], e2[12], e2[13], e2[14], e2[15]];
|
|
26859
|
-
}
|
|
26860
|
-
function buildCollisionEntries(objects, objectSettings, objectMatrices) {
|
|
26861
|
-
const entries = [];
|
|
26862
|
-
objects.forEach((obj) => {
|
|
26863
|
-
var _a3;
|
|
26864
|
-
if (!obj.shape) return;
|
|
26865
|
-
if (((_a3 = objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) return;
|
|
26866
|
-
try {
|
|
26867
|
-
const bb = obj.shape.boundingBox();
|
|
26868
|
-
entries.push({
|
|
26869
|
-
id: obj.id,
|
|
26870
|
-
name: obj.name,
|
|
26871
|
-
shape: obj.shape,
|
|
26872
|
-
min: [bb.min[0], bb.min[1], bb.min[2]],
|
|
26873
|
-
max: [bb.max[0], bb.max[1], bb.max[2]],
|
|
26874
|
-
transform: matrixToCollisionMat4(objectMatrices[obj.id]),
|
|
26875
|
-
groupName: obj.groupName,
|
|
26876
|
-
treePath: obj.treePath,
|
|
26877
|
-
mock: obj.mock
|
|
26878
|
-
});
|
|
26879
|
-
} catch {
|
|
26880
|
-
}
|
|
26881
|
-
});
|
|
26882
|
-
return entries;
|
|
26883
|
-
}
|
|
26884
26915
|
function CollisionInspectionOverlay({
|
|
26885
26916
|
objects,
|
|
26886
26917
|
objectSettings,
|
|
26887
26918
|
objectMatrices
|
|
26888
26919
|
}) {
|
|
26889
26920
|
const collisionGeometries = reactExports.useMemo(() => {
|
|
26890
|
-
const report =
|
|
26891
|
-
maxCandidatePairs: MAX_VIEWPORT_COLLISION_CANDIDATES,
|
|
26892
|
-
maxElapsedMs: MAX_VIEWPORT_COLLISION_MS,
|
|
26893
|
-
includeBBoxCandidates: false
|
|
26894
|
-
});
|
|
26921
|
+
const report = analyzeViewportCollisions(objects, objectSettings, objectMatrices);
|
|
26895
26922
|
return report.collisions.flatMap((collision) => {
|
|
26896
26923
|
try {
|
|
26897
26924
|
const geometry = shapeToGeometry(collision.shape);
|
|
@@ -26941,53 +26968,108 @@ function ConstructionGhostOverlay({ matrix }) {
|
|
|
26941
26968
|
/* @__PURE__ */ jsxRuntimeExports.jsx("lineSegments", { geometry: edgesGeo, renderOrder: 3, children: /* @__PURE__ */ jsxRuntimeExports.jsx("lineBasicMaterial", { color: "#4a9eff", transparent: true, opacity: 0.55, depthTest: false, depthWrite: false }) })
|
|
26942
26969
|
] });
|
|
26943
26970
|
}
|
|
26944
|
-
|
|
26945
|
-
|
|
26946
|
-
|
|
26947
|
-
|
|
26948
|
-
|
|
26949
|
-
|
|
26950
|
-
|
|
26951
|
-
|
|
26952
|
-
|
|
26953
|
-
|
|
26954
|
-
const entry = { solid, edges, hasSmoothNormals };
|
|
26955
|
-
if (geometryCache.size >= MAX_CACHE_SIZE) {
|
|
26956
|
-
const firstKey = geometryCache.keys().next().value;
|
|
26957
|
-
if (firstKey !== void 0) {
|
|
26958
|
-
const old = geometryCache.get(firstKey);
|
|
26959
|
-
old == null ? void 0 : old.solid.dispose();
|
|
26960
|
-
old == null ? void 0 : old.edges.dispose();
|
|
26961
|
-
geometryCache.delete(firstKey);
|
|
26962
|
-
}
|
|
26963
|
-
}
|
|
26964
|
-
geometryCache.set(cacheKey, entry);
|
|
26965
|
-
return entry;
|
|
26966
|
-
} catch {
|
|
26967
|
-
return null;
|
|
26971
|
+
class ConstructionHistoryWorkerClient {
|
|
26972
|
+
constructor(workerFactory = () => new Worker(new URL(
|
|
26973
|
+
/* @vite-ignore */
|
|
26974
|
+
"/assets/constructionHistoryWorker-z9_LGiRd.js",
|
|
26975
|
+
import.meta.url
|
|
26976
|
+
), { type: "module" })) {
|
|
26977
|
+
__publicField(this, "worker", null);
|
|
26978
|
+
__publicField(this, "reqId", 0);
|
|
26979
|
+
__publicField(this, "pending", null);
|
|
26980
|
+
this.workerFactory = workerFactory;
|
|
26968
26981
|
}
|
|
26982
|
+
getWorker() {
|
|
26983
|
+
if (this.worker) return this.worker;
|
|
26984
|
+
this.worker = this.workerFactory();
|
|
26985
|
+
this.worker.onmessage = (event) => {
|
|
26986
|
+
const data = event.data;
|
|
26987
|
+
const pending = this.pending;
|
|
26988
|
+
if (!pending) return;
|
|
26989
|
+
this.pending = null;
|
|
26990
|
+
if (data.type === "history-geometry-error") {
|
|
26991
|
+
pending.reject(new Error(data.payload.message));
|
|
26992
|
+
} else {
|
|
26993
|
+
pending.resolve(data.payload.result);
|
|
26994
|
+
}
|
|
26995
|
+
};
|
|
26996
|
+
this.worker.onerror = (event) => {
|
|
26997
|
+
var _a3, _b2;
|
|
26998
|
+
const error = new Error(event.message || "Construction history worker failed unexpectedly.");
|
|
26999
|
+
(_a3 = this.pending) == null ? void 0 : _a3.reject(error);
|
|
27000
|
+
this.pending = null;
|
|
27001
|
+
(_b2 = this.worker) == null ? void 0 : _b2.terminate();
|
|
27002
|
+
this.worker = null;
|
|
27003
|
+
};
|
|
27004
|
+
return this.worker;
|
|
27005
|
+
}
|
|
27006
|
+
replaceActiveWorker() {
|
|
27007
|
+
var _a3, _b2;
|
|
27008
|
+
(_a3 = this.pending) == null ? void 0 : _a3.reject(new Error("cancelled"));
|
|
27009
|
+
this.pending = null;
|
|
27010
|
+
(_b2 = this.worker) == null ? void 0 : _b2.terminate();
|
|
27011
|
+
this.worker = null;
|
|
27012
|
+
}
|
|
27013
|
+
build(payload) {
|
|
27014
|
+
if (this.pending) this.replaceActiveWorker();
|
|
27015
|
+
const reqId = ++this.reqId;
|
|
27016
|
+
const request = {
|
|
27017
|
+
type: "build",
|
|
27018
|
+
payload: {
|
|
27019
|
+
reqId,
|
|
27020
|
+
...payload
|
|
27021
|
+
}
|
|
27022
|
+
};
|
|
27023
|
+
return new Promise((resolve2, reject) => {
|
|
27024
|
+
this.pending = { resolve: resolve2, reject };
|
|
27025
|
+
this.getWorker().postMessage(request);
|
|
27026
|
+
});
|
|
27027
|
+
}
|
|
27028
|
+
dispose() {
|
|
27029
|
+
this.replaceActiveWorker();
|
|
27030
|
+
}
|
|
27031
|
+
}
|
|
27032
|
+
const constructionHistoryWorkerClient = new ConstructionHistoryWorkerClient();
|
|
27033
|
+
function historyGeometryRequestKey(activeBackend, items) {
|
|
27034
|
+
return `${activeBackend}:${items.map(({ objectId, step }) => `${objectId}:${step.index}:${step.cumulativePlanCacheKey}`).join("|")}`;
|
|
26969
27035
|
}
|
|
26970
|
-
function
|
|
26971
|
-
|
|
26972
|
-
|
|
26973
|
-
|
|
27036
|
+
function geometryItemKey(objectId, stepIndex) {
|
|
27037
|
+
return `${objectId}:${stepIndex}`;
|
|
27038
|
+
}
|
|
27039
|
+
function bufferGeometryFromWorkerGeometry(geometry) {
|
|
27040
|
+
const solid = new BufferGeometry();
|
|
27041
|
+
solid.setAttribute("position", new BufferAttribute(geometry.positions, 3));
|
|
27042
|
+
if (geometry.normals.length > 0) solid.setAttribute("normal", new BufferAttribute(geometry.normals, 3));
|
|
27043
|
+
if (geometry.triangleFaceIds.length > 0) {
|
|
27044
|
+
solid.userData.forgeTriangleFaceIds = geometry.triangleFaceIds;
|
|
27045
|
+
solid.userData.forgeFaceIdNames = geometry.faceIdNames;
|
|
26974
27046
|
}
|
|
26975
|
-
|
|
27047
|
+
const edges = new BufferGeometry();
|
|
27048
|
+
edges.setAttribute("position", new BufferAttribute(geometry.edgePositions, 3));
|
|
27049
|
+
return { solid, edges, hasSmoothNormals: geometry.hasSmoothNormals };
|
|
27050
|
+
}
|
|
27051
|
+
function disposeBufferedHistoryGeometry(geometry) {
|
|
27052
|
+
geometry.solid.dispose();
|
|
27053
|
+
geometry.edges.dispose();
|
|
26976
27054
|
}
|
|
26977
27055
|
function ConstructionHistoryOverlay({
|
|
27056
|
+
activeBackend,
|
|
26978
27057
|
objectMatrices,
|
|
26979
|
-
objectSettings
|
|
27058
|
+
objectSettings,
|
|
27059
|
+
onGeometryStatusChange
|
|
26980
27060
|
}) {
|
|
26981
27061
|
const historyMode = useForgeStore((s) => s.historyMode);
|
|
26982
27062
|
const historySteps = useForgeStore((s) => s.historySteps);
|
|
26983
27063
|
const historyCurrentStep = useForgeStore((s) => s.historyCurrentStep);
|
|
26984
27064
|
const theme = useForgeStore((s) => themes[s.theme]);
|
|
26985
27065
|
const [fadeOpacity, setFadeOpacity] = reactExports.useState(1);
|
|
27066
|
+
const [objectGeos, setObjectGeos] = reactExports.useState([]);
|
|
26986
27067
|
const fadeRef = reactExports.useRef(0);
|
|
27068
|
+
const objectGeosRef = reactExports.useRef([]);
|
|
26987
27069
|
const prevStepRef = reactExports.useRef(-1);
|
|
26988
27070
|
reactExports.useEffect(() => {
|
|
26989
|
-
return () =>
|
|
26990
|
-
}, []);
|
|
27071
|
+
return () => onGeometryStatusChange == null ? void 0 : onGeometryStatusChange({ status: "idle", stepCount: 0, error: null });
|
|
27072
|
+
}, [onGeometryStatusChange]);
|
|
26991
27073
|
reactExports.useEffect(() => {
|
|
26992
27074
|
if (prevStepRef.current !== historyCurrentStep) {
|
|
26993
27075
|
prevStepRef.current = historyCurrentStep;
|
|
@@ -27008,16 +27090,86 @@ function ConstructionHistoryOverlay({
|
|
|
27008
27090
|
}, [historyCurrentStep]);
|
|
27009
27091
|
const visibleStacks = reactExports.useMemo(() => buildVisibleHistoryStacks(historySteps, historyCurrentStep), [historySteps, historyCurrentStep]);
|
|
27010
27092
|
const currentStep = historySteps[historyCurrentStep] ?? null;
|
|
27011
|
-
const
|
|
27012
|
-
const
|
|
27093
|
+
const visibleHistoryItems = reactExports.useMemo(() => {
|
|
27094
|
+
const items = [];
|
|
27013
27095
|
for (const [objectId, stack] of visibleStacks) {
|
|
27014
|
-
for (const step of stack) {
|
|
27015
|
-
const geo = getCachedGeometry(step);
|
|
27016
|
-
if (geo) result.push({ objectId, geo, step });
|
|
27017
|
-
}
|
|
27096
|
+
for (const step of stack) items.push({ objectId, step });
|
|
27018
27097
|
}
|
|
27019
|
-
return
|
|
27098
|
+
return items;
|
|
27020
27099
|
}, [visibleStacks]);
|
|
27100
|
+
const requestKey = reactExports.useMemo(
|
|
27101
|
+
() => historyMode && visibleHistoryItems.length > 0 ? historyGeometryRequestKey(activeBackend, visibleHistoryItems) : "idle",
|
|
27102
|
+
[activeBackend, historyMode, visibleHistoryItems]
|
|
27103
|
+
);
|
|
27104
|
+
const [geometryState, setGeometryState] = reactExports.useState({
|
|
27105
|
+
status: "idle",
|
|
27106
|
+
requestKey: "idle",
|
|
27107
|
+
geometries: [],
|
|
27108
|
+
error: null
|
|
27109
|
+
});
|
|
27110
|
+
reactExports.useEffect(() => {
|
|
27111
|
+
onGeometryStatusChange == null ? void 0 : onGeometryStatusChange({
|
|
27112
|
+
status: historyMode ? geometryState.status : "idle",
|
|
27113
|
+
stepCount: visibleHistoryItems.length,
|
|
27114
|
+
error: historyMode ? geometryState.error : null
|
|
27115
|
+
});
|
|
27116
|
+
}, [geometryState.error, geometryState.status, historyMode, onGeometryStatusChange, visibleHistoryItems.length]);
|
|
27117
|
+
reactExports.useEffect(() => {
|
|
27118
|
+
if (!historyMode || visibleHistoryItems.length === 0) {
|
|
27119
|
+
constructionHistoryWorkerClient.dispose();
|
|
27120
|
+
setGeometryState({ status: "idle", requestKey, geometries: [], error: null });
|
|
27121
|
+
return;
|
|
27122
|
+
}
|
|
27123
|
+
let cancelled = false;
|
|
27124
|
+
setGeometryState({ status: "loading", requestKey, geometries: [], error: null });
|
|
27125
|
+
void constructionHistoryWorkerClient.build({
|
|
27126
|
+
activeBackend,
|
|
27127
|
+
items: visibleHistoryItems.map(({ objectId, step }) => ({
|
|
27128
|
+
objectId,
|
|
27129
|
+
stepIndex: step.index,
|
|
27130
|
+
cumulativePlan: step.cumulativePlan
|
|
27131
|
+
}))
|
|
27132
|
+
}).then((result) => {
|
|
27133
|
+
if (cancelled) return;
|
|
27134
|
+
setGeometryState({ status: "ready", requestKey, geometries: result.geometries, error: null });
|
|
27135
|
+
}).catch((error) => {
|
|
27136
|
+
if (cancelled || error instanceof Error && error.message === "cancelled") return;
|
|
27137
|
+
setGeometryState({
|
|
27138
|
+
status: "error",
|
|
27139
|
+
requestKey,
|
|
27140
|
+
geometries: [],
|
|
27141
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27142
|
+
});
|
|
27143
|
+
});
|
|
27144
|
+
return () => {
|
|
27145
|
+
cancelled = true;
|
|
27146
|
+
constructionHistoryWorkerClient.dispose();
|
|
27147
|
+
};
|
|
27148
|
+
}, [activeBackend, historyMode, requestKey, visibleHistoryItems]);
|
|
27149
|
+
reactExports.useEffect(() => {
|
|
27150
|
+
const nextGeos = [];
|
|
27151
|
+
if (historyMode && geometryState.status === "ready" && geometryState.requestKey === requestKey) {
|
|
27152
|
+
const itemByKey = new Map(visibleHistoryItems.map((item) => [geometryItemKey(item.objectId, item.step.index), item]));
|
|
27153
|
+
for (const geometry of geometryState.geometries) {
|
|
27154
|
+
const item = itemByKey.get(geometryItemKey(geometry.objectId, geometry.stepIndex));
|
|
27155
|
+
if (!item) continue;
|
|
27156
|
+
nextGeos.push({
|
|
27157
|
+
objectId: item.objectId,
|
|
27158
|
+
step: item.step,
|
|
27159
|
+
geo: bufferGeometryFromWorkerGeometry(geometry)
|
|
27160
|
+
});
|
|
27161
|
+
}
|
|
27162
|
+
}
|
|
27163
|
+
for (const { geo } of objectGeosRef.current) disposeBufferedHistoryGeometry(geo);
|
|
27164
|
+
objectGeosRef.current = nextGeos;
|
|
27165
|
+
setObjectGeos(nextGeos);
|
|
27166
|
+
}, [geometryState, historyMode, requestKey, visibleHistoryItems]);
|
|
27167
|
+
reactExports.useEffect(() => {
|
|
27168
|
+
return () => {
|
|
27169
|
+
for (const { geo } of objectGeosRef.current) disposeBufferedHistoryGeometry(geo);
|
|
27170
|
+
objectGeosRef.current = [];
|
|
27171
|
+
};
|
|
27172
|
+
}, []);
|
|
27021
27173
|
if (!historyMode || objectGeos.length === 0) return null;
|
|
27022
27174
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: objectGeos.map(({ objectId, geo, step }) => {
|
|
27023
27175
|
var _a3;
|
|
@@ -29147,7 +29299,7 @@ function generateReportInWorker(options) {
|
|
|
29147
29299
|
return new Promise((resolve2, reject) => {
|
|
29148
29300
|
const worker = new Worker(new URL(
|
|
29149
29301
|
/* @vite-ignore */
|
|
29150
|
-
"/assets/reportWorker-
|
|
29302
|
+
"/assets/reportWorker-Bz9tGiHb.js",
|
|
29151
29303
|
import.meta.url
|
|
29152
29304
|
), { type: "module" });
|
|
29153
29305
|
const cleanup = () => {
|
|
@@ -32352,6 +32504,7 @@ const PHASE_CONFIG = {
|
|
|
32352
32504
|
serializing: { color: "#7c4dff", label: "Preparing display" },
|
|
32353
32505
|
exporting: { color: "#4caf50", label: "Exporting geometry" },
|
|
32354
32506
|
inspecting: { color: "#14b8a6", label: "Generating inspect view" },
|
|
32507
|
+
history: { color: "#c084fc", label: "Building timeline geometry" },
|
|
32355
32508
|
idle: { color: "#888", label: "" }
|
|
32356
32509
|
};
|
|
32357
32510
|
const PHASE_ORDER = ["kernel-init", "evaluating", "serializing"];
|
|
@@ -32359,36 +32512,18 @@ function formatEvaluationBackendLabel(activeBackend, computeTarget) {
|
|
|
32359
32512
|
const backend = activeBackend === "occt" ? "OCCT" : activeBackend === "manifold" ? "Manifold" : activeBackend === "truck" ? "Truck" : "kernel";
|
|
32360
32513
|
return computeTarget === "server" ? `Server ${backend}` : `Local ${backend}`;
|
|
32361
32514
|
}
|
|
32362
|
-
function constructionStepRoleSymbol(role) {
|
|
32363
|
-
if (role === "primitive") return "+";
|
|
32364
|
-
if (role === "operation") return "->";
|
|
32365
|
-
return "~";
|
|
32366
|
-
}
|
|
32367
|
-
function constructionStepPreview(constructionSteps, previewStepIndex) {
|
|
32368
|
-
const stepCount = constructionSteps.length;
|
|
32369
|
-
const displayStepIndex = stepCount > 0 ? (previewStepIndex % stepCount + stepCount) % stepCount : 0;
|
|
32370
|
-
return {
|
|
32371
|
-
displayStepIndex,
|
|
32372
|
-
previewStep: stepCount > 0 ? constructionSteps[displayStepIndex] : null,
|
|
32373
|
-
progress: stepCount > 1 ? (displayStepIndex + 1) / stepCount : 1
|
|
32374
|
-
};
|
|
32375
|
-
}
|
|
32376
32515
|
function EvaluationIndicator({
|
|
32377
32516
|
phase,
|
|
32378
32517
|
label,
|
|
32379
|
-
constructionSteps = [],
|
|
32380
32518
|
activeBackend,
|
|
32381
32519
|
computeTarget
|
|
32382
32520
|
}) {
|
|
32383
32521
|
const [frame2, setFrame] = reactExports.useState(0);
|
|
32384
32522
|
const [elapsed, setElapsed] = reactExports.useState(0);
|
|
32385
|
-
const [previewStepIndex, setPreviewStepIndex] = reactExports.useState(0);
|
|
32386
32523
|
const startRef = reactExports.useRef(Date.now());
|
|
32387
|
-
const stepCount = constructionSteps.length;
|
|
32388
32524
|
reactExports.useEffect(() => {
|
|
32389
32525
|
startRef.current = Date.now();
|
|
32390
32526
|
setElapsed(0);
|
|
32391
|
-
setPreviewStepIndex(0);
|
|
32392
32527
|
}, [phase]);
|
|
32393
32528
|
reactExports.useEffect(() => {
|
|
32394
32529
|
const spinnerInterval = setInterval(() => setFrame((f2) => (f2 + 1) % BRAILLE_FRAMES.length), 80);
|
|
@@ -32398,166 +32533,85 @@ function EvaluationIndicator({
|
|
|
32398
32533
|
clearInterval(timerInterval);
|
|
32399
32534
|
};
|
|
32400
32535
|
}, []);
|
|
32401
|
-
reactExports.useEffect(() => {
|
|
32402
|
-
setPreviewStepIndex(0);
|
|
32403
|
-
if (stepCount <= 1) return;
|
|
32404
|
-
const interval = setInterval(() => setPreviewStepIndex((i) => (i + 1) % stepCount), 700);
|
|
32405
|
-
return () => clearInterval(interval);
|
|
32406
|
-
}, [stepCount]);
|
|
32407
32536
|
const config = PHASE_CONFIG[phase] ?? PHASE_CONFIG["evaluating"];
|
|
32408
32537
|
const elapsedSec = (elapsed / 1e3).toFixed(1);
|
|
32409
32538
|
const phaseOrder = PHASE_ORDER.includes(phase) ? PHASE_ORDER : [phase];
|
|
32410
32539
|
const phaseIdx = phaseOrder.indexOf(phase);
|
|
32411
|
-
const
|
|
32412
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
32540
|
+
const backendLabel = formatEvaluationBackendLabel(activeBackend, computeTarget);
|
|
32541
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32413
32542
|
"div",
|
|
32414
32543
|
{
|
|
32415
32544
|
style: {
|
|
32416
32545
|
position: "absolute",
|
|
32417
32546
|
bottom: 16,
|
|
32418
32547
|
right: 16,
|
|
32419
|
-
width: previewStep ? "min(360px, calc(100vw - 32px))" : void 0,
|
|
32420
32548
|
background: "var(--fc-bgPanel)",
|
|
32421
32549
|
border: "1px solid var(--fc-border)",
|
|
32422
32550
|
borderRadius: 8,
|
|
32423
|
-
padding:
|
|
32551
|
+
padding: "8px 14px",
|
|
32424
32552
|
pointerEvents: "none",
|
|
32425
32553
|
display: "grid",
|
|
32426
|
-
gap:
|
|
32554
|
+
gap: 0,
|
|
32427
32555
|
fontSize: 12,
|
|
32428
32556
|
animation: "fc-fadein 0.2s ease-out",
|
|
32429
32557
|
boxShadow: "0 4px 16px rgba(0,0,0,0.25)"
|
|
32430
32558
|
},
|
|
32431
|
-
children: [
|
|
32432
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
32433
|
-
|
|
32434
|
-
|
|
32559
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, minWidth: 0 }, children: [
|
|
32560
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: config.color, fontSize: 16, fontWeight: 700, width: 16, textAlign: "center", flex: "0 0 auto" }, children: BRAILLE_FRAMES[frame2] }),
|
|
32561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32562
|
+
"span",
|
|
32563
|
+
{
|
|
32564
|
+
style: {
|
|
32565
|
+
color: "var(--fc-text)",
|
|
32566
|
+
fontWeight: 500,
|
|
32567
|
+
minWidth: 0,
|
|
32568
|
+
overflow: "hidden",
|
|
32569
|
+
textOverflow: "ellipsis",
|
|
32570
|
+
whiteSpace: "nowrap"
|
|
32571
|
+
},
|
|
32572
|
+
children: label ?? config.label
|
|
32573
|
+
}
|
|
32574
|
+
),
|
|
32575
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32576
|
+
"span",
|
|
32577
|
+
{
|
|
32578
|
+
style: {
|
|
32579
|
+
color: "var(--fc-textMuted)",
|
|
32580
|
+
fontSize: 11,
|
|
32581
|
+
minWidth: 0,
|
|
32582
|
+
overflow: "hidden",
|
|
32583
|
+
textOverflow: "ellipsis",
|
|
32584
|
+
whiteSpace: "nowrap"
|
|
32585
|
+
},
|
|
32586
|
+
children: backendLabel
|
|
32587
|
+
}
|
|
32588
|
+
),
|
|
32589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "flex", gap: 4, alignItems: "center", marginLeft: "auto", flex: "0 0 auto" }, children: phaseOrder.map((p2, i) => {
|
|
32590
|
+
var _a3;
|
|
32591
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32435
32592
|
"span",
|
|
32436
32593
|
{
|
|
32437
32594
|
style: {
|
|
32438
|
-
|
|
32439
|
-
|
|
32440
|
-
|
|
32441
|
-
|
|
32442
|
-
|
|
32443
|
-
|
|
32444
|
-
},
|
|
32445
|
-
children: label ?? config.label
|
|
32446
|
-
}
|
|
32447
|
-
),
|
|
32448
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "flex", gap: 4, alignItems: "center", marginLeft: "auto", flex: "0 0 auto" }, children: phaseOrder.map((p2, i) => {
|
|
32449
|
-
var _a3;
|
|
32450
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32451
|
-
"span",
|
|
32452
|
-
{
|
|
32453
|
-
style: {
|
|
32454
|
-
width: 6,
|
|
32455
|
-
height: 6,
|
|
32456
|
-
borderRadius: "50%",
|
|
32457
|
-
background: i <= phaseIdx ? ((_a3 = PHASE_CONFIG[p2]) == null ? void 0 : _a3.color) ?? "var(--fc-border)" : "var(--fc-border)",
|
|
32458
|
-
transition: "background 0.3s ease",
|
|
32459
|
-
animation: i === phaseIdx ? "fc-pulse 1.2s ease-in-out infinite" : void 0
|
|
32460
|
-
}
|
|
32461
|
-
},
|
|
32462
|
-
p2
|
|
32463
|
-
);
|
|
32464
|
-
}) }),
|
|
32465
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { color: "var(--fc-textDim)", fontVariantNumeric: "tabular-nums", fontSize: 11, flex: "0 0 auto" }, children: [
|
|
32466
|
-
elapsedSec,
|
|
32467
|
-
"s"
|
|
32468
|
-
] })
|
|
32469
|
-
] }),
|
|
32470
|
-
previewStep && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "grid", gap: 6, minWidth: 0 }, children: [
|
|
32471
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [
|
|
32472
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32473
|
-
"span",
|
|
32474
|
-
{
|
|
32475
|
-
style: {
|
|
32476
|
-
color: "var(--fc-textDim)",
|
|
32477
|
-
fontSize: 10,
|
|
32478
|
-
textTransform: "uppercase",
|
|
32479
|
-
fontWeight: 700,
|
|
32480
|
-
letterSpacing: 0,
|
|
32481
|
-
flex: "0 0 auto"
|
|
32482
|
-
},
|
|
32483
|
-
children: "Cached build path"
|
|
32484
|
-
}
|
|
32485
|
-
),
|
|
32486
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32487
|
-
"span",
|
|
32488
|
-
{
|
|
32489
|
-
style: {
|
|
32490
|
-
color: "var(--fc-textMuted)",
|
|
32491
|
-
fontSize: 11,
|
|
32492
|
-
minWidth: 0,
|
|
32493
|
-
overflow: "hidden",
|
|
32494
|
-
textOverflow: "ellipsis",
|
|
32495
|
-
whiteSpace: "nowrap"
|
|
32496
|
-
},
|
|
32497
|
-
children: formatEvaluationBackendLabel(activeBackend, computeTarget)
|
|
32498
|
-
}
|
|
32499
|
-
)
|
|
32500
|
-
] }),
|
|
32501
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [
|
|
32502
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32503
|
-
"span",
|
|
32504
|
-
{
|
|
32505
|
-
style: {
|
|
32506
|
-
color: config.color,
|
|
32507
|
-
fontVariantNumeric: "tabular-nums",
|
|
32508
|
-
fontSize: 11,
|
|
32509
|
-
fontWeight: 700,
|
|
32510
|
-
flex: "0 0 auto",
|
|
32511
|
-
width: 46
|
|
32512
|
-
},
|
|
32513
|
-
children: [
|
|
32514
|
-
displayStepIndex + 1,
|
|
32515
|
-
"/",
|
|
32516
|
-
stepCount
|
|
32517
|
-
]
|
|
32518
|
-
}
|
|
32519
|
-
),
|
|
32520
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32521
|
-
"span",
|
|
32522
|
-
{
|
|
32523
|
-
style: {
|
|
32524
|
-
color: "var(--fc-text)",
|
|
32525
|
-
minWidth: 0,
|
|
32526
|
-
overflow: "hidden",
|
|
32527
|
-
textOverflow: "ellipsis",
|
|
32528
|
-
whiteSpace: "nowrap"
|
|
32529
|
-
},
|
|
32530
|
-
children: [
|
|
32531
|
-
constructionStepRoleSymbol(previewStep.role),
|
|
32532
|
-
" ",
|
|
32533
|
-
previewStep.label
|
|
32534
|
-
]
|
|
32535
|
-
}
|
|
32536
|
-
),
|
|
32537
|
-
previewStep.displayAsTool && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: config.color, fontSize: 11, flex: "0 0 auto" }, children: "tool" })
|
|
32538
|
-
] }),
|
|
32539
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { height: 3, borderRadius: 999, background: "var(--fc-borderLight)", overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32540
|
-
"div",
|
|
32541
|
-
{
|
|
32542
|
-
style: {
|
|
32543
|
-
width: `${Math.round(progress * 100)}%`,
|
|
32544
|
-
height: "100%",
|
|
32545
|
-
borderRadius: 999,
|
|
32546
|
-
background: config.color,
|
|
32547
|
-
transition: "width 0.2s ease-out"
|
|
32595
|
+
width: 6,
|
|
32596
|
+
height: 6,
|
|
32597
|
+
borderRadius: "50%",
|
|
32598
|
+
background: i <= phaseIdx ? ((_a3 = PHASE_CONFIG[p2]) == null ? void 0 : _a3.color) ?? "var(--fc-border)" : "var(--fc-border)",
|
|
32599
|
+
transition: "background 0.3s ease",
|
|
32600
|
+
animation: i === phaseIdx ? "fc-pulse 1.2s ease-in-out infinite" : void 0
|
|
32548
32601
|
}
|
|
32549
|
-
}
|
|
32550
|
-
|
|
32602
|
+
},
|
|
32603
|
+
p2
|
|
32604
|
+
);
|
|
32605
|
+
}) }),
|
|
32606
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { color: "var(--fc-textDim)", fontVariantNumeric: "tabular-nums", fontSize: 11, flex: "0 0 auto" }, children: [
|
|
32607
|
+
elapsedSec,
|
|
32608
|
+
"s"
|
|
32551
32609
|
] })
|
|
32552
|
-
]
|
|
32610
|
+
] })
|
|
32553
32611
|
}
|
|
32554
32612
|
);
|
|
32555
32613
|
}
|
|
32556
|
-
const MIN_FIELD_GRID_SIZE = 18;
|
|
32557
|
-
const MAX_FIELD_GRID_SIZE = 32;
|
|
32558
|
-
const MAX_BLEND_SAMPLES = 12;
|
|
32559
32614
|
const MAX_SEARCH_RADIUS = 5;
|
|
32560
|
-
const SAMPLE_RING_OFFSETS = [];
|
|
32561
32615
|
for (let radius = 0; radius <= MAX_SEARCH_RADIUS; radius += 1) {
|
|
32562
32616
|
const ring = [];
|
|
32563
32617
|
for (let x = -radius; x <= radius; x += 1) {
|
|
@@ -32567,7 +32621,6 @@ for (let radius = 0; radius <= MAX_SEARCH_RADIUS; radius += 1) {
|
|
|
32567
32621
|
}
|
|
32568
32622
|
}
|
|
32569
32623
|
}
|
|
32570
|
-
SAMPLE_RING_OFFSETS.push(ring);
|
|
32571
32624
|
}
|
|
32572
32625
|
const INSPECT_HEATMAP_VERTEX_SHADER = `
|
|
32573
32626
|
varying vec3 vLocalPosition;
|
|
@@ -32635,127 +32688,14 @@ const INSPECT_HEATMAP_FRAGMENT_SHADER = `
|
|
|
32635
32688
|
gl_FragColor = vec4(color, 1.0);
|
|
32636
32689
|
}
|
|
32637
32690
|
`;
|
|
32638
|
-
function
|
|
32639
|
-
|
|
32640
|
-
|
|
32641
|
-
|
|
32642
|
-
|
|
32643
|
-
|
|
32644
|
-
|
|
32645
|
-
|
|
32646
|
-
const size = bounds.getSize(new Vector3());
|
|
32647
|
-
const pad = Math.max(size.x, size.y, size.z, 1) * 1e-5;
|
|
32648
|
-
bounds.expandByScalar(pad);
|
|
32649
|
-
return bounds;
|
|
32650
|
-
}
|
|
32651
|
-
function buildSampleGrid(pointCloud) {
|
|
32652
|
-
const sampleCount = Math.floor(pointCloud.positions.length / 3);
|
|
32653
|
-
if (sampleCount <= 0) return null;
|
|
32654
|
-
const bounds = new Box3();
|
|
32655
|
-
const point = new Vector3();
|
|
32656
|
-
for (let sample = 0; sample < sampleCount; sample += 1) {
|
|
32657
|
-
const offset = sample * 3;
|
|
32658
|
-
bounds.expandByPoint(point.set(pointCloud.positions[offset], pointCloud.positions[offset + 1], pointCloud.positions[offset + 2]));
|
|
32659
|
-
}
|
|
32660
|
-
const size = bounds.getSize(new Vector3());
|
|
32661
|
-
const maxDim = Math.max(size.x, size.y, size.z);
|
|
32662
|
-
const cellSize = maxDim > 0 ? Math.max(maxDim / Math.cbrt(sampleCount), 1e-6) : 1;
|
|
32663
|
-
const cells = /* @__PURE__ */ new Map();
|
|
32664
|
-
for (let sample = 0; sample < sampleCount; sample += 1) {
|
|
32665
|
-
const offset = sample * 3;
|
|
32666
|
-
const x = Math.floor((pointCloud.positions[offset] - bounds.min.x) / cellSize);
|
|
32667
|
-
const y = Math.floor((pointCloud.positions[offset + 1] - bounds.min.y) / cellSize);
|
|
32668
|
-
const z = Math.floor((pointCloud.positions[offset + 2] - bounds.min.z) / cellSize);
|
|
32669
|
-
const key = gridKey(x, y, z);
|
|
32670
|
-
const entries = cells.get(key);
|
|
32671
|
-
if (entries) {
|
|
32672
|
-
entries.push(sample);
|
|
32673
|
-
} else {
|
|
32674
|
-
cells.set(key, [sample]);
|
|
32675
|
-
}
|
|
32676
|
-
}
|
|
32677
|
-
return { origin: bounds.min, cellSize, cells };
|
|
32678
|
-
}
|
|
32679
|
-
function fieldGridSizeForSampleCount(sampleCount) {
|
|
32680
|
-
if (sampleCount <= 0) return MIN_FIELD_GRID_SIZE;
|
|
32681
|
-
const scaled = Math.ceil(Math.cbrt(sampleCount) * 2.6);
|
|
32682
|
-
return Math.max(MIN_FIELD_GRID_SIZE, Math.min(MAX_FIELD_GRID_SIZE, scaled));
|
|
32683
|
-
}
|
|
32684
|
-
function distanceSquaredToSample(pointCloud, sample, point) {
|
|
32685
|
-
const offset = sample * 3;
|
|
32686
|
-
return (pointCloud.positions[offset] - point.x) ** 2 + (pointCloud.positions[offset + 1] - point.y) ** 2 + (pointCloud.positions[offset + 2] - point.z) ** 2;
|
|
32687
|
-
}
|
|
32688
|
-
function nearestSamples(point, pointCloud, sampleGrid) {
|
|
32689
|
-
const baseX = Math.floor((point.x - sampleGrid.origin.x) / sampleGrid.cellSize);
|
|
32690
|
-
const baseY = Math.floor((point.y - sampleGrid.origin.y) / sampleGrid.cellSize);
|
|
32691
|
-
const baseZ = Math.floor((point.z - sampleGrid.origin.z) / sampleGrid.cellSize);
|
|
32692
|
-
const found = [];
|
|
32693
|
-
for (const ring of SAMPLE_RING_OFFSETS) {
|
|
32694
|
-
for (const [dx, dy, dz] of ring) {
|
|
32695
|
-
const entries = sampleGrid.cells.get(gridKey(baseX + dx, baseY + dy, baseZ + dz));
|
|
32696
|
-
if (!entries) continue;
|
|
32697
|
-
for (const sample of entries) {
|
|
32698
|
-
found.push({ sample, distSq: distanceSquaredToSample(pointCloud, sample, point) });
|
|
32699
|
-
}
|
|
32700
|
-
}
|
|
32701
|
-
if (found.length >= MAX_BLEND_SAMPLES) break;
|
|
32702
|
-
}
|
|
32703
|
-
if (found.length === 0) {
|
|
32704
|
-
const sampleCount = Math.floor(pointCloud.positions.length / 3);
|
|
32705
|
-
for (let sample = 0; sample < sampleCount; sample += 1) {
|
|
32706
|
-
found.push({ sample, distSq: distanceSquaredToSample(pointCloud, sample, point) });
|
|
32707
|
-
}
|
|
32708
|
-
}
|
|
32709
|
-
found.sort((a2, b2) => a2.distSq - b2.distSq);
|
|
32710
|
-
return found.slice(0, MAX_BLEND_SAMPLES);
|
|
32711
|
-
}
|
|
32712
|
-
function blendedColorAt(point, pointCloud, sampleGrid) {
|
|
32713
|
-
const samples = nearestSamples(point, pointCloud, sampleGrid);
|
|
32714
|
-
if (samples.length === 0) return [90, 90, 90];
|
|
32715
|
-
const sigma = Math.max(sampleGrid.cellSize * 1.65, 1e-6);
|
|
32716
|
-
const sigmaSq = sigma * sigma;
|
|
32717
|
-
let weightSum = 0;
|
|
32718
|
-
let r2 = 0;
|
|
32719
|
-
let g2 = 0;
|
|
32720
|
-
let b2 = 0;
|
|
32721
|
-
for (const { sample, distSq } of samples) {
|
|
32722
|
-
const colorOffset = sample * 3;
|
|
32723
|
-
const weight = Math.exp(-distSq / (2 * sigmaSq)) + 1e-4 / Math.max(distSq, 1e-8);
|
|
32724
|
-
weightSum += weight;
|
|
32725
|
-
r2 += (pointCloud.colors[colorOffset] ?? 0.35) * 255 * weight;
|
|
32726
|
-
g2 += (pointCloud.colors[colorOffset + 1] ?? 0.35) * 255 * weight;
|
|
32727
|
-
b2 += (pointCloud.colors[colorOffset + 2] ?? 0.35) * 255 * weight;
|
|
32728
|
-
}
|
|
32729
|
-
if (weightSum <= 0) return [90, 90, 90];
|
|
32730
|
-
return [r2 / weightSum, g2 / weightSum, b2 / weightSum];
|
|
32731
|
-
}
|
|
32732
|
-
function buildInspectHeatmapField(geometry, pointCloud) {
|
|
32733
|
-
const bounds = buildGeometryBounds(geometry);
|
|
32734
|
-
const sampleGrid = buildSampleGrid(pointCloud);
|
|
32735
|
-
if (!bounds || !sampleGrid) return null;
|
|
32736
|
-
const gridSize = fieldGridSizeForSampleCount(Math.floor(pointCloud.positions.length / 3));
|
|
32737
|
-
const boundsSize = bounds.getSize(new Vector3());
|
|
32738
|
-
const data = new Uint8Array(gridSize * gridSize * gridSize * 4);
|
|
32739
|
-
const point = new Vector3();
|
|
32740
|
-
let dataOffset = 0;
|
|
32741
|
-
for (let y = 0; y < gridSize; y += 1) {
|
|
32742
|
-
for (let z = 0; z < gridSize; z += 1) {
|
|
32743
|
-
for (let x = 0; x < gridSize; x += 1) {
|
|
32744
|
-
point.set(
|
|
32745
|
-
bounds.min.x + boundsSize.x * x / (gridSize - 1),
|
|
32746
|
-
bounds.min.y + boundsSize.y * y / (gridSize - 1),
|
|
32747
|
-
bounds.min.z + boundsSize.z * z / (gridSize - 1)
|
|
32748
|
-
);
|
|
32749
|
-
const [r2, g2, b2] = blendedColorAt(point, pointCloud, sampleGrid);
|
|
32750
|
-
data[dataOffset] = Math.max(0, Math.min(255, Math.round(r2)));
|
|
32751
|
-
data[dataOffset + 1] = Math.max(0, Math.min(255, Math.round(g2)));
|
|
32752
|
-
data[dataOffset + 2] = Math.max(0, Math.min(255, Math.round(b2)));
|
|
32753
|
-
data[dataOffset + 3] = 255;
|
|
32754
|
-
dataOffset += 4;
|
|
32755
|
-
}
|
|
32756
|
-
}
|
|
32757
|
-
}
|
|
32758
|
-
const texture = new DataTexture(data, gridSize * gridSize, gridSize, RGBAFormat, UnsignedByteType);
|
|
32691
|
+
function createInspectHeatmapField(field) {
|
|
32692
|
+
const texture = new DataTexture(
|
|
32693
|
+
field.data,
|
|
32694
|
+
field.gridSize * field.gridSize,
|
|
32695
|
+
field.gridSize,
|
|
32696
|
+
RGBAFormat,
|
|
32697
|
+
UnsignedByteType
|
|
32698
|
+
);
|
|
32759
32699
|
texture.minFilter = NearestFilter;
|
|
32760
32700
|
texture.magFilter = NearestFilter;
|
|
32761
32701
|
texture.generateMipmaps = false;
|
|
@@ -32763,11 +32703,72 @@ function buildInspectHeatmapField(geometry, pointCloud) {
|
|
|
32763
32703
|
texture.needsUpdate = true;
|
|
32764
32704
|
return {
|
|
32765
32705
|
texture,
|
|
32766
|
-
boundsMin:
|
|
32767
|
-
boundsSize,
|
|
32768
|
-
gridSize
|
|
32706
|
+
boundsMin: new Vector3(...field.boundsMin),
|
|
32707
|
+
boundsSize: new Vector3(...field.boundsSize),
|
|
32708
|
+
gridSize: field.gridSize
|
|
32769
32709
|
};
|
|
32770
32710
|
}
|
|
32711
|
+
function fieldKindUniform(kind) {
|
|
32712
|
+
return kind === "hybrid" ? 1 : 0;
|
|
32713
|
+
}
|
|
32714
|
+
function SurfaceFieldMaterial({
|
|
32715
|
+
field,
|
|
32716
|
+
color: color2,
|
|
32717
|
+
clippingPlanes,
|
|
32718
|
+
fieldScale
|
|
32719
|
+
}) {
|
|
32720
|
+
const uniforms = reactExports.useMemo(
|
|
32721
|
+
() => ({
|
|
32722
|
+
uAccentColor: { value: new Color(field.accentColor) },
|
|
32723
|
+
uBaseColor: { value: new Color(field.baseColor) },
|
|
32724
|
+
uDarkColor: { value: new Color(field.darkColor) },
|
|
32725
|
+
uFieldKind: { value: fieldKindUniform(field.kind) },
|
|
32726
|
+
uFieldScale: { value: fieldScale },
|
|
32727
|
+
uGlow: { value: field.glow },
|
|
32728
|
+
uLineColor: { value: new Color(field.lineColor) },
|
|
32729
|
+
uLineWidth: { value: field.lineWidth },
|
|
32730
|
+
uNodeColor: { value: new Color(field.nodeColor) },
|
|
32731
|
+
uObjectColor: { value: new Color(color2) },
|
|
32732
|
+
uObjectColorMix: { value: field.objectColorMix },
|
|
32733
|
+
uSpacing: { value: field.spacing }
|
|
32734
|
+
}),
|
|
32735
|
+
[color2, field, fieldScale]
|
|
32736
|
+
);
|
|
32737
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32738
|
+
"shaderMaterial",
|
|
32739
|
+
{
|
|
32740
|
+
vertexShader: SURFACE_FIELD_VERTEX_SHADER,
|
|
32741
|
+
fragmentShader: SURFACE_FIELD_FRAGMENT_SHADER,
|
|
32742
|
+
uniforms,
|
|
32743
|
+
side: DoubleSide,
|
|
32744
|
+
toneMapped: false,
|
|
32745
|
+
clippingPlanes
|
|
32746
|
+
}
|
|
32747
|
+
);
|
|
32748
|
+
}
|
|
32749
|
+
function ZebraInspectionMaterial({ clippingPlanes }) {
|
|
32750
|
+
const uniforms = reactExports.useMemo(
|
|
32751
|
+
() => ({
|
|
32752
|
+
uAccentColor: { value: new Color(ZEBRA_ACCENT_COLOR) },
|
|
32753
|
+
uDarkColor: { value: new Color(ZEBRA_DARK_COLOR) },
|
|
32754
|
+
uLightColor: { value: new Color(ZEBRA_LIGHT_COLOR) },
|
|
32755
|
+
uStripeScale: { value: ZEBRA_STRIPE_SCALE },
|
|
32756
|
+
uStripeSoftness: { value: ZEBRA_STRIPE_SOFTNESS }
|
|
32757
|
+
}),
|
|
32758
|
+
[]
|
|
32759
|
+
);
|
|
32760
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32761
|
+
"shaderMaterial",
|
|
32762
|
+
{
|
|
32763
|
+
vertexShader: ZEBRA_STRIPE_VERTEX_SHADER,
|
|
32764
|
+
fragmentShader: ZEBRA_STRIPE_FRAGMENT_SHADER,
|
|
32765
|
+
uniforms,
|
|
32766
|
+
side: DoubleSide,
|
|
32767
|
+
toneMapped: false,
|
|
32768
|
+
clippingPlanes
|
|
32769
|
+
}
|
|
32770
|
+
);
|
|
32771
|
+
}
|
|
32771
32772
|
function ForgeObject({
|
|
32772
32773
|
obj,
|
|
32773
32774
|
settings,
|
|
@@ -32778,8 +32779,10 @@ function ForgeObject({
|
|
|
32778
32779
|
inspectColor,
|
|
32779
32780
|
inspectMeshColors,
|
|
32780
32781
|
inspectPointCloud,
|
|
32782
|
+
inspectHeatmapFieldData,
|
|
32781
32783
|
isInteracting,
|
|
32782
32784
|
matrix,
|
|
32785
|
+
surfaceFieldScale,
|
|
32783
32786
|
isHovered,
|
|
32784
32787
|
clippingPlanes,
|
|
32785
32788
|
debugHighlightColor,
|
|
@@ -32825,15 +32828,16 @@ function ForgeObject({
|
|
|
32825
32828
|
if (!solidGeo || !inspectMeshColors) return null;
|
|
32826
32829
|
const position = solidGeo.getAttribute("position");
|
|
32827
32830
|
if (!position || inspectMeshColors.length !== position.count * 3) return null;
|
|
32831
|
+
if (inspectChannel === "floating") return geometryWithVisibleVertexColors(solidGeo, inspectMeshColors);
|
|
32828
32832
|
const geometry = solidGeo.clone();
|
|
32829
32833
|
geometry.setAttribute("color", new BufferAttribute(inspectMeshColors, 3));
|
|
32830
32834
|
return geometry;
|
|
32831
|
-
}, [inspectMeshColors, solidGeo]);
|
|
32835
|
+
}, [inspectChannel, inspectMeshColors, solidGeo]);
|
|
32832
32836
|
const isScalarInspect = inspectChannel === "thickness" || inspectChannel === "roughness";
|
|
32833
32837
|
const inspectHeatmapField = reactExports.useMemo(() => {
|
|
32834
|
-
if (!isScalarInspect || !
|
|
32835
|
-
return
|
|
32836
|
-
}, [
|
|
32838
|
+
if (!isScalarInspect || !inspectHeatmapFieldData) return null;
|
|
32839
|
+
return createInspectHeatmapField(inspectHeatmapFieldData);
|
|
32840
|
+
}, [inspectHeatmapFieldData, isScalarInspect]);
|
|
32837
32841
|
reactExports.useEffect(() => {
|
|
32838
32842
|
return () => {
|
|
32839
32843
|
solidGeo == null ? void 0 : solidGeo.dispose();
|
|
@@ -32861,11 +32865,13 @@ function ForgeObject({
|
|
|
32861
32865
|
const showInspectHeatmap = Boolean(
|
|
32862
32866
|
isScalarInspect && inspectHeatmapField && (inspectDisplayMode === "heatmap" || inspectDisplayMode === "both")
|
|
32863
32867
|
);
|
|
32868
|
+
const showScalarContextMesh = Boolean(isScalarInspect && !showInspectHeatmap);
|
|
32864
32869
|
const showInspectPoints = Boolean(
|
|
32865
32870
|
isScalarInspect && inspectPointGeo && (inspectDisplayMode === "points" || inspectDisplayMode === "both")
|
|
32866
32871
|
);
|
|
32867
32872
|
const renderStylePreset = getRenderStylePreset(renderStyle);
|
|
32868
32873
|
const materialDefaults = renderStylePreset.material;
|
|
32874
|
+
const surfaceField = renderStylePreset.surfaceField;
|
|
32869
32875
|
const authoredMaterialOpacity = (_a3 = obj.materialProps) == null ? void 0 : _a3.opacity;
|
|
32870
32876
|
const authoredMaterialTransmission = (_b2 = obj.materialProps) == null ? void 0 : _b2.transmission;
|
|
32871
32877
|
const hasAuthoredTransparency = authoredMaterialOpacity !== void 0 && authoredMaterialOpacity < 0.99 || authoredMaterialTransmission !== void 0 && authoredMaterialTransmission > 0;
|
|
@@ -32881,6 +32887,8 @@ function ForgeObject({
|
|
|
32881
32887
|
const effectiveClippingPlanes = clippingPlanes ?? [];
|
|
32882
32888
|
const inspectSolidGeo = inspectMeshColorGeo ?? solidGeo;
|
|
32883
32889
|
const hasInspectMeshColors = inspectMeshColorGeo !== null;
|
|
32890
|
+
const showFloatingContext = showSolid && inspectChannel === "floating";
|
|
32891
|
+
const showFloatingObject = inspectChannel !== "floating" || hasInspectMeshColors || inspectColor !== "#000000";
|
|
32884
32892
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32885
32893
|
"group",
|
|
32886
32894
|
{
|
|
@@ -32893,17 +32901,42 @@ function ForgeObject({
|
|
|
32893
32901
|
onDoubleClick,
|
|
32894
32902
|
onContextMenu,
|
|
32895
32903
|
children: [
|
|
32896
|
-
|
|
32904
|
+
showFloatingContext && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, renderOrder: 1, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32905
|
+
"meshBasicMaterial",
|
|
32906
|
+
{
|
|
32907
|
+
color: rgbToHex(FLOATING_CONTEXT_COLOR),
|
|
32908
|
+
transparent: true,
|
|
32909
|
+
opacity: 0.18,
|
|
32910
|
+
side: DoubleSide,
|
|
32911
|
+
depthWrite: false,
|
|
32912
|
+
toneMapped: false,
|
|
32913
|
+
clippingPlanes: effectiveClippingPlanes
|
|
32914
|
+
}
|
|
32915
|
+
) }),
|
|
32916
|
+
showSolid && (inspectChannel === "mask" || inspectChannel === "connectivity" || inspectChannel === "floating" || inspectChannel === "distance") && showFloatingObject && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: inspectSolidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32897
32917
|
"meshBasicMaterial",
|
|
32898
32918
|
{
|
|
32899
32919
|
color: hasInspectMeshColors ? "#ffffff" : inspectColor ?? settings.color,
|
|
32900
32920
|
vertexColors: hasInspectMeshColors,
|
|
32901
32921
|
side: DoubleSide,
|
|
32902
32922
|
toneMapped: false,
|
|
32923
|
+
clippingPlanes: effectiveClippingPlanes,
|
|
32924
|
+
polygonOffset: inspectChannel === "floating",
|
|
32925
|
+
polygonOffsetFactor: -1,
|
|
32926
|
+
polygonOffsetUnits: -1
|
|
32927
|
+
}
|
|
32928
|
+
) }),
|
|
32929
|
+
showSolid && inspectChannel === "normals" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32930
|
+
"meshNormalMaterial",
|
|
32931
|
+
{
|
|
32932
|
+
flatShading: !hasSmoothNormals,
|
|
32933
|
+
side: DoubleSide,
|
|
32934
|
+
toneMapped: false,
|
|
32903
32935
|
clippingPlanes: effectiveClippingPlanes
|
|
32904
32936
|
}
|
|
32905
32937
|
) }),
|
|
32906
|
-
showSolid &&
|
|
32938
|
+
showSolid && inspectChannel === "zebra" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ZebraInspectionMaterial, { clippingPlanes: effectiveClippingPlanes }) }),
|
|
32939
|
+
showSolid && showScalarContextMesh && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, renderOrder: 3, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32907
32940
|
"meshBasicMaterial",
|
|
32908
32941
|
{
|
|
32909
32942
|
color: "#26313a",
|
|
@@ -32931,7 +32964,7 @@ function ForgeObject({
|
|
|
32931
32964
|
clippingPlanes: effectiveClippingPlanes
|
|
32932
32965
|
}
|
|
32933
32966
|
) }),
|
|
32934
|
-
|
|
32967
|
+
showInspectPoints && inspectPointGeo && /* @__PURE__ */ jsxRuntimeExports.jsx("points", { geometry: inspectPointGeo, raycast: () => null, renderOrder: 5, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32935
32968
|
"pointsMaterial",
|
|
32936
32969
|
{
|
|
32937
32970
|
size: 3,
|
|
@@ -32956,7 +32989,15 @@ function ForgeObject({
|
|
|
32956
32989
|
clippingPlanes: effectiveClippingPlanes
|
|
32957
32990
|
}
|
|
32958
32991
|
) }),
|
|
32959
|
-
showSolid && inspectChannel === "none" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32992
|
+
showSolid && inspectChannel === "none" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: surfaceField.enabled ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32993
|
+
SurfaceFieldMaterial,
|
|
32994
|
+
{
|
|
32995
|
+
field: surfaceField,
|
|
32996
|
+
color: settings.color,
|
|
32997
|
+
clippingPlanes: effectiveClippingPlanes,
|
|
32998
|
+
fieldScale: surfaceFieldScale
|
|
32999
|
+
}
|
|
33000
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32960
33001
|
"meshPhysicalMaterial",
|
|
32961
33002
|
{
|
|
32962
33003
|
color: settings.color,
|
|
@@ -33315,6 +33356,263 @@ function HoveredJointOverlay({ state: state2, config }) {
|
|
|
33315
33356
|
] })
|
|
33316
33357
|
] });
|
|
33317
33358
|
}
|
|
33359
|
+
function colorToHex(color2) {
|
|
33360
|
+
return rgbToHex(color2);
|
|
33361
|
+
}
|
|
33362
|
+
function fmt(value) {
|
|
33363
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
33364
|
+
}
|
|
33365
|
+
function inspectionLegendDefinitionFor(channel) {
|
|
33366
|
+
switch (channel) {
|
|
33367
|
+
case "mask":
|
|
33368
|
+
return {
|
|
33369
|
+
title: "Mask Colors",
|
|
33370
|
+
summary: "Each color identifies a different top-level object for picking or image analysis.",
|
|
33371
|
+
swatches: [
|
|
33372
|
+
{ label: "Object A", detail: "unique id", color: rgbToHex(maskRgbForIndex(0)) },
|
|
33373
|
+
{ label: "Object B", detail: "unique id", color: rgbToHex(maskRgbForIndex(1)) },
|
|
33374
|
+
{ label: "Object C", detail: "unique id", color: rgbToHex(maskRgbForIndex(2)) },
|
|
33375
|
+
{ label: "Object D", detail: "unique id", color: rgbToHex(maskRgbForIndex(3)) }
|
|
33376
|
+
]
|
|
33377
|
+
};
|
|
33378
|
+
case "normals":
|
|
33379
|
+
return {
|
|
33380
|
+
title: "Normal Colors",
|
|
33381
|
+
summary: "Color comes from surface direction in view space, so seams and flipped normals become visible."
|
|
33382
|
+
};
|
|
33383
|
+
case "zebra":
|
|
33384
|
+
return {
|
|
33385
|
+
title: "Zebra Stripes",
|
|
33386
|
+
summary: "Continuous stripes imply smooth surface flow; kinks or broken stripes reveal continuity changes."
|
|
33387
|
+
};
|
|
33388
|
+
case "connectivity":
|
|
33389
|
+
return {
|
|
33390
|
+
title: "Connected Bodies",
|
|
33391
|
+
summary: "Each color is one physically connected component. Different colors mean disconnected islands.",
|
|
33392
|
+
swatches: [
|
|
33393
|
+
{ label: "Component 1", detail: "connected", color: rgbToHex(maskRgbForIndex(0)) },
|
|
33394
|
+
{ label: "Component 2", detail: "separate", color: rgbToHex(maskRgbForIndex(1)) },
|
|
33395
|
+
{ label: "Component 3", detail: "separate", color: rgbToHex(maskRgbForIndex(2)) }
|
|
33396
|
+
]
|
|
33397
|
+
};
|
|
33398
|
+
case "floating":
|
|
33399
|
+
return {
|
|
33400
|
+
title: "Floating Bodies",
|
|
33401
|
+
summary: "Highlights bodies that are disconnected from grounded material above the build plane.",
|
|
33402
|
+
swatches: [
|
|
33403
|
+
{ label: "Floating", detail: "unsupported", color: rgbToHex(FLOATING_HIGHLIGHT_COLOR) },
|
|
33404
|
+
{ label: "Context", detail: "other geometry", color: rgbToHex(FLOATING_CONTEXT_COLOR) }
|
|
33405
|
+
]
|
|
33406
|
+
};
|
|
33407
|
+
case "distance":
|
|
33408
|
+
return {
|
|
33409
|
+
title: "Root Distance",
|
|
33410
|
+
summary: "Shows how far each disconnected component is from the rooted component graph.",
|
|
33411
|
+
ramp: {
|
|
33412
|
+
colors: [rgbToHex(DISTANCE_NEAR_COLOR), rgbToHex(DISTANCE_MID_COLOR), rgbToHex(DISTANCE_FAR_COLOR)],
|
|
33413
|
+
leftLabel: "Near root",
|
|
33414
|
+
centerLabel: "Mid",
|
|
33415
|
+
rightLabel: "Far"
|
|
33416
|
+
},
|
|
33417
|
+
swatches: [{ label: "Unknown", detail: "not resolved", color: rgbToHex(DISTANCE_UNKNOWN_COLOR) }]
|
|
33418
|
+
};
|
|
33419
|
+
case "collisions":
|
|
33420
|
+
return {
|
|
33421
|
+
title: "Collision Overlaps",
|
|
33422
|
+
summary: "Bright solids are actual overlap volumes; source bodies are ghosted behind them.",
|
|
33423
|
+
swatches: [
|
|
33424
|
+
{ label: "Overlap", detail: "intersecting volume", color: rgbToHex(COLLISION_HIGHLIGHT_COLOR) },
|
|
33425
|
+
{ label: "Ghost body", detail: "source geometry", color: rgbToHex(COLLISION_SOURCE_COLOR) }
|
|
33426
|
+
]
|
|
33427
|
+
};
|
|
33428
|
+
case "thickness": {
|
|
33429
|
+
const options = DEFAULT_THICKNESS_INSPECTION_OPTIONS;
|
|
33430
|
+
return {
|
|
33431
|
+
title: "Wall Thickness",
|
|
33432
|
+
summary: "Red/orange is thin material. Green/blue has more printable or machinable thickness.",
|
|
33433
|
+
ramp: {
|
|
33434
|
+
colors: [
|
|
33435
|
+
colorToHex(THICKNESS_COLORS.critical),
|
|
33436
|
+
colorToHex(THICKNESS_COLORS.warning),
|
|
33437
|
+
colorToHex(THICKNESS_COLORS.ok),
|
|
33438
|
+
colorToHex(THICKNESS_COLORS.thick)
|
|
33439
|
+
],
|
|
33440
|
+
leftLabel: `<= ${fmt(options.minThickness)} mm`,
|
|
33441
|
+
centerLabel: `${fmt(options.warnThickness)} mm warn`,
|
|
33442
|
+
rightLabel: `>= ${fmt(options.maxThickness)} mm`
|
|
33443
|
+
}
|
|
33444
|
+
};
|
|
33445
|
+
}
|
|
33446
|
+
case "roughness": {
|
|
33447
|
+
const options = DEFAULT_ROUGHNESS_INSPECTION_OPTIONS;
|
|
33448
|
+
return {
|
|
33449
|
+
title: "Surface Roughness",
|
|
33450
|
+
summary: "Color follows local angle change. Dark is smooth; warmer colors mean sharper or harsher mesh transitions.",
|
|
33451
|
+
swatches: [
|
|
33452
|
+
{ label: "Smooth", detail: `< ${fmt(options.smoothAngleDeg)} deg`, color: colorToHex(ROUGHNESS_COLORS.smooth) },
|
|
33453
|
+
{
|
|
33454
|
+
label: "Moderate",
|
|
33455
|
+
detail: `${fmt(options.smoothAngleDeg)}-${fmt(options.sharpAngleDeg)} deg`,
|
|
33456
|
+
color: colorToHex(ROUGHNESS_COLORS.moderate)
|
|
33457
|
+
},
|
|
33458
|
+
{
|
|
33459
|
+
label: "Sharp",
|
|
33460
|
+
detail: `${fmt(options.sharpAngleDeg)}-${fmt(options.harshAngleDeg)} deg`,
|
|
33461
|
+
color: colorToHex(ROUGHNESS_COLORS.sharp)
|
|
33462
|
+
},
|
|
33463
|
+
{ label: "Harsh", detail: `>= ${fmt(options.harshAngleDeg)} deg`, color: colorToHex(ROUGHNESS_COLORS.harsh) }
|
|
33464
|
+
]
|
|
33465
|
+
};
|
|
33466
|
+
}
|
|
33467
|
+
default:
|
|
33468
|
+
return null;
|
|
33469
|
+
}
|
|
33470
|
+
}
|
|
33471
|
+
const panelStyle = {
|
|
33472
|
+
position: "absolute",
|
|
33473
|
+
left: 12,
|
|
33474
|
+
bottom: 12,
|
|
33475
|
+
width: "min(300px, calc(100% - 24px))",
|
|
33476
|
+
padding: "9px 10px",
|
|
33477
|
+
borderRadius: 8,
|
|
33478
|
+
border: "1px solid color-mix(in srgb, var(--fc-border) 86%, transparent)",
|
|
33479
|
+
background: "color-mix(in srgb, var(--fc-bgPanel) 92%, transparent)",
|
|
33480
|
+
boxShadow: "0 10px 26px rgba(0, 0, 0, 0.22)",
|
|
33481
|
+
color: "var(--fc-text)",
|
|
33482
|
+
fontSize: 11,
|
|
33483
|
+
lineHeight: 1.35,
|
|
33484
|
+
pointerEvents: "none",
|
|
33485
|
+
zIndex: 9
|
|
33486
|
+
};
|
|
33487
|
+
const titleStyle = {
|
|
33488
|
+
display: "flex",
|
|
33489
|
+
alignItems: "center",
|
|
33490
|
+
justifyContent: "space-between",
|
|
33491
|
+
gap: 8,
|
|
33492
|
+
marginBottom: 5,
|
|
33493
|
+
color: "var(--fc-text)",
|
|
33494
|
+
fontSize: 11,
|
|
33495
|
+
fontWeight: 700,
|
|
33496
|
+
letterSpacing: 0
|
|
33497
|
+
};
|
|
33498
|
+
const summaryStyle = {
|
|
33499
|
+
marginBottom: 7,
|
|
33500
|
+
color: "var(--fc-textDim)",
|
|
33501
|
+
overflowWrap: "anywhere"
|
|
33502
|
+
};
|
|
33503
|
+
const swatchGridStyle = {
|
|
33504
|
+
display: "grid",
|
|
33505
|
+
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
33506
|
+
gap: 6
|
|
33507
|
+
};
|
|
33508
|
+
function Ramp({ compact, ramp }) {
|
|
33509
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { minWidth: 0 }, children: [
|
|
33510
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33511
|
+
"div",
|
|
33512
|
+
{
|
|
33513
|
+
style: {
|
|
33514
|
+
height: 9,
|
|
33515
|
+
borderRadius: 999,
|
|
33516
|
+
border: "1px solid rgba(255, 255, 255, 0.24)",
|
|
33517
|
+
background: `linear-gradient(90deg, ${ramp.colors.join(", ")})`
|
|
33518
|
+
}
|
|
33519
|
+
}
|
|
33520
|
+
),
|
|
33521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
33522
|
+
"div",
|
|
33523
|
+
{
|
|
33524
|
+
style: {
|
|
33525
|
+
display: "grid",
|
|
33526
|
+
gridTemplateColumns: ramp.centerLabel ? "repeat(3, minmax(0, 1fr))" : "repeat(2, minmax(0, 1fr))",
|
|
33527
|
+
gap: 6,
|
|
33528
|
+
marginTop: 4,
|
|
33529
|
+
color: "var(--fc-textDim)",
|
|
33530
|
+
fontSize: compact ? 9 : 10
|
|
33531
|
+
},
|
|
33532
|
+
children: [
|
|
33533
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: ramp.leftLabel }),
|
|
33534
|
+
ramp.centerLabel && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { textAlign: "center" }, children: ramp.centerLabel }),
|
|
33535
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { textAlign: "right" }, children: ramp.rightLabel })
|
|
33536
|
+
]
|
|
33537
|
+
}
|
|
33538
|
+
)
|
|
33539
|
+
] });
|
|
33540
|
+
}
|
|
33541
|
+
function Swatch({ item }) {
|
|
33542
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "grid", gridTemplateColumns: "12px minmax(0, 1fr)", alignItems: "center", gap: 6, minWidth: 0 }, children: [
|
|
33543
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33544
|
+
"span",
|
|
33545
|
+
{
|
|
33546
|
+
style: {
|
|
33547
|
+
width: 12,
|
|
33548
|
+
height: 12,
|
|
33549
|
+
borderRadius: 3,
|
|
33550
|
+
border: "1px solid rgba(255, 255, 255, 0.28)",
|
|
33551
|
+
background: item.color
|
|
33552
|
+
}
|
|
33553
|
+
}
|
|
33554
|
+
),
|
|
33555
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: [
|
|
33556
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--fc-text)" }, children: item.label }),
|
|
33557
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { color: "var(--fc-textDim)" }, children: [
|
|
33558
|
+
" - ",
|
|
33559
|
+
item.detail
|
|
33560
|
+
] })
|
|
33561
|
+
] })
|
|
33562
|
+
] });
|
|
33563
|
+
}
|
|
33564
|
+
function InspectionLegend({ channel, warnings }) {
|
|
33565
|
+
const panelRef = reactExports.useRef(null);
|
|
33566
|
+
const [compact, setCompact] = reactExports.useState(false);
|
|
33567
|
+
const definition = inspectionLegendDefinitionFor(channel);
|
|
33568
|
+
reactExports.useEffect(() => {
|
|
33569
|
+
var _a3;
|
|
33570
|
+
const parent = (_a3 = panelRef.current) == null ? void 0 : _a3.parentElement;
|
|
33571
|
+
if (!parent || typeof ResizeObserver === "undefined") return;
|
|
33572
|
+
const updateCompact = () => setCompact(parent.clientWidth < 260);
|
|
33573
|
+
updateCompact();
|
|
33574
|
+
const observer = new ResizeObserver(updateCompact);
|
|
33575
|
+
observer.observe(parent);
|
|
33576
|
+
return () => observer.disconnect();
|
|
33577
|
+
}, [channel]);
|
|
33578
|
+
if (!definition) return null;
|
|
33579
|
+
const warning = warnings[0];
|
|
33580
|
+
const effectivePanelStyle = compact ? { ...panelStyle, padding: "7px 8px" } : panelStyle;
|
|
33581
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: panelRef, className: "fc-inspection-legend", style: effectivePanelStyle, children: [
|
|
33582
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: titleStyle, children: [
|
|
33583
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: definition.title }),
|
|
33584
|
+
warning && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--fc-warning)", fontSize: 10 }, children: "Warning" })
|
|
33585
|
+
] }),
|
|
33586
|
+
!compact && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: summaryStyle, children: definition.summary }),
|
|
33587
|
+
definition.ramp && /* @__PURE__ */ jsxRuntimeExports.jsx(Ramp, { compact, ramp: definition.ramp }),
|
|
33588
|
+
definition.swatches && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33589
|
+
"div",
|
|
33590
|
+
{
|
|
33591
|
+
style: {
|
|
33592
|
+
...swatchGridStyle,
|
|
33593
|
+
gridTemplateColumns: compact ? "minmax(0, 1fr)" : swatchGridStyle.gridTemplateColumns,
|
|
33594
|
+
marginTop: definition.ramp ? 8 : 0
|
|
33595
|
+
},
|
|
33596
|
+
children: definition.swatches.map((item) => /* @__PURE__ */ jsxRuntimeExports.jsx(Swatch, { item }, `${item.label}:${item.detail}`))
|
|
33597
|
+
}
|
|
33598
|
+
),
|
|
33599
|
+
warning && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
33600
|
+
"div",
|
|
33601
|
+
{
|
|
33602
|
+
style: {
|
|
33603
|
+
marginTop: 7,
|
|
33604
|
+
paddingTop: 7,
|
|
33605
|
+
borderTop: "1px solid color-mix(in srgb, var(--fc-border) 72%, transparent)",
|
|
33606
|
+
color: "var(--fc-warning)",
|
|
33607
|
+
overflow: "hidden",
|
|
33608
|
+
textOverflow: "ellipsis",
|
|
33609
|
+
whiteSpace: "nowrap"
|
|
33610
|
+
},
|
|
33611
|
+
children: warning
|
|
33612
|
+
}
|
|
33613
|
+
)
|
|
33614
|
+
] });
|
|
33615
|
+
}
|
|
33318
33616
|
function LabeledAxes({ size = 50 }) {
|
|
33319
33617
|
const axesRef = reactExports.useRef(null);
|
|
33320
33618
|
reactExports.useEffect(() => {
|
|
@@ -38548,11 +38846,13 @@ function useViewportState() {
|
|
|
38548
38846
|
const files = useForgeStore((s) => s.files);
|
|
38549
38847
|
const renderMode = useForgeStore((s) => s.renderMode);
|
|
38550
38848
|
const renderStyle = useForgeStore((s) => s.renderStyle);
|
|
38849
|
+
const manualScene = useForgeStore((s) => s.manualScene);
|
|
38551
38850
|
const inspectChannel = useForgeStore((s) => s.inspectChannel);
|
|
38552
38851
|
const inspectDisplayMode = useForgeStore((s) => s.inspectDisplayMode);
|
|
38553
38852
|
const inspectPointSampleCount = useForgeStore((s) => s.inspectPointSampleCount);
|
|
38554
38853
|
const projectionMode = useForgeStore((s) => s.projectionMode);
|
|
38555
38854
|
const gridEnabled = useForgeStore((s) => s.gridEnabled);
|
|
38855
|
+
const axesVisible = useForgeStore((s) => s.axesVisible);
|
|
38556
38856
|
const gridSize = useForgeStore((s) => s.gridSize);
|
|
38557
38857
|
const showPerformanceInfo = useForgeStore((s) => s.showPerformanceInfo);
|
|
38558
38858
|
const objectSettings = useForgeStore((s) => s.objectSettings);
|
|
@@ -38713,6 +39013,26 @@ function useViewportState() {
|
|
|
38713
39013
|
});
|
|
38714
39014
|
return hasBounds ? bounds.min.z : null;
|
|
38715
39015
|
}, [objects, objectMatrices]);
|
|
39016
|
+
const surfaceFieldScale = reactExports.useMemo(() => {
|
|
39017
|
+
const bounds = new Box3();
|
|
39018
|
+
let hasBounds = false;
|
|
39019
|
+
objects.forEach((obj) => {
|
|
39020
|
+
var _a3;
|
|
39021
|
+
if (((_a3 = objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) return;
|
|
39022
|
+
const matrix = objectMatrices[obj.id] ?? new Matrix4();
|
|
39023
|
+
if (obj.shape) {
|
|
39024
|
+
try {
|
|
39025
|
+
const bb = obj.shape.boundingBox();
|
|
39026
|
+
if (expandBoundsByTransformedAabb(bounds, bb.min, bb.max, matrix)) hasBounds = true;
|
|
39027
|
+
} catch {
|
|
39028
|
+
}
|
|
39029
|
+
}
|
|
39030
|
+
});
|
|
39031
|
+
if (!hasBounds) return 1;
|
|
39032
|
+
const size = bounds.getSize(new Vector3());
|
|
39033
|
+
const maxDim = Math.max(size.x, size.y, size.z);
|
|
39034
|
+
return Number.isFinite(maxDim) && maxDim > 0 ? maxDim / 5 : 1;
|
|
39035
|
+
}, [objectMatrices, objects, objectSettings]);
|
|
38716
39036
|
useJointAnimationLoop(activeJointAnimation);
|
|
38717
39037
|
const anySectionActive = activeCutPlaneDefs.length > 0;
|
|
38718
39038
|
const sectionGuideBoundsKey = (sectionPlaneGuidesEnabled || sectionExplorerEnabled) && anySectionActive ? objectMatrices : null;
|
|
@@ -38877,11 +39197,13 @@ function useViewportState() {
|
|
|
38877
39197
|
files,
|
|
38878
39198
|
renderMode,
|
|
38879
39199
|
renderStyle,
|
|
39200
|
+
manualScene,
|
|
38880
39201
|
inspectChannel,
|
|
38881
39202
|
inspectDisplayMode,
|
|
38882
39203
|
inspectPointSampleCount,
|
|
38883
39204
|
projectionMode,
|
|
38884
39205
|
gridEnabled,
|
|
39206
|
+
axesVisible,
|
|
38885
39207
|
gridSize,
|
|
38886
39208
|
showPerformanceInfo,
|
|
38887
39209
|
objectSettings,
|
|
@@ -38954,6 +39276,7 @@ function useViewportState() {
|
|
|
38954
39276
|
jointsConfig,
|
|
38955
39277
|
sceneConfig,
|
|
38956
39278
|
modelBoundsMinZ,
|
|
39279
|
+
surfaceFieldScale,
|
|
38957
39280
|
focusedObjectIdSet,
|
|
38958
39281
|
visibleSceneObjectCount,
|
|
38959
39282
|
visibleModelTriangles,
|
|
@@ -40259,7 +40582,7 @@ function RenderLabelsOverlay({ labels }) {
|
|
|
40259
40582
|
class InspectWorkerClient {
|
|
40260
40583
|
constructor(workerFactory = () => new Worker(new URL(
|
|
40261
40584
|
/* @vite-ignore */
|
|
40262
|
-
"/assets/inspectWorker-
|
|
40585
|
+
"/assets/inspectWorker-BZ2CkQZr.js",
|
|
40263
40586
|
import.meta.url
|
|
40264
40587
|
), { type: "module" })) {
|
|
40265
40588
|
__publicField(this, "worker", null);
|
|
@@ -40319,10 +40642,11 @@ class InspectWorkerClient {
|
|
|
40319
40642
|
}
|
|
40320
40643
|
}
|
|
40321
40644
|
const inspectWorkerClient = new InspectWorkerClient();
|
|
40322
|
-
const WORKER_CHANNELS = /* @__PURE__ */ new Set(["thickness", "roughness", "connectivity", "distance"]);
|
|
40645
|
+
const WORKER_CHANNELS = /* @__PURE__ */ new Set(["thickness", "roughness", "connectivity", "floating", "distance"]);
|
|
40323
40646
|
const SCALAR_WORKER_CHANNELS = /* @__PURE__ */ new Set(["thickness", "roughness"]);
|
|
40324
|
-
const MESH_COMPONENT_WORKER_CHANNELS = /* @__PURE__ */ new Set(["connectivity", "distance"]);
|
|
40325
|
-
const
|
|
40647
|
+
const MESH_COMPONENT_WORKER_CHANNELS = /* @__PURE__ */ new Set(["connectivity", "floating", "distance"]);
|
|
40648
|
+
const IDENTITY_MATRIX_ELEMENTS = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
40649
|
+
const INSPECT_BUILD_YIELD_INTERVAL_MS = 8;
|
|
40326
40650
|
class InspectBuildCancelledError extends Error {
|
|
40327
40651
|
constructor() {
|
|
40328
40652
|
super("cancelled");
|
|
@@ -40334,23 +40658,34 @@ function isScalarWorkerChannel(channel) {
|
|
|
40334
40658
|
function needsMeshComponents(channel) {
|
|
40335
40659
|
return MESH_COMPONENT_WORKER_CHANNELS.has(channel);
|
|
40336
40660
|
}
|
|
40661
|
+
function shouldIncludeInspectPositions(channel, obj) {
|
|
40662
|
+
var _a3;
|
|
40663
|
+
if (isScalarWorkerChannel(channel)) return true;
|
|
40664
|
+
if (!needsMeshComponents(channel)) return false;
|
|
40665
|
+
if (channel === "floating") return true;
|
|
40666
|
+
const sources = (_a3 = obj.geometryInfo) == null ? void 0 : _a3.sources;
|
|
40667
|
+
return !((sources == null ? void 0 : sources.length) === 1 && sources[0] === "primitive");
|
|
40668
|
+
}
|
|
40337
40669
|
function viewportScalarSamplesPerObject(objectCount, inspectPointSampleCount) {
|
|
40338
40670
|
const perObjectCap = resolveInspectPointSampleCount(inspectPointSampleCount);
|
|
40339
|
-
|
|
40340
|
-
|
|
40341
|
-
|
|
40342
|
-
|
|
40671
|
+
return resolveScalarSceneSampleBudget({
|
|
40672
|
+
objectCount,
|
|
40673
|
+
maxSamplesPerObject: perObjectCap,
|
|
40674
|
+
minSamplesPerObject: INSPECT_POINT_SAMPLE_COUNT_MIN
|
|
40675
|
+
}).effectiveMaxSamplesPerObject;
|
|
40343
40676
|
}
|
|
40344
40677
|
function yieldToBrowser() {
|
|
40345
40678
|
if (typeof window === "undefined") return Promise.resolve();
|
|
40346
|
-
return new Promise((resolve2) =>
|
|
40347
|
-
|
|
40348
|
-
|
|
40349
|
-
|
|
40350
|
-
|
|
40351
|
-
|
|
40352
|
-
|
|
40353
|
-
|
|
40679
|
+
return new Promise((resolve2) => window.setTimeout(resolve2, 0));
|
|
40680
|
+
}
|
|
40681
|
+
function createBuildYield(isCancelled) {
|
|
40682
|
+
let lastYield = performance.now();
|
|
40683
|
+
return async () => {
|
|
40684
|
+
if (performance.now() - lastYield < INSPECT_BUILD_YIELD_INTERVAL_MS) return;
|
|
40685
|
+
await yieldToBrowser();
|
|
40686
|
+
if (isCancelled()) throw new InspectBuildCancelledError();
|
|
40687
|
+
lastYield = performance.now();
|
|
40688
|
+
};
|
|
40354
40689
|
}
|
|
40355
40690
|
function transformedBounds(obj, matrix) {
|
|
40356
40691
|
if (!obj.shape) return null;
|
|
@@ -40367,6 +40702,31 @@ function transformedBounds(obj, matrix) {
|
|
|
40367
40702
|
return null;
|
|
40368
40703
|
}
|
|
40369
40704
|
}
|
|
40705
|
+
function matrixIsIdentity(matrix) {
|
|
40706
|
+
if (!matrix) return true;
|
|
40707
|
+
const elements = matrix.elements;
|
|
40708
|
+
return IDENTITY_MATRIX_ELEMENTS.every((value, index) => elements[index] === value);
|
|
40709
|
+
}
|
|
40710
|
+
function clonePositionsWithOptionalTransform(source, matrix) {
|
|
40711
|
+
const positions = new Float32Array(source);
|
|
40712
|
+
if (matrixIsIdentity(matrix)) return positions;
|
|
40713
|
+
const e2 = matrix.elements;
|
|
40714
|
+
for (let index = 0; index < positions.length; index += 3) {
|
|
40715
|
+
const x = positions[index];
|
|
40716
|
+
const y = positions[index + 1];
|
|
40717
|
+
const z = positions[index + 2];
|
|
40718
|
+
const w = e2[3] * x + e2[7] * y + e2[11] * z + e2[15];
|
|
40719
|
+
positions[index] = e2[0] * x + e2[4] * y + e2[8] * z + e2[12];
|
|
40720
|
+
positions[index + 1] = e2[1] * x + e2[5] * y + e2[9] * z + e2[13];
|
|
40721
|
+
positions[index + 2] = e2[2] * x + e2[6] * y + e2[10] * z + e2[14];
|
|
40722
|
+
if (w !== 1 && w !== 0) {
|
|
40723
|
+
positions[index] /= w;
|
|
40724
|
+
positions[index + 1] /= w;
|
|
40725
|
+
positions[index + 2] /= w;
|
|
40726
|
+
}
|
|
40727
|
+
}
|
|
40728
|
+
return positions;
|
|
40729
|
+
}
|
|
40370
40730
|
function clonePositions(obj, matrix) {
|
|
40371
40731
|
var _a3;
|
|
40372
40732
|
if (!obj.shape) return void 0;
|
|
@@ -40374,17 +40734,7 @@ function clonePositions(obj, matrix) {
|
|
|
40374
40734
|
try {
|
|
40375
40735
|
const source = obj.shape instanceof FrozenShape ? obj.shape.getPrecomputedGeometry().positions : (_a3 = geometry == null ? void 0 : geometry.solid.getAttribute("position")) == null ? void 0 : _a3.array;
|
|
40376
40736
|
if (!source) return void 0;
|
|
40377
|
-
|
|
40378
|
-
if (matrix) {
|
|
40379
|
-
const point = new Vector3();
|
|
40380
|
-
for (let index = 0; index < positions.length; index += 3) {
|
|
40381
|
-
point.set(positions[index], positions[index + 1], positions[index + 2]).applyMatrix4(matrix);
|
|
40382
|
-
positions[index] = point.x;
|
|
40383
|
-
positions[index + 1] = point.y;
|
|
40384
|
-
positions[index + 2] = point.z;
|
|
40385
|
-
}
|
|
40386
|
-
}
|
|
40387
|
-
return positions;
|
|
40737
|
+
return clonePositionsWithOptionalTransform(source, matrix);
|
|
40388
40738
|
} finally {
|
|
40389
40739
|
geometry == null ? void 0 : geometry.solid.dispose();
|
|
40390
40740
|
geometry == null ? void 0 : geometry.edges.dispose();
|
|
@@ -40392,18 +40742,17 @@ function clonePositions(obj, matrix) {
|
|
|
40392
40742
|
}
|
|
40393
40743
|
async function buildWorkerObjects(args) {
|
|
40394
40744
|
var _a3;
|
|
40395
|
-
const needsMesh = isScalarWorkerChannel(args.inspectChannel) || needsMeshComponents(args.inspectChannel);
|
|
40396
40745
|
const out = [];
|
|
40746
|
+
const maybeYield = createBuildYield(args.isCancelled);
|
|
40397
40747
|
for (const obj of args.objects) {
|
|
40398
40748
|
if (args.isCancelled()) throw new InspectBuildCancelledError();
|
|
40399
40749
|
if (!obj.shape) continue;
|
|
40400
40750
|
if (((_a3 = args.objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) continue;
|
|
40401
|
-
await yieldToBrowser();
|
|
40402
|
-
if (args.isCancelled()) throw new InspectBuildCancelledError();
|
|
40403
40751
|
const matrix = args.objectMatrices[obj.id] ?? new Matrix4();
|
|
40404
40752
|
const bbox = transformedBounds(obj, matrix);
|
|
40405
40753
|
if (!bbox) continue;
|
|
40406
40754
|
if (args.isCancelled()) throw new InspectBuildCancelledError();
|
|
40755
|
+
const positions = shouldIncludeInspectPositions(args.inspectChannel, obj) ? clonePositions(obj, needsMeshComponents(args.inspectChannel) ? matrix : void 0) : void 0;
|
|
40407
40756
|
out.push({
|
|
40408
40757
|
id: obj.id,
|
|
40409
40758
|
name: obj.name,
|
|
@@ -40411,13 +40760,13 @@ async function buildWorkerObjects(args) {
|
|
|
40411
40760
|
treePath: obj.treePath,
|
|
40412
40761
|
mock: obj.mock,
|
|
40413
40762
|
bbox,
|
|
40414
|
-
...
|
|
40763
|
+
...positions ? { positions } : {}
|
|
40415
40764
|
});
|
|
40416
|
-
await
|
|
40765
|
+
await maybeYield();
|
|
40417
40766
|
}
|
|
40418
40767
|
return out;
|
|
40419
40768
|
}
|
|
40420
|
-
function analyzePayloadFor(channel, objects, inspectPointSampleCount) {
|
|
40769
|
+
function analyzePayloadFor(channel, objects, inspectPointSampleCount, groundZ) {
|
|
40421
40770
|
const maxSamplesPerObject = viewportScalarSamplesPerObject(objects.length, inspectPointSampleCount);
|
|
40422
40771
|
if (channel === "thickness") {
|
|
40423
40772
|
return {
|
|
@@ -40437,7 +40786,7 @@ function analyzePayloadFor(channel, objects, inspectPointSampleCount) {
|
|
|
40437
40786
|
}
|
|
40438
40787
|
};
|
|
40439
40788
|
}
|
|
40440
|
-
return { channel, objects };
|
|
40789
|
+
return { channel, objects, groundZ };
|
|
40441
40790
|
}
|
|
40442
40791
|
function resultToState(channel, result) {
|
|
40443
40792
|
return {
|
|
@@ -40445,6 +40794,17 @@ function resultToState(channel, result) {
|
|
|
40445
40794
|
channel,
|
|
40446
40795
|
objectColors: result.objectColors,
|
|
40447
40796
|
meshColors: Object.fromEntries(result.meshColorObjects.map((object) => [object.objectId, object.colors])),
|
|
40797
|
+
heatmapFields: Object.fromEntries(
|
|
40798
|
+
result.heatmapFieldObjects.map((object) => [
|
|
40799
|
+
object.objectId,
|
|
40800
|
+
{
|
|
40801
|
+
data: object.data,
|
|
40802
|
+
boundsMin: object.boundsMin,
|
|
40803
|
+
boundsSize: object.boundsSize,
|
|
40804
|
+
gridSize: object.gridSize
|
|
40805
|
+
}
|
|
40806
|
+
])
|
|
40807
|
+
),
|
|
40448
40808
|
pointClouds: Object.fromEntries(
|
|
40449
40809
|
result.pointObjects.map((object) => [
|
|
40450
40810
|
object.objectId,
|
|
@@ -40466,6 +40826,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40466
40826
|
objectColors: {},
|
|
40467
40827
|
meshColors: {},
|
|
40468
40828
|
pointClouds: {},
|
|
40829
|
+
heatmapFields: {},
|
|
40469
40830
|
warnings: [],
|
|
40470
40831
|
error: null
|
|
40471
40832
|
});
|
|
@@ -40478,6 +40839,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40478
40839
|
objectColors: {},
|
|
40479
40840
|
meshColors: {},
|
|
40480
40841
|
pointClouds: {},
|
|
40842
|
+
heatmapFields: {},
|
|
40481
40843
|
warnings: [],
|
|
40482
40844
|
error: null
|
|
40483
40845
|
});
|
|
@@ -40491,6 +40853,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40491
40853
|
objectColors: {},
|
|
40492
40854
|
meshColors: {},
|
|
40493
40855
|
pointClouds: {},
|
|
40856
|
+
heatmapFields: {},
|
|
40494
40857
|
warnings: [],
|
|
40495
40858
|
error: null
|
|
40496
40859
|
});
|
|
@@ -40501,7 +40864,8 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40501
40864
|
isCancelled: () => cancelled
|
|
40502
40865
|
});
|
|
40503
40866
|
if (cancelled) return;
|
|
40504
|
-
const
|
|
40867
|
+
const groundZ = typeof args.groundZ === "number" && Number.isFinite(args.groundZ) ? args.groundZ : 0;
|
|
40868
|
+
const result = await inspectWorkerClient.analyze(analyzePayloadFor(channel, objects, args.inspectPointSampleCount, groundZ));
|
|
40505
40869
|
if (cancelled) return;
|
|
40506
40870
|
setState(resultToState(args.inspectChannel, result));
|
|
40507
40871
|
} catch (error) {
|
|
@@ -40514,6 +40878,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40514
40878
|
objectColors: {},
|
|
40515
40879
|
meshColors: {},
|
|
40516
40880
|
pointClouds: {},
|
|
40881
|
+
heatmapFields: {},
|
|
40517
40882
|
warnings: [],
|
|
40518
40883
|
error: error instanceof Error ? error.message : String(error)
|
|
40519
40884
|
});
|
|
@@ -40523,9 +40888,72 @@ function useInspectWorkerAnalysis(args) {
|
|
|
40523
40888
|
cancelled = true;
|
|
40524
40889
|
inspectWorkerClient.dispose();
|
|
40525
40890
|
};
|
|
40526
|
-
}, [
|
|
40891
|
+
}, [
|
|
40892
|
+
args.inspectChannel,
|
|
40893
|
+
args.inspectPointSampleCount,
|
|
40894
|
+
args.sceneVersion,
|
|
40895
|
+
args.objects,
|
|
40896
|
+
args.objectSettings,
|
|
40897
|
+
args.objectMatrices,
|
|
40898
|
+
args.groundZ
|
|
40899
|
+
]);
|
|
40527
40900
|
return state2;
|
|
40528
40901
|
}
|
|
40902
|
+
function buildManualSceneConfig(base, manualScene, renderStylePreset) {
|
|
40903
|
+
var _a3, _b2, _c;
|
|
40904
|
+
const lights = [
|
|
40905
|
+
{ type: "ambient", color: "#ffffff", intensity: manualScene.ambientIntensity },
|
|
40906
|
+
{
|
|
40907
|
+
type: "directional",
|
|
40908
|
+
position: renderStylePreset.lights.keyPosition,
|
|
40909
|
+
color: renderStylePreset.lights.keyColor,
|
|
40910
|
+
intensity: manualScene.keyIntensity,
|
|
40911
|
+
castShadow: true
|
|
40912
|
+
},
|
|
40913
|
+
{
|
|
40914
|
+
type: "directional",
|
|
40915
|
+
position: renderStylePreset.lights.fillPosition,
|
|
40916
|
+
color: renderStylePreset.lights.fillColor,
|
|
40917
|
+
intensity: manualScene.fillIntensity
|
|
40918
|
+
}
|
|
40919
|
+
];
|
|
40920
|
+
if (manualScene.rimIntensity > 0) {
|
|
40921
|
+
lights.push({
|
|
40922
|
+
type: "directional",
|
|
40923
|
+
position: renderStylePreset.lights.rimPosition,
|
|
40924
|
+
color: renderStylePreset.lights.rimColor,
|
|
40925
|
+
intensity: manualScene.rimIntensity
|
|
40926
|
+
});
|
|
40927
|
+
}
|
|
40928
|
+
lights.push({
|
|
40929
|
+
type: "hemisphere",
|
|
40930
|
+
skyColor: renderStylePreset.lights.hemisphereSky,
|
|
40931
|
+
groundColor: manualScene.groundColor,
|
|
40932
|
+
intensity: renderStylePreset.lights.hemisphereIntensity
|
|
40933
|
+
});
|
|
40934
|
+
return {
|
|
40935
|
+
background: manualScene.backgroundColor,
|
|
40936
|
+
camera: (base == null ? void 0 : base.camera) ?? null,
|
|
40937
|
+
views: (base == null ? void 0 : base.views) ?? null,
|
|
40938
|
+
journeys: (base == null ? void 0 : base.journeys) ?? null,
|
|
40939
|
+
lights,
|
|
40940
|
+
environment: {
|
|
40941
|
+
...(base == null ? void 0 : base.environment) ?? {},
|
|
40942
|
+
preset: ((_a3 = base == null ? void 0 : base.environment) == null ? void 0 : _a3.preset) ?? "studio",
|
|
40943
|
+
intensity: manualScene.environmentIntensity,
|
|
40944
|
+
background: ((_b2 = base == null ? void 0 : base.environment) == null ? void 0 : _b2.background) ?? false
|
|
40945
|
+
},
|
|
40946
|
+
fog: (base == null ? void 0 : base.fog) ?? null,
|
|
40947
|
+
postProcessing: (base == null ? void 0 : base.postProcessing) ?? null,
|
|
40948
|
+
ground: {
|
|
40949
|
+
...(base == null ? void 0 : base.ground) ?? {},
|
|
40950
|
+
visible: manualScene.groundVisible,
|
|
40951
|
+
color: manualScene.groundColor,
|
|
40952
|
+
receiveShadow: ((_c = base == null ? void 0 : base.ground) == null ? void 0 : _c.receiveShadow) ?? true
|
|
40953
|
+
},
|
|
40954
|
+
capture: (base == null ? void 0 : base.capture) ?? null
|
|
40955
|
+
};
|
|
40956
|
+
}
|
|
40529
40957
|
function panelNumber(value) {
|
|
40530
40958
|
if (!Number.isFinite(value)) return String(value);
|
|
40531
40959
|
if (Number.isInteger(value)) return String(value);
|
|
@@ -40555,8 +40983,14 @@ function inspectChannelLabel(channel) {
|
|
|
40555
40983
|
switch (channel) {
|
|
40556
40984
|
case "connectivity":
|
|
40557
40985
|
return "Connect";
|
|
40986
|
+
case "floating":
|
|
40987
|
+
return "Floating";
|
|
40558
40988
|
case "distance":
|
|
40559
40989
|
return "Distance";
|
|
40990
|
+
case "normals":
|
|
40991
|
+
return "Normals";
|
|
40992
|
+
case "zebra":
|
|
40993
|
+
return "Zebra";
|
|
40560
40994
|
case "thickness":
|
|
40561
40995
|
return "Thickness";
|
|
40562
40996
|
case "roughness":
|
|
@@ -40650,7 +41084,7 @@ function RenderStyleExposure({ exposure }) {
|
|
|
40650
41084
|
return null;
|
|
40651
41085
|
}
|
|
40652
41086
|
function Viewport() {
|
|
40653
|
-
var _a3, _b2, _c;
|
|
41087
|
+
var _a3, _b2, _c, _d;
|
|
40654
41088
|
const activeFile = useForgeStore((s) => s.activeFile);
|
|
40655
41089
|
const activeBackend = useForgeStore((s) => s.activeBackend);
|
|
40656
41090
|
const computeTarget = useForgeStore((s) => s.computeTarget);
|
|
@@ -40662,11 +41096,13 @@ function Viewport() {
|
|
|
40662
41096
|
evaluationPhase,
|
|
40663
41097
|
renderMode,
|
|
40664
41098
|
renderStyle,
|
|
41099
|
+
manualScene,
|
|
40665
41100
|
inspectChannel,
|
|
40666
41101
|
inspectDisplayMode,
|
|
40667
41102
|
inspectPointSampleCount,
|
|
40668
41103
|
projectionMode,
|
|
40669
41104
|
gridEnabled,
|
|
41105
|
+
axesVisible,
|
|
40670
41106
|
gridSize,
|
|
40671
41107
|
showPerformanceInfo,
|
|
40672
41108
|
objectSettings,
|
|
@@ -40714,6 +41150,7 @@ function Viewport() {
|
|
|
40714
41150
|
isSketchOnly,
|
|
40715
41151
|
sceneConfig,
|
|
40716
41152
|
modelBoundsMinZ,
|
|
41153
|
+
surfaceFieldScale,
|
|
40717
41154
|
focusedObjectIdSet,
|
|
40718
41155
|
visibleSceneObjectCount,
|
|
40719
41156
|
visibleModelTriangles,
|
|
@@ -40734,6 +41171,11 @@ function Viewport() {
|
|
|
40734
41171
|
const historyObjectIds = useForgeStore((s) => s.historyObjectIds);
|
|
40735
41172
|
useHistoryPlaybackLoop();
|
|
40736
41173
|
const [viewPersistenceResolved, setViewPersistenceResolved] = reactExports.useState(false);
|
|
41174
|
+
const [historyGeometryStatus, setHistoryGeometryStatus] = reactExports.useState({
|
|
41175
|
+
status: "idle",
|
|
41176
|
+
stepCount: 0,
|
|
41177
|
+
error: null
|
|
41178
|
+
});
|
|
40737
41179
|
const [isViewportInteracting, setIsViewportInteracting] = reactExports.useState(false);
|
|
40738
41180
|
const [zoomMmPerPx, setZoomMmPerPx] = reactExports.useState(null);
|
|
40739
41181
|
const hoverTooltipRef = reactExports.useRef(null);
|
|
@@ -40748,6 +41190,12 @@ function Viewport() {
|
|
|
40748
41190
|
const contextMenuRef = reactExports.useRef(null);
|
|
40749
41191
|
const t2 = themes[themeName];
|
|
40750
41192
|
const renderStylePreset = reactExports.useMemo(() => getRenderStylePreset(renderStyle), [renderStyle]);
|
|
41193
|
+
const effectiveSceneConfig = reactExports.useMemo(
|
|
41194
|
+
() => manualScene.enabled ? buildManualSceneConfig(sceneConfig, manualScene, renderStylePreset) : sceneConfig,
|
|
41195
|
+
[manualScene, renderStylePreset, sceneConfig]
|
|
41196
|
+
);
|
|
41197
|
+
const inspectGroundOffset = typeof ((_a3 = effectiveSceneConfig == null ? void 0 : effectiveSceneConfig.ground) == null ? void 0 : _a3.offset) === "number" && Number.isFinite(effectiveSceneConfig.ground.offset) ? effectiveSceneConfig.ground.offset : 0;
|
|
41198
|
+
const inspectGroundZ = (modelBoundsMinZ ?? 0) - inspectGroundOffset;
|
|
40751
41199
|
const inspectChannelActive = inspectChannel !== "none";
|
|
40752
41200
|
const hasVisibleSdfObjects = objects.some((obj) => {
|
|
40753
41201
|
var _a4;
|
|
@@ -40771,21 +41219,13 @@ function Viewport() {
|
|
|
40771
41219
|
sceneVersion,
|
|
40772
41220
|
objects,
|
|
40773
41221
|
objectSettings,
|
|
40774
|
-
objectMatrices
|
|
41222
|
+
objectMatrices,
|
|
41223
|
+
groundZ: inspectGroundZ
|
|
40775
41224
|
});
|
|
40776
41225
|
const inspectLoading = inspectChannelActive && inspectAnalysis.status === "loading";
|
|
40777
|
-
const
|
|
40778
|
-
const
|
|
40779
|
-
const
|
|
40780
|
-
if (!isEvaluating || historyMode) return [];
|
|
40781
|
-
const historyObjects = [];
|
|
40782
|
-
for (const obj of objects) {
|
|
40783
|
-
if (!obj.shape) continue;
|
|
40784
|
-
const plan = getShapeCompilePlan(obj.shape);
|
|
40785
|
-
if (plan) historyObjects.push({ id: obj.id, plan });
|
|
40786
|
-
}
|
|
40787
|
-
return historyObjects.length > 0 ? linearizeMultiObjectSteps(historyObjects) : [];
|
|
40788
|
-
}, [historyMode, isEvaluating, objects]);
|
|
41226
|
+
const historyGeometryLoading = historyMode && historyGeometryStatus.status === "loading";
|
|
41227
|
+
const viewportBusyPhase = isEvaluating || evaluationPhase === "exporting" ? evaluationPhase : historyGeometryLoading ? "history" : inspectLoading ? "inspecting" : null;
|
|
41228
|
+
const viewportBusyLabel = historyGeometryLoading ? "Building timeline geometry" : inspectLoading ? `Generating ${inspectChannelLabel(inspectChannel)} inspect view` : void 0;
|
|
40789
41229
|
const handlers = useViewportHandlers({
|
|
40790
41230
|
containerRef,
|
|
40791
41231
|
contextMenuRef,
|
|
@@ -40849,7 +41289,7 @@ function Viewport() {
|
|
|
40849
41289
|
Canvas,
|
|
40850
41290
|
{
|
|
40851
41291
|
style: {
|
|
40852
|
-
background:
|
|
41292
|
+
background: renderStyle === "classic" ? t2.viewportBg : renderStylePreset.background,
|
|
40853
41293
|
cursor: measureMode ? "crosshair" : "default"
|
|
40854
41294
|
},
|
|
40855
41295
|
dpr: canvasDpr,
|
|
@@ -40866,19 +41306,21 @@ function Viewport() {
|
|
|
40866
41306
|
children: [
|
|
40867
41307
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(reactExports.Suspense, { fallback: null, children: [
|
|
40868
41308
|
projectionMode === "orthographic" ? /* @__PURE__ */ jsxRuntimeExports.jsx(OrthographicCamera, { makeDefault: true, position: [120, 80, 120], zoom: 2, near: -5e4, far: 5e4, up: [0, 0, 1] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PerspectiveCamera, { makeDefault: true, position: [120, 80, 120], fov: 45, near: 0.1, far: 1e5, up: [0, 0, 1] }),
|
|
40869
|
-
((
|
|
40870
|
-
|
|
41309
|
+
((_b2 = effectiveSceneConfig == null ? void 0 : effectiveSceneConfig.postProcessing) == null ? void 0 : _b2.toneMappingExposure) === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(RenderStyleExposure, { exposure: renderStylePreset.toneMappingExposure }),
|
|
41310
|
+
effectiveSceneConfig && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40871
41311
|
SceneConfigurator,
|
|
40872
41312
|
{
|
|
40873
|
-
config:
|
|
41313
|
+
config: effectiveSceneConfig,
|
|
41314
|
+
interactivePreview: isViewportInteracting,
|
|
40874
41315
|
controlsRef,
|
|
40875
41316
|
modelBoundsMinZ,
|
|
41317
|
+
hideGround: inspectChannelActive,
|
|
40876
41318
|
onDefaultLightsOverridden: handleDefaultLightsOverridden,
|
|
40877
41319
|
onDefaultEnvironmentOverridden: handleDefaultEnvironmentOverridden
|
|
40878
41320
|
}
|
|
40879
41321
|
),
|
|
40880
|
-
!defaultEnvironmentOverridden && /* @__PURE__ */ jsxRuntimeExports.jsx(LocalEnvironment, { preset: "studio", intensity: renderStylePreset.environmentIntensity }),
|
|
40881
|
-
!defaultLightsOverridden && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
41322
|
+
!isViewportInteracting && !defaultEnvironmentOverridden && /* @__PURE__ */ jsxRuntimeExports.jsx(LocalEnvironment, { preset: "studio", intensity: renderStylePreset.environmentIntensity }),
|
|
41323
|
+
(isViewportInteracting || !defaultLightsOverridden) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
40882
41324
|
/* @__PURE__ */ jsxRuntimeExports.jsx("ambientLight", { intensity: renderStylePreset.lights.ambientIntensity }),
|
|
40883
41325
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40884
41326
|
"directionalLight",
|
|
@@ -40917,8 +41359,8 @@ function Viewport() {
|
|
|
40917
41359
|
)
|
|
40918
41360
|
] }),
|
|
40919
41361
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ClippingManager, { active: hasAnyObjectCutPlanes }),
|
|
40920
|
-
|
|
40921
|
-
|
|
41362
|
+
sectionExplorerEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(SectionExplorerGizmo, { size: sectionGuideSize }),
|
|
41363
|
+
sectionPlaneGuidesEnabled && activeCutPlaneDefs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40922
41364
|
SectionPlaneGuides,
|
|
40923
41365
|
{
|
|
40924
41366
|
cutPlanes: scriptCutPlaneDefs,
|
|
@@ -40952,11 +41394,13 @@ function Viewport() {
|
|
|
40952
41394
|
renderMode,
|
|
40953
41395
|
inspectChannel,
|
|
40954
41396
|
inspectDisplayMode,
|
|
40955
|
-
inspectColor: inspectAnalysis.objectColors[obj.id] ?? maskColorForIndex(objIndex),
|
|
41397
|
+
inspectColor: inspectChannel === "floating" ? inspectAnalysis.objectColors[obj.id] ?? "#000000" : inspectAnalysis.objectColors[obj.id] ?? maskColorForIndex(objIndex),
|
|
40956
41398
|
inspectMeshColors: inspectAnalysis.meshColors[obj.id],
|
|
40957
41399
|
inspectPointCloud: inspectAnalysis.pointClouds[obj.id],
|
|
41400
|
+
inspectHeatmapFieldData: inspectAnalysis.heatmapFields[obj.id],
|
|
40958
41401
|
isInteracting: isViewportInteracting,
|
|
40959
41402
|
matrix,
|
|
41403
|
+
surfaceFieldScale,
|
|
40960
41404
|
isHovered,
|
|
40961
41405
|
clippingPlanes: objectClippingPlanes,
|
|
40962
41406
|
debugHighlightColor: shapeHl == null ? void 0 : shapeHl.color,
|
|
@@ -41020,7 +41464,7 @@ function Viewport() {
|
|
|
41020
41464
|
return null;
|
|
41021
41465
|
}),
|
|
41022
41466
|
inspectChannel === "collisions" && /* @__PURE__ */ jsxRuntimeExports.jsx(CollisionInspectionOverlay, { objects, objectSettings, objectMatrices }),
|
|
41023
|
-
|
|
41467
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41024
41468
|
SectionCaps,
|
|
41025
41469
|
{
|
|
41026
41470
|
sceneVersion,
|
|
@@ -41032,17 +41476,25 @@ function Viewport() {
|
|
|
41032
41476
|
isInteracting: isViewportInteracting
|
|
41033
41477
|
}
|
|
41034
41478
|
),
|
|
41035
|
-
|
|
41036
|
-
|
|
41037
|
-
|
|
41038
|
-
|
|
41039
|
-
|
|
41040
|
-
|
|
41479
|
+
constructionGhost && /* @__PURE__ */ jsxRuntimeExports.jsx(ConstructionGhostOverlay, { matrix: constructionGhostMatrix }),
|
|
41480
|
+
historyMode && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41481
|
+
ConstructionHistoryOverlay,
|
|
41482
|
+
{
|
|
41483
|
+
activeBackend,
|
|
41484
|
+
objectMatrices,
|
|
41485
|
+
objectSettings,
|
|
41486
|
+
onGeometryStatusChange: setHistoryGeometryStatus
|
|
41487
|
+
}
|
|
41488
|
+
),
|
|
41489
|
+
hoveredJointOverlay && /* @__PURE__ */ jsxRuntimeExports.jsx(HoveredJointOverlay, { state: hoveredJointOverlay, config: jointOverlayConfig }),
|
|
41490
|
+
dimensionsVisible && dimensions.map((d) => /* @__PURE__ */ jsxRuntimeExports.jsx(DimensionAnnotation, { def: d, lengthUnit }, d.id)),
|
|
41491
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(RenderLabelsOverlay, { labels: renderLabels }),
|
|
41492
|
+
attachmentsVisible !== "none" && attachmentPoints.map((ap) => {
|
|
41041
41493
|
const matrix = objectMatrices[ap.objectId];
|
|
41042
41494
|
return matrix ? /* @__PURE__ */ jsxRuntimeExports.jsx("group", { matrixAutoUpdate: false, matrix, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorAttachmentAnnotation, { def: ap }) }, `${ap.objectId}:${ap.name}`) : /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorAttachmentAnnotation, { def: ap }, `${ap.objectId}:${ap.name}`);
|
|
41043
41495
|
}),
|
|
41044
41496
|
/* @__PURE__ */ jsxRuntimeExports.jsx(MeasureTool, {}),
|
|
41045
|
-
|
|
41497
|
+
debugHighlights3D.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(DebugHighlightsOverlay, { highlights: debugHighlights3D }),
|
|
41046
41498
|
drawFlagEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(DrawCanvas, {}),
|
|
41047
41499
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41048
41500
|
PerformanceInfoSampler,
|
|
@@ -41055,7 +41507,7 @@ function Viewport() {
|
|
|
41055
41507
|
}
|
|
41056
41508
|
),
|
|
41057
41509
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ZoomSampler, { onZoomChange: setZoomMmPerPx }),
|
|
41058
|
-
|
|
41510
|
+
gridEnabled && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41059
41511
|
Grid,
|
|
41060
41512
|
{
|
|
41061
41513
|
args: [500, 500],
|
|
@@ -41070,7 +41522,7 @@ function Viewport() {
|
|
|
41070
41522
|
infiniteGrid: true
|
|
41071
41523
|
}
|
|
41072
41524
|
),
|
|
41073
|
-
!
|
|
41525
|
+
!isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41074
41526
|
SdfRaymarchLayer,
|
|
41075
41527
|
{
|
|
41076
41528
|
objects,
|
|
@@ -41085,11 +41537,11 @@ function Viewport() {
|
|
|
41085
41537
|
onContextMenu: (obj, event) => handleObjectContextMenu(obj, event)
|
|
41086
41538
|
}
|
|
41087
41539
|
),
|
|
41088
|
-
|
|
41089
|
-
|
|
41540
|
+
axesVisible && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(LabeledAxes, {}),
|
|
41541
|
+
axesVisible && isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(SketchAxes, {}),
|
|
41090
41542
|
isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(CursorTracker, { onMove: (x, y) => setCursorPos({ x, y }) }),
|
|
41091
41543
|
isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(SketchRulersUpdater, { hCanvasRef: hRulerRef, vCanvasRef: vRulerRef }),
|
|
41092
|
-
|
|
41544
|
+
gridEnabled && isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41093
41545
|
Grid,
|
|
41094
41546
|
{
|
|
41095
41547
|
args: [500, 500],
|
|
@@ -41202,7 +41654,7 @@ function Viewport() {
|
|
|
41202
41654
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41203
41655
|
ModelJourneyBar,
|
|
41204
41656
|
{
|
|
41205
|
-
journeys:
|
|
41657
|
+
journeys: effectiveSceneConfig == null ? void 0 : effectiveSceneConfig.journeys,
|
|
41206
41658
|
isViewportInteracting,
|
|
41207
41659
|
requestViewCommand,
|
|
41208
41660
|
selectObject,
|
|
@@ -41211,14 +41663,15 @@ function Viewport() {
|
|
|
41211
41663
|
}
|
|
41212
41664
|
),
|
|
41213
41665
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PerformanceInfoPanel, { enabled: showPerformanceInfo, stats: performanceInfo }),
|
|
41666
|
+
!viewportBusyPhase && /* @__PURE__ */ jsxRuntimeExports.jsx(InspectionLegend, { channel: inspectChannel, warnings: inspectAnalysis.warnings }),
|
|
41214
41667
|
!viewportBusyPhase && /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomIndicatorPanel, { mmPerPx: zoomMmPerPx }),
|
|
41215
41668
|
isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41216
41669
|
SketchRulersOverlay,
|
|
41217
41670
|
{
|
|
41218
41671
|
hCanvasRef: hRulerRef,
|
|
41219
41672
|
vCanvasRef: vRulerRef,
|
|
41220
|
-
viewportWidth: ((
|
|
41221
|
-
viewportHeight: ((
|
|
41673
|
+
viewportWidth: ((_c = containerRef.current) == null ? void 0 : _c.clientWidth) ?? 800,
|
|
41674
|
+
viewportHeight: ((_d = containerRef.current) == null ? void 0 : _d.clientHeight) ?? 600
|
|
41222
41675
|
}
|
|
41223
41676
|
),
|
|
41224
41677
|
isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(CursorCoordinatesPanel, { x: cursorPos.x, y: cursorPos.y }),
|
|
@@ -41247,7 +41700,6 @@ function Viewport() {
|
|
|
41247
41700
|
{
|
|
41248
41701
|
phase: viewportBusyPhase,
|
|
41249
41702
|
label: viewportBusyLabel,
|
|
41250
|
-
constructionSteps: rebuildHistorySteps,
|
|
41251
41703
|
activeBackend,
|
|
41252
41704
|
computeTarget
|
|
41253
41705
|
}
|
|
@@ -41280,6 +41732,34 @@ function Viewport() {
|
|
|
41280
41732
|
]
|
|
41281
41733
|
}
|
|
41282
41734
|
),
|
|
41735
|
+
historyMode && historyGeometryStatus.status === "error" && historyGeometryStatus.error && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
41736
|
+
"div",
|
|
41737
|
+
{
|
|
41738
|
+
style: {
|
|
41739
|
+
position: "absolute",
|
|
41740
|
+
top: 12,
|
|
41741
|
+
left: "50%",
|
|
41742
|
+
transform: "translateX(-50%)",
|
|
41743
|
+
background: "rgba(127, 29, 29, 0.92)",
|
|
41744
|
+
color: "#fee2e2",
|
|
41745
|
+
border: "1px solid rgba(254, 202, 202, 0.4)",
|
|
41746
|
+
borderRadius: 6,
|
|
41747
|
+
padding: "7px 12px",
|
|
41748
|
+
fontSize: 12,
|
|
41749
|
+
fontWeight: 600,
|
|
41750
|
+
pointerEvents: "none",
|
|
41751
|
+
zIndex: 12,
|
|
41752
|
+
maxWidth: "min(520px, calc(100% - 32px))",
|
|
41753
|
+
whiteSpace: "nowrap",
|
|
41754
|
+
overflow: "hidden",
|
|
41755
|
+
textOverflow: "ellipsis"
|
|
41756
|
+
},
|
|
41757
|
+
children: [
|
|
41758
|
+
"Timeline failed: ",
|
|
41759
|
+
historyGeometryStatus.error
|
|
41760
|
+
]
|
|
41761
|
+
}
|
|
41762
|
+
),
|
|
41283
41763
|
/* @__PURE__ */ jsxRuntimeExports.jsx(HoverTooltipLayer, { ref: hoverTooltipRef, enabled: objectPickSyncEnabled && !measureMode }),
|
|
41284
41764
|
objectContextMenu && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
41285
41765
|
"div",
|
|
@@ -41737,7 +42217,7 @@ function Viewport() {
|
|
|
41737
42217
|
}
|
|
41738
42218
|
);
|
|
41739
42219
|
}
|
|
41740
|
-
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
42220
|
+
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-DnddQvBt.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
41741
42221
|
const PENDING_SHARE_COPY_KEY = "fc-pending-share-copy";
|
|
41742
42222
|
function storePendingShareCopy(shareId) {
|
|
41743
42223
|
sessionStorage.setItem(PENDING_SHARE_COPY_KEY, shareId);
|
|
@@ -41924,15 +42404,15 @@ const PublishedModelPage$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Objec
|
|
|
41924
42404
|
consumePendingShareCopy,
|
|
41925
42405
|
storePendingShareCopy
|
|
41926
42406
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
41927
|
-
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-
|
|
41928
|
-
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-
|
|
41929
|
-
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-
|
|
41930
|
-
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-
|
|
42407
|
+
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-CFet-l3o.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
|
|
42408
|
+
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-9U1hGjrg.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
|
|
42409
|
+
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-Cc41PP4d.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
|
|
42410
|
+
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-CNEvQM7c.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
|
|
41931
42411
|
reactExports.lazy(() => __vitePreload(() => Promise.resolve().then(() => PublishedModelPage$1), true ? void 0 : void 0).then((m2) => ({ default: m2.PublishedModelPage })));
|
|
41932
|
-
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-
|
|
41933
|
-
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-
|
|
41934
|
-
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
41935
|
-
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-
|
|
42412
|
+
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-BarZonVZ.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
|
|
42413
|
+
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-CPm8mQx3.js"), true ? __vite__mapDeps([2,1]) : void 0).then((m2) => ({ default: m2.PricingPage })));
|
|
42414
|
+
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-DnddQvBt.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
42415
|
+
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-B2lhWTcd.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
|
|
41936
42416
|
const embedMode = isEmbedMode() && !window.location.pathname.startsWith("/m/");
|
|
41937
42417
|
const EDITABLE_CRASH_FILE = /\.(?:forge\.js|[cm]?[jt]sx?|json|md|txt|svg)$/i;
|
|
41938
42418
|
function firstMeaningfulLine(text) {
|