@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.cjs.js
CHANGED
|
@@ -10460,7 +10460,7 @@ const tempVec4b$6 = math.vec4();
|
|
|
10460
10460
|
* });
|
|
10461
10461
|
*
|
|
10462
10462
|
* // Create the Marker, associated with our Mesh Entity
|
|
10463
|
-
* const myMarker = new Marker({
|
|
10463
|
+
* const myMarker = new Marker(viewer, {
|
|
10464
10464
|
* entity: entity,
|
|
10465
10465
|
* worldPos: [10,0,0],
|
|
10466
10466
|
* occludable: true
|
|
@@ -10589,7 +10589,7 @@ class Marker extends Component {
|
|
|
10589
10589
|
return;
|
|
10590
10590
|
}
|
|
10591
10591
|
if (this._onEntityDestroyed !== null) {
|
|
10592
|
-
this._entity.off(this._onEntityDestroyed);
|
|
10592
|
+
this._entity.model.off(this._onEntityDestroyed);
|
|
10593
10593
|
this._onEntityDestroyed = null;
|
|
10594
10594
|
}
|
|
10595
10595
|
if (this._onEntityModelDestroyed !== null) {
|
|
@@ -10605,7 +10605,7 @@ class Marker extends Component {
|
|
|
10605
10605
|
this._onEntityModelDestroyed = null;
|
|
10606
10606
|
});
|
|
10607
10607
|
} else {
|
|
10608
|
-
this._onEntityDestroyed = this._entity.on("destroyed", () => {
|
|
10608
|
+
this._onEntityDestroyed = this._entity.model.on("destroyed", () => {
|
|
10609
10609
|
this._entity = null;
|
|
10610
10610
|
this._onEntityDestroyed = null;
|
|
10611
10611
|
});
|
|
@@ -10771,6 +10771,16 @@ class Marker extends Component {
|
|
|
10771
10771
|
}
|
|
10772
10772
|
}
|
|
10773
10773
|
|
|
10774
|
+
const os = {
|
|
10775
|
+
isIphoneSafari() {
|
|
10776
|
+
const userAgent = window.navigator.userAgent;
|
|
10777
|
+
const isIphone = /iPhone/i.test(userAgent);
|
|
10778
|
+
const isSafari = /Safari/i.test(userAgent) && !/Chrome/i.test(userAgent);
|
|
10779
|
+
|
|
10780
|
+
return isIphone && isSafari;
|
|
10781
|
+
}
|
|
10782
|
+
};
|
|
10783
|
+
|
|
10774
10784
|
/** @private */
|
|
10775
10785
|
class Wire {
|
|
10776
10786
|
|
|
@@ -10883,11 +10893,42 @@ class Wire {
|
|
|
10883
10893
|
}
|
|
10884
10894
|
|
|
10885
10895
|
if (cfg.onContextMenu) {
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10896
|
+
if(os.isIphoneSafari()){
|
|
10897
|
+
wireClickable.addEventListener('touchstart', (event) => {
|
|
10898
|
+
event.preventDefault();
|
|
10899
|
+
if(this._timeout){
|
|
10900
|
+
clearTimeout(this._timeout);
|
|
10901
|
+
this._timeout = null;
|
|
10902
|
+
}
|
|
10903
|
+
this._timeout = setTimeout(() => {
|
|
10904
|
+
event.clientX = event.touches[0].clientX;
|
|
10905
|
+
event.clientY = event.touches[0].clientY;
|
|
10906
|
+
cfg.onContextMenu(event, this);
|
|
10907
|
+
clearTimeout(this._timeout);
|
|
10908
|
+
this._timeout = null;
|
|
10909
|
+
}, 500);
|
|
10910
|
+
});
|
|
10911
|
+
|
|
10912
|
+
wireClickable.addEventListener('touchend', (event) => {
|
|
10913
|
+
event.preventDefault();
|
|
10914
|
+
//stops short touches from calling the timeout
|
|
10915
|
+
if(this._timeout) {
|
|
10916
|
+
clearTimeout(this._timeout);
|
|
10917
|
+
this._timeout = null;
|
|
10918
|
+
}
|
|
10919
|
+
} );
|
|
10920
|
+
|
|
10921
|
+
}
|
|
10922
|
+
else {
|
|
10923
|
+
wireClickable.addEventListener('contextmenu', (event) => {
|
|
10924
|
+
console.log(event);
|
|
10925
|
+
cfg.onContextMenu(event, this);
|
|
10926
|
+
event.preventDefault();
|
|
10927
|
+
event.stopPropagation();
|
|
10928
|
+
console.log("Label context menu");
|
|
10929
|
+
});
|
|
10930
|
+
}
|
|
10931
|
+
|
|
10891
10932
|
}
|
|
10892
10933
|
|
|
10893
10934
|
this._x1 = 0;
|
|
@@ -10962,7 +11003,7 @@ class Wire {
|
|
|
10962
11003
|
}
|
|
10963
11004
|
|
|
10964
11005
|
setClickable(clickable) {
|
|
10965
|
-
this._wireClickable.style["pointer-events"] = (
|
|
11006
|
+
this._wireClickable.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
10966
11007
|
}
|
|
10967
11008
|
|
|
10968
11009
|
setHighlighted(highlighted) {
|
|
@@ -11082,11 +11123,42 @@ class Dot {
|
|
|
11082
11123
|
}
|
|
11083
11124
|
|
|
11084
11125
|
if (cfg.onContextMenu) {
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11126
|
+
if(os.isIphoneSafari()){
|
|
11127
|
+
dotClickable.addEventListener('touchstart', (event) => {
|
|
11128
|
+
event.preventDefault();
|
|
11129
|
+
if(this._timeout){
|
|
11130
|
+
clearTimeout(this._timeout);
|
|
11131
|
+
this._timeout = null;
|
|
11132
|
+
}
|
|
11133
|
+
this._timeout = setTimeout(() => {
|
|
11134
|
+
event.clientX = event.touches[0].clientX;
|
|
11135
|
+
event.clientY = event.touches[0].clientY;
|
|
11136
|
+
cfg.onContextMenu(event, this);
|
|
11137
|
+
clearTimeout(this._timeout);
|
|
11138
|
+
this._timeout = null;
|
|
11139
|
+
}, 500);
|
|
11140
|
+
});
|
|
11141
|
+
|
|
11142
|
+
dotClickable.addEventListener('touchend', (event) => {
|
|
11143
|
+
event.preventDefault();
|
|
11144
|
+
//stops short touches from calling the timeout
|
|
11145
|
+
if(this._timeout) {
|
|
11146
|
+
clearTimeout(this._timeout);
|
|
11147
|
+
this._timeout = null;
|
|
11148
|
+
}
|
|
11149
|
+
} );
|
|
11150
|
+
|
|
11151
|
+
}
|
|
11152
|
+
else {
|
|
11153
|
+
dotClickable.addEventListener('contextmenu', (event) => {
|
|
11154
|
+
console.log(event);
|
|
11155
|
+
cfg.onContextMenu(event, this);
|
|
11156
|
+
event.preventDefault();
|
|
11157
|
+
event.stopPropagation();
|
|
11158
|
+
console.log("Label context menu");
|
|
11159
|
+
});
|
|
11160
|
+
}
|
|
11161
|
+
|
|
11090
11162
|
}
|
|
11091
11163
|
|
|
11092
11164
|
this.setPos(cfg.x || 0, cfg.y || 0);
|
|
@@ -11135,7 +11207,7 @@ class Dot {
|
|
|
11135
11207
|
}
|
|
11136
11208
|
|
|
11137
11209
|
setClickable(clickable) {
|
|
11138
|
-
this._dotClickable.style["pointer-events"] = (
|
|
11210
|
+
this._dotClickable.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
11139
11211
|
}
|
|
11140
11212
|
|
|
11141
11213
|
setHighlighted(highlighted) {
|
|
@@ -11176,6 +11248,7 @@ class Label {
|
|
|
11176
11248
|
|
|
11177
11249
|
this._label = document.createElement('div');
|
|
11178
11250
|
this._label.className += this._label.className ? ' viewer-ruler-label' : 'viewer-ruler-label';
|
|
11251
|
+
this._timeout = null;
|
|
11179
11252
|
|
|
11180
11253
|
var label = this._label;
|
|
11181
11254
|
var style = label.style;
|
|
@@ -11245,12 +11318,42 @@ class Label {
|
|
|
11245
11318
|
}
|
|
11246
11319
|
|
|
11247
11320
|
if (cfg.onContextMenu) {
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
|
|
11252
|
-
|
|
11253
|
-
|
|
11321
|
+
if(os.isIphoneSafari()){
|
|
11322
|
+
label.addEventListener('touchstart', (event) => {
|
|
11323
|
+
event.preventDefault();
|
|
11324
|
+
if(this._timeout){
|
|
11325
|
+
clearTimeout(this._timeout);
|
|
11326
|
+
this._timeout = null;
|
|
11327
|
+
}
|
|
11328
|
+
this._timeout = setTimeout(() => {
|
|
11329
|
+
event.clientX = event.touches[0].clientX;
|
|
11330
|
+
event.clientY = event.touches[0].clientY;
|
|
11331
|
+
cfg.onContextMenu(event, this);
|
|
11332
|
+
clearTimeout(this._timeout);
|
|
11333
|
+
this._timeout = null;
|
|
11334
|
+
}, 500);
|
|
11335
|
+
});
|
|
11336
|
+
|
|
11337
|
+
label.addEventListener('touchend', (event) => {
|
|
11338
|
+
event.preventDefault();
|
|
11339
|
+
//stops short touches from calling the timeout
|
|
11340
|
+
if(this._timeout) {
|
|
11341
|
+
clearTimeout(this._timeout);
|
|
11342
|
+
this._timeout = null;
|
|
11343
|
+
}
|
|
11344
|
+
} );
|
|
11345
|
+
|
|
11346
|
+
}
|
|
11347
|
+
else {
|
|
11348
|
+
label.addEventListener('contextmenu', (event) => {
|
|
11349
|
+
console.log(event);
|
|
11350
|
+
cfg.onContextMenu(event, this);
|
|
11351
|
+
event.preventDefault();
|
|
11352
|
+
event.stopPropagation();
|
|
11353
|
+
console.log("Label context menu");
|
|
11354
|
+
});
|
|
11355
|
+
}
|
|
11356
|
+
|
|
11254
11357
|
}
|
|
11255
11358
|
}
|
|
11256
11359
|
|
|
@@ -11325,7 +11428,14 @@ class Label {
|
|
|
11325
11428
|
}
|
|
11326
11429
|
|
|
11327
11430
|
setClickable(clickable) {
|
|
11328
|
-
this._label.style["pointer-events"] = (
|
|
11431
|
+
this._label.style["pointer-events"] = (clickable) ? "all" : "none";
|
|
11432
|
+
}
|
|
11433
|
+
|
|
11434
|
+
setPrefix(prefix) {
|
|
11435
|
+
if(this._prefix === prefix){
|
|
11436
|
+
return;
|
|
11437
|
+
}
|
|
11438
|
+
this._prefix = prefix;
|
|
11329
11439
|
}
|
|
11330
11440
|
|
|
11331
11441
|
destroy() {
|
|
@@ -11333,6 +11443,8 @@ class Label {
|
|
|
11333
11443
|
this._label.parentElement.removeChild(this._label);
|
|
11334
11444
|
}
|
|
11335
11445
|
}
|
|
11446
|
+
|
|
11447
|
+
|
|
11336
11448
|
}
|
|
11337
11449
|
|
|
11338
11450
|
var originVec = math.vec3();
|
|
@@ -12130,6 +12242,16 @@ class AngleMeasurementsControl extends Component {
|
|
|
12130
12242
|
reset() {
|
|
12131
12243
|
}
|
|
12132
12244
|
|
|
12245
|
+
/**
|
|
12246
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsControl, if any.
|
|
12247
|
+
*
|
|
12248
|
+
* @returns {null|AngleMeasurement}
|
|
12249
|
+
* @abstract
|
|
12250
|
+
*/
|
|
12251
|
+
get currentMeasurement() {
|
|
12252
|
+
return null;
|
|
12253
|
+
}
|
|
12254
|
+
|
|
12133
12255
|
/**
|
|
12134
12256
|
* Destroys this AngleMeasurementsMouseControl.
|
|
12135
12257
|
*
|
|
@@ -12580,6 +12702,15 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
12580
12702
|
this._mouseState = MOUSE_FINDING_ORIGIN;
|
|
12581
12703
|
}
|
|
12582
12704
|
|
|
12705
|
+
/**
|
|
12706
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsMouseControl, if any.
|
|
12707
|
+
*
|
|
12708
|
+
* @returns {null|AngleMeasurement}
|
|
12709
|
+
*/
|
|
12710
|
+
get currentMeasurement() {
|
|
12711
|
+
return this._currentAngleMeasurement;
|
|
12712
|
+
}
|
|
12713
|
+
|
|
12583
12714
|
/**
|
|
12584
12715
|
* Destroys this AngleMeasurementsMouseControl.
|
|
12585
12716
|
*/
|
|
@@ -13933,6 +14064,15 @@ class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
|
|
|
13933
14064
|
}
|
|
13934
14065
|
}
|
|
13935
14066
|
|
|
14067
|
+
/**
|
|
14068
|
+
* Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsTouchControl, if any.
|
|
14069
|
+
*
|
|
14070
|
+
* @returns {null|AngleMeasurement}
|
|
14071
|
+
*/
|
|
14072
|
+
get currentMeasurement() {
|
|
14073
|
+
return this._currentAngleMeasurement;
|
|
14074
|
+
}
|
|
14075
|
+
|
|
13936
14076
|
/**
|
|
13937
14077
|
* Destroys this AngleMeasurementsTouchControl.
|
|
13938
14078
|
*/
|
|
@@ -81028,10 +81168,11 @@ class SceneModelTransform {
|
|
|
81028
81168
|
const tempVec3a$a = math.vec3();
|
|
81029
81169
|
|
|
81030
81170
|
const tempOBB3 = math.OBB3();
|
|
81171
|
+
const tempQuaternion = math.vec4();
|
|
81031
81172
|
|
|
81032
81173
|
const DEFAULT_SCALE = math.vec3([1, 1, 1]);
|
|
81033
81174
|
const DEFAULT_POSITION = math.vec3([0, 0, 0]);
|
|
81034
|
-
|
|
81175
|
+
math.vec3([0, 0, 0]);
|
|
81035
81176
|
const DEFAULT_QUATERNION = math.identityQuaternion();
|
|
81036
81177
|
const DEFAULT_MATRIX = math.identityMat4();
|
|
81037
81178
|
|
|
@@ -83708,6 +83849,7 @@ class SceneModel extends Component {
|
|
|
83708
83849
|
* @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.
|
|
83709
83850
|
* @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh. Overridden by ````transformId````.
|
|
83710
83851
|
* @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````.
|
|
83852
|
+
* @param {Number[]} [cfg.quaternion] Rotation of the mesh as a quaternion. Overridden by ````rotation````.
|
|
83711
83853
|
* @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````.
|
|
83712
83854
|
* @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````.
|
|
83713
83855
|
* @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.
|
|
@@ -83782,12 +83924,15 @@ class SceneModel extends Component {
|
|
|
83782
83924
|
|
|
83783
83925
|
if (cfg.matrix) {
|
|
83784
83926
|
cfg.meshMatrix = cfg.matrix;
|
|
83785
|
-
} else if (cfg.scale || cfg.rotation || cfg.position) {
|
|
83927
|
+
} else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
|
|
83786
83928
|
const scale = cfg.scale || DEFAULT_SCALE;
|
|
83787
83929
|
const position = cfg.position || DEFAULT_POSITION;
|
|
83788
|
-
|
|
83789
|
-
|
|
83790
|
-
|
|
83930
|
+
if (cfg.rotation) {
|
|
83931
|
+
math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
|
|
83932
|
+
cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
|
|
83933
|
+
} else {
|
|
83934
|
+
cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
|
|
83935
|
+
}
|
|
83791
83936
|
}
|
|
83792
83937
|
|
|
83793
83938
|
if (cfg.positionsDecodeBoundary) {
|
|
@@ -83975,13 +84120,16 @@ class SceneModel extends Component {
|
|
|
83975
84120
|
// MATRIX
|
|
83976
84121
|
|
|
83977
84122
|
if (cfg.matrix) {
|
|
83978
|
-
cfg.meshMatrix = cfg.matrix
|
|
83979
|
-
} else {
|
|
84123
|
+
cfg.meshMatrix = cfg.matrix;
|
|
84124
|
+
} else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
|
|
83980
84125
|
const scale = cfg.scale || DEFAULT_SCALE;
|
|
83981
84126
|
const position = cfg.position || DEFAULT_POSITION;
|
|
83982
|
-
|
|
83983
|
-
|
|
83984
|
-
|
|
84127
|
+
if (cfg.rotation) {
|
|
84128
|
+
math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
|
|
84129
|
+
cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
|
|
84130
|
+
} else {
|
|
84131
|
+
cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
|
|
84132
|
+
}
|
|
83985
84133
|
}
|
|
83986
84134
|
|
|
83987
84135
|
math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);
|
|
@@ -86134,6 +86282,14 @@ const lengthWire = (x1, y1, x2, y2) => {
|
|
|
86134
86282
|
return Math.sqrt(a * a + b * b);
|
|
86135
86283
|
};
|
|
86136
86284
|
|
|
86285
|
+
function determineMeasurementOrientation(A, B, distance) {
|
|
86286
|
+
const yDiff = Math.abs(B[1] - A[1]);
|
|
86287
|
+
|
|
86288
|
+
return yDiff > distance ? 'Vertical' : 'Horizontal';
|
|
86289
|
+
}
|
|
86290
|
+
|
|
86291
|
+
// function findDistance
|
|
86292
|
+
|
|
86137
86293
|
/**
|
|
86138
86294
|
* @desc Measures the distance between two 3D points.
|
|
86139
86295
|
*
|
|
@@ -86162,17 +86318,16 @@ class DistanceMeasurement extends Component {
|
|
|
86162
86318
|
this._eventSubs = {};
|
|
86163
86319
|
|
|
86164
86320
|
var scene = this.plugin.viewer.scene;
|
|
86165
|
-
|
|
86166
86321
|
this._originMarker = new Marker(scene, cfg.origin);
|
|
86167
86322
|
this._targetMarker = new Marker(scene, cfg.target);
|
|
86168
86323
|
|
|
86169
86324
|
this._originWorld = math.vec3();
|
|
86170
86325
|
this._targetWorld = math.vec3();
|
|
86171
86326
|
|
|
86172
|
-
this._wp = new Float64Array(24);
|
|
86173
|
-
this._vp = new Float64Array(24);
|
|
86327
|
+
this._wp = new Float64Array(24); //world position
|
|
86328
|
+
this._vp = new Float64Array(24); //view position
|
|
86174
86329
|
this._pp = new Float64Array(24);
|
|
86175
|
-
this._cp = new Float64Array(8);
|
|
86330
|
+
this._cp = new Float64Array(8); //canvas position
|
|
86176
86331
|
|
|
86177
86332
|
this._xAxisLabelCulled = false;
|
|
86178
86333
|
this._yAxisLabelCulled = false;
|
|
@@ -86346,6 +86501,7 @@ class DistanceMeasurement extends Component {
|
|
|
86346
86501
|
onContextMenu
|
|
86347
86502
|
});
|
|
86348
86503
|
|
|
86504
|
+
this._measurementOrientation = 'Horizontal';
|
|
86349
86505
|
this._wpDirty = false;
|
|
86350
86506
|
this._vpDirty = false;
|
|
86351
86507
|
this._cpDirty = false;
|
|
@@ -86360,18 +86516,22 @@ class DistanceMeasurement extends Component {
|
|
|
86360
86516
|
this._yAxisVisible = false;
|
|
86361
86517
|
this._zAxisVisible = false;
|
|
86362
86518
|
this._axisEnabled = true;
|
|
86519
|
+
this._xLabelEnabled = false;
|
|
86520
|
+
this._yLabelEnabled = false;
|
|
86521
|
+
this._zLabelEnabled = false;
|
|
86522
|
+
this._lengthLabelEnabled = false;
|
|
86363
86523
|
this._labelsVisible = false;
|
|
86364
86524
|
this._labelsOnWires = false;
|
|
86365
86525
|
this._clickable = false;
|
|
86366
86526
|
|
|
86367
86527
|
this._originMarker.on("worldPos", (value) => {
|
|
86368
|
-
this._originWorld.set(value || [0,
|
|
86528
|
+
this._originWorld.set(value || [0,0,0]);
|
|
86369
86529
|
this._wpDirty = true;
|
|
86370
86530
|
this._needUpdate(0); // No lag
|
|
86371
86531
|
});
|
|
86372
86532
|
|
|
86373
86533
|
this._targetMarker.on("worldPos", (value) => {
|
|
86374
|
-
this._targetWorld.set(value || [0,
|
|
86534
|
+
this._targetWorld.set(value || [0,0,0]);
|
|
86375
86535
|
this._wpDirty = true;
|
|
86376
86536
|
this._needUpdate(0); // No lag
|
|
86377
86537
|
});
|
|
@@ -86420,6 +86580,10 @@ class DistanceMeasurement extends Component {
|
|
|
86420
86580
|
this.xAxisVisible = cfg.xAxisVisible;
|
|
86421
86581
|
this.yAxisVisible = cfg.yAxisVisible;
|
|
86422
86582
|
this.zAxisVisible = cfg.zAxisVisible;
|
|
86583
|
+
this.xLabelEnabled = cfg.xLabelEnabled;
|
|
86584
|
+
this.yLabelEnabled = cfg.yLabelEnabled;
|
|
86585
|
+
this.zLabelEnabled = cfg.zLabelEnabled;
|
|
86586
|
+
this.lengthLabelEnabled = cfg.lengthLabelEnabled;
|
|
86423
86587
|
this.labelsVisible = cfg.labelsVisible;
|
|
86424
86588
|
this.labelsOnWires = cfg.labelsOnWires;
|
|
86425
86589
|
}
|
|
@@ -86434,25 +86598,50 @@ class DistanceMeasurement extends Component {
|
|
|
86434
86598
|
|
|
86435
86599
|
if (this._wpDirty) {
|
|
86436
86600
|
|
|
86437
|
-
this.
|
|
86438
|
-
this.
|
|
86439
|
-
|
|
86440
|
-
|
|
86601
|
+
this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 1);
|
|
86602
|
+
if(this._measurementOrientation === 'Vertical'){
|
|
86603
|
+
this._wp[0] = this._originWorld[0];
|
|
86604
|
+
this._wp[1] = this._originWorld[1];
|
|
86605
|
+
this._wp[2] = this._originWorld[2];
|
|
86606
|
+
this._wp[3] = 1.0;
|
|
86441
86607
|
|
|
86442
|
-
|
|
86443
|
-
|
|
86444
|
-
|
|
86445
|
-
|
|
86608
|
+
this._wp[4] = this._originWorld[0]; //x-axis
|
|
86609
|
+
this._wp[5] = this._originWorld[1];
|
|
86610
|
+
this._wp[6] = this._originWorld[2];
|
|
86611
|
+
this._wp[7] = 1.0;
|
|
86446
86612
|
|
|
86447
|
-
|
|
86448
|
-
|
|
86449
|
-
|
|
86450
|
-
|
|
86613
|
+
this._wp[8] = this._originWorld[0]; //x-axis
|
|
86614
|
+
this._wp[9] = this._targetWorld[1]; //y-axis
|
|
86615
|
+
this._wp[10] = this._originWorld[2];
|
|
86616
|
+
this._wp[11] = 1.0;
|
|
86451
86617
|
|
|
86452
|
-
|
|
86453
|
-
|
|
86454
|
-
|
|
86455
|
-
|
|
86618
|
+
this._wp[12] = this._targetWorld[0];
|
|
86619
|
+
this._wp[13] = this._targetWorld[1];
|
|
86620
|
+
this._wp[14] = this._targetWorld[2];
|
|
86621
|
+
this._wp[15] = 1.0;
|
|
86622
|
+
}
|
|
86623
|
+
else {
|
|
86624
|
+
this._wp[0] = this._originWorld[0];
|
|
86625
|
+
this._wp[1] = this._originWorld[1];
|
|
86626
|
+
this._wp[2] = this._originWorld[2];
|
|
86627
|
+
this._wp[3] = 1.0;
|
|
86628
|
+
|
|
86629
|
+
this._wp[4] = this._targetWorld[0];
|
|
86630
|
+
this._wp[5] = this._originWorld[1];
|
|
86631
|
+
this._wp[6] = this._originWorld[2];
|
|
86632
|
+
this._wp[7] = 1.0;
|
|
86633
|
+
|
|
86634
|
+
this._wp[8] = this._targetWorld[0];
|
|
86635
|
+
this._wp[9] = this._targetWorld[1];
|
|
86636
|
+
this._wp[10] = this._originWorld[2];
|
|
86637
|
+
this._wp[11] = 1.0;
|
|
86638
|
+
|
|
86639
|
+
this._wp[12] = this._targetWorld[0];
|
|
86640
|
+
this._wp[13] = this._targetWorld[1];
|
|
86641
|
+
this._wp[14] = this._targetWorld[2];
|
|
86642
|
+
this._wp[15] = 1.0;
|
|
86643
|
+
}
|
|
86644
|
+
|
|
86456
86645
|
|
|
86457
86646
|
this._wpDirty = false;
|
|
86458
86647
|
this._vpDirty = true;
|
|
@@ -86623,7 +86812,14 @@ class DistanceMeasurement extends Component {
|
|
|
86623
86812
|
}
|
|
86624
86813
|
|
|
86625
86814
|
if (!this._zAxisLabelCulled) {
|
|
86626
|
-
|
|
86815
|
+
if(this._measurementOrientation === 'Vertical') {
|
|
86816
|
+
this._zAxisLabel.setPrefix("");
|
|
86817
|
+
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);
|
|
86818
|
+
}
|
|
86819
|
+
else {
|
|
86820
|
+
this._zAxisLabel.setPrefix("Z");
|
|
86821
|
+
this._zAxisLabel.setText(tilde + Math.abs((this._targetWorld[2] - this._originWorld[2]) * scale).toFixed(2) + unitAbbrev);
|
|
86822
|
+
}
|
|
86627
86823
|
this._zAxisLabel.setCulled(!this.axisVisible);
|
|
86628
86824
|
} else {
|
|
86629
86825
|
this._zAxisLabel.setCulled(true);
|
|
@@ -86743,7 +86939,7 @@ class DistanceMeasurement extends Component {
|
|
|
86743
86939
|
this._originDot.setVisible(this._visible && this._originVisible);
|
|
86744
86940
|
this._targetDot.setVisible(this._visible && this._targetVisible);
|
|
86745
86941
|
this._lengthWire.setVisible(this._visible && this._wireVisible);
|
|
86746
|
-
this._lengthLabel.setVisible(this._visible && this._wireVisible);
|
|
86942
|
+
this._lengthLabel.setVisible(this._visible && this._wireVisible && this._lengthLabelEnabled);
|
|
86747
86943
|
|
|
86748
86944
|
const xAxisVisible = this._visible && this._axisVisible && this._xAxisVisible;
|
|
86749
86945
|
const yAxisVisible = this._visible && this._axisVisible && this._yAxisVisible;
|
|
@@ -86753,9 +86949,9 @@ class DistanceMeasurement extends Component {
|
|
|
86753
86949
|
this._yAxisWire.setVisible(yAxisVisible);
|
|
86754
86950
|
this._zAxisWire.setVisible(zAxisVisible);
|
|
86755
86951
|
|
|
86756
|
-
this._xAxisLabel.setVisible(xAxisVisible && !this._xAxisLabelCulled);
|
|
86757
|
-
this._yAxisLabel.setVisible(yAxisVisible && !this._yAxisLabelCulled);
|
|
86758
|
-
this._zAxisLabel.setVisible(zAxisVisible && !this._zAxisLabelCulled);
|
|
86952
|
+
this._xAxisLabel.setVisible(xAxisVisible && !this._xAxisLabelCulled && this._EnabledVisible);
|
|
86953
|
+
this._yAxisLabel.setVisible(yAxisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
|
|
86954
|
+
this._zAxisLabel.setVisible(zAxisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
|
|
86759
86955
|
|
|
86760
86956
|
this._cpDirty = true;
|
|
86761
86957
|
|
|
@@ -86825,9 +87021,9 @@ class DistanceMeasurement extends Component {
|
|
|
86825
87021
|
this._xAxisWire.setVisible(axisVisible && this._xAxisVisible);
|
|
86826
87022
|
this._yAxisWire.setVisible(axisVisible && this._yAxisVisible);
|
|
86827
87023
|
this._zAxisWire.setVisible(axisVisible && this._zAxisVisible);
|
|
86828
|
-
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible);
|
|
86829
|
-
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._xAxisVisible);
|
|
86830
|
-
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._xAxisVisible);
|
|
87024
|
+
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible && this._xLabelEnabled);
|
|
87025
|
+
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._xAxisVisible && this._yLabelEnabled);
|
|
87026
|
+
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._xAxisVisible && this._zLabelEnabled);
|
|
86831
87027
|
this._cpDirty = true;
|
|
86832
87028
|
this._needUpdate();
|
|
86833
87029
|
}
|
|
@@ -86887,7 +87083,7 @@ class DistanceMeasurement extends Component {
|
|
|
86887
87083
|
this._xAxisVisible = value;
|
|
86888
87084
|
const axisVisible = this._visible && this._axisVisible && this._xAxisVisible && this._axisEnabled;
|
|
86889
87085
|
this._xAxisWire.setVisible(axisVisible);
|
|
86890
|
-
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled);
|
|
87086
|
+
this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled && this._xLabelEnabled);
|
|
86891
87087
|
this._cpDirty = true;
|
|
86892
87088
|
this._needUpdate();
|
|
86893
87089
|
}
|
|
@@ -86915,7 +87111,7 @@ class DistanceMeasurement extends Component {
|
|
|
86915
87111
|
this._yAxisVisible = value;
|
|
86916
87112
|
const axisVisible = this._visible && this._axisVisible && this._yAxisVisible && this._axisEnabled;
|
|
86917
87113
|
this._yAxisWire.setVisible(axisVisible);
|
|
86918
|
-
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled);
|
|
87114
|
+
this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
|
|
86919
87115
|
this._cpDirty = true;
|
|
86920
87116
|
this._needUpdate();
|
|
86921
87117
|
}
|
|
@@ -86943,7 +87139,7 @@ class DistanceMeasurement extends Component {
|
|
|
86943
87139
|
this._zAxisVisible = value;
|
|
86944
87140
|
const axisVisible = this._visible && this._axisVisible && this._zAxisVisible && this._axisEnabled;
|
|
86945
87141
|
this._zAxisWire.setVisible(axisVisible);
|
|
86946
|
-
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled);
|
|
87142
|
+
this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
|
|
86947
87143
|
this._cpDirty = true;
|
|
86948
87144
|
this._needUpdate();
|
|
86949
87145
|
}
|
|
@@ -86968,7 +87164,7 @@ class DistanceMeasurement extends Component {
|
|
|
86968
87164
|
value = value !== undefined ? Boolean(value) : this.plugin.defaultWireVisible;
|
|
86969
87165
|
this._wireVisible = value;
|
|
86970
87166
|
var wireVisible = this._visible && this._wireVisible;
|
|
86971
|
-
this._lengthLabel.setVisible(wireVisible);
|
|
87167
|
+
this._lengthLabel.setVisible(wireVisible && this._lengthLabelEnabled);
|
|
86972
87168
|
this._lengthWire.setVisible(wireVisible);
|
|
86973
87169
|
}
|
|
86974
87170
|
|
|
@@ -86982,7 +87178,7 @@ class DistanceMeasurement extends Component {
|
|
|
86982
87178
|
}
|
|
86983
87179
|
|
|
86984
87180
|
/**
|
|
86985
|
-
* Sets if the labels are visible.
|
|
87181
|
+
* Sets if the labels are visible except the length label.
|
|
86986
87182
|
*
|
|
86987
87183
|
* @type {Boolean}
|
|
86988
87184
|
*/
|
|
@@ -86990,10 +87186,10 @@ class DistanceMeasurement extends Component {
|
|
|
86990
87186
|
value = value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible;
|
|
86991
87187
|
this._labelsVisible = value;
|
|
86992
87188
|
var labelsVisible = this._visible && this._labelsVisible;
|
|
86993
|
-
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86994
|
-
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86995
|
-
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled);
|
|
86996
|
-
this._lengthLabel.setVisible(labelsVisible);
|
|
87189
|
+
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
|
|
87190
|
+
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
|
|
87191
|
+
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
|
|
87192
|
+
this._lengthLabel.setVisible(labelsVisible && this._lengthLabelEnabled);
|
|
86997
87193
|
this._cpDirty = true;
|
|
86998
87194
|
this._needUpdate();
|
|
86999
87195
|
}
|
|
@@ -87007,6 +87203,98 @@ class DistanceMeasurement extends Component {
|
|
|
87007
87203
|
return this._labelsVisible;
|
|
87008
87204
|
}
|
|
87009
87205
|
|
|
87206
|
+
/**
|
|
87207
|
+
* Sets if the x label is enabled.
|
|
87208
|
+
*
|
|
87209
|
+
* @type {Boolean}
|
|
87210
|
+
*/
|
|
87211
|
+
set xLabelEnabled(value) {
|
|
87212
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultXLabelEnabled;
|
|
87213
|
+
this._xLabelEnabled = value;
|
|
87214
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87215
|
+
this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
|
|
87216
|
+
this._cpDirty = true;
|
|
87217
|
+
this._needUpdate();
|
|
87218
|
+
}
|
|
87219
|
+
|
|
87220
|
+
/**
|
|
87221
|
+
* Gets if the x label is enabled.
|
|
87222
|
+
*
|
|
87223
|
+
* @type {Boolean}
|
|
87224
|
+
*/
|
|
87225
|
+
get xLabelEnabled(){
|
|
87226
|
+
return this._xLabelEnabled;
|
|
87227
|
+
}
|
|
87228
|
+
|
|
87229
|
+
/**
|
|
87230
|
+
* Sets if the y label is enabled.
|
|
87231
|
+
*
|
|
87232
|
+
* @type {Boolean}
|
|
87233
|
+
*/
|
|
87234
|
+
set yLabelEnabled(value) {
|
|
87235
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultYLabelEnabled;
|
|
87236
|
+
this._yLabelEnabled = value;
|
|
87237
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87238
|
+
this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
|
|
87239
|
+
this._cpDirty = true;
|
|
87240
|
+
this._needUpdate();
|
|
87241
|
+
}
|
|
87242
|
+
|
|
87243
|
+
/**
|
|
87244
|
+
* Gets if the y label is enabled.
|
|
87245
|
+
*
|
|
87246
|
+
* @type {Boolean}
|
|
87247
|
+
*/
|
|
87248
|
+
get yLabelEnabled(){
|
|
87249
|
+
return this._yLabelEnabled;
|
|
87250
|
+
}
|
|
87251
|
+
|
|
87252
|
+
/**
|
|
87253
|
+
* Sets if the z label is enabled.
|
|
87254
|
+
*
|
|
87255
|
+
* @type {Boolean}
|
|
87256
|
+
*/
|
|
87257
|
+
set zLabelEnabled(value) {
|
|
87258
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultZLabelEnabled;
|
|
87259
|
+
this._zLabelEnabled = value;
|
|
87260
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87261
|
+
this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
|
|
87262
|
+
this._cpDirty = true;
|
|
87263
|
+
this._needUpdate();
|
|
87264
|
+
}
|
|
87265
|
+
|
|
87266
|
+
/**
|
|
87267
|
+
* Gets if the z label is enabled.
|
|
87268
|
+
*
|
|
87269
|
+
* @type {Boolean}
|
|
87270
|
+
*/
|
|
87271
|
+
get zLabelEnabled(){
|
|
87272
|
+
return this._zLabelEnabled;
|
|
87273
|
+
}
|
|
87274
|
+
|
|
87275
|
+
/**
|
|
87276
|
+
* Sets if the length label is enabled.
|
|
87277
|
+
*
|
|
87278
|
+
* @type {Boolean}
|
|
87279
|
+
*/
|
|
87280
|
+
set lengthLabelEnabled(value) {
|
|
87281
|
+
value = value !== undefined ? Boolean(value) : this.plugin.defaultLengthLabelEnabled;
|
|
87282
|
+
this._lengthLabelEnabled = value;
|
|
87283
|
+
var labelsVisible = this._visible && this._labelsVisible;
|
|
87284
|
+
this._lengthLabel.setVisible(labelsVisible && !this._lengthAxisLabelCulled && this._clickable && this._axisEnabled && this._lengthLabelEnabled);
|
|
87285
|
+
this._cpDirty = true;
|
|
87286
|
+
this._needUpdate();
|
|
87287
|
+
}
|
|
87288
|
+
|
|
87289
|
+
/**
|
|
87290
|
+
* Gets if the length label is enabled.
|
|
87291
|
+
*
|
|
87292
|
+
* @type {Boolean}
|
|
87293
|
+
*/
|
|
87294
|
+
get lengthLabelEnabled(){
|
|
87295
|
+
return this._lengthLabelEnabled;
|
|
87296
|
+
}
|
|
87297
|
+
|
|
87010
87298
|
/**
|
|
87011
87299
|
* Sets if labels should be positioned on the wires.
|
|
87012
87300
|
*
|
|
@@ -87189,6 +87477,17 @@ class DistanceMeasurementsControl extends Component {
|
|
|
87189
87477
|
reset() {
|
|
87190
87478
|
}
|
|
87191
87479
|
|
|
87480
|
+
/**
|
|
87481
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl, if any.
|
|
87482
|
+
*
|
|
87483
|
+
* @returns {null|DistanceMeasurement}
|
|
87484
|
+
*
|
|
87485
|
+
* @abstract
|
|
87486
|
+
*/
|
|
87487
|
+
get currentMeasurement() {
|
|
87488
|
+
return null;
|
|
87489
|
+
}
|
|
87490
|
+
|
|
87192
87491
|
/**
|
|
87193
87492
|
* Destroys this DistanceMeasurementsControl.
|
|
87194
87493
|
*
|
|
@@ -87595,6 +87894,17 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
|
|
|
87595
87894
|
this._currentDistanceMeasurement.destroy();
|
|
87596
87895
|
this._currentDistanceMeasurement = null;
|
|
87597
87896
|
}
|
|
87897
|
+
|
|
87898
|
+
this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;
|
|
87899
|
+
}
|
|
87900
|
+
|
|
87901
|
+
/**
|
|
87902
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl, if any.
|
|
87903
|
+
*
|
|
87904
|
+
* @returns {null|DistanceMeasurement}
|
|
87905
|
+
*/
|
|
87906
|
+
get currentMeasurement() {
|
|
87907
|
+
return this._currentDistanceMeasurement;
|
|
87598
87908
|
}
|
|
87599
87909
|
|
|
87600
87910
|
/**
|
|
@@ -87882,6 +88192,10 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
87882
88192
|
* @param {boolean} [cfg.defaultTargetVisible=true] The default value of the DistanceMeasurements `targetVisible` property.
|
|
87883
88193
|
* @param {boolean} [cfg.defaultWireVisible=true] The default value of the DistanceMeasurements `wireVisible` property.
|
|
87884
88194
|
* @param {boolean} [cfg.defaultLabelsVisible=true] The default value of the DistanceMeasurements `labelsVisible` property.
|
|
88195
|
+
* @param {boolean} [cfg.defaultXLabelEnabled=true] The default value of the DistanceMeasurements `xLabelEnabled` property.
|
|
88196
|
+
* @param {boolean} [cfg.defaultYLabelEnabled=true] The default value of the DistanceMeasurements `yLabelEnabled` property.
|
|
88197
|
+
* @param {boolean} [cfg.defaultZLabelEnabled=true] The default value of the DistanceMeasurements `zLabelEnabled` property.
|
|
88198
|
+
* @param {boolean} [cfg.defaultLengthLabelEnabled=true] The default value of the DistanceMeasurements `lengthLabelEnabled` property.
|
|
87885
88199
|
* @param {boolean} [cfg.defaultAxisVisible=true] The default value of the DistanceMeasurements `axisVisible` property.
|
|
87886
88200
|
* @param {boolean} [cfg.defaultXAxisVisible=true] The default value of the DistanceMeasurements `xAxisVisible` property.
|
|
87887
88201
|
* @param {boolean} [cfg.defaultYAxisVisible=true] The default value of the DistanceMeasurements `yAxisVisible` property.
|
|
@@ -87904,11 +88218,14 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
87904
88218
|
this._measurements = {};
|
|
87905
88219
|
|
|
87906
88220
|
this.labelMinAxisLength = cfg.labelMinAxisLength;
|
|
87907
|
-
|
|
87908
88221
|
this.defaultVisible = cfg.defaultVisible !== false;
|
|
87909
88222
|
this.defaultOriginVisible = cfg.defaultOriginVisible !== false;
|
|
87910
88223
|
this.defaultTargetVisible = cfg.defaultTargetVisible !== false;
|
|
87911
88224
|
this.defaultWireVisible = cfg.defaultWireVisible !== false;
|
|
88225
|
+
this.defaultXLabelEnabled = cfg.defaultXLabelEnabled !== false;
|
|
88226
|
+
this.defaultYLabelEnabled = cfg.defaultYLabelEnabled !== false;
|
|
88227
|
+
this.defaultZLabelEnabled = cfg.defaultZLabelEnabled !== false;
|
|
88228
|
+
this.defaultLengthLabelEnabled = cfg.defaultLengthLabelEnabled !== false;
|
|
87912
88229
|
this.defaultLabelsVisible = cfg.defaultLabelsVisible !== false;
|
|
87913
88230
|
this.defaultAxisVisible = cfg.defaultAxisVisible !== false;
|
|
87914
88231
|
this.defaultXAxisVisible = cfg.defaultXAxisVisible !== false;
|
|
@@ -88037,7 +88354,12 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88037
88354
|
* @param {Boolean} [params.xAxisVisible=true] Whether to initially show the X-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88038
88355
|
* @param {Boolean} [params.yAxisVisible=true] Whether to initially show the Y-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88039
88356
|
* @param {Boolean} [params.zAxisVisible=true] Whether to initially show the Z-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.
|
|
88357
|
+
* @param {Boolean} [params.xLabelEnabled=true] Whether to initially show the x label.
|
|
88358
|
+
* @param {Boolean} [params.yLabelEnabled=true] Whether to initially show the y label.
|
|
88359
|
+
* @param {Boolean} [params.zLabelEnabled=true] Whether to initially show the z label.
|
|
88360
|
+
* @param {Boolean} [params.lengthLabelEnabled=true] Whether to initially show the length label.
|
|
88040
88361
|
* @param {Boolean} [params.labelsVisible=true] Whether to initially show the labels.
|
|
88362
|
+
* @param {Boolean} [params.lengthLabelVisible=true] Whether to initially show the labels.
|
|
88041
88363
|
* @param {string} [params.color] The color of the length dot, wire and label.
|
|
88042
88364
|
* @param {Boolean} [params.labelsOnWires=true] Determines if labels will be set on wires or one below the other.
|
|
88043
88365
|
* @returns {DistanceMeasurement} The new {@link DistanceMeasurement}.
|
|
@@ -88067,6 +88389,10 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88067
88389
|
xAxisVisible: params.xAxisVisible !== false && this.defaultXAxisVisible !== false,
|
|
88068
88390
|
yAxisVisible: params.yAxisVisible !== false && this.defaultYAxisVisible !== false,
|
|
88069
88391
|
zAxisVisible: params.zAxisVisible !== false && this.defaultZAxisVisible !== false,
|
|
88392
|
+
xLabelEnabled: params.xLabelEnabled !== false && this.defaultXLabelEnabled !== false,
|
|
88393
|
+
yLabelEnabled: params.yLabelEnabled !== false && this.defaultYLabelEnabled !== false,
|
|
88394
|
+
zLabelEnabled: params.zLabelEnabled !== false && this.defaultZLabelEnabled !== false,
|
|
88395
|
+
lengthLabelEnabled: params.lengthLabelEnabled !== false && this.defaultLengthLabelEnabled !== false,
|
|
88070
88396
|
labelsVisible: params.labelsVisible !== false && this.defaultLabelsVisible !== false,
|
|
88071
88397
|
originVisible: params.originVisible,
|
|
88072
88398
|
targetVisible: params.targetVisible,
|
|
@@ -88077,6 +88403,7 @@ class DistanceMeasurementsPlugin extends Plugin {
|
|
|
88077
88403
|
onContextMenu: this._onContextMenu
|
|
88078
88404
|
});
|
|
88079
88405
|
this._measurements[measurement.id] = measurement;
|
|
88406
|
+
measurement.clickable = true;
|
|
88080
88407
|
measurement.on("destroyed", () => {
|
|
88081
88408
|
delete this._measurements[measurement.id];
|
|
88082
88409
|
});
|
|
@@ -88812,6 +89139,10 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88812
89139
|
this._currentDistanceMeasurement.targetVisible = true;
|
|
88813
89140
|
this._currentDistanceMeasurement.wireVisible = true;
|
|
88814
89141
|
this._currentDistanceMeasurement.labelsVisible = true;
|
|
89142
|
+
this._currentDistanceMeasurement.xAxisVisible = true;
|
|
89143
|
+
this._currentDistanceMeasurement.yAxisVisible = true;
|
|
89144
|
+
this._currentDistanceMeasurement.zAxisVisible = true;
|
|
89145
|
+
this._currentDistanceMeasurement.clickable = true;
|
|
88815
89146
|
this.distanceMeasurementsPlugin.fire("measurementEnd", this._currentDistanceMeasurement);
|
|
88816
89147
|
this._currentDistanceMeasurement = null;
|
|
88817
89148
|
} else {
|
|
@@ -88827,6 +89158,7 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88827
89158
|
break;
|
|
88828
89159
|
|
|
88829
89160
|
case WAITING_FOR_TARGET_LONG_TOUCH_END:
|
|
89161
|
+
console.log('long touch');
|
|
88830
89162
|
if (this.pointerLens) {
|
|
88831
89163
|
this.pointerLens.visible = false;
|
|
88832
89164
|
}
|
|
@@ -88894,6 +89226,16 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
|
|
|
88894
89226
|
this._currentDistanceMeasurement.destroy();
|
|
88895
89227
|
this._currentDistanceMeasurement = null;
|
|
88896
89228
|
}
|
|
89229
|
+
this._mouseState = WAITING_FOR_ORIGIN_TOUCH_START;
|
|
89230
|
+
}
|
|
89231
|
+
|
|
89232
|
+
/**
|
|
89233
|
+
* Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsTouchControl, if any.
|
|
89234
|
+
*
|
|
89235
|
+
* @returns {null|DistanceMeasurement}
|
|
89236
|
+
*/
|
|
89237
|
+
get currentMeasurement() {
|
|
89238
|
+
return this._currentDistanceMeasurement;
|
|
88897
89239
|
}
|
|
88898
89240
|
|
|
88899
89241
|
/**
|
|
@@ -96618,8 +96960,8 @@ function getCanvasPosFromEvent$2(event, canvas, canvasPos) {
|
|
|
96618
96960
|
canvasPos[1] = event.y;
|
|
96619
96961
|
} else {
|
|
96620
96962
|
const { left, top } = canvas.getBoundingClientRect();
|
|
96621
|
-
canvasPos[0] = event.clientX - left
|
|
96622
|
-
canvasPos[1] = event.clientY - top
|
|
96963
|
+
canvasPos[0] = event.clientX - left;
|
|
96964
|
+
canvasPos[1] = event.clientY - top;
|
|
96623
96965
|
}
|
|
96624
96966
|
return canvasPos;
|
|
96625
96967
|
}
|
|
@@ -115813,6 +116155,7 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
|
|
|
115813
116155
|
}).then((gltfData) => {
|
|
115814
116156
|
const ctx = {
|
|
115815
116157
|
src: src,
|
|
116158
|
+
entityId: options.entityId,
|
|
115816
116159
|
metaModelCorrections: metaModelJSON ? getMetaModelCorrections(metaModelJSON) : null,
|
|
115817
116160
|
loadBuffer: options.loadBuffer,
|
|
115818
116161
|
basePath: options.basePath,
|
|
@@ -116252,29 +116595,9 @@ function loadNode(ctx, node, depth, matrix) {
|
|
|
116252
116595
|
meshCfg.origin = origin;
|
|
116253
116596
|
}
|
|
116254
116597
|
|
|
116255
|
-
// if (createEntity) {
|
|
116256
|
-
// if (createEntity.colorize) {
|
|
116257
|
-
// meshCfg.color = createEntity.colorize;
|
|
116258
|
-
// }
|
|
116259
|
-
// if (createEntity.opacity !== undefined && createEntity.opacity !== null) {
|
|
116260
|
-
// meshCfg.opacity = createEntity.opacity;
|
|
116261
|
-
// }
|
|
116262
|
-
// }
|
|
116263
|
-
|
|
116264
116598
|
sceneModel.createMesh(meshCfg);
|
|
116265
116599
|
deferredMeshIds.push(meshCfg.id);
|
|
116266
116600
|
}
|
|
116267
|
-
// if (createEntity) {
|
|
116268
|
-
// sceneModel.createEntity(utils.apply(createEntity, {
|
|
116269
|
-
// meshIds: deferredMeshIds,
|
|
116270
|
-
// isObject: true
|
|
116271
|
-
// }));
|
|
116272
|
-
// } else {
|
|
116273
|
-
// sceneModel.createEntity({
|
|
116274
|
-
// meshIds: deferredMeshIds,
|
|
116275
|
-
// isObject: true
|
|
116276
|
-
// });
|
|
116277
|
-
// }
|
|
116278
116601
|
}
|
|
116279
116602
|
}
|
|
116280
116603
|
|
|
@@ -116288,48 +116611,62 @@ function loadNode(ctx, node, depth, matrix) {
|
|
|
116288
116611
|
|
|
116289
116612
|
// Post-order visit scene node
|
|
116290
116613
|
|
|
116291
|
-
|
|
116292
|
-
|
|
116293
|
-
|
|
116294
|
-
|
|
116614
|
+
if (ctx.entityId) {
|
|
116615
|
+
if (depth ===0) {
|
|
116616
|
+
sceneModel.createEntity({
|
|
116617
|
+
id: ctx.entityId,
|
|
116618
|
+
meshIds: deferredMeshIds,
|
|
116619
|
+
isObject: true
|
|
116620
|
+
});
|
|
116621
|
+
deferredMeshIds.length = 0;
|
|
116295
116622
|
}
|
|
116296
|
-
|
|
116297
|
-
|
|
116298
|
-
|
|
116299
|
-
|
|
116300
|
-
|
|
116301
|
-
|
|
116302
|
-
|
|
116303
|
-
|
|
116304
|
-
//
|
|
116305
|
-
|
|
116306
|
-
|
|
116307
|
-
|
|
116308
|
-
|
|
116309
|
-
|
|
116310
|
-
|
|
116311
|
-
|
|
116312
|
-
|
|
116313
|
-
|
|
116314
|
-
|
|
116623
|
+
} else {
|
|
116624
|
+
const nodeName = node.name;
|
|
116625
|
+
if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {
|
|
116626
|
+
if (nodeName === undefined || nodeName === null) {
|
|
116627
|
+
ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);
|
|
116628
|
+
}
|
|
116629
|
+
let entityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)
|
|
116630
|
+
// if (!!entityId && sceneModel.entities[entityId]) {
|
|
116631
|
+
// ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${nodeName} - will randomly-generating an object ID in XKT`);
|
|
116632
|
+
// }
|
|
116633
|
+
// while (!entityId || sceneModel.entities[entityId]) {
|
|
116634
|
+
// entityId = "entity-" + ctx.nextId++;
|
|
116635
|
+
// }
|
|
116636
|
+
if (ctx.metaModelCorrections) {
|
|
116637
|
+
// Merging meshes into XKTObjects that map to metaobjects
|
|
116638
|
+
const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[entityId];
|
|
116639
|
+
if (rootMetaObject) {
|
|
116640
|
+
const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];
|
|
116641
|
+
rootMetaObjectStats.countChildren++;
|
|
116642
|
+
if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {
|
|
116643
|
+
sceneModel.createEntity({
|
|
116644
|
+
id: rootMetaObject.id,
|
|
116645
|
+
meshIds: deferredMeshIds,
|
|
116646
|
+
isObject: true
|
|
116647
|
+
});
|
|
116648
|
+
deferredMeshIds.length = 0;
|
|
116649
|
+
}
|
|
116650
|
+
} else {
|
|
116651
|
+
const metaObject = ctx.metaModelCorrections.metaObjectsMap[entityId];
|
|
116652
|
+
if (metaObject) {
|
|
116653
|
+
sceneModel.createEntity({
|
|
116654
|
+
id: entityId,
|
|
116655
|
+
meshIds: deferredMeshIds,
|
|
116656
|
+
isObject: true
|
|
116657
|
+
});
|
|
116658
|
+
deferredMeshIds.length = 0;
|
|
116659
|
+
}
|
|
116315
116660
|
}
|
|
116316
116661
|
} else {
|
|
116317
|
-
|
|
116318
|
-
|
|
116319
|
-
|
|
116320
|
-
|
|
116321
|
-
|
|
116322
|
-
|
|
116323
|
-
|
|
116324
|
-
}
|
|
116662
|
+
// Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
|
|
116663
|
+
sceneModel.createEntity({
|
|
116664
|
+
id: entityId,
|
|
116665
|
+
meshIds: deferredMeshIds,
|
|
116666
|
+
isObject: true
|
|
116667
|
+
});
|
|
116668
|
+
deferredMeshIds.length = 0;
|
|
116325
116669
|
}
|
|
116326
|
-
} else {
|
|
116327
|
-
// Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
|
|
116328
|
-
sceneModel.createEntity({
|
|
116329
|
-
id: entityId,
|
|
116330
|
-
meshIds: deferredMeshIds
|
|
116331
|
-
});
|
|
116332
|
-
deferredMeshIds.length = 0;
|
|
116333
116670
|
}
|
|
116334
116671
|
}
|
|
116335
116672
|
}
|
|
@@ -116506,6 +116843,79 @@ const IFCObjectDefaults = {
|
|
|
116506
116843
|
* excludeTypes: ["IfcSpace"]
|
|
116507
116844
|
* });
|
|
116508
116845
|
* ````
|
|
116846
|
+
*
|
|
116847
|
+
* ## Showing a glTF model in TreeViewPlugin when metadata is not available
|
|
116848
|
+
*
|
|
116849
|
+
* When GLTFLoaderPlugin loads a glTF model, it creates an object Entity for each `node` in the glTF `scene` hierarchy that has a
|
|
116850
|
+
* `name` attribute, giving the Entity an ID that has the value of the `name` attribute.
|
|
116851
|
+
*
|
|
116852
|
+
* 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
|
|
116853
|
+
* ordinarily present in glTF that comes from other sources, such as LiDAR scanners. For such glTF models, GLTFLoaderPlugin
|
|
116854
|
+
* will create Entities, but they will have randomly-generated IDs, and therefore cannot be associated with MetaObjects in any
|
|
116855
|
+
* MetaModels that we create alongside the model.
|
|
116856
|
+
*
|
|
116857
|
+
* For glTF models containing `nodes` that don't have `name` attributes, we can use the `load()` method's `elementId` parameter
|
|
116858
|
+
* to make GLTFLoaderPlugin load the entire model into a single Entity that gets this ID.
|
|
116859
|
+
*
|
|
116860
|
+
* In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that
|
|
116861
|
+
* contains a MetaObject that corresponds to that Entity.
|
|
116862
|
+
*
|
|
116863
|
+
* When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the glTF model and controls
|
|
116864
|
+
* the visibility of that Entity (ie. to control the visibility of the entire model).
|
|
116865
|
+
*
|
|
116866
|
+
* The snippet below shows how this is done.
|
|
116867
|
+
*
|
|
116868
|
+
* ````javascript
|
|
116869
|
+
* import {Viewer, GLTFLoaderPlugin, NavCubePlugin, TreeViewPlugin} from "../../dist/xeokit-sdk.es.js";
|
|
116870
|
+
*
|
|
116871
|
+
* const viewer = new Viewer({
|
|
116872
|
+
* canvasId: "myCanvas",
|
|
116873
|
+
* transparent: true
|
|
116874
|
+
* });
|
|
116875
|
+
*
|
|
116876
|
+
* new TreeViewPlugin(viewer, {
|
|
116877
|
+
* containerElement: document.getElementById("treeViewContainer"),
|
|
116878
|
+
* hierarchy: "containment"
|
|
116879
|
+
* });
|
|
116880
|
+
*
|
|
116881
|
+
* const gltfLoader = new GLTFLoaderPlugin(viewer);
|
|
116882
|
+
*
|
|
116883
|
+
* const sceneModel = gltfLoader.load({ // Creates a SceneModel with ID "myScanModel"
|
|
116884
|
+
* id: "myScanModel",
|
|
116885
|
+
* src: "public-use-sample-apartment.glb",
|
|
116886
|
+
*
|
|
116887
|
+
* //-------------------------------------------------------------------------
|
|
116888
|
+
* // Specify an `elementId` parameter, which causes the
|
|
116889
|
+
* // entire model to be loaded into a single Entity that gets this ID.
|
|
116890
|
+
* //-------------------------------------------------------------------------
|
|
116891
|
+
*
|
|
116892
|
+
* entityId: "3toKckUfH2jBmd$7uhJHa4", // Creates an Entity with this ID
|
|
116893
|
+
*
|
|
116894
|
+
* //-------------------------------------------------------------------------
|
|
116895
|
+
* // Specify a `metaModelJSON` parameter, which creates a
|
|
116896
|
+
* // MetaModel with two MetaObjects, one of which corresponds
|
|
116897
|
+
* // to our Entity. Then the TreeViewPlugin is able to have a node
|
|
116898
|
+
* // that can represent the model and control the visibility of the Entity.
|
|
116899
|
+
* //--------------------------------------------------------------------------
|
|
116900
|
+
*
|
|
116901
|
+
* metaModelJSON: { // Creates a MetaModel with ID "myScanModel"
|
|
116902
|
+
* "metaObjects": [
|
|
116903
|
+
* {
|
|
116904
|
+
* "id": "3toKckUfH2jBmd$7uhJHa6", // Creates a MetaObject with this ID
|
|
116905
|
+
* "name": "My Project",
|
|
116906
|
+
* "type": "Default",
|
|
116907
|
+
* "parent": null
|
|
116908
|
+
* },
|
|
116909
|
+
* {
|
|
116910
|
+
* "id": "3toKckUfH2jBmd$7uhJHa4", // Creates a MetaObject with this ID (same ID as our Entity)
|
|
116911
|
+
* "name": "My Scan",
|
|
116912
|
+
* "type": "Default",
|
|
116913
|
+
* "parent": "3toKckUfH2jBmd$7uhJHa6"
|
|
116914
|
+
* }
|
|
116915
|
+
* ]
|
|
116916
|
+
* }
|
|
116917
|
+
* });
|
|
116918
|
+
* ````
|
|
116509
116919
|
* @class GLTFLoaderPlugin
|
|
116510
116920
|
*/
|
|
116511
116921
|
class GLTFLoaderPlugin extends Plugin {
|
|
@@ -116600,6 +117010,7 @@ class GLTFLoaderPlugin extends Plugin {
|
|
|
116600
117010
|
* represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
|
|
116601
117011
|
* to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
|
|
116602
117012
|
* primitives. Only works while {@link DTX#enabled} is also ````true````.
|
|
117013
|
+
* @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
|
|
116603
117014
|
* @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}
|
|
116604
117015
|
*/
|
|
116605
117016
|
load(params = {}) {
|
|
@@ -134772,6 +135183,60 @@ const MAX_VERTICES = 500000; // TODO: Rough estimate
|
|
|
134772
135183
|
* });
|
|
134773
135184
|
* ````
|
|
134774
135185
|
*
|
|
135186
|
+
* ## Showing a LAS/LAZ model in TreeViewPlugin
|
|
135187
|
+
*
|
|
135188
|
+
* We can use the `load()` method's `elementId` parameter
|
|
135189
|
+
* to make LASLoaderPlugin load the entire model into a single Entity that gets this ID.
|
|
135190
|
+
*
|
|
135191
|
+
* In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that
|
|
135192
|
+
* contains a MetaObject that corresponds to that Entity.
|
|
135193
|
+
*
|
|
135194
|
+
* When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the model and controls
|
|
135195
|
+
* the visibility of that Entity (ie. to control the visibility of the entire model).
|
|
135196
|
+
*
|
|
135197
|
+
* The snippet below shows how this is done.
|
|
135198
|
+
*
|
|
135199
|
+
* ````javascript
|
|
135200
|
+
* import {Viewer, LASLoaderPlugin, NavCubePlugin, TreeViewPlugin} from "../../dist/xeokit-sdk.es.js";
|
|
135201
|
+
*
|
|
135202
|
+
* const viewer = new Viewer({
|
|
135203
|
+
* canvasId: "myCanvas",
|
|
135204
|
+
* transparent: true
|
|
135205
|
+
* });
|
|
135206
|
+
*
|
|
135207
|
+
* new TreeViewPlugin(viewer, {
|
|
135208
|
+
* containerElement: document.getElementById("treeViewContainer"),
|
|
135209
|
+
* hierarchy: "containment"
|
|
135210
|
+
* });
|
|
135211
|
+
*
|
|
135212
|
+
* const lasLoader = new LASLoaderPlugin(viewer);
|
|
135213
|
+
*
|
|
135214
|
+
* const sceneModel = lasLoader.load({ // Creates a SceneModel with ID "myScanModel"
|
|
135215
|
+
* id: "myScanModel",
|
|
135216
|
+
* src: "../../assets/models/las/Nalls_Pumpkin_Hill.laz",
|
|
135217
|
+
* rotation: [-90, 0, 0],
|
|
135218
|
+
*
|
|
135219
|
+
* entityId: "3toKckUfH2jBmd$7uhJHa4", // Creates an Entity with this ID
|
|
135220
|
+
*
|
|
135221
|
+
* metaModelJSON: { // Creates a MetaModel with ID "myScanModel"
|
|
135222
|
+
* "metaObjects": [
|
|
135223
|
+
* {
|
|
135224
|
+
* "id": "3toKckUfH2jBmd$7uhJHa6", // Creates this MetaObject with this ID
|
|
135225
|
+
* "name": "My Project",
|
|
135226
|
+
* "type": "Default",
|
|
135227
|
+
* "parent": null
|
|
135228
|
+
* },
|
|
135229
|
+
* {
|
|
135230
|
+
* "id": "3toKckUfH2jBmd$7uhJHa4", // Creates this MetaObject with this ID
|
|
135231
|
+
* "name": "My Scan",
|
|
135232
|
+
* "type": "Default",
|
|
135233
|
+
* "parent": "3toKckUfH2jBmd$7uhJHa6"
|
|
135234
|
+
* }
|
|
135235
|
+
* ]
|
|
135236
|
+
* }
|
|
135237
|
+
* });
|
|
135238
|
+
* ````
|
|
135239
|
+
*
|
|
134775
135240
|
* @class LASLoaderPlugin
|
|
134776
135241
|
* @since 2.0.17
|
|
134777
135242
|
*/
|
|
@@ -135122,7 +135587,7 @@ class LASLoaderPlugin extends Plugin {
|
|
|
135122
135587
|
}
|
|
135123
135588
|
*/
|
|
135124
135589
|
|
|
135125
|
-
const pointsObjectId = math.createUUID();
|
|
135590
|
+
const pointsObjectId = params.entityId || math.createUUID();
|
|
135126
135591
|
|
|
135127
135592
|
sceneModel.createEntity({
|
|
135128
135593
|
id: pointsObjectId,
|
|
@@ -135132,7 +135597,10 @@ class LASLoaderPlugin extends Plugin {
|
|
|
135132
135597
|
|
|
135133
135598
|
sceneModel.finalize();
|
|
135134
135599
|
|
|
135135
|
-
if (params.
|
|
135600
|
+
if (params.metaModelJSON) {
|
|
135601
|
+
const metaModelId = sceneModel.id;
|
|
135602
|
+
this.viewer.metaScene.createMetaModel(metaModelId, params.metaModelJSON, options);
|
|
135603
|
+
} else if (params.loadMetadata !== false) {
|
|
135136
135604
|
const rootMetaObjectId = math.createUUID();
|
|
135137
135605
|
const metadata = {
|
|
135138
135606
|
projectId: "",
|
|
@@ -136630,6 +137098,566 @@ class CityJSONLoaderPlugin extends Plugin {
|
|
|
136630
137098
|
}
|
|
136631
137099
|
}
|
|
136632
137100
|
|
|
137101
|
+
/**
|
|
137102
|
+
* Default data access strategy for {@link DotBIMLoaderPlugin}.
|
|
137103
|
+
*
|
|
137104
|
+
* This just loads assets using XMLHttpRequest.
|
|
137105
|
+
*/
|
|
137106
|
+
class DotBIMDefaultDataSource {
|
|
137107
|
+
|
|
137108
|
+
constructor() {
|
|
137109
|
+
}
|
|
137110
|
+
|
|
137111
|
+
/**
|
|
137112
|
+
* Gets .BIM JSON.
|
|
137113
|
+
*
|
|
137114
|
+
* @param {String|Number} dotBIMSrc Identifies the .BIM JSON asset.
|
|
137115
|
+
* @param {Function} ok Fired on successful loading of the .BIM JSON asset.
|
|
137116
|
+
* @param {Function} error Fired on error while loading the .BIM JSON asset.
|
|
137117
|
+
*/
|
|
137118
|
+
getDotBIM(dotBIMSrc, ok, error) {
|
|
137119
|
+
utils.loadJSON(dotBIMSrc,
|
|
137120
|
+
(json) => {
|
|
137121
|
+
ok(json);
|
|
137122
|
+
},
|
|
137123
|
+
function (errMsg) {
|
|
137124
|
+
error(errMsg);
|
|
137125
|
+
});
|
|
137126
|
+
}
|
|
137127
|
+
}
|
|
137128
|
+
|
|
137129
|
+
/**
|
|
137130
|
+
* {@link Viewer} plugin that loads models from [.bim](https://dotbim.net/) format.
|
|
137131
|
+
*
|
|
137132
|
+
* [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/DotBIMLoaderPlugin-house.png">](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)
|
|
137133
|
+
*
|
|
137134
|
+
* [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)]
|
|
137135
|
+
*
|
|
137136
|
+
* * Creates an {@link Entity} representing each .bim model it loads, which will have {@link Entity#isModel} set ````true````
|
|
137137
|
+
* and will be registered by {@link Entity#id} in {@link Scene#models}.
|
|
137138
|
+
* * Creates an {@link Entity} for each object within the .bim model. Those Entities will have {@link Entity#isObject}
|
|
137139
|
+
* set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.
|
|
137140
|
+
* * When loading, can set the World-space position, scale and rotation of each model within World space,
|
|
137141
|
+
* along with initial properties for all the model's {@link Entity}s.
|
|
137142
|
+
* * Allows to mask which IFC types we want to load.
|
|
137143
|
+
* * Allows to configure initial viewer state for specified IFC types (color, visibility, selection, highlighted, X-rayed, pickable, etc).
|
|
137144
|
+
*
|
|
137145
|
+
* ## Usage
|
|
137146
|
+
*
|
|
137147
|
+
* In the example below we'll load a house model from a [.bim file](/assets/models/dotbim/House.bim).
|
|
137148
|
+
*
|
|
137149
|
+
* This will create a bunch of {@link Entity}s that represents the model and its objects, along with
|
|
137150
|
+
* a {@link MetaModel} and {@link MetaObject}s that hold their metadata.
|
|
137151
|
+
*
|
|
137152
|
+
* ````javascript
|
|
137153
|
+
* import {Viewer, DotBIMLoaderPlugin} from "xeokit-sdk.es.js";
|
|
137154
|
+
*
|
|
137155
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137156
|
+
* // 1. Create a Viewer,
|
|
137157
|
+
* // 2. Arrange the camera,
|
|
137158
|
+
* // 3. Tweak the selection material (tone it down a bit)
|
|
137159
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137160
|
+
*
|
|
137161
|
+
* // 1
|
|
137162
|
+
* const viewer = new Viewer({
|
|
137163
|
+
* canvasId: "myCanvas",
|
|
137164
|
+
* transparent: true
|
|
137165
|
+
* });
|
|
137166
|
+
*
|
|
137167
|
+
* // 2
|
|
137168
|
+
* viewer.camera.orbitPitch(20);
|
|
137169
|
+
* viewer.camera.orbitYaw(-45);
|
|
137170
|
+
*
|
|
137171
|
+
* // 3
|
|
137172
|
+
* viewer.scene.selectedMaterial.fillAlpha = 0.1;
|
|
137173
|
+
*
|
|
137174
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137175
|
+
* // 1. Create a .bim loader plugin,
|
|
137176
|
+
* // 2. Load a .bim building model, emphasizing the edges to make it look nicer
|
|
137177
|
+
* //------------------------------------------------------------------------------------------------------------------
|
|
137178
|
+
*
|
|
137179
|
+
* // 1
|
|
137180
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer);
|
|
137181
|
+
*
|
|
137182
|
+
* // 2
|
|
137183
|
+
* var model = dotBIMLoader.load({ // Returns an Entity that represents the model
|
|
137184
|
+
* id: "myModel",
|
|
137185
|
+
* src: "House.bim",
|
|
137186
|
+
* edges: true
|
|
137187
|
+
* });
|
|
137188
|
+
*
|
|
137189
|
+
* // Find the model Entity by ID
|
|
137190
|
+
* model = viewer.scene.models["myModel"];
|
|
137191
|
+
*
|
|
137192
|
+
* // Destroy the model
|
|
137193
|
+
* model.destroy();
|
|
137194
|
+
* ````
|
|
137195
|
+
*
|
|
137196
|
+
* ## Transforming
|
|
137197
|
+
*
|
|
137198
|
+
* We have the option to rotate, scale and translate each *````.bim````* model as we load it.
|
|
137199
|
+
*
|
|
137200
|
+
* This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.
|
|
137201
|
+
*
|
|
137202
|
+
* In the example below, we'll rotate our model 90 degrees about its local X-axis, then
|
|
137203
|
+
* translate it 100 units along its X axis.
|
|
137204
|
+
*
|
|
137205
|
+
* ````javascript
|
|
137206
|
+
* const model = dotBIMLoader.load({
|
|
137207
|
+
* src: "House.bim",
|
|
137208
|
+
* rotation: [90,0,0],
|
|
137209
|
+
* position: [100, 0, 0]
|
|
137210
|
+
* });
|
|
137211
|
+
* ````
|
|
137212
|
+
*
|
|
137213
|
+
* ## Including and excluding IFC types
|
|
137214
|
+
*
|
|
137215
|
+
* We can also load only those objects that have the specified IFC types. In the example below, we'll load only the
|
|
137216
|
+
* objects that represent walls.
|
|
137217
|
+
*
|
|
137218
|
+
* ````javascript
|
|
137219
|
+
* const model = dotBIMLoader.load({
|
|
137220
|
+
* id: "myModel",
|
|
137221
|
+
* src: "House.bim",
|
|
137222
|
+
* includeTypes: ["IfcWallStandardCase"]
|
|
137223
|
+
* });
|
|
137224
|
+
* ````
|
|
137225
|
+
*
|
|
137226
|
+
* We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the
|
|
137227
|
+
* objects that do not represent empty space.
|
|
137228
|
+
*
|
|
137229
|
+
* ````javascript
|
|
137230
|
+
* const model = dotBIMLoader.load({
|
|
137231
|
+
* id: "myModel",
|
|
137232
|
+
* src: "House.bim",
|
|
137233
|
+
* excludeTypes: ["IfcSpace"]
|
|
137234
|
+
* });
|
|
137235
|
+
* ````
|
|
137236
|
+
*
|
|
137237
|
+
* # Configuring initial IFC object appearances
|
|
137238
|
+
*
|
|
137239
|
+
* We can specify the custom initial appearance of loaded objects according to their IFC types.
|
|
137240
|
+
*
|
|
137241
|
+
* This is useful for things like:
|
|
137242
|
+
*
|
|
137243
|
+
* * setting the colors to our objects according to their IFC types,
|
|
137244
|
+
* * automatically hiding ````IfcSpace```` objects, and
|
|
137245
|
+
* * ensuring that ````IfcWindow```` objects are always transparent.
|
|
137246
|
+
* <br>
|
|
137247
|
+
* In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,
|
|
137248
|
+
* and ````IfcWindow```` types to be always translucent blue.
|
|
137249
|
+
*
|
|
137250
|
+
* ````javascript
|
|
137251
|
+
* const myObjectDefaults = {
|
|
137252
|
+
*
|
|
137253
|
+
* IfcSpace: {
|
|
137254
|
+
* visible: false
|
|
137255
|
+
* },
|
|
137256
|
+
* IfcWindow: {
|
|
137257
|
+
* colorize: [0.337255, 0.303922, 0.870588], // Blue
|
|
137258
|
+
* opacity: 0.3
|
|
137259
|
+
* },
|
|
137260
|
+
*
|
|
137261
|
+
* //...
|
|
137262
|
+
*
|
|
137263
|
+
* DEFAULT: {
|
|
137264
|
+
* colorize: [0.5, 0.5, 0.5]
|
|
137265
|
+
* }
|
|
137266
|
+
* };
|
|
137267
|
+
*
|
|
137268
|
+
* const model4 = dotBIMLoader.load({
|
|
137269
|
+
* id: "myModel4",
|
|
137270
|
+
* src: "House.bim",
|
|
137271
|
+
* objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities
|
|
137272
|
+
* });
|
|
137273
|
+
* ````
|
|
137274
|
+
*
|
|
137275
|
+
* When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other
|
|
137276
|
+
* elements, which can be confusing.
|
|
137277
|
+
*
|
|
137278
|
+
* It's often helpful to make IfcSpaces transparent and unpickable, like this:
|
|
137279
|
+
*
|
|
137280
|
+
* ````javascript
|
|
137281
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
|
|
137282
|
+
* objectDefaults: {
|
|
137283
|
+
* IfcSpace: {
|
|
137284
|
+
* pickable: false,
|
|
137285
|
+
* opacity: 0.2
|
|
137286
|
+
* }
|
|
137287
|
+
* }
|
|
137288
|
+
* });
|
|
137289
|
+
* ````
|
|
137290
|
+
*
|
|
137291
|
+
* Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:
|
|
137292
|
+
*
|
|
137293
|
+
* ````javascript
|
|
137294
|
+
* const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {
|
|
137295
|
+
* objectDefaults: {
|
|
137296
|
+
* IfcSpace: {
|
|
137297
|
+
* visible: false
|
|
137298
|
+
* }
|
|
137299
|
+
* }
|
|
137300
|
+
* });
|
|
137301
|
+
* ````
|
|
137302
|
+
*
|
|
137303
|
+
* # Configuring a custom data source
|
|
137304
|
+
*
|
|
137305
|
+
* By default, DotBIMLoaderPlugin will load *````.bim````* files and metadata JSON over HTTP.
|
|
137306
|
+
*
|
|
137307
|
+
* In the example below, we'll customize the way DotBIMLoaderPlugin loads the files by configuring it with our own data source
|
|
137308
|
+
* object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.
|
|
137309
|
+
*
|
|
137310
|
+
* ````javascript
|
|
137311
|
+
* import {utils} from "xeokit-sdk.es.js";
|
|
137312
|
+
*
|
|
137313
|
+
* class MyDataSource {
|
|
137314
|
+
*
|
|
137315
|
+
* constructor() {
|
|
137316
|
+
* }
|
|
137317
|
+
*
|
|
137318
|
+
* // Gets the contents of the given .bim file in a JSON object
|
|
137319
|
+
* getDotBIM(src, ok, error) {
|
|
137320
|
+
* utils.loadJSON(dotBIMSrc,
|
|
137321
|
+
* (json) => {
|
|
137322
|
+
* ok(json);
|
|
137323
|
+
* },
|
|
137324
|
+
* function (errMsg) {
|
|
137325
|
+
* error(errMsg);
|
|
137326
|
+
* });
|
|
137327
|
+
* }
|
|
137328
|
+
* }
|
|
137329
|
+
*
|
|
137330
|
+
* const dotBIMLoader2 = new DotBIMLoaderPlugin(viewer, {
|
|
137331
|
+
* dataSource: new MyDataSource()
|
|
137332
|
+
* });
|
|
137333
|
+
*
|
|
137334
|
+
* const model5 = dotBIMLoader2.load({
|
|
137335
|
+
* id: "myModel5",
|
|
137336
|
+
* src: "House.bim"
|
|
137337
|
+
* });
|
|
137338
|
+
* ````
|
|
137339
|
+
* @class DotBIMLoaderPlugin
|
|
137340
|
+
*/
|
|
137341
|
+
class DotBIMLoaderPlugin extends Plugin {
|
|
137342
|
+
|
|
137343
|
+
/**
|
|
137344
|
+
* @constructor
|
|
137345
|
+
*
|
|
137346
|
+
* @param {Viewer} viewer The Viewer.
|
|
137347
|
+
* @param {Object} cfg Plugin configuration.
|
|
137348
|
+
* @param {String} [cfg.id="DotBIMLoader"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
|
|
137349
|
+
* @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
|
|
137350
|
+
* @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.
|
|
137351
|
+
*/
|
|
137352
|
+
constructor(viewer, cfg = {}) {
|
|
137353
|
+
|
|
137354
|
+
super("DotBIMLoader", viewer, cfg);
|
|
137355
|
+
|
|
137356
|
+
this.dataSource = cfg.dataSource;
|
|
137357
|
+
this.objectDefaults = cfg.objectDefaults;
|
|
137358
|
+
}
|
|
137359
|
+
|
|
137360
|
+
/**
|
|
137361
|
+
* Sets a custom data source through which the DotBIMLoaderPlugin can .BIM files.
|
|
137362
|
+
*
|
|
137363
|
+
* Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
|
|
137364
|
+
*
|
|
137365
|
+
* @type {Object}
|
|
137366
|
+
*/
|
|
137367
|
+
set dataSource(value) {
|
|
137368
|
+
this._dataSource = value || new DotBIMDefaultDataSource();
|
|
137369
|
+
}
|
|
137370
|
+
|
|
137371
|
+
/**
|
|
137372
|
+
* Gets the custom data source through which the DotBIMLoaderPlugin can load .BIM files.
|
|
137373
|
+
*
|
|
137374
|
+
* Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.
|
|
137375
|
+
*
|
|
137376
|
+
* @type {Object}
|
|
137377
|
+
*/
|
|
137378
|
+
get dataSource() {
|
|
137379
|
+
return this._dataSource;
|
|
137380
|
+
}
|
|
137381
|
+
|
|
137382
|
+
/**
|
|
137383
|
+
* Sets map of initial default states for each loaded {@link Entity} that represents an object.
|
|
137384
|
+
*
|
|
137385
|
+
* Default value is {@link IFCObjectDefaults}.
|
|
137386
|
+
*
|
|
137387
|
+
* @type {{String: Object}}
|
|
137388
|
+
*/
|
|
137389
|
+
set objectDefaults(value) {
|
|
137390
|
+
this._objectDefaults = value || IFCObjectDefaults;
|
|
137391
|
+
}
|
|
137392
|
+
|
|
137393
|
+
/**
|
|
137394
|
+
* Gets map of initial default states for each loaded {@link Entity} that represents an object.
|
|
137395
|
+
*
|
|
137396
|
+
* Default value is {@link IFCObjectDefaults}.
|
|
137397
|
+
*
|
|
137398
|
+
* @type {{String: Object}}
|
|
137399
|
+
*/
|
|
137400
|
+
get objectDefaults() {
|
|
137401
|
+
return this._objectDefaults;
|
|
137402
|
+
}
|
|
137403
|
+
|
|
137404
|
+
/**
|
|
137405
|
+
* Loads a .BIM model from a file into this DotBIMLoaderPlugin's {@link Viewer}.
|
|
137406
|
+
*
|
|
137407
|
+
* @param {*} params Loading parameters.
|
|
137408
|
+
* @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.
|
|
137409
|
+
* @param {String} [params.src] Path to a .BIM file, as an alternative to the ````bim```` parameter.
|
|
137410
|
+
* @param {*} [params.bim] .BIM JSON, as an alternative to the ````src```` parameter.
|
|
137411
|
+
* @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
|
|
137412
|
+
* @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
|
|
137413
|
+
* @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
|
|
137414
|
+
* @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
|
|
137415
|
+
* @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
|
|
137416
|
+
* @param {Number[]} [params.scale=[1,1,1]] The model's scale.
|
|
137417
|
+
* @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.
|
|
137418
|
+
* @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.
|
|
137419
|
+
* @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to
|
|
137420
|
+
* represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
|
|
137421
|
+
* to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
|
|
137422
|
+
* primitives. Only works while {@link DTX#enabled} is also ````true````.
|
|
137423
|
+
* @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}
|
|
137424
|
+
*/
|
|
137425
|
+
load(params = {}) {
|
|
137426
|
+
|
|
137427
|
+
if (params.id && this.viewer.scene.components[params.id]) {
|
|
137428
|
+
this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
|
|
137429
|
+
delete params.id;
|
|
137430
|
+
}
|
|
137431
|
+
|
|
137432
|
+
const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
|
|
137433
|
+
isModel: true,
|
|
137434
|
+
backfaces: params.backfaces,
|
|
137435
|
+
dtxEnabled: params.dtxEnabled,
|
|
137436
|
+
rotation: params.rotation,
|
|
137437
|
+
origin: params.origin
|
|
137438
|
+
}));
|
|
137439
|
+
|
|
137440
|
+
const modelId = sceneModel.id; // In case ID was auto-generated
|
|
137441
|
+
|
|
137442
|
+
if (!params.src && !params.dotBIM) {
|
|
137443
|
+
this.error("load() param expected: src or dotBIM");
|
|
137444
|
+
return sceneModel; // Return new empty model
|
|
137445
|
+
}
|
|
137446
|
+
|
|
137447
|
+
const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
|
|
137448
|
+
|
|
137449
|
+
let includeTypes;
|
|
137450
|
+
if (params.includeTypes) {
|
|
137451
|
+
includeTypes = {};
|
|
137452
|
+
for (let i = 0, len = params.includeTypes.length; i < len; i++) {
|
|
137453
|
+
includeTypes[params.includeTypes[i]] = true;
|
|
137454
|
+
}
|
|
137455
|
+
}
|
|
137456
|
+
|
|
137457
|
+
let excludeTypes;
|
|
137458
|
+
if (params.excludeTypes) {
|
|
137459
|
+
excludeTypes = {};
|
|
137460
|
+
if (!includeTypes) {
|
|
137461
|
+
includeTypes = {};
|
|
137462
|
+
}
|
|
137463
|
+
for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
|
|
137464
|
+
includeTypes[params.excludeTypes[i]] = true;
|
|
137465
|
+
}
|
|
137466
|
+
}
|
|
137467
|
+
|
|
137468
|
+
const parseDotBIM = (ctx) => {
|
|
137469
|
+
|
|
137470
|
+
const fileData = ctx.fileData;
|
|
137471
|
+
const sceneModel = ctx.sceneModel;
|
|
137472
|
+
|
|
137473
|
+
const dbMeshIndices = {};
|
|
137474
|
+
const dbMeshLoaded = {};
|
|
137475
|
+
|
|
137476
|
+
const ifcProjectId = math.createUUID();
|
|
137477
|
+
const ifcSiteId = math.createUUID();
|
|
137478
|
+
const ifcBuildingId = math.createUUID();
|
|
137479
|
+
const ifcBuildingStoryId = math.createUUID();
|
|
137480
|
+
|
|
137481
|
+
const metaModelData = {
|
|
137482
|
+
metaObjects: [
|
|
137483
|
+
{
|
|
137484
|
+
id: ifcProjectId,
|
|
137485
|
+
name: "IfcProject",
|
|
137486
|
+
type: "IfcProject",
|
|
137487
|
+
parent: null
|
|
137488
|
+
},
|
|
137489
|
+
{
|
|
137490
|
+
id: ifcSiteId,
|
|
137491
|
+
name: "IfcSite",
|
|
137492
|
+
type: "IfcSite",
|
|
137493
|
+
parent: ifcProjectId
|
|
137494
|
+
},
|
|
137495
|
+
{
|
|
137496
|
+
id: ifcBuildingId,
|
|
137497
|
+
name: "IfcBuilding",
|
|
137498
|
+
type: "IfcBuilding",
|
|
137499
|
+
parent: ifcSiteId
|
|
137500
|
+
},
|
|
137501
|
+
{
|
|
137502
|
+
id: ifcBuildingStoryId,
|
|
137503
|
+
name: "IfcBuildingStorey",
|
|
137504
|
+
type: "IfcBuildingStorey",
|
|
137505
|
+
parent: ifcBuildingId
|
|
137506
|
+
}
|
|
137507
|
+
],
|
|
137508
|
+
propertySets: []
|
|
137509
|
+
};
|
|
137510
|
+
|
|
137511
|
+
for (let i = 0, len = fileData.meshes.length; i < len; i++) {
|
|
137512
|
+
const dbMesh = fileData.meshes[i];
|
|
137513
|
+
dbMeshIndices[dbMesh.mesh_id] = i;
|
|
137514
|
+
}
|
|
137515
|
+
|
|
137516
|
+
const parseDBMesh = (dbMeshId) => {
|
|
137517
|
+
if (dbMeshLoaded[dbMeshId]) {
|
|
137518
|
+
return;
|
|
137519
|
+
}
|
|
137520
|
+
const dbMeshIndex = dbMeshIndices[dbMeshId];
|
|
137521
|
+
const dbMesh = fileData.meshes[dbMeshIndex];
|
|
137522
|
+
sceneModel.createGeometry({
|
|
137523
|
+
id: dbMeshId,
|
|
137524
|
+
primitive: "triangles",
|
|
137525
|
+
positions: dbMesh.coordinates,
|
|
137526
|
+
indices: dbMesh.indices
|
|
137527
|
+
});
|
|
137528
|
+
dbMeshLoaded[dbMeshId] = true;
|
|
137529
|
+
};
|
|
137530
|
+
|
|
137531
|
+
const dbElements = fileData.elements;
|
|
137532
|
+
for (let i = 0, len = dbElements.length; i < len; i++) {
|
|
137533
|
+
const element = dbElements[i];
|
|
137534
|
+
const elementType = element.type;
|
|
137535
|
+
if (excludeTypes && excludeTypes[elementType]) {
|
|
137536
|
+
continue;
|
|
137537
|
+
|
|
137538
|
+
}
|
|
137539
|
+
if (includeTypes && (!includeTypes[elementType])) {
|
|
137540
|
+
continue;
|
|
137541
|
+
}
|
|
137542
|
+
const info = element.info;
|
|
137543
|
+
const objectId =
|
|
137544
|
+
element.guid !== undefined
|
|
137545
|
+
? `${element.guid}`
|
|
137546
|
+
: (info !== undefined && info.id !== undefined
|
|
137547
|
+
? info.id
|
|
137548
|
+
: i);
|
|
137549
|
+
|
|
137550
|
+
const dbMeshId = element.mesh_id;
|
|
137551
|
+
|
|
137552
|
+
parseDBMesh(dbMeshId);
|
|
137553
|
+
|
|
137554
|
+
const meshId = `${objectId}-mesh`;
|
|
137555
|
+
const vector = element.vector;
|
|
137556
|
+
const rotation = element.rotation;
|
|
137557
|
+
const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
|
|
137558
|
+
|
|
137559
|
+
let visible = true;
|
|
137560
|
+
let pickable = true;
|
|
137561
|
+
let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
|
|
137562
|
+
let opacity = element.color ? element.color.a / 255 : 1.0;
|
|
137563
|
+
|
|
137564
|
+
if (props) {
|
|
137565
|
+
if (props.visible === false) {
|
|
137566
|
+
visible = false;
|
|
137567
|
+
}
|
|
137568
|
+
if (props.pickable === false) {
|
|
137569
|
+
pickable = false;
|
|
137570
|
+
}
|
|
137571
|
+
if (props.colorize) {
|
|
137572
|
+
color = props.colorize;
|
|
137573
|
+
}
|
|
137574
|
+
if (props.opacity !== undefined && props.opacity !== null) {
|
|
137575
|
+
opacity = props.opacity;
|
|
137576
|
+
}
|
|
137577
|
+
}
|
|
137578
|
+
|
|
137579
|
+
sceneModel.createMesh({
|
|
137580
|
+
id: meshId,
|
|
137581
|
+
geometryId: dbMeshId,
|
|
137582
|
+
color,
|
|
137583
|
+
opacity,
|
|
137584
|
+
quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
|
|
137585
|
+
position: vector ? [vector.x, vector.y, vector.z] : undefined
|
|
137586
|
+
});
|
|
137587
|
+
|
|
137588
|
+
sceneModel.createEntity({
|
|
137589
|
+
id: objectId,
|
|
137590
|
+
meshIds: [meshId],
|
|
137591
|
+
visible,
|
|
137592
|
+
pickable,
|
|
137593
|
+
isObject: true
|
|
137594
|
+
});
|
|
137595
|
+
|
|
137596
|
+
metaModelData.metaObjects.push({
|
|
137597
|
+
id: objectId,
|
|
137598
|
+
name: info && info.Name && info.Name !== "None" ? info.Name : `${element.type} ${objectId}`,
|
|
137599
|
+
type: element.type,
|
|
137600
|
+
parent: ifcBuildingStoryId
|
|
137601
|
+
});
|
|
137602
|
+
}
|
|
137603
|
+
|
|
137604
|
+
sceneModel.finalize();
|
|
137605
|
+
|
|
137606
|
+
this.viewer.metaScene.createMetaModel(modelId, metaModelData);
|
|
137607
|
+
|
|
137608
|
+
sceneModel.scene.once("tick", () => {
|
|
137609
|
+
if (sceneModel.destroyed) {
|
|
137610
|
+
return;
|
|
137611
|
+
}
|
|
137612
|
+
sceneModel.scene.fire("modelLoaded", sceneModel.id); // FIXME: Assumes listeners know order of these two events
|
|
137613
|
+
sceneModel.fire("loaded", true, false); // Don't forget the event, for late subscribers
|
|
137614
|
+
});
|
|
137615
|
+
};
|
|
137616
|
+
|
|
137617
|
+
if (params.src) {
|
|
137618
|
+
const src = params.src;
|
|
137619
|
+
this.viewer.scene.canvas.spinner.processes++;
|
|
137620
|
+
this._dataSource.getDotBIM(src, (fileData) => { // OK
|
|
137621
|
+
const ctx = {
|
|
137622
|
+
fileData,
|
|
137623
|
+
sceneModel,
|
|
137624
|
+
nextId: 0,
|
|
137625
|
+
error: function (errMsg) {
|
|
137626
|
+
}
|
|
137627
|
+
};
|
|
137628
|
+
parseDotBIM(ctx);
|
|
137629
|
+
this.viewer.scene.canvas.spinner.processes--;
|
|
137630
|
+
},
|
|
137631
|
+
(err) => {
|
|
137632
|
+
this.viewer.scene.canvas.spinner.processes--;
|
|
137633
|
+
this.error(err);
|
|
137634
|
+
});
|
|
137635
|
+
} else if (params.dotBIM) {
|
|
137636
|
+
const ctx = {
|
|
137637
|
+
fileData: params.dotBIM,
|
|
137638
|
+
sceneModel,
|
|
137639
|
+
nextId: 0,
|
|
137640
|
+
error: function (errMsg) {
|
|
137641
|
+
}
|
|
137642
|
+
};
|
|
137643
|
+
parseDotBIM(ctx);
|
|
137644
|
+
}
|
|
137645
|
+
|
|
137646
|
+
sceneModel.once("destroyed", () => {
|
|
137647
|
+
this.viewer.metaScene.destroyMetaModel(modelId);
|
|
137648
|
+
});
|
|
137649
|
+
|
|
137650
|
+
return sceneModel;
|
|
137651
|
+
}
|
|
137652
|
+
|
|
137653
|
+
/**
|
|
137654
|
+
* Destroys this DotBIMLoaderPlugin.
|
|
137655
|
+
*/
|
|
137656
|
+
destroy() {
|
|
137657
|
+
super.destroy();
|
|
137658
|
+
}
|
|
137659
|
+
}
|
|
137660
|
+
|
|
136633
137661
|
exports.AlphaFormat = AlphaFormat;
|
|
136634
137662
|
exports.AmbientLight = AmbientLight;
|
|
136635
137663
|
exports.AngleMeasurementsControl = AngleMeasurementsControl;
|
|
@@ -136660,6 +137688,8 @@ exports.DistanceMeasurementsControl = DistanceMeasurementsControl;
|
|
|
136660
137688
|
exports.DistanceMeasurementsMouseControl = DistanceMeasurementsMouseControl;
|
|
136661
137689
|
exports.DistanceMeasurementsPlugin = DistanceMeasurementsPlugin;
|
|
136662
137690
|
exports.DistanceMeasurementsTouchControl = DistanceMeasurementsTouchControl;
|
|
137691
|
+
exports.DotBIMDefaultDataSource = DotBIMDefaultDataSource;
|
|
137692
|
+
exports.DotBIMLoaderPlugin = DotBIMLoaderPlugin;
|
|
136663
137693
|
exports.EdgeMaterial = EdgeMaterial;
|
|
136664
137694
|
exports.EmphasisMaterial = EmphasisMaterial;
|
|
136665
137695
|
exports.FaceAlignedSectionPlanesPlugin = FaceAlignedSectionPlanesPlugin;
|