+
+ Peça selecionada
@@ -102,8 +175,8 @@ const Viewer = () => {
- Use o mouse para orbitar, scroll para zoom. Controle a opacidade e o modo de renderização nos
- controles flutuantes.
+ Clique em uma peça na cena para selecioná-la — os controles de ajuste fino
+ passam a operar sobre ela. Use "Adicionar" / "Nuvem" para empilhar peças.
From b302b91de9423e15c52805a48fc7ad83bcd36677 Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Thu, 14 May 2026 16:45:24 +0000
Subject: [PATCH 15/18] Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
---
src/pages/XRSession.tsx | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/src/pages/XRSession.tsx b/src/pages/XRSession.tsx
index 9c33a90..3ffb5f8 100644
--- a/src/pages/XRSession.tsx
+++ b/src/pages/XRSession.tsx
@@ -32,10 +32,11 @@ const store = createXRStore({
});
// ─── XRModel ───────────────────────────────────────────
-function XRModel({ url }: { url: string }) {
- const { scene } = useGLTF(url);
+function XRModel({ sceneModel }: { sceneModel: import('@/stores/useModelStore').SceneModel }) {
+ const { scene: rawScene } = useGLTF(sceneModel.url);
+ const scene = useMemo(() => rawScene.clone(true), [rawScene]);
const ref = useRef
(null);
- const fineTuning = useModelStore((s) => s.fineTuning);
+ const fineTuning = sceneModel.fineTuning;
const opacity = useModelStore((s) => s.opacity);
const renderMode = useModelStore((s) => s.renderMode);
const wireframeColor = useModelStore((s) => s.wireframeColor);
@@ -64,7 +65,6 @@ function XRModel({ url }: { url: string }) {
child.material = child.material.clone();
}
- // Clean up previous edge lines
const toRemove: THREE.Object3D[] = [];
child.children.forEach(c => {
if (c.userData.__edgeLine) toRemove.push(c);
@@ -95,7 +95,7 @@ function XRModel({ url }: { url: string }) {
} else if (allApproved) {
mat.color.setHSL(0.38, 0.7, 0.45);
} else {
- mat.color.set(0x8899aa);
+ mat.color.set(sceneModel.color);
}
}
mat.needsUpdate = true;
@@ -111,7 +111,7 @@ function XRModel({ url }: { url: string }) {
}
}
});
- }, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle]);
+ }, [scene, opacity, renderMode, checklist, wireframeColor, wireframeThickness, edgeThresholdAngle, sceneModel.color]);
const rotXRad = (fineTuning.rotX * Math.PI) / 180;
const rotYRad = (fineTuning.rotY * Math.PI) / 180;
@@ -120,6 +120,8 @@ function XRModel({ url }: { url: string }) {
const scaleRatio = useModelStore((st) => st.scaleRatio);
const renderFactor = scaleRatio?.factor ?? 1;
+ if (!sceneModel.visible) return null;
+
return (
s.models);
+ const activeId = useModelStore((s) => s.activeModelId);
+ return (
+ <>
+ {models.filter(m => m.id !== activeId).map((m) => (
+
+ ))}
+ >
+ );
+}
+
+/** Renders the currently-active model (the one wrapped by grab/placement). */
+function XRActiveModel() {
+ const models = useModelStore((s) => s.models);
+ const activeId = useModelStore((s) => s.activeModelId);
+ const active = models.find(m => m.id === activeId);
+ if (!active) return null;
+ return ;
+}
+
// ─── ControllerFineTuning ──────────────────────────────
// Joystick for slow numeric adjustments. Disabled while any grip is held
// (grab takes priority). Trigger pressure modulates speed: light = fine,
From 306ddef061eba795015459ba77099e1272fdddab Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Thu, 14 May 2026 16:45:43 +0000
Subject: [PATCH 16/18] Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
---
src/pages/XRSession.tsx | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/pages/XRSession.tsx b/src/pages/XRSession.tsx
index 3ffb5f8..f612423 100644
--- a/src/pages/XRSession.tsx
+++ b/src/pages/XRSession.tsx
@@ -533,14 +533,15 @@ const XRSession = () => {
{effectiveInXR ? (
<>
- {/* In XR (or SimXR): grab wrapper → model. Skip hit-test in SimXR mode. */}
+ {/* In XR (or SimXR): grab wrapper → ACTIVE model. Other models render as static background. */}
+
{simXR ? (
{ if (placementMode) setPlacementMode(false); }}
>
-
+
) : (
@@ -556,7 +557,7 @@ const XRSession = () => {
allowScale={allowScale}
onGrabStart={() => { if (placementMode) setPlacementMode(false); }}
>
-
+
)}
@@ -580,9 +581,10 @@ const XRSession = () => {
>
) : (
<>
- {/* Desktop preview (no headset): show model with OrbitControls */}
+ {/* Desktop preview (no headset): show all models with OrbitControls */}
-
+
+
Date: Thu, 14 May 2026 16:45:51 +0000
Subject: [PATCH 17/18] Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
---
src/components/XRHud.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/XRHud.tsx b/src/components/XRHud.tsx
index 30d04a2..cdc9c19 100644
--- a/src/components/XRHud.tsx
+++ b/src/components/XRHud.tsx
@@ -12,6 +12,7 @@ import { InspectionChecklist } from '@/components/InspectionChecklist';
import { ScaleSelector } from '@/components/ScaleSelector';
import { CloudLoader } from '@/components/CloudLoader';
import { ShareButton } from '@/components/ShareButton';
+import { SceneModelList } from '@/components/SceneModelList';
import { toast } from 'sonner';
const POSITION_STEP = 0.001;
From a9ba99e06fc5db417fae7fc9a85c768b8c8ee6f6 Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Thu, 14 May 2026 16:46:07 +0000
Subject: [PATCH 18/18] Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
---
src/components/XRHud.tsx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/components/XRHud.tsx b/src/components/XRHud.tsx
index cdc9c19..5416d11 100644
--- a/src/components/XRHud.tsx
+++ b/src/components/XRHud.tsx
@@ -198,7 +198,10 @@ export function XRHud({ freeMove, onToggleFreeMove, placementMode = false, onTog
{/* Expanded panel */}
{expanded && (
-
+
+ {/* Scene models list */}
+
+
{/* Opacity */}