Fraxinus  17.12
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) 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 "cxInteractiveClipper.h"
34 
35 #include "cxSliceComputer.h"
36 #include "cxSlicePlaneClipper.h"
37 #include "cxSlicePlanes3DRep.h"
38 #include "cxSliceProxy.h"
39 #include "cxData.h"
40 #include "cxTrackingService.h"
41 #include "cxCoreServices.h"
42 #include "cxLogger.h"
43 #include "cxEnumConverter.h"
44 #include "cxPatientModelService.h"
45 
46 namespace cx
47 {
48 
50  mUseClipper(true),
51  mServices(services),
52  mUseActiveTool(true)
53 {
54 
55  // create a slice planes proxy containing all slice definitions,
56  // for use with the clipper
57  PatientModelServicePtr dm = mServices->patient();
59  mSlicePlanesProxy->addSimpleSlicePlane(ptSAGITTAL, dm);
60  mSlicePlanesProxy->addSimpleSlicePlane(ptCORONAL, dm);
61  mSlicePlanesProxy->addSimpleSlicePlane(ptAXIAL, dm);
62  mSlicePlanesProxy->addSimpleSlicePlane(ptANYPLANE, dm);
63  mSlicePlanesProxy->addSimpleSlicePlane(ptSIDEPLANE, dm);
64  mSlicePlanesProxy->addSimpleSlicePlane(ptRADIALPLANE, dm);
65  mSlicePlanesProxy->addSimpleSlicePlane(ptTOOLSIDEPLANE, dm);
66 
68 
69  connect(mSlicePlaneClipper.get(), SIGNAL(slicePlaneChanged()), this, SLOT(changedSlot()));
70  connect(this, SIGNAL(changed()), this, SLOT(changedSlot()));
71  connect(mServices->tracking().get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(activeToolChangedSlot()));
72 
73  this->activeToolChangedSlot();
74  this->changedSlot();
75 }
76 
77 void InteractiveClipper::addXml(QDomNode& dataNode)
78 {
79  QDomElement elem = dataNode.toElement();
80 
81  QString plane = enum2string<PLANE_TYPE>(this->getSlicePlane());
82 
83  elem.setAttribute("plane", plane);
84  elem.setAttribute("invert", this->getInvertPlane());
85  elem.setAttribute("uids", this->getDataUids());
86  }
87 
88 void InteractiveClipper::parseXml(QDomNode dataNode)
89 {
90  QDomElement elem = dataNode.toElement();
91 
92  QString existingPlane = enum2string<PLANE_TYPE>(this->getSlicePlane());
93  PLANE_TYPE newPlane = string2enum<PLANE_TYPE>(elem.attribute("plane", existingPlane));
94 
95  this->setSlicePlane(newPlane);
96  this->invertPlane(elem.attribute("invert", QString::number(this->getInvertPlane())).toInt());
97  this->setDataUids(elem.attribute("uids", this->getDataUids()));
98 }
99 
100 QString InteractiveClipper::getDataUids()
101 {
102  QStringList dataUids;
103  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
104  for (; iter != mDatas.end(); ++iter)
105  {
106  dataUids << iter->first;
107  }
108  return dataUids.join(" ");
109 }
110 
111 void InteractiveClipper::setDataUids(QString uids)
112 {
113  QStringList dataUids = uids.split(" ");
114  for(int i = 0; i < dataUids.size(); ++i)
115  {
116  DataPtr data = mServices->patient()->getData(dataUids.at(i));
117  this->addData(data);
118  }
119 }
120 
121 void InteractiveClipper::setSlicePlane(PLANE_TYPE plane)
122 {
123  if (mSlicePlaneClipper->getSlicer() && mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType() == plane)
124  return;
125 
126  if (mSlicePlanesProxy->getData().count(plane))
127  {
128  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[plane].mSliceProxy);
129  emit changed();
130  }
131 }
132 
134 {
135  if (!mData)
136  return;
137 
138  mData->addPersistentClipPlane(mSlicePlaneClipper->getClipPlaneCopy());
139 }
141 {
142  if (!mData)
143  return;
144  mData->clearPersistentClipPlanes();
145 }
146 
148 {
149  if (!mSlicePlaneClipper->getSlicer())
150  return ptCOUNT;
151  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
152 }
153 
155 {
156  return mUseClipper;
157 }
159 {
160  return mSlicePlaneClipper->getInvertPlane();
161 }
163 {
164  mUseClipper = on;
165  this->updateClipPlanesInData();
166 }
168 {
169  mSlicePlaneClipper->setInvertPlane(on);
170  emit changed();
171 }
172 
174 {
175  if (!mSlicePlaneClipper->getSlicer())
176  return ptCOUNT;
177  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
178 }
179 
181 {
182  return mData;
183 }
184 
186 {
187  if (mData)
188  mData->setInteractiveClipPlane(vtkPlanePtr());
189  mData = data;
190  emit changed();
191 }
192 
194 {
195  if(!data)
196  return;
197  mDatas[data->getUid()] = data;
198  this->updateClipPlanesInData();
199 }
200 
202 {
203  if(!data)
204  return;
205  std::map<QString, DataPtr>::iterator iter = mDatas.find(data->getUid());
206  if(iter != mDatas.end())
207  {
208  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
209  mDatas.erase(iter);
210  }
211  this->updateClipPlanesInData();
212 }
213 
215 {
216  if(!data)
217  return false;
218  return mDatas.count(data->getUid());
219 }
220 
222 {
223  if (mUseClipper)
225  else
227 
228  emit changed();
229 }
230 
231 std::map<QString, DataPtr> InteractiveClipper::getDatas()
232 {
233  return mDatas;
234 }
235 
237 {
238  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
239  for(; iter != mDatas.end(); ++iter)
240  iter->second->addInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
241 }
242 
244 {
245  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
246  for(; iter != mDatas.end(); ++iter)
247  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
248 }
249 
250 void InteractiveClipper::changedSlot()
251 {
252  if (!mData)
253  return;
254 
255  if (mUseClipper)
256  {
257  PLANE_TYPE currentPlane = this->getPlaneType();
258 
259  std::vector<PLANE_TYPE> planes = this->getAvailableSlicePlanes();
260 
261  if (!std::count(planes.begin(), planes.end(), currentPlane)) //if (this->getPlaneType()==ptCOUNT)
262  {
263  if (planes.empty()) // no slices: remove clipping
264  {
265  currentPlane = ptCOUNT;
266  }
267  else
268  {
269  currentPlane = planes.front();
270  }
271  }
272 
273  // reset plane anyway. It might be the same planeType but a different sliceProxy.
274  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[currentPlane].mSliceProxy);
275  mData->setInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
276  }
277  else
278  {
279  mData->setInteractiveClipPlane(vtkPlanePtr());
280  }
281 
282 }
283 
284 std::vector<PLANE_TYPE> InteractiveClipper::getAvailableSlicePlanes() const
285 {
286  std::vector<PLANE_TYPE> retval;
288  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
289  {
290  retval.push_back(iter->first);
291  }
292  return retval;
293 }
294 
295 void InteractiveClipper::activeToolChangedSlot()
296 {
297  ToolPtr activeTool = mServices->tracking()->getActiveTool();
298 
299  if(mUseActiveTool)
300  this->setTool(activeTool);
301 }
302 
304 {
306  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
307  {
308  iter->second.mSliceProxy->setTool(tool);
309  }
310 }
311 
313 {
314  mUseActiveTool = on;
315 }
316 
317 } // namespace cx
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:56
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:56
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:56
ptTOOLSIDEPLANE
z-rotated 90* relative to anyplane like side plane, but always kept oriented like the plane defined b...
Definition: cxDefinitions.h:56
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:56
static SlicePlaneClipperPtr New()
boost::shared_ptr< class CoreServices > CoreServicesPtr
Definition: cxCameraStyle.h:59
void setSlicePlane(PLANE_TYPE plane)
ptANYPLANE
a plane aligned with the tool base plane
Definition: cxDefinitions.h:56
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:56
void addXml(QDomNode &dataNode)
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr