@xeokit/xeokit-sdk 2.5.2-beta-4 → 2.5.2-beta-7

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.
@@ -80323,8 +80323,6 @@ class SceneModel extends Component {
80323
80323
  this._vboBatchingLayers = {};
80324
80324
  this._dtxLayers = {};
80325
80325
 
80326
- this._meshList = [];
80327
-
80328
80326
  this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second
80329
80327
  this._entityList = [];
80330
80328
 
@@ -80337,6 +80335,7 @@ class SceneModel extends Component {
80337
80335
  this._entities = {};
80338
80336
 
80339
80337
  this._scheduledMeshes = {};
80338
+ this._meshesCfgsBeforeMeshCreation = {};
80340
80339
 
80341
80340
  /** @private **/
80342
80341
  this.renderFlags = new RenderFlags();
@@ -81867,7 +81866,7 @@ class SceneModel extends Component {
81867
81866
  /**
81868
81867
  * Creates a new {@link SceneModelMesh} within this SceneModel.
81869
81868
  *
81870
- * * Stores the new SceneModelMesh in {@link SceneModel#meshes}.
81869
+ * * It prepares and saves data for a SceneModelMesh {@link SceneModel#meshes} creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.
81871
81870
  * * The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the
81872
81871
  * various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier
81873
81872
  * with {@link SceneModel#createGeometry}.
@@ -81902,18 +81901,18 @@ class SceneModel extends Component {
81902
81901
  * @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.
81903
81902
  * @param {Number} [cfg.metallic=0] Metallic factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.
81904
81903
  * @param {Number} [cfg.roughness=1] Roughness factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.
81905
- * @returns {SceneModelMesh} The new mesh.
81904
+ * @returns {Boolean} True = successfully mesh was created. False = error during creation of a mesh.
81906
81905
  */
81907
81906
  createMesh(cfg) {
81908
81907
 
81909
81908
  if (cfg.id === undefined || cfg.id === null) {
81910
81909
  this.error("[createMesh] SceneModel.createMesh() config missing: id");
81911
- return;
81910
+ return false;
81912
81911
  }
81913
81912
 
81914
81913
  if (this._scheduledMeshes[cfg.id]) {
81915
81914
  this.error(`[createMesh] SceneModel already has a mesh with this ID: ${cfg.id}`);
81916
- return;
81915
+ return false;
81917
81916
  }
81918
81917
 
81919
81918
  const instancing = (cfg.geometryId !== undefined);
@@ -81928,31 +81927,31 @@ class SceneModel extends Component {
81928
81927
  }
81929
81928
  if (cfg.primitive !== "points" && cfg.primitive !== "lines" && cfg.primitive !== "triangles" && cfg.primitive !== "solid" && cfg.primitive !== "surface") {
81930
81929
  this.error(`Unsupported value for 'primitive': '${primitive}' ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`);
81931
- return;
81930
+ return false;
81932
81931
  }
81933
81932
  if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {
81934
81933
  this.error("Param expected: 'positions', 'positionsCompressed' or `buckets` ('geometryId' is absent)");
81935
- return null;
81934
+ return false;
81936
81935
  }
81937
81936
  if (cfg.positions && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)) {
81938
81937
  this.error("Illegal params: 'positions' not expected with 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)");
81939
- return null;
81938
+ return false;
81940
81939
  }
81941
81940
  if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {
81942
81941
  this.error("Param expected: 'positionsCompressed' should be accompanied by 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)");
81943
- return null;
81942
+ return false;
81944
81943
  }
81945
81944
  if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {
81946
81945
  this.error("Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)");
81947
- return null;
81946
+ return false;
81948
81947
  }
81949
81948
  if (!cfg.buckets && !cfg.indices && cfg.primitive !== "points") {
81950
81949
  this.error(`Param expected: indices (required for '${cfg.primitive}' primitive type)`);
81951
- return null;
81950
+ return false;
81952
81951
  }
81953
81952
  if ((cfg.matrix || cfg.position || cfg.rotation || cfg.scale) && (cfg.positionsCompressed || cfg.positionsDecodeBoundary)) {
81954
81953
  this.error("Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'");
81955
- return null;
81954
+ return false;
81956
81955
  }
81957
81956
 
81958
81957
  const useDTX = (!!this._dtxEnabled && (cfg.primitive === "triangles"
@@ -82117,7 +82116,7 @@ class SceneModel extends Component {
82117
82116
  cfg.textureSet = this._textureSets[cfg.textureSetId];
82118
82117
  if (!cfg.textureSet) {
82119
82118
  this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
82120
- return;
82119
+ return false;
82121
82120
  }
82122
82121
  }
82123
82122
  }
@@ -82128,13 +82127,13 @@ class SceneModel extends Component {
82128
82127
 
82129
82128
  if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {
82130
82129
  this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);
82131
- return;
82130
+ return false;
82132
82131
  }
82133
82132
 
82134
82133
  cfg.geometry = this._geometries[cfg.geometryId];
82135
82134
  if (!cfg.geometry) {
82136
82135
  this.error(`[createMesh] Geometry not found: ${cfg.geometryId} - ensure that you create it first with createGeometry()`);
82137
- return;
82136
+ return false;
82138
82137
  }
82139
82138
 
82140
82139
  cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
@@ -82148,7 +82147,7 @@ class SceneModel extends Component {
82148
82147
 
82149
82148
  if (!cfg.transform) {
82150
82149
  this.error(`[createMesh] Transform not found: ${cfg.transformId} - ensure that you create it first with createTransform()`);
82151
- return;
82150
+ return false;
82152
82151
  }
82153
82152
 
82154
82153
  cfg.aabb = cfg.geometry.aabb;
@@ -82216,7 +82215,7 @@ class SceneModel extends Component {
82216
82215
  cfg.textureSet = this._textureSets[cfg.textureSetId];
82217
82216
  // if (!cfg.textureSet) {
82218
82217
  // this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
82219
- // return;
82218
+ // return false;
82220
82219
  // }
82221
82220
  }
82222
82221
  }
@@ -82224,7 +82223,9 @@ class SceneModel extends Component {
82224
82223
 
82225
82224
  cfg.numPrimitives = this._getNumPrimitives(cfg);
82226
82225
 
82227
- return this._createMesh(cfg);
82226
+ this._meshesCfgsBeforeMeshCreation[cfg.id] = cfg;
82227
+
82228
+ return true;
82228
82229
  }
82229
82230
 
82230
82231
  _createMesh(cfg) {
@@ -82256,8 +82257,6 @@ class SceneModel extends Component {
82256
82257
  cfg.meshMatrix = cfg.transform.worldMatrix;
82257
82258
  }
82258
82259
  mesh.portionId = mesh.layer.createPortion(mesh, cfg);
82259
- this._meshes[cfg.id] = mesh;
82260
- this._meshList.push(mesh);
82261
82260
  return mesh;
82262
82261
  }
82263
82262
 
@@ -82616,10 +82615,15 @@ class SceneModel extends Component {
82616
82615
  let meshes = [];
82617
82616
  for (let i = 0, len = cfg.meshIds.length; i < len; i++) {
82618
82617
  const meshId = cfg.meshIds[i];
82619
- const mesh = this._meshes[meshId];
82620
- if (!mesh) {
82621
- this.error(`Mesh with this ID not found: "${meshId}" - ignoring this mesh`);
82622
- continue;
82618
+ let mesh = this._meshes[meshId]; // Trying to get already created mesh
82619
+ if (!mesh) { // Checks if there is already created mesh for this meshId
82620
+ let meshCfg = this._meshesCfgsBeforeMeshCreation[meshId]; // Trying to get already created cfg
82621
+ if (!meshCfg) { // Checks if there is already created cfg for this meshId
82622
+ this.error(`Mesh with this ID not found: "${meshId}" - ignoring this mesh`); // There is no such cfg
82623
+ continue;
82624
+ }
82625
+ mesh = this._createMesh(meshCfg); // There is no such mesh yet, but there is already created cfg, so it creates this mesh
82626
+ this._meshes[cfg.id] = mesh; // Now it will also add this mesh to dictionary of created meshes
82623
82627
  }
82624
82628
  if (mesh.parent) {
82625
82629
  this.error(`Mesh with ID "${meshId}" already belongs to object with ID "${mesh.parent.id}" - ignoring this mesh`);
@@ -114018,6 +114022,7 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
114018
114022
 
114019
114023
  const cubeColor = "lightgrey";
114020
114024
  const cubeHighlightColor = cfg.hoverColor || "rgba(0,0,0,0.4)";
114025
+ const textColor = cfg.textColor || "black";
114021
114026
 
114022
114027
  const height = 500;
114023
114028
  const width = height + (height / 3);
@@ -114167,7 +114172,7 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
114167
114172
  }
114168
114173
  }
114169
114174
  if (area.label) {
114170
- context.fillStyle = "black";
114175
+ context.fillStyle = textColor;
114171
114176
  context.font = '60px sans-serif';
114172
114177
  context.textAlign = "center";
114173
114178
  var xcenter = xmin + (width * 0.5);
@@ -114371,7 +114376,7 @@ class NavCubePlugin extends Plugin {
114371
114376
  * @param {String} [cfg.cameraFly=true] Whether the {@link Camera} flies or jumps to each selected axis or diagonal.
114372
114377
  * @param {String} [cfg.cameraFitFOV=45] How much of the field-of-view, in degrees, that the 3D scene should fill the {@link Canvas} when the {@link Camera} moves to an axis or diagonal.
114373
114378
  * @param {String} [cfg.cameraFlyDuration=0.5] When flying the {@link Camera} to each new axis or diagonal, how long, in seconds, that the Camera takes to get there.
114374
- * @param {String} [cfg.color="lightgrey] Custom uniform color for the faces of the NavCube.
114379
+ * @param {String} [cfg.color="lightgrey"] Custom uniform color for the faces of the NavCube.
114375
114380
  * @param {String} [cfg.frontColor="#55FF55"] Custom color for the front face of the NavCube. Overrides ````color````.
114376
114381
  * @param {String} [cfg.backColor="#55FF55"] Custom color for the back face of the NavCube. Overrides ````color````.
114377
114382
  * @param {String} [cfg.leftColor="#FF5555"] Custom color for the left face of the NavCube. Overrides ````color````.
@@ -114379,6 +114384,7 @@ class NavCubePlugin extends Plugin {
114379
114384
  * @param {String} [cfg.topColor="#5555FF"] Custom color for the top face of the NavCube. Overrides ````color````.
114380
114385
  * @param {String} [cfg.bottomColor="#5555FF"] Custom color for the bottom face of the NavCube. Overrides ````color````.
114381
114386
  * @param {String} [cfg.hoverColor="rgba(0,0,0,0.4)"] Custom color for highlighting regions on the NavCube as we hover the pointer over them.
114387
+ * @param {String} [cfg.textColor="black"] Custom text color for labels of the NavCube.
114382
114388
  * @param {Boolean} [cfg.fitVisible=false] Sets whether the axis, corner and edge-aligned views will fit the
114383
114389
  * view to the entire {@link Scene} or just to visible object-{@link Entity}s. Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.
114384
114390
  * @param {Boolean} [cfg.synchProjection=false] Sets whether the NavCube switches between perspective and orthographic projections in synchrony with the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.
@@ -121081,6 +121087,176 @@ class STLLoaderPlugin extends Plugin {
121081
121087
  }
121082
121088
  }
121083
121089
 
121090
+ /**
121091
+ * @desc A {@link TreeViewPlugin} render class.
121092
+ *
121093
+ */
121094
+ class RenderService {
121095
+
121096
+ /*
121097
+ * Creates the root node of the tree.
121098
+ * @return {HTMLElement} The root node of the tree.
121099
+ */
121100
+ createRootNode() {
121101
+ return document.createElement('ul')
121102
+ }
121103
+
121104
+ /*
121105
+ * Creates node of the tree.
121106
+ * @param {Object} node The node to create.
121107
+
121108
+ * @return {HTMLElement} The html element for the node.
121109
+ */
121110
+ createNodeElement(node, expandHandler, checkHandler, contextmenuHandler, titleClickHandler) {
121111
+ const nodeElement = document.createElement('li');
121112
+ nodeElement.id = node.nodeId;
121113
+
121114
+ if (node.xrayed) {
121115
+ nodeElement.classList.add('xrayed-node');
121116
+ }
121117
+
121118
+ if (node.children.length > 0) {
121119
+ const switchElement = document.createElement('a');
121120
+ switchElement.href = '#';
121121
+ switchElement.id = `switch-${node.nodeId}`;
121122
+ switchElement.textContent = '+';
121123
+ switchElement.classList.add('plus');
121124
+ if (expandHandler) switchElement.addEventListener('click', expandHandler);
121125
+ nodeElement.appendChild(switchElement);
121126
+ }
121127
+
121128
+ const checkbox = document.createElement('input');
121129
+ checkbox.id = `checkbox-${node.nodeId}`;
121130
+ checkbox.type = "checkbox";
121131
+ checkbox.checked = node.checked;
121132
+ checkbox.style["pointer-events"] = "all";
121133
+ if (checkHandler) checkbox.addEventListener("change", checkHandler);
121134
+ nodeElement.appendChild(checkbox);
121135
+
121136
+ const span = document.createElement('span');
121137
+ span.textContent = node.title;
121138
+ nodeElement.appendChild(span);
121139
+
121140
+ if (contextmenuHandler) {
121141
+ span.oncontextmenu = contextmenuHandler;
121142
+ }
121143
+
121144
+ if (titleClickHandler) {
121145
+ span.onclick = titleClickHandler;
121146
+ }
121147
+
121148
+ return nodeElement;
121149
+ }
121150
+
121151
+ createDisabledNodeElement(rootName) {
121152
+ const li = document.createElement('li');
121153
+
121154
+ const switchElement = document.createElement('a');
121155
+ switchElement.href = '#';
121156
+ switchElement.textContent = '!';
121157
+ switchElement.classList.add('warn');
121158
+ switchElement.classList.add('warning');
121159
+ li.appendChild(switchElement);
121160
+
121161
+ const span = document.createElement('span');
121162
+ span.textContent = rootName;
121163
+ li.appendChild(span);
121164
+
121165
+ return li;
121166
+ }
121167
+
121168
+ addChildren(element, nodes) {
121169
+ const ul = document.createElement('ul');
121170
+ nodes.forEach((nodeElement) => {
121171
+ ul.appendChild(nodeElement);
121172
+ });
121173
+
121174
+ element.parentElement.appendChild(ul);
121175
+ }
121176
+
121177
+ expand(element, expandHandler, collapseHandler) {
121178
+ element.classList.remove('plus');
121179
+ element.classList.add('minus');
121180
+ element.textContent = '-';
121181
+ element.removeEventListener('click', expandHandler);
121182
+ element.addEventListener('click', collapseHandler);
121183
+ }
121184
+
121185
+ collapse(element, expandHandler, collapseHandler) {
121186
+ if (!element) {
121187
+ return;
121188
+ }
121189
+ const parent = element.parentElement;
121190
+ if (!parent) {
121191
+ return;
121192
+ }
121193
+ const ul = parent.querySelector('ul');
121194
+ if (!ul) {
121195
+ return;
121196
+ }
121197
+ parent.removeChild(ul);
121198
+ element.classList.remove('minus');
121199
+ element.classList.add('plus');
121200
+ element.textContent = '+';
121201
+ element.removeEventListener('click', collapseHandler);
121202
+ element.addEventListener('click', expandHandler);
121203
+ }
121204
+
121205
+ isExpanded(element) {
121206
+ const parentElement = element.parentElement;
121207
+ return parentElement.getElementsByTagName('li')[0] !== undefined;
121208
+ }
121209
+
121210
+ getId(element) {
121211
+ const parentElement = element.parentElement;
121212
+ return parentElement.id;
121213
+ }
121214
+
121215
+ getIdFromCheckbox(element) {
121216
+ return element.id.replace('checkbox-', '');
121217
+ }
121218
+
121219
+ getSwitchElement(nodeId) {
121220
+ return document.getElementById(`switch-${nodeId}`);
121221
+ }
121222
+
121223
+ isChecked(element) {
121224
+ return element.checked;
121225
+ }
121226
+
121227
+ setCheckbox(nodeId, checked) {
121228
+ const checkbox = document.getElementById(`checkbox-${nodeId}`);
121229
+ if (checkbox) {
121230
+ if (checked !== checkbox.checked) {
121231
+ checkbox.checked = checked;
121232
+ }
121233
+ }
121234
+ }
121235
+
121236
+ setXRayed(nodeId, xrayed) {
121237
+ const treeNode = document.getElementById(nodeId);
121238
+ if (treeNode) {
121239
+ if (xrayed) {
121240
+ treeNode.classList.add('xrayed-node');
121241
+ } else {
121242
+ treeNode.classList.remove('xrayed-node');
121243
+ }
121244
+ }
121245
+ }
121246
+
121247
+ setHighlighted(nodeId, highlighted) {
121248
+ const treeNode = document.getElementById(nodeId);
121249
+ if (treeNode) {
121250
+ if (highlighted) {
121251
+ treeNode.scrollIntoView({block: "center"});
121252
+ treeNode.classList.add('highlighted-node');
121253
+ } else {
121254
+ treeNode.classList.remove('highlighted-node');
121255
+ }
121256
+ }
121257
+ }
121258
+ }
121259
+
121084
121260
  const treeViews = [];
121085
121261
 
121086
121262
  /**
@@ -121440,6 +121616,7 @@ class TreeViewPlugin extends Plugin {
121440
121616
  * ````IfcBuildingStorey```` nodes will be ordered spatially, from the highest storey down to the lowest, on the
121441
121617
  * vertical World axis. For all hierarchy types, other node types will be ordered in the ascending alphanumeric order of their titles.
121442
121618
  * @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.
121619
+ * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
121443
121620
  */
121444
121621
  constructor(viewer, cfg = {}) {
121445
121622
 
@@ -121479,7 +121656,6 @@ class TreeViewPlugin extends Plugin {
121479
121656
  this._autoAddModels = (cfg.autoAddModels !== false);
121480
121657
  this._autoExpandDepth = (cfg.autoExpandDepth || 0);
121481
121658
  this._sortNodes = (cfg.sortNodes !== false);
121482
- this._pruneEmptyNodes = (cfg.pruneEmptyNodes !== false);
121483
121659
  this._viewer = viewer;
121484
121660
  this._rootElement = null;
121485
121661
  this._muteSceneEvents = false;
@@ -121487,10 +121663,15 @@ class TreeViewPlugin extends Plugin {
121487
121663
  this._rootNodes = [];
121488
121664
  this._objectNodes = {}; // Object ID -> Node
121489
121665
  this._nodeNodes = {}; // Node ID -> Node
121490
- this._rootName = cfg.rootName;
121666
+ this._rootNames = {}; // Node ID -> Root name
121491
121667
  this._sortNodes = cfg.sortNodes;
121492
121668
  this._pruneEmptyNodes = cfg.pruneEmptyNodes;
121493
121669
  this._showListItemElementId = null;
121670
+ this._renderService = cfg.renderService || new RenderService();
121671
+
121672
+ if (!this._renderService) {
121673
+ throw new Error('TreeViewPlugin: no render service set');
121674
+ }
121494
121675
 
121495
121676
  this._containerElement.oncontextmenu = (e) => {
121496
121677
  e.preventDefault();
@@ -121517,10 +121698,9 @@ class TreeViewPlugin extends Plugin {
121517
121698
  } else {
121518
121699
  node.numVisibleEntities--;
121519
121700
  }
121520
- const checkbox = document.getElementById(`checkbox-${node.nodeId}`);
121521
- if (checkbox) {
121522
- checkbox.checked = visible;
121523
- }
121701
+
121702
+ this._renderService.setCheckbox(node.nodeId, visible);
121703
+
121524
121704
  let parent = node.parent;
121525
121705
  while (parent) {
121526
121706
  parent.checked = visible;
@@ -121529,15 +121709,12 @@ class TreeViewPlugin extends Plugin {
121529
121709
  } else {
121530
121710
  parent.numVisibleEntities--;
121531
121711
  }
121532
- const parentCheckbox = document.getElementById(`checkbox-${parent.nodeId}`);
121533
- if (parentCheckbox) {
121534
- const newChecked = (parent.numVisibleEntities > 0);
121535
- if (newChecked !== parentCheckbox.checked) {
121536
- parentCheckbox.checked = newChecked;
121537
- }
121538
- }
121712
+
121713
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
121714
+
121539
121715
  parent = parent.parent;
121540
121716
  }
121717
+
121541
121718
  this._muteTreeEvents = false;
121542
121719
  });
121543
121720
 
@@ -121557,15 +121734,8 @@ class TreeViewPlugin extends Plugin {
121557
121734
  return;
121558
121735
  }
121559
121736
  node.xrayed = xrayed;
121560
- const listItemElementId = node.nodeId;
121561
- const listItemElement = document.getElementById(listItemElementId);
121562
- if (listItemElement !== null) {
121563
- if (xrayed) {
121564
- listItemElement.classList.add('xrayed-node');
121565
- } else {
121566
- listItemElement.classList.remove('xrayed-node');
121567
- }
121568
- }
121737
+
121738
+ this._renderService.setXRayed(node.nodeId, xrayed);
121569
121739
  this._muteTreeEvents = false;
121570
121740
  });
121571
121741
 
@@ -121589,14 +121759,15 @@ class TreeViewPlugin extends Plugin {
121589
121759
  }
121590
121760
  this._muteSceneEvents = true;
121591
121761
  const checkbox = event.target;
121592
- const visible = checkbox.checked;
121593
- const nodeId = checkbox.id.replace('checkbox-', '');
121762
+ const visible = this._renderService.isChecked(checkbox);
121763
+ const nodeId = this._renderService.getIdFromCheckbox(checkbox);
121764
+
121594
121765
  const checkedNode = this._nodeNodes[nodeId];
121595
121766
  const objects = this._viewer.scene.objects;
121596
121767
  let numUpdated = 0;
121768
+
121597
121769
  this._withNodeTree(checkedNode, (node) => {
121598
121770
  const objectId = node.objectId;
121599
- const checkBoxId = `checkbox-${node.nodeId}`;
121600
121771
  const entity = objects[objectId];
121601
121772
  const isLeaf = (node.children.length === 0);
121602
121773
  node.numVisibleEntities = visible ? node.numEntities : 0;
@@ -121604,27 +121775,26 @@ class TreeViewPlugin extends Plugin {
121604
121775
  numUpdated++;
121605
121776
  }
121606
121777
  node.checked = visible;
121607
- const checkbox2 = document.getElementById(checkBoxId);
121608
- if (checkbox2) {
121609
- checkbox2.checked = visible;
121610
- }
121778
+
121779
+ this._renderService.setCheckbox(node.nodeId, visible);
121780
+
121611
121781
  if (entity) {
121612
121782
  entity.visible = visible;
121613
121783
  }
121614
121784
  });
121785
+
121615
121786
  let parent = checkedNode.parent;
121616
121787
  while (parent) {
121617
121788
  parent.checked = visible;
121618
- const checkbox2 = document.getElementById(`checkbox-${parent.nodeId}`); // Parent checkboxes are always in DOM
121789
+
121619
121790
  if (visible) {
121620
121791
  parent.numVisibleEntities += numUpdated;
121621
121792
  } else {
121622
121793
  parent.numVisibleEntities -= numUpdated;
121623
121794
  }
121624
- const newChecked = (parent.numVisibleEntities > 0);
121625
- if (newChecked !== checkbox2.checked) {
121626
- checkbox2.checked = newChecked;
121627
- }
121795
+
121796
+ this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0));
121797
+
121628
121798
  parent = parent.parent;
121629
121799
  }
121630
121800
  this._muteSceneEvents = false;
@@ -121722,6 +121892,11 @@ class TreeViewPlugin extends Plugin {
121722
121892
  return;
121723
121893
  }
121724
121894
  this._metaModels[modelId] = metaModel;
121895
+
121896
+ if (options && options.rootName) {
121897
+ this._rootNames[modelId] = options.rootName;
121898
+ }
121899
+
121725
121900
  model.on("destroyed", () => {
121726
121901
  this.removeModel(model.id);
121727
121902
  });
@@ -121743,6 +121918,11 @@ class TreeViewPlugin extends Plugin {
121743
121918
  if (!metaModel) {
121744
121919
  return;
121745
121920
  }
121921
+
121922
+ if (this._rootNames[modelId]) {
121923
+ delete this._rootNames[modelId];
121924
+ }
121925
+
121746
121926
  delete this._metaModels[modelId];
121747
121927
  this._createNodes();
121748
121928
  }
@@ -121764,21 +121944,22 @@ class TreeViewPlugin extends Plugin {
121764
121944
  * @param {String} objectId ID of the {@link Entity}.
121765
121945
  */
121766
121946
  showNode(objectId) {
121767
- if (this._showListItemElementId) {
121768
- this.unShowNode();
121769
- }
121947
+ this.unShowNode();
121948
+
121770
121949
  const node = this._objectNodes[objectId];
121771
121950
  if (!node) {
121772
121951
  return; // Node may not exist for the given object if (this._pruneEmptyNodes == true)
121773
121952
  }
121953
+
121774
121954
  const nodeId = node.nodeId;
121775
- const switchElementId = "switch-" + nodeId;
121776
- const switchElement = document.getElementById(switchElementId);
121955
+
121956
+ const switchElement = this._renderService.getSwitchElement(nodeId);
121777
121957
  if (switchElement) {
121778
121958
  this._expandSwitchElement(switchElement);
121779
121959
  switchElement.scrollIntoView();
121780
- return;
121960
+ return true;
121781
121961
  }
121962
+
121782
121963
  const path = [];
121783
121964
  path.unshift(node);
121784
121965
  let parent = node.parent;
@@ -121786,20 +121967,17 @@ class TreeViewPlugin extends Plugin {
121786
121967
  path.unshift(parent);
121787
121968
  parent = parent.parent;
121788
121969
  }
121970
+
121789
121971
  for (let i = 0, len = path.length; i < len; i++) {
121790
- const node = path[i];
121791
- const nodeId = node.nodeId;
121792
- const switchElementId = "switch-" + nodeId;
121793
- const switchElement = document.getElementById(switchElementId);
121972
+ const switchElement = this._renderService.getSwitchElement(path[i].nodeId);
121794
121973
  if (switchElement) {
121795
121974
  this._expandSwitchElement(switchElement);
121796
121975
  }
121797
121976
  }
121798
- const listItemElementId = nodeId;
121799
- const listItemElement = document.getElementById(listItemElementId);
121800
- listItemElement.scrollIntoView({block: "center"});
121801
- listItemElement.classList.add("highlighted-node");
121802
- this._showListItemElementId = listItemElementId;
121977
+
121978
+ this._renderService.setHighlighted(nodeId, true);
121979
+
121980
+ this._showListItemElementId = nodeId;
121803
121981
  }
121804
121982
 
121805
121983
  /**
@@ -121813,12 +121991,9 @@ class TreeViewPlugin extends Plugin {
121813
121991
  if (!this._showListItemElementId) {
121814
121992
  return;
121815
121993
  }
121816
- const listItemElement = document.getElementById(this._showListItemElementId);
121817
- if (!listItemElement) {
121818
- this._showListItemElementId = null;
121819
- return;
121820
- }
121821
- listItemElement.classList.remove("highlighted-node");
121994
+
121995
+ this._renderService.setHighlighted(this._showListItemElementId, false);
121996
+
121822
121997
  this._showListItemElementId = null;
121823
121998
  }
121824
121999
 
@@ -121835,9 +122010,8 @@ class TreeViewPlugin extends Plugin {
121835
122010
  if (countDepth === depth) {
121836
122011
  return;
121837
122012
  }
121838
- const nodeId = node.nodeId;
121839
- const switchElementId = "switch-" + nodeId;
121840
- const switchElement = document.getElementById(switchElementId);
122013
+
122014
+ const switchElement = this._renderService.getSwitchElement(node.nodeId);
121841
122015
  if (switchElement) {
121842
122016
  this._expandSwitchElement(switchElement);
121843
122017
  const childNodes = node.children;
@@ -121992,11 +122166,12 @@ class TreeViewPlugin extends Plugin {
121992
122166
 
121993
122167
  _createDisabledNodes() {
121994
122168
 
121995
- const ul = document.createElement('ul');
121996
- this._rootElement = ul;
121997
- this._containerElement.appendChild(ul);
122169
+ const rootNode = this._renderService.createRootNode();
122170
+ this._rootElement = rootNode;
122171
+ this._containerElement.appendChild(rootNode);
121998
122172
 
121999
122173
  const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;
122174
+
122000
122175
  for (let objectId in rootMetaObjects) {
122001
122176
  const rootMetaObject = rootMetaObjects[objectId];
122002
122177
  const metaObjectType = rootMetaObject.type;
@@ -122004,17 +122179,9 @@ class TreeViewPlugin extends Plugin {
122004
122179
  const rootName = ((metaObjectName && metaObjectName !== ""
122005
122180
  && metaObjectName !== "Undefined"
122006
122181
  && metaObjectName !== "Default") ? metaObjectName : metaObjectType);
122007
- const li = document.createElement('li');
122008
- ul.appendChild(li);
122009
- const switchElement = document.createElement('a');
122010
- switchElement.href = '#';
122011
- switchElement.textContent = '!';
122012
- switchElement.classList.add('warn');
122013
- switchElement.classList.add('warning');
122014
- li.appendChild(switchElement);
122015
- const span = document.createElement('span');
122016
- span.textContent = rootName;
122017
- li.appendChild(span);
122182
+
122183
+ const childNode = this._renderService.createDisabledNodeElement(rootName);
122184
+ rootNode.appendChild(childNode);
122018
122185
  }
122019
122186
  }
122020
122187
 
@@ -122065,7 +122232,7 @@ class TreeViewPlugin extends Plugin {
122065
122232
  buildingNode = {
122066
122233
  nodeId: `${this._id}-${objectId}`,
122067
122234
  objectId: objectId,
122068
- title: this._rootName || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
122235
+ title: this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
122069
122236
  type: metaObjectType,
122070
122237
  parent: null,
122071
122238
  numEntities: 0,
@@ -122168,7 +122335,7 @@ class TreeViewPlugin extends Plugin {
122168
122335
  rootNode = {
122169
122336
  nodeId: `${this._id}-${objectId}`,
122170
122337
  objectId: objectId,
122171
- title: this._rootName || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
122338
+ title: this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
122172
122339
  type: metaObjectType,
122173
122340
  parent: null,
122174
122341
  numEntities: 0,
@@ -122249,7 +122416,7 @@ class TreeViewPlugin extends Plugin {
122249
122416
  const node = {
122250
122417
  nodeId: `${this._id}-${objectId}`,
122251
122418
  objectId: objectId,
122252
- title: (!parent) ? (this._rootName || metaObjectName) : (metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType,
122419
+ title: (!parent) ? (this._rootNames[metaObject.metaModels[0].id] || metaObjectName) : (metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType,
122253
122420
  type: metaObjectType,
122254
122421
  parent: parent,
122255
122422
  numEntities: 0,
@@ -122397,112 +122564,63 @@ class TreeViewPlugin extends Plugin {
122397
122564
  const rootNodeElements = this._rootNodes.map((rootNode) => {
122398
122565
  return this._createNodeElement(rootNode);
122399
122566
  });
122400
- const ul = document.createElement('ul');
122567
+
122568
+ const rootNode = this._renderService.createRootNode();
122401
122569
  rootNodeElements.forEach((nodeElement) => {
122402
- ul.appendChild(nodeElement);
122570
+ rootNode.appendChild(nodeElement);
122403
122571
  });
122404
- this._containerElement.appendChild(ul);
122405
- this._rootElement = ul;
122572
+
122573
+ this._containerElement.appendChild(rootNode);
122574
+ this._rootElement = rootNode;
122406
122575
  }
122407
122576
 
122408
122577
  _createNodeElement(node) {
122409
- const nodeElement = document.createElement('li');
122410
- //const nodeId = this._objectToNodeID(node.objectId);
122411
- const nodeId = node.nodeId;
122412
- if (node.xrayed) {
122413
- nodeElement.classList.add('xrayed-node');
122414
- }
122415
- nodeElement.id = nodeId;
122416
- if (node.children.length > 0) {
122417
- const switchElementId = "switch-" + nodeId;
122418
- const switchElement = document.createElement('a');
122419
- switchElement.href = '#';
122420
- switchElement.id = switchElementId;
122421
- switchElement.textContent = '+';
122422
- switchElement.classList.add('plus');
122423
- switchElement.addEventListener('click', this._switchExpandHandler);
122424
- nodeElement.appendChild(switchElement);
122425
- }
122426
- const checkbox = document.createElement('input');
122427
- checkbox.id = `checkbox-${nodeId}`;
122428
- checkbox.type = "checkbox";
122429
- checkbox.checked = node.checked;
122430
- checkbox.style["pointer-events"] = "all";
122431
- checkbox.addEventListener("change", this._checkboxChangeHandler);
122432
- nodeElement.appendChild(checkbox);
122433
- const span = document.createElement('span');
122434
- span.textContent = node.title;
122435
- nodeElement.appendChild(span);
122436
- span.oncontextmenu = (e) => {
122437
- this.fire("contextmenu", {
122438
- event: e,
122578
+ const contextmenuHandler = (event) =>{
122579
+ this.fire("contextmenu", {
122580
+ event: event,
122439
122581
  viewer: this._viewer,
122440
122582
  treeViewPlugin: this,
122441
122583
  treeViewNode: node
122442
122584
  });
122443
- e.preventDefault();
122585
+ event.preventDefault();
122444
122586
  };
122445
- span.onclick = (e) => {
122587
+ const onclickHandler = (event) => {
122446
122588
  this.fire("nodeTitleClicked", {
122447
- event: e,
122589
+ event: event,
122448
122590
  viewer: this._viewer,
122449
122591
  treeViewPlugin: this,
122450
122592
  treeViewNode: node
122451
122593
  });
122452
- e.preventDefault();
122594
+ event.preventDefault();
122453
122595
  };
122454
- return nodeElement;
122596
+
122597
+ return this._renderService.createNodeElement(node, this._switchExpandHandler, this._checkboxChangeHandler, contextmenuHandler, onclickHandler);
122455
122598
  }
122456
122599
 
122457
122600
  _expandSwitchElement(switchElement) {
122458
- const parentElement = switchElement.parentElement;
122459
- const expanded = parentElement.getElementsByTagName('li')[0];
122601
+ const expanded = this._renderService.isExpanded(switchElement);
122460
122602
  if (expanded) {
122461
122603
  return;
122462
122604
  }
122463
- const nodeId = parentElement.id;
122464
- const switchNode = this._nodeNodes[nodeId];
122465
- const childNodes = switchNode.children;
122466
- const nodeElements = childNodes.map((node) => {
122605
+
122606
+ const nodeId = this._renderService.getId(switchElement);
122607
+
122608
+ const nodeElements = this._nodeNodes[nodeId].children.map((node) => {
122467
122609
  return this._createNodeElement(node);
122468
122610
  });
122469
- const ul = document.createElement('ul');
122470
- nodeElements.forEach((nodeElement) => {
122471
- ul.appendChild(nodeElement);
122472
- });
122473
- parentElement.appendChild(ul);
122474
- switchElement.classList.remove('plus');
122475
- switchElement.classList.add('minus');
122476
- switchElement.textContent = '-';
122477
- switchElement.removeEventListener('click', this._switchExpandHandler);
122478
- switchElement.addEventListener('click', this._switchCollapseHandler);
122479
- }
122480
-
122481
- _collapseNode(objectId) {
122482
- const nodeId = objectId;
122483
- const switchElementId = "switch-" + nodeId;
122484
- const switchElement = document.getElementById(switchElementId);
122611
+
122612
+ this._renderService.addChildren(switchElement, nodeElements);
122613
+
122614
+ this._renderService.expand(switchElement, this._switchExpandHandler, this._switchCollapseHandler);
122615
+ }
122616
+
122617
+ _collapseNode(nodeId) {
122618
+ const switchElement = this._renderService.getSwitchElement(nodeId);
122485
122619
  this._collapseSwitchElement(switchElement);
122486
122620
  }
122487
122621
 
122488
122622
  _collapseSwitchElement(switchElement) {
122489
- if (!switchElement) {
122490
- return;
122491
- }
122492
- const parent = switchElement.parentElement;
122493
- if (!parent) {
122494
- return;
122495
- }
122496
- const ul = parent.querySelector('ul');
122497
- if (!ul) {
122498
- return;
122499
- }
122500
- parent.removeChild(ul);
122501
- switchElement.classList.remove('minus');
122502
- switchElement.classList.add('plus');
122503
- switchElement.textContent = '+';
122504
- switchElement.removeEventListener('click', this._switchCollapseHandler);
122505
- switchElement.addEventListener('click', this._switchExpandHandler);
122623
+ this._renderService.collapse(switchElement, this._switchExpandHandler, this._switchCollapseHandler);
122506
122624
  }
122507
122625
  }
122508
122626
 
@@ -126987,9 +127105,9 @@ parsers[ParserV10.version] = ParserV10;
126987
127105
  * }
126988
127106
  *
126989
127107
  * // Gets the contents of the given .XKT file in an arraybuffer
126990
- * getXKT(src, ok, error) {
127108
+ * getXKT(xKTSrc, ok, error) {
126991
127109
  * console.log("MyDataSource#getXKT(" + xKTSrc + ", ... )");
126992
- * utils.loadArraybuffer(src,
127110
+ * utils.loadArraybuffer(xKTSrc,
126993
127111
  * (arraybuffer) => {
126994
127112
  * ok(arraybuffer);
126995
127113
  * },