PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusIgtlMessageFactory.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 
9 #include "igsioTrackedFrame.h"
10 #include "igsioVideoFrame.h"
11 #include "vtkImageData.h"
12 #include "vtkNew.h"
13 #include "vtkMatrix4x4.h"
14 #include "vtkObjectFactory.h"
17 #include "vtkIGSIOTrackedFrameList.h"
18 #include "vtkIGSIOTransformRepository.h"
19 #include "vtksys/SystemTools.hxx"
20 #include <typeinfo>
21 
22 //----------------------------------------------------------------------------
23 // IGT message types
24 #include "igtlCommandMessage.h"
25 #include "igtlImageMessage.h"
28 #include "igtlPlusUsMessage.h"
29 #include "igtlPositionMessage.h"
30 #include "igtlStatusMessage.h"
31 #include "igtlTrackingDataMessage.h"
32 #include "igtlTransformMessage.h"
33 
34 #if defined(OpenIGTLink_ENABLE_VIDEOSTREAMING)
35  #include "igtlVideoMessage.h"
36  #include "igtl_video.h"
37  #include "igtlI420Encoder.h"
38  #if defined(OpenIGTLink_USE_VP9)
39  #include "igtlVP9Encoder.h"
40  #endif
41  #if defined(OpenIGTLink_USE_H264)
42  #include "igtlH264Encoder.h"
43  #endif
44 #endif
45 
46 //----------------------------------------------------------------------------
47 
49 
50 //----------------------------------------------------------------------------
52  : IgtlFactory(igtl::MessageFactory::New())
53 {
54  this->IgtlFactory->AddMessageType("CLIENTINFO", (PointerToMessageBaseNew)&igtl::PlusClientInfoMessage::New);
55  this->IgtlFactory->AddMessageType("TRACKEDFRAME", (PointerToMessageBaseNew)&igtl::PlusTrackedFrameMessage::New);
56  this->IgtlFactory->AddMessageType("USMESSAGE", (PointerToMessageBaseNew)&igtl::PlusUsMessage::New);
57 }
58 
59 //----------------------------------------------------------------------------
61 {
62 
63 }
64 
65 //----------------------------------------------------------------------------
66 void vtkPlusIgtlMessageFactory::PrintSelf(ostream& os, vtkIndent indent)
67 {
68  this->Superclass::PrintSelf(os, indent);
69  this->PrintAvailableMessageTypes(os, indent);
70 }
71 
72 //----------------------------------------------------------------------------
74 {
75  return this->IgtlFactory->GetMessageTypeNewPointer(messageTypeName);
76 }
77 
78 //----------------------------------------------------------------------------
79 void vtkPlusIgtlMessageFactory::PrintAvailableMessageTypes(ostream& os, vtkIndent indent)
80 {
81  os << indent << "Supported OpenIGTLink message types: " << std::endl;
82  std::vector<std::string> types;
83  this->IgtlFactory->GetAvailableMessageTypes(types);
84  for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); ++it)
85  {
86  os << indent.GetNextIndent() << "- " << *it << std::endl;
87  }
88 }
89 
90 //----------------------------------------------------------------------------
91 igtl::MessageHeader::Pointer vtkPlusIgtlMessageFactory::CreateHeaderMessage(int headerVersion) const
92 {
93  return this->IgtlFactory->CreateHeaderMessage(headerVersion);
94 }
95 
96 //----------------------------------------------------------------------------
97 igtl::MessageBase::Pointer vtkPlusIgtlMessageFactory::CreateReceiveMessage(const igtl::MessageHeader::Pointer aIgtlMessageHdr) const
98 {
99  if (aIgtlMessageHdr.IsNull())
100  {
101  LOG_ERROR("Null header sent to factory. Unable to produce a message.");
102  return NULL;
103  }
104 
105  igtl::MessageBase::Pointer aMessageBase;
106  try
107  {
108  aMessageBase = this->IgtlFactory->CreateReceiveMessage(aIgtlMessageHdr);
109  }
110  catch (std::invalid_argument& e)
111  {
112  LOG_ERROR("Unable to create message: " << e.what());
113  return NULL;
114  }
115 
116  if (aMessageBase.IsNull())
117  {
118  LOG_ERROR("IGTL factory unable to produce message of type:" << aIgtlMessageHdr->GetMessageType());
119  return NULL;
120  }
121 
122  return aMessageBase;
123 }
124 
125 //----------------------------------------------------------------------------
126 igtl::MessageBase::Pointer vtkPlusIgtlMessageFactory::CreateSendMessage(const std::string& messageType, int headerVersion) const
127 {
128  igtl::MessageBase::Pointer aMessageBase;
129  try
130  {
131  aMessageBase = this->IgtlFactory->CreateSendMessage(messageType, headerVersion);
132  }
133  catch (std::invalid_argument& e)
134  {
135  LOG_ERROR("Unable to create message: " << e.what());
136  return NULL;
137  }
138  return aMessageBase;
139 }
140 
141 //----------------------------------------------------------------------------
142 PlusStatus vtkPlusIgtlMessageFactory::PackMessages(int clientId, const PlusIgtlClientInfo& clientInfo, std::vector<igtl::MessageBase::Pointer>& igtlMessages, igsioTrackedFrame& trackedFrame,
143  bool packValidTransformsOnly, vtkIGSIOTransformRepository* transformRepository/*=NULL*/)
144 {
145  int numberOfErrors(0);
146  igtlMessages.clear();
147 
148  if (transformRepository != NULL)
149  {
150  transformRepository->SetTransforms(trackedFrame);
151  }
152 
153  for (std::vector<std::string>::const_iterator messageTypeIterator = clientInfo.IgtlMessageTypes.begin(); messageTypeIterator != clientInfo.IgtlMessageTypes.end(); ++ messageTypeIterator)
154  {
155  std::string messageType = (*messageTypeIterator);
156  igtl::MessageBase::Pointer igtlMessage;
157  try
158  {
159  igtlMessage = this->IgtlFactory->CreateSendMessage(messageType, clientInfo.GetClientHeaderVersion());
160  }
161  catch (std::invalid_argument& e)
162  {
163  LOG_ERROR("Unable to create message: " << e.what());
164  continue;
165  }
166 
167  if (igtlMessage.IsNull())
168  {
169  LOG_ERROR("Failed to pack IGT messages - unable to create instance from message type: " << messageType);
170  numberOfErrors++;
171  continue;
172  }
173 
174  if (typeid(*igtlMessage) == typeid(igtl::ImageMessage))
175  {
176  numberOfErrors += PackImageMessage(clientInfo, *transformRepository, messageType, igtlMessage, trackedFrame, igtlMessages, clientId);
177  }
178 #if defined(OpenIGTLink_ENABLE_VIDEOSTREAMING)
179  else if (typeid(*igtlMessage) == typeid(igtl::VideoMessage))
180  {
181  numberOfErrors += PackVideoMessage(clientInfo, *transformRepository, messageType, igtlMessage, trackedFrame, igtlMessages, clientId);
182  }
183 #endif
184  else if (typeid(*igtlMessage) == typeid(igtl::TransformMessage))
185  {
186  numberOfErrors += PackTransformMessage(clientInfo, *transformRepository, packValidTransformsOnly, igtlMessage, trackedFrame, igtlMessages);
187  }
188  else if (typeid(*igtlMessage) == typeid(igtl::TrackingDataMessage))
189  {
190  numberOfErrors += PackTrackingDataMessage(clientInfo, trackedFrame, *transformRepository, packValidTransformsOnly, igtlMessage, igtlMessages);
191  }
192  else if (typeid(*igtlMessage) == typeid(igtl::PositionMessage))
193  {
194  numberOfErrors += PackPositionMessage(clientInfo, *transformRepository, igtlMessage, trackedFrame, igtlMessages);
195  }
196  else if (typeid(*igtlMessage) == typeid(igtl::PlusTrackedFrameMessage))
197  {
198  numberOfErrors += PackTrackedFrameMessage(igtlMessage, clientInfo, *transformRepository, trackedFrame, igtlMessages);
199  }
200  else if (typeid(*igtlMessage) == typeid(igtl::PlusUsMessage))
201  {
202  numberOfErrors += PackUsMessage(igtlMessage, trackedFrame, igtlMessages);
203  }
204  else if (typeid(*igtlMessage) == typeid(igtl::StringMessage))
205  {
206  numberOfErrors += PackStringMessage(clientInfo, trackedFrame, igtlMessage, igtlMessages);
207  }
208  else if (typeid(*igtlMessage) == typeid(igtl::CommandMessage))
209  {
210  numberOfErrors += PackCommandMessage(igtlMessage, igtlMessages);
211  }
212  else
213  {
214  LOG_WARNING("This message type (" << messageType << ") is not supported!");
215  }
216  }
217 
218  return (numberOfErrors == 0 ? PLUS_SUCCESS : PLUS_FAIL);
219 }
220 
221 //----------------------------------------------------------------------------
222 int vtkPlusIgtlMessageFactory::PackCommandMessage(igtl::MessageBase::Pointer igtlMessage, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
223 {
224  // Is there any use case for the server sending commands to the client?
225  igtl::CommandMessage::Pointer commandMessage = dynamic_cast<igtl::CommandMessage*>(igtlMessage->Clone().GetPointer());
226  //vtkPlusIgtlMessageCommon::PackCommandMessage( commandMessage );
227  igtlMessages.push_back(commandMessage.GetPointer());
228 
229  return 0; // message type does not produce errors
230 }
231 
232 //----------------------------------------------------------------------------
233 int vtkPlusIgtlMessageFactory::PackStringMessage(const PlusIgtlClientInfo& clientInfo, igsioTrackedFrame& trackedFrame, igtl::MessageBase::Pointer igtlMessage, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
234 {
235  for (std::vector<std::string>::const_iterator stringNameIterator = clientInfo.StringNames.begin(); stringNameIterator != clientInfo.StringNames.end(); ++stringNameIterator)
236  {
237  std::string stringValue = trackedFrame.GetFrameField(*stringNameIterator);
238  if (stringValue.empty())
239  {
240  // no value is available, do not send anything
241  continue;
242  }
243  igtl::StringMessage::Pointer stringMessage = dynamic_cast<igtl::StringMessage*>(igtlMessage->Clone().GetPointer());
244  vtkPlusIgtlMessageCommon::PackStringMessage(stringMessage, *stringNameIterator, stringValue, trackedFrame.GetTimestamp());
245  igtlMessages.push_back(stringMessage.GetPointer());
246  }
247  return 0; // message type does not produce errors
248 }
249 
250 //----------------------------------------------------------------------------
251 int vtkPlusIgtlMessageFactory::PackUsMessage(igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
252 {
253  int numberOfErrors(0);
254  igtl::PlusUsMessage::Pointer usMessage = dynamic_cast<igtl::PlusUsMessage*>(igtlMessage->Clone().GetPointer());
255  if (vtkPlusIgtlMessageCommon::PackUsMessage(usMessage, trackedFrame) != PLUS_SUCCESS)
256  {
257  LOG_ERROR("Failed to pack IGT messages - unable to pack US message");
258  numberOfErrors++;
259  return numberOfErrors;
260  }
261  igtlMessages.push_back(usMessage.GetPointer());
262  return numberOfErrors;
263 }
264 
265 //----------------------------------------------------------------------------
266 int vtkPlusIgtlMessageFactory::PackTrackedFrameMessage(igtl::MessageBase::Pointer igtlMessage, const PlusIgtlClientInfo& clientInfo, vtkIGSIOTransformRepository& transformRepository, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
267 {
268  int numberOfErrors(0);
269  igtl::PlusTrackedFrameMessage::Pointer trackedFrameMessage = dynamic_cast<igtl::PlusTrackedFrameMessage*>(igtlMessage->Clone().GetPointer());
270 
271  for (auto nameIter = clientInfo.TransformNames.begin(); nameIter != clientInfo.TransformNames.end(); ++nameIter)
272  {
273  ToolStatus status(TOOL_INVALID);
274  vtkSmartPointer<vtkMatrix4x4> matrix(vtkSmartPointer<vtkMatrix4x4>::New());
275  transformRepository.GetTransform(*nameIter, matrix, &status);
276  trackedFrame.SetFrameTransform(*nameIter, matrix);
277  trackedFrame.SetFrameTransformStatus(*nameIter, status);
278  }
279 
280  vtkSmartPointer<vtkMatrix4x4> imageMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
281  imageMatrix->Identity();
282  if (!clientInfo.ImageStreams.empty())
283  {
284  ToolStatus status(TOOL_INVALID);
285  if (transformRepository.GetTransform(igsioTransformName(clientInfo.ImageStreams[0].Name, clientInfo.ImageStreams[0].EmbeddedTransformToFrame), imageMatrix, &status) != PLUS_SUCCESS)
286  {
287  LOG_ERROR("Unable to retrieve embedded image transform: " << clientInfo.ImageStreams[0].Name << "To" << clientInfo.ImageStreams[0].EmbeddedTransformToFrame << ".");
288  numberOfErrors++;
289  return numberOfErrors;
290  }
291  }
292  if (vtkPlusIgtlMessageCommon::PackTrackedFrameMessage(trackedFrameMessage, trackedFrame, imageMatrix, clientInfo.TransformNames) != PLUS_SUCCESS)
293  {
294  LOG_ERROR("Failed to pack IGT messages - unable to pack tracked frame message");
295  numberOfErrors++;
296  return numberOfErrors;
297  }
298  igtlMessages.push_back(trackedFrameMessage.GetPointer());
299  return numberOfErrors;
300 }
301 
302 //----------------------------------------------------------------------------
303 int vtkPlusIgtlMessageFactory::PackPositionMessage(const PlusIgtlClientInfo& clientInfo, vtkIGSIOTransformRepository& transformRepository, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
304 {
305  for (std::vector<igsioTransformName>::const_iterator transformNameIterator = clientInfo.TransformNames.begin(); transformNameIterator != clientInfo.TransformNames.end(); ++transformNameIterator)
306  {
307  /*
308  Advantage of using position message type:
309  Although equivalent position and orientation can be described with the TRANSFORM data type,
310  the POSITION data type has the advantage of smaller data size (19%). It is therefore more suitable for
311  pushing high frame-rate data from tracking devices.
312  */
313  igsioTransformName transformName = (*transformNameIterator);
314  igtl::Matrix4x4 igtlMatrix;
315  vtkPlusIgtlMessageCommon::GetIgtlMatrix(igtlMatrix, &transformRepository, transformName);
316 
317  ToolStatus status;
318  vtkNew<vtkMatrix4x4> temp;
319  transformRepository.GetTransform(transformName, temp.GetPointer(), &status);
320 
321  float position[3] = { igtlMatrix[0][3], igtlMatrix[1][3], igtlMatrix[2][3] };
322  float quaternion[4] = { 0, 0, 0, 1 };
323  igtl::MatrixToQuaternion(igtlMatrix, quaternion);
324 
325  igtl::PositionMessage::Pointer positionMessage = dynamic_cast<igtl::PositionMessage*>(igtlMessage->Clone().GetPointer());
326  vtkPlusIgtlMessageCommon::PackPositionMessage(positionMessage, transformName, status, position, quaternion, trackedFrame.GetTimestamp());
327  igtlMessages.push_back(positionMessage.GetPointer());
328  }
329 
330  return 0; // no errors possible with this message type
331 }
332 
333 //----------------------------------------------------------------------------
334 int vtkPlusIgtlMessageFactory::PackTrackingDataMessage(const PlusIgtlClientInfo& clientInfo, igsioTrackedFrame& trackedFrame, vtkIGSIOTransformRepository& transformRepository, bool packValidTransformsOnly, igtl::MessageBase::Pointer igtlMessage, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
335 {
336  if (clientInfo.GetTDATARequested() && clientInfo.GetLastTDATASentTimeStamp() + clientInfo.GetTDATAResolution() < trackedFrame.GetTimestamp())
337  {
338  std::vector<igsioTransformName> names;
339 
340  std::map<std::string, vtkSmartPointer<vtkMatrix4x4> > transforms;
341  for (std::vector<igsioTransformName>::const_iterator transformNameIterator = clientInfo.TransformNames.begin(); transformNameIterator != clientInfo.TransformNames.end(); ++transformNameIterator)
342  {
343  igsioTransformName transformName = (*transformNameIterator);
344 
345  ToolStatus status(TOOL_INVALID);
346  vtkSmartPointer<vtkMatrix4x4> mat = vtkSmartPointer<vtkMatrix4x4>::New();
347  transformRepository.GetTransform(transformName, mat, &status);
348 
349  if (status != TOOL_OK && packValidTransformsOnly)
350  {
351  LOG_TRACE("Attempted to send invalid transform over IGT Link when server has prevented sending.");
352  continue;
353  }
354 
355  names.push_back(transformName);
356  }
357 
358  igtl::TrackingDataMessage::Pointer trackingDataMessage = dynamic_cast<igtl::TrackingDataMessage*>(igtlMessage->Clone().GetPointer());
359  vtkPlusIgtlMessageCommon::PackTrackingDataMessage(trackingDataMessage, names, transformRepository, trackedFrame.GetTimestamp());
360  igtlMessages.push_back(trackingDataMessage.GetPointer());
361  }
362  return 0; // no errors possible for this message type
363 }
364 
365 //----------------------------------------------------------------------------
366 int vtkPlusIgtlMessageFactory::PackTransformMessage(const PlusIgtlClientInfo& clientInfo, vtkIGSIOTransformRepository& transformRepository, bool packValidTransformsOnly, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages)
367 {
368  for (std::vector<igsioTransformName>::const_iterator transformNameIterator = clientInfo.TransformNames.begin(); transformNameIterator != clientInfo.TransformNames.end(); ++transformNameIterator)
369  {
370  igsioTransformName transformName = (*transformNameIterator);
371  ToolStatus status(TOOL_UNKNOWN);
372  vtkNew<vtkMatrix4x4> temp;
373  transformRepository.GetTransform(transformName, temp.GetPointer(), &status);
374 
375  if (status != TOOL_OK && packValidTransformsOnly)
376  {
377  LOG_TRACE("Attempted to send invalid transform over IGT Link when server has prevented sending.");
378  continue;
379  }
380 
381  igtl::Matrix4x4 igtlMatrix;
382  vtkPlusIgtlMessageCommon::GetIgtlMatrix(igtlMatrix, &transformRepository, transformName);
383  igtl::TransformMessage::Pointer transformMessage = dynamic_cast<igtl::TransformMessage*>(igtlMessage->Clone().GetPointer());
384  igsioFieldMapType frameFields = trackedFrame.GetFrameFields();
385  for (igsioFieldMapType::iterator iter = frameFields.begin(); iter != frameFields.end(); ++iter)
386  {
387  if (iter->first.find(transformName.GetTransformName()) == 0)
388  {
389  // field starts with transform name, check flags
390  if ((iter->second.first & igsioFrameFieldFlags::FRAMEFIELD_FORCE_SERVER_SEND) > 0)
391  {
392  std::string stripped = iter->first.substr(transformName.GetTransformName().length());
393  transformMessage->SetMetaDataElement(stripped, IANA_TYPE_US_ASCII, iter->second.second);
394  }
395  }
396  }
397  vtkPlusIgtlMessageCommon::PackTransformMessage(transformMessage, transformName, igtlMatrix, status, trackedFrame.GetTimestamp());
398  igtlMessages.push_back(transformMessage.GetPointer());
399  }
400 
401  return 0; // no errors possible in this message type
402 }
403 
404 //----------------------------------------------------------------------------
405 int vtkPlusIgtlMessageFactory::PackImageMessage(const PlusIgtlClientInfo& clientInfo, vtkIGSIOTransformRepository& transformRepository, const std::string& messageType, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages, int clientId)
406 {
407  int numberOfErrors = 0;
408  for (std::vector<PlusIgtlClientInfo::ImageStream>::const_iterator imageStreamIterator = clientInfo.ImageStreams.begin(); imageStreamIterator != clientInfo.ImageStreams.end(); ++imageStreamIterator)
409  {
410  PlusIgtlClientInfo::ImageStream imageStream = (*imageStreamIterator);
411 
412  // Set transform name to [Name]To[CoordinateFrame]
413  igsioTransformName imageTransformName = igsioTransformName(imageStream.Name, imageStream.EmbeddedTransformToFrame);
414 
415  vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
416  ToolStatus status;
417  if (transformRepository.GetTransform(imageTransformName, matrix.Get(), &status) != PLUS_SUCCESS)
418  {
419  LOG_WARNING("Failed to create " << messageType << " message: cannot get image transform. ToolStatus: " << status);
420  numberOfErrors++;
421  continue;
422  }
423 
424  std::string deviceName = imageTransformName.From() + std::string("_") + imageTransformName.To();
425 
426  igtl::ImageMessage::Pointer imageMessage = dynamic_cast<igtl::ImageMessage*>(igtlMessage->Clone().GetPointer());
427  if (trackedFrame.IsFrameFieldDefined(igsioTrackedFrame::FIELD_FRIENDLY_DEVICE_NAME))
428  {
429  // Allow overriding of device name with something human readable
430  // The transform name is passed in the metadata
431  deviceName = trackedFrame.GetFrameField(igsioTrackedFrame::FIELD_FRIENDLY_DEVICE_NAME);
432  }
433  imageMessage->SetDeviceName(deviceName.c_str());
434 
435  // Send igsioTrackedFrame::CustomFrameFields as meta data in the image message.
436  std::vector<std::string> frameFields;
437  trackedFrame.GetFrameFieldNameList(frameFields);
438  for (std::vector<std::string>::const_iterator stringNameIterator = frameFields.begin(); stringNameIterator != frameFields.end(); ++stringNameIterator)
439  {
440  if (trackedFrame.GetFrameField(*stringNameIterator).empty())
441  {
442  // No value is available, do not send anything
443  LOG_WARNING("No metadata value for: " << *stringNameIterator)
444  continue;
445  }
446  imageMessage->SetMetaDataElement(*stringNameIterator, IANA_TYPE_US_ASCII, trackedFrame.GetFrameField(*stringNameIterator));
447  }
448 
449  if (vtkPlusIgtlMessageCommon::PackImageMessage(imageMessage, trackedFrame, *matrix, imageStream.FrameConverter) != PLUS_SUCCESS)
450  {
451  LOG_ERROR("Failed to create " << messageType << " message - unable to pack image message");
452  numberOfErrors++;
453  continue;
454  }
455  igtlMessages.push_back(imageMessage.GetPointer());
456  }
457  return numberOfErrors;
458 }
459 
460 #if defined(OpenIGTLink_ENABLE_VIDEOSTREAMING)
461 //----------------------------------------------------------------------------
462 int vtkPlusIgtlMessageFactory::PackVideoMessage(const PlusIgtlClientInfo& clientInfo, vtkIGSIOTransformRepository& transformRepository, const std::string& messageType, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame& trackedFrame, std::vector<igtl::MessageBase::Pointer>& igtlMessages, int clientId)
463 {
464  int numberOfErrors = 0;
465  for (std::vector<PlusIgtlClientInfo::VideoStream>::const_iterator videoStreamIterator = clientInfo.VideoStreams.begin(); videoStreamIterator != clientInfo.VideoStreams.end(); ++videoStreamIterator)
466  {
467  PlusIgtlClientInfo::VideoStream videoStream = (*videoStreamIterator);
468 
469  // Set transform name to [Name]To[CoordinateFrame]
470  igsioTransformName imageTransformName = igsioTransformName(videoStream.Name, videoStream.EmbeddedTransformToFrame);
471 
472  vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
473  if (transformRepository.GetTransform(imageTransformName, matrix.Get()) != PLUS_SUCCESS)
474  {
475  LOG_WARNING("Failed to create " << messageType << " message: cannot get image transform");
476  numberOfErrors++;
477  continue;
478  }
479 
480  std::string deviceName = imageTransformName.From() + std::string("_") + imageTransformName.To();
481 
482  igtl::VideoMessage::Pointer videoMessage = dynamic_cast<igtl::VideoMessage*>(igtlMessage->Clone().GetPointer());
483  if (trackedFrame.IsFrameFieldDefined(igsioTrackedFrame::FIELD_FRIENDLY_DEVICE_NAME))
484  {
485  // Allow overriding of device name with something human readable
486  // The transform name is passed in the metadata
487  deviceName = trackedFrame.GetFrameField(igsioTrackedFrame::FIELD_FRIENDLY_DEVICE_NAME);
488  }
489  videoMessage->SetDeviceName(deviceName.c_str());
490 
491  // Send igsioTrackedFrame::CustomFrameFields as meta data in the image message.
492  std::vector<std::string> frameFields;
493  trackedFrame.GetFrameFieldNameList(frameFields);
494  for (std::vector<std::string>::const_iterator stringNameIterator = frameFields.begin(); stringNameIterator != frameFields.end(); ++stringNameIterator)
495  {
496  if (trackedFrame.GetFrameField(*stringNameIterator).empty())
497  {
498  // No value is available, do not send anything
499  LOG_WARNING("No metadata value for: " << *stringNameIterator);
500  continue;
501  }
502  videoMessage->SetMetaDataElement(*stringNameIterator, IANA_TYPE_US_ASCII, trackedFrame.GetFrameField(*stringNameIterator));
503  }
504  videoMessage = igtl::VideoMessage::New();
505  videoMessage->SetDeviceName(deviceName.c_str());
506  std::map<std::string, std::string> parameters;
507  parameters["losslessEncoding"] = videoStream.EncodeVideoParameters.Lossless ? "1" : "0";
508  if (!videoStream.EncodeVideoParameters.Lossless)
509  {
510  parameters["rateControl"] = videoStream.EncodeVideoParameters.RateControl;
511  parameters["minimumKeyFrameDistance"] = igsioCommon::ToString(videoStream.EncodeVideoParameters.MinKeyframeDistance);
512  parameters["maximumKeyFrameDistance"] = igsioCommon::ToString(videoStream.EncodeVideoParameters.MaxKeyframeDistance);
513  parameters["encodingSpeed"] = igsioCommon::ToString(videoStream.EncodeVideoParameters.Speed);
514  parameters["bitRate"] = igsioCommon::ToString(videoStream.EncodeVideoParameters.TargetBitrate);
515  parameters["deadlineMode"] = videoStream.EncodeVideoParameters.DeadlineMode;
516  }
517 
518  if (vtkPlusIgtlMessageCommon::PackVideoMessage(videoMessage, trackedFrame, *matrix, videoStream.FrameConverter, videoStream.EncodeVideoParameters.FourCC, parameters) != PLUS_SUCCESS)
519  {
520  LOG_ERROR("Failed to create " << messageType << " message - unable to pack image message");
521  numberOfErrors++;
522  continue;
523  }
524  igtlMessages.push_back(videoMessage.GetPointer());
525  }
526  return numberOfErrors;
527 }
528 #endif
static PlusStatus PackImageMessage(igtl::ImageMessage::Pointer imageMessage, igsioTrackedFrame &trackedFrame, const vtkMatrix4x4 &imageToReferenceTransform, vtkIGSIOFrameConverter *frameConverter=NULL)
double GetLastTDATASentTimeStamp() const
igtl::MessageBase::Pointer CreateReceiveMessage(igtl::MessageHeader::Pointer headerMsg) const
virtual void PrintAvailableMessageTypes(ostream &os, vtkIndent indent)
static PlusStatus GetIgtlMatrix(igtl::Matrix4x4 &igtlMatrix, vtkIGSIOTransformRepository *transformRepository, igsioTransformName &transformName)
vtkStandardNewMacro(vtkPlusIgtlMessageFactory)
std::vector< ImageStream > ImageStreams
std::vector< std::string > IgtlMessageTypes
int PackPositionMessage(const PlusIgtlClientInfo &clientInfo, vtkIGSIOTransformRepository &transformRepository, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame &trackedFrame, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
std::vector< std::string > StringNames
vtkSmartPointer< vtkIGSIOFrameConverter > FrameConverter
int PackTrackingDataMessage(const PlusIgtlClientInfo &clientInfo, igsioTrackedFrame &trackedFrame, vtkIGSIOTransformRepository &transformRepository, bool packValidTransformsOnly, igtl::MessageBase::Pointer igtlMessage, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
std::vector< igsioTransformName > TransformNames
#define PLUS_FAIL
Definition: PlusCommon.h:43
IGTL message helper class for tracked frame messages.
static PlusStatus PackTransformMessage(igtl::TransformMessage::Pointer transformMessage, igsioTransformName &transformName, igtl::Matrix4x4 &igtlMatrix, ToolStatus status, double timestamp)
static PlusStatus PackPositionMessage(igtl::PositionMessage::Pointer positionMessage, igsioTransformName &transformName, ToolStatus status, float position[3], float quaternion[4], double timestamp)
bool GetTDATARequested() const
static PlusStatus PackUsMessage(igtl::PlusUsMessage::Pointer usMessage, igsioTrackedFrame &trackedFrame)
int PackStringMessage(const PlusIgtlClientInfo &clientInfo, igsioTrackedFrame &trackedFrame, igtl::MessageBase::Pointer igtlMessage, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
int PackTransformMessage(const PlusIgtlClientInfo &clientInfo, vtkIGSIOTransformRepository &transformRepository, bool packValidTransformsOnly, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame &trackedFrame, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
EncodingParameters EncodeVideoParameters
int PackCommandMessage(igtl::MessageBase::Pointer igtlMessage, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
iter
Definition: algo3.m:29
virtual vtkPlusIgtlMessageFactory::PointerToMessageBaseNew GetMessageTypeNewPointer(const std::string &messageTypeName)
const char ** deviceName
Definition: phidget22.h:1316
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
IGTL message helper class for sending USMessage device messages as IMAGE type message from tracked fr...
igtl::MessageFactory::Pointer IgtlFactory
std::vector< VideoStream > VideoStreams
Factory class of supported OpenIGTLink message types.
int GetClientHeaderVersion() const
int PackTrackedFrameMessage(igtl::MessageBase::Pointer igtlMessage, const PlusIgtlClientInfo &clientInfo, vtkIGSIOTransformRepository &transformRepository, igsioTrackedFrame &trackedFrame, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
static PlusStatus PackStringMessage(igtl::StringMessage::Pointer stringMessage, const char *stringName, const char *stringValue, double timestamp)
igtl::MessageBase::Pointer(* PointerToMessageBaseNew)()
static PlusStatus PackTrackedFrameMessage(igtl::PlusTrackedFrameMessage::Pointer trackedFrameMessage, igsioTrackedFrame &trackedFrame, vtkSmartPointer< vtkMatrix4x4 > embeddedImageTransform, const std::vector< igsioTransformName > &requestedTransforms)
igtl::MessageBase::Pointer CreateSendMessage(const std::string &messageType, int headerVersion) const
igtl::MessageHeader::Pointer CreateHeaderMessage(int headerVersion) const
int PackImageMessage(const PlusIgtlClientInfo &clientInfo, vtkIGSIOTransformRepository &transformRepository, const std::string &messageType, igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame &trackedFrame, std::vector< igtl::MessageBase::Pointer > &igtlMessages, int clientId)
double * position
Definition: phidget22.h:3303
static PlusStatus PackTrackingDataMessage(igtl::TrackingDataMessage::Pointer tdataMessage, const std::vector< igsioTransformName > &names, const vtkIGSIOTransformRepository &repository, double timestamp)
This class provides client information for vtkPlusOpenIGTLinkServer.
vtkSmartPointer< vtkIGSIOFrameConverter > FrameConverter
int PackUsMessage(igtl::MessageBase::Pointer igtlMessage, igsioTrackedFrame &trackedFrame, std::vector< igtl::MessageBase::Pointer > &igtlMessages)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
PlusStatus PackMessages(int clientId, const PlusIgtlClientInfo &clientInfo, std::vector< igtl::MessageBase::Pointer > &igtMessages, igsioTrackedFrame &trackedFrame, bool packValidTransformsOnly, vtkIGSIOTransformRepository *transformRepository=NULL)