Fraxinus  18.10
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 #include <igtlioUsSectorDefinitions.h>
18 
19 #include "cxLogger.h"
20 
21 namespace cx
22 {
23 
31 struct SectorInfo
32 {
33  const int tooLarge = 100000;
34 
35  ProbeDefinition::TYPE mProbeType; //0 = unknown, 1 = sector, 2 = linear
36 
38 
39  //Spacing are sent as separate messages, should be sent with image in the future.
40  double mSpacingX;
41  double mSpacingY;
42 
43  //new standard
44  std::vector<double> mOrigin;
45  std::vector<double> mAngles;
46  std::vector<double> mBoundingBox;
47  std::vector<double> mDepths;
48  double mLinearWidth;
49 
51 
53  {
54  reset();
55  }
56  void reset()
57  {
58  mHaveChanged = true;
59  mProbeType = ProbeDefinition::tNONE;
60 
61  //new standard
62  mOrigin.clear();
63  mAngles.clear();
64  mBoundingBox.clear();
65  mDepths.clear();
66  mLinearWidth = tooLarge;
67 
68  mSpacingX = tooLarge;
69  mSpacingY = tooLarge;
70 
71  mImage = ImagePtr();
72  }
73  bool isValid()
74  {
75  bool retval = true;
76  retval = retval && mImage;
77  retval = retval && ((mProbeType == ProbeDefinition::tSECTOR) || (mProbeType == ProbeDefinition::tLINEAR));
78  retval = retval && (mOrigin.size() == 3);
79  retval = retval && ((mAngles.size() == 2) || (mAngles.size() == 4));//2D == 2, 3D == 4
80  retval = retval && ((mBoundingBox.size() == 4) || (mBoundingBox.size() == 6)); //2D == 4, 3D == 6
81  retval = retval && (mDepths.size() == 2);
82  if(mProbeType == ProbeDefinition::tLINEAR)
83  retval = retval && (mLinearWidth < tooLarge);//Only for linear probes
84 
85  //Send spacing for now. Try to send it as image spacing
86  retval = retval && (mSpacingX < tooLarge);
87  retval = retval && (mSpacingY < tooLarge);
88  retval = retval && !similar(mSpacingX, 0);
89  retval = retval && !similar(mSpacingY, 0);
90 
91  return retval;
92  }
93 
94  bool haveChanged()
95  {
96  return mHaveChanged;
97  }
98 
99 };
100 
101 
103  mSectorInfo(new SectorInfo)
104 {}
105 
107 {
108  mSectorInfo->reset();
109 }
110 
111 void ProbeDefinitionFromStringMessages::parseStringMessage(igtlioBaseConverter::HeaderData header, QString message)
112 {
113  QString name = QString(header.deviceName.c_str());
114  QString value = message;
115  this->parseValue(name, value);
116 }
117 
128 std::vector<double> ProbeDefinitionFromStringMessages::toDoubleVector(QString values, QString separator) const
129 {
130  std::vector<double> retval;
131  QStringList valueList = values.split(separator);
132  for (int i = 0; i < valueList.size(); ++i)
133  {
134  double doublevalue = valueList[i].toDouble();
135  retval.push_back(doublevalue);
136  }
137  return retval;
138 }
139 
140 void ProbeDefinitionFromStringMessages::parseValue(QString name, QString value)
141 {
142  int intValue = value.toInt();
143  double doubleValue = value.toDouble();
144  std::vector<double> doubleVector = toDoubleVector(value);
145 
146 // CX_LOG_DEBUG() << "parseStringMessage: " << " name: " << name
147 // << " intValue: " << intValue
148 // << " doubleValue: " << doubleValue;
149 
150  if (name == IGTLIO_KEY_PROBE_TYPE)
151  {
152  if (mSectorInfo->mProbeType != intValue)
153  {
154  mSectorInfo->mProbeType = static_cast<ProbeDefinition::TYPE>(intValue);
155  }
156  }
157  //New standard
158  else if (name == IGTLIO_KEY_ORIGIN)
159  {
160  if(mSectorInfo->mOrigin != doubleVector)
161  {
162  mSectorInfo->mHaveChanged = true;
163  mSectorInfo->mOrigin = doubleVector;
164  }
165  }
166  else if (name == IGTLIO_KEY_ANGLES)
167  {
168  if(mSectorInfo->mAngles != doubleVector)
169  {
170  mSectorInfo->mHaveChanged = true;
171  mSectorInfo->mAngles = doubleVector;
172  }
173  }
174  else if (name == IGTLIO_KEY_BOUNDING_BOX)
175  {
176  if(mSectorInfo->mBoundingBox != doubleVector)
177  {
178  mSectorInfo->mHaveChanged = true;
179  mSectorInfo->mBoundingBox = doubleVector;
180  }
181  }
182  else if (name == IGTLIO_KEY_DEPTHS)
183  {
184  if(mSectorInfo->mDepths != doubleVector)
185  {
186  mSectorInfo->mHaveChanged = true;
187  mSectorInfo->mDepths = doubleVector;
188  }
189  }
190  else if (name == IGTLIO_KEY_LINEAR_WIDTH)
191  {
192  if(mSectorInfo->mLinearWidth != doubleValue)
193  {
194  mSectorInfo->mHaveChanged = true;
195  mSectorInfo->mLinearWidth = doubleValue;
196  }
197  }
198  else if (name == IGTLIO_KEY_SPACING_X)
199  {
200  mSectorInfo->mSpacingX = doubleValue;
201  }
202  else if (name == IGTLIO_KEY_SPACING_Y)
203  {
204  mSectorInfo->mSpacingY = doubleValue;
205  }
206 }
207 
209 {
210  mSectorInfo->mImage = image;
211 }
212 
214 {
215  return mSectorInfo->isValid();
216 }
217 
219 {
220  return mSectorInfo->haveChanged();
221 }
222 
224 {
225  mSectorInfo->mHaveChanged = false;
226 
227  if(!this->haveValidValues())
228  return ProbeDefinitionPtr();
229 
230  //Send spacing as messages for now. Should be sent together with image.
231  mSectorInfo->mImage->getBaseVtkImageData()->SetSpacing(mSectorInfo->mSpacingX, mSectorInfo->mSpacingY, 1.0);
232  Vector3D spacing = mSectorInfo->mImage->getSpacing();
233  Vector3D origin_p(mSectorInfo->mOrigin[0], mSectorInfo->mOrigin[1], mSectorInfo->mOrigin[2]);
234 
235  ProbeDefinitionPtr probeDefinition = this->initProbeDefinition();
236  probeDefinition->setUid(uid);
237  probeDefinition->setOrigin_p(origin_p);
238  probeDefinition->setSpacing(spacing);
239  probeDefinition->setClipRect_p(this->getBoundinBox());
240  probeDefinition->setSector(mSectorInfo->mDepths[0], mSectorInfo->mDepths[1], this->getWidth());
241  probeDefinition->setSize(this->getSize());
242  probeDefinition->setUseDigitalVideo(true);
243 
244  return probeDefinition;
245 }
246 
247 ProbeDefinitionPtr ProbeDefinitionFromStringMessages::initProbeDefinition()
248 {
249  ProbeDefinitionPtr probeDefinition;
250  probeDefinition = ProbeDefinitionPtr(new ProbeDefinition(mSectorInfo->mProbeType));
251 
252  if (mSectorInfo->mProbeType == ProbeDefinition::tNONE)
253  {
254  CX_LOG_ERROR() << "ProbeDefinitionFromStringMessages::initProbeDefinition: Incorrect probe type: " << mSectorInfo->mProbeType;
255  }
256  return probeDefinition;
257 }
258 
259 double ProbeDefinitionFromStringMessages::getWidth()
260 {
261  double width = 0;
262  if(mSectorInfo->mProbeType == ProbeDefinition::tLINEAR)
263  {
264  width = mSectorInfo->mLinearWidth;
265  }
266  else if (mSectorInfo->mProbeType == ProbeDefinition::tSECTOR)
267  {
268  width = mSectorInfo->mAngles[1] - mSectorInfo->mAngles[0];
269  }
270  return width;
271 }
272 
273 QSize ProbeDefinitionFromStringMessages::getSize()
274 {
275  Eigen::Array3i dimensions(mSectorInfo->mImage->getBaseVtkImageData()->GetDimensions());
276  QSize size(dimensions[0], dimensions[1]);
277  return size;
278 }
279 
280 DoubleBoundingBox3D ProbeDefinitionFromStringMessages::getBoundinBox() const
281 {
282  DoubleBoundingBox3D retval(mSectorInfo->mBoundingBox[0], mSectorInfo->mBoundingBox[1],
283  mSectorInfo->mBoundingBox[2], mSectorInfo->mBoundingBox[3],
284  this->getBoundingBoxThirdDimensionStart(),
285  this->getBoundingBoxThirdDimensionEnd());
286  return retval;
287 }
288 
289 double ProbeDefinitionFromStringMessages::getBoundingBoxThirdDimensionStart() const
290 {
291  if(mSectorInfo->mBoundingBox.size() == 6)
292  return mSectorInfo->mBoundingBox[4];
293  else
294  return 0;
295 }
296 
297 double ProbeDefinitionFromStringMessages::getBoundingBoxThirdDimensionEnd() const
298 {
299  if(mSectorInfo->mBoundingBox.size() == 6)
300  return mSectorInfo->mBoundingBox[5];
301  else
302  return 0;
303 }
304 
305 }//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
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
void parseStringMessage(igtlioBaseConverter::HeaderData header, QString message)
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.