feat(custom displayOptions): add custom options to every level of hp (#3372)

* feat(custom displayOptions): add custom options to every level of hanging protocols

* move set preset down to cornerstone3d

* works

* fix tmtv based on new api

* fix unit test

* close

* review1

* upgrade packages

* update packages

* apply review comments

* recursive call

* less copy

* apply review comments

* fix e2e tests

* apply review comments

* revert

* apply review comments

* apply review comments

---------

Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
This commit is contained in:
AlirezaandBill Wallace authored and GitHub committed 2023-05-16 13:07:37 -04:00
1 parent 045e54aa02
commit 1881ce5cbc
19 files changed
+240 -851

No files matched your search

+2 -3
View File
@@ -14,7 +14,6 @@ import { Types as OhifTypes } from '@ohif/core';
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
import callInputDialog from './utils/callInputDialog';
import { setColormap } from './utils/colormap/transferFunctionHelpers';
import toggleStackImageSync from './utils/stackSync/toggleStackImageSync';
import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection';
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
@@ -556,9 +555,9 @@ function commandsModule({
return actorEntry.uid.includes(displaySetInstanceUID);
});
const { actor: volumeActor } = actorEntry;
const { actor: volumeActor, uid: volumeId } = actorEntry;
setColormap(volumeActor, colormap);
viewport.setProperties({ colormap, volumeActor }, volumeId);
if (immediate) {
viewport.render();
@@ -315,7 +315,7 @@ function DicomUploadProgress({
className="ml-auto"
onClick={onComplete}
>
{'Open Viewer'}
{'Close'}
</Button>
</>
) : (
@@ -245,7 +245,7 @@ const mprAnd3DVolumeViewport = {
{
id: 'mprDisplaySet',
options: {
presetName: 'CT-Bone',
displayPreset: 'CT-Bone',
},
},
],
-1
View File
@@ -121,7 +121,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
},
getEnabledElement,
dicomLoaderService,
registerColormap,
},
},
{
@@ -30,10 +30,6 @@ import {
VolumeViewportData,
} from '../../types/CornerstoneCacheService';
import { Presentation, Presentations } from '../../types/Presentation';
import {
setColormap,
setLowerUpperColorTransferFunction,
} from '../../utils/colormap/transferFunctionHelpers';
import JumpPresets from '../../utils/JumpPresets';
@@ -525,16 +521,9 @@ class CornerstoneViewportService extends PubSubService
const displaySetOptions = displaySetOptionsArray[index];
const { volumeId } = volume;
const voiCallbacks = this._getVOICallbacks(volumeId, displaySetOptions);
const callback = ({ volumeActor }) => {
voiCallbacks.forEach(callback => callback(volumeActor));
};
volumeInputArray.push({
imageIds,
volumeId,
callback,
blendMode: displaySetOptions.blendMode,
slabThickness: this._getSlabThickness(displaySetOptions, volumeId),
});
@@ -577,7 +566,44 @@ class CornerstoneViewportService extends PubSubService
toolGroupService,
} = this.servicesManager.services;
const viewportInfo = this.getViewportInfo(viewport.id);
const displaySetOptions = viewportInfo.getDisplaySetOptions();
// Todo: use presentations states
const volumesProperties = volumeInputArray.map((volumeInput, index) => {
const { volumeId } = volumeInput;
const displaySetOption = displaySetOptions[index];
const { voi, voiInverted, colormap, displayPreset } = displaySetOption;
const properties = {};
if (voi && (voi.windowWidth || voi.windowCenter)) {
const { lower, upper } = csUtils.windowLevel.toLowHighRange(
voi.windowWidth,
voi.windowCenter
);
properties.voiRange = { lower, upper };
}
if (voiInverted !== undefined) {
properties.invert = voiInverted;
}
if (colormap !== undefined) {
properties.colormap = colormap;
}
if (displayPreset !== undefined) {
properties.preset = displayPreset;
}
return { properties, volumeId };
});
await viewport.setVolumes(volumeInputArray);
volumesProperties.forEach(({ properties, volumeId }) => {
viewport.setProperties(properties, volumeId);
});
this.setPresentations(viewport, presentations);
// load any secondary displaySets
@@ -602,7 +628,6 @@ class CornerstoneViewportService extends PubSubService
);
}
const viewportInfo = this.getViewportInfo(viewport.id);
const toolGroup = toolGroupService.getToolGroupForViewport(viewport.id);
csToolsUtils.segmentation.triggerSegmentationRender(toolGroup.id);
@@ -737,50 +762,6 @@ class CornerstoneViewportService extends PubSubService
}
}
_getVOICallbacks(volumeId, displaySetOptions) {
const {
voi,
voiInverted: inverted,
colormap,
presetName,
} = displaySetOptions;
const voiCallbackArray = [];
// If colormap is set, use it to set the color transfer function
if (colormap) {
voiCallbackArray.push(volumeActor => setColormap(volumeActor, colormap));
}
if (voi instanceof Object && voi.windowWidth && voi.windowCenter) {
const { windowWidth, windowCenter } = voi;
const { lower, upper } = csUtils.windowLevel.toLowHighRange(
windowWidth,
windowCenter
);
voiCallbackArray.push(volumeActor =>
setLowerUpperColorTransferFunction({
volumeActor,
lower,
upper,
inverted,
})
);
}
if (presetName) {
voiCallbackArray.push(volumeActor => {
utilities.applyPreset(
volumeActor,
CONSTANTS.VIEWPORT_PRESETS.find(preset => {
return preset.name === presetName;
})
);
});
}
return voiCallbackArray;
}
_setDisplaySets(
viewport: StackViewport | VolumeViewport,
viewportData: StackViewportData | VolumeViewportData,
@@ -63,7 +63,7 @@ export type PublicDisplaySetOptions = {
blendMode?: string;
slabThickness?: number;
colormap?: string;
presetName?: string;
displayPreset?: string;
};
export type DisplaySetOptions = {
@@ -73,7 +73,7 @@ export type DisplaySetOptions = {
blendMode?: Enums.BlendModes;
slabThickness?: number;
colormap?: string;
presetName?: string;
displayPreset?: string;
};
type VOI = {
@@ -315,7 +315,7 @@ class ViewportInfo {
colormap: option.colormap,
slabThickness: option.slabThickness,
blendMode,
presetName: option.presetName,
displayPreset: option.displayPreset,
});
});
@@ -1,139 +0,0 @@
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
import presets from './presets';
// get preset from preset name
function getPreset(name) {
return presets.find(preset => preset.name === name);
}
// Todo: we should be able to register a new preset via the utilityModule
// of the cornerstone extension
export default function applyPreset(actor, presetName) {
const preset = getPreset(presetName);
// Create color transfer function
const colorTransferArray = preset.colorTransfer
.split(' ')
.splice(1)
.map(parseFloat);
const { shiftRange } = getShiftRange(colorTransferArray);
let min = shiftRange[0];
const width = shiftRange[1] - shiftRange[0];
const cfun = vtkColorTransferFunction.newInstance();
const normColorTransferValuePoints = [];
for (let i = 0; i < colorTransferArray.length; i += 4) {
let value = colorTransferArray[i];
const r = colorTransferArray[i + 1];
const g = colorTransferArray[i + 2];
const b = colorTransferArray[i + 3];
value = (value - min) / width;
normColorTransferValuePoints.push([value, r, g, b]);
}
applyPointsToRGBFunction(normColorTransferValuePoints, shiftRange, cfun);
actor.getProperty().setRGBTransferFunction(0, cfun);
// Create scalar opacity function
const scalarOpacityArray = preset.scalarOpacity
.split(' ')
.splice(1)
.map(parseFloat);
const ofun = vtkPiecewiseFunction.newInstance();
const normPoints = [];
for (let i = 0; i < scalarOpacityArray.length; i += 2) {
let value = scalarOpacityArray[i];
const opacity = scalarOpacityArray[i + 1];
value = (value - min) / width;
normPoints.push([value, opacity]);
}
applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun);
actor.getProperty().setScalarOpacity(0, ofun);
const [
gradientMinValue,
gradientMinOpacity,
gradientMaxValue,
gradientMaxOpacity,
] = preset.gradientOpacity
.split(' ')
.splice(1)
.map(parseFloat);
actor.getProperty().setUseGradientOpacity(0, true);
actor.getProperty().setGradientOpacityMinimumValue(0, gradientMinValue);
actor.getProperty().setGradientOpacityMinimumOpacity(0, gradientMinOpacity);
actor.getProperty().setGradientOpacityMaximumValue(0, gradientMaxValue);
actor.getProperty().setGradientOpacityMaximumOpacity(0, gradientMaxOpacity);
if (preset.interpolation === '1') {
actor.getProperty().setInterpolationTypeToFastLinear();
//actor.getProperty().setInterpolationTypeToLinear()
}
const ambient = parseFloat(preset.ambient);
//const shade = preset.shade === '1'
const diffuse = parseFloat(preset.diffuse);
const specular = parseFloat(preset.specular);
const specularPower = parseFloat(preset.specularPower);
//actor.getProperty().setShade(shade)
actor.getProperty().setAmbient(ambient);
actor.getProperty().setDiffuse(diffuse);
actor.getProperty().setSpecular(specular);
actor.getProperty().setSpecularPower(specularPower);
}
function getShiftRange(colorTransferArray) {
// Credit to paraview-glance
// https://github.com/Kitware/paraview-glance/blob/3fec8eeff31e9c19ad5b6bff8e7159bd745e2ba9/src/components/controls/ColorBy/script.js#L133
// shift range is original rgb/opacity range centered around 0
let min = Infinity;
let max = -Infinity;
for (let i = 0; i < colorTransferArray.length; i += 4) {
min = Math.min(min, colorTransferArray[i]);
max = Math.max(max, colorTransferArray[i]);
}
const center = (max - min) / 2;
return {
shiftRange: [-center, center],
min,
max,
};
}
function applyPointsToRGBFunction(points, range, cfun) {
const width = range[1] - range[0];
const rescaled = points.map(([x, r, g, b]) => [
x * width + range[0],
r,
g,
b,
]);
cfun.removeAllPoints();
rescaled.forEach(([x, r, g, b]) => cfun.addRGBPoint(x, r, g, b));
return rescaled;
}
function applyPointsToPiecewiseFunction(points, range, pwf) {
const width = range[1] - range[0];
const rescaled = points.map(([x, y]) => [x * width + range[0], y]);
pwf.removeAllPoints();
rescaled.forEach(([x, y]) => pwf.addPoint(x, y));
return rescaled;
}
@@ -1,29 +0,0 @@
// https://www.slicer.org/w/index.php/Slicer3:2010_GenericAnatomyColors#Lookup_table
const colors = [
{
integerLabel: 0,
textLabel: 'background',
color: [0, 0, 0, 0],
},
{
integerLabel: 1,
textLabel: 'tissue',
// color: [255, 174, 128, 255],
color: [255, 0, 0, 255],
},
{
integerLabel: 2,
textLabel: 'bone',
// color: [241, 214, 145, 255],
color: [0, 255, 0, 255],
},
{
integerLabel: 3,
textLabel: 'skin',
// color: [177, 122, 101, 255],
color: [0, 0, 255, 255],
},
// ....
];
export default colors;
@@ -1,435 +0,0 @@
const presets = [
{
name: 'CT-AAA',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'12 -3024 0 143.556 0 166.222 0.686275 214.389 0.696078 419.736 0.833333 3071 0.803922',
id: 'vtkMRMLVolumePropertyNode1',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'24 -3024 0 0 0 143.556 0.615686 0.356863 0.184314 166.222 0.882353 0.603922 0.290196 214.389 1 1 1 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '143.556 419.736',
},
{
name: 'CT-AAA2',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'16 -3024 0 129.542 0 145.244 0.166667 157.02 0.5 169.918 0.627451 395.575 0.8125 1578.73 0.8125 3071 0.8125',
id: 'vtkMRMLVolumePropertyNode2',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'32 -3024 0 0 0 129.542 0.54902 0.25098 0.14902 145.244 0.6 0.627451 0.843137 157.02 0.890196 0.47451 0.6 169.918 0.992157 0.870588 0.392157 395.575 1 0.886275 0.658824 1578.73 1 0.829256 0.957922 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '0 1600',
},
{
name: 'CT-Bone',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity: '8 -3024 0 -16.4458 0 641.385 0.715686 3071 0.705882',
id: 'vtkMRMLVolumePropertyNode3',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'16 -3024 0 0 0 -16.4458 0.729412 0.254902 0.301961 641.385 0.905882 0.815686 0.552941 3071 1 1 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-16.4458 641.385',
},
{
name: 'CT-Bones',
gradientOpacity: '4 0 1 985.12 1',
specularPower: '1',
scalarOpacity: '8 -1000 0 152.19 0 278.93 0.190476 952 0.2',
id: 'vtkMRMLVolumePropertyNode4',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'20 -1000 0.3 0.3 1 -488 0.3 1 0.3 463.28 1 0 0 659.15 1 0.912535 0.0374849 953 1 0.3 0.3',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '152.19 952',
},
{
name: 'CT-Cardiac',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'12 -3024 0 -77.6875 0 94.9518 0.285714 179.052 0.553571 260.439 0.848214 3071 0.875',
id: 'vtkMRMLVolumePropertyNode5',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'24 -3024 0 0 0 -77.6875 0.54902 0.25098 0.14902 94.9518 0.882353 0.603922 0.290196 179.052 1 0.937033 0.954531 260.439 0.615686 0 0 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-77.6875 260.439',
},
{
name: 'CT-Cardiac2',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'12 -3024 0 42.8964 0 163.488 0.428571 277.642 0.776786 1587 0.754902 3071 0.754902',
id: 'vtkMRMLVolumePropertyNode6',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'24 -3024 0 0 0 42.8964 0.54902 0.25098 0.14902 163.488 0.917647 0.639216 0.0588235 277.642 1 0.878431 0.623529 1587 1 1 1 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '42.8964 1587',
},
{
name: 'CT-Cardiac3',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071',
id: 'vtkMRMLVolumePropertyNode7',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-86.9767 1224.16',
},
{
name: 'CT-Chest-Contrast-Enhanced',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'10 -3024 0 67.0106 0 251.105 0.446429 439.291 0.625 3071 0.616071',
id: 'vtkMRMLVolumePropertyNode8',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'20 -3024 0 0 0 67.0106 0.54902 0.25098 0.14902 251.105 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '67.0106 439.291',
},
{
name: 'CT-Chest-Vessels',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'10 -3024 0 -1278.35 0 22.8277 0.428571 439.291 0.625 3071 0.616071',
id: 'vtkMRMLVolumePropertyNode9',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'20 -3024 0 0 0 -1278.35 0.54902 0.25098 0.14902 22.8277 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-1278.35 439.291',
},
{
name: 'CT-Coronary-Arteries',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'12 -2048 0 136.47 0 159.215 0.258929 318.43 0.571429 478.693 0.776786 3661 1',
id: 'vtkMRMLVolumePropertyNode10',
specular: '0',
shade: '0',
ambient: '0.2',
colorTransfer:
'24 -2048 0 0 0 136.47 0 0 0 159.215 0.159804 0.159804 0.159804 318.43 0.764706 0.764706 0.764706 478.693 1 1 1 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '136.47 478.693',
},
{
name: 'CT-Coronary-Arteries-2',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'14 -2048 0 142.677 0 145.016 0.116071 192.174 0.5625 217.24 0.776786 384.347 0.830357 3661 0.830357',
id: 'vtkMRMLVolumePropertyNode11',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'28 -2048 0 0 0 142.677 0 0 0 145.016 0.615686 0 0.0156863 192.174 0.909804 0.454902 0 217.24 0.972549 0.807843 0.611765 384.347 0.909804 0.909804 1 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '142.677 384.347',
},
{
name: 'CT-Coronary-Arteries-3',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'14 -2048 0 128.643 0 129.982 0.0982143 173.636 0.669643 255.884 0.857143 584.878 0.866071 3661 1',
id: 'vtkMRMLVolumePropertyNode12',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'28 -2048 0 0 0 128.643 0 0 0 129.982 0.615686 0 0.0156863 173.636 0.909804 0.454902 0 255.884 0.886275 0.886275 0.886275 584.878 0.968627 0.968627 0.968627 3661 1 1 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '128.643 584.878',
},
{
name: 'CT-Cropped-Volume-Bone',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity: '10 -2048 0 -451 0 -450 1 1050 1 3661 1',
id: 'vtkMRMLVolumePropertyNode13',
specular: '0',
shade: '0',
ambient: '0.2',
colorTransfer:
'20 -2048 0 0 0 -451 0 0 0 -450 0.0556356 0.0556356 0.0556356 1050 1 1 1 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-451 1050',
},
{
name: 'CT-Fat',
gradientOpacity: '6 0 1 985.12 1 988 1',
specularPower: '1',
scalarOpacity: '14 -1000 0 -100 0 -99 0.15 -60 0.15 -59 0 101.2 0 952 0',
id: 'vtkMRMLVolumePropertyNode14',
specular: '0',
references: '0',
shade: '0',
ambient: '0.2',
colorTransfer:
'36 -1000 0.3 0.3 1 -497.5 0.3 1 0.3 -99 0 0 1 -76.946 0 1 0 -65.481 0.835431 0.888889 0.0165387 83.89 1 0 0 463.28 1 0 0 659.15 1 0.912535 0.0374849 2952 1 0.300267 0.299886',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-100 101.2',
},
{
name: 'CT-Liver-Vasculature',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'14 -2048 0 149.113 0 157.884 0.482143 339.96 0.660714 388.526 0.830357 1197.95 0.839286 3661 0.848214',
id: 'vtkMRMLVolumePropertyNode15',
specular: '0',
shade: '0',
ambient: '0.2',
colorTransfer:
'28 -2048 0 0 0 149.113 0 0 0 157.884 0.501961 0.25098 0 339.96 0.695386 0.59603 0.36886 388.526 0.854902 0.85098 0.827451 1197.95 1 1 1 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '149.113 1197.95',
},
{
name: 'CT-Lung',
gradientOpacity: '6 0 1 985.12 1 988 1',
specularPower: '1',
scalarOpacity: '12 -1000 0 -600 0 -599 0.15 -400 0.15 -399 0 2952 0',
id: 'vtkMRMLVolumePropertyNode16',
specular: '0',
references: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'24 -1000 0.3 0.3 1 -600 0 0 1 -530 0.134704 0.781726 0.0724558 -460 0.929244 1 0.109473 -400 0.888889 0.254949 0.0240258 2952 1 0.3 0.3',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-600 -399',
},
{
name: 'CT-MIP',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity: '8 -3024 0 -637.62 0 700 1 3071 1',
id: 'vtkMRMLVolumePropertyNode17',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer: '16 -3024 0 0 0 -637.62 1 1 1 700 1 1 1 3071 1 1 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-637.62 700',
},
{
name: 'CT-Muscle',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity:
'10 -3024 0 -155.407 0 217.641 0.676471 419.736 0.833333 3071 0.803922',
id: 'vtkMRMLVolumePropertyNode18',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'20 -3024 0 0 0 -155.407 0.54902 0.25098 0.14902 217.641 0.882353 0.603922 0.290196 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-155.407 419.736',
},
{
name: 'CT-Pulmonary-Arteries',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'14 -2048 0 -568.625 0 -364.081 0.0714286 -244.813 0.401786 18.2775 0.607143 447.798 0.830357 3592.73 0.839286',
id: 'vtkMRMLVolumePropertyNode19',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'28 -2048 0 0 0 -568.625 0 0 0 -364.081 0.396078 0.301961 0.180392 -244.813 0.611765 0.352941 0.0705882 18.2775 0.843137 0.0156863 0.156863 447.798 0.752941 0.752941 0.752941 3592.73 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-568.625 447.798',
},
{
name: 'CT-Soft-Tissue',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity: '10 -2048 0 -167.01 0 -160 1 240 1 3661 1',
id: 'vtkMRMLVolumePropertyNode20',
specular: '0',
shade: '0',
ambient: '0.2',
colorTransfer:
'20 -2048 0 0 0 -167.01 0 0 0 -160 0.0556356 0.0556356 0.0556356 240 1 1 1 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '-167.01 240',
},
{
name: 'CT-Air',
gradientOpacity: '4 0 1 255 1',
specularPower: '10',
scalarOpacity: '8 -3024 0.705882 -900.0 0.715686 -500.0 0 3071 0',
id: 'vtkMRMLVolumePropertyNode21',
specular: '0.2',
shade: '1',
ambient: '0.1',
colorTransfer:
'16 -3024 1 1 1 -900.0 0.2 1.0 1.0 -500.0 0.3 0.3 1.0 3071 0 0 0 ',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '-1200.0 -200.0',
},
{
name: 'MR-Angio',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity:
'12 -2048 0 151.354 0 158.279 0.4375 190.112 0.580357 200.873 0.732143 3661 0.741071',
id: 'vtkMRMLVolumePropertyNode22',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'24 -2048 0 0 0 151.354 0 0 0 158.279 0.74902 0.376471 0 190.112 1 0.866667 0.733333 200.873 0.937255 0.937255 0.937255 3661 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '151.354 200.873',
},
{
name: 'MR-Default',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity: '12 0 0 20 0 40 0.15 120 0.3 220 0.375 1024 0.5',
id: 'vtkMRMLVolumePropertyNode23',
specular: '0',
shade: '1',
ambient: '0.2',
colorTransfer:
'24 0 0 0 0 20 0.168627 0 0 40 0.403922 0.145098 0.0784314 120 0.780392 0.607843 0.380392 220 0.847059 0.835294 0.788235 1024 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '0 220',
},
{
name: 'MR-MIP',
gradientOpacity: '4 0 1 255 1',
specularPower: '1',
scalarOpacity: '8 0 0 98.3725 0 416.637 1 2800 1',
id: 'vtkMRMLVolumePropertyNode24',
specular: '0',
shade: '0',
ambient: '0.2',
colorTransfer: '16 0 1 1 1 98.3725 1 1 1 416.637 1 1 1 2800 1 1 1',
selectable: 'true',
diffuse: '1',
interpolation: '1',
effectiveRange: '0 416.637',
},
{
name: 'MR-T2-Brain',
gradientOpacity: '4 0 1 160.25 1',
specularPower: '40',
scalarOpacity: '10 0 0 36.05 0 218.302 0.171429 412.406 1 641 1',
id: 'vtkMRMLVolumePropertyNode25',
specular: '0.5',
shade: '1',
ambient: '0.3',
colorTransfer:
'16 0 0 0 0 98.7223 0.956863 0.839216 0.192157 412.406 0 0.592157 0.807843 641 1 1 1',
selectable: 'true',
diffuse: '0.6',
interpolation: '1',
effectiveRange: '0 412.406',
},
{
name: 'DTI-FA-Brain',
gradientOpacity: '4 0 1 0.9950 1',
specularPower: '40',
scalarOpacity:
'16 0 0 0 0 0.3501 0.0158 0.49379 0.7619 0.6419 1 0.9920 1 0.9950 0 0.9950 0',
id: 'vtkMRMLVolumePropertyNode26',
specular: '0.5',
shade: '1',
ambient: '0.3',
colorTransfer:
'28 0 1 0 0 0 1 0 0 0.24974 0.4941 1 0 0.49949 0 0.9882 1 0.7492 0.51764 0 1 0.9950 1 0 0 0.9950 1 0 0',
selectable: 'true',
diffuse: '0.9',
interpolation: '1',
effectiveRange: '0 1',
},
];
export default presets;
@@ -1,93 +0,0 @@
import { cache, utilities } from '@cornerstonejs/core';
import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
const colormaps = {};
export function registerColormap(colormap) {
colormaps[colormap.Name] = colormap;
}
function setColorTransferFunctionFromVolumeMetadata({
volumeActor,
volumeId,
inverted,
}) {
let lower, upper, windowWidth, windowCenter;
if (volumeId) {
const volume = cache.getVolume(volumeId);
const voiLutModule = volume.metadata.voiLut[0];
if (voiLutModule) {
windowWidth = voiLutModule.windowWidth;
windowCenter = voiLutModule.windowCenter;
}
} else {
windowWidth = 400;
windowCenter = 40;
}
if (windowWidth == undefined || windowCenter === undefined) {
// Set to something so we can window level it manually.
lower = 200;
upper = 400;
} else {
lower = windowCenter - windowWidth / 2.0;
upper = windowCenter + windowWidth / 2.0;
}
setLowerUpperColorTransferFunction({ volumeActor, lower, upper, inverted });
}
function setLowerUpperColorTransferFunction({
volumeActor,
lower,
upper,
inverted,
}) {
volumeActor
.getProperty()
.getRGBTransferFunction(0)
.setMappingRange(lower, upper);
if (inverted) {
utilities.invertRgbTransferFunction(
volumeActor.getProperty().getRGBTransferFunction(0)
);
}
}
function setColormap(volumeActor, colormap) {
const mapper = volumeActor.getMapper();
mapper.setSampleDistance(1.0);
const cfun = vtkColorTransferFunction.newInstance();
// if we have a custom colormap, use it
let preset;
if (colormaps[colormap]) {
preset = colormaps[colormap];
} else {
preset = vtkColorMaps.getPresetByName(colormap);
}
cfun.applyColorMap(preset);
cfun.setMappingRange(0, 5);
volumeActor.getProperty().setRGBTransferFunction(0, cfun);
// Create scalar opacity function
const ofun = vtkPiecewiseFunction.newInstance();
ofun.addPoint(0, 0.0);
ofun.addPoint(0.1, 0.9);
ofun.addPoint(5, 1.0);
volumeActor.getProperty().setScalarOpacity(0, ofun);
}
export {
setColormap,
setColorTransferFunctionFromVolumeMetadata,
setLowerUpperColorTransferFunction,
};