diff --git a/common/reviews/api/core.api.md b/common/reviews/api/core.api.md index 41e304aa65..d1c27c710e 100644 --- a/common/reviews/api/core.api.md +++ b/common/reviews/api/core.api.md @@ -797,6 +797,8 @@ export enum EVENTS { // (undocumented) PRE_STACK_NEW_IMAGE = "CORNERSTONE_PRE_STACK_NEW_IMAGE", // (undocumented) + PRESET_MODIFIED = "CORNERSTONE_VIEWPORT_RENDERING_PRESET_MODIFIED", + // (undocumented) STACK_NEW_IMAGE = "CORNERSTONE_STACK_NEW_IMAGE", // (undocumented) STACK_VIEWPORT_NEW_STACK = "CORNERSTONE_STACK_VIEWPORT_NEW_STACK", diff --git a/packages/core/examples/volumeViewport3D/index.ts b/packages/core/examples/volumeViewport3D/index.ts index c8c7a81bd8..d8f985025a 100644 --- a/packages/core/examples/volumeViewport3D/index.ts +++ b/packages/core/examples/volumeViewport3D/index.ts @@ -5,13 +5,13 @@ import { RenderingEngine, setVolumesForViewports, Types, - utilities, volumeLoader, } from '@cornerstonejs/core'; import * as cornerstoneTools from '@cornerstonejs/tools'; import { addButtonToToolbar, addDropdownToToolbar, + addManipulationBindings, createImageIdsAndCacheMetaData, initDemo, setTitleAndDescription, @@ -22,11 +22,7 @@ console.warn( 'Click on index.ts to open source code for this example --------->' ); -const { - ToolGroupManager, - TrackballRotateTool, - Enums: csToolsEnums, -} = cornerstoneTools; +const { ToolGroupManager, Enums: csToolsEnums } = cornerstoneTools; const { ViewportType } = Enums; const { MouseBindings } = csToolsEnums; @@ -91,21 +87,15 @@ addDropdownToToolbar({ defaultValue: 'CT-Bone', }, onSelectedValueChange: (presetName) => { - const volumeActor = renderingEngine - .getViewport(viewportId) - .getDefaultActor().actor as Types.VolumeActor; - - utilities.applyPreset( - volumeActor, - CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === presetName) - ); - - renderingEngine.render(); + viewport.setProperties({ preset: presetName }); + viewport.render(); }, }); // ============================= // +let viewport; + /** * Runs the demo */ @@ -115,26 +105,13 @@ async function run() { const toolGroupId = 'TOOL_GROUP_ID'; - // Add tools to Cornerstone3D - cornerstoneTools.addTool(TrackballRotateTool); - // Define a tool group, which defines how mouse events map to tool commands for // Any viewport using the group const toolGroup = ToolGroupManager.createToolGroup(toolGroupId); // Add the tools to the tool group and specify which volume they are pointing at - toolGroup.addTool(TrackballRotateTool.toolName, { - configuration: { volumeId }, - }); - - // Set the initial state of the tools, here we set one tool active on left click. - // This means left click will draw that tool. - toolGroup.setToolActive(TrackballRotateTool.toolName, { - bindings: [ - { - mouseButton: MouseBindings.Primary, // Left Click - }, - ], + addManipulationBindings(toolGroup, { + is3DViewport: true, }); // Get Cornerstone imageIds and fetch metadata into RAM @@ -158,7 +135,7 @@ async function run() { element: element1, defaultOptions: { orientation: Enums.OrientationAxis.CORONAL, - background: [0.2, 0, 0.2], + background: CONSTANTS.BACKGROUND_COLORS.slicer3D, }, }, ]; @@ -175,24 +152,16 @@ async function run() { // Set the volume to load volume.load(); + viewport = renderingEngine.getViewport(viewportId); setVolumesForViewports(renderingEngine, [{ volumeId }], [viewportId]).then( () => { - const volumeActor = renderingEngine - .getViewport(viewportId) - .getDefaultActor().actor as Types.VolumeActor; - - utilities.applyPreset( - volumeActor, - CONSTANTS.VIEWPORT_PRESETS.find((preset) => preset.name === 'CT-Bone') - ); - + viewport.setProperties({ + preset: 'CT-Bone', + }); viewport.render(); } ); - - const viewport = renderingEngine.getViewport(viewportId); - renderingEngine.render(); } run(); diff --git a/packages/core/src/RenderingEngine/BaseVolumeViewport.ts b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts index 080a25db23..5f3519d0bf 100644 --- a/packages/core/src/RenderingEngine/BaseVolumeViewport.ts +++ b/packages/core/src/RenderingEngine/BaseVolumeViewport.ts @@ -663,7 +663,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { * * @returns void */ - private setPreset(presetName, volumeId, suppressEvents) { + private setPreset(presetNameOrObj, volumeId, suppressEvents) { const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId); if (!applicableVolumeActorInfo) { @@ -672,9 +672,13 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { const { volumeActor } = applicableVolumeActorInfo; - const preset = VIEWPORT_PRESETS.find((preset) => { - return preset.name === presetName; - }); + let preset = presetNameOrObj; + + if (typeof preset === 'string') { + preset = VIEWPORT_PRESETS.find((preset) => { + return preset.name === presetNameOrObj; + }); + } if (!preset) { return; @@ -682,7 +686,14 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport { applyPreset(volumeActor, preset); - this.viewportProperties.preset = presetName; + if (!suppressEvents) { + triggerEvent(this.element, Events.PRESET_MODIFIED, { + viewportId: this.id, + volumeId: applicableVolumeActorInfo.volumeId, + actor: volumeActor, + presetName: preset.name, + }); + } } /** diff --git a/packages/core/src/enums/Events.ts b/packages/core/src/enums/Events.ts index 875d35d0a8..79e8cfb5b4 100644 --- a/packages/core/src/enums/Events.ts +++ b/packages/core/src/enums/Events.ts @@ -38,6 +38,12 @@ enum Events { * and see what event detail is included in {@link EventTypes.VoiModifiedEventDetail | VoiModified Event Detail } */ VOI_MODIFIED = 'CORNERSTONE_VOI_MODIFIED', + /** + * Triggers on the HTML element when viewport modifies its preset (used in volume viewport 3D) + * + * Make use of {@link EventTypes.PresetModifiedEvent | PresetModified Event Type } for typing your event listeners for PRESET_MODIFIED event, + */ + PRESET_MODIFIED = 'CORNERSTONE_VIEWPORT_RENDERING_PRESET_MODIFIED', /** * Triggers on the HTML element when viewport modifies its display area * diff --git a/packages/core/src/utilities/applyPreset.ts b/packages/core/src/utilities/applyPreset.ts index 3e330c99e5..997d239e90 100644 --- a/packages/core/src/utilities/applyPreset.ts +++ b/packages/core/src/utilities/applyPreset.ts @@ -57,8 +57,9 @@ export default function applyPreset( applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun); - actor.getProperty().setScalarOpacity(0, ofun); + const property = actor.getProperty(); + property.setScalarOpacity(0, ofun); const [ gradientMinValue, gradientMinOpacity, @@ -66,26 +67,28 @@ export default function applyPreset( 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); + property.setUseGradientOpacity(0, true); + property.setGradientOpacityMinimumValue(0, gradientMinValue); + property.setGradientOpacityMinimumOpacity(0, gradientMinOpacity); + property.setGradientOpacityMaximumValue(0, gradientMaxValue); + property.setGradientOpacityMaximumOpacity(0, gradientMaxOpacity); if (preset.interpolation === '1') { - actor.getProperty().setInterpolationTypeToFastLinear(); - //actor.getProperty().setInterpolationTypeToLinear() + property.setInterpolationTypeToFastLinear(); + //property.setInterpolationTypeToLinear() } + property.setShade(preset.shade === '1'); + const ambient = parseFloat(preset.ambient); const diffuse = parseFloat(preset.diffuse); const specular = parseFloat(preset.specular); const specularPower = parseFloat(preset.specularPower); - actor.getProperty().setAmbient(ambient); - actor.getProperty().setDiffuse(diffuse); - actor.getProperty().setSpecular(specular); - actor.getProperty().setSpecularPower(specularPower); + property.setAmbient(ambient); + property.setDiffuse(diffuse); + property.setSpecular(specular); + property.setSpecularPower(specularPower); } function getShiftRange(colorTransferArray) {