Corrigiu seleção de chapas e bloqueio
X-Lovable-Edit-ID: edt-1984935b-5500-4f44-84a9-a0d5f5eeb8db Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -10,15 +10,35 @@ interface ModelViewerProps {
|
||||
url?: string; // legacy, ignored — uses store.models
|
||||
}
|
||||
|
||||
/** Walk up the parent chain until we find a node tagged as `ifcElement`,
|
||||
* or the model root. Returns null if neither found. */
|
||||
function isPickableModelMesh(obj: THREE.Object3D): obj is THREE.Mesh {
|
||||
if (!(obj instanceof THREE.Mesh)) return false;
|
||||
if (obj.userData.__edgeLine) return false;
|
||||
if (obj.geometry instanceof THREE.SphereGeometry) return false;
|
||||
if (obj.geometry instanceof THREE.RingGeometry) return false;
|
||||
if (obj.geometry instanceof THREE.PlaneGeometry) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Walk up the parent chain until we find a node tagged as `ifcElement`.
|
||||
* Falls back to the clicked mesh so older/demo GLBs without IFC metadata
|
||||
* still support selection/highlight. */
|
||||
export function findElementRoot(obj: THREE.Object3D | null): THREE.Object3D | null {
|
||||
const fallback = isPickableModelMesh(obj as THREE.Object3D) ? obj : null;
|
||||
let cur: THREE.Object3D | null = obj;
|
||||
while (cur) {
|
||||
if (cur.userData?.ifcElement) return cur;
|
||||
cur = cur.parent;
|
||||
}
|
||||
return null;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function hasIfcAncestor(obj: THREE.Object3D): boolean {
|
||||
let cur = obj.parent;
|
||||
while (cur) {
|
||||
if (cur.userData?.ifcElement) return true;
|
||||
cur = cur.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Stable key for an element across reloads: prefers ifcId, falls back to name. */
|
||||
@@ -703,26 +723,16 @@ function SelectionHandler() {
|
||||
mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
||||
raycaster.setFromCamera(mouse, camera);
|
||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||
const hit = intersects.find((i) => {
|
||||
const o = i.object;
|
||||
if (!(o instanceof THREE.Mesh)) return false;
|
||||
if (o.userData.__edgeLine) return false;
|
||||
if (o.geometry instanceof THREE.SphereGeometry) return false;
|
||||
if (o.geometry instanceof THREE.RingGeometry) return false;
|
||||
if (o.geometry instanceof THREE.PlaneGeometry) return false;
|
||||
return true;
|
||||
});
|
||||
const hit = intersects.find((i) => isPickableModelMesh(i.object));
|
||||
if (!hit) return;
|
||||
|
||||
const element = findElementRoot(hit.object);
|
||||
let cur: THREE.Object3D | null = hit.object;
|
||||
let element: THREE.Object3D | null = null;
|
||||
let modelId: string | null = null;
|
||||
while (cur) {
|
||||
if (!element && cur.userData?.ifcElement) element = cur;
|
||||
if (!modelId && cur.userData?.modelId) modelId = cur.userData.modelId as string;
|
||||
cur = cur.parent;
|
||||
}
|
||||
if (!element) element = hit.object;
|
||||
if (!modelId) modelId = useModelStore.getState().activeModelId;
|
||||
if (!modelId || !element) return;
|
||||
const key = elementKey(modelId, element);
|
||||
@@ -759,7 +769,7 @@ function VisibilityApplier() {
|
||||
const modelId = root.userData?.modelId as string | undefined;
|
||||
if (!modelId) return;
|
||||
root.traverse((el) => {
|
||||
if (!el.userData?.ifcElement) return;
|
||||
if (!el.userData?.ifcElement && !(isPickableModelMesh(el) && !hasIfcAncestor(el))) return;
|
||||
const key = elementKey(modelId, el);
|
||||
const hidden = hiddenElementKeys.has(key);
|
||||
const isolated = isolatedElementKeys ? !isolatedElementKeys.has(key) : false;
|
||||
@@ -1044,7 +1054,7 @@ export function ModelViewerCanvas({ url }: ModelViewerProps) {
|
||||
dampingFactor={0.1}
|
||||
minDistance={0.05}
|
||||
maxDistance={50}
|
||||
enabled={!positionMode && !selectionMode}
|
||||
enabled={!positionMode}
|
||||
/>
|
||||
|
||||
</Canvas>
|
||||
|
||||
@@ -514,7 +514,7 @@ export const useModelStore = create<ModelStore>((set, get) => ({
|
||||
setSelectionMode: (on) => set((s) => ({
|
||||
selectionMode: on,
|
||||
measureMode: on ? false : s.measureMode,
|
||||
positionMode: on ? false : s.positionMode,
|
||||
positionMode: s.positionMode,
|
||||
selectedElementKeys: on ? s.selectedElementKeys : new Set(),
|
||||
})),
|
||||
selectedElementKeys: new Set<string>(),
|
||||
|
||||
Reference in New Issue
Block a user