@tscircuit/3d-viewer 0.0.418 → 0.0.419
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/index.js +739 -297
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14228,11 +14228,11 @@ var require_browser = __commonJS({
|
|
|
14228
14228
|
});
|
|
14229
14229
|
|
|
14230
14230
|
// src/CadViewer.tsx
|
|
14231
|
-
import { useState as
|
|
14231
|
+
import { useState as useState19, useCallback as useCallback11, useRef as useRef9, useEffect as useEffect24 } from "react";
|
|
14232
14232
|
|
|
14233
14233
|
// src/CadViewerJscad.tsx
|
|
14234
14234
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
14235
|
-
import { forwardRef as forwardRef3, useMemo as
|
|
14235
|
+
import { forwardRef as forwardRef3, useMemo as useMemo19 } from "react";
|
|
14236
14236
|
|
|
14237
14237
|
// src/AnyCadComponent.tsx
|
|
14238
14238
|
import { su } from "@tscircuit/circuit-json-util";
|
|
@@ -26641,17 +26641,13 @@ var AnyCadComponent = ({
|
|
|
26641
26641
|
};
|
|
26642
26642
|
|
|
26643
26643
|
// src/CadViewerContainer.tsx
|
|
26644
|
-
import {
|
|
26645
|
-
|
|
26646
|
-
useMemo as useMemo14,
|
|
26647
|
-
useState as useState8
|
|
26648
|
-
} from "react";
|
|
26649
|
-
import * as THREE13 from "three";
|
|
26644
|
+
import { forwardRef as forwardRef2, useMemo as useMemo15, useState as useState8 } from "react";
|
|
26645
|
+
import * as THREE14 from "three";
|
|
26650
26646
|
|
|
26651
26647
|
// package.json
|
|
26652
26648
|
var package_default = {
|
|
26653
26649
|
name: "@tscircuit/3d-viewer",
|
|
26654
|
-
version: "0.0.
|
|
26650
|
+
version: "0.0.418",
|
|
26655
26651
|
main: "./dist/index.js",
|
|
26656
26652
|
module: "./dist/index.js",
|
|
26657
26653
|
type: "module",
|
|
@@ -27052,13 +27048,21 @@ var OrbitControls = ({
|
|
|
27052
27048
|
zoomSpeed,
|
|
27053
27049
|
enableDamping,
|
|
27054
27050
|
dampingFactor,
|
|
27055
|
-
target
|
|
27051
|
+
target,
|
|
27052
|
+
onControlsChange
|
|
27056
27053
|
}) => {
|
|
27057
27054
|
const { camera, renderer } = useThree();
|
|
27058
27055
|
const controls = useMemo11(() => {
|
|
27059
27056
|
if (!camera || !renderer) return null;
|
|
27060
27057
|
return new ThreeOrbitControls(camera, renderer.domElement);
|
|
27061
27058
|
}, [camera, renderer]);
|
|
27059
|
+
useEffect13(() => {
|
|
27060
|
+
if (!onControlsChange) return;
|
|
27061
|
+
onControlsChange(controls ?? null);
|
|
27062
|
+
return () => {
|
|
27063
|
+
onControlsChange(null);
|
|
27064
|
+
};
|
|
27065
|
+
}, [controls, onControlsChange]);
|
|
27062
27066
|
useEffect13(() => {
|
|
27063
27067
|
if (!controls) return;
|
|
27064
27068
|
controls.autoRotate = autoRotate || false;
|
|
@@ -27222,6 +27226,272 @@ var Lights = () => {
|
|
|
27222
27226
|
return null;
|
|
27223
27227
|
};
|
|
27224
27228
|
|
|
27229
|
+
// src/hooks/useCameraController.ts
|
|
27230
|
+
import { useCallback as useCallback5, useEffect as useEffect16, useMemo as useMemo14, useRef as useRef5 } from "react";
|
|
27231
|
+
import * as THREE13 from "three";
|
|
27232
|
+
var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
27233
|
+
var CameraAnimator = ({
|
|
27234
|
+
defaultTarget,
|
|
27235
|
+
controlsRef,
|
|
27236
|
+
onReady
|
|
27237
|
+
}) => {
|
|
27238
|
+
const { camera } = useThree();
|
|
27239
|
+
const animationRef = useRef5(null);
|
|
27240
|
+
const tempQuaternion = useRef5(new THREE13.Quaternion());
|
|
27241
|
+
const tempTarget = useRef5(new THREE13.Vector3());
|
|
27242
|
+
const tempUp = useRef5(new THREE13.Vector3());
|
|
27243
|
+
const tempRoll = useRef5(new THREE13.Quaternion());
|
|
27244
|
+
const tempRollTarget = useRef5(new THREE13.Quaternion());
|
|
27245
|
+
const baseOrientationHelper = useRef5(new THREE13.Object3D());
|
|
27246
|
+
const orientationHelper = useRef5(new THREE13.Object3D());
|
|
27247
|
+
const animateTo = useCallback5(
|
|
27248
|
+
({ position, target, up, durationMs = 600 }) => {
|
|
27249
|
+
if (!camera) return;
|
|
27250
|
+
const currentTarget = controlsRef.current?.target ?? defaultTarget;
|
|
27251
|
+
const toPosition = new THREE13.Vector3(
|
|
27252
|
+
position[0],
|
|
27253
|
+
position[1],
|
|
27254
|
+
position[2]
|
|
27255
|
+
);
|
|
27256
|
+
const resolvedTarget = target ? new THREE13.Vector3(target[0], target[1], target[2]) : defaultTarget.clone();
|
|
27257
|
+
const resolvedUp = new THREE13.Vector3(...up ?? [0, 0, 1]).normalize();
|
|
27258
|
+
const toOrientationHelper = orientationHelper.current;
|
|
27259
|
+
toOrientationHelper.position.copy(toPosition);
|
|
27260
|
+
toOrientationHelper.up.copy(resolvedUp);
|
|
27261
|
+
toOrientationHelper.lookAt(resolvedTarget);
|
|
27262
|
+
const toQuaternion = toOrientationHelper.quaternion.clone();
|
|
27263
|
+
const fromQuaternion = camera.quaternion.clone();
|
|
27264
|
+
const fromPosition = camera.position.clone();
|
|
27265
|
+
const fromTarget = currentTarget.clone();
|
|
27266
|
+
const baseHelper = baseOrientationHelper.current;
|
|
27267
|
+
baseHelper.up.set(0, 0, 1);
|
|
27268
|
+
baseHelper.position.copy(fromPosition);
|
|
27269
|
+
baseHelper.lookAt(fromTarget);
|
|
27270
|
+
const baseFromQuaternion = baseHelper.quaternion.clone();
|
|
27271
|
+
baseHelper.up.set(0, 0, 1);
|
|
27272
|
+
baseHelper.position.copy(toPosition);
|
|
27273
|
+
baseHelper.lookAt(resolvedTarget);
|
|
27274
|
+
const baseToQuaternion = baseHelper.quaternion.clone();
|
|
27275
|
+
const rollFrom = baseFromQuaternion.clone().invert().multiply(fromQuaternion).normalize();
|
|
27276
|
+
const rollTo = baseToQuaternion.clone().invert().multiply(toQuaternion).normalize();
|
|
27277
|
+
animationRef.current = {
|
|
27278
|
+
fromPosition,
|
|
27279
|
+
toPosition,
|
|
27280
|
+
fromTarget,
|
|
27281
|
+
toTarget: resolvedTarget,
|
|
27282
|
+
toQuaternion,
|
|
27283
|
+
rollFrom,
|
|
27284
|
+
rollTo,
|
|
27285
|
+
startTime: performance.now(),
|
|
27286
|
+
duration: durationMs
|
|
27287
|
+
};
|
|
27288
|
+
},
|
|
27289
|
+
[camera, controlsRef, defaultTarget]
|
|
27290
|
+
);
|
|
27291
|
+
useEffect16(() => {
|
|
27292
|
+
if (!onReady || !camera) return;
|
|
27293
|
+
onReady({ animateTo });
|
|
27294
|
+
return () => {
|
|
27295
|
+
onReady(null);
|
|
27296
|
+
};
|
|
27297
|
+
}, [animateTo, camera, onReady]);
|
|
27298
|
+
useFrame(() => {
|
|
27299
|
+
if (!camera || !animationRef.current) return;
|
|
27300
|
+
const {
|
|
27301
|
+
fromPosition,
|
|
27302
|
+
toPosition,
|
|
27303
|
+
fromTarget,
|
|
27304
|
+
toTarget,
|
|
27305
|
+
toQuaternion,
|
|
27306
|
+
rollFrom,
|
|
27307
|
+
rollTo,
|
|
27308
|
+
startTime,
|
|
27309
|
+
duration
|
|
27310
|
+
} = animationRef.current;
|
|
27311
|
+
const elapsed = performance.now() - startTime;
|
|
27312
|
+
const progress = duration <= 0 ? 1 : Math.min(elapsed / duration, 1);
|
|
27313
|
+
const eased = easeInOutCubic(progress);
|
|
27314
|
+
camera.position.lerpVectors(fromPosition, toPosition, eased);
|
|
27315
|
+
const nextTarget = tempTarget.current;
|
|
27316
|
+
nextTarget.copy(fromTarget).lerp(toTarget, eased);
|
|
27317
|
+
const baseHelper = baseOrientationHelper.current;
|
|
27318
|
+
baseHelper.up.set(0, 0, 1);
|
|
27319
|
+
baseHelper.position.copy(camera.position);
|
|
27320
|
+
baseHelper.lookAt(nextTarget);
|
|
27321
|
+
const baseQuaternion = tempQuaternion.current;
|
|
27322
|
+
baseQuaternion.copy(baseHelper.quaternion);
|
|
27323
|
+
const interpolatedRoll = tempRoll.current;
|
|
27324
|
+
interpolatedRoll.copy(rollFrom);
|
|
27325
|
+
const rollTarget = tempRollTarget.current;
|
|
27326
|
+
rollTarget.copy(rollTo);
|
|
27327
|
+
if (rollFrom.dot(rollTo) < 0) {
|
|
27328
|
+
rollTarget.x *= -1;
|
|
27329
|
+
rollTarget.y *= -1;
|
|
27330
|
+
rollTarget.z *= -1;
|
|
27331
|
+
rollTarget.w *= -1;
|
|
27332
|
+
}
|
|
27333
|
+
rollTarget.normalize();
|
|
27334
|
+
interpolatedRoll.slerp(rollTarget, eased);
|
|
27335
|
+
camera.quaternion.copy(baseQuaternion).multiply(interpolatedRoll).normalize();
|
|
27336
|
+
const upVector = tempUp.current;
|
|
27337
|
+
upVector.set(0, 1, 0).applyQuaternion(camera.quaternion).normalize();
|
|
27338
|
+
camera.up.copy(upVector);
|
|
27339
|
+
controlsRef.current?.target.copy(nextTarget);
|
|
27340
|
+
camera.updateMatrixWorld();
|
|
27341
|
+
controlsRef.current?.update();
|
|
27342
|
+
if (progress >= 1) {
|
|
27343
|
+
camera.position.copy(toPosition);
|
|
27344
|
+
camera.quaternion.copy(toQuaternion);
|
|
27345
|
+
camera.up.set(0, 0, 1);
|
|
27346
|
+
camera.updateMatrixWorld();
|
|
27347
|
+
controlsRef.current?.target.copy(toTarget);
|
|
27348
|
+
controlsRef.current?.update();
|
|
27349
|
+
animationRef.current = null;
|
|
27350
|
+
}
|
|
27351
|
+
});
|
|
27352
|
+
return null;
|
|
27353
|
+
};
|
|
27354
|
+
var useCameraController = ({
|
|
27355
|
+
defaultTarget,
|
|
27356
|
+
initialCameraPosition,
|
|
27357
|
+
onCameraControllerReady
|
|
27358
|
+
}) => {
|
|
27359
|
+
const controlsRef = useRef5(null);
|
|
27360
|
+
const baseDistance = useMemo14(() => {
|
|
27361
|
+
const [x, y, z126] = initialCameraPosition ?? [5, 5, 5];
|
|
27362
|
+
const distance2 = Math.hypot(
|
|
27363
|
+
x - defaultTarget.x,
|
|
27364
|
+
y - defaultTarget.y,
|
|
27365
|
+
z126 - defaultTarget.z
|
|
27366
|
+
);
|
|
27367
|
+
return distance2 > 0 ? distance2 : 5;
|
|
27368
|
+
}, [initialCameraPosition, defaultTarget]);
|
|
27369
|
+
const getPresetConfig = useCallback5(
|
|
27370
|
+
(preset) => {
|
|
27371
|
+
const targetVector = [
|
|
27372
|
+
defaultTarget.x,
|
|
27373
|
+
defaultTarget.y,
|
|
27374
|
+
defaultTarget.z
|
|
27375
|
+
];
|
|
27376
|
+
const distance2 = baseDistance;
|
|
27377
|
+
const heightOffset = distance2 * 0.3;
|
|
27378
|
+
switch (preset) {
|
|
27379
|
+
case "Top Centered": {
|
|
27380
|
+
const angledOffset = distance2 / Math.sqrt(2);
|
|
27381
|
+
return {
|
|
27382
|
+
position: [
|
|
27383
|
+
defaultTarget.x,
|
|
27384
|
+
defaultTarget.y - angledOffset,
|
|
27385
|
+
defaultTarget.z + angledOffset
|
|
27386
|
+
],
|
|
27387
|
+
target: targetVector,
|
|
27388
|
+
up: [0, 0, 1]
|
|
27389
|
+
};
|
|
27390
|
+
}
|
|
27391
|
+
case "Top Down":
|
|
27392
|
+
return {
|
|
27393
|
+
position: [
|
|
27394
|
+
defaultTarget.x,
|
|
27395
|
+
defaultTarget.y,
|
|
27396
|
+
defaultTarget.z + distance2
|
|
27397
|
+
],
|
|
27398
|
+
target: targetVector,
|
|
27399
|
+
up: [0, 0, 1]
|
|
27400
|
+
};
|
|
27401
|
+
case "Top Left Corner":
|
|
27402
|
+
return {
|
|
27403
|
+
position: [
|
|
27404
|
+
defaultTarget.x - distance2 * 0.6,
|
|
27405
|
+
defaultTarget.y - distance2 * 0.6,
|
|
27406
|
+
defaultTarget.z + distance2 * 0.6
|
|
27407
|
+
],
|
|
27408
|
+
target: targetVector,
|
|
27409
|
+
up: [0, 0, 1]
|
|
27410
|
+
};
|
|
27411
|
+
case "Top Right Corner":
|
|
27412
|
+
return {
|
|
27413
|
+
position: [
|
|
27414
|
+
defaultTarget.x + distance2 * 0.6,
|
|
27415
|
+
defaultTarget.y - distance2 * 0.6,
|
|
27416
|
+
defaultTarget.z + distance2 * 0.6
|
|
27417
|
+
],
|
|
27418
|
+
target: targetVector,
|
|
27419
|
+
up: [0, 0, 1]
|
|
27420
|
+
};
|
|
27421
|
+
case "Left Sideview":
|
|
27422
|
+
return {
|
|
27423
|
+
position: [
|
|
27424
|
+
defaultTarget.x - distance2,
|
|
27425
|
+
defaultTarget.y,
|
|
27426
|
+
defaultTarget.z + heightOffset
|
|
27427
|
+
],
|
|
27428
|
+
target: targetVector,
|
|
27429
|
+
up: [0, 0, 1]
|
|
27430
|
+
};
|
|
27431
|
+
case "Right Sideview":
|
|
27432
|
+
return {
|
|
27433
|
+
position: [
|
|
27434
|
+
defaultTarget.x + distance2,
|
|
27435
|
+
defaultTarget.y,
|
|
27436
|
+
defaultTarget.z + heightOffset
|
|
27437
|
+
],
|
|
27438
|
+
target: targetVector,
|
|
27439
|
+
up: [0, 0, 1]
|
|
27440
|
+
};
|
|
27441
|
+
case "Front":
|
|
27442
|
+
return {
|
|
27443
|
+
position: [
|
|
27444
|
+
defaultTarget.x,
|
|
27445
|
+
defaultTarget.y - distance2,
|
|
27446
|
+
defaultTarget.z + heightOffset
|
|
27447
|
+
],
|
|
27448
|
+
target: targetVector,
|
|
27449
|
+
up: [0, 0, 1]
|
|
27450
|
+
};
|
|
27451
|
+
case "Custom":
|
|
27452
|
+
default:
|
|
27453
|
+
return null;
|
|
27454
|
+
}
|
|
27455
|
+
},
|
|
27456
|
+
[baseDistance, defaultTarget]
|
|
27457
|
+
);
|
|
27458
|
+
const handleControllerReady = useCallback5(
|
|
27459
|
+
(controller) => {
|
|
27460
|
+
if (!onCameraControllerReady) return;
|
|
27461
|
+
if (!controller) {
|
|
27462
|
+
onCameraControllerReady(null);
|
|
27463
|
+
return;
|
|
27464
|
+
}
|
|
27465
|
+
const enhancedController = {
|
|
27466
|
+
animateTo: controller.animateTo,
|
|
27467
|
+
animateToPreset: (preset) => {
|
|
27468
|
+
if (preset === "Custom") return;
|
|
27469
|
+
const config = getPresetConfig(preset);
|
|
27470
|
+
if (!config) return;
|
|
27471
|
+
controller.animateTo(config);
|
|
27472
|
+
}
|
|
27473
|
+
};
|
|
27474
|
+
onCameraControllerReady(enhancedController);
|
|
27475
|
+
},
|
|
27476
|
+
[getPresetConfig, onCameraControllerReady]
|
|
27477
|
+
);
|
|
27478
|
+
const handleControlsChange = useCallback5(
|
|
27479
|
+
(controls) => {
|
|
27480
|
+
controlsRef.current = controls;
|
|
27481
|
+
},
|
|
27482
|
+
[]
|
|
27483
|
+
);
|
|
27484
|
+
const cameraAnimatorProps = useMemo14(
|
|
27485
|
+
() => ({
|
|
27486
|
+
defaultTarget,
|
|
27487
|
+
controlsRef,
|
|
27488
|
+
onReady: handleControllerReady
|
|
27489
|
+
}),
|
|
27490
|
+
[defaultTarget, handleControllerReady]
|
|
27491
|
+
);
|
|
27492
|
+
return { cameraAnimatorProps, handleControlsChange };
|
|
27493
|
+
};
|
|
27494
|
+
|
|
27225
27495
|
// src/CadViewerContainer.tsx
|
|
27226
27496
|
import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
27227
27497
|
var RotationTracker = () => {
|
|
@@ -27241,12 +27511,13 @@ var CadViewerContainer = forwardRef2(
|
|
|
27241
27511
|
clickToInteractEnabled = false,
|
|
27242
27512
|
boardDimensions,
|
|
27243
27513
|
boardCenter,
|
|
27244
|
-
onUserInteraction
|
|
27514
|
+
onUserInteraction,
|
|
27515
|
+
onCameraControllerReady
|
|
27245
27516
|
}, ref) => {
|
|
27246
27517
|
const [isInteractionEnabled, setIsInteractionEnabled] = useState8(
|
|
27247
27518
|
!clickToInteractEnabled
|
|
27248
27519
|
);
|
|
27249
|
-
const gridSectionSize =
|
|
27520
|
+
const gridSectionSize = useMemo15(() => {
|
|
27250
27521
|
if (!boardDimensions) return 10;
|
|
27251
27522
|
const width10 = boardDimensions.width ?? 0;
|
|
27252
27523
|
const height10 = boardDimensions.height ?? 0;
|
|
@@ -27254,10 +27525,21 @@ var CadViewerContainer = forwardRef2(
|
|
|
27254
27525
|
const desired = largest * 1.5;
|
|
27255
27526
|
return desired > 10 ? desired : 10;
|
|
27256
27527
|
}, [boardDimensions]);
|
|
27257
|
-
const orbitTarget =
|
|
27528
|
+
const orbitTarget = useMemo15(() => {
|
|
27258
27529
|
if (!boardCenter) return void 0;
|
|
27259
27530
|
return [boardCenter.x, boardCenter.y, 0];
|
|
27260
27531
|
}, [boardCenter]);
|
|
27532
|
+
const defaultTarget = useMemo15(() => {
|
|
27533
|
+
if (orbitTarget) {
|
|
27534
|
+
return new THREE14.Vector3(orbitTarget[0], orbitTarget[1], orbitTarget[2]);
|
|
27535
|
+
}
|
|
27536
|
+
return new THREE14.Vector3(0, 0, 0);
|
|
27537
|
+
}, [orbitTarget]);
|
|
27538
|
+
const { cameraAnimatorProps, handleControlsChange } = useCameraController({
|
|
27539
|
+
defaultTarget,
|
|
27540
|
+
initialCameraPosition,
|
|
27541
|
+
onCameraControllerReady
|
|
27542
|
+
});
|
|
27261
27543
|
return /* @__PURE__ */ jsxs4("div", { style: { position: "relative", width: "100%", height: "100%" }, children: [
|
|
27262
27544
|
/* @__PURE__ */ jsx12(
|
|
27263
27545
|
"div",
|
|
@@ -27286,9 +27568,10 @@ var CadViewerContainer = forwardRef2(
|
|
|
27286
27568
|
Canvas,
|
|
27287
27569
|
{
|
|
27288
27570
|
ref,
|
|
27289
|
-
scene: { up: new
|
|
27571
|
+
scene: { up: new THREE14.Vector3(0, 0, 1) },
|
|
27290
27572
|
camera: { up: [0, 0, 1], position: initialCameraPosition },
|
|
27291
27573
|
children: [
|
|
27574
|
+
/* @__PURE__ */ jsx12(CameraAnimator, { ...cameraAnimatorProps }),
|
|
27292
27575
|
/* @__PURE__ */ jsx12(RotationTracker, {}),
|
|
27293
27576
|
isInteractionEnabled && /* @__PURE__ */ jsx12(
|
|
27294
27577
|
OrbitControls,
|
|
@@ -27301,7 +27584,8 @@ var CadViewerContainer = forwardRef2(
|
|
|
27301
27584
|
zoomSpeed: 0.5,
|
|
27302
27585
|
enableDamping: true,
|
|
27303
27586
|
dampingFactor: 0.1,
|
|
27304
|
-
target: orbitTarget
|
|
27587
|
+
target: orbitTarget,
|
|
27588
|
+
onControlsChange: handleControlsChange
|
|
27305
27589
|
}
|
|
27306
27590
|
),
|
|
27307
27591
|
/* @__PURE__ */ jsx12(Lights, {}),
|
|
@@ -27379,9 +27663,9 @@ var CadViewerContainer = forwardRef2(
|
|
|
27379
27663
|
|
|
27380
27664
|
// src/hooks/use-convert-children-to-soup.ts
|
|
27381
27665
|
import { Circuit } from "@tscircuit/core";
|
|
27382
|
-
import { useMemo as
|
|
27666
|
+
import { useMemo as useMemo16 } from "react";
|
|
27383
27667
|
var useConvertChildrenToCircuitJson = (children) => {
|
|
27384
|
-
return
|
|
27668
|
+
return useMemo16(() => {
|
|
27385
27669
|
if (!children) return [];
|
|
27386
27670
|
const circuit = new Circuit();
|
|
27387
27671
|
circuit.add(children);
|
|
@@ -29089,8 +29373,8 @@ var useBoardGeomBuilder = (circuitJson) => {
|
|
|
29089
29373
|
};
|
|
29090
29374
|
|
|
29091
29375
|
// src/three-components/Error3d.tsx
|
|
29092
|
-
import { useState as useState11, useCallback as
|
|
29093
|
-
import * as
|
|
29376
|
+
import { useState as useState11, useCallback as useCallback6, useEffect as useEffect19, useMemo as useMemo17 } from "react";
|
|
29377
|
+
import * as THREE15 from "three";
|
|
29094
29378
|
import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
29095
29379
|
var Error3d = ({
|
|
29096
29380
|
error,
|
|
@@ -29099,7 +29383,7 @@ var Error3d = ({
|
|
|
29099
29383
|
const { rootObject } = useThree();
|
|
29100
29384
|
const [isHovered, setIsHovered] = useState11(false);
|
|
29101
29385
|
const [hoverPosition, setHoverPosition] = useState11(null);
|
|
29102
|
-
const handleHover =
|
|
29386
|
+
const handleHover = useCallback6((e) => {
|
|
29103
29387
|
if (e?.mousePosition) {
|
|
29104
29388
|
setIsHovered(true);
|
|
29105
29389
|
setHoverPosition(e.mousePosition);
|
|
@@ -29108,11 +29392,11 @@ var Error3d = ({
|
|
|
29108
29392
|
setHoverPosition(null);
|
|
29109
29393
|
}
|
|
29110
29394
|
}, []);
|
|
29111
|
-
const handleUnhover =
|
|
29395
|
+
const handleUnhover = useCallback6(() => {
|
|
29112
29396
|
setIsHovered(false);
|
|
29113
29397
|
setHoverPosition(null);
|
|
29114
29398
|
}, []);
|
|
29115
|
-
const position =
|
|
29399
|
+
const position = useMemo17(() => {
|
|
29116
29400
|
if (cad_component2?.position) {
|
|
29117
29401
|
const p = [
|
|
29118
29402
|
cad_component2.position.x,
|
|
@@ -29123,8 +29407,8 @@ var Error3d = ({
|
|
|
29123
29407
|
}
|
|
29124
29408
|
return [0, 0, 0];
|
|
29125
29409
|
}, [cad_component2]);
|
|
29126
|
-
const group =
|
|
29127
|
-
const g = new
|
|
29410
|
+
const group = useMemo17(() => {
|
|
29411
|
+
const g = new THREE15.Group();
|
|
29128
29412
|
g.position.fromArray(position);
|
|
29129
29413
|
return g;
|
|
29130
29414
|
}, [position]);
|
|
@@ -29183,10 +29467,10 @@ var Error3d = ({
|
|
|
29183
29467
|
] });
|
|
29184
29468
|
};
|
|
29185
29469
|
var ErrorBox = ({ parent }) => {
|
|
29186
|
-
const mesh =
|
|
29187
|
-
const m = new
|
|
29188
|
-
new
|
|
29189
|
-
new
|
|
29470
|
+
const mesh = useMemo17(() => {
|
|
29471
|
+
const m = new THREE15.Mesh(
|
|
29472
|
+
new THREE15.BoxGeometry(0.5, 0.5, 0.5),
|
|
29473
|
+
new THREE15.MeshStandardMaterial({
|
|
29190
29474
|
depthTest: false,
|
|
29191
29475
|
transparent: true,
|
|
29192
29476
|
color: "red",
|
|
@@ -29207,8 +29491,8 @@ var ErrorBox = ({ parent }) => {
|
|
|
29207
29491
|
};
|
|
29208
29492
|
|
|
29209
29493
|
// src/three-components/STLModel.tsx
|
|
29210
|
-
import { useState as useState12, useEffect as useEffect20, useMemo as
|
|
29211
|
-
import * as
|
|
29494
|
+
import { useState as useState12, useEffect as useEffect20, useMemo as useMemo18 } from "react";
|
|
29495
|
+
import * as THREE16 from "three";
|
|
29212
29496
|
import { STLLoader } from "three-stdlib";
|
|
29213
29497
|
function STLModel({
|
|
29214
29498
|
stlUrl,
|
|
@@ -29237,14 +29521,14 @@ function STLModel({
|
|
|
29237
29521
|
});
|
|
29238
29522
|
}
|
|
29239
29523
|
}, [stlUrl, stlData]);
|
|
29240
|
-
const mesh =
|
|
29524
|
+
const mesh = useMemo18(() => {
|
|
29241
29525
|
if (!geom) return null;
|
|
29242
|
-
const material = new
|
|
29243
|
-
color: Array.isArray(color) ? new
|
|
29526
|
+
const material = new THREE16.MeshStandardMaterial({
|
|
29527
|
+
color: Array.isArray(color) ? new THREE16.Color(color[0], color[1], color[2]) : color,
|
|
29244
29528
|
transparent: opacity !== 1,
|
|
29245
29529
|
opacity
|
|
29246
29530
|
});
|
|
29247
|
-
return new
|
|
29531
|
+
return new THREE16.Mesh(geom, material);
|
|
29248
29532
|
}, [geom, color, opacity]);
|
|
29249
29533
|
useEffect20(() => {
|
|
29250
29534
|
if (!rootObject || !mesh) return;
|
|
@@ -29316,15 +29600,16 @@ var CadViewerJscad = forwardRef3(
|
|
|
29316
29600
|
children,
|
|
29317
29601
|
autoRotateDisabled,
|
|
29318
29602
|
clickToInteractEnabled,
|
|
29319
|
-
onUserInteraction
|
|
29603
|
+
onUserInteraction,
|
|
29604
|
+
onCameraControllerReady
|
|
29320
29605
|
}, ref) => {
|
|
29321
29606
|
const childrenSoup = useConvertChildrenToCircuitJson(children);
|
|
29322
|
-
const internalCircuitJson =
|
|
29607
|
+
const internalCircuitJson = useMemo19(() => {
|
|
29323
29608
|
const cj = soup ?? circuitJson;
|
|
29324
29609
|
return cj ?? childrenSoup;
|
|
29325
29610
|
}, [soup, circuitJson, childrenSoup]);
|
|
29326
29611
|
const boardGeom = useBoardGeomBuilder(internalCircuitJson);
|
|
29327
|
-
const initialCameraPosition =
|
|
29612
|
+
const initialCameraPosition = useMemo19(() => {
|
|
29328
29613
|
if (!internalCircuitJson) return [5, 5, 5];
|
|
29329
29614
|
try {
|
|
29330
29615
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29343,7 +29628,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
29343
29628
|
return [5, 5, 5];
|
|
29344
29629
|
}
|
|
29345
29630
|
}, [internalCircuitJson]);
|
|
29346
|
-
const boardDimensions =
|
|
29631
|
+
const boardDimensions = useMemo19(() => {
|
|
29347
29632
|
if (!internalCircuitJson) return void 0;
|
|
29348
29633
|
try {
|
|
29349
29634
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29354,7 +29639,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
29354
29639
|
return void 0;
|
|
29355
29640
|
}
|
|
29356
29641
|
}, [internalCircuitJson]);
|
|
29357
|
-
const boardCenter =
|
|
29642
|
+
const boardCenter = useMemo19(() => {
|
|
29358
29643
|
if (!internalCircuitJson) return void 0;
|
|
29359
29644
|
try {
|
|
29360
29645
|
const board = su4(internalCircuitJson).pcb_board.list()[0];
|
|
@@ -29377,6 +29662,7 @@ var CadViewerJscad = forwardRef3(
|
|
|
29377
29662
|
boardDimensions,
|
|
29378
29663
|
boardCenter,
|
|
29379
29664
|
onUserInteraction,
|
|
29665
|
+
onCameraControllerReady,
|
|
29380
29666
|
children: [
|
|
29381
29667
|
boardStls.map(({ stlData, color, layerType }, index) => /* @__PURE__ */ jsx15(
|
|
29382
29668
|
VisibleSTLModel,
|
|
@@ -29411,22 +29697,22 @@ var CadViewerJscad = forwardRef3(
|
|
|
29411
29697
|
|
|
29412
29698
|
// src/CadViewerManifold.tsx
|
|
29413
29699
|
import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
29414
|
-
import { useEffect as useEffect22, useMemo as
|
|
29700
|
+
import { useEffect as useEffect22, useMemo as useMemo21, useState as useState15 } from "react";
|
|
29415
29701
|
|
|
29416
29702
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
29417
|
-
import { useState as useState14, useEffect as useEffect21, useMemo as
|
|
29703
|
+
import { useState as useState14, useEffect as useEffect21, useMemo as useMemo20, useRef as useRef7 } from "react";
|
|
29418
29704
|
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
29419
|
-
import * as
|
|
29705
|
+
import * as THREE24 from "three";
|
|
29420
29706
|
|
|
29421
29707
|
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
29422
|
-
import * as
|
|
29708
|
+
import * as THREE17 from "three";
|
|
29423
29709
|
function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
29424
|
-
const geometry = new
|
|
29710
|
+
const geometry = new THREE17.BufferGeometry();
|
|
29425
29711
|
geometry.setAttribute(
|
|
29426
29712
|
"position",
|
|
29427
|
-
new
|
|
29713
|
+
new THREE17.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
|
|
29428
29714
|
);
|
|
29429
|
-
geometry.setIndex(new
|
|
29715
|
+
geometry.setIndex(new THREE17.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
|
|
29430
29716
|
if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
|
|
29431
29717
|
for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
|
|
29432
29718
|
const start = manifoldMesh.runIndex[i];
|
|
@@ -29440,7 +29726,7 @@ function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
|
29440
29726
|
}
|
|
29441
29727
|
|
|
29442
29728
|
// src/utils/trace-texture.ts
|
|
29443
|
-
import * as
|
|
29729
|
+
import * as THREE18 from "three";
|
|
29444
29730
|
import { su as su5 } from "@tscircuit/circuit-json-util";
|
|
29445
29731
|
function isWireRoutePoint(point2) {
|
|
29446
29732
|
return point2 && point2.route_type === "wire" && typeof point2.layer === "string" && typeof point2.width === "number";
|
|
@@ -29523,10 +29809,10 @@ function createTraceTextureForLayer({
|
|
|
29523
29809
|
}
|
|
29524
29810
|
});
|
|
29525
29811
|
ctx.globalCompositeOperation = "source-over";
|
|
29526
|
-
const texture = new
|
|
29812
|
+
const texture = new THREE18.CanvasTexture(canvas);
|
|
29527
29813
|
texture.generateMipmaps = true;
|
|
29528
|
-
texture.minFilter =
|
|
29529
|
-
texture.magFilter =
|
|
29814
|
+
texture.minFilter = THREE18.LinearMipmapLinearFilter;
|
|
29815
|
+
texture.magFilter = THREE18.LinearFilter;
|
|
29530
29816
|
texture.anisotropy = 16;
|
|
29531
29817
|
texture.needsUpdate = true;
|
|
29532
29818
|
return texture;
|
|
@@ -29534,7 +29820,7 @@ function createTraceTextureForLayer({
|
|
|
29534
29820
|
|
|
29535
29821
|
// src/utils/silkscreen-texture.ts
|
|
29536
29822
|
var import_text2 = __toESM(require_text(), 1);
|
|
29537
|
-
import * as
|
|
29823
|
+
import * as THREE19 from "three";
|
|
29538
29824
|
import { su as su6 } from "@tscircuit/circuit-json-util";
|
|
29539
29825
|
function createSilkscreenTextureForLayer({
|
|
29540
29826
|
layer,
|
|
@@ -29663,10 +29949,10 @@ function createSilkscreenTextureForLayer({
|
|
|
29663
29949
|
ctx.stroke();
|
|
29664
29950
|
});
|
|
29665
29951
|
});
|
|
29666
|
-
const texture = new
|
|
29952
|
+
const texture = new THREE19.CanvasTexture(canvas);
|
|
29667
29953
|
texture.generateMipmaps = true;
|
|
29668
|
-
texture.minFilter =
|
|
29669
|
-
texture.magFilter =
|
|
29954
|
+
texture.minFilter = THREE19.LinearMipmapLinearFilter;
|
|
29955
|
+
texture.magFilter = THREE19.LinearFilter;
|
|
29670
29956
|
texture.anisotropy = 16;
|
|
29671
29957
|
texture.needsUpdate = true;
|
|
29672
29958
|
return texture;
|
|
@@ -29850,8 +30136,8 @@ function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, m
|
|
|
29850
30136
|
|
|
29851
30137
|
// src/utils/manifold/process-plated-holes.ts
|
|
29852
30138
|
import { su as su8 } from "@tscircuit/circuit-json-util";
|
|
29853
|
-
import * as
|
|
29854
|
-
var COPPER_COLOR = new
|
|
30139
|
+
import * as THREE20 from "three";
|
|
30140
|
+
var COPPER_COLOR = new THREE20.Color(...colors.copper);
|
|
29855
30141
|
var PLATED_HOLE_LIP_HEIGHT = 0.05;
|
|
29856
30142
|
function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
29857
30143
|
const platedHoleBoardDrills = [];
|
|
@@ -30169,7 +30455,7 @@ function processPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, mani
|
|
|
30169
30455
|
|
|
30170
30456
|
// src/utils/manifold/process-vias.ts
|
|
30171
30457
|
import { su as su9 } from "@tscircuit/circuit-json-util";
|
|
30172
|
-
import * as
|
|
30458
|
+
import * as THREE21 from "three";
|
|
30173
30459
|
|
|
30174
30460
|
// src/utils/via-geoms.ts
|
|
30175
30461
|
function createViaCopper({
|
|
@@ -30202,7 +30488,7 @@ function createViaCopper({
|
|
|
30202
30488
|
}
|
|
30203
30489
|
|
|
30204
30490
|
// src/utils/manifold/process-vias.ts
|
|
30205
|
-
var COPPER_COLOR2 = new
|
|
30491
|
+
var COPPER_COLOR2 = new THREE21.Color(...colors.copper);
|
|
30206
30492
|
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
30207
30493
|
const viaBoardDrills = [];
|
|
30208
30494
|
const pcbVias = su9(circuitJson).pcb_via.list();
|
|
@@ -30255,8 +30541,8 @@ function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldIns
|
|
|
30255
30541
|
|
|
30256
30542
|
// src/utils/manifold/process-smt-pads.ts
|
|
30257
30543
|
import { su as su10 } from "@tscircuit/circuit-json-util";
|
|
30258
|
-
import * as
|
|
30259
|
-
var COPPER_COLOR3 = new
|
|
30544
|
+
import * as THREE22 from "three";
|
|
30545
|
+
var COPPER_COLOR3 = new THREE22.Color(...colors.copper);
|
|
30260
30546
|
function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, holeUnion, boardClipVolume) {
|
|
30261
30547
|
const smtPadGeoms = [];
|
|
30262
30548
|
const smtPads = su10(circuitJson).pcb_smtpad.list();
|
|
@@ -30352,8 +30638,8 @@ function createManifoldBoard(Manifold, CrossSection, boardData, pcbThickness, ma
|
|
|
30352
30638
|
}
|
|
30353
30639
|
|
|
30354
30640
|
// src/utils/manifold/process-copper-pours.ts
|
|
30355
|
-
import * as
|
|
30356
|
-
var COPPER_COLOR4 = new
|
|
30641
|
+
import * as THREE23 from "three";
|
|
30642
|
+
var COPPER_COLOR4 = new THREE23.Color(...colors.copper);
|
|
30357
30643
|
var arePointsClockwise4 = (points) => {
|
|
30358
30644
|
let area = 0;
|
|
30359
30645
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -30629,7 +30915,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30629
30915
|
const [error, setError] = useState14(null);
|
|
30630
30916
|
const [isLoading, setIsLoading] = useState14(true);
|
|
30631
30917
|
const manifoldInstancesForCleanup = useRef7([]);
|
|
30632
|
-
const boardData =
|
|
30918
|
+
const boardData = useMemo20(() => {
|
|
30633
30919
|
const boards = su12(circuitJson).pcb_board.list();
|
|
30634
30920
|
if (boards.length === 0) {
|
|
30635
30921
|
return null;
|
|
@@ -30757,7 +31043,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30757
31043
|
{
|
|
30758
31044
|
key: "plated-holes-union",
|
|
30759
31045
|
geometry: cutPlatedGeom,
|
|
30760
|
-
color: new
|
|
31046
|
+
color: new THREE24.Color(
|
|
30761
31047
|
colors.copper[0],
|
|
30762
31048
|
colors.copper[1],
|
|
30763
31049
|
colors.copper[2]
|
|
@@ -30787,7 +31073,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30787
31073
|
const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Green;
|
|
30788
31074
|
currentGeoms.board = {
|
|
30789
31075
|
geometry: finalBoardGeom,
|
|
30790
|
-
color: new
|
|
31076
|
+
color: new THREE24.Color(
|
|
30791
31077
|
matColorArray[0],
|
|
30792
31078
|
matColorArray[1],
|
|
30793
31079
|
matColorArray[2]
|
|
@@ -30873,18 +31159,18 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
30873
31159
|
};
|
|
30874
31160
|
|
|
30875
31161
|
// src/utils/manifold/create-three-geometry-meshes.ts
|
|
30876
|
-
import * as
|
|
31162
|
+
import * as THREE26 from "three";
|
|
30877
31163
|
|
|
30878
31164
|
// src/utils/create-board-material.ts
|
|
30879
|
-
import * as
|
|
30880
|
-
var DEFAULT_SIDE =
|
|
31165
|
+
import * as THREE25 from "three";
|
|
31166
|
+
var DEFAULT_SIDE = THREE25.DoubleSide;
|
|
30881
31167
|
var createBoardMaterial = ({
|
|
30882
31168
|
material,
|
|
30883
31169
|
color,
|
|
30884
31170
|
side = DEFAULT_SIDE
|
|
30885
31171
|
}) => {
|
|
30886
31172
|
if (material === "fr4") {
|
|
30887
|
-
return new
|
|
31173
|
+
return new THREE25.MeshPhysicalMaterial({
|
|
30888
31174
|
color,
|
|
30889
31175
|
side,
|
|
30890
31176
|
metalness: 0,
|
|
@@ -30898,7 +31184,7 @@ var createBoardMaterial = ({
|
|
|
30898
31184
|
flatShading: true
|
|
30899
31185
|
});
|
|
30900
31186
|
}
|
|
30901
|
-
return new
|
|
31187
|
+
return new THREE25.MeshStandardMaterial({
|
|
30902
31188
|
color,
|
|
30903
31189
|
side,
|
|
30904
31190
|
flatShading: true,
|
|
@@ -30914,12 +31200,12 @@ function createGeometryMeshes(geoms) {
|
|
|
30914
31200
|
const meshes = [];
|
|
30915
31201
|
if (!geoms) return meshes;
|
|
30916
31202
|
if (geoms.board && geoms.board.geometry) {
|
|
30917
|
-
const mesh = new
|
|
31203
|
+
const mesh = new THREE26.Mesh(
|
|
30918
31204
|
geoms.board.geometry,
|
|
30919
31205
|
createBoardMaterial({
|
|
30920
31206
|
material: geoms.board.material,
|
|
30921
31207
|
color: geoms.board.color,
|
|
30922
|
-
side:
|
|
31208
|
+
side: THREE26.DoubleSide
|
|
30923
31209
|
})
|
|
30924
31210
|
);
|
|
30925
31211
|
mesh.name = "board-geom";
|
|
@@ -30928,11 +31214,11 @@ function createGeometryMeshes(geoms) {
|
|
|
30928
31214
|
const createMeshesFromArray = (geomArray) => {
|
|
30929
31215
|
if (geomArray) {
|
|
30930
31216
|
geomArray.forEach((comp) => {
|
|
30931
|
-
const mesh = new
|
|
31217
|
+
const mesh = new THREE26.Mesh(
|
|
30932
31218
|
comp.geometry,
|
|
30933
|
-
new
|
|
31219
|
+
new THREE26.MeshStandardMaterial({
|
|
30934
31220
|
color: comp.color,
|
|
30935
|
-
side:
|
|
31221
|
+
side: THREE26.DoubleSide,
|
|
30936
31222
|
flatShading: true
|
|
30937
31223
|
// Consistent with board
|
|
30938
31224
|
})
|
|
@@ -30950,21 +31236,21 @@ function createGeometryMeshes(geoms) {
|
|
|
30950
31236
|
}
|
|
30951
31237
|
|
|
30952
31238
|
// src/utils/manifold/create-three-texture-meshes.ts
|
|
30953
|
-
import * as
|
|
31239
|
+
import * as THREE27 from "three";
|
|
30954
31240
|
function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
30955
31241
|
const meshes = [];
|
|
30956
31242
|
if (!textures || !boardData || pcbThickness === null) return meshes;
|
|
30957
31243
|
const createTexturePlane = (texture, yOffset, isBottomLayer, keySuffix) => {
|
|
30958
31244
|
if (!texture) return null;
|
|
30959
|
-
const planeGeom = new
|
|
30960
|
-
const material = new
|
|
31245
|
+
const planeGeom = new THREE27.PlaneGeometry(boardData.width, boardData.height);
|
|
31246
|
+
const material = new THREE27.MeshBasicMaterial({
|
|
30961
31247
|
map: texture,
|
|
30962
31248
|
transparent: true,
|
|
30963
|
-
side:
|
|
31249
|
+
side: THREE27.DoubleSide,
|
|
30964
31250
|
depthWrite: false
|
|
30965
31251
|
// Important for layers to avoid z-fighting issues with board itself
|
|
30966
31252
|
});
|
|
30967
|
-
const mesh = new
|
|
31253
|
+
const mesh = new THREE27.Mesh(planeGeom, material);
|
|
30968
31254
|
mesh.position.set(boardData.center.x, boardData.center.y, yOffset);
|
|
30969
31255
|
if (isBottomLayer) {
|
|
30970
31256
|
mesh.rotation.set(Math.PI, 0, 0);
|
|
@@ -31072,10 +31358,11 @@ var CadViewerManifold = ({
|
|
|
31072
31358
|
autoRotateDisabled,
|
|
31073
31359
|
clickToInteractEnabled,
|
|
31074
31360
|
onUserInteraction,
|
|
31075
|
-
children
|
|
31361
|
+
children,
|
|
31362
|
+
onCameraControllerReady
|
|
31076
31363
|
}) => {
|
|
31077
31364
|
const childrenCircuitJson = useConvertChildrenToCircuitJson(children);
|
|
31078
|
-
const circuitJson =
|
|
31365
|
+
const circuitJson = useMemo21(() => {
|
|
31079
31366
|
return circuitJsonProp ?? childrenCircuitJson;
|
|
31080
31367
|
}, [circuitJsonProp, childrenCircuitJson]);
|
|
31081
31368
|
const [manifoldJSModule, setManifoldJSModule] = useState15(null);
|
|
@@ -31150,27 +31437,27 @@ try {
|
|
|
31150
31437
|
isLoading: builderIsLoading,
|
|
31151
31438
|
boardData
|
|
31152
31439
|
} = useManifoldBoardBuilder(manifoldJSModule, circuitJson);
|
|
31153
|
-
const geometryMeshes =
|
|
31154
|
-
const textureMeshes =
|
|
31440
|
+
const geometryMeshes = useMemo21(() => createGeometryMeshes(geoms), [geoms]);
|
|
31441
|
+
const textureMeshes = useMemo21(
|
|
31155
31442
|
() => createTextureMeshes(textures, boardData, pcbThickness),
|
|
31156
31443
|
[textures, boardData, pcbThickness]
|
|
31157
31444
|
);
|
|
31158
|
-
const cadComponents =
|
|
31445
|
+
const cadComponents = useMemo21(
|
|
31159
31446
|
() => su13(circuitJson).cad_component.list(),
|
|
31160
31447
|
[circuitJson]
|
|
31161
31448
|
);
|
|
31162
|
-
const boardDimensions =
|
|
31449
|
+
const boardDimensions = useMemo21(() => {
|
|
31163
31450
|
if (!boardData) return void 0;
|
|
31164
31451
|
const { width: width10 = 0, height: height10 = 0 } = boardData;
|
|
31165
31452
|
return { width: width10, height: height10 };
|
|
31166
31453
|
}, [boardData]);
|
|
31167
|
-
const boardCenter =
|
|
31454
|
+
const boardCenter = useMemo21(() => {
|
|
31168
31455
|
if (!boardData) return void 0;
|
|
31169
31456
|
const { center } = boardData;
|
|
31170
31457
|
if (!center) return void 0;
|
|
31171
31458
|
return { x: center.x, y: center.y };
|
|
31172
31459
|
}, [boardData]);
|
|
31173
|
-
const initialCameraPosition =
|
|
31460
|
+
const initialCameraPosition = useMemo21(() => {
|
|
31174
31461
|
if (!boardData) return [5, 5, 5];
|
|
31175
31462
|
const { width: width10 = 0, height: height10 = 0 } = boardData;
|
|
31176
31463
|
const safeWidth = Math.max(width10, 1);
|
|
@@ -31227,6 +31514,7 @@ try {
|
|
|
31227
31514
|
boardDimensions,
|
|
31228
31515
|
boardCenter,
|
|
31229
31516
|
onUserInteraction,
|
|
31517
|
+
onCameraControllerReady,
|
|
31230
31518
|
children: [
|
|
31231
31519
|
/* @__PURE__ */ jsx16(
|
|
31232
31520
|
BoardMeshes,
|
|
@@ -31256,7 +31544,7 @@ try {
|
|
|
31256
31544
|
var CadViewerManifold_default = CadViewerManifold;
|
|
31257
31545
|
|
|
31258
31546
|
// src/hooks/useContextMenu.ts
|
|
31259
|
-
import { useState as useState16, useCallback as
|
|
31547
|
+
import { useState as useState16, useCallback as useCallback8, useRef as useRef8, useEffect as useEffect23 } from "react";
|
|
31260
31548
|
var useContextMenu = ({ containerRef }) => {
|
|
31261
31549
|
const [menuVisible, setMenuVisible] = useState16(false);
|
|
31262
31550
|
const [menuPos, setMenuPos] = useState16({
|
|
@@ -31273,7 +31561,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31273
31561
|
longPressTimeoutRef.current = null;
|
|
31274
31562
|
}
|
|
31275
31563
|
};
|
|
31276
|
-
const handleContextMenu =
|
|
31564
|
+
const handleContextMenu = useCallback8(
|
|
31277
31565
|
(e) => {
|
|
31278
31566
|
e.preventDefault();
|
|
31279
31567
|
const eventX = typeof e.clientX === "number" ? e.clientX : 0;
|
|
@@ -31299,7 +31587,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31299
31587
|
},
|
|
31300
31588
|
[setMenuPos, setMenuVisible]
|
|
31301
31589
|
);
|
|
31302
|
-
const handleTouchStart =
|
|
31590
|
+
const handleTouchStart = useCallback8(
|
|
31303
31591
|
(e) => {
|
|
31304
31592
|
if (e.touches.length === 1) {
|
|
31305
31593
|
const touch = e.touches[0];
|
|
@@ -31332,7 +31620,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31332
31620
|
},
|
|
31333
31621
|
[containerRef]
|
|
31334
31622
|
);
|
|
31335
|
-
const handleTouchMove =
|
|
31623
|
+
const handleTouchMove = useCallback8((e) => {
|
|
31336
31624
|
if (!interactionOriginPosRef.current || e.touches.length !== 1) {
|
|
31337
31625
|
return;
|
|
31338
31626
|
}
|
|
@@ -31350,7 +31638,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31350
31638
|
clearLongPressTimeout();
|
|
31351
31639
|
}
|
|
31352
31640
|
}, []);
|
|
31353
|
-
const handleTouchEnd =
|
|
31641
|
+
const handleTouchEnd = useCallback8(() => {
|
|
31354
31642
|
clearLongPressTimeout();
|
|
31355
31643
|
setTimeout(() => {
|
|
31356
31644
|
if (interactionOriginPosRef.current) {
|
|
@@ -31358,7 +31646,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31358
31646
|
}
|
|
31359
31647
|
}, 0);
|
|
31360
31648
|
}, []);
|
|
31361
|
-
const handleClickAway =
|
|
31649
|
+
const handleClickAway = useCallback8((e) => {
|
|
31362
31650
|
const target = e.target;
|
|
31363
31651
|
if (menuRef.current && !menuRef.current.contains(target)) {
|
|
31364
31652
|
setMenuVisible(false);
|
|
@@ -31398,10 +31686,10 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
31398
31686
|
};
|
|
31399
31687
|
|
|
31400
31688
|
// src/hooks/useGlobalDownloadGltf.ts
|
|
31401
|
-
import { useCallback as
|
|
31689
|
+
import { useCallback as useCallback9 } from "react";
|
|
31402
31690
|
import { GLTFExporter } from "three-stdlib";
|
|
31403
31691
|
var useGlobalDownloadGltf = () => {
|
|
31404
|
-
return
|
|
31692
|
+
return useCallback9(() => {
|
|
31405
31693
|
const root = window.__TSCIRCUIT_THREE_OBJECT;
|
|
31406
31694
|
if (!root) return;
|
|
31407
31695
|
const exporter = new GLTFExporter();
|
|
@@ -31426,6 +31714,9 @@ var useGlobalDownloadGltf = () => {
|
|
|
31426
31714
|
}, []);
|
|
31427
31715
|
};
|
|
31428
31716
|
|
|
31717
|
+
// src/components/ContextMenu.tsx
|
|
31718
|
+
import { useState as useState18, useCallback as useCallback10 } from "react";
|
|
31719
|
+
|
|
31429
31720
|
// src/components/AppearanceMenu.tsx
|
|
31430
31721
|
import { useState as useState17 } from "react";
|
|
31431
31722
|
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -31602,14 +31893,258 @@ var AppearanceMenu = () => {
|
|
|
31602
31893
|
] });
|
|
31603
31894
|
};
|
|
31604
31895
|
|
|
31605
|
-
// src/
|
|
31896
|
+
// src/components/ContextMenu.tsx
|
|
31606
31897
|
import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
31898
|
+
var cameraOptions = [
|
|
31899
|
+
"Custom",
|
|
31900
|
+
"Top Centered",
|
|
31901
|
+
"Top Down",
|
|
31902
|
+
"Top Left Corner",
|
|
31903
|
+
"Top Right Corner",
|
|
31904
|
+
"Left Sideview",
|
|
31905
|
+
"Right Sideview",
|
|
31906
|
+
"Front"
|
|
31907
|
+
];
|
|
31908
|
+
var ContextMenu = ({
|
|
31909
|
+
menuRef,
|
|
31910
|
+
menuPos,
|
|
31911
|
+
engine,
|
|
31912
|
+
cameraPreset,
|
|
31913
|
+
autoRotate,
|
|
31914
|
+
onEngineSwitch,
|
|
31915
|
+
onCameraPresetSelect,
|
|
31916
|
+
onAutoRotateToggle,
|
|
31917
|
+
onDownloadGltf
|
|
31918
|
+
}) => {
|
|
31919
|
+
const [activeSubmenu, setActiveSubmenu] = useState18(null);
|
|
31920
|
+
const handleMenuItemHover = useCallback10(
|
|
31921
|
+
(event, hovered) => {
|
|
31922
|
+
event.currentTarget.style.background = hovered ? "#2d313a" : "transparent";
|
|
31923
|
+
},
|
|
31924
|
+
[]
|
|
31925
|
+
);
|
|
31926
|
+
return /* @__PURE__ */ jsxs9(
|
|
31927
|
+
"div",
|
|
31928
|
+
{
|
|
31929
|
+
ref: menuRef,
|
|
31930
|
+
style: {
|
|
31931
|
+
position: "fixed",
|
|
31932
|
+
top: menuPos.y,
|
|
31933
|
+
left: menuPos.x,
|
|
31934
|
+
background: "#23272f",
|
|
31935
|
+
color: "#f5f6fa",
|
|
31936
|
+
borderRadius: 6,
|
|
31937
|
+
boxShadow: "0 6px 24px 0 rgba(0,0,0,0.18)",
|
|
31938
|
+
zIndex: 1e3,
|
|
31939
|
+
minWidth: 200,
|
|
31940
|
+
border: "1px solid #353945",
|
|
31941
|
+
padding: 0,
|
|
31942
|
+
fontSize: 15,
|
|
31943
|
+
fontWeight: 500,
|
|
31944
|
+
transition: "opacity 0.1s"
|
|
31945
|
+
},
|
|
31946
|
+
children: [
|
|
31947
|
+
/* @__PURE__ */ jsxs9(
|
|
31948
|
+
"div",
|
|
31949
|
+
{
|
|
31950
|
+
style: {
|
|
31951
|
+
padding: "12px 18px",
|
|
31952
|
+
cursor: "pointer",
|
|
31953
|
+
display: "flex",
|
|
31954
|
+
alignItems: "center",
|
|
31955
|
+
gap: 10,
|
|
31956
|
+
color: "#f5f6fa",
|
|
31957
|
+
fontWeight: 500,
|
|
31958
|
+
borderRadius: 6,
|
|
31959
|
+
transition: "background 0.1s"
|
|
31960
|
+
},
|
|
31961
|
+
onClick: () => onEngineSwitch(engine === "jscad" ? "manifold" : "jscad"),
|
|
31962
|
+
onMouseOver: (event) => handleMenuItemHover(event, true),
|
|
31963
|
+
onMouseOut: (event) => handleMenuItemHover(event, false),
|
|
31964
|
+
children: [
|
|
31965
|
+
"Switch to ",
|
|
31966
|
+
engine === "jscad" ? "Manifold" : "JSCAD",
|
|
31967
|
+
" Engine",
|
|
31968
|
+
/* @__PURE__ */ jsx18(
|
|
31969
|
+
"span",
|
|
31970
|
+
{
|
|
31971
|
+
style: {
|
|
31972
|
+
fontSize: 12,
|
|
31973
|
+
marginLeft: "auto",
|
|
31974
|
+
opacity: 0.5,
|
|
31975
|
+
fontWeight: 400
|
|
31976
|
+
},
|
|
31977
|
+
children: engine === "jscad" ? "experimental" : "default"
|
|
31978
|
+
}
|
|
31979
|
+
)
|
|
31980
|
+
]
|
|
31981
|
+
}
|
|
31982
|
+
),
|
|
31983
|
+
/* @__PURE__ */ jsxs9(
|
|
31984
|
+
"div",
|
|
31985
|
+
{
|
|
31986
|
+
style: { position: "relative" },
|
|
31987
|
+
onMouseEnter: () => setActiveSubmenu("camera"),
|
|
31988
|
+
onMouseLeave: () => setActiveSubmenu(null),
|
|
31989
|
+
children: [
|
|
31990
|
+
/* @__PURE__ */ jsxs9(
|
|
31991
|
+
"div",
|
|
31992
|
+
{
|
|
31993
|
+
style: {
|
|
31994
|
+
padding: "10px 18px",
|
|
31995
|
+
cursor: "pointer",
|
|
31996
|
+
display: "flex",
|
|
31997
|
+
alignItems: "center",
|
|
31998
|
+
gap: 10,
|
|
31999
|
+
color: "#f5f6fa",
|
|
32000
|
+
fontWeight: 500,
|
|
32001
|
+
borderRadius: 6,
|
|
32002
|
+
transition: "background 0.1s",
|
|
32003
|
+
background: activeSubmenu === "camera" ? "#2d313a" : "transparent"
|
|
32004
|
+
},
|
|
32005
|
+
onClick: () => setActiveSubmenu(
|
|
32006
|
+
(current2) => current2 === "camera" ? null : "camera"
|
|
32007
|
+
),
|
|
32008
|
+
children: [
|
|
32009
|
+
"Camera Position",
|
|
32010
|
+
/* @__PURE__ */ jsx18("span", { style: { marginLeft: "auto", opacity: 0.75 }, children: cameraPreset }),
|
|
32011
|
+
/* @__PURE__ */ jsx18("span", { style: { marginLeft: 4, opacity: 0.5 }, children: "\u203A" })
|
|
32012
|
+
]
|
|
32013
|
+
}
|
|
32014
|
+
),
|
|
32015
|
+
activeSubmenu === "camera" && /* @__PURE__ */ jsx18(
|
|
32016
|
+
"div",
|
|
32017
|
+
{
|
|
32018
|
+
style: {
|
|
32019
|
+
position: "absolute",
|
|
32020
|
+
top: 0,
|
|
32021
|
+
left: "100%",
|
|
32022
|
+
marginLeft: -2,
|
|
32023
|
+
background: "#23272f",
|
|
32024
|
+
color: "#f5f6fa",
|
|
32025
|
+
borderRadius: 6,
|
|
32026
|
+
boxShadow: "0 6px 24px 0 rgba(0,0,0,0.18)",
|
|
32027
|
+
border: "1px solid #353945",
|
|
32028
|
+
minWidth: 200,
|
|
32029
|
+
padding: "6px 0",
|
|
32030
|
+
zIndex: 1001
|
|
32031
|
+
},
|
|
32032
|
+
children: cameraOptions.map((option) => /* @__PURE__ */ jsxs9(
|
|
32033
|
+
"div",
|
|
32034
|
+
{
|
|
32035
|
+
style: {
|
|
32036
|
+
padding: "10px 18px",
|
|
32037
|
+
cursor: "pointer",
|
|
32038
|
+
display: "flex",
|
|
32039
|
+
alignItems: "center",
|
|
32040
|
+
gap: 10,
|
|
32041
|
+
color: "#f5f6fa",
|
|
32042
|
+
fontWeight: 500,
|
|
32043
|
+
borderRadius: 6,
|
|
32044
|
+
transition: "background 0.1s"
|
|
32045
|
+
},
|
|
32046
|
+
onClick: () => onCameraPresetSelect(option),
|
|
32047
|
+
onMouseOver: (event) => handleMenuItemHover(event, true),
|
|
32048
|
+
onMouseOut: (event) => handleMenuItemHover(event, false),
|
|
32049
|
+
children: [
|
|
32050
|
+
/* @__PURE__ */ jsx18("span", { style: { width: 18 }, children: cameraPreset === option ? "\u2714" : "" }),
|
|
32051
|
+
option
|
|
32052
|
+
]
|
|
32053
|
+
},
|
|
32054
|
+
option
|
|
32055
|
+
))
|
|
32056
|
+
}
|
|
32057
|
+
)
|
|
32058
|
+
]
|
|
32059
|
+
}
|
|
32060
|
+
),
|
|
32061
|
+
/* @__PURE__ */ jsxs9(
|
|
32062
|
+
"div",
|
|
32063
|
+
{
|
|
32064
|
+
style: {
|
|
32065
|
+
padding: "12px 18px",
|
|
32066
|
+
cursor: "pointer",
|
|
32067
|
+
display: "flex",
|
|
32068
|
+
alignItems: "center",
|
|
32069
|
+
gap: 10,
|
|
32070
|
+
color: "#f5f6fa",
|
|
32071
|
+
fontWeight: 500,
|
|
32072
|
+
borderRadius: 6,
|
|
32073
|
+
transition: "background 0.1s"
|
|
32074
|
+
},
|
|
32075
|
+
onClick: onAutoRotateToggle,
|
|
32076
|
+
onMouseOver: (event) => handleMenuItemHover(event, true),
|
|
32077
|
+
onMouseOut: (event) => handleMenuItemHover(event, false),
|
|
32078
|
+
children: [
|
|
32079
|
+
/* @__PURE__ */ jsx18("span", { style: { marginRight: 8 }, children: autoRotate ? "\u2714" : "" }),
|
|
32080
|
+
"Auto rotate"
|
|
32081
|
+
]
|
|
32082
|
+
}
|
|
32083
|
+
),
|
|
32084
|
+
/* @__PURE__ */ jsx18(
|
|
32085
|
+
"div",
|
|
32086
|
+
{
|
|
32087
|
+
style: {
|
|
32088
|
+
padding: "12px 18px",
|
|
32089
|
+
cursor: "pointer",
|
|
32090
|
+
display: "flex",
|
|
32091
|
+
alignItems: "center",
|
|
32092
|
+
gap: 10,
|
|
32093
|
+
color: "#f5f6fa",
|
|
32094
|
+
fontWeight: 500,
|
|
32095
|
+
borderRadius: 6,
|
|
32096
|
+
transition: "background 0.1s"
|
|
32097
|
+
},
|
|
32098
|
+
onClick: onDownloadGltf,
|
|
32099
|
+
onMouseOver: (event) => handleMenuItemHover(event, true),
|
|
32100
|
+
onMouseOut: (event) => handleMenuItemHover(event, false),
|
|
32101
|
+
children: "Download GLTF"
|
|
32102
|
+
}
|
|
32103
|
+
),
|
|
32104
|
+
/* @__PURE__ */ jsx18(AppearanceMenu, {}),
|
|
32105
|
+
/* @__PURE__ */ jsx18(
|
|
32106
|
+
"div",
|
|
32107
|
+
{
|
|
32108
|
+
style: {
|
|
32109
|
+
display: "flex",
|
|
32110
|
+
justifyContent: "center",
|
|
32111
|
+
padding: "8px 0",
|
|
32112
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
32113
|
+
marginTop: "8px"
|
|
32114
|
+
},
|
|
32115
|
+
children: /* @__PURE__ */ jsxs9(
|
|
32116
|
+
"span",
|
|
32117
|
+
{
|
|
32118
|
+
style: {
|
|
32119
|
+
fontSize: 10,
|
|
32120
|
+
opacity: 0.6,
|
|
32121
|
+
fontWeight: 300,
|
|
32122
|
+
color: "#c0c0c0"
|
|
32123
|
+
},
|
|
32124
|
+
children: [
|
|
32125
|
+
"@tscircuit/3d-viewer@",
|
|
32126
|
+
package_default.version
|
|
32127
|
+
]
|
|
32128
|
+
}
|
|
32129
|
+
)
|
|
32130
|
+
}
|
|
32131
|
+
)
|
|
32132
|
+
]
|
|
32133
|
+
}
|
|
32134
|
+
);
|
|
32135
|
+
};
|
|
32136
|
+
|
|
32137
|
+
// src/CadViewer.tsx
|
|
32138
|
+
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
31607
32139
|
var CadViewerInner = (props) => {
|
|
31608
|
-
const [engine, setEngine] =
|
|
32140
|
+
const [engine, setEngine] = useState19("manifold");
|
|
31609
32141
|
const containerRef = useRef9(null);
|
|
31610
|
-
const [autoRotate, setAutoRotate] =
|
|
31611
|
-
const [autoRotateUserToggled, setAutoRotateUserToggled] =
|
|
32142
|
+
const [autoRotate, setAutoRotate] = useState19(true);
|
|
32143
|
+
const [autoRotateUserToggled, setAutoRotateUserToggled] = useState19(false);
|
|
32144
|
+
const [cameraPreset, setCameraPreset] = useState19("Custom");
|
|
31612
32145
|
const { visibility, toggleLayer } = useLayerVisibility();
|
|
32146
|
+
const cameraControllerRef = useRef9(null);
|
|
32147
|
+
const externalCameraControllerReady = props.onCameraControllerReady;
|
|
31613
32148
|
const {
|
|
31614
32149
|
menuVisible,
|
|
31615
32150
|
menuPos,
|
|
@@ -31619,20 +32154,39 @@ var CadViewerInner = (props) => {
|
|
|
31619
32154
|
} = useContextMenu({ containerRef });
|
|
31620
32155
|
const autoRotateUserToggledRef = useRef9(autoRotateUserToggled);
|
|
31621
32156
|
autoRotateUserToggledRef.current = autoRotateUserToggled;
|
|
31622
|
-
const handleUserInteraction =
|
|
32157
|
+
const handleUserInteraction = useCallback11(() => {
|
|
31623
32158
|
if (!autoRotateUserToggledRef.current) {
|
|
31624
32159
|
setAutoRotate(false);
|
|
31625
32160
|
}
|
|
32161
|
+
setCameraPreset("Custom");
|
|
31626
32162
|
}, []);
|
|
31627
|
-
const toggleAutoRotate =
|
|
32163
|
+
const toggleAutoRotate = useCallback11(() => {
|
|
31628
32164
|
setAutoRotate((prev) => !prev);
|
|
31629
32165
|
setAutoRotateUserToggled(true);
|
|
31630
32166
|
}, []);
|
|
31631
32167
|
const downloadGltf = useGlobalDownloadGltf();
|
|
31632
|
-
const
|
|
31633
|
-
setEngine(newEngine);
|
|
32168
|
+
const closeMenu = useCallback11(() => {
|
|
31634
32169
|
setMenuVisible(false);
|
|
31635
|
-
};
|
|
32170
|
+
}, [setMenuVisible]);
|
|
32171
|
+
const handleCameraControllerReady = useCallback11(
|
|
32172
|
+
(controller) => {
|
|
32173
|
+
cameraControllerRef.current = controller;
|
|
32174
|
+
externalCameraControllerReady?.(controller);
|
|
32175
|
+
if (controller && cameraPreset !== "Custom") {
|
|
32176
|
+
controller.animateToPreset(cameraPreset);
|
|
32177
|
+
}
|
|
32178
|
+
},
|
|
32179
|
+
[cameraPreset, externalCameraControllerReady]
|
|
32180
|
+
);
|
|
32181
|
+
const handleCameraPresetSelect = useCallback11(
|
|
32182
|
+
(preset) => {
|
|
32183
|
+
setCameraPreset(preset);
|
|
32184
|
+
closeMenu();
|
|
32185
|
+
if (preset === "Custom") return;
|
|
32186
|
+
cameraControllerRef.current?.animateToPreset(preset);
|
|
32187
|
+
},
|
|
32188
|
+
[closeMenu]
|
|
32189
|
+
);
|
|
31636
32190
|
useEffect24(() => {
|
|
31637
32191
|
const stored = window.localStorage.getItem("cadViewerEngine");
|
|
31638
32192
|
if (stored === "jscad" || stored === "manifold") {
|
|
@@ -31643,7 +32197,7 @@ var CadViewerInner = (props) => {
|
|
|
31643
32197
|
window.localStorage.setItem("cadViewerEngine", engine);
|
|
31644
32198
|
}, [engine]);
|
|
31645
32199
|
const viewerKey = props.circuitJson ? JSON.stringify(props.circuitJson) : void 0;
|
|
31646
|
-
return /* @__PURE__ */
|
|
32200
|
+
return /* @__PURE__ */ jsxs10(
|
|
31647
32201
|
"div",
|
|
31648
32202
|
{
|
|
31649
32203
|
ref: containerRef,
|
|
@@ -31659,22 +32213,24 @@ var CadViewerInner = (props) => {
|
|
|
31659
32213
|
},
|
|
31660
32214
|
...contextMenuEventHandlers,
|
|
31661
32215
|
children: [
|
|
31662
|
-
engine === "jscad" ? /* @__PURE__ */
|
|
32216
|
+
engine === "jscad" ? /* @__PURE__ */ jsx19(
|
|
31663
32217
|
CadViewerJscad,
|
|
31664
32218
|
{
|
|
31665
32219
|
...props,
|
|
31666
32220
|
autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
|
|
31667
|
-
onUserInteraction: handleUserInteraction
|
|
32221
|
+
onUserInteraction: handleUserInteraction,
|
|
32222
|
+
onCameraControllerReady: handleCameraControllerReady
|
|
31668
32223
|
}
|
|
31669
|
-
) : /* @__PURE__ */
|
|
32224
|
+
) : /* @__PURE__ */ jsx19(
|
|
31670
32225
|
CadViewerManifold_default,
|
|
31671
32226
|
{
|
|
31672
32227
|
...props,
|
|
31673
32228
|
autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
|
|
31674
|
-
onUserInteraction: handleUserInteraction
|
|
32229
|
+
onUserInteraction: handleUserInteraction,
|
|
32230
|
+
onCameraControllerReady: handleCameraControllerReady
|
|
31675
32231
|
}
|
|
31676
32232
|
),
|
|
31677
|
-
/* @__PURE__ */
|
|
32233
|
+
/* @__PURE__ */ jsxs10(
|
|
31678
32234
|
"div",
|
|
31679
32235
|
{
|
|
31680
32236
|
style: {
|
|
@@ -31691,145 +32247,31 @@ var CadViewerInner = (props) => {
|
|
|
31691
32247
|
},
|
|
31692
32248
|
children: [
|
|
31693
32249
|
"Engine: ",
|
|
31694
|
-
/* @__PURE__ */
|
|
32250
|
+
/* @__PURE__ */ jsx19("b", { children: engine === "jscad" ? "JSCAD" : "Manifold" })
|
|
31695
32251
|
]
|
|
31696
32252
|
}
|
|
31697
32253
|
),
|
|
31698
|
-
menuVisible && /* @__PURE__ */
|
|
31699
|
-
|
|
32254
|
+
menuVisible && /* @__PURE__ */ jsx19(
|
|
32255
|
+
ContextMenu,
|
|
31700
32256
|
{
|
|
31701
|
-
|
|
31702
|
-
|
|
31703
|
-
|
|
31704
|
-
|
|
31705
|
-
|
|
31706
|
-
|
|
31707
|
-
|
|
31708
|
-
|
|
31709
|
-
boxShadow: "0 6px 24px 0 rgba(0,0,0,0.18)",
|
|
31710
|
-
zIndex: 1e3,
|
|
31711
|
-
minWidth: 200,
|
|
31712
|
-
border: "1px solid #353945",
|
|
31713
|
-
padding: 0,
|
|
31714
|
-
fontSize: 15,
|
|
31715
|
-
fontWeight: 500,
|
|
31716
|
-
transition: "opacity 0.1s"
|
|
32257
|
+
menuRef,
|
|
32258
|
+
menuPos,
|
|
32259
|
+
engine,
|
|
32260
|
+
cameraPreset,
|
|
32261
|
+
autoRotate,
|
|
32262
|
+
onEngineSwitch: (newEngine) => {
|
|
32263
|
+
setEngine(newEngine);
|
|
32264
|
+
closeMenu();
|
|
31717
32265
|
},
|
|
31718
|
-
|
|
31719
|
-
|
|
31720
|
-
|
|
31721
|
-
|
|
31722
|
-
|
|
31723
|
-
|
|
31724
|
-
|
|
31725
|
-
|
|
31726
|
-
|
|
31727
|
-
gap: 10,
|
|
31728
|
-
color: "#f5f6fa",
|
|
31729
|
-
fontWeight: 500,
|
|
31730
|
-
borderRadius: 6,
|
|
31731
|
-
transition: "background 0.1s"
|
|
31732
|
-
},
|
|
31733
|
-
onClick: () => handleMenuClick(engine === "jscad" ? "manifold" : "jscad"),
|
|
31734
|
-
onMouseOver: (e) => e.currentTarget.style.background = "#2d313a",
|
|
31735
|
-
onMouseOut: (e) => e.currentTarget.style.background = "transparent",
|
|
31736
|
-
children: [
|
|
31737
|
-
"Switch to ",
|
|
31738
|
-
engine === "jscad" ? "Manifold" : "JSCAD",
|
|
31739
|
-
" Engine",
|
|
31740
|
-
/* @__PURE__ */ jsx18(
|
|
31741
|
-
"span",
|
|
31742
|
-
{
|
|
31743
|
-
style: {
|
|
31744
|
-
fontSize: 12,
|
|
31745
|
-
marginLeft: "auto",
|
|
31746
|
-
opacity: 0.5,
|
|
31747
|
-
fontWeight: 400
|
|
31748
|
-
},
|
|
31749
|
-
children: engine === "jscad" ? "experimental" : "default"
|
|
31750
|
-
}
|
|
31751
|
-
)
|
|
31752
|
-
]
|
|
31753
|
-
}
|
|
31754
|
-
),
|
|
31755
|
-
/* @__PURE__ */ jsxs9(
|
|
31756
|
-
"div",
|
|
31757
|
-
{
|
|
31758
|
-
style: {
|
|
31759
|
-
padding: "12px 18px",
|
|
31760
|
-
cursor: "pointer",
|
|
31761
|
-
display: "flex",
|
|
31762
|
-
alignItems: "center",
|
|
31763
|
-
gap: 10,
|
|
31764
|
-
color: "#f5f6fa",
|
|
31765
|
-
fontWeight: 500,
|
|
31766
|
-
borderRadius: 6,
|
|
31767
|
-
transition: "background 0.1s"
|
|
31768
|
-
},
|
|
31769
|
-
onClick: () => {
|
|
31770
|
-
toggleAutoRotate();
|
|
31771
|
-
setMenuVisible(false);
|
|
31772
|
-
},
|
|
31773
|
-
onMouseOver: (e) => e.currentTarget.style.background = "#2d313a",
|
|
31774
|
-
onMouseOut: (e) => e.currentTarget.style.background = "transparent",
|
|
31775
|
-
children: [
|
|
31776
|
-
/* @__PURE__ */ jsx18("span", { style: { marginRight: 8 }, children: autoRotate ? "\u2714" : "" }),
|
|
31777
|
-
"Auto rotate"
|
|
31778
|
-
]
|
|
31779
|
-
}
|
|
31780
|
-
),
|
|
31781
|
-
/* @__PURE__ */ jsx18(
|
|
31782
|
-
"div",
|
|
31783
|
-
{
|
|
31784
|
-
style: {
|
|
31785
|
-
padding: "12px 18px",
|
|
31786
|
-
cursor: "pointer",
|
|
31787
|
-
display: "flex",
|
|
31788
|
-
alignItems: "center",
|
|
31789
|
-
gap: 10,
|
|
31790
|
-
color: "#f5f6fa",
|
|
31791
|
-
fontWeight: 500,
|
|
31792
|
-
borderRadius: 6,
|
|
31793
|
-
transition: "background 0.1s"
|
|
31794
|
-
},
|
|
31795
|
-
onClick: () => {
|
|
31796
|
-
downloadGltf();
|
|
31797
|
-
setMenuVisible(false);
|
|
31798
|
-
},
|
|
31799
|
-
onMouseOver: (e) => e.currentTarget.style.background = "#2d313a",
|
|
31800
|
-
onMouseOut: (e) => e.currentTarget.style.background = "transparent",
|
|
31801
|
-
children: "Download GLTF"
|
|
31802
|
-
}
|
|
31803
|
-
),
|
|
31804
|
-
/* @__PURE__ */ jsx18(AppearanceMenu, {}),
|
|
31805
|
-
/* @__PURE__ */ jsx18(
|
|
31806
|
-
"div",
|
|
31807
|
-
{
|
|
31808
|
-
style: {
|
|
31809
|
-
display: "flex",
|
|
31810
|
-
justifyContent: "center",
|
|
31811
|
-
padding: "8px 0",
|
|
31812
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
31813
|
-
marginTop: "8px"
|
|
31814
|
-
},
|
|
31815
|
-
children: /* @__PURE__ */ jsxs9(
|
|
31816
|
-
"span",
|
|
31817
|
-
{
|
|
31818
|
-
style: {
|
|
31819
|
-
fontSize: 10,
|
|
31820
|
-
opacity: 0.6,
|
|
31821
|
-
fontWeight: 300,
|
|
31822
|
-
color: "#c0c0c0"
|
|
31823
|
-
},
|
|
31824
|
-
children: [
|
|
31825
|
-
"@tscircuit/3d-viewer@",
|
|
31826
|
-
package_default.version
|
|
31827
|
-
]
|
|
31828
|
-
}
|
|
31829
|
-
)
|
|
31830
|
-
}
|
|
31831
|
-
)
|
|
31832
|
-
]
|
|
32266
|
+
onCameraPresetSelect: handleCameraPresetSelect,
|
|
32267
|
+
onAutoRotateToggle: () => {
|
|
32268
|
+
toggleAutoRotate();
|
|
32269
|
+
closeMenu();
|
|
32270
|
+
},
|
|
32271
|
+
onDownloadGltf: () => {
|
|
32272
|
+
downloadGltf();
|
|
32273
|
+
closeMenu();
|
|
32274
|
+
}
|
|
31833
32275
|
}
|
|
31834
32276
|
)
|
|
31835
32277
|
]
|
|
@@ -31838,17 +32280,17 @@ var CadViewerInner = (props) => {
|
|
|
31838
32280
|
);
|
|
31839
32281
|
};
|
|
31840
32282
|
var CadViewer = (props) => {
|
|
31841
|
-
return /* @__PURE__ */
|
|
32283
|
+
return /* @__PURE__ */ jsx19(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx19(CadViewerInner, { ...props }) });
|
|
31842
32284
|
};
|
|
31843
32285
|
|
|
31844
32286
|
// src/convert-circuit-json-to-3d-svg.ts
|
|
31845
32287
|
var import_debug = __toESM(require_browser(), 1);
|
|
31846
32288
|
import { su as su14 } from "@tscircuit/circuit-json-util";
|
|
31847
|
-
import * as
|
|
32289
|
+
import * as THREE31 from "three";
|
|
31848
32290
|
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
|
|
31849
32291
|
|
|
31850
32292
|
// src/utils/create-geometry-from-polygons.ts
|
|
31851
|
-
import * as
|
|
32293
|
+
import * as THREE28 from "three";
|
|
31852
32294
|
import { BufferGeometry as BufferGeometry3, Float32BufferAttribute as Float32BufferAttribute2 } from "three";
|
|
31853
32295
|
function createGeometryFromPolygons(polygons) {
|
|
31854
32296
|
const geometry = new BufferGeometry3();
|
|
@@ -31862,12 +32304,12 @@ function createGeometryFromPolygons(polygons) {
|
|
|
31862
32304
|
...polygon3.vertices[i + 1]
|
|
31863
32305
|
// Third vertex
|
|
31864
32306
|
);
|
|
31865
|
-
const v1 = new
|
|
31866
|
-
const v2 = new
|
|
31867
|
-
const v3 = new
|
|
31868
|
-
const normal = new
|
|
31869
|
-
new
|
|
31870
|
-
new
|
|
32307
|
+
const v1 = new THREE28.Vector3(...polygon3.vertices[0]);
|
|
32308
|
+
const v2 = new THREE28.Vector3(...polygon3.vertices[i]);
|
|
32309
|
+
const v3 = new THREE28.Vector3(...polygon3.vertices[i + 1]);
|
|
32310
|
+
const normal = new THREE28.Vector3().crossVectors(
|
|
32311
|
+
new THREE28.Vector3().subVectors(v2, v1),
|
|
32312
|
+
new THREE28.Vector3().subVectors(v3, v1)
|
|
31871
32313
|
).normalize();
|
|
31872
32314
|
normals.push(
|
|
31873
32315
|
normal.x,
|
|
@@ -31891,10 +32333,10 @@ function createGeometryFromPolygons(polygons) {
|
|
|
31891
32333
|
var import_modeling2 = __toESM(require_src(), 1);
|
|
31892
32334
|
var import_jscad_planner2 = __toESM(require_dist(), 1);
|
|
31893
32335
|
var jscadModeling2 = __toESM(require_src(), 1);
|
|
31894
|
-
import * as
|
|
32336
|
+
import * as THREE30 from "three";
|
|
31895
32337
|
|
|
31896
32338
|
// src/utils/load-model.ts
|
|
31897
|
-
import * as
|
|
32339
|
+
import * as THREE29 from "three";
|
|
31898
32340
|
import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
31899
32341
|
import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
31900
32342
|
import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
|
|
@@ -31902,12 +32344,12 @@ async function load3DModel(url) {
|
|
|
31902
32344
|
if (url.endsWith(".stl")) {
|
|
31903
32345
|
const loader = new STLLoader2();
|
|
31904
32346
|
const geometry = await loader.loadAsync(url);
|
|
31905
|
-
const material = new
|
|
32347
|
+
const material = new THREE29.MeshStandardMaterial({
|
|
31906
32348
|
color: 8947848,
|
|
31907
32349
|
metalness: 0.5,
|
|
31908
32350
|
roughness: 0.5
|
|
31909
32351
|
});
|
|
31910
|
-
return new
|
|
32352
|
+
return new THREE29.Mesh(geometry, material);
|
|
31911
32353
|
}
|
|
31912
32354
|
if (url.endsWith(".obj")) {
|
|
31913
32355
|
const loader = new OBJLoader2();
|
|
@@ -31940,9 +32382,9 @@ async function renderComponent(component, scene) {
|
|
|
31940
32382
|
}
|
|
31941
32383
|
if (component.rotation) {
|
|
31942
32384
|
model.rotation.set(
|
|
31943
|
-
|
|
31944
|
-
|
|
31945
|
-
|
|
32385
|
+
THREE30.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
32386
|
+
THREE30.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
32387
|
+
THREE30.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
31946
32388
|
);
|
|
31947
32389
|
}
|
|
31948
32390
|
scene.add(model);
|
|
@@ -31956,13 +32398,13 @@ async function renderComponent(component, scene) {
|
|
|
31956
32398
|
);
|
|
31957
32399
|
if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
|
|
31958
32400
|
const threeGeom = convertCSGToThreeGeom(jscadObject);
|
|
31959
|
-
const material2 = new
|
|
32401
|
+
const material2 = new THREE30.MeshStandardMaterial({
|
|
31960
32402
|
color: 8947848,
|
|
31961
32403
|
metalness: 0.5,
|
|
31962
32404
|
roughness: 0.5,
|
|
31963
|
-
side:
|
|
32405
|
+
side: THREE30.DoubleSide
|
|
31964
32406
|
});
|
|
31965
|
-
const mesh2 = new
|
|
32407
|
+
const mesh2 = new THREE30.Mesh(threeGeom, material2);
|
|
31966
32408
|
if (component.position) {
|
|
31967
32409
|
mesh2.position.set(
|
|
31968
32410
|
component.position.x ?? 0,
|
|
@@ -31972,9 +32414,9 @@ async function renderComponent(component, scene) {
|
|
|
31972
32414
|
}
|
|
31973
32415
|
if (component.rotation) {
|
|
31974
32416
|
mesh2.rotation.set(
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
|
|
32417
|
+
THREE30.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
32418
|
+
THREE30.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
32419
|
+
THREE30.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
31978
32420
|
);
|
|
31979
32421
|
}
|
|
31980
32422
|
scene.add(mesh2);
|
|
@@ -31991,17 +32433,17 @@ async function renderComponent(component, scene) {
|
|
|
31991
32433
|
if (!geom || !geom.polygons && !geom.sides) {
|
|
31992
32434
|
continue;
|
|
31993
32435
|
}
|
|
31994
|
-
const color = new
|
|
32436
|
+
const color = new THREE30.Color(geomInfo.color);
|
|
31995
32437
|
color.convertLinearToSRGB();
|
|
31996
32438
|
const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
|
|
31997
32439
|
const threeGeom = convertCSGToThreeGeom(geomWithColor);
|
|
31998
|
-
const material2 = new
|
|
32440
|
+
const material2 = new THREE30.MeshStandardMaterial({
|
|
31999
32441
|
vertexColors: true,
|
|
32000
32442
|
metalness: 0.2,
|
|
32001
32443
|
roughness: 0.8,
|
|
32002
|
-
side:
|
|
32444
|
+
side: THREE30.DoubleSide
|
|
32003
32445
|
});
|
|
32004
|
-
const mesh2 = new
|
|
32446
|
+
const mesh2 = new THREE30.Mesh(threeGeom, material2);
|
|
32005
32447
|
if (component.position) {
|
|
32006
32448
|
mesh2.position.set(
|
|
32007
32449
|
component.position.x ?? 0,
|
|
@@ -32011,22 +32453,22 @@ async function renderComponent(component, scene) {
|
|
|
32011
32453
|
}
|
|
32012
32454
|
if (component.rotation) {
|
|
32013
32455
|
mesh2.rotation.set(
|
|
32014
|
-
|
|
32015
|
-
|
|
32016
|
-
|
|
32456
|
+
THREE30.MathUtils.degToRad(component.rotation.x ?? 0),
|
|
32457
|
+
THREE30.MathUtils.degToRad(component.rotation.y ?? 0),
|
|
32458
|
+
THREE30.MathUtils.degToRad(component.rotation.z ?? 0)
|
|
32017
32459
|
);
|
|
32018
32460
|
}
|
|
32019
32461
|
scene.add(mesh2);
|
|
32020
32462
|
}
|
|
32021
32463
|
return;
|
|
32022
32464
|
}
|
|
32023
|
-
const geometry = new
|
|
32024
|
-
const material = new
|
|
32465
|
+
const geometry = new THREE30.BoxGeometry(0.5, 0.5, 0.5);
|
|
32466
|
+
const material = new THREE30.MeshStandardMaterial({
|
|
32025
32467
|
color: 16711680,
|
|
32026
32468
|
transparent: true,
|
|
32027
32469
|
opacity: 0.25
|
|
32028
32470
|
});
|
|
32029
|
-
const mesh = new
|
|
32471
|
+
const mesh = new THREE30.Mesh(geometry, material);
|
|
32030
32472
|
if (component.position) {
|
|
32031
32473
|
mesh.position.set(
|
|
32032
32474
|
component.position.x ?? 0,
|
|
@@ -32047,11 +32489,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
32047
32489
|
padding = 20,
|
|
32048
32490
|
zoom = 1.5
|
|
32049
32491
|
} = options;
|
|
32050
|
-
const scene = new
|
|
32492
|
+
const scene = new THREE31.Scene();
|
|
32051
32493
|
const renderer = new SVGRenderer();
|
|
32052
32494
|
renderer.setSize(width10, height10);
|
|
32053
|
-
renderer.setClearColor(new
|
|
32054
|
-
const camera = new
|
|
32495
|
+
renderer.setClearColor(new THREE31.Color(backgroundColor), 1);
|
|
32496
|
+
const camera = new THREE31.OrthographicCamera();
|
|
32055
32497
|
const aspect = width10 / height10;
|
|
32056
32498
|
const frustumSize = 100;
|
|
32057
32499
|
const halfFrustumSize = frustumSize / 2 / zoom;
|
|
@@ -32065,11 +32507,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
32065
32507
|
camera.position.set(position.x, position.y, position.z);
|
|
32066
32508
|
camera.up.set(0, 1, 0);
|
|
32067
32509
|
const lookAt = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
|
|
32068
|
-
camera.lookAt(new
|
|
32510
|
+
camera.lookAt(new THREE31.Vector3(lookAt.x, lookAt.y, lookAt.z));
|
|
32069
32511
|
camera.updateProjectionMatrix();
|
|
32070
|
-
const ambientLight = new
|
|
32512
|
+
const ambientLight = new THREE31.AmbientLight(16777215, Math.PI / 2);
|
|
32071
32513
|
scene.add(ambientLight);
|
|
32072
|
-
const pointLight = new
|
|
32514
|
+
const pointLight = new THREE31.PointLight(16777215, Math.PI / 4);
|
|
32073
32515
|
pointLight.position.set(-10, -10, 10);
|
|
32074
32516
|
scene.add(pointLight);
|
|
32075
32517
|
const components = su14(circuitJson).cad_component.list();
|
|
@@ -32083,7 +32525,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
32083
32525
|
const g = geom;
|
|
32084
32526
|
if (!g.polygons || g.polygons.length === 0) continue;
|
|
32085
32527
|
const geometry = createGeometryFromPolygons(g.polygons);
|
|
32086
|
-
const baseColor = new
|
|
32528
|
+
const baseColor = new THREE31.Color(
|
|
32087
32529
|
g.color?.[0] ?? 0,
|
|
32088
32530
|
g.color?.[1] ?? 0,
|
|
32089
32531
|
g.color?.[2] ?? 0
|
|
@@ -32091,18 +32533,18 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
32091
32533
|
const material = createBoardMaterial({
|
|
32092
32534
|
material: boardData?.material,
|
|
32093
32535
|
color: baseColor,
|
|
32094
|
-
side:
|
|
32536
|
+
side: THREE31.DoubleSide
|
|
32095
32537
|
});
|
|
32096
|
-
const mesh = new
|
|
32538
|
+
const mesh = new THREE31.Mesh(geometry, material);
|
|
32097
32539
|
scene.add(mesh);
|
|
32098
32540
|
}
|
|
32099
32541
|
}
|
|
32100
|
-
const gridHelper = new
|
|
32542
|
+
const gridHelper = new THREE31.GridHelper(100, 100);
|
|
32101
32543
|
gridHelper.rotation.x = Math.PI / 2;
|
|
32102
32544
|
scene.add(gridHelper);
|
|
32103
|
-
const box = new
|
|
32104
|
-
const center = box.getCenter(new
|
|
32105
|
-
const size2 = box.getSize(new
|
|
32545
|
+
const box = new THREE31.Box3().setFromObject(scene);
|
|
32546
|
+
const center = box.getCenter(new THREE31.Vector3());
|
|
32547
|
+
const size2 = box.getSize(new THREE31.Vector3());
|
|
32106
32548
|
scene.position.sub(center);
|
|
32107
32549
|
const maxDim = Math.max(size2.x, size2.y, size2.z);
|
|
32108
32550
|
if (maxDim > 0) {
|
|
@@ -32120,10 +32562,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
32120
32562
|
|
|
32121
32563
|
// src/hooks/exporter/gltf.ts
|
|
32122
32564
|
import { GLTFExporter as GLTFExporter2 } from "three-stdlib";
|
|
32123
|
-
import { useEffect as useEffect25, useState as
|
|
32565
|
+
import { useEffect as useEffect25, useState as useState20, useMemo as useMemo22, useCallback as useCallback12 } from "react";
|
|
32124
32566
|
function useSaveGltfAs(options = {}) {
|
|
32125
32567
|
const parse = useParser(options);
|
|
32126
|
-
const link =
|
|
32568
|
+
const link = useMemo22(() => document.createElement("a"), []);
|
|
32127
32569
|
const saveAs = async (filename) => {
|
|
32128
32570
|
const name = filename ?? options.filename ?? "";
|
|
32129
32571
|
if (options.binary == null) options.binary = name.endsWith(".glb");
|
|
@@ -32141,16 +32583,16 @@ function useSaveGltfAs(options = {}) {
|
|
|
32141
32583
|
[]
|
|
32142
32584
|
);
|
|
32143
32585
|
let instance;
|
|
32144
|
-
const ref =
|
|
32586
|
+
const ref = useCallback12((obj3D) => {
|
|
32145
32587
|
instance = obj3D;
|
|
32146
32588
|
}, []);
|
|
32147
32589
|
return [ref, saveAs];
|
|
32148
32590
|
}
|
|
32149
32591
|
function useExportGltfUrl(options = {}) {
|
|
32150
32592
|
const parse = useParser(options);
|
|
32151
|
-
const [url, setUrl] =
|
|
32152
|
-
const [error, setError] =
|
|
32153
|
-
const ref =
|
|
32593
|
+
const [url, setUrl] = useState20();
|
|
32594
|
+
const [error, setError] = useState20();
|
|
32595
|
+
const ref = useCallback12(
|
|
32154
32596
|
(instance) => parse(instance).then(setUrl).catch(setError),
|
|
32155
32597
|
[]
|
|
32156
32598
|
);
|
|
@@ -32158,7 +32600,7 @@ function useExportGltfUrl(options = {}) {
|
|
|
32158
32600
|
return [ref, url, error];
|
|
32159
32601
|
}
|
|
32160
32602
|
function useParser(options = {}) {
|
|
32161
|
-
const exporter =
|
|
32603
|
+
const exporter = useMemo22(() => new GLTFExporter2(), []);
|
|
32162
32604
|
return (instance) => {
|
|
32163
32605
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
32164
32606
|
exporter.parse(
|