Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0b3e104
add MPR Rotate support as an interactor - based on Madison Dickson v…
Zaid-Safadi Sep 12, 2019
199d5e0
fix segmetnation pipline
Zaid-Safadi Sep 12, 2019
8ab67c9
add gl-matrix dependency
Zaid-Safadi Sep 12, 2019
01b9d37
clear unneeded comments
Zaid-Safadi Sep 12, 2019
404329b
WIP - update example to use a range control for manual rotation with …
Zaid-Safadi Sep 13, 2019
f64e779
WIP - update DCM4CHEE server URL
Zaid-Safadi Sep 13, 2019
af501a3
Merge branch 'master' of github.com:OHIF/react-vtkjs-viewport into ad…
dannyrb Sep 17, 2019
8a2b7ef
setSliceNormal with an array (that can be spread by methods signature)
dannyrb Sep 17, 2019
8de0ff0
from vtk-viewport
dannyrb Sep 17, 2019
ae7cfe1
feat(rotate on scroll): support rotation on mouse wheel
Zaid-Safadi Sep 17, 2019
d77b8d2
WIP: fix rotation direction and add orientation cube widget
Zaid-Safadi Sep 20, 2019
d995081
Fix the mouse wheel rotation and rotation direction to match the rota…
Zaid-Safadi Sep 21, 2019
096a21d
Fix: initial display of the view and orientation cube. Clean all unne…
Zaid-Safadi Sep 21, 2019
33e9a48
Fix invalid slider rotation values and render rotation only when needed
Zaid-Safadi Sep 22, 2019
973496b
use existing camera view parameters -if exist- when setting slice normal
Zaid-Safadi Sep 23, 2019
6ad4a68
Implement a sensetivity factor for the rotation to slow it down
Zaid-Safadi Sep 24, 2019
e6c0329
Merge branch 'master' into add-mprRotation-interactor
swederik Sep 24, 2019
f1a26e2
Merge branch 'master' into add-mprRotation-interactor
swederik Sep 24, 2019
0a01be8
Refactored the rotation code into a viewportData object and created a…
Zaid-Safadi Sep 25, 2019
c6b36eb
Fix initial display of slices and setting the corsshair scroll manipu…
Zaid-Safadi Sep 25, 2019
3267033
support setSliceNormal to be called externally and reverting mouse wh…
Zaid-Safadi Sep 26, 2019
fe6485d
WIP: fix rotation
Zaid-Safadi Sep 30, 2019
47dd6c7
Fix rotation by applying in an iterative rather than additive fashion.
JamesAPetts Oct 1, 2019
037ad32
merge changes from master
Zaid-Safadi Oct 1, 2019
f6601fe
refactor: cleanup the viewportData mehods
Zaid-Safadi Oct 1, 2019
80e5038
refactor: remove the sliders from the example until updated to work w…
Zaid-Safadi Oct 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions examples/VTKMPRRotateExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ class VTKMPRRotateExample extends Component {

const viewport = istyle.getViewport();

viewport.setInitialOrientation(
viewport.setOrientation(
volumeData[viewportIndex].slicePlaneNormal,
volumeData[viewportIndex].sliceViewUp
);
Expand All @@ -367,15 +367,14 @@ class VTKMPRRotateExample extends Component {
.addEventListener(EVENTS.VIEWPORT_ROTATED, args => {
const rotation = this.state.rotation;

if (
rotation[viewportIndex].x === args.detail.horizontalRotation &&
rotation[viewportIndex].y === args.detail.verticalRotation
) {
if (args.detail.dThetaX === 0 && args.detail.dThetaY === 0) {
return;
}

rotation[viewportIndex].x = args.detail.horizontalRotation;
rotation[viewportIndex].y = args.detail.verticalRotation;
rotation[viewportIndex].x =
(rotation[viewportIndex].x + args.detail.dThetaY) % 360;
rotation[viewportIndex].y =
(rotation[viewportIndex].y + args.detail.dThetaX) % 360;

this.setState({ rotation });
});
Expand All @@ -387,8 +386,6 @@ class VTKMPRRotateExample extends Component {
};

handleChangeX = (index, event) => {
volumeData[index].horizontalRotation = +event.target.value;

const rotation = this.state.rotation;

rotation[index].x = +event.target.value;
Expand All @@ -399,8 +396,6 @@ class VTKMPRRotateExample extends Component {
};

handleChangeY = (index, event) => {
volumeData[index].verticalRotation = +event.target.value;

const rotation = this.state.rotation;

rotation[index].y = +event.target.value;
Expand All @@ -413,24 +408,22 @@ class VTKMPRRotateExample extends Component {
updateRotate = index => {
const api = this.apis[index];
const renderWindow = api.genericRenderWindow.getRenderWindow();

const rotation = this.state.rotation;
const istyle = renderWindow.getInteractor().getInteractorStyle();
const viewport = istyle.getViewport();
const dThetaY = rotation[index].x - volumeData[index].horizontalRotation;
const dThetaX = rotation[index].y - volumeData[index].verticalRotation;

istyle
.getViewport()
.rotate(
volumeData[index].horizontalRotation,
volumeData[index].verticalRotation
);
viewport.rotate(-dThetaX, -dThetaY);

volumeData[index].horizontalRotation = rotation[index].x;
volumeData[index].verticalRotation = rotation[index].y;

this.apis.orientations[index].updateMarkerOrientation();

renderWindow.render();
};

getSliceXRotation = index => {
return volumeData[index].horizontalRotation;
};
render() {
if (!this.state.volumes || !this.state.volumes.length) {
return <h4>Loading...</h4>;
Expand All @@ -441,7 +434,7 @@ class VTKMPRRotateExample extends Component {
for (let index = 0; index < volumeData.length; index++) {
columns.push(
<div key={index.toString()} className="col-xs-12 col-sm-6">
<div>
{/* <div>
<input
className="rotate"
type="range"
Expand All @@ -468,7 +461,7 @@ class VTKMPRRotateExample extends Component {
}}
/>
<span>{this.state.rotation[index].y}</span>
</div>
</div> */}
<View2D
volumes={this.state.volumes}
onCreated={this.storeApi(index)}
Expand Down
4 changes: 2 additions & 2 deletions src/Custom/VTKMPRViewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default class VtkMpr extends Component {
this.renderer.addVolume(this.labelPipeline.actor);

istyle.setVolumeMapper(this.pipeline.mapper);
istyle.setSliceNormal(0, 0, 1);
istyle.setSliceNormal([0, 0, 1]);
const range = istyle.getSliceRange();
istyle.setSlice((range[0] + range[1]) / 2);

Expand Down Expand Up @@ -239,7 +239,7 @@ export default class VtkMpr extends Component {

if (prevProps.sliceNormal !== this.props.sliceNormal) {
const istyle = this.istyle;
istyle.setSliceNormal(...this.props.sliceNormal);
istyle.setSliceNormal([...this.props.sliceNormal]);

const range = istyle.getSliceRange();
istyle.setSlice((range[0] + range[1]) / 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ function vtkMouseRangeRotateManipulator(publicAPI, model) {
-MAX_SAFE_INTEGER,
MAX_SAFE_INTEGER,
1,
model.viewportData.getHRotation,
horizontalRotation => {
let hRotation = horizontalRotation % 360;
() => 0,
dThetaY => {
let thetaY = dThetaY % 360;

model.viewportData.rotate(hRotation, model.viewportData.getVRotation());
model.viewportData.rotate(0, thetaY);

// onInteractiveRotationChanged();
}
Expand Down
101 changes: 25 additions & 76 deletions src/VTKViewport/ViewportData.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,8 @@ function validateNumber(numberValue) {
throw `Invalid number ${numberValue}`;
}

function areInitialRotationValues(horizontalRotation, verticalRotation) {
return horizontalRotation === 0 && verticalRotation === 0;
}

function createNewViewportData() {
return {
horizontalRotation: 0,
verticalRotation: 0,
initialViewUp: [0, 1, 0],
initialSliceNormal: [0, 0, 1],
viewUp: [0, 1, 0],
sliceNormal: [0, 0, 1],
};
Expand All @@ -46,71 +38,41 @@ export default class {
return this.eventWindow;
};

getHRotation = () => {
return this._state.horizontalRotation;
};

getVRotation = () => {
return this._state.verticalRotation;
};
rotate = (dThetaX, dThetaY) => {
validateNumber(dThetaX);
validateNumber(dThetaY);

rotate = (horizontalRotation, verticalRotation) => {
validateNumber(horizontalRotation);
validateNumber(verticalRotation);

if (
!areInitialRotationValues(horizontalRotation, verticalRotation) &&
this._state.horizontalRotation === horizontalRotation &&
this._state.verticalRotation === verticalRotation
) {
return;
}
let xAxis = [];
vec3.cross(xAxis, this._state.viewUp, this._state.sliceNormal);
vec3.normalize(xAxis, xAxis);

let yAxis = this._state.viewUp;
// rotate around the vector of the cross product of the
// plane and viewup as the X component
const sliceXRot = [];

const sliceNormal = [];
const sliceViewUp = [];

vec3.cross(
sliceXRot,
this._state.initialViewUp,
this._state.initialSliceNormal
);
vec3.normalize(sliceXRot, sliceXRot);

const planeMat = mat4.create();

// Rotate around the vertical (slice-up) vector
mat4.rotate(
planeMat,
planeMat,
degrees2radians(-horizontalRotation),
this._state.initialViewUp
);

// Rotate around the horizontal (screen-x) vector
mat4.rotate(
planeMat,
planeMat,
degrees2radians(-verticalRotation),
sliceXRot
);

vec3.transformMat4(sliceNormal, this._state.initialSliceNormal, planeMat);
vec3.transformMat4(sliceViewUp, this._state.initialViewUp, planeMat);

this._state.horizontalRotation = horizontalRotation;
this._state.verticalRotation = verticalRotation;
//Rotate around the vertical (slice-up) vector
mat4.rotate(planeMat, planeMat, degrees2radians(dThetaY), yAxis);

//Rotate around the horizontal (screen-x) vector
mat4.rotate(planeMat, planeMat, degrees2radians(dThetaX), xAxis);

vec3.transformMat4(sliceNormal, this._state.sliceNormal, planeMat);
vec3.transformMat4(sliceViewUp, this._state.viewUp, planeMat);

this._state.sliceNormal = sliceNormal;
this._state.sliceViewUp = sliceViewUp;
this._state.viewUp = sliceViewUp;

var event = new CustomEvent(EVENTS.VIEWPORT_ROTATED, {
detail: {
horizontalRotation,
verticalRotation,
sliceNormal,
sliceViewUp,
dThetaX,
dThetaY,
},
bubbles: true,
cancelable: true,
Expand All @@ -119,32 +81,19 @@ export default class {
this.eventWindow.dispatchEvent(event);
};

getInitialViewUp = () => {
return this._state.initialViewUp;
};

getInitialSliceNormal = () => {
return this._state.initialSliceNormal;
};

setInitialOrientation = (initialSliceNormal, initialViewUp = [0, 1, 0]) => {
this._state.initialSliceNormal = initialSliceNormal;
this._state.initialViewUp = initialViewUp;
setOrientation = (sliceNormal, viewUp = [0, 1, 0]) => {
this._state.sliceNormal = sliceNormal;
this._state.viewUp = viewUp;
};

getviewUp = () => {
getViewUp = () => {
return this._state.viewUp;
};

getsliceNormal = () => {
getSliceNormal = () => {
return this._state.sliceNormal;
};

// this.setOrientation = (viewUp, sliceNormal) => {
// state.viewUp = viewUp;
// state.sliceNormal = sliceNormal;
// };

getReadOnlyViewPort = () => {
const readOnlyState = JSON.parse(JSON.stringify(this._state));

Expand Down
12 changes: 4 additions & 8 deletions src/VTKViewport/vtkInteractorStyleMPRRotate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import vtkInteractorStyleMPRSlice from './vtkInteractorStyleMPRSlice.js';
import Constants from 'vtk.js/Sources/Rendering/Core/InteractorStyle/Constants';
import { vec3, mat4 } from 'gl-matrix';
import { degrees2radians } from '../lib/math/angles.js';
import ViewportData from './ViewportData.js';

const { States } = Constants;
const MAX_SAFE_INTEGER = 2147483647;
Expand Down Expand Up @@ -43,16 +44,11 @@ function vtkInteractorStyleMPRRotate(publicAPI, model) {
const size = rwi.getView().getViewportSize(renderer);
const xSensitivity = 100.0 / size[0];
const ySensitivity = 100.0 / size[1];
const dx = Math.round((pos[0] - model.rotateStartPos[0]) * xSensitivity);
const dy = Math.round((pos[1] - model.rotateStartPos[1]) * ySensitivity);
const dThetaX = -((pos[1] - model.rotateStartPos[1]) * ySensitivity);
const dThetaY = -((pos[0] - model.rotateStartPos[0]) * xSensitivity);
const viewport = publicAPI.getViewport();
let horizontalRotation = viewport.getHRotation() + dx;
let verticalRotation = viewport.getVRotation() + dy;

horizontalRotation %= 360;
verticalRotation %= 360;

viewport.rotate(horizontalRotation, verticalRotation);
viewport.rotate(dThetaX, dThetaY);

model.rotateStartPos[0] = Math.round(pos[0]);
model.rotateStartPos[1] = Math.round(pos[1]);
Expand Down
20 changes: 7 additions & 13 deletions src/VTKViewport/vtkInteractorStyleMPRSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import vtkMouseCameraTrackballRotateManipulator from 'vtk.js/Sources/Interaction
import vtkMouseCameraTrackballPanManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseCameraTrackballPanManipulator';
import vtkMouseCameraTrackballZoomManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseCameraTrackballZoomManipulator';
import vtkMouseRangeManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseRangeManipulator';
import vtkMouseRangeRotateManipulator from './Manipulators/vtkMouseRangeRotateManipulator';
//import vtkMouseRangeRotateManipulator from './Manipulators/vtkMouseRangeRotateManipulator';
import ViewportData from './ViewportData';
import EVENTS from '../events';

Expand Down Expand Up @@ -226,8 +226,8 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
}

if (viewportData) {
setSliceNormalInternal(viewportData.getInitialSliceNormal());
setViewUpInternal(viewportData.getInitialViewUp());
setSliceNormalInternal(viewportData.getSliceNormal());
setViewUpInternal(viewportData.getViewUp());

viewportData
.getEventWindow()
Expand Down Expand Up @@ -305,8 +305,8 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
const viewportData = publicAPI.getViewport();

if (viewportData) {
setSliceNormalInternal(viewportData.getInitialSliceNormal());
setViewUpInternal(viewportData.getInitialViewUp());
setSliceNormalInternal(viewportData.getSliceNormal());
setViewUpInternal(viewportData.getViewUp());
}

updateScrollManipulator();
Expand Down Expand Up @@ -439,10 +439,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
const viewportData = publicAPI.getViewport();

if (viewportData) {
viewportData.setInitialOrientation(
normal,
viewportData.getInitialViewUp()
);
viewportData.setOrientation(normal, viewportData.getViewUp());
}

setSliceNormalInternal(normal);
Expand All @@ -463,10 +460,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
const viewportData = publicAPI.getViewport();

if (viewportData) {
viewportData.setInitialOrientation(
viewportData.getInitialSliceNormal(),
viewUp
);
viewportData.setOrientation(viewportData.getSliceNormal(), viewUp);
}

setViewUpInternal(viewUp);
Expand Down