@xeokit/xeokit-sdk 2.6.30 → 2.6.31

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.30",
3
+ "version": "2.6.31",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -426,50 +426,127 @@ export class DotBIMLoaderPlugin extends Plugin {
426
426
 
427
427
  const dbMeshId = element.mesh_id;
428
428
 
429
- parseDBMesh(dbMeshId);
430
-
431
- const meshId = `${objectId}-mesh`;
432
429
  const vector = element.vector;
433
430
  const rotation = element.rotation;
434
431
  const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
435
-
436
432
  let visible = true;
437
433
  let pickable = true;
438
- let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
439
- let opacity = element.color ? element.color.a / 255 : 1.0;
440
434
 
441
- if (props) {
442
- if (props.visible === false) {
443
- visible = false;
444
- }
445
- if (props.pickable === false) {
446
- pickable = false;
435
+ if (element.face_colors === undefined) {
436
+
437
+ parseDBMesh(dbMeshId);
438
+
439
+ const meshId = `${objectId}-mesh`;
440
+
441
+ let color = element.color ? [element.color.r / 255.0, element.color.g / 255.0, element.color.b / 255.0] : [1, 1, 1];
442
+ let opacity = element.color ? element.color.a / 255.0 : 1.0;
443
+
444
+ if (props) {
445
+ if (props.visible === false) {
446
+ visible = false;
447
+ }
448
+ if (props.pickable === false) {
449
+ pickable = false;
450
+ }
451
+ if (props.colorize) {
452
+ color = props.colorize;
453
+ }
454
+ if (props.opacity !== undefined && props.opacity !== null) {
455
+ opacity = props.opacity;
456
+ }
447
457
  }
448
- if (props.colorize) {
449
- color = props.colorize;
458
+
459
+ sceneModel.createMesh({
460
+ id: meshId,
461
+ geometryId: dbMeshId,
462
+ color: color,
463
+ opacity: opacity,
464
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
465
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
466
+ });
467
+
468
+ sceneModel.createEntity({
469
+ id: objectId,
470
+ meshIds: [meshId],
471
+ visible: visible,
472
+ pickable: pickable,
473
+ isObject: true
474
+ });
475
+ }
476
+ else {
477
+ let faceColors = element.face_colors;
478
+ let coloredTrianglesDictionary = {};
479
+ let currentTriangleIndicesCount = 0;
480
+ let dbMesh = fileData.meshes[element.mesh_id];
481
+ for (let i = 0, len = faceColors.length; i < len; i+=4) {
482
+ let faceColor = [faceColors[i], faceColors[i+1], faceColors[i+2], faceColors[i+3]];
483
+ if (coloredTrianglesDictionary[faceColor] === undefined) {
484
+ coloredTrianglesDictionary[faceColor] = [];
485
+ }
486
+ let indexForPoint0 = dbMesh.indices[currentTriangleIndicesCount];
487
+ let x0 = dbMesh.coordinates[indexForPoint0*3];
488
+ let y0 = dbMesh.coordinates[indexForPoint0*3+1];
489
+ let z0 = dbMesh.coordinates[indexForPoint0*3+2];
490
+ let indexForPoint1 = dbMesh.indices[currentTriangleIndicesCount+1];
491
+ let x1 = dbMesh.coordinates[indexForPoint1*3];
492
+ let y1 = dbMesh.coordinates[indexForPoint1*3+1];
493
+ let z1 = dbMesh.coordinates[indexForPoint1*3+2];
494
+ let indexForPoint2 = dbMesh.indices[currentTriangleIndicesCount+2];
495
+ let x2 = dbMesh.coordinates[indexForPoint2*3];
496
+ let y2 = dbMesh.coordinates[indexForPoint2*3+1];
497
+ let z2 = dbMesh.coordinates[indexForPoint2*3+2];
498
+ coloredTrianglesDictionary[faceColor].push(x0, y0, z0, x1, y1, z1, x2, y2, z2);
499
+
500
+ currentTriangleIndicesCount += 3;
450
501
  }
451
- if (props.opacity !== undefined && props.opacity !== null) {
452
- opacity = props.opacity;
502
+ let meshIds = [];
503
+ for (const [faceColor, trianglesCoordinates] of Object.entries(coloredTrianglesDictionary)) {
504
+ sceneModel.createGeometry({
505
+ id: `${dbMeshId}-${faceColor}`,
506
+ primitive: "triangles",
507
+ positions: trianglesCoordinates,
508
+ indices: [...Array(trianglesCoordinates.length).keys()]
509
+ });
510
+ const meshId = `${objectId}-mesh-${faceColor}`;
511
+ const faceColorArray = faceColor.split(',').map(Number);
512
+
513
+ let color = [faceColorArray[0] / 255.0, faceColorArray[1] / 255.0, faceColorArray[2] / 255.0];
514
+ let opacity = faceColorArray[3] / 255.0;
515
+
516
+ if (props) {
517
+ if (props.visible === false) {
518
+ visible = false;
519
+ }
520
+ if (props.pickable === false) {
521
+ pickable = false;
522
+ }
523
+ if (props.colorize) {
524
+ color = props.colorize;
525
+ }
526
+ if (props.opacity !== undefined && props.opacity !== null) {
527
+ opacity = props.opacity;
528
+ }
529
+ }
530
+
531
+ sceneModel.createMesh({
532
+ id: meshId,
533
+ geometryId: `${dbMeshId}-${faceColor}`,
534
+ color: color,
535
+ opacity: opacity,
536
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
537
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
538
+ });
539
+ meshIds.push(meshId);
453
540
  }
541
+ sceneModel.createEntity({
542
+ id: objectId,
543
+ meshIds: meshIds,
544
+ visible: visible,
545
+ pickable: pickable,
546
+ isObject: true
547
+ });
454
548
  }
455
549
 
456
- sceneModel.createMesh({
457
- id: meshId,
458
- geometryId: dbMeshId,
459
- color,
460
- opacity,
461
- quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
462
- position: vector ? [vector.x, vector.y, vector.z] : undefined
463
- });
464
-
465
- sceneModel.createEntity({
466
- id: objectId,
467
- meshIds: [meshId],
468
- visible,
469
- pickable,
470
- isObject: true
471
- });
472
-
473
550
  for (let infoKey in info) {
474
551
  let properties;
475
552
  if (infoKey.startsWith("IFC_Pset_")) {
@@ -5,6 +5,7 @@ import {sRGBEncoding} from "../../viewer/scene/constants/constants.js";
5
5
  import {worldToRTCPositions} from "../../viewer/scene/math/rtcCoords.js";
6
6
  import {parse} from '@loaders.gl/core';
7
7
  import {GLTFLoader} from '@loaders.gl/gltf/dist/esm/gltf-loader.js';
8
+
8
9
  import {
9
10
  ClampToEdgeWrapping,
10
11
  LinearFilter,
@@ -503,7 +504,7 @@ const parseNodesWithNames = (function () {
503
504
 
504
505
  const objectIdStack = [];
505
506
  const meshIdsStack = [];
506
- let meshIds = null;
507
+ let meshIds = [];
507
508
 
508
509
  return function (ctx, node, depth, matrix) {
509
510
  matrix = parseNodeMatrix(node, matrix);
@@ -681,7 +682,11 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
681
682
  if (primitive.indices) {
682
683
  meshCfg.indices = primitive.indices.value;
683
684
  }
684
- math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
685
+ if (matrix) {
686
+ math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
687
+ } else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
688
+ meshCfg.positions.set(meshCfg.localPositions);
689
+ }
685
690
  const origin = math.vec3();
686
691
  const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
687
692
  if (rtcNeeded) {
@@ -990,7 +990,7 @@ export class TreeViewPlugin extends Plugin {
990
990
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
991
991
  } else if (metaObjectType === "IfcBuildingStorey") {
992
992
  if (!buildingNode) {
993
- this.error("Failed to build storeys hierarchy for model '" + this.metaModel.id + "' - model does not have an IfcBuilding object, or is not an IFC model");
993
+ this.error("Failed to build storeys hierarchy for model - model does not have an IfcBuilding object, or is not an IFC model");
994
994
  return;
995
995
  }
996
996
  storeyNode = {
@@ -1539,13 +1539,16 @@ const Renderer = function (scene, options) {
1539
1539
  }
1540
1540
 
1541
1541
  const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
1542
+ if (!snappedEntity && pickable) {
1543
+ pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
1544
+ }
1542
1545
 
1543
1546
  pickResult.reset();
1544
1547
  pickResult.snappedToEdge = (snapType === "edge");
1545
1548
  pickResult.snappedToVertex = (snapType === "vertex");
1546
- pickResult.worldPos = snappedWorldPos;
1547
- pickResult.worldNormal = snappedWorldNormal;
1548
- pickResult.entity = snappedEntity;
1549
+ pickResult.worldPos = snappedWorldPos || worldPos;
1550
+ pickResult.worldNormal = snappedWorldNormal || worldNormal;
1551
+ pickResult.entity = snappedEntity || pickable;
1549
1552
  pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
1550
1553
  pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
1551
1554
 
@@ -1,4 +1,4 @@
1
- import { Plugin, Viewer, Entity, IFCObjectDefaults } from "../../viewer";
1
+ import { Entity, IFCObjectDefaults, Plugin, SceneModel, Viewer } from "../../viewer";
2
2
 
3
3
  export declare interface IGLTFDefaultDataSource {
4
4
  /**
@@ -77,6 +77,8 @@ export declare type LoadGLTFModel = {
77
77
  edgeThreshold?: number[]
78
78
  /** Set ````false```` to load all the materials and textures provided by the glTF file, otherwise leave ````true```` to load the default high-performance representation optimized for low memory usage and efficient rendering. */
79
79
  performance?: boolean;
80
+ /** When true, generate a single MetaObject that represents the entire glTF model, and a MetaObject for each entity within it. */
81
+ autoMetaModel?: boolean;
80
82
  };
81
83
 
82
84
  /**
@@ -134,7 +136,7 @@ export declare class GLTFLoaderPlugin extends Plugin {
134
136
  * Loads a glTF model from a file into this GLTFLoaderPlugin's {@link Viewer}.
135
137
  *
136
138
  * @param {LoadGLTFModel} params Loading parameters.
137
- * @returns {Entity} Entity representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}
139
+ * @returns {SceneModel} SceneModel representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}.
138
140
  */
139
- load(params: LoadGLTFModel): Entity;
141
+ load(params: LoadGLTFModel): SceneModel;
140
142
  }
@@ -1,4 +1,4 @@
1
- import { Entity, Plugin, Viewer } from "../../viewer";
1
+ import { Entity, Plugin, SceneModel, Viewer } from "../../viewer";
2
2
  import { ModelStats } from "../index";
3
3
 
4
4
  export declare interface ILASDefaultDataSource {
@@ -142,5 +142,5 @@ export declare class LASLoaderPlugin extends Plugin {
142
142
  * @param {LoadLASModel} params Loading parameters.
143
143
  * @returns {SceneModel} SceneModel representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}.
144
144
  */
145
- load(params?: LoadLASModel): Entity;
145
+ load(params?: LoadLASModel): SceneModel;
146
146
  }
@@ -1,4 +1,4 @@
1
- import { Plugin, Viewer, Entity } from "../../viewer";
1
+ import { Entity, Node, Plugin, Viewer } from "../../viewer";
2
2
 
3
3
  export declare type LoadOBJModel = {
4
4
  /** ID to assign to the model's root {@link Entity}, unique among all components in the Viewer's {@link Scene}. */
@@ -38,7 +38,7 @@ export declare class OBJLoaderPlugin extends Plugin {
38
38
  * Loads an OBJ model from a file into this OBJLoader's {@link Viewer}.
39
39
  *
40
40
  * @param {LoadOBJModel} params Loading parameters.
41
- * @returns {Entity} Entity representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}
41
+ * @returns {Node} An {@link Entity} that is a scene graph node that can have child Nodes and {@link Mesh}es.
42
42
  */
43
- load(params: LoadOBJModel): Entity;
43
+ load(params: LoadOBJModel): Node;
44
44
  }