From 09e74f17f5305f4994adb63e3569a70dcf92fe4d Mon Sep 17 00:00:00 2001 From: Marcos Reifonas Date: Mon, 21 Sep 2026 19:06:39 +0000 Subject: [PATCH] feat(viewer3d): solido translucido atenuado para pecas nao apontadas e remocao de aramado --- src/components/viewer3d/ModelViewer3D.tsx | 122 +++++--------------- src/components/viewer3d/Viewer3DSidebar.tsx | 27 +---- 2 files changed, 34 insertions(+), 115 deletions(-) diff --git a/src/components/viewer3d/ModelViewer3D.tsx b/src/components/viewer3d/ModelViewer3D.tsx index 8a0c7eb..e72c8ca 100644 --- a/src/components/viewer3d/ModelViewer3D.tsx +++ b/src/components/viewer3d/ModelViewer3D.tsx @@ -50,7 +50,6 @@ export const ModelViewer3D: React.FC = ({ const [opacity, setOpacity] = useState(100); const [showGrid, setShowGrid] = useState(true); const [isOrthographic, setIsOrthographic] = useState(false); - const [isWireframe, setIsWireframe] = useState(false); const [colorMode, setColorMode] = useState<'description' | 'production'>('production'); const [selectedProcess, setSelectedProcess] = useState('all'); @@ -429,50 +428,32 @@ export const ModelViewer3D: React.FC = ({ else isPointedInThisProcess = Boolean(procPointedMap[targetProcKey] > 0 || procsDone.includes(targetProcKey)); if (isPointedInThisProcess) { - // SÓLIDO COM A COR DO PROCESSO SELECIONADO + // SÓLIDO COM A COR DO PROCESSO SELECIONADO (OPACO 100%) mesh.material = new THREE.MeshStandardMaterial({ color: new THREE.Color(targetColorHex), metalness: 0.35, roughness: 0.45, transparent: opacity < 100, opacity: opacity / 100, + depthWrite: true, side: THREE.DoubleSide, }); if (mesh.userData.edgesLine) { mesh.userData.edgesLine.visible = false; } } else { - // ARAMADO FANTASMA CINZA CLARO ULTRA-SUAVE (5% de opacidade) - if (!mesh.userData.edgesLine) { - const edgesGeo = new THREE.EdgesGeometry(mesh.geometry, 24); - const lineMat = new THREE.LineBasicMaterial({ - color: 0x94a3b8, // Cinza claro industrial - transparent: true, - opacity: 0.05, // 5% de opacidade - }); - const edgesLine = new THREE.LineSegments(edgesGeo, lineMat); - mesh.userData.edgesLine = edgesLine; - mesh.add(edgesLine); - } else { - if (mesh.userData.edgesLine.material) { - mesh.userData.edgesLine.material.color.set(0x94a3b8); - mesh.userData.edgesLine.material.transparent = true; - mesh.userData.edgesLine.material.opacity = 0.05; - } - } - mesh.userData.edgesLine.visible = true; - - // Mantém material ativo para Raycaster mas 100% translúcido visualmente - if (Array.isArray(mesh.material)) { - mesh.material.forEach((m) => { - m.visible = true; - m.transparent = true; - m.opacity = 0.001; - }); - } else if (mesh.material) { - mesh.material.visible = true; - mesh.material.transparent = true; - mesh.material.opacity = 0.001; + // SÓLIDO TRANSLÚCIDO ATENUADO (Ghost Solid volumétrico a 8% - sem linhas de aramado) + mesh.material = new THREE.MeshStandardMaterial({ + color: new THREE.Color('#94a3b8'), // Cinza industrial translúcido + metalness: 0.1, + roughness: 0.8, + transparent: true, + opacity: 0.08, // 8% de opacidade volumétrica suave + depthWrite: false, + side: THREE.DoubleSide, + }); + if (mesh.userData.edgesLine) { + mesh.userData.edgesLine.visible = false; } } } else { @@ -502,6 +483,7 @@ export const ModelViewer3D: React.FC = ({ roughness: 0.45, transparent: opacity < 100, opacity: opacity / 100, + depthWrite: true, side: THREE.DoubleSide, }); @@ -509,37 +491,19 @@ export const ModelViewer3D: React.FC = ({ mesh.userData.edgesLine.visible = false; } } else { - // A PEÇA NÃO TEM NENHUM APONTAMENTO: ARAMADO FANTASMA CINZA CLARO A 5% (ATENUADA) - if (!mesh.userData.edgesLine) { - const edgesGeo = new THREE.EdgesGeometry(mesh.geometry, 24); - const lineMat = new THREE.LineBasicMaterial({ - color: 0x94a3b8, - transparent: true, - opacity: 0.05, - }); - const edgesLine = new THREE.LineSegments(edgesGeo, lineMat); - mesh.userData.edgesLine = edgesLine; - mesh.add(edgesLine); - } else { - if (mesh.userData.edgesLine.material) { - mesh.userData.edgesLine.material.color.set(0x94a3b8); - mesh.userData.edgesLine.material.transparent = true; - mesh.userData.edgesLine.material.opacity = 0.05; - } - } - mesh.userData.edgesLine.visible = true; + // A PEÇA NÃO TEM NENHUM APONTAMENTO: SÓLIDO TRANSLÚCIDO ATENUADO (Ghost Solid a 8%) + mesh.material = new THREE.MeshStandardMaterial({ + color: new THREE.Color('#94a3b8'), + metalness: 0.1, + roughness: 0.8, + transparent: true, + opacity: 0.08, + depthWrite: false, + side: THREE.DoubleSide, + }); - // Material ativo para Raycaster mas translúcido - if (Array.isArray(mesh.material)) { - mesh.material.forEach((m) => { - m.visible = true; - m.transparent = true; - m.opacity = 0.001; - }); - } else if (mesh.material) { - mesh.material.visible = true; - mesh.material.transparent = true; - mesh.material.opacity = 0.001; + if (mesh.userData.edgesLine) { + mesh.userData.edgesLine.visible = false; } } } else { @@ -550,6 +514,7 @@ export const ModelViewer3D: React.FC = ({ roughness: 0.65, transparent: opacity < 100, opacity: opacity / 100, + depthWrite: true, side: THREE.DoubleSide, }); if (mesh.userData.edgesLine) { @@ -557,33 +522,6 @@ export const ModelViewer3D: React.FC = ({ } } } - - // Controle de Aramado Geral (Botão Sólido / Aramado) - if (isWireframe) { - if (!mesh.userData.edgesLine) { - const edgesGeo = new THREE.EdgesGeometry(mesh.geometry, 24); - const lineMat = new THREE.LineBasicMaterial({ - color: 0x94a3b8, // Cinza claro industrial idêntico às peças não apontadas - transparent: true, - opacity: 0.85, - }); - const edgesLine = new THREE.LineSegments(edgesGeo, lineMat); - mesh.userData.edgesLine = edgesLine; - mesh.add(edgesLine); - } else { - if (mesh.userData.edgesLine.material) { - mesh.userData.edgesLine.material.color.set(0x94a3b8); - mesh.userData.edgesLine.material.opacity = 0.85; - } - } - mesh.userData.edgesLine.visible = true; - - if (Array.isArray(mesh.material)) { - mesh.material.forEach((m) => { m.visible = false; }); - } else if (mesh.material) { - mesh.material.visible = false; - } - } } }); @@ -605,7 +543,7 @@ export const ModelViewer3D: React.FC = ({ ); } } - }, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, isWireframe, selectedProcess]); + }, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, selectedProcess]); // Camera Toggle (Ortogonal / Perspectiva) const handleToggleCamera = useCallback(() => { @@ -815,8 +753,6 @@ export const ModelViewer3D: React.FC = ({ }} isOrthographic={isOrthographic} onToggleCamera={handleToggleCamera} - isWireframe={isWireframe} - onToggleWireframe={() => setIsWireframe(!isWireframe)} colorMode={colorMode} onColorModeChange={setColorMode} selectedProcess={selectedProcess} diff --git a/src/components/viewer3d/Viewer3DSidebar.tsx b/src/components/viewer3d/Viewer3DSidebar.tsx index f49c1f7..a42b775 100644 --- a/src/components/viewer3d/Viewer3DSidebar.tsx +++ b/src/components/viewer3d/Viewer3DSidebar.tsx @@ -26,8 +26,6 @@ interface Viewer3DSidebarProps { onToggleGrid: () => void; isOrthographic: boolean; onToggleCamera: () => void; - isWireframe: boolean; - onToggleWireframe: () => void; colorMode: 'description' | 'production'; onColorModeChange: (mode: 'description' | 'production') => void; selectedProcess?: string; @@ -52,8 +50,6 @@ export const Viewer3DSidebar: React.FC = ({ onToggleGrid, isOrthographic, onToggleCamera, - isWireframe, - onToggleWireframe, colorMode, onColorModeChange, selectedProcess = 'all', @@ -166,37 +162,24 @@ export const Viewer3DSidebar: React.FC = ({ - {/* Grupo 3: Visibilidade & Grade */} + {/* Grupo 3: Ambiente & Grade */}
-
+
{/* Toggle Grid */} - - {/* Sólido / Aramado */} -