ModelHandle/source/website/stepdeletionstate.js
sladro 16a2e43649
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
fix step save flow and add portable backend runtime support
2026-04-13 15:16:30 +08:00

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 ();
}
}