Some checks failed
Build / build (18.x, macos-latest) (push) Has been cancelled
Build / build (18.x, ubuntu-latest) (push) Has been cancelled
Build / build (18.x, windows-latest) (push) Has been cancelled
Build / build (20.x, macos-latest) (push) Has been cancelled
Build / build (20.x, ubuntu-latest) (push) Has been cancelled
Build / build (20.x, windows-latest) (push) Has been cancelled
119 lines
3.2 KiB
JavaScript
119 lines
3.2 KiB
JavaScript
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 ();
|
|
}
|
|
}
|