核心概念
本页示例代码已过时
渲染
index.html
<canvas class="target-canvas"></canvas>
app.js
import {
RenderingEngine, // 类
ORIENTATION, // 常量
ViewportType, // 枚举
} from 'vtkjs-viewport';
// 渲染
const renderingEngine = new RenderingEngine('ExampleRenderingEngineID');
const volumeId = 'VOLUME_ID ';
const viewports = [];
const viewport = {
sceneUID,
viewportId: 'viewportUID_0',
type: ViewportType.ORTHOGRAPHIC,
canvas: document.querySelector('.target-canvas'),
defaultOptions: {
orientation: Enums.OrientationAxis.AXIAL,
background: [Math.random(), Math.random(), Math.random()],
},
};
// 启动渲染
viewports.push(viewport);
renderingEngine.setViewports(viewports);
// 渲染背景
renderingEngine.render();
// 创建并加载我们的影像体数据
// 可参考:`./examples/helpers/getImageIdsAndCacheMetadata.js`
const imageIds = [
'wadors:https://wadoRsRoot.com/studies/studyInstanceUID/series/SeriesInstanceUID/instances/SOPInstanceUID/frames/1',
'wadors:https://wadoRsRoot.com/studies/studyInstanceUID/series/SeriesInstanceUID/instances/SOPInstanceUID/frames/2',
'wadors:https://wadoRsRoot.com/studies/studyInstanceUID/series/SeriesInstanceUID/instances/SOPInstanceUID/frames/3',
];
imageCache.makeAndCacheImageVolume(imageIds, volumeId);
imageCache.loadVolume(volumeId, (event) => {
if (event.framesProcessed === event.numFrames) {
console.log('done loading!');
}
});
// 把 scene 与一份或多份影像体数据关联起来
const scene = renderingEngine.getScene(sceneUID);
scene.setVolumes([
{
volumeId,
callback: ({ volumeActor, volumeId }) => {
// 可以在这里设置传递函数或 PET 颜色映射表
console.log('volume loaded!');
},
},
]);
const viewport = scene.getViewport(viewports[0].viewportId);
// 这一步会在 GPU 内存中初始化体数据
renderingEngine.render();
大部分情况下,更新只需用到:
RenderingEngine.setViewportsScene.setVolumes
如果你用了客户端路由、或者需要更积极地清理资源,
大多数构件都带有 .destroy 方法。例如:
renderingEngine.destroy();
工具
工具是一个未实例化的类,至少实现 BaseTool 接口。
工具可以通过其构造函数进行配置。要使用一个工具,必须:
- 使用库的顶层
addTool函数添加未实例化的工具 - 按名称把同一个工具添加到某个工具组(ToolGroup)中
与原文的一处差异
官方英文原文中,上面这段说明因编辑失误被连续重复了四遍。 这里只保留一遍。
工具的行为随后取决于:哪些渲染引擎、scene 和视口与它所属的工具组相关联, 以及该工具当前处于什么模式。
添加工具
@Tools 库内置了若干常用工具,它们都实现了 BaseTool 或 AnnotationTool。
添加一个工具就是让工具组能够使用它。另有一个顶层的 .removeTool。
import * as csTools3d from '@cornerstonejs/tools';
// 把未实例化的工具类添加到库中
// 之后当我们把每个工具显式加入一个或多个工具组时,
// 会用它们来初始化工具实例
const { PanTool, StackScrollMouseWheelTool, ZoomTool, LengthTool } = csTools3d;
csTools3d.addTool(PanTool);
csTools3d.addTool(StackScrollMouseWheelTool);
csTools3d.addTool(ZoomTool);
csTools3d.addTool(LengthTool);
工具组管理器
工具组是一种在一组 RenderingEngine、Scene 和 / 或 Viewport 之间
共享工具配置、状态和模式的方式。工具组由工具组管理器管理,
后者用于创建、查找和销毁工具组。
import { ToolGroupManager } from '@cornerstonejs/tools';
import { ctVolumeId } from './constants';
const toolGroupId = 'TOOL_GROUP_ID';
const sceneToolGroup = ToolGroupManager.createToolGroup(TOOL_GROUP_ID);
// 把工具加入工具组
sceneToolGroup.addTool(PanTool.toolName);
sceneToolGroup.addTool(ZoomTool.toolName);
sceneToolGroup.addTool(StackScrollMouseWheelTool.toolName);
sceneToolGroup.addTool(LengthTool.toolName, {
configuration: { volumeId: ctVolumeId },
});
工具模式
工具可以处于四种模式之一。每种模式都会影响工具如何响应交互。这些模式是:
| 工具模式 | 说明 |
| Active(激活) |
|
| Passive(被动,默认) |
|
| Enabled(启用) |
|
| Disabled(禁用) |
|
注意:
- 绝不应该存在两个绑定相同的 Active 工具
// 为每个工具设置该工具组中的工具模式
// 可能的模式包括:'Active'、'Passive'、'Enabled'、'Disabled'
sceneToolGroup.setToolActive(StackScrollMouseWheelTool.toolName);
sceneToolGroup.setToolActive(LengthTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
sceneToolGroup.setToolActive(PanTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Auxiliary }],
});
sceneToolGroup.setToolActive(ZoomTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Secondary }],
});
同步器
SynchronizerManager 暴露的 API 与 ToolGroupManager 类似。
创建出来的同步器带有 addTarget、addSource、add
(把该视口同时作为「源」和「目标」加入)等方法,以及对应的 remove* 方法。
同步器的工作方式是:监听某个指定事件在任意源上被触发。 一旦检测到,就为每个目标各调用一次回调函数。 其思路是:对源的改动应当被同步到各个目标上。
当某个视口被禁用时,同步器会自行把它从源 / 目标中移除。
同步器还暴露了一个 disabled 标志,可用于临时阻止同步。
import { Events as RENDERING_EVENTS } from 'vtkjs-viewport';
import { SynchronizerManager } from '@cornerstonejs/tools';
const cameraPositionSyncrhonizer = SynchronizerManager.createSynchronizer(
synchronizerName,
RENDERING_EVENTS.CAMERA_MODIFIED,
(
synchronizerInstance,
sourceViewport,
targetViewport,
cameraModifiedEvent
) => {
// 同步逻辑写在这里
}
);
// 添加要同步的视口
const firstViewport = { renderingEngineId, sceneUID, viewportId };
const secondViewport = {
/* */
};
sync.add(firstViewport);
sync.add(secondViewport);
下一步
接下来你可以: