Medical Imaging Interaction Toolkit  2018.4.99-07c45cb1
Medical Imaging Interaction Toolkit
mitkNeedleProjectionFilter.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 // MITK
15 #include <mitkPlaneGeometry.h>
16 
17 // VTK
18 #include <vtkPlane.h>
19 
21  : m_Projection(mitk::PointSet::New()),
22  m_OriginalPoints(mitk::PointSet::New()),
23  m_ShowToolAxis(false),
24  m_SelectedInput(0)
25 {
26  // Tool Coordinates: z-axis is chosen as default axis when no axis is specified
27 
28  MITK_DEBUG << "Constructor called";
29 
30  mitk::Point3D toolAxis;
31  mitk::FillVector3D(toolAxis, 0, 0, -1);
32  m_ToolAxis = toolAxis;
34 
35  MITK_DEBUG << "orginal point 0 set constructor" << m_OriginalPoints->GetPoint(0);
36  MITK_DEBUG << "orginal point 1 set constructor" << m_OriginalPoints->GetPoint(1);
37 }
38 
40 {
42 
43  mitk::Point3D projectionPoint;
44  projectionPoint.SetElement(0, toolAxis.GetElement(0) * 400);
45  projectionPoint.SetElement(1, toolAxis.GetElement(1) * 400);
46  projectionPoint.SetElement(2, toolAxis.GetElement(2) * 400);
47  m_OriginalPoints->InsertPoint(projectionPoint);
48 
49  mitk::Point3D toolOrigin;
50  toolOrigin.SetElement(0, 0);
51  toolOrigin.SetElement(1, 0);
52  toolOrigin.SetElement(2, 0);
53  m_OriginalPoints->InsertPoint(toolOrigin);
54 
55  if (showToolAxis)
56  {
57  mitk::Point3D axisPoint;
58  axisPoint.SetElement(0, toolAxis.GetElement(0) * -400);
59  axisPoint.SetElement(1, toolAxis.GetElement(1) * -400);
60  axisPoint.SetElement(2, toolAxis.GetElement(2) * -400);
61  m_OriginalPoints->InsertPoint(axisPoint);
62  }
63 
64 }
65 
67 {
68  m_ShowToolAxis = enabled;
70 }
71 
73 {
74  m_ToolAxis = point;
76 
77  MITK_DEBUG << "orginal point 1 set mutator" << m_OriginalPoints->GetPoint(1);
78  MITK_DEBUG << "orginal point 0 set mutator" << m_OriginalPoints->GetPoint(0);
79 }
80 
82 {
83 }
84 
86 {
87  if (i < 0) mitkThrow() << "Negative Input selected in NeedleProjectionFilter";
88  if (! (static_cast<unsigned int>(i) < this->GetInputs().size())) mitkThrow() << "Selected input index is larger than actual number of inputs in NeedleProjectionFilter";
89  m_SelectedInput = i;
90 }
91 
93 {
94  // copy the navigation data from the inputs to the outputs
96 
97  // If no reference has been set yet, warn and abort
98  if (m_SelectedInput == -1)
99  {
100  MITK_INFO << "No input has been selected in NeedleProjection Filter. Only forwarding NavigationData...";
101  return;
102  }
103 
104  // Cancel, if selected tool is currently not being tracked
105  if (! GetInput(m_SelectedInput)->IsDataValid()) return;
106 
107  // Outputs have been updated, now to calculate the Projection
108  // 1) Generate Pseudo-Geometry for Input
109  mitk::AffineTransform3D::Pointer refTrans = this->NavigationDataToTransform(this->GetInput(m_SelectedInput));
110  mitk::Geometry3D::Pointer refGeom = this->TransformToGeometry(refTrans);
111 
112  // 2) Transform Original Pointset
113  m_OriginalPoints->SetGeometry(refGeom);
114  // Update Projection (We do not clone, since we want to keep properties alive)
115  m_Projection->SetPoint(0, m_OriginalPoints->GetPoint(0));
116  m_Projection->SetPoint(1, m_OriginalPoints->GetPoint(1));
117  if (m_ShowToolAxis) { m_Projection->SetPoint(2, m_OriginalPoints->GetPoint(2)); }
118 
119  // 3a) If no target Plane has been set, then leave it at that
120  if (this->m_TargetPlane.IsNull())
121  return;
122 
123  // 3b) else, calculate intersection with plane
125  plane->SetIndexToWorldTransform(m_TargetPlane);
126  //plane->TransferItkToVtkTransform(); //included in SetIndexToWorldTransform
127 
128  double t;
129  double x[3];
130  // Points that define the needle vector
131  double p1[3] = {m_OriginalPoints->GetPoint(0)[0], m_OriginalPoints->GetPoint(0)[1], m_OriginalPoints->GetPoint(0)[2]};
132  double p2[3] = {m_OriginalPoints->GetPoint(1)[0], m_OriginalPoints->GetPoint(1)[1], m_OriginalPoints->GetPoint(1)[2]};
133  // Center of image plane and it's normal
134  double center[3] = {plane->GetCenter()[0], plane->GetCenter()[1], plane->GetCenter()[2]};
135  double normal[3] = {plane->GetNormal()[0], plane->GetNormal()[1], plane->GetNormal()[2]};
136 
137  vtkPlane::IntersectWithLine(p1, p2, normal, center, t, x);
138 
139  // change (cut) needle path only if the needle points to the image plane;
140  // otherwise the needle path direction would be changed pointing to the image plane
141  if ( t >= 0 )
142  {
143  // Convert vtk to itk
144  mitk::Point3D intersection;
145  intersection[0] = x[0];
146  intersection[1] = x[1];
147  intersection[2] = x[2];
148 
149  // Replace distant point with image intersection
150  m_Projection->SetPoint(0, intersection);
151 
152  }
153 }
154 
156 {
157  mitk::AffineTransform3D::Pointer affineTransform = mitk::AffineTransform3D::New();
158  affineTransform->SetIdentity();
159 
160  //calculate the transform from the quaternions
161  static itk::QuaternionRigidTransform<double>::Pointer quatTransform = itk::QuaternionRigidTransform<double>::New();
162 
164  // convert mitk::ScalarType quaternion to double quaternion because of itk bug
165  vnl_quaternion<double> doubleQuaternion(orientation.x(), orientation.y(), orientation.z(), orientation.r());
166  quatTransform->SetIdentity();
167  quatTransform->SetRotation(doubleQuaternion);
168  quatTransform->Modified();
169 
170  /* because of an itk bug, the transform can not be calculated with float data type.
171  To use it in the mitk geometry classes, it has to be transfered to mitk::ScalarType which is float */
172  static AffineTransform3D::MatrixType m;
173  mitk::TransferMatrix(quatTransform->GetMatrix(), m);
174  affineTransform->SetMatrix(m);
175 
176  /*set the offset by convert from itkPoint to itkVector and setting offset of transform*/
177  mitk::Vector3D pos;
178  pos.SetVnlVector(nd->GetPosition().GetVnlVector());
179  affineTransform->SetOffset(pos);
180 
181  affineTransform->Modified();
182  return affineTransform;
183 }
184 
187  mitk::ScalarType scale[] = {1.0, 1.0, 1.0};
188  g3d->SetSpacing(scale);
189  g3d->SetIndexToWorldTransform(transform);
190  //g3d->TransferItkToVtkTransform(); // update VTK Transform for rendering too //included in SetIndexToWorldTransform
191  g3d->Modified();
192  return g3d;
193 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
double ScalarType
Navigation Data.
static Pointer New()
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
DataCollection - Class to facilitate loading/accessing structured data.
static Pointer New()
mitk::Quaternion OrientationType
Type that holds the orientation part of the tracking data.
virtual PositionType GetPosition() const
returns position of the NavigationData object
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:106
mitk::Geometry3D::Pointer TransformToGeometry(mitk::AffineTransform3D::Pointer transform)
Creates an Geometry 3D Object from an AffineTransformation.
const NavigationData * GetInput(void) const
Get the input of this filter.
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:75
#define mitkThrow()
void GenerateData() override
Passes navigation data from all inputs to all outputs. If a subclass wants to implement its own versi...
void TransferMatrix(const itk::Matrix< U, NRows, NColumns > &in, itk::Matrix< V, NRows, NColumns > &out)
mitk::PointSet::Pointer m_OriginalPoints
mitk::AffineTransform3D::Pointer m_TargetPlane
static Pointer New()
void InitializeOriginalPoints(mitk::Point3D toolAxis, bool showToolAxis)
virtual OrientationType GetOrientation() const
returns the orientation of the NavigationData object
void SetToolAxisForFilter(mitk::Point3D point)
mitk::AffineTransform3D::Pointer NavigationDataToTransform(const mitk::NavigationData *nd)
Creates an Affine Transformation from a Navigation Data Object.