@sequent-org/ifc-viewer 1.1.1-ci.20.0 → 1.2.3-ci.22.0

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.
@@ -0,0 +1,2657 @@
1
+ import * as WebIFC from 'web-ifc';
2
+ import { IFCSPACE, IFCOPENINGELEMENT, IFCPRODUCTDEFINITIONSHAPE, IFCRELAGGREGATES, IFCRELCONTAINEDINSPATIALSTRUCTURE, IFCRELDEFINESBYPROPERTIES, IFCRELASSOCIATESMATERIAL, IFCRELDEFINESBYTYPE, IFCPROJECT, IFCBUILDING } from 'web-ifc';
3
+ import { Mesh, Color, MeshLambertMaterial, DoubleSide, Matrix4, BufferGeometry, BufferAttribute, Loader, FileLoader } from 'three';
4
+ import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
5
+
6
+ const nullIfcManagerErrorMessage = 'IfcManager is null!';
7
+
8
+ class IFCModel extends Mesh {
9
+
10
+ constructor() {
11
+ super(...arguments);
12
+ this.modelID = IFCModel.modelIdCounter++;
13
+ this.ifcManager = null;
14
+ this.mesh = this;
15
+ }
16
+
17
+ static dispose() {
18
+ IFCModel.modelIdCounter = 0;
19
+ }
20
+
21
+ setIFCManager(manager) {
22
+ this.ifcManager = manager;
23
+ }
24
+
25
+ setWasmPath(path) {
26
+ if (this.ifcManager === null)
27
+ throw new Error(nullIfcManagerErrorMessage);
28
+ this.ifcManager.setWasmPath(path);
29
+ }
30
+
31
+ close(scene) {
32
+ if (this.ifcManager === null)
33
+ throw new Error(nullIfcManagerErrorMessage);
34
+ this.ifcManager.close(this.modelID, scene);
35
+ }
36
+
37
+ getExpressId(geometry, faceIndex) {
38
+ if (this.ifcManager === null)
39
+ throw new Error(nullIfcManagerErrorMessage);
40
+ return this.ifcManager.getExpressId(geometry, faceIndex);
41
+ }
42
+
43
+ getAllItemsOfType(type, verbose) {
44
+ if (this.ifcManager === null)
45
+ throw new Error(nullIfcManagerErrorMessage);
46
+ return this.ifcManager.getAllItemsOfType(this.modelID, type, verbose);
47
+ }
48
+
49
+ getItemProperties(id, recursive = false) {
50
+ if (this.ifcManager === null)
51
+ throw new Error(nullIfcManagerErrorMessage);
52
+ return this.ifcManager.getItemProperties(this.modelID, id, recursive);
53
+ }
54
+
55
+ getPropertySets(id, recursive = false) {
56
+ if (this.ifcManager === null)
57
+ throw new Error(nullIfcManagerErrorMessage);
58
+ return this.ifcManager.getPropertySets(this.modelID, id, recursive);
59
+ }
60
+
61
+ getTypeProperties(id, recursive = false) {
62
+ if (this.ifcManager === null)
63
+ throw new Error(nullIfcManagerErrorMessage);
64
+ return this.ifcManager.getTypeProperties(this.modelID, id, recursive);
65
+ }
66
+
67
+ getIfcType(id) {
68
+ if (this.ifcManager === null)
69
+ throw new Error(nullIfcManagerErrorMessage);
70
+ return this.ifcManager.getIfcType(this.modelID, id);
71
+ }
72
+
73
+ getSpatialStructure() {
74
+ if (this.ifcManager === null)
75
+ throw new Error(nullIfcManagerErrorMessage);
76
+ return this.ifcManager.getSpatialStructure(this.modelID);
77
+ }
78
+
79
+ getSubset(material) {
80
+ if (this.ifcManager === null)
81
+ throw new Error(nullIfcManagerErrorMessage);
82
+ return this.ifcManager.getSubset(this.modelID, material);
83
+ }
84
+
85
+ removeSubset(material, customID) {
86
+ if (this.ifcManager === null)
87
+ throw new Error(nullIfcManagerErrorMessage);
88
+ this.ifcManager.removeSubset(this.modelID, material, customID);
89
+ }
90
+
91
+ createSubset(config) {
92
+ if (this.ifcManager === null)
93
+ throw new Error(nullIfcManagerErrorMessage);
94
+ const modelConfig = {
95
+ ...config,
96
+ modelID: this.modelID
97
+ };
98
+ return this.ifcManager.createSubset(modelConfig);
99
+ }
100
+
101
+ }
102
+
103
+ IFCModel.modelIdCounter = 0;
104
+
105
+ class IFCParser {
106
+
107
+ constructor(state, BVH) {
108
+ this.state = state;
109
+ this.BVH = BVH;
110
+ this.loadedModels = 0;
111
+ this.optionalCategories = {
112
+ [IFCSPACE]: true,
113
+ [IFCOPENINGELEMENT]: false
114
+ };
115
+ this.geometriesByMaterials = {};
116
+ this.loadingState = {
117
+ total: 0,
118
+ current: 0,
119
+ step: 0.1
120
+ };
121
+ this.currentWebIfcID = -1;
122
+ this.currentModelID = -1;
123
+ }
124
+
125
+ async setupOptionalCategories(config) {
126
+ this.optionalCategories = config;
127
+ }
128
+
129
+ async parse(buffer, coordinationMatrix) {
130
+ if (this.state.api.wasmModule === undefined)
131
+ await this.state.api.Init();
132
+ await this.newIfcModel(buffer);
133
+ this.loadedModels++;
134
+ if (coordinationMatrix) {
135
+ await this.state.api.SetGeometryTransformation(this.currentWebIfcID, coordinationMatrix);
136
+ }
137
+ return this.loadAllGeometry(this.currentWebIfcID);
138
+ }
139
+
140
+ getAndClearErrors(_modelId) {}
141
+
142
+ notifyProgress(loaded, total) {
143
+ if (this.state.onProgress)
144
+ this.state.onProgress({
145
+ loaded,
146
+ total
147
+ });
148
+ }
149
+
150
+ async newIfcModel(buffer) {
151
+ const data = new Uint8Array(buffer);
152
+ this.currentWebIfcID = await this.state.api.OpenModel(data, this.state.webIfcSettings);
153
+ this.currentModelID = this.state.useJSON ? this.loadedModels : this.currentWebIfcID;
154
+ this.state.models[this.currentModelID] = {
155
+ modelID: this.currentModelID,
156
+ mesh: {},
157
+ types: {},
158
+ jsonData: {}
159
+ };
160
+ }
161
+
162
+ async loadAllGeometry(modelID) {
163
+ this.addOptionalCategories(modelID);
164
+ await this.initializeLoadingState(modelID);
165
+ this.state.api.StreamAllMeshes(modelID, (mesh) => {
166
+ this.updateLoadingState();
167
+ this.streamMesh(modelID, mesh);
168
+ });
169
+ this.notifyLoadingEnded();
170
+ const geometries = [];
171
+ const materials = [];
172
+ Object.keys(this.geometriesByMaterials).forEach((key) => {
173
+ const geometriesByMaterial = this.geometriesByMaterials[key].geometries;
174
+ const merged = mergeBufferGeometries(geometriesByMaterial);
175
+ materials.push(this.geometriesByMaterials[key].material);
176
+ geometries.push(merged);
177
+ });
178
+ const combinedGeometry = mergeBufferGeometries(geometries, true);
179
+ this.cleanUpGeometryMemory(geometries);
180
+ if (this.BVH)
181
+ this.BVH.applyThreeMeshBVH(combinedGeometry);
182
+ const model = new IFCModel(combinedGeometry, materials);
183
+ this.state.models[this.currentModelID].mesh = model;
184
+ return model;
185
+ }
186
+
187
+ async initializeLoadingState(modelID) {
188
+ const shapes = await this.state.api.GetLineIDsWithType(modelID, IFCPRODUCTDEFINITIONSHAPE);
189
+ this.loadingState.total = shapes.size();
190
+ this.loadingState.current = 0;
191
+ this.loadingState.step = 0.1;
192
+ }
193
+
194
+ notifyLoadingEnded() {
195
+ this.notifyProgress(this.loadingState.total, this.loadingState.total);
196
+ }
197
+
198
+ updateLoadingState() {
199
+ const realCurrentItem = Math.min(this.loadingState.current++, this.loadingState.total);
200
+ if (realCurrentItem / this.loadingState.total >= this.loadingState.step) {
201
+ const currentProgress = Math.ceil(this.loadingState.total * this.loadingState.step);
202
+ this.notifyProgress(currentProgress, this.loadingState.total);
203
+ this.loadingState.step += 0.1;
204
+ }
205
+ }
206
+
207
+ addOptionalCategories(modelID) {
208
+ const optionalTypes = [];
209
+ for (let key in this.optionalCategories) {
210
+ if (this.optionalCategories.hasOwnProperty(key)) {
211
+ const category = parseInt(key);
212
+ if (this.optionalCategories[category])
213
+ optionalTypes.push(category);
214
+ }
215
+ }
216
+ this.state.api.StreamAllMeshesWithTypes(this.currentWebIfcID, optionalTypes, (mesh) => {
217
+ this.streamMesh(modelID, mesh);
218
+ });
219
+ }
220
+
221
+ streamMesh(modelID, mesh) {
222
+ const placedGeometries = mesh.geometries;
223
+ const size = placedGeometries.size();
224
+ for (let i = 0; i < size; i++) {
225
+ const placedGeometry = placedGeometries.get(i);
226
+ let itemMesh = this.getPlacedGeometry(modelID, mesh.expressID, placedGeometry);
227
+ let geom = itemMesh.geometry.applyMatrix4(itemMesh.matrix);
228
+ this.storeGeometryByMaterial(placedGeometry.color, geom);
229
+ }
230
+ }
231
+
232
+ getPlacedGeometry(modelID, expressID, placedGeometry) {
233
+ const geometry = this.getBufferGeometry(modelID, expressID, placedGeometry);
234
+ const mesh = new Mesh(geometry);
235
+ mesh.matrix = this.getMeshMatrix(placedGeometry.flatTransformation);
236
+ mesh.matrixAutoUpdate = false;
237
+ return mesh;
238
+ }
239
+
240
+ getBufferGeometry(modelID, expressID, placedGeometry) {
241
+ const geometry = this.state.api.GetGeometry(modelID, placedGeometry.geometryExpressID);
242
+ const verts = this.state.api.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());
243
+ const indices = this.state.api.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());
244
+ const buffer = this.ifcGeometryToBuffer(expressID, verts, indices);
245
+ geometry.delete();
246
+ return buffer;
247
+ }
248
+
249
+ storeGeometryByMaterial(color, geometry) {
250
+ let colID = `${color.x}${color.y}${color.z}${color.w}`;
251
+ if (this.geometriesByMaterials[colID]) {
252
+ this.geometriesByMaterials[colID].geometries.push(geometry);
253
+ return;
254
+ }
255
+ const col = new Color().setRGB(color.x, color.y, color.z, 'srgb');
256
+ const material = new MeshLambertMaterial({
257
+ color: col,
258
+ side: DoubleSide
259
+ });
260
+ material.transparent = color.w !== 1;
261
+ if (material.transparent)
262
+ material.opacity = color.w;
263
+ this.geometriesByMaterials[colID] = {
264
+ material,
265
+ geometries: [geometry]
266
+ };
267
+ }
268
+
269
+ getMeshMatrix(matrix) {
270
+ const mat = new Matrix4();
271
+ mat.fromArray(matrix);
272
+ return mat;
273
+ }
274
+
275
+ ifcGeometryToBuffer(expressID, vertexData, indexData) {
276
+ const geometry = new BufferGeometry();
277
+ const posFloats = new Float32Array(vertexData.length / 2);
278
+ const normFloats = new Float32Array(vertexData.length / 2);
279
+ const idAttribute = new Uint32Array(vertexData.length / 6);
280
+ for (let i = 0; i < vertexData.length; i += 6) {
281
+ posFloats[i / 2] = vertexData[i];
282
+ posFloats[i / 2 + 1] = vertexData[i + 1];
283
+ posFloats[i / 2 + 2] = vertexData[i + 2];
284
+ normFloats[i / 2] = vertexData[i + 3];
285
+ normFloats[i / 2 + 1] = vertexData[i + 4];
286
+ normFloats[i / 2 + 2] = vertexData[i + 5];
287
+ idAttribute[i / 6] = expressID;
288
+ }
289
+ geometry.setAttribute('position', new BufferAttribute(posFloats, 3));
290
+ geometry.setAttribute('normal', new BufferAttribute(normFloats, 3));
291
+ geometry.setAttribute('expressID', new BufferAttribute(idAttribute, 1));
292
+ geometry.setIndex(new BufferAttribute(indexData, 1));
293
+ return geometry;
294
+ }
295
+
296
+ cleanUpGeometryMemory(geometries) {
297
+ geometries.forEach(geometry => geometry.dispose());
298
+ Object.keys(this.geometriesByMaterials).forEach((materialID) => {
299
+ const geometriesByMaterial = this.geometriesByMaterials[materialID];
300
+ geometriesByMaterial.geometries.forEach(geometry => geometry.dispose());
301
+ geometriesByMaterial.geometries = [];
302
+ geometriesByMaterial.material = null;
303
+ });
304
+ this.geometriesByMaterials = {};
305
+ }
306
+
307
+ }
308
+
309
+ class ItemsMap {
310
+
311
+ constructor(state) {
312
+ this.state = state;
313
+ this.map = {};
314
+ }
315
+
316
+ generateGeometryIndexMap(modelID) {
317
+ if (this.map[modelID])
318
+ return;
319
+ const geometry = this.getGeometry(modelID);
320
+ const items = this.newItemsMap(modelID, geometry);
321
+ for (const group of geometry.groups) {
322
+ this.fillItemsWithGroupInfo(group, geometry, items);
323
+ }
324
+ }
325
+
326
+ getSubsetID(modelID, material, customID = 'DEFAULT') {
327
+ const baseID = modelID;
328
+ const materialID = material ? material.uuid : 'DEFAULT';
329
+ return `${baseID} - ${materialID} - ${customID}`;
330
+ }
331
+
332
+ dispose() {
333
+ Object.values(this.map).forEach(model => {
334
+ model.indexCache = null;
335
+ model.map = null;
336
+ });
337
+ this.map = null;
338
+ }
339
+
340
+ getGeometry(modelID) {
341
+ const geometry = this.state.models[modelID].mesh.geometry;
342
+ if (!geometry)
343
+ throw new Error('Model without geometry.');
344
+ if (!geometry.index)
345
+ throw new Error('Geometry must be indexed');
346
+ return geometry;
347
+ }
348
+
349
+ newItemsMap(modelID, geometry) {
350
+ const startIndices = geometry.index.array;
351
+ this.map[modelID] = {
352
+ indexCache: startIndices.slice(0, geometry.index.array.length),
353
+ map: new Map()
354
+ };
355
+ return this.map[modelID];
356
+ }
357
+
358
+ fillItemsWithGroupInfo(group, geometry, items) {
359
+ let prevExpressID = -1;
360
+ const materialIndex = group.materialIndex;
361
+ const materialStart = group.start;
362
+ const materialEnd = materialStart + group.count - 1;
363
+ let objectStart = -1;
364
+ let objectEnd = -1;
365
+ for (let i = materialStart; i <= materialEnd; i++) {
366
+ const index = geometry.index.array[i];
367
+ const bufferAttr = geometry.attributes.expressID;
368
+ const expressID = bufferAttr.array[index];
369
+ if (prevExpressID === -1) {
370
+ prevExpressID = expressID;
371
+ objectStart = i;
372
+ }
373
+ const isEndOfMaterial = i === materialEnd;
374
+ if (isEndOfMaterial) {
375
+ const store = this.getMaterialStore(items.map, expressID, materialIndex);
376
+ store.push(objectStart, materialEnd);
377
+ break;
378
+ }
379
+ if (prevExpressID === expressID)
380
+ continue;
381
+ const store = this.getMaterialStore(items.map, prevExpressID, materialIndex);
382
+ objectEnd = i - 1;
383
+ store.push(objectStart, objectEnd);
384
+ prevExpressID = expressID;
385
+ objectStart = i;
386
+ }
387
+ }
388
+
389
+ getMaterialStore(map, id, matIndex) {
390
+ if (map.get(id) === undefined) {
391
+ map.set(id, {});
392
+ }
393
+ const storedIfcItem = map.get(id);
394
+ if (storedIfcItem === undefined)
395
+ throw new Error('Geometry map generation error');
396
+ if (storedIfcItem[matIndex] === undefined) {
397
+ storedIfcItem[matIndex] = [];
398
+ }
399
+ return storedIfcItem[matIndex];
400
+ }
401
+
402
+ }
403
+
404
+ class SubsetUtils {
405
+
406
+ static getAllIndicesOfGroup(modelID, ids, materialIndex, items, flatten = true) {
407
+ const indicesByGroup = [];
408
+ for (const expressID of ids) {
409
+ const entry = items.map.get(expressID);
410
+ if (!entry)
411
+ continue;
412
+ const value = entry[materialIndex];
413
+ if (!value)
414
+ continue;
415
+ SubsetUtils.getIndexChunk(value, indicesByGroup, materialIndex, items, flatten);
416
+ }
417
+ return indicesByGroup;
418
+ }
419
+
420
+ static getIndexChunk(value, indicesByGroup, materialIndex, items, flatten) {
421
+ const pairs = value.length / 2;
422
+ for (let pair = 0; pair < pairs; pair++) {
423
+ const pairIndex = pair * 2;
424
+ const start = value[pairIndex];
425
+ const end = value[pairIndex + 1];
426
+ for (let j = start; j <= end; j++) {
427
+ if (flatten)
428
+ indicesByGroup.push(items.indexCache[j]);
429
+ else {
430
+ if (!indicesByGroup[materialIndex])
431
+ indicesByGroup[materialIndex] = [];
432
+ indicesByGroup[materialIndex].push(items.indexCache[j]);
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ }
439
+
440
+ class SubsetCreator {
441
+
442
+ constructor(state, items, subsets, BVH) {
443
+ this.state = state;
444
+ this.items = items;
445
+ this.subsets = subsets;
446
+ this.BVH = BVH;
447
+ this.tempIndex = [];
448
+ }
449
+
450
+ createSubset(config, subsetID) {
451
+ if (!this.items.map[config.modelID])
452
+ this.items.generateGeometryIndexMap(config.modelID);
453
+ if (!this.subsets[subsetID])
454
+ this.initializeSubset(config, subsetID);
455
+ this.filterIndices(config, subsetID);
456
+ this.constructSubsetByMaterial(config, subsetID);
457
+ config.ids.forEach(id => this.subsets[subsetID].ids.add(id));
458
+ this.subsets[subsetID].mesh.geometry.setIndex(this.tempIndex);
459
+ this.tempIndex.length = 0;
460
+ const subset = this.subsets[subsetID].mesh;
461
+ if (config.applyBVH)
462
+ this.BVH.applyThreeMeshBVH(subset.geometry);
463
+ if (config.scene)
464
+ config.scene.add(subset);
465
+ return this.subsets[subsetID].mesh;
466
+ }
467
+
468
+ dispose() {
469
+ this.tempIndex = [];
470
+ }
471
+
472
+ initializeSubset(config, subsetID) {
473
+ const model = this.state.models[config.modelID].mesh;
474
+ const subsetGeom = new BufferGeometry();
475
+ this.initializeSubsetAttributes(subsetGeom, model);
476
+ if (!config.material)
477
+ this.initializeSubsetGroups(subsetGeom, model);
478
+ const mesh = new Mesh(subsetGeom, config.material || model.material);
479
+ mesh.modelID = config.modelID;
480
+ const bvh = Boolean(config.applyBVH);
481
+ this.subsets[subsetID] = {
482
+ ids: new Set(),
483
+ mesh,
484
+ bvh
485
+ };
486
+ model.add(mesh);
487
+ }
488
+
489
+ initializeSubsetAttributes(subsetGeom, model) {
490
+ subsetGeom.setAttribute('position', model.geometry.attributes.position);
491
+ subsetGeom.setAttribute('normal', model.geometry.attributes.normal);
492
+ subsetGeom.setAttribute('expressID', model.geometry.attributes.expressID);
493
+ subsetGeom.setIndex([]);
494
+ }
495
+
496
+ initializeSubsetGroups(subsetGeom, model) {
497
+ subsetGeom.groups = JSON.parse(JSON.stringify(model.geometry.groups));
498
+ this.resetGroups(subsetGeom);
499
+ }
500
+
501
+ filterIndices(config, subsetID) {
502
+ const geometry = this.subsets[subsetID].mesh.geometry;
503
+ if (config.removePrevious) {
504
+ geometry.setIndex([]);
505
+ this.resetGroups(geometry);
506
+ return;
507
+ }
508
+ const previousIndices = geometry.index.array;
509
+ const previousIDs = this.subsets[subsetID].ids;
510
+ config.ids = config.ids.filter(id => !previousIDs.has(id));
511
+ this.tempIndex = Array.from(previousIndices);
512
+ }
513
+
514
+ constructSubsetByMaterial(config, subsetID) {
515
+ const model = this.state.models[config.modelID].mesh;
516
+ const newIndices = {
517
+ count: 0
518
+ };
519
+ for (let i = 0; i < model.geometry.groups.length; i++) {
520
+ this.insertNewIndices(config, subsetID, i, newIndices);
521
+ }
522
+ }
523
+
524
+ insertNewIndices(config, subsetID, materialIndex, newIndices) {
525
+ const items = this.items.map[config.modelID];
526
+ const indicesOfOneMaterial = SubsetUtils.getAllIndicesOfGroup(config.modelID, config.ids, materialIndex, items);
527
+ if (!config.material) {
528
+ this.insertIndicesAtGroup(subsetID, indicesOfOneMaterial, materialIndex, newIndices);
529
+ } else {
530
+ indicesOfOneMaterial.forEach(index => this.tempIndex.push(index));
531
+ }
532
+ }
533
+
534
+ insertIndicesAtGroup(subsetID, indicesByGroup, index, newIndices) {
535
+ const currentGroup = this.getCurrentGroup(subsetID, index);
536
+ currentGroup.start += newIndices.count;
537
+ let newIndicesPosition = currentGroup.start + currentGroup.count;
538
+ newIndices.count += indicesByGroup.length;
539
+ if (indicesByGroup.length > 0) {
540
+ let position = newIndicesPosition;
541
+ const start = this.tempIndex.slice(0, position);
542
+ const end = this.tempIndex.slice(position);
543
+ this.tempIndex = Array.prototype.concat.apply([], [start, indicesByGroup, end]);
544
+ currentGroup.count += indicesByGroup.length;
545
+ }
546
+ }
547
+
548
+ getCurrentGroup(subsetID, groupIndex) {
549
+ const geometry = this.subsets[subsetID].mesh.geometry;
550
+ return geometry.groups[groupIndex];
551
+ }
552
+
553
+ resetGroups(geometry) {
554
+ geometry.groups.forEach((group) => {
555
+ group.start = 0;
556
+ group.count = 0;
557
+ });
558
+ }
559
+
560
+ }
561
+
562
+ class SubsetManager {
563
+
564
+ constructor(state, BVH) {
565
+ this.subsets = {};
566
+ this.state = state;
567
+ this.items = new ItemsMap(state);
568
+ this.BVH = BVH;
569
+ this.subsetCreator = new SubsetCreator(state, this.items, this.subsets, this.BVH);
570
+ }
571
+
572
+ getAllSubsets() {
573
+ return this.subsets;
574
+ }
575
+
576
+ getSubset(modelID, material, customId) {
577
+ const subsetID = this.getSubsetID(modelID, material, customId);
578
+ return this.subsets[subsetID].mesh;
579
+ }
580
+
581
+ removeSubset(modelID, material, customID) {
582
+ const subsetID = this.getSubsetID(modelID, material, customID);
583
+ const subset = this.subsets[subsetID];
584
+ if (!subset)
585
+ return;
586
+ if (subset.mesh.parent)
587
+ subset.mesh.removeFromParent();
588
+ subset.mesh.geometry.attributes = {};
589
+ subset.mesh.geometry.index = null;
590
+ subset.mesh.geometry.dispose();
591
+ subset.mesh.geometry = null;
592
+ delete this.subsets[subsetID];
593
+ }
594
+
595
+ createSubset(config) {
596
+ const subsetID = this.getSubsetID(config.modelID, config.material, config.customID);
597
+ return this.subsetCreator.createSubset(config, subsetID);
598
+ }
599
+
600
+ removeFromSubset(modelID, ids, customID, material) {
601
+ const subsetID = this.getSubsetID(modelID, material, customID);
602
+ if (!this.subsets[subsetID])
603
+ return;
604
+ const previousIDs = this.subsets[subsetID].ids;
605
+ ids.forEach((id) => {
606
+ if (previousIDs.has(id))
607
+ previousIDs.delete(id);
608
+ });
609
+ return this.createSubset({
610
+ modelID,
611
+ removePrevious: true,
612
+ material,
613
+ customID,
614
+ applyBVH: this.subsets[subsetID].bvh,
615
+ ids: Array.from(previousIDs),
616
+ scene: this.subsets[subsetID].mesh.parent
617
+ });
618
+ }
619
+
620
+ clearSubset(modelID, customID, material) {
621
+ const subsetID = this.getSubsetID(modelID, material, customID);
622
+ if (!this.subsets[subsetID])
623
+ return;
624
+ this.subsets[subsetID].ids.clear();
625
+ const subset = this.getSubset(modelID, material, customID);
626
+ subset.geometry.setIndex([]);
627
+ }
628
+
629
+ dispose() {
630
+ this.items.dispose();
631
+ this.subsetCreator.dispose();
632
+ Object.values(this.subsets).forEach(subset => {
633
+ subset.ids = null;
634
+ subset.mesh.removeFromParent();
635
+ const mats = subset.mesh.material;
636
+ if (Array.isArray(mats))
637
+ mats.forEach(mat => mat.dispose());
638
+ else
639
+ mats.dispose();
640
+ subset.mesh.geometry.index = null;
641
+ subset.mesh.geometry.dispose();
642
+ const geom = subset.mesh.geometry;
643
+ if (geom.disposeBoundsTree)
644
+ geom.disposeBoundsTree();
645
+ subset.mesh = null;
646
+ });
647
+ this.subsets = null;
648
+ }
649
+
650
+ getSubsetID(modelID, material, customID = 'DEFAULT') {
651
+ const baseID = modelID;
652
+ const materialID = material ? material.uuid : 'DEFAULT';
653
+ return `${baseID} - ${materialID} - ${customID}`;
654
+ }
655
+
656
+ }
657
+
658
+ const IdAttrName = 'expressID';
659
+ const PropsNames = {
660
+ aggregates: {
661
+ name: IFCRELAGGREGATES,
662
+ relating: 'RelatingObject',
663
+ related: 'RelatedObjects',
664
+ key: 'children'
665
+ },
666
+ spatial: {
667
+ name: IFCRELCONTAINEDINSPATIALSTRUCTURE,
668
+ relating: 'RelatingStructure',
669
+ related: 'RelatedElements',
670
+ key: 'children'
671
+ },
672
+ psets: {
673
+ name: IFCRELDEFINESBYPROPERTIES,
674
+ relating: 'RelatingPropertyDefinition',
675
+ related: 'RelatedObjects',
676
+ key: 'hasPsets'
677
+ },
678
+ materials: {
679
+ name: IFCRELASSOCIATESMATERIAL,
680
+ relating: 'RelatingMaterial',
681
+ related: 'RelatedObjects',
682
+ key: 'hasMaterial'
683
+ },
684
+ type: {
685
+ name: IFCRELDEFINESBYTYPE,
686
+ relating: 'RelatingType',
687
+ related: 'RelatedObjects',
688
+ key: 'hasType'
689
+ }
690
+ };
691
+
692
+ class BasePropertyManager {
693
+
694
+ constructor(state) {
695
+ this.state = state;
696
+ }
697
+
698
+ async getPropertySets(modelID, elementID, recursive = false) {
699
+ return await this.getProperty(modelID, elementID, recursive, PropsNames.psets);
700
+ }
701
+
702
+ async getTypeProperties(modelID, elementID, recursive = false) {
703
+ return await this.getProperty(modelID, elementID, recursive, PropsNames.type);
704
+ }
705
+
706
+ async getMaterialsProperties(modelID, elementID, recursive = false) {
707
+ return await this.getProperty(modelID, elementID, recursive, PropsNames.materials);
708
+ }
709
+
710
+ async getSpatialNode(modelID, node, treeChunks, includeProperties) {
711
+ await this.getChildren(modelID, node, treeChunks, PropsNames.aggregates, includeProperties);
712
+ await this.getChildren(modelID, node, treeChunks, PropsNames.spatial, includeProperties);
713
+ }
714
+
715
+ async getChildren(modelID, node, treeChunks, propNames, includeProperties) {
716
+ const children = treeChunks[node.expressID];
717
+ if (children == undefined)
718
+ return;
719
+ const prop = propNames.key;
720
+ const nodes = [];
721
+ for (let i = 0; i < children.length; i++) {
722
+ const child = children[i];
723
+ let node = this.newNode(modelID, child);
724
+ if (includeProperties) {
725
+ const properties = await this.getItemProperties(modelID, node.expressID);
726
+ node = {
727
+ ...properties, ...node
728
+ };
729
+ }
730
+ await this.getSpatialNode(modelID, node, treeChunks, includeProperties);
731
+ nodes.push(node);
732
+ }
733
+ node[prop] = nodes;
734
+ }
735
+
736
+ newNode(modelID, id) {
737
+ const typeName = this.getNodeType(modelID, id);
738
+ return {
739
+ expressID: id,
740
+ type: typeName,
741
+ children: []
742
+ };
743
+ }
744
+
745
+ async getSpatialTreeChunks(modelID) {
746
+ const treeChunks = {};
747
+ await this.getChunks(modelID, treeChunks, PropsNames.aggregates);
748
+ await this.getChunks(modelID, treeChunks, PropsNames.spatial);
749
+ return treeChunks;
750
+ }
751
+
752
+ saveChunk(chunks, propNames, rel) {
753
+ const relating = rel[propNames.relating].value;
754
+ const related = rel[propNames.related].map((r) => r.value);
755
+ if (chunks[relating] == undefined) {
756
+ chunks[relating] = related;
757
+ } else {
758
+ chunks[relating] = chunks[relating].concat(related);
759
+ }
760
+ }
761
+
762
+ getRelated(rel, propNames, IDs) {
763
+ const element = rel[propNames.relating];
764
+ if (!element) {
765
+ return console.warn(`The object with ID ${rel.expressID} has a broken reference.`);
766
+ }
767
+ if (!Array.isArray(element))
768
+ IDs.push(element.value);
769
+ else
770
+ element.forEach((ele) => IDs.push(ele.value));
771
+ }
772
+
773
+ static isRelated(id, rel, propNames) {
774
+ const relatedItems = rel[propNames.related];
775
+ if (Array.isArray(relatedItems)) {
776
+ const values = relatedItems.map((item) => item.value);
777
+ return values.includes(id);
778
+ }
779
+ return relatedItems.value === id;
780
+ }
781
+
782
+ static newIfcProject(id) {
783
+ return {
784
+ expressID: id,
785
+ type: 'IFCPROJECT',
786
+ children: []
787
+ };
788
+ }
789
+
790
+ async getProperty(modelID, elementID, recursive = false, propName) {}
791
+
792
+ async getChunks(modelID, chunks, propNames) {}
793
+
794
+ async getItemProperties(modelID, expressID, recursive = false) {}
795
+
796
+ getNodeType(modelID, id) {}
797
+
798
+ }
799
+
800
+ class WebIfcPropertyManager extends BasePropertyManager {
801
+
802
+ async getItemProperties(modelID, id, recursive = false) {
803
+ return this.state.api.GetLine(modelID, id, recursive);
804
+ }
805
+
806
+ async getHeaderLine(modelID, headerType) {
807
+ return this.state.api.GetHeaderLine(modelID, headerType);
808
+ }
809
+
810
+ async getSpatialStructure(modelID, includeProperties) {
811
+ const chunks = await this.getSpatialTreeChunks(modelID);
812
+ const allLines = await this.state.api.GetLineIDsWithType(modelID, IFCPROJECT);
813
+ const projectID = allLines.get(0);
814
+ const project = WebIfcPropertyManager.newIfcProject(projectID);
815
+ await this.getSpatialNode(modelID, project, chunks, includeProperties);
816
+ return project;
817
+ }
818
+
819
+ async getAllItemsOfType(modelID, type, verbose) {
820
+ let items = [];
821
+ const lines = await this.state.api.GetLineIDsWithType(modelID, type);
822
+ for (let i = 0; i < lines.size(); i++)
823
+ items.push(lines.get(i));
824
+ if (!verbose)
825
+ return items;
826
+ const result = [];
827
+ for (let i = 0; i < items.length; i++) {
828
+ result.push(await this.state.api.GetLine(modelID, items[i]));
829
+ }
830
+ return result;
831
+ }
832
+
833
+ async getProperty(modelID, elementID, recursive = false, propName) {
834
+ const propSetIds = await this.getAllRelatedItemsOfType(modelID, elementID, propName);
835
+ const result = [];
836
+ for (let i = 0; i < propSetIds.length; i++) {
837
+ result.push(await this.state.api.GetLine(modelID, propSetIds[i], recursive));
838
+ }
839
+ return result;
840
+ }
841
+
842
+ getNodeType(modelID, id) {
843
+ const typeID = this.state.models[modelID].types[id];
844
+ return this.state.api.GetNameFromTypeCode(typeID);
845
+ }
846
+
847
+ async getChunks(modelID, chunks, propNames) {
848
+ const relation = await this.state.api.GetLineIDsWithType(modelID, propNames.name);
849
+ for (let i = 0; i < relation.size(); i++) {
850
+ const rel = await this.state.api.GetLine(modelID, relation.get(i), false);
851
+ this.saveChunk(chunks, propNames, rel);
852
+ }
853
+ }
854
+
855
+ async getAllRelatedItemsOfType(modelID, id, propNames) {
856
+ const lines = await this.state.api.GetLineIDsWithType(modelID, propNames.name);
857
+ const IDs = [];
858
+ for (let i = 0; i < lines.size(); i++) {
859
+ const rel = await this.state.api.GetLine(modelID, lines.get(i));
860
+ const isRelated = BasePropertyManager.isRelated(id, rel, propNames);
861
+ if (isRelated)
862
+ this.getRelated(rel, propNames, IDs);
863
+ }
864
+ return IDs;
865
+ }
866
+
867
+ }
868
+
869
+ class JSONPropertyManager extends BasePropertyManager {
870
+
871
+ async getItemProperties(modelID, id, recursive = false) {
872
+ return {
873
+ ...this.state.models[modelID].jsonData[id]
874
+ };
875
+ }
876
+
877
+ async getHeaderLine(modelID) {
878
+ return {};
879
+ }
880
+
881
+ async getSpatialStructure(modelID, includeProperties) {
882
+ const chunks = await this.getSpatialTreeChunks(modelID);
883
+ const projectsIDs = await this.getAllItemsOfType(modelID, IFCPROJECT, false);
884
+ const projectID = projectsIDs[0];
885
+ const project = JSONPropertyManager.newIfcProject(projectID);
886
+ await this.getSpatialNode(modelID, project, chunks, includeProperties);
887
+ return {
888
+ ...project
889
+ };
890
+ }
891
+
892
+ async getAllItemsOfType(modelID, type, verbose) {
893
+ const data = this.state.models[modelID].jsonData;
894
+ const typeName = await this.state.api.GetNameFromTypeCode(type);
895
+ if (!typeName) {
896
+ throw new Error(`Type not found: ${type}`);
897
+ }
898
+ return this.filterItemsByType(data, typeName, verbose);
899
+ }
900
+
901
+ async getProperty(modelID, elementID, recursive = false, propName) {
902
+ const resultIDs = await this.getAllRelatedItemsOfType(modelID, elementID, propName);
903
+ const result = this.getItemsByID(modelID, resultIDs);
904
+ if (recursive) {
905
+ result.forEach(result => this.getReferencesRecursively(modelID, result));
906
+ }
907
+ return result;
908
+ }
909
+
910
+ getNodeType(modelID, id) {
911
+ return this.state.models[modelID].jsonData[id].type;
912
+ }
913
+
914
+ async getChunks(modelID, chunks, propNames) {
915
+ const relation = await this.getAllItemsOfType(modelID, propNames.name, true);
916
+ relation.forEach(rel => {
917
+ this.saveChunk(chunks, propNames, rel);
918
+ });
919
+ }
920
+
921
+ filterItemsByType(data, typeName, verbose) {
922
+ const result = [];
923
+ Object.keys(data).forEach(key => {
924
+ const numKey = parseInt(key);
925
+ if (data[numKey].type.toUpperCase() === typeName) {
926
+ result.push(verbose ? {
927
+ ...data[numKey]
928
+ } : numKey);
929
+ }
930
+ });
931
+ return result;
932
+ }
933
+
934
+ async getAllRelatedItemsOfType(modelID, id, propNames) {
935
+ const lines = await this.getAllItemsOfType(modelID, propNames.name, true);
936
+ const IDs = [];
937
+ lines.forEach(line => {
938
+ const isRelated = JSONPropertyManager.isRelated(id, line, propNames);
939
+ if (isRelated)
940
+ this.getRelated(line, propNames, IDs);
941
+ });
942
+ return IDs;
943
+ }
944
+
945
+ getItemsByID(modelID, ids) {
946
+ const data = this.state.models[modelID].jsonData;
947
+ const result = [];
948
+ ids.forEach(id => result.push({
949
+ ...data[id]
950
+ }));
951
+ return result;
952
+ }
953
+
954
+ getReferencesRecursively(modelID, jsonObject) {
955
+ if (jsonObject == undefined)
956
+ return;
957
+ const keys = Object.keys(jsonObject);
958
+ for (let i = 0; i < keys.length; i++) {
959
+ const key = keys[i];
960
+ this.getJSONItem(modelID, jsonObject, key);
961
+ }
962
+ }
963
+
964
+ getJSONItem(modelID, jsonObject, key) {
965
+ if (Array.isArray(jsonObject[key])) {
966
+ return this.getMultipleJSONItems(modelID, jsonObject, key);
967
+ }
968
+ if (jsonObject[key] && jsonObject[key].type === 5) {
969
+ jsonObject[key] = this.getItemsByID(modelID, [jsonObject[key].value])[0];
970
+ this.getReferencesRecursively(modelID, jsonObject[key]);
971
+ }
972
+ }
973
+
974
+ getMultipleJSONItems(modelID, jsonObject, key) {
975
+ jsonObject[key] = jsonObject[key].map((item) => {
976
+ if (item.type === 5) {
977
+ item = this.getItemsByID(modelID, [item.value])[0];
978
+ this.getReferencesRecursively(modelID, item);
979
+ }
980
+ return item;
981
+ });
982
+ }
983
+
984
+ }
985
+
986
+ const geometryTypes = new Set([
987
+ 1123145078, 574549367, 1675464909, 2059837836, 3798115385, 32440307, 3125803723, 3207858831,
988
+ 2740243338, 2624227202, 4240577450, 3615266464, 3724593414, 220341763, 477187591, 1878645084,
989
+ 1300840506, 3303107099, 1607154358, 1878645084, 846575682, 1351298697, 2417041796, 3049322572,
990
+ 3331915920, 1416205885, 776857604, 3285139300, 3958052878, 2827736869, 2732653382, 673634403,
991
+ 3448662350, 4142052618, 2924175390, 803316827, 2556980723, 1809719519, 2205249479, 807026263,
992
+ 3737207727, 1660063152, 2347385850, 3940055652, 2705031697, 3732776249, 2485617015, 2611217952,
993
+ 1704287377, 2937912522, 2770003689, 1281925730, 1484403080, 3448662350, 4142052618, 3800577675,
994
+ 4006246654, 3590301190, 1383045692, 2775532180, 2047409740, 370225590, 3593883385, 2665983363,
995
+ 4124623270, 812098782, 3649129432, 987898635, 1105321065, 3510044353, 1635779807, 2603310189,
996
+ 3406155212, 1310608509, 4261334040, 2736907675, 3649129432, 1136057603, 1260505505, 4182860854,
997
+ 2713105998, 2898889636, 59481748, 3749851601, 3486308946, 3150382593, 1062206242, 3264961684,
998
+ 15328376, 1485152156, 370225590, 1981873012, 2859738748, 45288368, 2614616156, 2732653382,
999
+ 775493141, 2147822146, 2601014836, 2629017746, 1186437898, 2367409068, 1213902940, 3632507154,
1000
+ 3900360178, 476780140, 1472233963, 2804161546, 3008276851, 738692330, 374418227, 315944413,
1001
+ 3905492369, 3570813810, 2571569899, 178912537, 2294589976, 1437953363, 2133299955, 572779678,
1002
+ 3092502836, 388784114, 2624227202, 1425443689, 3057273783, 2347385850, 1682466193, 2519244187,
1003
+ 2839578677, 3958567839, 2513912981, 2830218821, 427810014
1004
+ ]);
1005
+
1006
+ class PropertySerializer {
1007
+
1008
+ constructor(webIfc) {
1009
+ this.webIfc = webIfc;
1010
+ }
1011
+
1012
+ dispose() {
1013
+ this.webIfc = null;
1014
+ }
1015
+
1016
+ async serializeAllProperties(modelID, maxSize, event) {
1017
+ const blobs = [];
1018
+ await this.getPropertiesAsBlobs(modelID, blobs, maxSize, event);
1019
+ return blobs;
1020
+ }
1021
+
1022
+ async getPropertiesAsBlobs(modelID, blobs, maxSize, event) {
1023
+ const geometriesIDs = await this.getAllGeometriesIDs(modelID);
1024
+ let properties = await this.initializePropertiesObject(modelID);
1025
+ const allLinesIDs = await this.webIfc.GetAllLines(modelID);
1026
+ const linesCount = allLinesIDs.size();
1027
+ let lastEvent = 0.1;
1028
+ let counter = 0;
1029
+ for (let i = 0; i < linesCount; i++) {
1030
+ const id = allLinesIDs.get(i);
1031
+ if (!geometriesIDs.has(id)) {
1032
+ await this.getItemProperty(modelID, id, properties);
1033
+ counter++;
1034
+ }
1035
+ if (maxSize && counter > maxSize) {
1036
+ blobs.push(new Blob([JSON.stringify(properties)], {
1037
+ type: 'application/json'
1038
+ }));
1039
+ properties = {};
1040
+ counter = 0;
1041
+ }
1042
+ if (event && i / linesCount > lastEvent) {
1043
+ event(i, linesCount);
1044
+ lastEvent += 0.1;
1045
+ }
1046
+ }
1047
+ blobs.push(new Blob([JSON.stringify(properties)], {
1048
+ type: 'application/json'
1049
+ }));
1050
+ }
1051
+
1052
+ async getItemProperty(modelID, id, properties) {
1053
+ try {
1054
+ const props = await this.webIfc.GetLine(modelID, id);
1055
+ if (props.type) {
1056
+ props.type = this.webIfc.GetNameFromTypeCode(props.type);
1057
+ }
1058
+ this.formatItemProperties(props);
1059
+ properties[id] = props;
1060
+ } catch (e) {
1061
+ console.log(`There was a problem getting the properties of the item with ID ${id}`);
1062
+ }
1063
+ }
1064
+
1065
+ formatItemProperties(props) {
1066
+ Object.keys(props).forEach((key) => {
1067
+ const value = props[key];
1068
+ if (value && value.value !== undefined)
1069
+ props[key] = value.value;
1070
+ else if (Array.isArray(value))
1071
+ props[key] = value.map((item) => {
1072
+ if (item && item.value)
1073
+ return item.value;
1074
+ return item;
1075
+ });
1076
+ });
1077
+ }
1078
+
1079
+ async initializePropertiesObject(modelID) {
1080
+ return {
1081
+ coordinationMatrix: await this.webIfc.GetCoordinationMatrix(modelID),
1082
+ globalHeight: await this.getBuildingHeight(modelID)
1083
+ };
1084
+ }
1085
+
1086
+ async getBuildingHeight(modelID) {
1087
+ const building = await this.getBuilding(modelID);
1088
+ let placement;
1089
+ const siteReference = building.ObjectPlacement.PlacementRelTo;
1090
+ if (siteReference)
1091
+ placement = siteReference.RelativePlacement.Location;
1092
+ else
1093
+ placement = building.ObjectPlacement.RelativePlacement.Location;
1094
+ const transform = placement.Coordinates.map((coord) => coord.value);
1095
+ return transform[2];
1096
+ }
1097
+
1098
+ async getBuilding(modelID) {
1099
+ const allBuildingsIDs = await this.webIfc.GetLineIDsWithType(modelID, IFCBUILDING);
1100
+ const buildingID = allBuildingsIDs.get(0);
1101
+ return this.webIfc.GetLine(modelID, buildingID, true);
1102
+ }
1103
+
1104
+ async getAllGeometriesIDs(modelID) {
1105
+ const geometriesIDs = new Set();
1106
+ const geomTypesArray = Array.from(geometryTypes);
1107
+ for (let i = 0; i < geomTypesArray.length; i++) {
1108
+ const category = geomTypesArray[i];
1109
+ const ids = await this.webIfc.GetLineIDsWithType(modelID, category);
1110
+ const idsSize = ids.size();
1111
+ for (let j = 0; j < idsSize; j++) {
1112
+ geometriesIDs.add(ids.get(j));
1113
+ }
1114
+ }
1115
+ return geometriesIDs;
1116
+ }
1117
+
1118
+ }
1119
+
1120
+ class PropertyManager {
1121
+
1122
+ constructor(state) {
1123
+ this.state = state;
1124
+ this.webIfcProps = new WebIfcPropertyManager(state);
1125
+ this.jsonProps = new JSONPropertyManager(state);
1126
+ this.currentProps = this.webIfcProps;
1127
+ this.serializer = new PropertySerializer(this.state.api);
1128
+ }
1129
+
1130
+ getExpressId(geometry, faceIndex) {
1131
+ if (!geometry.index)
1132
+ throw new Error('Geometry does not have index information.');
1133
+ const geoIndex = geometry.index.array;
1134
+ const bufferAttr = geometry.attributes[IdAttrName];
1135
+ return bufferAttr.getX(geoIndex[3 * faceIndex]);
1136
+ }
1137
+
1138
+ async getHeaderLine(modelID, headerType) {
1139
+ this.updateCurrentProps();
1140
+ return this.currentProps.getHeaderLine(modelID, headerType);
1141
+ }
1142
+
1143
+ async getItemProperties(modelID, elementID, recursive = false) {
1144
+ this.updateCurrentProps();
1145
+ return this.currentProps.getItemProperties(modelID, elementID, recursive);
1146
+ }
1147
+
1148
+ async getAllItemsOfType(modelID, type, verbose) {
1149
+ this.updateCurrentProps();
1150
+ return this.currentProps.getAllItemsOfType(modelID, type, verbose);
1151
+ }
1152
+
1153
+ async getPropertySets(modelID, elementID, recursive = false) {
1154
+ this.updateCurrentProps();
1155
+ return this.currentProps.getPropertySets(modelID, elementID, recursive);
1156
+ }
1157
+
1158
+ async getTypeProperties(modelID, elementID, recursive = false) {
1159
+ this.updateCurrentProps();
1160
+ return this.currentProps.getTypeProperties(modelID, elementID, recursive);
1161
+ }
1162
+
1163
+ async getMaterialsProperties(modelID, elementID, recursive = false) {
1164
+ this.updateCurrentProps();
1165
+ return this.currentProps.getMaterialsProperties(modelID, elementID, recursive);
1166
+ }
1167
+
1168
+ async getSpatialStructure(modelID, includeProperties) {
1169
+ this.updateCurrentProps();
1170
+ if (!this.state.useJSON && includeProperties) {
1171
+ console.warn('Including properties in getSpatialStructure with the JSON workflow disabled can lead to poor performance.');
1172
+ }
1173
+ return await this.currentProps.getSpatialStructure(modelID, includeProperties);
1174
+ }
1175
+
1176
+ updateCurrentProps() {
1177
+ this.currentProps = this.state.useJSON ? this.jsonProps : this.webIfcProps;
1178
+ }
1179
+
1180
+ }
1181
+
1182
+ class TypeManager {
1183
+
1184
+ constructor(state) {
1185
+ this.state = state;
1186
+ this.state = state;
1187
+ }
1188
+
1189
+ async getAllTypes(worker) {
1190
+ for (let modelID in this.state.models) {
1191
+ if (this.state.models.hasOwnProperty(modelID)) {
1192
+ const types = this.state.models[modelID].types;
1193
+ if (Object.keys(types).length == 0) {
1194
+ await this.getAllTypesOfModel(parseInt(modelID), worker);
1195
+ }
1196
+ }
1197
+ }
1198
+ }
1199
+
1200
+ async getAllTypesOfModel(modelID, worker) {
1201
+ const result = {};
1202
+ const elements = await this.state.api.GetIfcEntityList(modelID);
1203
+ for (let i = 0; i < elements.length; i++) {
1204
+ const element = elements[i];
1205
+ const lines = await this.state.api.GetLineIDsWithType(modelID, element);
1206
+ const size = lines.size();
1207
+ for (let i = 0; i < size; i++)
1208
+ result[lines.get(i)] = element;
1209
+ }
1210
+ if (this.state.worker.active && worker) {
1211
+ await worker.workerState.updateModelStateTypes(modelID, result);
1212
+ }
1213
+ this.state.models[modelID].types = result;
1214
+ }
1215
+
1216
+ }
1217
+
1218
+ class BvhManager {
1219
+
1220
+ initializeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast) {
1221
+ this.computeBoundsTree = computeBoundsTree;
1222
+ this.disposeBoundsTree = disposeBoundsTree;
1223
+ this.acceleratedRaycast = acceleratedRaycast;
1224
+ this.setupThreeMeshBVH();
1225
+ }
1226
+
1227
+ applyThreeMeshBVH(geometry) {
1228
+ if (this.computeBoundsTree)
1229
+ geometry.computeBoundsTree();
1230
+ }
1231
+
1232
+ setupThreeMeshBVH() {
1233
+ if (!this.computeBoundsTree || !this.disposeBoundsTree || !this.acceleratedRaycast)
1234
+ return;
1235
+ BufferGeometry.prototype.computeBoundsTree = this.computeBoundsTree;
1236
+ BufferGeometry.prototype.disposeBoundsTree = this.disposeBoundsTree;
1237
+ Mesh.prototype.raycast = this.acceleratedRaycast;
1238
+ }
1239
+
1240
+ }
1241
+
1242
+ var WorkerActions;
1243
+ (function(WorkerActions) {
1244
+ WorkerActions["updateStateUseJson"] = "updateStateUseJson";
1245
+ WorkerActions["updateStateWebIfcSettings"] = "updateStateWebIfcSettings";
1246
+ WorkerActions["updateModelStateTypes"] = "updateModelStateTypes";
1247
+ WorkerActions["updateModelStateJsonData"] = "updateModelStateJsonData";
1248
+ WorkerActions["loadJsonDataFromWorker"] = "loadJsonDataFromWorker";
1249
+ WorkerActions["dispose"] = "dispose";
1250
+ WorkerActions["Close"] = "Close";
1251
+ WorkerActions["DisposeWebIfc"] = "DisposeWebIfc";
1252
+ WorkerActions["Init"] = "Init";
1253
+ WorkerActions["OpenModel"] = "OpenModel";
1254
+ WorkerActions["CreateModel"] = "CreateModel";
1255
+ WorkerActions["ExportFileAsIFC"] = "ExportFileAsIFC";
1256
+ WorkerActions["GetGeometry"] = "GetGeometry";
1257
+ WorkerActions["GetLine"] = "GetLine";
1258
+ WorkerActions["GetAndClearErrors"] = "GetAndClearErrors";
1259
+ WorkerActions["WriteLine"] = "WriteLine";
1260
+ WorkerActions["FlattenLine"] = "FlattenLine";
1261
+ WorkerActions["GetRawLineData"] = "GetRawLineData";
1262
+ WorkerActions["WriteRawLineData"] = "WriteRawLineData";
1263
+ WorkerActions["GetLineIDsWithType"] = "GetLineIDsWithType";
1264
+ WorkerActions["GetAllLines"] = "GetAllLines";
1265
+ WorkerActions["SetGeometryTransformation"] = "SetGeometryTransformation";
1266
+ WorkerActions["GetCoordinationMatrix"] = "GetCoordinationMatrix";
1267
+ WorkerActions["GetVertexArray"] = "GetVertexArray";
1268
+ WorkerActions["GetIndexArray"] = "GetIndexArray";
1269
+ WorkerActions["getSubArray"] = "getSubArray";
1270
+ WorkerActions["CloseModel"] = "CloseModel";
1271
+ WorkerActions["StreamAllMeshes"] = "StreamAllMeshes";
1272
+ WorkerActions["StreamAllMeshesWithTypes"] = "StreamAllMeshesWithTypes";
1273
+ WorkerActions["IsModelOpen"] = "IsModelOpen";
1274
+ WorkerActions["LoadAllGeometry"] = "LoadAllGeometry";
1275
+ WorkerActions["GetFlatMesh"] = "GetFlatMesh";
1276
+ WorkerActions["SetWasmPath"] = "SetWasmPath";
1277
+ WorkerActions["GetNameFromTypeCode"] = "GetNameFromTypeCode";
1278
+ WorkerActions["GetIfcEntityList"] = "GetIfcEntityList";
1279
+ WorkerActions["GetTypeCodeFromName"] = "GetTypeCodeFromName";
1280
+ WorkerActions["parse"] = "parse";
1281
+ WorkerActions["setupOptionalCategories"] = "setupOptionalCategories";
1282
+ WorkerActions["getExpressId"] = "getExpressId";
1283
+ WorkerActions["initializeProperties"] = "initializeProperties";
1284
+ WorkerActions["getAllItemsOfType"] = "getAllItemsOfType";
1285
+ WorkerActions["getItemProperties"] = "getItemProperties";
1286
+ WorkerActions["getMaterialsProperties"] = "getMaterialsProperties";
1287
+ WorkerActions["getPropertySets"] = "getPropertySets";
1288
+ WorkerActions["getSpatialStructure"] = "getSpatialStructure";
1289
+ WorkerActions["getTypeProperties"] = "getTypeProperties";
1290
+ WorkerActions["getHeaderLine"] = "getHeaderLine";
1291
+ })(WorkerActions || (WorkerActions = {}));
1292
+ var WorkerAPIs;
1293
+ (function(WorkerAPIs) {
1294
+ WorkerAPIs["workerState"] = "workerState";
1295
+ WorkerAPIs["webIfc"] = "webIfc";
1296
+ WorkerAPIs["properties"] = "properties";
1297
+ WorkerAPIs["parser"] = "parser";
1298
+ })(WorkerAPIs || (WorkerAPIs = {}));
1299
+
1300
+ class Vector {
1301
+
1302
+ constructor(vector) {
1303
+ this._data = {};
1304
+ this._size = vector.size;
1305
+ const keys = Object.keys(vector).filter((key) => key.indexOf('size') === -1).map(key => parseInt(key));
1306
+ keys.forEach((key) => this._data[key] = vector[key]);
1307
+ }
1308
+
1309
+ size() {
1310
+ return this._size;
1311
+ }
1312
+
1313
+ get(index) {
1314
+ return this._data[index];
1315
+ }
1316
+
1317
+ }
1318
+
1319
+ class IfcGeometry {
1320
+
1321
+ constructor(vector) {
1322
+ this._GetVertexData = vector.GetVertexData;
1323
+ this._GetVertexDataSize = vector.GetVertexDataSize;
1324
+ this._GetIndexData = vector.GetIndexData;
1325
+ this._GetIndexDataSize = vector.GetIndexDataSize;
1326
+ }
1327
+
1328
+ GetVertexData() {
1329
+ return this._GetVertexData;
1330
+ }
1331
+
1332
+ GetVertexDataSize() {
1333
+ return this._GetVertexDataSize;
1334
+ }
1335
+
1336
+ GetIndexData() {
1337
+ return this._GetIndexData;
1338
+ }
1339
+
1340
+ GetIndexDataSize() {
1341
+ return this._GetIndexDataSize;
1342
+ }
1343
+
1344
+ }
1345
+
1346
+ class FlatMesh {
1347
+
1348
+ constructor(serializer, flatMesh) {
1349
+ this.expressID = flatMesh.expressID;
1350
+ this.geometries = serializer.reconstructVector(flatMesh.geometries);
1351
+ }
1352
+
1353
+ }
1354
+
1355
+ class FlatMeshVector {
1356
+
1357
+ constructor(serializer, vector) {
1358
+ this._data = {};
1359
+ this._size = vector.size;
1360
+ const keys = Object.keys(vector).filter((key) => key.indexOf('size') === -1).map(key => parseInt(key));
1361
+ keys.forEach(key => this._data[key] = serializer.reconstructFlatMesh(vector[key]));
1362
+ }
1363
+
1364
+ size() {
1365
+ return this._size;
1366
+ }
1367
+
1368
+ get(index) {
1369
+ return this._data[index];
1370
+ }
1371
+
1372
+ }
1373
+
1374
+ class SerializedMaterial {
1375
+
1376
+ constructor(material) {
1377
+ this.color = [material.color.r, material.color.g, material.color.b];
1378
+ this.opacity = material.opacity;
1379
+ this.transparent = material.transparent;
1380
+ }
1381
+
1382
+ }
1383
+
1384
+ class MaterialReconstructor {
1385
+
1386
+ static new(material) {
1387
+ return new MeshLambertMaterial({
1388
+ color: new Color(material.color[0], material.color[1], material.color[2]),
1389
+ opacity: material.opacity,
1390
+ transparent: material.transparent,
1391
+ side: DoubleSide
1392
+ });
1393
+ }
1394
+
1395
+ }
1396
+
1397
+ class SerializedGeometry {
1398
+
1399
+ constructor(geometry) {
1400
+ var _a,
1401
+ _b,
1402
+ _c,
1403
+ _d;
1404
+ this.position = ((_a = geometry.attributes.position) === null || _a === void 0 ? void 0 : _a.array) || [];
1405
+ this.normal = ((_b = geometry.attributes.normal) === null || _b === void 0 ? void 0 : _b.array) || [];
1406
+ this.expressID = ((_c = geometry.attributes.expressID) === null || _c === void 0 ? void 0 : _c.array) || [];
1407
+ this.index = ((_d = geometry.index) === null || _d === void 0 ? void 0 : _d.array) || [];
1408
+ this.groups = geometry.groups;
1409
+ }
1410
+
1411
+ }
1412
+
1413
+ class GeometryReconstructor {
1414
+
1415
+ static new(serialized) {
1416
+ const geom = new BufferGeometry();
1417
+ GeometryReconstructor.set(geom, 'expressID', new Uint32Array(serialized.expressID), 1);
1418
+ GeometryReconstructor.set(geom, 'position', new Float32Array(serialized.position), 3);
1419
+ GeometryReconstructor.set(geom, 'normal', new Float32Array(serialized.normal), 3);
1420
+ geom.setIndex(Array. from (serialized.index));
1421
+ geom.groups = serialized.groups;
1422
+ return geom;
1423
+ }
1424
+
1425
+ static set(geom, name, data, size) {
1426
+ if (data.length > 0) {
1427
+ geom.setAttribute(name, new BufferAttribute(data, size));
1428
+ }
1429
+ }
1430
+
1431
+ }
1432
+
1433
+ class SerializedMesh {
1434
+
1435
+ constructor(model) {
1436
+ this.materials = [];
1437
+ this.modelID = model.modelID;
1438
+ this.geometry = new SerializedGeometry(model.geometry);
1439
+ if (Array.isArray(model.material)) {
1440
+ model.material.forEach(mat => {
1441
+ this.materials.push(new SerializedMaterial(mat));
1442
+ });
1443
+ } else {
1444
+ this.materials.push(new SerializedMaterial(model.material));
1445
+ }
1446
+ }
1447
+
1448
+ }
1449
+
1450
+ class MeshReconstructor {
1451
+
1452
+ static new(serialized) {
1453
+ const model = new IFCModel();
1454
+ model.modelID = serialized.modelID;
1455
+ model.geometry = GeometryReconstructor.new(serialized.geometry);
1456
+ MeshReconstructor.getMaterials(serialized, model);
1457
+ return model;
1458
+ }
1459
+
1460
+ static getMaterials(serialized, model) {
1461
+ model.material = [];
1462
+ const mats = model.material;
1463
+ serialized.materials.forEach(mat => {
1464
+ mats.push(MaterialReconstructor.new(mat));
1465
+ });
1466
+ }
1467
+
1468
+ }
1469
+
1470
+ class Serializer {
1471
+
1472
+ serializeVector(vector) {
1473
+ const size = vector.size();
1474
+ const serialized = {
1475
+ size
1476
+ };
1477
+ for (let i = 0; i < size; i++) {
1478
+ serialized[i] = vector.get(i);
1479
+ }
1480
+ return serialized;
1481
+ }
1482
+
1483
+ reconstructVector(vector) {
1484
+ return new Vector(vector);
1485
+ }
1486
+
1487
+ serializeIfcGeometry(geometry) {
1488
+ const GetVertexData = geometry.GetVertexData();
1489
+ const GetVertexDataSize = geometry.GetVertexDataSize();
1490
+ const GetIndexData = geometry.GetIndexData();
1491
+ const GetIndexDataSize = geometry.GetIndexDataSize();
1492
+ return {
1493
+ GetVertexData,
1494
+ GetVertexDataSize,
1495
+ GetIndexData,
1496
+ GetIndexDataSize
1497
+ };
1498
+ }
1499
+
1500
+ reconstructIfcGeometry(geometry) {
1501
+ return new IfcGeometry(geometry);
1502
+ }
1503
+
1504
+ serializeFlatMesh(flatMesh) {
1505
+ return {
1506
+ expressID: flatMesh.expressID,
1507
+ geometries: this.serializeVector(flatMesh.geometries)
1508
+ };
1509
+ }
1510
+
1511
+ reconstructFlatMesh(flatMesh) {
1512
+ return new FlatMesh(this, flatMesh);
1513
+ }
1514
+
1515
+ serializeFlatMeshVector(vector) {
1516
+ const size = vector.size();
1517
+ const serialized = {
1518
+ size
1519
+ };
1520
+ for (let i = 0; i < size; i++) {
1521
+ const flatMesh = vector.get(i);
1522
+ serialized[i] = this.serializeFlatMesh(flatMesh);
1523
+ }
1524
+ return serialized;
1525
+ }
1526
+
1527
+ reconstructFlatMeshVector(vector) {
1528
+ return new FlatMeshVector(this, vector);
1529
+ }
1530
+
1531
+ serializeIfcModel(model) {
1532
+ return new SerializedMesh(model);
1533
+ }
1534
+
1535
+ reconstructIfcModel(model) {
1536
+ return MeshReconstructor.new(model);
1537
+ }
1538
+
1539
+ }
1540
+
1541
+ class PropertyHandler {
1542
+
1543
+ constructor(handler) {
1544
+ this.handler = handler;
1545
+ this.API = WorkerAPIs.properties;
1546
+ }
1547
+
1548
+ getExpressId(geometry, faceIndex) {
1549
+ if (!geometry.index)
1550
+ throw new Error('Geometry does not have index information.');
1551
+ const geoIndex = geometry.index.array;
1552
+ const bufferAttr = geometry.attributes[IdAttrName];
1553
+ return bufferAttr.getX(geoIndex[3 * faceIndex]);
1554
+ }
1555
+
1556
+ getHeaderLine(modelID, headerType) {
1557
+ return this.handler.request(this.API, WorkerActions.getHeaderLine, {
1558
+ modelID,
1559
+ headerType
1560
+ });
1561
+ }
1562
+
1563
+ getAllItemsOfType(modelID, type, verbose) {
1564
+ return this.handler.request(this.API, WorkerActions.getAllItemsOfType, {
1565
+ modelID,
1566
+ type,
1567
+ verbose
1568
+ });
1569
+ }
1570
+
1571
+ getItemProperties(modelID, elementID, recursive) {
1572
+ return this.handler.request(this.API, WorkerActions.getItemProperties, {
1573
+ modelID,
1574
+ elementID,
1575
+ recursive
1576
+ });
1577
+ }
1578
+
1579
+ getMaterialsProperties(modelID, elementID, recursive) {
1580
+ return this.handler.request(this.API, WorkerActions.getMaterialsProperties, {
1581
+ modelID,
1582
+ elementID,
1583
+ recursive
1584
+ });
1585
+ }
1586
+
1587
+ getPropertySets(modelID, elementID, recursive) {
1588
+ return this.handler.request(this.API, WorkerActions.getPropertySets, {
1589
+ modelID,
1590
+ elementID,
1591
+ recursive
1592
+ });
1593
+ }
1594
+
1595
+ getTypeProperties(modelID, elementID, recursive) {
1596
+ return this.handler.request(this.API, WorkerActions.getTypeProperties, {
1597
+ modelID,
1598
+ elementID,
1599
+ recursive
1600
+ });
1601
+ }
1602
+
1603
+ getSpatialStructure(modelID, includeProperties) {
1604
+ return this.handler.request(this.API, WorkerActions.getSpatialStructure, {
1605
+ modelID,
1606
+ includeProperties
1607
+ });
1608
+ }
1609
+
1610
+ }
1611
+
1612
+ class WebIfcHandler {
1613
+
1614
+ constructor(handler, serializer) {
1615
+ this.handler = handler;
1616
+ this.serializer = serializer;
1617
+ this.API = WorkerAPIs.webIfc;
1618
+ }
1619
+
1620
+ async Init() {
1621
+ this.wasmModule = true;
1622
+ return this.handler.request(this.API, WorkerActions.Init);
1623
+ }
1624
+
1625
+ async OpenModel(data, settings) {
1626
+ return this.handler.request(this.API, WorkerActions.OpenModel, {
1627
+ data,
1628
+ settings
1629
+ });
1630
+ }
1631
+
1632
+ async CreateModel(model, settings) {
1633
+ return this.handler.request(this.API, WorkerActions.CreateModel, {
1634
+ model,
1635
+ settings
1636
+ });
1637
+ }
1638
+
1639
+ async ExportFileAsIFC(modelID) {
1640
+ return this.handler.request(this.API, WorkerActions.ExportFileAsIFC, {
1641
+ modelID
1642
+ });
1643
+ }
1644
+
1645
+ async GetHeaderLine(modelID, headerType) {
1646
+ return this.handler.request(this.API, WorkerActions.getHeaderLine, {
1647
+ modelID,
1648
+ headerType
1649
+ });
1650
+ }
1651
+
1652
+ async GetGeometry(modelID, geometryExpressID) {
1653
+ this.handler.serializeHandlers[this.handler.requestID] = (geom) => {
1654
+ return this.serializer.reconstructIfcGeometry(geom);
1655
+ };
1656
+ return this.handler.request(this.API, WorkerActions.GetGeometry, {
1657
+ modelID,
1658
+ geometryExpressID
1659
+ });
1660
+ }
1661
+
1662
+ async GetLine(modelID, expressID, flatten) {
1663
+ return this.handler.request(this.API, WorkerActions.GetLine, {
1664
+ modelID,
1665
+ expressID,
1666
+ flatten
1667
+ });
1668
+ }
1669
+
1670
+ async GetAndClearErrors(modelID) {
1671
+ this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
1672
+ return this.serializer.reconstructVector(vector);
1673
+ };
1674
+ return this.handler.request(this.API, WorkerActions.GetAndClearErrors, {
1675
+ modelID
1676
+ });
1677
+ }
1678
+
1679
+ async GetNameFromTypeCode(type) {
1680
+ return this.handler.request(this.API, WorkerActions.GetNameFromTypeCode, {
1681
+ type
1682
+ });
1683
+ }
1684
+
1685
+ async GetIfcEntityList(modelID) {
1686
+ return this.handler.request(this.API, WorkerActions.GetIfcEntityList, {
1687
+ modelID
1688
+ });
1689
+ }
1690
+
1691
+ async GetTypeCodeFromName(modelID, typeName) {
1692
+ return this.handler.request(this.API, WorkerActions.GetTypeCodeFromName, {
1693
+ modelID,
1694
+ typeName
1695
+ });
1696
+ }
1697
+
1698
+ async WriteLine(modelID, lineObject) {
1699
+ return this.handler.request(this.API, WorkerActions.WriteLine, {
1700
+ modelID,
1701
+ lineObject
1702
+ });
1703
+ }
1704
+
1705
+ async FlattenLine(modelID, line) {
1706
+ return this.handler.request(this.API, WorkerActions.FlattenLine, {
1707
+ modelID,
1708
+ line
1709
+ });
1710
+ }
1711
+
1712
+ async GetRawLineData(modelID, expressID) {
1713
+ return this.handler.request(this.API, WorkerActions.GetRawLineData, {
1714
+ modelID,
1715
+ expressID
1716
+ });
1717
+ }
1718
+
1719
+ async WriteRawLineData(modelID, data) {
1720
+ return this.handler.request(this.API, WorkerActions.WriteRawLineData, {
1721
+ modelID,
1722
+ data
1723
+ });
1724
+ }
1725
+
1726
+ async GetLineIDsWithType(modelID, type) {
1727
+ this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
1728
+ return this.serializer.reconstructVector(vector);
1729
+ };
1730
+ return this.handler.request(this.API, WorkerActions.GetLineIDsWithType, {
1731
+ modelID,
1732
+ type
1733
+ });
1734
+ }
1735
+
1736
+ async GetAllLines(modelID) {
1737
+ this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
1738
+ return this.serializer.reconstructVector(vector);
1739
+ };
1740
+ return this.handler.request(this.API, WorkerActions.GetAllLines, {
1741
+ modelID
1742
+ });
1743
+ }
1744
+
1745
+ async SetGeometryTransformation(modelID, transformationMatrix) {
1746
+ return this.handler.request(this.API, WorkerActions.SetGeometryTransformation, {
1747
+ modelID,
1748
+ transformationMatrix
1749
+ });
1750
+ }
1751
+
1752
+ async GetCoordinationMatrix(modelID) {
1753
+ return this.handler.request(this.API, WorkerActions.GetCoordinationMatrix, {
1754
+ modelID
1755
+ });
1756
+ }
1757
+
1758
+ async GetVertexArray(ptr, size) {
1759
+ return this.handler.request(this.API, WorkerActions.GetVertexArray, {
1760
+ ptr,
1761
+ size
1762
+ });
1763
+ }
1764
+
1765
+ async GetIndexArray(ptr, size) {
1766
+ return this.handler.request(this.API, WorkerActions.GetIndexArray, {
1767
+ ptr,
1768
+ size
1769
+ });
1770
+ }
1771
+
1772
+ async getSubArray(heap, startPtr, sizeBytes) {
1773
+ return this.handler.request(this.API, WorkerActions.getSubArray, {
1774
+ heap,
1775
+ startPtr,
1776
+ sizeBytes
1777
+ });
1778
+ }
1779
+
1780
+ async CloseModel(modelID) {
1781
+ return this.handler.request(this.API, WorkerActions.CloseModel, {
1782
+ modelID
1783
+ });
1784
+ }
1785
+
1786
+ async StreamAllMeshes(modelID, meshCallback) {
1787
+ this.handler.callbackHandlers[this.handler.requestID] = {
1788
+ action: meshCallback,
1789
+ serializer: this.serializer.reconstructFlatMesh
1790
+ };
1791
+ return this.handler.request(this.API, WorkerActions.StreamAllMeshes, {
1792
+ modelID
1793
+ });
1794
+ }
1795
+
1796
+ async StreamAllMeshesWithTypes(modelID, types, meshCallback) {
1797
+ this.handler.callbackHandlers[this.handler.requestID] = {
1798
+ action: meshCallback,
1799
+ serializer: this.serializer.reconstructFlatMesh
1800
+ };
1801
+ return this.handler.request(this.API, WorkerActions.StreamAllMeshesWithTypes, {
1802
+ modelID,
1803
+ types
1804
+ });
1805
+ }
1806
+
1807
+ async IsModelOpen(modelID) {
1808
+ return this.handler.request(this.API, WorkerActions.IsModelOpen, {
1809
+ modelID
1810
+ });
1811
+ }
1812
+
1813
+ async LoadAllGeometry(modelID) {
1814
+ this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
1815
+ return this.serializer.reconstructFlatMeshVector(vector);
1816
+ };
1817
+ return this.handler.request(this.API, WorkerActions.LoadAllGeometry, {
1818
+ modelID
1819
+ });
1820
+ }
1821
+
1822
+ async GetFlatMesh(modelID, expressID) {
1823
+ this.handler.serializeHandlers[this.handler.requestID] = (flatMesh) => {
1824
+ return this.serializer.reconstructFlatMesh(flatMesh);
1825
+ };
1826
+ return this.handler.request(this.API, WorkerActions.GetFlatMesh, {
1827
+ modelID,
1828
+ expressID
1829
+ });
1830
+ }
1831
+
1832
+ async SetWasmPath(path) {
1833
+ return this.handler.request(this.API, WorkerActions.SetWasmPath, {
1834
+ path
1835
+ });
1836
+ }
1837
+
1838
+ }
1839
+
1840
+ class WorkerStateHandler {
1841
+
1842
+ constructor(handler) {
1843
+ this.handler = handler;
1844
+ this.API = WorkerAPIs.workerState;
1845
+ this.state = this.handler.state;
1846
+ }
1847
+
1848
+ async updateStateUseJson() {
1849
+ const useJson = this.state.useJSON;
1850
+ return this.handler.request(this.API, WorkerActions.updateStateUseJson, {
1851
+ useJson
1852
+ });
1853
+ }
1854
+
1855
+ async updateStateWebIfcSettings() {
1856
+ const webIfcSettings = this.state.webIfcSettings;
1857
+ return this.handler.request(this.API, WorkerActions.updateStateWebIfcSettings, {
1858
+ webIfcSettings
1859
+ });
1860
+ }
1861
+
1862
+ async updateModelStateTypes(modelID, types) {
1863
+ return this.handler.request(this.API, WorkerActions.updateModelStateTypes, {
1864
+ modelID,
1865
+ types
1866
+ });
1867
+ }
1868
+
1869
+ async updateModelStateJsonData(modelID, jsonData) {
1870
+ return this.handler.request(this.API, WorkerActions.updateModelStateJsonData, {
1871
+ modelID,
1872
+ jsonData
1873
+ });
1874
+ }
1875
+
1876
+ async loadJsonDataFromWorker(modelID, path) {
1877
+ return this.handler.request(this.API, WorkerActions.loadJsonDataFromWorker, {
1878
+ modelID,
1879
+ path
1880
+ });
1881
+ }
1882
+
1883
+ }
1884
+
1885
+ var DBOperation;
1886
+ (function(DBOperation) {
1887
+ DBOperation[DBOperation["transferIfcModel"] = 0] = "transferIfcModel";
1888
+ DBOperation[DBOperation["transferIndividualItems"] = 1] = "transferIndividualItems";
1889
+ })(DBOperation || (DBOperation = {}));
1890
+
1891
+ class IndexedDatabase {
1892
+
1893
+ async save(item, id) {
1894
+ const open = IndexedDatabase.openOrCreateDB(id);
1895
+ this.createSchema(open, id);
1896
+ return new Promise((resolve, reject) => {
1897
+ open.onsuccess = () => this.saveItem(item, open, id, resolve);
1898
+ });
1899
+ }
1900
+
1901
+ async load(id) {
1902
+ const open = IndexedDatabase.openOrCreateDB(id);
1903
+ return new Promise((resolve, reject) => {
1904
+ open.onsuccess = () => this.loadItem(open, id, resolve);
1905
+ });
1906
+ }
1907
+
1908
+ createSchema(open, id) {
1909
+ open.onupgradeneeded = function() {
1910
+ const db = open.result;
1911
+ db.createObjectStore(id.toString(), {
1912
+ keyPath: "id"
1913
+ });
1914
+ };
1915
+ }
1916
+
1917
+ saveItem(item, open, id, resolve) {
1918
+ const {db, tx, store} = IndexedDatabase.getDBItems(open, id);
1919
+ item.id = id;
1920
+ store.put(item);
1921
+ tx.oncomplete = () => IndexedDatabase.closeDB(db, tx, resolve);
1922
+ }
1923
+
1924
+ loadItem(open, id, resolve) {
1925
+ const {db, tx, store} = IndexedDatabase.getDBItems(open, id);
1926
+ const item = store.get(id);
1927
+ const callback = () => {
1928
+ delete item.result.id;
1929
+ resolve(item.result);
1930
+ };
1931
+ tx.oncomplete = () => IndexedDatabase.closeDB(db, tx, callback);
1932
+ }
1933
+
1934
+ static getDBItems(open, id) {
1935
+ const db = open.result;
1936
+ const tx = db.transaction(id.toString(), "readwrite");
1937
+ const store = tx.objectStore(id.toString());
1938
+ return {
1939
+ db,
1940
+ tx,
1941
+ store
1942
+ };
1943
+ }
1944
+
1945
+ static openOrCreateDB(id) {
1946
+ return indexedDB.open(id.toString(), 1);
1947
+ }
1948
+
1949
+ static closeDB(db, tx, resolve) {
1950
+ db.close();
1951
+ resolve("success");
1952
+ }
1953
+
1954
+ }
1955
+
1956
+ class ParserHandler {
1957
+
1958
+ constructor(handler, serializer, BVH, IDB) {
1959
+ this.handler = handler;
1960
+ this.serializer = serializer;
1961
+ this.BVH = BVH;
1962
+ this.IDB = IDB;
1963
+ this.optionalCategories = {
1964
+ [IFCSPACE]: true,
1965
+ [IFCOPENINGELEMENT]: false
1966
+ };
1967
+ this.API = WorkerAPIs.parser;
1968
+ }
1969
+
1970
+ async setupOptionalCategories(config) {
1971
+ this.optionalCategories = config;
1972
+ return this.handler.request(this.API, WorkerActions.setupOptionalCategories, {
1973
+ config
1974
+ });
1975
+ }
1976
+
1977
+ async parse(buffer, coordinationMatrix) {
1978
+ this.handler.onprogressHandlers[this.handler.requestID] = (progress) => {
1979
+ if (this.handler.state.onProgress)
1980
+ this.handler.state.onProgress(progress);
1981
+ };
1982
+ this.handler.serializeHandlers[this.handler.requestID] = async (result) => {
1983
+ this.updateState(result.modelID);
1984
+ return this.getModel();
1985
+ };
1986
+ return this.handler.request(this.API, WorkerActions.parse, {
1987
+ buffer,
1988
+ coordinationMatrix
1989
+ });
1990
+ }
1991
+
1992
+ getAndClearErrors(_modelId) {}
1993
+
1994
+ updateState(modelID) {
1995
+ this.handler.state.models[modelID] = {
1996
+ modelID: modelID,
1997
+ mesh: {},
1998
+ types: {},
1999
+ jsonData: {}
2000
+ };
2001
+ }
2002
+
2003
+ async getModel() {
2004
+ const serializedModel = await this.IDB.load(DBOperation.transferIfcModel);
2005
+ const model = this.serializer.reconstructIfcModel(serializedModel);
2006
+ this.BVH.applyThreeMeshBVH(model.geometry);
2007
+ this.handler.state.models[model.modelID].mesh = model;
2008
+ return model;
2009
+ }
2010
+
2011
+ }
2012
+
2013
+ class IFCWorkerHandler {
2014
+
2015
+ constructor(state, BVH) {
2016
+ this.state = state;
2017
+ this.BVH = BVH;
2018
+ this.requestID = 0;
2019
+ this.rejectHandlers = {};
2020
+ this.resolveHandlers = {};
2021
+ this.serializeHandlers = {};
2022
+ this.callbackHandlers = {};
2023
+ this.onprogressHandlers = {};
2024
+ this.serializer = new Serializer();
2025
+ this.IDB = new IndexedDatabase();
2026
+ this.workerPath = this.state.worker.path;
2027
+ this.ifcWorker = new Worker(this.workerPath);
2028
+ this.ifcWorker.onmessage = (data) => this.handleResponse(data);
2029
+ this.properties = new PropertyHandler(this);
2030
+ this.parser = new ParserHandler(this, this.serializer, this.BVH, this.IDB);
2031
+ this.webIfc = new WebIfcHandler(this, this.serializer);
2032
+ this.workerState = new WorkerStateHandler(this);
2033
+ }
2034
+
2035
+ request(worker, action, args) {
2036
+ const data = {
2037
+ worker,
2038
+ action,
2039
+ args,
2040
+ id: this.requestID,
2041
+ result: undefined,
2042
+ onProgress: false
2043
+ };
2044
+ return new Promise((resolve, reject) => {
2045
+ this.resolveHandlers[this.requestID] = resolve;
2046
+ this.rejectHandlers[this.requestID] = reject;
2047
+ this.requestID++;
2048
+ this.ifcWorker.postMessage(data);
2049
+ });
2050
+ }
2051
+
2052
+ async terminate() {
2053
+ await this.request(WorkerAPIs.workerState, WorkerActions.dispose);
2054
+ await this.request(WorkerAPIs.webIfc, WorkerActions.DisposeWebIfc);
2055
+ this.ifcWorker.terminate();
2056
+ }
2057
+
2058
+ async Close() {
2059
+ await this.request(WorkerAPIs.webIfc, WorkerActions.Close);
2060
+ }
2061
+
2062
+ handleResponse(event) {
2063
+ const data = event.data;
2064
+ if (data.onProgress) {
2065
+ this.resolveOnProgress(data);
2066
+ return;
2067
+ }
2068
+ this.callHandlers(data);
2069
+ delete this.resolveHandlers[data.id];
2070
+ delete this.rejectHandlers[data.id];
2071
+ delete this.onprogressHandlers[data.id];
2072
+ }
2073
+
2074
+ callHandlers(data) {
2075
+ try {
2076
+ this.resolveSerializations(data);
2077
+ this.resolveCallbacks(data);
2078
+ this.resolveHandlers[data.id](data.result);
2079
+ } catch (error) {
2080
+ this.rejectHandlers[data.id](error);
2081
+ }
2082
+ }
2083
+
2084
+ resolveOnProgress(data) {
2085
+ if (this.onprogressHandlers[data.id]) {
2086
+ data.result = this.onprogressHandlers[data.id](data.result);
2087
+ }
2088
+ }
2089
+
2090
+ resolveSerializations(data) {
2091
+ if (this.serializeHandlers[data.id]) {
2092
+ data.result = this.serializeHandlers[data.id](data.result);
2093
+ delete this.serializeHandlers[data.id];
2094
+ }
2095
+ }
2096
+
2097
+ resolveCallbacks(data) {
2098
+ if (this.callbackHandlers[data.id]) {
2099
+ let callbackParameter = data.result;
2100
+ if (this.callbackHandlers[data.id].serializer) {
2101
+ callbackParameter = this.callbackHandlers[data.id].serializer(data.result);
2102
+ }
2103
+ this.callbackHandlers[data.id].action(callbackParameter);
2104
+ }
2105
+ }
2106
+
2107
+ }
2108
+
2109
+ class MemoryCleaner {
2110
+
2111
+ constructor(state) {
2112
+ this.state = state;
2113
+ }
2114
+
2115
+ async dispose() {
2116
+ Object.keys(this.state.models).forEach(modelID => {
2117
+ const model = this.state.models[parseInt(modelID, 10)];
2118
+ model.mesh.removeFromParent();
2119
+ const geom = model.mesh.geometry;
2120
+ if (geom.disposeBoundsTree)
2121
+ geom.disposeBoundsTree();
2122
+ geom.dispose();
2123
+ if (!Array.isArray(model.mesh.material))
2124
+ model.mesh.material.dispose();
2125
+ else
2126
+ model.mesh.material.forEach(mat => mat.dispose());
2127
+ model.mesh = null;
2128
+ model.types = null;
2129
+ model.jsonData = null;
2130
+ });
2131
+ this.state.api = null;
2132
+ this.state.models = null;
2133
+ }
2134
+
2135
+ }
2136
+
2137
+ class IFCUtils {
2138
+
2139
+ constructor(state) {
2140
+ this.state = state;
2141
+ this.map = {};
2142
+ }
2143
+
2144
+ isA(entity, entity_class) {
2145
+ var test = false;
2146
+ if (entity_class) {
2147
+ if (this.state.api.GetNameFromTypeCode(entity.type) === entity_class.toUpperCase()) {
2148
+ test = true;
2149
+ }
2150
+ return test;
2151
+ } else {
2152
+ return this.state.api.GetNameFromTypeCode(entity.type);
2153
+ }
2154
+ }
2155
+
2156
+ async byId(modelID, id) {
2157
+ return this.state.api.GetLine(modelID, id);
2158
+ }
2159
+
2160
+ async idsByType(modelID, entity_class) {
2161
+ let entities_ids = await this.state.api.GetLineIDsWithType(modelID, Number(this.state.api.GetTypeCodeFromName(modelID, entity_class.toUpperCase())));
2162
+ return entities_ids;
2163
+ }
2164
+
2165
+ async byType(modelID, entity_class) {
2166
+ let entities_ids = await this.idsByType(modelID, entity_class);
2167
+ if (entities_ids !== null) {
2168
+ let items = [];
2169
+ for (let i = 0; i < entities_ids.size(); i++) {
2170
+ let entity = await this.byId(modelID, entities_ids.get(i));
2171
+ items.push(entity);
2172
+ }
2173
+ return items;
2174
+ }
2175
+ }
2176
+
2177
+ }
2178
+
2179
+ class Data {
2180
+
2181
+ constructor(state) {
2182
+ this.state = state;
2183
+ this.isLoaded = false;
2184
+ this.workPlans = {};
2185
+ this.workSchedules = {};
2186
+ this.workCalendars = {};
2187
+ this.workTimes = {};
2188
+ this.recurrencePatterns = {};
2189
+ this.timePeriods = {};
2190
+ this.tasks = {};
2191
+ this.taskTimes = {};
2192
+ this.lagTimes = {};
2193
+ this.sequences = {};
2194
+ this.utils = new IFCUtils(this.state);
2195
+ }
2196
+
2197
+ async load(modelID) {
2198
+ await this.loadTasks(modelID);
2199
+ await this.loadWorkSchedules(modelID);
2200
+ await this.loadWorkCalendars(modelID);
2201
+ await this.loadWorkTimes(modelID);
2202
+ await this.loadTimePeriods(modelID);
2203
+ this.isLoaded = true;
2204
+ }
2205
+
2206
+ async loadWorkSchedules(modelID) {
2207
+ let workSchedules = await this.utils.byType(modelID, "IfcWorkSchedule");
2208
+ for (let i = 0; i < workSchedules.length; i++) {
2209
+ let workSchedule = workSchedules[i];
2210
+ this.workSchedules[workSchedule.expressID] = {
2211
+ "Id": workSchedule.expressID,
2212
+ "Name": workSchedule.Name.value,
2213
+ "Description": ((workSchedule.Description) ? workSchedule.Description.value : ""),
2214
+ "Creators": [],
2215
+ "CreationDate": ((workSchedule.CreationDate) ? workSchedule.CreationDate.value : ""),
2216
+ "StartTime": ((workSchedule.StartTime) ? workSchedule.StartTime.value : ""),
2217
+ "FinishTime": ((workSchedule.FinishTime) ? workSchedule.FinishTime.value : ""),
2218
+ "TotalFloat": ((workSchedule.TotalFloat) ? workSchedule.TotalFloat.value : ""),
2219
+ "RelatedObjects": [],
2220
+ };
2221
+ }
2222
+ this.loadWorkScheduleRelatedObjects(modelID);
2223
+ }
2224
+
2225
+ async loadWorkScheduleRelatedObjects(modelID) {
2226
+ let relsControls = await this.utils.byType(modelID, "IfcRelAssignsToControl");
2227
+ for (let i = 0; i < relsControls.length; i++) {
2228
+ let relControls = relsControls[i];
2229
+ let relatingControl = await this.utils.byId(modelID, relControls.RelatingControl.value);
2230
+ let relatedObjects = relControls.RelatedObjects;
2231
+ if (this.utils.isA(relatingControl, "IfcWorkSchedule")) {
2232
+ for (var objectIndex = 0; objectIndex < relatedObjects.length; objectIndex++) {
2233
+ this.workSchedules[relatingControl.expressID]["RelatedObjects"].push(relatedObjects[objectIndex].value);
2234
+ }
2235
+ }
2236
+ }
2237
+ }
2238
+
2239
+ async loadTasks(modelID) {
2240
+ let tasks = await this.utils.byType(modelID, "IfcTask");
2241
+ for (let i = 0; i < tasks.length; i++) {
2242
+ let task = tasks[i];
2243
+ this.tasks[task.expressID] = {
2244
+ "Id": task.expressID,
2245
+ "Name": ((task.Name) ? task.Name.value : ""),
2246
+ "PredefinedType": ((task.PredefinedType) ? task.PredefinedType.value : ""),
2247
+ "TaskTime": ((task.TaskTime) ? await this.utils.byId(modelID, task.TaskTime.value) : ""),
2248
+ "Identification": ((task.Identification) ? task.Identification.value : ""),
2249
+ "IsMilestone": ((task.IsMilestone) ? task.IsMilestone.value : ""),
2250
+ "IsPredecessorTo": [],
2251
+ "IsSucessorFrom": [],
2252
+ "Inputs": [],
2253
+ "Resources": [],
2254
+ "Outputs": [],
2255
+ "Controls": [],
2256
+ "Nests": [],
2257
+ "IsNestedBy": [],
2258
+ "OperatesOn": [],
2259
+ "HasAssignmentsWorkCalendars": [],
2260
+ };
2261
+ }
2262
+ await this.loadTaskSequence(modelID);
2263
+ await this.loadTaskOutputs(modelID);
2264
+ await this.loadTaskNesting(modelID);
2265
+ await this.loadTaskOperations(modelID);
2266
+ await this.loadAssignementsWorkCalendar(modelID);
2267
+ }
2268
+
2269
+ async loadTaskSequence(modelID) {
2270
+ let relsSequence = await this.utils.idsByType(modelID, "IfcRelSequence");
2271
+ for (let i = 0; i < relsSequence.size(); i++) {
2272
+ let relSequenceId = relsSequence.get(i);
2273
+ if (relSequenceId !== 0) {
2274
+ let relSequence = await this.utils.byId(modelID, relSequenceId);
2275
+ let related_process = relSequence.RelatedProcess.value;
2276
+ let relatingProcess = relSequence.RelatingProcess.value;
2277
+ this.tasks[relatingProcess]["IsPredecessorTo"].push(relSequence.expressID);
2278
+ this.tasks[related_process]["IsSucessorFrom"].push(relSequence.expressID);
2279
+ }
2280
+ }
2281
+ }
2282
+
2283
+ async loadTaskOutputs(modelID) {
2284
+ let rels_assigns_to_product = await this.utils.byType(modelID, "IfcRelAssignsToProduct");
2285
+ for (let i = 0; i < rels_assigns_to_product.length; i++) {
2286
+ let relAssignsToProduct = rels_assigns_to_product[i];
2287
+ let relatedObject = await this.utils.byId(modelID, relAssignsToProduct.RelatedObjects[0].value);
2288
+ if (this.utils.isA(relatedObject, "IfcTask")) {
2289
+ let relatingProduct = await this.utils.byId(modelID, relAssignsToProduct.RelatingProduct.value);
2290
+ this.tasks[relatedObject.expressID]["Outputs"].push(relatingProduct.expressID);
2291
+ }
2292
+ }
2293
+ }
2294
+
2295
+ async loadTaskNesting(modelID) {
2296
+ let rels_nests = await this.utils.byType(modelID, "IfcRelNests");
2297
+ for (let i = 0; i < rels_nests.length; i++) {
2298
+ let relNests = rels_nests[i];
2299
+ let relating_object = await this.utils.byId(modelID, relNests.RelatingObject.value);
2300
+ if (this.utils.isA(relating_object, "IfcTask")) {
2301
+ let relatedObjects = relNests.RelatedObjects;
2302
+ for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
2303
+ this.tasks[relating_object.expressID]["IsNestedBy"].push(relatedObjects[object_index].value);
2304
+ this.tasks[relatedObjects[object_index].value]["Nests"].push(relating_object.expressID);
2305
+ }
2306
+ }
2307
+ }
2308
+ }
2309
+
2310
+ async loadTaskOperations(modelID) {
2311
+ let relsAssignsToProcess = await this.utils.byType(modelID, "IfcRelAssignsToProcess");
2312
+ for (let i = 0; i < relsAssignsToProcess.length; i++) {
2313
+ let relAssignToProcess = relsAssignsToProcess[i];
2314
+ let relatingProcess = await this.utils.byId(modelID, relAssignToProcess.RelatingProcess.value);
2315
+ if (this.utils.isA(relatingProcess, "IfcTask")) {
2316
+ let relatedObjects = relAssignToProcess.RelatedObjects;
2317
+ for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
2318
+ this.tasks[relatingProcess.expressID]["OperatesOn"].push(relatedObjects[object_index].value);
2319
+ }
2320
+ }
2321
+ }
2322
+ }
2323
+
2324
+ async loadAssignementsWorkCalendar(modelID) {
2325
+ let relsAssignsToControl = await this.utils.byType(modelID, "IfcRelAssignsToControl");
2326
+ for (let i = 0; i < relsAssignsToControl.length; i++) {
2327
+ let relAssignsToControl = relsAssignsToControl[i];
2328
+ let relatingControl = await this.utils.byId(modelID, relAssignsToControl.RelatingControl.value);
2329
+ if (this.utils.isA(relatingControl, "IfcWorkCalendar")) {
2330
+ let relatedObjects = relAssignsToControl.RelatedObjects;
2331
+ for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
2332
+ this.tasks[relatedObjects[object_index].value]["HasAssignmentsWorkCalendars"].push(relatingControl.expressID);
2333
+ }
2334
+ }
2335
+ }
2336
+ }
2337
+
2338
+ async loadWorkCalendars(modelID) {
2339
+ let workCalendars = await this.utils.byType(modelID, "IfcWorkCalendar");
2340
+ for (let i = 0; i < workCalendars.length; i++) {
2341
+ let workCalendar = workCalendars[i];
2342
+ let workCalenderData = {
2343
+ "Id": workCalendar.expressID,
2344
+ "Name": ((workCalendar.Name) ? workCalendar.Name.value : ""),
2345
+ "Description": ((workCalendar.Description) ? workCalendar.Description.value : ""),
2346
+ "WorkingTimes": ((workCalendar.WorkingTimes) ? workCalendar.WorkingTimes : []),
2347
+ "ExceptionTimes": ((workCalendar.ExceptionTimes) ? workCalendar.ExceptionTimes : []),
2348
+ };
2349
+ this.workCalendars[workCalendar.expressID] = workCalenderData;
2350
+ }
2351
+ }
2352
+
2353
+ async loadWorkTimes(modelID) {
2354
+ let workTimes = await this.utils.byType(modelID, "IfcWorkTime");
2355
+ for (let i = 0; i < workTimes.length; i++) {
2356
+ let workTime = workTimes[i];
2357
+ let workTimeData = {
2358
+ "Name": ((workTime.Name) ? workTime.Name.value : ""),
2359
+ "RecurrencePattern": ((workTime.RecurrencePattern) ? await this.utils.byId(modelID, workTime.RecurrencePattern.value) : ""),
2360
+ "Start": ((workTime.Start) ? new Date(workTime.Start.value) : ""),
2361
+ "Finish": ((workTime.Finish) ? new Date(workTime.Finish.value) : ""),
2362
+ };
2363
+ this.workTimes[workTime.expressID] = workTimeData;
2364
+ }
2365
+ }
2366
+
2367
+ async loadTimePeriods(modelID) {
2368
+ let timePeriods = await this.utils.byType(modelID, "IfcTimePeriod");
2369
+ for (let i = 0; i < timePeriods.length; i++) {
2370
+ let timePeriod = timePeriods[i];
2371
+ let workTimeData = {
2372
+ "StartTime": ((timePeriod.StartTime) ? new Date(timePeriod.StartTime.value) : ""),
2373
+ "EndTime": ((timePeriod.EndTime) ? new Date(timePeriod.EndTime.value) : ""),
2374
+ };
2375
+ this.timePeriods[timePeriod.expressID] = workTimeData;
2376
+ }
2377
+ }
2378
+
2379
+ }
2380
+
2381
+ class IFCManager {
2382
+
2383
+ constructor() {
2384
+ this.state = {
2385
+ models: [],
2386
+ api: new WebIFC.IfcAPI(),
2387
+ useJSON: false,
2388
+ worker: {
2389
+ active: false,
2390
+ path: ''
2391
+ }
2392
+ };
2393
+ this.BVH = new BvhManager();
2394
+ this.parser = new IFCParser(this.state, this.BVH);
2395
+ this.subsets = new SubsetManager(this.state, this.BVH);
2396
+ this.utils = new IFCUtils(this.state);
2397
+ this.sequenceData = new Data(this.state);
2398
+ this.properties = new PropertyManager(this.state);
2399
+ this.types = new TypeManager(this.state);
2400
+ this.useFragments = false;
2401
+ this.cleaner = new MemoryCleaner(this.state);
2402
+ }
2403
+
2404
+ get ifcAPI() {
2405
+ return this.state.api;
2406
+ }
2407
+
2408
+ async parse(buffer) {
2409
+ var _a;
2410
+ let model = await this.parser.parse(buffer, (_a = this.state.coordinationMatrix) === null || _a === void 0 ? void 0 : _a.toArray());
2411
+ model.setIFCManager(this);
2412
+ try {
2413
+ await this.types.getAllTypes(this.worker);
2414
+ } catch (e) {
2415
+ console.log("Could not get all types of model.");
2416
+ }
2417
+ return model;
2418
+ }
2419
+
2420
+ async setWasmPath(path) {
2421
+ this.state.api.SetWasmPath(path);
2422
+ this.state.wasmPath = path;
2423
+ }
2424
+
2425
+ setupThreeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast) {
2426
+ this.BVH.initializeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast);
2427
+ }
2428
+
2429
+ setOnProgress(onProgress) {
2430
+ this.state.onProgress = onProgress;
2431
+ }
2432
+
2433
+ setupCoordinationMatrix(matrix) {
2434
+ this.state.coordinationMatrix = matrix;
2435
+ }
2436
+
2437
+ clearCoordinationMatrix() {
2438
+ delete this.state.coordinationMatrix;
2439
+ }
2440
+
2441
+ async applyWebIfcConfig(settings) {
2442
+ this.state.webIfcSettings = settings;
2443
+ if (this.state.worker.active && this.worker) {
2444
+ await this.worker.workerState.updateStateWebIfcSettings();
2445
+ }
2446
+ }
2447
+
2448
+ async useWebWorkers(active, path) {
2449
+ if (this.state.worker.active === active)
2450
+ return;
2451
+ this.state.api = null;
2452
+ if (active) {
2453
+ if (!path)
2454
+ throw new Error('You must provide a path to the web worker.');
2455
+ this.state.worker.active = active;
2456
+ this.state.worker.path = path;
2457
+ await this.initializeWorkers();
2458
+ const wasm = this.state.wasmPath;
2459
+ if (wasm)
2460
+ await this.setWasmPath(wasm);
2461
+ } else {
2462
+ this.state.api = new WebIFC.IfcAPI();
2463
+ }
2464
+ }
2465
+
2466
+ async useJSONData(useJSON = true) {
2467
+ var _a;
2468
+ this.state.useJSON = useJSON;
2469
+ if (useJSON) {
2470
+ await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.updateStateUseJson());
2471
+ }
2472
+ }
2473
+
2474
+ async addModelJSONData(modelID, data) {
2475
+ var _a;
2476
+ const model = this.state.models[modelID];
2477
+ if (!model)
2478
+ throw new Error('The specified model for the JSON data does not exist');
2479
+ if (this.state.worker.active) {
2480
+ await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.updateModelStateJsonData(modelID, data));
2481
+ } else {
2482
+ model.jsonData = data;
2483
+ }
2484
+ }
2485
+
2486
+ async loadJsonDataFromWorker(modelID, path) {
2487
+ var _a;
2488
+ if (this.state.worker.active) {
2489
+ await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.loadJsonDataFromWorker(modelID, path));
2490
+ }
2491
+ }
2492
+
2493
+ close(modelID, scene) {
2494
+ try {
2495
+ this.state.api.CloseModel(modelID);
2496
+ const mesh = this.state.models[modelID].mesh;
2497
+ const {geometry, material} = mesh;
2498
+ if (scene)
2499
+ scene.remove(mesh);
2500
+ geometry === null || geometry === void 0 ? void 0 : geometry.dispose();
2501
+ Array.isArray(material) ? material.forEach(m => m.dispose()) : material === null || material === void 0 ? void 0 : material.dispose();
2502
+ delete this.state.models[modelID];
2503
+ } catch (e) {
2504
+ console.warn(`Close IFCModel ${modelID} failed`);
2505
+ }
2506
+ }
2507
+
2508
+ getExpressId(geometry, faceIndex) {
2509
+ return this.properties.getExpressId(geometry, faceIndex);
2510
+ }
2511
+
2512
+ getAllItemsOfType(modelID, type, verbose) {
2513
+ return this.properties.getAllItemsOfType(modelID, type, verbose);
2514
+ }
2515
+
2516
+ getItemProperties(modelID, id, recursive = false) {
2517
+ return this.properties.getItemProperties(modelID, id, recursive);
2518
+ }
2519
+
2520
+ getPropertySets(modelID, id, recursive = false) {
2521
+ return this.properties.getPropertySets(modelID, id, recursive);
2522
+ }
2523
+
2524
+ getTypeProperties(modelID, id, recursive = false) {
2525
+ return this.properties.getTypeProperties(modelID, id, recursive);
2526
+ }
2527
+
2528
+ getMaterialsProperties(modelID, id, recursive = false) {
2529
+ return this.properties.getMaterialsProperties(modelID, id, recursive);
2530
+ }
2531
+
2532
+ getIfcType(modelID, id) {
2533
+ const typeID = this.state.models[modelID].types[id];
2534
+ return this.state.api.GetNameFromTypeCode(typeID);
2535
+ }
2536
+
2537
+ getSpatialStructure(modelID, includeProperties) {
2538
+ return this.properties.getSpatialStructure(modelID, includeProperties);
2539
+ }
2540
+
2541
+ getSubset(modelID, material, customId) {
2542
+ return this.subsets.getSubset(modelID, material, customId);
2543
+ }
2544
+
2545
+ removeSubset(modelID, material, customID) {
2546
+ this.subsets.removeSubset(modelID, material, customID);
2547
+ }
2548
+
2549
+ createSubset(config) {
2550
+ return this.subsets.createSubset(config);
2551
+ }
2552
+
2553
+ removeFromSubset(modelID, ids, customID, material) {
2554
+ return this.subsets.removeFromSubset(modelID, ids, customID, material);
2555
+ }
2556
+
2557
+ clearSubset(modelID, customID, material) {
2558
+ return this.subsets.clearSubset(modelID, customID, material);
2559
+ }
2560
+
2561
+ async isA(entity, entity_class) {
2562
+ return this.utils.isA(entity, entity_class);
2563
+ }
2564
+
2565
+ async getSequenceData(modelID) {
2566
+ await this.sequenceData.load(modelID);
2567
+ return this.sequenceData;
2568
+ }
2569
+
2570
+ async byType(modelID, entityClass) {
2571
+ return this.utils.byType(modelID, entityClass);
2572
+ }
2573
+
2574
+ async byId(modelID, id) {
2575
+ return this.utils.byId(modelID, id);
2576
+ }
2577
+
2578
+ async idsByType(modelID, entityClass) {
2579
+ return this.utils.idsByType(modelID, entityClass);
2580
+ }
2581
+
2582
+ async dispose() {
2583
+ IFCModel.dispose();
2584
+ await this.cleaner.dispose();
2585
+ this.subsets.dispose();
2586
+ if (this.worker && this.state.worker.active)
2587
+ await this.worker.terminate();
2588
+ this.state = null;
2589
+ }
2590
+
2591
+ async disposeMemory() {
2592
+ var _a;
2593
+ if (this.state.worker.active) {
2594
+ await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.Close());
2595
+ } else {
2596
+ this.state.api.Close();
2597
+ this.state.api = null;
2598
+ this.state.api = new WebIFC.IfcAPI();
2599
+ }
2600
+ }
2601
+
2602
+ getAndClearErrors(modelID) {
2603
+ return this.parser.getAndClearErrors(modelID);
2604
+ }
2605
+
2606
+ async initializeWorkers() {
2607
+ this.worker = new IFCWorkerHandler(this.state, this.BVH);
2608
+ this.state.api = this.worker.webIfc;
2609
+ this.properties = this.worker.properties;
2610
+ await this.worker.parser.setupOptionalCategories(this.parser.optionalCategories);
2611
+ this.parser = this.worker.parser;
2612
+ await this.worker.workerState.updateStateUseJson();
2613
+ await this.worker.workerState.updateStateWebIfcSettings();
2614
+ }
2615
+
2616
+ }
2617
+
2618
+ class IFCLoader extends Loader {
2619
+
2620
+ constructor(manager) {
2621
+ super(manager);
2622
+ this.ifcManager = new IFCManager();
2623
+ }
2624
+
2625
+ load(url, onLoad, onProgress, onError) {
2626
+ const scope = this;
2627
+ const loader = new FileLoader(scope.manager);
2628
+ this.onProgress = onProgress;
2629
+ loader.setPath(scope.path);
2630
+ loader.setResponseType('arraybuffer');
2631
+ loader.setRequestHeader(scope.requestHeader);
2632
+ loader.setWithCredentials(scope.withCredentials);
2633
+ loader.load(url, async function (buffer) {
2634
+ try {
2635
+ if (typeof buffer == 'string') {
2636
+ throw new Error('IFC files must be given as a buffer!');
2637
+ }
2638
+ onLoad(await scope.parse(buffer));
2639
+ } catch (e) {
2640
+ if (onError) {
2641
+ onError(e);
2642
+ } else {
2643
+ console.error(e);
2644
+ }
2645
+ scope.manager.itemError(url);
2646
+ }
2647
+ }, onProgress, onError);
2648
+ }
2649
+
2650
+ parse(buffer) {
2651
+ return this.ifcManager.parse(buffer);
2652
+ }
2653
+
2654
+ }
2655
+
2656
+ export { IFCLoader };
2657
+ //# sourceMappingURL=IFCLoader.js.map