UNPKG

@acransac/vtk.js

Version:

Visualization Toolkit for the Web

128 lines (106 loc) 4.13 kB
import macro from 'vtk.js/Sources/macro'; import { AXES, transformVec3, handleTypeFromName, } from 'vtk.js/Sources/Widgets/Widgets3D/ImageCroppingWidget/helpers'; export default function widgetBehavior(publicAPI, model) { let isDragging = null; publicAPI.setDisplayCallback = (callback) => model.representations[0].setDisplayCallback(callback); publicAPI.handleLeftButtonPress = () => { if ( !model.activeState || !model.activeState.getActive() || !model.pickable ) { return macro.VOID; } isDragging = true; model.interactor.requestAnimation(publicAPI); return macro.EVENT_ABORT; }; publicAPI.handleMouseMove = (callData) => { if (isDragging && model.pickable) { return publicAPI.handleEvent(callData); } return macro.VOID; }; publicAPI.handleLeftButtonRelease = () => { if (isDragging && model.pickable) { isDragging = false; model.interactor.cancelAnimation(publicAPI); model.widgetState.deactivate(); } }; publicAPI.handleEvent = (callData) => { if (model.pickable && model.activeState && model.activeState.getActive()) { const manipulator = model.activeState.getManipulator(); if (manipulator) { const name = model.activeState.getName(); const type = handleTypeFromName(name); const index = name.split('').map((l) => AXES.indexOf(l)); const planes = model.widgetState.getCroppingPlanes().getPlanes(); const indexToWorldT = model.widgetState.getIndexToWorldT(); let worldCoords = []; if (type === 'corners') { // manipulator should be a plane manipulator manipulator.setNormal(model.camera.getDirectionOfProjection()); worldCoords = manipulator.handleEvent( callData, model.openGLRenderWindow ); } if (type === 'faces') { // constraint axis is line defined by the index and center point. // Since our index point is defined inside a box [0, 2, 0, 2, 0, 2], // center point is [1, 1, 1]. const constraintAxis = [1 - index[0], 1 - index[1], 1 - index[2]]; // get center of current crop box const center = [ (planes[0] + planes[1]) / 2, (planes[2] + planes[3]) / 2, (planes[4] + planes[5]) / 2, ]; // manipulator should be a line manipulator manipulator.setOrigin(transformVec3(center, indexToWorldT)); manipulator.setNormal(transformVec3(constraintAxis, indexToWorldT)); worldCoords = manipulator.handleEvent( callData, model.openGLRenderWindow ); } if (type === 'edges') { // constrain to a plane with a normal parallel to the edge const edgeAxis = index.map((a) => (a === 1 ? a : 0)); manipulator.setNormal(transformVec3(edgeAxis, indexToWorldT)); worldCoords = manipulator.handleEvent( callData, model.openGLRenderWindow ); } if (worldCoords.length) { // transform worldCoords to indexCoords, and then update the croppingPlanes() state with setPlanes(). const worldToIndexT = model.widgetState.getWorldToIndexT(); const indexCoords = transformVec3(worldCoords, worldToIndexT); for (let i = 0; i < 3; i++) { if (index[i] === 0) { planes[i * 2] = indexCoords[i]; } else if (index[i] === 2) { planes[i * 2 + 1] = indexCoords[i]; } } model.activeState.setOrigin(...worldCoords); model.widgetState.getCroppingPlanes().setPlanes(...planes); return macro.EVENT_ABORT; } } } return macro.VOID; }; // -------------------------------------------------------------------------- // initialization // -------------------------------------------------------------------------- model.camera = model.renderer.getActiveCamera(); model.classHierarchy.push('vtkImageCroppingWidgetProp'); }