@abi-software/scaffoldvuer 1.11.0-demo.2 → 1.11.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.
- package/dist/scaffoldvuer.js +9673 -9311
- package/dist/scaffoldvuer.umd.cjs +173 -173
- package/dist/style.css +1 -1
- package/mapped_fma_nerves.json +10914 -0
- package/nerve_mapping.js +10917 -0
- package/package.json +3 -3
- package/src/App.vue +5 -1
- package/src/components/LinesControls.vue +105 -27
- package/src/components/PrimitiveControls.vue +19 -2
- package/src/components/ScaffoldTreeControls.vue +21 -5
- package/src/components/ScaffoldVuer.vue +122 -69
- package/src/scripts/GraphicsHighlight.js +38 -3
- package/src/scripts/MappedNerves.js +0 -1
- package/src/scripts/MappedOrgans.js +50 -0
- package/src/scripts/OrgansRenderer.js +12 -2
- package/src/scripts/RendererModule.js +3 -20
- package/src/scripts/Utilities.js +27 -0
- package/vite.web-component.js +36 -0
|
@@ -104,15 +104,15 @@
|
|
|
104
104
|
@object-selected="objectSelected"
|
|
105
105
|
@object-hovered="objectHovered"
|
|
106
106
|
@drawer-toggled="drawerToggled"
|
|
107
|
-
@checked-regions="setCheckedRegions"
|
|
108
107
|
/>
|
|
109
108
|
</template>
|
|
110
109
|
</el-popover>
|
|
111
110
|
<div class="primitive-controls-box">
|
|
112
111
|
<primitive-controls
|
|
113
|
-
v-if="viewingMode === 'Exploration'"
|
|
114
112
|
ref="primitiveControls"
|
|
115
113
|
:createData="createData"
|
|
114
|
+
:viewingMode="viewingMode"
|
|
115
|
+
:usageConfig="usageConfig"
|
|
116
116
|
@primitivesUpdated="primitivesUpdated"
|
|
117
117
|
/>
|
|
118
118
|
</div>
|
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
ref="backgroundPopover"
|
|
291
291
|
:virtual-ref="backgroundIconRef"
|
|
292
292
|
placement="top-start"
|
|
293
|
-
width="
|
|
293
|
+
width="320"
|
|
294
294
|
:teleported="false"
|
|
295
295
|
trigger="click"
|
|
296
296
|
popper-class="background-popper non-selectable h-auto"
|
|
@@ -457,12 +457,21 @@ import { AnnotationService } from '@abi-software/sparc-annotation';
|
|
|
457
457
|
import { EventNotifier } from "../scripts/EventNotifier.js";
|
|
458
458
|
import { OrgansViewer } from "../scripts/OrgansRenderer.js";
|
|
459
459
|
import { SearchIndex } from "../scripts/Search.js";
|
|
460
|
-
import { mapState } from 'pinia';
|
|
460
|
+
import { mapState, mapStores } from 'pinia';
|
|
461
461
|
import { useMainStore } from "@/store/index";
|
|
462
462
|
import { getNerveMaps } from "../scripts/MappedNerves.js";
|
|
463
|
+
import { getOrganMaps } from '../scripts/MappedOrgans.js';
|
|
463
464
|
const nervesMap = getNerveMaps();
|
|
465
|
+
const organsMap = getOrganMaps();
|
|
464
466
|
let totalNerves = 0, foundNerves = 0;
|
|
465
467
|
|
|
468
|
+
const haveSameElements = (arr1, arr2) => {
|
|
469
|
+
if (arr1.length !== arr2.length) return false;
|
|
470
|
+
return arr1.sort().every((value, index) => {
|
|
471
|
+
return value === arr2.sort()[index]
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
466
475
|
/**
|
|
467
476
|
* A vue component of the scaffold viewer.
|
|
468
477
|
*
|
|
@@ -762,6 +771,16 @@ export default {
|
|
|
762
771
|
type: Boolean,
|
|
763
772
|
default: true,
|
|
764
773
|
},
|
|
774
|
+
/**
|
|
775
|
+
* Manage the settings when used in standalone or as child component.
|
|
776
|
+
*/
|
|
777
|
+
usageConfig: {
|
|
778
|
+
type: Object,
|
|
779
|
+
default: {
|
|
780
|
+
showTubeLinesControls: true,
|
|
781
|
+
tubeLines: false,
|
|
782
|
+
},
|
|
783
|
+
},
|
|
765
784
|
},
|
|
766
785
|
provide() {
|
|
767
786
|
return {
|
|
@@ -864,6 +883,7 @@ export default {
|
|
|
864
883
|
viewingMode: "Exploration",
|
|
865
884
|
viewingModes: {
|
|
866
885
|
"Exploration": "View and explore detailed visualization of 3D scaffolds",
|
|
886
|
+
"Neuron Connection": "Discover nerve connections by selecting a nerve and viewing its associated connections",
|
|
867
887
|
"Annotation": ['View feature annotations', 'Add, comment on and view feature annotations'],
|
|
868
888
|
},
|
|
869
889
|
openMapRef: undefined,
|
|
@@ -890,7 +910,7 @@ export default {
|
|
|
890
910
|
group: "",
|
|
891
911
|
isSearch: false,
|
|
892
912
|
}),
|
|
893
|
-
checkedRegions: []
|
|
913
|
+
//checkedRegions: []
|
|
894
914
|
};
|
|
895
915
|
},
|
|
896
916
|
watch: {
|
|
@@ -1018,6 +1038,7 @@ export default {
|
|
|
1018
1038
|
this.$module = undefined;
|
|
1019
1039
|
},
|
|
1020
1040
|
computed: {
|
|
1041
|
+
...mapStores(useMainStore),
|
|
1021
1042
|
...mapState(useMainStore, ['userToken']),
|
|
1022
1043
|
annotationDisplay: function() {
|
|
1023
1044
|
return this.viewingMode === 'Annotation' && this.tData.active === true &&
|
|
@@ -1038,42 +1059,34 @@ export default {
|
|
|
1038
1059
|
},
|
|
1039
1060
|
},
|
|
1040
1061
|
methods: {
|
|
1062
|
+
/*
|
|
1041
1063
|
setCheckedRegions: function (data) {
|
|
1042
1064
|
this.checkedRegions = data;
|
|
1043
1065
|
},
|
|
1066
|
+
*/
|
|
1067
|
+
/**
|
|
1068
|
+
*
|
|
1069
|
+
* @param nerves array of nerve names, show all nerves if empty
|
|
1070
|
+
* @param processed boolean, whether unselect all checkboxes
|
|
1071
|
+
*/
|
|
1044
1072
|
zoomToNerves: function (nerves, processed = false) {
|
|
1045
1073
|
if (this.$module.scene) {
|
|
1046
|
-
|
|
1074
|
+
this.$module.setIgnorePicking(processed);
|
|
1075
|
+
const nervesList = [];
|
|
1047
1076
|
const regions = this.$module.scene.getRootRegion().getChildRegions();
|
|
1048
1077
|
regions.forEach((region) => {
|
|
1049
1078
|
const regionName = region.getName();
|
|
1050
|
-
if (
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
object.setVisibility(true);
|
|
1057
|
-
return `${object.region.uuid}/${object.uuid}`;
|
|
1058
|
-
});
|
|
1059
|
-
acc.push(...ids);
|
|
1060
|
-
return acc;
|
|
1061
|
-
}, []);
|
|
1062
|
-
idsList.push(...ids)
|
|
1063
|
-
}
|
|
1064
|
-
} else {
|
|
1065
|
-
// if the checkboxes are checked previously, restore them
|
|
1066
|
-
const isChecked = this.checkedRegions.find(item => item.label === regionName);
|
|
1067
|
-
if (isChecked) {
|
|
1068
|
-
region.showAllPrimitives();
|
|
1069
|
-
const zincObjects = region.getAllObjects();
|
|
1070
|
-
const ids = zincObjects.map(object => object.region.uuid);
|
|
1071
|
-
idsList.push(...ids);
|
|
1079
|
+
if (regionName === 'Nerves') {
|
|
1080
|
+
if (processed) {
|
|
1081
|
+
nerves.forEach((nerve) => {
|
|
1082
|
+
const primitives = this.findObjectsWithGroupName(nerve);
|
|
1083
|
+
nervesList.push(...primitives);
|
|
1084
|
+
});
|
|
1072
1085
|
}
|
|
1073
1086
|
}
|
|
1074
1087
|
});
|
|
1075
|
-
this.
|
|
1076
|
-
this.$
|
|
1088
|
+
this.$module.setSelectedByZincObjects(nervesList, undefined, {}, true);
|
|
1089
|
+
this.$module.scene.viewAll();
|
|
1077
1090
|
}
|
|
1078
1091
|
},
|
|
1079
1092
|
enableAxisDisplay: function (enable, miniaxes) {
|
|
@@ -1108,25 +1121,27 @@ export default {
|
|
|
1108
1121
|
if (this.timeVarying === false && zincObject.isTimeVarying()) {
|
|
1109
1122
|
this.timeVarying = true;
|
|
1110
1123
|
}
|
|
1124
|
+
const groupName = zincObject.groupName.toLowerCase();
|
|
1125
|
+
if (groupName in organsMap) {
|
|
1126
|
+
zincObject.setAnatomicalId(organsMap[groupName]);
|
|
1127
|
+
}
|
|
1111
1128
|
//Temporary way to mark an object as nerves
|
|
1112
1129
|
const regions = this.isNerves?.regions;
|
|
1113
1130
|
if (regions) {
|
|
1114
1131
|
const regionPath = zincObject.getRegion().getFullPath().toLowerCase();
|
|
1115
1132
|
for (let i = 0; i < regions.length; i++) {
|
|
1116
1133
|
if (regionPath.includes(regions[i].toLowerCase())) {
|
|
1117
|
-
totalNerves++;
|
|
1118
1134
|
zincObject.userData.isNerves = true;
|
|
1119
|
-
|
|
1135
|
+
zincObject.userData.defaultColour = `#${zincObject.getColourHex()}`;
|
|
1136
|
+
zincObject.userData.isGreyScale = false;
|
|
1120
1137
|
if (groupName in nervesMap) {
|
|
1121
1138
|
foundNerves++;
|
|
1122
1139
|
zincObject.setAnatomicalId(nervesMap[groupName]);
|
|
1123
|
-
console.log(groupName, zincObject.anatomicalId, zincObject.uuid)
|
|
1124
1140
|
}
|
|
1125
1141
|
} else {
|
|
1126
1142
|
zincObject.userData.isNerves = false;
|
|
1127
1143
|
}
|
|
1128
1144
|
}
|
|
1129
|
-
|
|
1130
1145
|
}
|
|
1131
1146
|
/**
|
|
1132
1147
|
* Emit when a new object is added to the scene
|
|
@@ -1734,16 +1749,21 @@ export default {
|
|
|
1734
1749
|
this.$refs.scaffoldTreeControls.removeActive(false);
|
|
1735
1750
|
}
|
|
1736
1751
|
}
|
|
1752
|
+
|
|
1737
1753
|
//Store the following for state saving. Search will handle the case with more than 1
|
|
1738
1754
|
//identifiers.
|
|
1739
1755
|
if (event.identifiers.length === 1) {
|
|
1740
|
-
this.lastSelected
|
|
1741
|
-
|
|
1742
|
-
|
|
1756
|
+
this.lastSelected = {
|
|
1757
|
+
isSearch: false,
|
|
1758
|
+
region: regionPath,
|
|
1759
|
+
group: event.identifiers[0].data.group,
|
|
1760
|
+
}
|
|
1743
1761
|
} else if (event.identifiers.length === 0) {
|
|
1744
|
-
this.lastSelected
|
|
1745
|
-
|
|
1746
|
-
|
|
1762
|
+
this.lastSelected = {
|
|
1763
|
+
isSearch: false,
|
|
1764
|
+
region: "",
|
|
1765
|
+
group: "",
|
|
1766
|
+
}
|
|
1747
1767
|
}
|
|
1748
1768
|
/**
|
|
1749
1769
|
* Emit when an object is selected
|
|
@@ -1830,7 +1850,7 @@ export default {
|
|
|
1830
1850
|
* @arg objects objects to be set for the selected
|
|
1831
1851
|
*/
|
|
1832
1852
|
updatePrimitiveControls: function (objects) {
|
|
1833
|
-
if (this.viewingMode === 'Exploration') {
|
|
1853
|
+
if (this.viewingMode === 'Exploration' || this.viewingMode === 'Annotation') {
|
|
1834
1854
|
this.selectedObjects = objects;
|
|
1835
1855
|
if (this.selectedObjects && this.selectedObjects.length > 0) {
|
|
1836
1856
|
this.$refs.primitiveControls.setObject(this.selectedObjects[0]);
|
|
@@ -1847,6 +1867,7 @@ export default {
|
|
|
1847
1867
|
* is made
|
|
1848
1868
|
*/
|
|
1849
1869
|
objectSelected: function (objects, propagate) {
|
|
1870
|
+
if (this.$module.isIgnorePicking()) return;
|
|
1850
1871
|
this.updatePrimitiveControls(objects);
|
|
1851
1872
|
this.$module.setSelectedByZincObjects(objects, undefined, {}, propagate);
|
|
1852
1873
|
},
|
|
@@ -2178,6 +2199,7 @@ export default {
|
|
|
2178
2199
|
* Optional, can be used to update the view mode.
|
|
2179
2200
|
*/
|
|
2180
2201
|
changeViewingMode: function (modeName) {
|
|
2202
|
+
let objectIsPickable = true;
|
|
2181
2203
|
if (this.$module) {
|
|
2182
2204
|
if (modeName) {
|
|
2183
2205
|
this.viewingMode = modeName;
|
|
@@ -2197,14 +2219,16 @@ export default {
|
|
|
2197
2219
|
this.addAnnotationFeature();
|
|
2198
2220
|
this.loading = false;
|
|
2199
2221
|
});
|
|
2200
|
-
} else {
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2222
|
+
} else if (this.viewingMode === "Exploration") {
|
|
2223
|
+
this.activeDrawTool = undefined;
|
|
2224
|
+
this.activeDrawMode = undefined;
|
|
2225
|
+
this.createData.shape = "";
|
|
2226
|
+
} else if (this.viewingMode === "Neuron Connection") {
|
|
2227
|
+
// enable to make organs and nerves clickable and searchable for neuron connection mode
|
|
2228
|
+
objectIsPickable = false;
|
|
2206
2229
|
}
|
|
2207
2230
|
if ((this.viewingMode === "Exploration") ||
|
|
2231
|
+
(this.viewingMode === "Neuron Connection") ||
|
|
2208
2232
|
(this.viewingMode === "Annotation") &&
|
|
2209
2233
|
(this.createData.shape === "")) {
|
|
2210
2234
|
this.$module.selectObjectOnPick = true;
|
|
@@ -2212,6 +2236,9 @@ export default {
|
|
|
2212
2236
|
this.$module.selectObjectOnPick = false;
|
|
2213
2237
|
}
|
|
2214
2238
|
this.cancelCreate();
|
|
2239
|
+
if (modeName) {
|
|
2240
|
+
this.setObjectIsPickable(objectIsPickable);
|
|
2241
|
+
}
|
|
2215
2242
|
}
|
|
2216
2243
|
},
|
|
2217
2244
|
/**
|
|
@@ -2237,20 +2264,36 @@ export default {
|
|
|
2237
2264
|
this.tData.region = undefined;
|
|
2238
2265
|
},
|
|
2239
2266
|
/**
|
|
2240
|
-
*
|
|
2267
|
+
* Currently will apply to non-nerve object and object without anatomical id
|
|
2268
|
+
* @param flag boolean to control whether objects pickable
|
|
2269
|
+
*/
|
|
2270
|
+
setObjectIsPickable: function (flag) {
|
|
2271
|
+
const objects = this.$module.scene.getRootRegion().getAllObjects(true);
|
|
2272
|
+
objects.forEach((zincObject) => {
|
|
2273
|
+
if (!zincObject.userData?.isNerves && !zincObject.anatomicalId) {
|
|
2274
|
+
zincObject.setIsPickable(flag);
|
|
2275
|
+
}
|
|
2276
|
+
});
|
|
2277
|
+
},
|
|
2278
|
+
/**
|
|
2279
|
+
* Update objects to greyscale or colour.
|
|
2280
|
+
* This will update all objects except those with the provided nerves labels.
|
|
2241
2281
|
* @param flag boolean
|
|
2242
|
-
* @param
|
|
2282
|
+
* @param labels array of nerve names that exclude from greyscale
|
|
2243
2283
|
*/
|
|
2244
|
-
setGreyScale: function (flag,
|
|
2284
|
+
setGreyScale: function (flag, labels = []) {
|
|
2245
2285
|
const objects = this.$module.scene.getRootRegion().getAllObjects(true);
|
|
2246
2286
|
objects.forEach((zincObject) => {
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2287
|
+
const groupName = zincObject.groupName.toLowerCase();
|
|
2288
|
+
const isNerves = zincObject.userData?.isNerves;
|
|
2289
|
+
|
|
2290
|
+
const shouldUpdate =
|
|
2291
|
+
(labels.length > 0 && isNerves && !labels.includes(groupName)) ||
|
|
2292
|
+
(labels.length === 0 && !isNerves);
|
|
2293
|
+
|
|
2294
|
+
if (shouldUpdate) {
|
|
2295
|
+
zincObject.setGreyScale(flag);
|
|
2296
|
+
zincObject.userData.isGreyScale = flag;
|
|
2254
2297
|
}
|
|
2255
2298
|
});
|
|
2256
2299
|
this.$refs.scaffoldTreeControls.updateAllNodeColours();
|
|
@@ -2263,7 +2306,7 @@ export default {
|
|
|
2263
2306
|
*/
|
|
2264
2307
|
setColour: function (flag, forced = false) {
|
|
2265
2308
|
if (this.isReady && this.$module.scene &&
|
|
2266
|
-
typeof flag === "boolean" &&
|
|
2309
|
+
typeof flag === "boolean" &&
|
|
2267
2310
|
(forced || flag !== this.colourRadio)) {
|
|
2268
2311
|
this.loading = true;
|
|
2269
2312
|
//This can take sometime to finish , nextTick does not bring out
|
|
@@ -2274,7 +2317,7 @@ export default {
|
|
|
2274
2317
|
this.colourRadio = flag;
|
|
2275
2318
|
}, 100);
|
|
2276
2319
|
}
|
|
2277
|
-
},
|
|
2320
|
+
},
|
|
2278
2321
|
/**
|
|
2279
2322
|
* @public
|
|
2280
2323
|
* Function to toggle lines graphics.
|
|
@@ -2283,7 +2326,7 @@ export default {
|
|
|
2283
2326
|
*/
|
|
2284
2327
|
setOutlines: function (flag, forced = false) {
|
|
2285
2328
|
if (this.isReady && this.$module.scene &&
|
|
2286
|
-
typeof flag === "boolean" &&
|
|
2329
|
+
typeof flag === "boolean" &&
|
|
2287
2330
|
(forced || flag !== this.outlinesRadio)) {
|
|
2288
2331
|
this.outlinesRadio = flag;
|
|
2289
2332
|
this.$nextTick(() => this.$refs.scaffoldTreeControls.setOutlines(flag));
|
|
@@ -2360,15 +2403,19 @@ export default {
|
|
|
2360
2403
|
if (text === undefined || text === "" ||
|
|
2361
2404
|
((Array.isArray(text) && text.length === 0))
|
|
2362
2405
|
) {
|
|
2363
|
-
this.lastSelected
|
|
2364
|
-
|
|
2365
|
-
|
|
2406
|
+
this.lastSelected = {
|
|
2407
|
+
region: "",
|
|
2408
|
+
group: "",
|
|
2409
|
+
isSearch: true,
|
|
2410
|
+
}
|
|
2366
2411
|
this.objectSelected([], true);
|
|
2367
2412
|
return false;
|
|
2368
2413
|
} else {
|
|
2369
|
-
this.lastSelected
|
|
2370
|
-
|
|
2371
|
-
|
|
2414
|
+
this.lastSelected = {
|
|
2415
|
+
region: "",
|
|
2416
|
+
group: text,
|
|
2417
|
+
isSearch: true,
|
|
2418
|
+
}
|
|
2372
2419
|
const result = this.$_searchIndex.searchAndProcessResult(text);
|
|
2373
2420
|
const zincObjects = result.zincObjects;
|
|
2374
2421
|
if (zincObjects.length > 0) {
|
|
@@ -2455,7 +2502,7 @@ export default {
|
|
|
2455
2502
|
if (options.offlineAnnotations) {
|
|
2456
2503
|
sessionStorage.setItem('anonymous-annotation', options.offlineAnnotations);
|
|
2457
2504
|
}
|
|
2458
|
-
if ("outlines" in options) {
|
|
2505
|
+
if ("outlines" in options) {
|
|
2459
2506
|
this.setOutlines(options.outlines);
|
|
2460
2507
|
}
|
|
2461
2508
|
if (options.viewingMode) {
|
|
@@ -2501,7 +2548,7 @@ export default {
|
|
|
2501
2548
|
//this.$module.scene.createAxisDisplay(false);
|
|
2502
2549
|
//this.$module.scene.enableAxisDisplay(true, true);
|
|
2503
2550
|
this.isReady = true;
|
|
2504
|
-
console.log(`Total ${totalNerves}, found ${foundNerves}`);
|
|
2551
|
+
//console.log(`Total ${totalNerves}, found ${foundNerves}`);
|
|
2505
2552
|
this.$nextTick(() => {
|
|
2506
2553
|
this.restoreSettings(options);
|
|
2507
2554
|
this.$emit("on-ready");
|
|
@@ -2524,6 +2571,7 @@ export default {
|
|
|
2524
2571
|
colour: this.colourRadio,
|
|
2525
2572
|
outlines: this.outlinesRadio,
|
|
2526
2573
|
viewingMode: this.viewingMode,
|
|
2574
|
+
usageConfig: this.usageConfig,
|
|
2527
2575
|
};
|
|
2528
2576
|
if (this.$refs.scaffoldTreeControls)
|
|
2529
2577
|
state.visibility = this.$refs.scaffoldTreeControls.getState();
|
|
@@ -2645,6 +2693,7 @@ export default {
|
|
|
2645
2693
|
*/
|
|
2646
2694
|
setURLAndState: function (newValue, state) {
|
|
2647
2695
|
if (newValue != this._currentURL) {
|
|
2696
|
+
const options = {};
|
|
2648
2697
|
if (state?.format) this.fileFormat = state.format;
|
|
2649
2698
|
this._currentURL = newValue;
|
|
2650
2699
|
if (this.$refs.scaffoldTreeControls) this.$refs.scaffoldTreeControls.clear();
|
|
@@ -2673,13 +2722,17 @@ export default {
|
|
|
2673
2722
|
if (this.fileFormat === "gltf") {
|
|
2674
2723
|
this.$module.loadGLTFFromURL(newValue, "scene", true);
|
|
2675
2724
|
} else {
|
|
2725
|
+
if (this?.usageConfig?.tubeLines || state?.usageConfig?.tubeLines){
|
|
2726
|
+
options.tubeLines = true;
|
|
2727
|
+
}
|
|
2676
2728
|
this.$module.loadOrgansFromURL(
|
|
2677
2729
|
newValue,
|
|
2678
2730
|
undefined,
|
|
2679
2731
|
undefined,
|
|
2680
2732
|
"scene",
|
|
2681
2733
|
undefined,
|
|
2682
|
-
true
|
|
2734
|
+
true,
|
|
2735
|
+
options
|
|
2683
2736
|
);
|
|
2684
2737
|
}
|
|
2685
2738
|
if (this.$module && this.$module.scene) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { THREE } from 'zincjs';
|
|
2
|
+
import { objectsToZincObjects, NERVE_CONFIG } from "./Utilities";
|
|
2
3
|
|
|
3
4
|
const setEmissiveColour = (fullList, colour, setDepthFunc) => {
|
|
4
5
|
for (let i = 0; i < fullList.length; i++) {
|
|
@@ -117,11 +118,13 @@ const GraphicsHighlight = function() {
|
|
|
117
118
|
*/
|
|
118
119
|
|
|
119
120
|
this.setHighlighted = function(objects) {
|
|
120
|
-
const previousHighlightedObjects = [...currentHighlightedObjects];
|
|
121
|
+
const previousHighlightedObjects = [...currentHighlightedObjects];
|
|
122
|
+
this.setNervesStyle(previousHighlightedObjects);
|
|
121
123
|
_this.resetHighlighted();
|
|
122
124
|
// Selected object cannot be highlighted
|
|
123
125
|
const array = getUnmatchingObjects(objects, currentSelectedObjects);
|
|
124
126
|
const fullList = getFullListOfObjects(array);
|
|
127
|
+
this.setNervesStyle(array, NERVE_CONFIG.HIGHLIGHTED_COLOUR);
|
|
125
128
|
setEmissiveColour(fullList, _this.highlightColour, false);
|
|
126
129
|
currentHighlightedObjects = array;
|
|
127
130
|
return isDifferent(currentHighlightedObjects, previousHighlightedObjects);
|
|
@@ -129,14 +132,16 @@ const GraphicsHighlight = function() {
|
|
|
129
132
|
|
|
130
133
|
this.setSelected = function(objects) {
|
|
131
134
|
// first find highlighted object that are not selected
|
|
132
|
-
const
|
|
135
|
+
const previousSelectedObjects = [...currentSelectedObjects];
|
|
136
|
+
this.setNervesStyle(previousSelectedObjects);
|
|
133
137
|
//const array = getUnmatchingObjects(currentHighlightedObjects, objects);
|
|
134
138
|
_this.resetHighlighted();
|
|
135
139
|
_this.resetSelected();
|
|
136
140
|
const fullList = getFullListOfObjects(objects);
|
|
141
|
+
this.setNervesStyle(objects, NERVE_CONFIG.SELECTED_COLOUR);
|
|
137
142
|
setEmissiveColour(fullList, _this.selectColour, false);
|
|
138
143
|
currentSelectedObjects = objects;
|
|
139
|
-
return isDifferent(currentSelectedObjects,
|
|
144
|
+
return isDifferent(currentSelectedObjects, previousSelectedObjects);
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
const getFullListOfObjects = function(objects) {
|
|
@@ -147,15 +152,45 @@ const GraphicsHighlight = function() {
|
|
|
147
152
|
}
|
|
148
153
|
return _temp2;
|
|
149
154
|
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
*
|
|
158
|
+
* @param {*} target
|
|
159
|
+
* @param {*} colour use colour as flag to set or reset the style
|
|
160
|
+
* @returns
|
|
161
|
+
*/
|
|
162
|
+
this.setNervesStyle = function(target, colour) {
|
|
163
|
+
const currentObjects = objectsToZincObjects(target);
|
|
164
|
+
if (currentObjects && currentObjects.length) {
|
|
165
|
+
const radius = colour ?
|
|
166
|
+
NERVE_CONFIG.ZOOM_RADIUS : NERVE_CONFIG.DEFAULT_RADIUS;
|
|
167
|
+
const radialSegments = colour ?
|
|
168
|
+
NERVE_CONFIG.ZOOM_RADIAL_SEGMENTS : NERVE_CONFIG.DEFAULT_RADIAL_SEGMENTS;
|
|
169
|
+
currentObjects.forEach((currentObject) => {
|
|
170
|
+
if (
|
|
171
|
+
currentObject.isTubeLines &&
|
|
172
|
+
currentObject.userData?.isNerves &&
|
|
173
|
+
!currentObject.userData?.isGreyScale
|
|
174
|
+
) {
|
|
175
|
+
currentObject.setTubeLines(radius, radialSegments);
|
|
176
|
+
let hexString = colour ? colour : currentObject.userData?.defaultColour;
|
|
177
|
+
hexString = hexString.replace("#", "0x");
|
|
178
|
+
currentObject.setColourHex(hexString);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
150
183
|
|
|
151
184
|
this.resetHighlighted = function() {
|
|
152
185
|
const fullList = getFullListOfObjects(currentHighlightedObjects);
|
|
186
|
+
this.setNervesStyle(currentHighlightedObjects);
|
|
153
187
|
setEmissiveColour(fullList, _this.originalColour, true);
|
|
154
188
|
currentHighlightedObjects = [];
|
|
155
189
|
}
|
|
156
190
|
|
|
157
191
|
this.resetSelected = function() {
|
|
158
192
|
const fullList = getFullListOfObjects(currentSelectedObjects);
|
|
193
|
+
this.setNervesStyle(currentHighlightedObjects);
|
|
159
194
|
setEmissiveColour(fullList, _this.originalColour, true);
|
|
160
195
|
currentSelectedObjects = [];
|
|
161
196
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const organsWithAnatomicalIds = [
|
|
2
|
+
{
|
|
3
|
+
"label": "urinary bladder",
|
|
4
|
+
"anatomicalId": "UBERON:0001255",
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"label": "brainstem",
|
|
8
|
+
"anatomicalId": "UBERON:0002298",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"label": "caecum",
|
|
12
|
+
"anatomicalId": "UBERON:0001153",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"label": "colon",
|
|
16
|
+
"anatomicalId": "UBERON:0001155",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"label": "esophagus",
|
|
20
|
+
"anatomicalId": "UBERON:0001043",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"label": "small intestine",
|
|
24
|
+
"anatomicalId": "UBERON:0002108",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"label": "stomach",
|
|
28
|
+
"anatomicalId": "UBERON:0000945",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"label": "heart",
|
|
32
|
+
"anatomicalId": "UBERON:0000948",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"label": "lung",
|
|
36
|
+
"anatomicalId": "UBERON:0002048",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const getOrganMaps = () => {
|
|
41
|
+
const curatedMap = {};
|
|
42
|
+
organsWithAnatomicalIds.forEach((item) => {
|
|
43
|
+
const label = item.label.toLowerCase();
|
|
44
|
+
if (!(label in curatedMap))
|
|
45
|
+
curatedMap[label.toLowerCase()] = item["anatomicalId"];
|
|
46
|
+
});
|
|
47
|
+
return curatedMap;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { getOrganMaps };
|
|
@@ -44,6 +44,15 @@ const OrgansSceneData = function() {
|
|
|
44
44
|
const modelsLoader = ModelsLoaderIn;
|
|
45
45
|
this.NDCCameraControl = undefined;
|
|
46
46
|
_this.typeName = "Organ Viewer";
|
|
47
|
+
let ignorePicking = false;
|
|
48
|
+
|
|
49
|
+
this.isIgnorePicking = function() {
|
|
50
|
+
return ignorePicking;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.setIgnorePicking = function(value) {
|
|
54
|
+
ignorePicking = value;
|
|
55
|
+
}
|
|
47
56
|
|
|
48
57
|
this.getSceneData = function() {
|
|
49
58
|
return _this.sceneData;
|
|
@@ -275,6 +284,7 @@ const OrgansSceneData = function() {
|
|
|
275
284
|
}
|
|
276
285
|
return;
|
|
277
286
|
} else {
|
|
287
|
+
if (ignorePicking) return;
|
|
278
288
|
_this.setSelectedByObjects([], coords, extraData, true);
|
|
279
289
|
}
|
|
280
290
|
}
|
|
@@ -546,7 +556,7 @@ const OrgansSceneData = function() {
|
|
|
546
556
|
_this.sceneData.currentName = name;
|
|
547
557
|
}
|
|
548
558
|
|
|
549
|
-
this.loadOrgansFromURL = function(url, speciesName, systemName, partName, viewURL, clearFirst) {
|
|
559
|
+
this.loadOrgansFromURL = function(url, speciesName, systemName, partName, viewURL, clearFirst, options) {
|
|
550
560
|
if (_this.zincRenderer) {
|
|
551
561
|
if (partName && (_this.sceneData.metaURL !== url)) {
|
|
552
562
|
setSceneData(speciesName, systemName, partName, undefined);
|
|
@@ -571,7 +581,7 @@ const OrgansSceneData = function() {
|
|
|
571
581
|
_this.sceneData.metaURL = url;
|
|
572
582
|
organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
|
|
573
583
|
organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
|
|
574
|
-
organScene.loadMetadataURL(url, singleItemFinishCallback(), downloadCompletedCallback());
|
|
584
|
+
organScene.loadMetadataURL(url, singleItemFinishCallback(), downloadCompletedCallback(), options);
|
|
575
585
|
_this.scene = organScene;
|
|
576
586
|
_this.zincRenderer.setCurrentScene(organScene);
|
|
577
587
|
_this.graphicsHighlight.reset();
|
|
@@ -4,6 +4,7 @@ const THREE = Zinc.THREE;
|
|
|
4
4
|
import { BaseModule } from './BaseModule';
|
|
5
5
|
import { EVENT_TYPE } from "./EventNotifier";
|
|
6
6
|
import GraphicsHighlight from "./GraphicsHighlight";
|
|
7
|
+
import { objectsToZincObjects } from "./Utilities";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Create a {@link Zinc.Renderer} on the dom element with corresponding elementID.
|
|
@@ -112,8 +113,8 @@ RendererModule.prototype.getAnnotationsFromObjects = function(objects) {
|
|
|
112
113
|
|
|
113
114
|
RendererModule.prototype.setHighlightedByObjects = function(
|
|
114
115
|
objects, coords, extraData, propagateChanges) {
|
|
116
|
+
const zincObjects = objectsToZincObjects(objects);
|
|
115
117
|
const changed = this.graphicsHighlight.setHighlighted(objects);
|
|
116
|
-
const zincObjects = this.objectsToZincObjects(objects);
|
|
117
118
|
if (propagateChanges) {
|
|
118
119
|
let eventType = EVENT_TYPE.MOVE;
|
|
119
120
|
if (changed)
|
|
@@ -162,24 +163,6 @@ RendererModule.prototype.setupLiveCoordinates = function(zincObjects) {
|
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
|
|
165
|
-
RendererModule.prototype.objectsToZincObjects = function(objects) {
|
|
166
|
-
const zincObjects = [];
|
|
167
|
-
for (let i = 0; i < objects.length; i++) {
|
|
168
|
-
let zincObject = objects[i].userData;
|
|
169
|
-
if (zincObject) {
|
|
170
|
-
if (zincObject.isGlyph || zincObject.isGlyphset) {
|
|
171
|
-
let glyphset = zincObject;
|
|
172
|
-
if (zincObject.isGlyph)
|
|
173
|
-
glyphset = zincObject.getGlyphset();
|
|
174
|
-
zincObjects.push(glyphset);
|
|
175
|
-
} else {
|
|
176
|
-
zincObjects.push(zincObject);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return zincObjects;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
166
|
|
|
184
167
|
RendererModule.prototype.setSelectedByObjects = function(
|
|
185
168
|
objects, coords, extraData, propagateChanges) {
|
|
@@ -190,7 +173,7 @@ RendererModule.prototype.setSelectedByObjects = function(
|
|
|
190
173
|
changed = true;
|
|
191
174
|
}
|
|
192
175
|
if (changed || this.ignorePreviousSelected) {
|
|
193
|
-
const zincObjects =
|
|
176
|
+
const zincObjects = objectsToZincObjects(objects);
|
|
194
177
|
if (this.selectObjectOnPick) {
|
|
195
178
|
this.setupLiveCoordinates(zincObjects);
|
|
196
179
|
}
|