Fraxinus  17.12
An IGT application
cxTrackPadWidget.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 #include "cxTrackPadWidget.h"
33 
34 #include <QVBoxLayout>
35 #include <QScrollBar>
36 #include <QTouchEvent>
37 
38 #include <QAction>
39 #include <QRadialGradient>
40 #include "vtkRenderer.h"
41 #include "vtkCamera.h"
42 #include "vtkSmartPointer.h"
43 #include "cxDataInterface.h"
44 #include "cxCameraControl.h"
45 #include "cxBoundingBox3D.h"
46 #include "cxView.h"
47 #include "cxViewService.h"
48 #include "cxLogger.h"
49 
50 namespace cx
51 {
52 
56 
57 TrackPadWidget::TrackPadWidget(ViewServicePtr viewService, QWidget* parent) :
58  BaseWidget(parent, "track_pad_widget", "Camera Control"),
59  mViewService(viewService)
60 {
61  this->setToolTip("Track pad camera control");
62  mCameraControl = viewService->getCameraControl();
63 
64  mMinPadSize = QSize(50,50);
65  mMinBarSize = QSize(20,50);
66 
67  mTopLayout = new QVBoxLayout(this);
68 
69  this->createStandard3DViewActions();
70  this->definePanLayout();
71  this->defineRotateLayout();
72 }
73 
74 void TrackPadWidget::createStandard3DViewActions()
75 {
76  if(!mCameraControl)
77  {
78  CX_LOG_WARNING() << "TrackPadWidget::createStandard3DViewActions: Got no mCameraControl";
79  return;
80  }
81 
82  QActionGroup* group = mCameraControl->createStandard3DViewActions();
83 
84  QToolBar* toolBar = new QToolBar(this);
85  mTopLayout->addWidget(toolBar);
86  toolBar->addActions(group->actions());
87  toolBar->addSeparator();
88 }
89 
90 void TrackPadWidget::defineRotateLayout()
91 {
92  QGroupBox* group = new QGroupBox("rotate", this);
93  group->setFlat(true);
94  mTopLayout->addWidget(group);
95 
96  QHBoxLayout* layout = new QHBoxLayout;
97  layout->setMargin(4);
98  group->setLayout(layout);
99 
100  MousePadWidget* rotateWidget = new MousePadWidget(this, mMinPadSize);
101  connect(rotateWidget, SIGNAL(mouseMoved(QPointF)), this, SLOT(rotateXZSlot(QPointF)));
102  layout->addWidget(rotateWidget, 4);
103 
104  MousePadWidget* rotateYWidget = new MousePadWidget(this, mMinBarSize);
105  rotateYWidget->setFixedXPos(true);
106  connect(rotateYWidget, SIGNAL(mouseMoved(QPointF)), this, SLOT(rotateYSlot(QPointF)));
107  layout->addWidget(rotateYWidget, 1);
108 }
109 
110 
111 void TrackPadWidget::definePanLayout()
112 {
113  QGroupBox* group = new QGroupBox("pan", this);
114  group->setFlat(true);
115  mTopLayout->addWidget(group);
116 
117  QHBoxLayout* panLayout = new QHBoxLayout;
118  panLayout->setMargin(4);
119  group->setLayout(panLayout);
120 
121  MousePadWidget* panWidget = new MousePadWidget(this, mMinPadSize);
122  connect(panWidget, SIGNAL(mouseMoved(QPointF)), this, SLOT(panXZSlot(QPointF)));
123  panLayout->addWidget(panWidget, 4);
124 
125  MousePadWidget* dollyWidget = new MousePadWidget(this, mMinBarSize);
126  dollyWidget->setFixedXPos(true);
127  connect(dollyWidget, SIGNAL(mouseMoved(QPointF)), this, SLOT(dollySlot(QPointF)));
128  panLayout->addWidget(dollyWidget, 1);
129 }
130 
131 vtkCameraPtr TrackPadWidget::getCamera() const
132 {
133  return mViewService->get3DView()->getRenderer()->GetActiveCamera();
134 }
135 
136 void TrackPadWidget::rotateYSlot(QPointF delta)
137 {
138  double scale = 180;
139  double factor = scale * delta.y();
140 
141  this->getCamera()->Roll(factor);
142 }
143 
144 void TrackPadWidget::rotateXZSlot(QPointF delta)
145 {
146  vtkCameraPtr camera = this->getCamera();
147  double scale = 180;
148 
149  camera->Azimuth(-scale * delta.x());
150  camera->Elevation(scale * delta.y());
151  camera->OrthogonalizeViewUp(); // needed when using azimuth, according to docs (failure to do this causes strange zooming effects)
152 }
153 
154 void TrackPadWidget::dollySlot(QPointF delta)
155 {
156  double factor = 1 + delta.y();
157  this->getCamera()->Dolly(factor);
158  mViewService->get3DView()->getRenderer()->ResetCameraClippingRange();
159 }
160 
161 void TrackPadWidget::panXZSlot(QPointF delta)
162 {
163  vtkCameraPtr camera = this->getCamera();
164  Vector3D position(camera->GetPosition());
165  Vector3D focus(camera->GetFocalPoint());
166  Vector3D vup(camera->GetViewUp());
167 
168  Vector3D e_x = cross(focus-position, vup).normal();
169  Vector3D e_y = vup.normal();
170 
171  DoubleBoundingBox3D bb(mViewService->get3DView()->getRenderer()->ComputeVisiblePropBounds());
172 
173  double volSize = bb.range().length() / pow(3, 1.0/3.0); // mm size of volume
174  double scale = volSize;
175  Vector3D t = scale * (-delta.x() * e_x + delta.y() * e_y);
176 
177  position += t;
178  focus += t;
179 
180  camera->SetPosition(position.begin());
181  camera->SetFocalPoint(focus.begin());
182 }
183 
185 {
186 }
187 
188 void TrackPadWidget::showEvent(QShowEvent* event)
189 {
190  QWidget::showEvent(event);
191 }
192 
193 void TrackPadWidget::hideEvent(QCloseEvent* event)
194 {
195  QWidget::closeEvent(event);
196 }
197 
198 
199 }//end namespace cx
void rotateYSlot(QPointF delta)
void setFixedXPos(bool on)
A touchpad-friendly area for performing 1D/2D scroll operations.
boost::shared_ptr< class ViewService > ViewServicePtr
void rotateXZSlot(QPointF delta)
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
Definition: cxVector3D.cpp:62
TrackPadWidget(ViewServicePtr viewService, QWidget *parent)
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 panXZSlot(QPointF delta)
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:109
#define CX_LOG_WARNING
Definition: cxLogger.h:119
void dollySlot(QPointF delta)
vtkSmartPointer< class vtkCamera > vtkCameraPtr
Namespace for all CustusX production code.
virtual void hideEvent(QCloseEvent *event)
disconnects stuff