@abi-software/scaffoldvuer 0.1.50-beta-0 → 0.1.51

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.50-beta-0",
3
+ "version": "0.1.51",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,23 +22,22 @@
22
22
  "*.js"
23
23
  ],
24
24
  "dependencies": {
25
- "@abi-software/svg-sprite": "^0.1.13",
26
- "axios": "^0.21.1",
25
+ "@abi-software/svg-sprite": "^0.1.14",
26
+ "axios": "^0.21.2",
27
27
  "core-js": "^3.3.2",
28
28
  "current-script-polyfill": "^1.0.0",
29
29
  "element-ui": "^2.13.0",
30
30
  "google-spreadsheet": "^3.1.15",
31
31
  "lodash": "^4.17.21",
32
- "physiomeportal": "^0.4.27",
33
32
  "query-string": "^6.11.1",
34
33
  "vue": "^2.6.10",
35
34
  "vue-drag-resize": "^1.3.2",
36
35
  "vue-router": "^3.5.1",
37
- "zincjs": "^0.40.0"
36
+ "zincjs": "^0.41.2"
38
37
  },
39
38
  "devDependencies": {
40
39
  "@vue/cli-plugin-babel": "^4.0.0",
41
- "@vue/cli-plugin-eslint": "^4.0.0",
40
+ "@vue/cli-plugin-eslint": "^4.5.15",
42
41
  "@vue/cli-service": "^4.5.13",
43
42
  "babel-eslint": "^10.0.3",
44
43
  "babel-plugin-component": "^1.1.1",
package/src/App.vue CHANGED
@@ -100,16 +100,57 @@
100
100
  >
101
101
  Restore Settings
102
102
  </el-button>
103
+ <el-button
104
+ size="mini"
105
+ @click="exportGLB()"
106
+ >
107
+ Export GLTF
108
+ </el-button>
103
109
  </el-row>
104
- <el-row :gutter="20">
105
- <el-row :gutter="20">
110
+ <el-row :gutter="30">
111
+ <el-col
112
+ :span="7"
113
+ :offset="4"
114
+ >
106
115
  <el-switch
107
116
  v-model="render"
108
117
  active-text="Rendering"
109
118
  active-color="#8300bf"
110
119
  />
111
- </el-row>
120
+ </el-col>
121
+ <el-col
122
+ :span="8"
123
+ :offset="1"
124
+ >
125
+ <el-switch
126
+ v-model="renderInfoOn"
127
+ active-text="Renderer Info"
128
+ active-color="#8300bf"
129
+ />
130
+ </el-col>
112
131
  </el-row>
132
+ <template v-if="renderInfoOn && rendererInfo">
133
+ <el-row>
134
+ <el-col
135
+ v-for="(value, name) in rendererInfo.memory"
136
+ :key="name"
137
+ :offset="4"
138
+ :span="6"
139
+ >
140
+ {{ name }} : {{ value }}
141
+ </el-col>
142
+ </el-row>
143
+ <el-row>
144
+ <el-col
145
+ v-for="(value, name) in rendererInfo.render"
146
+ :key="name"
147
+ :offset="1"
148
+ :span="6"
149
+ >
150
+ {{ name }} : {{ value }}
151
+ </el-col>
152
+ </el-row>
153
+ </template>
113
154
  <el-input
114
155
  v-model="input"
115
156
  type="textarea"
@@ -212,7 +253,9 @@ export default {
212
253
  },
213
254
  render: true,
214
255
  region: "",
215
- viewURL: ""
256
+ viewURL: "",
257
+ renderInfoOn: false,
258
+ rendererInfo: undefined
216
259
  };
217
260
  },
218
261
  watch: {
@@ -232,8 +275,34 @@ export default {
232
275
  mounted: function() {
233
276
  this._sceneSettings = [];
234
277
  this.selectedCoordinates = this.$refs.scaffold.getDynamicSelectedCoordinates();
278
+ this.rendererInfo = this.$refs.scaffold.getRendererInfo();
235
279
  },
236
280
  methods: {
281
+ exportGLTF: function() {
282
+ this.$refs.scaffold.exportGLTF(false)
283
+ .then(data =>{
284
+ let dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
285
+ let hrefElement = document.createElement("a");
286
+ document.body.append(hrefElement);
287
+ hrefElement.download = `export.gltf`;
288
+ hrefElement.href = dataStr;
289
+ hrefElement.click();
290
+ hrefElement.remove();
291
+ })
292
+ },
293
+ exportGLB: function() {
294
+ this.$refs.scaffold.exportGLTF(true)
295
+ .then(data =>{
296
+ let blob = new Blob([data], {type: "octet/stream"});
297
+ let url = window.URL.createObjectURL(blob);
298
+ let hrefElement = document.createElement("a");
299
+ document.body.append(hrefElement);
300
+ hrefElement.download = `export.glb`;
301
+ hrefElement.href = url;
302
+ hrefElement.click();
303
+ hrefElement.remove();
304
+ })
305
+ },
237
306
  saveSettings: function() {
238
307
  this._sceneSettings.push(this.$refs.scaffold.getState());
239
308
  },
@@ -325,6 +394,12 @@ body {
325
394
 
326
395
  .options-container {
327
396
  text-align: center;
397
+ .el-row {
398
+ margin-bottom: 8px;
399
+ &:last-child {
400
+ margin-bottom: 0;
401
+ }
402
+ }
328
403
  }
329
404
 
330
405
  .vuer {
@@ -4,13 +4,6 @@
4
4
  ref="control"
5
5
  class="opacity-control"
6
6
  >
7
- <div
8
- v-if="!drawerOpen"
9
- class="tab-button open"
10
- @click="toggleDrawer"
11
- >
12
- <i class="el-icon-arrow-left" />
13
- </div>
14
7
  <el-drawer
15
8
  custom-class="my-drawer"
16
9
  class="drawer-content"
@@ -52,6 +45,13 @@
52
45
  </el-main>
53
46
  </el-container>
54
47
  </el-drawer>
48
+ <div
49
+ v-if="!drawerOpen"
50
+ class="tab-button open"
51
+ @click="toggleDrawer"
52
+ >
53
+ <i class="el-icon-arrow-left" />
54
+ </div>
55
55
  </div>
56
56
  </template>
57
57
 
@@ -116,9 +116,6 @@ export default {
116
116
  @import "~element-ui/packages/theme-chalk/src/slider";
117
117
 
118
118
  .opacity-control {
119
- position: absolute;
120
- top: 255px;
121
- right: 0px;
122
119
  text-align: left;
123
120
  width:300px;
124
121
  }
@@ -201,6 +198,7 @@ export default {
201
198
  vertical-align: middle;
202
199
  cursor: pointer;
203
200
  pointer-events: auto;
201
+ //transition: bottom 0.3s;
204
202
 
205
203
  &.close {
206
204
  float: left;
@@ -211,17 +209,8 @@ export default {
211
209
 
212
210
  &.open {
213
211
  position: absolute;
214
- top:26px;
215
- }
216
-
217
- i {
218
- margin-top: 12px;
219
- color: $app-primary-color;
220
- transform: scaleY(2.5);
212
+ bottom:26px;
221
213
  }
222
- }
223
-
224
- .open-tab{
225
214
 
226
215
  i {
227
216
  margin-top: 12px;
@@ -7,7 +7,7 @@
7
7
  element-loading-spinner="el-icon-loading"
8
8
  element-loading-background="rgba(0, 0, 0, 0.3)"
9
9
  >
10
- <SvgSpriteColor />
10
+ <map-svg-sprite-color />
11
11
  <div
12
12
  id="organsDisplayArea"
13
13
  ref="display"
@@ -54,7 +54,9 @@
54
54
  @object-hovered="objectHovered"
55
55
  @drawer-toggled="drawerToggled"
56
56
  />
57
- <OpacityControls ref="opacityControl" />
57
+ <div class="opacity-box">
58
+ <OpacityControls ref="opacityControl" />
59
+ </div>
58
60
  <el-popover
59
61
  v-if="sceneData.timeVarying"
60
62
  ref="sliderPopover"
@@ -74,13 +76,13 @@
74
76
  <el-tabs type="card">
75
77
  <el-tab-pane label="Animate scaffold">
76
78
  <el-row class="tab-content">
77
- <SvgIcon
79
+ <map-svg-icon
78
80
  v-if="isPlaying"
79
81
  icon="pause"
80
82
  class="icon-button video-button"
81
83
  @click.native="play(false)"
82
84
  />
83
- <SvgIcon
85
+ <map-svg-icon
84
86
  v-else
85
87
  icon="play"
86
88
  class="video-button icon-button"
@@ -144,7 +146,7 @@
144
146
  trigger="manual"
145
147
  popper-class="scaffold-popper left-popper non-selectable"
146
148
  >
147
- <SvgIcon
149
+ <map-svg-icon
148
150
  slot="reference"
149
151
  icon="zoomIn"
150
152
  class="icon-button zoomIn"
@@ -161,7 +163,7 @@
161
163
  trigger="manual"
162
164
  popper-class="scaffold-popper popper-zoomout non-selectable"
163
165
  >
164
- <SvgIcon
166
+ <map-svg-icon
165
167
  slot="reference"
166
168
  icon="zoomOut"
167
169
  class="icon-button zoomOut"
@@ -182,7 +184,7 @@
182
184
  <br>
183
185
  window
184
186
  </div>
185
- <SvgIcon
187
+ <map-svg-icon
186
188
  slot="reference"
187
189
  icon="fitWindow"
188
190
  class="icon-button fitWindow"
@@ -220,7 +222,7 @@
220
222
  trigger="manual"
221
223
  popper-class="scaffold-popper right-popper non-selectable"
222
224
  >
223
- <SvgIcon
225
+ <map-svg-icon
224
226
  slot="reference"
225
227
  v-popover:backgroundPopover
226
228
  icon="changeBckgd"
@@ -239,7 +241,7 @@
239
241
  import Vue from "vue";
240
242
  import OpacityControls from "./OpacityControls";
241
243
  import TraditionalControls from "./TraditionalControls";
242
- import { SvgIcon, SvgSpriteColor } from "@abi-software/svg-sprite";
244
+ import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
243
245
 
244
246
  import {
245
247
  Col,
@@ -266,10 +268,8 @@ Vue.use(Slider);
266
268
  Vue.use(TabPane);
267
269
  Vue.use(Tabs);
268
270
 
269
- const OrgansViewer = require("physiomeportal/src/modules/organsRenderer")
270
- .OrgansViewer;
271
- const EventNotifier = require("physiomeportal/src/utilities/eventNotifier")
272
- .EventNotifier;
271
+ const OrgansViewer = require("../scripts/organsRenderer").OrgansViewer;
272
+ const EventNotifier = require("../scripts/eventNotifier").EventNotifier;
273
273
 
274
274
  /**
275
275
  * A vue component of the scaffold viewer.
@@ -281,8 +281,8 @@ export default {
281
281
  name: "ScaffoldVuer",
282
282
  components: {
283
283
  OpacityControls,
284
- SvgIcon,
285
- SvgSpriteColor,
284
+ MapSvgIcon,
285
+ MapSvgSpriteColor,
286
286
  TraditionalControls
287
287
  },
288
288
  props: {
@@ -533,7 +533,6 @@ export default {
533
533
  this.$module.addOrganPartAddedCallback(this.organsAdded);
534
534
  this.$module.initialiseRenderer(this.$refs.display);
535
535
  this.toggleRendering(this.render);
536
- this.$module.toolTip = undefined;
537
536
  this.ro = new ResizeObserver(this.adjustLayout).observe(
538
537
  this.$refs.scaffoldContainer
539
538
  );
@@ -693,6 +692,12 @@ export default {
693
692
  }
694
693
  }
695
694
  },
695
+ getRendererInfo: function() {
696
+ if (this.$module.zincRenderer) {
697
+ return this.$module.zincRenderer.getThreeJSRenderer().info;
698
+ }
699
+ return undefined;
700
+ },
696
701
  /**
697
702
  * Function used to rotate the scene.
698
703
  * Also called when the associated button is pressed.
@@ -714,14 +719,14 @@ export default {
714
719
  */
715
720
  eventNotifierCallback: function(event) {
716
721
  if (event.eventType == 1) {
717
- if (this.controls) {
722
+ if (this.$refs.traditionalControl) {
718
723
  if (event.identifiers[0]) {
719
724
  let id = event.identifiers[0].data.id
720
725
  ? event.identifiers[0].data.id
721
726
  : event.identifiers[0].data.group;
722
- this.controls.changeActiveByName(id);
727
+ this.$refs.traditionalControl.changeActiveByName(id, true);
723
728
  } else {
724
- this.controls.removeActive();
729
+ this.$refs.traditionalControl.removeActive(true);
725
730
  }
726
731
  }
727
732
  /**
@@ -732,13 +737,13 @@ export default {
732
737
  */
733
738
  this.$emit("scaffold-selected", event.identifiers);
734
739
  } else if (event.eventType == 2) {
735
- if (this.controls) {
740
+ if (this.$refs.traditionalControl) {
736
741
  if (event.identifiers[0]) {
737
742
  let id = event.identifiers[0].data.id
738
743
  ? event.identifiers[0].data.id
739
744
  : event.identifiers[0].data.group;
740
- this.controls.changeHoverByName(id);
741
- } else this.controls.removeHover();
745
+ this.$refs.traditionalControl.changeHoverByName(id, true);
746
+ } else this.$refs.traditionalControl.removeHover(true);
742
747
  }
743
748
  /**
744
749
  * Triggers when an object has been highlighted
@@ -779,30 +784,52 @@ export default {
779
784
  this.$module.updateTime(normalizedTime);
780
785
  },
781
786
  /**
782
- * Set the selected zinc object
787
+ * A callback used by children components. Set the selected zinc object
783
788
  *
784
789
  * @param {object} object Zinc object
785
790
  */
786
- objectSelected: function(object) {
791
+ objectSelected: function(object, propagate) {
787
792
  if (object !== this.selectedObject) {
788
793
  this.selectedObject = object;
789
794
  this.$refs.opacityControl.setObject(this.selectedObject);
790
- if (object) this.$module.setSelectedByZincObject(object, true);
791
- else this.$module.setSelectedByObjects([], true);
795
+ if (object) this.$module.setSelectedByZincObject(object, propagate);
796
+ else this.$module.setSelectedByObjects([], propagate);
792
797
  }
793
798
  },
794
799
  /**
795
- * Set the highlighted zinc object
800
+ * A callback used by children components. Set the highlighted zinc object
796
801
  *
797
802
  * @param {object} object Zinc object
798
803
  */
799
- objectHovered: function(object) {
804
+ objectHovered: function(object, propagate) {
800
805
  if (object !== this.hoveredObject) {
801
806
  this.hoveredObject = object;
802
- if (object) this.$module.setHighlightedByZincObject(object, true);
803
- else this.$module.setHighlightedByObjects([], true);
807
+ if (object) this.$module.setHighlightedByZincObject(object, propagate);
808
+ else this.$module.setHighlightedByObjects([], propagate);
804
809
  }
805
810
  },
811
+ /**
812
+ * Set the selected by name.
813
+ *
814
+ * @param {name} name Name of the region
815
+ */
816
+ changeActiveByName: function(name, propagate) {
817
+ if (name === undefined)
818
+ this.$refs.traditionalControl.removeActive(propagate);
819
+ else
820
+ this.$refs.traditionalControl.changeActiveByName(name, propagate);
821
+ },
822
+ /**
823
+ * Set the highlighted by name.
824
+ *
825
+ * @param {name} name Name of the region
826
+ */
827
+ changeHighlightedByName: function(name, propagate) {
828
+ if (name === undefined)
829
+ this.$refs.traditionalControl.removeHover(propagate);
830
+ else
831
+ this.$refs.traditionalControl.changeHoverByName(name, propagate);
832
+ },
806
833
  /**
807
834
  * Start the animation.
808
835
  *
@@ -953,6 +980,9 @@ export default {
953
980
  }
954
981
  }
955
982
  },
983
+ exportGLTF: function(binary) {
984
+ return this.$module.scene.exportGLTF(binary);
985
+ },
956
986
  /**
957
987
  * Function used for reading in new scaffold metadata and a custom
958
988
  * viewport. This function will ignore the state prop and
@@ -1435,4 +1465,10 @@ export default {
1435
1465
  text-align: left;
1436
1466
  font-family: "Asap", sans-serif;
1437
1467
  }
1468
+
1469
+ .opacity-box {
1470
+ right: 0px;
1471
+ bottom:200px;
1472
+ position:absolute;
1473
+ }
1438
1474
  </style>
@@ -153,47 +153,41 @@ export default {
153
153
  /**
154
154
  * Select a region by its name.
155
155
  */
156
- changeActiveByName: function(name) {
156
+ changeActiveByName: function(name, propagate) {
157
157
  let targetObject = this.getFirstZincObjectWithGroupName(name);
158
158
  if (targetObject && targetObject.getVisibility()) {
159
159
  this.activeRegion = name;
160
- /**
161
- * Triggers when an item has been selected.
162
- *
163
- * @property {object} target selected object.
164
- */
165
- this.$emit("object-selected", targetObject);
160
+ this.$emit("object-selected", targetObject, propagate);
161
+ } else {
162
+ this.removeActive(propagate);
166
163
  }
167
- this.removeHover();
164
+ this.removeHover(propagate);
168
165
  },
169
166
  /**
170
167
  * Hover a region by its name.
171
168
  */
172
- changeHoverByName: function(name) {
169
+ changeHoverByName: function(name, propagate) {
173
170
  let targetObject = this.getFirstZincObjectWithGroupName(name);
174
171
  if (targetObject) {
175
172
  this.hoverRegion = name;
176
- /**
177
- * Triggers when an item has been hovered over.
178
- *
179
- * @property {object} target hovered object.
180
- */
181
- this.$emit("object-hovered", targetObject);
173
+ this.$emit("object-hovered", targetObject, propagate);
174
+ } else {
175
+ this.removeHover(propagate);
182
176
  }
183
177
  },
184
178
  /**
185
179
  * Unselect the current selected region.
186
180
  */
187
- removeActive: function() {
181
+ removeActive: function(propagate) {
188
182
  this.activeRegion = "";
189
- this.$emit("object-selected", undefined);
183
+ this.$emit("object-selected", undefined, propagate);
190
184
  },
191
185
  /**
192
186
  * Unselect the current hover region.
193
187
  */
194
- removeHover: function() {
188
+ removeHover: function(propagate) {
195
189
  this.hoverRegion = "";
196
- this.$emit("object-hovered", undefined);
190
+ this.$emit("object-hovered", undefined, propagate);
197
191
  },
198
192
  /**
199
193
  * Reset the controls.
@@ -236,7 +230,7 @@ export default {
236
230
  }
237
231
  },
238
232
  checkboxHover: function(name) {
239
- this.changeHoverByName(name);
233
+ this.changeHoverByName(name, true);
240
234
  },
241
235
  itemClicked: function(name, event) {
242
236
  if (
@@ -245,7 +239,7 @@ export default {
245
239
  event.target.classList.contains("el-checkbox__original")
246
240
  )
247
241
  ) {
248
- this.changeActiveByName(name);
242
+ this.changeActiveByName(name, true);
249
243
  event.preventDefault();
250
244
  }
251
245
  },
@@ -272,10 +266,10 @@ export default {
272
266
  this.module.changeOrganPartsVisibility(item, event);
273
267
  if (event == false) {
274
268
  if (this.activeRegion === item) {
275
- this.removeActive();
269
+ this.removeActive(true);
276
270
  }
277
271
  if (this.hoverRegion === item) {
278
- this.removeHover();
272
+ this.removeHover(true);
279
273
  }
280
274
  }
281
275
  },
@@ -0,0 +1,80 @@
1
+ const MODULE_CHANGE = { ALL: 0, DESTROYED: 1, NAME_CHANGED: 2, SETTINGS_CHANGED: 3 };
2
+
3
+ const BaseModule = function() {
4
+ this.typeName = "Base Module";
5
+ this.instanceName = "default";
6
+ this.onChangedCallbacks = [];
7
+ /** Notifier handle for informing other modules of any changes **/
8
+ this.eventNotifiers = [];
9
+ }
10
+
11
+ BaseModule.prototype.setName = function(name) {
12
+ if (name && this.instanceName !== name) {
13
+ this.instanceName = name;
14
+ const callbackArray = this.onChangedCallbacks.slice();
15
+ for (let i = 0; i < callbackArray.length; i++) {
16
+ callbackArray[i]( this, MODULE_CHANGE.NAME_CHANGED );
17
+ }
18
+ }
19
+ }
20
+
21
+ BaseModule.prototype.settingsChanged = function() {
22
+ const callbackArray = this.onChangedCallbacks.slice();
23
+ for (let i = 0; i < callbackArray.length; i++) {
24
+ callbackArray[i]( this, MODULE_CHANGE.SETTINGS_CHANGED );
25
+ }
26
+ }
27
+
28
+ BaseModule.prototype.exportSettings = function() {
29
+ const settings = {};
30
+ settings.dialog = this.typeName;
31
+ settings.name = this.instanceName;
32
+ return settings;
33
+ }
34
+
35
+ BaseModule.prototype.importSettings = function(settings) {
36
+ if (settings.dialog == this.typeName) {
37
+ this.setName(settings.name);
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+
43
+ BaseModule.prototype.publishChanges = function(annotations, eventType) {
44
+ for (let i = 0; i < this.eventNotifiers.length; i++) {
45
+ this.eventNotifiers[i].publish(this, eventType, annotations);
46
+ }
47
+ }
48
+
49
+ BaseModule.prototype.getName = function() {
50
+ return this.instanceName;
51
+ }
52
+
53
+ BaseModule.prototype.destroy = function() {
54
+ //Make a temorary copy as the array may be altered during the loop
55
+ const callbackArray = this.onChangedCallbacks.slice();
56
+ for (let i = 0; i < callbackArray.length; i++) {
57
+ callbackArray[i]( this, MODULE_CHANGE.DESTROYED );
58
+ }
59
+
60
+ delete this;
61
+ }
62
+
63
+ BaseModule.prototype.addChangedCallback = function(callback) {
64
+ if (this.onChangedCallbacks.includes(callback) == false)
65
+ this.onChangedCallbacks.push(callback);
66
+ }
67
+
68
+ BaseModule.prototype.removeChangedCallback = function(callback) {
69
+ const index = this.onChangedCallbacks.indexOf(callback);
70
+ if (index > -1) {
71
+ this.onChangedCallbacks.splice(index, 1);
72
+ }
73
+ }
74
+
75
+ BaseModule.prototype.addNotifier = function(eventNotifier) {
76
+ this.eventNotifiers.push(eventNotifier);
77
+ }
78
+
79
+ exports.BaseModule = BaseModule;
80
+ exports.MODULE_CHANGE = MODULE_CHANGE;