diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index a7ad651..81200d6 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -714,7 +714,6 @@ function SelectionHandler() { }); if (!hit) return; - // Walk up to find ifcElement node AND the GLBModel root (carrying modelId) let cur: THREE.Object3D | null = hit.object; let element: THREE.Object3D | null = null; let modelId: string | null = null; @@ -723,7 +722,6 @@ function SelectionHandler() { if (!modelId && cur.userData?.modelId) modelId = cur.userData.modelId as string; cur = cur.parent; } - // Non-IFC fallback: pick the mesh itself if (!element) element = hit.object; if (!modelId) modelId = useModelStore.getState().activeModelId; if (!modelId || !element) return; @@ -760,7 +758,6 @@ function VisibilityApplier() { scene.traverse((root) => { const modelId = root.userData?.modelId as string | undefined; if (!modelId) return; - // For each ifcElement descendant inside this model root root.traverse((el) => { if (!el.userData?.ifcElement) return; const key = elementKey(modelId, el); @@ -771,24 +768,26 @@ function VisibilityApplier() { const selected = selectedElementKeys.has(key); el.traverse((m) => { if (!(m instanceof THREE.Mesh)) return; - const mats = Array.isArray(m.material) ? m.material : [m.material]; - mats.forEach((mat) => { - if (!(mat instanceof THREE.MeshStandardMaterial)) return; - if (selected) { - if (m.userData.__origEmissive === undefined) { - m.userData.__origEmissive = mat.emissive.getHex(); - m.userData.__origEmissiveIntensity = mat.emissiveIntensity; + if (selected) { + if (!m.userData.__origMaterial) { + m.userData.__origMaterial = m.material; + const src = Array.isArray(m.material) ? m.material[0] : m.material; + const cloned = (src as THREE.Material).clone() as THREE.MeshStandardMaterial; + if (cloned instanceof THREE.MeshStandardMaterial) { + cloned.color.set('#f59e0b'); + cloned.emissive.set('#f59e0b'); + cloned.emissiveIntensity = 0.8; + cloned.needsUpdate = true; } - mat.emissive.set('#f59e0b'); - mat.emissiveIntensity = 0.6; - } else if (m.userData.__origEmissive !== undefined) { - mat.emissive.setHex(m.userData.__origEmissive as number); - mat.emissiveIntensity = (m.userData.__origEmissiveIntensity as number) ?? 0; - delete m.userData.__origEmissive; - delete m.userData.__origEmissiveIntensity; + m.material = cloned; } - mat.needsUpdate = true; - }); + } else if (m.userData.__origMaterial) { + // Dispose the cloned highlight material + const cur = Array.isArray(m.material) ? m.material[0] : m.material; + (cur as THREE.Material)?.dispose?.(); + m.material = m.userData.__origMaterial as THREE.Material; + delete m.userData.__origMaterial; + } }); }); });