@cornerstonejs/core 1.61.7 → 1.63.0
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/cjs/RenderingEngine/BaseVolumeViewport.d.ts +1 -0
- package/dist/cjs/RenderingEngine/BaseVolumeViewport.js +48 -2
- package/dist/cjs/RenderingEngine/BaseVolumeViewport.js.map +1 -1
- package/dist/esm/RenderingEngine/BaseVolumeViewport.js +49 -3
- package/dist/esm/RenderingEngine/BaseVolumeViewport.js.map +1 -1
- package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts +1 -0
- package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +2 -2
- package/src/RenderingEngine/BaseVolumeViewport.ts +82 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.63.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"type": "individual",
|
|
48
48
|
"url": "https://ohif.org/donate"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "952379ee23e86f276b66bc7f58c4b37431a35a53"
|
|
51
51
|
}
|
|
@@ -62,7 +62,6 @@ import type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCam
|
|
|
62
62
|
import vtkSlabCamera from './vtkClasses/vtkSlabCamera';
|
|
63
63
|
import transformWorldToIndex from '../utilities/transformWorldToIndex';
|
|
64
64
|
import { getTransferFunctionNodes } from '../utilities/transferFunctionUtils';
|
|
65
|
-
|
|
66
65
|
/**
|
|
67
66
|
* Abstract base class for volume viewports. VolumeViewports are used to render
|
|
68
67
|
* 3D volumes from which various orientations can be viewed. Since VolumeViewports
|
|
@@ -282,13 +281,16 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
|
|
|
282
281
|
cfun.setMappingRange(range[0], range[1]);
|
|
283
282
|
volumeActor.getProperty().setRGBTransferFunction(0, cfun);
|
|
284
283
|
|
|
284
|
+
// This configures the viewport to use the most recently applied colormap.
|
|
285
|
+
// However, this approach is not optimal when dealing with two volumes, as it prevents retrieval of the
|
|
286
|
+
// colormap for Volume A if Volume B's colormap was the last one applied.
|
|
285
287
|
this.viewportProperties.colormap = colormap;
|
|
286
288
|
|
|
287
289
|
if (!suppressEvents) {
|
|
288
290
|
const eventDetail = {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
291
|
+
viewportId: this.id,
|
|
292
|
+
colormap,
|
|
293
|
+
volumeId,
|
|
292
294
|
};
|
|
293
295
|
triggerEvent(this.element, Events.COLORMAP_MODIFIED, eventDetail);
|
|
294
296
|
}
|
|
@@ -789,7 +791,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
|
|
|
789
791
|
}
|
|
790
792
|
|
|
791
793
|
const {
|
|
792
|
-
colormap,
|
|
794
|
+
colormap: latestColormap,
|
|
793
795
|
VOILUTFunction,
|
|
794
796
|
interpolationType,
|
|
795
797
|
invert,
|
|
@@ -816,6 +818,15 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
|
|
|
816
818
|
|
|
817
819
|
const voiRange = voiRanges.length ? voiRanges[0].voiRange : null;
|
|
818
820
|
|
|
821
|
+
const volumeColormap = this.getColormap(applicableVolumeActorInfo);
|
|
822
|
+
|
|
823
|
+
let colormap;
|
|
824
|
+
if (volumeId && volumeColormap) {
|
|
825
|
+
colormap = volumeColormap;
|
|
826
|
+
} else {
|
|
827
|
+
colormap = latestColormap;
|
|
828
|
+
}
|
|
829
|
+
|
|
819
830
|
return {
|
|
820
831
|
colormap: colormap,
|
|
821
832
|
voiRange: voiRange,
|
|
@@ -827,6 +838,72 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
|
|
|
827
838
|
};
|
|
828
839
|
};
|
|
829
840
|
|
|
841
|
+
/**
|
|
842
|
+
* This function extracts the nodes from the RGB Transfer Function, transforming each node's x, r, g, b properties
|
|
843
|
+
* into a unified array "RGB Points." Then, it compares these RGB Points—specifically the r, g, b values—with
|
|
844
|
+
* those in the predefined vtk colormap presets. Upon finding a matching set of r, g, b values, the function identifies and selects the
|
|
845
|
+
* corresponding colormap.
|
|
846
|
+
*
|
|
847
|
+
* Next, the function extracts an array of opacity points, formatted as a sequence of [x,y] pairs, where 'x' represents a value and
|
|
848
|
+
* 'y' represents its opacity. It iterates through this array to construct an opacity object that maps each value to its opacity.
|
|
849
|
+
*
|
|
850
|
+
* The function returns an object that includes the name of the identified colormap and the constructed opacity object.
|
|
851
|
+
* @param applicableVolumeActorInfo - The volume actor information for the volume
|
|
852
|
+
* @returns colormap information for the volume if identified
|
|
853
|
+
*/
|
|
854
|
+
private getColormap = (applicableVolumeActorInfo) => {
|
|
855
|
+
const { volumeActor } = applicableVolumeActorInfo;
|
|
856
|
+
const cfun = volumeActor.getProperty().getRGBTransferFunction(0);
|
|
857
|
+
const { nodes } = cfun.getState();
|
|
858
|
+
const RGBPoints = nodes.reduce((acc, node) => {
|
|
859
|
+
acc.push(node.x, node.r, node.g, node.b);
|
|
860
|
+
return acc;
|
|
861
|
+
}, []);
|
|
862
|
+
const colormaps = vtkColorMaps.rgbPresetNames.map((presetName) =>
|
|
863
|
+
vtkColorMaps.getPresetByName(presetName)
|
|
864
|
+
);
|
|
865
|
+
const matchedColormap = colormaps.find((colormap) => {
|
|
866
|
+
const { RGBPoints: presetRGBPoints } = colormap;
|
|
867
|
+
if (presetRGBPoints.length !== RGBPoints.length) {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
for (let i = 0; i < presetRGBPoints.length; i += 4) {
|
|
872
|
+
if (
|
|
873
|
+
!isEqual(
|
|
874
|
+
presetRGBPoints.slice(i + 1, i + 4),
|
|
875
|
+
RGBPoints.slice(i + 1, i + 4)
|
|
876
|
+
)
|
|
877
|
+
) {
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
return true;
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
if (!matchedColormap) {
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const opacityPoints = volumeActor
|
|
890
|
+
.getProperty()
|
|
891
|
+
.getScalarOpacity(0)
|
|
892
|
+
.getDataPointer();
|
|
893
|
+
|
|
894
|
+
const opacity = [];
|
|
895
|
+
for (let i = 0; i < opacityPoints.length; i += 2) {
|
|
896
|
+
opacity.push({ value: opacityPoints[i], opacity: opacityPoints[i + 1] });
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const colormap = {
|
|
900
|
+
name: matchedColormap.Name,
|
|
901
|
+
opacity: opacity,
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
return colormap;
|
|
905
|
+
};
|
|
906
|
+
|
|
830
907
|
/**
|
|
831
908
|
* Creates volume actors for all volumes defined in the `volumeInputArray`.
|
|
832
909
|
* For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.
|