CustusX  15.3.4-beta
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  mBackend(backend),
217  mCamera3D(CameraData::create())
218 {
219  if(mBackend)
220  connect(mBackend->patientModelService.get(), SIGNAL(dataAddedOrRemoved()), this, SLOT(dataAddedOrRemovedInManager()));
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 void ViewGroupData::dataAddedOrRemovedInManager()
231 {
232  for (unsigned i = 0; i < mData.size(); )
233  {
234  if (!mBackend->patientModelService->getData(mData[i].first))
235  this->removeData(mData[i].first);
236  else
237  ++i;
238  }
239 }
240 
242 {
243  emit initialized();
244 }
245 
246 void ViewGroupData::addData(QString uid)
247 {
248  DataViewProperties properties = this->getProperties(uid);
249  properties = properties.addFlagsIn(DataViewProperties::createDefault());
250  this->setProperties(uid, properties);
251 }
252 
254 {
255  if (this->contains(uid))
256  return;
257 
259  DataAndViewProperties item(uid, properties);
260 
261  for (int i=int(mData.size())-1; i>=0; --i)
262  {
263  if (!dataTypeSort(this->getData(uid), this->getData(mData[i].first)))
264  {
265  mData.insert(mData.begin()+i+1, item);
266  break;
267  }
268  }
269  if (!this->contains(uid))
270  mData.insert(mData.begin(), item);
271  emit dataViewPropertiesChanged(uid);
272 }
273 
275 {
276  if (this->contains(uid))
277  return std::find_if(mData.begin(), mData.end(), data_equals(uid))->second;
278  return DataViewProperties();
279 }
280 
282 {
283  if (uid.isEmpty())
284  return;
285 
286  if (properties.empty())
287  {
288  this->removeData(uid);
289  return;
290  }
291 
292  if (!this->contains(uid))
293  {
294  DataAndViewProperties item(uid, properties);
295  mData.push_back(item);
296  }
297  else
298  {
299  std::find_if(mData.begin(), mData.end(), data_equals(uid))->second = properties;
300  }
301 
302  emit dataViewPropertiesChanged(uid);
303 }
304 
305 bool ViewGroupData::contains(QString uid) const
306 {
307  return std::count_if(mData.begin(), mData.end(), data_equals(uid));
308 }
309 
310 bool ViewGroupData::removeData(QString uid)
311 {
312  if (!this->contains(uid))
313  return false;
314  mData.erase(std::find_if(mData.begin(), mData.end(), data_equals(uid)));
315  emit dataViewPropertiesChanged(uid);
316  return true;
317 }
318 
320 {
321  while (!mData.empty())
322  this->removeData(mData.front().first);
323  this->setVideoSource("active");
324 
325  mGroup2DZoom->set(1.0);
326  mGlobal2DZoom->set(1.0);
327 }
328 
329 DataPtr ViewGroupData::getData(QString uid) const
330 {
331  DataPtr data = mBackend->patientModelService->getData(uid);
332  if (!data)
333  {
334  reportError("Couldn't find the data: [" + uid + "] in the datamanager.");
335  return DataPtr();
336  }
337  return data;
338 }
339 
341 {
342  if (mVideoSource==uid)
343  return;
344  mVideoSource = uid;
345  emit videoSourceChanged(mVideoSource);
346 }
347 
349 {
350  return mVideoSource;
351 }
352 
353 std::vector<DataPtr> ViewGroupData::getData(DataViewProperties properties) const
354 {
355  return this->getDataOfType<Data>(properties);
356 }
357 
358 template<class DATA_TYPE>
359 std::vector<boost::shared_ptr<DATA_TYPE> > ViewGroupData::getDataOfType(DataViewProperties requiredProperties) const
360 {
361  typedef boost::shared_ptr<DATA_TYPE> DATA_PTR;
362  std::vector<DATA_PTR> retval;
363  for (unsigned i = 0; i < mData.size(); ++i)
364  {
365  DATA_PTR data = boost::dynamic_pointer_cast<DATA_TYPE>(this->getData(mData[i].first));
366  if (!data)
367  continue;
368  DataViewProperties properties = mData[i].second;
369  if (!properties.containsAnyFlagsIn(requiredProperties))
370  continue;
371  retval.push_back(data);
372  }
373  return retval;
374 }
375 
376 std::vector<ImagePtr> ViewGroupData::getImages(DataViewProperties properties) const
377 {
378  return this->getDataOfType<Image>(properties);
379 }
380 
381 std::vector<MeshPtr> ViewGroupData::getMeshes(DataViewProperties properties) const
382 {
383  return this->getDataOfType<Mesh>(properties);
384 }
385 
387 {
388  return mOptions;
389 }
390 
392 {
393  mOptions = options;
394  emit optionsChanged();
395 }
396 
398 {
399  mGlobal2DZoom = val;
400 }
401 
403 {
404  return mGroup2DZoom;
405 }
407 {
408  return mGlobal2DZoom;
409 }
410 
411 void ViewGroupData::addXml(QDomNode& dataNode)
412 {
413  XMLNodeAdder base(dataNode);
414 
415  for (unsigned i = 0; i < mData.size(); ++i)
416  {
417  QDomElement elem;
418  elem = base.addTextToElement("data", mData[i].first);
419  mData[i].second.addXml(elem);
420  }
421 
422  base.addObjectToElement("camera3D", this->getCamera3D());
423  base.addTextToElement("slicesPlanes3D", mSliceDefinitions.toString());
424 }
425 
426 void ViewGroupData::parseXml(QDomNode dataNode)
427 {
428  XMLNodeParser base(dataNode);
429 
430  QString sliceText = base.parseTextFromElement("slicesPlanes3D");
431  mSliceDefinitions = PlaneTypeCollection::fromString(sliceText, mSliceDefinitions);
432 
433  std::vector<QDomElement> dataElems = base.getDuplicateElements("data");
434  for (unsigned i=0; i<dataElems.size(); ++i)
435  {
436  QDomElement elem = dataElems[i];
437  QString uid = elem.text();
438 // DataPtr data = mBackend->patientModelService->getData(uid);
439 // if (!data)
440 // {
441 // reportError("Couldn't find the data: [" + uid + "] in the datamanager.");
442 // continue;
443 // }
445  properties.parseXml(elem);
446 
447  this->addData(uid);
448  this->setProperties(uid, properties);
449  }
450 
451  base.parseObjectFromElement("camera3D", this->getCamera3D());
452 }
453 
454 void ViewGroupData::setRegistrationMode(REGISTRATION_STATUS mode)
455 {
456  ViewGroupData::Options options = this->getOptions();
457 
458  options.mShowLandmarks = false;
459  options.mShowPointPickerProbe = false;
460 
461  if (mode == rsIMAGE_REGISTRATED)
462  {
463  options.mShowLandmarks = true;
464  options.mShowPointPickerProbe = true;
465  }
466  if (mode == rsPATIENT_REGISTRATED)
467  {
468  options.mShowLandmarks = true;
469  options.mShowPointPickerProbe = false;
470  }
471 
472  this->setOptions(options);
473 }
474 
475 
476 } // namespace cx
int getPriority(DataPtr data)
static DataViewProperties createSlice3D()
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:54
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:54
void setProperties(QString uid, DataViewProperties properties)
static DataViewProperties createSlice2D()
void addObjectToElement(QString name, T object)
static DataViewProperties create3D()
ViewGroupData(CoreServicesPtr backend)
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:54
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:64
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)
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