Skip to content

Commit d0ccd4f

Browse files
committed
refactor(viewOrientation): use a matrix
Replace getLPSDirections with getSparseOrthogonalMatrix Replace the array of vectors with a matrix
1 parent c6cad90 commit d0ccd4f

File tree

3 files changed

+30
-73
lines changed

3 files changed

+30
-73
lines changed

src/components/core/VtkView/constants.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,4 @@ export const DEFAULT_LPS_VIEW_TYPES = {
3535
[VIEW_TYPE_VALUES.z]: 'Axial',
3636
};
3737

38-
export const DEFAULT_VIEW_ORIENTATION = [
39-
[1, 0, 0],
40-
[0, 1, 0],
41-
[0, 0, 1],
42-
];
38+
export const DEFAULT_VIEW_ORIENTATION = [1, 0, 0, 0, 1, 0, 0, 0, 1];

src/store/views.js

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import Vue from 'vue';
22
import vtkWidgetManager from '@kitware/vtk.js/Widgets/Core/WidgetManager';
33
import WidgetManagerConstants from '@kitware/vtk.js/Widgets/Core/WidgetManager/Constants';
4+
import { getSparseOrthogonalMatrix } from '@kitware/vtk.js/Common/Core/Math';
5+
6+
import { mat3 } from 'gl-matrix';
47

58
import {
69
DEFAULT_VIEW_TYPE,
@@ -15,7 +18,6 @@ import { DEFAULT_BACKGROUND } from 'paraview-glance/src/components/core/VtkView/
1518
import {
1619
remapIdValues,
1720
wrapMutationAsAction,
18-
getLPSDirections,
1921
updateViewOrientationFromBasisAndAxis,
2022
} from 'paraview-glance/src/utils';
2123

@@ -40,7 +42,7 @@ export default ({ proxyManager }) => ({
4042
maxTextureLODSize: 50000, // Units are in KiB
4143
viewOrder: Object.values(VIEW_TYPE_VALUES),
4244
visibleCount: 1,
43-
// a basis in column-major order (list of 3 vectors): number[3][3]
45+
// a column-major matrix
4446
viewOrientation: DEFAULT_VIEW_ORIENTATION,
4547
// for each view type, the corresponding text to display { viewType: text }
4648
viewTypes: DEFAULT_VIEW_TYPES,
@@ -225,20 +227,32 @@ export default ({ proxyManager }) => ({
225227
const masterSource = proxyManager.getProxyById(state.masterSourceId);
226228
if (masterSource?.getDataset().isA('vtkImageData')) {
227229
// lps mode with a master volume
230+
// directionMatrix is a column major index to world matrix
228231
const directionMatrix = masterSource.getDataset().getDirection();
229-
const lpsDirections = getLPSDirections(directionMatrix);
230-
const axisToXYZ = ['x', 'y', 'z'];
232+
const sparseDirectionMatrix =
233+
getSparseOrthogonalMatrix(directionMatrix);
234+
235+
const lpsToXyz = {};
236+
for (let row = 0; row < 3; ++row) {
237+
for (let col = 0; col < 3; ++col) {
238+
const index = row + 3 * col;
239+
if (sparseDirectionMatrix[index] !== 0) {
240+
lpsToXyz['lps'[row]] = 'xyz'[col];
241+
}
242+
}
243+
}
231244
const viewTypes = {
232245
[VIEW_TYPE_VALUES.default]: '3D',
233-
[VIEW_TYPE_VALUES[axisToXYZ[lpsDirections.l.axis]]]: 'Sagittal',
234-
[VIEW_TYPE_VALUES[axisToXYZ[lpsDirections.p.axis]]]: 'Coronal',
235-
[VIEW_TYPE_VALUES[axisToXYZ[lpsDirections.s.axis]]]: 'Axial',
246+
[VIEW_TYPE_VALUES[lpsToXyz.l]]: 'Sagittal',
247+
[VIEW_TYPE_VALUES[lpsToXyz.p]]: 'Coronal',
248+
[VIEW_TYPE_VALUES[lpsToXyz.s]]: 'Axial',
236249
};
237-
const viewOrientation = [
238-
lpsDirections.l.vector,
239-
lpsDirections.p.vector,
240-
lpsDirections.s.vector,
241-
];
250+
251+
// viewOrientation = directionMatrix * transpose(sparseDirectionMatrix)
252+
const viewOrientation = Array(3);
253+
mat3.transpose(viewOrientation, sparseDirectionMatrix);
254+
mat3.mul(viewOrientation, directionMatrix, viewOrientation);
255+
242256
dispatch('setViewTypes', viewTypes);
243257
dispatch('setViewOrientation', {
244258
orientation: viewOrientation,

src/utils.js

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -115,58 +115,6 @@ export function getCropFilter(pxm, proxy) {
115115
return volRep.getCropFilter();
116116
}
117117

118-
/**
119-
* Function adapted from getLPSDirections lps.ts from VolView.
120-
* Associates the column vectors of a 3x3 matrix with the LPS axes.
121-
*
122-
* For each of the LPS axes, this function returns the associated column index (0, 1, 2)
123-
* in the provided 3x3 column-major matrix and the corresponding positive vector.
124-
*
125-
* Approach:
126-
* - find the max of the direction matrix, ignoring columns and rows marked as done
127-
* - assign the column vector of that max value to the row axis
128-
* - mark that row and column as done
129-
* - continue until all rows and columns are done
130-
*/
131-
export function getLPSDirections(directionMatrix) {
132-
const axisToLPS = ['l', 'p', 's'];
133-
const lpsDirs = {};
134-
// Track the rows and columns that have yet to be assigned.
135-
const availableCols = [0, 1, 2];
136-
const availableRows = [0, 1, 2];
137-
138-
for (let i = 0; i < 3; i++) {
139-
let bestValue = 0;
140-
let bestValueLoc = [0, 0]; // col, row
141-
let removeIndices = [0, 0]; // indices into availableCols/Rows for deletion
142-
143-
availableCols.forEach((col, colIdx) => {
144-
availableRows.forEach((row, rowIdx) => {
145-
const value = directionMatrix[col * 3 + row];
146-
if (Math.abs(value) > Math.abs(bestValue)) {
147-
bestValue = value;
148-
bestValueLoc = [col, row];
149-
removeIndices = [colIdx, rowIdx];
150-
}
151-
});
152-
});
153-
154-
// the row index corresponds to the index of the LPS axis
155-
const [col, axis] = bestValueLoc;
156-
const axisVector = directionMatrix.slice(col * 3, (col + 1) * 3);
157-
const vecSign = Math.sign(bestValue);
158-
const posVector = vec3.scale(Array(3), axisVector, vecSign);
159-
lpsDirs[axisToLPS[axis]] = {
160-
axis: col,
161-
vector: posVector,
162-
};
163-
availableCols.splice(removeIndices[0], 1);
164-
availableRows.splice(removeIndices[1], 1);
165-
}
166-
167-
return lpsDirs;
168-
}
169-
170118
/**
171119
* Associate a key of VIEW_TYPE_VALUES to axis index and orientation
172120
* for forward and upward vectors.
@@ -201,7 +149,7 @@ const MODE_TO_AXES = {
201149
/**
202150
* Update the camera view using the given arguments:
203151
* - view which is a vtkViewProxy
204-
* - basis, a list of 3 vec3 defining a basis
152+
* - basis, a column major matrix defining a basis
205153
* - mode, a key of VIEW_TYPE_VALUES
206154
* - an optional number of animateSteps
207155
*
@@ -221,12 +169,12 @@ export function updateViewOrientationFromBasisAndAxis(
221169
MODE_TO_AXES[mode];
222170
const forwardVector = vec3.scale(
223171
Array(3),
224-
basis[forwardAxis],
172+
basis.slice(forwardAxis * 3, forwardAxis * 3 + 3),
225173
forwardOrientation
226174
);
227175
const upwardVector = vec3.scale(
228176
Array(3),
229-
basis[upwardAxis],
177+
basis.slice(upwardAxis * 3, upwardAxis * 3 + 3),
230178
upwardOrientation
231179
);
232180

@@ -268,6 +216,5 @@ export default {
268216
remapIdList,
269217
createRepresentationInAllViews,
270218
getCropFilter,
271-
getLPSDirections,
272219
updateViewOrientationFromBasisAndAxis,
273220
};

0 commit comments

Comments
 (0)