|
@@ -4,6 +4,7 @@ import TibialPlateauAngleTool from '@/components/measures/TibialPlateauAngleTool
|
|
|
import DARAMeasurementTool from '@/components/measures/DARAMeasurementTool';
|
|
|
import HipDIMeasurementTool from '@/components/measures/HipDIMeasurementTool';
|
|
|
import HipNHAAngleMeasurementTool from '@/components/measures/HipNHAAngleMeasurementTool';
|
|
|
+import VHSMeasurementTool from '@/components/measures/VHSMeasurementTool';
|
|
|
|
|
|
const {
|
|
|
ToolGroupManager,
|
|
@@ -1475,4 +1476,273 @@ export class MeasurementToolManager {
|
|
|
this.clearHipNHAAngleMeasurements(viewportId)
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ // ==================== 心锥比测量工具 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 激活心锥比测量工具
|
|
|
+ */
|
|
|
+ static activateVHSMeasurementTool(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.setToolPassive(TibialPlateauAngleTool.toolName, {
|
|
|
+ removeAllBindings: true,
|
|
|
+ });
|
|
|
+ toolGroup.setToolPassive(DARAMeasurementTool.toolName, {
|
|
|
+ removeAllBindings: true,
|
|
|
+ });
|
|
|
+ toolGroup.setToolPassive(HipDIMeasurementTool.toolName, {
|
|
|
+ removeAllBindings: true,
|
|
|
+ });
|
|
|
+ toolGroup.setToolPassive(HipNHAAngleMeasurementTool.toolName, {
|
|
|
+ removeAllBindings: true,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 激活心锥比测量工具
|
|
|
+ toolGroup.setToolActive(VHSMeasurementTool.toolName, {
|
|
|
+ bindings: [{ mouseButton: MouseBindings.Primary }],
|
|
|
+ });
|
|
|
+
|
|
|
+ // 获取工具实例并激活修改模式
|
|
|
+ const toolInstance = toolGroup.getToolInstance(
|
|
|
+ VHSMeasurementTool.toolName
|
|
|
+ ) as VHSMeasurementTool;
|
|
|
+
|
|
|
+ const viewport = cornerstone.getEnabledElementByViewportId(viewportId)?.viewport;
|
|
|
+ if (toolInstance && viewport.element) {
|
|
|
+ toolInstance._activateModify(viewport.element);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 自动创建一个预设的注解
|
|
|
+ try {
|
|
|
+ if (viewport && viewport.element) {
|
|
|
+ // 创建预设注解
|
|
|
+ const defaultAnnotation = VHSMeasurementTool.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(
|
|
|
+ VHSMeasurementTool.toolName
|
|
|
+ ) as VHSMeasurementTool;
|
|
|
+
|
|
|
+ if (toolInstance && '_updateCachedStats' in toolInstance) {
|
|
|
+ (toolInstance as any)._updateCachedStats(defaultAnnotation, enabledElement);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 触发渲染更新
|
|
|
+ viewport.render();
|
|
|
+
|
|
|
+ console.log('[MeasurementToolManager] Default VHS annotation created successfully');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('[MeasurementToolManager] Failed to create default VHS annotation:', error);
|
|
|
+ // 注解创建失败不影响工具激活
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(
|
|
|
+ `[MeasurementToolManager] VHS tool activated for viewport: ${viewportId}`
|
|
|
+ );
|
|
|
+ return true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(
|
|
|
+ `[MeasurementToolManager] Error activating VHS tool:`,
|
|
|
+ error
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停用心锥比测量工具
|
|
|
+ */
|
|
|
+ static deactivateVHSMeasurementTool(viewportId: string): boolean {
|
|
|
+ const toolGroup = this.getToolGroup(viewportId);
|
|
|
+ if (!toolGroup) return false;
|
|
|
+
|
|
|
+ try {
|
|
|
+ toolGroup.setToolPassive(VHSMeasurementTool.toolName, {
|
|
|
+ removeAllBindings: true,
|
|
|
+ });
|
|
|
+ console.log(
|
|
|
+ `[MeasurementToolManager] VHS tool deactivated for viewport: ${viewportId}`
|
|
|
+ );
|
|
|
+ return true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(
|
|
|
+ `[MeasurementToolManager] Error deactivating VHS tool:`,
|
|
|
+ error
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查心锥比测量工具是否处于激活状态
|
|
|
+ */
|
|
|
+ static isVHSMeasurementToolActive(viewportId: string): boolean {
|
|
|
+ const toolGroup = this.getToolGroup(viewportId);
|
|
|
+ if (!toolGroup) return false;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const activeTool = toolGroup.getActivePrimaryMouseButtonTool();
|
|
|
+ return activeTool === VHSMeasurementTool.toolName;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(
|
|
|
+ `[MeasurementToolManager] Error checking VHS tool state:`,
|
|
|
+ error
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切换心锥比测量工具状态
|
|
|
+ */
|
|
|
+ static toggleVHSMeasurementTool(viewportId: string): boolean {
|
|
|
+ const isActive = this.isVHSMeasurementToolActive(viewportId);
|
|
|
+
|
|
|
+ if (isActive) {
|
|
|
+ return this.deactivateVHSMeasurementTool(viewportId);
|
|
|
+ } else {
|
|
|
+ return this.activateVHSMeasurementTool(viewportId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清除指定 viewport 的所有心锥比测量标注
|
|
|
+ */
|
|
|
+ static clearVHSMeasurements(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(
|
|
|
+ VHSMeasurementTool.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} VHS measurements for viewport: ${viewportId}`
|
|
|
+ );
|
|
|
+ return true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(
|
|
|
+ `[MeasurementToolManager] Error clearing VHS measurements:`,
|
|
|
+ error
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定 viewport 的所有心锥比测量结果
|
|
|
+ */
|
|
|
+ // eslint-disable-next-line
|
|
|
+ static getVHSMeasurements(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(
|
|
|
+ VHSMeasurementTool.toolName,
|
|
|
+ viewport.element
|
|
|
+ );
|
|
|
+
|
|
|
+ return annotations.map((annotation) => ({
|
|
|
+ annotationUID: annotation.annotationUID,
|
|
|
+ vhs: annotation.data?.cachedStats?.vhs || 0,
|
|
|
+ longAxisCount: annotation.data?.cachedStats?.longAxisCount || 0,
|
|
|
+ shortAxisCount: annotation.data?.cachedStats?.shortAxisCount || 0,
|
|
|
+ ratio: annotation.data?.cachedStats?.ratio || 0,
|
|
|
+ unit: 'ratio',
|
|
|
+ points: annotation.data?.handles?.points || [],
|
|
|
+ }));
|
|
|
+ } catch (error) {
|
|
|
+ console.error(
|
|
|
+ `[MeasurementToolManager] Error getting VHS measurements:`,
|
|
|
+ error
|
|
|
+ );
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为多个 viewport 批量激活心锥比测量工具
|
|
|
+ */
|
|
|
+ static activateVHSMeasurementToolForViewports(
|
|
|
+ viewportIds: string[]
|
|
|
+ ): boolean[] {
|
|
|
+ return viewportIds.map((viewportId) =>
|
|
|
+ this.activateVHSMeasurementTool(viewportId)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为多个 viewport 批量停用心锥比测量工具
|
|
|
+ */
|
|
|
+ static deactivateVHSMeasurementToolForViewports(
|
|
|
+ viewportIds: string[]
|
|
|
+ ): boolean[] {
|
|
|
+ return viewportIds.map((viewportId) =>
|
|
|
+ this.deactivateVHSMeasurementTool(viewportId)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为多个 viewport 批量清除心锥比测量
|
|
|
+ */
|
|
|
+ static clearVHSMeasurementsForViewports(viewportIds: string[]): boolean[] {
|
|
|
+ return viewportIds.map((viewportId) =>
|
|
|
+ this.clearVHSMeasurements(viewportId)
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|