NorMIT-nav  18.04
An IGT application
cxViewGroupData.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 
12 #include "cxViewGroupData.h"
13 
14 #include <QMenu>
15 #include "vtkCamera.h"
16 
17 #include "cxPatientModelService.h"
18 #include "cxMesh.h"
19 #include "cxTypeConversions.h"
20 #include "cxCameraControl.h"
21 #include "cxImageAlgorithms.h"
22 #include "cxDataMetric.h"
23 #include "cxView.h"
24 #include "cxImage.h"
25 #include "cxTrackedStream.h"
26 #include "cxInteractiveClipper.h"
27 #include "boost/bind.hpp"
28 #include "cxXMLNodeWrapper.h"
29 #include "cxSyncedValue.h"
30 #include "cxCoreServices.h"
31 #include "cxLogger.h"
32 #include "cxDefinitionStrings.h"
33 #include "cxStringListProperty.h"
34 #include "cxSharedOpenGLContext.h"
35 
36 namespace cx
37 {
38 
40 {
41  this->clear();
42 }
43 
44 CameraStyleData::CameraStyleData(CAMERA_STYLE_TYPE style)
45 {
46  this->setCameraStyle(style);
47 }
48 
49 void CameraStyleData::setCameraStyle(CAMERA_STYLE_TYPE style)
50 {
51  this->clear();
52 
53  if (style==cstDEFAULT_STYLE)
54  {
55  }
56  if (style==cstTOOL_STYLE)
57  {
58  mCameraFollowTool = true;
59  mFocusFollowTool = true;
60  }
61  if (style==cstANGLED_TOOL_STYLE)
62  {
63  mCameraFollowTool = true;
64  mFocusFollowTool = true;
65  mElevation = 20.0/180.0*M_PI;
66  }
67  if (style==cstUNICAM_STYLE)
68  {
69  mUniCam = true;
70  }
71 }
72 
73 CAMERA_STYLE_TYPE CameraStyleData::getStyle()
74 {
75  for (unsigned int i=0; i<cstCOUNT; ++i)
76  {
77  CAMERA_STYLE_TYPE current = static_cast<CAMERA_STYLE_TYPE>(i);
78  if (CameraStyleData(current)==*this)
79  return current;
80  }
81  return cstCOUNT;
82 }
83 
84 
86 {
87  mCameraViewAngle = 30.0/180*M_PI;
88  mCameraFollowTool = false;
89  mFocusFollowTool = false;
90  mCameraLockToTooltip = false;
93  mTableLock = false;
94  mElevation = 0;
95  mUniCam = false;
96  mAutoZoomROI = "";
97  mFocusROI = "";
98 }
99 
100 void CameraStyleData::addXml(QDomNode &dataNode)
101 {
102  QDomElement elem = dataNode.toElement();
103  elem.setAttribute("cameraViewAngle", mCameraViewAngle);
104  elem.setAttribute("cameraFollowTool", mCameraFollowTool);
105  elem.setAttribute("focusFollowTool", mFocusFollowTool);
106  elem.setAttribute("cameraOnTooltip", mCameraLockToTooltip);
107  elem.setAttribute("cameraTooltipOffset", mCameraTooltipOffset);
108  elem.setAttribute("cameraNotBehindROI", mCameraNotBehindROI);
109  elem.setAttribute("tableLock", mTableLock);
110  elem.setAttribute("elevation", mElevation);
111  elem.setAttribute("uniCam", mUniCam);
112  elem.setAttribute("autoZoomROI", mAutoZoomROI);
113  elem.setAttribute("focusROI", mFocusROI);
114 }
115 
116 void CameraStyleData::parseXml(QDomNode dataNode)
117 {
118  QDomElement elem = dataNode.toElement();
119  mCameraViewAngle = elem.attribute("cameraViewAngle", QString::number(mCameraViewAngle)).toDouble();
120  mCameraFollowTool = elem.attribute("cameraFollowTool", QString::number(mCameraFollowTool)).toInt();
121  mFocusFollowTool = elem.attribute("focusFollowTool", QString::number(mFocusFollowTool)).toInt();
122  mCameraLockToTooltip = elem.attribute("cameraOnTooltip", QString::number(mCameraLockToTooltip)).toInt();
123  mCameraTooltipOffset = elem.attribute("cameraTooltipOffset", QString::number(mCameraTooltipOffset)).toDouble();
124  mCameraNotBehindROI = elem.attribute("cameraNotBehindROI", mCameraNotBehindROI);
125  mTableLock = elem.attribute("tableLock", QString::number(mTableLock)).toInt();
126  mElevation = elem.attribute("elevation", QString::number(mElevation)).toDouble();
127  mUniCam = elem.attribute("uniCam", QString::number(mUniCam)).toInt();
128  mAutoZoomROI = elem.attribute("autoZoomROI", mAutoZoomROI);
129  mFocusROI = elem.attribute("focusROI", mFocusROI);
130 }
131 
132 bool operator==(const CameraStyleData& lhs, const CameraStyleData& rhs)
133 {
134  return ((lhs.mCameraViewAngle==rhs.mCameraViewAngle) &&
136  (lhs.mFocusFollowTool==rhs.mFocusFollowTool) &&
140  (lhs.mTableLock==rhs.mTableLock) &&
141  similar(lhs.mElevation, rhs.mElevation) &&
142  (lhs.mUniCam==rhs.mUniCam) &&
143  (lhs.mAutoZoomROI==rhs.mAutoZoomROI) &&
144  (lhs.mFocusROI==rhs.mFocusROI)
145  );
146 }
147 
148 
149 
150 
152 {
153  DataViewProperties retval;
154  retval.mVolume3D = true;
155  retval.mSlice3D = false;
156  retval.mSlice2D = true;
157  return retval;
158 }
160 {
161  DataViewProperties retval;
162  retval.mVolume3D = true;
163  retval.mSlice3D = true;
164  retval.mSlice2D = true;
165  return retval;
166 }
167 
169 {
170  DataViewProperties retval;
171  retval.mVolume3D = true;
172  retval.mSlice3D = false;
173  retval.mSlice2D = false;
174  return retval;
175 }
176 
178 {
179  DataViewProperties retval;
180  retval.mVolume3D = false;
181  retval.mSlice3D = true;
182  retval.mSlice2D = false;
183  return retval;
184 }
185 
187 {
188  DataViewProperties retval;
189  retval.mVolume3D = false;
190  retval.mSlice3D = false;
191  retval.mSlice2D = true;
192  return retval;
193 }
194 
196 {
197  DataViewProperties retval;
198  retval.mVolume3D = true;
199  retval.mSlice3D = true;
200  retval.mSlice2D = false;
201  return retval;
202 }
203 
204 
205 void DataViewProperties::addXml(QDomNode& dataNode)
206 {
207  QDomElement elem = dataNode.toElement();
208  elem.setAttribute("volume3D", mVolume3D);
209  elem.setAttribute("slice3D", mSlice3D);
210  elem.setAttribute("slice2D", mSlice2D);
211 }
212 
213 void DataViewProperties::parseXml(QDomNode dataNode)
214 {
215  QDomElement elem = dataNode.toElement();
216  mVolume3D = elem.attribute("volume3D", QString::number(mVolume3D)).toInt();
217  mSlice3D = elem.attribute("slice3D", QString::number(mSlice3D)).toInt();
218  mSlice2D = elem.attribute("slice2D", QString::number(mSlice2D)).toInt();
219 }
220 
222 {
223  return !(mVolume3D || mSlice3D || mSlice2D);
224 }
225 
227 {
228  DataViewProperties retval;
229  retval.mSlice2D = mSlice2D || rhs.mSlice2D;
230  retval.mSlice3D = mSlice3D || rhs.mSlice3D;
231  retval.mVolume3D = mVolume3D || rhs.mVolume3D;
232  return retval;
233 }
234 
236 {
237  DataViewProperties retval;
238  retval.mSlice2D = mSlice2D && !rhs.mSlice2D;
239  retval.mSlice3D = mSlice3D && !rhs.mSlice3D;
240  retval.mVolume3D = mVolume3D && !rhs.mVolume3D;
241  return retval;
242 }
243 
245 {
246  if (required.mSlice2D && mSlice2D) return true;
247  if (required.mSlice3D && mSlice3D) return true;
248  if (required.mVolume3D && mVolume3D) return true;
249  return false;
250 }
251 
252 
253 
257 
258 bool dataTypeSort(const DataPtr data1, const DataPtr data2)
259 {
260  return getPriority(data1) < getPriority(data2);
261 }
262 
264 {
265  if (data->getType()=="mesh")
266  return 6;
267  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
268  if (metric)
269  return 7;
270 
271  ImagePtr image = boost::dynamic_pointer_cast<Image>(data);
272  if (image)
273  {
274  if (image->getModality().toUpper().contains("US"))
275  {
276  if (image->getImageType().toUpper().contains("B-MODE"))
277  return 4;
278  else // angio types
279  return 5;
280  }
281  else if (image->getModality().toUpper().contains("MR"))
282  {
283  // MR, CT, SC, others
284  return 2;
285  }
286  else if (image->getModality().toUpper().contains("CT"))
287  {
288  // MR, CT, SC, others
289  return 1;
290  }
291  else
292  {
293  return 0;
294  }
295  }
296 
297  return 3;
298 }
299 
303 
305  mShowLandmarks(false), mShowPointPickerProbe(false),
306  mPickerGlyph(new Mesh("PickerGlyph"))
307 {
308 }
309 
311  mUid(uid),
312  mServices(services),
313  mCamera3D(CameraData::create())
314 {
315  if(mServices)
316  connect(mServices->patient().get(), &PatientModelService::dataAddedOrRemoved, this, &ViewGroupData::purgeDataNotExistingInPatientModelService);
317  mVideoSource = "active";
318  mGroup2DZoom = SyncedValue::create(1);
319  mGlobal2DZoom = mGroup2DZoom;
320 
321  this->createSliceDefinitionProperty();
322 }
323 
324 //Remove all data, and wait to emit signals until all data is removed
325 void ViewGroupData::purgeDataNotExistingInPatientModelService()
326 {
327  QStringList purged;
328  for (unsigned i = 0; i < mData.size(); )
329  {
330  QString uid = mData[i].first;
331  if (!mServices->patient()->getData(uid))
332  {
333  if (this->contains(uid))
334  {
335  purged << uid;
336  mData.erase(std::find_if(mData.begin(), mData.end(), data_equals(uid)));
337  }
338  }
339  else
340  ++i;
341  }
342  //Emit delayed signals
343  for(int i = 0; i < purged.size(); ++i)
344  emit dataViewPropertiesChanged(purged[i]);
345 }
346 
347 
349 {
350  emit initialized();
351 }
352 
353 void ViewGroupData::addData(QString uid)
354 {
355  DataViewProperties properties = this->getProperties(uid);
356  properties = properties.addFlagsIn(DataViewProperties::createDefault());
357  this->setProperties(uid, properties);
358 }
359 
361 {
362  if (this->contains(uid))
363  return;
364 
366  DataAndViewPropertiesPair item(uid, properties);
367 
368  for (int i=int(mData.size())-1; i>=0; --i)
369  {
370  if (!dataTypeSort(this->getData(uid), this->getData(mData[i].first)))
371  {
372  this->insertData(mData.begin()+i+1, item);
373  break;
374  }
375  }
376  if (!this->contains(uid))
377  this->insertData(mData.begin(), item);
378  emit dataViewPropertiesChanged(uid);
379 }
380 
381 void ViewGroupData::insertData(std::vector<DataAndViewPropertiesPair>::iterator iter, DataAndViewPropertiesPair &item)
382 {
383  //this->upload3DTextureIfImageToSharedContext(item.first);
384  this->mData.insert(iter, item);
385 }
386 
387 /*
388 //TODO remove? maybe it is better to do this in the proxy?
389 void ViewGroupData::upload3DTextureIfImageToSharedContext(QString uid)
390 {
391  CX_LOG_DEBUG() << "upload3DTextureIfImageToSharedContext: " << uid;
392  ImagePtr image = mServices->patient()->getData<Image>(uid);
393  if(image)
394  {
395  if(mSharedOpenGLContext)
396  mSharedOpenGLContext->upload3DTexture(image);
397  else
398  CX_LOG_ERROR() << "ViewGroupData::uploadIfImageToSharedContext: Got no shared OpenGL context";
399  }
400 }
401 */
402 
404 {
405  if (this->contains(uid))
406  return std::find_if(mData.begin(), mData.end(), data_equals(uid))->second;
407  return DataViewProperties();
408 }
409 
411 {
412  if (uid.isEmpty())
413  return;
414 
415  if (properties.empty())
416  {
417  this->removeData(uid);
418  return;
419  }
420 
421  if (!this->contains(uid))
422  {
423  DataAndViewPropertiesPair item(uid, properties);
424 // mData.push_back(item);
425  this->insertData(mData.end(), item);
426  }
427  else
428  {
429  std::find_if(mData.begin(), mData.end(), data_equals(uid))->second = properties;
430  }
431 
432  emit dataViewPropertiesChanged(uid);
433 }
434 
435 bool ViewGroupData::contains(QString uid) const
436 {
437  return std::count_if(mData.begin(), mData.end(), data_equals(uid));
438 }
439 
440 bool ViewGroupData::removeData(QString uid)
441 {
442  if (!this->contains(uid))
443  return false;
444  mData.erase(std::find_if(mData.begin(), mData.end(), data_equals(uid)));
445  emit dataViewPropertiesChanged(uid);
446  return true;
447 }
448 
450 {
451  while (!mData.empty())
452  this->removeData(mData.front().first);
453  this->setVideoSource("active");
454 
455  mGroup2DZoom->set(1.0);
456  mGlobal2DZoom->set(1.0);
457 }
458 
459 DataPtr ViewGroupData::getData(QString uid) const
460 {
461  DataPtr data = mServices->patient()->getData(uid);
462  if (!data)
463  {
464  reportError("Couldn't find the data: [" + uid + "] in the datamanager.");
465  return DataPtr();
466  }
467  return data;
468 }
469 
471 {
472  if (mVideoSource==uid)
473  return;
474  mVideoSource = uid;
475  emit videoSourceChanged(mVideoSource);
476 }
477 
479 {
480  return mVideoSource;
481 }
482 
483 std::vector<DataPtr> ViewGroupData::getData(DataViewProperties properties) const
484 {
485  return this->getDataOfType<Data>(properties);
486 }
487 
488 
489 template<class DATA_TYPE>
490 std::vector<boost::shared_ptr<DATA_TYPE> > ViewGroupData::getDataOfType(DataViewProperties requiredProperties) const
491 {
492  // speed optimization: call getdatas() instead of getdata() in for loop
493  std::map<QString, DataPtr> alldata = mServices->patient()->getDatas();
494 
495  typedef boost::shared_ptr<DATA_TYPE> DATA_PTR;
496  std::vector<DATA_PTR> retval;
497  for (unsigned i = 0; i < mData.size(); ++i)
498  {
499  DATA_PTR data = boost::dynamic_pointer_cast<DATA_TYPE>(alldata[mData[i].first]);
500  if (!data)
501  continue;
502  DataViewProperties properties = mData[i].second;
503  if (!properties.containsAnyFlagsIn(requiredProperties))
504  continue;
505  retval.push_back(data);
506  }
507  return retval;
508 }
509 
510 std::vector<ImagePtr> ViewGroupData::getImages(DataViewProperties properties) const
511 {
512  return this->getDataOfType<Image>(properties);
513 }
514 
515 std::vector<MeshPtr> ViewGroupData::getMeshes(DataViewProperties properties) const
516 {
517  return this->getDataOfType<Mesh>(properties);
518 }
519 
520 std::vector<TrackedStreamPtr> ViewGroupData::getTrackedStreams(DataViewProperties properties) const
521 {
522  return this->getDataOfType<TrackedStream>(properties);
523 }
524 
525 std::vector<ImagePtr> ViewGroupData::getImagesAndChangingImagesFromTrackedStreams(DataViewProperties properties, bool include2D) const
526 {
527  std::vector<ImagePtr> images = this->getImages(properties);
528  std::vector<TrackedStreamPtr> streams = this->getTrackedStreams(properties);
529 
530  for(unsigned i = 0; i < streams.size(); ++i)
531  {
532  ImagePtr changingImage = streams[i]->getChangingImage();
533  if(streams[i]->is3D())
534  images.push_back(changingImage);
535  if(include2D && streams[i]->is2D())
536  images.push_back(changingImage);
537  }
538  return images;
539 }
540 
542 {
543  return mOptions;
544 }
545 
547 {
548  mOptions = options;
549  emit optionsChanged();
550 }
551 
553 {
554  mGlobal2DZoom = val;
555 }
556 
558 {
559  return mGroup2DZoom;
560 }
562 {
563  return mGlobal2DZoom;
564 }
565 
566 void ViewGroupData::zoomCamera3D(int zoomFactor)
567 {
568  CameraDataPtr cameraData = this->getCamera3D();
569  if(!cameraData)
570  return;
571 
572  vtkCameraPtr camera = cameraData->getCamera();
573  if(!camera)
574  return;
575 
576  camera->Dolly(zoomFactor);
577 }
578 
579 void ViewGroupData::createSliceDefinitionProperty()
580 {
581  QStringList slicedefs;
582  for (int i=0; i<ptCOUNT; ++i)
583  slicedefs << enum2string(PLANE_TYPE(i));
584  QStringList slicedefaults;
586  mSliceDefinitionProperty = StringListProperty::initialize("slice_definition_3D",
587  "3D Slices",
588  "Select slice planes to view in 3D",
589  slicedefaults,
590  slicedefs);
591  connect(mSliceDefinitionProperty.get(), &Property::changed, this, &ViewGroupData::optionsChanged);
592 }
593 
595 {
596  QStringList val = mSliceDefinitionProperty->getValue();
597  return PlaneTypeCollection::fromString(val.join("/"));
598 }
599 
601 {
602  QStringList val_list = val.toString().split("/");
603  mSliceDefinitionProperty->setValue(val_list);
604 }
605 
607 {
608  return mSliceDefinitionProperty;
609 }
610 
611 void ViewGroupData::addXml(QDomNode& dataNode)
612 {
613  XMLNodeAdder base(dataNode);
614 
615  for (unsigned i = 0; i < mData.size(); ++i)
616  {
617  QDomElement elem;
618  elem = base.addTextToElement("data", mData[i].first);
619  mData[i].second.addXml(elem);
620  }
621 
622  base.addObjectToElement("camera3D", this->getCamera3D());
623  base.addTextToElement("slicesPlanes3D", this->getSliceDefinitions().toString());
624 
625  Options options = this->getOptions();
626  base.addObjectToElement("cameraStyle", &options.mCameraStyle);
627 }
628 
629 void ViewGroupData::parseXml(QDomNode dataNode)
630 {
631  XMLNodeParser base(dataNode);
632 
633  QString sliceText = base.parseTextFromElement("slicesPlanes3D");
635 
636  std::vector<QDomElement> dataElems = base.getDuplicateElements("data");
637  for (unsigned i=0; i<dataElems.size(); ++i)
638  {
639  QDomElement elem = dataElems[i];
640  QString uid = elem.text();
642  properties.parseXml(elem);
643 
644  this->addData(uid);
645  this->setProperties(uid, properties);
646  }
647 
648  base.parseObjectFromElement("camera3D", this->getCamera3D());
649 
650  Options options = this->getOptions();
651  base.parseObjectFromElement("cameraStyle", &options.mCameraStyle);
652  this->setOptions(options);
653 }
654 
655 void ViewGroupData::setRegistrationMode(REGISTRATION_STATUS mode)
656 {
657  ViewGroupData::Options options = this->getOptions();
658 
659  options.mShowLandmarks = false;
660  options.mShowPointPickerProbe = false;
661 
662  if (mode == rsIMAGE_REGISTRATED)
663  {
664  options.mShowLandmarks = true;
665  options.mShowPointPickerProbe = true;
666  }
667  if (mode == rsPATIENT_REGISTRATED)
668  {
669  options.mShowLandmarks = true;
670  options.mShowPointPickerProbe = false;
671  }
672 
673  this->setOptions(options);
674 }
675 
676 
677 } // namespace cx
int getPriority(DataPtr data)
static DataViewProperties createSlice3D()
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:38
void reportError(QString msg)
Definition: cxLogger.cpp:71
void initializeGlobal2DZoom(SyncedValuePtr val)
A mesh data set.
Definition: cxMesh.h:45
CameraDataPtr getCamera3D()
void addXml(QDomNode &dataNode)
static DataViewProperties createDefault()
boost::shared_ptr< class CameraData > CameraDataPtr
Definition: cxViewWrapper.h:36
PlaneTypeCollection getSliceDefinitions()
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:755
boost::shared_ptr< DataMetric > DataMetricPtr
Definition: cxDataMetric.h:73
void parseXml(QDomNode dataNode)
std::vector< QDomElement > getDuplicateElements(QString name)
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
std::vector< ImagePtr > getImagesAndChangingImagesFromTrackedStreams(DataViewProperties properties, bool include2D=false) const
CAMERA_STYLE_TYPE getStyle()
SyncedValuePtr getGroup2DZoom()
void parseXml(QDomNode dataNode)
SyncedValuePtr getGlobal2DZoom()
DataViewProperties getProperties(QString uid)
ptAXIAL
a slice seen from the top of the patient
Definition: cxDefinitions.h:38
cstTOOL_STYLE
Definition: cxViewService.h:34
ViewGroupData(CoreServicesPtr services, QString uid)
void setProperties(QString uid, DataViewProperties properties)
static DataViewProperties createSlice2D()
static StringListPropertyPtr initialize(const QString &uid, QString name, QString help, QStringList value, QStringList range, QDomNode root=QDomNode())
void addObjectToElement(QString name, T object)
cstDEFAULT_STYLE
Definition: cxViewService.h:34
static DataViewProperties create3D()
boost::shared_ptr< class Data > DataPtr
std::vector< MeshPtr > getMeshes(DataViewProperties properties) const
ptSAGITTAL
a slice seen from the side of the patient
Definition: cxDefinitions.h:38
static PlaneTypeCollection fromString(QString input, PlaneTypeCollection defVal=PlaneTypeCollection())
void setCameraStyle(CAMERA_STYLE_TYPE style)
void addData(QString uid)
void addDataSorted(QString uid)
add data in a predefined ordering: CT/MR/SC/US/USA/Mesh/Metrics
static SyncedValuePtr create(QVariant val=QVariant())
A volumetric data set.
Definition: cxImage.h:45
cstANGLED_TOOL_STYLE
Definition: cxViewService.h:34
QDomElement addTextToElement(QString name, QString text)
Options getOptions() const
void addXml(QDomNode &dataNode)
bool containsAnyFlagsIn(DataViewProperties required) const
static DataViewProperties createFull()
std::vector< ImagePtr > getImages(DataViewProperties properties) const
void parseXml(QDomNode dataNode)
std::vector< TrackedStreamPtr > getTrackedStreams(DataViewProperties properties) const
void dataViewPropertiesChanged(QString uid)
void changed()
emit when the underlying data value is changed: The user interface will be updated.
static DataViewProperties createVolume3D()
void zoomCamera3D(int zoomFactor)
bool dataTypeSort(const DataPtr data1, const DataPtr data2)
bool removeData(QString uid)
boost::shared_ptr< class StringListProperty > StringListPropertyPtr
bool operator==(const RegistrationTransform &lhs, const RegistrationTransform &rhs)
QString parseTextFromElement(QString name)
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
void setVideoSource(QString uid)
boost::shared_ptr< class CoreServices > CoreServicesPtr
Definition: cxCameraStyle.h:38
DataViewProperties removeFlagsIn(DataViewProperties rhs) const
void parseObjectFromElement(QString name, T object)
cstUNICAM_STYLE
Definition: cxViewService.h:34
DataViewProperties addFlagsIn(DataViewProperties rhs) const
void videoSourceChanged(QString uid)
boost::shared_ptr< class SyncedValue > SyncedValuePtr
Definition: cxViewGroup.h:30
void setRegistrationMode(REGISTRATION_STATUS mode)
StringListPropertyPtr getSliceDefinitionProperty()
void addXml(QDomNode &dataNode)
std::vector< DataPtr > getData(DataViewProperties properties=DataViewProperties::createFull()) const
Base class for all Data Metrics.
Definition: cxDataMetric.h:43
void setSliceDefinitions(PlaneTypeCollection val)
QString enum2string(const ENUM &val)
QString getVideoSource() const
void setOptions(Options options)
#define M_PI
vtkSmartPointer< class vtkCamera > vtkCameraPtr
rsIMAGE_REGISTRATED
Namespace for all CustusX production code.