MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkUSNavigationTargetUpdateFilter.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
15#include <mitkBaseGeometry.h>
16#include "mitkDataNode.h"
17#include "mitkSurface.h"
18
19#include "vtkSmartPointer.h"
20#include "vtkUnsignedCharArray.h"
21#include "vtkPolyData.h"
22#include "vtkPointData.h"
23#include "vtkLookupTable.h"
24#include "mitkLookupTable.h"
25#include "mitkLookupTableProperty.h"
26#include "vtkFloatArray.h"
27#include "vtkTransformPolyDataFilter.h"
28#include "vtkLinearTransform.h"
29
31 : m_NumberOfTargets(0), m_OptimalAngle(0),
32 m_ScalarArrayIdentifier("USNavigation::NoIdentifierSet"),
33 m_UseMaximumScore(false)
34{
35}
36
40
41void mitk::USNavigationTargetUpdateFilter::SetTargetStructure(DataNode::Pointer targetStructure)
42{
43 m_TargetStructure = targetStructure;
44
45 // get vtk surface and the points
46 vtkSmartPointer<vtkPolyData> targetSurfaceVtk = this->GetVtkPolyDataOfTarget();
47 int numberOfPoints = targetSurfaceVtk->GetNumberOfPoints();
48
49 if ( numberOfPoints > 0 )
50 {
51 // create vtk scalar array for score values
53 colors->SetNumberOfComponents(1);
54 colors->SetName(m_ScalarArrayIdentifier.c_str());
55
56 // initialize with green color
57 float color = 1;
58 for (int n = 0; n < numberOfPoints ; ++n)
59 {
60 colors->InsertNextTuple1(color);
61 }
62
63 // add the scores array to the target surface
64 targetSurfaceVtk->GetPointData()->AddArray(colors);
65 targetSurfaceVtk->GetPointData()->Update();
66 }
67}
68
70{
71 if ( numberOfTargets < 1 || numberOfTargets > 4 )
72 {
73 MITK_WARN << "Number of targets can only be between 1 and 4.";
74 return false;
75 }
76
77 if ( numberOfTargets == 1 )
78 {
79 m_OptimalAngle = 0;
80 }
81 else if ( numberOfTargets < 5 )
82 {
83 // for every number of targets between 2 and 4 the optimal angle can be
84 // calculated using the arcus cosinus
85 m_OptimalAngle = acos(-1.0/(numberOfTargets-1));
86 }
87
88 m_NumberOfTargets = numberOfTargets;
89 return true;
90}
91
93{
94 m_OptimalAngle = optimalAngle;
95}
96
98{
99 return m_OptimalAngle;
100}
101
103{
104 m_ScalarArrayIdentifier = scalarArrayIdentifier;
105}
106
108{
109 m_UseMaximumScore = useMaximumScore;
110}
111
113{
114 // make sure that the node fit into the vector and insert it then
115 if ( m_ControlNodesVector.size() <= id ) { m_ControlNodesVector.resize(id+1); }
116 m_ControlNodesVector[id] = controlNode;
117
118 this->UpdateTargetScores();
119}
120
122{
123 if ( id >= m_ControlNodesVector.size() )
124 {
125 mitkThrow() << "Given id is larger than the vector size.";
126 }
127
128 m_ControlNodesVector.erase(m_ControlNodesVector.begin()+id);
129
130 this->UpdateTargetScores();
131}
132
134{
135 m_ControlNodesVector.clear();
136
137 if ( m_TargetStructure.IsNotNull() ) { this->UpdateTargetScores(); }
138}
139
141{
142 mitk::BaseGeometry::Pointer targetStructureGeometry = this->GetGeometryOfTarget();
143 mitk::Point3D targetStructureOrigin = targetStructureGeometry->GetOrigin();
144
145 // get vtk surface and the points
146 vtkSmartPointer<vtkPolyData> targetSurfaceVtk = this->GetVtkPolyDataOfTarget();
147 int numberOfPoints = targetSurfaceVtk->GetNumberOfPoints();
148
149 // transform vtk polydata according to mitk geometry
152 transformFilter->SetInputData(0, targetSurfaceVtk);
153 transformFilter->SetTransform(targetStructureGeometry->GetVtkTransform());
154 transformFilter->Update();
155 vtkSmartPointer<vtkPolyData> targetSurfaceVtkTransformed = transformFilter->GetOutput();
156
157 if ( numberOfPoints > 0 )
158 {
161 colors->SetNumberOfComponents(1);
162 colors->SetName(m_ScalarArrayIdentifier.c_str());
163
164 for (int n = 0; n < numberOfPoints ; ++n)
165 {
166 float score = m_UseMaximumScore ? 0.0 : 1.0;
167
168 if ( m_ControlNodesVector.empty() )
169 {
170 // first target can be placed everywhere
171 score = 1;
172 }
173 else if ( m_ControlNodesVector.size() == m_NumberOfTargets )
174 {
175 // if all targets are placed, there is no
176 // good position for another target
177 score = 0;
178 }
179 else
180 {
181 double coordinates[3];
182 mitk::Point3D coordinatesMitk;
183 targetSurfaceVtkTransformed->GetPoint(n, coordinates);
184 coordinatesMitk[0] = coordinates[0];
185 coordinatesMitk[1] = coordinates[1];
186 coordinatesMitk[2] = coordinates[2];
187
188 // vector pointing from the current surface coordinates to the origin
189 // of the target structure
190 itk::Vector<float, 3u> vector = targetStructureOrigin - coordinatesMitk;
191 vector.Normalize();
192
193 for (std::vector<mitk::DataNode::Pointer>::iterator it = m_ControlNodesVector.begin();
194 it != m_ControlNodesVector.end(); ++it)
195 {
196 if ( (*it)->GetData() == nullptr || (*it)->GetData()->GetGeometry() == nullptr )
197 {
198 mitkThrow() << "Control data node and geometry of the node must not be null.";
199 }
200
201 itk::Vector<float, 3u> controlPointToOriginVector = targetStructureOrigin - (*it)->GetData()->GetGeometry()->GetOrigin();
202 controlPointToOriginVector.Normalize();
203
204 float angle = acos( vector * controlPointToOriginVector );
205 float angleDifference = angle - m_OptimalAngle;
206 float tmpScore = 1 - (angleDifference >= 0 ? angleDifference : -angleDifference);
207
208 // update the score if the current score is larger (or lower) than
209 // this score
210 if ( (m_UseMaximumScore && tmpScore > score) || (!m_UseMaximumScore && tmpScore < score) )
211 {
212 score = tmpScore;
213 }
214 }
215 }
216 colors->InsertNextTuple1(score);
217 }
218
219 targetSurfaceVtk->GetPointData()->AddArray(colors);
220 targetSurfaceVtk->GetPointData()->Update();
221 }
222}
223
225{
226 if ( m_TargetStructure.IsNull() )
227 {
228 mitkThrow() << "Target structure must not be null.";
229 }
230
231 mitk::Surface::Pointer targetSurface = dynamic_cast<mitk::Surface*>(m_TargetStructure->GetData());
232 if ( targetSurface.IsNull() )
233 {
234 mitkThrow() << "A mitk::Surface has to be set to the data node.";
235 }
236
237 vtkSmartPointer<vtkPolyData> targetSurfaceVtk = targetSurface->GetVtkPolyData();
238 if( targetSurfaceVtk == nullptr )
239 {
240 mitkThrow() << "VtkPolyData of the mitk::Surface of the data node must not be null.";
241 }
242
243 return targetSurfaceVtk;
244}
245
247{
248 if ( m_TargetStructure.IsNull() )
249 {
250 mitkThrow() << "Target structure must be set before position of target is set.";
251 }
252
253 mitk::BaseData* targetStructureData = m_TargetStructure->GetData();
254 if ( ! targetStructureData )
255 {
256 mitkThrow() << "Data of target structure must not be null.";
257 }
258
259 mitk::BaseGeometry::Pointer targetStructureGeometry = targetStructureData->GetGeometry();
260 if ( targetStructureGeometry.IsNull() )
261 {
262 mitkThrow() << "Geometry of target structure must not be null.";
263 }
264
265 return targetStructureGeometry;
266}
bool SetNumberOfTargets(unsigned int numberOfTargets)
Setter for the number of targets to be placed on the target surface. The optimal angle for placing th...
void Reset()
Removes all target positions from the filter and resets the scores.
void RemovePositionOfTarget(unsigned int id)
Removes the position of the target with the current id from the filter.
void SetOptimalAngle(double optimalAngle)
Setter for the optimal angle between to targets on the target surface. This value overwrites the valu...
void SetUseMaximumScore(bool useMaximumScore)
Set whether the maximum score or the minimum score between the targets should be used....
void SetControlNode(unsigned int id, itk::SmartPointer< DataNode > controlNode)
Sets the origin of the given node for the filter. This origin is the position of an already placed ta...
itk::SmartPointer< mitk::BaseGeometry > GetGeometryOfTarget()
void SetScalarArrayIdentifier(std::string scalarArrayIdentifier)
Sets the identifier for the vtkFloatArray of scores. This array is stored as scalars of the vtkPolyDa...
void SetTargetStructure(itk::SmartPointer< DataNode > targetStructure)
Set the target surface for which the scores should be calculated.