@shapediver/viewer.shared.node-tree 3.3.4 → 3.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -7
- package/src/implementation/AbstractTreeNodeData.ts +0 -76
- package/src/implementation/Tree.ts +0 -129
- package/src/implementation/TreeNode.ts +0 -418
- package/src/index.ts +0 -18
- package/src/interfaces/ITree.ts +0 -55
- package/src/interfaces/ITreeNode.ts +0 -233
- package/src/interfaces/ITreeNodeData.ts +0 -37
- package/tsconfig.json +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapediver/viewer.shared.node-tree",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "Michael Oppitz <michael@shapediver.com>",
|
|
@@ -10,11 +10,10 @@
|
|
|
10
10
|
"test": "__tests__"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"dist",
|
|
14
|
-
"src",
|
|
15
13
|
"package.json",
|
|
14
|
+
"dist/",
|
|
16
15
|
"README.md",
|
|
17
|
-
"
|
|
16
|
+
"LICENSE"
|
|
18
17
|
],
|
|
19
18
|
"publishConfig": {
|
|
20
19
|
"access": "public"
|
|
@@ -39,9 +38,9 @@
|
|
|
39
38
|
"testEnvironment": "node"
|
|
40
39
|
},
|
|
41
40
|
"dependencies": {
|
|
42
|
-
"@shapediver/viewer.shared.math": "3.3.
|
|
43
|
-
"@shapediver/viewer.shared.services": "3.3.
|
|
41
|
+
"@shapediver/viewer.shared.math": "3.3.6",
|
|
42
|
+
"@shapediver/viewer.shared.services": "3.3.6",
|
|
44
43
|
"gl-matrix": "3.3.0"
|
|
45
44
|
},
|
|
46
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "13aea937b128a001e6e93be300674c4a04624c29"
|
|
47
46
|
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { ITreeNodeData } from '../interfaces/ITreeNodeData';
|
|
2
|
-
import { UuidGenerator } from '@shapediver/viewer.shared.services';
|
|
3
|
-
|
|
4
|
-
export abstract class AbstractTreeNodeData implements ITreeNodeData {
|
|
5
|
-
// #region Properties (5)
|
|
6
|
-
|
|
7
|
-
readonly #id: string;
|
|
8
|
-
readonly #uuidGenerator: UuidGenerator = UuidGenerator.instance;
|
|
9
|
-
|
|
10
|
-
#convertedObject: { [key: string]: unknown } = {};
|
|
11
|
-
#updateCallbackConvertedObject: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null = null;
|
|
12
|
-
#version: string;
|
|
13
|
-
|
|
14
|
-
// #endregion Properties (5)
|
|
15
|
-
|
|
16
|
-
// #region Constructors (1)
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a tree node data object.
|
|
20
|
-
*
|
|
21
|
-
* @param id Id of this data object
|
|
22
|
-
*/
|
|
23
|
-
constructor(id?: string, version?: string) {
|
|
24
|
-
this.#id = id || this.#uuidGenerator.create();
|
|
25
|
-
this.#version = version || this.#uuidGenerator.create();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// #endregion Constructors (1)
|
|
29
|
-
|
|
30
|
-
// #region Public Getters And Setters (6)
|
|
31
|
-
|
|
32
|
-
public get convertedObject(): { [key: string]: unknown } {
|
|
33
|
-
return this.#convertedObject;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public set convertedObject(value: { [key: string]: unknown }) {
|
|
37
|
-
this.#convertedObject = value;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public get id(): string {
|
|
41
|
-
return this.#id;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public get updateCallbackConvertedObject(): ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null {
|
|
45
|
-
return this.#updateCallbackConvertedObject;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public set updateCallbackConvertedObject(value: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null) {
|
|
49
|
-
this.#updateCallbackConvertedObject = value;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public get version(): string {
|
|
53
|
-
return this.#version;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// #endregion Public Getters And Setters (6)
|
|
57
|
-
|
|
58
|
-
// #region Public Methods (2)
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Clones the tree node data.
|
|
62
|
-
*/
|
|
63
|
-
public clone(): ITreeNodeData {
|
|
64
|
-
const clone = new (this.constructor as new () => ITreeNodeData)();
|
|
65
|
-
return clone;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Update the version
|
|
70
|
-
*/
|
|
71
|
-
public updateVersion(): void {
|
|
72
|
-
this.#version = this.#uuidGenerator.create();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// #endregion Public Methods (2)
|
|
76
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { ITree } from '../interfaces/ITree';
|
|
2
|
-
import { ITreeNode } from '../interfaces/ITreeNode';
|
|
3
|
-
import { TreeNode } from './TreeNode';
|
|
4
|
-
|
|
5
|
-
export class Tree implements ITree {
|
|
6
|
-
// #region Properties (2)
|
|
7
|
-
|
|
8
|
-
readonly #root: ITreeNode;
|
|
9
|
-
|
|
10
|
-
private static _instance: Tree;
|
|
11
|
-
|
|
12
|
-
// #endregion Properties (2)
|
|
13
|
-
|
|
14
|
-
// #region Constructors (1)
|
|
15
|
-
|
|
16
|
-
private constructor() {
|
|
17
|
-
this.#root = new TreeNode('root');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// #endregion Constructors (1)
|
|
21
|
-
|
|
22
|
-
// #region Public Static Getters And Setters (1)
|
|
23
|
-
|
|
24
|
-
public static get instance() {
|
|
25
|
-
return this._instance || (this._instance = new this());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// #endregion Public Static Getters And Setters (1)
|
|
29
|
-
|
|
30
|
-
// #region Public Getters And Setters (1)
|
|
31
|
-
|
|
32
|
-
public get root(): ITreeNode {
|
|
33
|
-
return this.#root;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// #endregion Public Getters And Setters (1)
|
|
37
|
-
|
|
38
|
-
// #region Public Methods (5)
|
|
39
|
-
|
|
40
|
-
public addNode(node: ITreeNode, parent: ITreeNode = this.#root, root: ITreeNode = this.#root): boolean {
|
|
41
|
-
if (root === parent) {
|
|
42
|
-
root.addChild(node);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
for (let i = 0; i < root.children.length; i++) {
|
|
47
|
-
const child = root.children[i];
|
|
48
|
-
if (child && this.addNode(node, parent, child)) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
public addNodeAtPath(node: ITreeNode, path: string = this.root.getPath(), root: ITreeNode = this.#root): boolean {
|
|
56
|
-
if (root.name === path) {
|
|
57
|
-
root.addChild(node);
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const pathStart = path.substr(0, path.indexOf('.'));
|
|
62
|
-
if (root.name === pathStart) {
|
|
63
|
-
const shortenedPath = path.substr(pathStart.length + 1, path.length);
|
|
64
|
-
|
|
65
|
-
for (let i = 0; i < root.children.length; i++) {
|
|
66
|
-
const child = root.children[i];
|
|
67
|
-
if (child && this.addNodeAtPath(node, shortenedPath, child)) {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public getNodeAtPath(path: string = this.root.getPath(), root: ITreeNode = this.#root): ITreeNode | null {
|
|
76
|
-
if (root.name === path)
|
|
77
|
-
return root;
|
|
78
|
-
|
|
79
|
-
const pathStart = path.substr(0, path.indexOf('.'));
|
|
80
|
-
if (root.name === pathStart) {
|
|
81
|
-
const shortenedPath = path.substr(pathStart.length + 1, path.length);
|
|
82
|
-
|
|
83
|
-
for (let i = 0; i < root.children.length; i++) {
|
|
84
|
-
const child = root.children[i];
|
|
85
|
-
const res = this.getNodeAtPath(shortenedPath, child);
|
|
86
|
-
if (res) return res;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public removeNode(node: ITreeNode, root: ITreeNode = this.#root): boolean {
|
|
93
|
-
if (root.hasChild(node)) {
|
|
94
|
-
root.removeChild(node);
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
for (let i = 0; i < root.children.length; i++) {
|
|
99
|
-
const child = root.children[i];
|
|
100
|
-
if (child && this.removeNode(node, child)) {
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
public removeNodeAtPath(path: string, root: ITreeNode = this.#root): boolean {
|
|
109
|
-
if (root.name === path) {
|
|
110
|
-
root.parent?.removeChild(root);
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const pathStart = path.substr(0, path.indexOf('.'));
|
|
115
|
-
if (root.name === pathStart) {
|
|
116
|
-
const shortenedPath = path.substr(pathStart.length + 1, path.length);
|
|
117
|
-
|
|
118
|
-
for (let i = 0; i < root.children.length; i++) {
|
|
119
|
-
const child = root.children[i];
|
|
120
|
-
if (child && this.removeNodeAtPath(shortenedPath, child)) {
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// #endregion Public Methods (5)
|
|
129
|
-
}
|
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
import { Box, IBox } from '@shapediver/viewer.shared.math';
|
|
2
|
-
import { ITransformation, ITreeNode } from '../interfaces/ITreeNode';
|
|
3
|
-
import { ITreeNodeData } from '../interfaces/ITreeNodeData';
|
|
4
|
-
import { mat4 } from 'gl-matrix';
|
|
5
|
-
import { UuidGenerator } from '@shapediver/viewer.shared.services';
|
|
6
|
-
|
|
7
|
-
export class TreeNode implements ITreeNode {
|
|
8
|
-
// #region Properties (19)
|
|
9
|
-
|
|
10
|
-
readonly #boundingBox: IBox = new Box();
|
|
11
|
-
readonly #boundingBoxViewport: { [key: string]: IBox } = {};
|
|
12
|
-
readonly #children: ITreeNode[] = [];
|
|
13
|
-
readonly #data: ITreeNodeData[] = [];
|
|
14
|
-
readonly #id: string;
|
|
15
|
-
readonly #uuidGenerator: UuidGenerator = UuidGenerator.instance;
|
|
16
|
-
|
|
17
|
-
#boneInverses: mat4[] = [];
|
|
18
|
-
#bones: ITreeNode[] = [];
|
|
19
|
-
#convertedObject: { [key: string]: unknown } = {};
|
|
20
|
-
#excludeViewports: string[] = [];
|
|
21
|
-
#name: string = '';
|
|
22
|
-
#originalId: string;
|
|
23
|
-
#originalName?: string;
|
|
24
|
-
#parent?: ITreeNode;
|
|
25
|
-
#restrictViewports: string[] = [];
|
|
26
|
-
#skinNode: boolean = false;
|
|
27
|
-
#transformations: ITransformation[] = [];
|
|
28
|
-
#updateCallbackConvertedObject: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null = null;
|
|
29
|
-
#version: string;
|
|
30
|
-
#visible: boolean = true;
|
|
31
|
-
|
|
32
|
-
// #endregion Properties (19)
|
|
33
|
-
|
|
34
|
-
// #region Constructors (1)
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Creation of a node that can be used in the node tree.
|
|
38
|
-
*
|
|
39
|
-
* @param name the name of the node
|
|
40
|
-
* @param parent the parent of this node
|
|
41
|
-
* @param data the array of data
|
|
42
|
-
* @param transformations the array of transformations
|
|
43
|
-
*/
|
|
44
|
-
constructor(
|
|
45
|
-
name: string = 'node',
|
|
46
|
-
parent?: ITreeNode,
|
|
47
|
-
data: ITreeNodeData[] = [],
|
|
48
|
-
transformations: ITransformation[] = []
|
|
49
|
-
) {
|
|
50
|
-
this.#name = name.replace(/\./g, '_');
|
|
51
|
-
this.#parent = parent;
|
|
52
|
-
this.#data = data;
|
|
53
|
-
this.#transformations = transformations;
|
|
54
|
-
|
|
55
|
-
this.#id = this.#uuidGenerator.create();
|
|
56
|
-
this.#originalId = this.#id;
|
|
57
|
-
this.#version = this.#uuidGenerator.create();
|
|
58
|
-
this.#parent?.addChild(this);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// #endregion Constructors (1)
|
|
62
|
-
|
|
63
|
-
// #region Public Getters And Setters (33)
|
|
64
|
-
|
|
65
|
-
public get boneInverses(): mat4[] {
|
|
66
|
-
return this.#boneInverses;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public set boneInverses(value: mat4[]) {
|
|
70
|
-
this.#boneInverses = value;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
public get bones(): ITreeNode[] {
|
|
74
|
-
return this.#bones;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public set bones(value: ITreeNode[]) {
|
|
78
|
-
this.#bones = value;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public get boundingBox(): IBox {
|
|
82
|
-
return this.#boundingBox;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public get boundingBoxViewport(): { [key: string]: IBox } {
|
|
86
|
-
return this.#boundingBoxViewport;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
public get children(): ITreeNode[] {
|
|
90
|
-
return this.#children;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public get convertedObject(): { [key: string]: unknown } {
|
|
94
|
-
return this.#convertedObject;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public set convertedObject(value: { [key: string]: unknown }) {
|
|
98
|
-
this.#convertedObject = value;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public get data(): ITreeNodeData[] {
|
|
102
|
-
return this.#data;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public get excludeViewports(): string[] {
|
|
106
|
-
return this.#excludeViewports;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
public set excludeViewports(value: string[]) {
|
|
110
|
-
this.#excludeViewports = value;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public get id(): string {
|
|
114
|
-
return this.#id;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public get name(): string {
|
|
118
|
-
return this.#name;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public set name(value: string) {
|
|
122
|
-
this.#name = value;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public get nodeMatrix(): mat4 {
|
|
126
|
-
const matrix: mat4 = mat4.create();
|
|
127
|
-
for (const transform of this.#transformations)
|
|
128
|
-
if (transform.id !== 'sdtf') mat4.multiply(matrix, matrix, transform.matrix);
|
|
129
|
-
return matrix;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
public get originalId(): string {
|
|
133
|
-
return this.#originalId;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public set originalId(value: string) {
|
|
137
|
-
this.#originalId = value;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
public get originalName(): string | undefined {
|
|
141
|
-
return this.#originalName;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
public set originalName(value: string | undefined) {
|
|
145
|
-
this.#originalName = value;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
public get parent(): ITreeNode | undefined {
|
|
149
|
-
return this.#parent;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
public set parent(value: ITreeNode | undefined) {
|
|
153
|
-
// check if it was removed from previous parent
|
|
154
|
-
if (this.#parent)
|
|
155
|
-
this.#parent.removeChild(this);
|
|
156
|
-
|
|
157
|
-
// check if it is in children of new parent
|
|
158
|
-
if (value)
|
|
159
|
-
value.addChild(this);
|
|
160
|
-
|
|
161
|
-
this.#parent = value;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
public get restrictViewports(): string[] {
|
|
165
|
-
return this.#restrictViewports;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
public set restrictViewports(value: string[]) {
|
|
169
|
-
this.#restrictViewports = value;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public get skinNode(): boolean {
|
|
173
|
-
return this.#skinNode;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public set skinNode(value: boolean) {
|
|
177
|
-
this.#skinNode = value;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
public get transformations(): ITransformation[] {
|
|
181
|
-
return this.#transformations;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
public set transformations(value: ITransformation[]) {
|
|
185
|
-
this.#transformations = value;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
public get updateCallbackConvertedObject(): ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null {
|
|
189
|
-
return this.#updateCallbackConvertedObject;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
public set updateCallbackConvertedObject(value: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null) {
|
|
193
|
-
this.#updateCallbackConvertedObject = value;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public get version(): string {
|
|
197
|
-
return this.#version;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
public set version(value: string) {
|
|
201
|
-
this.#version = value;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
public get visible(): boolean {
|
|
205
|
-
return this.#visible;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
public set visible(value: boolean) {
|
|
209
|
-
this.#visible = value;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
public get worldMatrix(): mat4 {
|
|
213
|
-
const matrix: mat4 = mat4.create();
|
|
214
|
-
|
|
215
|
-
for (const transform of this.#transformations)
|
|
216
|
-
mat4.multiply(matrix, matrix, transform.matrix);
|
|
217
|
-
|
|
218
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
219
|
-
let node: ITreeNode = this;
|
|
220
|
-
while (node.parent) {
|
|
221
|
-
mat4.multiply(matrix, node.parent.nodeMatrix, matrix);
|
|
222
|
-
node = node.parent;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return matrix;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// #endregion Public Getters And Setters (33)
|
|
229
|
-
|
|
230
|
-
// #region Public Methods (20)
|
|
231
|
-
|
|
232
|
-
public addChild(child: ITreeNode): boolean {
|
|
233
|
-
if (this.hasChild(child)) return false;
|
|
234
|
-
|
|
235
|
-
this.#children.push(child);
|
|
236
|
-
if (child.parent)
|
|
237
|
-
child.parent.removeChild(child);
|
|
238
|
-
(<ITreeNode>child.parent) = this;
|
|
239
|
-
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
public addData(data: ITreeNodeData): boolean {
|
|
244
|
-
this.#data.push(data);
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
public addTransformation(transformation: ITransformation): boolean {
|
|
249
|
-
this.#transformations.push(transformation);
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
public clone(): ITreeNode {
|
|
254
|
-
const clone = new (this.constructor as new () => ITreeNode)();
|
|
255
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
256
|
-
// @ts-ignore
|
|
257
|
-
clone.name = this.name;
|
|
258
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
259
|
-
// @ts-ignore
|
|
260
|
-
clone.originalId = this.originalId;
|
|
261
|
-
clone.visible = this.visible;
|
|
262
|
-
for (const child of this.#children)
|
|
263
|
-
clone.addChild(child.clone());
|
|
264
|
-
for (const data of this.#data)
|
|
265
|
-
clone.data.push(data.clone());
|
|
266
|
-
for (const transform of this.#transformations)
|
|
267
|
-
clone.addTransformation({
|
|
268
|
-
id: transform.id,
|
|
269
|
-
matrix: mat4.clone(transform.matrix)
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
return clone;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
public cloneInstance(): ITreeNode {
|
|
276
|
-
const clone = new (this.constructor as new () => ITreeNode)();
|
|
277
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
278
|
-
// @ts-ignore
|
|
279
|
-
clone.name = this.name;
|
|
280
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
281
|
-
// @ts-ignore
|
|
282
|
-
clone.originalId = this.originalId;
|
|
283
|
-
clone.visible = this.visible;
|
|
284
|
-
for (const child of this.#children)
|
|
285
|
-
clone.addChild(child.cloneInstance());
|
|
286
|
-
for (const data of this.#data)
|
|
287
|
-
clone.data.push(data);
|
|
288
|
-
for (const transform of this.#transformations)
|
|
289
|
-
clone.addTransformation({
|
|
290
|
-
id: transform.id,
|
|
291
|
-
matrix: mat4.clone(transform.matrix)
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
return clone;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
public getChild(id: string): ITreeNode | undefined {
|
|
298
|
-
for (let i = 0; i < this.#children.length; i++)
|
|
299
|
-
if (this.#children[i].id === id)
|
|
300
|
-
return this.#children[i];
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
public getData(id: string): ITreeNodeData | undefined {
|
|
305
|
-
for (let i = 0; i < this.#data.length; i++)
|
|
306
|
-
if (this.#data[i].id === id)
|
|
307
|
-
return this.#data[i];
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
public getNodesByName(name: string): ITreeNode[] {
|
|
312
|
-
const nodes: ITreeNode[] = [];
|
|
313
|
-
if (name === this.name) nodes.push(<ITreeNode><unknown>this);
|
|
314
|
-
this.traverse((n) => {
|
|
315
|
-
if (name === n.name) nodes.push(n);
|
|
316
|
-
});
|
|
317
|
-
return nodes;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
public getNodesByNameWithRegex(regex: RegExp): ITreeNode[] {
|
|
321
|
-
const nodes: ITreeNode[] = [];
|
|
322
|
-
if (regex.test(this.name)) nodes.push(<ITreeNode><unknown>this);
|
|
323
|
-
this.traverse((n) => {
|
|
324
|
-
if (regex.test(n.name)) nodes.push(n);
|
|
325
|
-
});
|
|
326
|
-
return nodes;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
public getPath(): string {
|
|
330
|
-
let path = this.name;
|
|
331
|
-
let node: ITreeNode | undefined = this.parent;
|
|
332
|
-
while (node) {
|
|
333
|
-
path = node.name + '.' + path;
|
|
334
|
-
node = node.parent;
|
|
335
|
-
}
|
|
336
|
-
return path;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
public getTransformation(id: string): ITransformation | undefined {
|
|
340
|
-
for (let i = 0; i < this.#transformations.length; i++)
|
|
341
|
-
if (this.#transformations[i].id === id)
|
|
342
|
-
return this.#transformations[i];
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
public hasChild(child: ITreeNode): boolean {
|
|
347
|
-
return this.#children.includes(child);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
public hasData(data: ITreeNodeData): boolean {
|
|
351
|
-
return this.#data.includes(data);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
public hasTransformation(transformation: ITransformation): boolean {
|
|
355
|
-
return this.#transformations.includes(transformation);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
public removeChild(child: ITreeNode): boolean {
|
|
359
|
-
const index = this.#children.indexOf(child);
|
|
360
|
-
if (index === -1) return false;
|
|
361
|
-
this.#children.splice(index, 1);
|
|
362
|
-
(<ITreeNode | undefined>child.parent) = undefined;
|
|
363
|
-
|
|
364
|
-
return true;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
public removeData(data: ITreeNodeData): boolean {
|
|
368
|
-
const index = this.#data.indexOf(data);
|
|
369
|
-
if (index === -1) return false;
|
|
370
|
-
this.#data.splice(index, 1);
|
|
371
|
-
|
|
372
|
-
return true;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
public removeTransformation(transformation: ITransformation): boolean {
|
|
376
|
-
const index = this.#transformations.indexOf(transformation);
|
|
377
|
-
if (index === -1) return false;
|
|
378
|
-
this.#transformations.splice(index, 1);
|
|
379
|
-
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
public traverse(callback: (node: ITreeNode) => void): void {
|
|
384
|
-
callback(<ITreeNode><unknown>this);
|
|
385
|
-
|
|
386
|
-
for (let i = 0; i < this.children.length; i++)
|
|
387
|
-
this.children[i].traverse(callback);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
public traverseData(callback: (node: ITreeNodeData) => void): void {
|
|
391
|
-
for (let j = 0; j < this.data.length; j++)
|
|
392
|
-
callback(<ITreeNodeData>this.data[j]);
|
|
393
|
-
|
|
394
|
-
for (let i = 0; i < this.children.length; i++)
|
|
395
|
-
this.children[i].traverseData(<(data: ITreeNodeData) => void>callback);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
public updateVersion(parents: boolean = true, children: boolean = true): void {
|
|
399
|
-
if (parents === true) {
|
|
400
|
-
let node = <ITreeNode>this;
|
|
401
|
-
while (node.parent) {
|
|
402
|
-
node = node.parent;
|
|
403
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
404
|
-
// @ts-ignore
|
|
405
|
-
node.version = this.#uuidGenerator.create();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
if (children === true) {
|
|
410
|
-
for (let i = 0; i < this.#children.length; i++)
|
|
411
|
-
this.#children[i].updateVersion(parents, children);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
this.#version = this.#uuidGenerator.create();
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// #endregion Public Methods (20)
|
|
418
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { AbstractTreeNodeData } from './implementation/AbstractTreeNodeData';
|
|
2
|
-
import { ITransformation, ITreeNode } from './interfaces/ITreeNode';
|
|
3
|
-
import { ITree } from './interfaces/ITree';
|
|
4
|
-
import { ITreeNodeData } from './interfaces/ITreeNodeData';
|
|
5
|
-
import { Tree } from './implementation/Tree';
|
|
6
|
-
import { TreeNode } from './implementation/TreeNode';
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
ITree, Tree
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export {
|
|
13
|
-
ITreeNode, TreeNode, ITransformation
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
ITreeNodeData, AbstractTreeNodeData
|
|
18
|
-
};
|
package/src/interfaces/ITree.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { ITreeNode } from './ITreeNode';
|
|
2
|
-
|
|
3
|
-
export interface ITree {
|
|
4
|
-
// #region Properties (1)
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The root of the tree.
|
|
8
|
-
*/
|
|
9
|
-
readonly root: ITreeNode;
|
|
10
|
-
|
|
11
|
-
// #endregion Properties (1)
|
|
12
|
-
|
|
13
|
-
// #region Public Methods (5)
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Add the node as a child of the corresponding parent node.
|
|
17
|
-
*
|
|
18
|
-
* @param node the node to be added
|
|
19
|
-
* @param parent the targeted parent node
|
|
20
|
-
* @param root optional root at which the process begins, root node will be used per default
|
|
21
|
-
*/
|
|
22
|
-
addNode(node: ITreeNode, parent?: ITreeNode, root?: ITreeNode): boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Add the node at the corresponding path. (paths are dot separated ids)
|
|
25
|
-
*
|
|
26
|
-
* @param node the node to be added
|
|
27
|
-
* @param path the path at which the node should be added
|
|
28
|
-
* @param root optional root at which the process begins, root node will be used per default
|
|
29
|
-
*/
|
|
30
|
-
addNodeAtPath(node: ITreeNode, path?: string, root?: ITreeNode): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Get the node at the provided path.
|
|
33
|
-
*
|
|
34
|
-
* @param path
|
|
35
|
-
* @param root
|
|
36
|
-
* @returns
|
|
37
|
-
*/
|
|
38
|
-
getNodeAtPath(path?: string, root?: ITreeNode): ITreeNode | null;
|
|
39
|
-
/**
|
|
40
|
-
* Remove a node from the tree.
|
|
41
|
-
*
|
|
42
|
-
* @param node the node to remove
|
|
43
|
-
* @param root optional root at which the process begins, root node will be used per default
|
|
44
|
-
*/
|
|
45
|
-
removeNode(node: ITreeNode, root?: ITreeNode): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Remove a node via the path of it.
|
|
48
|
-
*
|
|
49
|
-
* @param path the path of the node to be removed
|
|
50
|
-
* @param root optional root at which the process begins, root node will be used per default
|
|
51
|
-
*/
|
|
52
|
-
removeNodeAtPath(path: string, root?: ITreeNode): boolean;
|
|
53
|
-
|
|
54
|
-
// #endregion Public Methods (5)
|
|
55
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { IBox } from '@shapediver/viewer.shared.math';
|
|
2
|
-
import { ITreeNodeData } from './ITreeNodeData';
|
|
3
|
-
import { mat4 } from 'gl-matrix';
|
|
4
|
-
|
|
5
|
-
// #region Interfaces (2)
|
|
6
|
-
|
|
7
|
-
export interface ITransformation {
|
|
8
|
-
// #region Properties (2)
|
|
9
|
-
|
|
10
|
-
id: string,
|
|
11
|
-
matrix: mat4
|
|
12
|
-
|
|
13
|
-
// #endregion Properties (2)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ITreeNode {
|
|
17
|
-
// #region Properties (20)
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The bounding box of this tree node.
|
|
21
|
-
*/
|
|
22
|
-
readonly boundingBox: IBox;
|
|
23
|
-
/**
|
|
24
|
-
* The bounding box of this tree node for each viewport.
|
|
25
|
-
* As there can be properties where tree nodes are excluded from the viewport, the bounding boxes may be different per viewport.
|
|
26
|
-
* The {@link boundingBox} property can be used as the general bounding box without any viewport specific exclusions.
|
|
27
|
-
*/
|
|
28
|
-
readonly boundingBoxViewport: { [key: string]: IBox };
|
|
29
|
-
/**
|
|
30
|
-
* The children of this tree node. Can be added and remove via {@link addChild} and {@link removeChild}.
|
|
31
|
-
*/
|
|
32
|
-
readonly children: ITreeNode[];
|
|
33
|
-
/**
|
|
34
|
-
* The data of this tree node.
|
|
35
|
-
* The data can include Geometry, Materials, Lights, Cameras, but also informational or custom data.
|
|
36
|
-
*
|
|
37
|
-
* Can be added and remove via {@link addData} and {@link removeData}.
|
|
38
|
-
*/
|
|
39
|
-
readonly data: ITreeNodeData[];
|
|
40
|
-
/**
|
|
41
|
-
* The ID of the tree node.
|
|
42
|
-
*/
|
|
43
|
-
readonly id: string;
|
|
44
|
-
/**
|
|
45
|
-
* The name of the tree node.
|
|
46
|
-
*/
|
|
47
|
-
readonly name: string;
|
|
48
|
-
/**
|
|
49
|
-
* The matrix of the tree node.
|
|
50
|
-
* This is computed via all transformations in the {@link transformations} property.
|
|
51
|
-
*/
|
|
52
|
-
readonly nodeMatrix: mat4;
|
|
53
|
-
/**
|
|
54
|
-
* The original ID of the tree node, if it was copied.
|
|
55
|
-
*/
|
|
56
|
-
readonly originalId: string;
|
|
57
|
-
/**
|
|
58
|
-
* The original name of the tree node, if one was supplied.
|
|
59
|
-
*/
|
|
60
|
-
readonly originalName?: string;
|
|
61
|
-
/**
|
|
62
|
-
* The parent of the tree node.
|
|
63
|
-
* This property is automatically managed by {@link addChild} and {@link removeChild}.
|
|
64
|
-
*/
|
|
65
|
-
readonly parent?: ITreeNode;
|
|
66
|
-
/**
|
|
67
|
-
* The version of the tree node.
|
|
68
|
-
* If the version changes, the node will be marked for an update.
|
|
69
|
-
* A version change can be triggered via {@link updateVersion}.
|
|
70
|
-
*/
|
|
71
|
-
readonly version: string;
|
|
72
|
-
/**
|
|
73
|
-
* The world matrix of the tree node.
|
|
74
|
-
* This includes also the transformations of all parents.
|
|
75
|
-
*/
|
|
76
|
-
readonly worldMatrix: mat4;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The inverse matrices for the bones, if specified.
|
|
80
|
-
*/
|
|
81
|
-
boneInverses: mat4[];
|
|
82
|
-
/**
|
|
83
|
-
* The optional bones that build a skeleton for animations.
|
|
84
|
-
*/
|
|
85
|
-
bones: ITreeNode[];
|
|
86
|
-
/**
|
|
87
|
-
* The converted object of the tree node.
|
|
88
|
-
*/
|
|
89
|
-
convertedObject: { [key: string]: unknown };
|
|
90
|
-
/**
|
|
91
|
-
* The viewports to exclude this tree node from.
|
|
92
|
-
*/
|
|
93
|
-
excludeViewports: string[];
|
|
94
|
-
/**
|
|
95
|
-
* The viewports to restrict this tree node to.
|
|
96
|
-
*/
|
|
97
|
-
restrictViewports: string[];
|
|
98
|
-
/**
|
|
99
|
-
* Property to mark this node as a skin node. (default: false)
|
|
100
|
-
*/
|
|
101
|
-
skinNode: boolean;
|
|
102
|
-
/**
|
|
103
|
-
* The transformation to be applied to this tree node.
|
|
104
|
-
*/
|
|
105
|
-
transformations: ITransformation[];
|
|
106
|
-
/**
|
|
107
|
-
* The update callback for the converted object of the tree node.
|
|
108
|
-
*/
|
|
109
|
-
updateCallbackConvertedObject: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null;
|
|
110
|
-
/**
|
|
111
|
-
* Option to make this tree node visible. (default: true)
|
|
112
|
-
*/
|
|
113
|
-
visible: boolean;
|
|
114
|
-
|
|
115
|
-
// #endregion Properties (20)
|
|
116
|
-
|
|
117
|
-
// #region Public Methods (20)
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Add a child to the children of this node.
|
|
121
|
-
*
|
|
122
|
-
* @param child the child to add
|
|
123
|
-
*/
|
|
124
|
-
addChild(child: ITreeNode): boolean;
|
|
125
|
-
/**
|
|
126
|
-
* Add a data item to node.
|
|
127
|
-
*
|
|
128
|
-
* @param data the data to add
|
|
129
|
-
*/
|
|
130
|
-
addData(data: ITreeNodeData): boolean;
|
|
131
|
-
/**
|
|
132
|
-
* Add a transformation to this node.
|
|
133
|
-
*
|
|
134
|
-
* @param transformation the transformation to add
|
|
135
|
-
*/
|
|
136
|
-
addTransformation(transformation: ITransformation): boolean;
|
|
137
|
-
/**
|
|
138
|
-
* Clones this node and all its children.
|
|
139
|
-
* The data objects like GeometryData, MaterialData, etc. are cloned as well.
|
|
140
|
-
* Depending on the size of the node and the amount of children, this can therefore be relatively slow.
|
|
141
|
-
*/
|
|
142
|
-
clone(): ITreeNode;
|
|
143
|
-
/**
|
|
144
|
-
* Clones this node and all its children.
|
|
145
|
-
* The data objects like GeometryData, MaterialData, etc. are not copied in this case.
|
|
146
|
-
*/
|
|
147
|
-
cloneInstance(): ITreeNode;
|
|
148
|
-
/**
|
|
149
|
-
* Returns the child with the specified id
|
|
150
|
-
*/
|
|
151
|
-
getChild(id: string): ITreeNode | undefined;
|
|
152
|
-
/**
|
|
153
|
-
* Returns the data item with the specified id
|
|
154
|
-
*/
|
|
155
|
-
getData(id: string): ITreeNodeData | undefined;
|
|
156
|
-
/**
|
|
157
|
-
* Test this node and all it's descendants for nodes with the specified name and return them in an array.
|
|
158
|
-
* @param name
|
|
159
|
-
*/
|
|
160
|
-
getNodesByName(name: string): ITreeNode[]
|
|
161
|
-
/**
|
|
162
|
-
* Test this nodes name and all it's descendants name for nodes for the specified regex and return them in an array.
|
|
163
|
-
* @param regex
|
|
164
|
-
*/
|
|
165
|
-
getNodesByNameWithRegex(regex: RegExp): ITreeNode[]
|
|
166
|
-
/**
|
|
167
|
-
* Return the path to this node.
|
|
168
|
-
*/
|
|
169
|
-
getPath(): string;
|
|
170
|
-
/**
|
|
171
|
-
* Returns the transformation with the specified id
|
|
172
|
-
*/
|
|
173
|
-
getTransformation(id: string): ITransformation | undefined;
|
|
174
|
-
/**
|
|
175
|
-
* Check for existence of a child from the children of this node.
|
|
176
|
-
*
|
|
177
|
-
* @param child the child to check
|
|
178
|
-
*/
|
|
179
|
-
hasChild(child: ITreeNode): boolean;
|
|
180
|
-
/**
|
|
181
|
-
* Check for existence of a data item of this node.
|
|
182
|
-
*
|
|
183
|
-
* @param data the data item to check
|
|
184
|
-
*/
|
|
185
|
-
hasData(data: ITreeNodeData): boolean;
|
|
186
|
-
/**
|
|
187
|
-
* Check for existence of a transformation of this node.
|
|
188
|
-
*
|
|
189
|
-
* @param data the transformation to check
|
|
190
|
-
*/
|
|
191
|
-
hasTransformation(transformation: ITransformation): boolean;
|
|
192
|
-
/**
|
|
193
|
-
* Remove a child from the children of this node.
|
|
194
|
-
*
|
|
195
|
-
* @param child the child to remove
|
|
196
|
-
*/
|
|
197
|
-
removeChild(child: ITreeNode): boolean;
|
|
198
|
-
/**
|
|
199
|
-
* Remove a data item from this node.
|
|
200
|
-
*
|
|
201
|
-
* @param data the data to remove
|
|
202
|
-
*/
|
|
203
|
-
removeData(data: ITreeNodeData): boolean;
|
|
204
|
-
/**
|
|
205
|
-
* Remove a transformation from this node.
|
|
206
|
-
*
|
|
207
|
-
* @param transformation the transformation to remove
|
|
208
|
-
*/
|
|
209
|
-
removeTransformation(transformation: ITransformation): boolean;
|
|
210
|
-
/**
|
|
211
|
-
* Traverse this node and all it's children and executes the callback for all of them
|
|
212
|
-
*
|
|
213
|
-
* @param callback
|
|
214
|
-
*/
|
|
215
|
-
traverse(callback: (node: ITreeNode) => void): void;
|
|
216
|
-
/**
|
|
217
|
-
* Traverse this node and all it's children and executes the callback for all data items of them
|
|
218
|
-
*
|
|
219
|
-
* @param callback
|
|
220
|
-
*/
|
|
221
|
-
traverseData(callback: (data: ITreeNodeData) => void): void;
|
|
222
|
-
/**
|
|
223
|
-
* Update the version.
|
|
224
|
-
*
|
|
225
|
-
* @param parents if true, the version of all parents will be updated as well (default: true)
|
|
226
|
-
* @param children if true, the version of all children will be updated as well (default: true)
|
|
227
|
-
*/
|
|
228
|
-
updateVersion(parents?: boolean, children?: boolean): void;
|
|
229
|
-
|
|
230
|
-
// #endregion Public Methods (20)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// #endregion Interfaces (2)
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export interface ITreeNodeData {
|
|
2
|
-
// #region Properties (4)
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The converted object of the tree node.
|
|
6
|
-
*/
|
|
7
|
-
convertedObject: { [key: string]: unknown };
|
|
8
|
-
/**
|
|
9
|
-
* The ID of the tree node data.
|
|
10
|
-
*/
|
|
11
|
-
id: string;
|
|
12
|
-
/**
|
|
13
|
-
* The update callback for the converted object of the tree node.
|
|
14
|
-
*/
|
|
15
|
-
updateCallbackConvertedObject: ((newObj: unknown, oldObj: unknown, viewport: string) => void) | null;
|
|
16
|
-
/**
|
|
17
|
-
* The version of the tree node data.
|
|
18
|
-
* If the version changes, the node data will be marked for an update.
|
|
19
|
-
* A version change can be triggered via {@link updateVersion}.
|
|
20
|
-
*/
|
|
21
|
-
version: string;
|
|
22
|
-
|
|
23
|
-
// #endregion Properties (4)
|
|
24
|
-
|
|
25
|
-
// #region Public Methods (2)
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Clones this node tree data.
|
|
29
|
-
*/
|
|
30
|
-
clone(): ITreeNodeData;
|
|
31
|
-
/**
|
|
32
|
-
* Update the version.
|
|
33
|
-
*/
|
|
34
|
-
updateVersion(): void;
|
|
35
|
-
|
|
36
|
-
// #endregion Public Methods (2)
|
|
37
|
-
}
|
package/tsconfig.json
DELETED