Skip to content

Commit

Permalink
fix(ImageCroppingRegionsWidget): Code reorganization
Browse files Browse the repository at this point in the history
  • Loading branch information
floryst committed Jan 10, 2018
1 parent ed0ff30 commit be536d9
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import macro from 'vtk.js/Sources/macro';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkCellPicker from 'vtk.js/Sources/Rendering/Core/CellPicker';
import vtkWidgetRepresentation from 'vtk.js/Sources/Interaction/Widgets/WidgetRepresentation';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
Expand All @@ -15,93 +14,45 @@ const { Orientation } = WidgetConstants;
// vtkImageCroppingRegionsRepresentation methods
// ----------------------------------------------------------------------------

// Reorders a bounds array such that each (a,b) pairing is a
// (min,max) pairing.
function reorderBounds(bounds) {
for (let i = 0; i < 6; i += 2) {
if (bounds[i] > bounds[i + 1]) {
const tmp = bounds[i + 1];
bounds[i + 1] = bounds[i];
bounds[i] = tmp;
}
}
}

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

// this is called at the end of the enclosing function.
function constructor() {
// set fields from parent classes
model.placeFactor = 1;

model.initialBounds = [0, 1, 0, 1, 0, 1];
// Format:
// [xmin, xmax, ymin, ymax, zmin, zmax]
model.planePositions = [0, 0, 0, 0, 0, 0];
model.sliceOrientation = Orientation.XY;
model.slice = 0;

// construct region polydata
model.regionPolyData = vtkPolyData.newInstance();
model.regionPolyData.getPoints().setData(new Float32Array(16 * 3), 3);

// This is a separate vtkPolyData for the center region
model.centerRegionPolyData = vtkPolyData.newInstance();
model.centerRegionPolyData.getPoints().setData(new Float32Array(4 * 3), 3);

/*
15-14-----11-10
| |
12 13-----8 9
| | | |
3 2------7 6
| |
0--1------4--5
*/
// set polys

// prettier-ignore
model.regionPolyData
.getPolys()
.setData(
new Uint32Array([
4, 0, 1, 2, 3,
4, 1, 4, 7, 2,
4, 4, 5, 6, 7,
4, 7, 6, 9, 8,
4, 8, 9, 10, 11,
4, 13, 8, 11, 14,
4, 12, 13, 14, 15,
4, 3, 2, 13, 12,
]),
1,
);
model.centerRegionPolyData
.getPolys()
.setData(new Uint32Array([4, 0, 1, 2, 3]), 1);

model.mapper = vtkMapper.newInstance();
model.actor = vtkActor.newInstance();
model.centerMapper = vtkMapper.newInstance();
model.centerActor = vtkActor.newInstance();

model.mapper.setInputData(model.regionPolyData);
model.actor.setMapper(model.mapper);
model.actor.getProperty().setEdgeVisibility(true);
publicAPI.setEdgeColor(...model.edgeColor);
publicAPI.setOpacity(model.opacity);

model.centerMapper.setInputData(model.centerRegionPolyData);
model.centerActor.setMapper(model.centerMapper);

// set picker
model.cursorPicker = vtkCellPicker.newInstance();
}
// set fields from parent classes
model.placeFactor = 1;

publicAPI.getActors = () => [model.actor, model.centerActor];
publicAPI.getNestedProps = () => publicAPI.getActors();
model.initialBounds = [0, 1, 0, 1, 0, 1];
// Format:
// [xmin, xmax, ymin, ymax, zmin, zmax]
model.planePositions = [0, 0, 0, 0, 0, 0];
model.sliceOrientation = Orientation.XY;
model.slice = 0;

// Reorders a bounds array such that each (a,b) pairing is a
// (min,max) pairing.
function reorderBounds(bounds) {
for (let i = 0; i < 6; i += 2) {
if (bounds[i] > bounds[i + 1]) {
const tmp = bounds[i + 1];
bounds[i + 1] = bounds[i];
bounds[i] = tmp;
}
}
}
model.regionPolyData = vtkPolyData.newInstance();
model.regionPolyData.getPoints().setData(new Float32Array(16 * 3), 3);

// This is a separate vtkPolyData for the center region
model.centerRegionPolyData = vtkPolyData.newInstance();
model.centerRegionPolyData.getPoints().setData(new Float32Array(4 * 3), 3);

model.mapper = vtkMapper.newInstance();
model.actor = vtkActor.newInstance();
model.centerMapper = vtkMapper.newInstance();
model.centerActor = vtkActor.newInstance();

// methods

function updateCenterOpacity() {
const slicePos = model.slice;
Expand Down Expand Up @@ -134,6 +85,9 @@ function vtkImageCroppingRegionsRepresentation(publicAPI, model) {
.setOpacity(centerInvisible ? 0 : model.opacity);
}

publicAPI.getActors = () => [model.actor, model.centerActor];
publicAPI.getNestedProps = () => publicAPI.getActors();

publicAPI.placeWidget = (...bounds) => {
const boundsArray = [];

Expand Down Expand Up @@ -232,6 +186,7 @@ function vtkImageCroppingRegionsRepresentation(publicAPI, model) {
publicAPI.updateGeometry();
};

// Force update the geometry
publicAPI.updateGeometry = () => {
const slicePos = model.slice;
const verts = model.regionPolyData.getPoints().getData();
Expand Down Expand Up @@ -340,16 +295,55 @@ function vtkImageCroppingRegionsRepresentation(publicAPI, model) {
model.validPick = 1;
model.placed = 1;
}

/*
15-14-----11-10
| |
12 13-----8 9
| | | |
3 2------7 6
| |
0--1------4--5
*/
// set polys

// prettier-ignore
model.regionPolyData
.getPolys()
.setData(
new Uint32Array([
4, 0, 1, 2, 3,
4, 1, 4, 7, 2,
4, 4, 5, 6, 7,
4, 7, 6, 9, 8,
4, 8, 9, 10, 11,
4, 13, 8, 11, 14,
4, 12, 13, 14, 15,
4, 3, 2, 13, 12,
]),
1,
);
model.centerRegionPolyData
.getPolys()
.setData(new Uint32Array([4, 0, 1, 2, 3]), 1);

model.mapper.setInputData(model.regionPolyData);
model.actor.setMapper(model.mapper);
model.actor.getProperty().setEdgeVisibility(true);

model.centerMapper.setInputData(model.centerRegionPolyData);
model.centerActor.setMapper(model.centerMapper);

publicAPI.setEdgeColor(...model.edgeColor);
publicAPI.setOpacity(model.opacity);

publicAPI.modified();
}
};

publicAPI.setProperty = (property) => {
model.actor.setProperty(property);
};

// invoke the constructor after setting up public methods
constructor();
}

// ----------------------------------------------------------------------------
Expand Down
108 changes: 58 additions & 50 deletions Sources/Interaction/Widgets/ImageCroppingRegionsWidget/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,29 @@ const events = [
// vtkImageCroppingRegionsWidget methods
// ----------------------------------------------------------------------------

// Returns cursor name based on widget state
function getCursorState(state) {
switch (state) {
case WidgetState.MOVE_LEFT:
case WidgetState.MOVE_RIGHT:
return 'ew-resize';

case WidgetState.MOVE_BOTTOM:
case WidgetState.MOVE_TOP:
return 'ns-resize';

case WidgetState.MOVE_LEFT_BOTTOM:
case WidgetState.MOVE_LEFT_TOP:
case WidgetState.MOVE_RIGHT_BOTTOM:
case WidgetState.MOVE_RIGHT_TOP:
return 'all-scroll';

case WidgetState.IDLE:
default:
return 'default';
}
}

function vtkImageCroppingRegionsWidget(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkImageCroppingRegionsWidget');
Expand All @@ -28,45 +51,6 @@ function vtkImageCroppingRegionsWidget(publicAPI, model) {
let widgetState = WidgetState.IDLE;
let isCropMoving = false;

// sets cursor based on widget state
function setCursor(state) {
switch (state) {
case WidgetState.MOVE_LEFT:
case WidgetState.MOVE_RIGHT:
model.interactor.getView().setCursor('ew-resize');
break;

case WidgetState.MOVE_BOTTOM:
case WidgetState.MOVE_TOP:
model.interactor.getView().setCursor('ns-resize');
break;

case WidgetState.MOVE_LEFT_BOTTOM:
case WidgetState.MOVE_LEFT_TOP:
case WidgetState.MOVE_RIGHT_BOTTOM:
case WidgetState.MOVE_RIGHT_TOP:
model.interactor.getView().setCursor('all-scroll');
break;

case WidgetState.IDLE:
default:
model.interactor.getView().setCursor('default');
}
}

function updateWidget() {
const data = model.volumeMapper.getInputData();
const origin = data.getOrigin();
const spacing = data.getSpacing();
const slice =
origin[model.sliceOrientation] +
spacing[model.sliceOrientation] * model.slice;

model.widgetRep.setSliceOrientation(model.sliceOrientation);
// set the widget slice + 1 to prevent z fighting
model.widgetRep.setSlice(slice + 1);
}

// Overriden method
publicAPI.createDefaultRepresentation = () => {
if (!model.widgetRep) {
Expand Down Expand Up @@ -115,12 +99,16 @@ function vtkImageCroppingRegionsWidget(publicAPI, model) {
if (i) {
publicAPI.listenEvents();
}

publicAPI.modified();
};

publicAPI.setVolumeMapper = (volumeMapper) => {
model.volumeMapper = volumeMapper;
if (model.enabled) {
publicAPI.updateRepresentation();
if (volumeMapper !== model.volumeMapper) {
model.volumeMapper = volumeMapper;
if (model.enabled) {
publicAPI.updateRepresentation();
}
}
};

Expand All @@ -137,20 +125,40 @@ function vtkImageCroppingRegionsWidget(publicAPI, model) {
const bounds = model.volumeMapper.getBounds();

model.widgetRep.placeWidget(...bounds);
updateWidget();
publicAPI.updateWidget();
};

// Force a widget update
publicAPI.updateWidget = () => {
const data = model.volumeMapper.getInputData();
const origin = data.getOrigin();
const spacing = data.getSpacing();
const slice =
origin[model.sliceOrientation] +
spacing[model.sliceOrientation] * model.slice;

model.widgetRep.setSliceOrientation(model.sliceOrientation);
// set the widget representation slice + 1 to prevent z fighting
model.widgetRep.setSlice(slice + 1);

publicAPI.modified();
};

publicAPI.setSlice = (slice) => {
model.slice = slice;
if (model.enabled) {
updateWidget();
if (slice !== model.slice) {
model.slice = slice;
if (model.enabled) {
publicAPI.updateWidget();
}
}
};

publicAPI.setSliceOrientation = (sliceOrientation) => {
model.sliceOrientation = sliceOrientation;
if (model.enabled) {
updateWidget();
if (sliceOrientation !== model.sliceOrientation) {
model.sliceOrientation = sliceOrientation;
if (model.enabled) {
publicAPI.updateWidget();
}
}
};

Expand Down Expand Up @@ -332,7 +340,7 @@ function vtkImageCroppingRegionsWidget(publicAPI, model) {
widgetState = WidgetState.IDLE;
}

setCursor(widgetState);
model.interactor.getView().setCursor(getCursorState(widgetState));
return VOID;
};

Expand Down

0 comments on commit be536d9

Please sign in to comment.