NorMIT-nav  18.04
An IGT application
cxProbeDefinitionFromStringMessages.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
14 #include <vtkXMLDataElement.h>
15 #include <vtkXMLUtilities.h>
16 #include <vtkImageData.h>
17 
18 #include "cxLogger.h"
19 
20 //This information should be part of the new OpenIGTLinkIO standard
21 //These values are also defined in vtkPlusBkProFocusOemVideoSource in PLUS (as static variables)
22 #define KEY_PROBE_TYPE "ProbeType"
23 #define KEY_ORIGIN "Origin"
24 #define KEY_ANGLES "Angles"
25 #define KEY_BOUNDING_BOX "BouningBox"
26 #define KEY_DEPTHS "Depths"
27 #define KEY_LINEAR_WIDTH "LinearWidth"
28 #define KEY_SPACING_X "SpacingX"
29 #define KEY_SPACING_Y "SpacingY"
30 
31 namespace cx
32 {
33 
41 struct SectorInfo
42 {
43  const int tooLarge = 100000;
44 
45  ProbeDefinition::TYPE mProbeType; //0 = unknown, 1 = sector, 2 = linear
46 
48 
49  //Spacing are sent as separate messages, should be sent with image in the future.
50  double mSpacingX;
51  double mSpacingY;
52 
53  //new standard
54  std::vector<double> mOrigin;
55  std::vector<double> mAngles;
56  std::vector<double> mBouningBox;
57  std::vector<double> mDepths;
58  double mLinearWidth;
59 
61 
63  {
64  reset();
65  }
66  void reset()
67  {
68  mHaveChanged = true;
69  mProbeType = ProbeDefinition::tNONE;
70 
71  //new standard
72  mOrigin.clear();
73  mAngles.clear();
74  mBouningBox.clear();
75  mDepths.clear();
76  mLinearWidth = tooLarge;
77 
78  mSpacingX = tooLarge;
79  mSpacingY = tooLarge;
80 
81  mImage = ImagePtr();
82  }
83  bool isValid()
84  {
85  bool retval = true;
86  retval = retval && mImage;
87  retval = retval && ((mProbeType == ProbeDefinition::tSECTOR) || (mProbeType == ProbeDefinition::tLINEAR));
88  retval = retval && (mOrigin.size() == 3);
89  retval = retval && ((mAngles.size() == 2) || (mAngles.size() == 4));//2D == 2, 3D == 4
90  retval = retval && ((mBouningBox.size() == 4) || (mBouningBox.size() == 6)); //2D == 4, 3D == 6
91  retval = retval && (mDepths.size() == 2);
92  if(mProbeType == ProbeDefinition::tLINEAR)
93  retval = retval && (mLinearWidth < tooLarge);//Only for linear probes
94 
95  //Send spacing for now. Try to send it as image spacing
96  retval = retval && (mSpacingX < tooLarge);
97  retval = retval && (mSpacingY < tooLarge);
98  retval = retval && !similar(mSpacingX, 0);
99  retval = retval && !similar(mSpacingY, 0);
100 
101  return retval;
102  }
103 
104  bool haveChanged()
105  {
106  return mHaveChanged;
107  }
108 
109 };
110 
111 
113  mSectorInfo(new SectorInfo)
114 {}
115 
117 {
118  mSectorInfo->reset();
119 }
120 
121 void ProbeDefinitionFromStringMessages::parseStringMessage(igtlio::BaseConverter::HeaderData header, QString message)
122 {
123  QString name = QString(header.deviceName.c_str());
124  QString value = message;
125  this->parseValue(name, value);
126 }
127 
138 std::vector<double> ProbeDefinitionFromStringMessages::toDoubleVector(QString values, QString separator) const
139 {
140  std::vector<double> retval;
141  QStringList valueList = values.split(separator);
142  for (int i = 0; i < valueList.size(); ++i)
143  {
144  double doublevalue = valueList[i].toDouble();
145  retval.push_back(doublevalue);
146  }
147  return retval;
148 }
149 
150 void ProbeDefinitionFromStringMessages::parseValue(QString name, QString value)
151 {
152  int intValue = value.toInt();
153  double doubleValue = value.toDouble();
154  std::vector<double> doubleVector = toDoubleVector(value);
155 
156 // CX_LOG_DEBUG() << "parseStringMessage: " << " name: " << name
157 // << " intValue: " << intValue
158 // << " doubleValue: " << doubleValue;
159 
160  if (name == KEY_PROBE_TYPE)
161  {
162  if (mSectorInfo->mProbeType != intValue)
163  {
164  mSectorInfo->mProbeType = static_cast<ProbeDefinition::TYPE>(intValue);
165  }
166  }
167  //New standard
168  else if (name == KEY_ORIGIN)
169  {
170  if(mSectorInfo->mOrigin != doubleVector)
171  {
172  mSectorInfo->mHaveChanged = true;
173  mSectorInfo->mOrigin = doubleVector;
174  }
175  }
176  else if (name == KEY_ANGLES)
177  {
178  if(mSectorInfo->mAngles != doubleVector)
179  {
180  mSectorInfo->mHaveChanged = true;
181  mSectorInfo->mAngles = doubleVector;
182  }
183  }
184  else if (name == KEY_BOUNDING_BOX)
185  {
186  if(mSectorInfo->mBouningBox != doubleVector)
187  {
188  mSectorInfo->mHaveChanged = true;
189  mSectorInfo->mBouningBox = doubleVector;
190  }
191  }
192  else if (name == KEY_DEPTHS)
193  {
194  if(mSectorInfo->mDepths != doubleVector)
195  {
196  mSectorInfo->mHaveChanged = true;
197  mSectorInfo->mDepths = doubleVector;
198  }
199  }
200  else if (name == KEY_LINEAR_WIDTH)
201  {
202  if(mSectorInfo->mLinearWidth != doubleValue)
203  {
204  mSectorInfo->mHaveChanged = true;
205  mSectorInfo->mLinearWidth = doubleValue;
206  }
207  }
208  else if (name == KEY_SPACING_X)
209  {
210  mSectorInfo->mSpacingX = doubleValue;
211  }
212  else if (name == KEY_SPACING_Y)
213  {
214  mSectorInfo->mSpacingY = doubleValue;
215  }
216 }
217 
219 {
220  mSectorInfo->mImage = image;
221 }
222 
224 {
225  return mSectorInfo->isValid();
226 }
227 
229 {
230  return mSectorInfo->haveChanged();
231 }
232 
234 {
235  mSectorInfo->mHaveChanged = false;
236 
237  if(!this->haveValidValues())
238  return ProbeDefinitionPtr();
239 
240  //Send spacing as messages for now. Should be sent together with image.
241  mSectorInfo->mImage->getBaseVtkImageData()->SetSpacing(mSectorInfo->mSpacingX, mSectorInfo->mSpacingY, 1.0);
242  Vector3D spacing = mSectorInfo->mImage->getSpacing();
243  Vector3D origin_p(mSectorInfo->mOrigin[0], mSectorInfo->mOrigin[1], mSectorInfo->mOrigin[2]);
244 
245  ProbeDefinitionPtr probeDefinition = this->initProbeDefinition();
246  probeDefinition->setUid(uid);
247  probeDefinition->setOrigin_p(origin_p);
248  probeDefinition->setSpacing(spacing);
249  probeDefinition->setClipRect_p(this->getBoundinBox());
250  probeDefinition->setSector(mSectorInfo->mDepths[0], mSectorInfo->mDepths[1], this->getWidth());
251  probeDefinition->setSize(this->getSize());
252  probeDefinition->setUseDigitalVideo(true);
253 
254  return probeDefinition;
255 }
256 
257 ProbeDefinitionPtr ProbeDefinitionFromStringMessages::initProbeDefinition()
258 {
259  ProbeDefinitionPtr probeDefinition;
260  probeDefinition = ProbeDefinitionPtr(new ProbeDefinition(mSectorInfo->mProbeType));
261 
262  if (mSectorInfo->mProbeType == ProbeDefinition::tNONE)
263  {
264  CX_LOG_ERROR() << "ProbeDefinitionFromStringMessages::initProbeDefinition: Incorrect probe type: " << mSectorInfo->mProbeType;
265  }
266  return probeDefinition;
267 }
268 
269 double ProbeDefinitionFromStringMessages::getWidth()
270 {
271  double width = 0;
272  if(mSectorInfo->mProbeType == ProbeDefinition::tLINEAR)
273  {
274  width = mSectorInfo->mLinearWidth;
275  }
276  else if (mSectorInfo->mProbeType == ProbeDefinition::tSECTOR)
277  {
278  width = mSectorInfo->mAngles[1] - mSectorInfo->mAngles[0];
279  }
280  return width;
281 }
282 
283 QSize ProbeDefinitionFromStringMessages::getSize()
284 {
285  Eigen::Array3i dimensions(mSectorInfo->mImage->getBaseVtkImageData()->GetDimensions());
286  QSize size(dimensions[0], dimensions[1]);
287  return size;
288 }
289 
290 DoubleBoundingBox3D ProbeDefinitionFromStringMessages::getBoundinBox() const
291 {
292  DoubleBoundingBox3D retval(mSectorInfo->mBouningBox[0], mSectorInfo->mBouningBox[1],
293  mSectorInfo->mBouningBox[2], mSectorInfo->mBouningBox[3],
294  this->getBoundingBoxThirdDimensionStart(),
295  this->getBoundingBoxThirdDimensionEnd());
296  return retval;
297 }
298 
299 double ProbeDefinitionFromStringMessages::getBoundingBoxThirdDimensionStart() const
300 {
301  if(mSectorInfo->mBouningBox.size() == 6)
302  return mSectorInfo->mBouningBox[4];
303  else
304  return 0;
305 }
306 
307 double ProbeDefinitionFromStringMessages::getBoundingBoxThirdDimensionEnd() const
308 {
309  if(mSectorInfo->mBouningBox.size() == 6)
310  return mSectorInfo->mBouningBox[5];
311  else
312  return 0;
313 }
314 
315 }//cx
US beam is emitted straight forward.
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
US beam is emitted radially in a flat cone.
#define CX_LOG_ERROR
Definition: cxLogger.h:99
void parseStringMessage(igtlio::BaseConverter::HeaderData header, QString message)
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
Definition of characteristics for an Ultrasound Probe Sector.
CompositeGenerator< T > values(T val1, T val2)
Definition: catch.hpp:3128
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
boost::shared_ptr< class ProbeDefinition > ProbeDefinitionPtr
Namespace for all CustusX production code.