fix(viewer3d): fix process filtering dependency reactivity and multi-process matching in ModelViewer3D

This commit is contained in:
2026-09-21 01:53:22 +00:00
parent 3882e8c338
commit b947a7bc80
2 changed files with 22 additions and 15 deletions
+14 -12
View File
@@ -311,9 +311,9 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
} }
// 2. Determinação do vínculo de produção (com matching rigoroso de fase) // 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 = [ const searchKeys = [
elementPhase && selectedOF ? `${selectedOF}-${elementPhase}-${cleanAssMark}` : '', elementPhase && selectedOF ? `${selectedOF}-${elementPhase}-${cleanAssMark}` : '',
elementPhase ? `${elementPhase}-${cleanAssMark}` : '', elementPhase ? `${elementPhase}-${cleanAssMark}` : '',
@@ -327,7 +327,6 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
for (const key of searchKeys) { for (const key of searchKeys) {
const match = productionData.get(key); const match = productionData.get(key);
// Se encontramos, mas ele tem fase e nós temos fase, elas precisam bater.
if (match) { if (match) {
if (!elementPhase || !match.fase || String(match.fase) === String(elementPhase)) { if (!elementPhase || !match.fase || String(match.fase) === String(elementPhase)) {
prod = match; prod = match;
@@ -335,9 +334,6 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
} }
} }
} }
// 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 // 3. Controle Estrito de Visibilidade por Fase
@@ -363,16 +359,19 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
'expedição': 5, 'expedição': 5,
}; };
const targetProcKey = selectedProcess.toLowerCase(); const targetProcKey = String(selectedProcess || 'all').toLowerCase();
const targetOrder = PROCESS_ORDER_MAP[targetProcKey] || 0; const targetOrder = PROCESS_ORDER_MAP[targetProcKey] || 0;
let isPointedInTargetProcess = false; let isPointedInTargetProcess = false;
if (selectedProcess !== 'all' && prod && prod.pointedQtd > 0) { if (selectedProcess !== 'all' && prod && prod.pointedQtd > 0) {
const pieceProcOrder = prod.processOrdem || 1; const pieceProcOrder = Number(prod.processOrdem || 0);
const pieceProcName = (prod.currentProcessName || '').toLowerCase(); const pieceProcName = String(prod.currentProcessName || '').toLowerCase();
const procsDone: string[] = Array.isArray(prod.processesCompleted) ? prod.processesCompleted : [];
isPointedInTargetProcess = isPointedInTargetProcess =
pieceProcOrder >= targetOrder || procsDone.some((p: string) => p.includes(targetProcKey)) ||
pieceProcName.includes(targetProcKey); pieceProcName.includes(targetProcKey) ||
(targetOrder > 0 && pieceProcOrder >= targetOrder);
} }
// 5. Aplicação de Cores / Materiais (Sólido vs Aramado Híbrido) // 5. Aplicação de Cores / Materiais (Sólido vs Aramado Híbrido)
@@ -518,6 +517,9 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
if (selectedPhase && selectedPhase !== 'all') { if (selectedPhase && selectedPhase !== 'all') {
console.log(`[Viewer3D] Filtrando modelo 3D pela Fase: "${selectedPhase}"`); 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) { if (totalMeshCount > 0 && productionData && productionData.size > 0) {
console.log( console.log(
@@ -530,7 +532,7 @@ export const ModelViewer3D: React.FC<ModelViewer3DProps> = ({
); );
} }
} }
}, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, isWireframe]); }, [modelData, colorMode, productionData, selectedPhase, selectedOF, opacity, isWireframe, selectedProcess]);
// Camera Toggle (Ortogonal / Perspectiva) // Camera Toggle (Ortogonal / Perspectiva)
const handleToggleCamera = useCallback(() => { const handleToggleCamera = useCallback(() => {
+8 -3
View File
@@ -148,6 +148,7 @@ export default function Visualizador3D() {
currentProcessName: 'Pendente', currentProcessName: 'Pendente',
processColor: '#64748b', processColor: '#64748b',
processOrdem: 0, processOrdem: 0,
processesCompleted: [] as string[],
}; };
uniqueItems.push(item); uniqueItems.push(item);
@@ -189,9 +190,13 @@ export default function Visualizador3D() {
const qty = Number(ap.quantidade_produzida || 0); const qty = Number(ap.quantidade_produzida || 0);
if (qty > 0) { if (qty > 0) {
existing.pointedQtd = Math.max(existing.pointedQtd, qty); existing.pointedQtd = Math.max(existing.pointedQtd, qty);
existing.currentProcessName = ap.processo?.nome || existing.currentProcessName; const procNome = String(ap.processo?.nome || '').trim();
existing.processColor = ap.processo?.cor || PROCESS_COLORS[ap.processo?.nome || ''] || '#10b981'; if (procNome && !existing.processesCompleted.includes(procNome.toLowerCase())) {
existing.processOrdem = ap.processo?.ordem || existing.processOrdem; 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));
} }
} }
} }