Skip to content

Commit

Permalink
feat: 🎸 Mouse wheel scrollable ref lines + pan fix (#116)
Browse files Browse the repository at this point in the history
* feat: 🎸 Mouse wheel scrollable ref lines + pan fix
* Fix placement of color indicator
* Add setGet for disable scroll
  • Loading branch information
JamesAPetts authored Oct 9, 2020
1 parent 9480282 commit d7510ba
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 54 deletions.
12 changes: 12 additions & 0 deletions examples/VTKRotatableCrosshairsExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ class VTKRotatableCrosshairsExample extends Component {
this.setState({ displayCrosshairs: shouldDisplayCrosshairs });
};

resetCrosshairs = () => {
const apis = this.apis;

apis.forEach(api => {
api.resetOrientation();
});

// Reset the crosshairs
apis[0].svgWidgets.rotatableCrosshairsWidget.resetCrosshairs(apis, 0);
};

render() {
if (!this.state.volumes || !this.state.volumes.length) {
return <h4>Loading...</h4>;
Expand Down Expand Up @@ -241,6 +252,7 @@ class VTKRotatableCrosshairsExample extends Component {
? 'Switch To WL/Zoom/Pan/Scroll'
: 'Switch To Crosshairs'}
</button>
<button onClick={this.resetCrosshairs}>reset crosshairs</button>
</div>
</div>
<div className="row">
Expand Down
19 changes: 19 additions & 0 deletions src/VTKViewport/View2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export default class View2D extends Component {
const boundUpdateVOI = this.updateVOI.bind(this);
const boundGetOrienation = this.getOrientation.bind(this);
const boundSetOrientation = this.setOrientation.bind(this);
const boundResetOrientation = this.resetOrientation.bind(this);
const boundGetViewUp = this.getViewUp.bind(this);
const boundGetSliceNormal = this.getSliceNormal.bind(this);
const boundSetInteractorStyle = this.setInteractorStyle.bind(this);
Expand Down Expand Up @@ -261,6 +262,7 @@ export default class View2D extends Component {
updateVOI: boundUpdateVOI,
getOrientation: boundGetOrienation,
setOrientation: boundSetOrientation,
resetOrientation: boundResetOrientation,
getViewUp: boundGetViewUp,
getSliceNormal: boundGetSliceNormal,
setInteractorStyle: boundSetInteractorStyle,
Expand Down Expand Up @@ -307,6 +309,23 @@ export default class View2D extends Component {
currentIStyle.setSliceOrientation(sliceNormal, viewUp);
}

resetOrientation() {
const orientation = this.props.orientation || {
sliceNormal: [0, 0, 1],
viewUp: [0, -1, 0],
};

// Reset orientation.
this.setOrientation(orientation.sliceNormal, orientation.viewUp);

// Reset slice.
const renderWindow = this.genericRenderWindow.getRenderWindow();
const currentIStyle = renderWindow.getInteractor().getInteractorStyle();
const range = currentIStyle.getSliceRange();

currentIStyle.setSlice((range[0] + range[1]) / 2);
}

getApiProperty(propertyName) {
return this.apiProperties[propertyName];
}
Expand Down
50 changes: 36 additions & 14 deletions src/VTKViewport/vtkInteractorStyleMPRSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
sliceCenter: [],
};

function updateScrollManipulator() {
publicAPI.updateScrollManipulator = () => {
const range = publicAPI.getSliceRange();
model.scrollManipulator.removeScrollListener();
// The Scroll listener has min, max, step, and getValue setValue as params.
Expand All @@ -86,15 +86,15 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
publicAPI.getSlice,
publicAPI.scrollToSlice
);
}
};

function setManipulators() {
publicAPI.removeAllMouseManipulators();
publicAPI.addMouseManipulator(model.trackballManipulator);
publicAPI.addMouseManipulator(model.panManipulator);
publicAPI.addMouseManipulator(model.zoomManipulator);
publicAPI.addMouseManipulator(model.scrollManipulator);
updateScrollManipulator();
publicAPI.updateScrollManipulator();
}

function isCameraViewInitialized(camera) {
Expand Down Expand Up @@ -219,7 +219,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
const camera = renderer.getActiveCamera();

cameraSub = camera.onModified(() => {
updateScrollManipulator();
publicAPI.updateScrollManipulator();
publicAPI.modified();
});

Expand All @@ -238,7 +238,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
// TODO -> When we want a modular framework we'll have to rethink all this.
// TODO -> We need to think of a more generic way to do this for all widget types eventually.
// TODO -> We certainly need to be able to register widget types on instantiation.
function handleButtonPress() {
function handleButtonPress(callData) {
const { apis, apiIndex } = model;

if (apis && apis[apiIndex] && apis[apiIndex].type === 'VIEW2D') {
Expand All @@ -250,11 +250,33 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
api.svgWidgets.crosshairsWidget.updateCrosshairForApi(api);
}
if (api.svgWidgets.rotatableCrosshairsWidget) {
api.svgWidgets.rotatableCrosshairsWidget.updateCrosshairForApi(api);
updateRotatableCrosshairs(callData);
}
}
}

function updateRotatableCrosshairs(callData) {
const { apis, apiIndex } = model;
const thisApi = apis[apiIndex];
const { rotatableCrosshairsWidget } = thisApi.svgWidgets;
const renderer = callData.pokedRenderer;
const worldPos = thisApi.get('cachedCrosshairWorldPosition');

const camera = renderer.getActiveCamera();
const directionOfProjection = camera.getDirectionOfProjection();

const halfSlabThickness = thisApi.getSlabThickness() / 2;

// Add half of the slab thickness to the world position, such that we select
// The center of the slice.

for (let i = 0; i < worldPos.length; i++) {
worldPos[i] += halfSlabThickness * directionOfProjection[i];
}

rotatableCrosshairsWidget.moveCrosshairs(worldPos, apis, apiIndex);
}

publicAPI.handleMiddleButtonPress = macro.chain(
publicAPI.handleMiddleButtonPress,
handleButtonPress
Expand All @@ -280,12 +302,12 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
api.svgWidgets.crosshairsWidget.updateCrosshairForApi(api);
}
if (api.svgWidgets.rotatableCrosshairsWidget) {
api.svgWidgets.rotatableCrosshairsWidget.updateCrosshairForApi(api);
updateRotatableCrosshairs(callData);
}
}
};

function handleButtonRelease(superButtonRelease) {
function handleButtonRelease(superButtonRelease, callData) {
if (model.state === States.IS_PAN) {
publicAPI.endPan();
const { apis, apiIndex } = model;
Expand All @@ -295,7 +317,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
api.svgWidgets.crosshairsWidget.updateCrosshairForApi(api);
}
if (api.svgWidgets.rotatableCrosshairsWidget) {
api.svgWidgets.rotatableCrosshairsWidget.updateCrosshairForApi(api);
updateRotatableCrosshairs(callData);
}
}

Expand All @@ -304,13 +326,13 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {

publicAPI.superHandleMiddleButtonRelease =
publicAPI.handleMiddleButtonRelease;
publicAPI.handleMiddleButtonRelease = () => {
handleButtonRelease(publicAPI.superHandleMiddleButtonRelease);
publicAPI.handleMiddleButtonRelease = callData => {
handleButtonRelease(publicAPI.superHandleMiddleButtonRelease, callData);
};

publicAPI.superHandleRightButtonRelease = publicAPI.handleRightButtonRelease;
publicAPI.handleRightButtonRelease = () => {
handleButtonRelease(publicAPI.superHandleRightButtonRelease);
publicAPI.handleRightButtonRelease = callData => {
handleButtonRelease(publicAPI.superHandleRightButtonRelease, callData);
};

publicAPI.setVolumeActor = actor => {
Expand All @@ -328,7 +350,7 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
setViewUpInternal(viewportData.getCurrentViewUp());
}

updateScrollManipulator();
publicAPI.updateScrollManipulator();
// NOTE: Disabling this because it makes it more difficult to switch
// interactor styles. Need to find a better way to do this!
//publicAPI.setSliceNormal(...publicAPI.getSliceNormal());
Expand Down
Loading

0 comments on commit d7510ba

Please sign in to comment.