43 #include <vtkCamera.h>
44 #include <vtkRenderer.h>
45 #include <vtkRenderWindow.h>
48 #include <QActionGroup>
50 #include <QMouseEvent>
51 #include <QWheelEvent>
85 #include "vtkRenderWindowInteractor.h"
94 mOrientationActionGroup(new QActionGroup(view.get()))
100 mView->getRenderWindow()->GetInteractor()->Disable();
101 mView->getRenderer()->GetActiveCamera()->SetParallelProjection(
true);
102 double clipDepth = 1.0;
103 double length = clipDepth*10;
104 mView->getRenderer()->GetActiveCamera()->SetPosition(0,0,length);
105 mView->getRenderer()->GetActiveCamera()->SetClippingRange(length-clipDepth, length+0.1);
106 connect(
settings(), SIGNAL(valueChangedFor(QString)),
this, SLOT(settingsChangedSlot(QString)));
112 mDataRepContainer->setSliceProxy(mSliceProxy);
113 mDataRepContainer->setView(mView);
116 mViewFollower->setSliceProxy(mSliceProxy);
121 connect(mZoom2D.get(), SIGNAL(zoomChanged()),
this, SLOT(viewportChanged()));
124 connect(
mServices->getToolManager().get(), SIGNAL(activeToolChanged(
const QString&)),
this, SLOT(activeToolChangedSlot()));
125 connect(mView.get(), SIGNAL(resized(QSize)),
this, SLOT(viewportChanged()));
126 connect(mView.get(), SIGNAL(shown()),
this, SLOT(showSlot()));
127 connect(mView.get(), SIGNAL(mousePress(
int,
int, Qt::MouseButtons)),
this, SLOT(mousePressSlot(
int,
int, Qt::MouseButtons)));
128 connect(mView.get(), SIGNAL(mouseMove(
int,
int, Qt::MouseButtons)),
this, SLOT(mouseMoveSlot(
int,
int, Qt::MouseButtons)));
129 connect(mView.get(), SIGNAL(mouseWheel(
int,
int,
int,
int, Qt::MouseButtons)),
this, SLOT(mouseWheelSlot(
int,
int,
int,
int, Qt::MouseButtons)));
131 this->activeToolChangedSlot();
141 void ViewWrapper2D::appendToContextMenu(QMenu& contextMenu)
143 QAction* obliqueAction =
new QAction(
"Oblique", &contextMenu);
144 obliqueAction->setCheckable(
true);
146 obliqueAction->setChecked(getOrientationType() ==
otOBLIQUE);
147 connect(obliqueAction, SIGNAL(triggered()),
this, SLOT(orientationActionSlot()));
149 QAction* ortogonalAction =
new QAction(
"Ortogonal", &contextMenu);
150 ortogonalAction->setCheckable(
true);
152 ortogonalAction->setChecked(getOrientationType() ==
otORTHOGONAL);
153 connect(ortogonalAction, SIGNAL(triggered()),
this, SLOT(orientationActionSlot()));
156 mOrientationActionGroup->addAction(obliqueAction);
157 mOrientationActionGroup->addAction(ortogonalAction);
159 contextMenu.addSeparator();
160 contextMenu.addAction(obliqueAction);
161 contextMenu.addAction(ortogonalAction);
162 contextMenu.addSeparator();
164 mZoom2D->addActionsToMenu(&contextMenu);
171 mZoom2D->setGroupData(group);
172 connect(group.get(), SIGNAL(optionsChanged()),
this, SLOT(optionChangedSlot()));
173 this->optionChangedSlot();
176 void ViewWrapper2D::optionChangedSlot()
189 void ViewWrapper2D::orientationActionSlot()
191 QAction* theAction =
static_cast<QAction*
>(sender());
if(!theAction)
194 ORIENTATION_TYPE type = string2enum<ORIENTATION_TYPE>(theAction->data().toString());
195 mOrientationMode->set(type);
199 void ViewWrapper2D::addReps()
203 mView->addRep(mOrientationAnnotationRep);
207 mPlaneTypeText->addText(QColor(Qt::green),
"not initialized",
Vector3D(0.98, 0.02, 0.0));
208 mView->addRep(mPlaneTypeText);
212 mDataNameText->addText(QColor(Qt::green),
"not initialized",
Vector3D(0.02, 0.02, 0.0));
213 mView->addRep(mDataNameText);
217 mToolRep2D->setSliceProxy(mSliceProxy);
218 mToolRep2D->setUseCrosshair(
true);
220 mView->addRep(mToolRep2D);
223 mPickerGlyphRep->setSliceProxy(mSliceProxy);
226 mPickerGlyphRep->setMesh(
mGroupData->getOptions().mPickerGlyph);
228 mView->addRep(mPickerGlyphRep);
231 void ViewWrapper2D::settingsChangedSlot(QString key)
233 if (key ==
"View/showDataText")
237 if (key ==
"View/showOrientationAnnotation")
241 if (key ==
"useGPU2DRendering")
245 if (key ==
"Navigation/anyplaneViewOffset")
255 void ViewWrapper2D::resetMultiSlicer()
259 mView->removeRep(mSliceRep);
263 mView->removeRep(mMultiSliceRep);
264 if (!
settings()->value(
"useGPU2DRendering").toBool())
270 mMultiSliceRep->setSliceProxy(mSliceProxy);
271 mView->addRep(mMultiSliceRep);
274 this->viewportChanged();
280 void ViewWrapper2D::viewportChanged()
282 if (!mView->getRenderer()->IsActiveCameraCreated())
285 mView->setZoomFactor(mZoom2D->getFactor());
287 double viewHeight = mView->getViewport_s().range()[1];
288 mView->getRenderer()->GetActiveCamera()->SetParallelScale(viewHeight / 2);
292 double clipDepth = 2.0;
293 double length = clipDepth*10;
294 clipDepth = viewHeight/120 + 1.5;
295 mView->getRenderer()->GetActiveCamera()->SetPosition(0,0,length);
296 mView->getRenderer()->GetActiveCamera()->SetClippingRange(length-clipDepth, length+0.1);
298 mSliceProxy->setToolViewportHeight(viewHeight);
299 double anyplaneViewOffset =
settings()->
value(
"Navigation/anyplaneViewOffset").toDouble();
300 mSliceProxy->initializeFromPlane(mSliceProxy->getComputer().getPlaneType(),
false,
Vector3D(0, 0, 1),
true, viewHeight, anyplaneViewOffset,
true);
302 DoubleBoundingBox3D BB_vp = getViewport();
304 DoubleBoundingBox3D BB_s =
transform(vpMs.inv(), BB_vp);
305 PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
307 mToolRep2D->setViewportData(vpMs, BB_vp);
308 if (mSlicePlanes3DMarker)
310 mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy, BB_s);
313 mViewFollower->setView(BB_s);
318 DoubleBoundingBox3D ViewWrapper2D::getViewport()
const
320 QSize size = mView->size();
322 Vector3D p1_d(size.width(), size.height(), 0);
323 DoubleBoundingBox3D BB_vp(p0_d, p1_d);
327 void ViewWrapper2D::showSlot()
329 activeToolChangedSlot();
338 double viewHeight = mView->getViewport_s().range()[1];
339 mSliceProxy->initializeFromPlane(plane,
false,
Vector3D(0, 0, 1),
true, viewHeight, 0.25);
342 mOrientationAnnotationRep->setSliceProxy(mSliceProxy);
345 this->changeOrientationType(getOrientationType());
347 bool isOblique = mSliceProxy->getComputer().getOrientationType() ==
otOBLIQUE;
348 mToolRep2D->setUseCrosshair(!isOblique);
355 ORIENTATION_TYPE ViewWrapper2D::getOrientationType()
const
357 return mSliceProxy->getComputer().getOrientationType();
363 void ViewWrapper2D::orientationModeChanged()
365 ORIENTATION_TYPE type =
static_cast<ORIENTATION_TYPE
>(mOrientationMode->get().toInt());
367 if (type == this->getOrientationType())
372 SliceComputer computer = mSliceProxy->getComputer();
373 computer.switchOrientationMode(type);
375 PLANE_TYPE plane = computer.getPlaneType();
378 mSliceProxy->setComputer(computer);
383 void ViewWrapper2D::changeOrientationType(ORIENTATION_TYPE type)
385 mOrientationMode->set(type);
395 void ViewWrapper2D::imageAdded(
ImagePtr image)
411 image = images.back();
415 Vector3D c = image->get_rMd().coord(image->boundingBox().center());
416 mSliceProxy->setDefaultCenter(c);
420 if (
settings()->value(
"useGPU2DRendering").toBool())
422 this->resetMultiSlicer();
429 mView->removeRep(mMultiSliceRep);
430 mMultiSliceRep.reset();
436 mSliceRep->setSliceProxy(mSliceProxy);
437 mView->addRep(mSliceRep);
440 QStringList textList;
441 mSliceRep->setImage(image);
445 for (
unsigned i = 0; i < mesh.size(); ++i)
448 textList << image->getName();
449 text = textList.join(
"\n");
453 bool show =
settings()->
value(
"View/showDataText").value<
bool>();
458 mDataNameText->setText(0, text);
459 mDataNameText->setFontSize(std::max(12, 22 - 2 * text.size()));
461 mOrientationAnnotationRep->setVisible(
settings()->value(
"View/showOrientationAnnotation").value<bool>());
463 mDataRepContainer->updateSettings();
469 void ViewWrapper2D::imageRemoved(
const QString& uid)
480 this->dataAdded(data);
482 this->dataRemoved(uid);
486 void ViewWrapper2D::dataAdded(
DataPtr data)
488 if (boost::dynamic_pointer_cast<Image>(data))
490 this->imageAdded(boost::dynamic_pointer_cast<Image>(data));
494 mDataRepContainer->addData(data);
499 void ViewWrapper2D::dataRemoved(
const QString& uid)
501 mDataRepContainer->removeData(uid);
505 void ViewWrapper2D::activeToolChangedSlot()
508 mSliceProxy->setTool(activeTool);
513 if (mOrientationMode)
514 disconnect(mOrientationMode.get(), SIGNAL(changed()),
this, SLOT(orientationModeChanged()));
515 mOrientationMode = value;
516 if (mOrientationMode)
517 connect(mOrientationMode.get(), SIGNAL(changed()),
this, SLOT(orientationModeChanged()));
519 orientationModeChanged();
526 void ViewWrapper2D::mousePressSlot(
int x,
int y, Qt::MouseButtons buttons)
528 if (buttons & Qt::LeftButton)
532 setAxisPos(qvp2vp(QPoint(x,y)));
536 mClickPos = qvp2vp(QPoint(x,y));
537 this->shiftAxisPos(
Vector3D(0,0,0));
546 void ViewWrapper2D::mouseMoveSlot(
int x,
int y, Qt::MouseButtons buttons)
548 if (buttons & Qt::LeftButton)
552 setAxisPos(qvp2vp(QPoint(x,y)));
557 this->shiftAxisPos(p - mClickPos);
567 void ViewWrapper2D::mouseWheelSlot(
int x,
int y,
int delta,
int orientation, Qt::MouseButtons buttons)
570 double val = log10(mZoom2D->getFactor());
571 val += delta / 120.0 / 20.0;
572 double newZoom = pow(10.0, val);
574 mZoom2D->setFactor(newZoom);
582 Vector3D ViewWrapper2D::qvp2vp(QPoint pos_qvp)
584 QSize size = mView->size();
585 Vector3D pos_vp(pos_qvp.x(), size.height() - pos_qvp.y(), 0.0);
592 void ViewWrapper2D::shiftAxisPos(
Vector3D delta_vp)
594 delta_vp = -delta_vp;
601 Vector3D delta_s = vpMs.inv().vector(delta_vp);
603 Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);
608 tool->set_prMt(MD * prMt);
614 void ViewWrapper2D::setAxisPos(
Vector3D click_vp)
623 Vector3D tool_t(0, 0, tool->getTooltipOffset());
624 Vector3D tool_s = (sMr * rMpr * prMt).coord(tool_t);
628 Vector3D click_s = vpMs.inv().coord(click_vp);
631 Vector3D cross_s(click_s[0], click_s[1], tool_s[2]);
633 Vector3D delta_s = cross_s - tool_s;
634 Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);
639 tool->set_prMt(MD * prMt);
645 PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
646 mSlicePlanes3DMarker->setProxy(plane, proxy);
650 mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy,
transform(vpMs.inv(), BB_vp));
652 mView->addRep(mSlicePlanes3DMarker);
QString qstring_cast(const T &val)
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
boost::shared_ptr< class ViewGroupData > ViewGroupDataPtr
static SliceProxyPtr create(PatientModelServicePtr dataManager)
boost::shared_ptr< class SlicePlanesProxy > SlicePlanesProxyPtr
virtual void setOrientationMode(SyncedValuePtr value)
otOBLIQUE
orient planes relative to the tool space
boost::shared_ptr< class VisServices > VisServicesPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual ViewPtr getView()
boost::shared_ptr< class Image > ImagePtr
Superclass for ViewWrappers.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
static Texture3DSlicerRepPtr New(const QString &uid="")
boost::shared_ptr< class View > ViewPtr
virtual void setViewGroup(ViewGroupDataPtr group)
static DataViewProperties createSlice2D()
static SlicePlanes3DMarkerIn2DRepPtr New(const QString &uid="")
static OrientationAnnotationSmartRepPtr New(const QString &uid="")
virtual void setViewGroup(ViewGroupDataPtr group)
boost::shared_ptr< class Data > DataPtr
virtual void updateView()
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
otORTHOGONAL
orient planes relative to the image/reference space.
static SyncedValuePtr create(QVariant val=QVariant())
ViewGroupDataPtr mGroupData
static SliceRepSWPtr New(const QString &uid="")
Transform3D createTransformTranslate(const Vector3D &translation)
virtual void dataViewPropertiesChangedSlot(QString uid)
virtual void initializePlane(PLANE_TYPE plane)
Settings * settings()
Shortcut for accessing the settings instance.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
virtual void setSlicePlanesProxy(SlicePlanesProxyPtr proxy)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
static GeometricRep2DPtr New(const QString &uid="")
QStringList getAllDataNames(DataViewProperties properties) const
RealScalar length() const
static DisplayTextRepPtr New(const QString &uid="")
boost::shared_ptr< class SyncedValue > SyncedValuePtr
void connectContextMenu(ViewPtr view)
static ViewFollowerPtr create(PatientModelServicePtr dataManager)
ViewWrapper2D(ViewPtr view, VisServicesPtr backend)
boost::shared_ptr< class Tool > ToolPtr