From b947a7bc808baaf0ab118dfdd723d553e993a9b7 Mon Sep 17 00:00:00 2001 From: Marcos Reifonas Date: Mon, 21 Sep 2026 01:53:22 +0000 Subject: [PATCH] fix(viewer3d): fix process filtering dependency reactivity and multi-process matching in ModelViewer3D --- src/components/viewer3d/ModelViewer3D.tsx | 26 ++++++++++++----------- src/pages/Visualizador3D.tsx | 11 +++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/components/viewer3d/ModelViewer3D.tsx b/src/components/viewer3d/ModelViewer3D.tsx index 9d18f6f..66d4b39 100644 --- a/src/components/viewer3d/ModelViewer3D.tsx +++ b/src/components/viewer3d/ModelViewer3D.tsx @@ -311,9 +311,9 @@ export const ModelViewer3D: React.FC = ({ } // 2. Determinação do vínculo de produção (com matching rigoroso de fase) - let prod: ProductionPieceStatus | undefined = undefined; + let prod: any = undefined; - if (colorMode === 'production' && productionData && productionData.size > 0) { + if (productionData && productionData.size > 0) { const searchKeys = [ elementPhase && selectedOF ? `${selectedOF}-${elementPhase}-${cleanAssMark}` : '', elementPhase ? `${elementPhase}-${cleanAssMark}` : '', @@ -327,7 +327,6 @@ export const ModelViewer3D: React.FC = ({ for (const key of searchKeys) { const match = productionData.get(key); - // Se encontramos, mas ele tem fase e nós temos fase, elas precisam bater. if (match) { if (!elementPhase || !match.fase || String(match.fase) === String(elementPhase)) { prod = match; @@ -335,9 +334,6 @@ export const ModelViewer3D: React.FC = ({ } } } - - // Fallback para perfis / bitolas removido para evitar falsos positivos - // Peças genéricas (como diagonais sem marca) não devem herdar apontamento de outras peças com o mesmo perfil. } // 3. Controle Estrito de Visibilidade por Fase @@ -363,16 +359,19 @@ export const ModelViewer3D: React.FC = ({ 'expedição': 5, }; - const targetProcKey = selectedProcess.toLowerCase(); + const targetProcKey = String(selectedProcess || 'all').toLowerCase(); const targetOrder = PROCESS_ORDER_MAP[targetProcKey] || 0; let isPointedInTargetProcess = false; if (selectedProcess !== 'all' && prod && prod.pointedQtd > 0) { - const pieceProcOrder = prod.processOrdem || 1; - const pieceProcName = (prod.currentProcessName || '').toLowerCase(); + const pieceProcOrder = Number(prod.processOrdem || 0); + const pieceProcName = String(prod.currentProcessName || '').toLowerCase(); + const procsDone: string[] = Array.isArray(prod.processesCompleted) ? prod.processesCompleted : []; + isPointedInTargetProcess = - pieceProcOrder >= targetOrder || - pieceProcName.includes(targetProcKey); + procsDone.some((p: string) => p.includes(targetProcKey)) || + pieceProcName.includes(targetProcKey) || + (targetOrder > 0 && pieceProcOrder >= targetOrder); } // 5. Aplicação de Cores / Materiais (Sólido vs Aramado Híbrido) @@ -518,6 +517,9 @@ export const ModelViewer3D: React.FC = ({ if (selectedPhase && selectedPhase !== 'all') { console.log(`[Viewer3D] Filtrando modelo 3D pela Fase: "${selectedPhase}"`); } + if (selectedProcess && selectedProcess !== 'all') { + console.log(`[Viewer3D] Modo Híbrido Ativo: Destacando Processo "${selectedProcess}" em Verde Sólido + Aramado Fantasma Cinza`); + } if (totalMeshCount > 0 && productionData && productionData.size > 0) { console.log( @@ -530,7 +532,7 @@ export const ModelViewer3D: React.FC = ({ ); } } - }, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, isWireframe]); + }, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, isWireframe, selectedProcess]); // Camera Toggle (Ortogonal / Perspectiva) const handleToggleCamera = useCallback(() => { diff --git a/src/pages/Visualizador3D.tsx b/src/pages/Visualizador3D.tsx index f447d60..4356d7f 100644 --- a/src/pages/Visualizador3D.tsx +++ b/src/pages/Visualizador3D.tsx @@ -148,6 +148,7 @@ export default function Visualizador3D() { currentProcessName: 'Pendente', processColor: '#64748b', processOrdem: 0, + processesCompleted: [] as string[], }; uniqueItems.push(item); @@ -189,9 +190,13 @@ export default function Visualizador3D() { const qty = Number(ap.quantidade_produzida || 0); if (qty > 0) { existing.pointedQtd = Math.max(existing.pointedQtd, qty); - existing.currentProcessName = ap.processo?.nome || existing.currentProcessName; - existing.processColor = ap.processo?.cor || PROCESS_COLORS[ap.processo?.nome || ''] || '#10b981'; - existing.processOrdem = ap.processo?.ordem || existing.processOrdem; + const procNome = String(ap.processo?.nome || '').trim(); + if (procNome && !existing.processesCompleted.includes(procNome.toLowerCase())) { + existing.processesCompleted.push(procNome.toLowerCase()); + } + existing.currentProcessName = procNome || existing.currentProcessName; + existing.processColor = ap.processo?.cor || PROCESS_COLORS[procNome] || '#10b981'; + existing.processOrdem = Math.max(existing.processOrdem, Number(ap.processo?.ordem || 0)); } } }