import { MeshInstanceId } from '../engine/model/meshinstance.js'; function IsPathPrefix (parentPath, childPath) { if (parentPath.length === 0) { return childPath.length === 0; } return childPath === parentPath || childPath.startsWith (parentPath + '/'); } export class StepDeletionState { constructor (model) { this.model = model; this.nodeIdToPath = new Map (); this.meshKeyToNodePath = new Map (); this.deletedNodePaths = new Set (); this.BuildIndex (); } BuildIndex () { const rootNode = this.model.GetRootNode (); this.VisitNode (rootNode, ''); } VisitNode (node, nodePath) { this.nodeIdToPath.set (node.GetId (), nodePath); for (let meshIndex of node.GetMeshIndices ()) { let meshInstanceId = new MeshInstanceId (node.GetId (), meshIndex); this.meshKeyToNodePath.set (meshInstanceId.GetKey (), nodePath); } let childNodes = this.GetChildNodesInPathOrder (node); for (let childIndex = 0; childIndex < childNodes.length; childIndex++) { let childNode = childNodes[childIndex]; let childPath = nodePath.length === 0 ? childIndex.toString () : nodePath + '/' + childIndex.toString (); this.VisitNode (childNode, childPath); } } GetChildNodesInPathOrder (node) { let assemblyNodes = []; let leafPartNodes = []; for (let childNode of node.GetChildNodes ()) { if (childNode.IsMeshNode ()) { leafPartNodes.push (childNode); } else { assemblyNodes.push (childNode); } } return assemblyNodes.concat (leafPartNodes); } GetNodePath (nodeId) { return this.nodeIdToPath.get (nodeId); } GetMeshNodePath (meshInstanceId) { return this.meshKeyToNodePath.get (meshInstanceId.GetKey ()); } CanDeleteNode (nodeId) { let nodePath = this.GetNodePath (nodeId); return nodePath !== undefined && nodePath !== null && nodePath.length > 0; } DeleteNodePath (nodePath) { if (nodePath === undefined || nodePath === null || nodePath.length === 0) { return; } let nextDeleted = new Set (); for (let existingPath of this.deletedNodePaths) { if (IsPathPrefix (existingPath, nodePath)) { return; } if (IsPathPrefix (nodePath, existingPath)) { continue; } nextDeleted.add (existingPath); } nextDeleted.add (nodePath); this.deletedNodePaths = nextDeleted; } DeleteNodeById (nodeId) { this.DeleteNodePath (this.GetNodePath (nodeId)); } DeleteMeshNode (meshInstanceId) { this.DeleteNodePath (this.GetMeshNodePath (meshInstanceId)); } IsNodeDeletedByPath (nodePath) { for (let deletedPath of this.deletedNodePaths) { if (IsPathPrefix (deletedPath, nodePath)) { return true; } } return false; } GetDeletedNodePaths () { return Array.from (this.deletedNodePaths.values ()).sort (); } }