@abi-software/scaffoldvuer 1.2.1 → 1.3.0

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,46 +1,81 @@
1
1
  <template>
2
2
  <el-container class="transformation-container">
3
3
  <el-main class="slides-block">
4
- <el-row>
5
- <el-col :offset="0" :span="8">
6
- Position:
7
- </el-col>
8
- </el-row>
9
- <el-row class="">
10
- <el-col :offset="3" :span="1">
4
+ <el-row class="tool-row">
5
+ <el-col :offset="0" :span="6">
11
6
  x:
12
7
  </el-col>
13
- <el-col :span="3">
8
+ <el-col :offset="0" :span="10">
9
+ <el-slider
10
+ v-model="x"
11
+ :step="0.01"
12
+ :min="min[0]"
13
+ :max="max[0]"
14
+ :show-tooltip="false"
15
+ @input="modifyPosition()"
16
+ />
17
+ </el-col>
18
+ <el-col :offset="0" :span="6">
14
19
  <el-input-number
15
20
  v-model="x"
16
- :step="1"
21
+ :step="0.01"
22
+ :min="min[0]"
23
+ :max="max[0]"
17
24
  :controls="false"
18
25
  class="input-box number-input"
19
- @change="modifyPosition"
26
+ @change="modifyPosition()"
20
27
  />
21
28
  </el-col>
22
- <el-col :offset="3" :span="1">
29
+ </el-row>
30
+ <el-row class="tool-row">
31
+ <el-col :offset="0" :span="6">
23
32
  y:
24
33
  </el-col>
25
- <el-col :span="3">
34
+ <el-col :offset="0" :span="10">
35
+ <el-slider
36
+ v-model="y"
37
+ :step="0.01"
38
+ :min="min[1]"
39
+ :max="max[1]"
40
+ :show-tooltip="false"
41
+ @input="modifyPosition()"
42
+ />
43
+ </el-col>
44
+ <el-col :offset="0" :span="6">
26
45
  <el-input-number
27
46
  v-model="y"
28
- :step="1"
47
+ :step="0.01"
48
+ :min="min[1]"
49
+ :max="max[1]"
29
50
  :controls="false"
30
51
  class="input-box number-input"
31
- @change="modifyPosition"
52
+ @change="modifyPosition()"
32
53
  />
33
54
  </el-col>
34
- <el-col :offset="3" :span="1">
55
+ </el-row>
56
+ <el-row class="tool-row">
57
+ <el-col :offset="0" :span="6">
35
58
  z:
36
59
  </el-col>
37
- <el-col :span="3">
60
+ <el-col :offset="0" :span="10">
61
+ <el-slider
62
+ v-model="z"
63
+ :step="0.01"
64
+ :min="min[2]"
65
+ :max="max[2]"
66
+ :show-tooltip="false"
67
+ @input="modifyPosition()"
68
+ />
69
+ </el-col>
70
+ <el-col :offset="0" :span="6">
38
71
  <el-input-number
39
72
  v-model="z"
40
- :step="1"
73
+ :step="0.01"
74
+ :min="min[2]"
75
+ :max="max[2]"
41
76
  :controls="false"
42
77
  class="input-box number-input"
43
- @change="modifyPosition"
78
+ @change="modifyPosition()"
44
79
  />
45
80
  </el-col>
46
81
  </el-row>
@@ -82,6 +117,7 @@ import {
82
117
  ElContainer as Container,
83
118
  ElInputNumber as InputNumber,
84
119
  ElMain as Main,
120
+ ElSlider as Slider,
85
121
  } from "element-plus";
86
122
 
87
123
  /**
@@ -94,15 +130,39 @@ export default {
94
130
  Container,
95
131
  InputNumber,
96
132
  Main,
133
+ Slider,
97
134
  },
135
+ inject: ['boundingDims'],
98
136
  data: function () {
99
137
  return {
100
138
  x: 0,
101
139
  y: 0,
102
140
  z: 0,
103
141
  scale: 1,
142
+ min: [0, 0, 0],
143
+ max: [1, 1, 1],
104
144
  };
105
145
  },
146
+ watch: {
147
+ boundingDims: {
148
+ handler: function (value) {
149
+ const centre = value.centre;
150
+ const size = value.size;
151
+ this.min = [
152
+ centre[0] - size[0],
153
+ centre[1] - size[1],
154
+ centre[2] - size[2]
155
+ ];
156
+ this.max = [
157
+ centre[0] + size[0],
158
+ centre[1] + size[1],
159
+ centre[2] + size[2]
160
+ ];
161
+ },
162
+ immediate: true,
163
+ deep: true,
164
+ },
165
+ },
106
166
  mounted: function () {
107
167
  this._zincObject = undefined;
108
168
  },
@@ -1,9 +1,5 @@
1
1
  // The Vue build version to load with the `import` command
2
2
  // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3
3
  import ScaffoldVuer from "./ScaffoldVuer.vue";
4
- import HelpModeDialog from "./HelpModeDialog.vue";
5
4
 
6
- export {
7
- ScaffoldVuer,
8
- HelpModeDialog,
9
- };
5
+ export { ScaffoldVuer };
@@ -12,7 +12,6 @@ declare module 'vue' {
12
12
  ElCol: typeof import('element-plus/es')['ElCol']
13
13
  ElCollapse: typeof import('element-plus/es')['ElCollapse']
14
14
  ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
15
- ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
16
15
  ElContainer: typeof import('element-plus/es')['ElContainer']
17
16
  ElFooter: typeof import('element-plus/es')['ElFooter']
18
17
  ElHeader: typeof import('element-plus/es')['ElHeader']
@@ -32,8 +31,6 @@ declare module 'vue' {
32
31
  ElSlider: typeof import('element-plus/es')['ElSlider']
33
32
  ElTabPane: typeof import('element-plus/es')['ElTabPane']
34
33
  ElTabs: typeof import('element-plus/es')['ElTabs']
35
- ElTree: typeof import('element-plus/es')['ElTree']
36
- HelpModeDialog: typeof import('./components/HelpModeDialog.vue')['default']
37
34
  LinesControls: typeof import('./components/LinesControls.vue')['default']
38
35
  OpacityControls: typeof import('./components/OpacityControls.vue')['default']
39
36
  PointsControls: typeof import('./components/PointsControls.vue')['default']
@@ -41,10 +38,10 @@ declare module 'vue' {
41
38
  RouterLink: typeof import('vue-router')['RouterLink']
42
39
  RouterView: typeof import('vue-router')['RouterView']
43
40
  ScaffoldTooltip: typeof import('./components/ScaffoldTooltip.vue')['default']
41
+ ScaffoldTreeControls: typeof import('./components/ScaffoldTreeControls.vue')['default']
44
42
  ScaffoldVuer: typeof import('./components/ScaffoldVuer.vue')['default']
45
43
  TextureSlidesControls: typeof import('./components/TextureSlidesControls.vue')['default']
46
44
  TransformationControls: typeof import('./components/TransformationControls.vue')['default']
47
- TreeControls: typeof import('./components/TreeControls.vue')['default']
48
45
  }
49
46
  export interface ComponentCustomProperties {
50
47
  vLoading: typeof import('element-plus/es')['ElLoadingDirective']
@@ -38,6 +38,7 @@ const OrgansSceneData = function() {
38
38
  const timeChangedCallbacks = new Array();
39
39
  const sceneChangedCallbacks = new Array();
40
40
  const organPartAddedCallbacks = new Array();
41
+ const organPartRemovedCallbacks = new Array();
41
42
  let finishDownloadCallback = undefined;
42
43
  const modelsLoader = ModelsLoaderIn;
43
44
  this.NDCCameraControl = undefined;
@@ -148,9 +149,9 @@ const OrgansSceneData = function() {
148
149
  }
149
150
  }
150
151
 
151
- /**
152
- * Add a callback which will be called when time has changed
153
- */
152
+ /**
153
+ * Add a callback which will be called when time has changed
154
+ */
154
155
  this.addTimeChangedCallback = function(callback) {
155
156
  if (typeof(callback === "function"))
156
157
  timeChangedCallbacks.push(callback);
@@ -172,6 +173,11 @@ const OrgansSceneData = function() {
172
173
  organPartAddedCallbacks.push(callback);
173
174
  }
174
175
 
176
+ this.addOrganPartRemovedCallback = function(callback) {
177
+ if (typeof(callback === "function"))
178
+ organPartRemovedCallbacks.push(callback);
179
+ }
180
+
175
181
  this.setFinishDownloadCallback = function(callback) {
176
182
  if (typeof(callback === "function"))
177
183
  finishDownloadCallback = callback;
@@ -239,10 +245,12 @@ const OrgansSceneData = function() {
239
245
  intersected ? intersected.point.y : 0,
240
246
  intersected ? intersected.point.z : 0,
241
247
  ],
242
- intersected,
248
+ intersected: intersected,
249
+ intersects: intersects,
243
250
  };
244
251
  const coords = { x: window_x, y: window_y };
245
252
  if (idObject.id) {
253
+ extraData.threeID = idObject.object?.id;
246
254
  if (idObject.object.userData.isGlyph) {
247
255
  if (idObject.object.name) {
248
256
  _this.setSelectedByObjects([idObject.object], coords,
@@ -279,6 +287,7 @@ const OrgansSceneData = function() {
279
287
  }
280
288
  const coords = { x: window_x, y: window_y };
281
289
  if (idObject.id) {
290
+ extraData.threeID = idObject.object?.id;
282
291
  _this.displayArea.style.cursor = "pointer";
283
292
  _this.setHighlightedByObjects([idObject.object], coords, extraData, true);
284
293
  return;
@@ -393,6 +402,12 @@ const OrgansSceneData = function() {
393
402
  zincObject.userData["annotation"] = annotation;
394
403
  }
395
404
 
405
+ const removeOrganPart = function(systemName, partName, useDefautColour, zincObject) {
406
+ for (let i = 0; i < organPartRemovedCallbacks.length;i++) {
407
+ organPartRemovedCallbacks[i](zincObject);
408
+ }
409
+ }
410
+
396
411
  /**
397
412
  * New organs geometry has been added to the scene, add UIs and make
398
413
  * sure the viewport is correct.
@@ -402,6 +417,15 @@ const OrgansSceneData = function() {
402
417
  addOrganPart(systemName, partName, useDefautColour, zincObject);
403
418
  }
404
419
  }
420
+
421
+ /**
422
+ * Organs geometry has been removed to the scene.
423
+ */
424
+ const _removeOrganPartCallback = function(systemName, partName, useDefautColour) {
425
+ return function(zincObject) {
426
+ removeOrganPart(systemName, partName, useDefautColour, zincObject);
427
+ }
428
+ }
405
429
 
406
430
  const downloadCompletedCallback = function() {
407
431
  return function() {
@@ -465,6 +489,19 @@ const OrgansSceneData = function() {
465
489
  }
466
490
  return availableSpecies;
467
491
  }
492
+
493
+ /**
494
+ * Return the center and size of the cuurrent viewing scene
495
+ */
496
+ this.getCentreAndSize = function() {
497
+ const vector = new THREE.Vector3();
498
+ const boundingBox = this.scene.getBoundingBox();
499
+ boundingBox.getCenter(vector);
500
+ const centre = [vector.x, vector.y, vector.z];
501
+ boundingBox.getSize(vector);
502
+ const size = [vector.x, vector.y, vector.z];
503
+ return {centre, size};
504
+ }
468
505
 
469
506
  const setSceneData = function(speciesName, systemName, partName, organsDetails) {
470
507
  _this.sceneData.nerveMapIsActive = false;
@@ -511,7 +548,8 @@ const OrgansSceneData = function() {
511
548
  }
512
549
  _this.sceneData.metaURL = url;
513
550
  organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
514
- organScene.loadMetadataURL(url, undefined, downloadCompletedCallback());
551
+ organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
552
+ organScene.loadMetadataURL(url, undefined, downloadCompletedCallback());
515
553
  _this.scene = organScene;
516
554
  _this.zincRenderer.setCurrentScene(organScene);
517
555
  _this.graphicsHighlight.reset();
@@ -541,7 +579,8 @@ const OrgansSceneData = function() {
541
579
  _this.sceneData.viewURL = undefined;
542
580
  _this.sceneData.metaURL = url;
543
581
  organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(undefined, partName, false));
544
- organScene.loadGLTF(url, undefined, downloadCompletedCallback());
582
+ organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
583
+ organScene.loadGLTF(url, undefined, downloadCompletedCallback());
545
584
  _this.scene = organScene;
546
585
  _this.zincRenderer.setCurrentScene(organScene);
547
586
  _this.graphicsHighlight.reset();
@@ -37,6 +37,7 @@ const RendererModule = function() {
37
37
  this.selectedScreenCoordinates = new THREE.Vector3();
38
38
  this.selectedCenter = undefined;
39
39
  this.liveUpdatesObjects = undefined;
40
+ this.ignorePreviousSelected = false;
40
41
  }
41
42
 
42
43
  RendererModule.prototype = Object.create(BaseModule.prototype);
@@ -44,17 +45,18 @@ RendererModule.prototype = Object.create(BaseModule.prototype);
44
45
  RendererModule.prototype.getIntersectedObject = function(intersects) {
45
46
  if (intersects) {
46
47
  const typeMap = intersects.map(intersect => {
47
- if (intersect && intersect.object &&
48
- intersect.object.userData) {
49
- if (intersect.object.userData.isMarker) {
50
- return 1;
51
- } else if (intersect.object.name &&
52
- intersect.object.userData.isZincObject) {
53
- return 2;
54
- }
48
+ if (intersect && intersect.object &&
49
+ intersect.object.userData) {
50
+ if (intersect.object.userData.isMarker) {
51
+ return 1;
52
+ } else if (intersect.object.name &&
53
+ intersect.object.userData.isZincObject) {
54
+ return 2;
55
55
  }
56
- return 0;
56
+ }
57
+ return 0;
57
58
  });
59
+ //prioritise markers
58
60
  let i = typeMap.indexOf(1);
59
61
  i = (i > -1) ? i : typeMap.indexOf(2);
60
62
  return intersects[i];
@@ -71,8 +73,9 @@ RendererModule.prototype.getAnnotationsFromObjects = function(objects) {
71
73
  if (zincObject) {
72
74
  if (zincObject.isGlyph || zincObject.isGlyphset) {
73
75
  let glyphset = zincObject;
74
- if (zincObject.isGlyph)
76
+ if (zincObject.isGlyph) {
75
77
  glyphset = zincObject.getGlyphset();
78
+ }
76
79
  annotation = glyphset.userData ? glyphset.userData.annotation : undefined;
77
80
  if (annotation && annotation.data) {
78
81
  if (objects[i].name && objects[i].name != "")
@@ -86,6 +89,9 @@ RendererModule.prototype.getAnnotationsFromObjects = function(objects) {
86
89
  annotation.data.id = objects[i].name;
87
90
  }
88
91
  }
92
+ if (annotation) {
93
+ annotation.data.zincObject = zincObject;
94
+ }
89
95
  }
90
96
  if (annotation)
91
97
  annotations.push(annotation);
@@ -172,7 +178,7 @@ RendererModule.prototype.setSelectedByObjects = function(
172
178
  } else {
173
179
  changed = true;
174
180
  }
175
- if (changed) {
181
+ if (changed || this.ignorePreviousSelected) {
176
182
  const zincObjects = this.objectsToZincObjects(objects);
177
183
  if (this.selectObjectOnPick) {
178
184
  this.setupLiveCoordinates(zincObjects);
@@ -76,6 +76,22 @@ export class SearchIndex
76
76
  this.zincObjects.push(zincObject);
77
77
  }
78
78
 
79
+ removeZincObject(zincObject, id)
80
+ //=======================
81
+ {
82
+ const path = zincObject.getRegion().getFullPath();
83
+ const fullPath = path ? `${path}/${zincObject.groupName}` : zincObject.groupName;
84
+ const item = { path: fullPath, name: zincObject.groupName, id };
85
+ this._searchEngine.remove(item, {fields: ['path', 'name']});
86
+ for (let i = 0; i < this.zincObjects.length; i++) {
87
+ if (id === this.zincObjects[i].uuid) {
88
+ this.zincObjects.splice(i, 1);
89
+ return;
90
+ }
91
+ }
92
+
93
+ }
94
+
79
95
  addRegion(region, id)
80
96
  //=======================
81
97
  {
@@ -126,7 +142,7 @@ export class SearchIndex
126
142
  }
127
143
  result["zincObjects"] = createUnqiuesFromObjects(zincObjects);
128
144
  return result;
129
- }
145
+ }
130
146
 
131
147
  search(text) {
132
148
  const results = this._searchEngine.search(text, {prefix: true});
@@ -1,4 +1,4 @@
1
- import { THREE } from 'zincjs';
1
+ import { Label, THREE } from 'zincjs';
2
2
 
3
3
  export const createListFromPrimitives = (primitives, list) => {
4
4
  if (primitives) {
@@ -47,24 +47,76 @@ export const getEditableLines = (event) => {
47
47
  return undefined;
48
48
  }
49
49
 
50
- export const moveLine = (zincObject, faceIndex, unit) => {
50
+ export const getDeletableObjects = (event) => {
51
+ const zincObjects = event.zincObjects;
52
+ if (zincObjects.length > 0 && zincObjects[0]) {
53
+ const zincObject = zincObjects[0];
54
+ if (zincObject.isEditable) {
55
+ return zincObject;
56
+ }
57
+ }
58
+ return undefined;
59
+ }
60
+
61
+ export const movePoint = (zincObject, index, diff) => {
62
+ if (zincObject?.isEditable && zincObject?.isPointset) {
63
+ let found = false;
64
+ for (let i = 0; i < 3 && !found; i++) {
65
+ if (diff[i] !== 0) {
66
+ found = true;
67
+ }
68
+ }
69
+ if (found && index > -1) {
70
+ const v = zincObject.getVerticesByIndex(index);
71
+ if (v) {
72
+ v[0] = v[0] + diff[0];
73
+ v[1] = v[1] + diff[1];
74
+ v[2] = v[2] + diff[2];
75
+ }
76
+ zincObject.editVertices([v], index);
77
+ zincObject.boundingBoxUpdateRequired = true;
78
+ return true;
79
+ }
80
+ }
81
+ return false;
82
+ }
83
+
84
+ export const getLineDistance = (zincObject, faceIndex) => {
85
+ if (zincObject?.isEditable && zincObject?.isLines2) {
86
+ if (faceIndex > -1) {
87
+ const v = zincObject.getVerticesByFaceIndex(faceIndex);
88
+ if (v && v.length > 1) {
89
+ return getDistance(v[1], v[0]);
90
+ }
91
+ }
92
+ }
93
+ return 0;
94
+ }
95
+
96
+ //Move or extend a line
97
+ export const moveAndExtendLine = (zincObject, faceIndex, unit, extendOnly) => {
51
98
  if (zincObject && unit !== 0.0) {
52
99
  if (zincObject.isEditable && zincObject.isLines2) {
53
100
  if (faceIndex > -1) {
54
101
  const v = zincObject.getVerticesByFaceIndex(faceIndex);
55
- let d = [v[0][0] - v[1][0], v[0][1] - v[1][1], v[0][2] - v[1][2]];
102
+ let d = [v[1][0] - v[0][0], v[1][1] - v[0][1], v[1][2] - v[0][2]];
56
103
  const mag = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
57
104
  for (let i = 0; i < 3; i++) {
58
105
  d[i] = d[i] / mag * unit;
59
- v[0][i] = v[0][i] + d[i];
60
- v[1][i] = v[1][i] + d[i];
106
+ if (!extendOnly) {
107
+ v[0][i] = v[0][i] + d[i];
108
+ v[1][i] = v[1][i] + d[i];
109
+ } else {
110
+ v[1][i] = v[0][i] + d[i];
111
+ }
61
112
  }
62
- zincObject.editVertice(v, faceIndex * 2);
113
+ zincObject.editVertices(v, faceIndex * 2);
63
114
  zincObject.boundingBoxUpdateRequired = true;
115
+ return true;
64
116
  }
65
117
  }
66
118
  }
67
- return undefined;
119
+ return false;
68
120
  }
69
121
 
70
122
  export const updateBoundingBox = (geometry, scene) => {
@@ -246,7 +298,10 @@ const createNewAnnotationsWithFeatures = (zincObject, region, group, scaffoldUrl
246
298
  }
247
299
  if (type) {
248
300
  const coords = getCoordinatesForAnnotationFeature(zincObject);
249
- const featureID = encodeURIComponent(region + group);
301
+ //Check if region ends with a slash
302
+ let fullName = region.slice(-1) === "/" ? region : region + "/";
303
+ fullName = fullName + group;
304
+ const featureID = encodeURIComponent(fullName);
250
305
  const userAnnotation = {
251
306
  resource: encodeURIComponent(scaffoldUrl),
252
307
  item: {
@@ -268,6 +323,10 @@ const createNewAnnotationsWithFeatures = (zincObject, region, group, scaffoldUrl
268
323
  }
269
324
  },
270
325
  }
326
+ if (comment === "Deleted") {
327
+ userAnnotation.feature = undefined;
328
+ }
329
+
271
330
  return userAnnotation;
272
331
  }
273
332
  }
@@ -275,10 +334,11 @@ const createNewAnnotationsWithFeatures = (zincObject, region, group, scaffoldUrl
275
334
  /*
276
335
  * Add/Update drawn annotations to the server.
277
336
  */
278
- export const addUserAnnotationWithFeature = (service, userToken, zincObject, region, group, scaffoldUrl, action) => {
279
- if (service && service.currentUser) {
280
- const annotation = createNewAnnotationsWithFeatures(zincObject, region, group, scaffoldUrl, action);
281
- if (annotation) {
337
+ export const addUserAnnotationWithFeature = (service, userToken, zincObject,
338
+ region, group, scaffoldUrl, action) => {
339
+ const annotation = createNewAnnotationsWithFeatures(zincObject, region, group, scaffoldUrl, action);
340
+ if (annotation) {
341
+ if (service && service.currentUser) {
282
342
  annotation.creator = {...service.currentUser};
283
343
  if (!annotation.creator.orcid) annotation.creator.orcid = '0000-0000-0000-0000';
284
344
  service.addAnnotation(userToken, annotation)
@@ -291,6 +351,7 @@ export const addUserAnnotationWithFeature = (service, userToken, zincObject, reg
291
351
  console.log('There is a problem with the submission, please try again later');
292
352
  })
293
353
  }
354
+ return annotation;
294
355
  }
295
356
  }
296
357
 
@@ -319,7 +380,7 @@ export const annotationFeaturesToPrimitives = (scene, features) => {
319
380
  region,
320
381
  group,
321
382
  geometry.coordinates,
322
- undefined,
383
+ group,
323
384
  0x0022ee,
324
385
  );
325
386
  } else if (geometry.type === "MultiLineString") {
@@ -333,4 +394,5 @@ export const annotationFeaturesToPrimitives = (scene, features) => {
333
394
  if (object) object.zincObject.isEditable = true;
334
395
  });
335
396
  }
336
- }
397
+ }
398
+
@@ -21,4 +21,4 @@ export const useMainStore = defineStore('main', {
21
21
  this.userProfile.token = value
22
22
  },
23
23
  }
24
- })
24
+ })
package/vite.config.js CHANGED
@@ -46,12 +46,12 @@ export default defineConfig(({ command, mode }) => {
46
46
  fileName: 'scaffoldvuer',
47
47
  },
48
48
  rollupOptions: {
49
- external: ["vue", "@abi-software/flatmapvuer", "@abi-software/svg-sprite"],
49
+ external: ["vue", "@abi-software/svg-sprite", "@abi-software/map-utilities"],
50
50
  output: {
51
51
  globals: {
52
52
  vue: "Vue",
53
- "@abi-software/flatmapvuer": "@abi-software/flatmapvuer",
54
- "@abi-software/svg-sprite": "@abi-software/svg-sprite"
53
+ "@abi-software/svg-sprite": "@abi-software/svg-sprite",
54
+ "@abi-software/map-utilities": "@abi-software/map-utilities"
55
55
  },
56
56
  },
57
57
  },