Skip to content

Commit

Permalink
Merge pull request #505 from agirault/manipulators-improvement
Browse files Browse the repository at this point in the history
SliceManipulator and ImageMapper improvements
  • Loading branch information
jourdain authored Jan 18, 2018
2 parents 225f8e5 + b23eb5f commit 0f645ff
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 4 deletions.
109 changes: 109 additions & 0 deletions Sources/Interaction/Manipulators/SliceManipulator/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import macro from 'vtk.js/Sources/macro';
import vtkCameraManipulator from 'vtk.js/Sources/Interaction/Manipulators/CameraManipulator';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';

// ----------------------------------------------------------------------------
// vtkSliceManipulator methods
// ----------------------------------------------------------------------------

function vtkSliceManipulator(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkSliceManipulator');

publicAPI.onAnimation = (interactor, renderer) => {
const lastPtr = interactor.getPointerIndex();
const pos = interactor.getAnimationEventPosition(lastPtr);
const lastPos = interactor.getLastAnimationEventPosition(lastPtr);

if (!pos || !lastPos || !renderer) {
return;
}

const dy = pos.y - lastPos.y;

const camera = renderer.getActiveCamera();
const range = camera.getClippingRange();
let distance = camera.getDistance();

// scale the interaction by the height of the viewport
let viewportHeight = 0.0;
if (camera.getParallelProjection()) {
viewportHeight = camera.getParallelScale();
} else {
const angle = vtkMath.radiansFromDegrees(camera.getViewAngle());
viewportHeight = 2.0 * distance * Math.tan(0.5 * angle);
}

const size = interactor.getView().getViewportSize(renderer);
const delta = dy * viewportHeight / size[1];
distance += delta;

// clamp the distance to the clipping range
if (distance < range[0]) {
distance = range[0] + viewportHeight * 1e-3;
}
if (distance > range[1]) {
distance = range[1] - viewportHeight * 1e-3;
}
camera.setDistance(distance);
};

publicAPI.onPinch = (interactor) => {
const interactorStyle = interactor.getInteractorStyle();
let renderer = interactorStyle.getCurrentRenderer();

if (!renderer) {
const pos = interactor.getAnimationEventPosition(
interactor.getPointerIndex()
);
renderer = interactor.findPokedRenderer(pos);
if (!renderer) {
return;
}
}

let delta = interactor.getScale() / interactor.getLastScale();
delta = 1.0 - delta;
delta *= 25; // TODO: expose factor?

const camera = renderer.getActiveCamera();
const range = camera.getClippingRange();
let distance = camera.getDistance();
distance += delta;

// clamp the distance to the clipping range
if (distance < range[0]) {
distance = range[0];
}
if (distance > range[1]) {
distance = range[1];
}
camera.setDistance(distance);
};
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

// Inheritance
vtkCameraManipulator.extend(publicAPI, model, initialValues);

// Object specific methods
vtkSliceManipulator(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkSliceManipulator');

// ----------------------------------------------------------------------------

export default Object.assign({ newInstance, extend });
2 changes: 2 additions & 0 deletions Sources/Interaction/Manipulators/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import vtkCameraManipulator from './CameraManipulator';
import vtkSliceManipulator from './SliceManipulator';
import vtkTrackballMultiRotate from './TrackballMultiRotate';
import vtkTrackballPan from './TrackballPan';
import vtkTrackballRoll from './TrackballRoll';
Expand All @@ -8,6 +9,7 @@ import vtkTrackballZoomToMouse from './TrackballZoomToMouse';

export default {
vtkCameraManipulator,
vtkSliceManipulator,
vtkTrackballMultiRotate,
vtkTrackballPan,
vtkTrackballRoll,
Expand Down
1 change: 1 addition & 0 deletions Sources/Rendering/Core/ImageMapper/example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const iStyle = vtkInteractorStyleImage.newInstance();
iStyle.setInteractionMode('IMAGE_SLICING');
renderWindow.getInteractor().setInteractorStyle(iStyle);

renderer.getActiveCamera().setParallelProjection(true);
renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();
Expand Down
30 changes: 28 additions & 2 deletions Sources/Rendering/Core/ImageMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,38 @@ function vtkImageMapper(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkImageMapper');

publicAPI.setZSliceFromCamera = (cam) => {
publicAPI.setSliceFromCamera = (cam) => {
const image = publicAPI.getInputData();
const fp = cam.getFocalPoint();
const idx = [];
image.worldToIndex(fp, idx);
publicAPI.setZSlice(Math.floor(idx[2] + 0.5));

let id = 0;
const bds = publicAPI.getBounds();
switch (publicAPI.getCurrentSlicingMode()) {
case SlicingMode.X:
id = idx[0];
id = Math.floor(id + 0.5);
id = Math.min(id, bds[1]);
id = Math.max(id, bds[0]);
publicAPI.setXSlice(id);
break;
case SlicingMode.Y:
id = idx[1];
id = Math.floor(id + 0.5);
id = Math.min(id, bds[3]);
id = Math.max(id, bds[2]);
publicAPI.setYSlice(id);
break;
case SlicingMode.Z:
id = idx[2];
id = Math.floor(id + 0.5);
id = Math.min(id, bds[5]);
id = Math.max(id, bds[4]);
publicAPI.setZSlice(id);
break;
default:
}
};

publicAPI.setZSliceIndex = (id) => {
Expand Down
4 changes: 2 additions & 2 deletions Sources/Rendering/OpenGL/ImageMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function vtkOpenGLImageMapper(publicAPI, model) {
model.openGLCamera = model.openGLRenderer.getViewNodeFor(
ren.getActiveCamera()
);
// is zslice set by the camera
// is slice set by the camera
if (model.renderable.getSliceAtFocalPoint()) {
model.renderable.setZSliceFromCamera(ren.getActiveCamera());
model.renderable.setSliceFromCamera(ren.getActiveCamera());
}
}
};
Expand Down

0 comments on commit 0f645ff

Please sign in to comment.