@cornerstonejs/core 5.0.9 → 5.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/RenderingEngine/BaseVolumeViewport.d.ts +1 -0
- package/dist/esm/RenderingEngine/BaseVolumeViewport.js +24 -17
- package/dist/esm/types/Colormap.d.ts +2 -1
- package/dist/esm/utilities/colormap.d.ts +7 -0
- package/dist/esm/utilities/colormap.js +67 -4
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +6 -6
|
@@ -33,6 +33,7 @@ declare abstract class BaseVolumeViewport extends Viewport {
|
|
|
33
33
|
private initializeVolumeNewImageEventDispatcher;
|
|
34
34
|
private setVOILUTFunction;
|
|
35
35
|
private setColormap;
|
|
36
|
+
private _applyColormapOpacity;
|
|
36
37
|
private setOpacity;
|
|
37
38
|
private setInvert;
|
|
38
39
|
protected getVOIModifiedEventDetail(volumeId: string): VoiModifiedEventDetail;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
|
|
2
|
-
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
|
|
3
2
|
import { vec2, vec3 } from 'gl-matrix';
|
|
4
3
|
import cache from '../cache/cache';
|
|
5
4
|
import { MPR_CAMERA_VALUES, RENDERING_DEFAULTS, VIEWPORT_PRESETS, } from '../constants';
|
|
@@ -12,7 +11,7 @@ import * as colormapUtils from '../utilities/colormap';
|
|
|
12
11
|
import invertRgbTransferFunction from '../utilities/invertRgbTransferFunction';
|
|
13
12
|
import createSigmoidRGBTransferFunction from '../utilities/createSigmoidRGBTransferFunction';
|
|
14
13
|
import transformWorldToIndex from '../utilities/transformWorldToIndex';
|
|
15
|
-
import { findMatchingColormap, updateOpacity as colormapUpdateOpacity, updateThreshold as colormapUpdateThreshold,
|
|
14
|
+
import { findMatchingColormap, updateOpacity as colormapUpdateOpacity, updateThreshold as colormapUpdateThreshold, updateOpacityMapping as colormapUpdateOpacityMapping, getOpacityState, } from '../utilities/colormap';
|
|
16
15
|
import getAcquisitionPlaneOrientation from '../utilities/getAcquisitionPlaneOrientation';
|
|
17
16
|
import { getTransferFunctionNodes, setTransferFunctionNodes, } from '../utilities/transferFunctionUtils';
|
|
18
17
|
import createVolumeActor from './helpers/createVolumeActor';
|
|
@@ -163,10 +162,10 @@ class BaseVolumeViewport extends Viewport {
|
|
|
163
162
|
return acc;
|
|
164
163
|
}, []);
|
|
165
164
|
const matchedColormap = findMatchingColormap(RGBPoints, volumeActor) || {};
|
|
166
|
-
const threshold =
|
|
167
|
-
const opacity = getMaxOpacity(volumeActor);
|
|
168
|
-
matchedColormap.threshold = threshold;
|
|
165
|
+
const { opacity, opacityMapping, threshold } = getOpacityState(volumeActor);
|
|
169
166
|
matchedColormap.opacity = opacity;
|
|
167
|
+
matchedColormap.opacityMapping = opacityMapping;
|
|
168
|
+
matchedColormap.threshold = threshold;
|
|
170
169
|
return matchedColormap;
|
|
171
170
|
};
|
|
172
171
|
this.getRotation = () => {
|
|
@@ -447,6 +446,7 @@ class BaseVolumeViewport extends Viewport {
|
|
|
447
446
|
cfun.setMappingRange(range[0], range[1]);
|
|
448
447
|
volumeActor.getProperty().setRGBTransferFunction(0, cfun);
|
|
449
448
|
this.viewportProperties.colormap = colormap;
|
|
449
|
+
this._applyColormapOpacity(colormap, volumeActor);
|
|
450
450
|
if (!suppressEvents) {
|
|
451
451
|
const completeColormap = this.getColormap(volumeId);
|
|
452
452
|
const eventDetail = {
|
|
@@ -458,26 +458,33 @@ class BaseVolumeViewport extends Viewport {
|
|
|
458
458
|
triggerEvent(this.element, Events.COLORMAP_MODIFIED, eventDetail);
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
|
+
_applyColormapOpacity(colormap, volumeActor) {
|
|
462
|
+
const mapping = Array.isArray(colormap.opacityMapping)
|
|
463
|
+
? colormap.opacityMapping
|
|
464
|
+
: Array.isArray(colormap.opacity)
|
|
465
|
+
? colormap.opacity
|
|
466
|
+
: undefined;
|
|
467
|
+
const overall = typeof colormap.opacity === 'number' ? colormap.opacity : undefined;
|
|
468
|
+
if (mapping !== undefined) {
|
|
469
|
+
colormapUpdateOpacityMapping(volumeActor, mapping, overall);
|
|
470
|
+
}
|
|
471
|
+
else if (overall !== undefined) {
|
|
472
|
+
colormapUpdateOpacity(volumeActor, overall);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
461
475
|
setOpacity(colormap, volumeId) {
|
|
462
476
|
const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);
|
|
463
477
|
if (!applicableVolumeActorInfo) {
|
|
464
478
|
return;
|
|
465
479
|
}
|
|
466
480
|
const { volumeActor } = applicableVolumeActorInfo;
|
|
467
|
-
|
|
468
|
-
if (typeof colormap.opacity === 'number') {
|
|
469
|
-
colormapUpdateOpacity(volumeActor, colormap.opacity);
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
colormap.opacity.forEach(({ opacity, value }) => {
|
|
473
|
-
ofun.addPoint(value, opacity);
|
|
474
|
-
});
|
|
475
|
-
volumeActor.getProperty().setScalarOpacity(0, ofun);
|
|
476
|
-
}
|
|
481
|
+
this._applyColormapOpacity(colormap, volumeActor);
|
|
477
482
|
if (!this.viewportProperties.colormap) {
|
|
478
483
|
this.viewportProperties.colormap = {};
|
|
479
484
|
}
|
|
480
|
-
|
|
485
|
+
const { opacity, opacityMapping } = getOpacityState(volumeActor);
|
|
486
|
+
this.viewportProperties.colormap.opacity = opacity;
|
|
487
|
+
this.viewportProperties.colormap.opacityMapping = opacityMapping;
|
|
481
488
|
const matchedColormap = this.getColormap(volumeId);
|
|
482
489
|
const eventDetail = {
|
|
483
490
|
viewportId: this.id,
|
|
@@ -801,7 +808,7 @@ class BaseVolumeViewport extends Viewport {
|
|
|
801
808
|
if (colormap?.name) {
|
|
802
809
|
this.setColormap(colormap, volumeId, suppressEvents);
|
|
803
810
|
}
|
|
804
|
-
if (colormap?.opacity != null) {
|
|
811
|
+
if (colormap?.opacity != null || colormap?.opacityMapping != null) {
|
|
805
812
|
this.setOpacity(colormap, volumeId);
|
|
806
813
|
}
|
|
807
814
|
if (colormap?.threshold != null) {
|
|
@@ -12,6 +12,7 @@ interface OpacityMapping {
|
|
|
12
12
|
interface ColormapPublic {
|
|
13
13
|
name?: string;
|
|
14
14
|
opacity?: OpacityMapping[] | number;
|
|
15
|
-
|
|
15
|
+
opacityMapping?: OpacityMapping[];
|
|
16
|
+
threshold?: number | null;
|
|
16
17
|
}
|
|
17
18
|
export type { ColormapRegistration, ColormapPublic, OpacityMapping };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ColormapPublic, ColormapRegistration } from '../types';
|
|
2
|
+
import type { OpacityMapping } from '../types/Colormap';
|
|
2
3
|
declare function registerColormap(colormap: ColormapRegistration): void;
|
|
3
4
|
declare function getColormap(name: any): any;
|
|
4
5
|
declare function getColormapNames(): any[];
|
|
@@ -7,6 +8,12 @@ declare function findMatchingColormap(rgbPoints: any, actor: any): ColormapPubli
|
|
|
7
8
|
export declare function setColorMapTransferFunctionForVolumeActor(volumeInfo: any): void;
|
|
8
9
|
export declare function updateOpacity(volumeActor: any, newOpacity: any): void;
|
|
9
10
|
export declare function updateThreshold(volumeActor: any, newThreshold: any): void;
|
|
11
|
+
export declare function updateOpacityMapping(volumeActor: any, mapping: OpacityMapping[], overall?: number): void;
|
|
12
|
+
export declare function getOpacityState(volumeActor: any): {
|
|
13
|
+
opacity: number;
|
|
14
|
+
opacityMapping?: OpacityMapping[];
|
|
15
|
+
threshold: number | null;
|
|
16
|
+
};
|
|
10
17
|
declare function getThresholdValue(volumeActor: any): any;
|
|
11
18
|
declare function getMaxOpacity(volumeActor: any): number;
|
|
12
19
|
export { getColormap, getColormapNames, resolveColormap, registerColormap, findMatchingColormap, getThresholdValue, getMaxOpacity, };
|
|
@@ -3,6 +3,17 @@ import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransf
|
|
|
3
3
|
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
|
|
4
4
|
import isEqual from './isEqual';
|
|
5
5
|
import { actorIsA } from './actorCheck';
|
|
6
|
+
const opacitySpecByActor = new WeakMap();
|
|
7
|
+
function getOpacitySpec(volumeActor) {
|
|
8
|
+
const stored = opacitySpecByActor.get(volumeActor);
|
|
9
|
+
if (stored) {
|
|
10
|
+
return stored;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
overall: getMaxOpacity(volumeActor),
|
|
14
|
+
threshold: getThresholdValue(volumeActor),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
6
17
|
const _colormaps = new Map();
|
|
7
18
|
function normalizeColormapName(name) {
|
|
8
19
|
return name?.trim().toLowerCase();
|
|
@@ -109,12 +120,64 @@ export function setColorMapTransferFunctionForVolumeActor(volumeInfo) {
|
|
|
109
120
|
updateOpacityWithThreshold(volumeActor, opacity, threshold);
|
|
110
121
|
}
|
|
111
122
|
export function updateOpacity(volumeActor, newOpacity) {
|
|
112
|
-
const
|
|
113
|
-
|
|
123
|
+
const spec = getOpacitySpec(volumeActor);
|
|
124
|
+
applyOpacitySpec(volumeActor, { ...spec, overall: newOpacity });
|
|
114
125
|
}
|
|
115
126
|
export function updateThreshold(volumeActor, newThreshold) {
|
|
116
|
-
const
|
|
117
|
-
|
|
127
|
+
const spec = getOpacitySpec(volumeActor);
|
|
128
|
+
applyOpacitySpec(volumeActor, { ...spec, threshold: newThreshold });
|
|
129
|
+
}
|
|
130
|
+
export function updateOpacityMapping(volumeActor, mapping, overall) {
|
|
131
|
+
const spec = getOpacitySpec(volumeActor);
|
|
132
|
+
applyOpacitySpec(volumeActor, {
|
|
133
|
+
...spec,
|
|
134
|
+
mapping,
|
|
135
|
+
...(overall !== undefined && { overall }),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
export function getOpacityState(volumeActor) {
|
|
139
|
+
const spec = opacitySpecByActor.get(volumeActor);
|
|
140
|
+
if (spec) {
|
|
141
|
+
return {
|
|
142
|
+
opacity: spec.overall,
|
|
143
|
+
opacityMapping: spec.mapping,
|
|
144
|
+
threshold: spec.threshold ?? null,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
opacity: getMaxOpacity(volumeActor),
|
|
149
|
+
opacityMapping: undefined,
|
|
150
|
+
threshold: getThresholdValue(volumeActor),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function applyOpacitySpec(volumeActor, spec) {
|
|
154
|
+
const overall = spec.overall ?? 1;
|
|
155
|
+
const threshold = spec.threshold ?? null;
|
|
156
|
+
const mapping = spec.mapping;
|
|
157
|
+
opacitySpecByActor.set(volumeActor, { overall, mapping, threshold });
|
|
158
|
+
if (mapping?.length) {
|
|
159
|
+
const ofun = vtkPiecewiseFunction.newInstance();
|
|
160
|
+
const sorted = [...mapping].sort((a, b) => a.value - b.value);
|
|
161
|
+
if (threshold !== null) {
|
|
162
|
+
const span = Math.abs(sorted[sorted.length - 1].value - sorted[0].value) || 1;
|
|
163
|
+
const delta = span * 0.001;
|
|
164
|
+
ofun.addPoint(sorted[0].value, 0);
|
|
165
|
+
ofun.addPoint(threshold - delta, 0);
|
|
166
|
+
sorted.forEach(({ value, opacity }) => {
|
|
167
|
+
if (value >= threshold) {
|
|
168
|
+
ofun.addPoint(value, opacity * overall);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
sorted.forEach(({ value, opacity }) => {
|
|
174
|
+
ofun.addPoint(value, opacity * overall);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
volumeActor.getProperty().setScalarOpacity(0, ofun);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
updateOpacityWithThreshold(volumeActor, overall, threshold);
|
|
118
181
|
}
|
|
119
182
|
function updateOpacityWithThreshold(volumeActor, opacity, threshold) {
|
|
120
183
|
const meta = volumeActor.getMapper().getInputData().get('voxelManager');
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.0.
|
|
1
|
+
export declare const version = "5.0.11";
|
package/dist/esm/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.0.
|
|
1
|
+
export const version = '5.0.11';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.11",
|
|
4
4
|
"description": "Cornerstone3D Core",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/esm/index.d.ts",
|
|
@@ -84,18 +84,18 @@
|
|
|
84
84
|
"prepublishOnly": "pnpm run build"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@cornerstonejs/utils": "5.0.
|
|
87
|
+
"@cornerstonejs/utils": "5.0.11",
|
|
88
88
|
"@kitware/vtk.js": "35.5.3",
|
|
89
89
|
"comlink": "4.4.2",
|
|
90
90
|
"gl-matrix": "3.4.3",
|
|
91
91
|
"loglevel": "1.9.2"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@cornerstonejs/metadata": "5.0.
|
|
94
|
+
"@cornerstonejs/metadata": "5.0.11"
|
|
95
95
|
},
|
|
96
96
|
"peerDependencies": {
|
|
97
|
-
"@cornerstonejs/metadata": "5.0.
|
|
98
|
-
"@cornerstonejs/utils": "5.0.
|
|
97
|
+
"@cornerstonejs/metadata": "5.0.11",
|
|
98
|
+
"@cornerstonejs/utils": "5.0.11"
|
|
99
99
|
},
|
|
100
100
|
"contributors": [
|
|
101
101
|
{
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"type": "individual",
|
|
109
109
|
"url": "https://ohif.org/donate"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "40e7a86b4bc2cdee68df76f9abed9cd762c70dc6"
|
|
112
112
|
}
|