@vitrosoftware/common-ui-ts 1.1.238 → 1.1.240

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.
@@ -1,11 +1,11 @@
1
- import { BIMModel, BIMCommon, BIMAnnotation } from '/resource/bimViewer/js/bim-viewer-models.js?version=1.1.238';
1
+ import { BIMModel, BIMCommon, BIMAnnotation } from '/resource/bimViewer/js/bim-viewer-models.js?version=1.1.240';
2
2
 
3
3
  import {
4
4
  Viewer, XKTLoaderPlugin, NavCubePlugin, SectionPlanesPlugin, math, BCFViewpointsPlugin, AnnotationsPlugin,
5
5
  ContextMenu, TreeViewPlugin, StoreyViewsPlugin, AngleMeasurementsPlugin, CameraMemento, DistanceMeasurementsPlugin,
6
6
  GLTFLoaderPlugin, utils, FastNavPlugin, MetaObject, parsers
7
7
  }
8
- from '/resource/bimViewer/js/xeokit/xeokit-sdk.es.js?version=1.1.238';
8
+ from '/resource/bimViewer/js/xeokit/xeokit-sdk.es.js?version=1.1.240';
9
9
 
10
10
 
11
11
  //----------------------------------------------------------------------------------------------------------------------
@@ -33,6 +33,8 @@ const setSceneObjectsVisible = (scene, objectIds, visible) => {
33
33
  viewer.scene.fire("vitroObjectsVisibility", { objectIds, visible });
34
34
  };
35
35
 
36
+
37
+
36
38
  const setSceneObjectsXRay = (scene, objectIds, xrayed) => {
37
39
  scene.setObjectsXRayed(objectIds, xrayed);
38
40
  viewer.scene.fire("vitroObjectsXRayed", { objectIds, xrayed });
@@ -46,7 +48,7 @@ const setSceneAllObjectsVisible = (scene, visible) => {
46
48
  scene.setObjectsVisible(scene.objectIds, visible);
47
49
  }
48
50
 
49
- scene.fire("vitroAllObjectsVisibility", visible);
51
+ scene.fire("vitroAllObjectsVisibility", { visible : visible });
50
52
  };
51
53
 
52
54
  const setSceneAllObjectsXRay = (scene, xrayed) => {
@@ -57,9 +59,40 @@ const setSceneAllObjectsXRay = (scene, xrayed) => {
57
59
  scene.setObjectsXRayed(scene.objectIds, xrayed);
58
60
  }
59
61
 
60
- scene.fire("vitroAllObjectsXRayed", xrayed);
62
+ scene.fire("vitroAllObjectsXRayed", { xrayed: xrayed });
63
+ };
64
+
65
+
66
+ const setModelAllObjectsVisible = (model, visible) => {
67
+ const objectIds = model.entityList.map(m => m.id);
68
+
69
+ if (!visible) {
70
+ model.scene.setObjectsVisible(objectIds, visible);
71
+ }
72
+ else {
73
+ model.scene.setObjectsVisible(objectIds, visible);
74
+ }
75
+
76
+ model.scene.fire("vitroAllObjectsVisibility", { model: model, visible: visible });
77
+ };
78
+
79
+ const setModelAllObjectsXRay = (model, xrayed) => {
80
+ const objectIds = model.entityList.map(m => m.id);
81
+
82
+ if (!xrayed) {
83
+ model.scene.setObjectsXRayed(objectIds, xrayed);
84
+ }
85
+ else {
86
+ model.scene.setObjectsXRayed(objectIds, xrayed);
87
+ }
88
+
89
+ model.scene.fire("vitroAllObjectsXRayed", { model: model, visible: visible });
61
90
  };
62
-
91
+
92
+ const setModelObjectsVisible = (model, objectIds, visible) => {
93
+ model.scene.setObjectsVisible(objectIds, visible);
94
+ model.scene.fire("vitroObjectsVisibility", { model, objectIds, visible });
95
+ };
63
96
 
64
97
  const treeViewContextMenu = new ContextMenu({
65
98
 
@@ -669,7 +702,7 @@ class VitroTreeViewPlugin extends TreeViewPlugin
669
702
  this._onCanvasBoundary = viewer.scene.canvas.on("boundary", culledSmallModelList);
670
703
  this._onCameraMatrix = viewer.scene.camera.on("matrix", culledSmallModelList);
671
704
 
672
- this._onSceneTick = viewer.scene.on("reloadSmallScenes", () =>
705
+ this._onReloadSmallScenes = viewer.scene.on("reloadSmallScenes", () =>
673
706
  {
674
707
  culledSmallModelList();
675
708
  });
@@ -715,6 +748,17 @@ class VitroTreeViewPlugin extends TreeViewPlugin
715
748
  this.isXRay = false;
716
749
  this.xrayedEntityMap = {};
717
750
 
751
+ this.requiredEntityMap = {};
752
+
753
+ var addRequiredEntity = (entityId, required) => {
754
+ if (required) {
755
+ this.requiredEntityMap[entityId] = true;
756
+ } else {
757
+ delete this.requiredEntityMap[entityId];
758
+ }
759
+ };
760
+
761
+
718
762
  var addXrayedEntity = (entityId, xrayed) => {
719
763
  const a = xrayed;
720
764
 
@@ -734,52 +778,104 @@ class VitroTreeViewPlugin extends TreeViewPlugin
734
778
  };
735
779
 
736
780
  this._onObjectXRayed = this.scene.on("objectXRayed", (entity) => {
737
- const a = entity.xrayed;
738
- const b = this.isXRay;
739
- const c = this.xrayedEntityMap[entity.id];
740
-
741
- addXrayedEntity(entity.id, entity.xrayed);
781
+ if (entity.model == this.largeModel) {
782
+ const a = entity.xrayed;
783
+ const b = this.isXRay;
784
+ const c = this.xrayedEntityMap[entity.id];
742
785
 
743
- if ((a && !b && !c) || (a && b && c)) {
744
- culledSmallModelList();
786
+ addXrayedEntity(entity.id, entity.xrayed);
787
+
788
+ if ((a && !b && !c) || (a && b && c)) {
789
+ culledSmallModelList();
790
+ }
745
791
  }
746
792
  });
747
793
 
748
- this._onTreeObjectVisibility = this.scene.on("vitroObjectsXRayed", (data) => {
749
- data.objectIds.forEach(objectId => addXrayedEntity(objectId, data.xrayed));
750
- culledSmallModelList();
794
+ this._onVitroClearObjectsRequired = this.scene.on("vitroClearObjectsRequired", (cfg) => {
795
+ if (!cfg.model || cfg.model == this.largeModel) {
796
+ this.requiredEntityMap = {};
797
+ }
751
798
  });
752
799
 
753
- this._onTreeObjectVisibility = this.scene.on("vitroAllObjectsXRayed", (xrayed) => {
754
-
755
- this.xrayedEntityMap = {};
756
- this.isXRay = xrayed;
800
+ this._onVitroObjectsRequired = this.scene.on("vitroObjectsRequired", (cfg) => {
801
+ if (!cfg.model || cfg.model == this.largeModel) {
802
+ cfg.objectIds.forEach(objectId => addRequiredEntity(objectId, true));
803
+ }
804
+ });
757
805
 
758
- culledSmallModelList();
806
+ this._onVitroObjectsXRayed = this.scene.on("vitroObjectsXRayed", (cfg) => {
807
+ if (!cfg.model || cfg.model == this.largeModel) {
808
+ cfg.objectIds.forEach(objectId => addXrayedEntity(objectId, cfg.xrayed));
809
+ culledSmallModelList();
810
+ }
759
811
  });
760
812
 
761
- this._onObjectVisibility = this.scene.on("objectVisibility", (entity) => {
762
- addInvisibleEntity(entity.id, entity.visible);
813
+ this._onVitroAllObjectsXRayed = this.scene.on("vitroAllObjectsXRayed", (cfg) => {
814
+ if (!cfg.model || cfg.model == this.largeModel) {
815
+ this.xrayedEntityMap = {};
816
+ this.isXRay = cfg.xrayed;
763
817
 
764
- if (!entity.visible) {
765
818
  culledSmallModelList();
766
819
  }
767
820
  });
768
821
 
769
- this._onTreeObjectVisibility = this.scene.on("vitroObjectsVisibility", (data) => {
770
- data.objectIds.forEach(objectId => addInvisibleEntity(objectId, data.visible));
771
- culledSmallModelList();
822
+ this._onObjectVisibility = this.scene.on("objectVisibility", (entity) => {
823
+ if (entity.model == this.largeModel) {
824
+ addInvisibleEntity(entity.id, entity.visible);
825
+
826
+ if (!entity.visible) {
827
+ culledSmallModelList();
828
+ }
829
+ }
772
830
  });
773
831
 
774
- this._onTreeObjectVisibility = this.scene.on("vitroAllObjectsVisibility", (visible) => {
832
+ this._onVitroObjectsVisibility = this.scene.on("vitroObjectsVisibility", (cfg) => {
833
+ if (!cfg.model || cfg.model == this.largeModel) {
834
+ cfg.objectIds.forEach(objectId => addInvisibleEntity(objectId, cfg.visible));
835
+ culledSmallModelList();
836
+ }
837
+ });
775
838
 
776
- this.visibilityEntityMap = {};
777
- this.isVisible = visible;
839
+ this._onVitroAllObjectsVisibility = this.scene.on("vitroAllObjectsVisibility", (cfg) => {
840
+ if (!cfg.model || cfg.model == this.largeModel)
841
+ {
842
+ this.visibilityEntityMap = {};
843
+ this.isVisible = cfg.visible;
778
844
 
779
- culledSmallModelList();
845
+ culledSmallModelList();
846
+ }
780
847
  });
781
848
  }
782
849
 
850
+ destroy() {
851
+ this.destroyed = true;
852
+ this.startSmallLoad = false;
853
+
854
+ this.viewer.scene.canvas.off(this._onCanvasBoundary);
855
+ this.viewer.scene.canvas.off(this._onCameraMatrix);
856
+ this.viewer.scene.off(this._onReloadSmallScenes);
857
+ this.viewer.scene.off(this._onSceneTick);
858
+
859
+ this.viewer.scene.input.off(this._onSceneMouseDown);
860
+ this.viewer.scene.input.off(this._onSceneMouseUp);
861
+ this.viewer.scene.input.off(this._onSceneMouseMove);
862
+
863
+ this.scene.off(this._onObjectXRayed);
864
+ this.scene.off(this._onVitroObjectsXRayed);
865
+ this.scene.off(this._onVitroAllObjectsXRayed);
866
+ this.scene.off(this._onObjectVisibility);
867
+ this.scene.off(this._onVitroObjectsVisibility);
868
+ this.scene.off(this._onVitroAllObjectsVisibility);
869
+
870
+ this.scene.off(this._onVitroClearObjectsRequired);
871
+ this.scene.off(this._onVitroObjectsRequired);
872
+
873
+
874
+ this.deleteModels();
875
+
876
+ super.destroy();
877
+ }
878
+
783
879
  culledModels() {
784
880
  if (this.controller) {
785
881
  this.controller.abort();
@@ -851,6 +947,8 @@ class VitroTreeViewPlugin extends TreeViewPlugin
851
947
  sceneOptions.xrayMode = this.isXRay ? 1 : 0;
852
948
  sceneOptions.xrayedEntityIdList = Object.keys(this.xrayedEntityMap);
853
949
  sceneOptions.sectionPlanes = [];
950
+
951
+ sceneOptions.requiredEntityIdList = Object.keys(this.requiredEntityMap);
854
952
 
855
953
  viewer.scene._sectionPlanesState.sectionPlanes.forEach((plane) => {
856
954
  var sectionPlane = {};
@@ -861,203 +959,899 @@ class VitroTreeViewPlugin extends TreeViewPlugin
861
959
  sceneOptions.sectionPlanes.push(sectionPlane);
862
960
  });
863
961
 
864
- BIMCommon.GetSmallModel(this.viewer.scene, BIMCommon.ModelList, sceneOptions, this.controller.signal, this.loadSmallPart.bind(this));
962
+ BIMCommon.GetSmallModel(this.viewer.scene, this.largeModel.ModelList, sceneOptions, this.controller.signal, this.loadSmallPart.bind(this));
865
963
  }
866
964
  }
867
965
  }
868
966
 
869
967
  /*! jquery-dialogextend 2.0.3 2014-07-08 */
870
- (function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.0",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"!==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().click(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()}).end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapshot:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+15,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:hidden").show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{maximize:{option:"maximizable",state:"maximized"}},options:{maximizable:!1,icons:{maximize:"ui-icon-extlink"},beforeMaximize:null,maximize:null},maximize:function(){var t,e;return t=i(window).height()-11,e=i(window).width()-11,this._trigger("beforeMaximize"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),i(this.element[0]).dialog("option","draggable")&&i(this.element[0]).dialog("widget").draggable("option","handle",null).find(".ui-dialog-draggable-handle").css("cursor","text").end(),i(this.element[0]).dialog("widget").css("position","fixed").find(".ui-dialog-content").show().dialog("widget").find(".ui-dialog-buttonpane").show().end().find(".ui-dialog-content").dialog("option",{resizable:!1,draggable:!1,height:t,width:e,position:{my:"left top",at:"left top",of:window}}),this._setState("maximized"),this._toggleButtons(),this._trigger("maximize")},_restore_maximized:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).dialog("widget").css("position",t.position.mode).find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,draggable:t.config.draggable,height:t.size.height,width:t.size.width,maxHeight:t.size.maxHeight,position:{my:"left top",at:"left+"+t.position.left+" top+"+t.position.top,of:window}}),i(this.element[0]).dialog("option","draggable")?i(this.element[0]).dialog("widget").draggable("option","handle",i(this.element[0]).dialog("widget").find(".ui-dialog-draggable-handle").length?i(this.element[0]).dialog("widget").find(".ui-dialog-draggable-handle"):".ui-dialog-titlebar").find(".ui-dialog-draggable-handle").css("cursor","move"):void 0},_initStyles_maximize:function(){var t;return i(".dialog-extend-maximize-css").length?void 0:(t="",t+='<style class="dialog-extend-maximize-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-maximize { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-maximize span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-maximize:hover,",t+=".ui-dialog .ui-dialog-titlebar-maximize:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))}})}.call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{minimize:{option:"minimizable",state:"minimized"}},options:{minimizable:!1,minimizeLocation:"left",icons:{minimize:"ui-icon-minus"},beforeMinimize:null,minimize:null},minimize:function(){var t,e,o;return this._trigger("beforeMinimize"),"normal"!==this._state&&this._restore(),o=200,i("#dialog-extend-fixed-container").length?e=i("#dialog-extend-fixed-container"):(e=i('<div id="dialog-extend-fixed-container"></div>').appendTo("body"),e.css({position:"fixed",bottom:1,left:1,right:1,"z-index":9999})),this._toggleButtons("minimized"),t=i(this.element[0]).dialog("widget").clone().children().remove().end(),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").clone(!0,!0).appendTo(t),t.css({"float":this.options.minimizeLocation,margin:1}),e.append(t),i(this.element[0]).data("dialog-extend-minimize-controls",t),i(this.element[0]).dialog("option","draggable")&&t.removeClass("ui-draggable"),t.css({height:"auto",width:o,position:"static"}),i(this.element[0]).on("dialogbeforeclose",this._minimize_restoreOnClose).dialog("widget").hide(),this._setState("minimized"),this._trigger("minimize")},_restore_minimized:function(){return i(this.element[0]).dialog("widget").show(),i(this.element[0]).off("dialogbeforeclose",this._minimize_restoreOnClose),i(this.element[0]).data("dialog-extend-minimize-controls").remove(),i(this.element[0]).removeData("dialog-extend-minimize-controls")},_initStyles_minimize:function(){var t;return i(".dialog-extend-minimize-css").length?void 0:(t="",t+='<style class="dialog-extend-minimize-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-minimize { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-minimize span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-minimize:hover,",t+=".ui-dialog .ui-dialog-titlebar-minimize:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_verifyOptions_minimize:function(){var t;return!this.options.minimizeLocation||"left"!==(t=this.options.minimizeLocation)&&"right"!==t?(i.error("jQuery.dialogExtend Error : Invalid <minimizeLocation> value '"+this.options.minimizeLocation+"'"),this.options.minimizeLocation="left"):void 0},_minimize_restoreOnClose:function(){return i(this).dialogExtend("restore")}})}.call(this);window.initBimViewer = function(context) {function showPropertyInspector(pickResult) {
871
- //var metaObject;
872
- //var model = getPickResultModel(pickResult);
873
- var objectId = pickResult.entity.id;
874
-
875
- collapseSidebarIssueDetail();
876
- collapseSidebarNotes();
877
- $('#btnToggleSidebarNotes').removeClass('toggled');
968
+ (function(){var i;i=jQuery,i.widget("ui.dialogExtend",{version:"2.0.0",modes:{},options:{closable:!0,dblclick:!1,titlebar:!1,icons:{close:"ui-icon-closethick",restore:"ui-icon-newwin"},load:null,beforeRestore:null,restore:null},_create:function(){return this._state="normal",i(this.element[0]).data("ui-dialog")||i.error("jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted"),this._verifyOptions(),this._initStyles(),this._initButtons(),this._initTitleBar(),this._setState("normal"),this._on("load",function(i){return console.log("test",i)}),this._trigger("load")},_setState:function(t){return i(this.element[0]).removeClass("ui-dialog-"+this._state).addClass("ui-dialog-"+t),this._state=t},_verifyOptions:function(){var t,e,o;!this.options.dblclick||this.options.dblclick in this.modes||(i.error("jQuery.dialogExtend Error : Invalid <dblclick> value '"+this.options.dblclick+"'"),this.options.dblclick=!1),this.options.titlebar&&"none"!==(e=this.options.titlebar)&&"transparent"!==e&&(i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'"),this.options.titlebar=!1),o=[];for(t in this.modes)this["_verifyOptions_"+t]?o.push(this["_verifyOptions_"+t]()):o.push(void 0);return o},_initStyles:function(){var t,e,o;i(".dialog-extend-css").length||(e="",e+='<style class="dialog-extend-css" type="text/css">',e+=".ui-dialog .ui-dialog-titlebar-buttonpane>a { float: right; }",e+=".ui-dialog .ui-dialog-titlebar-restore { width: 19px; height: 18px; }",e+=".ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }",e+=".ui-dialog .ui-dialog-titlebar-restore:hover,",e+=".ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }",e+=".ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }",e+="</style>",i(e).appendTo("body")),o=[];for(t in this.modes)o.push(this["_initStyles_"+t]());return o},_initButtons:function(){var t,e,o,n,a,l=this;n=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar"),t=i('<div class="ui-dialog-titlebar-buttonpane"></div>').appendTo(n),t.css({position:"absolute",top:"50%",right:"0.3em","margin-top":"-10px",height:"18px"}),n.find(".ui-dialog-titlebar-close").css({position:"relative","float":"right",top:"auto",right:"auto",margin:0}).find(".ui-icon").removeClass("ui-icon-closethick").addClass(this.options.icons.close).end().appendTo(t).end(),t.append('<a class="ui-dialog-titlebar-restore ui-corner-all ui-state-default" href="#"><span class="ui-icon '+this.options.icons.restore+'" title="restore">restore</span></a>').find(".ui-dialog-titlebar-restore").attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-close").toggle(this.options.closable).end().find(".ui-dialog-titlebar-restore").hide().click(function(i){return i.preventDefault(),l.restore()}).end(),a=this.modes;for(o in a)e=a[o],this._initModuleButton(o,e);return n.dblclick(function(){return l.options.dblclick?"normal"!==l._state?l.restore():l[l.options.dblclick]():void 0}).select(function(){return!1})},_initModuleButton:function(t,e){var o,n=this;return o=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-buttonpane"),o.append('<a class="ui-dialog-titlebar-'+t+' ui-corner-all ui-state-default" href="#" title="'+t+'"><span class="ui-icon '+this.options.icons[t]+'">'+t+"</span></a>").find(".ui-dialog-titlebar-"+t).attr("role","button").mouseover(function(){return i(this).addClass("ui-state-hover")}).mouseout(function(){return i(this).removeClass("ui-state-hover")}).focus(function(){return i(this).addClass("ui-state-focus")}).blur(function(){return i(this).removeClass("ui-state-focus")}).end().find(".ui-dialog-titlebar-"+t).toggle(this.options[e.option]).click(function(i){return i.preventDefault(),n[t]()}).end()},_initTitleBar:function(){var t;switch(this.options.titlebar){case!1:return 0;case"none":return i(this.element[0]).dialog("option","draggable")&&(t=i("<div />").addClass("ui-dialog-draggable-handle").css("cursor","move").height(5),i(this.element[0]).dialog("widget").prepend(t).draggable("option","handle",t)),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").find(".ui-dialog-title").html("&nbsp;").end().css({"background-color":"transparent","background-image":"none",border:0,position:"absolute",right:0,top:0,"z-index":9999}).end();case"transparent":return i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css({"background-color":"transparent","background-image":"none",border:0});default:return i.error("jQuery.dialogExtend Error : Invalid <titlebar> value '"+this.options.titlebar+"'")}},state:function(){return this._state},restore:function(){return this._trigger("beforeRestore"),this._restore(),this._toggleButtons(),this._trigger("restore")},_restore:function(){return"normal"!==this._state?(this["_restore_"+this._state](),this._setState("normal"),i(this.element[0]).dialog("widget").focus()):void 0},_saveSnapshot:function(){return"normal"===this._state?(this.original_config_resizable=i(this.element[0]).dialog("option","resizable"),this.original_config_draggable=i(this.element[0]).dialog("option","draggable"),this.original_size_height=i(this.element[0]).dialog("widget").outerHeight(),this.original_size_width=i(this.element[0]).dialog("option","width"),this.original_size_maxHeight=i(this.element[0]).dialog("option","maxHeight"),this.original_position_mode=i(this.element[0]).dialog("widget").css("position"),this.original_position_left=i(this.element[0]).dialog("widget").offset().left-i("body").scrollLeft(),this.original_position_top=i(this.element[0]).dialog("widget").offset().top-i("body").scrollTop(),this.original_titlebar_wrap=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").css("white-space")):void 0},_loadSnapshot:function(){return{config:{resizable:this.original_config_resizable,draggable:this.original_config_draggable},size:{height:this.original_size_height,width:this.original_size_width,maxHeight:this.original_size_maxHeight},position:{mode:this.original_position_mode,left:this.original_position_left,top:this.original_position_top},titlebar:{wrap:this.original_titlebar_wrap}}},_toggleButtons:function(t){var e,o,n,a,l,s;n=t||this._state,i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").toggle("normal"!==n).css({right:"1.4em"}).end(),a=this.modes;for(o in a)e=a[o],i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o).toggle(n!==e.state&&this.options[e.option]);l=this.modes,s=[];for(o in l)e=l[o],e.state===n?s.push(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-restore").insertAfter(i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar-"+o)).end()):s.push(void 0);return s}})}).call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{collapse:{option:"collapsable",state:"collapsed"}},options:{collapsable:!1,icons:{collapse:"ui-icon-triangle-1-s"},beforeCollapse:null,collapse:null},collapse:function(){var t,e;return t=i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").height()+15,this._trigger("beforeCollapse"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),e=i(this.element[0]).dialog("widget").position(),i(this.element[0]).dialog("option",{resizable:!1,height:t,maxHeight:t,position:[e.left-i(document).scrollLeft(),e.top-i(document).scrollTop()]}).on("dialogclose",this._collapse_restore).hide().dialog("widget").find(".ui-dialog-buttonpane:visible").hide().end().find(".ui-dialog-titlebar").css("white-space","nowrap").end().find(".ui-dialog-content"),this._setState("collapsed"),this._toggleButtons(),this._trigger("collapse")},_restore_collapsed:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).show().dialog("widget").find(".ui-dialog-buttonpane:hidden").show().end().find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,height:t.size.height,maxHeight:t.size.maxHeight}).off("dialogclose",this._collapse_restore)},_initStyles_collapse:function(){var t;return i(".dialog-extend-collapse-css").length?void 0:(t="",t+='<style class="dialog-extend-collapse-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-collapse { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-collapse:hover,",t+=".ui-dialog .ui-dialog-titlebar-collapse:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_collapse_restore:function(){return i(this).dialogExtend("restore")}})}.call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{maximize:{option:"maximizable",state:"maximized"}},options:{maximizable:!1,icons:{maximize:"ui-icon-extlink"},beforeMaximize:null,maximize:null},maximize:function(){var t,e;return t=i(window).height()-11,e=i(window).width()-11,this._trigger("beforeMaximize"),"normal"!==this._state&&this._restore(),this._saveSnapshot(),i(this.element[0]).dialog("option","draggable")&&i(this.element[0]).dialog("widget").draggable("option","handle",null).find(".ui-dialog-draggable-handle").css("cursor","text").end(),i(this.element[0]).dialog("widget").css("position","fixed").find(".ui-dialog-content").show().dialog("widget").find(".ui-dialog-buttonpane").show().end().find(".ui-dialog-content").dialog("option",{resizable:!1,draggable:!1,height:t,width:e,position:{my:"left top",at:"left top",of:window}}),this._setState("maximized"),this._toggleButtons(),this._trigger("maximize")},_restore_maximized:function(){var t;return t=this._loadSnapshot(),i(this.element[0]).dialog("widget").css("position",t.position.mode).find(".ui-dialog-titlebar").css("white-space",t.titlebar.wrap).end().find(".ui-dialog-content").dialog("option",{resizable:t.config.resizable,draggable:t.config.draggable,height:t.size.height,width:t.size.width,maxHeight:t.size.maxHeight,position:{my:"left top",at:"left+"+t.position.left+" top+"+t.position.top,of:window}}),i(this.element[0]).dialog("option","draggable")?i(this.element[0]).dialog("widget").draggable("option","handle",i(this.element[0]).dialog("widget").find(".ui-dialog-draggable-handle").length?i(this.element[0]).dialog("widget").find(".ui-dialog-draggable-handle"):".ui-dialog-titlebar").find(".ui-dialog-draggable-handle").css("cursor","move"):void 0},_initStyles_maximize:function(){var t;return i(".dialog-extend-maximize-css").length?void 0:(t="",t+='<style class="dialog-extend-maximize-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-maximize { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-maximize span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-maximize:hover,",t+=".ui-dialog .ui-dialog-titlebar-maximize:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))}})}.call(this),function(){var i;i=jQuery,i.extend(!0,i.ui.dialogExtend.prototype,{modes:{minimize:{option:"minimizable",state:"minimized"}},options:{minimizable:!1,minimizeLocation:"left",icons:{minimize:"ui-icon-minus"},beforeMinimize:null,minimize:null},minimize:function(){var t,e,o;return this._trigger("beforeMinimize"),"normal"!==this._state&&this._restore(),o=200,i("#dialog-extend-fixed-container").length?e=i("#dialog-extend-fixed-container"):(e=i('<div id="dialog-extend-fixed-container"></div>').appendTo("body"),e.css({position:"fixed",bottom:1,left:1,right:1,"z-index":9999})),this._toggleButtons("minimized"),t=i(this.element[0]).dialog("widget").clone().children().remove().end(),i(this.element[0]).dialog("widget").find(".ui-dialog-titlebar").clone(!0,!0).appendTo(t),t.css({"float":this.options.minimizeLocation,margin:1}),e.append(t),i(this.element[0]).data("dialog-extend-minimize-controls",t),i(this.element[0]).dialog("option","draggable")&&t.removeClass("ui-draggable"),t.css({height:"auto",width:o,position:"static"}),i(this.element[0]).on("dialogbeforeclose",this._minimize_restoreOnClose).dialog("widget").hide(),this._setState("minimized"),this._trigger("minimize")},_restore_minimized:function(){return i(this.element[0]).dialog("widget").show(),i(this.element[0]).off("dialogbeforeclose",this._minimize_restoreOnClose),i(this.element[0]).data("dialog-extend-minimize-controls").remove(),i(this.element[0]).removeData("dialog-extend-minimize-controls")},_initStyles_minimize:function(){var t;return i(".dialog-extend-minimize-css").length?void 0:(t="",t+='<style class="dialog-extend-minimize-css" type="text/css">',t+=".ui-dialog .ui-dialog-titlebar-minimize { width: 19px; height: 18px; }",t+=".ui-dialog .ui-dialog-titlebar-minimize span { display: block; margin: 1px; }",t+=".ui-dialog .ui-dialog-titlebar-minimize:hover,",t+=".ui-dialog .ui-dialog-titlebar-minimize:focus { padding: 0; }",t+="</style>",i(t).appendTo("body"))},_verifyOptions_minimize:function(){var t;return!this.options.minimizeLocation||"left"!==(t=this.options.minimizeLocation)&&"right"!==t?(i.error("jQuery.dialogExtend Error : Invalid <minimizeLocation> value '"+this.options.minimizeLocation+"'"),this.options.minimizeLocation="left"):void 0},_minimize_restoreOnClose:function(){return i(this).dialogExtend("restore")}})}.call(this);window.initBimViewer = function(context) {const EVENT_SEARCH_ISSUE_LIST = 'vitro.search.issue.list';
969
+ const EVENT_ISSUE_LIST_REFRESH = 'vitro.issue.list.refresh';
970
+ const EVENT_ISSUE_LIST_SELECT_ITEM = 'vitro.issue.list.select.item';
971
+ const PANE_LEFT_MIN_WIDTH = 150;
972
+ const PANE_RIGHT_MIN_WIDTH = 200;
878
973
 
879
- setPropertyBDSets(objectId);
974
+ var notesDescriptionVisibleList = {};
880
975
 
881
- return false;
976
+ BIMAnnotation.GetNote = (callback) => {
977
+ callback([]);
882
978
  }
883
979
 
884
- function getPickResultModel(pickResult) {
885
- var modelId = getPickResultModelId(pickResult);
886
- if (modelId) {
887
- if (window.model.id == modelId) {
888
- return window.model;
889
- } else if (window.model2 && window.model2.id == modelId) {
890
- return window.model2;
891
- } else {
892
- return false;
893
- }
894
- } else {
895
- return false;
896
- }
897
- }
980
+ function saveNote(pickResult) {
898
981
 
899
- function getPickResultModelId(pickResult) {
900
- if (pickResult.entity.model && pickResult.entity.model.id) {
901
- return pickResult.entity.model.id;
902
- } else if (pickResult.entity._owner && pickResult.entity._owner.id) {
903
- return pickResult.entity._owner.id;
904
- } else {
905
- return false;
906
- }
907
982
  }
908
983
 
909
- function getPropertyValue(property) {
910
- if (property.valueBool != null && property.valueBool != undefined) {
911
- return property.valueBool;
912
- }
913
- else if (property.valueInt != null && property.valueInt != undefined) {
914
- return property.valueInt;
915
- }
916
- else if (property.valueText != null && property.valueText != undefined) {
917
- return property.valueText;
918
- }
919
- else if (property.valueReal != null && property.valueReal != undefined) {
920
- const normalized = property.valueReal.replace(',', '.').trim();
921
- const num = Number(normalized);
922
- if (!isNaN(num)) {
923
- if (Math.abs(num) < 1) {
924
- return Number(num.toPrecision(3));
925
- } else {
926
- return Number(num.toFixed(2));
927
- }
928
- }
929
- return property.valueReal;
930
- }
931
- }
984
+ function createMarkupData(pickResult) {
985
+ let markup = {};
986
+ markup.worldPos = [];
987
+ markup.worldPos.push(pickResult._worldPos[0]);
988
+ markup.worldPos.push(pickResult._worldPos[1]);
989
+ markup.worldPos.push(pickResult._worldPos[2]);
932
990
 
933
- function convertProperty(data) {
934
- let groups = [];
991
+ var eye = viewer.camera.eye;
992
+ markup.eye = [];
993
+ markup.eye.push(eye[0]);
994
+ markup.eye.push(eye[1]);
995
+ markup.eye.push(eye[2]);
935
996
 
936
- for (let property of data) {
937
- let existingGroups = groups.filter(group => group.name == property.groupName);
938
- if (existingGroups.length > 0) {
939
- existingGroups[0].properties.push({ name: property.name, value: getPropertyValue(property) });
940
- }
941
- else {
942
- let newGroup = {
943
- name: property.groupName,
944
- properties: [],
945
- };
946
- newGroup.properties.push({ name: property.name, value: getPropertyValue(property) });
997
+ var look = viewer.camera.look;
998
+ markup.look = [];
999
+ markup.look.push(look[0]);
1000
+ markup.look.push(look[1]);
1001
+ markup.look.push(look[2]);
947
1002
 
1003
+ var up = viewer.camera.up;
1004
+ markup.up = [];
1005
+ markup.up.push(up[0]);
1006
+ markup.up.push(up[1]);
1007
+ markup.up.push(up[2]);
948
1008
 
949
- groups.push(newGroup);
950
- }
1009
+ if (pickResult.entity && pickResult.entity.id) {
1010
+ markup.entity = pickResult.entity.id;
951
1011
  }
952
1012
 
953
- return groups;
1013
+ return markup;
954
1014
  }
955
1015
 
956
- function setPropertyBDSets(id) {
957
- const html = [];
1016
+ function addIssue(itemId, data) {
1017
+ context.onCreateIssue(itemId, data);
958
1018
 
959
- html.push('<div class="element-attributes">');
960
- html.push('</div>');
1019
+ hidePropInspector();
1020
+ expandSidebarIssueDetail();
1021
+ }
961
1022
 
962
- viewer.scene.canvas.spinner.processes++;
1023
+ function createAnnotationByClick(pickResult) {
1024
+ let data = createMarkupData(pickResult);
1025
+
1026
+ if (data.entity) {
1027
+ viewer.scene.canvas.spinner.processes++;
1028
+
1029
+ const callback = (modelInfo, status, jqXHR) => {
1030
+
1031
+ const itemId = modelInfo?.itemId ? modelInfo?.itemId : context.file.id;
1032
+
1033
+ addIssue(itemId, data);
963
1034
 
964
- BIMModel.GetPropertyList(id,
965
- (data) => {
966
- const propertySets = convertProperty(data);
967
- addPropertySet(propertySets, html);
968
- viewer.scene.canvas.spinner.processes--;
969
- },
970
- (error) => {
971
1035
  viewer.scene.canvas.spinner.processes--;
972
- }
973
- );
1036
+ };
974
1037
 
975
- $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
976
- $('.xeokit-accordion-container').accordion({
977
- collapsible: true,
978
- heightStyle: "content"
979
- });
980
- showPropInspector();
981
- }
1038
+ const error = () => {
1039
+ viewer.scene.canvas.spinner.processes--;
1040
+ };
982
1041
 
983
- function addPropertySet(propertySets, html) {
984
- if (!propertySets || propertySets.length == 0) {
985
- html.push('<p class="subtitle">No properties sets found.</p>');
1042
+ BIMModel.GetModel(data.entity, callback, error);
986
1043
  }
987
1044
  else {
988
- html.push('<div class="xeokit-accordion">');
989
- for (let i = 0, len = propertySets.length; i < len; i++) {
990
- const propertySet = propertySets[i];
991
- const properties = propertySet.properties || propertySet.p || [];
992
- if (properties.length > 0) {
993
- html.push('<div class="xeokit-accordion-container">' +
994
- '<h3><span>' + (propertySet.name ? propertySet.name : propertySet.propertySetName) + '</span></h3>' +
995
- '<div class="xeokit-accordion-panel">' +
996
- '<table class="xeokit-table"><tbody>'
997
- );
998
- for (let i = 0, len = properties.length; i < len; i++) {
999
- const property = properties[i];
1000
- html.push('<tr><td class="td1">' + (property.Name || property.name || property.label) + ':</td><td class="td2">' + (property.v || property.Value || property.value) + '</td></tr>');
1001
- }
1002
- html.push('</tbody></table>' +
1003
- '</div>' +
1004
- '</div>');
1005
- } else {
1006
- html.push('<p class="subtitle">No properties sets found.</p>');
1007
- }
1008
- }
1009
- html.push('</div>');
1045
+ addIssue(context.file.id, data);
1010
1046
  }
1011
- $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
1012
- $('.xeokit-accordion-container').accordion({
1013
- collapsible: true,
1014
- heightStyle: "content"
1015
- });
1016
- showPropInspector();
1017
1047
  }
1018
1048
 
1019
- function setPropertySets(metaObject, dictionaryName = []) {
1020
- const html = [];
1021
- var propertySets = metaObject.propertySets || metaObject.ps;
1022
-
1023
- html.push('<div class="element-attributes">');
1024
- if (!metaObject) {
1025
- html.push('<p class="subsubtitle">No object selected</p>');
1026
- } else {
1027
- html.push('<table class="xeokit-table">');
1028
- html.push('<tr><td class="td1">Name:</td><td class="td2">' + metaObject.name + '</td></tr>');
1029
- if (metaObject.type) {
1030
- html.push('<tr><td class="td1">Class:</td><td class="td2">' + metaObject.type + '</td></tr>');
1031
- }
1032
- html.push('<tr><td class="td1">UUID:</td><td class="td2">' + metaObject.id + '</td></tr>');
1033
- html.push('</table>');
1049
+ function bindBtnToggleCreateNotes() {
1050
+ $(document).on('click', '#btnCreateNotes', function () {
1051
+ $(this).toggleClass('toggled');
1034
1052
 
1035
- addPropertySet(propertySets, html);
1036
- }
1037
- $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
1038
- $('.xeokit-accordion-container').accordion({
1039
- collapsible: true,
1040
- heightStyle: "content"
1053
+ if ($(this).hasClass('toggled')) {
1054
+ $('#btnCreateSectionPlan').removeClass('toggled');
1055
+ disableSectionPlanByClick();
1056
+ disableAngleMeasurementsByClick();
1057
+ disableDistanceMeasurementsByClick();
1058
+ showAnnotationMarkers();
1059
+ $('#btnToggleNotes').removeClass('show');
1060
+ collapseSidebarNotes();
1061
+ $('#btnToggleSidebarNotes').removeClass('toggled');
1062
+ annotationByClick = true;
1063
+ } else {
1064
+ annotationByClick = false;
1065
+ collapseSidebarIssueDetail();
1066
+ }
1067
+ });
1068
+ }
1069
+
1070
+ function bindBtnToggleSidebarNotes() {
1071
+ $(document).on('click', '#btnToggleSidebarNotes', function () {
1072
+ $(this).toggleClass('toggled');
1073
+
1074
+ if ($(this).hasClass('toggled')) {
1075
+ $('#btnCreateNotes').removeClass('toggled');
1076
+ annotationByClick = false;
1077
+ if (!$('.sidebar').is(':visible')) {
1078
+ initSidebarNotes();
1079
+ expandSidebarNotes();
1080
+ }
1081
+ } else {
1082
+ collapseSidebarNotes();
1083
+ }
1084
+ });
1085
+ }
1086
+
1087
+ function bindSidebarNotesClose() {
1088
+ $('.sidebar-close').on('click', function () {
1089
+ $('#btnToggleSidebarNotes').removeClass('toggled');
1090
+ collapseSidebarNotes();
1091
+ });
1092
+ }
1093
+
1094
+ function expandSidebarNotes() {
1095
+ hidePropInspector();
1096
+ collapseSidebarIssueDetail();
1097
+
1098
+ $('#sidebarWrap').show();
1099
+ $('#navCubeCanvas').css('right', $('#sidebarWrap').width() + 10);
1100
+ $('#sectionPlanesOverviewCanvas').css('right', $('#sidebarWrap').width() + 10);
1101
+ var body = $('body');
1102
+ var bodyScrollWidth = body[0].offsetWidth - body[0].scrollWidth;
1103
+ var vScrollWidth = bodyScrollWidth ? bodyScrollWidth : 0;
1104
+ $('.sidebar').css('right', (vScrollWidth + 'px')).show("slide", { direction: "right" }, 200);
1105
+ body.addClass('sidebar-expanded');
1106
+ }
1107
+
1108
+ function getMarkupData(item) {
1109
+
1110
+ let markup = JSON.parse(item.fieldValueMap.markup);
1111
+ var options = {
1112
+ id: item.fieldValueMap.item_id,
1113
+ creator: item.insUserName,
1114
+ worldPos: markup.worldPos,
1115
+ eye: markup.eye, // need for camera fly on sidebar click
1116
+ look: markup.look, // need for camera fly on sidebar click
1117
+ up: markup.up, // need for camera fly on sidebar click
1118
+ occludable: false,
1119
+ markerShown: true,
1120
+ labelShown: false,
1121
+ version: '',
1122
+ fileVersionPath: '',
1123
+ values: {
1124
+ glyph: item.fieldValueMap.item_id,
1125
+ title: item.fieldValueMap.name,
1126
+ description: item.fieldValueMap.description,
1127
+ markerBGColor: item.fieldValueMap.task_status?.fieldValueMap?.color || '#2d9cdb',
1128
+ imageSrc: ''
1129
+ }
1130
+ };
1131
+
1132
+ if (markup.entity) {
1133
+ options.entity = viewer.scene.objects[markup.entity];
1134
+ }
1135
+
1136
+ return options;
1137
+ }
1138
+
1139
+ function bindUpdatePage() {
1140
+ if (context.deleteIssueEvent) {
1141
+ window.addEventListener(context.deleteIssueEvent, updatePage);
1142
+ }
1143
+
1144
+ if (context.updateIssueEvent) {
1145
+ window.addEventListener(context.updateIssueEvent, updatePage);
1146
+ }
1147
+ }
1148
+
1149
+ bindUpdatePage();
1150
+
1151
+ function updatePage(e) {
1152
+ if (e.type === context.updateIssueEvent) {
1153
+ const item = e.detail.itemList[0];
1154
+ if (item.fieldValueMap?.markup) {
1155
+ const data = getMarkupData(item);
1156
+ annotations.destroyAnnotation(item.fieldValueMap.item_id);
1157
+ createNote(data);
1158
+ setTimeout(function () {
1159
+ if (isNoteDescriptionVisible(data.id)) {
1160
+ annotations.annotations[data.id].setLabelShown(true);
1161
+ } else {
1162
+ annotations.annotations[data.id].setLabelShown(false);
1163
+ }
1164
+ }, 10);
1165
+ }
1166
+
1167
+ if (!$('#btnToggleSidebarNotes').hasClass('toggled')) {
1168
+ refreshIssueList();
1169
+ }
1170
+ }
1171
+
1172
+ if (e.type === context.deleteIssueEvent) {
1173
+
1174
+ let item = e.detail.itemList[0];
1175
+ annotations.destroyAnnotation(item.fieldValueMap.item_id);
1176
+ refreshIssueList();
1177
+ if (isNoteDescriptionVisible(item.fieldValueMap.item_id)) {
1178
+ removeFromNotesDescriptionVisibleList(item.fieldValueMap.item_id);
1179
+ }
1180
+ }
1181
+ }
1182
+
1183
+ function refreshIssueList() {
1184
+ const event = new CustomEvent(EVENT_ISSUE_LIST_REFRESH, { detail: {} });
1185
+ window.dispatchEvent(event);
1186
+ }
1187
+
1188
+ function goToNoteMarker(issue) {
1189
+ if (!$('#btnCreateNotes').hasClass('toggled')) {
1190
+ hideNotesDescription();
1191
+ clearNotesDesriptionVisibleList();
1192
+ addToNotesDescriptionVisibleList(issue.id);
1193
+ var annotation = annotations.annotations[issue.id];
1194
+ viewer.cameraFlight.flyTo(annotation);
1195
+ annotation.occludable = false;
1196
+ annotation.setLabelShown(true);
1197
+ highlightSidebarNote(issue.id);
1198
+ }
1199
+ }
1200
+
1201
+ function onIssueShowMoreClick(issue) {
1202
+ const listId = issue.item.listId;
1203
+ const itemId = {
1204
+ id: issue.item.id,
1205
+ contentTypeId: issue.item.contentTypeId,
1206
+ listId: listId,
1207
+ parentId: issue.item.parentId,
1208
+ siteId: issue.item.siteId
1209
+ };
1210
+
1211
+ let event = new CustomEvent('vitro.item.changed', {
1212
+ detail: {
1213
+ itemIdList: [itemId],
1214
+ listId: listId
1215
+ }
1216
+ });
1217
+ window.dispatchEvent(event);
1218
+ collapseSidebarNotes();
1219
+ hidePropInspector();
1220
+ expandSidebarIssueDetail();
1221
+ $('#btnToggleSidebarNotes').removeClass('toggled');
1222
+ }
1223
+
1224
+ function collapseSidebarNotes() {
1225
+ $('#sidebarWrap').hide();
1226
+ $('#navCubeCanvas').css('right', 10);
1227
+ $('#sectionPlanesOverviewCanvas').css('right', 10);
1228
+ $('.sidebar').hide();
1229
+ $('body').removeClass('sidebar-expanded');
1230
+ }
1231
+
1232
+ function initSidebarNotes() {
1233
+ context.initIssueList(goToNoteMarker, onIssueShowMoreClick);
1234
+ }
1235
+
1236
+ function expandSidebarIssueDetail() {
1237
+ $('#issueDetail').show();
1238
+ $('#navCubeCanvas').css('right', $('#issueDetail').width() + 10);
1239
+ $('#sectionPlanesOverviewCanvas').css('right', $('#issueDetail').width() + 10);
1240
+ $('body').addClass('sidebar-expanded');
1241
+ }
1242
+
1243
+ function collapseSidebarIssueDetail() {
1244
+ $('#issueDetail').hide();
1245
+ $('#navCubeCanvas').css('right', 10);
1246
+ $('#sectionPlanesOverviewCanvas').css('right', 10);
1247
+ $('body').removeClass('sidebar-expanded');
1248
+ }
1249
+
1250
+ //------------------------------------------------------------------------------------------------------------------
1251
+ // Load Annotations
1252
+ //------------------------------------------------------------------------------------------------------------------
1253
+ function createSidebarNotesItemHeader(noteData) {
1254
+
1255
+ }
1256
+
1257
+ function hidePropInspector() {
1258
+ $('#propInspector').hide();
1259
+ setPositionNavCubeCanvas(0);
1260
+ setPositionSectionPlanesOverviewCanvas(0);
1261
+ }
1262
+
1263
+ function onAnnotationsMarkerClickedHandler(annotation) {
1264
+ showNoteDesc(annotation.id);
1265
+ if (annotation.getLabelShown()) {
1266
+ removeFromNotesDescriptionVisibleList(annotation.id);
1267
+ } else {
1268
+ addToNotesDescriptionVisibleList(annotation.id);
1269
+ }
1270
+ annotation.occludable = false;
1271
+ annotation.setLabelShown(!annotation.getLabelShown());
1272
+ viewer.cameraFlight.flyTo(annotation);
1273
+ }
1274
+
1275
+ function doGetNoteOptions(noteId, creator, pickResult, glyph, title, description, imageSrc, bgColor) {
1276
+ var options = {
1277
+ id: noteId,
1278
+ creator: creator,
1279
+ pickResult: pickResult,
1280
+ worldPos: pickResult.worldPos,
1281
+ eye: viewer.camera.eye, // need for camera fly on sidebar click
1282
+ look: viewer.camera.look, // need for camera fly on sidebar click
1283
+ up: viewer.camera.up, // need for camera fly on sidebar click
1284
+ occludable: false,
1285
+ markerShown: true,
1286
+ labelShown: false,
1287
+ version: fileVersion,
1288
+ fileVersionPath: fileVersionPath,
1289
+ values: {
1290
+ glyph: glyph,
1291
+ title: title,
1292
+ description: description,
1293
+ markerBGColor: bgColor,
1294
+ imageSrc: imageSrc
1295
+ }
1296
+ };
1297
+
1298
+ if (pickResult.entity && pickResult.entity.id) {
1299
+ options.entity = pickResult.entity.id;
1300
+ }
1301
+
1302
+ return options;
1303
+ }
1304
+
1305
+ function bindToggleNotesDescription() {
1306
+ $(document).on('click', '#btnToggleNotesDescription', function () {
1307
+ $(this).toggleClass('show');
1308
+ if ($(this).hasClass('show')) {
1309
+ hideNotesDescription();
1310
+ } else {
1311
+ showNotesDescription();
1312
+ }
1313
+ });
1314
+ }
1315
+
1316
+ function hideNotesDescription() {
1317
+ if (annotations?.annotations) {
1318
+ $.each(annotations.annotations, function () {
1319
+ this.setLabelShown(false);
1320
+ });
1321
+ }
1322
+ clearNotesDesriptionVisibleList();
1323
+ }
1324
+
1325
+ function addToNotesDescriptionVisibleList(itemKey) {
1326
+ if (!notesDescriptionVisibleList.hasOwnProperty(itemKey)) {
1327
+ notesDescriptionVisibleList[itemKey] = true;
1328
+ }
1329
+ }
1330
+
1331
+ function removeFromNotesDescriptionVisibleList(itemKey) {
1332
+ if (notesDescriptionVisibleList.hasOwnProperty(itemKey)) {
1333
+ delete notesDescriptionVisibleList[itemKey];
1334
+ }
1335
+ }
1336
+
1337
+ function clearNotesDesriptionVisibleList() {
1338
+ notesDescriptionVisibleList = {};
1339
+ }
1340
+
1341
+ function isNoteDescriptionVisible(itemKey) {
1342
+ return notesDescriptionVisibleList.hasOwnProperty(itemKey);
1343
+ }
1344
+
1345
+ function showNotesDescription() {
1346
+ if (annotations?.annotations) {
1347
+ $.each(annotations.annotations, function () {
1348
+ addToNotesDescriptionVisibleList(this.id);
1349
+ this.occludable = false;
1350
+ this.setLabelShown(true);
1351
+ });
1352
+ }
1353
+ }
1354
+
1355
+ function initIssueDetailResizable() {
1356
+ initResizable($('#issueDetail'), 'w', PANE_RIGHT_MIN_WIDTH, onIssueDetailResizeHandler, onIssueDetailResizeEndHandler);
1357
+ }
1358
+
1359
+ function addToTreeView(model, sceneModelId) {
1360
+ if (treeView && treeView._rootNodes.length > 0) {
1361
+ const callback = (metaObjects, status, jqXHR) => {
1362
+ const metaModel = viewer.metaScene.metaModels[sceneModelId];
1363
+
1364
+ treeView.addObjectsToMetaModel(metaObjects, metaModel);
1365
+ treeView.addModel(sceneModelId);
1366
+
1367
+ viewer.scene.canvas.spinner.processes--;
1368
+ };
1369
+
1370
+ const error = () => {
1371
+ viewer.scene.canvas.spinner.processes--;
1372
+ };
1373
+
1374
+ BIMModel.GetElementChildList(model.FileItemId, model.FileVersion, "-1", false, null, callback, error);
1375
+ }
1376
+ }
1377
+
1378
+ function bindBtnAddModel() {
1379
+ $(document).on('click', '#btnAddModel', function () {
1380
+ context.showItemSelectDialog().then(itemIdList => {
1381
+ itemIdList.forEach(itemId =>
1382
+ {
1383
+ BIMCommon.GetFileItem(itemId, undefined, function (modelId) {
1384
+ context.getItem(modelId).then(itemAttach => {
1385
+
1386
+ context.getItem(itemId).then(item =>
1387
+ {
1388
+ context.addItem(item);
1389
+ });
1390
+
1391
+ const filePath = context.getFilePath(itemAttach.id);
1392
+ const fileName = context.file.fieldValueMap?.name;
1393
+ const model = new BIMCommon.VitroModel(itemId, undefined, filePath, fileName);
1394
+
1395
+ BIMCommon.ModelList.push(model);
1396
+
1397
+ const sceneModel = doLoadModel(viewer, xktLoader, model, false);
1398
+ addToTreeView(model, sceneModel.id);
1399
+
1400
+ $('#btnToggleCompare').hide();
1401
+ })
1402
+
1403
+ }, function () {
1404
+ alert("The file is being processed");
1405
+ });
1406
+
1407
+ })
1408
+ });
1409
+ });
1410
+ }
1411
+
1412
+ function bindUpdateDocumentMarkupList() {
1413
+ window.addEventListener(EVENT_SEARCH_ISSUE_LIST, updateDocumentMarkupList);
1414
+ }
1415
+
1416
+ function updateDocumentMarkupList(e) {
1417
+ annotations.clear();
1418
+ if (e.detail.issueList && e.detail.issueList.length) {
1419
+ e.detail.issueList.map(issue => {
1420
+ let data = getMarkupData(issue.item);
1421
+ data.occludable = false;
1422
+ annotations.createAnnotation(data);
1423
+ });
1424
+ }
1425
+ }
1426
+
1427
+ bindUpdateDocumentMarkupList();
1428
+
1429
+ function highlightSidebarNote(noteId) {
1430
+ var noteWrap = $('#vitro-issue-tile-' + noteId);
1431
+
1432
+ if (!noteWrap.position()) {
1433
+ setTimeout(() => {
1434
+ highlightSidebarNote(noteId);
1435
+ }, 500);
1436
+
1437
+ return;
1438
+ }
1439
+
1440
+ selectIssueListItem(noteId);
1441
+ }
1442
+
1443
+ function selectIssueListItem(itemId) {
1444
+ const event = new CustomEvent(EVENT_ISSUE_LIST_SELECT_ITEM, { detail: { itemId: itemId } });
1445
+ window.dispatchEvent(event);
1446
+ }
1447
+
1448
+ function setSettings(settings) {
1449
+ const settingsString = settings ? JSON.stringify(settings) : '';
1450
+ context.setSettingsToLocalStorage(settingsString);
1451
+ }
1452
+
1453
+ function getSettings() {
1454
+ const settings = context.getSettingsFromLocalStorage();
1455
+ return settings ? JSON.parse(settings) : {};
1456
+ }
1457
+
1458
+ function setPaneRightSettings(width) {
1459
+ const settings = getSettings();
1460
+ settings.rightPaneWidth = width;
1461
+ setSettings(settings);
1462
+ }
1463
+
1464
+ function setPaneLeftSettings(width) {
1465
+ const settings = getSettings();
1466
+ settings.leftPaneWidth = width;
1467
+ setSettings(settings);
1468
+ }
1469
+
1470
+ function initPaneWidth() {
1471
+ const settings = getSettings();
1472
+ setWidthPaneRight(settings.rightPaneWidth);
1473
+ setWidthPaneLeft(settings.leftPaneWidth);
1474
+ }
1475
+
1476
+ function setWidthPaneRight(width) {
1477
+ if (width) {
1478
+ $('#sidebarWrap').width(width);
1479
+ $('#issueDetail').width(width);
1480
+ $('#propInspector').width(width);
1481
+ }
1482
+ }
1483
+
1484
+ function setWidthPaneLeft(width) {
1485
+ if (width) {
1486
+ $('#treeViewContainerWrap').width(width);
1487
+ $('#storeyViewsSidebar').width(width);
1488
+ }
1489
+ }
1490
+
1491
+ function setPositionSectionPlanesOverviewCanvas(width) {
1492
+ $('#sectionPlanesOverviewCanvas').css('right', width + 10);
1493
+ }
1494
+
1495
+ function setPositionNavCubeCanvas(width) {
1496
+ $('#navCubeCanvas').css('right', width + 10);
1497
+ }
1498
+
1499
+ function initResizable(element, handles, minWidth, resizeHadler, onResizeEndHadler) {
1500
+ element.resizable({
1501
+ handles: handles,
1502
+ minWidth: minWidth,
1503
+ resize: function (event, ui) {
1504
+ if (typeof resizeHadler === 'function') {
1505
+ resizeHadler(element.width());
1506
+ }
1507
+ },
1508
+ stop: function (event, ui) {
1509
+ if (typeof onResizeEndHadler === 'function') {
1510
+ onResizeEndHadler(event, ui);
1511
+ }
1512
+ }
1513
+ });
1514
+ }
1515
+
1516
+ function onIssueDetailResizeHandler(width) {
1517
+ onPaneRightResizeHandler(width);
1518
+ };
1519
+
1520
+ function onPaneRightResizeHandler(width) {
1521
+ setPositionNavCubeCanvas(width);
1522
+ setPositionSectionPlanesOverviewCanvas(width);
1523
+ }
1524
+
1525
+ function onIssueDetailResizeEndHandler(event, ui) {
1526
+ $('#propInspector').width(ui.size.width);
1527
+ $('#sidebarWrap').width(ui.size.width);
1528
+ setPaneRightSettings(ui.size.width);
1529
+ }
1530
+
1531
+ function initTreeViewPanelResizable() {
1532
+ initResizable($('#treeViewContainerWrap'), 'e', PANE_LEFT_MIN_WIDTH, false, onTreeViewResizeEndHandler);
1533
+ }
1534
+
1535
+ function onTreeViewResizeEndHandler(event, ui) {
1536
+ const width = ui.size.width - $('#treeViewContainerWrap > .ui-resizable-handle').width();
1537
+ $('#storeyViewsSidebar').width(width);
1538
+ setPaneLeftSettings(width);
1539
+ }
1540
+
1541
+ function initStoreyViewResizable() {
1542
+ initResizable($('#storeyViewsSidebar'), 'e', PANE_LEFT_MIN_WIDTH, false, onStoreyViewResizeEndHandler);
1543
+ }
1544
+
1545
+ function onStoreyViewResizeEndHandler(event, ui) {
1546
+ $('#treeViewContainerWrap').width(ui.size.width);
1547
+ setPaneLeftSettings(ui.size.width);
1548
+ }
1549
+
1550
+ function initPropertySetsResizable() {
1551
+ initResizable($('#propInspector'), 'w', PANE_RIGHT_MIN_WIDTH, onPropsInspectorResizeHandler, onPropsInspectorResizeEndHandler);
1552
+ }
1553
+
1554
+ function onPropsInspectorResizeHandler(width) {
1555
+ onPaneRightResizeHandler(width);
1556
+ };
1557
+
1558
+ function onPropsInspectorResizeEndHandler(event, ui) {
1559
+ $('#issueDetail').width(ui.size.width);
1560
+ $('#sidebarWrap').width(ui.size.width);
1561
+ setPaneRightSettings(ui.size.width);
1562
+ }
1563
+
1564
+ function initSidebarResizable() {
1565
+ initResizable($('#sidebarWrap'), 'w', PANE_RIGHT_MIN_WIDTH, onIssueListResizeHandler, onIssueListResizeEndHandler);
1566
+ }
1567
+
1568
+ function onIssueListResizeHandler(width) {
1569
+ onPaneRightResizeHandler(width);
1570
+ }
1571
+
1572
+ function onIssueListResizeEndHandler(event, ui) {
1573
+ $('#issueDetail').width(ui.size.width);
1574
+ $('#propInspector').width(ui.size.width);
1575
+ setPaneRightSettings(ui.size.width);
1576
+ }
1577
+
1578
+ function getPaneRightPosition(width) {
1579
+ return ($('body').width() - width);
1580
+ }
1581
+
1582
+ function showPropInspector() {
1583
+ $('#propInspector').show();
1584
+ const width = $('#propInspector').width();
1585
+ setPositionNavCubeCanvas(width);
1586
+ setPositionSectionPlanesOverviewCanvas(width);
1587
+ }
1588
+ //------------------------------------------------------------------------------------------------------------------
1589
+ // MAIN Viewer
1590
+ //------------------------------------------------------------------------------------------------------------------
1591
+
1592
+
1593
+ //------------------------------------------------------------------------------------------------------------------
1594
+ // Create a Viewer
1595
+ //------------------------------------------------------------------------------------------------------------------
1596
+ const viewer = new Viewer({
1597
+ canvasId: "xeokitCanvas",
1598
+ transparent: true
1599
+ });
1600
+ //------------------------------------------------------------------------------------------------------------------
1601
+ // Arrange the camera
1602
+ //------------------------------------------------------------------------------------------------------------------
1603
+ function setCameraSetting(viewer) {
1604
+ viewer.camera.eye = [-5.02, 2.22, 15.09];
1605
+ viewer.camera.look = [4.97, 2.79, 9.89];
1606
+ viewer.camera.up = [-0.05, 0.99, 0.02];
1607
+ viewer.camera.project.fov = 70;
1608
+
1609
+ viewer.camera.zoom(5);
1610
+
1611
+ viewer.cameraControl.followPointer = true;
1612
+ }
1613
+
1614
+ setCameraSetting(viewer);
1615
+
1616
+ // For TreeView
1617
+ function setViewerSetting(viewer) {
1618
+ viewer.scene.xrayMaterial.fill = true;
1619
+ viewer.scene.xrayMaterial.fillAlpha = 0.1;
1620
+ viewer.scene.xrayMaterial.fillColor = [0, 0, 0];
1621
+ viewer.scene.xrayMaterial.edgeAlpha = 0.3;
1622
+ viewer.scene.xrayMaterial.edgeColor = [0, 0, 0];
1623
+
1624
+ viewer.scene.highlightMaterial.fill = true;
1625
+ viewer.scene.highlightMaterial.edges = true;
1626
+ viewer.scene.highlightMaterial.fillAlpha = 0.1;
1627
+ viewer.scene.highlightMaterial.edgeAlpha = 0.1;
1628
+ viewer.scene.highlightMaterial.edgeColor = [1, 1, 0];
1629
+
1630
+ viewer.scene.selectedMaterial.fill = true;
1631
+ viewer.scene.selectedMaterial.edges = true;
1632
+ viewer.scene.selectedMaterial.fillColor = [0.8627, 0.9333, 1.0];
1633
+ viewer.scene.selectedMaterial.fillAlpha = 0.5;
1634
+ viewer.scene.selectedMaterial.edgeAlpha = 0.6;
1635
+ viewer.scene.selectedMaterial.edgeColor = [0, 1, 1];
1636
+ }
1637
+
1638
+ setViewerSetting(viewer);
1639
+
1640
+ //------------------------------------------------------------------------------------------------------------------
1641
+ // NavCube
1642
+ //------------------------------------------------------------------------------------------------------------------
1643
+
1644
+ const navCube = new NavCubePlugin(viewer, {
1645
+ canvasId: "navCubeCanvas",
1646
+ visible: true, // Initially visible (default)
1647
+ cameraFly: true, // Fly camera to each selected axis/diagonal
1648
+ cameraFitFOV: 45, // How much field-of-view the scene takes once camera has fitted it to view
1649
+ cameraFlyDuration: 0.5 // How long (in seconds) camera takes to fly to each new axis/diagonal
1650
+ });
1651
+
1652
+ //------------------------------------------------------------------------------------------------------------------
1653
+ // Add a XKTLoaderPlugin - we'll use this to load the model geometry and IFC metadata
1654
+ //------------------------------------------------------------------------------------------------------------------
1655
+
1656
+ const xktLoader = new XKTLoaderPlugin(viewer);
1657
+
1658
+
1659
+ xktLoader.globalizeObjectIds = false; // For multiple models in TreeView
1660
+
1661
+
1662
+ //------------------------------------------------------------------------------------------------------------------
1663
+ // Load Model
1664
+ //------------------------------------------------------------------------------------------------------------------
1665
+ function doLoadModel(viewer, xktLoader, srcModel, isMain) {
1666
+ const model = xktLoader.load({
1667
+ id: Date.now(),
1668
+ src: srcModel.FilePath,
1669
+ edges: true,
1670
+ backfaces: true,
1041
1671
  });
1042
- showPropInspector();
1672
+
1673
+ srcModel.id = model.id;
1674
+
1675
+ model.vitroModel = srcModel;
1676
+ model.isLarge = true;
1677
+ model.isMain = isMain;
1678
+
1679
+ model.on('loaded', () => {
1680
+ if (isMain) {
1681
+ ViewFitAll(viewer);
1682
+ //------------------------------------------------------------------------------------------------------------------
1683
+ // Load Small Scene
1684
+ //------------------------------------------------------------------------------------------------------------------
1685
+ model.vitroModelLoader = new VitroXKTLoaderPlugin(viewer);
1686
+
1687
+ model.vitroModelLoader.largeModel = model;
1688
+ model.vitroModelLoader.startSmallLoad = true;
1689
+
1690
+ $('#btnToggleSectionPlan').addClass('toggled');
1691
+ }
1692
+ else {
1693
+ viewer.scene.fire("reloadSmallScenes");
1694
+ }
1695
+
1696
+ //------------------------------------------------------------------------------------------------------------------
1697
+ // Create some Annotations
1698
+ //------------------------------------------------------------------------------------------------------------------
1699
+ //loadAnnotations();
1700
+ });
1701
+
1702
+ if (isPointCloud(srcModel.FileName)) {
1703
+ var navPlugin = viewer._plugins.find((p) => p.id == 'FastNav');
1704
+
1705
+ if (navPlugin) {
1706
+ navPlugin.hideTransparentObjects = false;
1707
+ }
1708
+ }
1709
+
1710
+ return model;
1043
1711
  }
1044
1712
 
1045
- function bindPropInspectorClose() {
1046
- $('.prop-inspector-close').on('click', function () {
1047
- hidePropInspector();
1048
- })
1713
+ function isPointCloud(filename) {
1714
+ const ext = filename.split('.').pop().toLowerCase();
1715
+ return ext === 'las' || ext === 'laz';
1716
+ }
1717
+
1718
+ function ViewFitAll(viewer) {
1719
+ const aabb = viewer.scene.getAABB({});
1720
+ const diag = math.getAABB3Diag(aabb);
1721
+
1722
+ if (diag > viewer.camera.perspective.far) {
1723
+ viewer.camera.perspective.far = diag;
1724
+ }
1725
+
1726
+ viewer.cameraFlight.flyTo({
1727
+ projection: "perspective",
1728
+ aabb: aabb,
1729
+ duration: 0.5
1730
+ });
1049
1731
  }
1050
1732
 
1051
1733
  //------------------------------------------------------------------------------------------------------------------
1052
- // PropertySets resizable
1734
+ // FastNavPlugin
1053
1735
  //------------------------------------------------------------------------------------------------------------------
1054
- function initPropertySetsResizable() {
1055
- $('#propInspector').resizable({
1056
- handles: "w",
1057
- minWidth: 150
1736
+
1737
+ function initFastNavPlugin(viewer) {
1738
+ const fastNavPlugin = new FastNavPlugin(viewer, {
1739
+ hideEdges: true, // Don't show edges while we interact (default is true)
1740
+ hideSAO: true, // Don't show ambient shadows while we interact (default is true)
1741
+ hideColorTexture: true, // No color textures while we interact (default is true)
1742
+ hidePBR: true, // No physically-based rendering while we interact (default is true)
1743
+ hideTransparentObjects: true, // Hide transparent objects while we interact (default is false)
1744
+ scaleCanvasResolution: true, // Scale canvas resolution while we interact (default is false)
1745
+ scaleCanvasResolutionFactor: 0.5, // Factor by which we scale canvas resolution when we interact (default is 0.6)
1746
+ delayBeforeRestore: true, // When we stop interacting, delay before restoring normal render (default is true)
1747
+ delayBeforeRestoreSeconds: 1, // The delay duration, in seconds (default is 0.5)
1748
+ hideTempObj: false,
1749
+ maxTreeDepth: 20,
1058
1750
  });
1059
- }
1060
- var angleMeasurementsData = [
1751
+ }
1752
+
1753
+ initFastNavPlugin(viewer);
1754
+ //------------------------------------------------------------------------------------------------------------------
1755
+ //
1756
+ //------------------------------------------------------------------------------------------------------------------
1757
+ function showXeokitSpinner() {
1758
+ $('.sk-fading-circle').parent().css('visibility', 'visible');
1759
+ }
1760
+
1761
+ function hideXeokitSpinner() {
1762
+ $('.sk-fading-circle').parent().css('visibility', 'hidden');
1763
+ }
1764
+
1765
+
1766
+ //------------------------------------------------------------------------------------------------------------------
1767
+ // MAIN Viewer END
1768
+ //------------------------------------------------------------------------------------------------------------------
1769
+
1770
+
1771
+ function initButtonSet() {
1772
+ bindBtnToggleSidebarNotes();
1773
+ bindSidebarNotesClose();
1774
+ bindDeleteNoteEventHandler();
1775
+
1776
+ bindBtnToggleSidebarTreeView();
1777
+
1778
+ fixNotesTextareaBlur();
1779
+
1780
+ bindBtnToggleCreateNotes();
1781
+ bindBtnCreateSectionPlan();
1782
+ bindBtnClearSectionPlan();
1783
+ bindBtnToggleSectionPlan();
1784
+ bindToggleNotes();
1785
+ bindToggleNotesDescription();
1786
+
1787
+ bindBtnCreateAngleMeasurements();
1788
+ bindBtnToggleAngleMeasurements();
1789
+
1790
+ initTreeViewPanelResizable();
1791
+ initSidebarResizable();
1792
+ initIssueDetailResizable();
1793
+
1794
+ bindBtnToggleSidebarStoreyViews();
1795
+
1796
+ bindBtnSaveBCFViewpointJSON();
1797
+ bindBtnLoadBCFViewpointJSON();
1798
+
1799
+ bindBtnCreateDistanceMeasurements();
1800
+ bindBtnToggleDistanceMeasurements();
1801
+
1802
+ bindPropInspectorClose();
1803
+ initPropertySetsResizable();
1804
+ bindBtnAddModel();
1805
+ }
1806
+
1807
+ initButtonSet();
1808
+
1809
+
1810
+
1811
+
1812
+ //------------------------------------------------------------------------------------------------------------------
1813
+ // Compare
1814
+ //------------------------------------------------------------------------------------------------------------------
1815
+
1816
+ function setStyleDisplay(id, style_Display) {
1817
+ const el = document.getElementById(id);
1818
+ if (el) {
1819
+ el.style.display = style_Display;}
1820
+ };
1821
+
1822
+
1823
+ viewer.on('vitroCompareStatus', (status) => {
1824
+ const style_Display = status ? 'none' : '';
1825
+
1826
+ setStyleDisplay('btnCreateNotes', style_Display);
1827
+ setStyleDisplay('btnToggleNotes', style_Display);
1828
+ setStyleDisplay('btnToggleNotesDescription', style_Display);
1829
+ setStyleDisplay('btnToggleSidebarNotes', style_Display);
1830
+ setStyleDisplay('btnCreateSectionPlan', style_Display);
1831
+ setStyleDisplay('btnClearSectionPlan', style_Display);
1832
+ setStyleDisplay('btnToggleSectionPlan', style_Display);
1833
+ setStyleDisplay('btnToggleSidebarTreeView', style_Display);
1834
+ setStyleDisplay('btnCreateAngleMeasurements', style_Display);
1835
+ setStyleDisplay('btnToggleAngleMeasurements', style_Display);
1836
+ setStyleDisplay('btnCreateDistanceMeasurements', style_Display);
1837
+ setStyleDisplay('btnToggleDistanceMeasurements', style_Display);
1838
+ // setDisplay('btnToggleSidebarStoreyViews', style_Display);
1839
+ // setDisplay('btnSaveBCFViewpointJSON', style_Display);
1840
+ // setDisplay('btnLoadBCFViewpointJSON', style_Display);
1841
+ setStyleDisplay('btnAddModel', style_Display);
1842
+
1843
+ if (status) {
1844
+ delContextMenu(viewer);
1845
+ closeTreeView();
1846
+ clearSectionPanes();
1847
+ }
1848
+ else {
1849
+ addContextMenu(viewer);
1850
+ }
1851
+ });
1852
+
1853
+
1854
+ var angleMeasurementsData = [
1061
1855
 
1062
1856
  ];
1063
1857
  var bcfData = {};
@@ -1075,55 +1869,18 @@ var fileVersionPath = undefined;
1075
1869
  // TODO - PATH!!!
1076
1870
  const modelPathDefault = '';
1077
1871
  const modelPathConverted = '../BIM/assets/models/converted/';
1078
- //------------------------------------------------------------------------------------------------------------------
1079
- // Create a Viewer
1080
- //------------------------------------------------------------------------------------------------------------------
1081
- const viewer = new Viewer({
1082
- canvasId: "xeokitCanvas",
1083
- transparent: true
1084
- });
1085
-
1086
- //------------------------------------------------------------------------------------------------------------------
1087
- // Arrange the camera
1088
- //------------------------------------------------------------------------------------------------------------------
1089
-
1090
- viewer.camera.eye = [-5.02, 2.22, 15.09];
1091
- viewer.camera.look = [4.97, 2.79, 9.89];
1092
- viewer.camera.up = [-0.05, 0.99, 0.02];
1093
- viewer.camera.project.fov = 70;
1094
1872
 
1095
- viewer.camera.zoom(5);
1096
1873
 
1097
- viewer.cameraControl.followPointer = true;
1098
-
1099
- // For TreeView
1100
- viewer.scene.xrayMaterial.fill = true;
1101
- viewer.scene.xrayMaterial.fillAlpha = 0.1;
1102
- viewer.scene.xrayMaterial.fillColor = [0, 0, 0];
1103
- viewer.scene.xrayMaterial.edgeAlpha = 0.3;
1104
- viewer.scene.xrayMaterial.edgeColor = [0, 0, 0];
1105
-
1106
- viewer.scene.highlightMaterial.fill = true;
1107
- viewer.scene.highlightMaterial.edges = true;
1108
- viewer.scene.highlightMaterial.fillAlpha = 0.1;
1109
- viewer.scene.highlightMaterial.edgeAlpha = 0.1;
1110
- viewer.scene.highlightMaterial.edgeColor = [1, 1, 0];
1111
-
1112
- viewer.scene.selectedMaterial.fill = true;
1113
- viewer.scene.selectedMaterial.edges = true;
1114
- viewer.scene.selectedMaterial.fillAlpha = 0.5;
1115
- viewer.scene.selectedMaterial.edgeAlpha = 0.6;
1116
- viewer.scene.selectedMaterial.edgeColor = [0, 1, 1];
1117
1874
 
1118
1875
  //----------------------------------------------------------------------------------------------------------------------
1119
1876
  // Create a tree view
1120
1877
  //----------------------------------------------------------------------------------------------------------------------
1121
1878
 
1122
1879
  var treeView = new VitroTreeViewPlugin(viewer, {
1123
- containerElement: document.getElementById("treeViewContainer"),
1124
- autoExpandDepth: 1,
1125
- hierarchy: "containment",
1126
- autoAddModels: false,
1880
+ containerElement: document.getElementById("treeViewContainer"),
1881
+ autoExpandDepth: 1,
1882
+ hierarchy: "containment",
1883
+ autoAddModels: false,
1127
1884
  });
1128
1885
 
1129
1886
  //------------------------------------------------------------------------------------------------------------------
@@ -1266,7 +2023,7 @@ const objectContextMenu = new ContextMenu({
1266
2023
 
1267
2024
  });
1268
2025
  };
1269
-
2026
+
1270
2027
 
1271
2028
  processByChildIdList(entity.id, event);
1272
2029
  }
@@ -1386,47 +2143,44 @@ const objectContextMenu = new ContextMenu({
1386
2143
  enabled: true
1387
2144
  });
1388
2145
 
1389
- viewer.cameraControl.on("rightClick", function (e) {
1390
-
1391
- var hit = viewer.scene.pick({
1392
- canvasPos: e.canvasPos
1393
- });
2146
+ function addContextMenu(viewer) {
2147
+ viewer.cameraControl.vitroAddContextMenu = viewer.cameraControl.on("rightClick", function (e) {
1394
2148
 
1395
- if (hit && hit.entity.isObject) {
2149
+ var hit = viewer.scene.pick({
2150
+ canvasPos: e.canvasPos
2151
+ });
1396
2152
 
1397
- objectContextMenu.context = { // Must set context before showing menu
1398
- viewer: viewer,
1399
- treeViewPlugin: treeView,
1400
- entity: hit.entity
1401
- };
2153
+ if (hit && hit.entity.isObject) {
1402
2154
 
1403
- objectContextMenu.show(e.event.pageX, e.event.pageY);
2155
+ objectContextMenu.context = { // Must set context before showing menu
2156
+ viewer: viewer,
2157
+ treeViewPlugin: treeView,
2158
+ entity: hit.entity
2159
+ };
1404
2160
 
1405
- } else {
2161
+ objectContextMenu.show(e.event.pageX, e.event.pageY);
1406
2162
 
1407
- canvasContextMenu.context = { // Must set context before showing menu
1408
- viewer: viewer,
1409
- treeViewPlugin: treeView,
1410
- };
2163
+ } else {
1411
2164
 
1412
- canvasContextMenu.show(e.event.pageX, e.event.pageY);
1413
- }
2165
+ canvasContextMenu.context = { // Must set context before showing menu
2166
+ viewer: viewer,
2167
+ treeViewPlugin: treeView,
2168
+ };
1414
2169
 
1415
- e.event.preventDefault();
1416
- });
2170
+ canvasContextMenu.show(e.event.pageX, e.event.pageY);
2171
+ }
1417
2172
 
2173
+ e.event.preventDefault();
2174
+ });
2175
+ }
1418
2176
 
1419
- //------------------------------------------------------------------------------------------------------------------
1420
- // NavCube
1421
- //------------------------------------------------------------------------------------------------------------------
2177
+ function delContextMenu(viewer) {
2178
+ if (viewer.cameraControl.vitroAddContextMenu) {
2179
+ viewer.cameraControl.off(viewer.cameraControl.vitroAddContextMenu);
2180
+ }
2181
+ }
1422
2182
 
1423
- const navCube = new NavCubePlugin(viewer, {
1424
- canvasId: "navCubeCanvas",
1425
- visible: true, // Initially visible (default)
1426
- cameraFly: true, // Fly camera to each selected axis/diagonal
1427
- cameraFitFOV: 45, // How much field-of-view the scene takes once camera has fitted it to view
1428
- cameraFlyDuration: 0.5 // How long (in seconds) camera takes to fly to each new axis/diagonal
1429
- });
2183
+ addContextMenu(viewer);
1430
2184
 
1431
2185
  //------------------------------------------------------------------------------------------------------------------
1432
2186
  // Add a SectionPlanesPlugin - we'll use this to create cross-section planes
@@ -1437,14 +2191,7 @@ const sectionPlanes = new SectionPlanesPlugin(viewer, {
1437
2191
  overviewVisible: true
1438
2192
  });
1439
2193
 
1440
- //------------------------------------------------------------------------------------------------------------------
1441
- // Add a XKTLoaderPlugin - we'll use this to load the model geometry and IFC metadata
1442
- //------------------------------------------------------------------------------------------------------------------
1443
-
1444
- const xktLoader = new XKTLoaderPlugin(viewer);
1445
-
1446
2194
 
1447
- xktLoader.globalizeObjectIds = false; // For multiple models in TreeView
1448
2195
 
1449
2196
  //------------------------------------------------------------------------------------------------------------------
1450
2197
  // Add a BCFViewpointsPlugin - we'll use this to load the BCF viewpoint
@@ -1464,13 +2211,7 @@ function getRequestParams() {
1464
2211
  return vars;
1465
2212
  }
1466
2213
 
1467
- function showXeokitSpinner() {
1468
- $('.sk-fading-circle').parent().css('visibility', 'visible');
1469
- }
1470
2214
 
1471
- function hideXeokitSpinner() {
1472
- $('.sk-fading-circle').parent().css('visibility', 'hidden');
1473
- }
1474
2215
 
1475
2216
  var isModelAddedToTreeView = false;
1476
2217
 
@@ -1488,15 +2229,16 @@ function openSidebarTreeView() {
1488
2229
  // $(window).trigger('resize');
1489
2230
  }
1490
2231
 
2232
+
2233
+
1491
2234
  function addModelToTreeView() {
1492
2235
 
1493
- viewer.scene.canvas.spinner.processes++;
2236
+ viewer.scene.canvas.spinner.processes++;
1494
2237
 
1495
- const callback = (metaObjects, status, jqXHR) =>
1496
- {
2238
+ const callback = (metaObjects, status, jqXHR) => {
1497
2239
  const metaModel = viewer.metaScene.metaModels[viewer.scene.modelIds[0]];
1498
2240
 
1499
- treeView.addObjectsToMetaModel(metaObjects, metaModel);
2241
+ treeView.addObjectsToMetaModel(metaObjects, metaModel);
1500
2242
  treeView.addModel(viewer.scene.modelIds[0]);
1501
2243
 
1502
2244
  $('body').addClass('treeview-expanded');
@@ -1547,102 +2289,25 @@ annotations.on("markerClicked", (annotation) => {
1547
2289
  onAnnotationsMarkerClickedHandler(annotation);
1548
2290
  });
1549
2291
 
1550
- function onAnnotationsMarkerClickedHandler(annotation) {
1551
- //console.log('annotation', annotation.id);
1552
- showNoteDesc(annotation.id);
1553
-
1554
- if (prevAnnotationClicked) {
1555
- prevAnnotationClicked.setLabelShown(false);
1556
- }
1557
- annotation.setLabelShown(true);
1558
- viewer.cameraFlight.flyTo(annotation);
1559
- prevAnnotationClicked = annotation;
1560
- }
1561
-
1562
- //------------------------------------------------------------------------------------------------------------------
1563
- // Load Model
1564
- //------------------------------------------------------------------------------------------------------------------
1565
- function doLoadModel(srcModel, isMain) {
1566
- const model = xktLoader.load({
1567
- id: Date.now(),
1568
- src: srcModel.FilePath,
1569
- edges: true,
1570
- backfaces: true,
1571
- });
1572
-
1573
- srcModel.id = model.id;
1574
-
1575
- model.vitroModel = srcModel;
1576
- model.isLarge = true;
1577
- model.on('loaded', () => {
1578
- if (isMain) {
1579
- modelOnLoaded();
1580
- //------------------------------------------------------------------------------------------------------------------
1581
- // Load Small Scene
1582
- //------------------------------------------------------------------------------------------------------------------
1583
- model.vitroModelLoader = new VitroXKTLoaderPlugin(viewer);
1584
-
1585
- model.vitroModelLoader.largeModel = model;
1586
- model.vitroModelLoader.startSmallLoad = true;
1587
-
1588
- $('#btnToggleSectionPlan').addClass('toggled');
1589
- }
1590
- else {
1591
- viewer.scene.fire("reloadSmallScenes");
1592
- }
1593
-
1594
- //------------------------------------------------------------------------------------------------------------------
1595
- // Create some Annotations
1596
- //------------------------------------------------------------------------------------------------------------------
1597
- loadAnnotations();
1598
- });
1599
-
1600
- window.model = model;
1601
-
1602
- if (isPointCloud(srcModel.FileName)) {
1603
- var navPlugin = viewer._plugins.find((p) => p.id == 'FastNav');
2292
+ function onAnnotationsMarkerClickedHandler(annotation) {
2293
+ //console.log('annotation', annotation.id);
2294
+ showNoteDesc(annotation.id);
1604
2295
 
1605
- if (navPlugin) {
1606
- navPlugin.hideTransparentObjects = false;
1607
- }
2296
+ if (prevAnnotationClicked) {
2297
+ prevAnnotationClicked.setLabelShown(false);
1608
2298
  }
1609
-
1610
- return model;
2299
+ annotation.setLabelShown(true);
2300
+ viewer.cameraFlight.flyTo(annotation);
2301
+ prevAnnotationClicked = annotation;
1611
2302
  }
1612
2303
 
1613
- function isPointCloud(filename) {
1614
- const ext = filename.split('.').pop().toLowerCase();
1615
- return ext === 'las' || ext === 'laz';
1616
- }
1617
2304
 
1618
2305
  function getDisableCacheStr() {
1619
2306
  var dt = new Date();
1620
2307
  return "?rev=" + dt.getTime();
1621
2308
  }
1622
2309
 
1623
- function modelOnLoaded() {
1624
-
1625
-
1626
-
1627
- //----------------------------------------------------------------------------------------------------------
1628
- // Angle Measurements
1629
- //----------------------------------------------------------------------------------------------------------
1630
- const angleMeasurements = createAngleMeasurements(angleMeasurementsData);
1631
-
1632
- //----------------------------------------------------------------------------------------------------------
1633
- // Storey Views
1634
- //----------------------------------------------------------------------------------------------------------
1635
- // ????????! ???? ?? initStoreyViews ????? ?????? SectionPlane -> ???????? ?????? ?????? ????? ????????? ? "??????????" ????
1636
- // ?? ??? ????? ?????? ??????? ????? ??????????? ???????? ??????????? SectionPlane
1637
- initStoreyViews();
1638
-
1639
- //----------------------------------------------------------------------------------------------------------
1640
- // Distance Measurements
1641
- //----------------------------------------------------------------------------------------------------------
1642
- const distanceMeasurements = createDistanceMeasurements(distanceMeasurementsData);
1643
2310
 
1644
- ViewFitAll(viewer);
1645
- }
1646
2311
 
1647
2312
  //------------------------------------------------------------------------------------------------------------------
1648
2313
  // Clear SectionPlanes
@@ -1726,29 +2391,29 @@ function initDlg(pickResult) {
1726
2391
  buttons: [{
1727
2392
  text: "Save",
1728
2393
  "id": "btnSaveConfirm",
1729
- click: function() {
2394
+ click: function () {
1730
2395
  saveNote(pickResult);
1731
2396
  closeDlg();
1732
2397
  },
1733
2398
  }, {
1734
2399
  text: "Cancel",
1735
2400
  "id": "btnSaveCancel",
1736
- click: function() {
2401
+ click: function () {
1737
2402
  closeDlg();
1738
2403
  }
1739
2404
  }],
1740
- close: function() {
2405
+ close: function () {
1741
2406
  closeDlg();
1742
2407
  },
1743
- open: function(event, ui ) {
2408
+ open: function (event, ui) {
1744
2409
  disableXeokitClickEvent();
1745
2410
  }
1746
2411
  });
1747
2412
 
1748
2413
  var saveLabel = document.webL10n.get('save');
1749
2414
  var cancelLabel = document.webL10n.get('cancel');
1750
- $("#btnSaveConfirm").html('<span class="ui-button-text">'+ saveLabel +'</span>')
1751
- $("#btnSaveCancel").html('<span class="ui-button-text">'+ cancelLabel +'</span>')
2415
+ $("#btnSaveConfirm").html('<span class="ui-button-text">' + saveLabel + '</span>')
2416
+ $("#btnSaveCancel").html('<span class="ui-button-text">' + cancelLabel + '</span>')
1752
2417
  }
1753
2418
 
1754
2419
  function disableXeokitClickEvent() {
@@ -1767,15 +2432,15 @@ function getDlgElm() {
1767
2432
 
1768
2433
  function closeDlg() {
1769
2434
  resetDlgForm();
1770
- $(this).dialog( "close" );
1771
- $(this).dialog( "destroy" );
2435
+ $(this).dialog("close");
2436
+ $(this).dialog("destroy");
1772
2437
  getDlgElm().remove();
1773
2438
  annotationByClick = true;
1774
2439
  }
1775
2440
 
1776
2441
  function createDlgElm() {
1777
2442
  var addNoteLabel = document.webL10n.get('note_add');
1778
- var div = $('<div id="dialog-form" title="'+ addNoteLabel + '" style="display: none;"/>');
2443
+ var div = $('<div id="dialog-form" title="' + addNoteLabel + '" style="display: none;"/>');
1779
2444
  var title = $('<input id="dlgNoteTitle" />');
1780
2445
  var txtArea = $('<textarea id="dlgNoteTxt"></textarea>');
1781
2446
 
@@ -1788,7 +2453,7 @@ function createDlgElm() {
1788
2453
 
1789
2454
  function createDeleteDlgElm() {
1790
2455
  var noteConfirmDeleteMessage = document.webL10n.get('note_delete_confirm');
1791
- var div = $('<div id="dialog-form" title="'+ noteConfirmDeleteMessage + '" style="display: none;"/>');
2456
+ var div = $('<div id="dialog-form" title="' + noteConfirmDeleteMessage + '" style="display: none;"/>');
1792
2457
  $('body').append(div);
1793
2458
  }
1794
2459
 
@@ -1805,7 +2470,7 @@ function doAddNote(noteOptions) {
1805
2470
  notes.push(noteOptions);
1806
2471
  createNote(noteOptions);
1807
2472
 
1808
- if($('.sidebar').is(':visible')) {
2473
+ if ($('.sidebar').is(':visible')) {
1809
2474
  initSidebarNotes();
1810
2475
  highlightSidebarNote(noteOptions.id);
1811
2476
  }
@@ -1867,7 +2532,7 @@ function doGetNoteOptions(noteId, creator, pickResult, glyph, title, description
1867
2532
  }
1868
2533
  };
1869
2534
 
1870
- if(pickResult.entity && pickResult.entity.id) {
2535
+ if (pickResult.entity && pickResult.entity.id) {
1871
2536
  options.entity = pickResult.entity.id;
1872
2537
  }
1873
2538
 
@@ -1888,14 +2553,14 @@ function clearSidebarNotes() {
1888
2553
  }
1889
2554
 
1890
2555
  function createSidebarNotes() {
1891
- $.each(notes, function(index, note) {
2556
+ $.each(notes, function (index, note) {
1892
2557
  var noteElm = createSidebarNotesItem(note);
1893
2558
  $('.sidebar-content').append(noteElm);
1894
2559
  });
1895
2560
  }
1896
2561
 
1897
2562
  function createSidebarNotesItem(noteData) {
1898
- var noteWrap = $('<div class="sidebar-note-wrap" id="noteWrap-'+noteData.id+'" />');
2563
+ var noteWrap = $('<div class="sidebar-note-wrap" id="noteWrap-' + noteData.id + '" />');
1899
2564
 
1900
2565
  var noteHeader = createSidebarNotesItemHeader(noteData);
1901
2566
  var noteBody = createSidebarNotesItemBody(noteData);
@@ -1921,10 +2586,10 @@ function createSidebarNotesItemBody(noteData) {
1921
2586
  statusText = document.webL10n.get('note_status_default');
1922
2587
  }
1923
2588
  var status = $('<span class="sidebar-note-status-mark" style="background-color:' + noteContent.values.markerBGColor + '"></span><span class="sidebar-note-status-text">' + statusText + '</span>');
1924
- var expandLabel=document.webL10n.get('note_expand');
1925
- var collapseLabel=document.webL10n.get('note_collapse');
2589
+ var expandLabel = document.webL10n.get('note_expand');
2590
+ var collapseLabel = document.webL10n.get('note_collapse');
1926
2591
  var expandBtnExpand = $('<a class="btn-expand">' + expandLabel + '</a>');
1927
- var expandBtnCollapse = $('<a class="btn-collapse">'+ collapseLabel + '</a>');
2592
+ var expandBtnCollapse = $('<a class="btn-collapse">' + collapseLabel + '</a>');
1928
2593
  bindOnClickTextareaExpand(expandBtnExpand);
1929
2594
  bindOnClickTextareaCollapse(expandBtnCollapse);
1930
2595
  expandBtnWrapInner.append(status);
@@ -1935,7 +2600,7 @@ function createSidebarNotesItemBody(noteData) {
1935
2600
  noteBody.append(noteTextarea);
1936
2601
  noteBody.append(expandBtnWrap);
1937
2602
 
1938
- if(noteContent.values.imageSrc) {
2603
+ if (noteContent.values.imageSrc) {
1939
2604
  var noteImage = $('<div class="sidebar-note-img-wrap"><img src="' + noteContent.values.imageSrc + '" /><div>');
1940
2605
  noteBody.append(noteImage);
1941
2606
  }
@@ -1944,11 +2609,11 @@ function createSidebarNotesItemBody(noteData) {
1944
2609
  }
1945
2610
 
1946
2611
  function bindTextareaHandlers(textarea, noteData) {
1947
- textarea.on('focus', function() {
2612
+ textarea.on('focus', function () {
1948
2613
  doTextareaOnFocus($(this));
1949
2614
  });
1950
2615
 
1951
- textarea.on('change', function() {
2616
+ textarea.on('change', function () {
1952
2617
  doNoteOnChange($(this), noteData);
1953
2618
  });
1954
2619
  }
@@ -1966,12 +2631,12 @@ function doNoteOnChange(textarea, noteData) {
1966
2631
  var noteTitle = noteData.values.title;
1967
2632
  var noteDesc = textarea.val();
1968
2633
 
1969
- BIMAnnotation.UpdateNote(noteId, noteTitle, noteDesc, function() {
2634
+ BIMAnnotation.UpdateNote(noteId, noteTitle, noteDesc, function () {
1970
2635
  var date = getCurrentDate();
1971
2636
  var user = '';
1972
2637
 
1973
- $.each(notes, function(index, val) {
1974
- if(val.id == noteId) {
2638
+ $.each(notes, function (index, val) {
2639
+ if (val.id == noteId) {
1975
2640
  notes[index]['values']['description'] = noteDesc;
1976
2641
  notes[index]['date'] = date;
1977
2642
  }
@@ -1980,7 +2645,7 @@ function doNoteOnChange(textarea, noteData) {
1980
2645
  }
1981
2646
 
1982
2647
  function bindOnClickTextareaExpand(btnElm) {
1983
- btnElm.on('click', function() {
2648
+ btnElm.on('click', function () {
1984
2649
  doTextareaExpand(btnElm);
1985
2650
  $(this).closest('.sidebar-note-expand-btn').removeClass('collapsed');
1986
2651
  });
@@ -1992,7 +2657,7 @@ function doTextareaExpand(btnElm) {
1992
2657
  }
1993
2658
 
1994
2659
  function bindOnClickTextareaCollapse(btnElm) {
1995
- btnElm.on('click', function() {
2660
+ btnElm.on('click', function () {
1996
2661
  doTextareaCollapse(btnElm);
1997
2662
  $(this).closest('.sidebar-note-expand-btn').addClass('collapsed');
1998
2663
  });
@@ -2022,7 +2687,7 @@ function createSidebarNotesItemHeader(noteData) {
2022
2687
  var titleContainer = $('<div class="note-title-container"></div>');
2023
2688
 
2024
2689
  var noteTitle = $('<div class="sidebar-note-title">' + noteData.values.title + '</div>');
2025
- noteTitle.on('click', function() {
2690
+ noteTitle.on('click', function () {
2026
2691
  goToNoteMarker($(this));
2027
2692
  });
2028
2693
 
@@ -2075,13 +2740,13 @@ function goToCommentList(noteId) {
2075
2740
  }
2076
2741
 
2077
2742
  function bindSidebarNotesBtnDelete(btn) {
2078
- btn.on('click', function(e) {
2743
+ btn.on('click', function (e) {
2079
2744
  $(document).trigger('deleteNote', [$(this)]);
2080
2745
  });
2081
2746
  }
2082
2747
 
2083
2748
  function bindDeleteNoteEventHandler() {
2084
- $(document).on('deleteNote', function(e, item) {
2749
+ $(document).on('deleteNote', function (e, item) {
2085
2750
 
2086
2751
  createDeleteDlgElm();
2087
2752
 
@@ -2094,7 +2759,7 @@ function bindDeleteNoteEventHandler() {
2094
2759
  buttons: [{
2095
2760
  text: "Confirm",
2096
2761
  "id": "btnDeleteConfirm",
2097
- click: function() {
2762
+ click: function () {
2098
2763
  var id = item.attr('id') ? item.attr('id') : item.data('id');
2099
2764
  BIMAnnotation.DeleteNote(id, deleteNote);
2100
2765
  closeDlg();
@@ -2102,7 +2767,7 @@ function bindDeleteNoteEventHandler() {
2102
2767
  }, {
2103
2768
  text: "Cancel",
2104
2769
  "id": "btnDeleteCancel",
2105
- click: function() {
2770
+ click: function () {
2106
2771
  closeDlg();
2107
2772
  }
2108
2773
  }],
@@ -2113,28 +2778,28 @@ function bindDeleteNoteEventHandler() {
2113
2778
 
2114
2779
  var confirmLabel = document.webL10n.get('confirm');
2115
2780
  var cancelLabel = document.webL10n.get('cancel');
2116
- $("#btnDeleteConfirm").html('<span class="ui-button-text">'+ confirmLabel +'</span>')
2117
- $("#btnDeleteCancel").html('<span class="ui-button-text">'+ cancelLabel +'</span>')
2781
+ $("#btnDeleteConfirm").html('<span class="ui-button-text">' + confirmLabel + '</span>')
2782
+ $("#btnDeleteCancel").html('<span class="ui-button-text">' + cancelLabel + '</span>')
2118
2783
  });
2119
2784
  }
2120
2785
 
2121
2786
  function deleteNote(id) {
2122
- notes = jQuery.grep(notes, function(elm, index) {
2787
+ notes = jQuery.grep(notes, function (elm, index) {
2123
2788
  return (elm.id != id);
2124
2789
  });
2125
2790
 
2126
2791
  annotations.destroyAnnotation(id);
2127
2792
 
2128
- if($('.sidebar').is(':visible')) {
2793
+ if ($('.sidebar').is(':visible')) {
2129
2794
  initSidebarNotes();
2130
2795
  }
2131
2796
  }
2132
2797
 
2133
2798
  function fixNotesTextareaBlur() {
2134
- $('#xeokitCanvas').on('click', function() {
2135
- if($('.sidebar-content').is(':visible')) {
2799
+ $('#xeokitCanvas').on('click', function () {
2800
+ if ($('.sidebar-content').is(':visible')) {
2136
2801
  var textareas = $('.sidebar-content').find('textarea');
2137
- if(textareas.length) {
2802
+ if (textareas.length) {
2138
2803
  textareas.trigger('blur');
2139
2804
  }
2140
2805
  }
@@ -2166,7 +2831,7 @@ function doHighlightSidebarNote(noteWrap) {
2166
2831
  }
2167
2832
 
2168
2833
  function showNoteDesc(noteId) {
2169
- if(!$('.sidebar').is(':visible')) {
2834
+ if (!$('.sidebar').is(':visible')) {
2170
2835
  $('#btnToggleSidebarNotes').addClass('toggled');
2171
2836
  initSidebarNotes();
2172
2837
  expandSidebarNotes();
@@ -2178,9 +2843,9 @@ function showNoteDesc(noteId) {
2178
2843
  // Toolbar
2179
2844
  //------------------------------------------------------------------------------------------------------------------
2180
2845
  function bindToggleNotes() {
2181
- $(document).on('click', '#btnToggleNotes', function() {
2846
+ $(document).on('click', '#btnToggleNotes', function () {
2182
2847
  $(this).toggleClass('show');
2183
- if($(this).hasClass('show')) {
2848
+ if ($(this).hasClass('show')) {
2184
2849
  hideAnnotationMarkers();
2185
2850
  } else {
2186
2851
  showAnnotationMarkers();
@@ -2197,11 +2862,11 @@ function showAnnotationMarkers() {
2197
2862
  }
2198
2863
 
2199
2864
  function bindBtnToggleSidebarNotes() {
2200
- $(document).on('click', '#btnToggleSidebarNotes', function() {
2865
+ $(document).on('click', '#btnToggleSidebarNotes', function () {
2201
2866
  $(this).toggleClass('toggled');
2202
2867
 
2203
- if($(this).hasClass('toggled')) {
2204
- if(!$('.sidebar').is(':visible')) {
2868
+ if ($(this).hasClass('toggled')) {
2869
+ if (!$('.sidebar').is(':visible')) {
2205
2870
  initSidebarNotes();
2206
2871
  expandSidebarNotes();
2207
2872
  }
@@ -2226,7 +2891,7 @@ function expandSidebarNotes() {
2226
2891
  }
2227
2892
 
2228
2893
  function bindSidebarNotesClose() {
2229
- $('.sidebar-close').on('click', function() {
2894
+ $('.sidebar-close').on('click', function () {
2230
2895
  $('#navCubeCanvas').css('right', 10);
2231
2896
  $('#sectionPlanesOverviewCanvas').css('right', $('#sidebarWrap').width() + 10);
2232
2897
  $('.sidebar').hide();
@@ -2235,10 +2900,10 @@ function bindSidebarNotesClose() {
2235
2900
  }
2236
2901
 
2237
2902
  function bindBtnCreateAngleMeasurements() {
2238
- $(document).on('click', '#btnCreateAngleMeasurements', function() {
2903
+ $(document).on('click', '#btnCreateAngleMeasurements', function () {
2239
2904
  $(this).toggleClass('toggled');
2240
2905
 
2241
- if($(this).hasClass('toggled')) {
2906
+ if ($(this).hasClass('toggled')) {
2242
2907
  $('#btnCreateNotes').removeClass('toggled');
2243
2908
  annotationByClick = false;
2244
2909
 
@@ -2269,10 +2934,10 @@ function disableAngleMeasurementsByClick() {
2269
2934
 
2270
2935
  /* *** Вариант реализации, если необходима возможность создавать SectionPlan по клику *** */
2271
2936
  function bindBtnToggleCreateNotes() {
2272
- $(document).on('click', '#btnCreateNotes', function() {
2937
+ $(document).on('click', '#btnCreateNotes', function () {
2273
2938
  $(this).toggleClass('toggled');
2274
2939
 
2275
- if($(this).hasClass('toggled')) {
2940
+ if ($(this).hasClass('toggled')) {
2276
2941
  $('#btnCreateSectionPlan').removeClass('toggled');
2277
2942
  disableSectionPlanByClick();
2278
2943
  disableAngleMeasurementsByClick();
@@ -2287,10 +2952,10 @@ function bindBtnToggleCreateNotes() {
2287
2952
  }
2288
2953
 
2289
2954
  function bindBtnCreateSectionPlan() {
2290
- $(document).on('click', '#btnCreateSectionPlan', function() {
2955
+ $(document).on('click', '#btnCreateSectionPlan', function () {
2291
2956
  $(this).toggleClass('toggled');
2292
2957
 
2293
- if($(this).hasClass('toggled')) {
2958
+ if ($(this).hasClass('toggled')) {
2294
2959
  $('#btnCreateNotes').removeClass('toggled');
2295
2960
  $('#btnToggleSectionPlan').addClass('toggled');
2296
2961
  annotationByClick = false;
@@ -2310,10 +2975,10 @@ function bindBtnClearSectionPlan() {
2310
2975
  }
2311
2976
 
2312
2977
  function bindBtnToggleSectionPlan() {
2313
- $(document).on('click', '#btnToggleSectionPlan', function() {
2978
+ $(document).on('click', '#btnToggleSectionPlan', function () {
2314
2979
  $(this).toggleClass('toggled');
2315
2980
 
2316
- if($(this).hasClass('toggled')) {
2981
+ if ($(this).hasClass('toggled')) {
2317
2982
  enableSectionPlan();
2318
2983
  } else {
2319
2984
  disableSectionPlan();
@@ -2327,7 +2992,7 @@ function bindBtnToggleSectionPlan() {
2327
2992
  function enableSectionPlanByClick() {
2328
2993
  sectionPlanByClick = true;
2329
2994
 
2330
- if(lastVisibleSectionPlanId) {
2995
+ if (lastVisibleSectionPlanId) {
2331
2996
  sectionPlanes.showControl(lastVisibleSectionPlanId); // Shows the 3D editing gizmo for a SectionPlane.
2332
2997
  }
2333
2998
 
@@ -2335,7 +3000,7 @@ function enableSectionPlanByClick() {
2335
3000
  }
2336
3001
 
2337
3002
  function enableSectionPlan() {
2338
- if(lastVisibleSectionPlanId) {
3003
+ if (lastVisibleSectionPlanId) {
2339
3004
  sectionPlanes.showControl(lastVisibleSectionPlanId); // Shows the 3D editing gizmo for a SectionPlane.
2340
3005
  }
2341
3006
 
@@ -2359,27 +3024,30 @@ function disableSectionPlan() {
2359
3024
  }
2360
3025
 
2361
3026
  function bindBtnToggleSidebarTreeView() {
2362
- $(document).on('click', '#btnToggleSidebarTreeView', function() {
3027
+ $(document).on('click', '#btnToggleSidebarTreeView', function () {
2363
3028
  $(this).toggleClass('toggled');
2364
3029
 
2365
- if($(this).hasClass('toggled')) {
3030
+ if ($(this).hasClass('toggled')) {
2366
3031
  openSidebarTreeView();
2367
3032
  } else {
2368
- $('#treeViewContainerWrap').hide();
2369
- $('body').removeClass('treeview-expanded');
3033
+ closeTreeView();
2370
3034
  // $(window).trigger('resize');
2371
3035
  }
2372
3036
  });
2373
3037
  }
2374
3038
 
3039
+ function closeTreeView() {
3040
+ $('#treeViewContainerWrap').hide();
3041
+ $('#btnToggleSidebarTreeView').removeClass('toggled');
3042
+ $('body').removeClass('treeview-expanded');
3043
+ }
3044
+
2375
3045
  function bindBtnToggleSidebarStoreyViews() {
2376
- $(document).on('click', '#btnToggleSidebarStoreyViews', function() {
3046
+ $(document).on('click', '#btnToggleSidebarStoreyViews', function () {
2377
3047
  $(this).toggleClass('toggled');
2378
3048
 
2379
- if($(this).hasClass('toggled')) {
2380
- $('#treeViewContainerWrap').hide();
2381
- $('#btnToggleSidebarTreeView').removeClass('toggled');
2382
- $('body').removeClass('treeview-expanded');
3049
+ if ($(this).hasClass('toggled')) {
3050
+ closeTreeView();
2383
3051
 
2384
3052
  $('#storeyViewsSidebar').show();
2385
3053
  } else {
@@ -2425,7 +3093,7 @@ function initSidebarResizable() {
2425
3093
  $('#sidebarWrap').resizable({
2426
3094
  handles: "w",
2427
3095
  minWidth: 150,
2428
- resize: function(event, ui) {
3096
+ resize: function (event, ui) {
2429
3097
  $('#navCubeCanvas').css('right', $('#sidebarWrap').width() + 10);
2430
3098
  $('#sectionPlanesOverviewCanvas').css('right', $('#sidebarWrap').width() + 10);
2431
3099
  }
@@ -2446,7 +3114,7 @@ const angleMeasurements = new AngleMeasurementsPlugin(viewer);
2446
3114
 
2447
3115
  function createAngleMeasurements(angleMeasurementsData) {
2448
3116
  var angleMeasurements = [];
2449
- $.each(angleMeasurementsData,function(index,value){
3117
+ $.each(angleMeasurementsData, function (index, value) {
2450
3118
  angleMeasurements.push(createAngleMeasurementItem(value));
2451
3119
  });
2452
3120
 
@@ -2479,10 +3147,10 @@ function createAngleMeasurementItem(angleMeasurementItemData) {
2479
3147
  //------------------------------------------------------------------------------------------------------------------
2480
3148
 
2481
3149
  function bindBtnToggleAngleMeasurements() {
2482
- $(document).on('click', '#btnToggleAngleMeasurements', function() {
3150
+ $(document).on('click', '#btnToggleAngleMeasurements', function () {
2483
3151
  $(this).toggleClass('toggled');
2484
3152
 
2485
- if($(this).hasClass('toggled')) {
3153
+ if ($(this).hasClass('toggled')) {
2486
3154
  $('#btnCreateAngleMeasurements').removeClass('toggled');
2487
3155
  disableAngleMeasurementsByClick();
2488
3156
  disableAngleMeasurements();
@@ -2493,13 +3161,13 @@ function bindBtnToggleAngleMeasurements() {
2493
3161
  }
2494
3162
 
2495
3163
  function enableAngleMeasurements() {
2496
- $.each(angleMeasurements.measurements, function(index) {
3164
+ $.each(angleMeasurements.measurements, function (index) {
2497
3165
  this.visible = true;
2498
3166
  });
2499
3167
  }
2500
3168
 
2501
3169
  function disableAngleMeasurements() {
2502
- $.each(angleMeasurements.measurements, function(index) {
3170
+ $.each(angleMeasurements.measurements, function (index) {
2503
3171
  this.visible = false;
2504
3172
  });
2505
3173
  }
@@ -2595,388 +3263,61 @@ function createStoreyMapsMenu() {
2595
3263
  const storey = storeyViewsPlugin.storeys[storeyMap.storeyId];
2596
3264
  worldPos[idx] = (storey.aabb[idx] + storey.aabb[3 + idx]) / 2;
2597
3265
 
2598
- viewer.cameraFlight.flyTo({
2599
- eye: worldPos,
2600
- up: viewer.camera.worldUp,
2601
- look: math.addVec3(worldPos, viewer.camera.worldForward, []),
2602
- projection: "perspective",
2603
- duration: 1.5
2604
- }, () => {
2605
- viewer.cameraControl.navMode = "firstPerson";
2606
- viewer.cameraControl.followPointer = false;
2607
- });
2608
- } else {
2609
- cameraMemento.restoreCamera(viewer.scene, () => {
2610
- viewer.cameraControl.navMode = "planView";
2611
- });
2612
- }
2613
- };
2614
- }
2615
- }
2616
-
2617
- //------------------------------------------------------------------------------------------------------------------
2618
- // BCF Viewpoint JSON
2619
- //------------------------------------------------------------------------------------------------------------------
2620
- function bindBtnSaveBCFViewpointJSON() {
2621
- $('#btnSaveBCFViewpointJSON').on('click', function() {
2622
- saveBCFViewpointJSON();
2623
- });
2624
- }
2625
-
2626
- function saveBCFViewpointJSON() {
2627
- const viewpoint = bcfViewpoints.getViewpoint({ // Options
2628
- spacesVisible: false, // Don't force IfcSpace types visible in viewpoint (default)
2629
- spaceBoundariesVisible: false, // Don't show IfcSpace boundaries in viewpoint (default)
2630
- openingsVisible: false // Don't force IfcOpening types visible in viewpoint (default)
2631
- });
2632
-
2633
- const viewpointStr = JSON.stringify(viewpoint, null, 4);
2634
-
2635
- // TODO -> save JSON
2636
- alert(viewpointStr); // Only for Test
2637
- console.log(viewpointStr); // Only for Test
2638
- }
2639
-
2640
- function bindBtnLoadBCFViewpointJSON() {
2641
- $('#btnLoadBCFViewpointJSON').on('click', function() {
2642
- loadBCFViewpointJSON();
2643
- });
2644
- }
2645
-
2646
- function getBCFViewpoint() {
2647
- return bcfData; // Return Test-data from bcf.data.js
2648
- }
2649
-
2650
- function loadBCFViewpointJSON() {
2651
- const bcfViewpoint = getBCFViewpoint();
2652
- bcfViewpoints.setViewpoint(bcfViewpoint);
2653
- }
2654
-
2655
- //------------------------------------------------------------------------------------------------------------------
2656
- // Compare Models
2657
- //------------------------------------------------------------------------------------------------------------------
2658
- let compareModelsResult;
2659
- let viewerSceneObjectsNewBeforeCompare;
2660
-
2661
- function bindBtnCompareOneOverOne() {
2662
- $(document).on('click', '#btnCompareOneOverOne', function() {
2663
- if($('#btnCompareSideBySide').hasClass('toggled')) {
2664
- $('#btnCompareSideBySide').removeClass('toggled');
2665
- doRemoveComparison();
2666
- }
2667
- if(!$(this).hasClass('toggled')) {
2668
- compareModels(false);
2669
- }
2670
- $(this).addClass('toggled');
2671
- });
2672
- }
2673
-
2674
- function bindBtnCompareSideBySide() {
2675
- $(document).on('click', '#btnCompareSideBySide', function() {
2676
- if($('#btnCompareOneOverOne').hasClass('toggled')) {
2677
- $('#btnCompareOneOverOne').removeClass('toggled');
2678
- doRemoveComparison();
2679
- }
2680
- if(!$(this).hasClass('toggled')) {
2681
- compareModels(true);
2682
- }
2683
- $(this).addClass('toggled');
2684
- });
2685
-
2686
- }
2687
- function bindBtnClearComparison() {
2688
- $(document).on('click', '#btnClearComparison', function() {
2689
- $('#btnCompareOneOverOne').removeClass('toggled');
2690
- $('#btnCompareSideBySide').removeClass('toggled');
2691
- $('#btnToggleCompare').removeClass('toggled');
2692
-
2693
- doRemoveComparison();
2694
-
2695
- });
2696
- }
2697
-
2698
- function doRemoveComparison() {
2699
- if (model2) {
2700
- model2.destroy();
2701
- }
2702
- $('.comparison-popup-wrap').dialog( "destroy" );
2703
- restoreObjectColorsAfterCompare();
2704
- }
2705
-
2706
- function restoreObjectColorsAfterCompare() {
2707
- if (compareModelsResult && compareModelsResult['new'] && compareModelsResult['new'].length) {
2708
- for (let i = 0; i < compareModelsResult['new'].length; i++) {
2709
- if(viewer.scene.objects[compareModelsResult['new'][i]]) {
2710
- viewer.scene.objects[compareModelsResult['new'][i]].colorize = viewerSceneObjectsNewBeforeCompare[compareModelsResult['new'][i]].colorize;
2711
- }
2712
- }
2713
- }
2714
-
2715
- compareModelsResult = false;
2716
- viewerSceneObjectsNewBeforeCompare = false;
2717
- }
2718
-
2719
- function compareModels(isSideBySide) {
2720
-
2721
- var fileItem = BIMCommon.FileItem.FileVersionList[0];
2722
-
2723
- var disableCacheStr = getDisableCacheStr();
2724
- var compareModelUrl = fileItem.ModelPath;
2725
- var modelUrl = compareModelUrl + disableCacheStr;
2726
- var metaModelDataUrl = fileItem.MetaModelDataPath + disableCacheStr;
2727
-
2728
- var settings = {
2729
- id: Date.now(),
2730
- src: modelUrl,
2731
- edges: true,
2732
- performance: true,
2733
- position: [0, 0, 0]
2734
- };
2735
-
2736
- if (isSideBySide) {
2737
- settings.position = [-55, 0, 0];
2738
- }
2739
-
2740
- window.model2 = xktLoader.load(settings);
2741
- window.model2.on('loaded', () => {
2742
- viewer.scene.canvas.spinner.processes++;
2743
- doCompareModels(isSideBySide);
2744
- });
2745
- }
2746
-
2747
- function doCompareModels(isSideBySide) {
2748
- BIMModel.Compare(function (result) {
2749
- var objResult = JSON.parse(result);
2750
- compareModelsResult = objResult;
2751
- viewerSceneObjectsNewBeforeCompare = {};
2752
-
2753
- if (compareModelsResult['new'] && compareModelsResult['new'].length) {
2754
- for (let i = 0; i < compareModelsResult['new'].length; i++) {
2755
- viewerSceneObjectsNewBeforeCompare[compareModelsResult['new'][i]] = Object.assign({}, viewer.scene.objects[compareModelsResult['new'][i]]);
2756
- }
2757
- }
2758
-
2759
- window.objResult = objResult;
2760
-
2761
- highlightModelsDifference(objResult, isSideBySide);
2762
- createComparisonResultPopup();
2763
-
2764
- $('#btnAddModel').hide();
2765
-
2766
- viewer.scene.canvas.spinner.processes--;
2767
- },
2768
- function () {
2769
- viewer.scene.canvas.spinner.processes--;
2770
- });
2771
- }
2772
-
2773
- function createComparisonResultPopup() {
2774
- var popupTitle = document.webL10n.get('version_changes');
2775
- var labelAll = document.webL10n.get('version_changes_all');
2776
- var labelAdded = document.webL10n.get('version_changes_added');
2777
- var labelRemoved = document.webL10n.get('version_changes_removed');
2778
-
2779
- var countAdded = compareModelsResult['new'].length ? compareModelsResult['new'].length : 0;
2780
- var countRemoved = compareModelsResult['old']['unique'].length ? compareModelsResult['old']['unique'].length : 0;
2781
-
2782
- var popupWrap = $('<div class="comparison-popup-wrap"/>');
2783
-
2784
- var header = createComparisonResultPopupHeader(countAdded, labelAdded, countRemoved, labelRemoved);
2785
-
2786
- var allItemsList = $('<ul class="list-items"/>');
2787
-
2788
- if (countAdded) {
2789
- var addedItemsList = getComparisonResultAddedItemsListElm(allItemsList);
2790
- }
2791
-
2792
- if (countRemoved) {
2793
- var removedItemsList = getComparisonResultRemovedItemsListElm(allItemsList);
2794
- }
2795
-
2796
- var body = $('<div class="comparison-popup-body"/>');
2797
- var ukWrapRelative = $('<div class="uk-position-relative"/>');
2798
-
2799
- var ukTabHeader = $('<ul uk-tab="swiping: false" class="uk-tab">' +
2800
- '<li class="uk-active"><a href="#" aria-expanded="true">'+labelAll+'</a></li>' +
2801
- (countAdded ? '<li class=""><a href="#" aria-expanded="false">'+labelAdded+'</a></li>' : '') +
2802
- (countRemoved ? '<li class=""><a href="#" aria-expanded="false">'+labelRemoved+'</a></li>' : '') +
2803
- '</ul>');
2804
-
2805
- ukWrapRelative.append(ukTabHeader);
2806
-
2807
- var ukSwitcher = $('<ul class="uk-switcher"/>');
2808
-
2809
- var liAllElm = $('<li class="uk-active"/>');
2810
- if (countAdded || countRemoved) {
2811
- liAllElm.append(allItemsList);
2812
- }
2813
- ukSwitcher.append(liAllElm);
2814
-
2815
- var liAddedElm = $('<li/>');
2816
- if (countAdded) {
2817
- liAddedElm.append(addedItemsList);
2818
- }
2819
- ukSwitcher.append(liAddedElm);
2820
-
2821
- var liRemovedElm = $('<li/>');
2822
- if (countRemoved) {
2823
- liRemovedElm.append(removedItemsList);
2824
- }
2825
-
2826
- ukSwitcher.append(liRemovedElm);
2827
- ukWrapRelative.append(ukSwitcher);
2828
- body.append(ukWrapRelative);
2829
- popupWrap.append(header).append(body);
2830
- initComparisonResultPopup(popupWrap, popupTitle);
2831
- }
2832
-
2833
- function getComparisonResultAddedItemsListElm(allItemsList) {
2834
- var cssClass = 'item-added';
2835
- return getComparisonResulItemsListElm(window.model.customMeta, compareModelsResult['new'], cssClass, allItemsList);
2836
- }
2837
-
2838
- function getComparisonResultRemovedItemsListElm(allItemsList) {
2839
- var cssClass = 'item-removed';
2840
- return getComparisonResulItemsListElm(window.model2.customMeta, compareModelsResult['old']['unique'], cssClass, allItemsList);
2841
- }
2842
-
2843
- function getComparisonResulItemsListElm(arCustomMeta, resultData, cssClass, allItemsList) {
2844
- var itemsList = $('<ul class="list-items">');
2845
- for (var i = 0; i < resultData.length; i++) {
2846
- var objId = arCustomMeta[resultData[i]]['id'];
2847
- var objName = arCustomMeta[resultData[i]]['name'];
2848
- var item = $('<li class="' + cssClass + '"><span class="name">' + objName + '</span><span class="props">' + ' [ ' + objId + ' ]' + '</span></li>');
2849
- item.data('objId', objId);
2850
- item.on('click', function () {
2851
- goToObject($(this).data('objId'));
2852
- });
2853
- allItemsList.append(item.clone(true));
2854
- itemsList.append(item);
2855
- }
2856
-
2857
- return itemsList;
2858
- }
2859
-
2860
- function initComparisonResultPopup(popupWrap, popupTitle) {
2861
- var toolbarHeight = $('.toolbar').height();
2862
-
2863
- popupWrap.dialog({
2864
- title: popupTitle,
2865
- classes: {
2866
- "ui-dialog": "ui-dialog-comparison"
2867
- },
2868
- maxHeight: ($(window).height()-toolbarHeight),
2869
- height: ($(window).height()-toolbarHeight),
2870
- position: {
2871
- my: 'right top',
2872
- at: 'right top',
2873
- of: '.canvas-wrap',
2874
- }
2875
- }).dialogExtend({
2876
- closable: false,
2877
- collapsable: true,
2878
- maximizable: true,
2879
- minimizable: true,
2880
- dblclick: "maximize",
2881
- titlebar: "transparent",
2882
- minimizeLocation: "left",
2883
- });
2884
- }
2885
-
2886
- function createComparisonResultPopupHeader(countAdded, labelAdded, countRemoved, labelRemoved) {
2887
- var header = $('<div class="comparison-popup-head">' +
2888
- '<div class="comparison-popup-head-item added"><div class="count uk-text-large uk-text-bold">'+countAdded+'</div><div class="label uk-text-bold">'+labelAdded+'</div></div>' +
2889
- '<div class="comparison-popup-head-item removed"><div class="count uk-text-large uk-text-bold">'+countRemoved+'</div><div class="label uk-text-bold">'+labelRemoved+'</div></div>'
2890
- + '</div>');
2891
-
2892
- return header;
2893
- }
2894
-
2895
- // Gltf
2896
- function highlightModelsDifference(result, isSideBySide) {
2897
- var color, arObjId;
2898
-
2899
- if (result['old']['unique'].length) {
2900
- arObjId = result['old']['unique'];
2901
- var opacity = 0.4; // TODO: old Model unique-objects opacity
2902
- if (isSideBySide) {
2903
- color = [1.0, 0.0, 0.8];
2904
- } else {
2905
- color = [0.9, 0.9, 0.9]; // TODO: old Model unique-objects color -> gray
2906
- setOpacityArObject(window.model, arObjId, opacity);
2907
- }
2908
- colorizeArObject(window.model2, arObjId, color); // TODO: old Model unique-objects change color
2909
- }
2910
-
2911
- // Make old Model not unique-objects unvisible
2912
- if (result['old']['notUnique'].length && !isSideBySide) {
2913
- arObjId = result['old']['notUnique'];
2914
- setVisibilityArObject(window.model2, arObjId, false);
2915
- }
2916
-
2917
- if (result['new'].length) {
2918
- arObjId = result['new'];
2919
- color = [1.0, 0.0, 0.8]; // TODO: new Model unique-objects color
2920
- colorizeArObject(window.model, arObjId, color);
2921
- }
2922
- }
2923
-
2924
- function colorizeArObject(arObjId, color) {
2925
- viewer.scene.setObjectsColorized(arObjId, color);
2926
- }
2927
-
2928
- function highlightArObject(arObjId, isHighlight) {
2929
- viewer.scene.setObjectsHighlighted(arObjId, isHighlight);
2930
- }
2931
-
2932
- function setOpacityArObject(arObjId, opacity) {
2933
- viewer.scene.setObjectsOpacity(arObjId, opacity);
3266
+ viewer.cameraFlight.flyTo({
3267
+ eye: worldPos,
3268
+ up: viewer.camera.worldUp,
3269
+ look: math.addVec3(worldPos, viewer.camera.worldForward, []),
3270
+ projection: "perspective",
3271
+ duration: 1.5
3272
+ }, () => {
3273
+ viewer.cameraControl.navMode = "firstPerson";
3274
+ viewer.cameraControl.followPointer = false;
3275
+ });
3276
+ } else {
3277
+ cameraMemento.restoreCamera(viewer.scene, () => {
3278
+ viewer.cameraControl.navMode = "planView";
3279
+ });
3280
+ }
3281
+ };
3282
+ }
2934
3283
  }
2935
3284
 
2936
- function setVisibilityArObject(arObjId, isVisible) {
2937
- viewer.scene.setObjectsVisible(arObjId, isVisible);
3285
+ //------------------------------------------------------------------------------------------------------------------
3286
+ // BCF Viewpoint JSON
3287
+ //------------------------------------------------------------------------------------------------------------------
3288
+ function bindBtnSaveBCFViewpointJSON() {
3289
+ $('#btnSaveBCFViewpointJSON').on('click', function () {
3290
+ saveBCFViewpointJSON();
3291
+ });
2938
3292
  }
2939
3293
 
2940
- function setVisibilityObject(objId, isVisible) {
2941
- viewer.scene.setObjectsVisible([objId], isVisible);
2942
- }
3294
+ function saveBCFViewpointJSON() {
3295
+ const viewpoint = bcfViewpoints.getViewpoint({ // Options
3296
+ spacesVisible: false, // Don't force IfcSpace types visible in viewpoint (default)
3297
+ spaceBoundariesVisible: false, // Don't show IfcSpace boundaries in viewpoint (default)
3298
+ openingsVisible: false // Don't force IfcOpening types visible in viewpoint (default)
3299
+ });
2943
3300
 
2944
- function colorizeObject(objId, color) {
2945
- viewer.scene.setObjectsColorized([objId], color);
2946
- }
3301
+ const viewpointStr = JSON.stringify(viewpoint, null, 4);
2947
3302
 
2948
- function highlightObject(objId, isHighlight) {
2949
- viewer.scene.setObjectsHighlighted([objId], isHighlight);
3303
+ // TODO -> save JSON
3304
+ alert(viewpointStr); // Only for Test
3305
+ console.log(viewpointStr); // Only for Test
2950
3306
  }
2951
3307
 
2952
- function setOpacityObject(objId, opacity) {
2953
- viewer.scene.setObjectsOpacity([objId], opacity);
3308
+ function bindBtnLoadBCFViewpointJSON() {
3309
+ $('#btnLoadBCFViewpointJSON').on('click', function () {
3310
+ loadBCFViewpointJSON();
3311
+ });
2954
3312
  }
2955
3313
 
2956
- function goToObject(objId) {
2957
- const scene = viewer.scene;
2958
- var entity = viewer.scene.objects[objId];
2959
- viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);
2960
-
2961
- if (entity) {
2962
- entity.selected = true;
2963
- viewer.cameraFlight.flyTo(entity);
2964
- }
3314
+ function getBCFViewpoint() {
3315
+ return bcfData; // Return Test-data from bcf.data.js
2965
3316
  }
2966
3317
 
2967
- function ViewFitAll(viewer) {
2968
- const aabb = viewer.scene.getAABB({});
2969
- const diag = math.getAABB3Diag(aabb);
2970
-
2971
- if (diag > viewer.camera.perspective.far) {
2972
- viewer.camera.perspective.far = diag;
2973
- }
2974
-
2975
- viewer.cameraFlight.flyTo({
2976
- projection: "perspective",
2977
- aabb: aabb,
2978
- duration: 0.5
2979
- });
3318
+ function loadBCFViewpointJSON() {
3319
+ const bcfViewpoint = getBCFViewpoint();
3320
+ bcfViewpoints.setViewpoint(bcfViewpoint);
2980
3321
  }
2981
3322
 
2982
3323
  //------------------------------------------------------------------------------------------------------------------
@@ -2989,7 +3330,7 @@ const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);
2989
3330
  //------------------------------------------------------------------------------------------------------------------
2990
3331
  function createDistanceMeasurements(distanceMeasurementsData) {
2991
3332
  var angleMeasurements = [];
2992
- $.each(distanceMeasurementsData,function(index,value){
3333
+ $.each(distanceMeasurementsData, function (index, value) {
2993
3334
  angleMeasurements.push(createDistanceMeasurementItem(value));
2994
3335
  });
2995
3336
 
@@ -3018,10 +3359,10 @@ function createDistanceMeasurementItem(measurement) {
3018
3359
  //------------------------------------------------------------------------------------------------------------------
3019
3360
 
3020
3361
  function bindBtnCreateDistanceMeasurements() {
3021
- $(document).on('click', '#btnCreateDistanceMeasurements', function() {
3362
+ $(document).on('click', '#btnCreateDistanceMeasurements', function () {
3022
3363
  $(this).toggleClass('toggled');
3023
3364
 
3024
- if($(this).hasClass('toggled')) {
3365
+ if ($(this).hasClass('toggled')) {
3025
3366
  $('#btnCreateNotes').removeClass('toggled');
3026
3367
  annotationByClick = false;
3027
3368
 
@@ -3032,367 +3373,692 @@ function bindBtnCreateDistanceMeasurements() {
3032
3373
  enableDistanceMeasurements();
3033
3374
  $('#btnToggleDistanceMeasurements').removeClass('toggled');
3034
3375
 
3035
- enableDistanceMeasurementsByClick();
3376
+ enableDistanceMeasurementsByClick();
3377
+
3378
+ } else {
3379
+ disableDistanceMeasurementsByClick();
3380
+ }
3381
+ });
3382
+ }
3383
+
3384
+ function enableDistanceMeasurementsByClick() {
3385
+ distanceMeasurementsByClick = true;
3386
+ distanceMeasurements.control.activate();
3387
+ }
3388
+
3389
+ function disableDistanceMeasurementsByClick() {
3390
+ distanceMeasurements.control.deactivate();
3391
+ distanceMeasurementsByClick = false;
3392
+ }
3393
+
3394
+ function bindBtnToggleDistanceMeasurements() {
3395
+ $(document).on('click', '#btnToggleDistanceMeasurements', function () {
3396
+ $(this).toggleClass('toggled');
3397
+
3398
+ if ($(this).hasClass('toggled')) {
3399
+ $('#btnCreateDistanceMeasurements').removeClass('toggled');
3400
+ disableDistanceMeasurementsByClick();
3401
+ disableDistanceMeasurements();
3402
+ } else {
3403
+ enableDistanceMeasurements();
3404
+ }
3405
+ });
3406
+ }
3407
+
3408
+ function enableDistanceMeasurements() {
3409
+ $.each(distanceMeasurements.measurements, function (index) {
3410
+ this.visible = true;
3411
+ });
3412
+ }
3413
+
3414
+ function disableDistanceMeasurements() {
3415
+ $.each(distanceMeasurements.measurements, function (index) {
3416
+ this.visible = false;
3417
+ });
3418
+ }
3419
+
3420
+
3421
+
3422
+ //------------------------------------------------------------------------------------------------------------------
3423
+ //
3424
+ //------------------------------------------------------------------------------------------------------------------
3425
+
3426
+ function showPropertyInspector(pickResult) {
3427
+ //var metaObject;
3428
+ //var model = getPickResultModel(pickResult);
3429
+ var objectId = pickResult.entity.id;
3430
+
3431
+ collapseSidebarIssueDetail();
3432
+ collapseSidebarNotes();
3433
+ $('#btnToggleSidebarNotes').removeClass('toggled');
3434
+
3435
+ setPropertyBDSets(objectId);
3436
+
3437
+ return false;
3438
+ }
3439
+
3440
+ function getPickResultModel(pickResult) {
3441
+ var modelId = getPickResultModelId(pickResult);
3442
+ if (modelId) {
3443
+ if (window.model.id == modelId) {
3444
+ return window.model;
3445
+ } else if (window.model2 && window.model2.id == modelId) {
3446
+ return window.model2;
3447
+ } else {
3448
+ return false;
3449
+ }
3450
+ } else {
3451
+ return false;
3452
+ }
3453
+ }
3454
+
3455
+ function getPickResultModelId(pickResult) {
3456
+ if (pickResult.entity.model && pickResult.entity.model.id) {
3457
+ return pickResult.entity.model.id;
3458
+ } else if (pickResult.entity._owner && pickResult.entity._owner.id) {
3459
+ return pickResult.entity._owner.id;
3460
+ } else {
3461
+ return false;
3462
+ }
3463
+ }
3464
+
3465
+ function getPropertyValue(property) {//todo: use in compare
3466
+ if (!property) {
3467
+ return '-';
3468
+ }
3469
+
3470
+ if (property.valueBool != null && property.valueBool != undefined) {
3471
+ return property.valueBool;
3472
+ }
3473
+ else if (property.valueInt != null && property.valueInt != undefined) {
3474
+ return property.valueInt;
3475
+ }
3476
+ else if (property.valueText != null && property.valueText != undefined) {
3477
+ return property.valueText;
3478
+ }
3479
+ else if (property.valueReal != null && property.valueReal != undefined) {
3480
+ const normalized = property.valueReal.replace(',', '.').trim();
3481
+ const num = Number(normalized);
3482
+ if (!isNaN(num)) {
3483
+ if (Math.abs(num) < 1) {
3484
+ return Number(num.toPrecision(3));
3485
+ } else {
3486
+ return Number(num.toFixed(2));
3487
+ }
3488
+ }
3489
+ return property.valueReal;
3490
+ }
3491
+ }
3492
+
3493
+ function convertProperty(data) {
3494
+ let groups = [];
3495
+
3496
+ for (let property of data) {
3497
+ let existingGroups = groups.filter(group => group.name == property.groupName);
3498
+ if (existingGroups.length > 0) {
3499
+ existingGroups[0].properties.push({ name: property.name, value: getPropertyValue(property) });
3500
+ }
3501
+ else {
3502
+ let newGroup = {
3503
+ name: property.groupName,
3504
+ properties: [],
3505
+ };
3506
+ newGroup.properties.push({ name: property.name, value: getPropertyValue(property) });
3507
+
3508
+
3509
+ groups.push(newGroup);
3510
+ }
3511
+ }
3512
+
3513
+ return groups;
3514
+ }
3515
+
3516
+ function setPropertyBDSets(id) {
3517
+ const html = [];
3518
+
3519
+ html.push('<div class="element-attributes">');
3520
+ html.push('</div>');
3521
+
3522
+ viewer.scene.canvas.spinner.processes++;
3523
+
3524
+ BIMModel.GetPropertyList(id,
3525
+ (data) => {
3526
+ const propertySets = convertProperty(data);
3527
+ addPropertySet(propertySets, html);
3528
+ viewer.scene.canvas.spinner.processes--;
3529
+ },
3530
+ (error) => {
3531
+ viewer.scene.canvas.spinner.processes--;
3532
+ }
3533
+ );
3534
+
3535
+ $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
3536
+ $('.xeokit-accordion-container').accordion({
3537
+ collapsible: true,
3538
+ heightStyle: "content"
3539
+ });
3540
+ showPropInspector();
3541
+ }
3542
+
3543
+ function addPropertySet(propertySets, html) {
3544
+ if (!propertySets || propertySets.length == 0) {
3545
+ html.push('<p class="subtitle">No properties sets found.</p>');
3546
+ }
3547
+ else {
3548
+ html.push('<div class="xeokit-accordion">');
3549
+ for (let i = 0, len = propertySets.length; i < len; i++) {
3550
+ const propertySet = propertySets[i];
3551
+ const properties = propertySet.properties || propertySet.p || [];
3552
+ if (properties.length > 0) {
3553
+ html.push('<div class="xeokit-accordion-container">' +
3554
+ '<h3><span>' + (propertySet.name ? propertySet.name : propertySet.propertySetName) + '</span></h3>' +
3555
+ '<div class="xeokit-accordion-panel">' +
3556
+ '<table class="xeokit-table"><tbody>'
3557
+ );
3558
+ for (let i = 0, len = properties.length; i < len; i++) {
3559
+ const property = properties[i];
3560
+ html.push('<tr><td class="td1">' + (property.Name || property.name || property.label) + ':</td><td class="td2">' + (property.v || property.Value || property.value) + '</td></tr>');
3561
+ }
3562
+ html.push('</tbody></table>' +
3563
+ '</div>' +
3564
+ '</div>');
3565
+ } else {
3566
+ html.push('<p class="subtitle">No properties sets found.</p>');
3567
+ }
3568
+ }
3569
+ html.push('</div>');
3570
+ }
3571
+ $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
3572
+ $('.xeokit-accordion-container').accordion({
3573
+ collapsible: true,
3574
+ heightStyle: "content"
3575
+ });
3576
+ showPropInspector();
3577
+ }
3578
+
3579
+ function setPropertySets(metaObject, dictionaryName = []) {
3580
+ const html = [];
3581
+ var propertySets = metaObject.propertySets || metaObject.ps;
3036
3582
 
3037
- } else {
3038
- disableDistanceMeasurementsByClick();
3583
+ html.push('<div class="element-attributes">');
3584
+ if (!metaObject) {
3585
+ html.push('<p class="subsubtitle">No object selected</p>');
3586
+ } else {
3587
+ html.push('<table class="xeokit-table">');
3588
+ html.push('<tr><td class="td1">Name:</td><td class="td2">' + metaObject.name + '</td></tr>');
3589
+ if (metaObject.type) {
3590
+ html.push('<tr><td class="td1">Class:</td><td class="td2">' + metaObject.type + '</td></tr>');
3039
3591
  }
3592
+ html.push('<tr><td class="td1">UUID:</td><td class="td2">' + metaObject.id + '</td></tr>');
3593
+ html.push('</table>');
3594
+
3595
+ addPropertySet(propertySets, html);
3596
+ }
3597
+ $('#propInspector .prop-inspector-content')[0].innerHTML = html.join("");
3598
+ $('.xeokit-accordion-container').accordion({
3599
+ collapsible: true,
3600
+ heightStyle: "content"
3040
3601
  });
3602
+ showPropInspector();
3041
3603
  }
3042
3604
 
3043
- function enableDistanceMeasurementsByClick() {
3044
- distanceMeasurementsByClick = true;
3045
- distanceMeasurements.control.activate();
3605
+ function bindPropInspectorClose() {
3606
+ $('.prop-inspector-close').on('click', function () {
3607
+ hidePropInspector();
3608
+ })
3046
3609
  }
3047
3610
 
3048
- function disableDistanceMeasurementsByClick() {
3049
- distanceMeasurements.control.deactivate();
3050
- distanceMeasurementsByClick = false;
3611
+ //------------------------------------------------------------------------------------------------------------------
3612
+ // PropertySets resizable
3613
+ //------------------------------------------------------------------------------------------------------------------
3614
+ function initPropertySetsResizable() {
3615
+ $('#propInspector').resizable({
3616
+ handles: "w",
3617
+ minWidth: 150
3618
+ });
3051
3619
  }
3052
3620
 
3053
- function bindBtnToggleDistanceMeasurements() {
3054
- $(document).on('click', '#btnToggleDistanceMeasurements', function() {
3055
- $(this).toggleClass('toggled');
3621
+ viewer.on('vitroCompareStatus', (status) => {
3622
+ if (status) {
3623
+ $('#propInspector').hide();
3624
+ }
3625
+ });
3626
+ //------------------------------------------------------------------------------------------------------------------
3627
+ // Do action wherever we click on an object
3628
+ //------------------------------------------------------------------------------------------------------------------
3056
3629
 
3057
- if($(this).hasClass('toggled')) {
3058
- $('#btnCreateDistanceMeasurements').removeClass('toggled');
3059
- disableDistanceMeasurementsByClick();
3060
- disableDistanceMeasurements();
3061
- } else {
3062
- enableDistanceMeasurements();
3063
- }
3064
- });
3065
- }
3630
+ viewer.scene.input.on("mouseclicked", (coords) => {
3066
3631
 
3067
- function enableDistanceMeasurements() {
3068
- $.each(distanceMeasurements.measurements, function(index) {
3069
- this.visible = true;
3632
+ const pickResult = viewer.scene.pick({
3633
+ canvasPos: coords,
3634
+ pickSurface: true, // <<------ This causes picking to find the intersection point on the entity
3635
+ //includeEntities: true,
3070
3636
  });
3071
- }
3072
3637
 
3073
- function disableDistanceMeasurements() {
3074
- $.each(distanceMeasurements.measurements, function(index) {
3075
- this.visible = false;
3076
- });
3077
- }
3638
+ if (pickResult) {
3639
+ if ($('#btnCreateNotes').hasClass('toggled')) {
3640
+ createAnnotationByClick(pickResult);
3641
+ }
3642
+ createSectionPlaneByClick(pickResult);
3643
+ }
3644
+ });
3078
3645
 
3079
3646
  //------------------------------------------------------------------------------------------------------------------
3080
- // FastNavPlugin
3647
+ // Show Object Properties on Click
3081
3648
  //------------------------------------------------------------------------------------------------------------------
3649
+ viewer.cameraControl.on("picked", (pickResult) => {
3650
+ if (!pickResult.entity) {
3651
+ return;
3652
+ }
3082
3653
 
3083
- const fastNavPlugin = new FastNavPlugin(viewer, {
3084
- hideEdges: true, // Don't show edges while we interact (default is true)
3085
- hideSAO: true, // Don't show ambient shadows while we interact (default is true)
3086
- hideColorTexture: true, // No color textures while we interact (default is true)
3087
- hidePBR: true, // No physically-based rendering while we interact (default is true)
3088
- hideTransparentObjects: true, // Hide transparent objects while we interact (default is false)
3089
- scaleCanvasResolution: true, // Scale canvas resolution while we interact (default is false)
3090
- scaleCanvasResolutionFactor: 0.5, // Factor by which we scale canvas resolution when we interact (default is 0.6)
3091
- delayBeforeRestore: true, // When we stop interacting, delay before restoring normal render (default is true)
3092
- delayBeforeRestoreSeconds: 1, // The delay duration, in seconds (default is 0.5)
3093
- hideTempObj: false,
3094
- maxTreeDepth: 20,
3654
+ if (pickResult.entity.id && !$('#btnCreateNotes').hasClass('toggled')) {
3655
+ showPropertyInspector(pickResult);
3656
+ }
3095
3657
  });
3096
3658
 
3659
+ /*viewer.cameraControl.on("pickedNothing", () => {
3660
+ return false;
3661
+ });*/
3662
+
3097
3663
  //------------------------------------------------------------------------------------------------------------------
3098
- //
3099
- //------------------------------------------------------------------------------------------------------------------
3100
-
3101
- const EVENT_SEARCH_ISSUE_LIST = 'vitro.search.issue.list';
3102
- const EVENT_ISSUE_LIST_REFRESH = 'vitro.issue.list.refresh';
3103
- const EVENT_ISSUE_LIST_SELECT_ITEM = 'vitro.issue.list.select.item';
3104
- const PANE_LEFT_MIN_WIDTH = 150;
3105
- const PANE_RIGHT_MIN_WIDTH = 200;
3106
3664
 
3107
- var notesDescriptionVisibleList = {};
3665
+ window.viewer = viewer;
3108
3666
 
3109
- BIMAnnotation.GetNote = (callback) => {
3110
- callback([]);
3111
- }
3667
+ let version = context.fileVersionList.find(x => x.id === context.versionId);
3668
+ let versionStr = version ? version.name : null;
3112
3669
 
3113
- function saveNote(pickResult) {
3670
+ BIMCommon.GetFileItem(context.file.id, versionStr, function (modelId) {
3114
3671
 
3115
- }
3672
+ context.getItem(modelId).then(item => {
3673
+ var filePath = context.getFilePath(item.id);
3674
+ var fileName = context.file.fieldValueMap?.name;
3116
3675
 
3117
- function createMarkupData(pickResult) {
3118
- let markup = {};
3119
- markup.worldPos = [];
3120
- markup.worldPos.push(pickResult._worldPos[0]);
3121
- markup.worldPos.push(pickResult._worldPos[1]);
3122
- markup.worldPos.push(pickResult._worldPos[2]);
3676
+ document.title += " - " + fileName;
3677
+ //fileVersion = '';
3678
+ //fileVersionPath = filePath;
3679
+ hideXeokitSpinner();
3123
3680
 
3124
- var eye = viewer.camera.eye;
3125
- markup.eye = [];
3126
- markup.eye.push(eye[0]);
3127
- markup.eye.push(eye[1]);
3128
- markup.eye.push(eye[2]);
3681
+ const model = new BIMCommon.VitroModel(context.file.id, versionStr, filePath, fileName);
3129
3682
 
3130
- var look = viewer.camera.look;
3131
- markup.look = [];
3132
- markup.look.push(look[0]);
3133
- markup.look.push(look[1]);
3134
- markup.look.push(look[2]);
3683
+ BIMCommon.ModelList.push(model);
3135
3684
 
3136
- var up = viewer.camera.up;
3137
- markup.up = [];
3138
- markup.up.push(up[0]);
3139
- markup.up.push(up[1]);
3140
- markup.up.push(up[2]);
3685
+ window.model = doLoadModel(viewer, xktLoader, model, true);
3686
+ window.model.ModelList = BIMCommon.ModelList;
3141
3687
 
3142
- if (pickResult.entity && pickResult.entity.id) {
3143
- markup.entity = pickResult.entity.id;
3144
- }
3688
+ })
3689
+
3690
+ }, function () {
3691
+ alert("The file is being processed");
3692
+ });
3145
3693
 
3146
- return markup;
3147
- }
3694
+ var userLocale =
3695
+ navigator.languages && navigator.languages.length
3696
+ ? navigator.languages[0]
3697
+ : navigator.language;
3148
3698
 
3149
- function addIssue(itemId, data) {
3150
- context.onCreateIssue(itemId, data);
3699
+ document.webL10n.setLanguage(userLocale, function () {
3700
+ document.webL10n.translate();
3701
+ });
3702
+
3703
+ //------------------------------------------------------------------------------------------------------------------
3704
+ // Compare Models
3705
+ //------------------------------------------------------------------------------------------------------------------
3706
+ const add = 'add';
3707
+ const del = 'del';
3708
+ const changeA = 'changeA';
3709
+ const changeB = 'changeB';
3710
+ const change = 'change';
3711
+ const property = 'property';
3712
+ const geometry = 'geometry';
3713
+ const CSS_CLASS_SELECTED = 'vitro-selected';
3714
+ const CSS_CLASS_ACTIVE = 'uk-active';
3715
+ const EVENT_FILTER_CHANGE_TYPE = 'vitro.changeType';
3716
+ const EVENT_COMPARE_TREE_ITEM_SLECT = 'vitro.compare.tree.item.select';
3151
3717
 
3152
- hidePropInspector();
3153
- expandSidebarIssueDetail();
3154
- }
3718
+ let compareModelsResult;
3719
+ let isCompareSideBySide;
3720
+ let compareObjList;
3721
+ let viewerCompare;
3155
3722
 
3156
- function createAnnotationByClick(pickResult) {
3157
- let data = createMarkupData(pickResult);
3723
+ function bindBtnCompareOneOverOne() {
3724
+ $(document).on('click', '#btnCompareOneOverOne', function () {
3725
+ if ($('#btnCompareSideBySide').hasClass('toggled')) {
3726
+ resetCanvasWrapWidth();
3727
+ $('#btnCompareSideBySide').removeClass('toggled');
3728
+ doRemoveComparison();
3729
+ }
3730
+ if (!$(this).hasClass('toggled')) {
3731
+ compareModels(false);
3732
+ }
3733
+ $(this).addClass('toggled');
3734
+ });
3735
+ }
3158
3736
 
3159
- if (data.entity) {
3160
- viewer.scene.canvas.spinner.processes++;
3737
+ function bindBtnCompareSideBySide() {
3738
+ $(document).on('click', '#btnCompareSideBySide', function () {
3739
+ if ($('#btnCompareOneOverOne').hasClass('toggled')) {
3740
+ resetCanvasWrapWidth();
3741
+ $('#btnCompareOneOverOne').removeClass('toggled');
3742
+ doRemoveComparison();
3743
+ }
3744
+ if (!$(this).hasClass('toggled')) {
3745
+ compareModels(true);
3746
+ }
3747
+ $(this).addClass('toggled');
3748
+ });
3749
+ }
3161
3750
 
3162
- const callback = (modelInfo, status, jqXHR) => {
3751
+ function bindBtnClearComparison() {
3752
+ $(document).on('click', '#btnClearComparison', function () {
3753
+ $('#btnCompareOneOverOne').removeClass('toggled');
3754
+ $('#btnCompareSideBySide').removeClass('toggled');
3755
+ $('#btnToggleCompare').removeClass('toggled');
3163
3756
 
3164
- const itemId = modelInfo?.itemId ? modelInfo?.itemId : context.file.id;
3757
+ removeCompareLabel();
3758
+ doRemoveComparison();
3759
+ resetCanvasWrapWidth();
3760
+ window.removeEventListener('resize', onWindowResizeCompareDialog);
3761
+ });
3762
+ }
3165
3763
 
3166
- addIssue(itemId, data);
3764
+ function doRemoveComparison() {
3765
+ if (isCompareSideBySide) {
3766
+ const left = document.getElementById("xeokitCanvas");
3767
+ const right = document.getElementById("xeokitCompareCanvas");
3167
3768
 
3168
- viewer.scene.canvas.spinner.processes--;
3169
- };
3769
+ left.style.width = "100%";
3770
+ right.style.display = "none";
3170
3771
 
3171
- const error = () => {
3172
- viewer.scene.canvas.spinner.processes--;
3173
- };
3772
+ offSyncCamera(viewer);
3773
+ offSyncCamera(viewerCompare);
3174
3774
 
3175
- BIMModel.GetModel(data.entity, callback, error);
3176
- }
3177
- else {
3178
- addIssue(context.file.id, data);
3775
+ viewerCompare.destroy();
3179
3776
  }
3180
- }
3181
3777
 
3778
+ setSceneAllObjectsVisible(viewer.scene, true);
3182
3779
 
3780
+ if (window.model2) {
3781
+ window.model2.vitroModelLoader.startSmallLoad = false;
3183
3782
 
3184
- function bindBtnToggleCreateNotes() {
3185
- $(document).on('click', '#btnCreateNotes', function () {
3186
- $(this).toggleClass('toggled');
3783
+ if (!window.model2.destroyed) {
3784
+ window.model2.destroy();
3187
3785
 
3188
- if ($(this).hasClass('toggled')) {
3189
- $('#btnCreateSectionPlan').removeClass('toggled');
3190
- disableSectionPlanByClick();
3191
- disableAngleMeasurementsByClick();
3192
- disableDistanceMeasurementsByClick();
3193
- showAnnotationMarkers();
3194
- $('#btnToggleNotes').removeClass('show');
3195
- collapseSidebarNotes();
3196
- $('#btnToggleSidebarNotes').removeClass('toggled');
3197
- annotationByClick = true;
3198
- } else {
3199
- annotationByClick = false;
3200
- collapseSidebarIssueDetail();
3786
+ if (window.model2.vitroModelLoader && !window.model2.vitroModelLoader.destroyed) {
3787
+ window.model2.vitroModelLoader.destroy();
3788
+ window.model2.vitroModelLoader = undefined
3789
+ }
3201
3790
  }
3202
- });
3791
+
3792
+ window.model2 = undefined
3793
+ }
3794
+
3795
+ $('.comparison-popup-wrap').dialog("destroy");
3796
+ $('.property-comparison-popup-wrap').dialog("destroy");
3797
+ restoreObjectColorsAfterCompare();
3798
+
3799
+ viewer.fire('vitroCompareStatus', false);
3203
3800
  }
3204
3801
 
3205
- function bindBtnToggleSidebarNotes() {
3206
- $(document).on('click', '#btnToggleSidebarNotes', function () {
3207
- $(this).toggleClass('toggled');
3802
+ function restoreObjectColorsAfterCompare() {
3803
+ viewer.scene.modelIds.forEach((modelId) => {
3804
+ const m = viewer.scene.models[modelId];
3208
3805
 
3209
- if ($(this).hasClass('toggled')) {
3210
- $('#btnCreateNotes').removeClass('toggled');
3211
- annotationByClick = false;
3212
- if (!$('.sidebar').is(':visible')) {
3213
- initSidebarNotes();
3214
- expandSidebarNotes();
3215
- }
3216
- } else {
3217
- collapseSidebarNotes();
3806
+ if (m.loadedVitroCompare) {
3807
+ var list = Object.keys(m.loadedVitroCompare);
3808
+
3809
+ list.forEach(key => {
3810
+ viewer.scene.off(m.loadedVitroCompare[key]);
3811
+ m.loadedVitroCompare[key] = false;
3812
+ });
3218
3813
  }
3814
+
3815
+ m.colorize = undefined;
3816
+ m.opacity = undefined;
3219
3817
  });
3818
+
3819
+ compareModelsResult = false;
3220
3820
  }
3221
3821
 
3222
- function bindSidebarNotesClose() {
3223
- $('.sidebar-close').on('click', function () {
3224
- $('#btnToggleSidebarNotes').removeClass('toggled');
3225
- collapseSidebarNotes();
3822
+ function compareModels(isSideBySide) {
3823
+ isCompareSideBySide = isSideBySide;
3824
+ showDlgCompare();
3825
+ }
3826
+
3827
+ function doCompareModels(isSideBySide) {
3828
+ runCompare({
3829
+ filters: getServerFiltersFromUI(),
3830
+ sideBySide: !!isSideBySide,
3831
+ createWindow: true,
3832
+ resetSkip: true
3226
3833
  });
3227
3834
  }
3228
3835
 
3229
- function expandSidebarNotes() {
3230
- hidePropInspector();
3231
- collapseSidebarIssueDetail();
3836
+ function createComparisonResultPopupWindow() {
3837
+ window.BIMModel = BIMModel; // todo: delete. It is only for test
3232
3838
 
3233
- $('#sidebarWrap').show();
3234
- $('#navCubeCanvas').css('right', $('#sidebarWrap').width() + 10);
3235
- $('#sectionPlanesOverviewCanvas').css('right', $('#sidebarWrap').width() + 10);
3236
- var body = $('body');
3237
- var bodyScrollWidth = body[0].offsetWidth - body[0].scrollWidth;
3238
- var vScrollWidth = bodyScrollWidth ? bodyScrollWidth : 0;
3239
- $('.sidebar').css('right', (vScrollWidth + 'px')).show("slide", { direction: "right" }, 200);
3240
- body.addClass('sidebar-expanded');
3241
- }
3839
+ var popupTitle = document.webL10n.get('version_changes');
3840
+ var labelList = 'Список'; // document.webL10n.get('version_changes_all'); // TODO - translation
3841
+ var labelTree = 'Дерево'; // TODO - translation
3842
+ var labelTreeContentHeader = 'Название'; // TODO - translation
3843
+ var labelTreeContentHeaderCount = 'Кол-во'; // TODO - translation
3844
+ var labelAdded = document.webL10n.get('version_changes_added');
3845
+ var labelRemoved = document.webL10n.get('version_changes_removed');
3846
+ var labelChanged = document.webL10n.get('version_changes_changed');
3242
3847
 
3243
- function getMarkupData(item) {
3848
+ var popupWrap = $('<div class="comparison-popup-wrap"/>');
3244
3849
 
3245
- let markup = JSON.parse(item.fieldValueMap.markup);
3246
- var options = {
3247
- id: item.fieldValueMap.item_id,
3248
- creator: item.insUserName,
3249
- worldPos: markup.worldPos,
3250
- eye: markup.eye, // need for camera fly on sidebar click
3251
- look: markup.look, // need for camera fly on sidebar click
3252
- up: markup.up, // need for camera fly on sidebar click
3253
- occludable: false,
3254
- markerShown: true,
3255
- labelShown: false,
3256
- version: '',
3257
- fileVersionPath: '',
3258
- values: {
3259
- glyph: item.fieldValueMap.item_id,
3260
- title: item.fieldValueMap.name,
3261
- description: item.fieldValueMap.description,
3262
- markerBGColor: item.fieldValueMap.task_status?.fieldValueMap?.color || '#2d9cdb',
3263
- imageSrc: ''
3264
- }
3265
- };
3850
+ const popupTitleElm = createComparisonResultPopupTitle(popupTitle);
3851
+ var header = createComparisonResultPopupHeader(labelAdded, labelRemoved, labelChanged);
3852
+ const search = createSearch();
3266
3853
 
3267
- if (markup.entity) {
3268
- options.entity = viewer.scene.objects[markup.entity];
3269
- }
3854
+ var compareListContentElm = $('<ul class="list-items" id="compareListContent"/>');
3270
3855
 
3271
- return options;
3856
+ var body = $('<div class="comparison-popup-body"/>');
3857
+ var ukWrapRelative = $('<div class="uk-position-relative"/>');
3858
+
3859
+ var ukTabHeader = $('<ul uk-tab="swiping: false" class="uk-tab"/>');
3860
+ const tabHeaderItemList = $('<li class="uk-active" id="compareList"><a href="#" aria-expanded="true">' + labelList + '</a></li>');
3861
+ const tabHeaderItemTree = $('<li id="compareTree"><a href="#" aria-expanded="false">' + labelTree + '</a></li>');
3862
+
3863
+ tabHeaderItemTree.on('click', function () { initCompareTreeView(); });
3864
+
3865
+ ukTabHeader.append(tabHeaderItemList).append(tabHeaderItemTree);
3866
+ ukWrapRelative.append(ukTabHeader);
3867
+
3868
+ var ukSwitcher = $('<ul class="uk-switcher"/>');
3869
+
3870
+ var liListElm = $('<li class="uk-active"/>');
3871
+ liListElm.append(compareListContentElm);
3872
+ ukSwitcher.append(liListElm);
3873
+
3874
+ var liTreeElm = $('<li/>');
3875
+ const treeContentHeader = $('<div class="vitro-compare-tree-header"/>');
3876
+ treeContentHeader.html('<span>' + labelTreeContentHeader + '</span><span>' + labelTreeContentHeaderCount + '</span>');
3877
+ const treeContent = $('<div id="compareTreeContent"/>');
3878
+ liTreeElm.append(treeContentHeader).append(treeContent);
3879
+ ukSwitcher.append(liTreeElm);
3880
+
3881
+ ukWrapRelative.append(ukSwitcher);
3882
+ body.append(ukWrapRelative);
3883
+
3884
+ popupWrap.append(popupTitleElm).append(header).append(search).append(body);
3885
+
3886
+ initComparisonResultPopup(popupWrap, popupTitle);
3887
+
3888
+ return popupWrap;
3272
3889
  }
3273
3890
 
3274
- function bindUpdatePage() {
3275
- if (context.deleteIssueEvent) {
3276
- window.addEventListener(context.deleteIssueEvent, updatePage);
3891
+ function fillComparisonResultList(compareModelsResult) {
3892
+ var $list = $('#compareListContent');
3893
+ if (!$list.length) {
3894
+ createComparisonResultPopupWindow();
3895
+ $list = $('#compareListContent');
3277
3896
  }
3278
3897
 
3279
- if (context.updateIssueEvent) {
3280
- window.addEventListener(context.updateIssueEvent, updatePage);
3898
+ const compareListContent = getCompareListContent(compareModelsResult);
3899
+ $list.empty();
3900
+ if (compareListContent && compareListContent.length) {
3901
+ $list.append(compareListContent);
3281
3902
  }
3282
3903
  }
3283
3904
 
3284
- bindUpdatePage();
3905
+ function initCompareTreeView() {
3906
+ context.initCompareTreeView();
3907
+ }
3285
3908
 
3286
- function updatePage(e) {
3287
- if (e.type === context.updateIssueEvent) {
3288
- const item = e.detail.itemList[0];
3289
- if (item.fieldValueMap?.markup) {
3290
- const data = getMarkupData(item);
3291
- annotations.destroyAnnotation(item.fieldValueMap.item_id);
3292
- createNote(data);
3293
- setTimeout(function () {
3294
- if (isNoteDescriptionVisible(data.id)) {
3295
- annotations.annotations[data.id].setLabelShown(true);
3296
- } else {
3297
- annotations.annotations[data.id].setLabelShown(false);
3298
- }
3299
- }, 10);
3300
- }
3301
-
3302
- if (!$('#btnToggleSidebarNotes').hasClass('toggled')) {
3303
- refreshIssueList();
3304
- }
3305
- }
3909
+ function getComparisonResultAddedItemsListElm(compareModelsResult) {
3910
+ var cssClass = 'item-added';
3911
+ var addResult = compareModelsResult?.filter(e => e.changeType === add);
3306
3912
 
3307
- if (e.type === context.deleteIssueEvent) {
3913
+ return getComparisonResulItemsListElm(addResult, cssClass);
3914
+ }
3308
3915
 
3309
- let item = e.detail.itemList[0];
3310
- annotations.destroyAnnotation(item.fieldValueMap.item_id);
3311
- refreshIssueList();
3312
- if (isNoteDescriptionVisible(item.fieldValueMap.item_id)) {
3313
- removeFromNotesDescriptionVisibleList(item.fieldValueMap.item_id);
3314
- }
3315
- }
3916
+ function getComparisonResultRemovedItemsListElm(compareModelsResult) {
3917
+ var cssClass = 'item-removed';
3918
+ var delResult = compareModelsResult?.filter(e => e.changeType === del);
3919
+
3920
+ return getComparisonResulItemsListElm(delResult, cssClass);
3316
3921
  }
3317
3922
 
3318
- function refreshIssueList() {
3319
- const event = new CustomEvent(EVENT_ISSUE_LIST_REFRESH, { detail: {} });
3320
- window.dispatchEvent(event);
3923
+ function getComparisonResultChangedItemsListElm(compareModelsResult) {
3924
+ var cssClass = 'item-changed';
3925
+ var changeResult = compareModelsResult?.filter(e => e.changeType === change);
3926
+
3927
+ return getComparisonResulItemsListElm(changeResult, cssClass);
3321
3928
  }
3322
3929
 
3323
- function goToNoteMarker(issue) {
3324
- if (!$('#btnCreateNotes').hasClass('toggled')) {
3325
- hideNotesDescription();
3326
- clearNotesDesriptionVisibleList();
3327
- addToNotesDescriptionVisibleList(issue.id);
3328
- var annotation = annotations.annotations[issue.id];
3329
- viewer.cameraFlight.flyTo(annotation);
3330
- annotation.occludable = false;
3331
- annotation.setLabelShown(true);
3332
- highlightSidebarNote(issue.id);
3930
+ function getComparisonResulItemsListElm(resultData, cssClass) {
3931
+ const itemsList = [];
3932
+
3933
+ for (let i = 0; i < resultData.length; i++) {
3934
+ const obj = resultData[i];
3935
+ const objName = obj.name;
3936
+ const objUuid = obj.uuid;
3937
+
3938
+ const item = $('<li class="' + cssClass + '"><span class="name">' + objName + '</span><span class="props">[ ' + objUuid + ' ]</span></li>');
3939
+
3940
+ item.data('obj', obj);
3941
+
3942
+ item.on('click', function () {
3943
+ const data = $(this).data('obj');
3944
+ onComparisonResulItemClick(data);
3945
+ selectListItem($(this));
3946
+ });
3947
+
3948
+ itemsList.push(item);
3333
3949
  }
3950
+
3951
+ return itemsList;
3334
3952
  }
3335
3953
 
3336
- function onIssueShowMoreClick(issue) {
3337
- const listId = issue.item.listId;
3338
- const itemId = {
3339
- id: issue.item.id,
3340
- contentTypeId: issue.item.contentTypeId,
3341
- listId: listId,
3342
- parentId: issue.item.parentId,
3343
- siteId: issue.item.siteId
3344
- };
3954
+ function initComparisonResultPopup(popupWrap, popupTitle) {
3955
+ var toolbarHeight = $('.toolbar').height();
3345
3956
 
3346
- let event = new CustomEvent('vitro.item.changed', {
3347
- detail: {
3348
- itemIdList: [itemId],
3349
- listId: listId
3957
+ popupWrap.dialog({
3958
+ title: popupTitle,
3959
+ classes: {
3960
+ "ui-dialog": "ui-dialog-comparison"
3961
+ },
3962
+ maxHeight: ($(window).height() - toolbarHeight),
3963
+ height: ($(window).height() - toolbarHeight),
3964
+ width: 434,
3965
+ position: {
3966
+ my: 'right top',
3967
+ at: 'right top',
3968
+ of: '.canvas-wrap',
3969
+ },
3970
+ open: function (event, ui) {
3971
+ onResizeCompareDialog();
3972
+ window.removeEventListener('resize', onWindowResizeCompareDialog);
3973
+ window.addEventListener('resize', onWindowResizeCompareDialog);
3974
+ },
3975
+ resize: function (event, ui) {
3976
+ onResizeCompareDialog();
3977
+ },
3978
+ resizeStop: function (event, ui) {
3979
+ onResizeCompareDialog();
3350
3980
  }
3981
+ }).dialogExtend({
3982
+ closable: false
3351
3983
  });
3352
- window.dispatchEvent(event);
3353
- collapseSidebarNotes();
3354
- hidePropInspector();
3355
- expandSidebarIssueDetail();
3356
- $('#btnToggleSidebarNotes').removeClass('toggled');
3357
3984
  }
3358
3985
 
3359
- function collapseSidebarNotes() {
3360
- $('#sidebarWrap').hide();
3361
- $('#navCubeCanvas').css('right', 10);
3362
- $('#sectionPlanesOverviewCanvas').css('right', 10);
3363
- $('.sidebar').hide();
3364
- $('body').removeClass('sidebar-expanded');
3365
- }
3986
+ function createComparisonResultPopupHeader(labelAdded, labelRemoved, labelChanged) {
3987
+ const header = $('<div class="comparison-popup-head"/>');
3988
+ const added = $('<div id="btnCompareFilterAdd" class="comparison-popup-head-item added ' + CSS_CLASS_SELECTED + '"><div class="count">' + 0 + '</div><div class="label">' + labelAdded + '</div></div>');
3989
+ bindOnClickBtnCompareFilterHandler(added);
3990
+ const changed = $('<div id="btnCompareFilterDel" class="comparison-popup-head-item removed ' + CSS_CLASS_SELECTED + '"><div class="count">' + 0 + '</div><div class="label">' + labelRemoved + '</div></div>');
3991
+ bindOnClickBtnCompareFilterHandler(changed);
3992
+ const deleted = $('<div id="btnCompareFilterChange" class="comparison-popup-head-item changed ' + CSS_CLASS_SELECTED + '"><div class="count">' + 0 + '</div><div class="label">' + labelChanged + '</div></div>');
3993
+ bindOnClickBtnCompareFilterHandler(deleted);
3994
+ header.append(added).append(changed).append(deleted);
3366
3995
 
3367
- function initSidebarNotes() {
3368
- context.initIssueList(goToNoteMarker, onIssueShowMoreClick);
3996
+ return header;
3369
3997
  }
3370
3998
 
3371
- function expandSidebarIssueDetail() {
3372
- $('#issueDetail').show();
3373
- $('#navCubeCanvas').css('right', $('#issueDetail').width() + 10);
3374
- $('#sectionPlanesOverviewCanvas').css('right', $('#issueDetail').width() + 10);
3375
- $('body').addClass('sidebar-expanded');
3999
+ function setComparisonCounts(addedCount, removedCount, changedCount) {
4000
+ $('#btnCompareFilterAdd .count').text(addedCount);
4001
+ $('#btnCompareFilterDel .count').text(removedCount);
4002
+ $('#btnCompareFilterChange .count').text(changedCount);
3376
4003
  }
3377
4004
 
3378
- function collapseSidebarIssueDetail() {
3379
- $('#issueDetail').hide();
3380
- $('#navCubeCanvas').css('right', 10);
3381
- $('#sectionPlanesOverviewCanvas').css('right', 10);
3382
- $('body').removeClass('sidebar-expanded');
3383
- }
3384
4005
 
3385
- //------------------------------------------------------------------------------------------------------------------
3386
- // Load Annotations
3387
- //------------------------------------------------------------------------------------------------------------------
3388
- function createSidebarNotesItemHeader(noteData) {
4006
+ function highlightModelsDifference(idList, isSideBySide) {
4007
+ const colorGray = [0.9529, 0.9529, 0.9529];
4008
+ const colorDel = [0.8549, 0.3843, 0.4157];
4009
+ const colorAdd = [0.6078, 0.8824, 0.7294];
4010
+ const colorChange = [0.9137, 0.9373, 0.4588];
4011
+
4012
+ if (!idList) {
4013
+ return;
4014
+ }
4015
+
4016
+ const addIds = idList[add];
4017
+ const delIds = idList[del];
4018
+ const changeAIds = idList[changeA];
4019
+ const changeBIds = idList[changeB];
4020
+
4021
+ setComparisonCounts(addIds?.length ?? 0, delIds?.length ?? 0, changeAIds?.length ?? 0 + changeBIds?.length ?? 0);
4022
+
4023
+ if (window.model2 && delIds) {
4024
+ withObjectIdsForModel(window.model2, delIds,
4025
+ entity => { entity.opacity = 1.0; entity.colorize = colorDel },
4026
+ entity => { entity.colorize = colorGray },
4027
+ 'onModelBColorize');
4028
+ }
3389
4029
 
4030
+ if (window.model && addIds) {
4031
+ withObjectIdsForModel(window.model, addIds,
4032
+ entity => { entity.opacity = 1.0; entity.colorize = colorAdd },
4033
+ entity => { entity.colorize = colorGray },
4034
+ 'onModelAColorize');
4035
+ if (!isSideBySide) {
4036
+ setModelAllObjectsVisible(window.model, false);
4037
+ setModelObjectsVisible(window.model, addIds, true);
4038
+ }
4039
+ }
4040
+ if (window.model && changeAIds) {
4041
+ withObjectIdsForModel(window.model, changeAIds,
4042
+ entity => { entity.opacity = 1.0; entity.colorize = colorChange },
4043
+ undefined,
4044
+ 'onChangeModelAColorize');
4045
+ }
4046
+ if (window.model2 && changeBIds) {
4047
+ withObjectIdsForModel(window.model2, changeBIds,
4048
+ entity => { entity.opacity = 1.0; entity.colorize = colorChange },
4049
+ undefined,
4050
+ 'onChangeModelBColorize');
4051
+ }
3390
4052
  }
3391
4053
 
3392
- function hidePropInspector() {
3393
- $('#propInspector').hide();
3394
- setPositionNavCubeCanvas(0);
3395
- setPositionSectionPlanesOverviewCanvas(0);
4054
+ function withObjectIdsForModel(model, callback, callbackOther, propertyName) {
4055
+ withObjectIds(model, callback, callbackOther, propertyName);
4056
+
4057
+ if (model.vitroModelLoader && model.vitroModelLoader.smallModelList) {
4058
+ model.vitroModelLoader.smallModelList.forEach(m => {
4059
+ withObjectIds(m, callback, callbackOther, propertyName);
4060
+ });
4061
+ }
3396
4062
  }
3397
4063
 
3398
4064
  //------------------------------------------------------------------------------------------------------------------
@@ -3468,6 +4134,8 @@ function bindBtnDoCompare() {
3468
4134
  hideDlgCompare();
3469
4135
  hideDlgOverlay();
3470
4136
  doCompare();
4137
+
4138
+ viewer.fire('vitroCompareStatus', true);
3471
4139
  }
3472
4140
  });
3473
4141
  }
@@ -3564,9 +4232,6 @@ function initCompare() {
3564
4232
  checkIsAllowedCompare();
3565
4233
  }
3566
4234
 
3567
- var compareObjList;
3568
- var isCompareSideBySide;
3569
-
3570
4235
  function getCompareObjList() {
3571
4236
  return {
3572
4237
  modelAVersion: getModelAVersion(),
@@ -3592,65 +4257,124 @@ function showDlgCompare() {
3592
4257
  $('.compare-dlg-wrap').show();
3593
4258
  }
3594
4259
 
3595
- function compareModels(isSideBySide) {
3596
- isCompareSideBySide = isSideBySide;
3597
- showDlgCompare();
4260
+
4261
+
4262
+ function highlightArObject(arObjId, isHighlight) {
4263
+ viewer.scene.setObjectsHighlighted(arObjId, isHighlight);
4264
+ }
4265
+
4266
+ function setOpacityArObject(arObjId, opacity) {
4267
+ viewer.scene.setObjectsOpacity(arObjId, opacity);
4268
+ }
4269
+
4270
+ function setVisibilityArObject(arObjId, isVisible) {
4271
+ viewer.scene.setObjectsVisible(arObjId, isVisible);
4272
+ }
4273
+
4274
+ function setVisibilityObject(objId, isVisible) {
4275
+ viewer.scene.setObjectsVisible([objId], isVisible);
4276
+ }
4277
+
4278
+ function colorizeObject(objId, color) {
4279
+ viewer.scene.setObjectsColorized([objId], color);
4280
+ }
4281
+
4282
+ function highlightObject(objId, isHighlight) {
4283
+ viewer.scene.setObjectsHighlighted([objId], isHighlight);
4284
+ }
4285
+
4286
+ function setOpacityObject(objId, opacity) {
4287
+ viewer.scene.setObjectsOpacity([objId], opacity);
4288
+ }
4289
+
4290
+ function goToObjectByAABB(objId, modelList) {
4291
+ var callback = (aabb) =>
4292
+ {
4293
+ viewer.scene.canvas.spinner.processes--;
4294
+ viewer.cameraFlight.flyTo(aabb);
4295
+ }
4296
+ var error = () =>
4297
+ {
4298
+ viewer.scene.canvas.spinner.processes--;
4299
+ }
4300
+
4301
+ viewer.scene.canvas.spinner.processes++;
4302
+
4303
+ BIMModel.GetAABB(objId, modelList, callback, error);
4304
+ }
4305
+
4306
+ function goToObject(objId, objIdB) {
4307
+ var entity = window.model.objects[objId];
4308
+ var entityB = window.model2.objects[objIdB];
4309
+
4310
+ if (entity) {
4311
+ entity.scene.scene.viewer.cameraFlight.flyTo(entity);
4312
+ }
4313
+ else if (entityB) {
4314
+ entityB.scene.scene.viewer.cameraFlight.flyTo(entityB);
4315
+ }
4316
+ else if (objId || objIdB) {
4317
+ var id = objId ? objId : objIdB;
4318
+
4319
+ goToObjectByAABB(id, window.model.ModelList.concat(window.model2.ModelList));
4320
+ }
3598
4321
  }
3599
4322
 
3600
- function doCompareModels(isSideBySide) {
4323
+ function selectObject(objId, objIdB) {
4324
+ const onModelASelected = 'onModelASelected';
4325
+ const onModelBSelected = 'onModelBSelected';
3601
4326
 
3602
- BIMModel.Compare(function (objResult) {
4327
+ var entity = window.model.objects[objId];
4328
+ var entityB = window.model2.objects[objIdB];
3603
4329
 
3604
- compareModelsResult = objResult;
3605
- viewerSceneObjectsNewBeforeCompare = {};
4330
+ window.model.scene.fire("vitroClearObjectsRequired", { model: window.model });
4331
+ window.model2.scene.fire("vitroClearObjectsRequired", { model: window.model2 });
3606
4332
 
3607
- if (compareModelsResult['new'] && compareModelsResult['new'].length) {
3608
- for (let i = 0; i < compareModelsResult['new'].length; i++) {
3609
- viewerSceneObjectsNewBeforeCompare[compareModelsResult['new'][i]] = Object.assign({}, viewer.scene.objects[compareModelsResult['new'][i]]);
3610
- }
3611
- }
3612
4333
 
3613
- window.objResult = objResult;
4334
+ window.model.selected = false;
4335
+ window.model2.selected = false;
3614
4336
 
3615
- highlightModelsDifference(objResult, isSideBySide);
3616
- createComparisonResultPopup();
3617
- viewer.scene.canvas.spinner.processes--;
3618
- },
3619
- function () {
3620
- viewer.scene.canvas.spinner.processes--;
3621
- });
3622
- }
4337
+ if (window.model && window.model.loadedVitroCompare && window.model.loadedVitroCompare[onModelASelected]) {
4338
+ window.model.scene.off(window.model.loadedVitroCompare.onModelASelected);
4339
+ }
3623
4340
 
3624
- function getComparisonResultAddedItemsListElm(allItemsList) {
3625
- var cssClass = 'item-added';
3626
- return getComparisonResulItemsListElm(window.model2, compareModelsResult['new'], cssClass, allItemsList);
3627
- }
4341
+ if (window.model2 && window.model2.loadedVitroCompare && window.model2.loadedVitroCompare[onModelBSelected]) {
4342
+ window.model2.scene.off(window.model2.loadedVitroCompare.onModelBSelected);
4343
+ }
3628
4344
 
3629
- function getComparisonResultRemovedItemsListElm(allItemsList) {
3630
- var cssClass = 'item-removed';
3631
- return getComparisonResulItemsListElm(window.model, compareModelsResult['old']['unique'], cssClass, allItemsList);
3632
- }
3633
-
3634
- function getComparisonResulItemsListElm(sceneModel, resultData, cssClass, allItemsList) {
3635
- var itemsList = $('<ul class="list-items">');
3636
- for (var i = 0; i < resultData.length; i++) {
3637
- var objId = resultData[i].id;
3638
- var objName = resultData[i].name;
3639
- var objUuid = resultData[i].uuid;
3640
- var item = $('<li class="' + cssClass + '"><span class="name">' + objName + '</span><span class="props">' + ' [ ' + objUuid + ' ]' + '</span></li>');
3641
- item.data('objId', objId);
3642
- item.data('modelId', sceneModel.id);
3643
- item.on('click', function () {
3644
- goToObject($(this).data('modelId'), $(this).data('objId'));
3645
- });
3646
- allItemsList.append(item.clone(true));
3647
- itemsList.append(item);
4345
+ if (entityB) {
4346
+ entityB.selected = true;
3648
4347
  }
4348
+ else if (objIdB) {
4349
+ window.model2.scene.fire("vitroObjectsRequired", { model: window.model2, objectIds: [objIdB] });
3649
4350
 
3650
- return itemsList;
4351
+ withObjectIds(window.model2, [objIdB], entity => { entity.selected = true }, undefined, onModelBSelected);
4352
+ }
4353
+
4354
+ if (entity) {
4355
+ entity.selected = true;
4356
+ }
4357
+ else if (objId) {
4358
+ window.model.scene.fire("vitroObjectsRequired", { model: window.model, objectIds: [objId] });
4359
+
4360
+ withObjectIds(window.model, [objId], entity => { entity.selected = true }, undefined, onModelASelected);
4361
+ }
4362
+ }
4363
+
4364
+
4365
+ function withObjectIdsByModel(sceneModel, dbObjIds, callback) {
4366
+ let changed = false;
4367
+ for (let i = 0, len = dbObjIds.length; i < len; i++) {
4368
+ const id = dbObjIds[i];
4369
+ let entity = sceneModel.objects[id];
4370
+ if (entity) {
4371
+ changed = callback(entity) || changed;
4372
+ }
4373
+ }
4374
+ return changed;
3651
4375
  }
3652
4376
 
3653
- function withObjects(sceneModel, dbObjs, callback) {
4377
+ function withObjectsByModel(sceneModel, dbObjs, callback) {
3654
4378
  let changed = false;
3655
4379
  for (let i = 0, len = dbObjs.length; i < len; i++) {
3656
4380
  const id = dbObjs[i].id;
@@ -3662,77 +4386,86 @@ function withObjects(sceneModel, dbObjs, callback) {
3662
4386
  return changed;
3663
4387
  }
3664
4388
 
3665
- function colorizeArObject(sceneModel, dbObjs, color) {
3666
- withObjects(sceneModel, dbObjs, entity => {
4389
+ /*function colorizeArObject(arObjId, color) {
4390
+ viewer.scene.setObjectsColorized(arObjId, color);
4391
+ }*/
4392
+
4393
+
4394
+ function colorizeArObjectByModel(model, dbObjs, color) {
4395
+ withObjectsByModel(model, dbObjs, entity => {
3667
4396
  entity.colorize = color;
3668
4397
  });
3669
4398
  }
3670
4399
 
4400
+ function withObjectIds(sceneModel, dbObjIds, callback, callbackOther, propertyName) {
4401
+ let changed = false;
4402
+
4403
+ if (callbackOther) {
4404
+ sceneModel._entityList.forEach(entity => {
4405
+ callbackOther(entity);
4406
+ });
4407
+ }
4408
+ if (dbObjIds && dbObjIds.length) {
4409
+ withObjectIdsByModel(sceneModel, dbObjIds, entity => {
4410
+ callback(entity);
4411
+ });
4412
+ }
4413
+
4414
+ if ((!model.largeModel) && ((dbObjIds && dbObjIds.length) || callbackOther)) {
4415
+ if (!sceneModel.loadedVitroCompare) {
4416
+ sceneModel.loadedVitroCompare = {};
4417
+ }
4418
+
4419
+ sceneModel.loadedVitroCompare[propertyName] = sceneModel.scene.on("modelLoaded", (modelId) => {
4420
+ const model = sceneModel.scene.models[modelId];
4421
+ if (model && (model.largeModel == sceneModel || model == sceneModel)) {
4422
+ if (callbackOther) {
4423
+ model._entityList.forEach(entity => {
4424
+ callbackOther(entity);
4425
+ });
4426
+ }
4427
+ if (dbObjIds && dbObjIds.length) {
4428
+ withObjectIdsByModel(model, dbObjIds, entity => {
4429
+ callback(entity);
4430
+ });
4431
+ }
4432
+ }
4433
+ });
4434
+ }
4435
+
4436
+ return changed;
4437
+ }
4438
+
3671
4439
  function highlightArObject(sceneModel, dbObjs, highlighted) {
3672
- withObjects(sceneModel, dbObjs, entity => {
4440
+ withObjectsByModel(sceneModel, dbObjs, entity => {
3673
4441
  entity.highlighted = highlighted;
3674
4442
  });
3675
4443
  }
3676
4444
 
3677
4445
  function setOpacityArObject(sceneModel, dbObjs, opacity) {
3678
- withObjects(sceneModel, dbObjs, entity => {
4446
+ withObjectsByModel(sceneModel, dbObjs, entity => {
3679
4447
  entity.opacity = opacity;
3680
4448
  });
3681
4449
  }
3682
4450
 
3683
4451
  function setVisibilityArObject(sceneModel, dbObjs, visible) {
3684
- withObjects(sceneModel, dbObjs, entity => {
4452
+ withObjectsByModel(sceneModel, dbObjs, entity => {
3685
4453
  entity.visible = visible;
3686
4454
  });
3687
4455
  }
3688
4456
 
3689
- function goToObject(modelId, objId) {
3690
- const scene = viewer.scene;
3691
- const sceneModel = scene.models[modelId];
3692
- var entity = sceneModel.objects[objId];
3693
-
3694
- window.model.selected = false;
3695
- window.model2.selected = false;
3696
-
3697
- if (entity) {
3698
- entity.selected = true;
3699
- viewer.cameraFlight.flyTo(entity);
3700
- }
3701
- }
3702
-
3703
4457
  function doCompare() {
3704
- const versionA = compareObjList.modelAVersion;
3705
4458
  const versionB = compareObjList.modelBVersion;
3706
-
3707
- BIMCommon.GetFileItem(context.file.id, versionB, function (modelId) {
3708
-
3709
- context.getItem(modelId).then(item => {
3710
- var filePath = context.getFilePath(item.id);
3711
- var settings = {
3712
- id: Date.now(),
3713
- src: filePath,
3714
- edges: true,
3715
- performance: true,
3716
- position: [0, 0, 0]
3717
- };
3718
-
3719
- if (isCompareSideBySide) {
3720
- settings.position = [-55, 0, 0];
3721
- }
3722
-
4459
+ const itemId = context.file.id;
4460
+ BIMCommon.GetFileItem(itemId, versionB, function (modelId) {
4461
+ context.getItem(modelId).then(itemAttach => {
3723
4462
  BIMCommon.FileCompareVersion = versionB;
3724
- window.model2 = xktLoader.load(settings);
3725
- window.model2.on('loaded', () => {
3726
- var vitroModelLoader = new VitroXKTLoaderPlugin(viewer);
3727
4463
 
3728
- window.model2.SmallSceneLoader = vitroModelLoader;
3729
- vitroModelLoader.version = BIMCommon.FileCompareVersion;
3730
- vitroModelLoader.startSmallLoad = true;
3731
- vitroModelLoader.position = settings.position;
4464
+ const filePath = context.getFilePath(itemAttach.id);
4465
+ const fileName = context.file.fieldValueMap?.name;
4466
+ const model = new BIMCommon.VitroModel(itemId, versionB, filePath, fileName);
3732
4467
 
3733
- viewer.scene.canvas.spinner.processes++;
3734
- doCompareModels(isCompareSideBySide);
3735
- });
4468
+ loadModel(model);
3736
4469
  })
3737
4470
 
3738
4471
  }, function () {
@@ -3740,464 +4473,703 @@ function doCompare() {
3740
4473
  });
3741
4474
  }
3742
4475
 
3743
-
3744
- function doRemoveComparison() {
3745
- if (model2) {
3746
- model2.destroy();
3747
- window.model2.SmallSceneLoader.startSmallLoad = false;
3748
- window.model2.SmallSceneLoader.deleteModels();
3749
- window.model2.SmallSceneLoader.destroy();
4476
+ function areEqual(arr1, arr2) {
4477
+ if (arr1.length !== arr2.length) return false;
4478
+ for (let i = 0; i < arr1.length; i++) {
4479
+ if (arr1[i] !== arr2[i]) return false;
3750
4480
  }
3751
- $('.comparison-popup-wrap').dialog("destroy");
3752
- restoreObjectColorsAfterCompare();
4481
+ return true;
3753
4482
  }
3754
4483
 
4484
+ function onCameraSync(fromViewer, toViewer) {
4485
+ fromViewer.camera.cameraSync = fromViewer.camera.on("matrix", () => {
4486
+ if (!areEqual(toViewer.camera.eye, fromViewer.camera.eye)) {
4487
+ toViewer.camera.eye = fromViewer.camera.eye.slice();
4488
+ }
4489
+ if (!areEqual(toViewer.camera.look, fromViewer.camera.look)) {
4490
+ toViewer.camera.look = fromViewer.camera.look.slice();
4491
+ }
4492
+ if (!areEqual(toViewer.camera.up, fromViewer.camera.up)) {
4493
+ toViewer.camera.up = fromViewer.camera.up.slice();
4494
+ }
4495
+ });
4496
+ }
3755
4497
 
3756
- function onAnnotationsMarkerClickedHandler(annotation) {
3757
- showNoteDesc(annotation.id);
3758
- if (annotation.getLabelShown()) {
3759
- removeFromNotesDescriptionVisibleList(annotation.id);
3760
- } else {
3761
- addToNotesDescriptionVisibleList(annotation.id);
3762
- }
3763
- annotation.occludable = false;
3764
- annotation.setLabelShown(!annotation.getLabelShown());
3765
- viewer.cameraFlight.flyTo(annotation);
4498
+
4499
+ function offSyncCamera(viewer) {
4500
+ viewer.camera.off(viewer.camera.cameraSync);
3766
4501
  }
3767
4502
 
3768
- function doGetNoteOptions(noteId, creator, pickResult, glyph, title, description, imageSrc, bgColor) {
3769
- var options = {
3770
- id: noteId,
3771
- creator: creator,
3772
- pickResult: pickResult,
3773
- worldPos: pickResult.worldPos,
3774
- eye: viewer.camera.eye, // need for camera fly on sidebar click
3775
- look: viewer.camera.look, // need for camera fly on sidebar click
3776
- up: viewer.camera.up, // need for camera fly on sidebar click
3777
- occludable: false,
3778
- markerShown: true,
3779
- labelShown: false,
3780
- version: fileVersion,
3781
- fileVersionPath: fileVersionPath,
3782
- values: {
3783
- glyph: glyph,
3784
- title: title,
3785
- description: description,
3786
- markerBGColor: bgColor,
3787
- imageSrc: imageSrc
3788
- }
3789
- };
4503
+ function loadModel(vitroModel) {
4504
+ let xktCompareLoader;
3790
4505
 
3791
- if (pickResult.entity && pickResult.entity.id) {
3792
- options.entity = pickResult.entity.id;
4506
+ if (isCompareSideBySide) {
4507
+ viewerCompare = new Viewer({
4508
+ canvasId: "xeokitCompareCanvas",
4509
+ transparent: true
4510
+ });
4511
+
4512
+ setViewerSetting(viewerCompare);
4513
+ setCameraSetting(viewerCompare);
4514
+
4515
+ xktCompareLoader = new XKTLoaderPlugin(viewerCompare);
4516
+ initFastNavPlugin(viewerCompare);
4517
+
4518
+ const left = document.getElementById("xeokitCanvas");
4519
+ const right = document.getElementById("xeokitCompareCanvas");
4520
+
4521
+ left.style.width = "50%";
4522
+ right.style.width = "50%";
4523
+ right.style.display = "block";
4524
+
4525
+ onCameraSync(viewer, viewerCompare);
4526
+ onCameraSync(viewerCompare, viewer);
4527
+ }
4528
+ else {
4529
+ viewerCompare = viewer;
4530
+ xktCompareLoader = xktLoader;
3793
4531
  }
3794
4532
 
3795
- return options;
3796
- }
4533
+ window.model2 = doLoadModel(viewerCompare, xktCompareLoader, vitroModel, true);
4534
+ window.model2.ModelList = [];
4535
+ window.model2.ModelList.push(vitroModel);
3797
4536
 
3798
- function bindToggleNotesDescription() {
3799
- $(document).on('click', '#btnToggleNotesDescription', function () {
3800
- $(this).toggleClass('show');
3801
- if ($(this).hasClass('show')) {
3802
- hideNotesDescription();
3803
- } else {
3804
- showNotesDescription();
4537
+ window.model2.on('loaded', () => {
4538
+ if (isCompareSideBySide) {
4539
+ viewer.scene.fire("reloadSmallScenes");
3805
4540
  }
3806
4541
  });
4542
+
4543
+ doCompareModels(isCompareSideBySide);
3807
4544
  }
3808
4545
 
3809
- function hideNotesDescription() {
3810
- if (annotations?.annotations) {
3811
- $.each(annotations.annotations, function () {
3812
- this.setLabelShown(false);
3813
- });
4546
+ //------------------------------------------------------------------------------------------------------------------
4547
+ // compare property and geometry
4548
+ //------------------------------------------------------------------------------------------------------------------
4549
+
4550
+ function comparePropertyAndGeometrySync(uuid, type) {
4551
+ let propertyResult = null;
4552
+ let geometryResult = null;
4553
+
4554
+ viewer.scene.canvas.spinner.processes++;
4555
+
4556
+ if (type.property) {
4557
+ BIMModel.CompareProperty(null, uuid, function (result) {
4558
+ propertyResult = result;
4559
+ }, function () { }, false); // async: false
3814
4560
  }
3815
- clearNotesDesriptionVisibleList();
3816
- }
3817
4561
 
3818
- function addToNotesDescriptionVisibleList(itemKey) {
3819
- if (!notesDescriptionVisibleList.hasOwnProperty(itemKey)) {
3820
- notesDescriptionVisibleList[itemKey] = true;
4562
+ if (type.geometry) {
4563
+ BIMModel.CompareGeometry(null, uuid, function (result) {
4564
+ geometryResult = result;
4565
+ }, function () { }, false); // async: false
3821
4566
  }
3822
- }
3823
4567
 
3824
- function removeFromNotesDescriptionVisibleList(itemKey) {
3825
- if (notesDescriptionVisibleList.hasOwnProperty(itemKey)) {
3826
- delete notesDescriptionVisibleList[itemKey];
4568
+ viewer.scene.canvas.spinner.processes--;
4569
+
4570
+ const popupWrap = createPopupContainer();
4571
+
4572
+ const propertyGroupListWrap = $('<div class="vitro-property-group-list-wrap"/>');
4573
+
4574
+ if (propertyResult) {
4575
+ const groupsContainer = createGroupsContainer(propertyResult);
4576
+ propertyGroupListWrap.append(groupsContainer);
3827
4577
  }
3828
- }
3829
4578
 
3830
- function clearNotesDesriptionVisibleList() {
3831
- notesDescriptionVisibleList = {};
4579
+ if (geometryResult) {
4580
+ const geometryContainer = createGeometryBlock(geometryResult);
4581
+ propertyGroupListWrap.append(geometryContainer);
4582
+ }
4583
+
4584
+ popupWrap.append(propertyGroupListWrap);
4585
+
4586
+ //const propertyComparePopupFooter = createPropertyComparisonPopupFooter();
4587
+
4588
+ //popupWrap.append(propertyComparePopupFooter);
4589
+
4590
+ var compareElementTitle = document.webL10n.get('compare_element_label');
4591
+
4592
+ initPropertyComparisonPopup(popupWrap, compareElementTitle);
3832
4593
  }
3833
4594
 
3834
- function isNoteDescriptionVisible(itemKey) {
3835
- return notesDescriptionVisibleList.hasOwnProperty(itemKey);
4595
+ function createPropertyComparisonPopupFooter() {
4596
+ const propertyComparePopupFooter = $('<div class="vitro-property-compare-popup-footer"/>');
4597
+ const modelAName = $('<div class="vitro-model-a-name"/>');
4598
+ const modelBName = $('<div class="vitro-model-b-name"/>');
4599
+
4600
+ const modelAInfo = getModelInfo(window.model);
4601
+ const modelBInfo = getModelInfo(window.model2);
4602
+
4603
+ modelAName.append(modelAInfo);
4604
+ modelBName.append(modelBInfo);
4605
+ propertyComparePopupFooter.append(modelAName);
4606
+ propertyComparePopupFooter.append(modelBName);
4607
+
4608
+ return propertyComparePopupFooter;
3836
4609
  }
3837
4610
 
3838
- function showNotesDescription() {
3839
- if (annotations?.annotations) {
3840
- $.each(annotations.annotations, function () {
3841
- addToNotesDescriptionVisibleList(this.id);
3842
- this.occludable = false;
3843
- this.setLabelShown(true);
3844
- });
4611
+ function createGeometryBlock(geometryDiff) {
4612
+ const geometryContainer = $('<div class="property-groups-container property-groups-container-geometry"/>');
4613
+
4614
+ if (geometryDiff) {
4615
+ // --- offset ---
4616
+ const offsetProps = [];
4617
+ if (geometryDiff.offset) {
4618
+ if (geometryDiff.offset.X !== 0) {
4619
+ offsetProps.push({ name: 'X', value: geometryDiff.offset.X.toFixed(6) });
4620
+ }
4621
+ if (geometryDiff.offset.Y !== 0) {
4622
+ offsetProps.push({ name: 'Y', value: geometryDiff.offset.Y.toFixed(6) });
4623
+ }
4624
+ if (geometryDiff.offset.Z !== 0) {
4625
+ offsetProps.push({ name: 'Z', value: geometryDiff.offset.Z.toFixed(6) });
4626
+ }
4627
+ }
4628
+
4629
+ if (offsetProps.length > 0) {
4630
+ const offsetGroupHeaderLabel = document.webL10n.get('offset_element_label');
4631
+ const offsetGroup = getGeometryGroup(offsetGroupHeaderLabel, offsetProps);
4632
+
4633
+ geometryContainer.append(offsetGroup);
4634
+ }
4635
+
4636
+ // --- Size ---
4637
+ const sizeProps = [];
4638
+ if (geometryDiff.size) {
4639
+ if (geometryDiff.size.X !== 0) {
4640
+ sizeProps.push({ name: 'X', value: geometryDiff.size.X.toFixed(6) });
4641
+ }
4642
+ if (geometryDiff.size.Y !== 0) {
4643
+ sizeProps.push({ name: 'Y', value: geometryDiff.size.Y.toFixed(6) });
4644
+ }
4645
+ if (geometryDiff.size.Z !== 0) {
4646
+ sizeProps.push({ name: 'Z', value: geometryDiff.size.Z.toFixed(6) });
4647
+ }
4648
+ }
4649
+
4650
+ if (sizeProps.length > 0) {
4651
+ const sizeGroupHeaderLabel = document.webL10n.get('size_element_label');
4652
+ const sizeGroup = getGeometryGroup(sizeGroupHeaderLabel, sizeProps);
4653
+ geometryContainer.append(sizeGroup);
4654
+ }
3845
4655
  }
4656
+
4657
+ return geometryContainer;
3846
4658
  }
3847
4659
 
3848
- function initIssueDetailResizable() {
3849
- initResizable($('#issueDetail'), 'w', PANE_RIGHT_MIN_WIDTH, onIssueDetailResizeHandler, onIssueDetailResizeEndHandler);
4660
+ function getGeometryGroup(groupHeaderLabel, propList) {
4661
+ const group = $('<div class="property-group"/>');
4662
+ const groupHeader = getGroupTitle(groupHeaderLabel);
4663
+ group.append(groupHeader);
4664
+ const propListWrap = $('<div class="property-list"/>');
4665
+ propList.forEach(prop => {
4666
+ propListWrap.append('<div class="property-item"><span class="property-name">' + prop.name + '</span> <span class="property-value">' + prop.value + '</span></div>');
4667
+ });
4668
+ group.append(propListWrap);
4669
+
4670
+ return group;
3850
4671
  }
3851
4672
 
3852
- function addToTreeView(model, sceneModelId) {
3853
- if (treeView && treeView._rootNodes.length > 0) {
3854
- const callback = (metaObjects, status, jqXHR) => {
3855
- const metaModel = viewer.metaScene.metaModels[sceneModelId];
4673
+ function getGroupTitle(label) {
4674
+ const sizeGroupHeader = $(`<div class="property-group-title">${label}</div>`);
4675
+ sizeGroupHeader.on('click', onClickGroupHeader);
4676
+ return sizeGroupHeader;
4677
+ }
3856
4678
 
3857
- treeView.addObjectsToMetaModel(metaObjects, metaModel);
3858
- treeView.addModel(sceneModelId);
4679
+ function createPropertyComparisonWindow(compareResult) {
4680
+ const popupWrap = createPopupContainer();
4681
+ const groupsContainer = createGroupsContainer(compareResult);
3859
4682
 
3860
- viewer.scene.canvas.spinner.processes--;
3861
- };
4683
+ popupWrap.append(groupsContainer);
4684
+ initPropertyComparisonPopup(popupWrap, 'Сравнение свойств');
4685
+ }
3862
4686
 
3863
- const error = () => {
3864
- viewer.scene.canvas.spinner.processes--;
3865
- };
4687
+ function createPopupContainer() {
4688
+ return $('<div class="property-comparison-popup-wrap"/>');
4689
+ }
3866
4690
 
3867
- BIMModel.GetElementChildList(model.FileItemId, model.FileVersion, "-1", false, null, callback, error);
4691
+ function createGroupsContainer(compareResult) {
4692
+ const groupsContainer = $('<div class="property-groups-container"/>');
4693
+ const groupedProperties = groupAllProperties(compareResult);
4694
+
4695
+ for (const groupName in groupedProperties) {
4696
+ const groupElement = createGroupElement(groupName, groupedProperties[groupName], compareResult);
4697
+ groupsContainer.append(groupElement);
3868
4698
  }
4699
+
4700
+ return groupsContainer;
3869
4701
  }
3870
4702
 
3871
- function bindBtnAddModel() {
3872
- $(document).on('click', '#btnAddModel', function () {
3873
- context.showItemSelectDialog().then(itemIdList => {
3874
- itemIdList.forEach(itemId =>
3875
- {
3876
- BIMCommon.GetFileItem(itemId, undefined, function (modelId) {
3877
- context.getItem(modelId).then(itemAttach => {
4703
+ function groupAllProperties(compareResult) {
4704
+ const allProperties = new Set();
3878
4705
 
3879
- context.getItem(itemId).then(item =>
3880
- {
3881
- context.addItem(item);
3882
- });
4706
+ addPropertiesFromSection(compareResult[del], allProperties);
4707
+ addPropertiesFromSection(compareResult[add], allProperties);
4708
+ addChangedProperties(compareResult[change][property], allProperties);
3883
4709
 
3884
- const filePath = context.getFilePath(itemAttach.id);
3885
- const fileName = context.file.fieldValueMap?.name;
3886
- const model = new BIMCommon.VitroModel(itemId, undefined, filePath, fileName);
4710
+ return groupPropertiesByName(allProperties);
4711
+ }
3887
4712
 
3888
- BIMCommon.ModelList.push(model);
4713
+ function addPropertiesFromSection(properties, allProperties) {
4714
+ if (!properties) return;
3889
4715
 
3890
- const sceneModel = doLoadModel(model, false);
3891
- addToTreeView(model, sceneModel.id);
4716
+ properties.forEach(prop => {
4717
+ allProperties.add(`${prop.groupName}|${prop.name}`);
4718
+ });
4719
+ }
3892
4720
 
3893
- $('#btnToggleCompare').hide();
3894
- })
4721
+ function addChangedProperties(changedProperties, allProperties) {
4722
+ if (!changedProperties) return;
3895
4723
 
3896
- }, function () {
3897
- alert("The file is being processed");
3898
- });
4724
+ changedProperties.forEach(pair => {
4725
+ allProperties.add(`${pair.a.groupName}|${pair.a.name}`);
4726
+ });
4727
+ }
3899
4728
 
3900
- })
4729
+ function groupPropertiesByName(allProperties) {
4730
+ const grouped = {};
4731
+ allProperties.forEach(propKey => {
4732
+ const [groupName, propName] = propKey.split('|');
4733
+ if (!grouped[groupName]) grouped[groupName] = [];
4734
+ if (!grouped[groupName].includes(propName)) {
4735
+ grouped[groupName].push(propName);
4736
+ }
3901
4737
  });
4738
+ return grouped;
4739
+ }
4740
+
4741
+ function createGroupElement(groupName, properties, compareResult) {
4742
+ const groupHeader = createGroupHeader(groupName);
4743
+ const groupElement = $('<div class="property-group"/>').append(groupHeader);
4744
+
4745
+ const propertiesList = $('<div class="properties-list"/>');
4746
+
4747
+ properties.forEach(propName => {
4748
+ propertiesList.append(createPropertyElement(propName, groupName, compareResult));
3902
4749
  });
4750
+
4751
+ return groupElement.append(propertiesList);
3903
4752
  }
3904
4753
 
3905
- function bindUpdateDocumentMarkupList() {
3906
- window.addEventListener(EVENT_SEARCH_ISSUE_LIST, updateDocumentMarkupList);
4754
+ function createGroupHeader(groupName) {
4755
+ const curentGroupName = groupName || document.webL10n.get('ungrouped_label');
4756
+ const groupHeader = $(`<div class="group-header">${curentGroupName}</div>`);
4757
+
4758
+ groupHeader.on('click', onClickGroupHeader);
4759
+ return groupHeader;
3907
4760
  }
3908
4761
 
3909
- function updateDocumentMarkupList(e) {
3910
- annotations.clear();
3911
- if (e.detail.issueList && e.detail.issueList.length) {
3912
- e.detail.issueList.map(issue => {
3913
- let data = getMarkupData(issue.item);
3914
- data.occludable = false;
3915
- annotations.createAnnotation(data);
3916
- });
3917
- }
4762
+ function onClickGroupHeader(e) {
4763
+ $(this).toggleClass('collapsed');
3918
4764
  }
3919
4765
 
3920
- bindUpdateDocumentMarkupList();
4766
+ function createPropertyElement(propName, groupName, compareResult) {
4767
+ const propElement = $('<div class="property-item"/>')
4768
+ .append(`<div class="property-name">${propName}</div>`);
3921
4769
 
3922
- function highlightSidebarNote(noteId) {
3923
- var noteWrap = $('#vitro-issue-tile-' + noteId);
4770
+ const modelAInfo = getModelInfo(window.model);
4771
+ const modelBInfo = getModelInfo(window.model2);
3924
4772
 
3925
- if (!noteWrap.position()) {
3926
- setTimeout(() => {
3927
- highlightSidebarNote(noteId);
3928
- }, 500);
4773
+ const valueA = findProperty(compareResult, propName, groupName, 'a');
4774
+ const valueB = findProperty(compareResult, propName, groupName, 'b');
3929
4775
 
3930
- return;
3931
- }
4776
+ propElement.append(
4777
+ createValueElement(modelAInfo, valueA, 'model-a'),
4778
+ createValueElement(modelBInfo, valueB, 'model-b')
4779
+ );
3932
4780
 
3933
- selectIssueListItem(noteId);
4781
+ return propElement;
3934
4782
  }
3935
4783
 
3936
- function selectIssueListItem(itemId) {
3937
- const event = new CustomEvent(EVENT_ISSUE_LIST_SELECT_ITEM, { detail: { itemId: itemId } });
3938
- window.dispatchEvent(event);
4784
+ function getModelInfo(model) {
4785
+ return `<span>${model.ModelList[0].FileName}</span><span>[v${model.ModelList[0].FileVersion}]</span>`;
3939
4786
  }
3940
4787
 
3941
- function setSettings(settings) {
3942
- const settingsString = settings ? JSON.stringify(settings) : '';
3943
- context.setSettingsToLocalStorage(settingsString);
4788
+ function findProperty(compareResult, propName, groupName, modelType) {
4789
+ if (modelType === 'a') {
4790
+ return findInDeleteOrChange(compareResult, propName, groupName, 'a');
4791
+ } else {
4792
+ return findInAddOrChange(compareResult, propName, groupName, 'b');
4793
+ }
3944
4794
  }
3945
4795
 
3946
- function getSettings() {
3947
- const settings = context.getSettingsFromLocalStorage();
3948
- return settings ? JSON.parse(settings) : {};
4796
+ function findInDeleteOrChange(compareResult, propName, groupName, modelType) {
4797
+ const inDelete = compareResult[del]?.find(
4798
+ p => p.name === propName && p.groupName === groupName
4799
+ );
4800
+ if (inDelete) return inDelete;
4801
+
4802
+ const inChange = compareResult[change]?.[property]?.find(
4803
+ pair => pair[modelType].name === propName && pair[modelType].groupName === groupName
4804
+ );
4805
+ return inChange ? inChange[modelType] : null;
3949
4806
  }
3950
4807
 
3951
- function setPaneRightSettings(width) {
3952
- const settings = getSettings();
3953
- settings.rightPaneWidth = width;
3954
- setSettings(settings);
4808
+ function findInAddOrChange(compareResult, propName, groupName, modelType) {
4809
+ const inAdd = compareResult[add]?.find(
4810
+ p => p.name === propName && p.groupName === groupName
4811
+ );
4812
+ if (inAdd) return inAdd;
4813
+ const inChange = compareResult[change]?.[property]?.find(
4814
+ pair => pair[modelType].name === propName && pair[modelType].groupName === groupName
4815
+ );
4816
+ return inChange ? inChange[modelType] : null;
3955
4817
  }
3956
4818
 
3957
- function setPaneLeftSettings(width) {
3958
- const settings = getSettings();
3959
- settings.leftPaneWidth = width;
3960
- setSettings(settings);
4819
+ function createValueElement(modelInfo, property, cssClass) {
4820
+ const value = property ? getPropertyValue(property) : '-';
4821
+ return $(`
4822
+ <div class="property-value ${cssClass}">
4823
+ <span class="model-name">${modelInfo}</span>
4824
+ <span class="value">${value}</span>
4825
+ </div>
4826
+ `);
3961
4827
  }
3962
4828
 
3963
- function initPaneWidth() {
3964
- const settings = getSettings();
3965
- setWidthPaneRight(settings.rightPaneWidth);
3966
- setWidthPaneLeft(settings.leftPaneWidth);
4829
+ function initPropertyComparisonPopup(popupWrap, title) {
4830
+ const toolbarHeight = $('.toolbar').height();
4831
+ const offsetLeft = 16 + 'px';
4832
+ const offsetTop = 118 + 'px';
4833
+
4834
+ popupWrap.dialog({
4835
+ title: title,
4836
+ classes: { "ui-dialog": "ui-dialog-comparison-left" },
4837
+ width: 506,
4838
+ maxHeight: ($(window).height() - toolbarHeight),
4839
+ height: 458,
4840
+ position: { my: 'left top', at: 'left top', of: $('.canvas-wrap') },
4841
+ open: function (event, ui) {
4842
+ $('.ui-dialog-comparison-left').css('left', offsetLeft).css('top', offsetTop);
4843
+ }
4844
+ }).dialogExtend({
4845
+ closable: true
4846
+ });
3967
4847
  }
3968
4848
 
3969
- function setWidthPaneRight(width) {
3970
- if (width) {
3971
- $('#sidebarWrap').width(width);
3972
- $('#issueDetail').width(width);
3973
- $('#propInspector').width(width);
4849
+ function createCompareModelLabel() {
4850
+ if (isCompareModeSideBySide()) {
4851
+ removeCompareLabelModeOneOverOne();
4852
+ createCompareModelLabelSideBySide();
4853
+ } else {
4854
+ removeCompareLabelModeSideBySide();
4855
+ createCompareModelLabelOneOverOne();
3974
4856
  }
3975
4857
  }
3976
4858
 
3977
- function setWidthPaneLeft(width) {
3978
- if (width) {
3979
- $('#treeViewContainerWrap').width(width);
3980
- $('#storeyViewsSidebar').width(width);
3981
- }
4859
+ function isCompareModeSideBySide() {
4860
+ return $('#btnCompareSideBySide').hasClass('toggled');
3982
4861
  }
3983
4862
 
3984
- function setPositionSectionPlanesOverviewCanvas(width) {
3985
- $('#sectionPlanesOverviewCanvas').css('right', width + 10);
4863
+ function createCompareModelLabelSideBySide() {
4864
+ const compareLabelModelA = $('<div class="vitro-compare-label-model-a">');
4865
+ const compareLabelModelB = $('<div class="vitro-compare-label-model-b">');
4866
+ const modelAInfo = getModelInfo(window.model);
4867
+ const modelBInfo = getModelInfo(window.model2);
4868
+ compareLabelModelA.append(modelAInfo);
4869
+ compareLabelModelB.append(modelBInfo);
4870
+ $('.canvas-wrap').append(compareLabelModelA).append(compareLabelModelB);
3986
4871
  }
3987
4872
 
3988
- function setPositionNavCubeCanvas(width) {
3989
- $('#navCubeCanvas').css('right', width + 10);
4873
+ function createCompareModelLabelOneOverOne() {
4874
+ const compareLabel = $('<div class="vitro-compare-label-one-over-one">');
4875
+ const modelAInfo = $('<span/>').append(getModelInfo(window.model));
4876
+ const modelBInfo = $('<span/>').append(getModelInfo(window.model2));
4877
+ const sep = $('<span class="vitro-separator">/')
4878
+ compareLabel.append(modelAInfo).append(sep).append(modelBInfo);
4879
+ $('.canvas-wrap').append(compareLabel);
3990
4880
  }
3991
4881
 
3992
- function initResizable(element, handles, minWidth, resizeHadler, onResizeEndHadler) {
3993
- element.resizable({
3994
- handles: handles,
3995
- minWidth: minWidth,
3996
- resize: function (event, ui) {
3997
- if (typeof resizeHadler === 'function') {
3998
- resizeHadler(element.width());
3999
- }
4000
- },
4001
- stop: function (event, ui) {
4002
- if (typeof onResizeEndHadler === 'function') {
4003
- onResizeEndHadler(event, ui);
4004
- }
4005
- }
4882
+ function createSearch() {
4883
+ const searchWrap = $('<div class="vitro-search-wrap"/>');
4884
+ const label = "Поиск";
4885
+ const searchInput = $('<input id="compareSearch" class="vitro-search-input" placeholder="' + label +'"/>');
4886
+ searchWrap.append(searchInput);
4887
+
4888
+ let searchTimer = null;
4889
+ searchInput.on('input', function () {
4890
+ clearTimeout(searchTimer);
4891
+ searchTimer = setTimeout(() => {
4892
+ reloadCompareWithFilters(true);
4893
+ }, 300);
4006
4894
  });
4895
+
4896
+ return searchWrap;
4007
4897
  }
4008
4898
 
4009
- function onIssueDetailResizeHandler(width) {
4010
- onPaneRightResizeHandler(width);
4011
- };
4899
+ function createComparisonResultPopupTitle(popupTitle) {
4900
+ const title = $('<div class="vitro-compare-popup-title"/>');
4901
+ const label = $('<span class="vitro-title"/>').text(popupTitle);
4902
+ //const btn = $('<a id="btnDownloadCompareResult" class="vitro-button"/>');// TODO ADD
4903
+ //btn.on('click', onDownloadCompareResult);
4904
+ title.append(label);
4905
+ //title.append(btn);
4012
4906
 
4013
- function onPaneRightResizeHandler(width) {
4014
- setPositionNavCubeCanvas(width);
4015
- setPositionSectionPlanesOverviewCanvas(width);
4907
+ return title;
4016
4908
  }
4017
4909
 
4018
- function onIssueDetailResizeEndHandler(event, ui) {
4019
- $('#propInspector').width(ui.size.width);
4020
- $('#sidebarWrap').width(ui.size.width);
4021
- setPaneRightSettings(ui.size.width);
4910
+ function onDownloadCompareResult() {
4911
+ // TODO
4912
+ alert('Download compare result'); // TODO - remove
4022
4913
  }
4023
4914
 
4024
- function initTreeViewPanelResizable() {
4025
- initResizable($('#treeViewContainerWrap'), 'e', PANE_LEFT_MIN_WIDTH, false, onTreeViewResizeEndHandler);
4915
+ function removeCompareLabel() {
4916
+ removeCompareLabelModeSideBySide();
4917
+ removeCompareLabelModeOneOverOne();
4026
4918
  }
4027
4919
 
4028
- function onTreeViewResizeEndHandler(event, ui) {
4029
- const width = ui.size.width - $('#treeViewContainerWrap > .ui-resizable-handle').width();
4030
- $('#storeyViewsSidebar').width(width);
4031
- setPaneLeftSettings(width);
4920
+ function removeCompareLabelModeSideBySide() {
4921
+ $('.vitro-compare-label-model-a').remove();
4922
+ $('.vitro-compare-label-model-b').remove();
4032
4923
  }
4033
4924
 
4034
- function initStoreyViewResizable() {
4035
- initResizable($('#storeyViewsSidebar'), 'e', PANE_LEFT_MIN_WIDTH, false, onStoreyViewResizeEndHandler);
4925
+ function removeCompareLabelModeOneOverOne() {
4926
+ $('.vitro-compare-label-one-over-one').remove();
4036
4927
  }
4037
4928
 
4038
- function onStoreyViewResizeEndHandler(event, ui) {
4039
- $('#treeViewContainerWrap').width(ui.size.width);
4040
- setPaneLeftSettings(ui.size.width);
4929
+ function onResizeCompareDialog() {
4930
+ $('.canvas-wrap').width($(window).width()-$('.ui-dialog-comparison').outerWidth());
4041
4931
  }
4042
4932
 
4043
- function initPropertySetsResizable() {
4044
- initResizable($('#propInspector'), 'w', PANE_RIGHT_MIN_WIDTH, onPropsInspectorResizeHandler, onPropsInspectorResizeEndHandler);
4933
+ function resetCanvasWrapWidth() {
4934
+ $('.canvas-wrap').css("width", "100%");
4045
4935
  }
4046
4936
 
4047
- function onPropsInspectorResizeHandler(width) {
4048
- onPaneRightResizeHandler(width);
4049
- };
4937
+ function onWindowResizeCompareDialog() {
4938
+ const dialog = $('.ui-dialog-comparison');
4939
+ const canvasNewWidth = $(window).width() - dialog.outerWidth();
4940
+ dialog.css('left', canvasNewWidth);
4941
+ $('.canvas-wrap').width(canvasNewWidth);
4942
+ }
4050
4943
 
4051
- function onPropsInspectorResizeEndHandler(event, ui) {
4052
- $('#issueDetail').width(ui.size.width);
4053
- $('#sidebarWrap').width(ui.size.width);
4054
- setPaneRightSettings(ui.size.width);
4944
+ function selectListItem(itemElm) {
4945
+ itemElm.parent().find('.' + CSS_CLASS_SELECTED).removeClass(CSS_CLASS_SELECTED);
4946
+ itemElm.addClass(CSS_CLASS_SELECTED);
4055
4947
  }
4056
4948
 
4057
- function initSidebarResizable() {
4058
- initResizable($('#sidebarWrap'), 'w', PANE_RIGHT_MIN_WIDTH, onIssueListResizeHandler, onIssueListResizeEndHandler);
4949
+ function bindOnClickBtnCompareFilterHandler($btn) {
4950
+ $btn.on('click', function () {
4951
+ $(this).toggleClass(CSS_CLASS_SELECTED);
4952
+ reloadCompareWithFilters(true);
4953
+ });
4059
4954
  }
4060
4955
 
4061
- function onIssueListResizeHandler(width) {
4062
- onPaneRightResizeHandler(width);
4956
+ function onClickBtnCompareFilterHandler(itemElm) {
4957
+ itemElm.toggleClass(CSS_CLASS_SELECTED);
4958
+ const changeTypeList = getChangeTypeList();
4959
+ //if ($('#compareList').hasClass(CSS_CLASS_ACTIVE)) {
4960
+ const compareListContent = getCompareListContent(compareModelsResult, changeTypeList);
4961
+ $('#compareListContent').empty().append(compareListContent);
4962
+ //} else {
4963
+ // TODO - Tree
4964
+ const event = new CustomEvent(EVENT_FILTER_CHANGE_TYPE, { detail: { changeTypeList: changeTypeList } });
4965
+ window.dispatchEvent(event);
4966
+ //}
4063
4967
  }
4064
4968
 
4065
- function onIssueListResizeEndHandler(event, ui) {
4066
- $('#issueDetail').width(ui.size.width);
4067
- $('#propInspector').width(ui.size.width);
4068
- setPaneRightSettings(ui.size.width);
4969
+ function getChangeTypeList() {
4970
+ const changeListType = [];
4971
+ if ($('#btnCompareFilterAdd').hasClass(CSS_CLASS_SELECTED)) {
4972
+ changeListType.push(add);
4973
+ }
4974
+ if ($('#btnCompareFilterDel').hasClass(CSS_CLASS_SELECTED)) {
4975
+ changeListType.push(del);
4976
+ }
4977
+ if ($('#btnCompareFilterChange').hasClass(CSS_CLASS_SELECTED)) {
4978
+ changeListType.push(change);
4979
+ }
4980
+
4981
+ return changeListType;
4069
4982
  }
4070
4983
 
4071
- function getPaneRightPosition(width) {
4072
- return ($('body').width() - width);
4984
+ function getCompareListContent(compareModelsResult, changeTypeList) {
4985
+ let compareList = [];
4986
+ if (isChangeContentTypeAll(changeTypeList) || changeTypeList?.includes(add)) {
4987
+ const addedItemsList = getComparisonResultAddedItemsListElm(compareModelsResult);
4988
+ compareList = [...addedItemsList];
4989
+ }
4990
+
4991
+ if (isChangeContentTypeAll(changeTypeList) || changeTypeList?.includes(del)) {
4992
+ const removedItemsList = getComparisonResultRemovedItemsListElm(compareModelsResult);
4993
+ compareList = [...compareList, ...removedItemsList];
4994
+ }
4995
+
4996
+ if (isChangeContentTypeAll(changeTypeList) || changeTypeList?.includes(change)) {
4997
+ const changedItemsList = getComparisonResultChangedItemsListElm(compareModelsResult);
4998
+ compareList = [...compareList, ...changedItemsList];
4999
+ }
5000
+
5001
+ return compareList;
4073
5002
  }
4074
5003
 
4075
- function showPropInspector() {
4076
- $('#propInspector').show();
4077
- const width = $('#propInspector').width();
4078
- setPositionNavCubeCanvas(width);
4079
- setPositionSectionPlanesOverviewCanvas(width);
4080
- }
4081
- //------------------------------------------------------------------------------------------------------------------
4082
- // Do action wherever we click on an object
4083
- //------------------------------------------------------------------------------------------------------------------
5004
+ function isChangeContentTypeAll(changeTypeList) {
5005
+ return !changeTypeList?.length || (changeTypeList.includes(add) && changeTypeList.includes(del) && changeTypeList.includes(change));
5006
+ }
4084
5007
 
4085
- viewer.scene.input.on("mouseclicked", (coords) => {
4086
5008
 
4087
- const pickResult = viewer.scene.pick({
4088
- canvasPos: coords,
4089
- pickSurface: true, // <<------ This causes picking to find the intersection point on the entity
4090
- //includeEntities: true,
4091
- });
4092
5009
 
4093
- if (pickResult) {
4094
- if ($('#btnCreateNotes').hasClass('toggled')) {
4095
- createAnnotationByClick(pickResult);
4096
- }
4097
- createSectionPlaneByClick(pickResult);
4098
- }
4099
- });
5010
+ function onComparisonResulItemClick(data) {
5011
+ selectObject(data.idA, data.idB);
5012
+ goToObject(data.idA, data.idB);
5013
+ $('.property-comparison-popup-wrap').dialog("destroy");
4100
5014
 
4101
- //------------------------------------------------------------------------------------------------------------------
4102
- // Show Object Properties on Click
4103
- //------------------------------------------------------------------------------------------------------------------
4104
- viewer.cameraControl.on("picked", (pickResult) => {
4105
- if (!pickResult.entity) {
4106
- return;
5015
+ if (data.changeType === 'change') {
5016
+ comparePropertyAndGeometrySync(data.uuid, {
5017
+ property: data.isPropertyChanged,
5018
+ geometry: data.isGeometryChanged
5019
+ });
4107
5020
  }
5021
+ }
4108
5022
 
4109
- if (pickResult.entity.id && !$('#btnCreateNotes').hasClass('toggled')) {
4110
- showPropertyInspector(pickResult);
5023
+ function onTreeItemSelect(e) {
5024
+ const data = compareModelsResult?.find(item => item.uuid === e.detail.itemId);
5025
+ if (data) {
5026
+ onComparisonResulItemClick(data);
4111
5027
  }
4112
- });
5028
+ }
4113
5029
 
4114
- /*viewer.cameraControl.on("pickedNothing", () => {
4115
- return false;
4116
- });*/
5030
+ function bindOnTreeItemSelect() {
5031
+ window.addEventListener(EVENT_COMPARE_TREE_ITEM_SLECT, onTreeItemSelect);
5032
+ }
4117
5033
 
5034
+ //------------------------------------------------------------------------------------------------------------------
5035
+ // init
4118
5036
  //------------------------------------------------------------------------------------------------------------------
4119
5037
 
4120
- window.viewer = viewer;
4121
-
4122
- let version = context.fileVersionList.find(x => x.id === context.versionId);
4123
- let versionStr = version ? version.name : null;
5038
+ bindBtnCompareOneOverOne();
5039
+ bindBtnCompareSideBySide();
5040
+ bindBtnClearComparison();
4124
5041
 
4125
- BIMCommon.GetFileItem(context.file.id, versionStr, function (modelId) {
5042
+ initCompare();
5043
+ bindSelectList();
5044
+ bindOnTreeItemSelect();
4126
5045
 
4127
- context.getItem(modelId).then(item => {
4128
- var filePath = context.getFilePath(item.id);
4129
- var fileName = context.file.fieldValueMap?.name;
5046
+ let compareFilters = {
5047
+ IsGeometry: null,
5048
+ SearchTerm: "",
5049
+ ChangeTypeList: [],
5050
+ Skip: 0,
5051
+ Take: 500
5052
+ };
4130
5053
 
4131
- document.title += " - " + fileName;
4132
- fileVersion = '';
4133
- fileVersionPath = filePath;
4134
- hideXeokitSpinner();
5054
+ function getServerFiltersFromUI() {
5055
+ const changeTypes = [];
4135
5056
 
4136
- const model = new BIMCommon.VitroModel(context.file.id, versionStr, filePath, fileName);
5057
+ if ($('#btnCompareFilterAdd').hasClass(CSS_CLASS_SELECTED)) changeTypes.push(add);
5058
+ if ($('#btnCompareFilterDel').hasClass(CSS_CLASS_SELECTED)) changeTypes.push(del);
5059
+ if ($('#btnCompareFilterChange').hasClass(CSS_CLASS_SELECTED)) changeTypes.push(change);
4137
5060
 
4138
- BIMCommon.ModelList.push(model);
5061
+ if (changeTypes.length == 0) {
5062
+ $('#btnCompareFilterAdd').addClass(CSS_CLASS_SELECTED);
5063
+ $('#btnCompareFilterDel').addClass(CSS_CLASS_SELECTED);
5064
+ $('#btnCompareFilterChange').addClass(CSS_CLASS_SELECTED);
4139
5065
 
4140
- doLoadModel(model, true);
4141
- })
4142
-
4143
- }, function () {
4144
- alert("The file is being processed");
4145
- });
5066
+ changeTypes.push(add)
5067
+ changeTypes.push(del)
5068
+ changeTypes.push(change)
5069
+ }
4146
5070
 
4147
- function init() {
4148
- bindBtnToggleSidebarNotes();
4149
- bindSidebarNotesClose();
4150
- bindDeleteNoteEventHandler();
5071
+ const searchTerm = ($('#compareSearch').val() || '').trim();
4151
5072
 
4152
- bindBtnToggleSidebarTreeView();
5073
+ compareFilters.ChangeTypeList = changeTypes;
5074
+ compareFilters.SearchTerm = searchTerm || "";
4153
5075
 
4154
- fixNotesTextareaBlur();
5076
+ return compareFilters;
5077
+ }
4155
5078
 
4156
- bindBtnToggleCreateNotes();
4157
- bindBtnCreateSectionPlan();
4158
- bindBtnClearSectionPlan();
4159
- bindBtnToggleSectionPlan();
4160
- bindToggleNotes();
4161
- bindToggleNotesDescription();
5079
+ function runCompare(opts) {
5080
+ var filters = opts.filters || getServerFiltersFromUI();
5081
+ var sideBySide = !!opts.sideBySide;
5082
+ var createWindow = !!opts.createWindow;
5083
+ var resetSkip = (typeof opts.resetSkip === 'undefined') ? true : !!opts.resetSkip;
4162
5084
 
4163
- bindBtnCreateAngleMeasurements();
4164
- bindBtnToggleAngleMeasurements();
5085
+ if (resetSkip) {
5086
+ compareFilters.Skip = 0;
5087
+ }
5088
+ if (createWindow) {
5089
+ createComparisonResultPopupWindow();
5090
+ }
4165
5091
 
4166
- initTreeViewPanelResizable();
4167
- initSidebarResizable();
4168
- initIssueDetailResizable();
4169
- initStoreyViewResizable();
4170
- initPaneWidth();
5092
+ viewer.scene.canvas.spinner.processes++;
4171
5093
 
4172
- bindBtnToggleSidebarStoreyViews();
5094
+ BIMModel.CompareElementId(
5095
+ function (idList) {
5096
+ try {
5097
+ restoreObjectColorsAfterCompare();
5098
+ highlightModelsDifference(idList, sideBySide);
5099
+ } finally {
5100
+ viewer.scene.canvas.spinner.processes--;
5101
+ }
5102
+ },
5103
+ function () {
5104
+ viewer.scene.canvas.spinner.processes--;
5105
+ },
5106
+ filters,
5107
+ true
5108
+ );
4173
5109
 
4174
- bindBtnSaveBCFViewpointJSON();
4175
- bindBtnLoadBCFViewpointJSON();
5110
+ viewer.scene.canvas.spinner.processes++;
4176
5111
 
4177
- bindBtnCreateDistanceMeasurements();
4178
- bindBtnToggleDistanceMeasurements();
5112
+ BIMModel.Compare(
5113
+ function (data) {
5114
+ try {
5115
+ var incoming = Array.isArray(data) ? data : [];
5116
+ if (compareFilters.Skip > 0 && Array.isArray(compareModelsResult)) {
5117
+ compareModelsResult = (compareModelsResult || []).concat(incoming);
5118
+ } else {
5119
+ compareModelsResult = incoming;
5120
+ }
4179
5121
 
4180
- bindPropInspectorClose();
4181
- initPropertySetsResizable();
5122
+ fillComparisonResultList(compareModelsResult);
5123
+ updateComparisonListAndTree(compareModelsResult);
4182
5124
 
4183
- bindBtnCompareOneOverOne();
4184
- bindBtnCompareSideBySide();
4185
- bindBtnClearComparison();
5125
+ if (typeof createCompareModelLabel === 'function') {
5126
+ createCompareModelLabel();
5127
+ }
5128
+ } finally {
5129
+ viewer.scene.canvas.spinner.processes--;
5130
+ }
5131
+ },
5132
+ function () {
5133
+ viewer.scene.canvas.spinner.processes--;
5134
+ },
5135
+ filters,
5136
+ true
5137
+ );
5138
+ }
4186
5139
 
4187
- bindBtnAddModel();
4188
5140
 
4189
- initCompare();
4190
- bindSelectList();
5141
+ function reloadCompareWithFilters(resetSkip) {
5142
+ runCompare({
5143
+ filters: getServerFiltersFromUI(),
5144
+ sideBySide: !!isCompareSideBySide,
5145
+ createWindow: false,
5146
+ resetSkip: (typeof resetSkip === 'undefined') ? true : !!resetSkip
5147
+ });
4191
5148
  }
4192
5149
 
4193
- init();
5150
+ function attachCompareInfiniteScroll() {
5151
+ const $list = $('#compareListContent');
5152
+ if (!$list.length) return;
4194
5153
 
4195
- var userLocale =
4196
- navigator.languages && navigator.languages.length
4197
- ? navigator.languages[0]
4198
- : navigator.language;
5154
+ $list.off('scroll.vitroCompare').on('scroll.vitroCompare', function () {
5155
+ const el = this;
5156
+ const nearBottom = (el.scrollTop + el.clientHeight) >= (el.scrollHeight - 50);
5157
+ if (nearBottom) {
5158
+ // увеличиваем Skip и догружаем
5159
+ compareFilters.Skip += compareFilters.Take;
5160
+ reloadCompareWithFilters(false);
5161
+ }
5162
+ });
5163
+ }
4199
5164
 
4200
- document.webL10n.setLanguage(userLocale, function () {
4201
- document.webL10n.translate();
4202
- });
4203
- }
5165
+ function updateComparisonListAndTree(data) {
5166
+ // Список
5167
+ const $list = $('#compareListContent');
5168
+ if ($list.length) {
5169
+ $list.empty().append(getCompareListContent(data));
5170
+ }
5171
+ // Дерево — если уже инициализировано
5172
+ if ($('#compareTree').hasClass('uk-active') || $('#compareTreeContent').children().length) {
5173
+ initCompareTreeView(data, getChangeTypeList());
5174
+ }
5175
+ }}