@cornerstonejs/core
Version:
Cornerstone3D Core
137 lines (136 loc) • 4.66 kB
JavaScript
const ORIENTATION_VECTOR_EPSILON = 1e-6;
const ORIENTATION_DOT_EPSILON = 1e-3;
function cloneVOIRange(voiRange) {
if (!voiRange) {
return;
}
return {
lower: voiRange.lower,
upper: voiRange.upper,
};
}
function cloneColormapOpacity(opacity) {
if (Array.isArray(opacity)) {
return opacity.map(({ opacity, value }) => ({
opacity,
value,
}));
}
return opacity;
}
function mergePlanarColormap(currentColormap, nextColormap) {
if (!nextColormap) {
return clonePlanarColormap(currentColormap);
}
if (nextColormap.name !== undefined) {
return clonePlanarColormap(nextColormap);
}
const mergedColormap = clonePlanarColormap(currentColormap) || {};
const nextClone = clonePlanarColormap(nextColormap);
if (nextClone) {
Object.assign(mergedColormap, nextClone);
}
return mergedColormap;
}
export function isPlanarOrientationVectors(orientation) {
return Boolean(orientation &&
typeof orientation === 'object' &&
'viewPlaneNormal' in orientation);
}
function normalizeOrientationVector(vector, fieldName) {
const [x, y, z] = vector || [];
const length = Math.hypot(x, y, z);
if (!Number.isFinite(x) ||
!Number.isFinite(y) ||
!Number.isFinite(z) ||
length < ORIENTATION_VECTOR_EPSILON) {
throw new Error(`[PlanarViewport] Invalid orientation vector ${fieldName}. Expected a finite non-zero Point3.`);
}
return [x / length, y / length, z / length];
}
export function clonePlanarOrientation(orientation) {
if (!isPlanarOrientationVectors(orientation)) {
return orientation;
}
const clone = {
viewPlaneNormal: normalizeOrientationVector(orientation.viewPlaneNormal, 'viewPlaneNormal'),
};
if (orientation.viewUp) {
clone.viewUp = normalizeOrientationVector(orientation.viewUp, 'viewUp');
const dot = clone.viewPlaneNormal[0] * clone.viewUp[0] +
clone.viewPlaneNormal[1] * clone.viewUp[1] +
clone.viewPlaneNormal[2] * clone.viewUp[2];
if (Math.abs(dot) > ORIENTATION_DOT_EPSILON) {
throw new Error('[PlanarViewport] Invalid orientation vectors. viewPlaneNormal and viewUp must be orthogonal.');
}
}
return clone;
}
export function clonePlanarColormap(colormap) {
if (!colormap) {
return;
}
const clone = {};
if (colormap.name !== undefined) {
clone.name = colormap.name;
}
const opacity = cloneColormapOpacity(colormap.opacity);
if (opacity !== undefined) {
clone.opacity = opacity;
}
if (colormap.threshold !== undefined) {
clone.threshold = colormap.threshold;
}
return clone;
}
export function clonePlanarLegacyProperties(properties = {}) {
const clone = Object.assign({}, properties);
if (properties.voiRange) {
clone.voiRange = cloneVOIRange(properties.voiRange);
}
if (properties.colormap) {
clone.colormap = clonePlanarColormap(properties.colormap);
}
if (properties.orientation !== undefined) {
clone.orientation = clonePlanarOrientation(properties.orientation);
}
return clone;
}
export function mergePlanarLegacyProperties(currentProperties = {}, nextProperties = {}) {
const current = clonePlanarLegacyProperties(currentProperties);
const next = clonePlanarLegacyProperties(nextProperties);
const merged = Object.assign({}, current);
Object.assign(merged, next);
if (next.colormap) {
merged.colormap = mergePlanarColormap(current.colormap, next.colormap);
}
return merged;
}
export function toPlanarDataPresentation(properties = {}) {
const presentation = {};
if (properties.colormap) {
presentation.colormap = clonePlanarColormap(properties.colormap);
}
if (properties.voiRange) {
presentation.voiRange = cloneVOIRange(properties.voiRange);
}
if (properties.invert !== undefined) {
presentation.invert = properties.invert;
}
if (properties.blendMode !== undefined) {
presentation.blendMode = properties.blendMode;
}
if (properties.interpolationType !== undefined) {
presentation.interpolationType = properties.interpolationType;
}
if (properties.opacity !== undefined) {
presentation.opacity = properties.opacity;
}
if (properties.slabThickness !== undefined) {
presentation.slabThickness = properties.slabThickness;
}
if (properties.visible !== undefined) {
presentation.visible = properties.visible;
}
return presentation;
}