@abi-software/scaffoldvuer 0.1.52-beta.5 → 0.1.53-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/scaffoldvuer",
3
- "version": "0.1.52-beta.5",
3
+ "version": "0.1.53-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,9 +22,9 @@
22
22
  "*.js"
23
23
  ],
24
24
  "dependencies": {
25
- "@abi-software/svg-sprite": "^0.1.14",
25
+ "@abi-software/svg-sprite": "^0.1.15",
26
26
  "axios": "^0.21.2",
27
- "core-js": "^3.3.2",
27
+ "core-js": "^3.22.5",
28
28
  "current-script-polyfill": "^1.0.0",
29
29
  "element-ui": "^2.13.0",
30
30
  "google-spreadsheet": "^3.1.15",
@@ -33,7 +33,7 @@
33
33
  "vue": "^2.6.10",
34
34
  "vue-drag-resize": "^1.3.2",
35
35
  "vue-router": "^3.5.1",
36
- "zincjs": "^1.0.0-alpha-3"
36
+ "zincjs": "^1.0.4"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@vue/cli-plugin-babel": "^4.0.0",
package/src/App.vue CHANGED
@@ -21,6 +21,7 @@
21
21
  :render="render"
22
22
  :region="region"
23
23
  :view-u-r-l="viewURL"
24
+ :format="format"
24
25
  @on-ready="onReady"
25
26
  @scaffold-selected="onSelected"
26
27
  @scaffold-navigated="onNavigated"
@@ -288,6 +289,8 @@ export default {
288
289
  rendererInfo: undefined,
289
290
  zoom: 1,
290
291
  pos: [0, 0],
292
+ format: "metadata",
293
+ sceneSettings: [],
291
294
  };
292
295
  },
293
296
  watch: {
@@ -307,7 +310,6 @@ export default {
307
310
  }
308
311
  },
309
312
  mounted: function() {
310
- this._sceneSettings = [];
311
313
  this.selectedCoordinates = this.$refs.scaffold.getDynamicSelectedCoordinates();
312
314
  this.rendererInfo = this.$refs.scaffold.getRendererInfo();
313
315
  },
@@ -338,11 +340,12 @@ export default {
338
340
  })
339
341
  },
340
342
  saveSettings: function() {
341
- this._sceneSettings.push(this.$refs.scaffold.getState());
343
+ const state = this.$refs.scaffold.getState();
344
+ this.sceneSettings.push(this.$refs.scaffold.getState());
342
345
  },
343
346
  restoreSettings: function() {
344
- if (this._sceneSettings.length > 0)
345
- this.$refs.scaffold.setState(this._sceneSettings.pop());
347
+ if (this.sceneSettings.length > 0)
348
+ this.$refs.scaffold.setState(this.sceneSettings.pop());
346
349
  },
347
350
  viewModelClicked: function(location) {
348
351
  this.input = location;
@@ -362,10 +365,13 @@ export default {
362
365
  }
363
366
  },
364
367
  onReady: function() {
368
+ console.log("ready")
365
369
  this.$refs.dropzone.revokeURLs();
370
+ const names = ["left ventricle.mesh2d", "right ventricle.mesh2d"];
371
+ this.$refs.scaffold.changeActiveByName(names, "", false);
366
372
  },
367
373
  onSelected: function(data) {
368
- if (data && data[0].data.group) {
374
+ if (data && (data.length > 0) && data[0].data.group) {
369
375
  delete this.$route.query["viewURL"];
370
376
  this.$router.replace({
371
377
  query: { ...this.$route.query, region: data[0].data.group }
@@ -377,8 +383,10 @@ export default {
377
383
  this.pos[0] = data.target[0];
378
384
  this.pos[1] = data.target[1];
379
385
  },
380
- onFilesDrop: function(metaURL) {
381
- this.input = metaURL;
386
+ onFilesDrop: function(payload) {
387
+ if (payload.format == "gltf") this.format = "gltf";
388
+ else this.format = "metadata";
389
+ this.input = payload.url;
382
390
  },
383
391
  parseInput: function() {
384
392
  if (this.$route.query.url !== this.input) {
@@ -400,6 +408,11 @@ export default {
400
408
  this.url =
401
409
  "https://mapcore-bucket1.s3-us-west-2.amazonaws.com/others/29_Jan_2020/heartICN_metadata.json";
402
410
  }
411
+ if (this.url.includes(".gltf") || this.url.includes(".glb")) {
412
+ this.format = "gltf";
413
+ } else if (this.url.includes(".json")) {
414
+ this.format = "metadata";
415
+ }
403
416
  this.input = this.url;
404
417
  if (query.region) {
405
418
  this.region = query.region;
@@ -33,7 +33,7 @@ export default {
33
33
  });
34
34
  },
35
35
  methods: {
36
- createObjectURLs: function (text, list) {
36
+ createMetadataObjectURLs: function (text, list) {
37
37
  let content = text;
38
38
  for (const [key, file] of Object.entries(list)) {
39
39
  if (content.includes(key)) {
@@ -45,7 +45,14 @@ export default {
45
45
  let blob = new Blob([content], { type: "application/json" });
46
46
  const metaURL = URL.createObjectURL(blob);
47
47
  this.objectURLs.push(metaURL);
48
- this.$emit("files-drop", metaURL);
48
+ this.$emit("files-drop", { url: metaURL, format : "metadata" } );
49
+ },
50
+ createGLTFURL: function (content, binary) {
51
+ let type = binary ? 'model/gltf+binary' : 'model/gltf+json';
52
+ let blob = new Blob([content], { type });
53
+ const gltfURL = URL.createObjectURL(blob);
54
+ this.objectURLs.push(gltfURL);
55
+ this.$emit("files-drop", { url: gltfURL, format : "gltf" });
49
56
  },
50
57
  revokeURLs: function () {
51
58
  this.objectURLs.forEach(objectURL => URL.revokeObjectURL(objectURL));
@@ -55,6 +62,8 @@ export default {
55
62
  const dataMaps = {};
56
63
  let list = {};
57
64
  let metadata = undefined;
65
+ let gltf = undefined;
66
+ let binary = false;
58
67
  const flatarray = Array.from(fileMap);
59
68
  let rootPath = "";
60
69
  for (let i = 0; i < flatarray.length; i++) {
@@ -63,6 +72,16 @@ export default {
63
72
  metadata = { rootPath, file: flatarray[i][1] };
64
73
  break;
65
74
  }
75
+ if (flatarray[i][1].name.includes(".glb")) {
76
+ gltf = { rootPath, file: flatarray[i][1] };
77
+ binary = true;
78
+ break;
79
+ }
80
+ if (flatarray[i][1].name.includes(".gltf")) {
81
+ gltf = { rootPath, file: flatarray[i][1] };
82
+ binary = false;
83
+ break;
84
+ }
66
85
  }
67
86
  if (metadata) {
68
87
  flatarray.forEach(([filePath, file]) => {
@@ -74,9 +93,12 @@ export default {
74
93
  const metaFileURL = URL.createObjectURL(metadata.file);
75
94
  fetch(metaFileURL)
76
95
  .then((response) => response.text())
77
- .then((text) => this.createObjectURLs(text, list));
96
+ .then((text) => this.createMetadataObjectURLs(text, list));
78
97
  URL.revokeObjectURL(metaFileURL);
79
98
  }
99
+ if (gltf) {
100
+ this.createGLTFURL(gltf.file, binary);
101
+ }
80
102
  },
81
103
  },
82
104
  };
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div :style="position" class="tooltipContainer">
2
+ <div :style="position" class="region-tooltip">
3
3
  <el-popover
4
4
  ref="tooltip"
5
5
  v-model="display"
@@ -82,45 +82,45 @@ export default {
82
82
  <style scoped lang="scss">
83
83
  @import "~element-ui/packages/theme-chalk/src/popover";
84
84
 
85
- ::v-deep .tooltip-popper {
86
- padding: 2px 6px;
87
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
88
- font-size: 16px;
89
- color: $app-primary-color;
90
- background-color: #fff;
91
- border: 1px solid $app-primary-color;
92
- border-radius: 4px;
93
- white-space: nowrap;
94
- min-width: unset;
95
- pointer-events: none;
85
+ .region-tooltip {
86
+ position: absolute;
87
+ height: 50px;
88
+ z-index: 2;
89
+ ::v-deep .tooltip-popper {
90
+ padding: 2px 6px;
91
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
92
+ font-size: 16px;
93
+ color: $app-primary-color;
94
+ background-color: #fff;
95
+ border: 1px solid $app-primary-color;
96
+ border-radius: 4px;
97
+ white-space: nowrap;
98
+ min-width: unset;
99
+ pointer-events: none;
100
+ top: -15px!important;
96
101
 
97
- &.el-popper[x-placement^="top"] {
98
- .popper__arrow {
99
- border-top-color: $app-primary-color !important;
100
- &:after {
101
- border-top-color: #fff !important;
102
+ &.el-popper[x-placement^="top"] {
103
+ .popper__arrow {
104
+ border-top-color: $app-primary-color !important;
105
+ &:after {
106
+ border-top-color: #fff !important;
107
+ }
102
108
  }
103
109
  }
104
- }
105
110
 
106
- &.el-popper[x-placement^="bottom"] {
107
- .popper__arrow {
108
- border-bottom-color: $app-primary-color !important;
109
- &:after {
110
- border-bottom-color: #fff !important;
111
+ &.el-popper[x-placement^="bottom"] {
112
+ .popper__arrow {
113
+ border-bottom-color: $app-primary-color !important;
114
+ &:after {
115
+ border-bottom-color: #fff !important;
116
+ }
111
117
  }
112
118
  }
113
119
  }
114
- }
115
120
 
116
- .tooltipContainer {
117
- position: absolute;
118
- height: 50px;
119
- z-index: 2;
120
- }
121
-
122
- ::v-deep .non-selectable {
123
- user-select: none;
124
- pointer-events: none;
121
+ ::v-deep .non-selectable {
122
+ user-select: none;
123
+ pointer-events: none;
124
+ }
125
125
  }
126
126
  </style>
@@ -249,7 +249,7 @@ import OpacityControls from "./OpacityControls";
249
249
  import ScaffoldTooltip from "./ScaffoldTooltip";
250
250
  import TreeControls from "./TreeControls";
251
251
  import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
252
-
252
+ import { findObjectsWithNames } from "../scripts/utilities.js";
253
253
  import {
254
254
  Col,
255
255
  Loading,
@@ -363,6 +363,13 @@ export default {
363
363
  type: Boolean,
364
364
  default: false
365
365
  },
366
+ /**
367
+ * Format of the input URL
368
+ */
369
+ format: {
370
+ type: String,
371
+ default: "metadata"
372
+ },
366
373
  /**
367
374
  * Settings for minimap position, size and alignment.
368
375
  */
@@ -473,10 +480,17 @@ export default {
473
480
  visible: false,
474
481
  x: 200,
475
482
  y: 200
476
- }
483
+ },
484
+ fileFormat: "metadata",
477
485
  };
478
486
  },
479
487
  watch: {
488
+ format: {
489
+ handler: function(value) {
490
+ this.fileFormat = value;
491
+ },
492
+ immediate: true
493
+ },
480
494
  url: {
481
495
  handler: function(newValue) {
482
496
  if (this.state === undefined || this.state.url === undefined)
@@ -535,8 +549,8 @@ export default {
535
549
  beforeCreate: function() {
536
550
  this.$module = new OrgansViewer();
537
551
  this.isReady = false;
538
- this.selectedObject = undefined;
539
- this.hoveredObject = undefined;
552
+ this.selectedObjects = [];
553
+ this.hoveredObjects = [];
540
554
  this.currentBackground = "white";
541
555
  this._currentURL = undefined;
542
556
  this.availableBackground = ["white", "black", "lightskyblue"];
@@ -682,8 +696,10 @@ export default {
682
696
  /**
683
697
  * Focus on named region
684
698
  */
685
- viewRegion: function(name) {
686
- let objects = this.findObjectsWithGroupName(name);
699
+ viewRegion: function(names) {
700
+ const rootRegion = this.$module.scene.getRootRegion();
701
+ const groups = Array.isArray(names) ? names : [names];
702
+ const objects = findObjectsWithNames(rootRegion, groups, "");
687
703
  let box = this.$module.scene.getBoundingBoxOfZincObjects(objects);
688
704
  if (box) {
689
705
  if (this.$module.isSyncControl()) {
@@ -744,14 +760,22 @@ export default {
744
760
  * It will also update other controls.
745
761
  */
746
762
  eventNotifierCallback: function(event) {
763
+ const names = [];
764
+ const region = undefined;
765
+ if (event.eventType == 1 || event.eventType == 2) {
766
+ event.identifiers.forEach(identifier => {
767
+ if (identifier) {
768
+ let id = identifier.data.id
769
+ ? identifier.data.id
770
+ : identifier.data.group;
771
+ names.push(id);
772
+ }
773
+ });
774
+ }
747
775
  if (event.eventType == 1) {
748
776
  if (this.$refs.treeControl) {
749
- if (event.identifiers[0]) {
750
- let id = event.identifiers[0].data.id
751
- ? event.identifiers[0].data.id
752
- : event.identifiers[0].data.group;
753
- let region = event.identifiers[0].data.region;
754
- this.$refs.treeControl.changeActiveByName(id, region, true);
777
+ if (names.length > 0) {
778
+ this.$refs.treeControl.changeActiveByNames(names, region, false);
755
779
  } else {
756
780
  this.$refs.treeControl.removeActive(true);
757
781
  }
@@ -760,28 +784,29 @@ export default {
760
784
  this.$emit("scaffold-selected", event.identifiers);
761
785
  } else if (event.eventType == 2) {
762
786
  this.tData.visible = false;
763
- const offsets = this.$refs.scaffoldContainer.getBoundingClientRect();
764
- if (event.identifiers[0]) {
787
+ // const offsets = this.$refs.scaffoldContainer.getBoundingClientRect();
788
+ if (this.$refs.treeControl) {
789
+ if (names.length > 0) {
790
+ this.$refs.treeControl.changeHoverByNames(names, region, false);
791
+ } else {
792
+ this.$refs.treeControl.removeHover(true);
793
+ }
794
+ }
795
+ if ((event.identifiers.length > 0) && event.identifiers[0]) {
765
796
  let id = event.identifiers[0].data.id
766
797
  ? event.identifiers[0].data.id
767
798
  : event.identifiers[0].data.group;
768
799
  if (event.identifiers[0].coords) {
769
800
  this.tData.visible = true;
770
801
  this.tData.label = id;
771
- this.tData.x = event.identifiers[0].coords.x - offsets.left;
772
- this.tData.y = event.identifiers[0].coords.y - offsets.top;
773
- }
774
- if (this.$refs.treeControl) {
775
- let region = event.identifiers[0].data.region;
776
- this.$refs.treeControl.changeHoverByName(id, region, true);
777
- } else {
778
- this.$refs.treeControl.removeHover(true);
802
+ this.tData.x = event.identifiers[0].coords.x;
803
+ this.tData.y = event.identifiers[0].coords.y;
779
804
  }
780
805
  }
781
806
  // Triggers when an object has been highlighted
782
807
  this.$emit("scaffold-highlighted", event.identifiers);
783
808
  } else if (event.eventType == 3) { //MOVE
784
- if (event.identifiers[0]) {
809
+ if ((event.identifiers.length > 0) && event.identifiers[0]) {
785
810
  if (event.identifiers[0].coords) {
786
811
  const offsets = this.$refs.scaffoldContainer.getBoundingClientRect();
787
812
  this.tData.x = event.identifiers[0].coords.x - offsets.left;
@@ -796,8 +821,8 @@ export default {
796
821
  * @public
797
822
  */
798
823
  getCoordinatesOfSelected: function() {
799
- if (this.selectedObject) {
800
- return this.$module.scene.getObjectsScreenXY([this.selectedObject]);
824
+ if (this.selectedObjects && this.selectedObjects.length > 0) {
825
+ return this.$module.scene.getObjectsScreenXY([this.selectedObjects]);
801
826
  }
802
827
  return undefined;
803
828
  },
@@ -824,47 +849,54 @@ export default {
824
849
  *
825
850
  * @param {object} object Zinc object
826
851
  */
827
- objectSelected: function(object, propagate) {
828
- if (object !== this.selectedObject) {
829
- this.selectedObject = object;
830
- this.$refs.opacityControl.setObject(this.selectedObject);
831
- if (object) this.$module.setSelectedByZincObject(object, undefined, propagate);
832
- else this.$module.setSelectedByObjects([], undefined, propagate);
833
- }
852
+ objectSelected: function(objects, propagate) {
853
+ this.selectedObjects = objects;
854
+ if (this.selectedObjects)
855
+ this.$refs.opacityControl.setObject(this.selectedObjects[0]);
856
+ if (objects) this.$module.setSelectedByZincObjects(objects, undefined, propagate);
857
+ else this.$module.setSelectedByObjects([], undefined, propagate);
834
858
  },
835
859
  /**
836
860
  * A callback used by children components. Set the highlighted zinc object
837
861
  *
838
862
  * @param {object} object Zinc object
839
863
  */
840
- objectHovered: function(object, propagate) {
841
- if (object !== this.hoveredObject) {
842
- this.hoveredObject = object;
843
- if (object) this.$module.setHighlightedByZincObject(object, undefined, propagate);
844
- else this.$module.setHighlightedByObjects([], undefined, propagate);
845
- }
864
+ objectHovered: function(objects, propagate) {
865
+ this.hoveredObjects = objects;
866
+ if (objects) this.$module.setHighlightedByZincObjects(objects, undefined, propagate);
867
+ else this.$module.setHighlightedByObjects([], undefined, propagate);
846
868
  },
847
869
  /**
848
870
  * Set the selected by name.
849
871
  *
850
- * @param {name} name Name of the group
872
+ * @param {} name Name of the group
851
873
  */
852
- changeActiveByName: function(name, region, propagate) {
853
- if (name === undefined)
874
+ changeActiveByName: function(names, region, propagate) {
875
+ const isArray = Array.isArray(names);
876
+ if (names === undefined || (isArray && names.length === 0)) {
854
877
  this.$refs.treeControl.removeActive(propagate);
855
- else
856
- this.$refs.treeControl.changeActiveByName(name, region, propagate);
878
+ } else {
879
+ let array = names;
880
+ if (!isArray)
881
+ array = [array];
882
+ this.$refs.treeControl.changeActiveByNames(array, region, propagate);
883
+ }
857
884
  },
858
885
  /**
859
886
  * Set the highlighted by name.
860
887
  *
861
888
  * @param {name} name Name of the group
862
889
  */
863
- changeHighlightedByName: function(name, region, propagate) {
864
- if (name === undefined)
890
+ changeHighlightedByName: function(names, region, propagate) {
891
+ const isArray = Array.isArray(names);
892
+ if (names === undefined || (isArray && names.length === 0)) {
865
893
  this.$refs.treeControl.removeHover(propagate);
866
- else
867
- this.$refs.treeControl.changeHoverByName(name, region, propagate);
894
+ } else {
895
+ let array = names;
896
+ if (!isArray)
897
+ array = [array];
898
+ this.$refs.treeControl.changeHoverByNames(array, region, propagate);
899
+ }
868
900
  },
869
901
  /**
870
902
  * Start the animation.
@@ -971,9 +1003,10 @@ export default {
971
1003
  */
972
1004
  getState: function() {
973
1005
  let state = {
1006
+ format: this.fileFormat,
974
1007
  url: this._currentURL,
975
1008
  viewport: undefined,
976
- visibility: undefined
1009
+ visibility: undefined,
977
1010
  };
978
1011
  if (this.$refs.treeControl)
979
1012
  state.visibility = this.$refs.treeControl.getState();
@@ -993,6 +1026,7 @@ export default {
993
1026
  if (state) {
994
1027
  if (state.url && state.url !== this._currentURL) {
995
1028
  this.setURLAndState(state.url, {
1029
+ fileFormat: state.fileFormat,
996
1030
  viewport: state.viewport,
997
1031
  visibility: state.visibility
998
1032
  });
@@ -1029,6 +1063,7 @@ export default {
1029
1063
  */
1030
1064
  setURLAndState: function(newValue, state) {
1031
1065
  if (newValue != this._currentURL) {
1066
+ if (state && state.format) this.fileFormat = state.format;
1032
1067
  let viewport = state && state.viewport ? state.viewport : undefined;
1033
1068
  let visibility =
1034
1069
  state && state.visibility ? state.visibility : undefined;
@@ -1045,13 +1080,18 @@ export default {
1045
1080
  visibility: visibility
1046
1081
  })
1047
1082
  );
1048
- this.$module.loadOrgansFromURL(
1049
- newValue,
1050
- undefined,
1051
- undefined,
1052
- "scene",
1053
- undefined
1054
- );
1083
+ if (this.fileFormat === "gltf") {
1084
+ this.$module.loadGLTFFromURL(newValue, "scene", true);
1085
+ } else {
1086
+ this.$module.loadOrgansFromURL(
1087
+ newValue,
1088
+ undefined,
1089
+ undefined,
1090
+ "scene",
1091
+ undefined,
1092
+ true
1093
+ );
1094
+ }
1055
1095
  this.$module.scene.displayMarkers = this.displayMarkers;
1056
1096
  this.$module.scene.displayMinimap = this.displayMinimap;
1057
1097
  this.updateMinimapScissor();
@@ -1068,9 +1108,8 @@ export default {
1068
1108
  },
1069
1109
  /**
1070
1110
  * Callback when drawer is toggled.
1071
- *
1072
1111
  */
1073
- drawerToggled: function(flag) {
1112
+ drawerToggled: function(flag) {pppp
1074
1113
  this.drawerOpen = flag;
1075
1114
  this.adjustLayout();
1076
1115
  },
@@ -1104,8 +1143,12 @@ export default {
1104
1143
  const payload = this.$module.NDCCameraControl.getPanZoom();
1105
1144
  this.$emit("scaffold-navigated", payload);
1106
1145
  },
1107
- toggleSyncControl: function(flag) {
1108
- this.$module.toggleSyncControl(flag);
1146
+ /**
1147
+ * Rotate mode - "none", "horizontal", "vertical", "free" but
1148
+ * it will be ignored if flag is set to false.
1149
+ */
1150
+ toggleSyncControl: function(flag, rotateMode) {
1151
+ this.$module.toggleSyncControl(flag, rotateMode);
1109
1152
  this.$module.setSyncControlCallback(this.syncControlCallback);
1110
1153
  }
1111
1154
  }