@shapediver/viewer.data-engine.sdtf-engine 3.3.4 → 3.3.7
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 +9 -10
- package/src/SDTFEngine.ts +0 -294
- package/src/index.ts +0 -5
- package/tsconfig.json +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapediver/viewer.data-engine.sdtf-engine",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.7",
|
|
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"
|
|
@@ -41,13 +40,13 @@
|
|
|
41
40
|
"dependencies": {
|
|
42
41
|
"@shapediver/sdk.geometry-api-sdk-v2": "1.11.0",
|
|
43
42
|
"@shapediver/sdk.sdtf-v1": "1.5.3",
|
|
44
|
-
"@shapediver/viewer.data-engine.shared-types": "3.3.
|
|
45
|
-
"@shapediver/viewer.shared.build-data": "3.3.
|
|
46
|
-
"@shapediver/viewer.shared.node-tree": "3.3.
|
|
47
|
-
"@shapediver/viewer.shared.services": "3.3.
|
|
48
|
-
"@shapediver/viewer.shared.types": "3.3.
|
|
43
|
+
"@shapediver/viewer.data-engine.shared-types": "3.3.7",
|
|
44
|
+
"@shapediver/viewer.shared.build-data": "3.3.7",
|
|
45
|
+
"@shapediver/viewer.shared.node-tree": "3.3.7",
|
|
46
|
+
"@shapediver/viewer.shared.services": "3.3.7",
|
|
47
|
+
"@shapediver/viewer.shared.types": "3.3.7",
|
|
49
48
|
"axios": "^1.2.6",
|
|
50
49
|
"gl-matrix": "3.3.0"
|
|
51
50
|
},
|
|
52
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "112787d5c5226cca5e89d08102d0b1a3dd4a1d71"
|
|
53
52
|
}
|
package/src/SDTFEngine.ts
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree'
|
|
2
|
-
import { Logger, ShapeDiverViewerDataProcessingError } from '@shapediver/viewer.shared.services'
|
|
3
|
-
import { SDTFAttributesData, SDTFAttributeData, SDTFItemData, SDTFOverviewData } from '@shapediver/viewer.shared.types'
|
|
4
|
-
import { ShapeDiverResponseOutputContent } from '@shapediver/sdk.geometry-api-sdk-v2'
|
|
5
|
-
import { create, ISdtfReadableAsset, ISdtfReadableAttributes, ISdtfReadableChunk, ISdtfReadableDataItem, ISdtfReadableNode, SdtfTypeHintName } from '@shapediver/sdk.sdtf-v1'
|
|
6
|
-
import { SdtfPrimitiveTypeGuard } from '@shapediver/sdk.sdtf-primitives'
|
|
7
|
-
|
|
8
|
-
export class SDTFEngine {
|
|
9
|
-
// #region Properties (3)
|
|
10
|
-
|
|
11
|
-
private readonly _logger: Logger = Logger.instance;
|
|
12
|
-
|
|
13
|
-
private static _instance: SDTFEngine;
|
|
14
|
-
|
|
15
|
-
private _parsedFile!: ISdtfReadableAsset;
|
|
16
|
-
|
|
17
|
-
// #endregion Properties (3)
|
|
18
|
-
|
|
19
|
-
// #region Public Static Accessors (1)
|
|
20
|
-
|
|
21
|
-
public static get instance() {
|
|
22
|
-
return this._instance || (this._instance = new this());
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// #endregion Public Static Accessors (1)
|
|
26
|
-
|
|
27
|
-
// #region Public Methods (1)
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Load the sdtf content into a scene graph node.
|
|
31
|
-
*
|
|
32
|
-
* @param content the geometry content
|
|
33
|
-
* @returns the scene graph node
|
|
34
|
-
*/
|
|
35
|
-
public async loadContent(content: ShapeDiverResponseOutputContent, jwtToken?: string): Promise<ITreeNode> {
|
|
36
|
-
const node = new TreeNode('sdtf');
|
|
37
|
-
|
|
38
|
-
// We have to be safe and check if the content is a valid SDTF file
|
|
39
|
-
if (!content || (content && !content.href))
|
|
40
|
-
throw new ShapeDiverViewerDataProcessingError('SDTFEngine.loadContent: Invalid content was provided to geometry engine.');
|
|
41
|
-
|
|
42
|
-
// create the sdtf sdk
|
|
43
|
-
const sdk = jwtToken ? await create({ authToken: jwtToken }) : await create();
|
|
44
|
-
// crete the sdtf parser
|
|
45
|
-
const parser = sdk.createParser();
|
|
46
|
-
// parse the file
|
|
47
|
-
this._parsedFile = await parser.readFromUrl(content.href!);
|
|
48
|
-
|
|
49
|
-
// crete the overview and save it in the node data
|
|
50
|
-
node.data.push(await this.createSDTFOverview());
|
|
51
|
-
|
|
52
|
-
// add the loaded chunks to the node
|
|
53
|
-
for (let i = 0; i < this._parsedFile.chunks.length; i++)
|
|
54
|
-
node.children.push(await this.loadChunk(this._parsedFile.chunks[i], i));
|
|
55
|
-
|
|
56
|
-
return node;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// #endregion Public Methods (1)
|
|
60
|
-
|
|
61
|
-
// #region Private Methods (5)
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create an overview of the SDTF file.
|
|
65
|
-
* This overview is used for the data visualization.
|
|
66
|
-
* It is structured as a dictionary with the name as the key and an array of Objects as the value.
|
|
67
|
-
* The array of objects contains the different types that can be found in the SDTF file under the same name.
|
|
68
|
-
*
|
|
69
|
-
* Example:
|
|
70
|
-
* {
|
|
71
|
-
* "color": [
|
|
72
|
-
* {
|
|
73
|
-
* typeHint: 'string',
|
|
74
|
-
* count: 2,
|
|
75
|
-
* values: ["red", "blue"]
|
|
76
|
-
* },
|
|
77
|
-
* {
|
|
78
|
-
* typeHint: 'numberArray',
|
|
79
|
-
* count: 2,
|
|
80
|
-
* values: [[1,0,0,1], [0,0,1,1]]
|
|
81
|
-
* },
|
|
82
|
-
* ]
|
|
83
|
-
* }
|
|
84
|
-
*
|
|
85
|
-
* The overview contains the following information:
|
|
86
|
-
* - name of the attribute + type of the attribute
|
|
87
|
-
* - the count
|
|
88
|
-
* - for numerical attributes, the min and max values
|
|
89
|
-
* - for string attributes, the unique values
|
|
90
|
-
*
|
|
91
|
-
* @returns
|
|
92
|
-
*/
|
|
93
|
-
private async createSDTFOverview(): Promise<SDTFOverviewData> {
|
|
94
|
-
const overview: {
|
|
95
|
-
[key: string]: {
|
|
96
|
-
typeHint: SdtfTypeHintName | string;
|
|
97
|
-
count: number;
|
|
98
|
-
values?: string[];
|
|
99
|
-
min?: number;
|
|
100
|
-
max?: number;
|
|
101
|
-
}[];
|
|
102
|
-
} = {};
|
|
103
|
-
|
|
104
|
-
// go through all attributes
|
|
105
|
-
for (let i = 0; i < this._parsedFile.attributes.length; i++) {
|
|
106
|
-
const attributes = this._parsedFile.attributes[i];
|
|
107
|
-
|
|
108
|
-
// go through all entries
|
|
109
|
-
for (let key in attributes.entries) {
|
|
110
|
-
const dataToCopy = attributes.entries[key];
|
|
111
|
-
const value = await dataToCopy.getContent();
|
|
112
|
-
|
|
113
|
-
// create the type hint to use
|
|
114
|
-
const dataTypehint = dataToCopy.typeHint === undefined ? 'undefined' : dataToCopy.typeHint.name;
|
|
115
|
-
|
|
116
|
-
// check if the attribute is already in the overview
|
|
117
|
-
const existingEntries = overview[key] ? overview[key].filter(o => o.typeHint === dataTypehint) : [];
|
|
118
|
-
|
|
119
|
-
if (overview[key] && existingEntries.length > 0) {
|
|
120
|
-
// update the existing entry
|
|
121
|
-
const entry = existingEntries[0];
|
|
122
|
-
// update the count
|
|
123
|
-
entry.count++;
|
|
124
|
-
|
|
125
|
-
// update the values
|
|
126
|
-
if (SdtfPrimitiveTypeGuard.isStringType(dataTypehint)) {
|
|
127
|
-
if (!entry.values?.includes(<string>value))
|
|
128
|
-
entry.values?.push(<string>value)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// update the min and max
|
|
132
|
-
if (SdtfPrimitiveTypeGuard.isNumberType(dataTypehint)) {
|
|
133
|
-
entry.min = Math.min(<number>value, entry.min!);
|
|
134
|
-
entry.max = Math.max(<number>value, entry.max!);
|
|
135
|
-
}
|
|
136
|
-
} else {
|
|
137
|
-
// create a new entry, if the name already exists, but the type does not
|
|
138
|
-
if (overview[key]) {
|
|
139
|
-
overview[key].push({
|
|
140
|
-
typeHint: dataTypehint,
|
|
141
|
-
count: 1,
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
|
-
// create completely new entry
|
|
145
|
-
else {
|
|
146
|
-
overview[key] = [{
|
|
147
|
-
typeHint: dataTypehint,
|
|
148
|
-
count: 1,
|
|
149
|
-
}]
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// update the values
|
|
153
|
-
if (SdtfPrimitiveTypeGuard.isStringType(dataTypehint)) {
|
|
154
|
-
overview[key][overview[key].length - 1].values = [<string>value];
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// update the min and max
|
|
158
|
-
if (SdtfPrimitiveTypeGuard.isNumberType(dataTypehint)) {
|
|
159
|
-
overview[key][overview[key].length - 1].min = <number>value;
|
|
160
|
-
overview[key][overview[key].length - 1].max = <number>value;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return new SDTFOverviewData(overview);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Load the attributes into a SDTFAttributesData data item.
|
|
170
|
-
*
|
|
171
|
-
* @param attributes
|
|
172
|
-
* @returns
|
|
173
|
-
*/
|
|
174
|
-
private async loadAttributes(attributes: ISdtfReadableAttributes): Promise<SDTFAttributesData> {
|
|
175
|
-
const data = new SDTFAttributesData();
|
|
176
|
-
// go through all attributes entries and save them in data items
|
|
177
|
-
for (let key in attributes.entries) {
|
|
178
|
-
if (SdtfPrimitiveTypeGuard.isBooleanType(attributes.entries[key].typeHint?.name) || SdtfPrimitiveTypeGuard.isColorType(attributes.entries[key].typeHint?.name) || SdtfPrimitiveTypeGuard.isNumberType(attributes.entries[key].typeHint?.name) || SdtfPrimitiveTypeGuard.isStringType(attributes.entries[key].typeHint?.name)) {
|
|
179
|
-
// create the data item and save it in the dictionary
|
|
180
|
-
const typeHint = attributes.entries[key].typeHint === undefined ? 'undefined' : attributes.entries[key].typeHint!.name;
|
|
181
|
-
data.attributes[key] = new SDTFAttributeData(typeHint, await attributes.entries[key].getContent());
|
|
182
|
-
} else {
|
|
183
|
-
// async data
|
|
184
|
-
const typeHint = attributes.entries[key].typeHint === undefined ? 'undefined' : attributes.entries[key].typeHint!.name;
|
|
185
|
-
data.attributes[key] = new SDTFAttributeData(typeHint, async () => {
|
|
186
|
-
return await attributes.entries[key].getContent();
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return data;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Load the chunk into a scene graph node.
|
|
195
|
-
*
|
|
196
|
-
* @param chunk
|
|
197
|
-
* @param chunkId
|
|
198
|
-
* @returns
|
|
199
|
-
*/
|
|
200
|
-
private async loadChunk(chunk: ISdtfReadableChunk, chunkId: number): Promise<TreeNode> {
|
|
201
|
-
const chunkDef = new TreeNode(chunk.name || 'chunk_' + chunkId);
|
|
202
|
-
|
|
203
|
-
// if there are attributes, add them to the chunk as data
|
|
204
|
-
if (chunk.attributes !== undefined) {
|
|
205
|
-
chunkDef.data.push(await this.loadAttributes(chunk.attributes));
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// if there are items, add them to the chunk as children
|
|
209
|
-
if (chunk.items !== undefined && chunk.items.length > 0) {
|
|
210
|
-
for (let i = 0, len = chunk.items.length; i < len; i++) {
|
|
211
|
-
// got through all items
|
|
212
|
-
chunkDef.addChild(await this.loadItem(chunk.items[i], i));
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// if there are nodes, add them to the chunk as children
|
|
217
|
-
if (chunk.nodes !== undefined && chunk.nodes.length > 0) {
|
|
218
|
-
for (let i = 0, len = chunk.nodes.length; i < len; i++) {
|
|
219
|
-
// got through all children
|
|
220
|
-
chunkDef.addChild(await this.loadNode(chunk.nodes[i], i));
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return chunkDef;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Load the item into a scene graph node.
|
|
229
|
-
*
|
|
230
|
-
* @param item
|
|
231
|
-
* @param itemId
|
|
232
|
-
* @returns
|
|
233
|
-
*/
|
|
234
|
-
private async loadItem(item: ISdtfReadableDataItem, itemId: number): Promise<TreeNode> {
|
|
235
|
-
const itemDef = new TreeNode(itemId + '');
|
|
236
|
-
|
|
237
|
-
// if there are attributes, add them to the item
|
|
238
|
-
let attributes;
|
|
239
|
-
if (item.attributes !== undefined)
|
|
240
|
-
attributes = await this.loadAttributes(item.attributes);
|
|
241
|
-
|
|
242
|
-
// create the typehint
|
|
243
|
-
const typeHint = item.typeHint === undefined ? 'undefined' : item.typeHint!.name;
|
|
244
|
-
|
|
245
|
-
let itemData;
|
|
246
|
-
// create the data and save it in the item node
|
|
247
|
-
if (SdtfPrimitiveTypeGuard.isBooleanType(typeHint) || SdtfPrimitiveTypeGuard.isColorType(typeHint) || SdtfPrimitiveTypeGuard.isNumberType(typeHint) || SdtfPrimitiveTypeGuard.isStringType(typeHint)) {
|
|
248
|
-
itemData = new SDTFItemData(typeHint, await item.getContent(), attributes?.attributes!)
|
|
249
|
-
} else {
|
|
250
|
-
itemData = new SDTFItemData(typeHint, async () => {
|
|
251
|
-
return await item.getContent();
|
|
252
|
-
}, attributes?.attributes!);
|
|
253
|
-
}
|
|
254
|
-
itemDef.data.push(itemData)
|
|
255
|
-
|
|
256
|
-
return itemDef;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Load the node into a scene graph node.
|
|
261
|
-
*
|
|
262
|
-
* @param node
|
|
263
|
-
* @param nodeId
|
|
264
|
-
* @returns
|
|
265
|
-
*/
|
|
266
|
-
private async loadNode(node: ISdtfReadableNode, nodeId: number): Promise<TreeNode> {
|
|
267
|
-
const nodeDef = new TreeNode(node.name || 'node_' + nodeId);
|
|
268
|
-
|
|
269
|
-
// if there are attributes, add them to the node as data
|
|
270
|
-
if (node.attributes !== undefined) {
|
|
271
|
-
nodeDef.data.push(await this.loadAttributes(node.attributes));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// if there are items, add them to the node as children
|
|
275
|
-
if (node.items !== undefined && node.items.length > 0) {
|
|
276
|
-
for (let i = 0, len = node.items.length; i < len; i++) {
|
|
277
|
-
// got through all items
|
|
278
|
-
nodeDef.addChild(await this.loadItem(node.items[i], i));
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// if there are nodes, add them to the node as children
|
|
283
|
-
if (node.nodes !== undefined && node.nodes.length > 0) {
|
|
284
|
-
for (let i = 0, len = node.nodes.length; i < len; i++) {
|
|
285
|
-
// got through all children
|
|
286
|
-
nodeDef.addChild(await this.loadNode(node.nodes[i], i));
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return nodeDef;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// #endregion Private Methods (5)
|
|
294
|
-
}
|
package/src/index.ts
DELETED
package/tsconfig.json
DELETED