MITK实现连续二维测量

一、背景描述:

MITK的Measurement插件支持多种二维测量工具,但是也有一定的缺点:完成一次测量后,测量工具对应的按钮自动弹起,需要再次选择工具方可再次测量,特别是对于连续进行一种类型的测量工具时,操作不连贯。

二、源码分析:

分析MITK的源码,每次测量时,点击按钮时将对应创建一个mitk::DataNode,并创建一个工具对应PlanarFigure类型的数据设置data。然后在view中实现NodeAdded()虚函数,并在该函数中为新创建的数据类型添加事件监听。

typedef itk::SimpleMemberCommand<QmitkMeasurementView> SimpleCommandType;
    typedef itk::MemberCommand<QmitkMeasurementView> MemberCommandType;

    // add observer for event when figure has been placed
    auto initializationCommand = SimpleCommandType::New();
    initializationCommand->SetCallbackFunction(this, &QmitkMeasurementView::PlanarFigureInitialized);
    data.m_EndPlacementObserverTag = planarFigure->AddObserver(mitk::EndPlacementPlanarFigureEvent(), initializationCommand);

    // add observer for event when figure is picked (selected)
    auto selectCommand = MemberCommandType::New();
    selectCommand->SetCallbackFunction(this, &QmitkMeasurementView::PlanarFigureSelected);
    data.m_SelectObserverTag = planarFigure->AddObserver(mitk::SelectPlanarFigureEvent(), selectCommand);

    // add observer for event during interaction when a point is moved
    auto duringInteractionCommand = SimpleCommandType::New();
    duringInteractionCommand->SetCallbackFunction(this, &QmitkMeasurementView::UpdateMeasurementText);
    data.m_DuringInteractionObserverTag = planarFigure->AddObserver(mitk::PointMovedPlanarFigureEvent(), duringInteractionCommand);

其中,监听mitk::EndPlacementPlanarFigureEvent()事件,即为完成一次测量时触发该事件,在PlanarFigureInitialized这个回调函数中将所有的测量工具初始化为未按下状态。

从而实现了点击一次按钮进行一次测量,测量结束后将所有的按钮初始化。

三、连接测量实现:

实现的基本思路是测量结束后,不去初始化按钮,而是根据按钮创建一个新的DataNode并给该dataNode设置上交互器,从而实现了连接测量。

1. 首先修改mitk::EndPlacementPlanarFigureEvent()的回调函数:

auto initializationCommand = SimpleCommandType::New();
     initializationCommand->SetCallbackFunction(this, &QmitkCommonToolView::After2DMeasurement);
     data.m_EndPlacementObserverTag =
       planarFigure->AddObserver(mitk::EndPlacementPlanarFigureEvent(), initializationCommand);

在After2DMeasurement()函数中实现根据按钮名创建新的PlanarFigure类型的数据节点,由于公司的项目修改了UI,使用了一个下拉框供用户选择测量工具,代码不具参考性,只将创建新node的函数粘贴如下:

void QmitkCommonToolView::CreateNewFigureDataNodeByType(QString type)
 {
   if (type.isEmpty())
   {
     return;
   }

   auto newNode = mitk::DataNode::New();
   if (type == tr("Select Tools"))
   {
     newNode = nullptr;
     return;
   }
   else if (type == tr("Line"))
   {
     newNode->SetName(QString("Line%1").arg(++m_LineCounter).toStdString());
     newNode->SetData(mitk::PlanarLine::New());
   }
   else if (type == tr("Angle"))
   {
     newNode->SetName(QString("Angle%1").arg(++m_AngleCounter).toStdString());
     newNode->SetData(mitk::PlanarAngle::New());
   }
   else if (type == tr("Rectangle"))
   {
     newNode->SetName(QString("Rectangle%1").arg(++m_RectangleCounter).toStdString());
     auto rect = mitk::PlanarRectangle::New();
     newNode->SetData(rect);
   }
   else if (type == tr("Polygon"))
   {
     auto Polygon = mitk::PlanarPolygon::New();
     Polygon->ClosedOn();
     newNode->SetName(QString("Polygon%1").arg(++m_PolygonCounter).toStdString());
     newNode->SetData(Polygon);
     newNode->SetBoolProperty("planarfigure.isextendable", true);
   }
   else if (type == tr("Ellipse"))
   {
     newNode->SetName(QString("Ellipse%1").arg(++m_EllipseCounter).toStdString());
     newNode->SetData(mitk::PlanarEllipse::New());
   }
   else
   {
     MITK_ERROR << "Input param is an invlid type name: " << type;
     newNode = nullptr;
     return;
   }

   //为新建的dataNode设置交互。
   auto interactor = mitk::PlanarFigureInteractor::New();
   auto planarFigureModule = us::ModuleRegistry::GetModule("MitkPlanarFigure");
   interactor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule);
   interactor->SetEventConfig("PlanarFigureConfig.xml", planarFigureModule);
   interactor->SetDataNode(newNode);

   newNode->SetSelected(true);
   this->GetDataStorage()->Add(newNode);
 }

这时,已经实现了连续测量的效果,需要注意的是,当用户切换工具时或者结束测量时,需要清理未完成测量的空DataNode. 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值