22 #include <vtkCamera.h>
23 #include <vtkRenderer.h>
24 #include <vtkRenderWindow.h>
27 #include <QActionGroup>
29 #include <QMouseEvent>
30 #include <QWheelEvent>
61 #include "vtkRenderWindowInteractor.h"
74 mOrientationActionGroup(new QActionGroup(view.get()))
76 qRegisterMetaType<Vector3D>(
"Vector3D");
81 mView->getRenderWindow()->GetInteractor()->Disable();
82 mView->getRenderer()->GetActiveCamera()->SetParallelProjection(
true);
83 double clipDepth = 1.0;
84 double length = clipDepth*10;
85 mView->getRenderer()->GetActiveCamera()->SetPosition(0,0,
length);
86 mView->getRenderer()->GetActiveCamera()->SetClippingRange(
length-clipDepth,
length+0.1);
92 mDataRepContainer->setSliceProxy(mSliceProxy);
93 mDataRepContainer->setView(mView);
96 mViewFollower->setSliceProxy(mSliceProxy);
101 connect(mZoom2D.get(), SIGNAL(zoomChanged()),
this, SLOT(viewportChanged()));
103 connect(
mServices->tracking().get(), SIGNAL(activeToolChanged(
const QString&)),
this, SLOT(activeToolChangedSlot()));
104 connect(mView.get(), SIGNAL(resized(QSize)),
this, SLOT(viewportChanged()));
105 connect(mView.get(), SIGNAL(shown()),
this, SLOT(showSlot()));
106 connect(mView.get(), SIGNAL(mousePress(
int,
int, Qt::MouseButtons)),
this, SLOT(mousePressSlot(
int,
int, Qt::MouseButtons)));
107 connect(mView.get(), SIGNAL(mouseMove(
int,
int, Qt::MouseButtons)),
this, SLOT(mouseMoveSlot(
int,
int, Qt::MouseButtons)));
108 connect(mView.get(), SIGNAL(mouseWheel(
int,
int,
int,
int, Qt::MouseButtons)),
this, SLOT(mouseWheelSlot(
int,
int,
int,
int, Qt::MouseButtons)));
112 this->activeToolChangedSlot();
122 void ViewWrapper2D::changeZoom(
double delta)
127 double zoom = mZoom2D->getFactor();
131 mZoom2D->setFactor(zoom);
137 if(!this->isAnyplane())
143 Vector3D p_s = vpMs.inv().coord(click_vp);
144 Vector3D p_r = sMr.inv().coord(p_s);
149 void ViewWrapper2D::appendToContextMenu(QMenu& contextMenu)
151 contextMenu.addSeparator();
152 mZoom2D->addActionsToMenu(&contextMenu);
154 contextMenu.addSeparator();
155 QAction* showManualTool =
new QAction(
"Show Manual Tool 2D", &contextMenu);
156 showManualTool->setCheckable(
true);
157 showManualTool->setChecked(
settings()->value(
"View2D/showManualTool").toBool());
158 showManualTool->setToolTip(
"Turn on/off visualization of the vire cross in 2D");
159 connect(showManualTool, SIGNAL(triggered(
bool)),
this, SLOT(showManualToolSlot(
bool)));
160 contextMenu.addAction(showManualTool);
167 mZoom2D->setGroupData(group);
168 connect(group.get(), SIGNAL(optionsChanged()),
this, SLOT(optionChangedSlot()));
169 this->optionChangedSlot();
172 void ViewWrapper2D::optionChangedSlot()
182 void ViewWrapper2D::addReps()
186 mView->addRep(mOrientationAnnotationRep);
192 mToolRep2D->setSliceProxy(mSliceProxy);
193 mToolRep2D->setUseCrosshair(
true);
194 this->toggleShowManualTool();
197 mPickerGlyphRep->setSliceProxy(mSliceProxy);
200 mPickerGlyphRep->setMesh(
mGroupData->getOptions().mPickerGlyph);
202 mView->addRep(mPickerGlyphRep);
209 if (key ==
"View2D/useGPU2DRendering")
213 if (key ==
"View2D/useLinearInterpolationIn2DRendering")
217 if (key ==
"Navigation/anyplaneViewOffset")
221 if (key ==
"View2D/showManualTool")
223 this->toggleShowManualTool();
227 void ViewWrapper2D::toggleShowManualTool()
229 if (
settings()->value(
"View2D/showManualTool").toBool())
230 mView->addRep(mToolRep2D);
232 mView->removeRep(mToolRep2D);
235 void ViewWrapper2D::removeAndResetSliceRep()
237 for(
int i = 0; i < mSliceReps.size(); ++i)
239 mView->removeRep(mSliceReps[i]);
240 mSliceReps[i].reset();
245 void ViewWrapper2D::removeAndResetMultiSliceRep()
249 mView->removeRep(mMultiSliceRep);
250 mMultiSliceRep.reset();
254 bool ViewWrapper2D::createAndAddMultiSliceRep()
258 CX_LOG_WARNING() <<
"ViewWrapper2D::createAndAddMultiSliceRep(): Got no mSharedOpenGLContext";
266 mMultiSliceRep->setSliceProxy(mSliceProxy);
267 mMultiSliceRep->setRenderWindow(mView->getRenderWindow());
269 mView->addRep(mMultiSliceRep);
279 void ViewWrapper2D::recreateMultiSlicer()
281 this->removeAndResetSliceRep();
283 if (!this->useGPU2DRendering())
285 this->removeAndResetMultiSliceRep();
289 if(!this->createAndAddMultiSliceRep())
295 mMultiSliceRep->setImages(this->getImagesToView());
297 mMultiSliceRep->setImages(std::vector<ImagePtr>());
299 this->viewportChanged();
302 std::vector<ImagePtr> ViewWrapper2D::getImagesToView()
304 bool include2D = this->isAnyplane();
309 bool ViewWrapper2D::isAnyplane()
311 PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
318 void ViewWrapper2D::viewportChanged()
320 if (!mView->getRenderer()->IsActiveCameraCreated())
323 mView->setZoomFactor(mZoom2D->getFactor());
325 double viewHeight = mView->getViewport_s().range()[1];
326 mView->getRenderer()->GetActiveCamera()->SetParallelScale(viewHeight / 2);
330 double clipDepth = 2.0;
331 double length = clipDepth*10;
332 clipDepth = viewHeight/120 + 1.5;
333 mView->getRenderer()->GetActiveCamera()->SetPosition(0,0,
length);
334 mView->getRenderer()->GetActiveCamera()->SetClippingRange(
length-clipDepth,
length+0.1);
336 mSliceProxy->setToolViewportHeight(viewHeight);
337 double anyplaneViewOffset =
settings()->
value(
"Navigation/anyplaneViewOffset").toDouble();
338 mSliceProxy->initializeFromPlane(mSliceProxy->getComputer().getPlaneType(),
false,
true, viewHeight, anyplaneViewOffset);
340 DoubleBoundingBox3D BB_vp = getViewport();
342 DoubleBoundingBox3D BB_s =
transform(vpMs.inv(), BB_vp);
343 PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
345 mToolRep2D->setViewportData(vpMs, BB_vp);
346 if (mSlicePlanes3DMarker)
348 mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy, BB_s);
352 void ViewWrapper2D::applyViewFollower()
356 QString roiUid =
mGroupData->getOptions().mCameraStyle.mAutoZoomROI;
357 mViewFollower->setAutoZoomROI(roiUid);
358 mViewFollower->setView(this->getViewport_s());
359 SliceAutoViewportCalculator::ReturnType result = mViewFollower->calculate();
363 this->changeZoom(result.zoom);
364 Vector3D newcenter_r = mViewFollower->findCenter_r_fromShift_s(result.center_shift_s);
365 mServices->patient()->setCenter(newcenter_r);
370 DoubleBoundingBox3D ViewWrapper2D::getViewport()
const
372 QSize size = mView->size();
374 Vector3D p1_d(size.width(), size.height(), 0);
375 DoubleBoundingBox3D BB_vp(p0_d, p1_d);
379 void ViewWrapper2D::showSlot()
381 activeToolChangedSlot();
387 double viewHeight = mView->getViewport_s().range()[1];
388 mSliceProxy->initializeFromPlane(plane,
false,
true, viewHeight, 0.25);
389 mOrientationAnnotationRep->setSliceProxy(mSliceProxy);
394 ORIENTATION_TYPE ViewWrapper2D::getOrientationType()
const
396 return mSliceProxy->getComputer().getOrientationType();
406 void ViewWrapper2D::imageAdded(
ImagePtr image)
422 image = images.back();
427 bool ViewWrapper2D::useGPU2DRendering()
429 return settings()->
value(
"View2D/useGPU2DRendering").toBool();
432 void ViewWrapper2D::createAndAddSliceReps(
int numberOfSlices)
434 this->removeAndResetSliceRep();
435 for(
int i = 0; i < numberOfSlices; ++i)
438 sliceRep->setSliceProxy(mSliceProxy);
439 mView->addRep(sliceRep);
440 mSliceReps.push_back(sliceRep);
453 return qstring_cast(mSliceProxy->getComputer().getPlaneType());
456 void ViewWrapper2D::updateItemsFromViewGroup()
465 Vector3D c = image->get_rMd().coord(image->boundingBox().center());
466 mSliceProxy->setDefaultCenter(c);
468 if (this->useGPU2DRendering())
470 this->recreateMultiSlicer();
474 this->removeAndResetMultiSliceRep();
475 setImagesSWRendering();
480 this->removeAndResetSliceRep();
481 this->removeAndResetMultiSliceRep();
485 void ViewWrapper2D::setImagesSWRendering()
487 std::vector<ImagePtr> images = this->getImagesToView();
488 this->createAndAddSliceReps(images.size());
490 if(mSliceReps.size() < images.size())
492 CX_LOG_ERROR() <<
"ViewWrapper2D::setImagesSW: mSliceReps.size() < images.size()";
495 for(
int i = 0; i < images.size(); ++i)
497 mSliceReps[i]->setImage(images[i]);
505 this->updateItemsFromViewGroup();
510 mOrientationAnnotationRep->setVisible(
settings()->value(
"View/showOrientationAnnotation").value<bool>());
513 mDataRepContainer->updateSettings();
517 bool isOblique = mSliceProxy->getComputer().getOrientationType() ==
otOBLIQUE;
518 bool useCrosshair =
settings()->
value(
"View2D/showToolCrosshair",
true).toBool();
519 mToolRep2D->setUseCrosshair(!isOblique && useCrosshair);
520 mToolRep2D->setCrosshairColor(
settings()->value(
"View2D/toolCrossHairColor").value<QColor>());
521 mToolRep2D->setTooltipLineColor(
settings()->value(
"View2D/toolColor").value<QColor>());
522 mToolRep2D->setTooltipPointColor(
settings()->value(
"View/toolTipPointColor").value<QColor>());
523 mToolRep2D->setToolOffsetPointColor(
settings()->value(
"View/toolOffsetPointColor").value<QColor>());
524 mToolRep2D->setToolOffsetLineColor(
settings()->value(
"View/toolOffsetLineColor").value<QColor>());
527 this->applyViewFollower();
544 this->dataAdded(data);
546 this->dataRemoved(uid);
549 void ViewWrapper2D::dataAdded(
DataPtr data)
551 if (boost::dynamic_pointer_cast<Image>(data))
553 this->imageAdded(boost::dynamic_pointer_cast<Image>(data));
557 mDataRepContainer->addData(data);
562 void ViewWrapper2D::dataRemoved(
const QString& uid)
564 mDataRepContainer->removeData(uid);
568 void ViewWrapper2D::activeToolChangedSlot()
572 mSliceProxy->setTool(controllingTool);
579 void ViewWrapper2D::mousePressSlot(
int x,
int y, Qt::MouseButtons buttons)
581 if (buttons & Qt::LeftButton)
583 Vector3D clickPos_vp = qvp2vp(QPoint(x,y));
584 moveManualTool(clickPos_vp,
Vector3D(0,0,0));
593 void ViewWrapper2D::mouseMoveSlot(
int x,
int y, Qt::MouseButtons buttons)
595 if (buttons & Qt::LeftButton)
597 Vector3D clickPos_vp = qvp2vp(QPoint(x,y));
598 moveManualTool(clickPos_vp, clickPos_vp - mLastClickPos_vp);
608 this->shiftAxisPos(delta_vp);
609 mLastClickPos_vp = vp;
616 void ViewWrapper2D::mouseWheelSlot(
int x,
int y,
int delta,
int orientation, Qt::MouseButtons buttons)
619 double val = log10(mZoom2D->getFactor());
620 val += delta / 120.0 / 20.0;
621 double newZoom = pow(10.0, val);
623 mZoom2D->setFactor(newZoom);
631 Vector3D ViewWrapper2D::qvp2vp(QPoint pos_qvp)
633 QSize size = mView->size();
634 Vector3D pos_vp(pos_qvp.x(), size.height()-1 - pos_qvp.y(), 0.0);
641 void ViewWrapper2D::shiftAxisPos(
Vector3D delta_vp)
643 delta_vp = -delta_vp;
650 Vector3D delta_s = vpMs.inv().vector(delta_vp);
652 Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);
657 tool->set_prMt(MD * prMt);
663 void ViewWrapper2D::setAxisPos(
Vector3D click_vp)
672 Vector3D tool_t(0, 0, tool->getTooltipOffset());
673 Vector3D tool_s = (sMr * rMpr * prMt).coord(tool_t);
677 Vector3D click_s = vpMs.inv().coord(click_vp);
680 Vector3D cross_s(click_s[0], click_s[1], tool_s[2]);
682 Vector3D delta_s = cross_s - tool_s;
683 Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);
688 tool->set_prMt(MD * prMt);
694 PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
695 mSlicePlanes3DMarker->setProxy(plane, proxy);
700 mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy, this->getViewport_s());
702 mView->addRep(mSlicePlanes3DMarker);
710 void ViewWrapper2D::showManualToolSlot(
bool visible)