MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
QmitkUSNavigationStepPunctuationIntervention.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14#include "ui_QmitkUSNavigationStepPunctuationIntervention.h"
15
17
20
21#include "usModuleRegistry.h"
22
23#include <mitkTrackingTypes.h>
24
28 m_ZoneNodes(nullptr),
29 m_NeedleProjectionFilter(mitk::NeedleProjectionFilter::New()),
30 m_NeedleNavigationTool(mitk::NavigationTool::New()),
31 m_OldColors(),
32 m_SphereSource(vtkSmartPointer<vtkSphereSource>::New()),
33 m_OBBTree(vtkSmartPointer<vtkOBBTree>::New()),
34 m_IntersectPoints(vtkSmartPointer<vtkPoints>::New())
35{
36 m_Ui->setupUi(this);
37 connect(m_Ui->m_AddNewAblationZone, SIGNAL(clicked()), this, SLOT(OnAddAblationZoneClicked()));
38 connect(m_Ui->m_ShowToolAxisN, SIGNAL(stateChanged(int)), this, SLOT(OnShowToolAxisEnabled(int)));
39 connect(m_Ui->m_EnableAblationMarking, SIGNAL(clicked()), this, SLOT(OnEnableAblationZoneMarkingClicked()));
40 connect(m_Ui->m_AblationZoneSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnAblationZoneSizeSliderChanged(int)));
41 m_Ui->m_AblationZonesBox->setVisible(false);
42}
43
44void QmitkUSNavigationStepPunctuationIntervention::SetNeedleMetaData(mitk::NavigationTool::Pointer needleNavigationTool)
45
46{
47 this->m_NeedleNavigationTool = needleNavigationTool;
48}
49
51{
52 if(m_Ui->m_EnableAblationMarking->isChecked())
53 m_Ui->m_AblationZonesBox->setVisible(true);
54 else
55 m_Ui->m_AblationZonesBox->setVisible(false);
56}
57
59{
60int id = m_Ui->m_AblationZonesList->currentRow();
61if (id!=-1) {emit AblationZoneChanged(id,size);}
62}//
63
65{
66 QListWidgetItem* newItem = new QListWidgetItem("Ablation Zone (initial size: " + QString::number(m_Ui->m_AblationZoneSizeSlider->value()) + " mm)", m_Ui->m_AblationZonesList);
67 newItem->setSelected(true);
68 emit AddAblationZoneClicked(m_Ui->m_AblationZoneSizeSlider->value());
69}
70
72{
73 mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(false);
74 if ( dataStorage.IsNotNull() )
75 {
76 // remove needle path from data storage if it is there
77 mitk::DataNode::Pointer node = this->GetNamedDerivedNode
79 if ( node.IsNotNull() ) { dataStorage->Remove(node); }
80 }
81
82 delete m_Ui;
83}
84
86{
87 // create node for Needle Projection
88 mitk::DataNode::Pointer node = this->GetNamedDerivedNodeAndCreate
90 node->SetData(m_NeedleProjectionFilter->GetProjection());
91 node->SetBoolProperty("show contour", true);
92 //m_NeedleProjectionFilter->SetToolAxisForFilter(m_NeedleNavigationTool->GetToolAxis());
93 return true;
94}
95
100
102{
103 mitk::DataNode::Pointer finishPunctionResult = mitk::DataNode::New();
104 finishPunctionResult->SetName("PunctionResult");
105 mitk::Point3D needlePos = m_NeedleProjectionFilter->GetOutput(0)->GetPosition();
106 mitk::Quaternion needleRot = m_NeedleProjectionFilter->GetOutput(0)->GetOrientation();
107 finishPunctionResult->SetProperty("USNavigation::TipPositionEnd", mitk::Point3dProperty::New(needlePos));
108 MITK_INFO("USNavigationLogging") << "Instrument tip at end: " <<needlePos<< " / " << needleRot;
109 emit SignalIntermediateResult(finishPunctionResult);
110 return true;
111}
112
114{
115 this->ClearZones();
116
117 mitk::DataStorage::Pointer dataStorage = this->GetDataStorage();
118
119
120 // add progress bars for risk zone nodes
121 m_ZoneNodes = dataStorage->GetDerivations(dataStorage->GetNamedNode(QmitkUSNavigationMarkerPlacement::DATANAME_ZONES));
122
123 // add zones to the widgets for risk structures
124 for (mitk::DataStorage::SetOfObjects::ConstIterator it = m_ZoneNodes->Begin();
125 it != m_ZoneNodes->End(); ++it)
126 {
127 m_Ui->riskStructuresRangeWidget->AddZone(it->Value());
128 float rgb[3];
129 it->Value()->GetColor(rgb);
130 mitk::Color color;
131 color.SetRed(rgb[0]);
132 color.SetGreen(rgb[1]);
133 color.SetBlue(rgb[2]);
134 m_OldColors[it->Value()] = color;
135 }
136
137 m_NeedleProjectionFilter->SelectInput(0);
138
139 return true;
140}
141
143{
144 if (enabled == 0) { m_NeedleProjectionFilter->ShowToolAxis(false); }
145 else { m_NeedleProjectionFilter->ShowToolAxis(true); }
146}
147
149{
150 if (this->GetCombinedModality(false).IsNull()) return;
151 // get navigation data source and make sure that it is not null
152 mitk::NavigationDataSource::Pointer navigationDataSource =
153 this->GetCombinedModality()->GetNavigationDataSource();
154
155 if ( navigationDataSource.IsNull() )
156 {
157
158 MITK_ERROR("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepPunctuationIntervention")
159 << "Navigation Data Source of Combined Modality must not be null.";
160 mitkThrow() << "Navigation Data Source of Combined Modality must not be null.";
161 }
162 // update body marker
163 this->UpdateBodyMarkerStatus(navigationDataSource->GetOutput(1));
164 // update critical structures
165 this->UpdateCriticalStructures(navigationDataSource->GetOutput(0),m_NeedleProjectionFilter->GetProjection());
166
167 m_NeedleProjectionFilter->Update();
168
169 //Update Distance to US image
170 mitk::Point3D point1 = m_NeedleProjectionFilter->GetProjection()->GetPoint(0);
171 mitk::Point3D point2 = m_NeedleProjectionFilter->GetProjection()->GetPoint(1);
172 double distance = point1.EuclideanDistanceTo(point2);
173 m_Ui->m_DistanceToUSPlane->setText(QString::number(distance) + " mm");
174}
175
177{
178 if ( settingsNode.IsNull() ) { return; }
179}
180
182{
183 return "Computer-assisted Intervention";
184}
185
190
195
197{
198 mitk::AbstractUltrasoundTrackerDevice::Pointer combinedModality = this->GetCombinedModality(false);
199 if ( combinedModality.IsNotNull() )
200 {
201 m_NeedleProjectionFilter->ConnectTo(combinedModality->GetNavigationDataSource());
202
203 // set calibration of the combined modality to the needle projection filter
204 mitk::AffineTransform3D::Pointer usPlaneTransform = combinedModality->GetUSPlaneTransform();
205 if (usPlaneTransform.IsNotNull())
206 {
207 m_NeedleProjectionFilter->SetTargetPlane(usPlaneTransform);
208 }
209 }
210 else
211 {
212 MITK_WARN << "CombinedModality is null!";
213 }
214}
215
217{
218 m_Ui->riskStructuresRangeWidget->ClearZones();
219}
220
222{
223 if ( bodyMarker.IsNull() )
224 {
225 MITK_ERROR("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepPunctuationIntervention")
226 << "Current Navigation Data for body marker of Combined Modality must not be null.";
227 mitkThrow() << "Current Navigation Data for body marker of Combined Modality must not be null.";
228 }
229
230 bool valid = bodyMarker->IsDataValid();
231
232 // update body marker status label
233 if (valid)
234 {
235 m_Ui->bodyMarkerTrackingStatusLabel->setStyleSheet(
236 "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey");
237 m_Ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume.");
238 }
239 else
240 {
241 m_Ui->bodyMarkerTrackingStatusLabel->setStyleSheet(
242 "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey");
243 m_Ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume.");
244 }
245
246 m_Ui->riskStructuresRangeGroupBox->setEnabled(valid);
247}
248
249void QmitkUSNavigationStepPunctuationIntervention::UpdateCriticalStructures(mitk::NavigationData::Pointer needle, mitk::PointSet::Pointer path)
250{
251 // update the distances for the risk structures widget
252 m_Ui->riskStructuresRangeWidget->UpdateDistancesToNeedlePosition(needle);
253
254 //iterate through all zones
255 for (mitk::DataStorage::SetOfObjects::ConstIterator it = m_ZoneNodes->Begin();
256 it != m_ZoneNodes->End(); ++it)
257 {
258 mitk::DataNode::Pointer currentNode = it->Value();
259 //get center point and radius
260 float radius = -1;
261 mitk::Point3D center;
262 currentNode->GetFloatProperty("zone.size", radius);
263 center = mitk::Point3D(currentNode->GetData()->GetGeometry()->GetIndexToWorldTransform()->GetTranslation());
264 mitk::Point3D point0 = path->GetPoint(0);
265 mitk::Point3D point1 = path->GetPoint(1);
266 if (CheckSphereLineIntersection(center,radius,point0,point1))
267 {currentNode->SetColor(mitk::IGTColor_WARNING);}
268 else
269 {currentNode->SetColor(m_OldColors[currentNode]);}
270 }
271}
272
273bool QmitkUSNavigationStepPunctuationIntervention::CheckSphereLineIntersection(mitk::Point3D& sphereOrigin, float& sphereRadius, mitk::Point3D& lineStart, mitk::Point3D& lineEnd)
274{
275 double center[3] = {sphereOrigin[0],sphereOrigin[1],sphereOrigin[2]};
276 m_SphereSource->SetCenter(center);
277 m_SphereSource->SetRadius(sphereRadius);
278 m_SphereSource->Update();
279
280 m_OBBTree->SetDataSet(m_SphereSource->GetOutput());
281 m_OBBTree->BuildLocator();
282
283 double lineP0[3] = {lineStart[0], lineStart[1], lineStart[2]};
284 double lineP1[3] = {lineEnd[0], lineEnd[1], lineEnd[2]};
285
286 m_OBBTree->IntersectWithLine(lineP0, lineP1, m_IntersectPoints, nullptr);
287
288 if (m_IntersectPoints->GetNumberOfPoints() > 0) {return true;}
289 else {return false;}
290}
Abstract base class for navigation step widgets.
itk::SmartPointer< mitk::DataStorage > GetDataStorage(bool throwNull=true)
Returns the data storage set for the navigation step.
itk::SmartPointer< mitk::DataNode > GetNamedDerivedNodeAndCreate(const char *name, const char *sourceName)
Returns node with the given name and the given source node (parent) from the data storage....
itk::SmartPointer< mitk::AbstractUltrasoundTrackerDevice > GetCombinedModality(bool throwNull=true)
Returns the combined modality set for the navigation step.
std::vector< itk::SmartPointer< mitk::NavigationDataToNavigationDataFilter > > FilterVector
void SignalIntermediateResult(const itk::SmartPointer< mitk::DataNode >)
Signals that an intermediate result was produced. The properties of the given data node must contain ...
itk::SmartPointer< mitk::DataNode > GetNamedDerivedNode(const char *name, const char *sourceName)
Returns node with the given name and the given source node (parent) from the data storage.
Navigations step for the actual punctuation intervention. The needle path is projected onto the image...
bool CheckSphereLineIntersection(mitk::Point3D &sphereOrigin, float &sphereRadius, mitk::Point3D &lineStart, mitk::Point3D &lineEnd)
bool OnActivateStep() override
Called when the navigation step gets activated. This method has to be implemented by a concrete subcl...
bool GetIsRestartable() override
Indicates if it makes sense to be able to restart the step. This method must be implemented by concre...
void OnUpdate() override
Called periodically while a navigation step is active. This method has to be implemented by a concret...
void UpdateBodyMarkerStatus(mitk::NavigationData::Pointer bodyMarker)
bool OnRestartStep() override
Called when restarting a navigation step. This method may be implemented by a concrete subclass to ha...
QString GetTitle() override
Getter for the title of the navigation step. This title should be human readable and can be used to d...
bool OnStartStep() override
Called when the navigation step gets started. This method has to be implemented by a concrete subclas...
void UpdateCriticalStructures(mitk::NavigationData::Pointer needle, mitk::PointSet::Pointer path)
FilterVector GetFilter() override
Getter for navigation data filters of the navigation step. This method may be implemented by a concre...
bool OnFinishStep() override
Called when all necessary actions for the step where done. This method has to be implemented by a con...
void OnSettingsChanged(const itk::SmartPointer< mitk::DataNode >) override
Called every time the settings for the navigation process where changed. This method may be implement...
void OnSetCombinedModality() override
Called every time SetCombinedModality() was called. This method may be implemented by a concrete subc...
void SetNeedleMetaData(mitk::NavigationTool::Pointer needleNavigationTool)
IGT Exceptions.