Fraxinus  2023.01.05-dev+develop.0da12
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  if(similar(position, focalPoint))
87  return;
88 
89  this->getCamera();
90 
91  mCamera->SetClippingRange(nearClip, farClip);
92  mCamera->SetPosition(position.begin());
93  mCamera->SetFocalPoint(focalPoint.begin());
94  mCamera->ComputeViewPlaneNormal();
95  mCamera->SetViewUp(viewUp.begin());
96  mCamera->SetParallelScale(parallelScale);
97 }
98 
102 
103 
105  QObject(parent),
106  mSuperiorViewAction(NULL),
107  mAnteriorViewAction(NULL)
108 {
109 }
110 
112 {
113 }
114 
116 {
117  return Vector3D(0, 1, 0);
118 }
120 {
121  return Vector3D(0, -1, 0);
122 }
124 {
125  return Vector3D(0, 0, -1);
126 }
128 {
129  return Vector3D(0, 0, 1);
130 }
132 {
133  return Vector3D(-1, 0, 0);
134 }
136 {
137  return Vector3D(1, 0, 0);
138 }
140 {
141  return Vector3D(-1, 1, -1).normal();
142 }
143 
144 /*Move the camera focus to p_r. Keep the view direction and distance constant
145  * (i.e. keep pos of camera constant relative to focus).
146  *
147  */
149 {
150  vtkCameraPtr camera = this->getCamera();
151  if (!camera)
152  return;
153 
154  Vector3D f(camera->GetFocalPoint());
155  Vector3D p(camera->GetPosition());
156  Vector3D delta = p_r - f;
157  f += delta;
158  p += delta;
159  camera->SetFocalPoint(f.begin());
160  camera->SetPosition(p.begin());
161 }
162 
164 {
165  if(mSuperiorViewAction)
166  mSuperiorViewAction->trigger();
167 }
168 
170 {
171  if(mAnteriorViewAction)
172  mAnteriorViewAction->trigger();
173 }
174 
176 {
177  QActionGroup* group = new QActionGroup(this);
178  mAnteriorViewAction = this->addStandard3DViewAction("A", "Anterior View", AnteriorDirection(), group);
179  this->addStandard3DViewAction("P", "Posterior View", PosteriorDirection(), group);
180  mSuperiorViewAction = this->addStandard3DViewAction("S", "Superior View", SuperiorDirection(), group);
181  this->addStandard3DViewAction("I", "Inferior View", InferiorDirection(), group);
182  this->addStandard3DViewAction("L", "Left View", LeftDirection(), group);
183  this->addStandard3DViewAction("R", "Right View", RightDirection(), group);
184  this->addStandard3DViewAction("O", "Orthogonal View", OrthogonalDirection(), group);
185  return group;
186 }
187 
190 QAction* CameraControl::addStandard3DViewAction(QString caption, QString help, Vector3D viewDirection,
191  QActionGroup* group)
192 {
193  QAction* action = new QAction(help, group);
194  action->setStatusTip(help);
195  action->setWhatsThis(help);
196  action->setIcon(QIcon(":/icons/camera_view_" + caption + ".png"));
197  // QFont font;
198  // font.setBold(true);
199  // if (font.pointSize()>=0)
200  // font.setPointSize(font.pointSize()*1.5);
201  // action->setFont(font);
202  action->setData(QVariant(qstring_cast(viewDirection)));
203  connect(action, &QAction::triggered, this, &CameraControl::setStandard3DViewActionSlot);
204  return action;
205 }
206 
208 {
209  this->setView(view);
210  if(view)
211  view->getRenderer()->ResetCameraClippingRange();
212 }
213 
215 {
216  mView = view;
217 }
218 
220 {
221  return mView;
222 }
223 
224 vtkRendererPtr CameraControl::getRenderer() const
225 {
226  if (!mView)
227  return vtkRendererPtr();
228  return mView->getRenderer();
229 }
230 vtkCameraPtr CameraControl::getCamera() const
231 {
232  if (!this->getRenderer())
233  return vtkCameraPtr();
234  return this->getRenderer()->GetActiveCamera();
235 }
236 
238 {
239  QAction* action = dynamic_cast<QAction*> (sender());
240  if (!action)
241  return;
242  Vector3D viewDirection = Vector3D::fromString(action->data().toString());
243  this->setStandard3DView(viewDirection);
244 }
245 
247 {
248  vtkRendererPtr renderer = this->getRenderer();
249  if (!renderer)
250  return;
251  vtkCameraPtr camera = this->getCamera();
252 
253  renderer->ResetCamera();
254 
255  Vector3D focus(camera->GetFocalPoint());
256  Vector3D pos = focus - 500 * viewDirection;
257  Vector3D vup(0, 0, 1);
258 
259  Vector3D left = cross(vup, viewDirection);
260  if (similar(left.length(), 0.0))
261  left = RightDirection();
262  vup = cross(viewDirection, left).normal();
263 
264  camera->SetPosition(pos.begin());
265  camera->SetViewUp(vup.begin());
266 
267  renderer->ResetCamera(); // let vtk do the zooming base work
268  camera->Dolly(1.5); // zoom in a bit more than the default vtk value
269  renderer->ResetCameraClippingRange();
270 }
271 
272 } // namespace cx
QString qstring_cast(const T &val)
static Vector3D LeftDirection()
void setSuperiorView() const
vtkCameraPtr getCamera() const
void translateByFocusTo(Vector3D p_r)
static Vector3D OrthogonalDirection()
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()
static Vector3D SuperiorDirection()
static Vector3D InferiorDirection()
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
void setView(ViewPtr view)
void refreshView(ViewPtr view)
void setStandard3DView(Vector3D viewDirection)
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)
static Vector3D AnteriorDirection()
void setAnteriorView() const
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
static Vector3D RightDirection()
static Vector3D PosteriorDirection()
ViewPtr getView() const
CameraControl(QObject *parent=NULL)
void setStandard3DViewActionSlot()
vtkSmartPointer< class vtkCamera > vtkCameraPtr
Namespace for all CustusX production code.