@xeokit/xeokit-sdk 2.6.69 → 2.6.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/xeokit-sdk.cjs.js +4332 -207
  2. package/dist/xeokit-sdk.es.js +4332 -208
  3. package/dist/xeokit-sdk.es5.js +221 -204
  4. package/dist/xeokit-sdk.min.cjs.js +10 -4
  5. package/dist/xeokit-sdk.min.es.js +11 -5
  6. package/dist/xeokit-sdk.min.es5.js +10 -4
  7. package/package.json +3 -1
  8. package/src/plugins/CxConverterIFCLoaderPlugin/CxConverterIFCLoaderPlugin.js +86 -0
  9. package/src/plugins/CxConverterIFCLoaderPlugin/index.js +1 -0
  10. package/src/plugins/LASLoaderPlugin/LASDefaultDataSource.js +13 -1
  11. package/src/plugins/LASLoaderPlugin/LASLoaderPlugin.js +89 -43
  12. package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +4 -3
  13. package/src/plugins/index.js +1 -0
  14. package/src/viewer/scene/math/math.js +14 -2
  15. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +2 -0
  16. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +2 -0
  17. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +2 -0
  18. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +2 -0
  19. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +2 -0
  20. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +2 -0
  21. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +2 -0
  22. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +1 -24
  23. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +2 -19
  24. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +1 -24
  25. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +1 -19
  26. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +1 -24
  27. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +2 -19
  28. package/types/plugins/CxConverterIFCLoaderPlugin/CxConverterIFCLoaderPlugin.d.ts +36 -0
  29. package/types/plugins/CxConverterIFCLoaderPlugin/index.d.ts +1 -0
  30. package/types/plugins/index.d.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.69",
3
+ "version": "2.6.71",
4
4
  "description": "3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -53,6 +53,7 @@
53
53
  },
54
54
  "homepage": "https://xeokit.io",
55
55
  "dependencies": {
56
+ "@creooxag/cx-converter": "^0.0.12-alpha",
56
57
  "@loaders.gl/core": "^4.3.3",
57
58
  "@loaders.gl/gltf": "^4.3.3",
58
59
  "@loaders.gl/las": "^4.3.3",
@@ -76,6 +77,7 @@
76
77
  "eslint": "^8.13.0",
77
78
  "parse5": "^7.0.0",
78
79
  "rollup": "^2.70.2",
80
+ "rollup-plugin-banner": "^0.2.1",
79
81
  "rollup-plugin-terser": "^7.0.2",
80
82
  "typedoc": "^0.22.15"
81
83
  },
@@ -0,0 +1,86 @@
1
+ import { Plugin } from "../../viewer/Plugin.js";
2
+ import { GLTFLoaderPlugin } from "../GLTFLoaderPlugin/GLTFLoaderPlugin.js";
3
+ import { ifc2gltf } from "@creooxag/cx-converter";
4
+
5
+ /**
6
+ * Fetches a file from the given URL and returns its contents as text.
7
+ *
8
+ * @param {string} url - The URL to fetch the file from.
9
+ * @returns {Promise<string>} A promise that resolves to the file contents.
10
+ * @private
11
+ */
12
+ async function fetchFile(url) {
13
+ try {
14
+ const response = await fetch(url);
15
+ if (!response.ok) {
16
+ throw new Error(`HTTP error! Status: ${response.status}`);
17
+ }
18
+ return response.text();
19
+ } catch (error) {
20
+ console.error('Error fetching file:', error);
21
+ }
22
+ }
23
+
24
+ /**
25
+ * {@link Viewer} plugin that uses [CxConverter](https://github.com/Creoox/cxconverter) to load BIM models directly from IFC files, using its WebAssembly buid from [npm package](https://www.npmjs.com/package/@creooxag/cx-converter).
26
+ *
27
+ * ## Overview
28
+ * The WebAssembly build of CxConverter is still in alfa stage, so it may not work as expected. This documentation will be updated as the library and the plugin evolve. The example below shows how to use the plugin:
29
+ * ````javascript
30
+ * import { CxConverterIFCLoaderPlugin, Viewer } from "../../dist/xeokit-sdk.es.js";
31
+ * const cxConverterIFCLoaderPlugin = new CxConverterIFCLoaderPlugin(viewer);
32
+ *
33
+ * const sceneModel = await cxConverterIFCLoaderPlugin.load({
34
+ * src: "../../assets/models/ifc/Duplex.ifc"
35
+ * });
36
+ * ````
37
+ See the code in action [here](https://xeokit.github.io/xeokit-sdk/examples/buildings/#cxConverterIFC_vbo_Duplex).
38
+ */
39
+
40
+ class CxConverterIFCLoaderPlugin extends Plugin {
41
+ /**
42
+ * @constructor
43
+ * @param {Viewer} viewer The Viewer.
44
+ * @param {Object} [cfg={}] Plugin configuration.
45
+ */
46
+ constructor(viewer, cfg = {}) {
47
+ super("ifcLoader", viewer, cfg);
48
+
49
+ /**
50
+ * The GLTFLoaderPlugin used internally to load the converted GLTF.
51
+ * @type {GLTFLoaderPlugin}
52
+ */
53
+ this.gltfLoader = new GLTFLoaderPlugin(this.viewer);
54
+ }
55
+
56
+ /**
57
+ * Loads an IFC model from the given source.
58
+ *
59
+ * @param {Object} [params={}] Loading parameters.
60
+ * @param {string} params.src Path to an IFC file.
61
+ * @param {Function} [params.progressCallback] Callback to track loading progress.
62
+ * @param {Function} [params.progressTextCallback] Callback to track loading progress with text updates.
63
+ * @returns {Promise<SceneModel>} A promise that resolves to the loaded SceneModel.
64
+ */
65
+ async load(params = {}) {
66
+ if (!params.src) {
67
+ this.error("load() param expected: src");
68
+ }
69
+ const data = await fetchFile(params.src);
70
+ const { gltf, metaData } = await ifc2gltf(
71
+ data,
72
+ {
73
+ remote: true,
74
+ progressCallback: params.progressCallback,
75
+ progressTextCallback: params.progressTextCallback
76
+ }
77
+ );
78
+ const sceneModel = this.gltfLoader.load({
79
+ id: "myModel",
80
+ gltf: gltf,
81
+ metaModelJSON: metaData
82
+ });
83
+ return sceneModel;
84
+ }
85
+ }
86
+ export { CxConverterIFCLoaderPlugin };
@@ -0,0 +1 @@
1
+ export * from "./CxConverterIFCLoaderPlugin.js";
@@ -1,3 +1,5 @@
1
+ import {utils} from "../../viewer/scene/utils.js";
2
+
1
3
  /**
2
4
  * Default data access strategy for {@link LASLoaderPlugin}.
3
5
  */
@@ -60,13 +62,23 @@ class LASDefaultDataSource {
60
62
  if (request.status === 200) {
61
63
  ok(request.response);
62
64
  } else {
63
- error('getXKT error : ' + request.response);
65
+ error('getLAS error : ' + request.response);
64
66
  }
65
67
  }
66
68
  };
67
69
  request.send(null);
68
70
  }
69
71
  }
72
+
73
+ getManifest(manifestSrc, ok, error) {
74
+ utils.loadJSON(this._cacheBusterURL(manifestSrc),
75
+ (json) => {
76
+ ok(json);
77
+ },
78
+ function (errMsg) {
79
+ error(errMsg);
80
+ });
81
+ }
70
82
  }
71
83
 
72
84
  export {LASDefaultDataSource};
@@ -430,6 +430,8 @@ class LASLoaderPlugin extends Plugin {
430
430
  * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.
431
431
  * @param {String} [params.src] Path to a LAS file, as an alternative to the ````las```` parameter.
432
432
  * @param {ArrayBuffer} [params.las] The LAS file data, as an alternative to the ````src```` parameter.
433
+ * @param {String} [params.manifestSrc] Path or URL to a JSON manifest file that provides paths to ````.laz```` || ````.las```` files to load as parts of the model. Use this option to load models that have been split into
434
+ * @param {Object} [params.manifest] A JSON manifest object (as an alternative to a path or URL) that provides paths to ````.laz```` || ````.las```` files to load as parts of the model. Use this option to load models that have been split into
433
435
  * @param {Boolean} [params.loadMetadata=true] Whether to load metadata for the LAS model.
434
436
  * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.
435
437
  * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.
@@ -451,7 +453,7 @@ class LASLoaderPlugin extends Plugin {
451
453
  isModel: true
452
454
  }));
453
455
 
454
- if (!params.src && !params.las) {
456
+ if (!params.src && !params.las && !params.manifest && !params.manifestSrc) {
455
457
  this.error("load() param expected: src or las");
456
458
  return sceneModel; // Return new empty model
457
459
  }
@@ -464,18 +466,77 @@ class LASLoaderPlugin extends Plugin {
464
466
  }
465
467
  };
466
468
 
469
+ const spinner = this.viewer.scene.canvas.spinner;
470
+ const done = () => {
471
+ sceneModel.scene.once("tick", () => {
472
+ if (sceneModel.destroyed) {
473
+ return;
474
+ }
475
+ sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
476
+ sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
477
+ });
478
+ spinner.processes--;
479
+ }
480
+ const error = (errMsg) => {
481
+ spinner.processes--;
482
+ this.error(errMsg);
483
+ sceneModel.fire("error", errMsg);
484
+ }
485
+
467
486
  if (params.src) {
468
487
  this._loadModel(params.src, params, options, sceneModel);
469
- } else {
470
- const spinner = this.viewer.scene.canvas.spinner;
488
+ } else if(params.las) {
471
489
  spinner.processes++;
472
- this._parseModel(params.las, params, options, sceneModel).then(() => {
473
- spinner.processes--;
474
- }, (errMsg) => {
475
- spinner.processes--;
476
- this.error(errMsg);
477
- sceneModel.fire("error", errMsg);
478
- });
490
+ this._parseModel(params.las, params, options, sceneModel).then(done, error);
491
+ } else if (params.manifest || params.manifestSrc) {
492
+ const baseDir = params.manifestSrc ? getBaseDirectory(params.manifestSrc) : "";
493
+ const loadAllFiles = (lasFiles) => {
494
+ let i = 0;
495
+ const modelsLoaded = new Array(lasFiles.length);
496
+ const loadNext = () => {
497
+ if (sceneModel.destroyed) {
498
+ done();
499
+ } else if (i >= lasFiles.length) {
500
+ return
501
+ } else {
502
+ modelsLoaded[i] = false;
503
+ this._dataSource.getLAS(`${baseDir}${lasFiles[i]}`, (arrayBuffer) => {
504
+ const modelParams = utils.apply(params, {isManifest: true, index: i});
505
+ this._parseModel(arrayBuffer, modelParams, options, sceneModel).then(() => {
506
+ modelsLoaded[modelParams.index] = true;
507
+ let allLoaded = true;
508
+ modelsLoaded.forEach((loaded) => {
509
+ if(!loaded) allLoaded = false;
510
+ })
511
+ if(allLoaded) done();
512
+ });
513
+ i++;
514
+ this.scheduleTask(loadNext, 200);
515
+ }, error);
516
+ }
517
+ }
518
+ loadNext();
519
+ };
520
+ const loadManifestData = (manifestData) => {
521
+ if(sceneModel.destroyed) return;
522
+ const files = manifestData.lasFiles || manifestData.lazFiles;
523
+ if(!files || files.length <= 0) {
524
+ this.error(`load(): Failed to load model manifest - manifest not valid`);
525
+ return;
526
+ }
527
+ loadAllFiles(files);
528
+ }
529
+ if(params.manifestSrc) {
530
+ this._dataSource.getManifest(params.manifestSrc, (manifestData) => {
531
+ loadManifestData(manifestData);
532
+ }, (errMsg) => {
533
+ this.error(errMsg);
534
+ sceneModel.fire("error", errMsg);
535
+ })
536
+ } else {
537
+ const manifestData = params.manifest;
538
+ loadManifestData(manifestData);
539
+ }
479
540
  }
480
541
 
481
542
  return sceneModel;
@@ -486,6 +547,13 @@ class LASLoaderPlugin extends Plugin {
486
547
  spinner.processes++;
487
548
  this._dataSource.getLAS(params.src, (arrayBuffer) => {
488
549
  this._parseModel(arrayBuffer, params, options, sceneModel).then(() => {
550
+ sceneModel.scene.once("tick", () => {
551
+ if (sceneModel.destroyed) {
552
+ return;
553
+ }
554
+ sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
555
+ sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
556
+ });
489
557
  spinner.processes--;
490
558
  }, (errMsg) => {
491
559
  spinner.processes--;
@@ -668,7 +736,7 @@ class LASLoaderPlugin extends Plugin {
668
736
  const meshIds = [];
669
737
 
670
738
  for (let i = 0, len = pointsChunks.length; i < len; i++) {
671
- const meshId = `pointsMesh${i}`;
739
+ const meshId = `${params.isManifest ? 'model'+params.index : ''}pointsMesh${i}`;
672
740
  meshIds.push(meshId);
673
741
  sceneModel.createMesh({
674
742
  id: meshId,
@@ -677,30 +745,6 @@ class LASLoaderPlugin extends Plugin {
677
745
  colorsCompressed: (i < colorsChunks.length) ? colorsChunks[i] : null
678
746
  });
679
747
  }
680
- /*
681
- const pointsChunks = chunkArray(positionsValue, MAX_VERTICES * 3);
682
- const colorsChunks = chunkArray(colorsCompressed, MAX_VERTICES * 4);
683
- const meshIds = [];
684
-
685
- for (let i = 0, len = pointsChunks.length; i < len; i++) {
686
-
687
- const geometryId = `geometryMesh${i}`;
688
- const meshId = `pointsMesh${i}`;
689
- meshIds.push(meshId);
690
-
691
- sceneModel.createGeometry({
692
- id: geometryId,
693
- primitive: "points",
694
- positions: pointsChunks[i],
695
- colorsCompressed: (i < colorsChunks.length) ? colorsChunks[i] : null
696
- });
697
-
698
- sceneModel.createMesh({
699
- id: meshId,
700
- geometryId
701
- });
702
- }
703
- */
704
748
 
705
749
  const pointsObjectId = params.entityId || math.createUUID();
706
750
 
@@ -743,14 +787,6 @@ class LASLoaderPlugin extends Plugin {
743
787
  this.viewer.metaScene.createMetaModel(metaModelId, metadata, options);
744
788
  }
745
789
 
746
- sceneModel.scene.once("tick", () => {
747
- if (sceneModel.destroyed) {
748
- return;
749
- }
750
- sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
751
- sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
752
- });
753
-
754
790
  resolve();
755
791
  });
756
792
  } catch (e) {
@@ -772,4 +808,14 @@ function chunkArray(array, chunkSize) {
772
808
  return result;
773
809
  }
774
810
 
811
+ function getBaseDirectory(filePath) {
812
+ if (filePath.indexOf('?') > -1) {
813
+ filePath = filePath.split('?')[0];
814
+ }
815
+
816
+ const pathArray = filePath.split('/');
817
+ pathArray.pop(); // Remove the file name or the last segment of the path
818
+ return pathArray.join('/') + '/';
819
+ }
820
+
775
821
  export {LASLoaderPlugin};
@@ -464,7 +464,8 @@ export class TreeViewPlugin extends Plugin {
464
464
  const indeterminate = this._showIndeterminate
465
465
  && parent.numVisibleEntities > 0
466
466
  && parent.numVisibleEntities < parent.numEntities;
467
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
467
+ parent.checked = parent.numVisibleEntities > 0;
468
+ this._renderService.setCheckbox(parent.nodeId, parent.checked, indeterminate);
468
469
 
469
470
  parent = parent.parent;
470
471
  }
@@ -539,7 +540,6 @@ export class TreeViewPlugin extends Plugin {
539
540
 
540
541
  let parent = checkedNode.parent;
541
542
  while (parent) {
542
- parent.checked = visible;
543
543
 
544
544
  if (visible) {
545
545
  parent.numVisibleEntities += numUpdated;
@@ -549,7 +549,8 @@ export class TreeViewPlugin extends Plugin {
549
549
  const indeterminate = this._showIndeterminate
550
550
  && parent.numVisibleEntities > 0
551
551
  && parent.numVisibleEntities < parent.numEntities;
552
- this._renderService.setCheckbox(parent.nodeId, (parent.numVisibleEntities > 0), indeterminate);
552
+ parent.checked = parent.numVisibleEntities > 0;
553
+ this._renderService.setCheckbox(parent.nodeId, parent.checked, indeterminate);
553
554
 
554
555
  parent = parent.parent;
555
556
  }
@@ -17,6 +17,7 @@ export * from "./ViewCullPlugin/index.js";
17
17
  export * from "./XKTLoaderPlugin/index.js";
18
18
  export * from "./XML3DLoaderPlugin/index.js";
19
19
  export * from "./WebIFCLoaderPlugin/index.js";
20
+ export * from "./CxConverterIFCLoaderPlugin/index.js";
20
21
  export * from "./LASLoaderPlugin/index.js";
21
22
  export * from "./CityJSONLoaderPlugin/index.js";
22
23
  export * from "./DotBIMLoaderPlugin/index.js";
@@ -158,8 +158,20 @@ const math = {
158
158
  * @static
159
159
  * @returns {Number[]}
160
160
  */
161
- mat4ToMat3(mat4, mat3) { // TODO
162
- //return new FloatArrayType(values || 9);
161
+ mat4ToMat3(mat4, mat3 = new FloatArrayType(9)) {
162
+ mat3[0] = mat4[0];
163
+ mat3[1] = mat4[1];
164
+ mat3[2] = mat4[2];
165
+
166
+ mat3[3] = mat4[4];
167
+ mat3[4] = mat4[5];
168
+ mat3[5] = mat4[6];
169
+
170
+ mat3[6] = mat4[8];
171
+ mat3[7] = mat4[9];
172
+ mat3[8] = mat4[10];
173
+
174
+ return mat3;
163
175
  },
164
176
 
165
177
  /**
@@ -127,6 +127,8 @@ export class VBOBatchingLineSnapInitRenderer extends VBORenderer {
127
127
  state.indicesBuf.bind();
128
128
  gl.drawElements(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0);
129
129
  state.indicesBuf.unbind();
130
+
131
+ gl.bindVertexArray(null);
130
132
  }
131
133
 
132
134
  _allocate() {
@@ -126,6 +126,8 @@ export class VBOBatchingLinesSnapInitRenderer extends VBORenderer {
126
126
  state.indicesBuf.bind();
127
127
  gl.drawElements(gl.LINES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0);
128
128
  state.indicesBuf.unbind();
129
+
130
+ gl.bindVertexArray(null);
129
131
  }
130
132
 
131
133
  _allocate() {
@@ -135,6 +135,8 @@ export class VBOBatchingLinesSnapRenderer extends VBORenderer{
135
135
  } else {
136
136
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
137
137
  }
138
+
139
+ gl.bindVertexArray(null);
138
140
  }
139
141
 
140
142
  _allocate() {
@@ -125,6 +125,8 @@ export class VBOBatchingPointsSnapInitRenderer extends VBORenderer {
125
125
  //=============================================================
126
126
 
127
127
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
128
+
129
+ gl.bindVertexArray(null);
128
130
  }
129
131
 
130
132
  _allocate() {
@@ -129,6 +129,8 @@ export class VBOBatchingPointsSnapRenderer extends VBORenderer{
129
129
  //=============================================================
130
130
 
131
131
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
132
+
133
+ gl.bindVertexArray(null);
132
134
  }
133
135
 
134
136
  _allocate() {
@@ -126,6 +126,8 @@ export class TrianglesSnapInitRenderer extends VBORenderer {
126
126
  state.indicesBuf.bind();
127
127
  gl.drawElements(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0);
128
128
  state.indicesBuf.unbind();
129
+
130
+ gl.bindVertexArray(null);
129
131
  }
130
132
 
131
133
  _allocate() {
@@ -136,6 +136,8 @@ export class TrianglesSnapRenderer extends VBORenderer{
136
136
  } else {
137
137
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
138
138
  }
139
+
140
+ gl.bindVertexArray(null);
139
141
  }
140
142
 
141
143
  _allocate() {
@@ -117,34 +117,11 @@ export class VBOInstancingLinesSnapInitRenderer extends VBORenderer {
117
117
 
118
118
  this.setSectionPlanesStateUniforms(instancingLayer);
119
119
 
120
- this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
121
- this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
122
- this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
123
-
124
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
125
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
126
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
127
-
128
-
129
- if (this._aFlags) {
130
- this._aFlags.bindArrayBuffer(state.flagsBuf);
131
- gl.vertexAttribDivisor(this._aFlags.location, 1);
132
- }
133
-
134
120
  state.indicesBuf.bind();
135
121
  gl.drawElementsInstanced(gl.LINES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
136
122
  state.indicesBuf.unbind();
137
123
 
138
- // Cleanup
139
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 0);
140
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 0);
141
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 0);
142
- if (this._aFlags) {
143
- gl.vertexAttribDivisor(this._aFlags.location, 0);
144
- }
145
- if (this._aOffset) {
146
- gl.vertexAttribDivisor(this._aOffset.location, 0);
147
- }
124
+ gl.bindVertexArray(null);
148
125
  }
149
126
 
150
127
  _allocate() {
@@ -116,17 +116,6 @@ export class VBOInstancingLinesSnapRenderer extends VBORenderer {
116
116
 
117
117
  this.setSectionPlanesStateUniforms(instancingLayer);
118
118
 
119
-
120
- this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
121
- this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
122
- this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
123
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
124
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
125
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
126
-
127
- this._aFlags.bindArrayBuffer(state.flagsBuf);
128
- gl.vertexAttribDivisor(this._aFlags.location, 1);
129
-
130
119
  if (frameCtx.snapMode === "edge") {
131
120
  state.indicesBuf.bind();
132
121
  gl.drawElementsInstanced(gl.LINES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
@@ -134,14 +123,8 @@ export class VBOInstancingLinesSnapRenderer extends VBORenderer {
134
123
  } else {
135
124
  gl.drawArraysInstanced(gl.POINTS, 0, state.positionsBuf.numItems, state.numInstances);
136
125
  }
137
- // Cleanup
138
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 0);
139
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 0);
140
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 0);
141
- gl.vertexAttribDivisor(this._aFlags.location, 0);
142
- if (this._aOffset) {
143
- gl.vertexAttribDivisor(this._aOffset.location, 0);
144
- }
126
+
127
+ gl.bindVertexArray(null);
145
128
  }
146
129
 
147
130
  _allocate() {
@@ -117,32 +117,9 @@ export class VBOInstancingPointsSnapInitRenderer extends VBORenderer {
117
117
 
118
118
  this.setSectionPlanesStateUniforms(instancingLayer);
119
119
 
120
- this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
121
- this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
122
- this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
123
-
124
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
125
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
126
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
127
-
128
-
129
- if (this._aFlags) {
130
- this._aFlags.bindArrayBuffer(state.flagsBuf);
131
- gl.vertexAttribDivisor(this._aFlags.location, 1);
132
- }
133
-
134
120
  gl.drawArraysInstanced(gl.POINTS, 0, state.positionsBuf.numItems, state.numInstances);
135
121
 
136
- // Cleanup
137
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 0);
138
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 0);
139
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 0);
140
- if (this._aFlags) {
141
- gl.vertexAttribDivisor(this._aFlags.location, 0);
142
- }
143
- if (this._aOffset) {
144
- gl.vertexAttribDivisor(this._aOffset.location, 0);
145
- }
122
+ gl.bindVertexArray(null);
146
123
  }
147
124
 
148
125
  _allocate() {
@@ -116,27 +116,9 @@ export class VBOInstancingPointsSnapRenderer extends VBORenderer {
116
116
 
117
117
  this.setSectionPlanesStateUniforms(instancingLayer);
118
118
 
119
-
120
- this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
121
- this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
122
- this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
123
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
124
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
125
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
126
-
127
- this._aFlags.bindArrayBuffer(state.flagsBuf);
128
- gl.vertexAttribDivisor(this._aFlags.location, 1);
129
-
130
119
  gl.drawArraysInstanced(gl.POINTS, 0, state.positionsBuf.numItems, state.numInstances);
131
120
 
132
- // Cleanup
133
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 0);
134
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 0);
135
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 0);
136
- gl.vertexAttribDivisor(this._aFlags.location, 0);
137
- if (this._aOffset) {
138
- gl.vertexAttribDivisor(this._aOffset.location, 0);
139
- }
121
+ gl.bindVertexArray(null);
140
122
  }
141
123
 
142
124
  _allocate() {
@@ -123,34 +123,11 @@ export class TrianglesSnapInitRenderer extends VBORenderer {
123
123
 
124
124
  this.setSectionPlanesStateUniforms(instancingLayer);
125
125
 
126
- this._aModelMatrixCol0.bindArrayBuffer(state.modelMatrixCol0Buf);
127
- this._aModelMatrixCol1.bindArrayBuffer(state.modelMatrixCol1Buf);
128
- this._aModelMatrixCol2.bindArrayBuffer(state.modelMatrixCol2Buf);
129
-
130
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 1);
131
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 1);
132
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 1);
133
-
134
-
135
- if (this._aFlags) {
136
- this._aFlags.bindArrayBuffer(state.flagsBuf);
137
- gl.vertexAttribDivisor(this._aFlags.location, 1);
138
- }
139
-
140
126
  state.indicesBuf.bind();
141
127
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
142
128
  state.indicesBuf.unbind();
143
129
 
144
- // Cleanup
145
- gl.vertexAttribDivisor(this._aModelMatrixCol0.location, 0);
146
- gl.vertexAttribDivisor(this._aModelMatrixCol1.location, 0);
147
- gl.vertexAttribDivisor(this._aModelMatrixCol2.location, 0);
148
- if (this._aFlags) {
149
- gl.vertexAttribDivisor(this._aFlags.location, 0);
150
- }
151
- if (this._aOffset) {
152
- gl.vertexAttribDivisor(this._aOffset.location, 0);
153
- }
130
+ gl.bindVertexArray(null);
154
131
  }
155
132
 
156
133
  _allocate() {