import Constants from 'vtk.js/Sources/Interaction/Widgets/LineRepresentation/Constants'; import macro from 'vtk.js/Sources/macro'; import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; import vtkBox from 'vtk.js/Sources/Common/DataModel/Box'; import vtkLine from 'vtk.js/Sources/Common/DataModel/Line'; import vtkLineSource from 'vtk.js/Sources/Filters/Sources/LineSource'; import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import vtkProperty from 'vtk.js/Sources/Rendering/Core/Property'; import vtkSphereHandleRepresentation from 'vtk.js/Sources/Interaction/Widgets/SphereHandleRepresentation'; import vtkWidgetRepresentation from 'vtk.js/Sources/Interaction/Widgets/WidgetRepresentation'; import { InteractionState } from '../HandleRepresentation/Constants';
const { State, Restrict } = Constants;
function vtkLineRepresentation(publicAPI, model) { model.classHierarchy.push('vtkLineRepresentation');
const superClass = { ...publicAPI };
publicAPI.setResolution = (res) => { model.lineSource.setResolution(res); };
publicAPI.setLineVisibility = (visibility) => { model.lineActor.setVisibility(visibility); };
publicAPI.setPoint1Visibility = (visibility) => { model.point1Representation.getActors()[0].setVisibility(visibility); };
publicAPI.setPoint2Visibility = (visibility) => { model.point2Representation.getActors()[0].setVisibility(visibility); };
publicAPI.getResolution = () => model.lineSource.getResolution();
publicAPI.getPoint1WorldPosition = () => model.point1Representation.getWorldPosition();
publicAPI.getPoint2WorldPosition = () => model.point2Representation.getWorldPosition();
publicAPI.getPoint1DisplayPosition = () => model.point1Representation.getDisplayPosition();
publicAPI.getPoint2DisplayPosition = () => model.point2Representation.getDisplayPosition();
publicAPI.setPoint1WorldPosition = (pos) => { model.point1Representation.setWorldPosition(pos); model.lineSource.setPoint1(...pos); };
publicAPI.setPoint2WorldPosition = (pos) => { model.point2Representation.setWorldPosition(pos); model.lineSource.setPoint2(...pos); };
publicAPI.setPoint1DisplayPosition = (pos) => { model.point1Representation.setDisplayPosition(pos); const p = model.point1Representation.getWorldPosition(); model.point1Representation.setWorldPosition(p); };
publicAPI.setPoint2DisplayPosition = (pos) => { model.point2Representation.setDisplayPosition(pos); const p = model.point2Representation.getWorldPosition(); model.point2Representation.setWorldPosition(p); };
publicAPI.setRenderer = (renderer) => { model.point1Representation.setRenderer(renderer); model.point2Representation.setRenderer(renderer); superClass.setRenderer(renderer); };
publicAPI.startComplexWidgetInteraction = (startEventPos) => { model.startEventPosition[0] = startEventPos[0]; model.startEventPosition[1] = startEventPos[1]; model.startEventPosition[2] = 0.0;
model.lastEventPosition[0] = startEventPos[0]; model.lastEventPosition[1] = startEventPos[1]; model.lastEventPosition[2] = 0.0;
model.startP1 = model.point1Representation.getWorldPosition(); model.startP2 = model.point2Representation.getWorldPosition();
if (model.interactionState === State.SCALING) { const dp1 = model.point1Representation.getDisplayPosition(); const dp2 = model.point2Representation.getDisplayPosition(); model.length = Math.sqrt( (dp1[0] - dp2[0]) * (dp1[0] - dp2[0]) + (dp1[1] - dp2[1]) * (dp1[1] - dp2[1]) ); } };
publicAPI.complexWidgetInteraction = (e) => { if (model.interactionState === State.ONP1) { if (model.restrictFlag !== 0) { const x = model.point1Representation.getWorldPosition(); for (let i = 0; i < 3; i++) { x[i] = model.restrictFlag === i + 1 ? x[i] : model.startP1[i]; } model.point1Representation.setWorldPosition(x); } } else if (model.interactionState === State.ONP2) { if (model.restrictFlag !== 0) { const x = model.point2Representation.getWorldPosition(); for (let i = 0; i < 3; i++) { x[i] = model.restrictFlag === i + 1 ? x[i] : model.startP2[i]; } model.point2Representation.setWorldPosition(x); } } else if (model.interactionState === State.ONLINE) { } else if (model.interactionState === State.SCALING) { } else if (model.interactionState === State.TRANSLATINGP1) { const x = model.point1Representation.getWorldPosition(); const p2 = []; for (let i = 0; i < 3; i++) { p2[i] = model.startP2[i] + (x[i] - model.startP1[i]); } model.point1Representation.setWorldPosition(p2); } else if (model.interactionState === State.TRANSLATINGP2) { const x = model.point2Representation.getWorldPosition(); const p2 = []; for (let i = 0; i < 3; i++) { p2[i] = model.startP1[i] + (x[i] - model.startP2[i]); } model.point2Representation.setWorldPosition(p2); }
model.lastEventPosition[0] = e[0]; model.lastEventPosition[1] = e[1]; model.lastEventPosition[2] = 0.0; publicAPI.modified(); };
publicAPI.placeWidget = (...bounds) => { let boundsArray = [];
if (Array.isArray(bounds[0])) { boundsArray = bounds[0]; } else { for (let i = 0; i < bounds.length; i++) { boundsArray.push(bounds[i]); } }
if (boundsArray.length !== 6) { return; }
const placeFactorTemp = model.placeFactor; model.placeFactor = 1.0; const newBounds = []; const center = []; publicAPI.adjustBounds(boundsArray, newBounds, center); model.placeFactor = placeFactorTemp;
for (let i = 0; i < 6; i++) { model.initialBounds[i] = newBounds[i]; } model.initialLength = Math.sqrt( (newBounds[1] - newBounds[0]) * (newBounds[1] - newBounds[0]) + (newBounds[3] - newBounds[2]) * (newBounds[3] - newBounds[2]) + (newBounds[5] - newBounds[4]) * (newBounds[5] - newBounds[4]) );
const p1 = model.lineSource.getPoint1(); const p2 = model.lineSource.getPoint2();
const r = [ model.initialLength * (p1[0] - p2[0]), model.initialLength * (p1[1] - p2[1]), model.initialLength * (p1[2] - p2[2]), ]; const o = [center[0] - r[0], center[1] - r[1], center[2] - r[2]];
const placedP1 = []; const t = []; vtkBox.intersectBox(boundsArray, o, r, placedP1, t); publicAPI.setPoint1WorldPosition(placedP1);
r[0] = model.initialLength * (p2[0] - p1[0]); r[1] = model.initialLength * (p2[1] - p1[1]); r[2] = model.initialLength * (p2[2] - p1[2]); o[0] = center[0] - r[0]; o[1] = center[1] - r[1]; o[2] = center[2] - r[2]; const placedP2 = []; vtkBox.intersectBox(boundsArray, o, r, placedP2, t); publicAPI.setPoint2WorldPosition(placedP2);
model.placed = 1; model.validPick = 1; publicAPI.buildRepresentation(); };
publicAPI.computeInteractionState = (pos) => { const p1State = model.point1Representation.computeInteractionState(pos); const p2State = model.point2Representation.computeInteractionState(pos); if (p1State === InteractionState.SELECTING) { model.interactionState = State.ONP1; publicAPI.setRepresentationState(State.ONP1); } else if (p2State === InteractionState.SELECTING) { model.interactionState = State.ONP2; publicAPI.setRepresentationState(State.ONP2); } else { model.interactionState = State.OUTSIDE; }
if (model.interactionState !== State.OUTSIDE) { return model.interactionState; }
let pos1 = publicAPI.getPoint1DisplayPosition(); let pos2 = publicAPI.getPoint2DisplayPosition(); const xyz = [pos[0], pos[1], 0.0]; const p1 = [pos1[0], pos1[1], 0.0]; const p2 = [pos2[0], pos2[1], 0.0]; const tol = model.tolerance * model.tolerance;
const out = vtkLine.distanceToLine(xyz, p1, p2); const onLine = out.distance <= tol; if (onLine && out.t < 1.0 && out.t > 0.0) { model.interactionState = State.ONLINE; publicAPI.setRepresentationState(State.ONLINE); pos1 = publicAPI.getPoint1WorldPosition(); pos2 = publicAPI.getPoint2WorldPosition(); } else { model.interactionState = State.OUTSIDE; publicAPI.setRepresentationState(State.OUTSIDE); }
return model.interactionState; };
publicAPI.setRepresentationState = (state) => { if (model.representationState === state) { return; } model.representationState = state; publicAPI.modified();
if (state === State.OUTSIDE) { publicAPI.highlightPoint(0, 0); publicAPI.highlightPoint(1, 0); publicAPI.highlightLine(0); } else if (state === State.ONP1) { publicAPI.highlightPoint(0, 1); publicAPI.highlightPoint(1, 0); publicAPI.highlightLine(0); } else if (state === State.ONP2) { publicAPI.highlightPoint(0, 0); publicAPI.highlightPoint(1, 1); publicAPI.highlightLine(0); } else if (state === State.ONLINE) { publicAPI.highlightPoint(0, 0); publicAPI.highlightPoint(1, 0); publicAPI.highlightLine(1); } else { publicAPI.highlightPoint(0, 1); publicAPI.highlightPoint(1, 1); publicAPI.highlightLine(1); } };
publicAPI.sizeHandles = () => { };
publicAPI.buildRepresentation = () => { model.point1Representation.buildRepresentation(); model.point2Representation.buildRepresentation();
if (model.initializeDisplayPosition === 0 && model.renderer) { publicAPI.setPoint1WorldPosition(model.lineSource.getPoint1()); publicAPI.setPoint2WorldPosition(model.lineSource.getPoint2()); model.validPick = 1; model.initializeDisplayPosition = 1; }
model.point1Representation.setTolerance(model.tolerance); model.point2Representation.setTolerance(model.tolerance);
const x1 = publicAPI.getPoint1WorldPosition(); model.lineSource.setPoint1(...x1); model.point1Representation.setWorldPosition(x1);
const x2 = publicAPI.getPoint2WorldPosition(); model.lineSource.setPoint2(...x2); model.point2Representation.setWorldPosition(x2);
publicAPI.sizeHandles(); publicAPI.modified(); };
publicAPI.highlightPoint = (pointId, highlight) => { if (pointId === 0) { if (highlight) { model.point1Representation.applyProperty( model.selectedEndPointProperty ); } else { model.point1Representation.applyProperty(model.endPointProperty); } } else if (pointId === 1) { if (highlight) { model.point2Representation.applyProperty( model.selectedEndPoint2Property ); } else { model.point2Representation.applyProperty(model.endPoint2Property); } } else { } };
publicAPI.highlightLine = (highlight) => { if (highlight) { model.lineActor.setProperty(model.selectedLineProperty); } else { model.lineActor.setProperty(model.lineProperty); } };
publicAPI.setLineColor = (...color) => { let col = [];
if (Array.isArray(color[0])) { col = color[0]; } else { for (let i = 0; i < color.length; i++) { col.push(color[i]); } }
if (col.length !== 3) { return; }
if (model.lineActor.getProperty()) { model.lineActor.getProperty().setColor(col[0], col[1], col[2]); } };
publicAPI.clampPosition = (x) => { for (let i = 0; i < 3; i++) { if (x[i] < model.initialBounds[2 * i]) { x[i] = model.initialBounds[2 * i]; } if (x[i] > model.initialBounds[2 * i + 1]) { x[i] = model.initialBounds[2 * i + 1]; } } };
publicAPI.getBounds = () => { model.boundingBox.setBounds(model.lineActor.getBounds()); model.boundingBox.addBounds(model.point1Representation.getBounds()); model.boundingBox.addBounds(model.point2Representation.getBounds());
return model.boundingBox.getBounds(); };
publicAPI.getActors = () => { const actors = []; actors.push(...model.point1Representation.getActors()); actors.push(...model.point2Representation.getActors()); actors.push(model.lineActor); return actors; };
publicAPI.getNestedProps = () => publicAPI.getActors(); }
const DEFAULT_VALUES = { point1Representation: null, point2Representation: null, lineSource: null, lineMapper: null, lineActor: null, endPointProperty: null, selectedEndPointProperty: null, endPoint2Property: null, selectedEndPoint2Property: null, lineProperty: null, selectedLineProperty: null, tolerance: 5, placed: 0, representationState: State.OUTSIDE, startP1: [0.0, 0.0, 0.0], startP2: [0.0, 0.0, 0.0], length: 0.0, restrictFlag: Restrict.NONE, initializeDisplayPosition: 0, boundingBox: null, };
export function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues);
vtkWidgetRepresentation.extend(publicAPI, model, initialValues);
macro.get(publicAPI, model, [ 'point1Representation', 'point2Representation', 'endPointProperty', 'selectedEndPointProperty', 'endPoint2Property', 'selectedEndPoint2Property', 'lineProperty', 'selectedLineProperty', ]);
publicAPI.setHandleSize(5); model.boundingBox = vtkBox.newInstance(); model.point1Representation = vtkSphereHandleRepresentation.newInstance(); model.point2Representation = vtkSphereHandleRepresentation.newInstance(); const handleSize = 10; model.point1Representation.setHandleSize(handleSize); model.point2Representation.setHandleSize(handleSize);
model.lineSource = vtkLineSource.newInstance({ point1: [-0.5, 0, 0], point2: [0.5, 0, 0], resolution: 5, }); model.lineSource.setResolution(5); model.lineMapper = vtkMapper.newInstance(); model.lineMapper.setInputConnection(model.lineSource.getOutputPort()); model.lineActor = vtkActor.newInstance(); model.lineActor.setMapper(model.lineMapper);
model.endPointProperty = vtkProperty.newInstance(); model.endPointProperty.setColor(1, 1, 1); model.selectedEndPointProperty = vtkProperty.newInstance(); model.selectedEndPointProperty.setColor(0, 1, 0); model.endPoint2Property = vtkProperty.newInstance(); model.endPoint2Property.setColor(1, 1, 1); model.selectedEndPoint2Property = vtkProperty.newInstance(); model.selectedEndPoint2Property.setColor(0, 1, 0); model.lineProperty = vtkProperty.newInstance(); model.lineProperty.setAmbient(1.0); model.lineProperty.setAmbientColor(1.0, 1.0, 1.0); model.lineProperty.setLineWidth(2.0); model.selectedLineProperty = vtkProperty.newInstance(); model.selectedLineProperty.setAmbient(1.0); model.selectedLineProperty.setColor(0.0, 1.0, 0.0); model.selectedLineProperty.setLineWidth(2.0);
model.point1Representation.applyProperty(model.endPointProperty); model.point2Representation.applyProperty(model.endPoint2Property); model.point1Representation.setWorldPosition(model.lineSource.getPoint1()); model.point2Representation.setWorldPosition(model.lineSource.getPoint2()); model.lineActor.setProperty(model.lineProperty);
vtkLineRepresentation(publicAPI, model); }
export const newInstance = macro.newInstance(extend, 'vtkLineRepresentation');
export default { newInstance, extend };
|