CustusX  15.3.3-beta
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  mView = view;
187 }
188 
189 vtkRendererPtr CameraControl::getRenderer() const
190 {
191  if (!mView)
192  return vtkRendererPtr();
193  return mView->getRenderer();
194 }
195 vtkCameraPtr CameraControl::getCamera() const
196 {
197  if (!this->getRenderer())
198  return vtkCameraPtr();
199  return this->getRenderer()->GetActiveCamera();
200 }
201 
203 {
204  QAction* action = dynamic_cast<QAction*> (sender());
205  if (!action)
206  return;
207  Vector3D viewDirection = Vector3D::fromString(action->data().toString());
208 
209  vtkRendererPtr renderer = this->getRenderer();
210  if (!renderer)
211  return;
212  vtkCameraPtr camera = this->getCamera();
213 
214  renderer->ResetCamera();
215 
216  Vector3D focus(camera->GetFocalPoint());
217  Vector3D pos = focus - 500 * viewDirection;
218  Vector3D vup(0, 0, 1);
219  //Vector3D dir = (focus-direction).normal();
220 
221  Vector3D left = cross(vup, viewDirection);
222  if (similar(left.length(), 0.0))
223  left = Vector3D(1, 0, 0);
224  vup = cross(viewDirection, left).normal();
225 
226  camera->SetPosition(pos.begin());
227  camera->SetViewUp(vup.begin());
228 
229  renderer->ResetCamera(); // let vtk do the zooming base work
230  camera->Dolly(1.5); // zoom in a bit more than the default vtk value
231  renderer->ResetCameraClippingRange();
232 }
233 
234 } // 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 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