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