@cluesmith/codev 1.5.11 → 1.5.13
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/package.json +1 -1
- package/templates/3d-viewer.html +44 -42
package/package.json
CHANGED
package/templates/3d-viewer.html
CHANGED
|
@@ -207,9 +207,9 @@
|
|
|
207
207
|
<div id="error-message">Failed to load 3D model</div>
|
|
208
208
|
</div>
|
|
209
209
|
<div id="axes-legend">
|
|
210
|
-
<div class="axis-x">X →
|
|
211
|
-
<div class="axis-y">Y →
|
|
212
|
-
<div class="axis-z">Z →
|
|
210
|
+
<div class="axis-x">X → Left</div>
|
|
211
|
+
<div class="axis-y">Y → Front</div>
|
|
212
|
+
<div class="axis-z">Z → Up</div>
|
|
213
213
|
</div>
|
|
214
214
|
</div>
|
|
215
215
|
|
|
@@ -272,13 +272,14 @@
|
|
|
272
272
|
scene = new THREE.Scene();
|
|
273
273
|
scene.background = new THREE.Color(0x1a1a2e);
|
|
274
274
|
|
|
275
|
-
// Camera
|
|
275
|
+
// Camera (Z-up coordinate system)
|
|
276
276
|
camera = new THREE.PerspectiveCamera(
|
|
277
277
|
45,
|
|
278
278
|
container.clientWidth / container.clientHeight,
|
|
279
279
|
0.1,
|
|
280
280
|
10000
|
|
281
281
|
);
|
|
282
|
+
camera.up.set(0, 0, 1); // Z is up
|
|
282
283
|
camera.position.set(100, 100, 100);
|
|
283
284
|
|
|
284
285
|
// Renderer
|
|
@@ -306,8 +307,9 @@
|
|
|
306
307
|
directionalLight2.position.set(-1, -1, -1);
|
|
307
308
|
scene.add(directionalLight2);
|
|
308
309
|
|
|
309
|
-
// Grid
|
|
310
|
+
// Grid (on XY plane for Z-up coordinate system)
|
|
310
311
|
gridHelper = new THREE.GridHelper(200, 20, 0x0f3460, 0x0f3460);
|
|
312
|
+
gridHelper.rotation.x = Math.PI / 2; // Rotate to XY plane
|
|
311
313
|
scene.add(gridHelper);
|
|
312
314
|
|
|
313
315
|
// Axes helper (X=red, Y=green, Z=blue)
|
|
@@ -326,14 +328,14 @@
|
|
|
326
328
|
axesBtn.addEventListener('click', toggleAxes);
|
|
327
329
|
gridBtn.addEventListener('click', toggleGrid);
|
|
328
330
|
|
|
329
|
-
// View buttons
|
|
330
|
-
viewTop.addEventListener('click', () => setView(0,
|
|
331
|
-
viewBottom.addEventListener('click', () => setView(0, -1
|
|
332
|
-
viewFront.addEventListener('click', () => setView(0,
|
|
333
|
-
viewBack.addEventListener('click', () => setView(0,
|
|
334
|
-
viewRight.addEventListener('click', () => setView(1, 0, 0));
|
|
335
|
-
viewLeft.addEventListener('click', () => setView(-1, 0, 0));
|
|
336
|
-
viewIso.addEventListener('click', () => setView(1, 1, 1));
|
|
331
|
+
// View buttons (Z-up coordinate system: X=left, Y=front, Z=up)
|
|
332
|
+
viewTop.addEventListener('click', () => setView(0, 0, 1)); // Looking down from +Z
|
|
333
|
+
viewBottom.addEventListener('click', () => setView(0, 0, -1)); // Looking up from -Z
|
|
334
|
+
viewFront.addEventListener('click', () => setView(0, -1, 0)); // Looking from -Y (front)
|
|
335
|
+
viewBack.addEventListener('click', () => setView(0, 1, 0)); // Looking from +Y (back)
|
|
336
|
+
viewRight.addEventListener('click', () => setView(1, 0, 0)); // Looking from +X
|
|
337
|
+
viewLeft.addEventListener('click', () => setView(-1, 0, 0)); // Looking from -X
|
|
338
|
+
viewIso.addEventListener('click', () => setView(1, -1, 1)); // Isometric from front-right-above
|
|
337
339
|
|
|
338
340
|
// Animation loop
|
|
339
341
|
animate();
|
|
@@ -353,17 +355,17 @@
|
|
|
353
355
|
const loader = new STLLoader();
|
|
354
356
|
|
|
355
357
|
loader.load(
|
|
356
|
-
'
|
|
358
|
+
'api/model',
|
|
357
359
|
(geometry) => {
|
|
358
|
-
// Center geometry
|
|
360
|
+
// Center geometry in XY, keep Z base at 0
|
|
359
361
|
geometry.computeBoundingBox();
|
|
360
362
|
const center = new THREE.Vector3();
|
|
361
363
|
geometry.boundingBox.getCenter(center);
|
|
362
364
|
geometry.translate(-center.x, -center.y, -center.z);
|
|
363
365
|
|
|
364
|
-
// Move to sit on grid
|
|
365
|
-
const
|
|
366
|
-
geometry.translate(0,
|
|
366
|
+
// Move to sit on grid (Z=0 plane)
|
|
367
|
+
const minZ = geometry.boundingBox.min.z - center.z;
|
|
368
|
+
geometry.translate(0, 0, -minZ);
|
|
367
369
|
|
|
368
370
|
// Recalculate bounding box after translation
|
|
369
371
|
geometry.computeBoundingBox();
|
|
@@ -396,20 +398,19 @@
|
|
|
396
398
|
const loader = new ThreeMFLoader();
|
|
397
399
|
|
|
398
400
|
loader.load(
|
|
399
|
-
'
|
|
401
|
+
'api/model',
|
|
400
402
|
(group) => {
|
|
401
403
|
// 3MFLoader returns a Group with meshes
|
|
402
|
-
// 3MF uses Z-up,
|
|
403
|
-
group.rotation.set(-Math.PI / 2, 0, 0);
|
|
404
|
+
// 3MF uses Z-up natively, which matches our coordinate system
|
|
404
405
|
|
|
405
|
-
// Center the group
|
|
406
|
+
// Center the group in XY
|
|
406
407
|
const box = new THREE.Box3().setFromObject(group);
|
|
407
408
|
const center = box.getCenter(new THREE.Vector3());
|
|
408
409
|
group.position.sub(center);
|
|
409
410
|
|
|
410
|
-
// Move to sit on grid (
|
|
411
|
+
// Move to sit on grid (Z=0 plane)
|
|
411
412
|
const newBox = new THREE.Box3().setFromObject(group);
|
|
412
|
-
group.position.
|
|
413
|
+
group.position.z -= newBox.min.z;
|
|
413
414
|
|
|
414
415
|
model = group;
|
|
415
416
|
scene.add(model);
|
|
@@ -452,6 +453,7 @@
|
|
|
452
453
|
const gridSize = Math.ceil(maxDim * 2 / 10) * 10; // Round up to nearest 10
|
|
453
454
|
scene.remove(gridHelper);
|
|
454
455
|
gridHelper = new THREE.GridHelper(gridSize, gridSize / 5, 0x0f3460, 0x0f3460);
|
|
456
|
+
gridHelper.rotation.x = Math.PI / 2; // Rotate to XY plane for Z-up
|
|
455
457
|
gridHelper.visible = showGrid;
|
|
456
458
|
scene.add(gridHelper);
|
|
457
459
|
|
|
@@ -484,8 +486,8 @@
|
|
|
484
486
|
const fov = camera.fov * (Math.PI / 180);
|
|
485
487
|
cameraDistance = maxDim / (2 * Math.tan(fov / 2)) * 1.5;
|
|
486
488
|
|
|
487
|
-
// Isometric view
|
|
488
|
-
setView(1, 1, 1);
|
|
489
|
+
// Isometric view from front-right-above (Z-up system)
|
|
490
|
+
setView(1, -1, 1);
|
|
489
491
|
}
|
|
490
492
|
|
|
491
493
|
function setView(x, y, z) {
|
|
@@ -500,11 +502,12 @@
|
|
|
500
502
|
// Set camera position
|
|
501
503
|
camera.position.copy(center).add(dir.multiplyScalar(cameraDistance));
|
|
502
504
|
|
|
503
|
-
// Set up vector (
|
|
504
|
-
|
|
505
|
-
|
|
505
|
+
// Set up vector (Z-up coordinate system)
|
|
506
|
+
// When looking straight up/down along Z, use Y as up reference
|
|
507
|
+
if (Math.abs(z) > 0.9) {
|
|
508
|
+
camera.up.set(0, z > 0 ? 1 : -1, 0);
|
|
506
509
|
} else {
|
|
507
|
-
camera.up.set(0,
|
|
510
|
+
camera.up.set(0, 0, 1);
|
|
508
511
|
}
|
|
509
512
|
|
|
510
513
|
// Look at center
|
|
@@ -648,7 +651,7 @@
|
|
|
648
651
|
|
|
649
652
|
async function checkForChanges() {
|
|
650
653
|
try {
|
|
651
|
-
const res = await fetch('
|
|
654
|
+
const res = await fetch('api/mtime');
|
|
652
655
|
if (res.ok) {
|
|
653
656
|
const data = await res.json();
|
|
654
657
|
if (lastMtime === null) {
|
|
@@ -702,16 +705,16 @@
|
|
|
702
705
|
|
|
703
706
|
function reloadSTL() {
|
|
704
707
|
const loader = new STLLoader();
|
|
705
|
-
loader.load('
|
|
706
|
-
// Center geometry
|
|
708
|
+
loader.load('api/model?t=' + Date.now(), (geometry) => {
|
|
709
|
+
// Center geometry in XY
|
|
707
710
|
geometry.computeBoundingBox();
|
|
708
711
|
const center = new THREE.Vector3();
|
|
709
712
|
geometry.boundingBox.getCenter(center);
|
|
710
713
|
geometry.translate(-center.x, -center.y, -center.z);
|
|
711
714
|
|
|
712
|
-
// Move to sit on grid
|
|
713
|
-
const
|
|
714
|
-
geometry.translate(0,
|
|
715
|
+
// Move to sit on grid (Z=0 plane)
|
|
716
|
+
const minZ = geometry.boundingBox.min.z - center.z;
|
|
717
|
+
geometry.translate(0, 0, -minZ);
|
|
715
718
|
|
|
716
719
|
// Recalculate bounding box after translation
|
|
717
720
|
geometry.computeBoundingBox();
|
|
@@ -745,18 +748,17 @@
|
|
|
745
748
|
|
|
746
749
|
function reload3MF() {
|
|
747
750
|
const loader = new ThreeMFLoader();
|
|
748
|
-
loader.load('
|
|
749
|
-
// Z-up
|
|
750
|
-
group.rotation.set(-Math.PI / 2, 0, 0);
|
|
751
|
+
loader.load('api/model?t=' + Date.now(), (group) => {
|
|
752
|
+
// 3MF uses Z-up natively, which matches our coordinate system
|
|
751
753
|
|
|
752
|
-
// Center the group
|
|
754
|
+
// Center the group in XY
|
|
753
755
|
const box = new THREE.Box3().setFromObject(group);
|
|
754
756
|
const center = box.getCenter(new THREE.Vector3());
|
|
755
757
|
group.position.sub(center);
|
|
756
758
|
|
|
757
|
-
// Move to sit on grid
|
|
759
|
+
// Move to sit on grid (Z=0 plane)
|
|
758
760
|
const newBox = new THREE.Box3().setFromObject(group);
|
|
759
|
-
group.position.
|
|
761
|
+
group.position.z -= newBox.min.z;
|
|
760
762
|
|
|
761
763
|
model = group;
|
|
762
764
|
scene.add(model);
|