@kitware/vtk.js
Version:
Visualization Toolkit for the Web
421 lines (403 loc) • 16.3 kB
JavaScript
import { m as macro } from '../../macros2.js';
import Constants from './Coordinate/Constants.js';
import { R as round, M as floor } from '../../Common/Core/Math/index.js';
const {
Coordinate
} = Constants;
const {
vtkErrorMacro
} = macro;
// ----------------------------------------------------------------------------
// vtkActor methods
// ----------------------------------------------------------------------------
function vtkCoordinate(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkCoordinate');
publicAPI.setValue = (...args) => {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return false;
}
let array = args;
// allow an array passed as a single arg.
if (array.length === 1 && Array.isArray(array[0])) {
array = array[0];
}
if (array.length === 2) {
publicAPI.setValue(array[0], array[1], 0.0);
return true;
}
if (array.length !== 3) {
throw new RangeError('Invalid number of values for array setter');
}
let changeDetected = false;
model.value.forEach((item, index) => {
if (item !== array[index]) {
if (changeDetected) {
return;
}
changeDetected = true;
}
});
if (changeDetected) {
model.value = [].concat(array);
publicAPI.modified();
}
return true;
};
publicAPI.setCoordinateSystemToDisplay = () => {
publicAPI.setCoordinateSystem(Coordinate.DISPLAY);
};
publicAPI.setCoordinateSystemToNormalizedDisplay = () => {
publicAPI.setCoordinateSystem(Coordinate.NORMALIZED_DISPLAY);
};
publicAPI.setCoordinateSystemToViewport = () => {
publicAPI.setCoordinateSystem(Coordinate.VIEWPORT);
};
publicAPI.setCoordinateSystemToNormalizedViewport = () => {
publicAPI.setCoordinateSystem(Coordinate.NORMALIZED_VIEWPORT);
};
publicAPI.setCoordinateSystemToProjection = () => {
publicAPI.setCoordinateSystem(Coordinate.PROJECTION);
};
publicAPI.setCoordinateSystemToView = () => {
publicAPI.setCoordinateSystem(Coordinate.VIEW);
};
publicAPI.setCoordinateSystemToWorld = () => {
publicAPI.setCoordinateSystem(Coordinate.WORLD);
};
publicAPI.getCoordinateSystemAsString = () => macro.enumToString(Coordinate, model.coordinateSystem);
publicAPI.getComputedWorldValue = ren => {
let val = model.computedWorldValue;
if (model.computing) {
return val;
}
model.computing = 1;
val[0] = model.value[0];
val[1] = model.value[1];
val[2] = model.value[2];
// Use our renderer if is defined
let renderer = ren;
if (model.renderer) {
renderer = model.renderer;
}
if (!renderer) {
if (model.coordinateSystem === Coordinate.WORLD) {
if (model.referenceCoordinate) {
const refValue = model.referenceCoordinate.getComputedWorldValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
val[2] += refValue[2];
}
model.computing = 0;
} else {
vtkErrorMacro('Attempt to compute world coordinates from another coordinate system without a renderer');
}
return val;
}
// convert to current coordinate system
let view = null;
if (renderer && renderer.getRenderWindow().getViews()) {
view = renderer.getRenderWindow().getViews()[0];
} else {
return model.computedWorldValue;
}
const dims = view.getViewportSize(renderer);
const aspect = dims[0] / dims[1];
if (model.referenceCoordinate && model.coordinateSystem !== Coordinate.WORLD) {
const fval = model.referenceCoordinate.getComputedDoubleDisplayValue(renderer);
let refValue = [fval[0], fval[1], 0.0];
switch (model.coordinateSystem) {
case Coordinate.NORMALIZED_DISPLAY:
refValue = view.displayToNormalizedDisplay(refValue[0], refValue[1], refValue[2]);
break;
case Coordinate.VIEWPORT:
refValue = view.displayToNormalizedDisplay(refValue[0], refValue[1], refValue[2]);
refValue = view.normalizedDisplayToViewport(refValue[0], refValue[1], refValue[2], renderer);
break;
case Coordinate.NORMALIZED_VIEWPORT:
refValue = view.displayToNormalizedDisplay(refValue[0], refValue[1], refValue[2]);
refValue = view.normalizedDisplayToViewport(refValue[0], refValue[1], refValue[2], renderer);
refValue = view.viewportToNormalizedViewport(refValue[0], refValue[1], refValue[2], renderer);
break;
case Coordinate.PROJECTION:
refValue = view.displayToNormalizedDisplay(refValue[0], refValue[1], refValue[2]);
refValue = view.normalizedDisplayToViewport(refValue[0], refValue[1], refValue[2], renderer);
refValue = view.viewportToNormalizedViewport(refValue[0], refValue[1], refValue[2], renderer);
refValue = renderer.normalizedViewportToProjection(refValue[0], refValue[1], refValue[2]);
break;
case Coordinate.VIEW:
refValue = view.displayToNormalizedDisplay(refValue[0], refValue[1], refValue[2]);
refValue = view.normalizedDisplayToViewport(refValue[0], refValue[1], refValue[2], renderer);
refValue = view.viewportToNormalizedViewport(refValue[0], refValue[1], refValue[2], renderer);
refValue = renderer.normalizedViewportToProjection(refValue[0], refValue[1], refValue[2]);
refValue = renderer.projectionToView(refValue[0], refValue[1], refValue[2], aspect);
break;
}
val[0] += refValue[0];
val[1] += refValue[1];
val[2] += refValue[2];
}
switch (model.coordinateSystem) {
case Coordinate.DISPLAY:
val = view.displayToNormalizedDisplay(val[0], val[1], val[2]);
val = view.normalizedDisplayToViewport(val[0], val[1], val[2], renderer);
val = view.viewportToNormalizedViewport(val[0], val[1], val[2], renderer);
val = renderer.normalizedViewportToProjection(val[0], val[1], val[2]);
val = renderer.projectionToView(val[0], val[1], val[2], aspect);
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
case Coordinate.NORMALIZED_DISPLAY:
val = view.normalizedDisplayToViewport(val[0], val[1], val[2], renderer);
val = view.viewportToNormalizedViewport(val[0], val[1], val[2], renderer);
val = renderer.normalizedViewportToProjection(val[0], val[1], val[2]);
val = renderer.projectionToView(val[0], val[1], val[2], aspect);
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
case Coordinate.VIEWPORT:
val = view.viewportToNormalizedViewport(val[0], val[1], val[2], renderer);
val = renderer.normalizedViewportToProjection(val[0], val[1], val[2]);
val = renderer.projectionToView(val[0], val[1], val[2], aspect);
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
case Coordinate.NORMALIZED_VIEWPORT:
val = renderer.normalizedViewportToProjection(val[0], val[1], val[2]);
val = renderer.projectionToView(val[0], val[1], val[2], aspect);
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
case Coordinate.PROJECTION:
val = renderer.projectionToView(val[0], val[1], val[2], aspect);
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
case Coordinate.VIEW:
val = renderer.viewToWorld(val[0], val[1], val[2]);
break;
}
if (model.referenceCoordinate && model.coordinateSystem === Coordinate.WORLD) {
const refValue = publicAPI.getComputedWorldValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
val[2] += refValue[2];
}
model.computing = 0;
model.computedWorldValue = val.slice(0);
return val;
};
publicAPI.getComputedViewportValue = ren => {
const f = publicAPI.getComputedDoubleViewportValue(ren);
return [round(f[0]), round(f[1])];
};
publicAPI.getComputedDisplayValue = ren => {
const val = publicAPI.getComputedDoubleDisplayValue(ren);
return [floor(val[0]), floor(val[1])];
};
publicAPI.getComputedLocalDisplayValue = ren => {
// Use our renderer if it is defined
let renderer = ren;
if (model.renderer) {
renderer = model.renderer;
}
let val = publicAPI.getComputedDisplayValue(renderer);
if (!renderer) {
vtkErrorMacro('Attempt to convert to local display coordinates without a renderer');
return val;
}
let view = null;
if (renderer && renderer.getRenderWindow().getViews()) {
view = renderer.getRenderWindow().getViews()[0];
} else {
return val;
}
val = view.displayToLocalDisplay(val[0], val[1], val[2]);
return [round(val[0]), round(val[1])];
};
publicAPI.getComputedDoubleViewportValue = ren => {
let renderer = ren;
if (model.renderer) {
renderer = model.renderer;
}
let val = publicAPI.getComputedDoubleDisplayValue(renderer);
if (!renderer) {
return val;
}
let view = null;
if (renderer && renderer.getRenderWindow().getViews()) {
view = renderer.getRenderWindow().getViews()[0];
} else {
return val;
}
val = view.displayToNormalizedDisplay(val[0], val[1], val[2]);
val = view.normalizedDisplayToViewport(val[0], val[1], val[2], renderer);
return [val[0], val[1]];
};
publicAPI.getComputedDoubleDisplayValue = ren => {
if (model.computing) {
return model.computedDoubleDisplayValue;
}
model.computing = 1;
let val = model.value.slice(0);
let renderer = ren;
if (model.renderer) {
renderer = model.renderer;
}
if (!renderer) {
if (model.coordinateSystem === Coordinate.DISPLAY) {
model.computedDoubleDisplayValue[0] = val[0];
model.computedDoubleDisplayValue[1] = val[1];
if (model.referenceCoordinate) {
const refValue = model.referenceCoordinate.getComputedDoubleDisplayValue();
model.computedDoubleDisplayValue[0] += refValue[0];
model.computedDoubleDisplayValue[1] += refValue[1];
}
} else {
model.computedDoubleDisplayValue[0] = Number.MAX_VALUE;
model.computedDoubleDisplayValue[1] = Number.MAX_VALUE;
vtkErrorMacro('Request for coordinate transformation without required viewport');
}
return model.computedDoubleDisplayValue;
}
let view = null;
if (renderer && renderer.getRenderWindow().getViews()) {
view = renderer.getRenderWindow().getViews()[0];
} else {
return val;
}
const dims = view.getViewportSize(renderer);
const aspect = dims[0] / dims[1];
switch (model.coordinateSystem) {
case Coordinate.WORLD:
{
if (model.referenceCoordinate) {
const refValue = model.referenceCoordinate.getComputedWorldValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
val[2] += refValue[2];
}
val = renderer.worldToView(val[0], val[1], val[2]);
val = renderer.viewToProjection(val[0], val[1], val[2], aspect);
val = renderer.projectionToNormalizedViewport(val[0], val[1], val[2]);
val = view.normalizedViewportToViewport(val[0], val[1], val[2], renderer);
val = view.viewportToNormalizedDisplay(val[0], val[1], val[2], renderer);
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
}
case Coordinate.VIEW:
{
val = renderer.viewToProjection(val[0], val[1], val[2], aspect);
val = renderer.projectionToNormalizedViewport(val[0], val[1], val[2]);
val = view.normalizedViewportToViewport(val[0], val[1], val[2], renderer);
val = view.viewportToNormalizedDisplay(val[0], val[1], val[2], renderer);
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
}
case Coordinate.PROJECTION:
{
val = renderer.projectionToNormalizedViewport(val[0], val[1], val[2]);
val = view.normalizedViewportToViewport(val[0], val[1], val[2], renderer);
val = view.viewportToNormalizedDisplay(val[0], val[1], val[2], renderer);
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
}
case Coordinate.NORMALIZED_VIEWPORT:
{
val = view.normalizedViewportToViewport(val[0], val[1], val[2], renderer);
if (model.referenceCoordinate) {
const refValue = model.referenceCoordinate.getComputedDoubleViewportValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
}
val = view.viewportToNormalizedDisplay(val[0], val[1], val[2], renderer);
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
}
case Coordinate.VIEWPORT:
{
if (model.referenceCoordinate) {
const refValue = model.referenceCoordinate.getComputedDoubleViewportValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
}
val = view.viewportToNormalizedDisplay(val[0], val[1], val[2], renderer);
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
}
case Coordinate.NORMALIZED_DISPLAY:
val = view.normalizedDisplayToDisplay(val[0], val[1], val[2]);
break;
case Coordinate.USERDEFINED:
val = model.value.slice(0);
break;
}
// if we have a reference coordinate and we haven't handled it yet
if (model.referenceCoordinate && (model.coordinateSystem === Coordinate.DISPLAY || model.coordinateSystem === Coordinate.NORMALIZED_DISPLAY)) {
const refValue = model.referenceCoordinate.getComputedDoubleDisplayValue(renderer);
val[0] += refValue[0];
val[1] += refValue[1];
}
model.computedDoubleDisplayValue[0] = val[0];
model.computedDoubleDisplayValue[1] = val[1];
model.computing = 0;
return model.computedDoubleDisplayValue;
};
publicAPI.getComputedValue = ren => {
let renderer = ren;
if (model.renderer) {
renderer = model.renderer;
}
switch (model.coordinateSystem) {
case Coordinate.WORLD:
return publicAPI.getComputedWorldValue(renderer);
case Coordinate.VIEW:
case Coordinate.NORMALIZED_VIEWPORT:
case Coordinate.VIEWPORT:
{
const val = publicAPI.getComputedViewportValue(renderer);
model.computedWorldValue[0] = val[0];
model.computedWorldValue[1] = val[1];
break;
}
case Coordinate.NORMALIZED_DISPLAY:
case Coordinate.DISPLAY:
{
const val = model.getComputedDisplayValue(renderer);
model.computedWorldValue[0] = val[0];
model.computedWorldValue[1] = val[1];
break;
}
}
return model.computedWorldValue;
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
coordinateSystem: Coordinate.WORLD,
value: [0.0, 0.0, 0.0],
renderer: null,
referenceCoordinate: null,
computing: 0,
computedWorldValue: [0.0, 0.0, 0.0],
computedDoubleDisplayValue: [0.0, 0.0]
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
macro.obj(publicAPI, model);
// Build VTK API
macro.set(publicAPI, model, ['property']);
macro.get(publicAPI, model, ['value']);
macro.setGet(publicAPI, model, ['coordinateSystem', 'referenceCoordinate', 'renderer']);
macro.getArray(publicAPI, model, ['value'], 3);
// Object methods
vtkCoordinate(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkCoordinate');
// ----------------------------------------------------------------------------
var vtkCoordinate$1 = {
newInstance,
extend,
...Constants
};
export { vtkCoordinate$1 as default, extend, newInstance };