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
|
url?: string; // legacy, ignored — uses store.models
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Walk up the parent chain until we find a node tagged as `ifcElement`,
|
function isPickableModelMesh(obj: THREE.Object3D): obj is THREE.Mesh {
|
||||||
* or the model root. Returns null if neither found. */
|
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 {
|
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;
|
let cur: THREE.Object3D | null = obj;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
if (cur.userData?.ifcElement) return cur;
|
if (cur.userData?.ifcElement) return cur;
|
||||||
cur = cur.parent;
|
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. */
|
/** 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;
|
mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
||||||
raycaster.setFromCamera(mouse, camera);
|
raycaster.setFromCamera(mouse, camera);
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||||
const hit = intersects.find((i) => {
|
const hit = intersects.find((i) => isPickableModelMesh(i.object));
|
||||||
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;
|
|
||||||
});
|
|
||||||
if (!hit) return;
|
if (!hit) return;
|
||||||
|
|
||||||
|
const element = findElementRoot(hit.object);
|
||||||
let cur: THREE.Object3D | null = hit.object;
|
let cur: THREE.Object3D | null = hit.object;
|
||||||
let element: THREE.Object3D | null = null;
|
|
||||||
let modelId: string | null = null;
|
let modelId: string | null = null;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
if (!element && cur.userData?.ifcElement) element = cur;
|
|
||||||
if (!modelId && cur.userData?.modelId) modelId = cur.userData.modelId as string;
|
if (!modelId && cur.userData?.modelId) modelId = cur.userData.modelId as string;
|
||||||
cur = cur.parent;
|
cur = cur.parent;
|
||||||
}
|
}
|
||||||
if (!element) element = hit.object;
|
|
||||||
if (!modelId) modelId = useModelStore.getState().activeModelId;
|
if (!modelId) modelId = useModelStore.getState().activeModelId;
|
||||||
if (!modelId || !element) return;
|
if (!modelId || !element) return;
|
||||||
const key = elementKey(modelId, element);
|
const key = elementKey(modelId, element);
|
||||||
@@ -759,7 +769,7 @@ function VisibilityApplier() {
|
|||||||
const modelId = root.userData?.modelId as string | undefined;
|
const modelId = root.userData?.modelId as string | undefined;
|
||||||
if (!modelId) return;
|
if (!modelId) return;
|
||||||
root.traverse((el) => {
|
root.traverse((el) => {
|
||||||
if (!el.userData?.ifcElement) return;
|
if (!el.userData?.ifcElement && !(isPickableModelMesh(el) && !hasIfcAncestor(el))) return;
|
||||||
const key = elementKey(modelId, el);
|
const key = elementKey(modelId, el);
|
||||||
const hidden = hiddenElementKeys.has(key);
|
const hidden = hiddenElementKeys.has(key);
|
||||||
const isolated = isolatedElementKeys ? !isolatedElementKeys.has(key) : false;
|
const isolated = isolatedElementKeys ? !isolatedElementKeys.has(key) : false;
|
||||||
@@ -1044,7 +1054,7 @@ export function ModelViewerCanvas({ url }: ModelViewerProps) {
|
|||||||
dampingFactor={0.1}
|
dampingFactor={0.1}
|
||||||
minDistance={0.05}
|
minDistance={0.05}
|
||||||
maxDistance={50}
|
maxDistance={50}
|
||||||
enabled={!positionMode && !selectionMode}
|
enabled={!positionMode}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ export const useModelStore = create<ModelStore>((set, get) => ({
|
|||||||
setSelectionMode: (on) => set((s) => ({
|
setSelectionMode: (on) => set((s) => ({
|
||||||
selectionMode: on,
|
selectionMode: on,
|
||||||
measureMode: on ? false : s.measureMode,
|
measureMode: on ? false : s.measureMode,
|
||||||
positionMode: on ? false : s.positionMode,
|
positionMode: s.positionMode,
|
||||||
selectedElementKeys: on ? s.selectedElementKeys : new Set(),
|
selectedElementKeys: on ? s.selectedElementKeys : new Set(),
|
||||||
})),
|
})),
|
||||||
selectedElementKeys: new Set<string>(),
|
selectedElementKeys: new Set<string>(),
|
||||||
|
|||||||
Reference in New Issue
Block a user