@abi-software/scaffoldvuer 1.21.1-beta.2 → 2.0.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.
Files changed (45) hide show
  1. package/README.md +31 -12
  2. package/dist/index.html +9 -6
  3. package/dist/scaffoldvuer.js +14095 -13154
  4. package/dist/scaffoldvuer.umd.cjs +48 -48
  5. package/dist/style.css +1 -1
  6. package/eslint.config.js +37 -9
  7. package/package.json +10 -3
  8. package/public/index.html +9 -6
  9. package/src/App.vue +312 -279
  10. package/src/ScaffoldVuer-wc.js +4 -4
  11. package/src/app/DropZone.vue +11 -27
  12. package/src/app/ModelsInformation.js +22 -19
  13. package/src/app/ModelsTable.vue +42 -65
  14. package/src/app/TextureDemos.js +38 -64
  15. package/src/assets/_variables.scss +12 -10
  16. package/src/components/GlyphsControls.vue +3 -23
  17. package/src/components/LinesControls.vue +27 -66
  18. package/src/components/OpacityControls.vue +22 -26
  19. package/src/components/PointsControls.vue +20 -71
  20. package/src/components/PrimitiveControls.vue +35 -49
  21. package/src/components/ScaffoldOverlay.vue +63 -63
  22. package/src/components/ScaffoldTooltip.vue +36 -49
  23. package/src/components/ScaffoldTreeControls.vue +81 -129
  24. package/src/components/ScaffoldVuer.vue +509 -498
  25. package/src/components/TextureSlidesControls.vue +22 -64
  26. package/src/components/TransformationControls.vue +15 -42
  27. package/src/components/index.js +2 -2
  28. package/src/main.js +16 -18
  29. package/src/scripts/Annotation.js +3 -3
  30. package/src/scripts/BaseModule.js +26 -30
  31. package/src/scripts/EventNotifier.js +30 -36
  32. package/src/scripts/GraphicsHighlight.js +43 -50
  33. package/src/scripts/LocalFilesHelper.js +27 -26
  34. package/src/scripts/MappedNerves.js +2139 -697
  35. package/src/scripts/MappedOrgans.js +24 -25
  36. package/src/scripts/OrgansRenderer.js +445 -425
  37. package/src/scripts/RendererModule.js +133 -122
  38. package/src/scripts/Search.js +135 -151
  39. package/src/scripts/Utilities.js +129 -127
  40. package/src/scripts/WebGL.js +57 -91
  41. package/src/scripts/niftiHelper.js +3 -3
  42. package/src/store/index.js +7 -7
  43. package/vite.config.js +51 -50
  44. package/vite.static-build.js +7 -7
  45. package/vuese-generator.js +48 -56
@@ -5,16 +5,16 @@ import Annotation from './Annotation.js';
5
5
  // Current model's associate data, data fields, external link, nerve map
6
6
  // informations,
7
7
  // these are proived in the organsFileMap array.
8
- const OrgansSceneData = function() {
9
- this.currentName = "";
10
- this.currentSystem = "";
11
- this.currentPart = "";
12
- this.currentSpecies = "";
13
- this.metaURL = "";
14
- this.viewURL = "";
8
+ const OrgansSceneData = function () {
9
+ this.currentName = '';
10
+ this.currentSystem = '';
11
+ this.currentPart = '';
12
+ this.currentSpecies = '';
13
+ this.metaURL = '';
14
+ this.viewURL = '';
15
15
  this.timeVarying = false;
16
- this.currentTime = 0.0;
17
- }
16
+ this.currentTime = 0.0;
17
+ };
18
18
 
19
19
  /**
20
20
  * Viewer of 3D-organs models. Users can toggle on/off different views. Data is
@@ -30,73 +30,68 @@ const OrgansSceneData = function() {
30
30
  * @author Alan Wu
31
31
  * @returns {PJP.OrgansViewer}
32
32
  */
33
- const OrgansViewer = function(ModelsLoaderIn) {
33
+ const OrgansViewer = function (ModelsLoaderIn) {
34
34
  RendererModule.call(this);
35
35
  const _this = this;
36
- let pickerScene = undefined;
37
- this.sceneData = new OrgansSceneData();
38
- const timeChangedCallbacks = new Array();
39
- const sceneChangedCallbacks = new Array();
36
+ let pickerScene = undefined;
37
+ this.sceneData = new OrgansSceneData();
38
+ const timeChangedCallbacks = new Array();
39
+ const sceneChangedCallbacks = new Array();
40
40
  const organPartAddedCallbacks = new Array();
41
- const organPartRemovedCallbacks = new Array();
41
+ const organPartRemovedCallbacks = new Array();
42
42
  let finishDownloadCallback = undefined;
43
- let downloadErrorCallback = undefined;
44
- const modelsLoader = ModelsLoaderIn;
43
+ let downloadErrorCallback = undefined;
44
+ const modelsLoader = ModelsLoaderIn;
45
+ const organsFileMap = modelsLoader?.organsFileMap ?? {};
45
46
  this.NDCCameraControl = undefined;
46
- _this.typeName = "Organ Viewer";
47
- let ignorePicking = false;
47
+ _this.typeName = 'Organ Viewer';
48
+ let ignorePicking = false;
48
49
 
49
- this.isIgnorePicking = function() {
50
- return ignorePicking;
51
- }
50
+ this.isIgnorePicking = function () {
51
+ return ignorePicking;
52
+ };
52
53
 
53
- this.setIgnorePicking = function(value) {
54
- ignorePicking = value;
55
- }
54
+ this.setIgnorePicking = function (value) {
55
+ ignorePicking = value;
56
+ };
56
57
 
57
- this.getSceneData = function() {
58
- return _this.sceneData;
59
- }
58
+ this.getSceneData = function () {
59
+ return _this.sceneData;
60
+ };
60
61
 
61
- /**
62
- * Used to update internal timer in scene when time slider has changed.
63
- */
64
- this.updateTime = function(value) {
62
+ /**
63
+ * Used to update internal timer in scene when time slider has changed.
64
+ */
65
+ this.updateTime = function (value) {
65
66
  let duration = 6000;
66
- if (_this.scene)
67
- duration = _this.scene.getDuration();
68
- const actualTime = value / 100.0 * duration;
69
- if (!_this.sceneData.nerveMapIsActive) {
70
- if (pickerScene)
71
- pickerScene.setMorphsTime(actualTime);
72
- if (_this.scene)
73
- _this.scene.setMorphsTime(actualTime);
74
- }
75
- _this.sceneData.currentTime = value;
76
- }
77
-
78
- /**
79
- * Update the time slider and other renderers/scenes when time has changed.
80
- */
81
- const preRenderTimeUpdate = function() {
67
+ if (_this.scene) duration = _this.scene.getDuration();
68
+ const actualTime = (value / 100.0) * duration;
69
+ if (!_this.sceneData.nerveMapIsActive) {
70
+ if (pickerScene) pickerScene.setMorphsTime(actualTime);
71
+ if (_this.scene) _this.scene.setMorphsTime(actualTime);
72
+ }
73
+ _this.sceneData.currentTime = value;
74
+ };
75
+
76
+ /**
77
+ * Update the time slider and other renderers/scenes when time has changed.
78
+ */
79
+ const preRenderTimeUpdate = function () {
82
80
  let duration = 3000;
83
- if (_this.scene)
84
- duration = _this.scene.getDuration();
81
+ if (_this.scene) duration = _this.scene.getDuration();
85
82
  const currentTime = _this.zincRenderer.getCurrentTime();
86
- for (let i = 0; i < timeChangedCallbacks.length;i++) {
87
- timeChangedCallbacks[i](currentTime);
88
- }
89
- if (!_this.sceneData.nerveMapIsActive && pickerScene)
90
- pickerScene.setMorphsTime(currentTime);
91
- if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
92
- _this.sceneData.nerveMap.additionalReader.setTime(currentTime /
93
- duration);
94
- _this.sceneData.currentTime = currentTime / duration * 100.0;
95
- }
96
-
97
- this.getCurrentTime = function() {
98
- return _this.sceneData.currentTime;
99
- }
83
+ for (let i = 0; i < timeChangedCallbacks.length; i++) {
84
+ timeChangedCallbacks[i](currentTime);
85
+ }
86
+ if (!_this.sceneData.nerveMapIsActive && pickerScene) pickerScene.setMorphsTime(currentTime);
87
+ if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
88
+ _this.sceneData.nerveMap.additionalReader.setTime(currentTime / duration);
89
+ _this.sceneData.currentTime = (currentTime / duration) * 100.0;
90
+ };
91
+
92
+ this.getCurrentTime = function () {
93
+ return _this.sceneData.currentTime;
94
+ };
100
95
 
101
96
  this.toggleSyncControl = (flag, rotateMode) => {
102
97
  let cameraControl = this.scene.getZincCameraControls();
@@ -107,33 +102,33 @@ const OrgansSceneData = function() {
107
102
  } else {
108
103
  cameraControl.disableSyncControl();
109
104
  this.NDCCameraControl = undefined;
110
- cameraControl.setRotationMode("free");
105
+ cameraControl.setRotationMode('free');
111
106
  }
112
- }
107
+ };
113
108
 
114
109
  this.isSyncControl = () => {
115
110
  return this.NDCCameraControl !== undefined;
116
- }
111
+ };
117
112
 
118
113
  this.setSyncControlZoomToBox = (box) => {
119
114
  if (this.NDCCameraControl) {
120
115
  this.NDCCameraControl.zoomToBox(box, 2);
121
116
  }
122
- }
117
+ };
123
118
 
124
119
  this.setSyncControlCallback = (callback) => {
125
120
  if (this.NDCCameraControl) {
126
121
  this.NDCCameraControl.setEventCallback(callback);
127
122
  }
128
- }
123
+ };
129
124
 
130
125
  this.setSyncControlCenterZoom = (center, zoom) => {
131
126
  if (this.NDCCameraControl) {
132
127
  this.NDCCameraControl.setCenterZoom(center, zoom);
133
128
  }
134
- }
129
+ };
135
130
 
136
- const postRenderSelectedCoordinatesUpdate = function() {
131
+ const postRenderSelectedCoordinatesUpdate = function () {
137
132
  //It is animating, the coordinates may have been updated
138
133
  if (_this.zincRenderer.playAnimation && _this.liveUpdatesObjects) {
139
134
  _this.setupLiveCoordinates(_this.liveUpdatesObjects);
@@ -145,339 +140,350 @@ const OrgansSceneData = function() {
145
140
  _this.selectedScreenCoordinates.x = coord.x;
146
141
  _this.selectedScreenCoordinates.y = coord.y;
147
142
  }
148
- }
143
+ };
149
144
 
150
- const preRenderUpdateCallback = function() {
145
+ const preRenderUpdateCallback = function () {
151
146
  preRenderTimeUpdate();
152
- }
147
+ };
153
148
 
154
- const postRenderUpdateCallback = function() {
149
+ const postRenderUpdateCallback = function () {
155
150
  postRenderSelectedCoordinatesUpdate();
156
- }
157
-
158
- /**
159
- * Add a callback which will be called when time has changed
160
- */
161
- this.addTimeChangedCallback = function(callback) {
162
- if (typeof(callback === "function"))
163
- timeChangedCallbacks.push(callback);
164
- }
165
-
166
- this.setTexturePos = function(value) {
167
- if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
168
- _this.sceneData.nerveMap.additionalReader.setSliderPos(value);
169
- }
170
-
171
- this.addSceneChangedCallback = function(callback) {
172
- if (typeof(callback === "function")) {
173
- sceneChangedCallbacks.push(callback);
174
- }
175
- }
176
-
177
- this.addOrganPartAddedCallback = function(callback) {
178
- if (typeof(callback === "function"))
179
- organPartAddedCallbacks.push(callback);
180
- }
181
-
182
- this.addOrganPartRemovedCallback = function(callback) {
183
- if (typeof(callback === "function"))
184
- organPartRemovedCallbacks.push(callback);
185
- }
186
-
187
- this.setFinishDownloadCallback = function(callback) {
188
- if (typeof(callback === "function"))
189
- finishDownloadCallback = callback;
190
- }
191
-
192
- this.unsetFinishDownloadCallback = function() {
193
- finishDownloadCallback = undefined;
194
- }
151
+ };
195
152
 
153
+ /**
154
+ * Add a callback which will be called when time has changed
155
+ */
156
+ this.addTimeChangedCallback = function (callback) {
157
+ if (typeof callback === 'function') timeChangedCallbacks.push(callback);
158
+ };
159
+
160
+ this.setTexturePos = function (value) {
161
+ if (_this.sceneData.nerveMap && _this.sceneData.nerveMap.additionalReader)
162
+ _this.sceneData.nerveMap.additionalReader.setSliderPos(value);
163
+ };
164
+
165
+ this.addSceneChangedCallback = function (callback) {
166
+ if (typeof callback === 'function') {
167
+ sceneChangedCallbacks.push(callback);
168
+ }
169
+ };
196
170
 
197
- this.setDownloadErrorCallback = function(callback) {
198
- if (typeof(callback === "function"))
199
- downloadErrorCallback = callback;
200
- }
171
+ this.addOrganPartAddedCallback = function (callback) {
172
+ if (typeof callback === 'function') organPartAddedCallbacks.push(callback);
173
+ };
201
174
 
202
- this.unsetDownloadErrorCallback = function() {
175
+ this.addOrganPartRemovedCallback = function (callback) {
176
+ if (typeof callback === 'function') organPartRemovedCallbacks.push(callback);
177
+ };
178
+
179
+ this.setFinishDownloadCallback = function (callback) {
180
+ if (typeof callback === 'function') finishDownloadCallback = callback;
181
+ };
182
+
183
+ this.unsetFinishDownloadCallback = function () {
184
+ finishDownloadCallback = undefined;
185
+ };
186
+
187
+ this.setDownloadErrorCallback = function (callback) {
188
+ if (typeof callback === 'function') downloadErrorCallback = callback;
189
+ };
190
+
191
+ this.unsetDownloadErrorCallback = function () {
203
192
  downloadErrorCallback = undefined;
204
- }
193
+ };
205
194
 
206
- this.getNamedObjectsToScreenCoordinates = function(name, camera) {
195
+ this.getNamedObjectsToScreenCoordinates = function (name, camera) {
207
196
  const vector = new THREE.Vector3();
208
- vector.setFromMatrixPosition( obj.matrixWorld );
209
- const widthHalf = (width/2);
210
- const heightHalf = (height/2);
197
+ if (!_this.scene || !camera) {
198
+ return vector;
199
+ }
200
+ const zincObject =
201
+ _this.scene.findGeometriesWithGroupName(name)[0] ||
202
+ _this.scene.findGlyphsetsWithGroupName(name)[0] ||
203
+ _this.scene.findPointsetsWithGroupName(name)[0] ||
204
+ _this.scene.findLinesWithGroupName(name)[0];
205
+ const obj = zincObject?.getMorph?.() || zincObject?.morph;
206
+ if (!obj) {
207
+ return vector;
208
+ }
209
+ const renderer = _this.zincRenderer?.getThreeJSRenderer();
210
+ const width = renderer?.domElement?.clientWidth ?? _this.displayArea?.clientWidth ?? 0;
211
+ const height = renderer?.domElement?.clientHeight ?? _this.displayArea?.clientHeight ?? 0;
212
+ vector.setFromMatrixPosition(obj.matrixWorld);
213
+ const widthHalf = width / 2;
214
+ const heightHalf = height / 2;
211
215
  vector.project(camera);
212
- vector.x = ( vector.x * widthHalf ) + widthHalf;
213
- vector.y = - ( vector.y * heightHalf ) + heightHalf;
216
+ vector.x = vector.x * widthHalf + widthHalf;
217
+ vector.y = -(vector.y * heightHalf) + heightHalf;
214
218
  return vector;
215
- }
219
+ };
216
220
 
217
- const getIdObjectFromIntersect = function(intersected) {
221
+ const getIdObjectFromIntersect = function (intersected) {
218
222
  let id = undefined;
219
223
  let intersectedObject = undefined;
220
224
  if (intersected !== undefined) {
221
225
  let marker = false;
222
- if (intersected.object.userData &&
223
- intersected.object.userData.isMarker) {
226
+ if (intersected.object.userData && intersected.object.userData.isMarker) {
224
227
  marker = true;
225
228
  intersectedObject = intersected.object.userData.parent.getMorph();
226
229
  } else {
227
230
  intersectedObject = intersected.object;
228
231
  }
229
- try {
232
+ if (intersectedObject?.userData?.userData?.annotation?.data) {
230
233
  intersectedObject.userData.userData.annotation.data.lastActionOnMarker = marker;
231
- } finally { }
234
+ }
232
235
  if (intersectedObject) {
233
236
  if (intersectedObject.name) {
234
237
  id = intersectedObject.name;
235
238
  } else {
236
- const annotations = _this.getAnnotationsFromObjects(
237
- [intersectedObject], undefined);
239
+ const annotations = _this.getAnnotationsFromObjects([intersectedObject], undefined);
238
240
  if (annotations && annotations[0]) {
239
241
  id = annotations[0].data.group;
240
242
  }
241
243
  }
242
244
  }
243
245
  }
244
- return {"id":id, "object":intersectedObject};
245
- }
246
-
247
- /**
248
- * Callback function when a pickable object has been picked. It will then
249
- * call functions in tissueViewer and cellPanel to show corresponding
250
- * informations.
251
- *
252
- * @callback
253
- */
254
- const _pickingCallback = function() {
255
- return function(intersects, window_x, window_y) {
246
+ return { id: id, object: intersectedObject };
247
+ };
248
+
249
+ /**
250
+ * Callback function when a pickable object has been picked. It will then
251
+ * call functions in tissueViewer and cellPanel to show corresponding
252
+ * informations.
253
+ *
254
+ * @callback
255
+ */
256
+ const _pickingCallback = function () {
257
+ return function (intersects, window_x, window_y) {
256
258
  const intersected = _this.getIntersectedObject(intersects);
257
259
  const idObject = getIdObjectFromIntersect(intersected);
258
- const extraData = {
259
- worldCoords: [
260
- intersected ? intersected.point.x : 0,
261
- intersected ? intersected.point.y : 0,
262
- intersected ? intersected.point.z : 0,
263
- ],
264
- intersected: intersected,
265
- intersects: intersects,
260
+ const extraData = {
261
+ worldCoords: [
262
+ intersected ? intersected.point.x : 0,
263
+ intersected ? intersected.point.y : 0,
264
+ intersected ? intersected.point.z : 0,
265
+ ],
266
+ intersected: intersected,
267
+ intersects: intersects,
266
268
  instanceId: intersected?.instanceId ? intersected.instanceId : -1,
267
- };
269
+ };
268
270
  const coords = { x: window_x, y: window_y };
269
271
  if (idObject.id) {
270
- extraData.threeID = idObject.object?.id;
272
+ extraData.threeID = idObject.object?.id;
271
273
  if (idObject.object.userData.isGlyph) {
272
274
  if (idObject.object.name) {
273
- _this.setSelectedByObjects([idObject.object], coords,
274
- extraData, true);
275
- } else {
276
- _this.setSelectedByZincObjects(idObject.object.userData.getGlyphset(),
277
- coords, extraData, true);
278
- }
275
+ _this.setSelectedByObjects([idObject.object], coords, extraData, true);
276
+ } else {
277
+ _this.setSelectedByZincObjects(
278
+ idObject.object.userData.getGlyphset(),
279
+ coords,
280
+ extraData,
281
+ true,
282
+ );
283
+ }
279
284
  } else {
280
285
  _this.setSelectedByObjects([idObject.object], coords, extraData, true);
281
286
  }
282
287
  return;
283
288
  } else {
284
- if (ignorePicking) return;
285
- _this.setSelectedByObjects([], coords, extraData, true);
286
- }
287
- }
288
- };
289
-
290
- /**
291
- * Callback function when a pickable object has been hovered over.
292
- *
293
- * @callback
294
- */
295
- const _hoverCallback = function() {
296
- return function(intersects, window_x, window_y) {
289
+ if (ignorePicking) return;
290
+ _this.setSelectedByObjects([], coords, extraData, true);
291
+ }
292
+ };
293
+ };
294
+
295
+ /**
296
+ * Callback function when a pickable object has been hovered over.
297
+ *
298
+ * @callback
299
+ */
300
+ const _hoverCallback = function () {
301
+ return function (intersects, window_x, window_y) {
297
302
  const intersected = _this.getIntersectedObject(intersects);
298
303
  const idObject = getIdObjectFromIntersect(intersected);
299
- const extraData = {
300
- worldCoords: [
301
- intersected ? intersected.point.x : 0,
302
- intersected ? intersected.point.y : 0,
303
- intersected ? intersected.point.z : 0,
304
- ],
304
+ const extraData = {
305
+ worldCoords: [
306
+ intersected ? intersected.point.x : 0,
307
+ intersected ? intersected.point.y : 0,
308
+ intersected ? intersected.point.z : 0,
309
+ ],
305
310
  instanceId: intersected?.instanceId ? intersected.instanceId : -1,
306
- }
311
+ };
307
312
  const coords = { x: window_x, y: window_y };
308
313
  if (idObject.id) {
309
- extraData.threeID = idObject.object?.id;
310
- _this.displayArea.style.cursor = "pointer";
314
+ extraData.threeID = idObject.object?.id;
315
+ _this.displayArea.style.cursor = 'pointer';
311
316
  _this.setHighlightedByObjects([idObject.object], coords, extraData, true);
312
317
  return;
318
+ } else {
319
+ _this.displayArea.style.cursor = 'auto';
320
+ _this.setHighlightedByObjects([], coords, extraData, true);
321
+ }
322
+ };
323
+ };
324
+
325
+ const changeOrganPartsVisibilityForScene = function (scene, name, value, type) {
326
+ if (type == 'all' || type == 'geometries') {
327
+ const geometries = scene.findGeometriesWithGroupName(name);
328
+ for (let i = 0; i < geometries.length; i++) {
329
+ geometries[i].setVisibility(value);
330
+ }
331
+ }
332
+ if (type == 'all' || type == 'glyphsets') {
333
+ const glyphsets = scene.findGlyphsetsWithGroupName(name);
334
+ for (let i = 0; i < glyphsets.length; i++) {
335
+ glyphsets[i].setVisibility(value);
336
+ }
337
+ }
338
+ if (type == 'all' || type == 'pointsets') {
339
+ const pointsets = scene.findPointsetsWithGroupName(name);
340
+ for (let i = 0; i < pointsets.length; i++) {
341
+ pointsets[i].setVisibility(value);
313
342
  }
314
- else {
315
- _this.displayArea.style.cursor = "auto";
316
- _this.setHighlightedByObjects([], coords, extraData, true);
343
+ }
344
+ if (type == 'all' || type == 'lines') {
345
+ const lines = scene.findLinesWithGroupName(name);
346
+ for (let i = 0; i < lines.length; i++) {
347
+ lines[i].setVisibility(value);
317
348
  }
318
- }
319
- };
320
-
321
- const changeOrganPartsVisibilityForScene = function(scene, name, value, type) {
322
- if (type == "all" || type == "geometries") {
323
- const geometries = scene.findGeometriesWithGroupName(name);
324
- for (let i = 0; i < geometries.length; i ++ ) {
325
- geometries[i].setVisibility(value);
326
- }
327
- }
328
- if (type == "all" || type == "glyphsets") {
329
- const glyphsets = scene.findGlyphsetsWithGroupName(name);
330
- for (let i = 0; i < glyphsets.length; i ++ ) {
331
- glyphsets[i].setVisibility(value);
332
- }
333
- }
334
- if (type == "all" || type == "pointsets") {
335
- const pointsets = scene.findPointsetsWithGroupName(name);
336
- for (let i = 0; i < pointsets.length; i ++ ) {
337
- pointsets[i].setVisibility(value);
338
- }
339
- }
340
- if (type == "all" || type == "lines") {
341
- const lines = scene.findLinesWithGroupName(name);
342
- for (let i = 0; i < lines.length; i ++ ) {
343
- lines[i].setVisibility(value);
344
- }
345
- }
346
- }
347
-
348
- /**
349
- * Change visibility for parts of the current scene.
350
- */
351
- this.changeGeometriesVisibility = function(name, value) {
352
- changeOrganPartsVisibilityForScene(_this.scene, name, value, 'geometries');
353
- if (pickerScene)
354
- changeOrganPartsVisibilityForScene(pickerScene, name, value, 'geometries');
355
- }
356
-
357
- /**
358
- * Change visibility for parts of the current scene.
359
- */
360
- this.changeGlyphsetsVisibility = function(name, value) {
361
- changeOrganPartsVisibilityForScene(_this.scene, name, value, 'glyphsets');
362
- if (pickerScene)
363
- changeOrganPartsVisibilityForScene(pickerScene, name, value, 'glyphsets');
364
- }
365
-
366
- /**
367
- * Change visibility for parts of the current scene.
368
- */
369
- this.changeLinesVisibility = function(name, value) {
370
- changeOrganPartsVisibilityForScene(_this.scene, name, value, 'lines');
371
- if (pickerScene)
372
- changeOrganPartsVisibilityForScene(pickerScene, name, value, 'lines');
373
- }
374
-
375
- /**
376
- * Change visibility for parts of the current scene.
377
- */
378
- this.changePointsetsVisibility = function(name, value) {
379
- changeOrganPartsVisibilityForScene(_this.scene, name, value, 'pointsets');
380
- if (pickerScene)
381
- changeOrganPartsVisibilityForScene(pickerScene, name, value, 'pointsets');
382
- }
383
-
384
- /**
385
- * Change visibility for parts of the current scene.
386
- */
387
- this.changeOrganPartsVisibility = function(name, value, typeIn) {
388
- let type = "all";
389
- if (typeIn !== undefined)
390
- type = typeIn;
391
- changeOrganPartsVisibilityForScene(_this.scene, name, value, type);
392
- if (pickerScene)
393
- changeOrganPartsVisibilityForScene(pickerScene, name, value, type);
394
- }
395
-
396
- this.changeOrganPartsVisibilityCallback = function(name) {
397
- return function(value) {
398
- _this.changeOrganPartsVisibility(name, value);
399
- }
400
- }
401
-
402
- this.changeBackgroundColour = function(backgroundColourString) {
403
- const colour = new THREE.Color(backgroundColourString);
404
- if (_this.zincRenderer) {
405
- const internalRenderer = _this.zincRenderer.getThreeJSRenderer();
406
- internalRenderer.setClearColor( colour, 1 );
407
- }
408
- }
409
-
410
- const addOrganPart = function(systemName, partName, useDefautColour, zincObject) {
411
- for (let i = 0; i < organPartAddedCallbacks.length;i++) {
349
+ }
350
+ };
351
+
352
+ /**
353
+ * Change visibility for parts of the current scene.
354
+ */
355
+ this.changeGeometriesVisibility = function (name, value) {
356
+ changeOrganPartsVisibilityForScene(_this.scene, name, value, 'geometries');
357
+ if (pickerScene) changeOrganPartsVisibilityForScene(pickerScene, name, value, 'geometries');
358
+ };
359
+
360
+ /**
361
+ * Change visibility for parts of the current scene.
362
+ */
363
+ this.changeGlyphsetsVisibility = function (name, value) {
364
+ changeOrganPartsVisibilityForScene(_this.scene, name, value, 'glyphsets');
365
+ if (pickerScene) changeOrganPartsVisibilityForScene(pickerScene, name, value, 'glyphsets');
366
+ };
367
+
368
+ /**
369
+ * Change visibility for parts of the current scene.
370
+ */
371
+ this.changeLinesVisibility = function (name, value) {
372
+ changeOrganPartsVisibilityForScene(_this.scene, name, value, 'lines');
373
+ if (pickerScene) changeOrganPartsVisibilityForScene(pickerScene, name, value, 'lines');
374
+ };
375
+
376
+ /**
377
+ * Change visibility for parts of the current scene.
378
+ */
379
+ this.changePointsetsVisibility = function (name, value) {
380
+ changeOrganPartsVisibilityForScene(_this.scene, name, value, 'pointsets');
381
+ if (pickerScene) changeOrganPartsVisibilityForScene(pickerScene, name, value, 'pointsets');
382
+ };
383
+
384
+ /**
385
+ * Change visibility for parts of the current scene.
386
+ */
387
+ this.changeOrganPartsVisibility = function (name, value, typeIn) {
388
+ let type = 'all';
389
+ if (typeIn !== undefined) type = typeIn;
390
+ changeOrganPartsVisibilityForScene(_this.scene, name, value, type);
391
+ if (pickerScene) changeOrganPartsVisibilityForScene(pickerScene, name, value, type);
392
+ };
393
+
394
+ this.changeOrganPartsVisibilityCallback = function (name) {
395
+ return function (value) {
396
+ _this.changeOrganPartsVisibility(name, value);
397
+ };
398
+ };
399
+
400
+ this.changeBackgroundColour = function (backgroundColourString) {
401
+ const colour = new THREE.Color(backgroundColourString);
402
+ if (_this.zincRenderer) {
403
+ const internalRenderer = _this.zincRenderer.getThreeJSRenderer();
404
+ internalRenderer.setClearColor(colour, 1);
405
+ }
406
+ };
407
+
408
+ const addOrganPart = function (systemName, partName, useDefautColour, zincObject) {
409
+ for (let i = 0; i < organPartAddedCallbacks.length; i++) {
412
410
  organPartAddedCallbacks[i](zincObject, _this.scene.isTimeVarying());
413
411
  }
414
- if (useDefautColour)
415
- modelsLoader.setGeometryColour(zincObject, systemName, partName);
416
- const annotation = new Annotation();
412
+ if (useDefautColour) modelsLoader.setGeometryColour(zincObject, systemName, partName);
413
+ const annotation = new Annotation();
417
414
  const region = zincObject.region.getFullPath();
418
- annotation.data = {species:_this.sceneData.currentSpecies, system:systemName,
419
- part:partName, group:zincObject.groupName, region: region, uuid:zincObject.uuid,
420
- lastActionOnMarker: false};
421
- zincObject.userData["annotation"] = annotation;
422
- }
423
-
424
- const removeOrganPart = function(systemName, partName, useDefautColour, zincObject) {
425
- for (let i = 0; i < organPartRemovedCallbacks.length;i++) {
415
+ annotation.data = {
416
+ species: _this.sceneData.currentSpecies,
417
+ system: systemName,
418
+ part: partName,
419
+ group: zincObject.groupName,
420
+ region: region,
421
+ uuid: zincObject.uuid,
422
+ lastActionOnMarker: false,
423
+ };
424
+ zincObject.userData['annotation'] = annotation;
425
+ };
426
+
427
+ const removeOrganPart = function (systemName, partName, useDefautColour, zincObject) {
428
+ for (let i = 0; i < organPartRemovedCallbacks.length; i++) {
426
429
  organPartRemovedCallbacks[i](zincObject);
427
430
  }
428
- }
431
+ };
429
432
 
430
433
  /**
431
434
  * New organs geometry has been added to the scene, add UIs and make
432
435
  * sure the viewport is correct.
433
436
  */
434
- const _addOrganPartCallback = function(systemName, partName, useDefautColour) {
435
- return function(zincObject) {
437
+ const _addOrganPartCallback = function (systemName, partName, useDefautColour) {
438
+ return function (zincObject) {
436
439
  addOrganPart(systemName, partName, useDefautColour, zincObject);
437
- }
438
- }
440
+ };
441
+ };
439
442
 
440
443
  /**
441
444
  * Organs geometry has been removed to the scene.
442
445
  */
443
- const _removeOrganPartCallback = function(systemName, partName, useDefautColour) {
444
- return function(zincObject) {
446
+ const _removeOrganPartCallback = function (systemName, partName, useDefautColour) {
447
+ return function (zincObject) {
445
448
  removeOrganPart(systemName, partName, useDefautColour, zincObject);
446
- }
447
- }
449
+ };
450
+ };
448
451
 
449
- const downloadCompletedCallback = function() {
450
- return function() {
452
+ const downloadCompletedCallback = function () {
453
+ return function () {
451
454
  _this.settingsChanged();
452
455
  _this.sceneData.timeVarying = _this.scene.isTimeVarying();
453
- if (finishDownloadCallback)
454
- finishDownloadCallback();
455
- }
456
- }
456
+ if (finishDownloadCallback) finishDownloadCallback();
457
+ };
458
+ };
457
459
 
458
460
  //The payload can either be a zinc object when the loading is successful or
459
461
  //an object containg the details of error message on failure.
460
462
  //We only use it to handle an error
461
- const singleItemFinishCallback = function() {
462
- return function(payload) {
463
- if (payload?.type === "Error") {
463
+ const singleItemFinishCallback = function () {
464
+ return function (payload) {
465
+ if (payload?.type === 'Error') {
464
466
  if (downloadErrorCallback) {
465
467
  const error = {
466
468
  xhr: payload.xhr,
467
- type: "download-error",
469
+ type: 'download-error',
468
470
  };
469
471
  downloadErrorCallback(error);
470
472
  }
471
473
  }
472
- }
473
- }
474
+ };
475
+ };
476
+
477
+ const getOrganDetails = function (systemName, partName) {
478
+ return organsFileMap[_this.sceneData.currentSpecies]?.[systemName]?.[partName];
479
+ };
474
480
 
475
481
  /**
476
482
  * Toggle data field displays. Data fields displays flow/pressure and <button @click="play">Play</button>
477
483
  * other activities of the organs.
478
484
  */
479
- this.updateFieldvisibility = function(dataFields, value) {
480
- for ( let i = 0; i < dataFields.length; i ++ ) {
485
+ this.updateFieldvisibility = function (dataFields, value) {
486
+ for (let i = 0; i < dataFields.length; i++) {
481
487
  if (value != i) {
482
488
  const geometryName = dataFields[i].PartName;
483
489
  _this.changeOrganPartsVisibility(geometryName, false);
@@ -485,17 +491,21 @@ const OrgansSceneData = function() {
485
491
  }
486
492
  if (value > -1) {
487
493
  const partName = dataFields[value].PartName;
488
- if ((_this.scene.findGeometriesWithGroupName(partName).length > 0) ||
489
- (_this.scene.findGlyphsetsWithGroupName(partName).length > 0)) {
494
+ if (
495
+ _this.scene.findGeometriesWithGroupName(partName).length > 0 ||
496
+ _this.scene.findGlyphsetsWithGroupName(partName).length > 0
497
+ ) {
490
498
  _this.changeOrganPartsVisibility(partName, true);
491
499
  } else {
492
500
  const partDetails = getOrganDetails(dataFields[value].SystemName, partName);
493
501
  if (partDetails != undefined) {
494
- _this.scene.loadMetadataURL(modelsLoader.getOrgansDirectoryPrefix() + "/" + partDetails.meta);
502
+ _this.scene.loadMetadataURL(
503
+ modelsLoader.getOrgansDirectoryPrefix() + '/' + partDetails.meta,
504
+ );
495
505
  }
496
506
  }
497
507
  }
498
- }
508
+ };
499
509
 
500
510
  /**
501
511
  * Return an array containing name(s) of species that also contains the
@@ -503,152 +513,162 @@ const OrgansSceneData = function() {
503
513
  *
504
514
  * @returns {Array} containing species name
505
515
  */
506
- this.getAvailableSpecies = function(currentSpecies, currentSystem, currentPart) {
516
+ this.getAvailableSpecies = function (currentSpecies, currentSystem, currentPart) {
507
517
  const availableSpecies = new Array();
508
- availableSpecies.push("none");
518
+ availableSpecies.push('none');
509
519
  const keysArray = Object.keys(organsFileMap);
510
- for (index in keysArray) {
511
- const species = keysArray[index];
520
+ for (const species of keysArray) {
512
521
  if (species != currentSpecies) {
513
- if (organsFileMap[species].hasOwnProperty(currentSystem) &&
514
- organsFileMap[species][currentSystem].hasOwnProperty(currentPart)) {
522
+ if (
523
+ Object.hasOwn(organsFileMap[species], currentSystem) &&
524
+ Object.hasOwn(organsFileMap[species][currentSystem], currentPart)
525
+ ) {
515
526
  availableSpecies.push(species);
516
527
  }
517
528
  }
518
529
  }
519
530
  return availableSpecies;
520
- }
531
+ };
521
532
 
522
533
  /**
523
534
  * Return the center and size of the cuurrent viewing scene
524
535
  */
525
- this.getCentreAndSize = function() {
536
+ this.getCentreAndSize = function () {
526
537
  const vector = new THREE.Vector3();
527
538
  const boundingBox = this.scene.getBoundingBox();
528
539
  boundingBox.getCenter(vector);
529
540
  const centre = [vector.x, vector.y, vector.z];
530
541
  boundingBox.getSize(vector);
531
542
  const size = [vector.x, vector.y, vector.z];
532
- return {centre, size};
533
- }
543
+ return { centre, size };
544
+ };
534
545
 
535
- const setSceneData = function(speciesName, systemName, partName, organsDetails) {
546
+ const setSceneData = function (speciesName, systemName, partName) {
536
547
  _this.sceneData.nerveMapIsActive = false;
537
548
  _this.sceneData.nerveMap = undefined;
538
- _this.sceneData.metaURL = "";
539
- _this.sceneData.viewURL = "";
549
+ _this.sceneData.metaURL = '';
550
+ _this.sceneData.viewURL = '';
540
551
  _this.sceneData.currentSpecies = speciesName;
541
552
  _this.sceneData.currentSystem = systemName;
542
553
  _this.sceneData.currentPart = partName;
543
554
  _this.sceneData.currentTime = 0.0;
544
555
  _this.sceneData.timeVarying = false;
545
556
  // This is used as title
546
- let name = "";
547
- if (speciesName)
548
- name = speciesName + "/";
549
- if (systemName)
550
- name = systemName + "/";
551
- if (partName)
552
- name = partName;
557
+ let name = '';
558
+ if (speciesName) name = speciesName + '/';
559
+ if (systemName) name = systemName + '/';
560
+ if (partName) name = partName;
553
561
  _this.sceneData.currentName = name;
554
- }
555
-
556
- this.loadOrgansFromURL = function(url, speciesName, systemName, partName, viewURL, clearFirst, options) {
562
+ };
563
+
564
+ this.loadOrgansFromURL = function (
565
+ url,
566
+ speciesName,
567
+ systemName,
568
+ partName,
569
+ viewURL,
570
+ clearFirst,
571
+ options,
572
+ ) {
557
573
  if (_this.zincRenderer) {
558
- if (partName && (_this.sceneData.metaURL !== url)) {
559
- setSceneData(speciesName, systemName, partName, undefined);
560
- const name = _this.sceneData.currentName;
561
- let organScene = _this.zincRenderer.getSceneByName(name);
562
- if (organScene) {
563
- if (clearFirst)
564
- organScene.clearAll();
565
- } else {
566
- organScene = _this.zincRenderer.createScene(name);
567
- }
568
- _this.selectObjectOnPick = true;
569
- for (let i = 0; i < sceneChangedCallbacks.length;i++) {
570
- sceneChangedCallbacks[i](_this.sceneData);
571
- }
572
- if (viewURL && viewURL != "") {
573
- _this.sceneData.viewURL = viewURL;
574
- organScene.loadViewURL(_this.sceneData.viewURL);
575
- } else {
576
- _this.sceneData.viewURL = undefined;
577
- }
578
- _this.sceneData.metaURL = url;
579
- organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
580
- organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
581
- organScene.loadMetadataURL(url, singleItemFinishCallback(), downloadCompletedCallback(), options);
582
- _this.scene = organScene;
583
- _this.zincRenderer.setCurrentScene(organScene);
584
- _this.graphicsHighlight.reset();
585
- const zincCameraControl = organScene.getZincCameraControls();
586
- zincCameraControl.enableRaycaster(organScene, _pickingCallback(), _hoverCallback());
587
- zincCameraControl.setMouseButtonAction("AUXILIARY", "ZOOM");
588
- zincCameraControl.setMouseButtonAction("SECONDARY", "PAN");
574
+ if (partName && _this.sceneData.metaURL !== url) {
575
+ setSceneData(speciesName, systemName, partName);
576
+ const name = _this.sceneData.currentName;
577
+ let organScene = _this.zincRenderer.getSceneByName(name);
578
+ if (organScene) {
579
+ if (clearFirst) organScene.clearAll();
580
+ } else {
581
+ organScene = _this.zincRenderer.createScene(name);
582
+ }
583
+ _this.selectObjectOnPick = true;
584
+ for (let i = 0; i < sceneChangedCallbacks.length; i++) {
585
+ sceneChangedCallbacks[i](_this.sceneData);
586
+ }
587
+ if (viewURL && viewURL != '') {
588
+ _this.sceneData.viewURL = viewURL;
589
+ organScene.loadViewURL(_this.sceneData.viewURL);
590
+ } else {
591
+ _this.sceneData.viewURL = undefined;
592
+ }
593
+ _this.sceneData.metaURL = url;
594
+ organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
595
+ organScene.addZincObjectRemovedCallbacks(
596
+ _removeOrganPartCallback(undefined, partName, false),
597
+ );
598
+ organScene.loadMetadataURL(
599
+ url,
600
+ singleItemFinishCallback(),
601
+ downloadCompletedCallback(),
602
+ options,
603
+ );
604
+ _this.scene = organScene;
605
+ _this.zincRenderer.setCurrentScene(organScene);
606
+ _this.graphicsHighlight.reset();
607
+ const zincCameraControl = organScene.getZincCameraControls();
608
+ zincCameraControl.enableRaycaster(organScene, _pickingCallback(), _hoverCallback());
609
+ zincCameraControl.setMouseButtonAction('AUXILIARY', 'ZOOM');
610
+ zincCameraControl.setMouseButtonAction('SECONDARY', 'PAN');
589
611
  }
590
612
  }
591
- }
613
+ };
592
614
 
593
- this.loadGLTFFromURL = function(url, partName, clearFirst) {
615
+ this.loadGLTFFromURL = function (url, partName, clearFirst) {
594
616
  if (_this.zincRenderer) {
595
- if (partName && (_this.sceneData.metaURL !== url)) {
596
- setSceneData(undefined, undefined, partName, undefined);
597
- const name = _this.sceneData.currentName;
598
- let organScene = _this.zincRenderer.getSceneByName(name);
599
- if (organScene) {
600
- if (clearFirst)
601
- organScene.clearAll();
602
- } else {
603
- organScene = _this.zincRenderer.createScene(name);
604
- }
605
- for (let i = 0; i < sceneChangedCallbacks.length;i++) {
606
- sceneChangedCallbacks[i](_this.sceneData);
607
- }
608
- _this.sceneData.viewURL = undefined;
609
- _this.sceneData.metaURL = url;
610
- organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(undefined, partName, false));
611
- organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
612
- organScene.loadGLTF(url, undefined, downloadCompletedCallback());
613
- _this.scene = organScene;
614
- _this.zincRenderer.setCurrentScene(organScene);
615
- _this.graphicsHighlight.reset();
616
- const zincCameraControl = organScene.getZincCameraControls();
617
- zincCameraControl.enableRaycaster(organScene, _pickingCallback(), _hoverCallback());
618
- zincCameraControl.setMouseButtonAction("AUXILIARY", "ZOOM");
619
- zincCameraControl.setMouseButtonAction("SECONDARY", "PAN");
617
+ if (partName && _this.sceneData.metaURL !== url) {
618
+ setSceneData(undefined, undefined, partName);
619
+ const name = _this.sceneData.currentName;
620
+ let organScene = _this.zincRenderer.getSceneByName(name);
621
+ if (organScene) {
622
+ if (clearFirst) organScene.clearAll();
623
+ } else {
624
+ organScene = _this.zincRenderer.createScene(name);
625
+ }
626
+ for (let i = 0; i < sceneChangedCallbacks.length; i++) {
627
+ sceneChangedCallbacks[i](_this.sceneData);
628
+ }
629
+ _this.sceneData.viewURL = undefined;
630
+ _this.sceneData.metaURL = url;
631
+ organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(undefined, partName, false));
632
+ organScene.addZincObjectRemovedCallbacks(
633
+ _removeOrganPartCallback(undefined, partName, false),
634
+ );
635
+ organScene.loadGLTF(url, undefined, downloadCompletedCallback());
636
+ _this.scene = organScene;
637
+ _this.zincRenderer.setCurrentScene(organScene);
638
+ _this.graphicsHighlight.reset();
639
+ const zincCameraControl = organScene.getZincCameraControls();
640
+ zincCameraControl.enableRaycaster(organScene, _pickingCallback(), _hoverCallback());
641
+ zincCameraControl.setMouseButtonAction('AUXILIARY', 'ZOOM');
642
+ zincCameraControl.setMouseButtonAction('SECONDARY', 'PAN');
620
643
  }
621
644
  }
622
- }
645
+ };
623
646
 
624
- this.alignCameraWithSelectedObject = function(transitionTime) {
647
+ this.alignCameraWithSelectedObject = function (transitionTime) {
625
648
  const objects = _this.graphicsHighlight.getSelected();
626
649
  if (objects && objects[0] && objects[0].userData) {
627
650
  _this.scene.alignObjectToCameraView(objects[0].userData, transitionTime);
628
651
  }
629
- }
630
-
631
- /**
632
- * initialise loading of the html layout for the organs panel, this is
633
- * called when the {@link PJP.OrgansViewer} is created.
634
- *
635
- * @async
636
- */
637
- this.initialise = async function(displayAreaIn) {
638
- await _this.initialiseRenderer(displayAreaIn);
639
- if (_this.zincRenderer) {
640
- _this.zincRenderer.addPreRenderCallbackFunction(() => {
641
- preRenderUpdateCallback();
642
- });
643
- _this.zincRenderer.addPostRenderCallbackFunction(() => {
644
- postRenderUpdateCallback()
645
- });
646
- }
647
- }
652
+ };
648
653
 
649
- }
654
+ /**
655
+ * initialise loading of the html layout for the organs panel, this is
656
+ * called when the {@link PJP.OrgansViewer} is created.
657
+ *
658
+ * @async
659
+ */
660
+ this.initialise = async function (displayAreaIn) {
661
+ await _this.initialiseRenderer(displayAreaIn);
662
+ if (_this.zincRenderer) {
663
+ _this.zincRenderer.addPreRenderCallbackFunction(() => {
664
+ preRenderUpdateCallback();
665
+ });
666
+ _this.zincRenderer.addPostRenderCallbackFunction(() => {
667
+ postRenderUpdateCallback();
668
+ });
669
+ }
670
+ };
671
+ };
650
672
 
651
673
  OrgansViewer.prototype = Object.create(RendererModule.prototype);
652
- export {
653
- OrgansViewer
654
- }
674
+ export { OrgansViewer };