@xeokit/xeokit-sdk 2.6.9 → 2.6.13
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/dist/web-ifc.wasm +0 -0
- package/dist/xeokit-sdk.cjs.js +1164 -134
- package/dist/xeokit-sdk.es.js +1163 -135
- package/dist/xeokit-sdk.es5.js +521 -53
- package/dist/xeokit-sdk.min.cjs.js +5 -5
- package/dist/xeokit-sdk.min.es.js +5 -5
- package/dist/xeokit-sdk.min.es5.js +4 -4
- package/package.json +1 -1
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsControl.js +10 -0
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +9 -0
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +9 -0
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +182 -42
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsControl.js +11 -0
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +11 -0
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.js +18 -1
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +15 -0
- package/src/plugins/DotBIMLoaderPlugin/DotBIMDefaultDataSource.js +29 -0
- package/src/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.js +536 -0
- package/src/plugins/DotBIMLoaderPlugin/index.js +2 -0
- package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +74 -0
- package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +53 -58
- package/src/plugins/LASLoaderPlugin/LASLoaderPlugin.js +59 -2
- package/src/plugins/index.js +2 -1
- package/src/plugins/lib/html/Dot.js +38 -6
- package/src/plugins/lib/html/Label.js +48 -7
- package/src/plugins/lib/html/Wire.js +38 -6
- package/src/viewer/Viewer.js +1 -1
- package/src/viewer/scene/CameraControl/lib/handlers/MouseMiscHandler.js +2 -2
- package/src/viewer/scene/marker/Marker.js +3 -3
- package/src/viewer/scene/model/SceneModel.js +17 -9
- package/src/viewer/utils/os.js +11 -0
- package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsControl.d.ts +7 -0
- package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.d.ts +8 -0
- package/types/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.d.ts +8 -0
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +70 -0
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsControl.d.ts +7 -0
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.d.ts +8 -0
- package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.d.ts +8 -0
package/dist/xeokit-sdk.es.js
CHANGED
|
@@ -10456,7 +10456,7 @@ const tempVec4b$6 = math.vec4();
|
|
|
10456
10456
|
* });
|
|
10457
10457
|
*
|
|
10458
10458
|
* // Create the Marker, associated with our Mesh Entity
|
|
10459
|
-
* const myMarker = new Marker({
|
|
10459
|
+
* const myMarker = new Marker(viewer, {
|
|
10460
10460
|
* entity: entity,
|
|
10461
10461
|
* worldPos: [10,0,0],
|
|
10462
10462
|
* occludable: true
|
|
@@ -10585,7 +10585,7 @@ class Marker extends Component {
|
|
|
10585
10585
|
return;
|
|
10586
10586
|
}
|
|
10587
10587
|
if (this._onEntityDestroyed !== null) {
|
|
10588
|
-
this._entity.off(this._onEntityDestroyed);
|
|
10588
|
+
this._entity.model.off(this._onEntityDestroyed);
|
|
10589
10589
|
this._onEntityDestroyed = null;
|
|
10590
10590
|
}
|
|
10591
10591
|
if (this._onEntityModelDestroyed !== null) {
|
|
@@ -10601,7 +10601,7 @@ class Marker extends Component {
|
|
|
10601
10601
|
this._onEntityModelDestroyed = null;
|
|
10602
10602
|
});
|
|
10603
10603
|
} else {
|
|
10604
|
-
this._onEntityDestroyed = this._entity.on("destroyed", () => {
|
|
10604
|
+
this._onEntityDestroyed = this._entity.model.on("destroyed", () => {
|
|
10605
10605
|
this._entity = null;
|
|
10606
10606
|
this._onEntityDestroyed = null;
|
|
10607
10607
|
});
|
|
@@ -10767,6 +10767,16 @@ class Marker extends Component {
|
|
|
10767
10767
|
}
|
|
10768
10768
|
}
|
|
10769
10769
|
|
|
10770
|
+
const os = {
|
|
10771
|
+
isIphoneSafari() {
|
|
10772
|
+
const userAgent = window.navigator.userAgent;
|
|
10773
|
+
const isIphone = /iPhone/i.test(userAgent);
|
|
10774
|
+
const isSafari = /Safari/i.test(userAgent) && !/Chrome/i.test(userAgent);
|
|
10775
|
+
|
|
10776
|
+
return isIphone && isSafari;
|
|
10777
|
+
}
|
|
10778
|
+
};
|
|
10779
|
+
|
|
10770
10780
|
/** @private */
|
|
10771
10781
|
class Wire {
|
|
10772
10782
|
|
|
@@ -10879,11 +10889,42 @@ class Wire {
|
|
|
10879
10889
|
}
|
|
10880
10890
|
|
|
10881
10891
|
if (cfg.onContextMenu) {
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10892
|
+
if(os.isIphoneSafari()){
|
|
10893
|
+
wireClickable.addEventListener('touchstart', (event) => {
|
|
10894
|
+
event.preventDefault();
|
|
10895
|
+
if(this._timeout){
|
|
10896
|
+
clearTimeout(this._timeout);
|
|
10897
|
+
this._timeout = null;
|
|
10898
|
+
}
|
|
10899
|
+
this._timeout = setTimeout(() => {
|
|
10900
|
+
event.clientX = event.touches[0].clientX;
|
|
10901
|
+
event.clientY = event.touches[0].clientY;
|
|
10902
|
+
cfg.onContextMenu(event, this);
|
|
10903
|
+
clearTimeout(this._timeout);
|
|
10904
|
+
this._timeout = null;
|
|
10905
|
+
}, 500);
|
|
10906
|
+
});
|
|
10907
|
+
|
|
10908
|
+
wireClickable.addEventListener('touchend', (event) => {
|
|
10909
|
+
event.preventDefault();
|
|
10910
|
+
//stops short touches from calling the timeout
|
|
10911
|
+
if(this._timeout) {
|
|
10912
|
+
clearTimeout(this._timeout);
|
|
10913
|
+
this._timeout = null;
|
|
10914
|
+
}
|
|
10915
|
+
} );
|
|
10916
|
+
|
|
10917
|
+
}
|
|
10918
|
+
else {
|
|
10919
|
+
wireClickable.addEventListener('contextmenu', (event) => {
|
|
10920
|
+
console.log(event);
|
|
10921
|
+
cfg.onContextMenu(event, this);
|
|
10922
|
+
event.preventDefault();
|
|
10923
|
+
event.stopPropagation();
|
|
10924
|
+
console.log("Label context menu");
|
|
10925
|
+
});
|
|
10926
|
+
}
|
|
10927
|
+
|
|
10887
10928
|
}
|
|
10888
10929
|
|
|
10889
10930
|
this._x1 = 0;
|
|
@@ -10958,7 +10999,7 @@ class Wire {
|
|
|
10958
10999
|
}
|
|
10959
11000
|
|
|
10960
11001
|
setClickable(clickable) {
|
|
10961
|
-
this._wireClickable.style["pointer-events"] = (
|
|
11002
|
+
this._wireClickable.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
10962
11003
|
}
|
|
10963
11004
|
|
|
10964
11005
|
setHighlighted(highlighted) {
|
|
@@ -11078,11 +11119,42 @@ class Dot {
|
|
|
11078
11119
|
}
|
|
11079
11120
|
|
|
11080
11121
|
if (cfg.onContextMenu) {
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
|
|
11122
|
+
if(os.isIphoneSafari()){
|
|
11123
|
+
dotClickable.addEventListener('touchstart', (event) => {
|
|
11124
|
+
event.preventDefault();
|
|
11125
|
+
if(this._timeout){
|
|
11126
|
+
clearTimeout(this._timeout);
|
|
11127
|
+
this._timeout = null;
|
|
11128
|
+
}
|
|
11129
|
+
this._timeout = setTimeout(() => {
|
|
11130
|
+
event.clientX = event.touches[0].clientX;
|
|
11131
|
+
event.clientY = event.touches[0].clientY;
|
|
11132
|
+
cfg.onContextMenu(event, this);
|
|
11133
|
+
clearTimeout(this._timeout);
|
|
11134
|
+
this._timeout = null;
|
|
11135
|
+
}, 500);
|
|
11136
|
+
});
|
|
11137
|
+
|
|
11138
|
+
dotClickable.addEventListener('touchend', (event) => {
|
|
11139
|
+
event.preventDefault();
|
|
11140
|
+
//stops short touches from calling the timeout
|
|
11141
|
+
if(this._timeout) {
|
|
11142
|
+
clearTimeout(this._timeout);
|
|
11143
|
+
this._timeout = null;
|
|
11144
|
+
}
|
|
11145
|
+
} );
|
|
11146
|
+
|
|
11147
|
+
}
|
|
11148
|
+
else {
|
|
11149
|
+
dotClickable.addEventListener('contextmenu', (event) => {
|
|
11150
|
+
console.log(event);
|
|
11151
|
+
cfg.onContextMenu(event, this);
|
|
11152
|
+
event.preventDefault();
|
|
11153
|
+
event.stopPropagation();
|
|
11154
|
+
console.log("Label context menu");
|
|
11155
|
+
});
|
|
11156
|
+
}
|
|
11157
|
+
|
|
11086
11158
|
}
|
|
11087
11159
|
|
|
11088
11160
|
this.setPos(cfg.x || 0, cfg.y || 0);
|
|
@@ -11131,7 +11203,7 @@ class Dot {
|
|
|
11131
11203
|
}
|
|
11132
11204
|
|
|
11133
11205
|
setClickable(clickable) {
|
|
11134
|
-
this._dotClickable.style["pointer-events"] = (
|
|
11206
|
+
this._dotClickable.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
11135
11207
|
}
|
|
11136
11208
|
|
|
11137
11209
|
setHighlighted(highlighted) {
|
|
@@ -11172,6 +11244,7 @@ class Label {
|
|
|
11172
11244
|
|
|
11173
11245
|
this._label = document.createElement('div');
|
|
11174
11246
|
this._label.className += this._label.className ? ' viewer-ruler-label' : 'viewer-ruler-label';
|
|
11247
|
+
this._timeout = null;
|
|
11175
11248
|
|
|
11176
11249
|
var label = this._label;
|
|
11177
11250
|
var style = label.style;
|
|
@@ -11241,12 +11314,42 @@ class Label {
|
|
|
11241
11314
|
}
|
|
11242
11315
|
|
|
11243
11316
|
if (cfg.onContextMenu) {
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
|
|
11317
|
+
if(os.isIphoneSafari()){
|
|
11318
|
+
label.addEventListener('touchstart', (event) => {
|
|
11319
|
+
event.preventDefault();
|
|
11320
|
+
if(this._timeout){
|
|
11321
|
+
clearTimeout(this._timeout);
|
|
11322
|
+
this._timeout = null;
|
|
11323
|
+
}
|
|
11324
|
+
this._timeout = setTimeout(() => {
|
|
11325
|
+
event.clientX = event.touches[0].clientX;
|
|
11326
|
+
event.clientY = event.touches[0].clientY;
|
|
11327
|
+
cfg.onContextMenu(event, this);
|
|
11328
|
+
clearTimeout(this._timeout);
|
|
11329
|
+
this._timeout = null;
|
|
11330
|
+
}, 500);
|
|
11331
|
+
});
|
|
11332
|
+
|
|
11333
|
+
label.addEventListener('touchend', (event) => {
|
|
11334
|
+
event.preventDefault();
|
|
11335
|
+
//stops short touches from calling the timeout
|
|
11336
|
+
if(this._timeout) {
|
|
11337
|
+
clearTimeout(this._timeout);
|
|
11338
|
+
this._timeout = null;
|
|
11339
|
+
}
|
|
11340
|
+
} );
|
|
11341
|
+
|
|
11342
|
+
}
|
|
11343
|
+
else {
|
|
11344
|
+
label.addEventListener('contextmenu', (event) => {
|
|
11345
|
+
console.log(event);
|
|
11346
|
+
cfg.onContextMenu(event, this);
|
|
11347
|
+
event.preventDefault();
|
|
11348
|
+
event.stopPropagation();
|
|
11349
|
+
console.log("Label context menu");
|
|
11350
|
+
});
|
|
11351
|
+
}
|
|
11352
|
+
|
|
11250
11353
|
}
|
|
11251
11354
|
}
|
|
11252
11355
|
|
|
@@ -11321,7 +11424,14 @@ class Label {
|
|
|
11321
11424
|
}
|
|
11322
11425
|
|
|
11323
11426
|
setClickable(clickable) {
|
|
11324
|
-
this._label.style["pointer-events"] = (
|
|
11427
|
+
this._label.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
11428
|
+
}
|
|
11429
|
+
|
|
11430
|
+
setPrefix(prefix) {
|
|
11431
|
+
if(this._prefix === prefix){
|
|
11432
|
+
return;
|
|
11433
|
+
}
|
|
11434
|
+
this._prefix = prefix;
|
|
11325
11435
|
}
|
|
11326
11436
|
|
|
11327
11437
|
destroy() {
|
|
@@ -11329,6 +11439,8 @@ class Label {
|
|
|
11329
11439
|
this._label.parentElement.removeChild(this._label);
|
|
11330
11440
|
}
|
|
11331
11441
|
}
|
|
11442
|
+
|
|
11443
|
+
|
|
11332
11444
|
}
|
|
11333
11445
|
|
|
11334
11446
|
var originVec = math.vec3();
|
|
@@ -12126,6 +12238,16 @@ class AngleMeasurementsControl extends Component {
|
|
|
12126
12238
|
reset() {
|
|
12127
12239
|
}
|
|
12128
12240
|
|
|
12241
|
+
/**
|
|
12242
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsControl, if any.
|
|
12243
|
+
*
|
|
12244
|
+
* @returns {null|AngleMeasurement}
|
|
12245
|
+
* @abstract
|
|
12246
|
+
*/
|
|
12247
|
+
get currentMeasurement() {
|
|
12248
|
+
return null;
|
|
12249
|
+
}
|
|
12250
|
+
|
|
12129
12251
|
/**
|
|
12130
12252
|
* Destroys this AngleMeasurementsMouseControl.
|
|
12131
12253
|
*
|
|
@@ -12576,6 +12698,15 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
12576
12698
|
this._mouseState = MOUSE_FINDING_ORIGIN;
|
|
12577
12699
|
}
|
|
12578
12700
|
|
|
12701
|
+
/**
|
|
12702
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsMouseControl, if any.
|
|
12703
|
+
*
|
|
12704
|
+
* @returns {null|AngleMeasurement}
|
|
12705
|
+
*/
|
|
12706
|
+
get currentMeasurement() {
|
|
12707
|
+
return this._currentAngleMeasurement;
|
|
12708
|
+
}
|
|
12709
|
+
|
|
12579
12710
|
/**
|
|
12580
12711
|
* Destroys this AngleMeasurementsMouseControl.
|
|
12581
12712
|
*/
|
|
@@ -13929,6 +14060,15 @@ class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
|
|
|
13929
14060
|
}
|
|
13930
14061
|
}
|
|
13931
14062
|
|
|
14063
|
+
/**
|
|
14064
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsTouchControl, if any.
|
|
14065
|
+
*
|
|
14066
|
+
* @returns {null|AngleMeasurement}
|
|
14067
|
+
*/
|
|
14068
|
+
get currentMeasurement() {
|
|
14069
|
+
return this._currentAngleMeasurement;
|
|
14070
|
+
}
|
|
14071
|
+
|
|
13932
14072
|
/**
|
|
13933
14073
|
* Destroys this AngleMeasurementsTouchControl.
|
|
13934
14074
|
*/
|
|
@@ -81024,10 +81164,11 @@ class SceneModelTransform {
|
|
|
81024
81164
|
const tempVec3a$a = math.vec3();
|
|
81025
81165
|
|
|
81026
81166
|
const tempOBB3 = math.OBB3();
|
|
81167
|
+
const tempQuaternion = math.vec4();
|
|
81027
81168
|
|
|
81028
81169
|
const DEFAULT_SCALE = math.vec3([1, 1, 1]);
|
|
81029
81170
|
const DEFAULT_POSITION = math.vec3([0, 0, 0]);
|
|
81030
|
-
|
|
81171
|
+
math.vec3([0, 0, 0]);
|
|
81031
81172
|
const DEFAULT_QUATERNION = math.identityQuaternion();
|
|
81032
81173
|
const DEFAULT_MATRIX = math.identityMat4();
|
|
81033
81174
|
|
|
@@ -83704,6 +83845,7 @@ class SceneModel extends Component {
|
|
|
83704
83845
|
* @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.
|
|
83705
83846
|
* @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh. Overridden by ````transformId````.
|
|
83706
83847
|
* @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by ````transformId````.
|
|
83848
|
+
* @param {Number[]} [cfg.quaternion] Rotation of the mesh as a quaternion. Overridden by ````rotation````.
|
|
83707
83849
|
* @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Mesh modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters. Also overridden by ````transformId````.
|
|
83708
83850
|
* @param {Number[]} [cfg.color=[1,1,1]] RGB color in range ````[0..1, 0..1, 0..1]````. Overridden by texture set ````colorTexture````. Overrides ````colors```` and ````colorsCompressed````.
|
|
83709
83851
|
* @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.
|
|
@@ -83778,12 +83920,15 @@ class SceneModel extends Component {
|
|
|
83778
83920
|
|
|
83779
83921
|
if (cfg.matrix) {
|
|
83780
83922
|
cfg.meshMatrix = cfg.matrix;
|
|
83781
|
-
} else if (cfg.scale || cfg.rotation || cfg.position) {
|
|
83923
|
+
} else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
|
|
83782
83924
|
const scale = cfg.scale || DEFAULT_SCALE;
|
|
83783
83925
|
const position = cfg.position || DEFAULT_POSITION;
|
|
83784
|
-
|
|
83785
|
-
|
|
83786
|
-
|
|
83926
|
+
if (cfg.rotation) {
|
|
83927
|
+
math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
|
|
83928
|
+
cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
|
|
83929
|
+
} else {
|
|
83930
|
+
cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
|
|
83931
|
+
}
|
|
83787
83932
|
}
|
|
83788
83933
|
|
|
83789
83934
|
if (cfg.positionsDecodeBoundary) {
|
|
@@ -83971,13 +84116,16 @@ class SceneModel extends Component {
|
|
|
83971
84116
|
// MATRIX
|
|
83972
84117
|
|
|
83973
84118
|
if (cfg.matrix) {
|
|
83974
|
-
cfg.meshMatrix = cfg.matrix
|
|
83975
|
-
} else {
|
|
84119
|
+
cfg.meshMatrix = cfg.matrix;
|
|
84120
|
+
} else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
|
|
83976
84121
|
const scale = cfg.scale || DEFAULT_SCALE;
|
|
83977
84122
|
const position = cfg.position || DEFAULT_POSITION;
|
|
83978
|
-
|
|
83979
|
-
|
|
83980
|
-
|
|
84123
|
+
if (cfg.rotation) {
|
|
84124
|
+
math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
|
|
84125
|
+
cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
|
|
84126
|
+
} else {
|
|
84127
|
+
cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
|
|
84128
|
+
}
|
|
83981
84129
|
}
|
|
83982
84130
|
|
|
83983
84131
|
math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);
|
|
@@ -86130,6 +86278,14 @@ const lengthWire = (x1, y1, x2, y2) => {
|
|
|
86130
86278
|
return Math.sqrt(a * a + b * b);
|
|
86131
86279
|
};
|
|
86132
86280
|
|
|
86281
|
+
function determineMeasurementOrientation(A, B, distance) {
|
|
86282
|
+
const yDiff = Math.abs(B[1] - A[1]);
|
|
86283
|
+
|
|
86284
|
+
return yDiff > distance ? 'Vertical' : 'Horizontal';
|
|
86285
|
+
}
|
|
86286
|
+
|
|
86287
|
+
// function findDistance
|
|
86288
|
+
|
|
86133
86289
|
/**
|
|
86134
86290
|
* @desc Measures the distance between two 3D points.
|
|
86135
86291
|
*
|
|
@@ -86158,17 +86314,16 @@ class DistanceMeasurement extends Component {
|
|
|
86158
86314
|
this._eventSubs = {};
|
|
86159
86315
|
|
|
86160
86316
|
var scene = this.plugin.viewer.scene;
|
|
86161
|
-
|
|
86162
86317
|
this._originMarker = new Marker(scene, cfg.origin);
|
|
86163
86318
|
this._targetMarker = new Marker(scene, cfg.target);
|
|
86164
86319
|
|
|
86165
86320
|
this._originWorld = math.vec3();
|
|
86166
86321
|
this._targetWorld = math.vec3();
|
|
86167
86322
|
|
|
86168
|
-
this._wp = new Float64Array(24);
|
|
86169
|
-
this._vp = new Float64Array(24);
|
|
86323
|
+
this._wp = new Float64Array(24); //world position
|
|
86324
|
+
this._vp = new Float64Array(24); //view position
|
|
86170
86325
|
this._pp = new Float64Array(24);
|
|
86171
|
-
this._cp = new Float64Array(8);
|
|
86326
|
+
this._cp = new Float64Array(8); //canvas position
|
|
86172
86327
|
|
|
86173
86328
|
this._xAxisLabelCulled = false;
|
|
86174
86329
|
this._yAxisLabelCulled = false;
|
|
@@ -86342,6 +86497,7 @@ class DistanceMeasurement extends Component {
|
|
|
86342
86497
|
onContextMenu
|
|
86343
86498
|
});
|
|
86344
86499
|
|
|
86500
|
+
this._measurementOrientation = 'Horizontal';
|
|
86345
86501
|
this._wpDirty = false;
|
|
86346
86502
|
this._vpDirty = false;
|
|
86347
86503
|
this._cpDirty = false;
|
|
@@ -86356,18 +86512,22 @@ class DistanceMeasurement extends Component {
|
|
|
86356
86512
|
this._yAxisVisible = false;
|
|
86357
86513
|
this._zAxisVisible = false;
|
|
86358
86514
|
this._axisEnabled = true;
|
|
86515
|
+
this._xLabelEnabled = false;
|
|
86516
|
+
this._yLabelEnabled = false;
|
|
86517
|
+
this._zLabelEnabled = false;
|
|
86518
|
+
this._lengthLabelEnabled = false;
|
|
86359
86519
|
this._labelsVisible = false;
|
|
86360
86520
|
this._labelsOnWires = false;
|
|
86361
86521
|
this._clickable = false;
|
|
86362
86522
|
|
|
86363
86523
|
this._originMarker.on("worldPos", (value) => {
|
|
86364
|
-
this._originWorld.set(value || [0,
|
|
86524
|
+
this._originWorld.set(value || [0,0,0]);
|
|
86365
86525
|
this._wpDirty = true;
|
|
86366
86526
|
this._needUpdate(0); // No lag
|
|
86367
86527
|
});
|
|
86368
86528
|
|
|
86369
86529
|
this._targetMarker.on("worldPos", (value) => {
|
|
86370
|
-
this._targetWorld.set(value || [0,
|
|
86530
|
+
this._targetWorld.set(value || [0,0,0]);
|
|
86371
86531
|
this._wpDirty = true;
|
|
86372
86532
|
this._needUpdate(0); // No lag
|
|
86373
86533
|
});
|
|
@@ -86416,6 +86576,10 @@ class DistanceMeasurement extends Component {
|
|
|
86416
86576
|
this.xAxisVisible = cfg.xAxisVisible;
|
|
86417
86577
|
this.yAxisVisible = cfg.yAxisVisible;
|
|
86418
86578
|
this.zAxisVisible = cfg.zAxisVisible;
|
|
86579
|
+
this.xLabelEnabled = cfg.xLabelEnabled;
|
|
86580
|
+
this.yLabelEnabled = cfg.yLabelEnabled;
|
|
86581
|
+
this.zLabelEnabled = cfg.zLabelEnabled;
|
|
86582
|
+
this.lengthLabelEnabled = cfg.lengthLabelEnabled;
|
|
86419
86583
|
this.labelsVisible = cfg.labelsVisible;
|
|
86420
86584
|
this.labelsOnWires = cfg.labelsOnWires;
|
|
86421
86585
|
}
|
|
@@ -86430,25 +86594,50 @@ class DistanceMeasurement extends Component {
|
|
|
86430
86594
|
|
|
86431
86595
|
if (this._wpDirty) {
|
|
86432
86596
|
|
|
86433
|
-
this.
|
|
86434
|
-
this.
|
|
86435
|
-
|
|
86436
|
-
|
|
86597
|
+
this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 1);
|
|
86598
|
+
if(this._measurementOrientation === 'Vertical'){
|
|
86599
|
+
this._wp[0] = this._originWorld[0];
|
|
86600
|
+
this._wp[1] = this._originWorld[1];
|
|
86601
|
+
this._wp[2] = this._originWorld[2];
|
|
86602
|
+
this._wp[3] = 1.0;
|
|
86437
86603
|
|
|
86438
|
-
|
|
86439
|
-
|
|
86440
|
-
|
|
86441
|
-
|
|
86604
|
+
this._wp[4] = this._originWorld[0]; //x-axis
|
|
86605
|
+
this._wp[5] = this._originWorld[1];
|
|
86606
|
+
this._wp[6] = this._originWorld[2];
|
|
86607
|
+
this._wp[7] = 1.0;
|
|
86442
86608
|
|
|
86443
|
-
|
|
86444
|
-
|
|
86445
|
-
|
|
86446
|
-
|
|
86609
|
+
this._wp[8] = this._originWorld[0]; //x-axis
|
|
86610
|
+
this._wp[9] = this._targetWorld[1]; //y-axis
|
|
86611
|
+
this._wp[10] = this._originWorld[2];
|
|
86612
|
+
this._wp[11] = 1.0;
|
|
86447
86613
|
|
|
86448
|
-
|
|
86449
|
-
|
|
86450
|
-
|
|
86451
|
-
|
|
86614
|
+
this._wp[12] = this._targetWorld[0];
|
|
86615
|
+
this._wp[13] = this._targetWorld[1];
|
|
86616
|
+
this._wp[14] = this._targetWorld[2];
|
|
86617
|
+
this._wp[15] = 1.0;
|
|
86618
|
+
}
|
|
86619
|
+
else {
|
|
86620
|
+
this._wp[0] = this._originWorld[0];
|
|
86621
|
+
this._wp[1] = this._originWorld[1];
|
|
86622
|
+
this._wp[2] = this._originWorld[2];
|
|
86623
|
+
this._wp[3] = 1.0;
|
|
86624
|
+
|
|
86625
|
+
this._wp[4] = this._targetWorld[0];
|
|
86626
|
+
this._wp[5] = this._originWorld[1];
|
|
86627
|
+
this._wp[6] = this._originWorld[2];
|
|
86628
|
+
this._wp[7] = 1.0;
|
|
86629
|
+
|
|
86630
|
+
this._wp[8] = this._targetWorld[0];
|
|
86631
|
+
this._wp[9] = this._targetWorld[1];
|
|
86632
|
+
this._wp[10] = this._originWorld[2];
|
|
86633
|
+
this._wp[11] = 1.0;
|
|
86634
|
+
|
|
86635
|
+
this._wp[12] = this._targetWorld[0];
|
|
86636
|
+
this._wp[13] = this._targetWorld[1];
|
|
86637
|
+
this._wp[14] = this._targetWorld[2];
|
|
86638
|
+
this._wp[15] = 1.0;
|
|
86639
|
+
}
|
|
86640
|
+
|
|
86452
86641
|
|
|
86453
86642
|
this._wpDirty = false;
|
|
86454
86643
|
this._vpDirty = true;
|
|
@@ -86619,7 +86808,14 @@ class DistanceMeasurement extends Component {
|
|
|
86619
86808
|
}
|
|
86620
86809
|
|
|
86621
86810
|
if (!this._zAxisLabelCulled) {
|
|
86622
|
-
|
|
86811
|
+
if(this._measurementOrientation === 'Vertical') {
|
|
86812
|
+
this._zAxisLabel.setPrefix("");
|
|
86813
|
+
this._zAxisLabel.setText(tilde + Math.abs(math.lenVec3(math.subVec3(this._targetWorld, [this._originWorld[0], this._targetWorld[1], this._originWorld[2]], distVec3)) * scale).toFixed(2) + unitAbbrev);
|
|
86814
|
+
}
|
|
86815
|
+
else {
|
|
86816
|
+
this._zAxisLabel.setPrefix("Z");
|
|
86817
|
+
this._zAxisLabel.setText(tilde + Math.abs((this._targetWorld[2] - this._originWorld[2]) * scale).toFixed(2) + unitAbbrev);
|
|
86818
|
+
}
|
|
86623
86819
|
this._zAxisLabel.setCulled(!this.axisVisible);
|
|
86624
86820
|
} else {
|
|
86625
86821
|
this._zAxisLabel.setCulled(true);
|
|
@@ -86739,7 +86935,7 @@ class DistanceMeasurement extends Component {
|
|
|
86739
86935
|
this._originDot.setVisible(this._visible && this._originVisible);
|
|
86740
86936
|
this._targetDot.setVisible(this._visible && this._targetVisible);
|
|
86741
86937
|
this._lengthWire.setVisible(this._visible && this._wireVisible);
|
|
86742
|
-
this._lengthLabel.setVisible(this._visible && this._wireVisible);
|
|
86938
|
+
this._lengthLabel.setVisible(this._visible && this._wireVisible && this._lengthLabelEnabled);
|
|
86743
86939
|
|
|
86744
86940
|
const xAxisVisible = this._visible && this._axisVisible && this._xAxisVisible;
|
|
86745
86941
|
const yAxisVisible = this._visible && this._axisVisible && this._yAxisVisible;
|
|
@@ -86749,9 +86945,9 @@ class DistanceMeasurement extends Component {
|
|
|
86749
86945
|
this._yAxisWire.setVisible(yAxisVisible);
|
|
86750
86946
|
this._zAxisWire.setVisible(zAxisVisible);
|
|
86751
86947
|
|
|
86752
|
-
this._xAxisLabel.setVisible(xAxisVisible && !this._xAxisLabelCulled);
|
|
86753
|
-
this._yAxisLabel.setVisible(yAxisVisible && !this._yAxisLabelCulled);
|
|
86754
|
-
this._zAxisLabel.setVisible(zAxisVisible && !this._zAxisLabelCulled);
|
|
86948
|
+
this._xAxisLabel.setVisible(xAxisVisible && !this._xAxisLabelCulled && this._EnabledVisible);
|
|
86949
|
+
this._yAxisLabel.setVisible(yAxisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
|
|
86950
|
+
this._zAxisLabel.setVisible(zAxisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
|
|
86755
86951
|
|
|
86756
86952
|
this._cpDirty = true;
|
|
86757
86953
|
|
|
@@ -86821,9 +87017,9 @@ class DistanceMeasurement extends Component {
|
|
|
86821
87017
|
this._xAxisWire.setVisible(axisVisible && this._xAxisVisible);
|
|
86822
87018
|
this._yAxisWire.setVisible(axisVisible && this._yAxisVisible);
|
|
86823
87019
|
this._zAxisWire.setVisible(axisVisible && this._zAxisVisible);
|
|
86824
|
-
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible);
|
|
86825
|
-
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._xAxisVisible);
|
|
86826
|
-
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._xAxisVisible);
|
|
87020
|
+
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible && this._xLabelEnabled);
|
|
87021
|
+
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._xAxisVisible && this._yLabelEnabled);
|
|
87022
|
+
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._xAxisVisible && this._zLabelEnabled);
|
|
86827
87023
|
this._cpDirty = true;
|
|
86828
87024
|
this._needUpdate();
|
|
86829
87025
|
}
|
|
@@ -86883,7 +87079,7 @@ class DistanceMeasurement extends Component {
|
|
|
86883
87079
|
this._xAxisVisible = value;
|
|
86884
87080
|
const axisVisible = this._visible && this._axisVisible && this._xAxisVisible && this._axisEnabled;
|
|
86885
87081
|
this._xAxisWire.setVisible(axisVisible);
|
|
86886
|
-
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled);
|
|
87082
|
+
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled && this._xLabelEnabled);
|
|
86887
87083
|
this._cpDirty = true;
|
|
86888
87084
|
this._needUpdate();
|
|
86889
87085
|
}
|
|
@@ -86911,7 +87107,7 @@ class DistanceMeasurement extends Component {
|
|
|
86911
87107
|
this._yAxisVisible = value;
|
|
86912
87108
|
const axisVisible = this._visible && this._axisVisible && this._yAxisVisible && this._axisEnabled;
|
|
86913
87109
|
this._yAxisWire.setVisible(axisVisible);
|
|
86914
|
-
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled);
|
|
87110
|
+
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
|
|
86915
87111
|
this._cpDirty = true;
|
|
86916
87112
|
this._needUpdate();
|
|
86917
87113
|
}
|
|
@@ -86939,7 +87135,7 @@ class DistanceMeasurement extends Component {
|
|
|
86939
87135
|
this._zAxisVisible = value;
|
|
86940
87136
|
const axisVisible = this._visible && this._axisVisible && this._zAxisVisible && this._axisEnabled;
|
|
86941
87137
|
this._zAxisWire.setVisible(axisVisible);
|
|
86942
|
-
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled);
|
|
87138
|
+
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
|
|
86943
87139
|
this._cpDirty = true;
|
|
86944
87140
|
this._needUpdate();
|
|
86945
87141
|
}
|
|
@@ -86964,7 +87160,7 @@ class DistanceMeasurement extends Component {
|
|
|
86964
87160
|
value = value !== undefined ? Boolean(value) : this.plugin.defaultWireVisible;
|
|
86965
87161
|
this._wireVisible = value;
|
|
86966
87162
|
var wireVisible = this._visible && this._wireVisible;
|
|
86967
|
-
this._lengthLabel.setVisible(wireVisible);
|
|
87163
|
+
this._lengthLabel.setVisible(wireVisible && this._lengthLabelEnabled);
|
|
86968
87164
|
this._lengthWire.setVisible(wireVisible);
|
|
86969
87165
|
}
|
|
86970
87166
|
|
|
@@ -86978,7 +87174,7 @@ class DistanceMeasurement extends Component {
|
|
|
86978
87174
|
}
|
|
86979
87175
|
|
|
86980
87176
|
/**
|
|
86981
|
-
* Sets if the labels are visible.
|
|
87177
|
+
* Sets if the labels are visible except the length label.
|
|
86982
87178
|
*
|
|
86983
87179
|
* @type {Boolean}
|
|
86984
87180
|
*/
|
|
@@ -86986,10 +87182,10 @@ class DistanceMeasurement extends Component {
|
|
|
86986
87182
|
value = value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible;
|
|
86987
87183
|
this._labelsVisible = value;
|
|
86988
87184
|
var labelsVisible = this._visible && this._labelsVisible;
|
|
86989
|
-
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86990
|
-
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86991
|
-
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86992
|
-
this._lengthLabel.setVisible(labelsVisible);
|
|
87185
|
+
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
|
|
87186
|
+
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
|
|
87187
|
+
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
|
|
87188
|
+
this._lengthLabel.setVisible(labelsVisible && this._lengthLabelEnabled);
|
|
86993
87189
|
this._cpDirty = true;
|
|
86994
87190
|
this._needUpdate();
|
|
86995
87191
|
}
|
|
@@ -87003,6 +87199,98 @@ class DistanceMeasurement extends Component {
|
|
|
87003
87199
|
return this._labelsVisible;
|
|
87004
87200
|
}
|
|
87005
87201
|
|
|
87202
|
+
/**
|
|
87203
|
+
* Sets if the x label is enabled.
|
|
87204
|
+
*
|
|
87205
|
+
* @type {Boolean}
|
|
87206
|
+
*/
|
|
87207
|
+
set xLabelEnabled(value) {
|
|
87208
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultXLabelEnabled;
|
|
87209
|
+
this._xLabelEnabled = value;
|
|
87210
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87211
|
+
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
|
|
87212
|
+
this._cpDirty = true;
|
|
87213
|
+
this._needUpdate();
|
|
87214
|
+
}
|
|
87215
|
+
|
|
87216
|
+
/**
|
|
87217
|
+
* Gets if the x label is enabled.
|
|
87218
|
+
*
|
|
87219
|
+
* @type {Boolean}
|
|
87220
|
+
*/
|
|
87221
|
+
get xLabelEnabled(){
|
|
87222
|
+
return this._xLabelEnabled;
|
|
87223
|
+
}
|
|
87224
|
+
|
|
87225
|
+
/**
|
|
87226
|
+
* Sets if the y label is enabled.
|
|
87227
|
+
*
|
|
87228
|
+
* @type {Boolean}
|
|
87229
|
+
*/
|
|
87230
|
+
set yLabelEnabled(value) {
|
|
87231
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultYLabelEnabled;
|
|
87232
|
+
this._yLabelEnabled = value;
|
|
87233
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87234
|
+
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
|
|
87235
|
+
this._cpDirty = true;
|
|
87236
|
+
this._needUpdate();
|
|
87237
|
+
}
|
|
87238
|
+
|
|
87239
|
+
/**
|
|
87240
|
+
* Gets if the y label is enabled.
|
|
87241
|
+
*
|
|
87242
|
+
* @type {Boolean}
|
|
87243
|
+
*/
|
|
87244
|
+
get yLabelEnabled(){
|
|
87245
|
+
return this._yLabelEnabled;
|
|
87246
|
+
}
|
|
87247
|
+
|
|
87248
|
+
/**
|
|
87249
|
+
* Sets if the z label is enabled.
|
|
87250
|
+
*
|
|
87251
|
+
* @type {Boolean}
|
|
87252
|
+
*/
|
|
87253
|
+
set zLabelEnabled(value) {
|
|
87254
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultZLabelEnabled;
|
|
87255
|
+
this._zLabelEnabled = value;
|
|
87256
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87257
|
+
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
|
|
87258
|
+
this._cpDirty = true;
|
|
87259
|
+
this._needUpdate();
|
|
87260
|
+
}
|
|
87261
|
+
|
|
87262
|
+
/**
|
|
87263
|
+
* Gets if the z label is enabled.
|
|
87264
|
+
*
|
|
87265
|
+
* @type {Boolean}
|
|
87266
|
+
*/
|
|
87267
|
+
get zLabelEnabled(){
|
|
87268
|
+
return this._zLabelEnabled;
|
|
87269
|
+
}
|
|
87270
|
+
|
|
87271
|
+
/**
|
|
87272
|
+
* Sets if the length label is enabled.
|
|
87273
|
+
*
|
|
87274
|
+
* @type {Boolean}
|
|
87275
|
+
*/
|
|
87276
|
+
set lengthLabelEnabled(value) {
|
|
87277
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultLengthLabelEnabled;
|
|
87278
|
+
this._lengthLabelEnabled = value;
|
|
87279
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87280
|
+
this._lengthLabel.setVisible(labelsVisible && !this._lengthAxisLabelCulled && this._clickable && this._axisEnabled && this._lengthLabelEnabled);
|
|
87281
|
+
this._cpDirty = true;
|
|
87282
|
+
this._needUpdate();
|
|
87283
|
+
}
|
|
87284
|
+
|
|
87285
|
+
/**
|
|
87286
|
+
* Gets if the length label is enabled.
|
|
87287
|
+
*
|
|
87288
|
+
* @type {Boolean}
|
|
87289
|
+
*/
|
|
87290
|
+
get lengthLabelEnabled(){
|
|
87291
|
+
return this._lengthLabelEnabled;
|
|
87292
|
+
}
|
|
87293
|
+
|
|
87006
87294
|
/**
|
|
87007
87295
|
* Sets if labels should be positioned on the wires.
|
|
87008
87296
|
*
|
|
@@ -87185,6 +87473,17 @@ class DistanceMeasurementsControl extends Component {
|
|
|
87185
87473
|
reset() {
|
|
87186
87474
|
}
|
|
87187
87475
|
|
|
87476
|
+
/**
|
|
87477
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl, if any.
|
|
87478
|
+
*
|
|
87479
|
+
* @returns {null|DistanceMeasurement}
|
|
87480
|
+
*
|
|
87481
|
+
* @abstract
|
|
87482
|
+
*/
|
|
87483
|
+
get currentMeasurement() {
|
|
87484
|
+
return null;
|
|
87485
|
+
}
|
|
87486
|
+
|
|
87188
87487
|
/**
|
|
87189
87488
|
* Destroys this DistanceMeasurementsControl.
|
|
87190
87489
|
*
|
|
@@ -87591,6 +87890,17 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
|
|
|
87591
87890
|
this._currentDistanceMeasurement.destroy();
|
|
87592
87891
|
this._currentDistanceMeasurement = null;
|
|
87593
87892
|
}
|
|
87893
|
+
|
|
87894
|
+
this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;
|
|
87895
|
+
}
|
|
87896
|
+
|
|
87897
|
+
/**
|
|
87898
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl, if any.
|
|
87899
|
+
*
|
|
87900
|
+
* @returns {null|DistanceMeasurement}
|
|
87901
|
+
*/
|
|
87902
|
+
get currentMeasurement() {
|
|
87903
|
+
return this._currentDistanceMeasurement;
|
|
87594
87904
|
}
|
|
87595
87905
|
|
|
87596
87906
|
/**
|
|
@@ -87878,6 +88188,10 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
87878
88188
|
* @param {boolean} [cfg.defaultTargetVisible=true] The default value of the DistanceMeasurements `targetVisible` property.
|
|
87879
88189
|
* @param {boolean} [cfg.defaultWireVisible=true] The default value of the DistanceMeasurements `wireVisible` property.
|
|
87880
88190
|
* @param {boolean} [cfg.defaultLabelsVisible=true] The default value of the DistanceMeasurements `labelsVisible` property.
|
|
88191
|
+
* @param {boolean} [cfg.defaultXLabelEnabled=true] The default value of the DistanceMeasurements `xLabelEnabled` property.
|
|
88192
|
+
* @param {boolean} [cfg.defaultYLabelEnabled=true] The default value of the DistanceMeasurements `yLabelEnabled` property.
|
|
88193
|
+
* @param {boolean} [cfg.defaultZLabelEnabled=true] The default value of the DistanceMeasurements `zLabelEnabled` property.
|
|
88194
|
+
* @param {boolean} [cfg.defaultLengthLabelEnabled=true] The default value of the DistanceMeasurements `lengthLabelEnabled` property.
|
|
87881
88195
|
* @param {boolean} [cfg.defaultAxisVisible=true] The default value of the DistanceMeasurements `axisVisible` property.
|
|
87882
88196
|
* @param {boolean} [cfg.defaultXAxisVisible=true] The default value of the DistanceMeasurements `xAxisVisible` property.
|
|
87883
88197
|
* @param {boolean} [cfg.defaultYAxisVisible=true] The default value of the DistanceMeasurements `yAxisVisible` property.
|
|
@@ -87900,11 +88214,14 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
87900
88214
|
this._measurements = {};
|
|
87901
88215
|
|
|
87902
88216
|
this.labelMinAxisLength = cfg.labelMinAxisLength;
|
|
87903
|
-
|
|
87904
88217
|
this.defaultVisible = cfg.defaultVisible !== false;
|
|
87905
88218
|
this.defaultOriginVisible = cfg.defaultOriginVisible !== false;
|
|
87906
88219
|
this.defaultTargetVisible = cfg.defaultTargetVisible !== false;
|
|
87907
88220
|
this.defaultWireVisible = cfg.defaultWireVisible !== false;
|
|
88221
|
+
this.defaultXLabelEnabled = cfg.defaultXLabelEnabled !== false;
|
|
88222
|
+
this.defaultYLabelEnabled = cfg.defaultYLabelEnabled !== false;
|
|
88223
|
+
this.defaultZLabelEnabled = cfg.defaultZLabelEnabled !== false;
|
|
88224
|
+
this.defaultLengthLabelEnabled = cfg.defaultLengthLabelEnabled !== false;
|
|
87908
88225
|
this.defaultLabelsVisible = cfg.defaultLabelsVisible !== false;
|
|
87909
88226
|
this.defaultAxisVisible = cfg.defaultAxisVisible !== false;
|
|
87910
88227
|
this.defaultXAxisVisible = cfg.defaultXAxisVisible !== false;
|
|
@@ -88033,7 +88350,12 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88033
88350
|
* @param {Boolean} [params.xAxisVisible=true] Whether to initially show the X-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88034
88351
|
* @param {Boolean} [params.yAxisVisible=true] Whether to initially show the Y-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88035
88352
|
* @param {Boolean} [params.zAxisVisible=true] Whether to initially show the Z-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88353
|
+
* @param {Boolean} [params.xLabelEnabled=true] Whether to initially show the x label.
|
|
88354
|
+
* @param {Boolean} [params.yLabelEnabled=true] Whether to initially show the y label.
|
|
88355
|
+
* @param {Boolean} [params.zLabelEnabled=true] Whether to initially show the z label.
|
|
88356
|
+
* @param {Boolean} [params.lengthLabelEnabled=true] Whether to initially show the length label.
|
|
88036
88357
|
* @param {Boolean} [params.labelsVisible=true] Whether to initially show the labels.
|
|
88358
|
+
* @param {Boolean} [params.lengthLabelVisible=true] Whether to initially show the labels.
|
|
88037
88359
|
* @param {string} [params.color] The color of the length dot, wire and label.
|
|
88038
88360
|
* @param {Boolean} [params.labelsOnWires=true] Determines if labels will be set on wires or one below the other.
|
|
88039
88361
|
* @returns {DistanceMeasurement} The new {@link DistanceMeasurement}.
|
|
@@ -88063,6 +88385,10 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88063
88385
|
xAxisVisible: params.xAxisVisible !== false && this.defaultXAxisVisible !== false,
|
|
88064
88386
|
yAxisVisible: params.yAxisVisible !== false && this.defaultYAxisVisible !== false,
|
|
88065
88387
|
zAxisVisible: params.zAxisVisible !== false && this.defaultZAxisVisible !== false,
|
|
88388
|
+
xLabelEnabled: params.xLabelEnabled !== false && this.defaultXLabelEnabled !== false,
|
|
88389
|
+
yLabelEnabled: params.yLabelEnabled !== false && this.defaultYLabelEnabled !== false,
|
|
88390
|
+
zLabelEnabled: params.zLabelEnabled !== false && this.defaultZLabelEnabled !== false,
|
|
88391
|
+
lengthLabelEnabled: params.lengthLabelEnabled !== false && this.defaultLengthLabelEnabled !== false,
|
|
88066
88392
|
labelsVisible: params.labelsVisible !== false && this.defaultLabelsVisible !== false,
|
|
88067
88393
|
originVisible: params.originVisible,
|
|
88068
88394
|
targetVisible: params.targetVisible,
|
|
@@ -88073,6 +88399,7 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88073
88399
|
onContextMenu: this._onContextMenu
|
|
88074
88400
|
});
|
|
88075
88401
|
this._measurements[measurement.id] = measurement;
|
|
88402
|
+
measurement.clickable = true;
|
|
88076
88403
|
measurement.on("destroyed", () => {
|
|
88077
88404
|
delete this._measurements[measurement.id];
|
|
88078
88405
|
});
|
|
@@ -88808,6 +89135,10 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88808
89135
|
this._currentDistanceMeasurement.targetVisible = true;
|
|
88809
89136
|
this._currentDistanceMeasurement.wireVisible = true;
|
|
88810
89137
|
this._currentDistanceMeasurement.labelsVisible = true;
|
|
89138
|
+
this._currentDistanceMeasurement.xAxisVisible = true;
|
|
89139
|
+
this._currentDistanceMeasurement.yAxisVisible = true;
|
|
89140
|
+
this._currentDistanceMeasurement.zAxisVisible = true;
|
|
89141
|
+
this._currentDistanceMeasurement.clickable = true;
|
|
88811
89142
|
this.distanceMeasurementsPlugin.fire("measurementEnd", this._currentDistanceMeasurement);
|
|
88812
89143
|
this._currentDistanceMeasurement = null;
|
|
88813
89144
|
} else {
|
|
@@ -88823,6 +89154,7 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88823
89154
|
break;
|
|
88824
89155
|
|
|
88825
89156
|
case WAITING_FOR_TARGET_LONG_TOUCH_END:
|
|
89157
|
+
console.log('long touch');
|
|
88826
89158
|
if (this.pointerLens) {
|
|
88827
89159
|
this.pointerLens.visible = false;
|
|
88828
89160
|
}
|
|
@@ -88890,6 +89222,16 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88890
89222
|
this._currentDistanceMeasurement.destroy();
|
|
88891
89223
|
this._currentDistanceMeasurement = null;
|
|
88892
89224
|
}
|
|
89225
|
+
this._mouseState = WAITING_FOR_ORIGIN_TOUCH_START;
|
|
89226
|
+
}
|
|
89227
|
+
|
|
89228
|
+
/**
|
|
89229
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsTouchControl, if any.
|
|
89230
|
+
*
|
|
89231
|
+
* @returns {null|DistanceMeasurement}
|
|
89232
|
+
*/
|
|
89233
|
+
get currentMeasurement() {
|
|
89234
|
+
return this._currentDistanceMeasurement;
|
|
88893
89235
|
}
|
|
88894
89236
|
|
|
88895
89237
|
/**
|
|
@@ -96614,8 +96956,8 @@ function getCanvasPosFromEvent$2(event, canvas, canvasPos) {
|
|
|
96614
96956
|
canvasPos[1] = event.y;
|
|
96615
96957
|
} else {
|
|
96616
96958
|
const { left, top } = canvas.getBoundingClientRect();
|
|
96617
|
-
canvasPos[0] = event.clientX - left
|
|
96618
|
-
canvasPos[1] = event.clientY - top
|
|
96959
|
+
canvasPos[0] = event.clientX - left;
|
|
96960
|
+
canvasPos[1] = event.clientY - top;
|
|
96619
96961
|
}
|
|
96620
96962
|
return canvasPos;
|
|
96621
96963
|
}
|
|
@@ -115809,6 +116151,7 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
|
|
|
115809
116151
|
}).then((gltfData) => {
|
|
115810
116152
|
const ctx = {
|
|
115811
116153
|
src: src,
|
|
116154
|
+
entityId: options.entityId,
|
|
115812
116155
|
metaModelCorrections: metaModelJSON ? getMetaModelCorrections(metaModelJSON) : null,
|
|
115813
116156
|
loadBuffer: options.loadBuffer,
|
|
115814
116157
|
basePath: options.basePath,
|
|
@@ -116248,29 +116591,9 @@ function loadNode(ctx, node, depth, matrix) {
|
|
|
116248
116591
|
meshCfg.origin = origin;
|
|
116249
116592
|
}
|
|
116250
116593
|
|
|
116251
|
-
// if (createEntity) {
|
|
116252
|
-
// if (createEntity.colorize) {
|
|
116253
|
-
// meshCfg.color = createEntity.colorize;
|
|
116254
|
-
// }
|
|
116255
|
-
// if (createEntity.opacity !== undefined && createEntity.opacity !== null) {
|
|
116256
|
-
// meshCfg.opacity = createEntity.opacity;
|
|
116257
|
-
// }
|
|
116258
|
-
// }
|
|
116259
|
-
|
|
116260
116594
|
sceneModel.createMesh(meshCfg);
|
|
116261
116595
|
deferredMeshIds.push(meshCfg.id);
|
|
116262
116596
|
}
|
|
116263
|
-
// if (createEntity) {
|
|
116264
|
-
// sceneModel.createEntity(utils.apply(createEntity, {
|
|
116265
|
-
// meshIds: deferredMeshIds,
|
|
116266
|
-
// isObject: true
|
|
116267
|
-
// }));
|
|
116268
|
-
// } else {
|
|
116269
|
-
// sceneModel.createEntity({
|
|
116270
|
-
// meshIds: deferredMeshIds,
|
|
116271
|
-
// isObject: true
|
|
116272
|
-
// });
|
|
116273
|
-
// }
|
|
116274
116597
|
}
|
|
116275
116598
|
}
|
|
116276
116599
|
|
|
@@ -116284,48 +116607,62 @@ function loadNode(ctx, node, depth, matrix) {
|
|
|
116284
116607
|
|
|
116285
116608
|
// Post-order visit scene node
|
|
116286
116609
|
|
|
116287
|
-
|
|
116288
|
-
|
|
116289
|
-
|
|
116290
|
-
|
|
116610
|
+
if (ctx.entityId) {
|
|
116611
|
+
if (depth ===0) {
|
|
116612
|
+
sceneModel.createEntity({
|
|
116613
|
+
id: ctx.entityId,
|
|
116614
|
+
meshIds: deferredMeshIds,
|
|
116615
|
+
isObject: true
|
|
116616
|
+
});
|
|
116617
|
+
deferredMeshIds.length = 0;
|
|
116291
116618
|
}
|
|
116292
|
-
|
|
116293
|
-
|
|
116294
|
-
|
|
116295
|
-
|
|
116296
|
-
|
|
116297
|
-
|
|
116298
|
-
|
|
116299
|
-
|
|
116300
|
-
//
|
|
116301
|
-
|
|
116302
|
-
|
|
116303
|
-
|
|
116304
|
-
|
|
116305
|
-
|
|
116306
|
-
|
|
116307
|
-
|
|
116308
|
-
|
|
116309
|
-
|
|
116310
|
-
|
|
116619
|
+
} else {
|
|
116620
|
+
const nodeName = node.name;
|
|
116621
|
+
if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {
|
|
116622
|
+
if (nodeName === undefined || nodeName === null) {
|
|
116623
|
+
ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);
|
|
116624
|
+
}
|
|
116625
|
+
let entityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)
|
|
116626
|
+
// if (!!entityId && sceneModel.entities[entityId]) {
|
|
116627
|
+
// ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${nodeName} - will randomly-generating an object ID in XKT`);
|
|
116628
|
+
// }
|
|
116629
|
+
// while (!entityId || sceneModel.entities[entityId]) {
|
|
116630
|
+
// entityId = "entity-" + ctx.nextId++;
|
|
116631
|
+
// }
|
|
116632
|
+
if (ctx.metaModelCorrections) {
|
|
116633
|
+
// Merging meshes into XKTObjects that map to metaobjects
|
|
116634
|
+
const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[entityId];
|
|
116635
|
+
if (rootMetaObject) {
|
|
116636
|
+
const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];
|
|
116637
|
+
rootMetaObjectStats.countChildren++;
|
|
116638
|
+
if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {
|
|
116639
|
+
sceneModel.createEntity({
|
|
116640
|
+
id: rootMetaObject.id,
|
|
116641
|
+
meshIds: deferredMeshIds,
|
|
116642
|
+
isObject: true
|
|
116643
|
+
});
|
|
116644
|
+
deferredMeshIds.length = 0;
|
|
116645
|
+
}
|
|
116646
|
+
} else {
|
|
116647
|
+
const metaObject = ctx.metaModelCorrections.metaObjectsMap[entityId];
|
|
116648
|
+
if (metaObject) {
|
|
116649
|
+
sceneModel.createEntity({
|
|
116650
|
+
id: entityId,
|
|
116651
|
+
meshIds: deferredMeshIds,
|
|
116652
|
+
isObject: true
|
|
116653
|
+
});
|
|
116654
|
+
deferredMeshIds.length = 0;
|
|
116655
|
+
}
|
|
116311
116656
|
}
|
|
116312
116657
|
} else {
|
|
116313
|
-
|
|
116314
|
-
|
|
116315
|
-
|
|
116316
|
-
|
|
116317
|
-
|
|
116318
|
-
|
|
116319
|
-
|
|
116320
|
-
}
|
|
116658
|
+
// Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
|
|
116659
|
+
sceneModel.createEntity({
|
|
116660
|
+
id: entityId,
|
|
116661
|
+
meshIds: deferredMeshIds,
|
|
116662
|
+
isObject: true
|
|
116663
|
+
});
|
|
116664
|
+
deferredMeshIds.length = 0;
|
|
116321
116665
|
}
|
|
116322
|
-
} else {
|
|
116323
|
-
// Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
|
|
116324
|
-
sceneModel.createEntity({
|
|
116325
|
-
id: entityId,
|
|
116326
|
-
meshIds: deferredMeshIds
|
|
116327
|
-
});
|
|
116328
|
-
deferredMeshIds.length = 0;
|
|
116329
116666
|
}
|
|
116330
116667
|
}
|
|
116331
116668
|
}
|
|
@@ -116502,6 +116839,79 @@ const IFCObjectDefaults = {
|
|
|
116502
116839
|
* excludeTypes: ["IfcSpace"]
|
|
116503
116840
|
* });
|
|
116504
116841
|
* ````
|
|
116842
|
+
*
|
|
116843
|
+
* ## Showing a glTF model in TreeViewPlugin when metadata is not available
|
|
116844
|
+
*
|
|
116845
|
+
* When GLTFLoaderPlugin loads a glTF model, it creates an object Entity for each `node` in the glTF `scene` hierarchy that has a
|
|
116846
|
+
* `name` attribute, giving the Entity an ID that has the value of the `name` attribute.
|
|
116847
|
+
*
|
|
116848
|
+
* Those name attributes are created by converter tools, such as by [IFC2GLTFCxConverter](https://github.com/Creoox/creoox-ifc2gltfcxconverter) when it generates glTF from IFC files. However, those name attributes are not
|
|
116849
|
+
* ordinarily present in glTF that comes from other sources, such as LiDAR scanners. For such glTF models, GLTFLoaderPlugin
|
|
116850
|
+
* will create Entities, but they will have randomly-generated IDs, and therefore cannot be associated with MetaObjects in any
|
|
116851
|
+
* MetaModels that we create alongside the model.
|
|
116852
|
+
*
|
|
116853
|
+
* For glTF models containing `nodes` that don't have `name` attributes, we can use the `load()` method's `elementId` parameter
|
|
116854
|
+
* to make GLTFLoaderPlugin load the entire model into a single Entity that gets this ID.
|
|
116855
|
+
*
|
|
116856
|
+
* In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that
|
|
116857
|
+
* contains a MetaObject that corresponds to that Entity.
|
|
116858
|
+
*
|
|
116859
|
+
* When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the glTF model and controls
|
|
116860
|
+
* the visibility of that Entity (ie. to control the visibility of the entire model).
|
|
116861
|
+
*
|
|
116862
|
+
* The snippet below shows how this is done.
|
|
116863
|
+
*
|
|
116864
|
+
* ````javascript
|
|
116865
|
+
* import {Viewer, GLTFLoaderPlugin, NavCubePlugin, TreeViewPlugin} from "../../dist/xeokit-sdk.es.js";
|
|
116866
|
+
*
|
|
116867
|
+
* const viewer = new Viewer({
|
|
116868
|
+
* canvasId: "myCanvas",
|
|
116869
|
+
* transparent: true
|
|
116870
|
+
* });
|
|
116871
|
+
*
|
|
116872
|
+
* new TreeViewPlugin(viewer, {
|
|
116873
|
+
* containerElement: document.getElementById("treeViewContainer"),
|
|
116874
|
+
* hierarchy: "containment"
|
|
116875
|
+
* });
|
|
116876
|
+
*
|
|
116877
|
+
* const gltfLoader = new GLTFLoaderPlugin(viewer);
|
|
116878
|
+
*
|
|
116879
|
+
* const sceneModel = gltfLoader.load({ // Creates a SceneModel with ID "myScanModel"
|
|
116880
|
+
* id: "myScanModel",
|
|
116881
|
+
* src: "public-use-sample-apartment.glb",
|
|
116882
|
+
*
|
|
116883
|
+
* //-------------------------------------------------------------------------
|
|
116884
|
+
* // Specify an `elementId` parameter, which causes the
|
|
116885
|
+
* // entire model to be loaded into a single Entity that gets this ID.
|
|
116886
|
+
* //-------------------------------------------------------------------------
|
|
116887
|
+
*
|
|
116888
|
+
* entityId: "3toKckUfH2jBmd$7uhJHa4", // Creates an Entity with this ID
|
|
116889
|
+
*
|
|
116890
|
+
* //-------------------------------------------------------------------------
|
|
116891
|
+
* // Specify a `metaModelJSON` parameter, which creates a
|
|
116892
|
+
* // MetaModel with two MetaObjects, one of which corresponds
|
|
116893
|
+
* // to our Entity. Then the TreeViewPlugin is able to have a node
|
|
116894
|
+
* // that can represent the model and control the visibility of the Entity.
|
|
116895
|
+
* //--------------------------------------------------------------------------
|
|
116896
|
+
*
|
|
116897
|
+
* metaModelJSON: { // Creates a MetaModel with ID "myScanModel"
|
|
116898
|
+
* "metaObjects": [
|
|
116899
|
+
* {
|
|
116900
|
+
* "id": "3toKckUfH2jBmd$7uhJHa6", // Creates a MetaObject with this ID
|
|
116901
|
+
* "name": "My Project",
|
|
116902
|
+
* "type": "Default",
|
|
116903
|
+
* "parent": null
|
|
116904
|
+
* },
|
|
116905
|
+
* {
|
|
116906
|
+
* "id": "3toKckUfH2jBmd$7uhJHa4", // Creates a MetaObject with this ID (same ID as our Entity)
|
|
116907
|
+
* "name": "My Scan",
|
|
116908
|
+
* "type": "Default",
|
|
116909
|
+
* "parent": "3toKckUfH2jBmd$7uhJHa6"
|
|
116910
|
+
* }
|
|
116911
|
+
* ]
|
|
116912
|
+
* }
|
|
116913
|
+
* });
|
|
116914
|
+
* ````
|
|
116505
116915
|
* @class GLTFLoaderPlugin
|
|
116506
116916
|
*/
|
|
116507
116917
|
class GLTFLoaderPlugin extends Plugin {
|
|
@@ -116596,6 +117006,7 @@ class GLTFLoaderPlugin extends Plugin {
|
|
|
116596
117006
|
* represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
|
|
116597
117007
|
* to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
|
|
116598
117008
|
* primitives. Only works while {@link DTX#enabled} is also ````true````.
|
|
117009
|
+
* @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
|
|
116599
117010
|
* @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}
|
|
116600
117011
|
*/
|
|
116601
117012
|
load(params = {}) {
|
|
@@ -134768,6 +135179,60 @@ const MAX_VERTICES = 500000; // TODO: Rough estimate
|
|
|
134768
135179
|
* });
|
|
134769
135180
|
* ````
|
|
134770
135181
|
*
|
|
135182
|
+
* ## Showing a LAS/LAZ model in TreeViewPlugin
|
|
135183
|
+
*
|
|
135184
|
+
* We can use the `load()` method's `elementId` parameter
|
|
135185
|
+
* to make LASLoaderPlugin load the entire model into a single Entity that gets this ID.
|
|
135186
|
+
*
|
|
135187
|
+
* In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that
|
|
135188
|
+
* contains a MetaObject that corresponds to that Entity.
|
|
135189
|
+
*
|
|
135190
|
+
* When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the model and controls
|
|
135191
|
+
* the visibility of that Entity (ie. to control the visibility of the entire model).
|
|
135192
|
+
*
|
|
135193
|
+
* The snippet below shows how this is done.
|
|
135194
|
+
*
|
|
135195
|
+
* ````javascript
|
|
135196
|
+
* import {Viewer, LASLoaderPlugin, NavCubePlugin, TreeViewPlugin} from "../../dist/xeokit-sdk.es.js";
|
|
135197
|
+
*
|
|
135198
|
+
* const viewer = new Viewer({
|
|
135199
|
+
* canvasId: "myCanvas",
|
|
135200
|
+
* transparent: true
|
|
135201
|
+
* });
|
|
135202
|
+
*
|
|
135203
|
+
* new TreeViewPlugin(viewer, {
|
|
135204
|
+
* containerElement: document.getElementById("treeViewContainer"),
|
|
135205
|
+
* hierarchy: "containment"
|
|
135206
|
+
* });
|
|
135207
|
+
*
|
|
135208
|
+
* const lasLoader = new LASLoaderPlugin(viewer);
|
|
135209
|
+
*
|
|
135210
|
+
* const sceneModel = lasLoader.load({ // Creates a SceneModel with ID "myScanModel"
|
|
135211
|
+
* id: "myScanModel",
|
|
135212
|
+
* src: "../../assets/models/las/Nalls_Pumpkin_Hill.laz",
|
|
135213
|
+
* rotation: [-90, 0, 0],
|
|
135214
|
+
*
|
|
135215
|
+
* entityId: "3toKckUfH2jBmd$7uhJHa4", // Creates an Entity with this ID
|
|
135216
|
+
*
|
|
135217
|
+
* metaModelJSON: { // Creates a MetaModel with ID "myScanModel"
|
|
135218
|
+
* "metaObjects": [
|
|
135219
|
+
* {
|
|
135220
|
+
* "id": "3toKckUfH2jBmd$7uhJHa6", // Creates this MetaObject with this ID
|
|
135221
|
+
* "name": "My Project",
|
|
135222
|
+
* "type": "Default",
|
|
135223
|
+
* "parent": null
|
|
135224
|
+
* },
|
|
135225
|
+
* {
|
|
135226
|
+
* "id": "3toKckUfH2jBmd$7uhJHa4", // Creates this MetaObject with this ID
|
|
135227
|
+
* "name": "My Scan",
|
|
135228
|
+
* "type": "Default",
|
|
135229
|
+
* "parent": "3toKckUfH2jBmd$7uhJHa6"
|
|
135230
|
+
* }
|
|
135231
|
+
* ]
|
|
135232
|
+
* }
|
|
135233
|
+
* });
|
|
135234
|
+
* ````
|
|
135235
|
+
*
|
|
134771
135236
|
* @class LASLoaderPlugin
|
|
134772
135237
|
* @since 2.0.17
|
|
134773
135238
|
*/
|
|
@@ -135118,7 +135583,7 @@ class LASLoaderPlugin extends Plugin {
|
|
|
135118
135583
|
}
|
|
135119
135584
|
*/
|
|
135120
135585
|
|
|
135121
|
-
const pointsObjectId = math.createUUID();
|
|
135586
|
+
const pointsObjectId = params.entityId || math.createUUID();
|
|
135122
135587
|
|
|
135123
135588
|
sceneModel.createEntity({
|
|
135124
135589
|
id: pointsObjectId,
|
|
@@ -135128,7 +135593,10 @@ class LASLoaderPlugin extends Plugin {
|
|
|
135128
135593
|
|
|
135129
135594
|
sceneModel.finalize();
|
|
135130
135595
|
|
|
135131
|
-
if (params.
|
|
135596
|
+
if (params.metaModelJSON) {
|
|
135597
|
+
const metaModelId = sceneModel.id;
|
|
135598
|
+
this.viewer.metaScene.createMetaModel(metaModelId, params.metaModelJSON, options);
|
|
135599
|
+
} else if (params.loadMetadata !== false) {
|
|
135132
135600
|
const rootMetaObjectId = math.createUUID();
|
|
135133
135601
|
const metadata = {
|
|
135134
135602
|
projectId: "",
|
|
@@ -136626,4 +137094,564 @@ class CityJSONLoaderPlugin extends Plugin {
|
|
|
136626
137094
|
}
|
|
136627
137095
|
}
|
|
136628
137096
|
|
|
136629
|
-
|
|
137097
|
+
/**
|
|
137098
|
+
* Default data access strategy for {@link DotBIMLoaderPlugin}.
|
|
137099
|
+
*
|
|
137100
|
+
* This just loads assets using XMLHttpRequest.
|
|
137101
|
+
*/
|
|
137102
|
+
class DotBIMDefaultDataSource {
|
|
137103
|
+
|
|
137104
|
+
constructor() {
|
|
137105
|
+
}
|
|
137106
|
+
|
|
137107
|
+
/**
|
|
137108
|
+
* Gets .BIM JSON.
|
|
137109
|
+
*
|
|
137110
|
+
* @param {String|Number} dotBIMSrc Identifies the .BIM JSON asset.
|
|
137111
|
+
* @param {Function} ok Fired on successful loading of the .BIM JSON asset.
|
|
137112
|
+
* @param {Function} error Fired on error while loading the .BIM JSON asset.
|
|
137113
|
+
*/
|
|
137114
|
+
getDotBIM(dotBIMSrc, ok, error) {
|
|
137115
|
+
utils.loadJSON(dotBIMSrc,
|
|
137116
|
+
(json) => {
|
|
137117
|
+
ok(json);
|
|
137118
|
+
},
|
|
137119
|
+
function (errMsg) {
|
|
137120
|
+
error(errMsg);
|
|
137121
|
+
});
|
|
137122
|
+
}
|
|
137123
|
+
}
|
|
137124
|
+
|
|
137125
|
+
/**
|
|
137126
|
+
* {@link Viewer} plugin that loads models from [.bim](https://dotbim.net/) format.
|
|
137127
|
+
*
|
|
137128
|
+
* [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/DotBIMLoaderPlugin-house.png">](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)
|
|
137129
|
+
*
|
|
137130
|
+
* [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)]
|
|
137131
|
+
*
|
|
137132
|
+
* * Creates an {@link Entity} representing each .bim model it loads, which will have {@link Entity#isModel} set ````true````
|
|
137133
|
+
* and will be registered by {@link Entity#id} in {@link Scene#models}.
|
|
137134
|
+
* * Creates an {@link Entity} for each object within the .bim model. Those Entities will have {@link Entity#isObject}
|
|
137135
|
+
* set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
|
|
137136
|
+
* * When loading, can set the World-space position, scale and rotation of each model within World space,
|
|
137137
|
+
* along with initial properties for all the model's {@link Entity}s.
|
|
137138
|
+
* * Allows to mask which IFC types we want to load.
|
|
137139
|
+
* * Allows to configure initial viewer state for specified IFC types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
|
|
137140
|
+
*
|
|
137141
|
+
* ## Usage
|
|
137142
|
+
*
|
|
137143
|
+
* In the example below we'll load a house model from a [.bim file](/assets/models/dotbim/House.bim).
|
|
137144
|
+
*
|
|
137145
|
+
* This will create a bunch of {@link Entity}s that represents the model and its objects, along with
|
|
137146
|
+
* a {@link MetaModel} and {@link MetaObject}s that hold their metadata.
|
|
137147
|
+
*
|
|
137148
|
+
* ````javascript
|
|
137149
|
+
* import {Viewer, DotBIMLoaderPlugin} from "xeokit-sdk.es.js";
|
|
137150
|
+
*
|
|
137151
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137152
|
+
* // 1. Create a Viewer,
|
|
137153
|
+
* // 2. Arrange the camera,
|
|
137154
|
+
* // 3. Tweak the selection material (tone it down a bit)
|
|
137155
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137156
|
+
*
|
|
137157
|
+
* // 1
|
|
137158
|
+
* const viewer = new Viewer({
|
|
137159
|
+
* canvasId: "myCanvas",
|
|
137160
|
+
* transparent: true
|
|
137161
|
+
* });
|
|
137162
|
+
*
|
|
137163
|
+
* // 2
|
|
137164
|
+
* viewer.camera.orbitPitch(20);
|
|
137165
|
+
* viewer.camera.orbitYaw(-45);
|
|
137166
|
+
*
|
|
137167
|
+
* // 3
|
|
137168
|
+
* viewer.scene.selectedMaterial.fillAlpha = 0.1;
|
|
137169
|
+
*
|
|
137170
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137171
|
+
* // 1. Create a .bim loader plugin,
|
|
137172
|
+
* // 2. Load a .bim building model, emphasizing the edges to make it look nicer
|
|
137173
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137174
|
+
*
|
|
137175
|
+
* // 1
|
|
137176
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer);
|
|
137177
|
+
*
|
|
137178
|
+
* // 2
|
|
137179
|
+
* var model = dotBIMLoader.load({ // Returns an Entity that represents the model
|
|
137180
|
+
* id: "myModel",
|
|
137181
|
+
* src: "House.bim",
|
|
137182
|
+
* edges: true
|
|
137183
|
+
* });
|
|
137184
|
+
*
|
|
137185
|
+
* // Find the model Entity by ID
|
|
137186
|
+
* model = viewer.scene.models["myModel"];
|
|
137187
|
+
*
|
|
137188
|
+
* // Destroy the model
|
|
137189
|
+
* model.destroy();
|
|
137190
|
+
* ````
|
|
137191
|
+
*
|
|
137192
|
+
* ## Transforming
|
|
137193
|
+
*
|
|
137194
|
+
* We have the option to rotate, scale and translate each *````.bim````* model as we load it.
|
|
137195
|
+
*
|
|
137196
|
+
* This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.
|
|
137197
|
+
*
|
|
137198
|
+
* In the example below, we'll rotate our model 90 degrees about its local X-axis, then
|
|
137199
|
+
* translate it 100 units along its X axis.
|
|
137200
|
+
*
|
|
137201
|
+
* ````javascript
|
|
137202
|
+
* const model = dotBIMLoader.load({
|
|
137203
|
+
* src: "House.bim",
|
|
137204
|
+
* rotation: [90,0,0],
|
|
137205
|
+
* position: [100, 0, 0]
|
|
137206
|
+
* });
|
|
137207
|
+
* ````
|
|
137208
|
+
*
|
|
137209
|
+
* ## Including and excluding IFC types
|
|
137210
|
+
*
|
|
137211
|
+
* We can also load only those objects that have the specified IFC types. In the example below, we'll load only the
|
|
137212
|
+
* objects that represent walls.
|
|
137213
|
+
*
|
|
137214
|
+
* ````javascript
|
|
137215
|
+
* const model = dotBIMLoader.load({
|
|
137216
|
+
* id: "myModel",
|
|
137217
|
+
* src: "House.bim",
|
|
137218
|
+
* includeTypes: ["IfcWallStandardCase"]
|
|
137219
|
+
* });
|
|
137220
|
+
* ````
|
|
137221
|
+
*
|
|
137222
|
+
* We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the
|
|
137223
|
+
* objects that do not represent empty space.
|
|
137224
|
+
*
|
|
137225
|
+
* ````javascript
|
|
137226
|
+
* const model = dotBIMLoader.load({
|
|
137227
|
+
* id: "myModel",
|
|
137228
|
+
* src: "House.bim",
|
|
137229
|
+
* excludeTypes: ["IfcSpace"]
|
|
137230
|
+
* });
|
|
137231
|
+
* ````
|
|
137232
|
+
*
|
|
137233
|
+
* # Configuring initial IFC object appearances
|
|
137234
|
+
*
|
|
137235
|
+
* We can specify the custom initial appearance of loaded objects according to their IFC types.
|
|
137236
|
+
*
|
|
137237
|
+
* This is useful for things like:
|
|
137238
|
+
*
|
|
137239
|
+
* * setting the colors to our objects according to their IFC types,
|
|
137240
|
+
* * automatically hiding ````IfcSpace```` objects, and
|
|
137241
|
+
* * ensuring that ````IfcWindow```` objects are always transparent.
|
|
137242
|
+
* <br>
|
|
137243
|
+
* In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,
|
|
137244
|
+
* and ````IfcWindow```` types to be always translucent blue.
|
|
137245
|
+
*
|
|
137246
|
+
* ````javascript
|
|
137247
|
+
* const myObjectDefaults = {
|
|
137248
|
+
*
|
|
137249
|
+
* IfcSpace: {
|
|
137250
|
+
* visible: false
|
|
137251
|
+
* },
|
|
137252
|
+
* IfcWindow: {
|
|
137253
|
+
* colorize: [0.337255, 0.303922, 0.870588], // Blue
|
|
137254
|
+
* opacity: 0.3
|
|
137255
|
+
* },
|
|
137256
|
+
*
|
|
137257
|
+
* //...
|
|
137258
|
+
*
|
|
137259
|
+
* DEFAULT: {
|
|
137260
|
+
* colorize: [0.5, 0.5, 0.5]
|
|
137261
|
+
* }
|
|
137262
|
+
* };
|
|
137263
|
+
*
|
|
137264
|
+
* const model4 = dotBIMLoader.load({
|
|
137265
|
+
* id: "myModel4",
|
|
137266
|
+
* src: "House.bim",
|
|
137267
|
+
* objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities
|
|
137268
|
+
* });
|
|
137269
|
+
* ````
|
|
137270
|
+
*
|
|
137271
|
+
* When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other
|
|
137272
|
+
* elements, which can be confusing.
|
|
137273
|
+
*
|
|
137274
|
+
* It's often helpful to make IfcSpaces transparent and unpickable, like this:
|
|
137275
|
+
*
|
|
137276
|
+
* ````javascript
|
|
137277
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
|
|
137278
|
+
* objectDefaults: {
|
|
137279
|
+
* IfcSpace: {
|
|
137280
|
+
* pickable: false,
|
|
137281
|
+
* opacity: 0.2
|
|
137282
|
+
* }
|
|
137283
|
+
* }
|
|
137284
|
+
* });
|
|
137285
|
+
* ````
|
|
137286
|
+
*
|
|
137287
|
+
* Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:
|
|
137288
|
+
*
|
|
137289
|
+
* ````javascript
|
|
137290
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
|
|
137291
|
+
* objectDefaults: {
|
|
137292
|
+
* IfcSpace: {
|
|
137293
|
+
* visible: false
|
|
137294
|
+
* }
|
|
137295
|
+
* }
|
|
137296
|
+
* });
|
|
137297
|
+
* ````
|
|
137298
|
+
*
|
|
137299
|
+
* # Configuring a custom data source
|
|
137300
|
+
*
|
|
137301
|
+
* By default, DotBIMLoaderPlugin will load *````.bim````* files and metadata JSON over HTTP.
|
|
137302
|
+
*
|
|
137303
|
+
* In the example below, we'll customize the way DotBIMLoaderPlugin loads the files by configuring it with our own data source
|
|
137304
|
+
* object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.
|
|
137305
|
+
*
|
|
137306
|
+
* ````javascript
|
|
137307
|
+
* import {utils} from "xeokit-sdk.es.js";
|
|
137308
|
+
*
|
|
137309
|
+
* class MyDataSource {
|
|
137310
|
+
*
|
|
137311
|
+
* constructor() {
|
|
137312
|
+
* }
|
|
137313
|
+
*
|
|
137314
|
+
* // Gets the contents of the given .bim file in a JSON object
|
|
137315
|
+
* getDotBIM(src, ok, error) {
|
|
137316
|
+
* utils.loadJSON(dotBIMSrc,
|
|
137317
|
+
* (json) => {
|
|
137318
|
+
* ok(json);
|
|
137319
|
+
* },
|
|
137320
|
+
* function (errMsg) {
|
|
137321
|
+
* error(errMsg);
|
|
137322
|
+
* });
|
|
137323
|
+
* }
|
|
137324
|
+
* }
|
|
137325
|
+
*
|
|
137326
|
+
* const dotBIMLoader2 = new DotBIMLoaderPlugin(viewer, {
|
|
137327
|
+
* dataSource: new MyDataSource()
|
|
137328
|
+
* });
|
|
137329
|
+
*
|
|
137330
|
+
* const model5 = dotBIMLoader2.load({
|
|
137331
|
+
* id: "myModel5",
|
|
137332
|
+
* src: "House.bim"
|
|
137333
|
+
* });
|
|
137334
|
+
* ````
|
|
137335
|
+
* @class DotBIMLoaderPlugin
|
|
137336
|
+
*/
|
|
137337
|
+
class DotBIMLoaderPlugin extends Plugin {
|
|
137338
|
+
|
|
137339
|
+
/**
|
|
137340
|
+
* @constructor
|
|
137341
|
+
*
|
|
137342
|
+
* @param {Viewer} viewer The Viewer.
|
|
137343
|
+
* @param {Object} cfg Plugin configuration.
|
|
137344
|
+
* @param {String} [cfg.id="DotBIMLoader"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
|
|
137345
|
+
* @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
|
|
137346
|
+
* @param {Object} [cfg.dataSource] A custom data source through which the DotBIMLoaderPlugin can load metadata, glTF and binary attachments. Defaults to an instance of {@link DotBIMDefaultDataSource}, which loads over HTTP.
|
|
137347
|
+
*/
|
|
137348
|
+
constructor(viewer, cfg = {}) {
|
|
137349
|
+
|
|
137350
|
+
super("DotBIMLoader", viewer, cfg);
|
|
137351
|
+
|
|
137352
|
+
this.dataSource = cfg.dataSource;
|
|
137353
|
+
this.objectDefaults = cfg.objectDefaults;
|
|
137354
|
+
}
|
|
137355
|
+
|
|
137356
|
+
/**
|
|
137357
|
+
* Sets a custom data source through which the DotBIMLoaderPlugin can .BIM files.
|
|
137358
|
+
*
|
|
137359
|
+
* Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
|
|
137360
|
+
*
|
|
137361
|
+
* @type {Object}
|
|
137362
|
+
*/
|
|
137363
|
+
set dataSource(value) {
|
|
137364
|
+
this._dataSource = value || new DotBIMDefaultDataSource();
|
|
137365
|
+
}
|
|
137366
|
+
|
|
137367
|
+
/**
|
|
137368
|
+
* Gets the custom data source through which the DotBIMLoaderPlugin can load .BIM files.
|
|
137369
|
+
*
|
|
137370
|
+
* Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
|
|
137371
|
+
*
|
|
137372
|
+
* @type {Object}
|
|
137373
|
+
*/
|
|
137374
|
+
get dataSource() {
|
|
137375
|
+
return this._dataSource;
|
|
137376
|
+
}
|
|
137377
|
+
|
|
137378
|
+
/**
|
|
137379
|
+
* Sets map of initial default states for each loaded {@link Entity} that represents an object.
|
|
137380
|
+
*
|
|
137381
|
+
* Default value is {@link IFCObjectDefaults}.
|
|
137382
|
+
*
|
|
137383
|
+
* @type {{String: Object}}
|
|
137384
|
+
*/
|
|
137385
|
+
set objectDefaults(value) {
|
|
137386
|
+
this._objectDefaults = value || IFCObjectDefaults;
|
|
137387
|
+
}
|
|
137388
|
+
|
|
137389
|
+
/**
|
|
137390
|
+
* Gets map of initial default states for each loaded {@link Entity} that represents an object.
|
|
137391
|
+
*
|
|
137392
|
+
* Default value is {@link IFCObjectDefaults}.
|
|
137393
|
+
*
|
|
137394
|
+
* @type {{String: Object}}
|
|
137395
|
+
*/
|
|
137396
|
+
get objectDefaults() {
|
|
137397
|
+
return this._objectDefaults;
|
|
137398
|
+
}
|
|
137399
|
+
|
|
137400
|
+
/**
|
|
137401
|
+
* Loads a .BIM model from a file into this DotBIMLoaderPlugin's {@link Viewer}.
|
|
137402
|
+
*
|
|
137403
|
+
* @param {*} params Loading parameters.
|
|
137404
|
+
* @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.
|
|
137405
|
+
* @param {String} [params.src] Path to a .BIM file, as an alternative to the ````bim```` parameter.
|
|
137406
|
+
* @param {*} [params.bim] .BIM JSON, as an alternative to the ````src```` parameter.
|
|
137407
|
+
* @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
|
|
137408
|
+
* @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
|
|
137409
|
+
* @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
|
|
137410
|
+
* @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
|
|
137411
|
+
* @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
|
|
137412
|
+
* @param {Number[]} [params.scale=[1,1,1]] The model's scale.
|
|
137413
|
+
* @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, as Euler angles given in degrees, for each of the X, Y and Z axis.
|
|
137414
|
+
* @param {Boolean} [params.backfaces=true] When true, always show backfaces, even on objects for which the .BIM material is single-sided. When false, only show backfaces on geometries whenever the .BIM material is double-sided.
|
|
137415
|
+
* @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to
|
|
137416
|
+
* represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
|
|
137417
|
+
* to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
|
|
137418
|
+
* primitives. Only works while {@link DTX#enabled} is also ````true````.
|
|
137419
|
+
* @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}
|
|
137420
|
+
*/
|
|
137421
|
+
load(params = {}) {
|
|
137422
|
+
|
|
137423
|
+
if (params.id && this.viewer.scene.components[params.id]) {
|
|
137424
|
+
this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
|
|
137425
|
+
delete params.id;
|
|
137426
|
+
}
|
|
137427
|
+
|
|
137428
|
+
const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
|
|
137429
|
+
isModel: true,
|
|
137430
|
+
backfaces: params.backfaces,
|
|
137431
|
+
dtxEnabled: params.dtxEnabled,
|
|
137432
|
+
rotation: params.rotation,
|
|
137433
|
+
origin: params.origin
|
|
137434
|
+
}));
|
|
137435
|
+
|
|
137436
|
+
const modelId = sceneModel.id; // In case ID was auto-generated
|
|
137437
|
+
|
|
137438
|
+
if (!params.src && !params.dotBIM) {
|
|
137439
|
+
this.error("load() param expected: src or dotBIM");
|
|
137440
|
+
return sceneModel; // Return new empty model
|
|
137441
|
+
}
|
|
137442
|
+
|
|
137443
|
+
const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
|
|
137444
|
+
|
|
137445
|
+
let includeTypes;
|
|
137446
|
+
if (params.includeTypes) {
|
|
137447
|
+
includeTypes = {};
|
|
137448
|
+
for (let i = 0, len = params.includeTypes.length; i < len; i++) {
|
|
137449
|
+
includeTypes[params.includeTypes[i]] = true;
|
|
137450
|
+
}
|
|
137451
|
+
}
|
|
137452
|
+
|
|
137453
|
+
let excludeTypes;
|
|
137454
|
+
if (params.excludeTypes) {
|
|
137455
|
+
excludeTypes = {};
|
|
137456
|
+
if (!includeTypes) {
|
|
137457
|
+
includeTypes = {};
|
|
137458
|
+
}
|
|
137459
|
+
for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
|
|
137460
|
+
includeTypes[params.excludeTypes[i]] = true;
|
|
137461
|
+
}
|
|
137462
|
+
}
|
|
137463
|
+
|
|
137464
|
+
const parseDotBIM = (ctx) => {
|
|
137465
|
+
|
|
137466
|
+
const fileData = ctx.fileData;
|
|
137467
|
+
const sceneModel = ctx.sceneModel;
|
|
137468
|
+
|
|
137469
|
+
const dbMeshIndices = {};
|
|
137470
|
+
const dbMeshLoaded = {};
|
|
137471
|
+
|
|
137472
|
+
const ifcProjectId = math.createUUID();
|
|
137473
|
+
const ifcSiteId = math.createUUID();
|
|
137474
|
+
const ifcBuildingId = math.createUUID();
|
|
137475
|
+
const ifcBuildingStoryId = math.createUUID();
|
|
137476
|
+
|
|
137477
|
+
const metaModelData = {
|
|
137478
|
+
metaObjects: [
|
|
137479
|
+
{
|
|
137480
|
+
id: ifcProjectId,
|
|
137481
|
+
name: "IfcProject",
|
|
137482
|
+
type: "IfcProject",
|
|
137483
|
+
parent: null
|
|
137484
|
+
},
|
|
137485
|
+
{
|
|
137486
|
+
id: ifcSiteId,
|
|
137487
|
+
name: "IfcSite",
|
|
137488
|
+
type: "IfcSite",
|
|
137489
|
+
parent: ifcProjectId
|
|
137490
|
+
},
|
|
137491
|
+
{
|
|
137492
|
+
id: ifcBuildingId,
|
|
137493
|
+
name: "IfcBuilding",
|
|
137494
|
+
type: "IfcBuilding",
|
|
137495
|
+
parent: ifcSiteId
|
|
137496
|
+
},
|
|
137497
|
+
{
|
|
137498
|
+
id: ifcBuildingStoryId,
|
|
137499
|
+
name: "IfcBuildingStorey",
|
|
137500
|
+
type: "IfcBuildingStorey",
|
|
137501
|
+
parent: ifcBuildingId
|
|
137502
|
+
}
|
|
137503
|
+
],
|
|
137504
|
+
propertySets: []
|
|
137505
|
+
};
|
|
137506
|
+
|
|
137507
|
+
for (let i = 0, len = fileData.meshes.length; i < len; i++) {
|
|
137508
|
+
const dbMesh = fileData.meshes[i];
|
|
137509
|
+
dbMeshIndices[dbMesh.mesh_id] = i;
|
|
137510
|
+
}
|
|
137511
|
+
|
|
137512
|
+
const parseDBMesh = (dbMeshId) => {
|
|
137513
|
+
if (dbMeshLoaded[dbMeshId]) {
|
|
137514
|
+
return;
|
|
137515
|
+
}
|
|
137516
|
+
const dbMeshIndex = dbMeshIndices[dbMeshId];
|
|
137517
|
+
const dbMesh = fileData.meshes[dbMeshIndex];
|
|
137518
|
+
sceneModel.createGeometry({
|
|
137519
|
+
id: dbMeshId,
|
|
137520
|
+
primitive: "triangles",
|
|
137521
|
+
positions: dbMesh.coordinates,
|
|
137522
|
+
indices: dbMesh.indices
|
|
137523
|
+
});
|
|
137524
|
+
dbMeshLoaded[dbMeshId] = true;
|
|
137525
|
+
};
|
|
137526
|
+
|
|
137527
|
+
const dbElements = fileData.elements;
|
|
137528
|
+
for (let i = 0, len = dbElements.length; i < len; i++) {
|
|
137529
|
+
const element = dbElements[i];
|
|
137530
|
+
const elementType = element.type;
|
|
137531
|
+
if (excludeTypes && excludeTypes[elementType]) {
|
|
137532
|
+
continue;
|
|
137533
|
+
|
|
137534
|
+
}
|
|
137535
|
+
if (includeTypes && (!includeTypes[elementType])) {
|
|
137536
|
+
continue;
|
|
137537
|
+
}
|
|
137538
|
+
const info = element.info;
|
|
137539
|
+
const objectId =
|
|
137540
|
+
element.guid !== undefined
|
|
137541
|
+
? `${element.guid}`
|
|
137542
|
+
: (info !== undefined && info.id !== undefined
|
|
137543
|
+
? info.id
|
|
137544
|
+
: i);
|
|
137545
|
+
|
|
137546
|
+
const dbMeshId = element.mesh_id;
|
|
137547
|
+
|
|
137548
|
+
parseDBMesh(dbMeshId);
|
|
137549
|
+
|
|
137550
|
+
const meshId = `${objectId}-mesh`;
|
|
137551
|
+
const vector = element.vector;
|
|
137552
|
+
const rotation = element.rotation;
|
|
137553
|
+
const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
|
|
137554
|
+
|
|
137555
|
+
let visible = true;
|
|
137556
|
+
let pickable = true;
|
|
137557
|
+
let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
|
|
137558
|
+
let opacity = element.color ? element.color.a / 255 : 1.0;
|
|
137559
|
+
|
|
137560
|
+
if (props) {
|
|
137561
|
+
if (props.visible === false) {
|
|
137562
|
+
visible = false;
|
|
137563
|
+
}
|
|
137564
|
+
if (props.pickable === false) {
|
|
137565
|
+
pickable = false;
|
|
137566
|
+
}
|
|
137567
|
+
if (props.colorize) {
|
|
137568
|
+
color = props.colorize;
|
|
137569
|
+
}
|
|
137570
|
+
if (props.opacity !== undefined && props.opacity !== null) {
|
|
137571
|
+
opacity = props.opacity;
|
|
137572
|
+
}
|
|
137573
|
+
}
|
|
137574
|
+
|
|
137575
|
+
sceneModel.createMesh({
|
|
137576
|
+
id: meshId,
|
|
137577
|
+
geometryId: dbMeshId,
|
|
137578
|
+
color,
|
|
137579
|
+
opacity,
|
|
137580
|
+
quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
|
|
137581
|
+
position: vector ? [vector.x, vector.y, vector.z] : undefined
|
|
137582
|
+
});
|
|
137583
|
+
|
|
137584
|
+
sceneModel.createEntity({
|
|
137585
|
+
id: objectId,
|
|
137586
|
+
meshIds: [meshId],
|
|
137587
|
+
visible,
|
|
137588
|
+
pickable,
|
|
137589
|
+
isObject: true
|
|
137590
|
+
});
|
|
137591
|
+
|
|
137592
|
+
metaModelData.metaObjects.push({
|
|
137593
|
+
id: objectId,
|
|
137594
|
+
name: info && info.Name && info.Name !== "None" ? info.Name : `${element.type} ${objectId}`,
|
|
137595
|
+
type: element.type,
|
|
137596
|
+
parent: ifcBuildingStoryId
|
|
137597
|
+
});
|
|
137598
|
+
}
|
|
137599
|
+
|
|
137600
|
+
sceneModel.finalize();
|
|
137601
|
+
|
|
137602
|
+
this.viewer.metaScene.createMetaModel(modelId, metaModelData);
|
|
137603
|
+
|
|
137604
|
+
sceneModel.scene.once("tick", () => {
|
|
137605
|
+
if (sceneModel.destroyed) {
|
|
137606
|
+
return;
|
|
137607
|
+
}
|
|
137608
|
+
sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
|
|
137609
|
+
sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
|
|
137610
|
+
});
|
|
137611
|
+
};
|
|
137612
|
+
|
|
137613
|
+
if (params.src) {
|
|
137614
|
+
const src = params.src;
|
|
137615
|
+
this.viewer.scene.canvas.spinner.processes++;
|
|
137616
|
+
this._dataSource.getDotBIM(src, (fileData) => { // OK
|
|
137617
|
+
const ctx = {
|
|
137618
|
+
fileData,
|
|
137619
|
+
sceneModel,
|
|
137620
|
+
nextId: 0,
|
|
137621
|
+
error: function (errMsg) {
|
|
137622
|
+
}
|
|
137623
|
+
};
|
|
137624
|
+
parseDotBIM(ctx);
|
|
137625
|
+
this.viewer.scene.canvas.spinner.processes--;
|
|
137626
|
+
},
|
|
137627
|
+
(err) => {
|
|
137628
|
+
this.viewer.scene.canvas.spinner.processes--;
|
|
137629
|
+
this.error(err);
|
|
137630
|
+
});
|
|
137631
|
+
} else if (params.dotBIM) {
|
|
137632
|
+
const ctx = {
|
|
137633
|
+
fileData: params.dotBIM,
|
|
137634
|
+
sceneModel,
|
|
137635
|
+
nextId: 0,
|
|
137636
|
+
error: function (errMsg) {
|
|
137637
|
+
}
|
|
137638
|
+
};
|
|
137639
|
+
parseDotBIM(ctx);
|
|
137640
|
+
}
|
|
137641
|
+
|
|
137642
|
+
sceneModel.once("destroyed", () => {
|
|
137643
|
+
this.viewer.metaScene.destroyMetaModel(modelId);
|
|
137644
|
+
});
|
|
137645
|
+
|
|
137646
|
+
return sceneModel;
|
|
137647
|
+
}
|
|
137648
|
+
|
|
137649
|
+
/**
|
|
137650
|
+
* Destroys this DotBIMLoaderPlugin.
|
|
137651
|
+
*/
|
|
137652
|
+
destroy() {
|
|
137653
|
+
super.destroy();
|
|
137654
|
+
}
|
|
137655
|
+
}
|
|
137656
|
+
|
|
137657
|
+
export { AlphaFormat, AmbientLight, AngleMeasurementsControl, AngleMeasurementsMouseControl, AngleMeasurementsPlugin, AngleMeasurementsTouchControl, AnnotationsPlugin, AxisGizmoPlugin, BCFViewpointsPlugin, Bitmap, ByteType, CameraMemento, CameraPath, CameraPathAnimation, CityJSONLoaderPlugin, ClampToEdgeWrapping, Component, CompressedMediaType, Configs, ContextMenu, CubicBezierCurve, Curve, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DirLight, DistanceMeasurementsControl, DistanceMeasurementsMouseControl, DistanceMeasurementsPlugin, DistanceMeasurementsTouchControl, DotBIMDefaultDataSource, DotBIMLoaderPlugin, EdgeMaterial, EmphasisMaterial, FaceAlignedSectionPlanesPlugin, FastNavPlugin, FloatType, Fresnel, Frustum$1 as Frustum, FrustumPlane, GIFMediaType, GLTFDefaultDataSource, GLTFLoaderPlugin, HalfFloatType, ImagePlane, IntType, JPEGMediaType, KTX2TextureTranscoder, LASLoaderPlugin, LambertMaterial, LightMap, LineSet, LinearEncoding, LinearFilter, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, Loader, LoadingManager, LocaleService, LuminanceAlphaFormat, LuminanceFormat, Map$1 as Map, Marker, MarqueePicker, MarqueePickerMouseControl, Mesh, MetallicMaterial, MirroredRepeatWrapping, ModelMemento, NavCubePlugin, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, Node$2 as Node, OBJLoaderPlugin, ObjectsKdTree3, ObjectsMemento, PNGMediaType, Path, PerformanceModel, PhongMaterial, PickResult, Plugin, PointLight, PointerCircle, PointerLens, QuadraticBezierCurve, Queue, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, ReadableGeometry, RedFormat, RedIntegerFormat, ReflectionMap, RepeatWrapping, STLDefaultDataSource, STLLoaderPlugin, SceneModel, SceneModelMesh, SceneModelTransform, SectionPlane, SectionPlanesPlugin, ShortType, Skybox, SkyboxesPlugin, SpecularMaterial, SplineCurve, SpriteMarker, StoreyViewsPlugin, Texture, TextureTranscoder, TreeViewPlugin, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VBOGeometry, ViewCullPlugin, Viewer, WebIFCLoaderPlugin, WorkerPool$1 as WorkerPool, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, buildBoxGeometry, buildBoxLinesGeometry, buildBoxLinesGeometryFromAABB, buildCylinderGeometry, buildGridGeometry, buildPlaneGeometry, buildPolylineGeometry, buildPolylineGeometryFromCurve, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, createRTCViewMat, frustumIntersectsAABB3, getKTX2TextureTranscoder, getPlaneRTCPos, load3DSGeometry, loadOBJGeometry, math, rtcToWorldPos, sRGBEncoding, setFrustum, stats, utils, worldToRTCPos, worldToRTCPositions };
|