Skip to content

Commit

Permalink
Merge pull request Kitware#1946 from laurennlam/update-old-reslice-cu…
Browse files Browse the repository at this point in the history
…rsor

fix(reslicecursor): keep correct viewUp on rotation
  • Loading branch information
finetjul authored May 31, 2021
2 parents ae1045c + f0bdbc1 commit 8cfe7f5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 49 deletions.
24 changes: 23 additions & 1 deletion Sources/Interaction/Widgets/ResliceCursor/ResliceCursor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ function vtkResliceCursor(publicAPI, model) {
model.xAxis = [1, 0, 0];
model.yAxis = [0, 1, 0];
model.zAxis = [0, 0, 1];
model.xViewUp = [0, 0, 1];
model.yViewUp = [0, 0, 1];
model.zViewUp = [0, -1, 0];

if (publicAPI.getImage()) {
model.center = publicAPI.getImage().getCenter();
Expand Down Expand Up @@ -228,6 +231,17 @@ function vtkResliceCursor(publicAPI, model) {
return model.zAxis;
};

publicAPI.getViewUp = (i) => {
if (i === 0) {
return model.xViewUp;
}
if (i === 1) {
return model.yViewUp;
}

return model.zViewUp;
};

publicAPI.getMTime = () => {
let mTime = superClass.getMTime();

Expand All @@ -253,6 +267,9 @@ const DEFAULT_VALUES = {
xAxis: [1, 0, 0],
yAxis: [0, 1, 0],
zAxis: [0, 0, 1],
xViewUp: [0, 0, 1],
yViewUp: [0, 0, 1],
zViewUp: [0, -1, 0],
};

// ----------------------------------------------------------------------------
Expand All @@ -262,7 +279,12 @@ export function extend(publicAPI, model, initialValues = {}) {

macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, ['image']);
macro.setGetArray(publicAPI, model, ['xAxis', 'yAxis', 'zAxis'], 3);
macro.setGetArray(
publicAPI,
model,
['xAxis', 'yAxis', 'zAxis', 'xViewUp', 'yViewUp', 'zViewUp'],
3
);
macro.getArray(publicAPI, model, ['center'], 3);

model.reslicePlanes = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ function vtkResliceCursorLineRepresentation(publicAPI, model) {
.getReslicePlaneNormal();

const planeToBeRotated = resliceCursor.getPlane(axis);
const viewUp = resliceCursor.getViewUp(axis);
const vectorToBeRotated = planeToBeRotated.getNormal();

const normalPlane = resliceCursor.getPlane(resliceCursorPlaneId);
Expand All @@ -332,6 +333,8 @@ function vtkResliceCursorLineRepresentation(publicAPI, model) {
.rotate(angle, aboutAxis)
.apply(rotatedVector);

vtkMatrixBuilder.buildFromRadian().rotate(angle, aboutAxis).apply(viewUp);

planeToBeRotated.setNormal(rotatedVector);
};

Expand Down Expand Up @@ -430,13 +433,12 @@ function vtkResliceCursorLineRepresentation(publicAPI, model) {
*/
publicAPI.resetCamera = () => {
if (model.renderer) {
const bounds = publicAPI.getBounds();
const center = [
(bounds[0] + bounds[1]) / 2,
(bounds[2] + bounds[3]) / 2,
(bounds[4] + bounds[5]) / 2,
];

const normalAxis = publicAPI.getCursorAlgorithm().getReslicePlaneNormal();
const normal = publicAPI
.getResliceCursor()
.getPlane(normalAxis)
.getNormal();
const viewUp = publicAPI.getResliceCursor().getViewUp(normalAxis);
const focalPoint = model.renderer.getActiveCamera().getFocalPoint();
const position = model.renderer.getActiveCamera().getPosition();

Expand All @@ -445,49 +447,23 @@ function vtkResliceCursorLineRepresentation(publicAPI, model) {
vtkMath.distance2BetweenPoints(position, focalPoint)
);

const normalAxis = publicAPI.getCursorAlgorithm().getReslicePlaneNormal();
const normal = publicAPI
.getResliceCursor()
.getPlane(normalAxis)
.getNormal();

const estimatedFocalPoint = center;
const estimatedCameraPosition = [
estimatedFocalPoint[0] + distance * normal[0],
estimatedFocalPoint[1] + distance * normal[1],
estimatedFocalPoint[2] + distance * normal[2],
const newCameraPosition = [
focalPoint[0] + distance * normal[0],
focalPoint[1] + distance * normal[1],
focalPoint[2] + distance * normal[2],
];

model.renderer
.getActiveCamera()
.setFocalPoint(
estimatedFocalPoint[0],
estimatedFocalPoint[1],
estimatedFocalPoint[2]
.setPosition(
newCameraPosition[0],
newCameraPosition[1],
newCameraPosition[2]
);

model.renderer
.getActiveCamera()
.setPosition(
estimatedCameraPosition[0],
estimatedCameraPosition[1],
estimatedCameraPosition[2]
);

const planeNormalType = publicAPI
.getCursorAlgorithm()
.getReslicePlaneNormal();
if (model.viewUpFromViewType[planeNormalType]) {
model.renderer
.getActiveCamera()
.setViewUp(...model.viewUpFromViewType[planeNormalType]);
}

// Project focalPoint onto image plane and preserve distance
publicAPI.updateCamera();

// Reset clipping range
publicAPI.updateCamera();
.setViewUp(viewUp[0], viewUp[1], viewUp[2]);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,7 @@ function vtkResliceCursorRepresentation(publicAPI, model) {
publicAPI.computeReslicePlaneOrigin();

// Compute view up to configure camera later on
const bottomLeftPoint = model.planeSource.getOrigin();
const topLeftPoint = model.planeSource.getPoint2();
const viewUp = vtkMath.subtract(topLeftPoint, bottomLeftPoint, [0, 0, 0]);
vtkMath.normalize(viewUp);
model.viewUpFromViewType[planeNormalType] = viewUp;
const viewUp = publicAPI.getResliceCursor().getViewUp(planeNormalType);

transformPlane(
model.planeSource,
Expand Down Expand Up @@ -344,6 +340,7 @@ function vtkResliceCursorRepresentation(publicAPI, model) {
publicAPI.modified();
}
buildTime.modified();
publicAPI.resetCamera();
};

publicAPI.setResliceParameters = (
Expand Down Expand Up @@ -476,7 +473,6 @@ export function extend(publicAPI, model, initialValues = {}) {
1.0,
1.0
);
model.viewUpFromViewType = {};
model.planeInitialized = false;

macro.setGet(publicAPI, model, [
Expand Down
3 changes: 3 additions & 0 deletions Sources/Interaction/Widgets/ResliceCursor/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
import vtkRenderWindowInteractor from 'vtk.js/Sources/Rendering/Core/RenderWindowInteractor';

// Force the loading of HttpDataAccessHelper to support gzip decompression
import 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper';

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------
Expand Down

0 comments on commit 8cfe7f5

Please sign in to comment.