16 #include "boost/bind.hpp"
17 #include "boost/function.hpp"
22 #include <vtkRenderWindow.h>
23 #include <vtkRenderer.h>
24 #include <vtkImageData.h>
97 view->getRenderer()->GetActiveCamera()->SetClippingRange(0.1, 2000);
98 if (!view->getRenderWindow()->GetStereoCapableWindow())
99 view->getRenderWindow()->StereoCapableWindowOn();
104 QString index = QString::number(startIndex);
105 QColor background =
settings()->
value(
"backgroundColor").value<QColor>();
106 mView->setBackgroundColor(background);
108 view->getRenderer()->GetActiveCamera()->SetParallelProjection(
false);
111 this->initializeMultiVolume3DRepProducer();
114 mLandmarkRep->setGraphicsSize(
settings()->value(
"View3D/sphereRadius").toDouble());
115 mLandmarkRep->setLabelSize(
settings()->value(
"View3D/labelSize").toDouble());
119 connect(mPickerRep.get(), SIGNAL(pointPicked(
Vector3D)),
this, SLOT(pickerRepPointPickedSlot(
Vector3D)));
121 mPickerRep->setSphereRadius(
settings()->value(
"View3D/sphereRadius").toDouble());
122 mPickerRep->setEnabled(
false);
123 mView->addRep(mPickerRep);
124 connect(
mServices->tracking().get(), SIGNAL(activeToolChanged(
const QString&)),
this, SLOT(activeToolChangedSlot()));
125 this->activeToolChangedSlot();
130 this->updateMetricNamesRep();
134 this->toolsAvailableSlot();
139 mView->addRep(mAnnotationMarker);
146 this->setStereoEyeAngle(
settings()->value(
"View3D/eyeAngle").toDouble());
149 if(
settings()->value(
"View3D/depthPeeling").toBool())
150 this->setTranslucentRenderingToDepthPeeling(
settings()->value(
"View3D/depthPeeling").toBool());
160 mMultiVolume3DRepProducer->removeRepsFromView();
164 void ViewWrapper3D::initializeMultiVolume3DRepProducer()
167 reportError(
"Missing View in initializeMultiVolume3DRepProducer");
169 if (!mMultiVolume3DRepProducer)
172 connect(mMultiVolume3DRepProducer.get(), SIGNAL(imagesChanged()),
this, SLOT(updateView()));
173 mMultiVolume3DRepProducer->setView(mView);
176 mMultiVolume3DRepProducer->setMaxRenderSize(
settings()->value(
"View3D/maxRenderSize").toInt());
177 mMultiVolume3DRepProducer->setVisualizerType(
settings()->value(
"View3D/ImageRender3DVisualizer").toString());
184 if (key ==
"View3D/stereoType")
188 if (key ==
"View3D/eyeAngle")
190 this->setStereoEyeAngle(
settings()->value(
"View3D/eyeAngle").toDouble());
192 if (key ==
"backgroundColor")
194 QColor background =
settings()->
value(
"backgroundColor").value<QColor>();
195 mView->setBackgroundColor(background);
197 if (( key==
"View3D/ImageRender3DVisualizer" )||( key==
"View3D/maxRenderSize" ))
199 this->initializeMultiVolume3DRepProducer();
201 if ((key ==
"View/showDataText")
202 || (key ==
"View/showOrientationAnnotation"))
206 if ((key ==
"View3D/annotationModelSize" )||( key ==
"View3D/annotationModel"))
208 QString annotationFile =
settings()->
value(
"View3D/annotationModel").toString();
210 mAnnotationMarker->setSize(
settings()->value(
"View3D/annotationModelSize").toDouble());
212 if (key ==
"View3D/showManualTool")
214 this->toolsAvailableSlot();
216 if ((key ==
"View3D/sphereRadius" )
217 ||( key ==
"View3D/labelSize" )
218 ||( key ==
"View/showLabels")
219 ||( key ==
"View/showMetricNamesInCorner"))
221 for (RepMap::iterator iter = mDataReps.begin(); iter != mDataReps.end(); ++iter)
223 this->readDataRepSettings(iter->second);
226 this->updateMetricNamesRep();
228 this->toolsAvailableSlot();
229 mLandmarkRep->setGraphicsSize(
settings()->value(
"View3D/sphereRadius").toDouble());
230 mLandmarkRep->setLabelSize(
settings()->value(
"View3D/labelSize").toDouble());
232 if (key ==
"View3D/depthPeeling")
233 this->setTranslucentRenderingToDepthPeeling(
settings()->value(
"View3D/depthPeeling").toBool());
236 void ViewWrapper3D::updateMetricNamesRep()
238 bool enabled =
settings()->
value(
"View/showMetricNamesInCorner").value<
bool>();
245 mView->addRep(mMetricNames);
253 mView->removeRep(mMetricNames);
254 mMetricNames.reset();
258 void ViewWrapper3D::pickerRepPointPickedSlot(
Vector3D p_r)
264 void ViewWrapper3D::pickerRepDataPickedSlot(QString uid)
269 void ViewWrapper3D::appendToContextMenu(QMenu& contextMenu)
271 QAction* slicePlanesAction = NULL;
272 QAction* fillSlicePlanesAction = NULL;
273 if (mSlicePlanes3DRep)
275 slicePlanesAction =
new QAction(
"Show Slice Planes", &contextMenu);
276 slicePlanesAction->setCheckable(
true);
277 slicePlanesAction->setChecked(mSlicePlanes3DRep->getProxy()->getVisible());
278 slicePlanesAction->setToolTip(
"Visialize the outline of the 2D views in 3D");
279 connect(slicePlanesAction, SIGNAL(triggered(
bool)),
this, SLOT(showSlicePlanesActionSlot(
bool)));
281 fillSlicePlanesAction =
new QAction(
"Fill Slice Planes", &contextMenu);
282 fillSlicePlanesAction->setCheckable(
true);
283 fillSlicePlanesAction->setEnabled(mSlicePlanes3DRep->getProxy()->getVisible());
284 fillSlicePlanesAction->setChecked(mSlicePlanes3DRep->getProxy()->getDrawPlanes());
285 slicePlanesAction->setToolTip(
"Fill the visualized 2D views with color");
286 connect(fillSlicePlanesAction, SIGNAL(triggered(
bool)),
this, SLOT(fillSlicePlanesActionSlot(
bool)));
289 QAction* resetCameraAction =
new QAction(
"Reset Camera (r)", &contextMenu);
290 resetCameraAction->setToolTip(
"Zoom out, and show all objects in the view");
291 connect(resetCameraAction, SIGNAL(triggered()),
this, SLOT(resetCameraActionSlot()));
293 QAction* centerImageAction =
new QAction(
"Center to image", &contextMenu);
294 centerImageAction->setToolTip(
"Move view to show center of active image in all views (no zoom)");
295 connect(centerImageAction, SIGNAL(triggered()),
this, SLOT(centerImageActionSlot()));
297 QAction* centerToolAction =
new QAction(
"Center to tool", &contextMenu);
298 centerToolAction->setToolTip(
"Move view to show active tool in all views (no zoom)");
299 connect(centerToolAction, SIGNAL(triggered()),
this, SLOT(centerToolActionSlot()));
301 QAction* showAxesAction =
new QAction(
"Show Coordinate Axes", &contextMenu);
302 showAxesAction->setCheckable(
true);
303 showAxesAction->setChecked(mShowAxes);
304 showAxesAction->setToolTip(
"Show coordinate axes for all objects in 3D scene.\n"
305 "Axes are placed in obejct origin.\n"
306 "Red = X, Green = Y, Blue = Z");
307 connect(showAxesAction, SIGNAL(triggered(
bool)),
this, SLOT(showAxesActionSlot(
bool)));
309 QAction* showManualTool =
new QAction(
"Show Manual Tool 3D", &contextMenu);
310 showManualTool->setCheckable(
true);
311 showManualTool->setChecked(
settings()->value(
"View3D/showManualTool").toBool());
312 showManualTool->setToolTip(
"Turn on/off visualization of the 3D vire cross");
313 connect(showManualTool, SIGNAL(triggered(
bool)),
this, SLOT(showManualToolSlot(
bool)));
315 QAction* showOrientation =
new QAction(
"Show Orientation", &contextMenu);
316 showOrientation->setCheckable(
true);
317 showOrientation->setChecked(mAnnotationMarker->getVisible());
318 showOrientation->setToolTip(
"Turn on/off visualization of the figure in the upper left corner in 3D,\n"
319 "and the orientation letters on the sides in 2D");
320 connect(showOrientation, SIGNAL(triggered(
bool)),
this, SLOT(showOrientationSlot(
bool)));
322 QAction* showToolPath =
new QAction(
"Show Tool Path", &contextMenu);
323 showToolPath->setCheckable(
true);
324 showToolPath->setChecked(
settings()->value(
"showToolPath").toBool());
325 showToolPath->setToolTip(
"Paint a line in 3D where the tool have been, as connected dots.\n"
326 "Turn off to reset");
327 connect(showToolPath, SIGNAL(triggered(
bool)),
this, SLOT(showToolPathSlot(
bool)));
329 QMenu* show3DSlicesMenu =
new QMenu(
"Show 3D slices");
330 show3DSlicesMenu->setToolTip(
"Visualize the 2D views in 3D for the selected image");
333 QMenu* showSlicesMenu =
new QMenu(
"Slice Type", &contextMenu);
334 showSlicesMenu->setToolTip(
"Specify which 2D slices to show in 3D,\n"
335 "when 3D sclices is turned on");
336 this->createSlicesActions(showSlicesMenu);
338 QAction* showRefTool =
new QAction(
"Show Reference Tool", &contextMenu);
339 showRefTool->setDisabled(
true);
340 showRefTool->setCheckable(
true);
341 showRefTool->setToolTip(
"Visualize the tool set as reference in 3D");
345 showRefTool->setText(
"Show " + refTool->getName());
346 showRefTool->setEnabled(
true);
347 showRefTool->setChecked(RepContainer(mView->getReps()).findFirst<ToolRep3D>(refTool) ?
true :
false);
348 connect(showRefTool, SIGNAL(toggled(
bool)),
this, SLOT(showRefToolSlot(
bool)));
351 contextMenu.addSeparator();
352 contextMenu.addMenu(show3DSlicesMenu);
353 contextMenu.addMenu(showSlicesMenu);
354 contextMenu.addSeparator();
355 contextMenu.addAction(resetCameraAction);
356 contextMenu.addAction(centerImageAction);
357 contextMenu.addAction(centerToolAction);
358 contextMenu.addAction(showAxesAction);
359 contextMenu.addAction(showOrientation);
360 contextMenu.addSeparator();
361 contextMenu.addAction(showManualTool);
362 contextMenu.addAction(showRefTool);
364 contextMenu.addAction(showToolPath);
365 contextMenu.addSeparator();
366 if (slicePlanesAction)
367 contextMenu.addAction(slicePlanesAction);
368 if (fillSlicePlanesAction)
369 contextMenu.addAction(fillSlicePlanesAction);
372 void ViewWrapper3D::createSlicesActions(QWidget* parent)
375 this->createSlicesAction(PlaneTypeCollection(
ptAXIAL), parent);
376 this->createSlicesAction(PlaneTypeCollection(
ptCORONAL), parent);
377 this->createSlicesAction(PlaneTypeCollection(
ptSAGITTAL), parent);
378 this->createSlicesAction(PlaneTypeCollection(
ptANYPLANE), parent);
380 this->createSlicesAction(PlaneTypeCollection(
ptRADIALPLANE), parent);
381 this->createSlicesAction(PlaneTypeCollection(
ptSIDEPLANE), parent);
382 this->createSlicesAction(PlaneTypeCollection(
ptTOOLSIDEPLANE), parent);
385 QAction* ViewWrapper3D::createSlicesAction(PlaneTypeCollection planes, QWidget* parent)
387 QString title = planes.toString();
388 QString active =
mGroupData->getSliceDefinitions().toString();
390 QAction* action =
new QAction(title, parent);
391 connect(action, SIGNAL(triggered()),
this, SLOT(showSlices()));
392 action->setData(title);
393 action->setCheckable(
true);
394 action->setChecked(active == title);
396 parent->addAction(action);
400 void ViewWrapper3D::showSlices()
402 QAction* action =
dynamic_cast<QAction*
>(sender());
408 if (!action->isChecked())
409 mGroupData->setSliceDefinitions(PlaneTypeCollection());
420 mView->getRenderer()->SetActiveCamera(
mGroupData->getCamera3D()->getCamera());
423 this->setStereoEyeAngle(
settings()->value(
"View3D/eyeAngle").toDouble());
424 this->optionChangedSlot();
428 void ViewWrapper3D::showToolPathSlot(
bool checked)
440 activeRep3D->getTracer()->stop();
441 activeRep3D->getTracer()->clear();
448 void ViewWrapper3D::showAxesActionSlot(
bool checked)
450 if (mShowAxes == checked)
456 for (
unsigned i=0; i<mAxis.size(); ++i)
457 mView->removeRep(mAxis[i]->mRep);
466 axis.reset(
new AxisConnector(CoordinateSystem(
csREF),
mServices->spaceProvider()));
467 axis->mRep->setAxisLength(0.12);
468 axis->mRep->setShowAxesLabels(
true);
469 axis->mRep->setCaption(
"ref",
Vector3D(1, 0, 0));
470 axis->mRep->setFontSize(0.03);
471 mAxis.push_back(axis);
474 std::vector<DataPtr> data =
mGroupData->getData();
475 for (
unsigned i = 0; i < data.size(); ++i)
477 axis.reset(
new AxisConnector(CoordinateSystem(
csDATA, data[i]->getUid()),
mServices->spaceProvider()));
478 axis->mRep->setAxisLength(0.08);
479 axis->mRep->setShowAxesLabels(
false);
480 axis->mRep->setCaption(data[i]->getName(),
Vector3D(1, 0, 0));
481 axis->mRep->setFontSize(0.03);
482 mAxis.push_back(axis);
487 TrackingService::ToolMap::iterator iter;
488 for (iter = tools.begin(); iter != tools.end(); ++iter)
492 axis.reset(
new AxisConnector(CoordinateSystem(
csTOOL, tool->getUid()),
mServices->spaceProvider()));
493 axis->mRep->setAxisLength(0.08);
494 axis->mRep->setShowAxesLabels(
false);
495 axis->mRep->setCaption(
"t",
Vector3D(0.7, 1, 0.7));
496 axis->mRep->setFontSize(0.03);
497 axis->connectTo(tool);
500 mAxis.push_back(axis);
502 axis.reset(
new AxisConnector(CoordinateSystem(
csSENSOR, tool->getUid()),
mServices->spaceProvider()));
503 axis->mRep->setAxisLength(0.05);
504 axis->mRep->setShowAxesLabels(
false);
505 axis->mRep->setCaption(
"s",
Vector3D(1, 1, 0));
506 axis->mRep->setFontSize(0.03);
507 axis->connectTo(tool);
508 axis->mergeWith(mToolListener);
509 mAxis.push_back(axis);
512 for (
unsigned i=0; i<mAxis.size(); ++i)
513 mView->addRep(mAxis[i]->mRep);
517 void ViewWrapper3D::showManualToolSlot(
bool visible)
522 void ViewWrapper3D::showOrientationSlot(
bool visible)
528 void ViewWrapper3D::resetCameraActionSlot()
530 mView->getRenderer()->ResetCamera();
532 this->setStereoEyeAngle(
settings()->value(
"View3D/eyeAngle").toDouble());
538 camera3D->setView(mView);
543 void ViewWrapper3D::centerImageActionSlot()
549 void ViewWrapper3D::centerToolActionSlot()
552 nav->centerToTooltip();
555 void ViewWrapper3D::showSlicePlanesActionSlot(
bool checked)
557 if (!mSlicePlanes3DRep)
559 mSlicePlanes3DRep->getProxy()->setVisible(checked);
563 void ViewWrapper3D::fillSlicePlanesActionSlot(
bool checked)
565 if (!mSlicePlanes3DRep)
567 mSlicePlanes3DRep->getProxy()->setDrawPlanes(checked);
576 this->addVolumeDataRep(data);
578 this->removeVolumeDataRep(uid);
580 this->updateSlices();
585 void ViewWrapper3D::addVolumeDataRep(
DataPtr data)
589 ImagePtr image = boost::dynamic_pointer_cast<Image>(data);
592 mMultiVolume3DRepProducer->addImage(image);
596 if (!mDataReps.count(data->getUid()))
598 RepPtr rep = this->createDataRep3D(data);
601 mDataReps[data->getUid()] = rep;
608 void ViewWrapper3D::removeVolumeDataRep(QString uid)
610 mMultiVolume3DRepProducer->removeImage(uid);
611 if (mDataReps.count(uid))
613 mView->removeRep(mDataReps[uid]);
614 mDataReps.erase(uid);
623 if (boost::dynamic_pointer_cast<Mesh>(data))
626 rep->setMesh(boost::dynamic_pointer_cast<Mesh>(data));
629 else if (boost::dynamic_pointer_cast<TrackedStream>(data))
631 TrackedStreamPtr trackedStream = boost::dynamic_pointer_cast<TrackedStream>(data);
632 return this->createTrackedStreamRep(trackedStream);
646 if(!trackedStream->hasVideo())
653 if(trackedStream->is3D())
656 rep->setTrackedStream(trackedStream);
659 else if (trackedStream->is2D())
662 rep->setTrackedStream(trackedStream);
667 reportWarning(
"ViewWrapper3D::createDataRep3D. TrackedStream is not 2D or 3D");
676 if (boost::dynamic_pointer_cast<PointMetric>(data))
678 else if (boost::dynamic_pointer_cast<FrameMetric>(data))
680 else if (boost::dynamic_pointer_cast<ToolMetric>(data))
682 else if (boost::dynamic_pointer_cast<DistanceMetric>(data))
684 else if (boost::dynamic_pointer_cast<AngleMetric>(data))
686 else if (boost::dynamic_pointer_cast<PlaneMetric>(data))
688 else if (boost::dynamic_pointer_cast<DonutMetric>(data))
690 else if (boost::dynamic_pointer_cast<CustomMetric>(data))
692 else if (boost::dynamic_pointer_cast<SphereMetric>(data))
694 else if (boost::dynamic_pointer_cast<RegionOfInterestMetric>(data))
699 this->readDataRepSettings(rep);
700 rep->setDataMetric(boost::dynamic_pointer_cast<DataMetric>(data));
708 void ViewWrapper3D::readDataRepSettings(
RepPtr rep)
714 val->setGraphicsSize(
settings()->value(
"View3D/sphereRadius").toDouble());
715 val->setShowLabel(
settings()->value(
"View/showLabels").toBool());
716 val->setLabelSize(
settings()->value(
"View3D/labelSize").toDouble());
717 val->setShowAnnotation(!
settings()->value(
"View/showMetricNamesInCorner").toBool());
730 void ViewWrapper3D::updateView()
737 this->updateMetricNamesRep();
739 mAnnotationMarker->setVisible(
settings()->value(
"View/showOrientationAnnotation").value<bool>());
745 manualToolRep->setToolOffsetPointColor(
settings()->
value(
"View/toolOffsetPointColor").value<QColor>());
746 manualToolRep->setToolOffsetLineColor(
settings()->
value(
"View/toolOffsetLineColor").value<QColor>());
750 void ViewWrapper3D::activeImageChangedSlot(QString uid)
758 if (!std::count(images.begin(), images.end(), image))
762 void ViewWrapper3D::showRefToolSlot(
bool checked)
767 ToolRep3DPtr refRep = RepContainer(mView->getReps()).findFirst<ToolRep3D>(refTool);
771 refRep->setTool(refTool);
775 mView->addRep(refRep);
778 mView->removeRep(refRep);
782 void ViewWrapper3D::updateSlices()
785 mView->removeRep(mSlices3DRep);
795 std::vector<PLANE_TYPE> planes =
mGroupData->getSliceDefinitions().get();
799 for (
unsigned i=0; i<planes.size(); ++i)
800 mSlices3DRep->addPlane(planes[i],
mServices->patient());
802 mSlices3DRep->setImages(images);
803 mSlices3DRep->setTool(
mServices->tracking()->getActiveTool());
804 mView->addRep(mSlices3DRep);
812 void ViewWrapper3D::activeToolChangedSlot()
817 mPickerRep->setTool(controllingTool);
819 mSlices3DRep->setTool(controllingTool);
822 void ViewWrapper3D::toolsAvailableSlot()
824 std::vector<ToolRep3DPtr> reps = RepContainer::findReps<ToolRep3D>(mView->getReps());
827 TrackingService::ToolMap::iterator iter;
828 for (iter = tools.begin(); iter != tools.end(); ++iter)
834 ToolRep3DPtr toolRep = RepContainer(mView->getReps()).findFirst<ToolRep3D>(tool);
836 std::vector<ToolRep3DPtr>::iterator oldRep = std::find(reps.begin(), reps.end(), toolRep);
837 if (oldRep!=reps.end())
843 mView->removeRep(toolRep);
850 if (
settings()->value(
"showToolPath").toBool())
851 toolRep->getTracer()->start();
854 toolRep->setSphereRadius(
settings()->value(
"View3D/sphereRadius").toDouble());
855 toolRep->setSphereRadiusInNormalizedViewport(
true);
857 toolRep->setTool(tool);
858 toolRep->setOffsetPointVisibleAtZeroOffset(
true);
859 mView->addRep(toolRep);
863 for (
unsigned i=0; i<reps.size(); ++i)
865 mView->removeRep(reps[i]);
869 void ViewWrapper3D::optionChangedSlot()
871 ViewGroupData::Options options =
mGroupData->getOptions();
873 this->showLandmarks(options.mShowLandmarks);
874 this->showPointPickerProbe(options.mShowPointPickerProbe);
875 mPickerRep->setGlyph(options.mPickerGlyph);
877 this->updateSlices();
880 void ViewWrapper3D::showLandmarks(
bool on)
882 if (mLandmarkRep->isConnectedToView(mView) == on)
887 mView->addRep(mLandmarkRep);
891 mView->removeRep(mLandmarkRep);
895 void ViewWrapper3D::showPointPickerProbe(
bool on)
897 mPickerRep->setEnabled(on);
903 mSlicePlanes3DRep->setProxy(proxy);
904 mSlicePlanes3DRep->setDynamicLabelSize(
true);
906 mSlicePlanes3DRep->getProxy()->setVisible(show);
908 mView->addRep(mSlicePlanes3DRep);
917 mView->getRenderWindow()->SetStereoTypeToCrystalEyes();
920 mView->getRenderWindow()->SetStereoTypeToInterlaced();
923 mView->getRenderWindow()->SetStereoTypeToDresden();
926 mView->getRenderWindow()->SetStereoTypeToRedBlue();
931 void ViewWrapper3D::setStereoEyeAngle(
double angle)
933 mView->getRenderer()->GetActiveCamera()->SetEyeAngle(angle);
936 void ViewWrapper3D::setTranslucentRenderingToDepthPeeling(
bool setDepthPeeling)
940 bool isDPSupported =
true;
946 reportWarning(
"GPU do not support depth peeling. Rendering of translucent surfaces is not supported");
947 isDPSupported =
false;
953 report(
"Set GPU depth peeling");
957 reportWarning(
"Error setting depth peeling. The GPU or operating system might not support it.");