Slicer学习笔记(三十一)slicer调试Markups模块
1、源码编译3d slicer
自己根据官网说明编译。
2、调试Markup模块
2.1、调试设置
编译时选择编译模式为RelWithDeb。 编译成功后就可以调试自己想学习的模块了。 此时我想学习的是Markups模块,所以就调试这个模块了。 先打开编译好的slicer.exe,并代开slicer.sln项目,然后“调试–附加到进程”找到 slicer-app-real.exe 选中。 在Markups项目中打好断点,程序入口一般是 setup和enter
void qSlicerMarkupsModuleWidget::setup()
{
Q_D(qSlicerMarkupsModuleWidget);
d->setupUi(this);
this->Superclass::setup();
}
void qSlicerMarkupsModuleWidget::enter()
{
Q_D(qSlicerMarkupsModuleWidget);
this->Superclass::enter();
this->checkForAnnotationFiducialConversion();
d->setMRMLMarkupsNodeFromSelectionNode();
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::NodeAddedEvent,
this, SLOT(onNodeAddedEvent(vtkObject*, vtkObject*)));
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::NodeRemovedEvent,
this, SLOT(onNodeRemovedEvent(vtkObject*, vtkObject*)));
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::EndImportEvent,
this, SLOT(onMRMLSceneEndImportEvent()));
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::EndBatchProcessEvent,
this, SLOT(onMRMLSceneEndBatchProcessEvent()));
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::EndCloseEvent,
this, SLOT(onMRMLSceneEndCloseEvent()));
this->qvtkConnect(this->mrmlScene(), vtkMRMLScene::EndRestoreEvent,
this, SLOT(onMRMLSceneEndRestoreEvent()));
vtkMRMLNode *selectionNode = d->selectionNode();
if (selectionNode)
{
this->qvtkConnect(selectionNode, vtkMRMLSelectionNode::ActivePlaceNodeIDChangedEvent,
this, SLOT(onSelectionNodeActivePlaceNodeIDChanged()));
}
if (d->MarkupsNode)
{
vtkMRMLMarkupsNode* markupsNode = d->MarkupsNode;
d->MarkupsNode = nullptr;
this->setMRMLMarkupsNode(markupsNode);
}
this->updateMaximumScaleFromVolumes();
}
2.2、进入调试
在slicer界面中选择Markups模块。
然后界面会进入Markups界面,同时调试的程序进入断点。 两个UI文件如下 进入后的界面如下图所示:
选择
void qSlicerMarkupsModuleWidget::onSelectionNodeActivePlaceNodeIDChanged()
{
Q_D(qSlicerMarkupsModuleWidget);
vtkMRMLMarkupsNode* markupsNode = vtkMRMLMarkupsNode::SafeDownCast(d->selectionNodeActivePlaceNode());
this->setMRMLMarkupsNode(markupsNode);
}
vtkMRMLNode* qSlicerMarkupsModuleWidgetPrivate::selectionNodeActivePlaceNode()
{
Q_Q(qSlicerMarkupsModuleWidget);
vtkMRMLSelectionNode *selNode = this->selectionNode();
if (!selNode)
{
return nullptr;
}
const char *selectionNodeActivePlaceNodeID = selNode->GetActivePlaceNodeID();
if (!selectionNodeActivePlaceNodeID)
{
return nullptr;
}
vtkMRMLNode* activePlaceNode = q->mrmlScene()->GetNodeByID(selectionNodeActivePlaceNodeID);
return activePlaceNode;
}
vtkMRMLSelectionNode* qSlicerMarkupsModuleWidgetPrivate::selectionNode()
{
Q_Q(qSlicerMarkupsModuleWidget);
if (!q->mrmlScene() || !q->markupsLogic())
{
return nullptr;
}
vtkMRMLSelectionNode *selectionNode = vtkMRMLSelectionNode::SafeDownCast(
q->mrmlScene()->GetNodeByID(q->markupsLogic()->GetSelectionNodeID().c_str()));
return selectionNode;
}
新增加一个fiducial,执行的代码如上,选择一个位置放下,效果如下。
2.3、通过上述一顿操作,我可以学到什么
void qSlicerMarkupsModuleWidget::onSelectionNodeActivePlaceNodeIDChanged()
{
Q_D(qSlicerMarkupsModuleWidget);
vtkMRMLMarkupsNode* markupsNode = vtkMRMLMarkupsNode::SafeDownCast(d->selectionNodeActivePlaceNode());
this->setMRMLMarkupsNode(markupsNode);
}
比如先分析上面这一段代码:
2.3.1、Q_D 与 Q_Q
Q_D(qSlicerMarkupsModuleWidget);
Q_D 是public调用private类中函数需要使用的指针,只用它之后就可以通过d-> 调用响应的函数。 与之对应的是Q_Q Q_Q 是private类中调用public类中函数需要使用的指针,只用它之后就可以通过q-> 调用响应的函数。
2.3.2、创建新基准点 fiducial
vtkMRMLMarkupsNode* markupsNode = vtkMRMLMarkupsNode::SafeDownCast(d->selectionNodeActivePlaceNode());
2.3.3 、需要用到fiducial相关函数可以去这个文件中查找
Slicer\Slicer\Modules\Loadable\Markups\qSlicerMarkupsModuleWidget.cxx
|