CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxCameraControl.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 /*
34  * cxCameraControl.cpp
35  *
36  * \date Oct 15, 2010
37  * \author christiana
38  */
39 #include "cxCameraControl.h"
40 
41 #include <QAction>
42 #include "vtkRenderer.h"
43 #include "vtkCamera.h"
44 #include "cxView.h"
45 #include <QDomNode>
46 #include "cxTypeConversions.h"
47 
48 namespace cx
49 {
50 
52 {
53 }
54 
56 {
57  mCamera = camera;
58 }
59 
61 {
62  if (!mCamera)
63  mCamera = vtkCameraPtr::New();
64  return mCamera;
65 }
66 
67 void CameraData::addTextElement(QDomNode parentNode, QString name, QString value) const
68 {
69  QDomDocument doc = parentNode.ownerDocument();
70  QDomElement node = doc.createElement(name);
71  node.appendChild(doc.createTextNode(value));
72  parentNode.appendChild(node);
73 }
74 
75 void CameraData::addXml(QDomNode dataNode) const
76 {
77  if (!mCamera)
78  return;
79 
80  this->addTextElement(dataNode, "position", qstring_cast(Vector3D(mCamera->GetPosition())));
81  this->addTextElement(dataNode, "focalPoint", qstring_cast(Vector3D(mCamera->GetFocalPoint())));
82  this->addTextElement(dataNode, "viewUp", qstring_cast(Vector3D(mCamera->GetViewUp())));
83  this->addTextElement(dataNode, "nearClip", qstring_cast(mCamera->GetClippingRange()[0]));
84  this->addTextElement(dataNode, "farClip", qstring_cast(mCamera->GetClippingRange()[1]));
85  this->addTextElement(dataNode, "parallelScale", qstring_cast(mCamera->GetParallelScale()));
86 }
87 
88 void CameraData::parseXml(QDomNode dataNode)
89 {
90  Vector3D position = Vector3D::fromString(dataNode.namedItem("position").toElement().text());
91  Vector3D focalPoint = Vector3D::fromString(dataNode.namedItem("focalPoint").toElement().text());
92  Vector3D viewUp = Vector3D::fromString(dataNode.namedItem("viewUp").toElement().text());
93  double nearClip = dataNode.namedItem("nearClip").toElement().text().toDouble();
94  double farClip = dataNode.namedItem("farClip").toElement().text().toDouble();
95  double parallelScale = dataNode.namedItem("parallelScale").toElement().text().toDouble();
96 
97  if (similar(viewUp.length(), 0.0))
98  return; // ignore reading if undefined data
99  double LARGE_NUMBER = 1.0E6; // corresponding to a distance of 1km - unphysical for human-sized data
100  if ((position-focalPoint).length() > LARGE_NUMBER)
101  return;
102  if (focalPoint.length() > LARGE_NUMBER)
103  return;
104  if (fabs(parallelScale) > LARGE_NUMBER)
105  return;
106 
107  this->getCamera();
108 
109  mCamera->SetClippingRange(nearClip, farClip);
110  mCamera->SetPosition(position.begin());
111  mCamera->SetFocalPoint(focalPoint.begin());
112  mCamera->ComputeViewPlaneNormal();
113  mCamera->SetViewUp(viewUp.begin());
114  mCamera->SetParallelScale(parallelScale);
115 }
116 
120 
121 
123  QObject(parent)
124 {
125 
126 }
127 
129 {
130 
131 }
132 
133 /*Move the camera focus to p_r. Keep the view direction and distance constant
134  * (i.e. keep pos of camera constant relative to focus).
135  *
136  */
138 {
139  vtkCameraPtr camera = this->getCamera();
140  if (!camera)
141  return;
142 
143  Vector3D f(camera->GetFocalPoint());
144  Vector3D p(camera->GetPosition());
145  Vector3D delta = p_r - f;
146  f += delta;
147  p += delta;
148  camera->SetFocalPoint(f.begin());
149  camera->SetPosition(p.begin());
150 }
151 
153 {
154  QActionGroup* group = new QActionGroup(this);
155  this->addStandard3DViewAction("A", "Anterior View", Vector3D(0, 1, 0), group);
156  this->addStandard3DViewAction("P", "Posterior View", Vector3D(0, -1, 0), group);
157  this->addStandard3DViewAction("S", "Superior View", Vector3D(0, 0, -1), group);
158  this->addStandard3DViewAction("I", "Inferior View", Vector3D(0, 0, 1), group);
159  this->addStandard3DViewAction("L", "Left View", Vector3D(-1, 0, 0), group);
160  this->addStandard3DViewAction("R", "Right View", Vector3D(1, 0, 0), group);
161  this->addStandard3DViewAction("O", "Orthogonal View", Vector3D(-1, 1, -1).normal(), group);
162  return group;
163 }
164 
167 QAction* CameraControl::addStandard3DViewAction(QString caption, QString help, Vector3D viewDirection,
168  QActionGroup* group)
169 {
170  QAction* action = new QAction(help, group);
171  action->setStatusTip(help);
172  action->setWhatsThis(help);
173  action->setIcon(QIcon(":/icons/camera_view_" + caption + ".png"));
174  // QFont font;
175  // font.setBold(true);
176  // if (font.pointSize()>=0)
177  // font.setPointSize(font.pointSize()*1.5);
178  // action->setFont(font);
179  action->setData(QVariant(qstring_cast(viewDirection)));
180  connect(action, SIGNAL(triggered()), this, SLOT(setStandard3DViewActionSlot()));
181  return action;
182 }
183 
185 {
186  this->setView(view);
187  if(view)
188  view->getRenderer()->ResetCameraClippingRange();
189 }
190 
192 {
193  mView = view;
194 }
195 
196 vtkRendererPtr CameraControl::getRenderer() const
197 {
198  if (!mView)
199  return vtkRendererPtr();
200  return mView->getRenderer();
201 }
202 vtkCameraPtr CameraControl::getCamera() const
203 {
204  if (!this->getRenderer())
205  return vtkCameraPtr();
206  return this->getRenderer()->GetActiveCamera();
207 }
208 
210 {
211  QAction* action = dynamic_cast<QAction*> (sender());
212  if (!action)
213  return;
214  Vector3D viewDirection = Vector3D::fromString(action->data().toString());
215 
216  vtkRendererPtr renderer = this->getRenderer();
217  if (!renderer)
218  return;
219  vtkCameraPtr camera = this->getCamera();
220 
221  renderer->ResetCamera();
222 
223  Vector3D focus(camera->GetFocalPoint());
224  Vector3D pos = focus - 500 * viewDirection;
225  Vector3D vup(0, 0, 1);
226  //Vector3D dir = (focus-direction).normal();
227 
228  Vector3D left = cross(vup, viewDirection);
229  if (similar(left.length(), 0.0))
230  left = Vector3D(1, 0, 0);
231  vup = cross(viewDirection, left).normal();
232 
233  camera->SetPosition(pos.begin());
234  camera->SetViewUp(vup.begin());
235 
236  renderer->ResetCamera(); // let vtk do the zooming base work
237  camera->Dolly(1.5); // zoom in a bit more than the default vtk value
238  renderer->ResetCameraClippingRange();
239 }
240 
241 } // namespace cx
QString qstring_cast(const T &val)
PlainObject normal() const
vtkCameraPtr getCamera() const
void translateByFocusTo(Vector3D p_r)
boost::shared_ptr< class View > ViewPtr
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
Definition: cxVector3D.cpp:62
QActionGroup * createStandard3DViewActions()
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
void setView(ViewPtr view)
void refreshView(ViewPtr view)
void parseXml(QDomNode dataNode)
load internal state info from dataNode
void addXml(QDomNode dataNode) const
store internal state info in dataNode
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
void setCamera(vtkCameraPtr camera)
CameraControl(QObject *parent=NULL)
void setStandard3DViewActionSlot()
vtkSmartPointer< class vtkCamera > vtkCameraPtr