UNPKG

@cornerstonejs/core

Version:
157 lines (156 loc) 5.41 kB
import '@kitware/vtk.js/Rendering/Profiles/Geometry.js'; import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor.js'; import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper.js'; import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js'; import vtkCellArray from '@kitware/vtk.js/Common/Core/CellArray.js'; import { GeometryType, ViewportType } from '../../../enums/index.js'; import uuidv4 from '../../../utilities/uuidv4.js'; import { canvasToWorldContextPool, worldToCanvasContextPool, } from '../../helpers/vtkCanvasCoordinateTransforms.js'; import applyVolume3DCamera from './applyVolume3DCamera.js'; export class VtkGeometry3DRenderPath { async addData(ctx, data, options) { const payload = data; const actors = createActorEntries(payload.geometry); const hadVisibleProps = hasVisibleProps(ctx); actors.forEach((actorEntry) => { ctx.vtk.renderer.addActor(actorEntry.actor); }); if (!hadVisibleProps) { ctx.vtk.renderer.resetCamera(); } ctx.vtk.renderer.resetCameraClippingRange(); const rendering = { renderMode: 'vtkGeometry3d', actors, frameOfReferenceUID: payload.geometry.type === GeometryType.SURFACE ? payload.geometry.data.frameOfReferenceUID : undefined, }; return { rendering, updateDataPresentation: (props) => { this.updateDataPresentation(rendering, props); }, applyViewState: (camera) => { this.applyViewState(ctx, camera); }, getFrameOfReferenceUID: () => { return this.getFrameOfReferenceUID(rendering); }, render: () => { this.render(ctx); }, resize: () => { this.resize(ctx); }, removeData: () => { this.removeData(ctx, rendering); }, }; } updateDataPresentation(rendering, props) { applyDataPresentation(rendering, props); } applyViewState(ctx, camera) { applyVolume3DCamera(ctx, camera, { resetClippingRange: true, }); } canvasToWorld(ctx, canvasPos) { return canvasToWorldContextPool({ canvas: ctx.vtk.canvas, renderer: ctx.vtk.renderer, canvasPos, }); } worldToCanvas(ctx, worldPos) { return worldToCanvasContextPool({ canvas: ctx.vtk.canvas, renderer: ctx.vtk.renderer, worldPos, }); } getFrameOfReferenceUID(rendering) { return rendering.frameOfReferenceUID; } render(ctx) { ctx.display.requestRender(); } resize(ctx) { ctx.display.requestRender(); } removeData(ctx, rendering) { rendering.actors.forEach((actorEntry) => { ctx.vtk.renderer.removeActor(actorEntry.actor); }); } } export class VtkGeometry3DPath { constructor() { this.id = 'volume3d:vtk-geometry'; this.type = ViewportType.VOLUME_3D_NEXT; } matches(data, options) { return data.type === 'geometry' && options.renderMode === 'vtkGeometry3d'; } createRenderPath() { return new VtkGeometry3DRenderPath(); } selectContext(rootContext) { return rootContext; } } function createActorEntries(geometry) { if (geometry.type === GeometryType.SURFACE) { const surface = geometry.data; const polyData = vtkPolyData.newInstance(); polyData.getPoints().setData(surface.points, 3); polyData.setPolys(vtkCellArray.newInstance({ values: Uint32Array.from(surface.polys), })); const mapper = vtkMapper.newInstance(); mapper.setInputData(polyData); const actor = vtkActor.newInstance(); actor.setMapper(mapper); actor.setVisibility(surface.visible !== false); actor .getProperty() .setColor(surface.color[0] / 255, surface.color[1] / 255, surface.color[2] / 255); return [ { actor, referencedId: geometry.id, uid: uuidv4(), }, ]; } if (geometry.type === GeometryType.MESH) { const mesh = geometry.data; return mesh.actors.map((sourceActor, index) => { return { actor: sourceActor, referencedId: geometry.id, uid: uuidv4(), }; }); } throw new Error(`[VolumeViewport3D] Geometry type ${geometry.type} is not supported in 3D Next rendering`); } function applyDataPresentation(rendering, props) { rendering.actors.forEach((actorEntry) => { const actor = actorEntry.actor; actor.setVisibility(props?.visible === false ? false : true); if (props?.opacity !== undefined) { actor.getProperty().setOpacity(props.opacity); } if (props?.color) { actor .getProperty() .setColor(props.color[0] / 255, props.color[1] / 255, props.color[2] / 255); } }); } function hasVisibleProps(ctx) { const renderer = ctx.vtk.renderer; return Boolean(renderer.getActors?.().length || renderer.getVolumes?.().length); }