NorMIT-nav  16.5
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
67 
68  connect(mSlicePlaneClipper.get(), SIGNAL(slicePlaneChanged()), this, SLOT(changedSlot()));
69  connect(this, SIGNAL(changed()), this, SLOT(changedSlot()));
70  connect(mServices->tracking().get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(activeToolChangedSlot()));
71 
72  this->activeToolChangedSlot();
73  this->changedSlot();
74 }
75 
76 void InteractiveClipper::addXml(QDomNode& dataNode)
77 {
78  QDomElement elem = dataNode.toElement();
79 
80  QString plane = enum2string<PLANE_TYPE>(this->getSlicePlane());
81 
82  elem.setAttribute("plane", plane);
83  elem.setAttribute("invert", this->getInvertPlane());
84  elem.setAttribute("uids", this->getDataUids());
85  }
86 
87 void InteractiveClipper::parseXml(QDomNode dataNode)
88 {
89  QDomElement elem = dataNode.toElement();
90 
91  QString existingPlane = enum2string<PLANE_TYPE>(this->getSlicePlane());
92  PLANE_TYPE newPlane = string2enum<PLANE_TYPE>(elem.attribute("plane", existingPlane));
93 
94  this->setSlicePlane(newPlane);
95  this->invertPlane(elem.attribute("invert", QString::number(this->getInvertPlane())).toInt());
96  this->setDataUids(elem.attribute("uids", this->getDataUids()));
97 }
98 
99 QString InteractiveClipper::getDataUids()
100 {
101  QStringList dataUids;
102  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
103  for (; iter != mDatas.end(); ++iter)
104  {
105  dataUids << iter->first;
106  }
107  return dataUids.join(" ");
108 }
109 
110 void InteractiveClipper::setDataUids(QString uids)
111 {
112  QStringList dataUids = uids.split(" ");
113  for(int i = 0; i < dataUids.size(); ++i)
114  {
115  DataPtr data = mServices->patient()->getData(dataUids.at(i));
116  this->addData(data);
117  }
118 }
119 
120 void InteractiveClipper::setSlicePlane(PLANE_TYPE plane)
121 {
122  if (mSlicePlaneClipper->getSlicer() && mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType() == plane)
123  return;
124 
125  if (mSlicePlanesProxy->getData().count(plane))
126  {
127  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[plane].mSliceProxy);
128  emit changed();
129  }
130 }
131 
133 {
134  if (!mData)
135  return;
136 
137  mData->addPersistentClipPlane(mSlicePlaneClipper->getClipPlaneCopy());
138 }
140 {
141  if (!mData)
142  return;
143  mData->clearPersistentClipPlanes();
144 }
145 
147 {
148  if (!mSlicePlaneClipper->getSlicer())
149  return ptCOUNT;
150  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
151 }
152 
154 {
155  return mUseClipper;
156 }
158 {
159  return mSlicePlaneClipper->getInvertPlane();
160 }
162 {
163  mUseClipper = on;
164  this->updateClipPlanesInData();
165 }
167 {
168  mSlicePlaneClipper->setInvertPlane(on);
169  emit changed();
170 }
171 
173 {
174  if (!mSlicePlaneClipper->getSlicer())
175  return ptCOUNT;
176  return mSlicePlaneClipper->getSlicer()->getComputer().getPlaneType();
177 }
178 
180 {
181  return mData;
182 }
183 
185 {
186  if (mData)
187  mData->setInteractiveClipPlane(vtkPlanePtr());
188  mData = data;
189  emit changed();
190 }
191 
193 {
194  if(!data)
195  return;
196  mDatas[data->getUid()] = data;
197  this->updateClipPlanesInData();
198 }
199 
201 {
202  if(!data)
203  return;
204  std::map<QString, DataPtr>::iterator iter = mDatas.find(data->getUid());
205  if(iter != mDatas.end())
206  {
207  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
208  mDatas.erase(iter);
209  }
210  this->updateClipPlanesInData();
211 }
212 
214 {
215  if(!data)
216  return false;
217  return mDatas.count(data->getUid());
218 }
219 
221 {
222  if (mUseClipper)
224  else
226 
227  emit changed();
228 }
229 
230 std::map<QString, DataPtr> InteractiveClipper::getDatas()
231 {
232  return mDatas;
233 }
234 
236 {
237  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
238  for(; iter != mDatas.end(); ++iter)
239  iter->second->addInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
240 }
241 
243 {
244  std::map<QString, DataPtr>::iterator iter = mDatas.begin();
245  for(; iter != mDatas.end(); ++iter)
246  iter->second->removeInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
247 }
248 
249 void InteractiveClipper::changedSlot()
250 {
251  if (!mData)
252  return;
253 
254  if (mUseClipper)
255  {
256  PLANE_TYPE currentPlane = this->getPlaneType();
257 
258  std::vector<PLANE_TYPE> planes = this->getAvailableSlicePlanes();
259 
260  if (!std::count(planes.begin(), planes.end(), currentPlane)) //if (this->getPlaneType()==ptCOUNT)
261  {
262  if (planes.empty()) // no slices: remove clipping
263  {
264  currentPlane = ptCOUNT;
265  }
266  else
267  {
268  currentPlane = planes.front();
269  }
270  }
271 
272  // reset plane anyway. It might be the same planeType but a different sliceProxy.
273  mSlicePlaneClipper->setSlicer(mSlicePlanesProxy->getData()[currentPlane].mSliceProxy);
274  mData->setInteractiveClipPlane(mSlicePlaneClipper->getClipPlane());
275  }
276  else
277  {
278  mData->setInteractiveClipPlane(vtkPlanePtr());
279  }
280 
281 }
282 
283 std::vector<PLANE_TYPE> InteractiveClipper::getAvailableSlicePlanes() const
284 {
285  std::vector<PLANE_TYPE> retval;
287  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
288  {
289  retval.push_back(iter->first);
290  }
291  return retval;
292 }
293 
294 void InteractiveClipper::activeToolChangedSlot()
295 {
296  ToolPtr activeTool = mServices->tracking()->getActiveTool();
297 
298  if(mUseActiveTool)
299  this->setTool(activeTool);
300 }
301 
303 {
305  for (SlicePlanesProxy::DataMap::iterator iter = data.begin(); iter != data.end(); ++iter)
306  {
307  iter->second.mSliceProxy->setTool(tool);
308  }
309 }
310 
312 {
313  mUseActiveTool = on;
314 }
315 
316 } // 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
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'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)
boost::shared_ptr< class Tool > ToolPtr