Medical Imaging Interaction Toolkit  2018.4.99-07c45cb1
Medical Imaging Interaction Toolkit
mitkNavigationTool.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkNavigationTool.h"
14 #include "mitkIGTException.h"
15 #include "mitkNavigationData.h"
16 #include "Poco/File.h"
18 
19 #include <vtkSphereSource.h>
20 #include "vtkConeSource.h"
21 #include "vtkLineSource.h"
22 #include "vtkCylinderSource.h"
23 #include "vtkTransformPolyDataFilter.h"
24 #include <vtkAppendPolyData.h>
25 #include "mitkTextAnnotation3D.h"
27 #include "mitkBaseRenderer.h"
28 
29 mitk::NavigationTool::NavigationTool() : m_Identifier("None"),
30 m_Type(mitk::NavigationTool::Unknown),
31 m_CalibrationFile("none"),
32 m_SerialNumber(""),
33 m_TrackingDeviceType(mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()),
34 m_ToolLandmarks(mitk::PointSet::New()),
35 m_ToolControlPoints(mitk::PointSet::New()),
36 m_ToolAxisOrientation(mitk::Quaternion(0, 0, 0, 1))
37 {
38  m_ToolTipPosition[0] = 0;
39  m_ToolTipPosition[1] = 0;
40  m_ToolTipPosition[2] = 0;
41 
43 }
44 
45 itk::LightObject::Pointer mitk::NavigationTool::InternalClone() const
46 {
47  Self::Pointer tool = new Self(*this);
48  tool->UnRegister();
49  return tool.GetPointer();
50 }
51 
53  : Superclass()
54 {
55  this->m_Identifier = other.m_Identifier;
56  this->m_Type = other.m_Type;
57  if (other.m_DataNode.IsNotNull())
58  {
59  this->m_DataNode = other.m_DataNode->Clone();
60  this->m_DataNode->SetName(other.m_DataNode->GetName());
61  if (other.m_DataNode->GetData())
62  {
63  this->m_DataNode->SetData(dynamic_cast<mitk::BaseData*>(other.m_DataNode->GetData()->Clone().GetPointer()));
64  }
65  }
66 
67  if (other.m_SpatialObject.IsNotNull())
68  this->m_SpatialObject = other.m_SpatialObject->Clone();
70  this->m_SerialNumber = other.m_SerialNumber;
72  if (other.m_ToolLandmarks.IsNotNull())
73  this->m_ToolLandmarks = other.m_ToolLandmarks->Clone();
74  if (other.m_ToolControlPoints.IsNotNull())
75  this->m_ToolControlPoints = other.m_ToolControlPoints->Clone();
78 }
79 
81 {
82 }
83 
85 {
86  // The tool axis in the sensor coordinate system is defined as the negative z-axis
87  mitk::Vector3D toolAxisSensorCoordinateSystem;
88  mitk::FillVector3D(toolAxisSensorCoordinateSystem, 0.0, 0.0, -1.0);
89  // Apply inverse tool axis transform to calculate tool axis
90  vnl_vector_fixed<mitk::ScalarType,3> toolAxisVector = m_ToolAxisOrientation.inverse().rotate(toolAxisSensorCoordinateSystem.GetVnlVector());
91  // Transfer to mitk::Point3D
92  mitk::Point3D toolAxis;
93  toolAxis[0] = toolAxisVector[0];
94  toolAxis[1] = toolAxisVector[1];
95  toolAxis[2] = toolAxisVector[2];
96  return toolAxis;
97 }
98 
100 {
101  // The tool axis in the sensor coordinate system is defined as the negative z-axis
102  mitk::Vector3D toolAxisSensorCoordinateSystem;
103  mitk::FillVector3D(toolAxisSensorCoordinateSystem, 0.0, 0.0, -1.0);
104  // Normalize the tool axis as obtained by a tool axis calibration
105  mitk::Vector3D toolAxisFromCalibration;
106  mitk::FillVector3D(toolAxisFromCalibration, toolAxis[0], toolAxis[1], toolAxis[2]);
107  toolAxisFromCalibration.Normalize();
108  // if tool axis to be set is different to the default tool axis (0,0,-1) calculate the tool axis orientation, otherwise set it to identity
109  if (toolAxisSensorCoordinateSystem == toolAxisFromCalibration)
110  {
112  }
113  else
114  {
115  // Determine rotation angle
116  mitk::ScalarType rotationAngle = acos(toolAxisSensorCoordinateSystem*toolAxisFromCalibration);
117  // Determine rotation axis
118  mitk::Vector3D rotationAxis = itk::CrossProduct(toolAxisSensorCoordinateSystem, toolAxisFromCalibration);
119  // Calculate transform
120  itk::AffineTransform<mitk::ScalarType>::Pointer sensorToToolAxisOrientation = itk::AffineTransform<mitk::ScalarType>::New();
121  sensorToToolAxisOrientation->Rotate3D(rotationAxis, rotationAngle);
122  // transfer to quaternion notation. Note that the vnl_quaternion expects the matrix in row major format, hence the transpose
123  mitk::Quaternion toolAxisTransform(sensorToToolAxisOrientation->GetMatrix().GetVnlMatrix().transpose());
124  // Update the tool axis orientation
125  m_ToolAxisOrientation = toolAxisTransform;
126  }
127 }
128 
129 mitk::AffineTransform3D::Pointer mitk::NavigationTool::GetToolTipTransform()
130 {
131  mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
132  returnValue->SetPosition(this->m_ToolTipPosition);
133  returnValue->SetOrientation(this->m_ToolAxisOrientation);
134  return returnValue->GetAffineTransform3D();
135 }
136 
137 void mitk::NavigationTool::Graft(const DataObject *data)
138 {
139  // Attempt to cast data to an NavigationData
140  const Self* nd;
141  try
142  {
143  nd = dynamic_cast<const Self *>(data);
144  }
145  catch (...)
146  {
147  mitkThrowException(mitk::IGTException) << "mitk::NavigationData::Graft cannot cast "
148  << typeid(data).name() << " to "
149  << typeid(const Self *).name();
150  }
151  if (!nd)
152  {
153  // pointer could not be cast back down
154  mitkThrowException(mitk::IGTException) << "mitk::NavigationData::Graft cannot cast "
155  << typeid(data).name() << " to "
156  << typeid(const Self *).name();
157  }
158  // Now copy anything that is needed
159  m_Identifier = nd->GetIdentifier();
160  m_Type = nd->GetType();
161  m_DataNode->SetName(nd->GetDataNode()->GetName());
162  m_DataNode->SetData(nd->GetDataNode()->GetData());
163  m_SpatialObject = nd->GetSpatialObject();
164  m_CalibrationFile = nd->GetCalibrationFile();
165  m_SerialNumber = nd->GetSerialNumber();
166  m_TrackingDeviceType = nd->GetTrackingDeviceType();
167  m_ToolLandmarks = nd->GetToolLandmarks();
168  m_ToolControlPoints = nd->GetToolControlPoints();
169  m_ToolTipPosition = nd->GetToolTipPosition();
170  m_ToolAxisOrientation = nd->GetToolAxisOrientation();
171 }
172 
174 {
175  if ((m_ToolTipPosition[0] == 0) &&
176  (m_ToolTipPosition[1] == 0) &&
177  (m_ToolTipPosition[2] == 0) &&
178  (m_ToolAxisOrientation.x() == 0) &&
179  (m_ToolAxisOrientation.y() == 0) &&
180  (m_ToolAxisOrientation.z() == 0) &&
181  (m_ToolAxisOrientation.r() == 1))
182  return false;
183  else return true;
184 }
185 
186 void mitk::NavigationTool::SetCalibrationFile(const std::string filename)
187 {
188  //check if file does exist:
189  if (filename == "")
190  {
191  m_CalibrationFile = "none";
192  }
193  else
194  {
195  Poco::File myFile(filename);
196  if (myFile.exists())
197  m_CalibrationFile = filename;
198  else
199  m_CalibrationFile = "none";
200  }
201 }
202 
204 {
205  if (this->m_DataNode.IsNull()) { return ""; }
206  else { return m_DataNode->GetName(); }
207 }
208 
210 {
211  if (this->m_DataNode.IsNull()) { return nullptr; }
212  else if (this->m_DataNode->GetData() == nullptr) { return nullptr; }
213  else { return dynamic_cast<mitk::Surface*>(m_DataNode->GetData()); }
214 }
215 
217 {
218  if (m_DataNode.IsNull())
220 
222 
223  double axisLength = 5.;
224 
225  vtkSmartPointer<vtkSphereSource> vtkSphere = vtkSmartPointer<vtkSphereSource>::New();
226  vtkSmartPointer<vtkConeSource> vtkCone = vtkSmartPointer<vtkConeSource>::New();
227  vtkSmartPointer<vtkCylinderSource> vtkCylinder = vtkSmartPointer<vtkCylinderSource>::New();
228  vtkSmartPointer<vtkPolyData> axis = vtkSmartPointer<vtkPolyData>::New();
229  vtkSmartPointer<vtkLineSource> vtkLine = vtkSmartPointer<vtkLineSource>::New();
230  vtkSmartPointer<vtkLineSource> vtkLine2 = vtkSmartPointer<vtkLineSource>::New();
231  vtkSmartPointer<vtkLineSource> vtkLine3 = vtkSmartPointer<vtkLineSource>::New();
232 
233  vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
234  vtkSmartPointer<vtkPolyData> surface = vtkSmartPointer<vtkPolyData>::New();
235 
236  //Y-Axis (start with y, cause cylinder is oriented in y by vtk default...)
237  vtkCone->SetDirection(0, 1, 0);
238  vtkCone->SetHeight(1.0);
239  vtkCone->SetRadius(0.4f);
240  vtkCone->SetResolution(16);
241  vtkCone->SetCenter(0.0, axisLength, 0.0);
242  vtkCone->Update();
243 
244  vtkCylinder->SetRadius(0.05);
245  vtkCylinder->SetHeight(axisLength);
246  vtkCylinder->SetCenter(0.0, 0.5*axisLength, 0.0);
247  vtkCylinder->Update();
248 
249  appendPolyData->AddInputData(vtkCone->GetOutput());
250  appendPolyData->AddInputData(vtkCylinder->GetOutput());
251  appendPolyData->Update();
252  axis->DeepCopy(appendPolyData->GetOutput());
253 
254  //y symbol
255  vtkLine->SetPoint1(-0.5, axisLength + 2., 0.0);
256  vtkLine->SetPoint2(0.0, axisLength + 1.5, 0.0);
257  vtkLine->Update();
258 
259  vtkLine2->SetPoint1(0.5, axisLength + 2., 0.0);
260  vtkLine2->SetPoint2(-0.5, axisLength + 1., 0.0);
261  vtkLine2->Update();
262 
263  appendPolyData->AddInputData(vtkLine->GetOutput());
264  appendPolyData->AddInputData(vtkLine2->GetOutput());
265  appendPolyData->AddInputData(axis);
266  appendPolyData->Update();
267  surface->DeepCopy(appendPolyData->GetOutput());
268 
269  //X-axis
270  vtkSmartPointer<vtkTransform> XTransform = vtkSmartPointer<vtkTransform>::New();
271  XTransform->RotateZ(-90);
272  vtkSmartPointer<vtkTransformPolyDataFilter> TrafoFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
273  TrafoFilter->SetTransform(XTransform);
274  TrafoFilter->SetInputData(axis);
275  TrafoFilter->Update();
276 
277  //x symbol
278  vtkLine->SetPoint1(axisLength + 2., -0.5, 0.0);
279  vtkLine->SetPoint2(axisLength + 1., 0.5, 0.0);
280  vtkLine->Update();
281 
282  vtkLine2->SetPoint1(axisLength + 2., 0.5, 0.0);
283  vtkLine2->SetPoint2(axisLength + 1., -0.5, 0.0);
284  vtkLine2->Update();
285 
286  appendPolyData->AddInputData(vtkLine->GetOutput());
287  appendPolyData->AddInputData(vtkLine2->GetOutput());
288  appendPolyData->AddInputData(TrafoFilter->GetOutput());
289  appendPolyData->AddInputData(surface);
290  appendPolyData->Update();
291  surface->DeepCopy(appendPolyData->GetOutput());
292 
293  //Z-axis
294  vtkSmartPointer<vtkTransform> ZTransform = vtkSmartPointer<vtkTransform>::New();
295  ZTransform->RotateX(90);
296  TrafoFilter->SetTransform(ZTransform);
297  TrafoFilter->SetInputData(axis);
298  TrafoFilter->Update();
299 
300  //z symbol
301  vtkLine->SetPoint1(-0.5, 0.0, axisLength + 2.);
302  vtkLine->SetPoint2(0.5, 0.0, axisLength + 2.);
303  vtkLine->Update();
304 
305  vtkLine2->SetPoint1(-0.5, 0.0, axisLength + 2.);
306  vtkLine2->SetPoint2(0.5, 0.0, axisLength + 1.);
307  vtkLine2->Update();
308 
309  vtkLine3->SetPoint1(0.5, 0.0, axisLength + 1.);
310  vtkLine3->SetPoint2(-0.5, 0.0, axisLength + 1.);
311  vtkLine3->Update();
312 
313  appendPolyData->AddInputData(vtkLine->GetOutput());
314  appendPolyData->AddInputData(vtkLine2->GetOutput());
315  appendPolyData->AddInputData(vtkLine3->GetOutput());
316  appendPolyData->AddInputData(TrafoFilter->GetOutput());
317  appendPolyData->AddInputData(surface);
318  appendPolyData->Update();
319  surface->DeepCopy(appendPolyData->GetOutput());
320 
321  //Center
322  vtkSphere->SetRadius(0.5f);
323  vtkSphere->SetCenter(0.0, 0.0, 0.0);
324  vtkSphere->Update();
325 
326  appendPolyData->AddInputData(vtkSphere->GetOutput());
327  appendPolyData->AddInputData(surface);
328  appendPolyData->Update();
329  surface->DeepCopy(appendPolyData->GetOutput());
330 
331  //Scale
332  vtkSmartPointer<vtkTransform> ScaleTransform = vtkSmartPointer<vtkTransform>::New();
333  ScaleTransform->Scale(20., 20., 20.);
334 
335  TrafoFilter->SetTransform(ScaleTransform);
336  TrafoFilter->SetInputData(surface);
337  TrafoFilter->Update();
338 
339  mySphere->SetVtkPolyData(TrafoFilter->GetOutput());
340 
341  this->GetDataNode()->SetData(mySphere);
342 }
343 
345 {
346  std::stringstream _info;
347  _info << " Identifier: " << this->m_Identifier << "\n"
348  << " NavigationToolType: " << m_Type << "\n"
349  << " Calibration file: " << m_CalibrationFile << "\n"
350  << " Serial number: " << m_SerialNumber << "\n"
351  << " TrackingDeviceType: " << m_TrackingDeviceType << "\n"
352  << " ToolTip Position: " << m_ToolTipPosition << "\n"
353  << " Tool Axis Orientation: " << m_ToolAxisOrientation << "\n"
354  << " Tool Axis: " << m_ToolAxisOrientation.inverse().rotate(vnl_vector_fixed<mitk::ScalarType,3>(0.0,0.0,-1.0))
355  ;
356 
357  return _info.str();
358 }
mitk::Quaternion m_ToolAxisOrientation
Holds the transformation of the main tool axis to the negative z-axis (0,0,-1)
static Pointer New()
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
std::string m_SerialNumber
A unique serial number of the tool which is needed to identify the tool correctly. This is very important in case of the NDI Aurora System.
mitk::DataNode::Pointer m_DataNode
This DataNode holds a toolname and a tool surface.
mitk::Point3D m_ToolTipPosition
Holds the position of the tool tip.
double ScalarType
void Graft(const DataObject *data) override
Graft the data and information from one NavigationTool to another.
An object of this class represents an exception of the MITK-IGT module.
virtual mitk::DataNode::Pointer GetDataNode() const
DataCollection - Class to facilitate loading/accessing structured data.
An object of this class represents a navigation tool in the view of the software. A few informations ...
mitk::TrackingDeviceType m_TrackingDeviceType
This member holds the tracking device type of the tool.
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:106
void SetCalibrationFile(const std::string filename)
NavigationToolType m_Type
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:75
static Pointer New()
itk::SpatialObject< 3 >::Pointer m_SpatialObject
This member variable holds a mathamatical description of the tool.
mitk::Point3D GetToolAxis()
vnl_quaternion< ScalarType > Quaternion
std::string m_CalibrationFile
The path to the calibration file of the tool.
mitk::AffineTransform3D::Pointer GetToolTipTransform()
#define mitkThrowException(classname)
Type information for unspecified or invalid tracking devices. This is often used as default or for te...
mitk::PointSet::Pointer m_ToolControlPoints
Holds control points in the tool coordinate system, e.g. 2 landmarks for a 5DoF tool and 3 landmarks ...
mitk::Surface::Pointer GetToolSurface()
void SetToolAxis(mitk::Point3D toolAxis)
itk::LightObject::Pointer InternalClone() const override
static Pointer New()
mitk::PointSet::Pointer m_ToolLandmarks
Holds landmarks for tool registration.
std::string GetStringWithAllToolInformation() const