Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkNavigationDataToIGTLMessageFilter.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include "igtlQuaternionTrackingDataMessage.h"
20 #include "igtlTrackingDataMessage.h"
21 #include "igtlTransformMessage.h"
22 #include "igtlPositionMessage.h"
23 
24 #include <mitkInteractionConst.h>
25 #include <itksys/SystemTools.hxx>
26 
28 {
30  this->SetNumberOfRequiredOutputs(1);
31  this->SetNthOutput(0, output.GetPointer());
32 
33  this->SetNumberOfRequiredInputs(1);
34 
35  // m_OperationMode = Mode3D;
37  // m_RingBufferSize = 50; //the default ring buffer size
38  // m_NumberForMean = 100;
39 }
40 
42 {
43 }
44 
46 {
47  switch (m_OperationMode)
48  {
49  case ModeSendQTDataMsg:
50  this->GenerateDataModeSendQTDataMsg();
51  break;
52  case ModeSendTDataMsg:
53  this->GenerateDataModeSendTDataMsg();
54  break;
55  case ModeSendQTransMsg:
56  this->GenerateDataModeSendQTransMsg();
57  break;
58  case ModeSendTransMsg:
59  this->GenerateDataModeSendTransMsg();
60  break;
61  default:
62  break;
63  }
64  igtl::MessageBase::Pointer curMessage = this->GetOutput()->GetMessage();
65  if (dynamic_cast<igtl::TrackingDataMessage*>(curMessage.GetPointer()) != nullptr)
66  {
67  igtl::TrackingDataMessage* tdMsg =
68  (igtl::TrackingDataMessage*)(curMessage.GetPointer());
69  }
70 
71 }
72 
74 {
75  // Process object is not const-correct so the const_cast is required here
76  this->ProcessObject::SetNthInput(0, const_cast<NavigationData*>(nd));
77  this->CreateOutputsForAllInputs();
78 }
79 
81 {
82  // Process object is not const-correct so the const_cast is required here
83  this->ProcessObject::SetNthInput(idx, const_cast<NavigationData*>(nd));
84  this->CreateOutputsForAllInputs();
85 }
86 
88 {
89  if (this->GetNumberOfInputs() < 1)
90  return NULL;
91  return static_cast<const NavigationData*>(this->ProcessObject::GetInput(0));
92 }
93 
95 {
96  if (this->GetNumberOfInputs() < 1)
97  return NULL;
98  return static_cast<const NavigationData*>(this->ProcessObject::GetInput(idx));
99 }
100 
102 {
103  switch (m_OperationMode)
104  {
105  case ModeSendQTDataMsg:
106  // create one message output for all navigation data inputs
107  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());
108  // set the type for this filter
109  this->SetType("QTDATA");
110  break;
111  case ModeSendTDataMsg:
112  // create one message output for all navigation data inputs
113  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());
114  // set the type for this filter
115  this->SetType("TDATA");
116  break;
117  case ModeSendQTransMsg:
118  // create one message output for all navigation data input together
119  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());
120  // set the type for this filter
121  this->SetType("POSITION");
122  break;
123  case ModeSendTransMsg:
124  // create one message output for all navigation data input together
125  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());
126  // set the type for this filter
127  this->SetType("TRANS");
128  break;
129  default:
130  break;
131  }
132 
133  for (unsigned int idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx)
134  {
135  if (this->GetOutput(idx) == NULL)
136  {
137  DataObjectPointer newOutput = this->MakeOutput(idx);
138  this->SetNthOutput(idx, newOutput);
139  }
140  this->Modified();
141  }
142 }
143 
145  igtl::Matrix4x4 igtlTransform)
146 {
147  const mitk::AffineTransform3D::MatrixType& matrix = trans->GetMatrix();
148  mitk::Vector3D position = trans->GetOffset();
149  //copy the data into a matrix type that igtl understands
150  for (unsigned int r = 0; r < 3; r++)
151  {
152  for (unsigned int c = 0; c < 3; c++)
153  {
154  igtlTransform[r][c] = matrix(r, c);
155  }
156  igtlTransform[r][3] = position[r];
157  }
158  for (unsigned int c = 0; c < 3; c++)
159  {
160  igtlTransform[3][c] = 0.0;
161  }
162  igtlTransform[3][3] = 1.0;
163 }
164 
166 {
167  // for each output message
168  for (unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
169  {
170  mitk::IGTLMessage* output = this->GetOutput(i);
171  assert(output);
172  const mitk::NavigationData* input = this->GetInput(i);
173  assert(input);
174  // do not add navigation data to message if input is invalid
175  if (input->IsDataValid() == false)
176  continue;
177 
178  //get the navigation data components
181 
182  //insert this information into the message
184  posMsg->SetPosition(pos[0], pos[1], pos[2]);
185  posMsg->SetQuaternion(ori[0], ori[1], ori[2], ori[3]);
187  timestamp->SetTime(input->GetTimeStamp().GetMTime() / 1000, input->GetTimeStamp().GetMTime() % 1000);
188  posMsg->SetTimeStamp(timestamp);
189  posMsg->SetDeviceName(input->GetName());
190  posMsg->Pack();
191 
192  //add the igtl message to the mitk::IGTLMessage
193  output->SetMessage(posMsg.GetPointer());
194  }
195 }
196 
198 {
199  // for each output message
200  for (unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
201  {
202  mitk::IGTLMessage* output = this->GetOutput(i);
203  assert(output);
204  const mitk::NavigationData* input = this->GetInput(i);
205  assert(input);
206  // do not add navigation data to message if input is invalid
207  if (input->IsDataValid() == false)
208  continue;
209 
210  //get the navigation data components
212  mitk::NavigationData::PositionType position = transform->GetOffset();
213 
214  //convert the transform into a igtl type
215  igtl::Matrix4x4 igtlTransform;
216  ConvertAffineTransformationIntoIGTLMatrix(transform, igtlTransform);
217 
218  //insert this information into the message
220  transMsg->SetMatrix(igtlTransform);
221  transMsg->SetPosition(position[0], position[1], position[2]);
223  timestamp->SetTime(input->GetTimeStamp().GetMTime() / 1000, input->GetTimeStamp().GetMTime() % 1000);
224  transMsg->SetTimeStamp(timestamp);
225  transMsg->SetDeviceName(input->GetName());
226  transMsg->Pack();
227 
228  //add the igtl message to the mitk::IGTLMessage
229  output->SetMessage(transMsg.GetPointer());
230  }
231 }
232 
234 {
235  mitk::IGTLMessage* output = this->GetOutput();
236  assert(output);
237 
238  //create a output igtl message
241 
244 
245  for (unsigned int index = 0; index < this->GetNumberOfIndexedInputs(); index++)
246  {
247  const mitk::NavigationData* nd = GetInput(index);
248  assert(nd);
249 
250  //get the navigation data components
251  pos = nd->GetPosition();
252  ori = nd->GetOrientation();
253 
254  //insert the information into the tracking element
257  tde->SetPosition(pos[0], pos[1], pos[2]);
258  tde->SetQuaternion(ori[0], ori[1], ori[2], ori[3]);
259  tde->SetName(nd->GetName());
260 
261  //insert this element into the tracking data message
262  qtdMsg->AddQuaternionTrackingDataElement(tde);
263 
264  //copy the time stamp
265  //todo find a better way to do that
267  timestamp->SetTime(nd->GetTimeStamp().GetMTime() / 1000, nd->GetTimeStamp().GetMTime() % 1000);
268  MITK_INFO << timestamp;
269  }
270  qtdMsg->Pack();
271 
272  //add the igtl message to the mitk::IGTLMessage
273  output->SetMessage(qtdMsg.GetPointer());
274 }
275 
277 {
278  bool isValidData = true;
279  mitk::IGTLMessage* output = this->GetOutput();
280  assert(output);
281 
282  //create a output igtl message
284 
286  Vector3D position;
287  igtl::Matrix4x4 igtlTransform;
288  vnl_matrix_fixed<ScalarType, 3, 3> rotationMatrix;
289  vnl_matrix_fixed<ScalarType, 3, 3> rotationMatrixTransposed;
290 
291  for (unsigned int index = 0; index < this->GetNumberOfIndexedInputs(); index++)
292  {
293  const mitk::NavigationData* nd = GetInput(index);
294  assert(nd);
295 
296  //create a new tracking element
298 
299  //get the navigation data components
300  transform = nd->GetAffineTransform3D();
301  position = transform->GetOffset();
302 
303  //check the rotation matrix
304  rotationMatrix = transform->GetMatrix().GetVnlMatrix();
305  rotationMatrixTransposed = rotationMatrix.transpose();
306  // a quadratic matrix is a rotation matrix exactly when determinant is 1
307  // and transposed is inverse
308  if (!Equal(1.0, vnl_det(rotationMatrix), 0.1)
309  || !((rotationMatrix*rotationMatrixTransposed).is_identity(0.1)))
310  {
311  //the rotation matrix is not valid! => invalidate the current element
312  isValidData = false;
313  }
314 
315  //convert the transform into a igtl type
316  ConvertAffineTransformationIntoIGTLMatrix(transform, igtlTransform);
317 
318  //fill the tracking element with life
319  tde->SetMatrix(igtlTransform);
320  tde->SetPosition(position[0], position[1], position[2]);
321  std::stringstream name;
322  name << nd->GetName();
323  if (name.rdbuf()->in_avail() == 0)
324  {
325  name << "TrackingTool" << index;
326  }
327  tde->SetName(name.str().c_str());
328 
329  //insert this element into the tracking data message
330  tdMsg->AddTrackingDataElement(tde);
331 
332  //copy the time stamp
333  //todo find a better way to do that
335  timestamp->SetTime(nd->GetTimeStamp().GetMTime() / 1000, nd->GetTimeStamp().GetMTime() % 1000);
336  tdMsg->SetTimeStamp(timestamp);
337 
338  }
339  tdMsg->Pack();
340  //add the igtl message to the mitk::IGTLMessage
341  output->SetMessage(tdMsg.GetPointer());
342  output->SetDataValid(isValidData);
343 }
344 
346 {
347  m_OperationMode = mode;
348  this->Modified();
349  this->CreateOutputsForAllInputs();
350 }
351 
353  mitk::NavigationDataSource* UpstreamFilter)
354 {
355  for (DataObjectPointerArraySizeType i = 0;
356  i < UpstreamFilter->GetNumberOfOutputs(); i++)
357  {
358  this->SetInput(i, UpstreamFilter->GetOutput(i));
359  }
360 }
itk::SmartPointer< Self > Pointer
NavigationData * GetOutput(void)
return the output (output with id 0) of the filter
#define MITK_INFO
Definition: mitkLogMacros.h:22
void SetMessage(igtl::MessageBase::Pointer msg)
Sets the OpenIGTLink message.
virtual const char * GetName() const
returns the name of the NavigationData object
Navigation Data.
unsigned int m_CurrentTimeStep
Indicates the current timestamp.
mitk::AffineTransform3D::Pointer GetAffineTransform3D() const
Calculate AffineTransform3D from the transformation held by this NavigationData. TODO: should throw a...
virtual OrientationType GetOrientation() const
returns the orientation of the NavigationData object
virtual void GenerateDataModeSendQTDataMsg()
Generates the output.
Constants for most interaction classes, due to the generic StateMachines.
mitk::Quaternion OrientationType
Type that holds the orientation part of the tracking data.
void ConvertAffineTransformationIntoIGTLMatrix(mitk::AffineTransform3D *trans, igtl::Matrix4x4 igtlTransform)
virtual void GenerateDataModeSendQTransMsg()
Generates the output for ModeSendQTransMsg.
virtual void GenerateData() override
filter execute method
virtual void ConnectTo(mitk::NavigationDataSource *UpstreamFilter)
Connects the input of this filter to the outputs of the given NavigationDataSource.
virtual void CreateOutputsForAllInputs()
create output objects according to OperationMode for all inputs
A wrapper for the OpenIGTLink message type.
virtual void SetInput(const mitk::NavigationData *NavigationData)
Sets one input NavigationData.
virtual void GenerateDataModeSendTransMsg()
Generates the output for ModeSendTransMsg.
itk::AffineGeometryFrame< ScalarType, 3 >::TransformType AffineTransform3D
virtual bool IsDataValid() const
returns true if the object contains valid data
virtual PositionType GetPosition() const
returns position of the NavigationData object
virtual void SetDataValid(bool _arg)
sets the dataValid flag of the IGTLMessage object indicating if the object contains valid data ...
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
const mitk::NavigationData * GetInput()
Returns the input of this filter.
virtual void GenerateDataModeSendTDataMsg()
Generates the output for ModeSendTDataMsg.
static Pointer New()
virtual void SetOperationMode(OperationMode mode)
Sets the mode of this filter.
OperationMode
There are four different operation modes.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.