Fraxinus  17.12
An IGT application
cxGraphicalBox.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 "cxGraphicalBox.h"
34 
35 #include "cxView.h"
36 
37 #include <vector>
38 #include <vtkTransform.h>
39 #include <vtkAbstractVolumeMapper.h>
40 #include <vtkVolumeMapper.h>
41 #include <vtkRenderWindow.h>
42 #include <vtkRenderer.h>
43 #include <vtkImageData.h>
44 #include <vtkCommand.h>
45 #include <vtkBoxWidget2.h>
46 #include <vtkBoxWidget.h>
47 #include "cxTypeConversions.h"
48 #include "cxBoundingBox3D.h"
49 #include "cxImage.h"
50 #include "cxTransform3D.h"
51 #include "cxVolumetricRep.h"
52 
53 #include "cxActiveImageProxy.h"
54 #include "cxActiveData.h"
55 #include "cxLogger.h"
56 
57 namespace cx
58 {
59 
60 class GraphicalBoxCallback: public vtkCommand
61 {
62 public:
64  {
65  }
67  {
68  return new GraphicalBoxCallback;
69  }
70  void SetCropper(GraphicalBox* cropper)
71  {
72  mCropper = cropper;
73  }
74  virtual void Execute(vtkObject* caller, unsigned long, void*)
75  {
76  mCropper->updateBoxFromWidget();
77  }
79 };
80 
81 class GraphicalBoxEnableCallback: public vtkCommand
82 {
83 public:
84  GraphicalBoxEnableCallback() : mCropper(NULL), mValue(false)
85  {
86  }
88  {
89  return new GraphicalBoxEnableCallback;
90  }
91  void SetCropper(bool val, GraphicalBox* cropper)
92  {
93  mValue = val;
94  mCropper = cropper;
95  }
96  virtual void Execute(vtkObject* caller, unsigned long, void*)
97  {
98  mCropper->setVisible(mValue);
99  }
100  bool mValue;
102 };
103 
104 //---------------------------------------------------------
105 //---------------------------------------------------------
106 //---------------------------------------------------------
107 
108 
110 {
111  mBox = DoubleBoundingBox3D::zero();
112  mMaxBox = DoubleBoundingBox3D::zero();
113  mInteractive = true;
114  mVisible = true;
115  m_rMd = Transform3D::Identity();
116 }
117 
119 {
120  if (mBoxWidget)
121  {
122  mBoxWidget->SetInteractor(NULL);
123  }
124 }
125 
127 {
128  mRenderWindow = renderWindow;
129  this->updateBoxWidgetInteractor();
130 }
131 
135 {
136  return mBox;
137 }
138 
140 {
141  if (similar(bb_d, mBox))
142  return;
143 
144  mBox = bb_d;
145  this->updateWidgetFromBox();
146  emit changed();
147 }
148 
150 {
151  if (similar(rMd, m_rMd))
152  return;
153 
154  m_rMd = rMd;
155  this->updateWidgetFromBox();
156  emit changed();
157 }
158 
160 {
161  if (mVisible==on)
162  return;
163  mVisible = on;
164  this->updateWidgetFromBox();
165  emit changed();
166 }
167 
169 {
170  return mVisible;
171 }
172 
174 {
175  if (mInteractive==on)
176  return;
177  mInteractive = on;
178  this->updateWidgetFromBox();
179  emit changed();
180 }
181 
183 {
184  return mInteractive;
185 }
186 
191 {
192  return mMaxBox;
193 }
194 
195 void GraphicalBox::updateWidgetFromBox()
196 {
197  this->updateBoxWidgetInteractor();
198  this->setBoxWidgetSize(mBox, m_rMd);
199 }
200 
201 void GraphicalBox::updateBoxFromWidget()
202 {
203  DoubleBoundingBox3D bb_d = this->getCurrentBoxWidgetSize();
204  mBox = bb_d;
205  emit changed();
206 }
207 
208 void GraphicalBox::initialize()
209 {
210  if (mBoxWidget) // already initialized
211  return;
212 
213  mBoxWidget = vtkBoxWidgetPtr::New();
214  mBoxWidget->RotationEnabledOff();
215 
216  double bb_hard[6] =
217  { -1, 1, -1, 1, -1, 1 };
218  mBoxWidget->PlaceWidget(bb_hard);
219 
220  mGraphicalBoxCallback = GraphicalBoxCallbackPtr::New();
221  mGraphicalBoxCallback->SetCropper(this);
222  mGraphicalBoxEnableCallback = GraphicalBoxEnableCallbackPtr::New();
223  mGraphicalBoxEnableCallback->SetCropper(true, this);
224  mGraphicalBoxDisableCallback = GraphicalBoxEnableCallbackPtr::New();
225  mGraphicalBoxDisableCallback->SetCropper(false, this);
226 
227  mBoxWidget->SetInteractor(mRenderWindow->GetInteractor());
228 
229  mBoxWidget->SetEnabled(mVisible);
230 }
231 
232 void GraphicalBox::updateBoxWidgetInteractor()
233 {
234  if (!mRenderWindow)
235  return;
236 
237  this->initialize();
238 
239  mBoxWidget->SetInteractor(mRenderWindow->GetInteractor());
240 
241  if (this->getInteractive())
242  {
243  mBoxWidget->AddObserver(vtkCommand::InteractionEvent, mGraphicalBoxCallback);
244  mBoxWidget->AddObserver(vtkCommand::EnableEvent, mGraphicalBoxEnableCallback);
245  mBoxWidget->AddObserver(vtkCommand::DisableEvent, mGraphicalBoxDisableCallback);
246  }
247 
248  if (!this->getInteractive())
249  {
250  mBoxWidget->RemoveObserver(vtkCommand::InteractionEvent);
251  mBoxWidget->RemoveObserver(vtkCommand::EnableEvent);
252  mBoxWidget->RemoveObserver(vtkCommand::DisableEvent);
253  }
254 
255  mBoxWidget->SetScalingEnabled(mInteractive);
256  mBoxWidget->SetTranslationEnabled(mInteractive);
257 
258  mBoxWidget->SetOutlineFaceWires(mInteractive);
259  mBoxWidget->SetOutlineCursorWires(mInteractive);
260  if (mInteractive)
261  mBoxWidget->HandlesOn();
262  else
263  mBoxWidget->HandlesOff();
264 
265  mBoxWidget->SetEnabled(mVisible);
266 }
267 
270 void GraphicalBox::setBoxWidgetSize(const DoubleBoundingBox3D& bb_d, Transform3D rMd)
271 {
272  if (!mBoxWidget)
273  return;
274 
275  double bb_hard[6] = { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
276  DoubleBoundingBox3D bb_unit(bb_hard);
277  Transform3D M = createTransformNormalize(bb_unit, bb_d);
278  M = rMd * M;
279 
280  if (similar(M, this->getBoxTransform()))
281  return;
282 
283  this->setBoxTransform(M);
284 }
285 
286 Transform3D GraphicalBox::getBoxTransform()
287 {
288  vtkTransformPtr transform = vtkTransformPtr::New();
289  mBoxWidget->GetTransform(transform);
290  Transform3D M(transform->GetMatrix());
291  return M;
292 }
293 void GraphicalBox::setBoxTransform(const Transform3D& M)
294 {
295  vtkTransformPtr transform = vtkTransformPtr::New();
296  transform->SetMatrix(M.getVtkMatrix());
297  mBoxWidget->SetTransform(transform);
298 }
299 
302 DoubleBoundingBox3D GraphicalBox::getCurrentBoxWidgetSize()
303 {
304  if (!mBoxWidget)
305  {
306  return DoubleBoundingBox3D::zero();
307  }
308 
309  double bb_hard[6] =
310  { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
311  DoubleBoundingBox3D bb_unit(bb_hard);
312 
313  Transform3D M = this->getBoxTransform();
314  M = m_rMd.inv() * M;
315  DoubleBoundingBox3D bb_new_d = cx::transform(M, bb_unit);
316 
317  return bb_new_d;
318 }
319 
320 
321 
322 } // namespace cx
virtual void Execute(vtkObject *caller, unsigned long, void *)
void SetCropper(bool val, GraphicalBox *cropper)
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
bool getInteractive() const
void SetCropper(GraphicalBox *cropper)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
vtkSmartPointer< class vtkRenderWindow > vtkRenderWindowPtr
void setBoundingBox(const DoubleBoundingBox3D &bb_d)
set BB in d space
virtual void Execute(vtkObject *caller, unsigned long, void *)
vtkSmartPointer< class vtkTransform > vtkTransformPtr
Definition: cxMathBase.h:62
Transform3D createTransformNormalize(const DoubleBoundingBox3D &in, const DoubleBoundingBox3D &out)
void setPosition(const Transform3D &rMd)
set BB position
DoubleBoundingBox3D getBoundingBox()
get BB in data space
static DoubleBoundingBox3D zero()
DoubleBoundingBox3D getMaxBoundingBox()
void setVisible(bool on)
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
void setRenderWindow(vtkRenderWindowPtr renderWindow)
adds an interactive box widget to the view. Press &#39;I&#39; to show
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
void setInteractive(bool on)
bool getVisible() const
static GraphicalBoxCallback * New()
static GraphicalBoxEnableCallback * New()
Namespace for all CustusX production code.