InteractiveOrientationWidget

Methods

extend

Method use to decorate a given object (publicAPI+model) with vtkInteractiveOrientationWidget characteristics.

Argument Type Required Description
publicAPI Yes object on which methods will be bounds (public)
model Yes object on which data structure will be bounds (protected)
initialValues object No (default: {})

getRepresentationForViewType

Argument Type Required Description
viewType ViewTypes Yes

newInstance

Creates a new instance of vtkInteractiveOrientationWidget

Argument Type Required Description
initialValues object No for pre-setting some of its content

setBounds

Set the widget bounds

Argument Type Required Description
bounds Bounds Yes The widget bounds

Source

behavior.js
import macro from 'vtk.js/Sources/macros';

export default function widgetBehavior(publicAPI, model) {
model.classHierarchy.push('vtkInteractiveOrientationWidgetProp');
macro.event(publicAPI, model, 'OrientationChange');

// --------------------------------------------------------------------------
// Right click: Delete handle
// --------------------------------------------------------------------------

publicAPI.handleRightButtonPress = (e) => {
if (
!model.activeState ||
!model.activeState.getActive() ||
!model.pickable
) {
return macro.VOID;
}
publicAPI.invokeOrientationChange({
action: 'rightPress',
event: e,
...model.activeState.get('up', 'right', 'direction'),
});
return macro.EVENT_ABORT;
};

// --------------------------------------------------------------------------
// Left press: Select handle to drag
// --------------------------------------------------------------------------

publicAPI.handleLeftButtonPress = (e) => {
if (
!model.activeState ||
!model.activeState.getActive() ||
!model.pickable
) {
return macro.VOID;
}
publicAPI.invokeOrientationChange({
action: 'leftPress',
event: e,
...model.activeState.get('up', 'right', 'direction'),
});
return macro.EVENT_ABORT;
};
}
index.d.ts
import vtkAbstractWidgetFactory from "../../Core/AbstractWidgetFactory";
import { Bounds } from "../../../types";
import { ViewTypes } from "../../Core/WidgetManager/Constants";

export interface vtkInteractiveOrientationWidget extends vtkAbstractWidgetFactory {
/**
* Set the widget bounds
*
* @param {Bounds} bounds The widget bounds
*/
setBounds(bounds: Bounds): void;

/**
* @param {ViewTypes} viewType
*/
getRepresentationForViewType(viewType: ViewTypes): unknown;
}

/**
* Method use to decorate a given object (publicAPI+model) with vtkInteractiveOrientationWidget characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {object} [initialValues] (default: {})
*/
export function extend(publicAPI: object, model: object, initialValues? : Record<string, unknown>): void;

/**
* Creates a new instance of vtkInteractiveOrientationWidget
*
* @param {object} [initialValues] for pre-setting some of its content
*/
export function newInstance(initialValues? : Record<string, unknown>): vtkInteractiveOrientationWidget;

export declare const vtkInteractiveOrientationWidget: {
newInstance: typeof newInstance,
extend: typeof extend,
};

export default vtkInteractiveOrientationWidget;
index.js
import macro from 'vtk.js/Sources/macros';
import vtkAbstractWidgetFactory from 'vtk.js/Sources/Widgets/Core/AbstractWidgetFactory';
import vtkConvexFaceContextRepresentation from 'vtk.js/Sources/Widgets/Representations/ConvexFaceContextRepresentation';

import widgetBehavior from 'vtk.js/Sources/Widgets/Widgets3D/InteractiveOrientationWidget/behavior';
import {
INITIAL_POINTS,
generateState,
} from 'vtk.js/Sources/Widgets/Widgets3D/InteractiveOrientationWidget/state';

import { Behavior } from 'vtk.js/Sources/Widgets/Representations/WidgetRepresentation/Constants';
import { ViewTypes } from 'vtk.js/Sources/Widgets/Core/WidgetManager/Constants';

// ----------------------------------------------------------------------------
// Factory
// ----------------------------------------------------------------------------

function vtkInteractiveOrientationWidget(publicAPI, model) {
model.classHierarchy.push('vtkInteractiveOrientationWidget');

// --- Widget Requirement ---------------------------------------------------

model.methodsToLink = [
'closePolyLine',
'activeScaleFactor',
'activeColor',
'useActiveColor',
'glyphResolution',
'defaultScale',
];

publicAPI.setBounds = (bounds) => {
const handles = model.widgetState.getStatesWithLabel('handles');
for (let i = 0; i < handles.length; i++) {
const xyz = INITIAL_POINTS[i];
const x = xyz[0] > 0 ? bounds[1] : bounds[0];
const y = xyz[1] > 0 ? bounds[3] : bounds[2];
const z = xyz[2] > 0 ? bounds[5] : bounds[4];
handles[i].setOrigin(x, y, z);
}
};

publicAPI.getRepresentationsForViewType = (viewType) => {
switch (viewType) {
case ViewTypes.DEFAULT:
case ViewTypes.GEOMETRY:
case ViewTypes.SLICE:
case ViewTypes.VOLUME:
default:
return [
{
builder: vtkConvexFaceContextRepresentation,
labels: ['---', '--+', '-++', '-+-'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 1',
},
},
{
builder: vtkConvexFaceContextRepresentation,
labels: ['---', '+--', '+-+', '--+'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 2',
},
},
{
builder: vtkConvexFaceContextRepresentation,
labels: ['+--', '++-', '+++', '+-+'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 3',
},
},
{
builder: vtkConvexFaceContextRepresentation,
labels: ['++-', '-+-', '-++', '+++'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 4',
},
},
{
builder: vtkConvexFaceContextRepresentation,
labels: ['-++', '--+', '+-+', '+++'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 5',
},
},
{
builder: vtkConvexFaceContextRepresentation,
labels: ['-+-', '++-', '+--', '---'],
initialValues: {
behavior: Behavior.HANDLE,
pickable: true,
activeScaleFactor: 1.2,
activeColor: 1,
useActiveColor: true,
name: 'Face 6',
},
},
];
}
};
}

// ----------------------------------------------------------------------------

const defaultValues = (initialValues) => ({
behavior: widgetBehavior,
widgetState: generateState(),
...initialValues,
});

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, defaultValues(initialValues));

vtkAbstractWidgetFactory.extend(publicAPI, model, initialValues);

vtkInteractiveOrientationWidget(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(
extend,
'vtkInteractiveOrientationWidget'
);

// ----------------------------------------------------------------------------

export default { newInstance, extend };
state.js
import vtkStateBuilder from 'vtk.js/Sources/Widgets/Core/StateBuilder';

export const INITIAL_POINTS = [
[-1, -1, -1], // 0
[-1, 1, -1], // 1
[1, -1, -1], // 2
[1, 1, -1], // 3
[-1, -1, 1], // 4
[-1, 1, 1], // 5
[1, -1, 1], // 6
[1, 1, 1], // 7
];

export function generateState() {
return vtkStateBuilder
.createBuilder()
.addStateFromMixin({
labels: ['handles', '---'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[0],
},
})
.addStateFromMixin({
labels: ['handles', '-+-'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[1],
},
})
.addStateFromMixin({
labels: ['handles', '+--'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[2],
},
})
.addStateFromMixin({
labels: ['handles', '++-'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[3],
},
})
.addStateFromMixin({
labels: ['handles', '--+'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[4],
},
})
.addStateFromMixin({
labels: ['handles', '-++'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[5],
},
})
.addStateFromMixin({
labels: ['handles', '+-+'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[6],
},
})
.addStateFromMixin({
labels: ['handles', '+++'],
mixins: ['origin'],
name: 'handle',
initialValues: {
origin: INITIAL_POINTS[7],
},
})
.build('orientation', 'name');
}

export default generateState;