@xeokit/xeokit-sdk 2.6.37 → 2.6.40

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.
@@ -682,21 +682,27 @@ class ContextMenu {
682
682
  if (itemSubMenu) {
683
683
 
684
684
  html.push(
685
- '<li id="' + item.id + '" class="xeokit-context-menu-item" style="' +
686
- ((groupIdx === groupLen - 1) || ((j < lenj - 1)) ? 'border-bottom: 0' : 'border-bottom: 1px solid black') +
687
- '">' +
685
+ '<li id="' + item.id + '" class="xeokit-context-menu-item">' +
688
686
  actionTitle +
689
687
  ' [MORE]' +
690
688
  '</li>');
689
+ if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {
690
+ html.push(
691
+ '<li id="' + item.id + '" class="xeokit-context-menu-item-separator"></li>'
692
+ );
693
+ }
691
694
 
692
695
  } else {
693
696
 
694
697
  html.push(
695
- '<li id="' + item.id + '" class="xeokit-context-menu-item" style="' +
696
- ((groupIdx === groupLen - 1) || ((j < lenj - 1)) ? 'border-bottom: 0' : 'border-bottom: 1px solid black') +
697
- '">' +
698
+ '<li id="' + item.id + '" class="xeokit-context-menu-item">' +
698
699
  actionTitle +
699
700
  '</li>');
701
+ if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {
702
+ html.push(
703
+ '<li id="' + item.id + '" class="xeokit-context-menu-item-separator"></li>'
704
+ );
705
+ }
700
706
  }
701
707
  }
702
708
  }
@@ -894,14 +900,11 @@ class ContextMenu {
894
900
  const shown = getShown(this._context);
895
901
  item.shown = shown;
896
902
  if (!shown) {
897
- itemElement.style.visibility = "hidden";
898
- itemElement.style.height = "0";
899
- itemElement.style.padding = "0";
903
+ itemElement.style.display = "none";
900
904
  continue;
901
905
  } else {
902
- itemElement.style.visibility = "visible";
903
- itemElement.style.height = "auto";
904
- itemElement.style.padding = null;
906
+ itemElement.style.display = "";
907
+
905
908
  }
906
909
  const enabled = getEnabled(this._context);
907
910
  item.enabled = enabled;
@@ -88167,6 +88170,16 @@ class DistanceMeasurement extends Component {
88167
88170
  const scene = this.plugin.viewer.scene;
88168
88171
 
88169
88172
  if (this._wpDirty) {
88173
+ const delta = math.subVec3(
88174
+ this._targetWorld,
88175
+ this._originWorld,
88176
+ tmpVec3
88177
+ );
88178
+
88179
+ /**
88180
+ * The length detected for each measurement axis.
88181
+ */
88182
+ this._factors = math.transformVec3(this._axesBasis, delta);
88170
88183
 
88171
88184
  this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 0);
88172
88185
  if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment){
@@ -88191,16 +88204,6 @@ class DistanceMeasurement extends Component {
88191
88204
  this._wp[15] = 1.0;
88192
88205
  }
88193
88206
  else {
88194
- const delta = math.subVec3(
88195
- this._targetWorld,
88196
- this._originWorld,
88197
- tmpVec3
88198
- );
88199
-
88200
- /**
88201
- * The length detected for each measurement axis.
88202
- */
88203
- this._factors = math.transformVec3(this._axesBasis, delta);
88204
88207
 
88205
88208
  this._wp[0] = this._originWorld[0];
88206
88209
  this._wp[1] = this._originWorld[1];
@@ -118140,172 +118143,74 @@ function loadDefaultScene(ctx) {
118140
118143
  error(ctx, "glTF has no default scene");
118141
118144
  return;
118142
118145
  }
118143
- loadScene(ctx, scene);
118144
- }
118145
118146
 
118146
- function loadScene(ctx, scene) {
118147
118147
  const nodes = scene.nodes;
118148
118148
  if (!nodes) {
118149
118149
  return;
118150
118150
  }
118151
- for (let i = 0, len = nodes.length; i < len; i++) {
118152
- const node = nodes[i];
118153
- countMeshUsage(ctx, node);
118154
- }
118155
- for (let i = 0, len = nodes.length; i < len && !ctx.nodesHaveNames; i++) {
118156
- const node = nodes[i];
118157
- if (testIfNodesHaveNames(node)) {
118158
- ctx.nodesHaveNames = true;
118159
- }
118160
- }
118161
- if (!ctx.nodesHaveNames) {
118162
- for (let i = 0, len = nodes.length; i < len; i++) {
118163
- const node = nodes[i];
118164
- parseNodesWithoutNames(ctx, node, 0, null);
118165
- }
118166
- } else {
118167
- for (let i = 0, len = nodes.length; i < len; i++) {
118168
- const node = nodes[i];
118169
- parseNodesWithNames(ctx, node, 0, null);
118170
- }
118171
- }
118172
- }
118173
118151
 
118174
- function countMeshUsage(ctx, node) {
118175
- const mesh = node.mesh;
118176
- if (mesh) {
118177
- mesh.instances = mesh.instances ? mesh.instances + 1 : 1;
118178
- }
118179
- if (node.children) {
118180
- const children = node.children;
118181
- for (let i = 0, len = children.length; i < len; i++) {
118182
- const childNode = children[i];
118183
- if (!childNode) {
118184
- error(ctx, "Node not found: " + i);
118185
- continue;
118152
+ (function accumulateMeshInstantes(nodes) {
118153
+ nodes.forEach(node => {
118154
+ const mesh = node.mesh;
118155
+ if (mesh) {
118156
+ mesh.instances ||= 0;
118157
+ mesh.instances += 1;
118186
118158
  }
118187
- countMeshUsage(ctx, childNode);
118188
- }
118189
- }
118190
- }
118191
-
118192
- function testIfNodesHaveNames(node) {
118193
- if (node.name) {
118194
- return true;
118195
- }
118196
- if (node.children) {
118197
- const children = node.children;
118198
- for (let i = 0, len = children.length; i < len; i++) {
118199
- const childNode = children[i];
118200
- if (testIfNodesHaveNames(childNode)) {
118201
- return true;
118159
+ if (node.children) {
118160
+ accumulateMeshInstantes(node.children);
118202
118161
  }
118203
- }
118204
- }
118205
- return false;
118206
- }
118162
+ });
118163
+ })(nodes);
118207
118164
 
118208
- /**
118209
- * Parses a glTF node hierarchy that is known to NOT contain "name" attributes on the nodes.
118210
- * Create a SceneMesh for each mesh primitive, and a single SceneObject.
118211
- */
118212
- const parseNodesWithoutNames = (function () {
118213
- const meshIds = [];
118214
- return function (ctx, node, depth, matrix, parentNode) {
118215
- matrix = parseNodeMatrix(node, matrix);
118216
- if (node.mesh) {
118217
- parseNodeMesh(node, ctx, matrix, meshIds);
118218
- }
118219
- if (node.children) {
118220
- const children = node.children;
118221
- for (let i = 0, len = children.length; i < len; i++) {
118222
- const childNode = children[i];
118223
- parseNodesWithoutNames(ctx, childNode, depth + 1, matrix, node);
118224
- }
118225
- }
118226
- if (depth === 0) {
118227
- let entityId = "entity-" + ctx.nextId++;
118228
- if (meshIds && meshIds.length > 0) {
118229
- ctx.sceneModel.createEntity({
118230
- id: entityId,
118231
- meshIds,
118232
- isObject: true
118233
- });
118234
- if (ctx.autoMetaModel) {
118235
- ctx.metaObjects.push({
118236
- id: entityId,
118237
- type: "Default",
118238
- name: entityId,
118239
- parent: ctx.sceneModel.id
118240
- });
118165
+ // Create a SceneMesh for each mesh primitive, and a SceneModelEntity for the root node and each named node.
118166
+ const meshIdsStack = [];
118167
+ let meshIds = null;
118168
+ (function createSceneMeshesAndEntities(nodes, depth, parentMatrix) {
118169
+ nodes.forEach(node => {
118170
+ const nodeName = node.name;
118171
+ let entityId = (((nodeName !== undefined) && (nodeName !== null) && nodeName)
118172
+ ||
118173
+ ((depth === 0) && ("entity-" + ctx.nextId++)));
118174
+
118175
+ if (entityId) {
118176
+ while (ctx.sceneModel.objects[entityId]) {
118177
+ entityId = "entity-" + ctx.nextId++;
118241
118178
  }
118242
- meshIds.length = 0;
118179
+ meshIdsStack.push(meshIds);
118180
+ meshIds = [];
118243
118181
  }
118244
- }
118245
- }
118246
- })();
118247
118182
 
118248
- const parseNodesWithNames = (function () {
118183
+ const matrix = parseNodeMatrix(node, parentMatrix);
118249
118184
 
118250
- const objectIdStack = [];
118251
- const meshIdsStack = [];
118252
- let meshIds = [];
118253
-
118254
- return function (ctx, node, depth, matrix) {
118255
- matrix = parseNodeMatrix(node, matrix);
118256
- if (meshIds && node.mesh) {
118257
- parseNodeMesh(node, ctx, matrix, meshIds);
118258
- }
118259
-
118260
- if (node.name) {
118261
- meshIds = [];
118262
- let entityId = node.name;
118263
- if (!!entityId && ctx.sceneModel.objects[entityId]) ;
118264
- while (!entityId || ctx.sceneModel.objects[entityId]) {
118265
- entityId = "entity-" + ctx.nextId++;
118185
+ if (node.mesh) {
118186
+ parseNodeMesh(node, ctx, matrix, meshIds);
118266
118187
  }
118267
- objectIdStack.push(entityId);
118268
- meshIdsStack.push(meshIds);
118269
- }
118270
118188
 
118271
- if (node.children) {
118272
- const children = node.children;
118273
- for (let i = 0, len = children.length; i < len; i++) {
118274
- const childNode = children[i];
118275
- parseNodesWithNames(ctx, childNode, depth + 1, matrix);
118189
+ if (node.children) {
118190
+ createSceneMeshesAndEntities(node.children, depth + 1, matrix);
118276
118191
  }
118277
- }
118278
-
118279
- // Post-order visit scene node
118280
118192
 
118281
- const nodeName = node.name;
118282
- if ((nodeName !== undefined && nodeName !== null) || depth === 0) {
118283
- let entityId = objectIdStack.pop();
118284
- if (!entityId) { // For when there are no nodes with names
118285
- entityId = "entity-" + ctx.nextId++;
118286
- }
118287
- let entityMeshIds = meshIdsStack.pop();
118288
- if (meshIds && meshIds.length > 0) {
118289
- ctx.sceneModel.createEntity({
118290
- id: entityId,
118291
- meshIds: entityMeshIds,
118292
- isObject: true
118293
- });
118294
- if (ctx.autoMetaModel) {
118295
- ctx.metaObjects.push({
118193
+ if (entityId) {
118194
+ if (meshIds.length > 0) {
118195
+ ctx.sceneModel.createEntity({
118296
118196
  id: entityId,
118297
- type: "Default",
118298
- name: entityId,
118299
- parent: ctx.sceneModel.id
118197
+ meshIds: meshIds,
118198
+ isObject: true
118300
118199
  });
118200
+ if (ctx.autoMetaModel) {
118201
+ ctx.metaObjects.push({
118202
+ id: entityId,
118203
+ type: "Default",
118204
+ name: entityId,
118205
+ parent: ctx.sceneModel.id
118206
+ });
118207
+ }
118301
118208
  }
118209
+ meshIds = meshIdsStack.pop();
118302
118210
  }
118303
- meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;
118304
- }
118305
- };
118306
- })();
118307
-
118308
-
118211
+ });
118212
+ })(nodes, 0, null);
118213
+ }
118309
118214
  /**
118310
118215
  * Parses transform at the given glTF node.
118311
118216
  *
@@ -126132,12 +126037,15 @@ class RenderService {
126132
126037
  return element.checked;
126133
126038
  }
126134
126039
 
126135
- setCheckbox(nodeId, checked) {
126040
+ setCheckbox(nodeId, checked, indeterminate = false) {
126136
126041
  const checkbox = document.getElementById(`checkbox-${nodeId}`);
126137
126042
  if (checkbox) {
126138
126043
  if (checked !== checkbox.checked) {
126139
126044
  checkbox.checked = checked;
126140
126045
  }
126046
+ if (indeterminate !== checkbox.indeterminate) {
126047
+ checkbox.indeterminate = indeterminate;
126048
+ }
126141
126049
  }
126142
126050
  }
126143
126051
 
@@ -126525,6 +126433,7 @@ class TreeViewPlugin extends Plugin {
126525
126433
  * vertical World axis. For all hierarchy types, other node types will be ordered in the ascending alphanumeric order of their titles.
126526
126434
  * @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.
126527
126435
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
126436
+ * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
126528
126437
  */
126529
126438
  constructor(viewer, cfg = {}) {
126530
126439
 
@@ -126576,6 +126485,7 @@ class TreeViewPlugin extends Plugin {
126576
126485
  this._pruneEmptyNodes = cfg.pruneEmptyNodes;
126577
126486
  this._showListItemElementId = null;
126578
126487
  this._renderService = cfg.renderService || new RenderService();
126488
+ this._showIndeterminate = cfg.showIndeterminate ?? false;
126579
126489
 
126580
126490
  if (!this._renderService) {
126581
126491
  throw new Error('TreeViewPlugin: no render service set');
@@ -126617,8 +126527,10 @@ class TreeViewPlugin extends Plugin {
126617
126527
  } else {
126618
126528
  parent.numVisibleEntities--;
126619
126529
  }
126620
-
126621
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
126530
+ const indeterminate = this._showIndeterminate
126531
+ && parent.numVisibleEntities > 0
126532
+ && parent.numVisibleEntities < parent.numEntities;
126533
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
126622
126534
 
126623
126535
  parent = parent.parent;
126624
126536
  }
@@ -126700,8 +126612,10 @@ class TreeViewPlugin extends Plugin {
126700
126612
  } else {
126701
126613
  parent.numVisibleEntities -= numUpdated;
126702
126614
  }
126703
-
126704
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
126615
+ const indeterminate = this._showIndeterminate
126616
+ && parent.numVisibleEntities > 0
126617
+ && parent.numVisibleEntities < parent.numEntities;
126618
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
126705
126619
 
126706
126620
  parent = parent.parent;
126707
126621
  }
@@ -126941,8 +126855,8 @@ class TreeViewPlugin extends Plugin {
126941
126855
  collapse() {
126942
126856
  for (let i = 0, len = this._rootNodes.length; i < len; i++) {
126943
126857
  const rootNode = this._rootNodes[i];
126944
- const objectId = rootNode.objectId;
126945
- this._collapseNode(objectId);
126858
+ const nodeId = rootNode.nodeId;
126859
+ this._collapseNode(nodeId);
126946
126860
  }
126947
126861
  }
126948
126862
 
@@ -139588,8 +139502,8 @@ class DotBIMDefaultDataSource {
139588
139502
  * set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
139589
139503
  * * When loading, can set the World-space position, scale and rotation of each model within World space,
139590
139504
  * along with initial properties for all the model's {@link Entity}s.
139591
- * * Allows to mask which IFC types we want to load.
139592
- * * Allows to configure initial viewer state for specified IFC types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
139505
+ * * Allows to mask which types we want to load.
139506
+ * * Allows to configure initial viewer state for specified types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
139593
139507
  *
139594
139508
  * ## Usage
139595
139509
  *
@@ -139659,9 +139573,9 @@ class DotBIMDefaultDataSource {
139659
139573
  * });
139660
139574
  * ````
139661
139575
  *
139662
- * ## Including and excluding IFC types
139576
+ * ## Including and excluding types
139663
139577
  *
139664
- * We can also load only those objects that have the specified IFC types. In the example below, we'll load only the
139578
+ * We can also load only those objects that have the specified types. In the example below, we'll load only the
139665
139579
  * objects that represent walls.
139666
139580
  *
139667
139581
  * ````javascript
@@ -139672,7 +139586,7 @@ class DotBIMDefaultDataSource {
139672
139586
  * });
139673
139587
  * ````
139674
139588
  *
139675
- * We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the
139589
+ * We can also load only those objects that **don't** have the specified types. In the example below, we'll load only the
139676
139590
  * objects that do not represent empty space.
139677
139591
  *
139678
139592
  * ````javascript
@@ -139683,13 +139597,13 @@ class DotBIMDefaultDataSource {
139683
139597
  * });
139684
139598
  * ````
139685
139599
  *
139686
- * # Configuring initial IFC object appearances
139600
+ * # Configuring initial object appearances
139687
139601
  *
139688
- * We can specify the custom initial appearance of loaded objects according to their IFC types.
139602
+ * We can specify the custom initial appearance of loaded objects according to their types.
139689
139603
  *
139690
139604
  * This is useful for things like:
139691
139605
  *
139692
- * * setting the colors to our objects according to their IFC types,
139606
+ * * setting the colors to our objects according to their types,
139693
139607
  * * automatically hiding ````IfcSpace```` objects, and
139694
139608
  * * ensuring that ````IfcWindow```` objects are always transparent.
139695
139609
  * <br>
@@ -139721,7 +139635,7 @@ class DotBIMDefaultDataSource {
139721
139635
  * });
139722
139636
  * ````
139723
139637
  *
139724
- * When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other
139638
+ * When we don't customize the appearance of types, as just above, then IfcSpace elements tend to obscure other
139725
139639
  * elements, which can be confusing.
139726
139640
  *
139727
139641
  * It's often helpful to make IfcSpaces transparent and unpickable, like this:
@@ -139921,36 +139835,36 @@ class DotBIMLoaderPlugin extends Plugin {
139921
139835
 
139922
139836
  const dbMeshLoaded = {};
139923
139837
 
139924
- const ifcProjectId = math.createUUID();
139925
- const ifcSiteId = math.createUUID();
139926
- const ifcBuildingId = math.createUUID();
139927
- const ifcBuildingStoryId = math.createUUID();
139838
+ const projectId = math.createUUID();
139839
+ const siteId = math.createUUID();
139840
+ const buildingId = math.createUUID();
139841
+ const buildingStoryId = math.createUUID();
139928
139842
 
139929
139843
  const metaModelData = {
139930
139844
  metaObjects: [
139931
139845
  {
139932
- id: ifcProjectId,
139933
- name: "IfcProject",
139934
- type: "IfcProject",
139846
+ id: projectId,
139847
+ name: "Project",
139848
+ type: "Project",
139935
139849
  parent: null
139936
139850
  },
139937
139851
  {
139938
- id: ifcSiteId,
139939
- name: "IfcSite",
139940
- type: "IfcSite",
139941
- parent: ifcProjectId
139852
+ id: siteId,
139853
+ name: "Site",
139854
+ type: "Site",
139855
+ parent: projectId
139942
139856
  },
139943
139857
  {
139944
- id: ifcBuildingId,
139945
- name: "IfcBuilding",
139946
- type: "IfcBuilding",
139947
- parent: ifcSiteId
139858
+ id: buildingId,
139859
+ name: "Building",
139860
+ type: "Building",
139861
+ parent: siteId
139948
139862
  },
139949
139863
  {
139950
- id: ifcBuildingStoryId,
139951
- name: "IfcBuildingStorey",
139952
- type: "IfcBuildingStorey",
139953
- parent: ifcBuildingId
139864
+ id: buildingStoryId,
139865
+ name: "BuildingStorey",
139866
+ type: "BuildingStorey",
139867
+ parent: buildingId
139954
139868
  }
139955
139869
  ],
139956
139870
  propertySets: []
@@ -140075,7 +139989,7 @@ class DotBIMLoaderPlugin extends Plugin {
140075
139989
  id: `${dbMeshId}-${faceColor}`,
140076
139990
  primitive: "triangles",
140077
139991
  positions: trianglesCoordinates,
140078
- indices: [...Array(trianglesCoordinates.length).keys()]
139992
+ indices: [...Array(trianglesCoordinates.length / 3).keys()]
140079
139993
  });
140080
139994
  const meshId = `${objectId}-mesh-${faceColor}`;
140081
139995
  const faceColorArray = faceColor.split(',').map(Number);
@@ -140117,30 +140031,23 @@ class DotBIMLoaderPlugin extends Plugin {
140117
140031
  });
140118
140032
  }
140119
140033
 
140034
+ let properties = [];
140120
140035
  for (let infoKey in info) {
140121
- let properties;
140122
- if (infoKey.startsWith("IFC_Pset_")) {
140123
- if (!properties) {
140124
- properties = [];
140125
- }
140126
- properties.push({
140127
- name: infoKey,
140128
- value: info[infoKey]
140129
- });
140130
- }
140131
- if (properties) {
140132
- metaModelData.propertySets.push({
140133
- id: objectId,
140134
- properties
140135
- });
140136
- }
140036
+ properties.push({
140037
+ name: infoKey,
140038
+ value: info[infoKey]
140039
+ });
140137
140040
  }
140041
+ metaModelData.propertySets.push({
140042
+ id: objectId,
140043
+ properties
140044
+ });
140138
140045
 
140139
140046
  metaModelData.metaObjects.push({
140140
140047
  id: objectId,
140141
140048
  name: info && info.Name && info.Name !== "None" ? info.Name : `${element.type} ${objectId}`,
140142
140049
  type: element.type,
140143
- parent: ifcBuildingStoryId,
140050
+ parent: buildingStoryId,
140144
140051
  propertySetIds: [objectId]
140145
140052
  });
140146
140053
  }