@abi-software/scaffoldvuer 1.13.1-beta.0 → 1.13.1-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": "1.13.1-beta.0",
3
+ "version": "1.13.1-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  "*.js"
42
42
  ],
43
43
  "dependencies": {
44
- "@abi-software/map-utilities": "^1.7.6",
44
+ "@abi-software/map-utilities": "^1.7.8-beta.0",
45
45
  "@abi-software/sparc-annotation": "^0.3.2",
46
46
  "@abi-software/svg-sprite": "1.0.3",
47
47
  "@element-plus/icons-vue": "^2.3.1",
@@ -53,7 +53,7 @@
53
53
  "unplugin-vue-components": "^0.26.0",
54
54
  "vue": "^3.4.21",
55
55
  "vue-router": "^4.2.5",
56
- "zincjs": "^1.16.2"
56
+ "zincjs": "^1.16.4"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@babel/eslint-parser": "^7.28.0",
package/src/App.vue CHANGED
@@ -150,7 +150,7 @@
150
150
  id="annotations-upload"
151
151
  type="file"
152
152
  accept="application/json"
153
- @change="importOfflineAnnotations"
153
+ @change="importOfflineAnnotations"
154
154
  />
155
155
  </el-button>
156
156
  </el-col>
@@ -357,7 +357,7 @@ const writeTextFile = (filename, data) => {
357
357
  hrefElement.href = dataStr;
358
358
  hrefElement.click();
359
359
  hrefElement.remove();
360
- }
360
+ }
361
361
 
362
362
  export default {
363
363
  name: "app",
@@ -231,6 +231,11 @@ export default {
231
231
  color:black;
232
232
  opacity:0.5;
233
233
  top: 50%;
234
+ text-shadow:
235
+ -1px -1px 0 white,
236
+ 1px -1px 0 white,
237
+ -1px 1px 0 white,
238
+ 1px 1px 0 white; /* White outline */
234
239
  }
235
240
  }
236
241
 
@@ -440,6 +440,7 @@ import {
440
440
  getClickedObjects,
441
441
  getDeletableObjects,
442
442
  getDrawnAnnotations,
443
+ getEditablePoint,
443
444
  getEditableLines,
444
445
  getObjectsFromAnnotations,
445
446
  findObjectsWithNames,
@@ -816,6 +817,7 @@ export default {
816
817
  drawingBox: false,
817
818
  toBeConfirmed: false,
818
819
  points: [],
820
+ tempGroupName: "",
819
821
  shape: "",
820
822
  x: 0,
821
823
  y: 0,
@@ -1176,12 +1178,7 @@ export default {
1176
1178
  }
1177
1179
  }
1178
1180
  //Recalculate the following if module is ready
1179
- if (this.isReady) {
1180
- const {centre, size} = this.$module.getCentreAndSize();
1181
- this.boundingDims.centre = centre;
1182
- this.boundingDims.size = size;
1183
- }
1184
-
1181
+ this.calculateBoundingBox();
1185
1182
 
1186
1183
  /**
1187
1184
  * Emit when a new object is added to the scene
@@ -1306,7 +1303,17 @@ export default {
1306
1303
  }
1307
1304
  annotation.region = regionPath;
1308
1305
  this.offlineAnnotations = JSON.parse(sessionStorage.getItem('anonymous-annotation')) || [];
1309
- this.offlineAnnotations.push(annotation);
1306
+ const found = this.offlineAnnotations.find((element) => {
1307
+ return element.group === annotation.group &&
1308
+ element.region === annotation.region &&
1309
+ element.resource === annotation.resource &&
1310
+ element.feature.geometry.type === annotation.feature.geometry.type;
1311
+ });
1312
+ if (found) {
1313
+ Object.assign(found, annotation);
1314
+ } else {
1315
+ this.offlineAnnotations.push(annotation);
1316
+ }
1310
1317
  sessionStorage.setItem('anonymous-annotation', JSON.stringify(this.offlineAnnotations));
1311
1318
  }
1312
1319
  this.$emit('userPrimitivesUpdated', {region, group, zincObject});
@@ -1349,7 +1356,15 @@ export default {
1349
1356
  );
1350
1357
  } else if (payload.editingIndex > -1) {
1351
1358
  if (this._editingZincObject) {
1352
- this._editingZincObject.editVertices([this.createData.points[1]],
1359
+ let editedPoint = undefined;
1360
+ if (payload.editingIndex > -1) {
1361
+ if (this.createData.faceIndex > -1) {
1362
+ editedPoint = this.createData.points[1];
1363
+ } else {
1364
+ editedPoint = this.createData.points[0];
1365
+ }
1366
+ }
1367
+ this._editingZincObject.editVertices([editedPoint],
1353
1368
  payload.editingIndex);
1354
1369
  const region = this._editingZincObject.region.getFullPath() + "/";
1355
1370
  const group = this._editingZincObject.groupName;
@@ -1371,6 +1386,7 @@ export default {
1371
1386
  * Cancel create workflows. Reset all relevant UIs and data.
1372
1387
  */
1373
1388
  cancelCreate: function() {
1389
+ this.changeActiveByName(undefined);
1374
1390
  this.createData.points.length = 0;
1375
1391
  this.createData.toBeConfirmed = false;
1376
1392
  this._editingZincObject = undefined;
@@ -1611,14 +1627,35 @@ export default {
1611
1627
  }
1612
1628
  }
1613
1629
  },
1614
- createEditTemporaryLines: function(identifiers) {
1630
+ createEditTemporaryPoint: function(identifiers) {
1615
1631
  const worldCoords = identifiers[0].extraData.worldCoords;
1616
1632
  if (worldCoords) {
1617
- if (this.createData.shape === "LineString" || this.createData.editingIndex > -1) {
1618
- if (this.createData.points.length === 1) {
1633
+ if (this.createData.shape === "Point" || this.createData.editingIndex > -1) {
1634
+ if (this.createData.points.length === 0) {
1619
1635
  this.showRegionTooltipWithAnnotations(identifiers, true, false);
1620
1636
  this.tData.x = 50;
1621
1637
  this.tData.y = 200;
1638
+ if (this._tempPoint) {
1639
+ const positionAttribute = this._tempPoint.geometry.getAttribute( 'position' );
1640
+ positionAttribute.setXYZ(0, worldCoords[0], worldCoords[1], worldCoords[2]);
1641
+ positionAttribute.needsUpdate = true;
1642
+ } else {
1643
+ this._tempPoint = this.$module.scene.addTemporaryPoints(
1644
+ [worldCoords], 0x00ffff);
1645
+ }
1646
+ }
1647
+ }
1648
+ }
1649
+ },
1650
+ createEditTemporaryLines: function(identifiers) {
1651
+ const worldCoords = identifiers[0].extraData.worldCoords;
1652
+ if (worldCoords) {
1653
+ if (this.createData.shape === "LineString" ||
1654
+ (this.createData.editingIndex > -1 && this.createData.faceIndex > -1)) {
1655
+ if (this.createData.points.length === 1) {
1656
+ this.showRegionTooltipWithAnnotations(identifiers, true, false);
1657
+ //this.tData.x = 50;
1658
+ //this.tData.y = 200;
1622
1659
  if (this._tempLine) {
1623
1660
  const positionAttribute = this._tempLine.geometry.getAttribute( 'position' );
1624
1661
  positionAttribute.setXYZ(1, worldCoords[0], worldCoords[1], worldCoords[2]);
@@ -1631,14 +1668,26 @@ export default {
1631
1668
  }
1632
1669
  }
1633
1670
  },
1671
+ createEditTemporaryPrimitive: function(identifiers) {
1672
+ if (this.createData.shape === "LineString" ||
1673
+ (this.createData.editingIndex > -1 &&
1674
+ this.createData.faceIndex > -1)) {
1675
+ this.createEditTemporaryLines(identifiers);
1676
+ } else {
1677
+ if (this.createData.shape === "Point" || this.createData.editingIndex > -1) {
1678
+ this.createEditTemporaryPoint(identifiers);
1679
+ }
1680
+ }
1681
+ },
1634
1682
  draw: function(data) {
1635
1683
  if (data && data.length > 0 && data[0].data.group) {
1636
1684
  if (data[0].extraData.worldCoords) {
1637
- if (this.createData.shape === "Point") {
1638
- this.drawPoint(data[0].extraData.worldCoords, data);
1639
- } else if (this.createData.shape === "LineString" ||
1640
- this.createData.editingIndex > -1) {
1685
+ if (this.createData.shape === "LineString" ||
1686
+ (this.createData.editingIndex > -1 && this.createData.faceIndex > -1)) {
1641
1687
  this.drawLine(data[0].extraData.worldCoords, data);
1688
+ } else if (this.createData.shape === "Point" ||
1689
+ (this.createData.editingIndex > -1 && this.createData.faceIndex === -1)) {
1690
+ this.drawPoint(data[0].extraData.worldCoords, data);
1642
1691
  }
1643
1692
  }
1644
1693
  }
@@ -1651,7 +1700,9 @@ export default {
1651
1700
  this.showRegionTooltipWithAnnotations(data, true, false);
1652
1701
  this.tData.x = 50;
1653
1702
  this.tData.y = 200;
1654
- this._tempPoint = this.$module.scene.addTemporaryPoints([coords], 0xffff00);
1703
+ if (!this._tempPoint) {
1704
+ this._tempPoint = this.$module.scene.addTemporaryPoints([coords], 0xffff00);
1705
+ }
1655
1706
  }
1656
1707
  },
1657
1708
  drawLine: function(coords, data) {
@@ -1694,6 +1745,19 @@ export default {
1694
1745
  setTimeout(this.stopFreeSpin, 4000);
1695
1746
  }
1696
1747
  },
1748
+ activateEditingMode: function(eventIdentifiers) {
1749
+ let editing = getEditablePoint(eventIdentifiers);
1750
+ if (editing) {
1751
+ this.activatePointEditingMode(editing.zincObject, editing.index,
1752
+ editing.point);
1753
+ } else {
1754
+ editing = getEditableLines(eventIdentifiers);
1755
+ if (editing) {
1756
+ this.activateLineEditingMode(editing.zincObject, editing.faceIndex,
1757
+ editing.vertexIndex, editing.point);
1758
+ }
1759
+ }
1760
+ },
1697
1761
  activateAnnotationMode: function(names, event) {
1698
1762
  if (this.authorisedUser || this.offlineAnnotationEnabled) {
1699
1763
  this.createData.toBeDeleted = false;
@@ -1709,11 +1773,7 @@ export default {
1709
1773
  } else {
1710
1774
  //Make sure the tooltip is displayed with annotaion mode
1711
1775
  if (this.activeDrawMode === "Edit") {
1712
- const editing = getEditableLines(event);
1713
- if (editing) {
1714
- this.activateEditingMode(editing.zincObject, editing.faceIndex,
1715
- editing.vertexIndex, editing.point);
1716
- }
1776
+ this.activateEditingMode(event.identifiers);
1717
1777
  } else if (this.activeDrawMode === "Delete") {
1718
1778
  const zincObject = getDeletableObjects(event);
1719
1779
  if (zincObject) {
@@ -1731,10 +1791,18 @@ export default {
1731
1791
  this.showRegionTooltipWithAnnotations(event.identifiers, true, true);
1732
1792
  }
1733
1793
  },
1734
- activateEditingMode: function(zincObject, faceIndex, vertexIndex, point) {
1794
+ activatePointEditingMode: function(zincObject, index, point) {
1795
+ this._editingZincObject = zincObject;
1796
+ this.createData.faceIndex = -1;
1797
+ this.createData.editingIndex = index;
1798
+ this.createData.tempGroupName = this._editingZincObject.groupName;
1799
+ //this.drawPoint(point, undefined);
1800
+ },
1801
+ activateLineEditingMode: function(zincObject, faceIndex, vertexIndex, point) {
1735
1802
  this._editingZincObject = zincObject;
1736
1803
  this.createData.faceIndex = faceIndex;
1737
1804
  this.createData.editingIndex = vertexIndex;
1805
+ this.createData.tempGroupName = this._editingZincObject.groupName;
1738
1806
  this.drawLine(point, undefined);
1739
1807
  },
1740
1808
  /**
@@ -1777,7 +1845,9 @@ export default {
1777
1845
  this.tData.label = id;
1778
1846
  this.tData.region = regionPath;
1779
1847
  const zincObject = getClickedObjects(event);
1780
- this._editingZincObject = zincObject;
1848
+ if (this.createData.editingIndex === -1 ) {
1849
+ this._editingZincObject = zincObject;
1850
+ }
1781
1851
  if (zincObject) {
1782
1852
  const regionPath = this._editingZincObject.region.getFullPath() + "/";
1783
1853
  const group = this._editingZincObject.groupName;
@@ -1836,7 +1906,7 @@ export default {
1836
1906
  this.tData.region = regionPath;
1837
1907
  this.tData.x = event.identifiers[0].coords.x;
1838
1908
  this.tData.y = event.identifiers[0].coords.y;
1839
- this.createEditTemporaryLines(event.identifiers);
1909
+ this.createEditTemporaryPrimitive(event.identifiers);
1840
1910
  }
1841
1911
  }
1842
1912
  /**
@@ -1853,7 +1923,7 @@ export default {
1853
1923
  this.tData.x = event.identifiers[0].coords.x - offsets.left;
1854
1924
  this.tData.y = event.identifiers[0].coords.y - offsets.top;
1855
1925
  }
1856
- this.createEditTemporaryLines(event.identifiers);
1926
+ this.createEditTemporaryPrimitive(event.identifiers);
1857
1927
  }
1858
1928
  }
1859
1929
  }
@@ -2070,6 +2140,7 @@ export default {
2070
2140
  this.$module.zincRenderer.removePostRenderCallbackFunction(
2071
2141
  this.$_regionTooltipCallback
2072
2142
  );
2143
+ this.$module.$_regionTooltipCallback = undefined;
2073
2144
  }
2074
2145
  this.$_regionTooltipCallback =
2075
2146
  this.$module.zincRenderer.addPostRenderCallbackFunction(
@@ -2097,6 +2168,7 @@ export default {
2097
2168
  this.$module.zincRenderer.removePostRenderCallbackFunction(
2098
2169
  this.$_liveCoordinatesUpdated
2099
2170
  );
2171
+ this.$_liveCoordinatesUpdated = undefined;
2100
2172
  }
2101
2173
  if (liveUpdates) {
2102
2174
  this.$module.setupLiveCoordinates(objects);
@@ -2168,6 +2240,10 @@ export default {
2168
2240
  showRegionTooltipWithAnnotations: function (annotations, resetView, liveUpdates) {
2169
2241
  if (this.$module.scene) {
2170
2242
  const result = getObjectsFromAnnotations(this.$module.scene, annotations);
2243
+ if (this._editingZincObject) {
2244
+ result.regionPath = this._editingZincObject.region.getFullPath() + "/";
2245
+ result.label = this._editingZincObject.groupName;
2246
+ }
2171
2247
  if (result && result.objects.length > 0) {
2172
2248
  if (!this.annotationSidebar) {
2173
2249
  return this.showRegionTooltipWithObjects(
@@ -2308,6 +2384,7 @@ export default {
2308
2384
  );
2309
2385
  //Unset the tracking
2310
2386
  this.$module.setupLiveCoordinates(undefined);
2387
+ this.$_liveCoordinatesUpdated = undefined;
2311
2388
  }
2312
2389
  this.tData.active = false;
2313
2390
  this.tData.visible = false;
@@ -2568,6 +2645,13 @@ export default {
2568
2645
  }
2569
2646
  }
2570
2647
  },
2648
+ calculateBoundingBox: function() {
2649
+ if (this.isReady) {
2650
+ const {centre, size} = this.$module.getCentreAndSize();
2651
+ this.boundingDims.centre = centre;
2652
+ this.boundingDims.size = size;
2653
+ }
2654
+ },
2571
2655
  downloadErrorCallback: function() {
2572
2656
  return (error) => {
2573
2657
  this.$emit('on-error', error);
@@ -2592,9 +2676,7 @@ export default {
2592
2676
  this._slides = this.$module.scene.addSlicesPrimitive(
2593
2677
  "_helper", ["x-plane", "y-plane", "z-plane"], [0xFF5555, 0x55FF55, 0x5555FF],
2594
2678
  0.5);
2595
- const {centre, size} = this.$module.getCentreAndSize();
2596
- this.boundingDims.centre = centre;
2597
- this.boundingDims.size = size;
2679
+ this.calculateBoundingBox();
2598
2680
  //this.$module.scene.createAxisDisplay(false);
2599
2681
  //this.$module.scene.enableAxisDisplay(true, true);
2600
2682
  this.isReady = true;
@@ -23,7 +23,7 @@
23
23
  <el-slider
24
24
  v-model="slide.value"
25
25
  class="my-slider"
26
- :step="0.01"
26
+ :step="0.005"
27
27
  :min="0"
28
28
  :max="1"
29
29
  :show-tooltip="false"
@@ -19,7 +19,7 @@ const OrgansSceneData = function() {
19
19
  /**
20
20
  * Viewer of 3D-organs models. Users can toggle on/off different views. Data is
21
21
  * displayed instead if models are not available.
22
- *
22
+ *
23
23
  * @class
24
24
  * @param {PJP.ModelsLoader}
25
25
  * ModelsLoaderIn - defined in modelsLoade.js, providing locations of
@@ -49,7 +49,7 @@ const OrgansSceneData = function() {
49
49
  this.isIgnorePicking = function() {
50
50
  return ignorePicking;
51
51
  }
52
-
52
+
53
53
  this.setIgnorePicking = function(value) {
54
54
  ignorePicking = value;
55
55
  }
@@ -74,7 +74,7 @@ const OrgansSceneData = function() {
74
74
  }
75
75
  _this.sceneData.currentTime = value;
76
76
  }
77
-
77
+
78
78
  /**
79
79
  * Update the time slider and other renderers/scenes when time has changed.
80
80
  */
@@ -89,7 +89,7 @@ const OrgansSceneData = function() {
89
89
  if (!_this.sceneData.nerveMapIsActive && pickerScene)
90
90
  pickerScene.setMorphsTime(currentTime);
91
91
  if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
92
- _this.sceneData.nerveMap.additionalReader.setTime(currentTime /
92
+ _this.sceneData.nerveMap.additionalReader.setTime(currentTime /
93
93
  duration);
94
94
  _this.sceneData.currentTime = currentTime / duration * 100.0;
95
95
  }
@@ -132,7 +132,7 @@ const OrgansSceneData = function() {
132
132
  this.NDCCameraControl.setCenterZoom(center, zoom);
133
133
  }
134
134
  }
135
-
135
+
136
136
  const postRenderSelectedCoordinatesUpdate = function() {
137
137
  //It is animating, the coordinates may have been updated
138
138
  if (_this.zincRenderer.playAnimation && _this.liveUpdatesObjects) {
@@ -146,19 +146,19 @@ const OrgansSceneData = function() {
146
146
  _this.selectedScreenCoordinates.y = coord.y;
147
147
  }
148
148
  }
149
-
149
+
150
150
  const preRenderUpdateCallback = function() {
151
151
  return function() {
152
152
  preRenderTimeUpdate();
153
153
  }
154
154
  }
155
-
155
+
156
156
  const postRenderUpdateCallback = function() {
157
157
  return function() {
158
158
  postRenderSelectedCoordinatesUpdate();
159
159
  }
160
160
  }
161
-
161
+
162
162
  /**
163
163
  * Add a callback which will be called when time has changed
164
164
  */
@@ -166,7 +166,7 @@ const OrgansSceneData = function() {
166
166
  if (typeof(callback === "function"))
167
167
  timeChangedCallbacks.push(callback);
168
168
  }
169
-
169
+
170
170
  this.setTexturePos = function(value) {
171
171
  if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
172
172
  _this.sceneData.nerveMap.additionalReader.setSliderPos(value);
@@ -177,7 +177,7 @@ const OrgansSceneData = function() {
177
177
  sceneChangedCallbacks.push(callback);
178
178
  }
179
179
  }
180
-
180
+
181
181
  this.addOrganPartAddedCallback = function(callback) {
182
182
  if (typeof(callback === "function"))
183
183
  organPartAddedCallbacks.push(callback);
@@ -223,7 +223,7 @@ const OrgansSceneData = function() {
223
223
  let intersectedObject = undefined;
224
224
  if (intersected !== undefined) {
225
225
  let marker = false;
226
- if (intersected.object.userData &&
226
+ if (intersected.object.userData &&
227
227
  intersected.object.userData.isMarker) {
228
228
  marker = true;
229
229
  intersectedObject = intersected.object.userData.parent.getMorph();
@@ -247,12 +247,12 @@ const OrgansSceneData = function() {
247
247
  }
248
248
  return {"id":id, "object":intersectedObject};
249
249
  }
250
-
250
+
251
251
  /**
252
252
  * Callback function when a pickable object has been picked. It will then
253
253
  * call functions in tissueViewer and cellPanel to show corresponding
254
254
  * informations.
255
- *
255
+ *
256
256
  * @callback
257
257
  */
258
258
  const _pickingCallback = function() {
@@ -271,7 +271,7 @@ const OrgansSceneData = function() {
271
271
  const coords = { x: window_x, y: window_y };
272
272
  if (idObject.id) {
273
273
  extraData.threeID = idObject.object?.id;
274
- if (idObject.object.userData.isGlyph) {
274
+ if (idObject.object.userData.isGlyph) {
275
275
  if (idObject.object.name) {
276
276
  _this.setSelectedByObjects([idObject.object], coords,
277
277
  extraData, true);
@@ -289,10 +289,10 @@ const OrgansSceneData = function() {
289
289
  }
290
290
  }
291
291
  };
292
-
292
+
293
293
  /**
294
294
  * Callback function when a pickable object has been hovered over.
295
- *
295
+ *
296
296
  * @callback
297
297
  */
298
298
  const _hoverCallback = function() {
@@ -382,7 +382,7 @@ const OrgansSceneData = function() {
382
382
  if (pickerScene)
383
383
  changeOrganPartsVisibilityForScene(pickerScene, name, value, 'pointsets');
384
384
  }
385
-
385
+
386
386
  /**
387
387
  * Change visibility for parts of the current scene.
388
388
  */
@@ -394,13 +394,13 @@ const OrgansSceneData = function() {
394
394
  if (pickerScene)
395
395
  changeOrganPartsVisibilityForScene(pickerScene, name, value, type);
396
396
  }
397
-
397
+
398
398
  this.changeOrganPartsVisibilityCallback = function(name) {
399
399
  return function(value) {
400
400
  _this.changeOrganPartsVisibility(name, value);
401
401
  }
402
402
  }
403
-
403
+
404
404
  this.changeBackgroundColour = function(backgroundColourString) {
405
405
  const colour = new THREE.Color(backgroundColourString);
406
406
  if (_this.zincRenderer) {
@@ -447,7 +447,7 @@ const OrgansSceneData = function() {
447
447
  removeOrganPart(systemName, partName, useDefautColour, zincObject);
448
448
  }
449
449
  }
450
-
450
+
451
451
  const downloadCompletedCallback = function() {
452
452
  return function() {
453
453
  _this.settingsChanged();
@@ -459,7 +459,7 @@ const OrgansSceneData = function() {
459
459
 
460
460
  //The payload can either be a zinc object when the loading is successful or
461
461
  //an object containg the details of error message on failure.
462
- //We only use it to handle an error
462
+ //We only use it to handle an error
463
463
  const singleItemFinishCallback = function() {
464
464
  return function(payload) {
465
465
 
@@ -474,7 +474,7 @@ const OrgansSceneData = function() {
474
474
  }
475
475
  }
476
476
  }
477
-
477
+
478
478
  /**
479
479
  * Toggle data field displays. Data fields displays flow/pressure and <button @click="play">Play</button>
480
480
  * other activities of the organs.
@@ -499,11 +499,11 @@ const OrgansSceneData = function() {
499
499
  }
500
500
  }
501
501
  }
502
-
502
+
503
503
  /**
504
504
  * Return an array containing name(s) of species that also contains the
505
505
  * currently displayed organs.
506
- *
506
+ *
507
507
  * @returns {Array} containing species name
508
508
  */
509
509
  this.getAvailableSpecies = function(currentSpecies, currentSystem, currentPart) {
@@ -534,7 +534,7 @@ const OrgansSceneData = function() {
534
534
  const size = [vector.x, vector.y, vector.z];
535
535
  return {centre, size};
536
536
  }
537
-
537
+
538
538
  const setSceneData = function(speciesName, systemName, partName, organsDetails) {
539
539
  _this.sceneData.nerveMapIsActive = false;
540
540
  _this.sceneData.nerveMap = undefined;
@@ -623,14 +623,14 @@ const OrgansSceneData = function() {
623
623
  }
624
624
  }
625
625
  }
626
-
626
+
627
627
  this.alignCameraWithSelectedObject = function(transitionTime) {
628
628
  const objects = _this.graphicsHighlight.getSelected();
629
629
  if (objects && objects[0] && objects[0].userData) {
630
630
  _this.scene.alignObjectToCameraView(objects[0].userData, transitionTime);
631
631
  }
632
632
  }
633
-
633
+
634
634
  this.exportSettings = function() {
635
635
  const settings = {};
636
636
  settings.name = _this.instanceName;
@@ -646,7 +646,7 @@ const OrgansSceneData = function() {
646
646
  settings.dialog = "Organ Viewer";
647
647
  return settings;
648
648
  }
649
-
649
+
650
650
  this.importSettings = function(settings) {
651
651
  if (settings && (settings.dialog == this.typeName)) {
652
652
  _this.setName(settings.name);
@@ -660,11 +660,11 @@ const OrgansSceneData = function() {
660
660
  }
661
661
  return false;
662
662
  }
663
-
663
+
664
664
  /**
665
665
  * initialise loading of the html layout for the organs panel, this is
666
666
  * called when the {@link PJP.OrgansViewer} is created.
667
- *
667
+ *
668
668
  * @async
669
669
  */
670
670
  const initialise = function() {
@@ -674,7 +674,7 @@ const OrgansSceneData = function() {
674
674
  _this.zincRenderer.addPostRenderCallbackFunction(postRenderUpdateCallback());
675
675
  }
676
676
  }
677
-
677
+
678
678
  initialise();
679
679
 
680
680
  }
@@ -33,15 +33,31 @@ const getDistance = (point1, point2) => {
33
33
  return Math.sqrt(dist0 * dist0 + dist1 * dist1 + dist2 * dist2);
34
34
  }
35
35
 
36
- export const getEditableLines = (event) => {
37
- const zincObjects = event.zincObjects;
38
- if (zincObjects.length > 0 && zincObjects[0]) {
39
- const zincObject = zincObjects[0];
36
+ export const getEditablePoint = (eventIdentifiers) => {
37
+ //const zincObjects = event.zincObjects;
38
+ const zincObject = eventIdentifiers[0].data?.zincObject;
39
+ if (zincObject) {
40
+ if (zincObject.isEditable && zincObject.isPointset) {
41
+ const info = eventIdentifiers[0].extraData.intersected;
42
+ if (info && info.index > -1) {
43
+ const v = zincObject.getVerticesByIndex(info.index);
44
+ if (v) {
45
+ return { zincObject, index: info.index, point: v};
46
+ }
47
+ }
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+
53
+ export const getEditableLines = (eventIdentifiers) => {
54
+ const zincObject = eventIdentifiers[0].data?.zincObject;
55
+ if (zincObject) {
40
56
  if (zincObject.isEditable && zincObject.isLines2) {
41
- const info = event.identifiers[0].extraData.intersected;
57
+ const info = eventIdentifiers[0].extraData.intersected;
42
58
  if (info && info.faceIndex > -1) {
43
59
  const v = zincObject.getVerticesByFaceIndex(info.faceIndex);
44
- const p = event.identifiers[0].extraData.intersected.pointOnLine;
60
+ const p = eventIdentifiers[0].extraData.intersected.pointOnLine;
45
61
  if (v.length > 1) {
46
62
  const dist0 = getDistance(v[0], [p.x, p.y, p.z]);
47
63
  const dist1 = getDistance(v[1], [p.x, p.y, p.z]);
@@ -111,7 +127,7 @@ export const getLineDistance = (zincObject, faceIndex) => {
111
127
  }
112
128
  return 0;
113
129
  }
114
-
130
+
115
131
  //Move or extend a line
116
132
  export const moveAndExtendLine = (zincObject, faceIndex, unit, extendOnly) => {
117
133
  if (zincObject && unit !== 0.0) {
@@ -218,7 +234,7 @@ export const convertUUIDsToFullPaths = (rootRegion, IDs) => {
218
234
  let region = undefined;
219
235
  let primitive = undefined;
220
236
  let regionID = undefined;
221
-
237
+
222
238
  IDs.forEach(id => {
223
239
  const uuids = id.split("/");
224
240
  regionID = uuids[0];