@xeokit/xeokit-sdk 2.6.77-slim-rc4 → 2.6.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.77-slim-rc4",
3
+ "version": "2.6.77",
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",
@@ -10,6 +10,7 @@
10
10
  "dev-build": "rollup --config rollup.dev.config.js",
11
11
  "docs": "rm -Rf ./docs/*; ./node_modules/.bin/esdoc",
12
12
  "typedocs": "rm -Rf ./docs/*; typedoc --tsconfig tsconfig.json",
13
+ "publish": "npm publish --access public",
13
14
  "changelog": "git fetch; auto-changelog --commit-limit false --package --template changelog-template.hbs",
14
15
  "test": "npx percy exec -- npx playwright test"
15
16
  },
@@ -52,10 +53,10 @@
52
53
  },
53
54
  "homepage": "https://xeokit.io",
54
55
  "dependencies": {
56
+ "@creooxag/cxconverter": "^0.0.3-alpha",
55
57
  "@loaders.gl/core": "^4.3.3",
56
58
  "@loaders.gl/gltf": "^4.3.3",
57
59
  "@loaders.gl/las": "^4.3.3",
58
- "@rollup/plugin-replace": "^6.0.2",
59
60
  "html2canvas": "^1.4.1"
60
61
  },
61
62
  "devDependencies": {
@@ -0,0 +1,42 @@
1
+ import {
2
+ buildSphereGeometry,
3
+ Mesh,
4
+ PhongMaterial,
5
+ ReadableGeometry
6
+ } from "../../viewer/index.js";
7
+
8
+ /**
9
+ *
10
+ * @param {*} scene
11
+ * @param {Texture} [texture] Texture to be used on the material for SphereMap
12
+ * @returns {Mesh}
13
+ */
14
+
15
+ export function createSphereMapMesh(scene, texture) {
16
+ const sphereMapGeometry = new ReadableGeometry(scene, buildSphereGeometry({
17
+ center: [0, 0, 0],
18
+ radius: 1,
19
+ heightSegments: 60,
20
+ widthSegments: 60
21
+ }));
22
+
23
+ const sphereMapMaterial = new PhongMaterial(scene, {
24
+ ambient: [0, 0, 0],
25
+ diffuse: [0, 0, 0],
26
+ specular: [0, 0, 0],
27
+ emissive: [1, 1, 1],
28
+ emissiveMap: texture,
29
+ backfaces: true
30
+ });
31
+
32
+ return new Mesh(scene, {
33
+ geometry: sphereMapGeometry,
34
+ background: true,
35
+ rotation: [0, 0, 180],
36
+ material: sphereMapMaterial,
37
+ visible: true,
38
+ pickable: false,
39
+ clippable: false,
40
+ collidable: false
41
+ });
42
+ }
@@ -0,0 +1 @@
1
+ export * from './SphereMap.js';
@@ -3,4 +3,5 @@ export * from "./PointerLens/index.js";
3
3
  export * from "./collision/index.js";
4
4
  export * from "./MarqueePicker/index.js";
5
5
  export * from "./PointerCircle/index.js";
6
- export * from "./Skybox/index.js";
6
+ export * from "./Skybox/index.js";
7
+ export * from "./SphereMap/index.js";
@@ -1,86 +1,86 @@
1
- // import { Plugin } from "../../viewer/Plugin.js";
2
- // import { GLTFLoaderPlugin } from "../GLTFLoaderPlugin/GLTFLoaderPlugin.js";
3
- // import { ifc2gltf } from "@creooxag/cx-converter";
1
+ import { Plugin } from "../../viewer/Plugin.js";
2
+ import { GLTFLoaderPlugin } from "../GLTFLoaderPlugin/GLTFLoaderPlugin.js";
3
+ import { ifc2gltf } from "@creooxag/cxconverter";
4
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
- // }
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
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
- // */
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/cxconverter).
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
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);
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
48
 
49
- // /**
50
- // * The GLTFLoaderPlugin used internally to load the converted GLTF.
51
- // * @type {GLTFLoaderPlugin}
52
- // */
53
- // this.gltfLoader = new GLTFLoaderPlugin(this.viewer);
54
- // }
49
+ /**
50
+ * The GLTFLoaderPlugin used internally to load the converted GLTF.
51
+ * @type {GLTFLoaderPlugin}
52
+ */
53
+ this.gltfLoader = new GLTFLoaderPlugin(this.viewer);
54
+ }
55
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 };
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 };
@@ -1 +1 @@
1
- // export * from "./CxConverterIFCLoaderPlugin.js";
1
+ export * from "./CxConverterIFCLoaderPlugin.js";
@@ -1,10 +1,10 @@
1
- import {math} from "../../viewer/scene/math/math.js";
2
- import {utils} from "../../viewer/scene/utils.js";
3
- import {core} from "../../viewer/scene/core.js";
4
- import {sRGBEncoding} from "../../viewer/scene/constants/constants.js";
5
- import {worldToRTCPositions} from "../../viewer/scene/math/rtcCoords.js";
6
- import {parse} from '@loaders.gl/core';
7
- import {GLTFLoader, postProcessGLTF} from '@loaders.gl/gltf';
1
+ import { parse } from '@loaders.gl/core';
2
+ import { GLTFLoader, postProcessGLTF } from '@loaders.gl/gltf';
3
+ import { sRGBEncoding } from "../../viewer/scene/constants/constants.js";
4
+ import { core } from "../../viewer/scene/core.js";
5
+ import { math } from "../../viewer/scene/math/math.js";
6
+ import { worldToRTCPositions } from "../../viewer/scene/math/rtcCoords.js";
7
+ import { utils } from "../../viewer/scene/utils.js";
8
8
 
9
9
  import {
10
10
  ClampToEdgeWrapping,
@@ -98,7 +98,7 @@ function getBasePath(src) {
98
98
  return (i !== 0) ? src.substring(0, i + 1) : "";
99
99
  }
100
100
 
101
- function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
101
+ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok, error) {
102
102
  const spinner = plugin.viewer.scene.canvas.spinner;
103
103
  spinner.processes++;
104
104
  parse(gltf, GLTFLoader, {
@@ -146,6 +146,8 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
146
146
  }
147
147
  spinner.processes--;
148
148
  ok();
149
+ }).catch((err) => {
150
+ if (error) error(err);
149
151
  });
150
152
  }
151
153
 
@@ -606,4 +608,5 @@ function error(ctx, msg) {
606
608
  ctx.plugin.error(msg);
607
609
  }
608
610
 
609
- export {GLTFSceneModelLoader};
611
+ export { GLTFSceneModelLoader };
612
+
@@ -1,9 +1,19 @@
1
1
  import {math} from "../../viewer/scene/math/math.js";
2
2
  import {Plugin} from "../../viewer/Plugin.js";
3
3
  import {SectionPlane} from "../../viewer/scene/sectionPlane/SectionPlane.js";
4
- import {Control} from "./Control.js";
4
+ import {TransformControl} from "../TransformControl/TransformControl.js";
5
5
  import {Overview} from "./Overview.js";
6
6
 
7
+ import {buildCylinderGeometry} from "../../viewer/scene/geometry/builders/buildCylinderGeometry.js";
8
+ import {buildSphereGeometry} from "../../viewer/scene/geometry/builders/buildSphereGeometry.js";
9
+ import {buildTorusGeometry} from "../../viewer/scene/geometry/builders/buildTorusGeometry.js";
10
+ import {ReadableGeometry} from "../../viewer/scene/geometry/ReadableGeometry.js";
11
+ import {PhongMaterial} from "../../viewer/scene/materials/PhongMaterial.js";
12
+ import {EmphasisMaterial} from "../../viewer/scene/materials/EmphasisMaterial.js";
13
+ import {Node} from "../../viewer/scene/nodes/Node.js";
14
+ import {Mesh} from "../../viewer/scene/mesh/Mesh.js";
15
+ import {worldToRTCPos} from "../../viewer/scene/math/rtcCoords.js";
16
+
7
17
  const tempAABB = math.AABB3();
8
18
  const tempVec3 = math.vec3();
9
19
 
@@ -234,7 +244,160 @@ class SectionPlanesPlugin extends Plugin {
234
244
  }
235
245
 
236
246
  _sectionPlaneCreated(sectionPlane) {
237
- const control = (this._freeControls.length > 0) ? this._freeControls.pop() : new Control(this);
247
+ const control = ((this._freeControls.length > 0)
248
+ ? this._freeControls.pop()
249
+ : (() => {
250
+ const scene = this.viewer.scene;
251
+ const planeRoot = (function() {
252
+ const rootNode = new Node(scene, { isObject: false });
253
+
254
+ rootNode.addChild(new Mesh(rootNode, { // plane
255
+ geometry: new ReadableGeometry(rootNode, {
256
+ primitive: "triangles",
257
+ positions: [
258
+ 0.5, 0.5, 0.0, 0.5, -0.5, 0.0, // 0
259
+ -0.5, -0.5, 0.0, -0.5, 0.5, 0.0, // 1
260
+ 0.5, 0.5, -0.0, 0.5, -0.5, -0.0, // 2
261
+ -0.5, -0.5, -0.0, -0.5, 0.5, -0.0 // 3
262
+ ],
263
+ indices: [0, 1, 2, 2, 3, 0]
264
+ }),
265
+ material: new PhongMaterial(rootNode, {
266
+ emissive: [0, 0.0, 0],
267
+ diffuse: [0, 0, 0],
268
+ backfaces: true
269
+ }),
270
+ opacity: 0.6,
271
+ ghosted: true,
272
+ ghostMaterial: new EmphasisMaterial(rootNode, {
273
+ edges: false,
274
+ filled: true,
275
+ fillColor: [1, 1, 0],
276
+ edgeColor: [0, 0, 0],
277
+ fillAlpha: 0.1,
278
+ backfaces: true
279
+ }),
280
+ pickable: false,
281
+ collidable: true,
282
+ clippable: false,
283
+ visible: false,
284
+ scale: [2.4, 2.4, 1],
285
+ isObject: false
286
+ }));
287
+
288
+ rootNode.addChild(new Mesh(rootNode, { // Visible frame
289
+ geometry: new ReadableGeometry(rootNode, buildTorusGeometry({
290
+ center: [0, 0, 0],
291
+ radius: 1.7,
292
+ tube: 0.02,
293
+ radialSegments: 4,
294
+ tubeSegments: 4,
295
+ arc: Math.PI * 2.0
296
+ })),
297
+ material: new PhongMaterial(rootNode, {
298
+ emissive: [0, 0, 0],
299
+ diffuse: [0, 0, 0],
300
+ specular: [0, 0, 0],
301
+ shininess: 0
302
+ }),
303
+ //highlighted: true,
304
+ highlightMaterial: new EmphasisMaterial(rootNode, {
305
+ edges: false,
306
+ edgeColor: [0.0, 0.0, 0.0],
307
+ filled: true,
308
+ fillColor: [0.8, 0.8, 0.8],
309
+ fillAlpha: 1.0
310
+ }),
311
+ pickable: false,
312
+ collidable: false,
313
+ clippable: false,
314
+ visible: false,
315
+ scale: [1, 1, .1],
316
+ rotation: [0, 0, 45],
317
+ isObject: false
318
+ }));
319
+
320
+ return {
321
+ setPosition: (function() {
322
+ const origin = math.vec3();
323
+ const rtcPos = math.vec3();
324
+ return function(p) {
325
+ worldToRTCPos(p, origin, rtcPos);
326
+ rootNode.origin = origin;
327
+ rootNode.position = rtcPos;
328
+ };
329
+ })(),
330
+ setQuaternion: q => { rootNode.quaternion = q; },
331
+ setScale: s => { rootNode.scale = s; },
332
+ setVisible: v => { rootNode.visible = v; }
333
+ };
334
+ })();
335
+ let unbindSectionPlane = () => { };
336
+ const ctrl = new TransformControl(this.viewer);
337
+
338
+ let culled = false;
339
+ let visible = false;
340
+ let handlers = null;
341
+ const updateVisible = () => {
342
+ const vis = visible && (! culled);
343
+ planeRoot.setVisible(vis);
344
+ ctrl.setHandlers(vis && handlers);
345
+ };
346
+
347
+ return {
348
+ _destroy: () => {
349
+ unbindSectionPlane();
350
+ ctrl.destroy();
351
+ },
352
+ setCulled: c => { culled = c; updateVisible(); },
353
+ setVisible: v => { visible = v; updateVisible(); },
354
+ _setSectionPlane: sectionPlane => {
355
+ unbindSectionPlane();
356
+ if (sectionPlane) {
357
+ let ignoreNextSectionPlaneDirUpdate = false;
358
+ handlers = {
359
+ onPosition: p => {
360
+ planeRoot.setPosition(p);
361
+ sectionPlane.pos = p;
362
+ },
363
+ onQuaternion: q => {
364
+ planeRoot.setQuaternion(q);
365
+ ignoreNextSectionPlaneDirUpdate = true;
366
+ sectionPlane.quaternion = q;
367
+ },
368
+ onScreenScale: s => {
369
+ planeRoot.setScale(s);
370
+ }
371
+ };
372
+
373
+ const setPosFromSectionPlane = () => {
374
+ planeRoot.setPosition(sectionPlane.pos);
375
+ ctrl.setPosition(sectionPlane.pos);
376
+ };
377
+ const setDirFromSectionPlane = () => {
378
+ planeRoot.setQuaternion(sectionPlane.quaternion);
379
+ ctrl.setQuaternion(sectionPlane.quaternion);
380
+ };
381
+ setPosFromSectionPlane();
382
+ setDirFromSectionPlane();
383
+ const onSectionPlanePos = sectionPlane.on("pos", setPosFromSectionPlane);
384
+ const onSectionPlaneDir = sectionPlane.on("dir", () => {
385
+ if (!ignoreNextSectionPlaneDirUpdate) {
386
+ setDirFromSectionPlane();
387
+ } else {
388
+ ignoreNextSectionPlaneDirUpdate = false;
389
+ }
390
+ });
391
+
392
+ unbindSectionPlane = () => {
393
+ sectionPlane.off(onSectionPlanePos);
394
+ sectionPlane.off(onSectionPlaneDir);
395
+ unbindSectionPlane = () => { };
396
+ };
397
+ }
398
+ }
399
+ };
400
+ })());
238
401
  control._setSectionPlane(sectionPlane);
239
402
  control.setVisible(false);
240
403
  this._controls[sectionPlane.id] = control;