35 #include <vtkRenderer.h>
36 #include <vtkCamera.h>
37 #include <vtkLightCollection.h>
43 #include "boost/bind.hpp"
44 #include <vtkRenderWindow.h>
45 #include "vtkInteractorStyleUnicam.h"
46 #include "vtkInteractorStyleTrackballCamera.h"
51 #include <vtkRenderWindowInteractor.h>
74 mBlockCameraUpdate(false),
78 mViewportListener->setCallback(boost::bind(&CameraStyleForView::viewportChangedSlot,
this));
81 mPreRenderListener->setCallback(boost::bind(&CameraStyleForView::onPreRender,
this));
84 this, &CameraStyleForView::activeToolChangedSlot);
89 mViewportListener->stopListen();
90 mPreRenderListener->stopListen();
92 this->disconnectTool();
96 mViewportListener->startListen(this->getRenderer());
97 mPreRenderListener->startListen(this->getRenderer());
101 ViewPtr CameraStyleForView::getView()
const
106 void CameraStyleForView::viewportChangedSlot()
108 if (mBlockCameraUpdate)
113 void CameraStyleForView::onPreRender()
115 this->applyCameraStyle();
120 if (!this->getView())
123 ToolRep3DPtr rep = RepContainer(this->getView()->getReps()).findFirst<ToolRep3D>(mFollowingTool);
129 if (!this->getView())
131 return this->getView()->getRenderer();
136 if (!this->getRenderer())
138 return this->getRenderer()->GetActiveCamera();
141 void CameraStyleForView::setModified()
143 mPreRenderListener->setModified();
146 void CameraStyleForView::applyCameraStyle()
152 CameraInfo cam_old(camera);
153 CameraInfo cam_new = cam_old;
161 cam_new.focus = roi_r.
center();
169 cam_new.vup = rMto.vector(
Vector3D(-1, 0, 0));
174 cam_new.focus = rMto.coord(Vector3D::Zero());
180 Vector3D tooloffset = rMto.coord(Vector3D::Zero());
191 Vector3D table_up = mBackend->patient()->getOperatingTable().getVectorUp();
192 cam_new.vup = table_up;
196 if (!
similar(cam_new.vup, cam_old.vup))
203 cam_new = this->viewEntireAutoZoomROI(cam_new);
211 this->updateCamera(cam_new);
216 Transform3D rMpr = mBackend->patient()->get_rMpr();
218 double offset = mFollowingTool->getTooltipOffset();
224 Vector3D CameraStyleForView::getToolTip_r()
227 return rMto.coord(Vector3D::Zero());
231 CameraInfo CameraStyleForView::viewEntireAutoZoomROI(CameraInfo info)
233 CameraInfo retval = info;
237 RegionOfInterest roi_r = this->getROI(mStyle.
mAutoZoomROI);
238 if (!roi_r.isValid())
241 double viewAngle = info.viewAngle/180.0*
M_PI;
243 this->getRenderer()->ComputeAspect();
245 this->getRenderer()->GetAspect(aspect);
247 double viewAngle_vertical = viewAngle;
248 double viewAngle_horizontal = viewAngle*aspect[0];
255 cam_proj.focus = pMr.coord(info.focus);
256 cam_proj.vup = pMr.vector(info.vup);
257 cam_proj.pos = pMr.coord(info.pos);
259 DoubleBoundingBox3D proj_bb = roi_r.getBox(pMr);
261 Vector3D viewdirection = (cam_proj.focus - cam_proj.pos).
normal();
263 viewAngle_horizontal,
269 cam_proj.focus = cam_proj.pos + viewdirection * 100;
271 cam_proj.pos = this->smoothZoomedCameraPosition(cam_proj.pos);
273 retval.pos = pMr.inv().coord(cam_proj.pos);
274 retval.focus = pMr.inv().coord(cam_proj.focus);
286 double bb_extension = 50;
287 double bb_extension_interpolate_interval = 50;
290 bb_extension_interpolate_interval = 50;
292 double tool_z =
dot(proj_tool, e_z);
293 double bb_max_z = proj_bb[5];
294 double bb_ext_z = proj_bb[5] + bb_extension;
297 DoubleBoundingBox3D notbehind_proj = notbehind_r.getBox((pMr));
298 double notbehind = notbehind_proj[4];
302 if (notbehind_r.isValid() && (tool_z < notbehind))
305 new_pos = proj_tool + (notbehind-tool_z)*e_z;
310 double s = (tool_z-bb_extension-bb_max_z)/bb_extension_interpolate_interval;
311 s = std::min(1.0, s);
312 s = std::max(0.0, s);
313 new_pos = (1.0-s)*proj_tool + (s)*cam_proj.pos;
322 Vector3D delta = pMr.inv().coord(new_pos) - retval.pos;
324 retval.focus += delta;
330 void CameraStyleForView::handleLights()
334 renderer->GetLights()->InitTraversal();
335 vtkLight* light = renderer->GetLights()->GetNextItem();
340 light->SetConeAngle(160);
341 light->SetLightTypeToCameraLight();
342 light->SetPosition(-0.5,0,1);
352 filteredPos[2] = mZoomJitterFilter.
newValue(pos[2]);
356 RegionOfInterest CameraStyleForView::getROI(QString uid)
const
358 DataPtr data = mBackend->patient()->getData(uid);
361 return roi->getROI();
362 return RegionOfInterest();
365 void CameraStyleForView::activeToolChangedSlot()
367 ToolPtr newTool = mBackend->tracking()->getActiveTool();
368 if (newTool == mFollowingTool)
371 this->disconnectTool();
375 bool CameraStyleForView::isToolFollowingStyle()
const
380 void CameraStyleForView::connectTool()
382 if (!this->isToolFollowingStyle())
385 mFollowingTool = mBackend->tracking()->getActiveTool();
390 if (!this->getView())
393 connect(mFollowingTool.get(), SIGNAL(toolTransformAndTimestamp(
Transform3D,
double)),
this,
394 SLOT(setModified()));
399 rep->setOffsetPointVisibleAtZeroOffset(
false);
401 rep->setStayHiddenAfterVisible(
true);
406 report(
"Camera is following " + mFollowingTool->getName());
409 void CameraStyleForView::disconnectTool()
413 disconnect(mFollowingTool.get(), SIGNAL(toolTransformAndTimestamp(
Transform3D,
double)),
this,
414 SLOT(setModified()));
419 rep->setOffsetPointVisibleAtZeroOffset(
true);
420 rep->setStayHiddenAfterVisible(
false);
423 mFollowingTool.reset();
432 this->disconnectTool();
435 this->setInteractor(vtkInteractorStyleUnicamPtr::New());
437 this->setInteractor(vtkInteractorStyleTrackballCameraPtr::New());
444 void CameraStyleForView::setInteractor(vtkSmartPointer<vtkInteractorStyle> style)
446 ViewPtr view = this->getView();
449 vtkRenderWindowInteractor* interactor = view->getRenderWindow()->GetInteractor();
450 interactor->SetInteractorStyle(style);
458 void CameraStyleForView::updateCamera(
CameraInfo info)
468 if (
similar(cam_old, info, tol))
473 mBlockCameraUpdate =
true;
474 camera->SetPosition(info.
pos.begin());
475 camera->SetFocalPoint(info.
focus.begin());
476 camera->SetViewUp(info.
vup.begin());
479 camera->SetClippingRange(1, std::max<double>(2000, info.
distance() * 10));
480 mBlockCameraUpdate =
false;
497 if (( value<=range.
min() )||( value>=range.
max() ))
499 double minimumInterval = 5.0;
500 double interval = std::min(minimumInterval, value/20);
503 if (value<range.
min())
504 level = value + interval/2;
505 else if (value>range.
max())
506 level = value - interval/2;
508 range =
DoubleRange(level-interval/2, level+interval/2, interval/10);
510 currentValue = value;
521 pos =
Vector3D(camera->GetPosition());
524 viewAngle = camera->GetViewAngle();
QString mCameraNotBehindROI
PlainObject normal() const
bool mCameraLockToTooltip
static Vector3D findCameraPosOnLineFixedDistanceFromFocus(Vector3D p_line, Vector3D e_line, double distance, Vector3D focus)
double max() const
maximum value
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
void setCameraStyle(CameraStyleData style)
Utility class for describing a bounded numeric range.
boost::shared_ptr< class View > ViewPtr
DoubleBoundingBox3D getBox(Transform3D qMd=Transform3D::Identity())
Listens to changes in viewport and camera matrix.
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
boost::shared_ptr< class Data > DataPtr
void activeToolChanged(const QString &uId)
Transform3D createTransformIJC(const Vector3D &ivec, const Vector3D &jvec, const Vector3D ¢er)
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
CameraStyleData getCameraStyle()
double newValue(double value)
static DoubleBoundingBox3D zero()
double min() const
minimum value
#define CX_LOG_CHANNEL_DEBUG(channel)
Transform3D createTransformTranslate(const Vector3D &translation)
void setView(ViewPtr widget)
double dot(const Vector3D &a, const Vector3D &b)
compute inner product (or dot product) of a and b.
boost::shared_ptr< class RegionOfInterestMetric > RegionOfInterestMetricPtr
double mCameraTooltipOffset
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
void debugPrint(CameraInfo info)
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
boost::shared_ptr< class CoreServices > CoreServicesPtr
Listens to the start render event in a vtkRenderer.
boost::shared_ptr< class ToolRep3D > ToolRep3DPtr
static Vector3D elevateCamera(double angle, Vector3D camera, Vector3D focus, Vector3D vup)
static Vector3D orthogonalize_vup(Vector3D vup, Vector3D vpn, Vector3D vup_fallback)
static Vector3D findCameraPosByZoomingToROI(double viewAngle_vertical, double viewAngle_horizontal, Vector3D focus, Vector3D vup, Vector3D vpn, const DoubleBoundingBox3D &bb)
CameraStyleForView(CoreServicesPtr backend)
vtkSmartPointer< class vtkCamera > vtkCameraPtr
boost::shared_ptr< class Tool > ToolPtr