14 #include <vtkRenderer.h>
15 #include <vtkCamera.h>
16 #include <vtkLightCollection.h>
22 #include "boost/bind.hpp"
23 #include <vtkRenderWindow.h>
24 #include "vtkInteractorStyleUnicam.h"
25 #include "vtkInteractorStyleTrackballCamera.h"
30 #include <vtkRenderWindowInteractor.h>
53 mBlockCameraUpdate(false),
57 mViewportListener->setCallback(boost::bind(&CameraStyleForView::viewportChangedSlot,
this));
60 mPreRenderListener->setCallback(boost::bind(&CameraStyleForView::onPreRender,
this));
63 this, &CameraStyleForView::activeToolChangedSlot);
68 mViewportListener->stopListen();
69 mPreRenderListener->stopListen();
71 this->disconnectTool();
75 mViewportListener->startListen(this->getRenderer());
76 mPreRenderListener->startListen(this->getRenderer());
80 ViewPtr CameraStyleForView::getView()
const
85 void CameraStyleForView::viewportChangedSlot()
87 if (mBlockCameraUpdate)
92 void CameraStyleForView::onPreRender()
94 this->applyCameraStyle();
102 ToolRep3DPtr rep = RepContainer(this->getView()->getReps()).findFirst<ToolRep3D>(mFollowingTool);
108 if (!this->getView())
110 return this->getView()->getRenderer();
115 if (!this->getRenderer())
117 return this->getRenderer()->GetActiveCamera();
120 void CameraStyleForView::setModified()
122 mPreRenderListener->setModified();
125 void CameraStyleForView::applyCameraStyle()
131 CameraInfo cam_old(camera);
132 CameraInfo cam_new = cam_old;
140 cam_new.focus = roi_r.
center();
148 cam_new.vup = rMto.vector(
Vector3D(-1, 0, 0));
153 cam_new.focus = rMto.coord(Vector3D::Zero());
159 Vector3D tooloffset = rMto.coord(Vector3D::Zero());
170 Vector3D table_up = mBackend->patient()->getOperatingTable().getVectorUp();
171 cam_new.vup = table_up;
175 if (!
similar(cam_new.vup, cam_old.vup))
182 cam_new = this->viewEntireAutoZoomROI(cam_new);
190 this->updateCamera(cam_new);
195 Transform3D rMpr = mBackend->patient()->get_rMpr();
197 double offset = mFollowingTool->getTooltipOffset();
203 Vector3D CameraStyleForView::getToolTip_r()
206 return rMto.coord(Vector3D::Zero());
210 CameraInfo CameraStyleForView::viewEntireAutoZoomROI(CameraInfo info)
212 CameraInfo retval = info;
216 RegionOfInterest roi_r = this->getROI(mStyle.
mAutoZoomROI);
217 if (!roi_r.isValid())
220 double viewAngle = info.viewAngle/180.0*
M_PI;
222 this->getRenderer()->ComputeAspect();
224 this->getRenderer()->GetAspect(aspect);
226 double viewAngle_vertical = viewAngle;
227 double viewAngle_horizontal = viewAngle*aspect[0];
234 cam_proj.focus = pMr.coord(info.focus);
235 cam_proj.vup = pMr.vector(info.vup);
236 cam_proj.pos = pMr.coord(info.pos);
238 DoubleBoundingBox3D proj_bb = roi_r.getBox(pMr);
240 Vector3D viewdirection = (cam_proj.focus - cam_proj.pos).
normal();
242 viewAngle_horizontal,
248 cam_proj.focus = cam_proj.pos + viewdirection * 100;
250 cam_proj.pos = this->smoothZoomedCameraPosition(cam_proj.pos);
252 retval.pos = pMr.inv().coord(cam_proj.pos);
253 retval.focus = pMr.inv().coord(cam_proj.focus);
265 double bb_extension = 50;
266 double bb_extension_interpolate_interval = 50;
269 bb_extension_interpolate_interval = 50;
271 double tool_z =
dot(proj_tool, e_z);
272 double bb_max_z = proj_bb[5];
273 double bb_ext_z = proj_bb[5] + bb_extension;
276 DoubleBoundingBox3D notbehind_proj = notbehind_r.getBox((pMr));
277 double notbehind = notbehind_proj[4];
281 if (notbehind_r.isValid() && (tool_z < notbehind))
284 new_pos = proj_tool + (notbehind-tool_z)*e_z;
289 double s = (tool_z-bb_extension-bb_max_z)/bb_extension_interpolate_interval;
290 s = std::min(1.0, s);
291 s = std::max(0.0, s);
292 new_pos = (1.0-s)*proj_tool + (s)*cam_proj.pos;
301 Vector3D delta = pMr.inv().coord(new_pos) - retval.pos;
303 retval.focus += delta;
309 void CameraStyleForView::handleLights()
313 renderer->GetLights()->InitTraversal();
314 vtkLight* light = renderer->GetLights()->GetNextItem();
319 light->SetConeAngle(160);
320 light->SetLightTypeToCameraLight();
321 light->SetPosition(-0.5,0,1);
331 filteredPos[2] = mZoomJitterFilter.
newValue(pos[2]);
335 RegionOfInterest CameraStyleForView::getROI(QString uid)
const
337 DataPtr data = mBackend->patient()->getData(uid);
340 return roi->getROI();
341 return RegionOfInterest();
344 void CameraStyleForView::activeToolChangedSlot()
346 ToolPtr newTool = mBackend->tracking()->getActiveTool();
347 if (newTool == mFollowingTool)
350 this->disconnectTool();
354 bool CameraStyleForView::isToolFollowingStyle()
const
359 void CameraStyleForView::connectTool()
361 if (!this->isToolFollowingStyle())
364 mFollowingTool = mBackend->tracking()->getActiveTool();
369 if (!this->getView())
372 connect(mFollowingTool.get(), SIGNAL(toolTransformAndTimestamp(
Transform3D,
double)),
this,
373 SLOT(setModified()));
378 rep->setOffsetPointVisibleAtZeroOffset(
false);
380 rep->setStayHiddenAfterVisible(
true);
385 report(
"Camera is following " + mFollowingTool->getName());
388 void CameraStyleForView::disconnectTool()
392 disconnect(mFollowingTool.get(), SIGNAL(toolTransformAndTimestamp(
Transform3D,
double)),
this,
393 SLOT(setModified()));
398 rep->setOffsetPointVisibleAtZeroOffset(
true);
399 rep->setStayHiddenAfterVisible(
false);
402 mFollowingTool.reset();
411 this->disconnectTool();
414 this->setInteractor(vtkInteractorStyleUnicamPtr::New());
416 this->setInteractor(vtkInteractorStyleTrackballCameraPtr::New());
423 void CameraStyleForView::setInteractor(vtkSmartPointer<vtkInteractorStyle> style)
425 ViewPtr view = this->getView();
428 vtkRenderWindowInteractor* interactor = view->getRenderWindow()->GetInteractor();
429 interactor->SetInteractorStyle(style);
437 void CameraStyleForView::updateCamera(
CameraInfo info)
447 if (
similar(cam_old, info, tol))
452 mBlockCameraUpdate =
true;
453 camera->SetPosition(info.
pos.begin());
454 camera->SetFocalPoint(info.
focus.begin());
455 camera->SetViewUp(info.
vup.begin());
458 camera->SetClippingRange(1, std::max<double>(2000, info.
distance() * 10));
459 mBlockCameraUpdate =
false;
476 if (( value<=range.min() )||( value>=range.max() ))
478 double minimumInterval = 5.0;
479 double interval = std::min(minimumInterval, value/20);
482 if (value<range.min())
483 level = value + interval/2;
484 else if (value>range.max())
485 level = value - interval/2;
487 range =
DoubleRange(level-interval/2, level+interval/2, interval/10);
489 currentValue = value;