@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.
@@ -678,21 +678,27 @@ class ContextMenu {
678
678
  if (itemSubMenu) {
679
679
 
680
680
  html.push(
681
- '<li id="' + item.id + '" class="xeokit-context-menu-item" style="' +
682
- ((groupIdx === groupLen - 1) || ((j < lenj - 1)) ? 'border-bottom: 0' : 'border-bottom: 1px solid black') +
683
- '">' +
681
+ '<li id="' + item.id + '" class="xeokit-context-menu-item">' +
684
682
  actionTitle +
685
683
  ' [MORE]' +
686
684
  '</li>');
685
+ if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {
686
+ html.push(
687
+ '<li id="' + item.id + '" class="xeokit-context-menu-item-separator"></li>'
688
+ );
689
+ }
687
690
 
688
691
  } else {
689
692
 
690
693
  html.push(
691
- '<li id="' + item.id + '" class="xeokit-context-menu-item" style="' +
692
- ((groupIdx === groupLen - 1) || ((j < lenj - 1)) ? 'border-bottom: 0' : 'border-bottom: 1px solid black') +
693
- '">' +
694
+ '<li id="' + item.id + '" class="xeokit-context-menu-item">' +
694
695
  actionTitle +
695
696
  '</li>');
697
+ if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {
698
+ html.push(
699
+ '<li id="' + item.id + '" class="xeokit-context-menu-item-separator"></li>'
700
+ );
701
+ }
696
702
  }
697
703
  }
698
704
  }
@@ -890,14 +896,11 @@ class ContextMenu {
890
896
  const shown = getShown(this._context);
891
897
  item.shown = shown;
892
898
  if (!shown) {
893
- itemElement.style.visibility = "hidden";
894
- itemElement.style.height = "0";
895
- itemElement.style.padding = "0";
899
+ itemElement.style.display = "none";
896
900
  continue;
897
901
  } else {
898
- itemElement.style.visibility = "visible";
899
- itemElement.style.height = "auto";
900
- itemElement.style.padding = null;
902
+ itemElement.style.display = "";
903
+
901
904
  }
902
905
  const enabled = getEnabled(this._context);
903
906
  item.enabled = enabled;
@@ -88163,6 +88166,16 @@ class DistanceMeasurement extends Component {
88163
88166
  const scene = this.plugin.viewer.scene;
88164
88167
 
88165
88168
  if (this._wpDirty) {
88169
+ const delta = math.subVec3(
88170
+ this._targetWorld,
88171
+ this._originWorld,
88172
+ tmpVec3
88173
+ );
88174
+
88175
+ /**
88176
+ * The length detected for each measurement axis.
88177
+ */
88178
+ this._factors = math.transformVec3(this._axesBasis, delta);
88166
88179
 
88167
88180
  this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 0);
88168
88181
  if(this._measurementOrientation === 'Vertical' && this.useRotationAdjustment){
@@ -88187,16 +88200,6 @@ class DistanceMeasurement extends Component {
88187
88200
  this._wp[15] = 1.0;
88188
88201
  }
88189
88202
  else {
88190
- const delta = math.subVec3(
88191
- this._targetWorld,
88192
- this._originWorld,
88193
- tmpVec3
88194
- );
88195
-
88196
- /**
88197
- * The length detected for each measurement axis.
88198
- */
88199
- this._factors = math.transformVec3(this._axesBasis, delta);
88200
88203
 
88201
88204
  this._wp[0] = this._originWorld[0];
88202
88205
  this._wp[1] = this._originWorld[1];
@@ -118136,172 +118139,74 @@ function loadDefaultScene(ctx) {
118136
118139
  error(ctx, "glTF has no default scene");
118137
118140
  return;
118138
118141
  }
118139
- loadScene(ctx, scene);
118140
- }
118141
118142
 
118142
- function loadScene(ctx, scene) {
118143
118143
  const nodes = scene.nodes;
118144
118144
  if (!nodes) {
118145
118145
  return;
118146
118146
  }
118147
- for (let i = 0, len = nodes.length; i < len; i++) {
118148
- const node = nodes[i];
118149
- countMeshUsage(ctx, node);
118150
- }
118151
- for (let i = 0, len = nodes.length; i < len && !ctx.nodesHaveNames; i++) {
118152
- const node = nodes[i];
118153
- if (testIfNodesHaveNames(node)) {
118154
- ctx.nodesHaveNames = true;
118155
- }
118156
- }
118157
- if (!ctx.nodesHaveNames) {
118158
- for (let i = 0, len = nodes.length; i < len; i++) {
118159
- const node = nodes[i];
118160
- parseNodesWithoutNames(ctx, node, 0, null);
118161
- }
118162
- } else {
118163
- for (let i = 0, len = nodes.length; i < len; i++) {
118164
- const node = nodes[i];
118165
- parseNodesWithNames(ctx, node, 0, null);
118166
- }
118167
- }
118168
- }
118169
118147
 
118170
- function countMeshUsage(ctx, node) {
118171
- const mesh = node.mesh;
118172
- if (mesh) {
118173
- mesh.instances = mesh.instances ? mesh.instances + 1 : 1;
118174
- }
118175
- if (node.children) {
118176
- const children = node.children;
118177
- for (let i = 0, len = children.length; i < len; i++) {
118178
- const childNode = children[i];
118179
- if (!childNode) {
118180
- error(ctx, "Node not found: " + i);
118181
- continue;
118148
+ (function accumulateMeshInstantes(nodes) {
118149
+ nodes.forEach(node => {
118150
+ const mesh = node.mesh;
118151
+ if (mesh) {
118152
+ mesh.instances ||= 0;
118153
+ mesh.instances += 1;
118182
118154
  }
118183
- countMeshUsage(ctx, childNode);
118184
- }
118185
- }
118186
- }
118187
-
118188
- function testIfNodesHaveNames(node) {
118189
- if (node.name) {
118190
- return true;
118191
- }
118192
- if (node.children) {
118193
- const children = node.children;
118194
- for (let i = 0, len = children.length; i < len; i++) {
118195
- const childNode = children[i];
118196
- if (testIfNodesHaveNames(childNode)) {
118197
- return true;
118155
+ if (node.children) {
118156
+ accumulateMeshInstantes(node.children);
118198
118157
  }
118199
- }
118200
- }
118201
- return false;
118202
- }
118158
+ });
118159
+ })(nodes);
118203
118160
 
118204
- /**
118205
- * Parses a glTF node hierarchy that is known to NOT contain "name" attributes on the nodes.
118206
- * Create a SceneMesh for each mesh primitive, and a single SceneObject.
118207
- */
118208
- const parseNodesWithoutNames = (function () {
118209
- const meshIds = [];
118210
- return function (ctx, node, depth, matrix, parentNode) {
118211
- matrix = parseNodeMatrix(node, matrix);
118212
- if (node.mesh) {
118213
- parseNodeMesh(node, ctx, matrix, meshIds);
118214
- }
118215
- if (node.children) {
118216
- const children = node.children;
118217
- for (let i = 0, len = children.length; i < len; i++) {
118218
- const childNode = children[i];
118219
- parseNodesWithoutNames(ctx, childNode, depth + 1, matrix, node);
118220
- }
118221
- }
118222
- if (depth === 0) {
118223
- let entityId = "entity-" + ctx.nextId++;
118224
- if (meshIds && meshIds.length > 0) {
118225
- ctx.sceneModel.createEntity({
118226
- id: entityId,
118227
- meshIds,
118228
- isObject: true
118229
- });
118230
- if (ctx.autoMetaModel) {
118231
- ctx.metaObjects.push({
118232
- id: entityId,
118233
- type: "Default",
118234
- name: entityId,
118235
- parent: ctx.sceneModel.id
118236
- });
118161
+ // Create a SceneMesh for each mesh primitive, and a SceneModelEntity for the root node and each named node.
118162
+ const meshIdsStack = [];
118163
+ let meshIds = null;
118164
+ (function createSceneMeshesAndEntities(nodes, depth, parentMatrix) {
118165
+ nodes.forEach(node => {
118166
+ const nodeName = node.name;
118167
+ let entityId = (((nodeName !== undefined) && (nodeName !== null) && nodeName)
118168
+ ||
118169
+ ((depth === 0) && ("entity-" + ctx.nextId++)));
118170
+
118171
+ if (entityId) {
118172
+ while (ctx.sceneModel.objects[entityId]) {
118173
+ entityId = "entity-" + ctx.nextId++;
118237
118174
  }
118238
- meshIds.length = 0;
118175
+ meshIdsStack.push(meshIds);
118176
+ meshIds = [];
118239
118177
  }
118240
- }
118241
- }
118242
- })();
118243
118178
 
118244
- const parseNodesWithNames = (function () {
118179
+ const matrix = parseNodeMatrix(node, parentMatrix);
118245
118180
 
118246
- const objectIdStack = [];
118247
- const meshIdsStack = [];
118248
- let meshIds = [];
118249
-
118250
- return function (ctx, node, depth, matrix) {
118251
- matrix = parseNodeMatrix(node, matrix);
118252
- if (meshIds && node.mesh) {
118253
- parseNodeMesh(node, ctx, matrix, meshIds);
118254
- }
118255
-
118256
- if (node.name) {
118257
- meshIds = [];
118258
- let entityId = node.name;
118259
- if (!!entityId && ctx.sceneModel.objects[entityId]) ;
118260
- while (!entityId || ctx.sceneModel.objects[entityId]) {
118261
- entityId = "entity-" + ctx.nextId++;
118181
+ if (node.mesh) {
118182
+ parseNodeMesh(node, ctx, matrix, meshIds);
118262
118183
  }
118263
- objectIdStack.push(entityId);
118264
- meshIdsStack.push(meshIds);
118265
- }
118266
118184
 
118267
- if (node.children) {
118268
- const children = node.children;
118269
- for (let i = 0, len = children.length; i < len; i++) {
118270
- const childNode = children[i];
118271
- parseNodesWithNames(ctx, childNode, depth + 1, matrix);
118185
+ if (node.children) {
118186
+ createSceneMeshesAndEntities(node.children, depth + 1, matrix);
118272
118187
  }
118273
- }
118274
-
118275
- // Post-order visit scene node
118276
118188
 
118277
- const nodeName = node.name;
118278
- if ((nodeName !== undefined && nodeName !== null) || depth === 0) {
118279
- let entityId = objectIdStack.pop();
118280
- if (!entityId) { // For when there are no nodes with names
118281
- entityId = "entity-" + ctx.nextId++;
118282
- }
118283
- let entityMeshIds = meshIdsStack.pop();
118284
- if (meshIds && meshIds.length > 0) {
118285
- ctx.sceneModel.createEntity({
118286
- id: entityId,
118287
- meshIds: entityMeshIds,
118288
- isObject: true
118289
- });
118290
- if (ctx.autoMetaModel) {
118291
- ctx.metaObjects.push({
118189
+ if (entityId) {
118190
+ if (meshIds.length > 0) {
118191
+ ctx.sceneModel.createEntity({
118292
118192
  id: entityId,
118293
- type: "Default",
118294
- name: entityId,
118295
- parent: ctx.sceneModel.id
118193
+ meshIds: meshIds,
118194
+ isObject: true
118296
118195
  });
118196
+ if (ctx.autoMetaModel) {
118197
+ ctx.metaObjects.push({
118198
+ id: entityId,
118199
+ type: "Default",
118200
+ name: entityId,
118201
+ parent: ctx.sceneModel.id
118202
+ });
118203
+ }
118297
118204
  }
118205
+ meshIds = meshIdsStack.pop();
118298
118206
  }
118299
- meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;
118300
- }
118301
- };
118302
- })();
118303
-
118304
-
118207
+ });
118208
+ })(nodes, 0, null);
118209
+ }
118305
118210
  /**
118306
118211
  * Parses transform at the given glTF node.
118307
118212
  *
@@ -126128,12 +126033,15 @@ class RenderService {
126128
126033
  return element.checked;
126129
126034
  }
126130
126035
 
126131
- setCheckbox(nodeId, checked) {
126036
+ setCheckbox(nodeId, checked, indeterminate = false) {
126132
126037
  const checkbox = document.getElementById(`checkbox-${nodeId}`);
126133
126038
  if (checkbox) {
126134
126039
  if (checked !== checkbox.checked) {
126135
126040
  checkbox.checked = checked;
126136
126041
  }
126042
+ if (indeterminate !== checkbox.indeterminate) {
126043
+ checkbox.indeterminate = indeterminate;
126044
+ }
126137
126045
  }
126138
126046
  }
126139
126047
 
@@ -126521,6 +126429,7 @@ class TreeViewPlugin extends Plugin {
126521
126429
  * vertical World axis. For all hierarchy types, other node types will be ordered in the ascending alphanumeric order of their titles.
126522
126430
  * @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.
126523
126431
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
126432
+ * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
126524
126433
  */
126525
126434
  constructor(viewer, cfg = {}) {
126526
126435
 
@@ -126572,6 +126481,7 @@ class TreeViewPlugin extends Plugin {
126572
126481
  this._pruneEmptyNodes = cfg.pruneEmptyNodes;
126573
126482
  this._showListItemElementId = null;
126574
126483
  this._renderService = cfg.renderService || new RenderService();
126484
+ this._showIndeterminate = cfg.showIndeterminate ?? false;
126575
126485
 
126576
126486
  if (!this._renderService) {
126577
126487
  throw new Error('TreeViewPlugin: no render service set');
@@ -126613,8 +126523,10 @@ class TreeViewPlugin extends Plugin {
126613
126523
  } else {
126614
126524
  parent.numVisibleEntities--;
126615
126525
  }
126616
-
126617
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
126526
+ const indeterminate = this._showIndeterminate
126527
+ && parent.numVisibleEntities > 0
126528
+ && parent.numVisibleEntities < parent.numEntities;
126529
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
126618
126530
 
126619
126531
  parent = parent.parent;
126620
126532
  }
@@ -126696,8 +126608,10 @@ class TreeViewPlugin extends Plugin {
126696
126608
  } else {
126697
126609
  parent.numVisibleEntities -= numUpdated;
126698
126610
  }
126699
-
126700
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
126611
+ const indeterminate = this._showIndeterminate
126612
+ && parent.numVisibleEntities > 0
126613
+ && parent.numVisibleEntities < parent.numEntities;
126614
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
126701
126615
 
126702
126616
  parent = parent.parent;
126703
126617
  }
@@ -126937,8 +126851,8 @@ class TreeViewPlugin extends Plugin {
126937
126851
  collapse() {
126938
126852
  for (let i = 0, len = this._rootNodes.length; i < len; i++) {
126939
126853
  const rootNode = this._rootNodes[i];
126940
- const objectId = rootNode.objectId;
126941
- this._collapseNode(objectId);
126854
+ const nodeId = rootNode.nodeId;
126855
+ this._collapseNode(nodeId);
126942
126856
  }
126943
126857
  }
126944
126858
 
@@ -139584,8 +139498,8 @@ class DotBIMDefaultDataSource {
139584
139498
  * set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
139585
139499
  * * When loading, can set the World-space position, scale and rotation of each model within World space,
139586
139500
  * along with initial properties for all the model's {@link Entity}s.
139587
- * * Allows to mask which IFC types we want to load.
139588
- * * Allows to configure initial viewer state for specified IFC types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
139501
+ * * Allows to mask which types we want to load.
139502
+ * * Allows to configure initial viewer state for specified types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
139589
139503
  *
139590
139504
  * ## Usage
139591
139505
  *
@@ -139655,9 +139569,9 @@ class DotBIMDefaultDataSource {
139655
139569
  * });
139656
139570
  * ````
139657
139571
  *
139658
- * ## Including and excluding IFC types
139572
+ * ## Including and excluding types
139659
139573
  *
139660
- * We can also load only those objects that have the specified IFC types. In the example below, we'll load only the
139574
+ * We can also load only those objects that have the specified types. In the example below, we'll load only the
139661
139575
  * objects that represent walls.
139662
139576
  *
139663
139577
  * ````javascript
@@ -139668,7 +139582,7 @@ class DotBIMDefaultDataSource {
139668
139582
  * });
139669
139583
  * ````
139670
139584
  *
139671
- * We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the
139585
+ * We can also load only those objects that **don't** have the specified types. In the example below, we'll load only the
139672
139586
  * objects that do not represent empty space.
139673
139587
  *
139674
139588
  * ````javascript
@@ -139679,13 +139593,13 @@ class DotBIMDefaultDataSource {
139679
139593
  * });
139680
139594
  * ````
139681
139595
  *
139682
- * # Configuring initial IFC object appearances
139596
+ * # Configuring initial object appearances
139683
139597
  *
139684
- * We can specify the custom initial appearance of loaded objects according to their IFC types.
139598
+ * We can specify the custom initial appearance of loaded objects according to their types.
139685
139599
  *
139686
139600
  * This is useful for things like:
139687
139601
  *
139688
- * * setting the colors to our objects according to their IFC types,
139602
+ * * setting the colors to our objects according to their types,
139689
139603
  * * automatically hiding ````IfcSpace```` objects, and
139690
139604
  * * ensuring that ````IfcWindow```` objects are always transparent.
139691
139605
  * <br>
@@ -139717,7 +139631,7 @@ class DotBIMDefaultDataSource {
139717
139631
  * });
139718
139632
  * ````
139719
139633
  *
139720
- * When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other
139634
+ * When we don't customize the appearance of types, as just above, then IfcSpace elements tend to obscure other
139721
139635
  * elements, which can be confusing.
139722
139636
  *
139723
139637
  * It's often helpful to make IfcSpaces transparent and unpickable, like this:
@@ -139917,36 +139831,36 @@ class DotBIMLoaderPlugin extends Plugin {
139917
139831
 
139918
139832
  const dbMeshLoaded = {};
139919
139833
 
139920
- const ifcProjectId = math.createUUID();
139921
- const ifcSiteId = math.createUUID();
139922
- const ifcBuildingId = math.createUUID();
139923
- const ifcBuildingStoryId = math.createUUID();
139834
+ const projectId = math.createUUID();
139835
+ const siteId = math.createUUID();
139836
+ const buildingId = math.createUUID();
139837
+ const buildingStoryId = math.createUUID();
139924
139838
 
139925
139839
  const metaModelData = {
139926
139840
  metaObjects: [
139927
139841
  {
139928
- id: ifcProjectId,
139929
- name: "IfcProject",
139930
- type: "IfcProject",
139842
+ id: projectId,
139843
+ name: "Project",
139844
+ type: "Project",
139931
139845
  parent: null
139932
139846
  },
139933
139847
  {
139934
- id: ifcSiteId,
139935
- name: "IfcSite",
139936
- type: "IfcSite",
139937
- parent: ifcProjectId
139848
+ id: siteId,
139849
+ name: "Site",
139850
+ type: "Site",
139851
+ parent: projectId
139938
139852
  },
139939
139853
  {
139940
- id: ifcBuildingId,
139941
- name: "IfcBuilding",
139942
- type: "IfcBuilding",
139943
- parent: ifcSiteId
139854
+ id: buildingId,
139855
+ name: "Building",
139856
+ type: "Building",
139857
+ parent: siteId
139944
139858
  },
139945
139859
  {
139946
- id: ifcBuildingStoryId,
139947
- name: "IfcBuildingStorey",
139948
- type: "IfcBuildingStorey",
139949
- parent: ifcBuildingId
139860
+ id: buildingStoryId,
139861
+ name: "BuildingStorey",
139862
+ type: "BuildingStorey",
139863
+ parent: buildingId
139950
139864
  }
139951
139865
  ],
139952
139866
  propertySets: []
@@ -140071,7 +139985,7 @@ class DotBIMLoaderPlugin extends Plugin {
140071
139985
  id: `${dbMeshId}-${faceColor}`,
140072
139986
  primitive: "triangles",
140073
139987
  positions: trianglesCoordinates,
140074
- indices: [...Array(trianglesCoordinates.length).keys()]
139988
+ indices: [...Array(trianglesCoordinates.length / 3).keys()]
140075
139989
  });
140076
139990
  const meshId = `${objectId}-mesh-${faceColor}`;
140077
139991
  const faceColorArray = faceColor.split(',').map(Number);
@@ -140113,30 +140027,23 @@ class DotBIMLoaderPlugin extends Plugin {
140113
140027
  });
140114
140028
  }
140115
140029
 
140030
+ let properties = [];
140116
140031
  for (let infoKey in info) {
140117
- let properties;
140118
- if (infoKey.startsWith("IFC_Pset_")) {
140119
- if (!properties) {
140120
- properties = [];
140121
- }
140122
- properties.push({
140123
- name: infoKey,
140124
- value: info[infoKey]
140125
- });
140126
- }
140127
- if (properties) {
140128
- metaModelData.propertySets.push({
140129
- id: objectId,
140130
- properties
140131
- });
140132
- }
140032
+ properties.push({
140033
+ name: infoKey,
140034
+ value: info[infoKey]
140035
+ });
140133
140036
  }
140037
+ metaModelData.propertySets.push({
140038
+ id: objectId,
140039
+ properties
140040
+ });
140134
140041
 
140135
140042
  metaModelData.metaObjects.push({
140136
140043
  id: objectId,
140137
140044
  name: info && info.Name && info.Name !== "None" ? info.Name : `${element.type} ${objectId}`,
140138
140045
  type: element.type,
140139
- parent: ifcBuildingStoryId,
140046
+ parent: buildingStoryId,
140140
140047
  propertySetIds: [objectId]
140141
140048
  });
140142
140049
  }