@xeokit/xeokit-sdk 2.6.10 → 2.6.13

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.
Files changed (37) hide show
  1. package/dist/web-ifc.wasm +0 -0
  2. package/dist/xeokit-sdk.cjs.js +1161 -131
  3. package/dist/xeokit-sdk.es.js +1160 -132
  4. package/dist/xeokit-sdk.es5.js +519 -51
  5. package/dist/xeokit-sdk.min.cjs.js +5 -5
  6. package/dist/xeokit-sdk.min.es.js +5 -5
  7. package/dist/xeokit-sdk.min.es5.js +4 -4
  8. package/package.json +1 -1
  9. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsControl.js +10 -0
  10. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +9 -0
  11. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +9 -0
  12. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +182 -42
  13. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsControl.js +11 -0
  14. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +11 -0
  15. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.js +18 -1
  16. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +15 -0
  17. package/src/plugins/DotBIMLoaderPlugin/DotBIMDefaultDataSource.js +29 -0
  18. package/src/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.js +536 -0
  19. package/src/plugins/DotBIMLoaderPlugin/index.js +2 -0
  20. package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +74 -0
  21. package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +53 -58
  22. package/src/plugins/LASLoaderPlugin/LASLoaderPlugin.js +59 -2
  23. package/src/plugins/index.js +2 -1
  24. package/src/plugins/lib/html/Dot.js +38 -6
  25. package/src/plugins/lib/html/Label.js +48 -7
  26. package/src/plugins/lib/html/Wire.js +38 -6
  27. package/src/viewer/Viewer.js +1 -1
  28. package/src/viewer/scene/marker/Marker.js +2 -2
  29. package/src/viewer/scene/model/SceneModel.js +17 -9
  30. package/src/viewer/utils/os.js +11 -0
  31. package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsControl.d.ts +7 -0
  32. package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.d.ts +8 -0
  33. package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.d.ts +8 -0
  34. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +70 -0
  35. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsControl.d.ts +7 -0
  36. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.d.ts +8 -0
  37. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.d.ts +8 -0
@@ -0,0 +1,536 @@
1
+ import {Plugin, SceneModel, utils} from "../../viewer/index.js"
2
+ import {math} from "../../viewer/scene/math/math.js";
3
+ import {DotBIMDefaultDataSource} from "./DotBIMDefaultDataSource.js";
4
+ import {IFCObjectDefaults} from "../../viewer/metadata/IFCObjectDefaults.js";
5
+
6
+ /**
7
+ * {@link Viewer} plugin that loads models from [.bim](https://dotbim.net/) format.
8
+ *
9
+ * [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/DotBIMLoaderPlugin-house.png">](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)
10
+ *
11
+ * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)]
12
+ *
13
+ * * Creates an {@link Entity} representing each .bim model it loads, which will have {@link Entity#isModel} set ````true````
14
+ * and will be registered by {@link Entity#id} in {@link Scene#models}.
15
+ * * Creates an {@link Entity} for each object within the .bim model. Those Entities will have {@link Entity#isObject}
16
+ * set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
17
+ * * When loading, can set the World-space position, scale and rotation of each model within World space,
18
+ * along with initial properties for all the model's {@link Entity}s.
19
+ * * Allows to mask which IFC types we want to load.
20
+ * * Allows to configure initial viewer state for specified IFC types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
21
+ *
22
+ * ## Usage
23
+ *
24
+ * In the example below we'll load a house model from a [.bim file](/assets/models/dotbim/House.bim).
25
+ *
26
+ * This will create a bunch of {@link Entity}s that represents the model and its objects, along with
27
+ * a {@link MetaModel} and {@link MetaObject}s that hold their metadata.
28
+ *
29
+ * ````javascript
30
+ * import {Viewer, DotBIMLoaderPlugin} from "xeokit-sdk.es.js";
31
+ *
32
+ * //------------------------------------------------------------------------------------------------------------------
33
+ * // 1. Create a Viewer,
34
+ * // 2. Arrange the camera,
35
+ * // 3. Tweak the selection material (tone it down a bit)
36
+ * //------------------------------------------------------------------------------------------------------------------
37
+ *
38
+ * // 1
39
+ * const viewer = new Viewer({
40
+ * canvasId: "myCanvas",
41
+ * transparent: true
42
+ * });
43
+ *
44
+ * // 2
45
+ * viewer.camera.orbitPitch(20);
46
+ * viewer.camera.orbitYaw(-45);
47
+ *
48
+ * // 3
49
+ * viewer.scene.selectedMaterial.fillAlpha = 0.1;
50
+ *
51
+ * //------------------------------------------------------------------------------------------------------------------
52
+ * // 1. Create a .bim loader plugin,
53
+ * // 2. Load a .bim building model, emphasizing the edges to make it look nicer
54
+ * //------------------------------------------------------------------------------------------------------------------
55
+ *
56
+ * // 1
57
+ * const dotBIMLoader = new DotBIMLoaderPlugin(viewer);
58
+ *
59
+ * // 2
60
+ * var model = dotBIMLoader.load({ // Returns an Entity that represents the model
61
+ * id: "myModel",
62
+ * src: "House.bim",
63
+ * edges: true
64
+ * });
65
+ *
66
+ * // Find the model Entity by ID
67
+ * model = viewer.scene.models["myModel"];
68
+ *
69
+ * // Destroy the model
70
+ * model.destroy();
71
+ * ````
72
+ *
73
+ * ## Transforming
74
+ *
75
+ * We have the option to rotate, scale and translate each *````.bim````* model as we load it.
76
+ *
77
+ * This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.
78
+ *
79
+ * In the example below, we'll rotate our model 90 degrees about its local X-axis, then
80
+ * translate it 100 units along its X axis.
81
+ *
82
+ * ````javascript
83
+ * const model = dotBIMLoader.load({
84
+ * src: "House.bim",
85
+ * rotation: [90,0,0],
86
+ * position: [100, 0, 0]
87
+ * });
88
+ * ````
89
+ *
90
+ * ## Including and excluding IFC types
91
+ *
92
+ * We can also load only those objects that have the specified IFC types. In the example below, we'll load only the
93
+ * objects that represent walls.
94
+ *
95
+ * ````javascript
96
+ * const model = dotBIMLoader.load({
97
+ * id: "myModel",
98
+ * src: "House.bim",
99
+ * includeTypes: ["IfcWallStandardCase"]
100
+ * });
101
+ * ````
102
+ *
103
+ * We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the
104
+ * objects that do not represent empty space.
105
+ *
106
+ * ````javascript
107
+ * const model = dotBIMLoader.load({
108
+ * id: "myModel",
109
+ * src: "House.bim",
110
+ * excludeTypes: ["IfcSpace"]
111
+ * });
112
+ * ````
113
+ *
114
+ * # Configuring initial IFC object appearances
115
+ *
116
+ * We can specify the custom initial appearance of loaded objects according to their IFC types.
117
+ *
118
+ * This is useful for things like:
119
+ *
120
+ * * setting the colors to our objects according to their IFC types,
121
+ * * automatically hiding ````IfcSpace```` objects, and
122
+ * * ensuring that ````IfcWindow```` objects are always transparent.
123
+ * <br>
124
+ * In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,
125
+ * and ````IfcWindow```` types to be always translucent blue.
126
+ *
127
+ * ````javascript
128
+ * const myObjectDefaults = {
129
+ *
130
+ * IfcSpace: {
131
+ * visible: false
132
+ * },
133
+ * IfcWindow: {
134
+ * colorize: [0.337255, 0.303922, 0.870588], // Blue
135
+ * opacity: 0.3
136
+ * },
137
+ *
138
+ * //...
139
+ *
140
+ * DEFAULT: {
141
+ * colorize: [0.5, 0.5, 0.5]
142
+ * }
143
+ * };
144
+ *
145
+ * const model4 = dotBIMLoader.load({
146
+ * id: "myModel4",
147
+ * src: "House.bim",
148
+ * objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities
149
+ * });
150
+ * ````
151
+ *
152
+ * When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other
153
+ * elements, which can be confusing.
154
+ *
155
+ * It's often helpful to make IfcSpaces transparent and unpickable, like this:
156
+ *
157
+ * ````javascript
158
+ * const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
159
+ * objectDefaults: {
160
+ * IfcSpace: {
161
+ * pickable: false,
162
+ * opacity: 0.2
163
+ * }
164
+ * }
165
+ * });
166
+ * ````
167
+ *
168
+ * Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:
169
+ *
170
+ * ````javascript
171
+ * const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
172
+ * objectDefaults: {
173
+ * IfcSpace: {
174
+ * visible: false
175
+ * }
176
+ * }
177
+ * });
178
+ * ````
179
+ *
180
+ * # Configuring a custom data source
181
+ *
182
+ * By default, DotBIMLoaderPlugin will load *````.bim````* files and metadata JSON over HTTP.
183
+ *
184
+ * In the example below, we'll customize the way DotBIMLoaderPlugin loads the files by configuring it with our own data source
185
+ * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.
186
+ *
187
+ * ````javascript
188
+ * import {utils} from "xeokit-sdk.es.js";
189
+ *
190
+ * class MyDataSource {
191
+ *
192
+ * constructor() {
193
+ * }
194
+ *
195
+ * // Gets the contents of the given .bim file in a JSON object
196
+ * getDotBIM(src, ok, error) {
197
+ * utils.loadJSON(dotBIMSrc,
198
+ * (json) => {
199
+ * ok(json);
200
+ * },
201
+ * function (errMsg) {
202
+ * error(errMsg);
203
+ * });
204
+ * }
205
+ * }
206
+ *
207
+ * const dotBIMLoader2 = new DotBIMLoaderPlugin(viewer, {
208
+ * dataSource: new MyDataSource()
209
+ * });
210
+ *
211
+ * const model5 = dotBIMLoader2.load({
212
+ * id: "myModel5",
213
+ * src: "House.bim"
214
+ * });
215
+ * ````
216
+ * @class DotBIMLoaderPlugin
217
+ */
218
+ export class DotBIMLoaderPlugin extends Plugin {
219
+
220
+ /**
221
+ * @constructor
222
+ *
223
+ * @param {Viewer} viewer The Viewer.
224
+ * @param {Object} cfg Plugin configuration.
225
+ * @param {String} [cfg.id="DotBIMLoader"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
226
+ * @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
227
+ * @param {Object} [cfg.dataSource] A custom data source through which the DotBIMLoaderPlugin can load metadata, glTF and binary attachments. Defaults to an instance of {@link DotBIMDefaultDataSource}, which loads over HTTP.
228
+ */
229
+ constructor(viewer, cfg = {}) {
230
+
231
+ super("DotBIMLoader", viewer, cfg);
232
+
233
+ this.dataSource = cfg.dataSource;
234
+ this.objectDefaults = cfg.objectDefaults;
235
+ }
236
+
237
+ /**
238
+ * Sets a custom data source through which the DotBIMLoaderPlugin can .BIM files.
239
+ *
240
+ * Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
241
+ *
242
+ * @type {Object}
243
+ */
244
+ set dataSource(value) {
245
+ this._dataSource = value || new DotBIMDefaultDataSource();
246
+ }
247
+
248
+ /**
249
+ * Gets the custom data source through which the DotBIMLoaderPlugin can load .BIM files.
250
+ *
251
+ * Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
252
+ *
253
+ * @type {Object}
254
+ */
255
+ get dataSource() {
256
+ return this._dataSource;
257
+ }
258
+
259
+ /**
260
+ * Sets map of initial default states for each loaded {@link Entity} that represents an object.
261
+ *
262
+ * Default value is {@link IFCObjectDefaults}.
263
+ *
264
+ * @type {{String: Object}}
265
+ */
266
+ set objectDefaults(value) {
267
+ this._objectDefaults = value || IFCObjectDefaults;
268
+ }
269
+
270
+ /**
271
+ * Gets map of initial default states for each loaded {@link Entity} that represents an object.
272
+ *
273
+ * Default value is {@link IFCObjectDefaults}.
274
+ *
275
+ * @type {{String: Object}}
276
+ */
277
+ get objectDefaults() {
278
+ return this._objectDefaults;
279
+ }
280
+
281
+ /**
282
+ * Loads a .BIM model from a file into this DotBIMLoaderPlugin's {@link Viewer}.
283
+ *
284
+ * @param {*} params Loading parameters.
285
+ * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.
286
+ * @param {String} [params.src] Path to a .BIM file, as an alternative to the ````bim```` parameter.
287
+ * @param {*} [params.bim] .BIM JSON, as an alternative to the ````src```` parameter.
288
+ * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
289
+ * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
290
+ * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
291
+ * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
292
+ * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
293
+ * @param {Number[]} [params.scale=[1,1,1]] The model's scale.
294
+ * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, as Euler angles given in degrees, for each of the X, Y and Z axis.
295
+ * @param {Boolean} [params.backfaces=true] When true, always show backfaces, even on objects for which the .BIM material is single-sided. When false, only show backfaces on geometries whenever the .BIM material is double-sided.
296
+ * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to
297
+ * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
298
+ * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
299
+ * primitives. Only works while {@link DTX#enabled} is also ````true````.
300
+ * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
301
+ */
302
+ load(params = {}) {
303
+
304
+ if (params.id && this.viewer.scene.components[params.id]) {
305
+ this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
306
+ delete params.id;
307
+ }
308
+
309
+ const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
310
+ isModel: true,
311
+ backfaces: params.backfaces,
312
+ dtxEnabled: params.dtxEnabled,
313
+ rotation: params.rotation,
314
+ origin: params.origin
315
+ }));
316
+
317
+ const modelId = sceneModel.id; // In case ID was auto-generated
318
+
319
+ if (!params.src && !params.dotBIM) {
320
+ this.error("load() param expected: src or dotBIM");
321
+ return sceneModel; // Return new empty model
322
+ }
323
+
324
+ const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
325
+
326
+ let includeTypes;
327
+ if (params.includeTypes) {
328
+ includeTypes = {};
329
+ for (let i = 0, len = params.includeTypes.length; i < len; i++) {
330
+ includeTypes[params.includeTypes[i]] = true;
331
+ }
332
+ }
333
+
334
+ let excludeTypes;
335
+ if (params.excludeTypes) {
336
+ excludeTypes = {};
337
+ if (!includeTypes) {
338
+ includeTypes = {};
339
+ }
340
+ for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
341
+ includeTypes[params.excludeTypes[i]] = true;
342
+ }
343
+ }
344
+
345
+ const parseDotBIM = (ctx) => {
346
+
347
+ const fileData = ctx.fileData;
348
+ const sceneModel = ctx.sceneModel;
349
+
350
+ const dbMeshIndices = {};
351
+ const dbMeshLoaded = {};
352
+
353
+ const ifcProjectId = math.createUUID();
354
+ const ifcSiteId = math.createUUID();
355
+ const ifcBuildingId = math.createUUID();
356
+ const ifcBuildingStoryId = math.createUUID();
357
+
358
+ const metaModelData = {
359
+ metaObjects: [
360
+ {
361
+ id: ifcProjectId,
362
+ name: "IfcProject",
363
+ type: "IfcProject",
364
+ parent: null
365
+ },
366
+ {
367
+ id: ifcSiteId,
368
+ name: "IfcSite",
369
+ type: "IfcSite",
370
+ parent: ifcProjectId
371
+ },
372
+ {
373
+ id: ifcBuildingId,
374
+ name: "IfcBuilding",
375
+ type: "IfcBuilding",
376
+ parent: ifcSiteId
377
+ },
378
+ {
379
+ id: ifcBuildingStoryId,
380
+ name: "IfcBuildingStorey",
381
+ type: "IfcBuildingStorey",
382
+ parent: ifcBuildingId
383
+ }
384
+ ],
385
+ propertySets: []
386
+ };
387
+
388
+ for (let i = 0, len = fileData.meshes.length; i < len; i++) {
389
+ const dbMesh = fileData.meshes[i];
390
+ dbMeshIndices[dbMesh.mesh_id] = i;
391
+ }
392
+
393
+ const parseDBMesh = (dbMeshId) => {
394
+ if (dbMeshLoaded[dbMeshId]) {
395
+ return;
396
+ }
397
+ const dbMeshIndex = dbMeshIndices[dbMeshId];
398
+ const dbMesh = fileData.meshes[dbMeshIndex];
399
+ sceneModel.createGeometry({
400
+ id: dbMeshId,
401
+ primitive: "triangles",
402
+ positions: dbMesh.coordinates,
403
+ indices: dbMesh.indices
404
+ });
405
+ dbMeshLoaded[dbMeshId] = true;
406
+ }
407
+
408
+ const dbElements = fileData.elements;
409
+ for (let i = 0, len = dbElements.length; i < len; i++) {
410
+ const element = dbElements[i];
411
+ const elementType = element.type;
412
+ if (excludeTypes && excludeTypes[elementType]) {
413
+ continue;
414
+
415
+ }
416
+ if (includeTypes && (!includeTypes[elementType])) {
417
+ continue;
418
+ }
419
+ const info = element.info;
420
+ const objectId =
421
+ element.guid !== undefined
422
+ ? `${element.guid}`
423
+ : (info !== undefined && info.id !== undefined
424
+ ? info.id
425
+ : i);
426
+
427
+ const dbMeshId = element.mesh_id;
428
+
429
+ parseDBMesh(dbMeshId);
430
+
431
+ const meshId = `${objectId}-mesh`;
432
+ const vector = element.vector;
433
+ const rotation = element.rotation;
434
+ const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
435
+
436
+ let visible = true;
437
+ let pickable = true;
438
+ let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
439
+ let opacity = element.color ? element.color.a / 255 : 1.0;
440
+
441
+ if (props) {
442
+ if (props.visible === false) {
443
+ visible = false;
444
+ }
445
+ if (props.pickable === false) {
446
+ pickable = false;
447
+ }
448
+ if (props.colorize) {
449
+ color = props.colorize;
450
+ }
451
+ if (props.opacity !== undefined && props.opacity !== null) {
452
+ opacity = props.opacity;
453
+ }
454
+ }
455
+
456
+ sceneModel.createMesh({
457
+ id: meshId,
458
+ geometryId: dbMeshId,
459
+ color,
460
+ opacity,
461
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
462
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
463
+ });
464
+
465
+ sceneModel.createEntity({
466
+ id: objectId,
467
+ meshIds: [meshId],
468
+ visible,
469
+ pickable,
470
+ isObject: true
471
+ });
472
+
473
+ metaModelData.metaObjects.push({
474
+ id: objectId,
475
+ name: info && info.Name && info.Name !== "None" ? info.Name : `${element.type} ${objectId}`,
476
+ type: element.type,
477
+ parent: ifcBuildingStoryId
478
+ });
479
+ }
480
+
481
+ sceneModel.finalize();
482
+
483
+ this.viewer.metaScene.createMetaModel(modelId, metaModelData);
484
+
485
+ sceneModel.scene.once("tick", () => {
486
+ if (sceneModel.destroyed) {
487
+ return;
488
+ }
489
+ sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
490
+ sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
491
+ });
492
+ }
493
+
494
+ if (params.src) {
495
+ const src = params.src;
496
+ this.viewer.scene.canvas.spinner.processes++;
497
+ this._dataSource.getDotBIM(src, (fileData) => { // OK
498
+ const ctx = {
499
+ fileData,
500
+ sceneModel,
501
+ nextId: 0,
502
+ error: function (errMsg) {
503
+ }
504
+ };
505
+ parseDotBIM(ctx);
506
+ this.viewer.scene.canvas.spinner.processes--;
507
+ },
508
+ (err) => {
509
+ this.viewer.scene.canvas.spinner.processes--;
510
+ this.error(err);
511
+ });
512
+ } else if (params.dotBIM) {
513
+ const ctx = {
514
+ fileData: params.dotBIM,
515
+ sceneModel,
516
+ nextId: 0,
517
+ error: function (errMsg) {
518
+ }
519
+ };
520
+ parseDotBIM(ctx);
521
+ }
522
+
523
+ sceneModel.once("destroyed", () => {
524
+ this.viewer.metaScene.destroyMetaModel(modelId);
525
+ });
526
+
527
+ return sceneModel;
528
+ }
529
+
530
+ /**
531
+ * Destroys this DotBIMLoaderPlugin.
532
+ */
533
+ destroy() {
534
+ super.destroy();
535
+ }
536
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./DotBIMDefaultDataSource.js";
2
+ export * from "./DotBIMLoaderPlugin.js";
@@ -156,6 +156,79 @@ import {IFCObjectDefaults} from "../../viewer/metadata/IFCObjectDefaults.js";
156
156
  * excludeTypes: ["IfcSpace"]
157
157
  * });
158
158
  * ````
159
+ *
160
+ * ## Showing a glTF model in TreeViewPlugin when metadata is not available
161
+ *
162
+ * When GLTFLoaderPlugin loads a glTF model, it creates an object Entity for each `node` in the glTF `scene` hierarchy that has a
163
+ * `name` attribute, giving the Entity an ID that has the value of the `name` attribute.
164
+ *
165
+ * Those name attributes are created by converter tools, such as by [IFC2GLTFCxConverter](https://github.com/Creoox/creoox-ifc2gltfcxconverter) when it generates glTF from IFC files. However, those name attributes are not
166
+ * ordinarily present in glTF that comes from other sources, such as LiDAR scanners. For such glTF models, GLTFLoaderPlugin
167
+ * will create Entities, but they will have randomly-generated IDs, and therefore cannot be associated with MetaObjects in any
168
+ * MetaModels that we create alongside the model.
169
+ *
170
+ * For glTF models containing `nodes` that don't have `name` attributes, we can use the `load()` method's `elementId` parameter
171
+ * to make GLTFLoaderPlugin load the entire model into a single Entity that gets this ID.
172
+ *
173
+ * In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that
174
+ * contains a MetaObject that corresponds to that Entity.
175
+ *
176
+ * When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the glTF model and controls
177
+ * the visibility of that Entity (ie. to control the visibility of the entire model).
178
+ *
179
+ * The snippet below shows how this is done.
180
+ *
181
+ * ````javascript
182
+ * import {Viewer, GLTFLoaderPlugin, NavCubePlugin, TreeViewPlugin} from "../../dist/xeokit-sdk.es.js";
183
+ *
184
+ * const viewer = new Viewer({
185
+ * canvasId: "myCanvas",
186
+ * transparent: true
187
+ * });
188
+ *
189
+ * new TreeViewPlugin(viewer, {
190
+ * containerElement: document.getElementById("treeViewContainer"),
191
+ * hierarchy: "containment"
192
+ * });
193
+ *
194
+ * const gltfLoader = new GLTFLoaderPlugin(viewer);
195
+ *
196
+ * const sceneModel = gltfLoader.load({ // Creates a SceneModel with ID "myScanModel"
197
+ * id: "myScanModel",
198
+ * src: "public-use-sample-apartment.glb",
199
+ *
200
+ * //-------------------------------------------------------------------------
201
+ * // Specify an `elementId` parameter, which causes the
202
+ * // entire model to be loaded into a single Entity that gets this ID.
203
+ * //-------------------------------------------------------------------------
204
+ *
205
+ * entityId: "3toKckUfH2jBmd$7uhJHa4", // Creates an Entity with this ID
206
+ *
207
+ * //-------------------------------------------------------------------------
208
+ * // Specify a `metaModelJSON` parameter, which creates a
209
+ * // MetaModel with two MetaObjects, one of which corresponds
210
+ * // to our Entity. Then the TreeViewPlugin is able to have a node
211
+ * // that can represent the model and control the visibility of the Entity.
212
+ * //--------------------------------------------------------------------------
213
+ *
214
+ * metaModelJSON: { // Creates a MetaModel with ID "myScanModel"
215
+ * "metaObjects": [
216
+ * {
217
+ * "id": "3toKckUfH2jBmd$7uhJHa6", // Creates a MetaObject with this ID
218
+ * "name": "My Project",
219
+ * "type": "Default",
220
+ * "parent": null
221
+ * },
222
+ * {
223
+ * "id": "3toKckUfH2jBmd$7uhJHa4", // Creates a MetaObject with this ID (same ID as our Entity)
224
+ * "name": "My Scan",
225
+ * "type": "Default",
226
+ * "parent": "3toKckUfH2jBmd$7uhJHa6"
227
+ * }
228
+ * ]
229
+ * }
230
+ * });
231
+ * ````
159
232
  * @class GLTFLoaderPlugin
160
233
  */
161
234
  class GLTFLoaderPlugin extends Plugin {
@@ -250,6 +323,7 @@ class GLTFLoaderPlugin extends Plugin {
250
323
  * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
251
324
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
252
325
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
326
+ * @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
253
327
  * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
254
328
  */
255
329
  load(params = {}) {