diff --git a/app/src/components/LayerControlBody.vue b/app/src/components/LayerControlBody.vue index 41c4c357..2524b02e 100644 --- a/app/src/components/LayerControlBody.vue +++ b/app/src/components/LayerControlBody.vue @@ -85,6 +85,65 @@ + + +
+
+ +
+ + + + + +
@@ -155,6 +214,7 @@
+
state.incVolTranslationLock ? 'lock' : 'lock-open', @@ -328,6 +396,7 @@ export default { return this.testScale[0] }, set: function (value) { + this.selectedResolutionX = this.fixed(+this.testScaleX * this.selectedIncomingVolumeResolutionX) this.scaleEvent({ axis: 'x', value @@ -339,6 +408,7 @@ export default { return this.testScale[1] }, set: function (value) { + this.selectedResolutionY = this.fixed(+this.testScaleY * this.selectedIncomingVolumeResolutionY) this.scaleEvent({ axis: 'y', value @@ -350,6 +420,7 @@ export default { return this.testScale[2] }, set: function (value) { + this.selectedResolutionZ = this.fixed(+this.testScaleZ * this.selectedIncomingVolumeResolutionZ) this.scaleEvent({ axis: 'z', value @@ -471,13 +542,36 @@ export default { }, renderedIncomingVolumes: function () { return [this.dummyIncomingTemplate].concat(this.$store.state.incomingVolumes) - } + }, + selectedIncomingVolumeResolutionX: { + get: function () { + return this.nmToSelectedUnit(this.selectedIncomingVolumeResolution[0]) + } + }, + selectedIncomingVolumeResolutionY: { + get: function () { + return this.nmToSelectedUnit(this.selectedIncomingVolumeResolution[1]) + } + }, + selectedIncomingVolumeResolutionZ: { + get: function () { + return this.nmToSelectedUnit(this.selectedIncomingVolumeResolution[2]) + } + }, }, watch: { isotropic: function (flag) { if (flag) { this.isotropicScaleEvent({ value: this.testScaleX }) } + }, + selectedIncomingVolumeResolution: function (flag) { + this.resetResolution() + }, + selectedUnit: function(newUnit, prevUnit) { + this.selectedResolutionX = this.changeUnit(this.selectedResolutionX, prevUnit) + this.selectedResolutionY = this.changeUnit(this.selectedResolutionY, prevUnit) + this.selectedResolutionZ = this.changeUnit(this.selectedResolutionZ, prevUnit) } }, methods: { @@ -511,6 +605,14 @@ export default { collapse: `scaleBySliderIsotropic` }) + + this.selectedResolutionX = this.fixed(+this.testScaleX * this.selectedIncomingVolumeResolutionX) + this.selectedResolutionY = this.fixed(+this.testScaleY * this.selectedIncomingVolumeResolutionY) + this.selectedResolutionZ = this.fixed(+this.testScaleZ * this.selectedIncomingVolumeResolutionZ) + + this.setIsotropicScale(value) + }, + setIsotropicScale: function(value) { this.setScaleInc({ axis: 'x', value @@ -610,7 +712,59 @@ export default { name: `flip on axis ${axis}` }) this.flipAxis({ axis }) - } + }, + setResolution: function () { + + const isotropic = +this.selectedResolutionX === +this.selectedResolutionY && +this.selectedResolutionY === +this.selectedResolutionZ + + if (isotropic) { + this.setIsotropicScale(+this.selectedResolutionX/this.selectedIncomingVolumeResolutionX) + } else { + this.isotropic = false + const scaleX = this.selectedResolutionX/this.selectedIncomingVolumeResolutionX + const scaleY = this.selectedResolutionY/this.selectedIncomingVolumeResolutionY + const scaleZ = this.selectedResolutionZ/this.selectedIncomingVolumeResolutionZ + + this.scaleEvent({axis: 'x', value: scaleX}) + this.scaleEvent({axis: 'y', value: scaleY}) + this.scaleEvent({axis: 'z', value: scaleZ}) + } + }, + + nmToSelectedUnit: function (num) { + const div = this.selectedUnit === 'μm'? 1000 + : this.selectedUnit === 'mm'? 1e6 + : this.selectedUnit === 'cm'? 1e7 : 1 + return +num / div + }, + + changeUnit: function (num, prevUnit) { + const mult = prevUnit === 'μm'? 1000 + : prevUnit === 'mm'? 1e6 + : prevUnit === 'cm'? 1e7 : 1 + const nm = +num * mult + return this.fixed(this.nmToSelectedUnit(nm)) + }, + fixed: function (num) { + const decimal = this.selectedUnit === 'μm'? 2 + : this.selectedUnit === 'mm'? 3 + : this.selectedUnit === 'cm'? 4 : 0 + return parseFloat(num.toFixed(decimal)) + }, + resetResolution: function () { + this.testScaleX = 1 + this.testScaleY = 1 + this.testScaleZ = 1 + this.isotropic = true + + this.selectedUnit = 'nm' + this.selectedResolutionX = this.selectedIncomingVolumeResolutionX + this.selectedResolutionY = this.selectedIncomingVolumeResolutionY + this.selectedResolutionZ = this.selectedIncomingVolumeResolutionZ + }, + }, + created: function () { + this.resetResolution() } } diff --git a/app/src/store/dataSelectionStore.js b/app/src/store/dataSelectionStore.js index e9434281..8f9d0b57 100644 --- a/app/src/store/dataSelectionStore.js +++ b/app/src/store/dataSelectionStore.js @@ -21,6 +21,7 @@ const dataSelectionStore = { ], selectedIncomingVolumeId: null, + selectedIncomingVolumeResolution: null, incomingVolumes: DEFAULT_BUNDLED_INCOMING_VOLUMES, }, @@ -34,6 +35,9 @@ const dataSelectionStore = { setSelectedIncomingVolumeId (state, id) { state.selectedIncomingVolumeId = id }, + setSelectedIncomingVolumeResolution (state, data) { + state.selectedIncomingVolumeResolution = data.resolution + }, setIncomingVolumes (state, { volumes }) { state.incomingVolumes = volumes }, @@ -43,7 +47,7 @@ const dataSelectionStore = { const vol = state.referenceVolumes.find(({ id: _id }) => _id === id) if (vol) commit('setSelectedReferenceVolumeWithId', id) }, - selectIncomingVolumeWithId ({ commit, state }, id) { + selectIncomingVolumeWithId ({ commit, state, dispatch }, id) { const vol = state.incomingVolumes.find(({ id: _id }) => _id === id) if (vol) { if (vol.extra && vol.extra.neuroglancer && vol.extra.neuroglancer.transform) { @@ -56,11 +60,32 @@ const dataSelectionStore = { { matrix }, { root: true }) } + + dispatch('setIncomingVolumeResolution', id) + commit('setSelectedIncomingVolumeId', id) const { shaderScaleFactor } = vol commit('viewerPreferenceStore/setShaderScaleFactor', shaderScaleFactor || 1, { root: true }) } }, + + async ['setIncomingVolumeResolution'] ({ commit, state, dispatch, rootGetters }, id) { + try { + const vol = state.incomingVolumes.find(({ id: _id }) => _id === id) + const { data } = await axios(`${vol.imageSource.substring(14)}/info`) + const resolution = data.scales[0].resolution + const size = data.scales[0].size + // const resolution = {} + // resolution.voxel = data.scales[0].resolution + // resolution.real = data.scales[0].resolution.map((r, i) => r * data.scales[0].size[i]) + commit('setSelectedIncomingVolumeResolution', {resolution, size}) + } catch (error) { + dispatch('updateIncVolumesResult', { + error: error ? error : null + }) + } + }, + updateIncVolumesResult (store, {error, message}) { /** * required for subscribe action