123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- import * as cornerstone from '@cornerstonejs/core';
- import * as cornerstoneTools from '@cornerstonejs/tools';
- import TibialPlateauAngleTool from '@/components/measures/TibialPlateauAngleTool';
- const {
- ToolGroupManager,
- LengthTool,
- AngleTool,
- WindowLevelTool,
- MagnifyTool,
- Enums: csToolsEnums,
- } = cornerstoneTools;
- const { MouseBindings } = csToolsEnums;
- /**
- * 测量工具管理器
- * 统一管理所有测量相关的工具操作
- */
- export class MeasurementToolManager {
- /**
- * 根据 viewportId 获取对应的工具组
- */
- static getToolGroup(
- viewportId: string
- ): cornerstoneTools.Types.IToolGroup | undefined {
- const toolGroupId = `STACK_TOOL_GROUP_ID_${viewportId}`;
- const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);
- if (!toolGroup) {
- console.warn(
- `[MeasurementToolManager] Tool group not found for viewport: ${viewportId}`
- );
- }
- return toolGroup;
- }
- /**
- * 激活线段测量工具
- */
- static activateLengthTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- // 停用其他可能冲突的工具
- toolGroup.setToolPassive(WindowLevelTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(MagnifyTool.toolName, {
- removeAllBindings: true,
- });
- // 激活线段测量工具
- toolGroup.setToolActive(LengthTool.toolName, {
- bindings: [{ mouseButton: MouseBindings.Primary }],
- });
- console.log(
- `[MeasurementToolManager] Length tool activated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error activating length tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 停用线段测量工具
- */
- static deactivateLengthTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- toolGroup.setToolPassive(LengthTool.toolName, {
- removeAllBindings: true,
- });
- console.log(
- `[MeasurementToolManager] Length tool deactivated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error deactivating length tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 检查线段测量工具是否处于激活状态
- */
- static isLengthToolActive(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- const activeTool = toolGroup.getActivePrimaryMouseButtonTool();
- return activeTool === LengthTool.toolName;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error checking tool state:`,
- error
- );
- return false;
- }
- }
- /**
- * 切换线段测量工具状态
- */
- static toggleLengthTool(viewportId: string): boolean {
- const isActive = this.isLengthToolActive(viewportId);
- if (isActive) {
- return this.deactivateLengthTool(viewportId);
- } else {
- return this.activateLengthTool(viewportId);
- }
- }
- /**
- * 清除指定 viewport 的所有线段测量标注
- */
- static clearLengthMeasurements(viewportId: string): boolean {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return false;
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- LengthTool.toolName,
- viewport.element
- );
- let removedCount = 0;
- annotations.forEach((annotation) => {
- if (annotation.annotationUID) {
- cornerstoneTools.annotation.state.removeAnnotation(
- annotation.annotationUID
- );
- removedCount++;
- }
- });
- viewport.render();
- console.log(
- `[MeasurementToolManager] Cleared ${removedCount} length measurements for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error clearing measurements:`,
- error
- );
- return false;
- }
- }
- /**
- * 获取指定 viewport 的所有线段测量结果
- */
- // eslint-disable-next-line
- static getLengthMeasurements(viewportId: string): any[] {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return [];
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- LengthTool.toolName,
- viewport.element
- );
- return annotations.map((annotation) => ({
- annotationUID: annotation.annotationUID,
- length: annotation.data?.cachedStats?.length || 0,
- unit: annotation.data?.cachedStats?.unit || 'mm',
- points: annotation.data?.handles?.points || [],
- }));
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error getting measurements:`,
- error
- );
- return [];
- }
- }
- /**
- * 为多个 viewport 批量激活线段测量工具
- */
- static activateLengthToolForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) => this.activateLengthTool(viewportId));
- }
- /**
- * 为多个 viewport 批量停用线段测量工具
- */
- static deactivateLengthToolForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) =>
- this.deactivateLengthTool(viewportId)
- );
- }
- /**
- * 为多个 viewport 批量清除线段测量
- */
- static clearLengthMeasurementsForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) =>
- this.clearLengthMeasurements(viewportId)
- );
- }
- /**
- * 激活角度测量工具
- */
- static activateAngleTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- // 停用其他可能冲突的工具
- toolGroup.setToolPassive(WindowLevelTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(MagnifyTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(LengthTool.toolName, {
- removeAllBindings: true,
- });
- // 激活角度测量工具
- toolGroup.setToolActive(AngleTool.toolName, {
- bindings: [{ mouseButton: MouseBindings.Primary }],
- });
- console.log(
- `[MeasurementToolManager] Angle tool activated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error activating angle tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 停用角度测量工具
- */
- static deactivateAngleTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- toolGroup.setToolPassive(AngleTool.toolName, {
- removeAllBindings: true,
- });
- console.log(
- `[MeasurementToolManager] Angle tool deactivated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error deactivating angle tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 检查角度测量工具是否处于激活状态
- */
- static isAngleToolActive(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- const activeTool = toolGroup.getActivePrimaryMouseButtonTool();
- return activeTool === AngleTool.toolName;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error checking angle tool state:`,
- error
- );
- return false;
- }
- }
- /**
- * 切换角度测量工具状态
- */
- static toggleAngleTool(viewportId: string): boolean {
- const isActive = this.isAngleToolActive(viewportId);
- if (isActive) {
- return this.deactivateAngleTool(viewportId);
- } else {
- return this.activateAngleTool(viewportId);
- }
- }
- /**
- * 清除指定 viewport 的所有角度测量标注
- */
- static clearAngleMeasurements(viewportId: string): boolean {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return false;
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- AngleTool.toolName,
- viewport.element
- );
- let removedCount = 0;
- annotations.forEach((annotation) => {
- if (annotation.annotationUID) {
- cornerstoneTools.annotation.state.removeAnnotation(
- annotation.annotationUID
- );
- removedCount++;
- }
- });
- viewport.render();
- console.log(
- `[MeasurementToolManager] Cleared ${removedCount} angle measurements for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error clearing angle measurements:`,
- error
- );
- return false;
- }
- }
- /**
- * 获取指定 viewport 的所有角度测量结果
- */
- // eslint-disable-next-line
- static getAngleMeasurements(viewportId: string): any[] {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return [];
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- AngleTool.toolName,
- viewport.element
- );
- return annotations.map((annotation) => ({
- annotationUID: annotation.annotationUID,
- angle: annotation.data?.cachedStats?.angle || 0,
- unit: annotation.data?.cachedStats?.unit || 'degrees',
- points: annotation.data?.handles?.points || [],
- }));
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error getting angle measurements:`,
- error
- );
- return [];
- }
- }
- /**
- * 为多个 viewport 批量激活角度测量工具
- */
- static activateAngleToolForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) => this.activateAngleTool(viewportId));
- }
- /**
- * 为多个 viewport 批量停用角度测量工具
- */
- static deactivateAngleToolForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) =>
- this.deactivateAngleTool(viewportId)
- );
- }
- /**
- * 为多个 viewport 批量清除角度测量
- */
- static clearAngleMeasurementsForViewports(viewportIds: string[]): boolean[] {
- return viewportIds.map((viewportId) =>
- this.clearAngleMeasurements(viewportId)
- );
- }
- // ==================== 胫骨平台夹角测量工具 ====================
- /**
- * 激活胫骨平台夹角测量工具
- */
- static activateTibialPlateauAngleTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- // 停用其他可能冲突的工具
- toolGroup.setToolPassive(WindowLevelTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(MagnifyTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(LengthTool.toolName, {
- removeAllBindings: true,
- });
- toolGroup.setToolPassive(AngleTool.toolName, {
- removeAllBindings: true,
- });
- // 激活胫骨平台夹角测量工具
- toolGroup.setToolActive(TibialPlateauAngleTool.toolName, {
- bindings: [{ mouseButton: MouseBindings.Primary }],
- });
- // 获取工具实例并激活修改模式
- const toolInstance = toolGroup.getToolInstance(
- TibialPlateauAngleTool.toolName
- ) as TibialPlateauAngleTool;
- // 使用参数中的 viewportId,而不是硬编码
- const viewport = cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (toolInstance && viewport.element) {
- toolInstance._activateModify(viewport.element);
- }
- // 自动创建一个预设的注解
- try {
- if (viewport && viewport.element) {
- // 创建预设注解
- const defaultAnnotation = TibialPlateauAngleTool.createDefaultAnnotation(
- viewport.element as HTMLDivElement,
- viewport as cornerstone.Types.IStackViewport
- );
- // 添加注解到状态管理
- cornerstoneTools.annotation.state.addAnnotation(
- defaultAnnotation,
- viewport.element
- );
- // 获取工具实例并更新缓存统计数据
- const enabledElement = cornerstone.getEnabledElement(viewport.element);
- if (enabledElement) {
- const toolInstance = toolGroup.getToolInstance(
- TibialPlateauAngleTool.toolName
- ) as TibialPlateauAngleTool;
- if (toolInstance && '_updateCachedStats' in toolInstance) {
- (toolInstance as any)._updateCachedStats(defaultAnnotation, enabledElement);
- }
- }
- // 触发渲染更新
- // 触发渲染更新
- const viewportIdsToRender = cornerstoneTools.utilities.viewportFilters.getViewportIdsWithToolToRender(
- viewport.element,
- TibialPlateauAngleTool.toolName
- );
- cornerstoneTools.utilities.triggerAnnotationRenderForViewportIds(
- viewportIdsToRender
- );
- console.log('[MeasurementToolManager] Default TPA annotation created successfully');
- }
- } catch (error) {
- console.error('[MeasurementToolManager] Failed to create default annotation:', error);
- // 注解创建失败不影响工具激活
- }
- console.log(
- `[MeasurementToolManager] TibialPlateauAngle tool activated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error activating TibialPlateauAngle tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 停用胫骨平台夹角测量工具
- */
- static deactivateTibialPlateauAngleTool(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- toolGroup.setToolPassive(TibialPlateauAngleTool.toolName, {
- removeAllBindings: true,
- });
- console.log(
- `[MeasurementToolManager] TibialPlateauAngle tool deactivated for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error deactivating TibialPlateauAngle tool:`,
- error
- );
- return false;
- }
- }
- /**
- * 检查胫骨平台夹角测量工具是否处于激活状态
- */
- static isTibialPlateauAngleToolActive(viewportId: string): boolean {
- const toolGroup = this.getToolGroup(viewportId);
- if (!toolGroup) return false;
- try {
- const activeTool = toolGroup.getActivePrimaryMouseButtonTool();
- return activeTool === TibialPlateauAngleTool.toolName;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error checking TibialPlateauAngle tool state:`,
- error
- );
- return false;
- }
- }
- /**
- * 切换胫骨平台夹角测量工具状态
- */
- static toggleTibialPlateauAngleTool(viewportId: string): boolean {
- const isActive = this.isTibialPlateauAngleToolActive(viewportId);
- if (isActive) {
- return this.deactivateTibialPlateauAngleTool(viewportId);
- } else {
- return this.activateTibialPlateauAngleTool(viewportId);
- }
- }
- /**
- * 清除指定 viewport 的所有胫骨平台夹角测量标注
- */
- static clearTibialPlateauAngleMeasurements(viewportId: string): boolean {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return false;
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- TibialPlateauAngleTool.toolName,
- viewport.element
- );
- let removedCount = 0;
- annotations.forEach((annotation) => {
- if (annotation.annotationUID) {
- cornerstoneTools.annotation.state.removeAnnotation(
- annotation.annotationUID
- );
- removedCount++;
- }
- });
- viewport.render();
- console.log(
- `[MeasurementToolManager] Cleared ${removedCount} TibialPlateauAngle measurements for viewport: ${viewportId}`
- );
- return true;
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error clearing TibialPlateauAngle measurements:`,
- error
- );
- return false;
- }
- }
- /**
- * 获取指定 viewport 的所有胫骨平台夹角测量结果
- */
- // eslint-disable-next-line
- static getTibialPlateauAngleMeasurements(viewportId: string): any[] {
- try {
- const viewport =
- cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
- if (!viewport) {
- console.warn(
- `[MeasurementToolManager] Viewport not found: ${viewportId}`
- );
- return [];
- }
- const annotations = cornerstoneTools.annotation.state.getAnnotations(
- TibialPlateauAngleTool.toolName,
- viewport.element
- );
- return annotations.map((annotation) => ({
- annotationUID: annotation.annotationUID,
- TPA: annotation.data?.cachedStats?.TPA || 0,
- unit: 'degrees',
- points: annotation.data?.handles?.points || [],
- }));
- } catch (error) {
- console.error(
- `[MeasurementToolManager] Error getting TibialPlateauAngle measurements:`,
- error
- );
- return [];
- }
- }
- /**
- * 为多个 viewport 批量激活胫骨平台夹角测量工具
- */
- static activateTibialPlateauAngleToolForViewports(
- viewportIds: string[]
- ): boolean[] {
- return viewportIds.map((viewportId) =>
- this.activateTibialPlateauAngleTool(viewportId)
- );
- }
- /**
- * 为多个 viewport 批量停用胫骨平台夹角测量工具
- */
- static deactivateTibialPlateauAngleToolForViewports(
- viewportIds: string[]
- ): boolean[] {
- return viewportIds.map((viewportId) =>
- this.deactivateTibialPlateauAngleTool(viewportId)
- );
- }
- /**
- * 为多个 viewport 批量清除胫骨平台夹角测量
- */
- static clearTibialPlateauAngleMeasurementsForViewports(
- viewportIds: string[]
- ): boolean[] {
- return viewportIds.map((viewportId) =>
- this.clearTibialPlateauAngleMeasurements(viewportId)
- );
- }
- }
|