@toolpath/viewer 2.2.0 → 2.2.1
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/dist/{chunk-WTTOUG4P.js → chunk-7S6SIYHL.js} +300 -165
- package/dist/engine/index.js +1 -1
- package/dist/index.js +107 -81
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/engine/engine-part.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect8, useMemo as useMemo8 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/part-mesh.tsx
|
|
5
|
-
import { useThree as
|
|
5
|
+
import { useThree as useThree8 } from "@react-three/fiber";
|
|
6
6
|
import {
|
|
7
7
|
useCallback as useCallback3,
|
|
8
|
-
useEffect as
|
|
9
|
-
useLayoutEffect as
|
|
10
|
-
useMemo as
|
|
8
|
+
useEffect as useEffect7,
|
|
9
|
+
useLayoutEffect as useLayoutEffect3,
|
|
10
|
+
useMemo as useMemo7,
|
|
11
11
|
useRef as useRef6,
|
|
12
12
|
useSyncExternalStore
|
|
13
13
|
} from "react";
|
|
@@ -2526,10 +2526,10 @@ var Viewer = forwardRef(function Viewer2({
|
|
|
2526
2526
|
});
|
|
2527
2527
|
|
|
2528
2528
|
// src/section-view.tsx
|
|
2529
|
-
import { useFrame as useFrame4, useThree as
|
|
2530
|
-
import { useCallback as useCallback2, useEffect as
|
|
2529
|
+
import { useFrame as useFrame4, useThree as useThree6 } from "@react-three/fiber";
|
|
2530
|
+
import { useCallback as useCallback2, useEffect as useEffect6, useLayoutEffect as useLayoutEffect2, useMemo as useMemo6, useRef as useRef4, useState } from "react";
|
|
2531
2531
|
import {
|
|
2532
|
-
Color as
|
|
2532
|
+
Color as Color4,
|
|
2533
2533
|
DoubleSide as DoubleSide4,
|
|
2534
2534
|
EdgesGeometry,
|
|
2535
2535
|
Mesh as Mesh3,
|
|
@@ -2538,42 +2538,209 @@ import {
|
|
|
2538
2538
|
Quaternion as Quaternion2,
|
|
2539
2539
|
Raycaster as Raycaster2,
|
|
2540
2540
|
Scene,
|
|
2541
|
-
Vector2 as
|
|
2541
|
+
Vector2 as Vector25,
|
|
2542
2542
|
Vector3 as Vector310
|
|
2543
2543
|
} from "three";
|
|
2544
2544
|
|
|
2545
|
-
// src/
|
|
2546
|
-
import {
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
var
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2545
|
+
// src/arrow-mesh.tsx
|
|
2546
|
+
import { useThree as useThree5 } from "@react-three/fiber";
|
|
2547
|
+
import { useEffect as useEffect5, useLayoutEffect, useMemo as useMemo5 } from "react";
|
|
2548
|
+
|
|
2549
|
+
// src/render/arrow-material.ts
|
|
2550
|
+
import { AlwaysDepth, Color as Color2, ShaderMaterial } from "three";
|
|
2551
|
+
var VERTEX = (
|
|
2552
|
+
/* glsl */
|
|
2553
|
+
`
|
|
2554
|
+
varying vec3 vNormal;
|
|
2555
|
+
|
|
2556
|
+
void main() {
|
|
2557
|
+
vNormal = normalize(normalMatrix * normal);
|
|
2558
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
2559
|
+
}
|
|
2560
|
+
`
|
|
2561
|
+
);
|
|
2562
|
+
var FRAGMENT = (
|
|
2563
|
+
/* glsl */
|
|
2564
|
+
`
|
|
2565
|
+
uniform vec3 uColor;
|
|
2566
|
+
uniform float uOpacity;
|
|
2567
|
+
|
|
2568
|
+
varying vec3 vNormal;
|
|
2569
|
+
|
|
2570
|
+
// Above, to the left and toward the camera, in the camera's own frame.
|
|
2571
|
+
const vec3 KEY = vec3(-0.4, 0.6, 0.7);
|
|
2572
|
+
|
|
2573
|
+
void main() {
|
|
2574
|
+
// Wrapped, and over a narrow range: a quarter darker at most, so the shape
|
|
2575
|
+
// shows without the colour going anywhere.
|
|
2576
|
+
float light = mix(0.75, 1.0, 0.5 + 0.5 * dot(normalize(vNormal), normalize(KEY)));
|
|
2577
|
+
gl_FragColor = vec4(uColor * light, uOpacity);
|
|
2578
|
+
#include <tonemapping_fragment>
|
|
2579
|
+
#include <colorspace_fragment>
|
|
2580
|
+
}
|
|
2581
|
+
`
|
|
2582
|
+
);
|
|
2583
|
+
function createArrowMaterial() {
|
|
2584
|
+
const uniforms = {
|
|
2585
|
+
uColor: { value: new Color2() },
|
|
2586
|
+
uOpacity: { value: 1 }
|
|
2587
|
+
};
|
|
2588
|
+
return new ShaderMaterial({
|
|
2589
|
+
vertexShader: VERTEX,
|
|
2590
|
+
fragmentShader: FRAGMENT,
|
|
2591
|
+
uniforms,
|
|
2592
|
+
transparent: true
|
|
2593
|
+
});
|
|
2594
|
+
}
|
|
2595
|
+
function createArrowDepthMaterial() {
|
|
2596
|
+
const material = createArrowMaterial();
|
|
2597
|
+
material.colorWrite = false;
|
|
2598
|
+
return material;
|
|
2599
|
+
}
|
|
2600
|
+
function applyArrowColor(material, color, opacity) {
|
|
2601
|
+
material.uniforms.uColor.value.set(color);
|
|
2602
|
+
material.uniforms.uOpacity.value = opacity;
|
|
2603
|
+
}
|
|
2604
|
+
var RESET_VERTEX = (
|
|
2605
|
+
/* glsl */
|
|
2606
|
+
`
|
|
2607
|
+
void main() {
|
|
2608
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
2609
|
+
// On the far plane, so what it leaves in the depth buffer is "nothing here".
|
|
2610
|
+
gl_Position.z = gl_Position.w;
|
|
2611
|
+
}
|
|
2612
|
+
`
|
|
2613
|
+
);
|
|
2614
|
+
var RESET_FRAGMENT = (
|
|
2615
|
+
/* glsl */
|
|
2616
|
+
`
|
|
2617
|
+
void main() {
|
|
2618
|
+
gl_FragColor = vec4(0.0);
|
|
2619
|
+
}
|
|
2620
|
+
`
|
|
2621
|
+
);
|
|
2622
|
+
function createDepthResetMaterial() {
|
|
2623
|
+
return new ShaderMaterial({
|
|
2624
|
+
vertexShader: RESET_VERTEX,
|
|
2625
|
+
fragmentShader: RESET_FRAGMENT,
|
|
2626
|
+
transparent: true,
|
|
2627
|
+
colorWrite: false,
|
|
2628
|
+
depthFunc: AlwaysDepth
|
|
2629
|
+
});
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
// src/arrow-mesh.tsx
|
|
2633
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2634
|
+
var ArrowMesh = ({ geometry, color, opacity, onTop = false, events }) => {
|
|
2635
|
+
const invalidate = useThree5((state) => state.invalidate);
|
|
2636
|
+
const material = useMemo5(() => createArrowMaterial(), []);
|
|
2637
|
+
useEffect5(() => () => material.dispose(), [material]);
|
|
2638
|
+
const depth = useMemo5(() => createArrowDepthMaterial(), []);
|
|
2639
|
+
useEffect5(() => () => depth.dispose(), [depth]);
|
|
2640
|
+
const reset = useMemo5(() => onTop ? createDepthResetMaterial() : null, [onTop]);
|
|
2641
|
+
useEffect5(() => () => reset?.dispose(), [reset]);
|
|
2642
|
+
useLayoutEffect(() => {
|
|
2643
|
+
applyArrowColor(material, color, opacity);
|
|
2644
|
+
invalidate();
|
|
2645
|
+
}, [color, invalidate, material, opacity]);
|
|
2646
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
2647
|
+
reset ? /* @__PURE__ */ jsx4("mesh", { geometry, material: reset, renderOrder: 0, raycast: () => null }) : null,
|
|
2648
|
+
/* @__PURE__ */ jsx4("mesh", { geometry, material: depth, renderOrder: 1, raycast: () => null }),
|
|
2649
|
+
/* @__PURE__ */ jsx4("mesh", { geometry, material, renderOrder: 2, ...events })
|
|
2650
|
+
] });
|
|
2651
|
+
};
|
|
2652
|
+
|
|
2653
|
+
// src/render/arrow.ts
|
|
2654
|
+
import { LatheGeometry, Vector2 as Vector23, Vector3 as Vector39 } from "three";
|
|
2655
|
+
var ARROW_AXIS2 = new Vector39(0, 1, 0);
|
|
2656
|
+
var ARROW_ROUND = 32;
|
|
2657
|
+
var HEAD_LENGTH = 0.415;
|
|
2658
|
+
var HEAD_RADIUS = 0.153;
|
|
2659
|
+
var SHAFT_RADIUS = 0.0515;
|
|
2660
|
+
var HANDLE_TIP = 0.76;
|
|
2661
|
+
var HANDLE_HEAD_LENGTH = 0.3;
|
|
2662
|
+
var HANDLE_HEAD_RADIUS = 0.14;
|
|
2663
|
+
var HANDLE_SHAFT_RADIUS = 0.035;
|
|
2664
|
+
var HANDLE_BEAD_RADIUS = 0.1;
|
|
2665
|
+
var RIM_ROUND = 6e-3;
|
|
2666
|
+
var NECK_ROUND = 8e-3;
|
|
2667
|
+
var BEAD_ROUND = 0.02;
|
|
2668
|
+
var ROUND_STEPS = 4;
|
|
2669
|
+
var CAP_STEPS = 6;
|
|
2670
|
+
var BEAD_STEPS = 12;
|
|
2671
|
+
var head = ({ length, radius, shaft }) => [
|
|
2672
|
+
{ at: new Vector23(0, 0) },
|
|
2673
|
+
{ at: new Vector23(radius, length), round: RIM_ROUND },
|
|
2674
|
+
{ at: new Vector23(shaft, length), round: NECK_ROUND }
|
|
2675
|
+
];
|
|
2676
|
+
var rounded = (corners) => corners.flatMap(({ at, round = 0 }, index) => {
|
|
2677
|
+
const before = corners[index - 1]?.at;
|
|
2678
|
+
const after = corners[index + 1]?.at;
|
|
2679
|
+
if (!(round > 0) || !before || !after) return [at];
|
|
2680
|
+
const back = before.clone().sub(at);
|
|
2681
|
+
const ahead = after.clone().sub(at);
|
|
2682
|
+
const reach = Math.min(back.length(), ahead.length()) / 2;
|
|
2683
|
+
back.normalize();
|
|
2684
|
+
ahead.normalize();
|
|
2685
|
+
const angle = Math.acos(Math.min(Math.max(back.dot(ahead), -1), 1));
|
|
2686
|
+
if (angle > Math.PI - 1e-6 || angle < 1e-6) return [at];
|
|
2687
|
+
const half = angle / 2;
|
|
2688
|
+
const offset = Math.min(round / Math.tan(half), reach);
|
|
2689
|
+
const radius = offset * Math.tan(half);
|
|
2690
|
+
const centre = at.clone().addScaledVector(back.clone().add(ahead).normalize(), radius / Math.sin(half));
|
|
2691
|
+
const from = at.clone().addScaledVector(back, offset).sub(centre);
|
|
2692
|
+
const to = at.clone().addScaledVector(ahead, offset).sub(centre);
|
|
2693
|
+
const start = Math.atan2(from.y, from.x);
|
|
2694
|
+
let sweep = Math.atan2(to.y, to.x) - start;
|
|
2695
|
+
if (sweep > Math.PI) sweep -= Math.PI * 2;
|
|
2696
|
+
if (sweep < -Math.PI) sweep += Math.PI * 2;
|
|
2697
|
+
return Array.from({ length: ROUND_STEPS + 1 }, (_, step) => {
|
|
2698
|
+
const turn = start + sweep * step / ROUND_STEPS;
|
|
2699
|
+
return new Vector23(centre.x + Math.cos(turn) * radius, centre.y + Math.sin(turn) * radius);
|
|
2700
|
+
});
|
|
2701
|
+
});
|
|
2702
|
+
function arrowProfile() {
|
|
2703
|
+
const body = rounded([
|
|
2704
|
+
...head({ length: HEAD_LENGTH, radius: HEAD_RADIUS, shaft: SHAFT_RADIUS }),
|
|
2705
|
+
{ at: new Vector23(SHAFT_RADIUS, 1 - SHAFT_RADIUS) }
|
|
2706
|
+
]);
|
|
2707
|
+
const tail = Array.from({ length: CAP_STEPS }, (_, step) => {
|
|
2708
|
+
const turn = (step + 1) / CAP_STEPS * (Math.PI / 2);
|
|
2709
|
+
return new Vector23(
|
|
2710
|
+
step + 1 === CAP_STEPS ? 0 : Math.cos(turn) * SHAFT_RADIUS,
|
|
2711
|
+
1 - SHAFT_RADIUS + Math.sin(turn) * SHAFT_RADIUS
|
|
2712
|
+
);
|
|
2713
|
+
});
|
|
2714
|
+
return [...body, ...tail];
|
|
2715
|
+
}
|
|
2716
|
+
function handleProfile() {
|
|
2717
|
+
const lower = head({
|
|
2718
|
+
length: HANDLE_HEAD_LENGTH,
|
|
2719
|
+
radius: HANDLE_HEAD_RADIUS,
|
|
2720
|
+
shaft: HANDLE_SHAFT_RADIUS
|
|
2721
|
+
}).map(({ at, round }) => ({ at: new Vector23(at.x, at.y - HANDLE_TIP), round }));
|
|
2722
|
+
const upper = lower.slice().reverse().map(({ at, round }) => ({ at: new Vector23(at.x, -at.y), round }));
|
|
2723
|
+
const meet = Math.acos(HANDLE_SHAFT_RADIUS / HANDLE_BEAD_RADIUS);
|
|
2724
|
+
const bead = Array.from({ length: BEAD_STEPS + 1 }, (_, step) => {
|
|
2725
|
+
const turn = -meet + 2 * meet * step / BEAD_STEPS;
|
|
2726
|
+
const at = new Vector23(Math.cos(turn), Math.sin(turn)).multiplyScalar(HANDLE_BEAD_RADIUS);
|
|
2727
|
+
return { at, round: step === 0 || step === BEAD_STEPS ? BEAD_ROUND : 0 };
|
|
2728
|
+
});
|
|
2729
|
+
return rounded([...lower, ...bead, ...upper]);
|
|
2570
2730
|
}
|
|
2731
|
+
var turned = (profile) => {
|
|
2732
|
+
const geometry = new LatheGeometry(profile, ARROW_ROUND);
|
|
2733
|
+
geometry.normalizeNormals();
|
|
2734
|
+
return geometry;
|
|
2735
|
+
};
|
|
2736
|
+
var arrowGeometry = () => turned(arrowProfile());
|
|
2737
|
+
var handleGeometry = () => turned(handleProfile());
|
|
2571
2738
|
|
|
2572
2739
|
// src/render/section-cap.ts
|
|
2573
2740
|
import {
|
|
2574
2741
|
AlwaysStencilFunc,
|
|
2575
2742
|
BackSide,
|
|
2576
|
-
Color as
|
|
2743
|
+
Color as Color3,
|
|
2577
2744
|
DecrementWrapStencilOp,
|
|
2578
2745
|
DoubleSide as DoubleSide3,
|
|
2579
2746
|
FrontSide,
|
|
@@ -2582,11 +2749,11 @@ import {
|
|
|
2582
2749
|
MeshBasicMaterial as MeshBasicMaterial2,
|
|
2583
2750
|
NotEqualStencilFunc,
|
|
2584
2751
|
ReplaceStencilOp,
|
|
2585
|
-
ShaderMaterial,
|
|
2586
|
-
Vector2 as
|
|
2752
|
+
ShaderMaterial as ShaderMaterial2,
|
|
2753
|
+
Vector2 as Vector24,
|
|
2587
2754
|
WebGLRenderTarget
|
|
2588
2755
|
} from "three";
|
|
2589
|
-
var
|
|
2756
|
+
var VERTEX2 = (
|
|
2590
2757
|
/* glsl */
|
|
2591
2758
|
`
|
|
2592
2759
|
void main() {
|
|
@@ -2594,7 +2761,7 @@ void main() {
|
|
|
2594
2761
|
}
|
|
2595
2762
|
`
|
|
2596
2763
|
);
|
|
2597
|
-
var
|
|
2764
|
+
var FRAGMENT2 = (
|
|
2598
2765
|
/* glsl */
|
|
2599
2766
|
`
|
|
2600
2767
|
uniform sampler2D uMask;
|
|
@@ -2642,17 +2809,17 @@ function createMaskTarget() {
|
|
|
2642
2809
|
function createCapMaterial(mask) {
|
|
2643
2810
|
const uniforms = {
|
|
2644
2811
|
uMask: { value: mask },
|
|
2645
|
-
uResolution: { value: new
|
|
2646
|
-
uFill: { value: new
|
|
2647
|
-
uHatch: { value: new
|
|
2648
|
-
uOutline: { value: new
|
|
2812
|
+
uResolution: { value: new Vector24(1, 1) },
|
|
2813
|
+
uFill: { value: new Color3() },
|
|
2814
|
+
uHatch: { value: new Color3() },
|
|
2815
|
+
uOutline: { value: new Color3() },
|
|
2649
2816
|
uPitch: { value: CAP_HATCH.pitch },
|
|
2650
2817
|
uLine: { value: CAP_HATCH.line },
|
|
2651
2818
|
uThickness: { value: CAP_HATCH.outline }
|
|
2652
2819
|
};
|
|
2653
|
-
return new
|
|
2654
|
-
vertexShader:
|
|
2655
|
-
fragmentShader:
|
|
2820
|
+
return new ShaderMaterial2({
|
|
2821
|
+
vertexShader: VERTEX2,
|
|
2822
|
+
fragmentShader: FRAGMENT2,
|
|
2656
2823
|
uniforms,
|
|
2657
2824
|
side: DoubleSide3,
|
|
2658
2825
|
stencilWrite: true,
|
|
@@ -2711,7 +2878,7 @@ function createMaskMaterial() {
|
|
|
2711
2878
|
}
|
|
2712
2879
|
|
|
2713
2880
|
// src/section-view.tsx
|
|
2714
|
-
import { Fragment, jsx as
|
|
2881
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2715
2882
|
var FURNITURE2 = { [EXCLUDE_FROM_FRAME]: true };
|
|
2716
2883
|
function resolveSectionPlane(options, box) {
|
|
2717
2884
|
if (!options?.enabled || box.isEmpty()) return null;
|
|
@@ -2747,43 +2914,45 @@ var SectionView = ({
|
|
|
2747
2914
|
showHandle,
|
|
2748
2915
|
onDrag
|
|
2749
2916
|
}) => {
|
|
2750
|
-
const camera =
|
|
2751
|
-
const size =
|
|
2752
|
-
const dpr =
|
|
2753
|
-
const gl =
|
|
2754
|
-
const invalidate =
|
|
2755
|
-
const controls =
|
|
2756
|
-
const domElement =
|
|
2917
|
+
const camera = useThree6((state) => state.camera);
|
|
2918
|
+
const size = useThree6((state) => state.size);
|
|
2919
|
+
const dpr = useThree6((state) => state.viewport.dpr);
|
|
2920
|
+
const gl = useThree6((state) => state.gl);
|
|
2921
|
+
const invalidate = useThree6((state) => state.invalidate);
|
|
2922
|
+
const controls = useThree6((state) => state.controls);
|
|
2923
|
+
const domElement = useThree6((state) => state.gl.domElement);
|
|
2757
2924
|
const handleRef = useRef4(null);
|
|
2758
2925
|
const [hovered, setHovered] = useState(false);
|
|
2759
2926
|
const dragging = useRef4(null);
|
|
2760
|
-
const span =
|
|
2927
|
+
const span = useMemo6(() => box.getSize(new Vector310()).length(), [box]);
|
|
2761
2928
|
const frameSize = span * SECTION_GIZMO_FRAME_SCALE;
|
|
2762
|
-
const directionColor2 =
|
|
2929
|
+
const directionColor2 = useMemo6(() => sectionDirectionColor(plane.normal), [plane]);
|
|
2763
2930
|
const resolvedHandleColor = sectionHandleColor(handleColor, directionColor2);
|
|
2764
|
-
const clip =
|
|
2765
|
-
const capPosition =
|
|
2766
|
-
const capQuaternion =
|
|
2767
|
-
const handleQuaternion =
|
|
2768
|
-
() => new Quaternion2().setFromUnitVectors(
|
|
2931
|
+
const clip = useMemo6(() => [plane], [plane]);
|
|
2932
|
+
const capPosition = useMemo6(() => sectionAnchor(box, plane), [box, plane]);
|
|
2933
|
+
const capQuaternion = useMemo6(() => new Quaternion2().setFromUnitVectors(Z, plane.normal), [plane]);
|
|
2934
|
+
const handleQuaternion = useMemo6(
|
|
2935
|
+
() => new Quaternion2().setFromUnitVectors(ARROW_AXIS2, plane.normal.clone().negate()),
|
|
2769
2936
|
[plane]
|
|
2770
2937
|
);
|
|
2771
|
-
const frameSurface =
|
|
2772
|
-
|
|
2773
|
-
const frameEdges =
|
|
2774
|
-
|
|
2775
|
-
const
|
|
2776
|
-
|
|
2777
|
-
|
|
2938
|
+
const frameSurface = useMemo6(() => new PlaneGeometry(frameSize, frameSize), [frameSize]);
|
|
2939
|
+
useEffect6(() => () => frameSurface.dispose(), [frameSurface]);
|
|
2940
|
+
const frameEdges = useMemo6(() => new EdgesGeometry(frameSurface), [frameSurface]);
|
|
2941
|
+
useEffect6(() => () => frameEdges.dispose(), [frameEdges]);
|
|
2942
|
+
const handleShape = useMemo6(() => handleGeometry(), []);
|
|
2943
|
+
useEffect6(() => () => handleShape.dispose(), [handleShape]);
|
|
2944
|
+
const stencils = useMemo6(() => createStencilMaterials([]), []);
|
|
2945
|
+
useEffect6(() => () => stencils.forEach((material) => material.dispose()), [stencils]);
|
|
2946
|
+
useLayoutEffect2(() => {
|
|
2778
2947
|
for (const material of stencils) material.clippingPlanes = clip;
|
|
2779
2948
|
}, [clip, stencils]);
|
|
2780
|
-
const mask =
|
|
2781
|
-
|
|
2782
|
-
const cap =
|
|
2783
|
-
|
|
2784
|
-
const quad =
|
|
2785
|
-
|
|
2786
|
-
const maskScene =
|
|
2949
|
+
const mask = useMemo6(() => createMaskTarget(), []);
|
|
2950
|
+
useEffect6(() => () => mask.dispose(), [mask]);
|
|
2951
|
+
const cap = useMemo6(() => createCapMaterial(mask.texture), [mask]);
|
|
2952
|
+
useEffect6(() => () => cap.dispose(), [cap]);
|
|
2953
|
+
const quad = useMemo6(() => new PlaneGeometry(span * 1.5, span * 1.5), [span]);
|
|
2954
|
+
useEffect6(() => () => quad.dispose(), [quad]);
|
|
2955
|
+
const maskScene = useMemo6(() => {
|
|
2787
2956
|
const scene = new Scene();
|
|
2788
2957
|
const [back, front] = stencils;
|
|
2789
2958
|
const backMesh = new Mesh3(geometry, back);
|
|
@@ -2795,19 +2964,19 @@ var SectionView = ({
|
|
|
2795
2964
|
scene.add(backMesh, frontMesh, maskMesh);
|
|
2796
2965
|
return { scene, maskMesh };
|
|
2797
2966
|
}, [geometry, quad, stencils]);
|
|
2798
|
-
|
|
2799
|
-
|
|
2967
|
+
useEffect6(() => () => maskScene.maskMesh.material.dispose(), [maskScene]);
|
|
2968
|
+
useEffect6(() => {
|
|
2800
2969
|
maskScene.maskMesh.position.copy(capPosition);
|
|
2801
2970
|
maskScene.maskMesh.quaternion.copy(capQuaternion);
|
|
2802
2971
|
}, [capPosition, capQuaternion, maskScene]);
|
|
2803
|
-
|
|
2804
|
-
const buffer = gl.getDrawingBufferSize(new
|
|
2972
|
+
useLayoutEffect2(() => {
|
|
2973
|
+
const buffer = gl.getDrawingBufferSize(new Vector25());
|
|
2805
2974
|
mask.setSize(buffer.x, buffer.y);
|
|
2806
2975
|
cap.uniforms.uResolution.value.copy(buffer);
|
|
2807
2976
|
applyCapTheme(cap, theme, dpr);
|
|
2808
2977
|
invalidate();
|
|
2809
2978
|
}, [cap, dpr, gl, invalidate, mask, size, theme]);
|
|
2810
|
-
const clearColor =
|
|
2979
|
+
const clearColor = useMemo6(() => new Color4(), []);
|
|
2811
2980
|
useFrame4(({ gl: renderer, camera: eye }) => {
|
|
2812
2981
|
const previousAlpha = renderer.getClearAlpha();
|
|
2813
2982
|
renderer.getClearColor(clearColor);
|
|
@@ -2848,7 +3017,7 @@ var SectionView = ({
|
|
|
2848
3017
|
dragging.current = start;
|
|
2849
3018
|
setControlsEnabled(false);
|
|
2850
3019
|
const raycaster = new Raycaster2();
|
|
2851
|
-
const pointer = new
|
|
3020
|
+
const pointer = new Vector25();
|
|
2852
3021
|
const move = (native) => {
|
|
2853
3022
|
const rect = domElement.getBoundingClientRect();
|
|
2854
3023
|
pointer.set(
|
|
@@ -2888,8 +3057,8 @@ var SectionView = ({
|
|
|
2888
3057
|
// Excluded from framing, all of it. The cap is a quad half again as wide as
|
|
2889
3058
|
// the part's diagonal, so a Fit that measured it would frame the cut rather
|
|
2890
3059
|
// than the part and leave the part a speck in the middle of it.
|
|
2891
|
-
/* @__PURE__ */
|
|
2892
|
-
/* @__PURE__ */
|
|
3060
|
+
/* @__PURE__ */ jsxs4("group", { userData: FURNITURE2, children: [
|
|
3061
|
+
/* @__PURE__ */ jsx5(
|
|
2893
3062
|
"mesh",
|
|
2894
3063
|
{
|
|
2895
3064
|
geometry,
|
|
@@ -2898,7 +3067,7 @@ var SectionView = ({
|
|
|
2898
3067
|
raycast: () => null
|
|
2899
3068
|
}
|
|
2900
3069
|
),
|
|
2901
|
-
/* @__PURE__ */
|
|
3070
|
+
/* @__PURE__ */ jsx5(
|
|
2902
3071
|
"mesh",
|
|
2903
3072
|
{
|
|
2904
3073
|
geometry,
|
|
@@ -2907,7 +3076,7 @@ var SectionView = ({
|
|
|
2907
3076
|
raycast: () => null
|
|
2908
3077
|
}
|
|
2909
3078
|
),
|
|
2910
|
-
/* @__PURE__ */
|
|
3079
|
+
/* @__PURE__ */ jsx5(
|
|
2911
3080
|
"mesh",
|
|
2912
3081
|
{
|
|
2913
3082
|
geometry: quad,
|
|
@@ -2918,15 +3087,15 @@ var SectionView = ({
|
|
|
2918
3087
|
raycast: () => null
|
|
2919
3088
|
}
|
|
2920
3089
|
),
|
|
2921
|
-
showHandle && onDrag ? /* @__PURE__ */
|
|
2922
|
-
/* @__PURE__ */
|
|
3090
|
+
showHandle && onDrag ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
3091
|
+
/* @__PURE__ */ jsxs4(
|
|
2923
3092
|
"group",
|
|
2924
3093
|
{
|
|
2925
3094
|
position: capPosition,
|
|
2926
3095
|
quaternion: capQuaternion,
|
|
2927
3096
|
renderOrder: SECTION_RENDER_ORDER.outline,
|
|
2928
3097
|
children: [
|
|
2929
|
-
/* @__PURE__ */
|
|
3098
|
+
/* @__PURE__ */ jsx5("mesh", { geometry: frameSurface, raycast: () => null, children: /* @__PURE__ */ jsx5(
|
|
2930
3099
|
"meshBasicMaterial",
|
|
2931
3100
|
{
|
|
2932
3101
|
color: directionColor2,
|
|
@@ -2937,59 +3106,27 @@ var SectionView = ({
|
|
|
2937
3106
|
depthWrite: false
|
|
2938
3107
|
}
|
|
2939
3108
|
) }),
|
|
2940
|
-
/* @__PURE__ */
|
|
3109
|
+
/* @__PURE__ */ jsx5("lineSegments", { geometry: frameEdges, raycast: () => null, children: /* @__PURE__ */ jsx5("lineBasicMaterial", { color: directionColor2, depthTest: false, depthWrite: false }) })
|
|
2941
3110
|
]
|
|
2942
3111
|
}
|
|
2943
3112
|
),
|
|
2944
|
-
/* @__PURE__ */
|
|
3113
|
+
/* @__PURE__ */ jsx5(
|
|
2945
3114
|
"group",
|
|
2946
3115
|
{
|
|
2947
3116
|
ref: handleRef,
|
|
2948
3117
|
position: capPosition,
|
|
2949
3118
|
quaternion: handleQuaternion,
|
|
2950
3119
|
renderOrder: SECTION_RENDER_ORDER.handle,
|
|
2951
|
-
children:
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
] }),
|
|
2962
|
-
/* @__PURE__ */ jsxs3("mesh", { ...grab, children: [
|
|
2963
|
-
/* @__PURE__ */ jsx4("cylinderGeometry", { args: [0.035, 0.035, 0.9, 12] }),
|
|
2964
|
-
/* @__PURE__ */ jsx4(
|
|
2965
|
-
"meshBasicMaterial",
|
|
2966
|
-
{
|
|
2967
|
-
color: hovered ? theme.hover : resolvedHandleColor,
|
|
2968
|
-
depthTest: false
|
|
2969
|
-
}
|
|
2970
|
-
)
|
|
2971
|
-
] }),
|
|
2972
|
-
/* @__PURE__ */ jsxs3("mesh", { position: [0, 0.61, 0], ...grab, children: [
|
|
2973
|
-
/* @__PURE__ */ jsx4("coneGeometry", { args: [0.15, 0.3, 20] }),
|
|
2974
|
-
/* @__PURE__ */ jsx4(
|
|
2975
|
-
"meshBasicMaterial",
|
|
2976
|
-
{
|
|
2977
|
-
color: hovered ? theme.hover : resolvedHandleColor,
|
|
2978
|
-
depthTest: false
|
|
2979
|
-
}
|
|
2980
|
-
)
|
|
2981
|
-
] }),
|
|
2982
|
-
/* @__PURE__ */ jsxs3("mesh", { position: [0, -0.61, 0], rotation: [Math.PI, 0, 0], ...grab, children: [
|
|
2983
|
-
/* @__PURE__ */ jsx4("coneGeometry", { args: [0.15, 0.3, 20] }),
|
|
2984
|
-
/* @__PURE__ */ jsx4(
|
|
2985
|
-
"meshBasicMaterial",
|
|
2986
|
-
{
|
|
2987
|
-
color: hovered ? theme.hover : resolvedHandleColor,
|
|
2988
|
-
depthTest: false
|
|
2989
|
-
}
|
|
2990
|
-
)
|
|
2991
|
-
] })
|
|
2992
|
-
]
|
|
3120
|
+
children: /* @__PURE__ */ jsx5(
|
|
3121
|
+
ArrowMesh,
|
|
3122
|
+
{
|
|
3123
|
+
geometry: handleShape,
|
|
3124
|
+
color: hovered ? theme.hover : resolvedHandleColor,
|
|
3125
|
+
opacity: 1,
|
|
3126
|
+
onTop: true,
|
|
3127
|
+
events: grab
|
|
3128
|
+
}
|
|
3129
|
+
)
|
|
2993
3130
|
}
|
|
2994
3131
|
)
|
|
2995
3132
|
] }) : null
|
|
@@ -2998,11 +3135,11 @@ var SectionView = ({
|
|
|
2998
3135
|
};
|
|
2999
3136
|
|
|
3000
3137
|
// src/content-box.ts
|
|
3001
|
-
import { useFrame as useFrame5, useThree as
|
|
3138
|
+
import { useFrame as useFrame5, useThree as useThree7 } from "@react-three/fiber";
|
|
3002
3139
|
import { useRef as useRef5, useState as useState2 } from "react";
|
|
3003
3140
|
import { Box3 as Box34 } from "three";
|
|
3004
3141
|
function useContentBox() {
|
|
3005
|
-
const scene =
|
|
3142
|
+
const scene = useThree7((state) => state.scene);
|
|
3006
3143
|
const [box, setBox] = useState2(() => new Box34());
|
|
3007
3144
|
const measured = useRef5(false);
|
|
3008
3145
|
useFrame5(() => {
|
|
@@ -3017,7 +3154,7 @@ function useContentBox() {
|
|
|
3017
3154
|
}
|
|
3018
3155
|
|
|
3019
3156
|
// src/part-mesh.tsx
|
|
3020
|
-
import { Fragment as
|
|
3157
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3021
3158
|
var PartMesh = ({
|
|
3022
3159
|
model,
|
|
3023
3160
|
geometry,
|
|
@@ -3041,13 +3178,13 @@ var PartMesh = ({
|
|
|
3041
3178
|
display = "solid",
|
|
3042
3179
|
children
|
|
3043
3180
|
}) => {
|
|
3044
|
-
const { camera, controls, invalidate } =
|
|
3045
|
-
const context =
|
|
3181
|
+
const { camera, controls, invalidate } = useThree8();
|
|
3182
|
+
const context = useMemo7(() => ({ model, geometry }), [model, geometry]);
|
|
3046
3183
|
const viewerControls = useViewerControls();
|
|
3047
3184
|
const resolved = useStableTheme(theme);
|
|
3048
3185
|
const currentTheme = useRef6(resolved);
|
|
3049
3186
|
currentTheme.current = resolved;
|
|
3050
|
-
const part =
|
|
3187
|
+
const part = useMemo7(() => createPart(model, geometry, currentTheme.current), [geometry, model]);
|
|
3051
3188
|
const hoverRegion = useRef6(null);
|
|
3052
3189
|
const onHoverRef = useRef6(onHover);
|
|
3053
3190
|
onHoverRef.current = onHover;
|
|
@@ -3056,7 +3193,7 @@ var PartMesh = ({
|
|
|
3056
3193
|
const shared = useSyncExternalStore(store.subscribe, store.get, store.get);
|
|
3057
3194
|
const controlled = section !== void 0;
|
|
3058
3195
|
const options = controlled ? section : shared ?? void 0;
|
|
3059
|
-
const cut =
|
|
3196
|
+
const cut = useMemo7(() => resolveSectionPlane(options, box), [box, options]);
|
|
3060
3197
|
const engaged = useSyncExternalStore(store.subscribe, store.isEngaged, store.isEngaged);
|
|
3061
3198
|
const pressedWhileEngaged = useRef6(false);
|
|
3062
3199
|
const layers = useRef6({
|
|
@@ -3084,19 +3221,19 @@ var PartMesh = ({
|
|
|
3084
3221
|
);
|
|
3085
3222
|
invalidate();
|
|
3086
3223
|
}, [invalidate, part]);
|
|
3087
|
-
|
|
3088
|
-
const adjacency =
|
|
3089
|
-
|
|
3224
|
+
useEffect7(() => () => part.dispose(), [part]);
|
|
3225
|
+
const adjacency = useMemo7(() => regionAdjacency(model, geometry), [model, geometry]);
|
|
3226
|
+
useEffect7(() => {
|
|
3090
3227
|
onAdjacency?.(adjacency);
|
|
3091
3228
|
}, [adjacency, onAdjacency]);
|
|
3092
3229
|
const framed = useRef6(null);
|
|
3093
|
-
|
|
3230
|
+
useEffect7(() => {
|
|
3094
3231
|
if (focusFeature === null || focusFeature === framed.current) return;
|
|
3095
3232
|
framed.current = focusFeature;
|
|
3096
3233
|
const box2 = part.boxForFeature(focusFeature);
|
|
3097
3234
|
if (box2) viewerControls.frameBox(box2);
|
|
3098
3235
|
}, [focusFeature, part, viewerControls]);
|
|
3099
|
-
|
|
3236
|
+
useLayoutEffect3(() => {
|
|
3100
3237
|
part.setTheme(resolved);
|
|
3101
3238
|
repaint();
|
|
3102
3239
|
}, [part, repaint, resolved]);
|
|
@@ -3105,20 +3242,20 @@ var PartMesh = ({
|
|
|
3105
3242
|
const selectionRef = useRef6(selection);
|
|
3106
3243
|
selectionRef.current = selection;
|
|
3107
3244
|
const focusKey = focusStateKey(focus, selection);
|
|
3108
|
-
|
|
3245
|
+
useLayoutEffect3(() => {
|
|
3109
3246
|
part.setFocus(selectionRef.current, focusRef.current);
|
|
3110
3247
|
invalidate();
|
|
3111
3248
|
}, [focusKey, invalidate, part]);
|
|
3112
|
-
|
|
3249
|
+
useLayoutEffect3(() => {
|
|
3113
3250
|
part.setDisplay(display, showEdges);
|
|
3114
3251
|
invalidate();
|
|
3115
3252
|
}, [display, invalidate, part, showEdges]);
|
|
3116
|
-
|
|
3253
|
+
useLayoutEffect3(() => {
|
|
3117
3254
|
part.setClippingPlanes(cut ? [cut.plane] : null);
|
|
3118
3255
|
invalidate();
|
|
3119
3256
|
}, [cut, invalidate, part]);
|
|
3120
3257
|
const reportedSection = useRef6("");
|
|
3121
|
-
|
|
3258
|
+
useLayoutEffect3(() => {
|
|
3122
3259
|
const state = cut?.state ?? null;
|
|
3123
3260
|
const key = state ? `${state.constant}|${state.normal.x},${state.normal.y},${state.normal.z}` : "";
|
|
3124
3261
|
if (key === reportedSection.current) return;
|
|
@@ -3135,12 +3272,12 @@ var PartMesh = ({
|
|
|
3135
3272
|
highlights.map((entry) => `${entry.tag}:${entry.color}:${entry.weight ?? ""}`).join(" "),
|
|
3136
3273
|
regionHighlights.map((entry) => `${entry.region}:${entry.color}:${entry.weight ?? ""}`).join(" ")
|
|
3137
3274
|
].join("|");
|
|
3138
|
-
|
|
3275
|
+
useLayoutEffect3(() => {
|
|
3139
3276
|
repaint();
|
|
3140
3277
|
}, [layerKey, repaint]);
|
|
3141
3278
|
const isTap = useTapGuard();
|
|
3142
3279
|
const retarget = useRetarget();
|
|
3143
|
-
const doubles =
|
|
3280
|
+
const doubles = useMemo7(() => trackDoubleTaps(), []);
|
|
3144
3281
|
const pickFor = (event, doubled = false) => {
|
|
3145
3282
|
const triangleIndex = event.faceIndex;
|
|
3146
3283
|
if (triangleIndex == null) return null;
|
|
@@ -3175,13 +3312,13 @@ var PartMesh = ({
|
|
|
3175
3312
|
repaint();
|
|
3176
3313
|
onHover?.(next);
|
|
3177
3314
|
};
|
|
3178
|
-
|
|
3315
|
+
useLayoutEffect3(() => {
|
|
3179
3316
|
if (hover || hoverRegion.current === null) return;
|
|
3180
3317
|
hoverRegion.current = null;
|
|
3181
3318
|
repaint();
|
|
3182
3319
|
onHoverRef.current?.(null);
|
|
3183
3320
|
}, [hover, repaint]);
|
|
3184
|
-
|
|
3321
|
+
useLayoutEffect3(() => {
|
|
3185
3322
|
if (!engaged || hoverRegion.current === null) return;
|
|
3186
3323
|
hoverRegion.current = null;
|
|
3187
3324
|
repaint();
|
|
@@ -3205,8 +3342,8 @@ var PartMesh = ({
|
|
|
3205
3342
|
},
|
|
3206
3343
|
[box, controlled, cut, onSectionChange, options, store]
|
|
3207
3344
|
);
|
|
3208
|
-
return /* @__PURE__ */
|
|
3209
|
-
/* @__PURE__ */
|
|
3345
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3346
|
+
/* @__PURE__ */ jsx6(
|
|
3210
3347
|
"primitive",
|
|
3211
3348
|
{
|
|
3212
3349
|
object: part.object,
|
|
@@ -3243,7 +3380,7 @@ var PartMesh = ({
|
|
|
3243
3380
|
}
|
|
3244
3381
|
}
|
|
3245
3382
|
),
|
|
3246
|
-
cut ? /* @__PURE__ */
|
|
3383
|
+
cut ? /* @__PURE__ */ jsx6(
|
|
3247
3384
|
SectionView,
|
|
3248
3385
|
{
|
|
3249
3386
|
geometry,
|
|
@@ -3255,7 +3392,7 @@ var PartMesh = ({
|
|
|
3255
3392
|
onDrag: !controlled || onSectionChange ? dragSection : void 0
|
|
3256
3393
|
}
|
|
3257
3394
|
) : null,
|
|
3258
|
-
children ? /* @__PURE__ */
|
|
3395
|
+
children ? /* @__PURE__ */ jsx6(PartContext.Provider, { value: context, children }) : null
|
|
3259
3396
|
] });
|
|
3260
3397
|
};
|
|
3261
3398
|
var ORIGIN = new Vector311();
|
|
@@ -3884,15 +4021,15 @@ function compareVersions(a, b) {
|
|
|
3884
4021
|
}
|
|
3885
4022
|
|
|
3886
4023
|
// src/engine/engine-part.tsx
|
|
3887
|
-
import { jsx as
|
|
4024
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
3888
4025
|
var EnginePart = ({ report, ...props }) => {
|
|
3889
|
-
const model =
|
|
4026
|
+
const model = useMemo8(() => normalizePartReport(report), [report]);
|
|
3890
4027
|
const resource = useGeometryResource(model);
|
|
3891
|
-
|
|
4028
|
+
useEffect8(() => {
|
|
3892
4029
|
engineGeometryCache.retain(resource);
|
|
3893
4030
|
return () => engineGeometryCache.release(resource);
|
|
3894
4031
|
}, [resource]);
|
|
3895
|
-
return /* @__PURE__ */
|
|
4032
|
+
return /* @__PURE__ */ jsx7(PartMesh, { model, geometry: resource.geometry, ...props });
|
|
3896
4033
|
};
|
|
3897
4034
|
function useGeometryResource(part) {
|
|
3898
4035
|
const resource = engineGeometryCache.get(part);
|
|
@@ -4045,11 +4182,9 @@ export {
|
|
|
4045
4182
|
useSectionStore,
|
|
4046
4183
|
useRetarget,
|
|
4047
4184
|
Viewer,
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
SHAFT_RADIUS,
|
|
4052
|
-
arrowPlacement,
|
|
4185
|
+
ArrowMesh,
|
|
4186
|
+
ARROW_AXIS2 as ARROW_AXIS,
|
|
4187
|
+
arrowGeometry,
|
|
4053
4188
|
createMaskTarget,
|
|
4054
4189
|
createCapMaterial,
|
|
4055
4190
|
applyCapTheme,
|
package/dist/engine/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ANGLE_ARC_FRACTION,
|
|
3
3
|
ANGLE_ARC_SEGMENTS,
|
|
4
|
+
ARROW_AXIS,
|
|
4
5
|
AXES_PLANE_OFFSET,
|
|
5
6
|
AXES_PLANE_SCALE,
|
|
6
7
|
AXIS_COLORS,
|
|
8
|
+
ArrowMesh,
|
|
7
9
|
CAD_CAMERA_UP,
|
|
8
10
|
CANDIDATE_WEIGHT,
|
|
9
11
|
CAP_HATCH,
|
|
10
12
|
CHAMFER,
|
|
11
|
-
CONE_AXIS,
|
|
12
13
|
CONTROL_SCHEME_OPTIONS,
|
|
13
14
|
CadCameraControls,
|
|
14
15
|
DEFAULT_FIT_MARGIN,
|
|
@@ -23,8 +24,6 @@ import {
|
|
|
23
24
|
ExtendedCameraControls,
|
|
24
25
|
FEATURE_TYPE_RANKS,
|
|
25
26
|
HANDLE_PIXELS,
|
|
26
|
-
HEAD,
|
|
27
|
-
HEAD_RADIUS,
|
|
28
27
|
HIGHLIGHT_COLORS,
|
|
29
28
|
HIGHLIGHT_WEIGHT,
|
|
30
29
|
HOVER_WEIGHT,
|
|
@@ -52,7 +51,6 @@ import {
|
|
|
52
51
|
REGION_ATTRIBUTE,
|
|
53
52
|
SECTION_GIZMO_FRAME_SCALE,
|
|
54
53
|
SECTION_RENDER_ORDER,
|
|
55
|
-
SHAFT_RADIUS,
|
|
56
54
|
SNAP_MARKER_PIXELS,
|
|
57
55
|
SNAP_PIXELS,
|
|
58
56
|
STOCK_OBJECT,
|
|
@@ -69,7 +67,7 @@ import {
|
|
|
69
67
|
applyCapTheme,
|
|
70
68
|
applyHighlightLayers,
|
|
71
69
|
applyProjection,
|
|
72
|
-
|
|
70
|
+
arrowGeometry,
|
|
73
71
|
aspectRatio,
|
|
74
72
|
axesPlanes,
|
|
75
73
|
bestOwner,
|
|
@@ -162,7 +160,7 @@ import {
|
|
|
162
160
|
viewUp,
|
|
163
161
|
viewVector,
|
|
164
162
|
visualSurfaces
|
|
165
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-7S6SIYHL.js";
|
|
166
164
|
|
|
167
165
|
// src/render/feature-triangles.ts
|
|
168
166
|
var EMPTY = { positions: new Float32Array(), normals: new Float32Array() };
|
|
@@ -1123,8 +1121,33 @@ var CubePanels = ({
|
|
|
1123
1121
|
|
|
1124
1122
|
// src/direction-arrows.tsx
|
|
1125
1123
|
import { useThree as useThree4 } from "@react-three/fiber";
|
|
1126
|
-
import { useMemo as useMemo4 } from "react";
|
|
1127
|
-
import { Quaternion as Quaternion2, Vector3 as
|
|
1124
|
+
import { useEffect as useEffect4, useMemo as useMemo4 } from "react";
|
|
1125
|
+
import { Quaternion as Quaternion2, Vector3 as Vector35 } from "three";
|
|
1126
|
+
|
|
1127
|
+
// src/render/directions.ts
|
|
1128
|
+
import { Vector3 as Vector34 } from "three";
|
|
1129
|
+
var LENGTH = 0.33;
|
|
1130
|
+
var GAP = 0.2;
|
|
1131
|
+
function arrowPlacement(direction, box) {
|
|
1132
|
+
const center = box.getCenter(new Vector34());
|
|
1133
|
+
const half = box.getSize(new Vector34()).multiplyScalar(0.5);
|
|
1134
|
+
const radius = half.length() || 1;
|
|
1135
|
+
const axis = new Vector34(direction.x, direction.y, direction.z);
|
|
1136
|
+
if (axis.lengthSq() === 0) axis.set(0, 0, 1);
|
|
1137
|
+
axis.normalize();
|
|
1138
|
+
let exit = Number.POSITIVE_INFINITY;
|
|
1139
|
+
for (const [component, extent] of [
|
|
1140
|
+
[axis.x, half.x],
|
|
1141
|
+
[axis.y, half.y],
|
|
1142
|
+
[axis.z, half.z]
|
|
1143
|
+
]) {
|
|
1144
|
+
if (Math.abs(component) > 1e-6) exit = Math.min(exit, extent / Math.abs(component));
|
|
1145
|
+
}
|
|
1146
|
+
if (!Number.isFinite(exit)) exit = radius;
|
|
1147
|
+
return { tip: center.addScaledVector(axis, exit + radius * GAP), length: radius * LENGTH };
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// src/direction-arrows.tsx
|
|
1128
1151
|
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1129
1152
|
var FURNITURE3 = { [EXCLUDE_FROM_FRAME]: true };
|
|
1130
1153
|
var DirectionArrows = ({
|
|
@@ -1139,6 +1162,8 @@ var DirectionArrows = ({
|
|
|
1139
1162
|
}) => {
|
|
1140
1163
|
const box = useContentBox();
|
|
1141
1164
|
const resolved = useMemo4(() => resolveTheme(theme), [theme]);
|
|
1165
|
+
const geometry = useMemo4(() => arrowGeometry(), []);
|
|
1166
|
+
useEffect4(() => () => geometry.dispose(), [geometry]);
|
|
1142
1167
|
const shown = shownDirection === void 0 ? activeDirection : shownDirection;
|
|
1143
1168
|
const drawn = (index) => {
|
|
1144
1169
|
if (shown === null) return true;
|
|
@@ -1158,6 +1183,7 @@ var DirectionArrows = ({
|
|
|
1158
1183
|
{
|
|
1159
1184
|
direction,
|
|
1160
1185
|
box,
|
|
1186
|
+
geometry,
|
|
1161
1187
|
color: directionColor(index),
|
|
1162
1188
|
opacity: 0.9,
|
|
1163
1189
|
onPick: onPickDirection ? () => onPickDirection(index) : void 0
|
|
@@ -1170,28 +1196,37 @@ var DirectionArrows = ({
|
|
|
1170
1196
|
{
|
|
1171
1197
|
direction: named.direction,
|
|
1172
1198
|
box,
|
|
1199
|
+
geometry,
|
|
1173
1200
|
color: named.color,
|
|
1174
1201
|
opacity: 0.9,
|
|
1175
1202
|
onPick: onPickDirection ? () => onPickDirection(named.index) : void 0
|
|
1176
1203
|
},
|
|
1177
1204
|
`named-${named.index}`
|
|
1178
1205
|
)),
|
|
1179
|
-
previewDirection ? /* @__PURE__ */ jsx7(
|
|
1206
|
+
previewDirection ? /* @__PURE__ */ jsx7(
|
|
1207
|
+
Arrow,
|
|
1208
|
+
{
|
|
1209
|
+
direction: previewDirection,
|
|
1210
|
+
box,
|
|
1211
|
+
geometry,
|
|
1212
|
+
color: resolved.hover,
|
|
1213
|
+
opacity: 0.95,
|
|
1214
|
+
onTop: true
|
|
1215
|
+
}
|
|
1216
|
+
) : null
|
|
1180
1217
|
] })
|
|
1181
1218
|
);
|
|
1182
1219
|
};
|
|
1183
|
-
var Arrow = ({ direction, box, color, opacity, onPick, onTop = false }) => {
|
|
1220
|
+
var Arrow = ({ direction, box, geometry, color, opacity, onPick, onTop = false }) => {
|
|
1184
1221
|
const invalidate = useThree4((state) => state.invalidate);
|
|
1185
1222
|
const { tip, length, quaternion } = useMemo4(() => {
|
|
1186
1223
|
const placement = arrowPlacement(direction, box);
|
|
1187
1224
|
const aim = new Quaternion2().setFromUnitVectors(
|
|
1188
|
-
|
|
1189
|
-
new
|
|
1225
|
+
ARROW_AXIS,
|
|
1226
|
+
new Vector35(direction.x, direction.y, direction.z).normalize()
|
|
1190
1227
|
);
|
|
1191
1228
|
return { tip: placement.tip, length: placement.length, quaternion: aim };
|
|
1192
1229
|
}, [box, direction]);
|
|
1193
|
-
const head = length * HEAD;
|
|
1194
|
-
const shaft = length * (1 - HEAD);
|
|
1195
1230
|
const press = onPick ? {
|
|
1196
1231
|
onClick: (event) => {
|
|
1197
1232
|
event.stopPropagation();
|
|
@@ -1199,32 +1234,23 @@ var Arrow = ({ direction, box, color, opacity, onPick, onTop = false }) => {
|
|
|
1199
1234
|
invalidate();
|
|
1200
1235
|
}
|
|
1201
1236
|
} : {};
|
|
1202
|
-
return /* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */ jsxs3("mesh", { position: [0, head * 0.5, 0], rotation: [Math.PI, 0, 0], ...press, children: [
|
|
1204
|
-
/* @__PURE__ */ jsx7("coneGeometry", { args: [length * HEAD_RADIUS, head, 20] }),
|
|
1205
|
-
/* @__PURE__ */ jsx7("meshBasicMaterial", { color, transparent: true, opacity, depthTest: !onTop })
|
|
1206
|
-
] }),
|
|
1207
|
-
/* @__PURE__ */ jsxs3("mesh", { position: [0, head + shaft * 0.5, 0], ...press, children: [
|
|
1208
|
-
/* @__PURE__ */ jsx7("cylinderGeometry", { args: [length * SHAFT_RADIUS, length * SHAFT_RADIUS, shaft, 12] }),
|
|
1209
|
-
/* @__PURE__ */ jsx7("meshBasicMaterial", { color, transparent: true, opacity, depthTest: !onTop })
|
|
1210
|
-
] })
|
|
1211
|
-
] });
|
|
1237
|
+
return /* @__PURE__ */ jsx7("group", { position: tip, quaternion, scale: length, renderOrder: onTop ? 10 : 3, children: /* @__PURE__ */ jsx7(ArrowMesh, { geometry, color, opacity, onTop, events: press }) });
|
|
1212
1238
|
};
|
|
1213
1239
|
|
|
1214
1240
|
// src/section-tool.tsx
|
|
1215
1241
|
import { useFrame, useThree as useThree5 } from "@react-three/fiber";
|
|
1216
|
-
import { useEffect as
|
|
1242
|
+
import { useEffect as useEffect5, useMemo as useMemo5, useRef as useRef3, useState as useState4, useSyncExternalStore } from "react";
|
|
1217
1243
|
import {
|
|
1218
1244
|
BufferGeometry as BufferGeometry2,
|
|
1219
1245
|
DoubleSide,
|
|
1220
1246
|
Quaternion as Quaternion3,
|
|
1221
1247
|
Raycaster,
|
|
1222
1248
|
Vector2,
|
|
1223
|
-
Vector3 as
|
|
1249
|
+
Vector3 as Vector36
|
|
1224
1250
|
} from "three";
|
|
1225
1251
|
import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1226
1252
|
var FURNITURE4 = { [EXCLUDE_FROM_FRAME]: true };
|
|
1227
|
-
var Z = new
|
|
1253
|
+
var Z = new Vector36(0, 0, 1);
|
|
1228
1254
|
var AXIS_ROTATIONS = {
|
|
1229
1255
|
x: [0, Math.PI / 2, 0],
|
|
1230
1256
|
y: [Math.PI / 2, 0, 0],
|
|
@@ -1237,11 +1263,11 @@ var SectionTool = ({ theme }) => {
|
|
|
1237
1263
|
const section = useSyncExternalStore(store.subscribe, store.get, store.get);
|
|
1238
1264
|
const box = useContentBox();
|
|
1239
1265
|
const resolved = useMemo5(() => resolveTheme(theme), [theme]);
|
|
1240
|
-
|
|
1266
|
+
useEffect5(() => {
|
|
1241
1267
|
store.setEngaged(true);
|
|
1242
1268
|
return () => store.setEngaged(false);
|
|
1243
1269
|
}, [store]);
|
|
1244
|
-
|
|
1270
|
+
useEffect5(() => {
|
|
1245
1271
|
if (!section) return void 0;
|
|
1246
1272
|
const clear = (event) => {
|
|
1247
1273
|
if (event.key === "Escape") store.set(null);
|
|
@@ -1255,14 +1281,14 @@ var SectionTool = ({ theme }) => {
|
|
|
1255
1281
|
var useSquare = () => {
|
|
1256
1282
|
const square = useMemo5(
|
|
1257
1283
|
() => new BufferGeometry2().setFromPoints([
|
|
1258
|
-
new
|
|
1259
|
-
new
|
|
1260
|
-
new
|
|
1261
|
-
new
|
|
1284
|
+
new Vector36(-1, 1, 0),
|
|
1285
|
+
new Vector36(1, 1, 0),
|
|
1286
|
+
new Vector36(1, -1, 0),
|
|
1287
|
+
new Vector36(-1, -1, 0)
|
|
1262
1288
|
]),
|
|
1263
1289
|
[]
|
|
1264
1290
|
);
|
|
1265
|
-
|
|
1291
|
+
useEffect5(() => () => square.dispose(), [square]);
|
|
1266
1292
|
return square;
|
|
1267
1293
|
};
|
|
1268
1294
|
var Picker = ({ box, theme }) => {
|
|
@@ -1276,17 +1302,17 @@ var Picker = ({ box, theme }) => {
|
|
|
1276
1302
|
const previewRef = useRef3(null);
|
|
1277
1303
|
const hover = useRef3(null);
|
|
1278
1304
|
const [hoveredPlane, setHoveredPlane] = useState4(null);
|
|
1279
|
-
const span = useMemo5(() => box.getSize(new
|
|
1280
|
-
const centre = useMemo5(() => box.getCenter(new
|
|
1305
|
+
const span = useMemo5(() => box.getSize(new Vector36()).length(), [box]);
|
|
1306
|
+
const centre = useMemo5(() => box.getCenter(new Vector36()), [box]);
|
|
1281
1307
|
const previewSize = span * PREVIEW_SCALE;
|
|
1282
|
-
|
|
1308
|
+
useEffect5(() => {
|
|
1283
1309
|
store.setPicking(true);
|
|
1284
1310
|
return () => store.setPicking(false);
|
|
1285
1311
|
}, [store]);
|
|
1286
|
-
|
|
1312
|
+
useEffect5(() => {
|
|
1287
1313
|
const raycaster = new Raycaster();
|
|
1288
1314
|
const pointer = new Vector2();
|
|
1289
|
-
const aim = new
|
|
1315
|
+
const aim = new Vector36();
|
|
1290
1316
|
const hide = () => {
|
|
1291
1317
|
if (!hover.current) return;
|
|
1292
1318
|
hover.current = null;
|
|
@@ -1430,7 +1456,7 @@ var Picker = ({ box, theme }) => {
|
|
|
1430
1456
|
var CutSheet = ({ box, section, theme }) => {
|
|
1431
1457
|
const square = useSquare();
|
|
1432
1458
|
const cut = useMemo5(() => resolveSectionPlane(section, box), [box, section]);
|
|
1433
|
-
const span = useMemo5(() => box.getSize(new
|
|
1459
|
+
const span = useMemo5(() => box.getSize(new Vector36()).length(), [box]);
|
|
1434
1460
|
const placement = useMemo5(() => {
|
|
1435
1461
|
if (!cut) return null;
|
|
1436
1462
|
const position = sectionAnchor(box, cut.plane).addScaledVector(
|
|
@@ -1481,7 +1507,7 @@ var CutSheet = ({ box, section, theme }) => {
|
|
|
1481
1507
|
import { Html, Line } from "@react-three/drei";
|
|
1482
1508
|
import { useFrame as useFrame2, useThree as useThree6 } from "@react-three/fiber";
|
|
1483
1509
|
import {
|
|
1484
|
-
useEffect as
|
|
1510
|
+
useEffect as useEffect6,
|
|
1485
1511
|
useLayoutEffect as useLayoutEffect3,
|
|
1486
1512
|
useMemo as useMemo6,
|
|
1487
1513
|
useRef as useRef4,
|
|
@@ -1493,18 +1519,18 @@ import {
|
|
|
1493
1519
|
Raycaster as Raycaster2,
|
|
1494
1520
|
SphereGeometry,
|
|
1495
1521
|
Vector2 as Vector22,
|
|
1496
|
-
Vector3 as
|
|
1522
|
+
Vector3 as Vector38
|
|
1497
1523
|
} from "three";
|
|
1498
1524
|
|
|
1499
1525
|
// src/render/resample.ts
|
|
1500
|
-
import { Vector3 as
|
|
1526
|
+
import { Vector3 as Vector37 } from "three";
|
|
1501
1527
|
var ON_PLANE = 1e-7;
|
|
1502
1528
|
var STITCH = 1e-5;
|
|
1503
1529
|
var COLLINEAR = 1e-6;
|
|
1504
1530
|
function clipSegments(positions, plane) {
|
|
1505
1531
|
const out = [];
|
|
1506
|
-
const a = new
|
|
1507
|
-
const b = new
|
|
1532
|
+
const a = new Vector37();
|
|
1533
|
+
const b = new Vector37();
|
|
1508
1534
|
const count = Math.floor(positions.length / 6);
|
|
1509
1535
|
for (let i = 0; i < count; i += 1) {
|
|
1510
1536
|
a.set(positions[i * 6], positions[i * 6 + 1], positions[i * 6 + 2]);
|
|
@@ -1519,11 +1545,11 @@ function clipSegments(positions, plane) {
|
|
|
1519
1545
|
return Float32Array.from(out);
|
|
1520
1546
|
}
|
|
1521
1547
|
function sectionContour(positions, regionOf, plane) {
|
|
1522
|
-
const a = new
|
|
1523
|
-
const b = new
|
|
1524
|
-
const c = new
|
|
1525
|
-
const p = new
|
|
1526
|
-
const q = new
|
|
1548
|
+
const a = new Vector37();
|
|
1549
|
+
const b = new Vector37();
|
|
1550
|
+
const c = new Vector37();
|
|
1551
|
+
const p = new Vector37();
|
|
1552
|
+
const q = new Vector37();
|
|
1527
1553
|
const byRegion = /* @__PURE__ */ new Map();
|
|
1528
1554
|
const triangleCount = Math.floor(positions.length / 9);
|
|
1529
1555
|
for (let t = 0; t < triangleCount; t += 1) {
|
|
@@ -1581,17 +1607,17 @@ function stitch(segments, out) {
|
|
|
1581
1607
|
return into.set(segments[o], segments[o + 1], segments[o + 2]);
|
|
1582
1608
|
};
|
|
1583
1609
|
const direction = (i, into) => {
|
|
1584
|
-
const s = new
|
|
1585
|
-
const e = new
|
|
1610
|
+
const s = new Vector37();
|
|
1611
|
+
const e = new Vector37();
|
|
1586
1612
|
point(i, 0, s);
|
|
1587
1613
|
point(i, 1, e);
|
|
1588
1614
|
return into.subVectors(e, s).normalize();
|
|
1589
1615
|
};
|
|
1590
1616
|
const consumed = new Uint8Array(count);
|
|
1591
|
-
const d = new
|
|
1592
|
-
const n = new
|
|
1617
|
+
const d = new Vector37();
|
|
1618
|
+
const n = new Vector37();
|
|
1593
1619
|
const next = (i, end) => {
|
|
1594
|
-
const at = point(i, end, new
|
|
1620
|
+
const at = point(i, end, new Vector37());
|
|
1595
1621
|
const list = ends.get(key(at.x, at.y, at.z)) ?? [];
|
|
1596
1622
|
if (list.length !== 2) return null;
|
|
1597
1623
|
const other = list.find((entry) => entry >> 1 !== i);
|
|
@@ -1620,8 +1646,8 @@ function stitch(segments, out) {
|
|
|
1620
1646
|
};
|
|
1621
1647
|
const back = walk(0);
|
|
1622
1648
|
const forward = walk(1);
|
|
1623
|
-
const s = point(back.index, back.end, new
|
|
1624
|
-
const e = point(forward.index, forward.end, new
|
|
1649
|
+
const s = point(back.index, back.end, new Vector37());
|
|
1650
|
+
const e = point(forward.index, forward.end, new Vector37());
|
|
1625
1651
|
out.push(s.x, s.y, s.z, e.x, e.y, e.z);
|
|
1626
1652
|
}
|
|
1627
1653
|
}
|
|
@@ -1629,8 +1655,8 @@ function pointInContour(point, plane, contour) {
|
|
|
1629
1655
|
const [u, v] = planeAxes(plane);
|
|
1630
1656
|
const px = point.dot(u);
|
|
1631
1657
|
const py = point.dot(v);
|
|
1632
|
-
const a = new
|
|
1633
|
-
const b = new
|
|
1658
|
+
const a = new Vector37();
|
|
1659
|
+
const b = new Vector37();
|
|
1634
1660
|
let inside = false;
|
|
1635
1661
|
const count = Math.floor(contour.length / 6);
|
|
1636
1662
|
for (let i = 0; i < count; i += 1) {
|
|
@@ -1647,15 +1673,15 @@ function pointInContour(point, plane, contour) {
|
|
|
1647
1673
|
return inside;
|
|
1648
1674
|
}
|
|
1649
1675
|
function capHit(ray, plane, contour) {
|
|
1650
|
-
const point = ray.intersectPlane(plane, new
|
|
1676
|
+
const point = ray.intersectPlane(plane, new Vector37());
|
|
1651
1677
|
if (!point) return null;
|
|
1652
1678
|
return pointInContour(point, plane, contour) ? point : null;
|
|
1653
1679
|
}
|
|
1654
1680
|
function planeAxes(plane) {
|
|
1655
1681
|
const n = plane.normal;
|
|
1656
|
-
const seed = Math.abs(n.x) < 0.9 ? new
|
|
1657
|
-
const u = new
|
|
1658
|
-
const v = new
|
|
1682
|
+
const seed = Math.abs(n.x) < 0.9 ? new Vector37(1, 0, 0) : new Vector37(0, 1, 0);
|
|
1683
|
+
const u = new Vector37().crossVectors(n, seed).normalize();
|
|
1684
|
+
const v = new Vector37().crossVectors(n, u).normalize();
|
|
1659
1685
|
return [u, v];
|
|
1660
1686
|
}
|
|
1661
1687
|
function sampleSection(meshPositions, regionOf, edgePositions, plane) {
|
|
@@ -1688,11 +1714,11 @@ var MeasureTool = ({
|
|
|
1688
1714
|
const controlled = measurements !== void 0;
|
|
1689
1715
|
const list = controlled ? measurements : held;
|
|
1690
1716
|
const [draft, setDraft] = useState5([]);
|
|
1691
|
-
|
|
1717
|
+
useEffect6(() => {
|
|
1692
1718
|
store.setEngaged(true);
|
|
1693
1719
|
return () => store.setEngaged(false);
|
|
1694
1720
|
}, [store]);
|
|
1695
|
-
|
|
1721
|
+
useEffect6(() => {
|
|
1696
1722
|
setDraft([]);
|
|
1697
1723
|
}, [mode]);
|
|
1698
1724
|
const commit = (next) => {
|
|
@@ -1701,7 +1727,7 @@ var MeasureTool = ({
|
|
|
1701
1727
|
};
|
|
1702
1728
|
const latest = useRef4({ list, commit });
|
|
1703
1729
|
latest.current = { list, commit };
|
|
1704
|
-
|
|
1730
|
+
useEffect6(() => {
|
|
1705
1731
|
const onKey = (event) => {
|
|
1706
1732
|
if (event.key === "Escape") {
|
|
1707
1733
|
setDraft([]);
|
|
@@ -1765,7 +1791,7 @@ var MeasureTool = ({
|
|
|
1765
1791
|
] });
|
|
1766
1792
|
};
|
|
1767
1793
|
var NO_POINTER = { pointerEvents: "none" };
|
|
1768
|
-
var NOWHERE = [new
|
|
1794
|
+
var NOWHERE = [new Vector38(), new Vector38()];
|
|
1769
1795
|
var Snapper = ({ mode, draft, onPlace, theme, format, label }) => {
|
|
1770
1796
|
const camera = useThree6((state) => state.camera);
|
|
1771
1797
|
const scene = useThree6((state) => state.scene);
|
|
@@ -1786,7 +1812,7 @@ var Snapper = ({ mode, draft, onPlace, theme, format, label }) => {
|
|
|
1786
1812
|
}, []);
|
|
1787
1813
|
const current = useRef4({ mode, draft, onPlace, format, size });
|
|
1788
1814
|
current.current = { mode, draft, onPlace, format, size };
|
|
1789
|
-
|
|
1815
|
+
useEffect6(() => {
|
|
1790
1816
|
const raycaster = new Raycaster2();
|
|
1791
1817
|
const pointer = new Vector22();
|
|
1792
1818
|
const samples = new SampleCache();
|
|
@@ -1818,7 +1844,7 @@ var Snapper = ({ mode, draft, onPlace, theme, format, label }) => {
|
|
|
1818
1844
|
const snapped = snapAt(target, target.edges, camera, viewport);
|
|
1819
1845
|
const from = placed[placed.length - 1];
|
|
1820
1846
|
const lock = shift && from ? lockToAxis(from, snapped.point) : null;
|
|
1821
|
-
const found = lock ? { ...snapped, point: new
|
|
1847
|
+
const found = lock ? { ...snapped, point: new Vector38(lock.point.x, lock.point.y, lock.point.z), edge: null } : snapped;
|
|
1822
1848
|
snap.current = found;
|
|
1823
1849
|
const node = marker.current;
|
|
1824
1850
|
if (node) {
|
|
@@ -1892,7 +1918,7 @@ var Snapper = ({ mode, draft, onPlace, theme, format, label }) => {
|
|
|
1892
1918
|
window.removeEventListener("keyup", key);
|
|
1893
1919
|
};
|
|
1894
1920
|
}, [camera, domElement, invalidate, isTap, scene, theme.measure]);
|
|
1895
|
-
|
|
1921
|
+
useEffect6(() => {
|
|
1896
1922
|
if (draft.length === 0 && band.current) {
|
|
1897
1923
|
band.current.visible = false;
|
|
1898
1924
|
if (bandLabel.current) bandLabel.current.visible = false;
|
|
@@ -2126,7 +2152,7 @@ var DeltaLegs = ({ a, b, id, format, label }) => {
|
|
|
2126
2152
|
const lines = useRef4([]);
|
|
2127
2153
|
const centre = useMemo6(() => {
|
|
2128
2154
|
const at = midpoint(a, b);
|
|
2129
|
-
return new
|
|
2155
|
+
return new Vector38(at.x, at.y, at.z);
|
|
2130
2156
|
}, [a, b]);
|
|
2131
2157
|
useFrame2(() => {
|
|
2132
2158
|
const dash = screenLength(camera, centre, size, DELTA_DASH_PIXELS);
|
|
@@ -2148,8 +2174,8 @@ var DeltaLegs = ({ a, b, id, format, label }) => {
|
|
|
2148
2174
|
lines.current[index] = line;
|
|
2149
2175
|
},
|
|
2150
2176
|
points: [
|
|
2151
|
-
new
|
|
2152
|
-
new
|
|
2177
|
+
new Vector38(leg.from.x, leg.from.y, leg.from.z),
|
|
2178
|
+
new Vector38(leg.to.x, leg.to.y, leg.to.z)
|
|
2153
2179
|
],
|
|
2154
2180
|
color: AXIS_COLORS[leg.axis],
|
|
2155
2181
|
lineWidth: MEASURE_LINE_PIXELS.leg,
|
|
@@ -2185,7 +2211,7 @@ var ScreenDot = ({ point, pixels, color }) => {
|
|
|
2185
2211
|
const invalidate = useThree6((state) => state.invalidate);
|
|
2186
2212
|
const node = useRef4(null);
|
|
2187
2213
|
const dot = useDot();
|
|
2188
|
-
const position = useMemo6(() => new
|
|
2214
|
+
const position = useMemo6(() => new Vector38(point.x, point.y, point.z), [point]);
|
|
2189
2215
|
useFrame2(() => {
|
|
2190
2216
|
const group = node.current;
|
|
2191
2217
|
if (!group) return;
|
|
@@ -2200,7 +2226,7 @@ var ScreenDot = ({ point, pixels, color }) => {
|
|
|
2200
2226
|
var Segment = ({ points, color }) => {
|
|
2201
2227
|
const [a, b] = points;
|
|
2202
2228
|
const ends = useMemo6(
|
|
2203
|
-
() => [new
|
|
2229
|
+
() => [new Vector38(a.x, a.y, a.z), new Vector38(b.x, b.y, b.z)],
|
|
2204
2230
|
// Keyed on the numbers: a draft's tuple is a fresh array on every render,
|
|
2205
2231
|
// and a rebuilt array would rebuild the line's geometry with it.
|
|
2206
2232
|
[a.x, a.y, a.z, b.x, b.y, b.z]
|
|
@@ -2225,7 +2251,7 @@ var Polyline = ({ points, color }) => {
|
|
|
2225
2251
|
};
|
|
2226
2252
|
function useDot() {
|
|
2227
2253
|
const geometry = useMemo6(() => new SphereGeometry(1, 16, 12), []);
|
|
2228
|
-
|
|
2254
|
+
useEffect6(() => () => geometry.dispose(), [geometry]);
|
|
2229
2255
|
return geometry;
|
|
2230
2256
|
}
|
|
2231
2257
|
function isEditing(target) {
|
|
@@ -2242,7 +2268,7 @@ import { useMemo as useMemo7 } from "react";
|
|
|
2242
2268
|
import { DoubleSide as DoubleSide2 } from "three";
|
|
2243
2269
|
|
|
2244
2270
|
// src/render/tool-marks.ts
|
|
2245
|
-
import { Quaternion as Quaternion4, Vector2 as Vector23, Vector3 as
|
|
2271
|
+
import { Quaternion as Quaternion4, Vector2 as Vector23, Vector3 as Vector39 } from "three";
|
|
2246
2272
|
var TOOL_CORNER_STEPS = 12;
|
|
2247
2273
|
var TOOL_ROUND = 64;
|
|
2248
2274
|
function toolProfile(radius, corner, height) {
|
|
@@ -2262,9 +2288,9 @@ function toolProfile(radius, corner, height) {
|
|
|
2262
2288
|
points.push(new Vector23(radius, Math.max(height, rounded)));
|
|
2263
2289
|
return points;
|
|
2264
2290
|
}
|
|
2265
|
-
var UP = new
|
|
2266
|
-
var AXES = [new
|
|
2267
|
-
var toVector = ({ x, y, z }) => new
|
|
2291
|
+
var UP = new Vector39(0, 1, 0);
|
|
2292
|
+
var AXES = [new Vector39(1, 0, 0), new Vector39(0, 1, 0), new Vector39(0, 0, 1)];
|
|
2293
|
+
var toVector = ({ x, y, z }) => new Vector39(x, y, z);
|
|
2268
2294
|
var squareTo = (w, along) => {
|
|
2269
2295
|
const wanted = along ? toVector(along) : null;
|
|
2270
2296
|
const flat = wanted?.clone().addScaledVector(w, -wanted.dot(w));
|
|
@@ -2284,7 +2310,7 @@ function toolMarkShape(mark) {
|
|
|
2284
2310
|
if (!(mark.diameter > 0) || axis.lengthSq() === 0) return null;
|
|
2285
2311
|
const w = axis.normalize();
|
|
2286
2312
|
const u = squareTo(w, mark.across);
|
|
2287
|
-
const v = new
|
|
2313
|
+
const v = new Vector39().crossVectors(w, u);
|
|
2288
2314
|
const radius = mark.diameter / 2;
|
|
2289
2315
|
const corner = Math.min(Math.max(mark.cornerRadius ?? 0, 0), radius);
|
|
2290
2316
|
const height = Math.max(mark.height, corner);
|