diff --git a/packages/editor/src/components/editor/floating-action-menu.tsx b/packages/editor/src/components/editor/floating-action-menu.tsx index 1f6a6280..0f4cdbc8 100755 --- a/packages/editor/src/components/editor/floating-action-menu.tsx +++ b/packages/editor/src/components/editor/floating-action-menu.tsx @@ -147,6 +147,7 @@ export function FloatingActionMenu() { duplicate.start = [duplicate.start[0] + 1, duplicate.start[1] + 1] duplicate.end = [duplicate.end[0] + 1, duplicate.end[1] + 1] } else if (node.type === 'roof') { + duplicateInfo.children = [] duplicate = RoofNode.parse(duplicateInfo) } else if (node.type === 'roof-segment') { duplicate = RoofSegmentNode.parse(duplicateInfo) @@ -160,6 +161,12 @@ export function FloatingActionMenu() { } } catch (error) { console.error('Failed to parse duplicate', error) + useScene.temporal.getState().resume() + return + } + + if (!duplicate) { + useScene.temporal.getState().resume() return } diff --git a/packages/editor/src/components/editor/selection-manager.tsx b/packages/editor/src/components/editor/selection-manager.tsx index a4b74934..3d9ef80a 100755 --- a/packages/editor/src/components/editor/selection-manager.tsx +++ b/packages/editor/src/components/editor/selection-manager.tsx @@ -920,13 +920,13 @@ const EditorOutlinerSync = () => { outliner.selectedObjects.length = 0 for (const id of idsToHighlight) { const obj = sceneRegistry.nodes.get(id) - if (obj) outliner.selectedObjects.push(obj) + if (obj?.parent) outliner.selectedObjects.push(obj) } outliner.hoveredObjects.length = 0 if (hoveredId) { const obj = sceneRegistry.nodes.get(hoveredId) - if (obj) outliner.hoveredObjects.push(obj) + if (obj?.parent) outliner.hoveredObjects.push(obj) } }, [phase, previewSelectedIds, selection, hoveredId, outliner]) diff --git a/packages/viewer/src/lib/merged-outline-node.ts b/packages/viewer/src/lib/merged-outline-node.ts index 440535d1..f3617b35 100644 --- a/packages/viewer/src/lib/merged-outline-node.ts +++ b/packages/viewer/src/lib/merged-outline-node.ts @@ -600,9 +600,14 @@ export class MergedOutlineNode extends TempNode { private _buildCache(objects: Object3D[], cache: Set) { for (const obj of objects) { - obj.traverse((child: any) => { - if (child.isMesh || child.isSprite) cache.add(child) - }) + if (!obj || !obj.traverse) continue + try { + obj.traverse((child: any) => { + if (child.isMesh || child.isSprite) cache.add(child) + }) + } catch { + // Skip objects that were disposed or removed from the scene graph + } } } }