CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxViewGroupData.h"
34 
35 #include <QMenu>
36 #include "vtkCamera.h"
37 
38 #include "cxPatientModelService.h"
39 #include "cxMesh.h"
40 #include "cxTypeConversions.h"
41 #include "cxCameraControl.h"
42 #include "cxImageAlgorithms.h"
43 #include "cxDataMetric.h"
44 #include "cxView.h"
45 #include "cxImage.h"
46 #include "cxInteractiveClipper.h"
47 #include "boost/bind.hpp"
48 #include "cxXMLNodeWrapper.h"
49 #include "cxSyncedValue.h"
50 #include "cxCoreServices.h"
51 #include "cxLogger.h"
52 
53 namespace cx
54 {
55 
57 {
58  DataViewProperties retval;
59  retval.mVolume3D = true;
60  retval.mSlice3D = false;
61  retval.mSlice2D = true;
62  return retval;
63 }
65 {
66  DataViewProperties retval;
67  retval.mVolume3D = true;
68  retval.mSlice3D = true;
69  retval.mSlice2D = true;
70  return retval;
71 }
72 
74 {
75  DataViewProperties retval;
76  retval.mVolume3D = true;
77  retval.mSlice3D = false;
78  retval.mSlice2D = false;
79  return retval;
80 }
81 
83 {
84  DataViewProperties retval;
85  retval.mVolume3D = false;
86  retval.mSlice3D = true;
87  retval.mSlice2D = false;
88  return retval;
89 }
90 
92 {
93  DataViewProperties retval;
94  retval.mVolume3D = false;
95  retval.mSlice3D = false;
96  retval.mSlice2D = true;
97  return retval;
98 }
99 
101 {
102  DataViewProperties retval;
103  retval.mVolume3D = true;
104  retval.mSlice3D = true;
105  retval.mSlice2D = false;
106  return retval;
107 }
108 
109 
110 void DataViewProperties::addXml(QDomNode& dataNode)
111 {
112  QDomElement elem = dataNode.toElement();
113  elem.setAttribute("volume3D", mVolume3D);
114  elem.setAttribute("slice3D", mSlice3D);
115  elem.setAttribute("slice2D", mSlice2D);
116 }
117 
118 void DataViewProperties::parseXml(QDomNode dataNode)
119 {
120  QDomElement elem = dataNode.toElement();
121  mVolume3D = elem.attribute("volume3D", QString::number(mVolume3D)).toInt();
122  mSlice3D = elem.attribute("slice3D", QString::number(mSlice3D)).toInt();
123  mSlice2D = elem.attribute("slice2D", QString::number(mSlice2D)).toInt();
124 }
125 
127 {
128  return !(mVolume3D || mSlice3D || mSlice2D);
129 }
130 
132 {
133  DataViewProperties retval;
134  retval.mSlice2D = mSlice2D || rhs.mSlice2D;
135  retval.mSlice3D = mSlice3D || rhs.mSlice3D;
136  retval.mVolume3D = mVolume3D || rhs.mVolume3D;
137  return retval;
138 }
139 
141 {
142  DataViewProperties retval;
143  retval.mSlice2D = mSlice2D && !rhs.mSlice2D;
144  retval.mSlice3D = mSlice3D && !rhs.mSlice3D;
145  retval.mVolume3D = mVolume3D && !rhs.mVolume3D;
146  return retval;
147 }
148 
150 {
151  if (required.mSlice2D && mSlice2D) return true;
152  if (required.mSlice3D && mSlice3D) return true;
153  if (required.mVolume3D && mVolume3D) return true;
154  return false;
155 }
156 
157 
158 
162 
163 bool dataTypeSort(const DataPtr data1, const DataPtr data2)
164 {
165  return getPriority(data1) < getPriority(data2);
166 }
167 
169 {
170  if (data->getType()=="mesh")
171  return 6;
172  DataMetricPtr metric = boost::dynamic_pointer_cast<DataMetric>(data);
173  if (metric)
174  return 7;
175 
176  ImagePtr image = boost::dynamic_pointer_cast<Image>(data);
177  if (image)
178  {
179  if (image->getModality().toUpper().contains("US"))
180  {
181  if (image->getImageType().toUpper().contains("B-MODE"))
182  return 4;
183  else // angio types
184  return 5;
185  }
186  else if (image->getModality().toUpper().contains("MR"))
187  {
188  // MR, CT, SC, others
189  return 2;
190  }
191  else if (image->getModality().toUpper().contains("CT"))
192  {
193  // MR, CT, SC, others
194  return 1;
195  }
196  else
197  {
198  return 0;
199  }
200  }
201 
202  return 3;
203 }
204 
208 
210  mShowLandmarks(false), mShowPointPickerProbe(false),
211  mPickerGlyph(new Mesh("PickerGlyph"))
212 {
213 }
214 
216  mServices(services),
217  mCamera3D(CameraData::create())
218 {
219  if(mServices)
220  connect(mServices->patientModelService.get(), &PatientModelService::dataAddedOrRemoved, this, &ViewGroupData::purgeDataNotExistingInPatientModelService);
221  mVideoSource = "active";
222  mGroup2DZoom = SyncedValue::create(1);
223  mGlobal2DZoom = mGroup2DZoom;
224 
225  mSliceDefinitions.add(ptAXIAL);
226  mSliceDefinitions.add(ptCORONAL);
227  mSliceDefinitions.add(ptSAGITTAL);
228 }
229 
230 //Remove all data, and wait to emit signals until all data is removed
231 void ViewGroupData::purgeDataNotExistingInPatientModelService()
232 {
233  QStringList purged;
234  for (unsigned i = 0; i < mData.size(); )
235  {
236  QString uid = mData[i].first;
237  if (!mServices->patientModelService->getData(uid))
238  {
239  if (this->contains(uid))
240  {
241  purged << uid;
242  mData.erase(std::find_if(mData.begin(), mData.end(), data_equals(uid)));
243  }
244  }
245  else
246  ++i;
247  }
248  //Emit delayed signals
249  for(unsigned i = 0; i < purged.size(); ++i)
250  emit dataViewPropertiesChanged(purged[i]);
251 }
252 
253 
255 {
256  emit initialized();
257 }
258 
259 void ViewGroupData::addData(QString uid)
260 {
261  DataViewProperties properties = this->getProperties(uid);
262  properties = properties.addFlagsIn(DataViewProperties::createDefault());
263  this->setProperties(uid, properties);
264 }
265 
267 {
268  if (this->contains(uid))
269  return;
270 
272  DataAndViewProperties item(uid, properties);
273 
274  for (int i=int(mData.size())-1; i>=0; --i)
275  {
276  if (!dataTypeSort(this->getData(uid), this->getData(mData[i].first)))
277  {
278  mData.insert(mData.begin()+i+1, item);
279  break;
280  }
281  }
282  if (!this->contains(uid))
283  mData.insert(mData.begin(), item);
284  emit dataViewPropertiesChanged(uid);
285 }
286 
288 {
289  if (this->contains(uid))
290  return std::find_if(mData.begin(), mData.end(), data_equals(uid))->second;
291  return DataViewProperties();
292 }
293 
295 {
296  if (uid.isEmpty())
297  return;
298 
299  if (properties.empty())
300  {
301  this->removeData(uid);
302  return;
303  }
304 
305  if (!this->contains(uid))
306  {
307  DataAndViewProperties item(uid, properties);
308  mData.push_back(item);
309  }
310  else
311  {
312  std::find_if(mData.begin(), mData.end(), data_equals(uid))->second = properties;
313  }
314 
315  emit dataViewPropertiesChanged(uid);
316 }
317 
318 bool ViewGroupData::contains(QString uid) const
319 {
320  return std::count_if(mData.begin(), mData.end(), data_equals(uid));
321 }
322 
323 bool ViewGroupData::removeData(QString uid)
324 {
325  if (!this->contains(uid))
326  return false;
327  mData.erase(std::find_if(mData.begin(), mData.end(), data_equals(uid)));
328  emit dataViewPropertiesChanged(uid);
329  return true;
330 }
331 
333 {
334  while (!mData.empty())
335  this->removeData(mData.front().first);
336  this->setVideoSource("active");
337 
338  mGroup2DZoom->set(1.0);
339  mGlobal2DZoom->set(1.0);
340 }
341 
342 DataPtr ViewGroupData::getData(QString uid) const
343 {
344  DataPtr data = mServices->patientModelService->getData(uid);
345  if (!data)
346  {
347  reportError("Couldn't find the data: [" + uid + "] in the datamanager.");
348  return DataPtr();
349  }
350  return data;
351 }
352 
354 {
355  if (mVideoSource==uid)
356  return;
357  mVideoSource = uid;
358  emit videoSourceChanged(mVideoSource);
359 }
360 
362 {
363  return mVideoSource;
364 }
365 
366 std::vector<DataPtr> ViewGroupData::getData(DataViewProperties properties) const
367 {
368  return this->getDataOfType<Data>(properties);
369 }
370 
371 template<class DATA_TYPE>
372 std::vector<boost::shared_ptr<DATA_TYPE> > ViewGroupData::getDataOfType(DataViewProperties requiredProperties) const
373 {
374  typedef boost::shared_ptr<DATA_TYPE> DATA_PTR;
375  std::vector<DATA_PTR> retval;
376  for (unsigned i = 0; i < mData.size(); ++i)
377  {
378  DATA_PTR data = boost::dynamic_pointer_cast<DATA_TYPE>(this->getData(mData[i].first));
379  if (!data)
380  continue;
381  DataViewProperties properties = mData[i].second;
382  if (!properties.containsAnyFlagsIn(requiredProperties))
383  continue;
384  retval.push_back(data);
385  }
386  return retval;
387 }
388 
389 std::vector<ImagePtr> ViewGroupData::getImages(DataViewProperties properties) const
390 {
391  return this->getDataOfType<Image>(properties);
392 }
393 
394 std::vector<MeshPtr> ViewGroupData::getMeshes(DataViewProperties properties) const
395 {
396  return this->getDataOfType<Mesh>(properties);
397 }
398 
400 {
401  return mOptions;
402 }
403 
405 {
406  mOptions = options;
407  emit optionsChanged();
408 }
409 
411 {
412  mGlobal2DZoom = val;
413 }
414 
416 {
417  return mGroup2DZoom;
418 }
420 {
421  return mGlobal2DZoom;
422 }
423 
424 void ViewGroupData::addXml(QDomNode& dataNode)
425 {
426  XMLNodeAdder base(dataNode);
427 
428  for (unsigned i = 0; i < mData.size(); ++i)
429  {
430  QDomElement elem;
431  elem = base.addTextToElement("data", mData[i].first);
432  mData[i].second.addXml(elem);
433  }
434 
435  base.addObjectToElement("camera3D", this->getCamera3D());
436  base.addTextToElement("slicesPlanes3D", mSliceDefinitions.toString());
437 }
438 
439 void ViewGroupData::parseXml(QDomNode dataNode)
440 {
441  XMLNodeParser base(dataNode);
442 
443  QString sliceText = base.parseTextFromElement("slicesPlanes3D");
444  mSliceDefinitions = PlaneTypeCollection::fromString(sliceText, mSliceDefinitions);
445 
446  std::vector<QDomElement> dataElems = base.getDuplicateElements("data");
447  for (unsigned i=0; i<dataElems.size(); ++i)
448  {
449  QDomElement elem = dataElems[i];
450  QString uid = elem.text();
452  properties.parseXml(elem);
453 
454  this->addData(uid);
455  this->setProperties(uid, properties);
456  }
457 
458  base.parseObjectFromElement("camera3D", this->getCamera3D());
459 }
460 
461 void ViewGroupData::setRegistrationMode(REGISTRATION_STATUS mode)
462 {
463  ViewGroupData::Options options = this->getOptions();
464 
465  options.mShowLandmarks = false;
466  options.mShowPointPickerProbe = false;
467 
468  if (mode == rsIMAGE_REGISTRATED)
469  {
470  options.mShowLandmarks = true;
471  options.mShowPointPickerProbe = true;
472  }
473  if (mode == rsPATIENT_REGISTRATED)
474  {
475  options.mShowLandmarks = true;
476  options.mShowPointPickerProbe = false;
477  }
478 
479  this->setOptions(options);
480 }
481 
482 
483 } // namespace cx
int getPriority(DataPtr data)
static DataViewProperties createSlice3D()
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:56
void reportError(QString msg)
Definition: cxLogger.cpp:92
void initializeGlobal2DZoom(SyncedValuePtr val)
A mesh data set.
Definition: cxMesh.h:61
CameraDataPtr getCamera3D()
void addXml(QDomNode &dataNode)
static DataViewProperties createDefault()
boost::shared_ptr< DataMetric > DataMetricPtr
Definition: cxDataMetric.h:93
void parseXml(QDomNode dataNode)
std::vector< QDomElement > getDuplicateElements(QString name)
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
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:56
void setProperties(QString uid, DataViewProperties properties)
static DataViewProperties createSlice2D()
void addObjectToElement(QString name, T object)
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:56
static PlaneTypeCollection fromString(QString input, PlaneTypeCollection defVal=PlaneTypeCollection())
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:66
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 dataViewPropertiesChanged(QString uid)
static DataViewProperties createVolume3D()
bool dataTypeSort(const DataPtr data1, const DataPtr data2)
bool removeData(QString uid)
QString parseTextFromElement(QString name)
void setVideoSource(QString uid)
boost::shared_ptr< class CoreServices > CoreServicesPtr
Definition: cxCameraStyle.h:59
DataViewProperties removeFlagsIn(DataViewProperties rhs) const
void parseObjectFromElement(QString name, T object)
DataViewProperties addFlagsIn(DataViewProperties rhs) const
void videoSourceChanged(QString uid)
void add(PLANE_TYPE plane)
boost::shared_ptr< class SyncedValue > SyncedValuePtr
Definition: cxViewGroup.h:51
void setRegistrationMode(REGISTRATION_STATUS mode)
ViewGroupData(CoreServicesPtr services)
std::vector< DataPtr > getData(DataViewProperties properties=DataViewProperties::createFull()) const
Base class for all Data Metrics.
Definition: cxDataMetric.h:64
QString getVideoSource() const
void setOptions(Options options)
rsIMAGE_REGISTRATED