@abi-software/scaffoldvuer 1.11.0-demo.3 → 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 +9899 -9551
- 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 +6 -2
- 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 +104 -73
- 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>
|
|
@@ -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 {
|
|
@@ -891,7 +910,7 @@ export default {
|
|
|
891
910
|
group: "",
|
|
892
911
|
isSearch: false,
|
|
893
912
|
}),
|
|
894
|
-
checkedRegions: []
|
|
913
|
+
//checkedRegions: []
|
|
895
914
|
};
|
|
896
915
|
},
|
|
897
916
|
watch: {
|
|
@@ -1019,6 +1038,7 @@ export default {
|
|
|
1019
1038
|
this.$module = undefined;
|
|
1020
1039
|
},
|
|
1021
1040
|
computed: {
|
|
1041
|
+
...mapStores(useMainStore),
|
|
1022
1042
|
...mapState(useMainStore, ['userToken']),
|
|
1023
1043
|
annotationDisplay: function() {
|
|
1024
1044
|
return this.viewingMode === 'Annotation' && this.tData.active === true &&
|
|
@@ -1039,52 +1059,34 @@ export default {
|
|
|
1039
1059
|
},
|
|
1040
1060
|
},
|
|
1041
1061
|
methods: {
|
|
1062
|
+
/*
|
|
1042
1063
|
setCheckedRegions: function (data) {
|
|
1043
1064
|
this.checkedRegions = data;
|
|
1044
1065
|
},
|
|
1066
|
+
*/
|
|
1045
1067
|
/**
|
|
1046
|
-
*
|
|
1068
|
+
*
|
|
1047
1069
|
* @param nerves array of nerve names, show all nerves if empty
|
|
1048
1070
|
* @param processed boolean, whether unselect all checkboxes
|
|
1049
1071
|
*/
|
|
1050
1072
|
zoomToNerves: function (nerves, processed = false) {
|
|
1051
1073
|
if (this.$module.scene) {
|
|
1052
|
-
|
|
1074
|
+
this.$module.setIgnorePicking(processed);
|
|
1075
|
+
const nervesList = [];
|
|
1053
1076
|
const regions = this.$module.scene.getRootRegion().getChildRegions();
|
|
1054
1077
|
regions.forEach((region) => {
|
|
1055
1078
|
const regionName = region.getName();
|
|
1056
|
-
if (
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const ids = primitive.map((object) => {
|
|
1063
|
-
object.setVisibility(true);
|
|
1064
|
-
return `${object.region.uuid}/${object.uuid}`;
|
|
1065
|
-
});
|
|
1066
|
-
acc.push(...ids);
|
|
1067
|
-
return acc;
|
|
1068
|
-
}, []);
|
|
1069
|
-
idsList.push(...ids)
|
|
1070
|
-
} else {
|
|
1071
|
-
region.showAllPrimitives();
|
|
1072
|
-
idsList.push(region.uuid)
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
} else {
|
|
1076
|
-
// if the checkboxes are checked previously, restore them
|
|
1077
|
-
const isChecked = this.checkedRegions.find(item => item.label === regionName);
|
|
1078
|
-
if (isChecked) {
|
|
1079
|
-
region.showAllPrimitives();
|
|
1080
|
-
idsList.push(region.uuid);
|
|
1079
|
+
if (regionName === 'Nerves') {
|
|
1080
|
+
if (processed) {
|
|
1081
|
+
nerves.forEach((nerve) => {
|
|
1082
|
+
const primitives = this.findObjectsWithGroupName(nerve);
|
|
1083
|
+
nervesList.push(...primitives);
|
|
1084
|
+
});
|
|
1081
1085
|
}
|
|
1082
1086
|
}
|
|
1083
1087
|
});
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
this.$refs.scaffoldTreeControls.setCheckedKeys(idsList, processed);
|
|
1088
|
+
this.$module.setSelectedByZincObjects(nervesList, undefined, {}, true);
|
|
1089
|
+
this.$module.scene.viewAll();
|
|
1088
1090
|
}
|
|
1089
1091
|
},
|
|
1090
1092
|
enableAxisDisplay: function (enable, miniaxes) {
|
|
@@ -1119,25 +1121,27 @@ export default {
|
|
|
1119
1121
|
if (this.timeVarying === false && zincObject.isTimeVarying()) {
|
|
1120
1122
|
this.timeVarying = true;
|
|
1121
1123
|
}
|
|
1124
|
+
const groupName = zincObject.groupName.toLowerCase();
|
|
1125
|
+
if (groupName in organsMap) {
|
|
1126
|
+
zincObject.setAnatomicalId(organsMap[groupName]);
|
|
1127
|
+
}
|
|
1122
1128
|
//Temporary way to mark an object as nerves
|
|
1123
1129
|
const regions = this.isNerves?.regions;
|
|
1124
1130
|
if (regions) {
|
|
1125
1131
|
const regionPath = zincObject.getRegion().getFullPath().toLowerCase();
|
|
1126
1132
|
for (let i = 0; i < regions.length; i++) {
|
|
1127
1133
|
if (regionPath.includes(regions[i].toLowerCase())) {
|
|
1128
|
-
totalNerves++;
|
|
1129
1134
|
zincObject.userData.isNerves = true;
|
|
1130
|
-
|
|
1135
|
+
zincObject.userData.defaultColour = `#${zincObject.getColourHex()}`;
|
|
1136
|
+
zincObject.userData.isGreyScale = false;
|
|
1131
1137
|
if (groupName in nervesMap) {
|
|
1132
1138
|
foundNerves++;
|
|
1133
1139
|
zincObject.setAnatomicalId(nervesMap[groupName]);
|
|
1134
|
-
// console.log(groupName, zincObject.anatomicalId, zincObject.uuid)
|
|
1135
1140
|
}
|
|
1136
1141
|
} else {
|
|
1137
1142
|
zincObject.userData.isNerves = false;
|
|
1138
1143
|
}
|
|
1139
1144
|
}
|
|
1140
|
-
|
|
1141
1145
|
}
|
|
1142
1146
|
/**
|
|
1143
1147
|
* Emit when a new object is added to the scene
|
|
@@ -1745,16 +1749,21 @@ export default {
|
|
|
1745
1749
|
this.$refs.scaffoldTreeControls.removeActive(false);
|
|
1746
1750
|
}
|
|
1747
1751
|
}
|
|
1752
|
+
|
|
1748
1753
|
//Store the following for state saving. Search will handle the case with more than 1
|
|
1749
1754
|
//identifiers.
|
|
1750
1755
|
if (event.identifiers.length === 1) {
|
|
1751
|
-
this.lastSelected
|
|
1752
|
-
|
|
1753
|
-
|
|
1756
|
+
this.lastSelected = {
|
|
1757
|
+
isSearch: false,
|
|
1758
|
+
region: regionPath,
|
|
1759
|
+
group: event.identifiers[0].data.group,
|
|
1760
|
+
}
|
|
1754
1761
|
} else if (event.identifiers.length === 0) {
|
|
1755
|
-
this.lastSelected
|
|
1756
|
-
|
|
1757
|
-
|
|
1762
|
+
this.lastSelected = {
|
|
1763
|
+
isSearch: false,
|
|
1764
|
+
region: "",
|
|
1765
|
+
group: "",
|
|
1766
|
+
}
|
|
1758
1767
|
}
|
|
1759
1768
|
/**
|
|
1760
1769
|
* Emit when an object is selected
|
|
@@ -1841,7 +1850,7 @@ export default {
|
|
|
1841
1850
|
* @arg objects objects to be set for the selected
|
|
1842
1851
|
*/
|
|
1843
1852
|
updatePrimitiveControls: function (objects) {
|
|
1844
|
-
if (this.viewingMode === 'Exploration') {
|
|
1853
|
+
if (this.viewingMode === 'Exploration' || this.viewingMode === 'Annotation') {
|
|
1845
1854
|
this.selectedObjects = objects;
|
|
1846
1855
|
if (this.selectedObjects && this.selectedObjects.length > 0) {
|
|
1847
1856
|
this.$refs.primitiveControls.setObject(this.selectedObjects[0]);
|
|
@@ -1858,6 +1867,7 @@ export default {
|
|
|
1858
1867
|
* is made
|
|
1859
1868
|
*/
|
|
1860
1869
|
objectSelected: function (objects, propagate) {
|
|
1870
|
+
if (this.$module.isIgnorePicking()) return;
|
|
1861
1871
|
this.updatePrimitiveControls(objects);
|
|
1862
1872
|
this.$module.setSelectedByZincObjects(objects, undefined, {}, propagate);
|
|
1863
1873
|
},
|
|
@@ -2189,10 +2199,10 @@ export default {
|
|
|
2189
2199
|
* Optional, can be used to update the view mode.
|
|
2190
2200
|
*/
|
|
2191
2201
|
changeViewingMode: function (modeName) {
|
|
2202
|
+
let objectIsPickable = true;
|
|
2192
2203
|
if (this.$module) {
|
|
2193
2204
|
if (modeName) {
|
|
2194
2205
|
this.viewingMode = modeName;
|
|
2195
|
-
this.setIsPickable(true);
|
|
2196
2206
|
}
|
|
2197
2207
|
this.clearAnnotationFeature();
|
|
2198
2208
|
if (this.viewingMode === "Annotation") {
|
|
@@ -2214,9 +2224,11 @@ export default {
|
|
|
2214
2224
|
this.activeDrawMode = undefined;
|
|
2215
2225
|
this.createData.shape = "";
|
|
2216
2226
|
} else if (this.viewingMode === "Neuron Connection") {
|
|
2217
|
-
|
|
2227
|
+
// enable to make organs and nerves clickable and searchable for neuron connection mode
|
|
2228
|
+
objectIsPickable = false;
|
|
2218
2229
|
}
|
|
2219
2230
|
if ((this.viewingMode === "Exploration") ||
|
|
2231
|
+
(this.viewingMode === "Neuron Connection") ||
|
|
2220
2232
|
(this.viewingMode === "Annotation") &&
|
|
2221
2233
|
(this.createData.shape === "")) {
|
|
2222
2234
|
this.$module.selectObjectOnPick = true;
|
|
@@ -2224,6 +2236,9 @@ export default {
|
|
|
2224
2236
|
this.$module.selectObjectOnPick = false;
|
|
2225
2237
|
}
|
|
2226
2238
|
this.cancelCreate();
|
|
2239
|
+
if (modeName) {
|
|
2240
|
+
this.setObjectIsPickable(objectIsPickable);
|
|
2241
|
+
}
|
|
2227
2242
|
}
|
|
2228
2243
|
},
|
|
2229
2244
|
/**
|
|
@@ -2249,30 +2264,36 @@ export default {
|
|
|
2249
2264
|
this.tData.region = undefined;
|
|
2250
2265
|
},
|
|
2251
2266
|
/**
|
|
2252
|
-
* Currently will
|
|
2267
|
+
* Currently will apply to non-nerve object and object without anatomical id
|
|
2253
2268
|
* @param flag boolean to control whether objects pickable
|
|
2254
2269
|
*/
|
|
2255
|
-
|
|
2270
|
+
setObjectIsPickable: function (flag) {
|
|
2256
2271
|
const objects = this.$module.scene.getRootRegion().getAllObjects(true);
|
|
2257
2272
|
objects.forEach((zincObject) => {
|
|
2258
|
-
if (!zincObject.userData
|
|
2273
|
+
if (!zincObject.userData?.isNerves && !zincObject.anatomicalId) {
|
|
2274
|
+
zincObject.setIsPickable(flag);
|
|
2275
|
+
}
|
|
2259
2276
|
});
|
|
2260
2277
|
},
|
|
2261
2278
|
/**
|
|
2262
|
-
*
|
|
2279
|
+
* Update objects to greyscale or colour.
|
|
2280
|
+
* This will update all objects except those with the provided nerves labels.
|
|
2263
2281
|
* @param flag boolean
|
|
2264
|
-
* @param
|
|
2282
|
+
* @param labels array of nerve names that exclude from greyscale
|
|
2265
2283
|
*/
|
|
2266
|
-
setGreyScale: function (flag,
|
|
2284
|
+
setGreyScale: function (flag, labels = []) {
|
|
2267
2285
|
const objects = this.$module.scene.getRootRegion().getAllObjects(true);
|
|
2268
2286
|
objects.forEach((zincObject) => {
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
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;
|
|
2276
2297
|
}
|
|
2277
2298
|
});
|
|
2278
2299
|
this.$refs.scaffoldTreeControls.updateAllNodeColours();
|
|
@@ -2285,7 +2306,7 @@ export default {
|
|
|
2285
2306
|
*/
|
|
2286
2307
|
setColour: function (flag, forced = false) {
|
|
2287
2308
|
if (this.isReady && this.$module.scene &&
|
|
2288
|
-
typeof flag === "boolean" &&
|
|
2309
|
+
typeof flag === "boolean" &&
|
|
2289
2310
|
(forced || flag !== this.colourRadio)) {
|
|
2290
2311
|
this.loading = true;
|
|
2291
2312
|
//This can take sometime to finish , nextTick does not bring out
|
|
@@ -2296,7 +2317,7 @@ export default {
|
|
|
2296
2317
|
this.colourRadio = flag;
|
|
2297
2318
|
}, 100);
|
|
2298
2319
|
}
|
|
2299
|
-
},
|
|
2320
|
+
},
|
|
2300
2321
|
/**
|
|
2301
2322
|
* @public
|
|
2302
2323
|
* Function to toggle lines graphics.
|
|
@@ -2305,7 +2326,7 @@ export default {
|
|
|
2305
2326
|
*/
|
|
2306
2327
|
setOutlines: function (flag, forced = false) {
|
|
2307
2328
|
if (this.isReady && this.$module.scene &&
|
|
2308
|
-
typeof flag === "boolean" &&
|
|
2329
|
+
typeof flag === "boolean" &&
|
|
2309
2330
|
(forced || flag !== this.outlinesRadio)) {
|
|
2310
2331
|
this.outlinesRadio = flag;
|
|
2311
2332
|
this.$nextTick(() => this.$refs.scaffoldTreeControls.setOutlines(flag));
|
|
@@ -2382,15 +2403,19 @@ export default {
|
|
|
2382
2403
|
if (text === undefined || text === "" ||
|
|
2383
2404
|
((Array.isArray(text) && text.length === 0))
|
|
2384
2405
|
) {
|
|
2385
|
-
this.lastSelected
|
|
2386
|
-
|
|
2387
|
-
|
|
2406
|
+
this.lastSelected = {
|
|
2407
|
+
region: "",
|
|
2408
|
+
group: "",
|
|
2409
|
+
isSearch: true,
|
|
2410
|
+
}
|
|
2388
2411
|
this.objectSelected([], true);
|
|
2389
2412
|
return false;
|
|
2390
2413
|
} else {
|
|
2391
|
-
this.lastSelected
|
|
2392
|
-
|
|
2393
|
-
|
|
2414
|
+
this.lastSelected = {
|
|
2415
|
+
region: "",
|
|
2416
|
+
group: text,
|
|
2417
|
+
isSearch: true,
|
|
2418
|
+
}
|
|
2394
2419
|
const result = this.$_searchIndex.searchAndProcessResult(text);
|
|
2395
2420
|
const zincObjects = result.zincObjects;
|
|
2396
2421
|
if (zincObjects.length > 0) {
|
|
@@ -2477,7 +2502,7 @@ export default {
|
|
|
2477
2502
|
if (options.offlineAnnotations) {
|
|
2478
2503
|
sessionStorage.setItem('anonymous-annotation', options.offlineAnnotations);
|
|
2479
2504
|
}
|
|
2480
|
-
if ("outlines" in options) {
|
|
2505
|
+
if ("outlines" in options) {
|
|
2481
2506
|
this.setOutlines(options.outlines);
|
|
2482
2507
|
}
|
|
2483
2508
|
if (options.viewingMode) {
|
|
@@ -2523,7 +2548,7 @@ export default {
|
|
|
2523
2548
|
//this.$module.scene.createAxisDisplay(false);
|
|
2524
2549
|
//this.$module.scene.enableAxisDisplay(true, true);
|
|
2525
2550
|
this.isReady = true;
|
|
2526
|
-
//
|
|
2551
|
+
//console.log(`Total ${totalNerves}, found ${foundNerves}`);
|
|
2527
2552
|
this.$nextTick(() => {
|
|
2528
2553
|
this.restoreSettings(options);
|
|
2529
2554
|
this.$emit("on-ready");
|
|
@@ -2546,6 +2571,7 @@ export default {
|
|
|
2546
2571
|
colour: this.colourRadio,
|
|
2547
2572
|
outlines: this.outlinesRadio,
|
|
2548
2573
|
viewingMode: this.viewingMode,
|
|
2574
|
+
usageConfig: this.usageConfig,
|
|
2549
2575
|
};
|
|
2550
2576
|
if (this.$refs.scaffoldTreeControls)
|
|
2551
2577
|
state.visibility = this.$refs.scaffoldTreeControls.getState();
|
|
@@ -2667,6 +2693,7 @@ export default {
|
|
|
2667
2693
|
*/
|
|
2668
2694
|
setURLAndState: function (newValue, state) {
|
|
2669
2695
|
if (newValue != this._currentURL) {
|
|
2696
|
+
const options = {};
|
|
2670
2697
|
if (state?.format) this.fileFormat = state.format;
|
|
2671
2698
|
this._currentURL = newValue;
|
|
2672
2699
|
if (this.$refs.scaffoldTreeControls) this.$refs.scaffoldTreeControls.clear();
|
|
@@ -2695,13 +2722,17 @@ export default {
|
|
|
2695
2722
|
if (this.fileFormat === "gltf") {
|
|
2696
2723
|
this.$module.loadGLTFFromURL(newValue, "scene", true);
|
|
2697
2724
|
} else {
|
|
2725
|
+
if (this?.usageConfig?.tubeLines || state?.usageConfig?.tubeLines){
|
|
2726
|
+
options.tubeLines = true;
|
|
2727
|
+
}
|
|
2698
2728
|
this.$module.loadOrgansFromURL(
|
|
2699
2729
|
newValue,
|
|
2700
2730
|
undefined,
|
|
2701
2731
|
undefined,
|
|
2702
2732
|
"scene",
|
|
2703
2733
|
undefined,
|
|
2704
|
-
true
|
|
2734
|
+
true,
|
|
2735
|
+
options
|
|
2705
2736
|
);
|
|
2706
2737
|
}
|
|
2707
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
|
}
|
package/src/scripts/Utilities.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { Label, THREE } from 'zincjs';
|
|
2
2
|
|
|
3
|
+
// This will be the config for nerves selection and highlight
|
|
4
|
+
export const NERVE_CONFIG = {
|
|
5
|
+
SELECTED_COLOUR: '#00ff00',
|
|
6
|
+
HIGHLIGHTED_COLOUR: '#ff0000',
|
|
7
|
+
DEFAULT_RADIUS: 1,
|
|
8
|
+
DEFAULT_RADIAL_SEGMENTS: 8,
|
|
9
|
+
ZOOM_RADIUS: 5,
|
|
10
|
+
ZOOM_RADIAL_SEGMENTS: 12,
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
export const createListFromPrimitives = (primitives, list) => {
|
|
4
14
|
if (primitives) {
|
|
5
15
|
let id = "";
|
|
@@ -409,3 +419,20 @@ export const annotationFeaturesToPrimitives = (scene, features) => {
|
|
|
409
419
|
}
|
|
410
420
|
}
|
|
411
421
|
|
|
422
|
+
export const objectsToZincObjects = function(objects) {
|
|
423
|
+
const zincObjects = [];
|
|
424
|
+
for (let i = 0; i < objects.length; i++) {
|
|
425
|
+
let zincObject = objects[i].userData;
|
|
426
|
+
if (zincObject) {
|
|
427
|
+
if (zincObject.isGlyph || zincObject.isGlyphset) {
|
|
428
|
+
let glyphset = zincObject;
|
|
429
|
+
if (zincObject.isGlyph)
|
|
430
|
+
glyphset = zincObject.getGlyphset();
|
|
431
|
+
zincObjects.push(glyphset);
|
|
432
|
+
} else {
|
|
433
|
+
zincObjects.push(zincObject);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return zincObjects;
|
|
438
|
+
}
|