@xeokit/xeokit-sdk 2.6.59 → 2.6.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.59",
3
+ "version": "2.6.61",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -119,7 +119,7 @@ class FastNavPlugin extends Plugin {
119
119
  this._hideEdges = cfg.hideEdges !== false;
120
120
  this._hideTransparentObjects = !!cfg.hideTransparentObjects;
121
121
  this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;
122
- this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor || 1.0;
122
+ this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor;
123
123
  this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
124
124
  this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
125
125
  this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
@@ -135,6 +135,7 @@ class FastNavPlugin extends Plugin {
135
135
  viewer.scene._renderer.setSAOEnabled(!this._hideSAO);
136
136
  viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);
137
137
  viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);
138
+ this._originalCanvasResolutionScale = viewer.scene.canvas.resolutionScale;
138
139
  if (this._scaleCanvasResolution) {
139
140
  viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;
140
141
  } else {
@@ -145,7 +146,7 @@ class FastNavPlugin extends Plugin {
145
146
  };
146
147
 
147
148
  const switchToHighQuality = () => {
148
- viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor;
149
+ viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor || this._originalCanvasResolutionScale || 1.0;
149
150
  viewer.scene._renderer.setEdgesEnabled(true);
150
151
  viewer.scene._renderer.setColorTextureEnabled(true);
151
152
  viewer.scene._renderer.setPBREnabled(true);
@@ -350,7 +351,7 @@ class FastNavPlugin extends Plugin {
350
351
  * @param {Number} defaultScaleCanvasResolutionFactor Factor by scale canvas resolution when we stop interacting with the viewer.
351
352
  */
352
353
  set defaultScaleCanvasResolutionFactor(defaultScaleCanvasResolutionFactor) {
353
- this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor || 1.0;
354
+ this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor;
354
355
  }
355
356
 
356
357
  /**
@@ -362,6 +362,7 @@ export class TreeViewPlugin extends Plugin {
362
362
  * @param {Boolean} [cfg.pruneEmptyNodes=true] When true, will not contain nodes that don't have content in the {@link Scene}. These are nodes whose {@link MetaObject}s don't have {@link Entity}s.
363
363
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
364
364
  * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
365
+ * @param {Boolean} [cfg.showProjectNode=false] When true, will show top level project node when hierarchy is set to "storeys"
365
366
  */
366
367
  constructor(viewer, cfg = {}) {
367
368
 
@@ -414,6 +415,7 @@ export class TreeViewPlugin extends Plugin {
414
415
  this._showListItemElementId = null;
415
416
  this._renderService = cfg.renderService || new RenderService();
416
417
  this._showIndeterminate = cfg.showIndeterminate ?? false;
418
+ this._showProjectNode = cfg.showProjectNode ?? false;
417
419
 
418
420
  if (!this._renderService) {
419
421
  throw new Error('TreeViewPlugin: no render service set');
@@ -968,11 +970,11 @@ export class TreeViewPlugin extends Plugin {
968
970
  _createStoreysNodes() {
969
971
  const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;
970
972
  for (let id in rootMetaObjects) {
971
- this._createStoreysNodes2(rootMetaObjects[id], null, null, null);
973
+ this._createStoreysNodes2(rootMetaObjects[id], null, null, null, null);
972
974
  }
973
975
  }
974
976
 
975
- _createStoreysNodes2(metaObject, buildingNode, storeyNode, typeNodes) {
977
+ _createStoreysNodes2(metaObject, projectNode, buildingNode, storeyNode, typeNodes) {
976
978
  if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {
977
979
  return;
978
980
  }
@@ -980,20 +982,41 @@ export class TreeViewPlugin extends Plugin {
980
982
  const metaObjectName = metaObject.name;
981
983
  const children = metaObject.children;
982
984
  const objectId = metaObject.id;
983
- if (metaObjectType === "IfcBuilding") {
985
+
986
+ if (this._showProjectNode && metaObjectType === 'IfcProject') {
987
+ projectNode = {
988
+ nodeId: `${this._id}-${objectId}`,
989
+ objectId,
990
+ title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
991
+ type: metaObjectType,
992
+ parent: null,
993
+ numEntities: 0,
994
+ numVisibleEntities: 0,
995
+ checked: false,
996
+ xrayed: false,
997
+ children: [],
998
+ };
999
+ this._rootNodes.push(projectNode);
1000
+ this._objectNodes[projectNode.objectId] = projectNode;
1001
+ this._nodeNodes[projectNode.nodeId] = projectNode;
1002
+ } else if (metaObjectType === "IfcBuilding") {
984
1003
  buildingNode = {
985
1004
  nodeId: `${this._id}-${objectId}`,
986
1005
  objectId: objectId,
987
1006
  title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
988
1007
  type: metaObjectType,
989
- parent: null,
1008
+ parent: projectNode,
990
1009
  numEntities: 0,
991
1010
  numVisibleEntities: 0,
992
1011
  checked: false,
993
1012
  xrayed: false,
994
1013
  children: []
995
1014
  };
996
- this._rootNodes.push(buildingNode);
1015
+ if (projectNode) {
1016
+ projectNode.children.push(buildingNode);
1017
+ } else {
1018
+ this._rootNodes.push(buildingNode);
1019
+ }
997
1020
  this._objectNodes[buildingNode.objectId] = buildingNode;
998
1021
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
999
1022
  } else if (metaObjectType === "IfcBuildingStorey") {
@@ -1063,7 +1086,7 @@ export class TreeViewPlugin extends Plugin {
1063
1086
  if (children) {
1064
1087
  for (let i = 0, len = children.length; i < len; i++) {
1065
1088
  const childMetaObject = children[i];
1066
- this._createStoreysNodes2(childMetaObject, buildingNode, storeyNode, typeNodes);
1089
+ this._createStoreysNodes2(childMetaObject, projectNode, buildingNode, storeyNode, typeNodes);
1067
1090
  }
1068
1091
  }
1069
1092
  }
@@ -0,0 +1,200 @@
1
+ import {Viewer, Component} from "../../viewer";
2
+ import {ObjectsKdTree3} from "../collision";
3
+
4
+ /**
5
+ * Picks a {@link Viewer}'s {@link Entity}s with a canvas-space 2D marquee box.
6
+ *
7
+ * [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/MarqueeSelect.gif">](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)
8
+ *
9
+ * * [[Example 1: Select Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)]
10
+ * * [[Example 2: View-Fit Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_viewFit)]
11
+ *
12
+ * # Usage
13
+ *
14
+ * In the example below, we
15
+ *
16
+ * 1. Create a {@link Viewer}, arrange the {@link Camera}
17
+ * 2. Use an {@link XKTLoaderPlugin} to load a BIM model,
18
+ * 3. Create a {@link ObjectsKdTree3} to automatically index the `Viewer's` {@link Entity}s for fast spatial lookup,
19
+ * 4. Create a `MarqueePicker` to pick {@link Entity}s in the {@link Viewer}, using the {@link ObjectsKdTree3} to accelerate picking
20
+ * 5. Create a {@link MarqueePickerMouseControl} to perform the marquee-picking with the `MarqueePicker`, using mouse input to draw the marquee box on the `Viewer's` canvas.
21
+ *
22
+ * When the {@link MarqueePickerMouseControl} is active:
23
+ *
24
+ * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
25
+ * * Drag left-to-right to pick {@link Entity}s that intersect the box.
26
+ * * Drag right-to-left to pick {@link Entity}s that are fully inside the box.
27
+ * * On release, the `MarqueePicker` will fire a "picked" event with IDs of the picked {@link Entity}s, if any.
28
+ * * Handling that event, we mark the {@link Entity}s as selected.
29
+ * * Hold down CTRL to multi-pick.
30
+ *
31
+ * ````javascript
32
+ * import {
33
+ * Viewer,
34
+ * XKTLoaderPlugin,
35
+ * ObjectsKdTree3,
36
+ * MarqueePicker,
37
+ * MarqueePickerMouseControl
38
+ * } from "xeokit-sdk.es.js";
39
+ *
40
+ * // 1
41
+ *
42
+ * const viewer = new Viewer({
43
+ * canvasId: "myCanvas"
44
+ * });
45
+ *
46
+ * viewer.scene.camera.eye = [14.9, 14.3, 5.4];
47
+ * viewer.scene.camera.look = [6.5, 8.3, -4.1];
48
+ * viewer.scene.camera.up = [-0.28, 0.9, -0.3];
49
+ *
50
+ * // 2
51
+ *
52
+ * const xktLoader = new XKTLoaderPlugin(viewer);
53
+ *
54
+ * const sceneModel = xktLoader.load({
55
+ * id: "myModel",
56
+ * src: "../../assets/models/xkt/v8/ifc/HolterTower.ifc.xkt"
57
+ * });
58
+ *
59
+ * // 3
60
+ *
61
+ * const objectsKdTree3 = new ObjectsKdTree3({viewer});
62
+ *
63
+ * // 4
64
+ *
65
+ * const marqueePicker = new MarqueePicker({viewer, objectsKdTree3});
66
+ *
67
+ * // 5
68
+ *
69
+ * const marqueePickerMouseControl = new MarqueePickerMouseControl({marqueePicker});
70
+ *
71
+ * marqueePicker.on("clear", () => {
72
+ * viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);
73
+ * });
74
+ *
75
+ * marqueePicker.on("picked", (objectIds) => {
76
+ * viewer.scene.setObjectsSelected(objectIds, true);
77
+ * });
78
+ *
79
+ * marqueePickerMouseControl.setActive(true);
80
+ * ````
81
+ *
82
+ * # Design Notes
83
+ *
84
+ * * The {@link ObjectsKdTree3} can be shared with any other components that want to use it to spatially search for {@link Entity}s.
85
+ * * The {@link MarqueePickerMouseControl} can be replaced with other types of controllers (i.e. touch), or used alongside them.
86
+ * * The `MarqueePicker` has no input handlers of its own, and provides an API through which to programmatically control marquee picking. By firing the "picked" events, `MarqueePicker` implements the *Blackboard Pattern*.
87
+ */
88
+ export class MarqueePicker extends Component {
89
+
90
+ /**
91
+ * Pick mode that picks {@link Entity}s that intersect the marquee box.
92
+ *
93
+ * @type {number}
94
+ */
95
+ static PICK_MODE_INTERSECTS: number;
96
+
97
+ /**
98
+ * Pick mode that picks {@link Entity}s that are completely inside the marquee box.
99
+ *
100
+ * @type {number}
101
+ */
102
+ static PICK_MODE_INSIDE: number;
103
+
104
+ /**
105
+ * Creates a MarqueePicker.
106
+ *
107
+ * @param {*} cfg Configuration
108
+ * @param {Viewer} cfg.viewer The Viewer to pick Entities from.
109
+ * @param {ObjectsKdTree3} cfg.objectsKdTree3 A k-d tree that indexes the Entities in the Viewer for fast spatial lookup.
110
+ */
111
+ constructor(cfg: {
112
+ viewer: Viewer;
113
+ objectsKdTree3: ObjectsKdTree3;
114
+ });
115
+
116
+ /**
117
+ * Sets the canvas-space position of the first marquee box corner.
118
+ *
119
+ * @param corner1
120
+ */
121
+ setMarqueeCorner1(corner1: number[]): void;
122
+
123
+ /**
124
+ * Sets the canvas-space position of the second marquee box corner.
125
+ *
126
+ * @param corner2
127
+ */
128
+ setMarqueeCorner2(corner2: number[]):void;
129
+
130
+ /**
131
+ * Sets both canvas-space corner positions of the marquee box.
132
+ *
133
+ * @param corner1
134
+ * @param corner2
135
+ */
136
+ setMarquee(corner1: number[], corner2: number[]):void;
137
+
138
+ /**
139
+ * Sets if the marquee box is visible.
140
+ *
141
+ * @param {boolean} visible True if the marquee box is to be visible, else false.
142
+ */
143
+ setMarqueeVisible(visible:boolean):void;
144
+
145
+ /**
146
+ * Gets if the marquee box is visible.
147
+ *
148
+ * @returns {boolean} True if the marquee box is visible, else false.
149
+ */
150
+ getMarqueeVisible() :boolean;
151
+
152
+ /**
153
+ * Sets the pick mode.
154
+ *
155
+ * Supported pick modes are:
156
+ *
157
+ * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box.
158
+ * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box.
159
+ *
160
+ * @param {number} pickMode The pick mode.
161
+ */
162
+ setPickMode(pickMode: number) :void;
163
+
164
+ /**
165
+ * Gets the pick mode.
166
+ *
167
+ * Supported pick modes are:
168
+ *
169
+ * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box.
170
+ * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box.
171
+ *
172
+ * @returns {number} The pick mode.
173
+ */
174
+ getPickMode() :number;
175
+
176
+ /**
177
+ * Fires a "clear" event on this MarqueePicker.
178
+ */
179
+ clear() :void;
180
+
181
+ /**
182
+ * Attempts to pick {@link Entity}s, using the current MarquePicker settings.
183
+ *
184
+ * Fires a "picked" event with the IDs of the {@link Entity}s that were picked, if any.
185
+ *
186
+ * @returns {string[]} IDs of the {@link Entity}s that were picked, if any
187
+ */
188
+ pick():string[];
189
+
190
+
191
+ /**
192
+ * Destroys this MarqueePicker.
193
+ *
194
+ * Does not destroy the {@link Viewer} or the {@link ObjectsKdTree3} provided to the constructor of this MarqueePicker.
195
+ */
196
+ destroy():void;
197
+ }
198
+
199
+
200
+
@@ -0,0 +1,48 @@
1
+ import {Component} from "../../viewer";
2
+ import {MarqueePicker} from "./MarqueePicker";
3
+
4
+ /**
5
+ * Controls a {@link MarqueePicker} with mouse input.
6
+ *
7
+ * See {@link MarqueePicker} for usage example.
8
+ *
9
+ * When the MarqueePickerMouseControl is active:
10
+ *
11
+ * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
12
+ * * Drag left-to-right to pick Entities that intersect the box.
13
+ * * Drag right-to-left to pick Entities that are fully inside the box.
14
+ * * On release, the MarqueePicker will fire a "picked" event with IDs of the picked Entities , if any.
15
+ */
16
+
17
+
18
+ export class MarqueePickerMouseControl extends Component {
19
+
20
+ /**
21
+ * Creates a new MarqueePickerMouseControl.
22
+ *
23
+ * @param {*} cfg Configuration
24
+ * @param {MarqueePicker} cfg.marqueePicker The MarqueePicker to control.
25
+ */
26
+ constructor(cfg: {
27
+ marqueePicker: MarqueePicker;
28
+ });
29
+
30
+ /**
31
+ * Activates or deactivates this MarqueePickerMouseControl.
32
+ *
33
+ * @param {boolean} active Whether or not to activate.
34
+ */
35
+ setActive(active: boolean): void;
36
+
37
+ /**
38
+ * Gets if this MarqueePickerMouseControl is active.
39
+ *
40
+ * @returns {boolean}
41
+ */
42
+ getActive(): boolean;
43
+
44
+ /**
45
+ *
46
+ */
47
+ destroy(): void;
48
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./MarqueePicker";
2
+ export * from "./MarqueePickerMouseControl";
@@ -0,0 +1,43 @@
1
+ import {Viewer} from "../../viewer";
2
+
3
+ /**
4
+ * Automatically indexes a {@link Viewer}'s {@link Entity}s in a 3D k-d tree
5
+ * to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums.
6
+ *
7
+ * See {@link MarqueePicker} for usage example.
8
+ *
9
+ * An ObjectsKdTree3 is configured with a Viewer, and will then automatically
10
+ * keep itself populated with k-d nodes that contain the Viewer's Entitys.
11
+ *
12
+ * We can then traverse the k-d nodes, starting at {@link ObjectsKdTree3#root}, to find
13
+ * the contained Entities.
14
+ */
15
+ export class ObjectsKdTree3 {
16
+
17
+ /**
18
+ * Creates an ObjectsKdTree3.
19
+ *
20
+ * @param {*} cfg Configuration
21
+ * @param {Viewer} cfg.viewer The Viewer that provides the {@link Entity}s in this ObjectsKdTree3.
22
+ * @param {number} [cfg.maxTreeDepth=15] Optional maximum depth for the k-d tree.
23
+ */
24
+ constructor(cfg: {
25
+ viewer: Viewer;
26
+ maxTreeDepth?: number;
27
+ });
28
+
29
+ /**
30
+ * Gets the root ObjectsKdTree3 node.
31
+ *
32
+ * Each time this accessor is accessed, it will lazy-rebuild the ObjectsKdTree3
33
+ * if {@link Entity}s have been created or removed in the {@link Viewer} since the last time it was accessed.
34
+ */
35
+ get root(): any;
36
+
37
+ /**
38
+ * Destroys this ObjectsKdTree3.
39
+ *
40
+ * Does not destroy the {@link Viewer} given to the constructor of the ObjectsKdTree3.
41
+ */
42
+ destroy(): void
43
+ }
@@ -0,0 +1 @@
1
+ export * from "./ObjectsKdTree3";
@@ -1,2 +1,4 @@
1
1
  export * from "./ContextMenu";
2
2
  export * from "./PointerLens";
3
+ export * from "./MarqueePicker";
4
+ export * from "./collision"