Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxInteractiveClipper.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 "cxInteractiveClipper.h"
13 
14 #include "cxSliceComputer.h"
15 #include "cxSlicePlaneClipper.h"
16 #include "cxSlicePlanes3DRep.h"
17 #include "cxSliceProxy.h"
18 #include "cxData.h"
19 #include "cxTrackingService.h"
20 #include "cxCoreServices.h"
21 #include "cxLogger.h"
22 #include "cxEnumConversion.h"
23 #include "cxPatientModelService.h"
24 
25 namespace cx
26 {
27 
29  mUseClipper(true),
30  mServices(services),
31  mUseActiveTool(true)
32 {
33 
34  // create a slice planes proxy containing all slice definitions,
35  // for use with the clipper
36  PatientModelServicePtr dm = mServices->patient();
38  mSlicePlanesProxy->addSimpleSlicePlane(ptSAGITTAL, dm);
39  mSlicePlanesProxy->addSimpleSlicePlane(ptCORONAL, dm);
40  mSlicePlanesProxy->addSimpleSlicePlane(ptAXIAL, dm);
41  mSlicePlanesProxy->addSimpleSlicePlane(ptANYPLANE, dm);
42  mSlicePlanesProxy->addSimpleSlicePlane(ptSIDEPLANE, dm);
43  mSlicePlanesProxy->addSimpleSlicePlane(ptRADIALPLANE, dm);
44  mSlicePlanesProxy->addSimpleSlicePlane(ptTOOLSIDEPLANE, dm);
45 
47 
48  connect(mSlicePlaneClipper.get(), SIGNAL(slicePlaneChanged()), this, SLOT(changedSlot()));
49  connect(this, SIGNAL(changed()), this, SLOT(changedSlot()));
50  connect(mServices->tracking().get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(activeToolChangedSlot()));
51 
52  this->activeToolChangedSlot();
53  this->changedSlot();
54 }
55 
56 void InteractiveClipper::addXml(QDomNode& dataNode)
57 {
58  QDomElement elem = dataNode.toElement();
59 
60  QString plane = enum2string<PLANE_TYPE>(this->getSlicePlane());
61 
62  elem.setAttribute("plane", plane);
63  elem.setAttribute("invert", this->getInvertPlane());
64  elem.setAttribute("uids", this->getDataUids());
65  }
66 
67 void InteractiveClipper::parseXml(QDomNode dataNode)
68 {
69  QDomElement elem = dataNode.toElement();
70 
71  QString existingPlane = enum2string<PLANE_TYPE>(this->getSlicePlane());
72  PLANE_TYPE newPlane = string2enum<PLANE_TYPE>(elem.attribute("plane", existingPlane));
73 
74  this->setSlicePlane(newPlane);
75  this->invertPlane(elem.attribute("invert", QString::number(this->getInvertPlane())).toInt());
76  this->setDataUids(elem.attribute("uids", this->getDataUids()));
77 }
78 
79 QString InteractiveClipper::getDataUids()
80 {
81  QStringList dataUids;
82  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
83  for (; iter != mDatas.end(); ++iter)
84  {
85  dataUids << iter->first;
86  }
87  return dataUids.join(" ");
88 }
89 
90 void InteractiveClipper::setDataUids(QString uids)
91 {
92  QStringList dataUids = uids.split(" ");
93  for(int i = 0; i < dataUids.size(); ++i)
94  {
95  DataPtr data = mServices->patient()->getData(dataUids.at(i));
96  this->addData(data);
97  }
98 }
99 
100 void InteractiveClipper::setSlicePlane(PLANE_TYPE plane)
101 {
102  if (mSlicePlaneClipper->getSlicer() && mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType() == plane)
103  return;
104 
105  if (mSlicePlanesProxy->getData().count(plane))
106  {
107  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[plane].mSliceProxy);
108  emit changed();
109  }
110 }
111 
113 {
114  if (!mData)
115  return;
116 
117  mData->addPersistentClipPlane(mSlicePlaneClipper->getClipPlaneCopy());
118 }
120 {
121  if (!mData)
122  return;
123  mData->clearPersistentClipPlanes();
124 }
125 
127 {
128  if (!mSlicePlaneClipper->getSlicer())
129  return ptCOUNT;
130  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
131 }
132 
134 {
135  return mUseClipper;
136 }
138 {
139  return mSlicePlaneClipper->getInvertPlane();
140 }
142 {
143  mUseClipper = on;
144  this->updateClipPlanesInData();
145 }
147 {
148  mSlicePlaneClipper->setInvertPlane(on);
149  emit changed();
150 }
151 
153 {
154  if (!mSlicePlaneClipper->getSlicer())
155  return ptCOUNT;
156  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
157 }
158 
160 {
161  return mData;
162 }
163 
165 {
166  if (mData)
167  mData->setInteractiveClipPlane(vtkPlanePtr());
168  mData = data;
169  emit changed();
170 }
171 
173 {
174  if(!data)
175  return;
176  mDatas[data->getUid()] = data;
177  this->updateClipPlanesInData();
178 }
179 
181 {
182  if(!data)
183  return;
184  std::map<QString, DataPtr>::iterator iter = mDatas.find(data->getUid());
185  if(iter != mDatas.end())
186  {
187  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
188  mDatas.erase(iter);
189  }
190  this->updateClipPlanesInData();
191 }
192 
194 {
195  if(!data)
196  return false;
197  return mDatas.count(data->getUid());
198 }
199 
201 {
202  if (mUseClipper)
204  else
206 
207  emit changed();
208 }
209 
210 std::map<QString, DataPtr> InteractiveClipper::getDatas()
211 {
212  return mDatas;
213 }
214 
216 {
217  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
218  for(; iter != mDatas.end(); ++iter)
219  iter->second->addInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
220 }
221 
223 {
224  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
225  for(; iter != mDatas.end(); ++iter)
226  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
227 }
228 
229 void InteractiveClipper::changedSlot()
230 {
231  if (!mData)
232  return;
233 
234  if (mUseClipper)
235  {
236  PLANE_TYPE currentPlane = this->getPlaneType();
237 
238  std::vector<PLANE_TYPE> planes = this->getAvailableSlicePlanes();
239 
240  if (!std::count(planes.begin(), planes.end(), currentPlane)) //if (this->getPlaneType()==ptCOUNT)
241  {
242  if (planes.empty()) // no slices: remove clipping
243  {
244  currentPlane = ptCOUNT;
245  }
246  else
247  {
248  currentPlane = planes.front();
249  }
250  }
251 
252  // reset plane anyway. It might be the same planeType but a different sliceProxy.
253  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[currentPlane].mSliceProxy);
254  mData->setInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
255  }
256  else
257  {
258  mData->setInteractiveClipPlane(vtkPlanePtr());
259  }
260 
261 }
262 
263 std::vector<PLANE_TYPE> InteractiveClipper::getAvailableSlicePlanes() const
264 {
265  std::vector<PLANE_TYPE> retval;
267  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
268  {
269  retval.push_back(iter->first);
270  }
271  return retval;
272 }
273 
274 void InteractiveClipper::activeToolChangedSlot()
275 {
276  ToolPtr activeTool = mServices->tracking()->getActiveTool();
277 
278  if(mUseActiveTool)
279  this->setTool(activeTool);
280 }
281 
283 {
285  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
286  {
287  iter->second.mSliceProxy->setTool(tool);
288  }
289 }
290 
292 {
293  mUseActiveTool = on;
294 }
295 
296 } // namespace cx
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:39
SlicePlaneClipperPtr mSlicePlaneClipper
boost::shared_ptr< class SlicePlanesProxy > SlicePlanesProxyPtr
std::vector< PLANE_TYPE > getAvailableSlicePlanes() const
InteractiveClipper(CoreServicesPtr services)
std::map< PLANE_TYPE, DataType > DataMap
ptAXIAL
a slice seen from the top of the patient
Definition: cxDefinitions.h:39
std::map< QString, DataPtr > getDatas()
boost::shared_ptr< class Data > DataPtr
void saveClipPlaneToVolume()
save the current clip to image
ptSAGITTAL
a slice seen from the side of the patient
Definition: cxDefinitions.h:39
ptTOOLSIDEPLANE
z-rotated 90* relative to anyplane like side plane, but always kept oriented like the plane defined b...
Definition: cxDefinitions.h:39
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
void parseXml(QDomNode dataNode)
std::map< QString, DataPtr > mDatas
Helper class for managing a set of slice planes.
SlicePlanesProxyPtr mSlicePlanesProxy
ptRADIALPLANE
y-rotated 90* relative to anyplane (bird&#39;s view)
Definition: cxDefinitions.h:39
static SlicePlaneClipperPtr New()
boost::shared_ptr< class CoreServices > CoreServicesPtr
Definition: cxCameraStyle.h:37
void setSlicePlane(PLANE_TYPE plane)
ptANYPLANE
a plane aligned with the tool base plane
Definition: cxDefinitions.h:39
vtkSmartPointer< class vtkPlane > vtkPlanePtr
void clearClipPlanesInVolume()
clear all saved clips in the image.
ptSIDEPLANE
z-rotated 90* relative to anyplane (dual anyplane)
Definition: cxDefinitions.h:39
void addXml(QDomNode &dataNode)
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr