CustusX  2023.01.05-dev+develop.0da12
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) 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 "cxGraphicalBox.h"
13 
14 #include "cxView.h"
15 
16 #include <vector>
17 #include <vtkTransform.h>
18 #include <vtkAbstractVolumeMapper.h>
19 #include <vtkVolumeMapper.h>
20 #include <vtkRenderWindow.h>
21 #include <vtkRenderer.h>
22 #include <vtkImageData.h>
23 #include <vtkCommand.h>
24 #include <vtkBoxWidget2.h>
25 #include <vtkBoxWidget.h>
26 #include "cxTypeConversions.h"
27 #include "cxBoundingBox3D.h"
28 #include "cxImage.h"
29 #include "cxTransform3D.h"
30 #include "cxVolumetricRep.h"
31 
32 #include "cxActiveImageProxy.h"
33 #include "cxActiveData.h"
34 #include "cxLogger.h"
35 
36 namespace cx
37 {
38 
39 class GraphicalBoxCallback: public vtkCommand
40 {
41 public:
43  {
44  }
46  {
47  return new GraphicalBoxCallback;
48  }
49  void SetCropper(GraphicalBox* cropper)
50  {
51  mCropper = cropper;
52  }
53  virtual void Execute(vtkObject* caller, unsigned long, void*)
54  {
55  mCropper->updateBoxFromWidget();
56  }
58 };
59 
60 class GraphicalBoxEnableCallback: public vtkCommand
61 {
62 public:
63  GraphicalBoxEnableCallback() : mCropper(NULL), mValue(false)
64  {
65  }
67  {
68  return new GraphicalBoxEnableCallback;
69  }
70  void SetCropper(bool val, GraphicalBox* cropper)
71  {
72  mValue = val;
73  mCropper = cropper;
74  }
75  virtual void Execute(vtkObject* caller, unsigned long, void*)
76  {
77  mCropper->setVisible(mValue);
78  }
79  bool mValue;
81 };
82 
83 //---------------------------------------------------------
84 //---------------------------------------------------------
85 //---------------------------------------------------------
86 
87 
89 {
91  mMaxBox = DoubleBoundingBox3D::zero();
92  mInteractive = true;
93  mVisible = true;
94  m_rMd = Transform3D::Identity();
95 }
96 
98 {
99  if (mBoxWidget)
100  {
101  mBoxWidget->SetInteractor(NULL);
102  }
103 }
104 
106 {
107  mRenderWindow = renderWindow;
108  this->updateBoxWidgetInteractor();
109 }
110 
114 {
115  return mBox;
116 }
117 
119 {
120  if (similar(bb_d, mBox))
121  return;
122 
123  mBox = bb_d;
124  this->updateWidgetFromBox();
125  emit changed();
126 }
127 
129 {
130  if (similar(rMd, m_rMd))
131  return;
132 
133  m_rMd = rMd;
134  this->updateWidgetFromBox();
135  emit changed();
136 }
137 
139 {
140  if (mVisible==on)
141  return;
142  mVisible = on;
143  this->updateWidgetFromBox();
144  emit changed();
145 }
146 
148 {
149  return mVisible;
150 }
151 
153 {
154  if (mInteractive==on)
155  return;
156  mInteractive = on;
157  this->updateWidgetFromBox();
158  emit changed();
159 }
160 
162 {
163  return mInteractive;
164 }
165 
170 {
171  return mMaxBox;
172 }
173 
174 void GraphicalBox::updateWidgetFromBox()
175 {
176  this->updateBoxWidgetInteractor();
177  this->setBoxWidgetSize(mBox, m_rMd);
178 }
179 
180 void GraphicalBox::updateBoxFromWidget()
181 {
182  DoubleBoundingBox3D bb_d = this->getCurrentBoxWidgetSize();
183  mBox = bb_d;
184  emit changed();
185 }
186 
187 void GraphicalBox::initialize()
188 {
189  if (mBoxWidget) // already initialized
190  return;
191 
192  mBoxWidget = vtkBoxWidgetPtr::New();
193  mBoxWidget->RotationEnabledOff();
194 
195  double bb_hard[6] =
196  { -1, 1, -1, 1, -1, 1 };
197  mBoxWidget->PlaceWidget(bb_hard);
198 
199  mGraphicalBoxCallback = GraphicalBoxCallbackPtr::New();
200  mGraphicalBoxCallback->SetCropper(this);
201  mGraphicalBoxEnableCallback = GraphicalBoxEnableCallbackPtr::New();
202  mGraphicalBoxEnableCallback->SetCropper(true, this);
203  mGraphicalBoxDisableCallback = GraphicalBoxEnableCallbackPtr::New();
204  mGraphicalBoxDisableCallback->SetCropper(false, this);
205 
206  mBoxWidget->SetInteractor(mRenderWindow->GetInteractor());
207 
208  mBoxWidget->SetEnabled(mVisible);
209 }
210 
211 void GraphicalBox::updateBoxWidgetInteractor()
212 {
213  if (!mRenderWindow)
214  return;
215 
216  this->initialize();
217 
218  mBoxWidget->SetInteractor(mRenderWindow->GetInteractor());
219 
220  if (this->getInteractive())
221  {
222  mBoxWidget->AddObserver(vtkCommand::InteractionEvent, mGraphicalBoxCallback);
223  mBoxWidget->AddObserver(vtkCommand::EnableEvent, mGraphicalBoxEnableCallback);
224  mBoxWidget->AddObserver(vtkCommand::DisableEvent, mGraphicalBoxDisableCallback);
225  }
226 
227  if (!this->getInteractive())
228  {
229  mBoxWidget->RemoveObserver(vtkCommand::InteractionEvent);
230  mBoxWidget->RemoveObserver(vtkCommand::EnableEvent);
231  mBoxWidget->RemoveObserver(vtkCommand::DisableEvent);
232  }
233 
234  mBoxWidget->SetScalingEnabled(mInteractive);
235  mBoxWidget->SetTranslationEnabled(mInteractive);
236 
237  mBoxWidget->SetOutlineFaceWires(mInteractive);
238  mBoxWidget->SetOutlineCursorWires(mInteractive);
239  if (mInteractive)
240  mBoxWidget->HandlesOn();
241  else
242  mBoxWidget->HandlesOff();
243 
244  mBoxWidget->SetEnabled(mVisible);
245 }
246 
249 void GraphicalBox::setBoxWidgetSize(const DoubleBoundingBox3D& bb_d, Transform3D rMd)
250 {
251  if (!mBoxWidget)
252  return;
253 
254  double bb_hard[6] = { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
255  DoubleBoundingBox3D bb_unit(bb_hard);
256  Transform3D M = createTransformNormalize(bb_unit, bb_d);
257  M = rMd * M;
258 
259  if (similar(M, this->getBoxTransform()))
260  return;
261 
262  this->setBoxTransform(M);
263 }
264 
265 Transform3D GraphicalBox::getBoxTransform()
266 {
267  vtkTransformPtr transform = vtkTransformPtr::New();
268  mBoxWidget->GetTransform(transform);
269  Transform3D M(transform->GetMatrix());
270  return M;
271 }
272 void GraphicalBox::setBoxTransform(const Transform3D& M)
273 {
274  vtkTransformPtr transform = vtkTransformPtr::New();
275  transform->SetMatrix(M.getVtkMatrix());
276  mBoxWidget->SetTransform(transform);
277 }
278 
281 DoubleBoundingBox3D GraphicalBox::getCurrentBoxWidgetSize()
282 {
283  if (!mBoxWidget)
284  {
285  return DoubleBoundingBox3D::zero();
286  }
287 
288  double bb_hard[6] =
289  { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
290  DoubleBoundingBox3D bb_unit(bb_hard);
291 
292  Transform3D M = this->getBoxTransform();
293  M = m_rMd.inv() * M;
294  DoubleBoundingBox3D bb_new_d = cx::transform(M, bb_unit);
295 
296  return bb_new_d;
297 }
298 
299 
300 
301 } // 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 *)
virtual ~GraphicalBox()
vtkSmartPointer< class vtkTransform > vtkTransformPtr
Definition: cxMathBase.h:41
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.