CustusX  20.03-rc1
An IGT application
cxViewWrapper3D.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxViewWrapper3D.h"
13 
14 #include <vector>
15 
16 #include "boost/bind.hpp"
17 #include "boost/function.hpp"
18 
19 #include <QAction>
20 #include <QMenu>
21 
22 #include <vtkRenderWindow.h>
23 #include <vtkRenderer.h>
24 #include <vtkImageData.h>
25 
26 #include "cxView.h"
27 #include "cxSliceProxy.h"
28 #include "cxSlicerRepSW.h"
29 #include "cxToolRep2D.h"
30 #include "cxDisplayTextRep.h"
31 #include "cxLogger.h"
32 #include "cxSlicePlanes3DRep.h"
33 #include "cxMesh.h"
34 #include "cxPickerRep.h"
35 #include "cxGeometricRep.h"
36 #include "cxToolRep3D.h"
37 #include "cxTypeConversions.h"
38 #include "cxVideoSource.h"
39 #include "cxVideoRep.h"
40 #include "cxToolTracer.h"
42 #include "cxSettings.h"
43 #include "cxTrackingService.h"
44 #include "cxRepManager.h"
45 #include "cxCameraControl.h"
46 #include "cxLandmarkRep.h"
47 #include "cxPointMetricRep.h"
48 #include "cxDistanceMetricRep.h"
50 #include "cxAngleMetricRep.h"
51 #include "cxPlaneMetricRep.h"
52 #include "cxFrameMetricRep.h"
53 #include "cxToolMetricRep.h"
54 #include "cxDataMetricRep.h"
55 #include "cxDataLocations.h"
56 #include "cxManualTool.h"
57 #include "cxImage2DRep3D.h"
58 
59 #include "cxPatientModelService.h"
60 #include "cxRepContainer.h"
61 
62 
63 #include "cxData.h"
64 #include "cxAxesRep.h"
65 #include "cxViewGroup.h"
66 
67 #include "cxAngleMetric.h"
68 #include "cxDistanceMetric.h"
69 #include "cxPointMetric.h"
70 #include "cxSphereMetric.h"
71 #include "cxShapedMetric.h"
72 #include "cxCustomMetric.h"
73 #include "cxSphereMetricRep.h"
74 #include "cxDonutMetricRep.h"
75 #include "cxCustomMetricRep.h"
76 
77 #include "cxDepthPeeling.h"
78 #include "cxAxisConnector.h"
80 #include "cxMetricNamesRep.h"
81 #include "cxVisServices.h"
82 #include "cxNavigation.h"
83 
84 #include "cxTrackedStream.h"
85 #include "cxStreamRep3D.h"
86 #include "cxStream2DRep3D.h"
87 #include "cxActiveData.h"
88 
89 #include "cxSlices3DRep.h"
90 
91 namespace cx
92 {
93 
94 ViewWrapper3D::ViewWrapper3D(int startIndex, ViewPtr view, VisServicesPtr services):
95  ViewWrapper(services)
96 {
97  view->getRenderer()->GetActiveCamera()->SetClippingRange(0.1, 2000);
98  if (!view->getRenderWindow()->GetStereoCapableWindow())
99  view->getRenderWindow()->StereoCapableWindowOn(); // Just set all 3D views 3D capable
100 
101  mShowAxes = false;
102  mView = view;
103  this->connectContextMenu(mView);
104  QString index = QString::number(startIndex);
105  QColor background = settings()->value("backgroundColor").value<QColor>();
106  mView->setBackgroundColor(background);
107 
108  view->getRenderer()->GetActiveCamera()->SetParallelProjection(false);
109 // connect(settings(), SIGNAL(valueChangedFor(QString)), this, SLOT(settingsChangedSlot(QString)));
110 
111  this->initializeMultiVolume3DRepProducer();
112 
113  mLandmarkRep = LandmarkRep::New(mServices->patient());
114  mLandmarkRep->setGraphicsSize(settings()->value("View3D/sphereRadius").toDouble());
115  mLandmarkRep->setLabelSize(settings()->value("View3D/labelSize").toDouble());
116 
117  mPickerRep = PickerRep::New(mServices->patient());
118 
119  connect(mPickerRep.get(), SIGNAL(pointPicked(Vector3D)), this, SLOT(pickerRepPointPickedSlot(Vector3D)));
120 // connect(mPickerRep.get(), SIGNAL(dataPicked(QString)), this, SLOT(pickerRepDataPickedSlot(QString)));
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();
126 
127  this->ViewWrapper::addReps();
128 
129  //data name text rep
130  this->updateMetricNamesRep();
131 
132  connect(mServices->tracking().get(), &TrackingService::stateChanged, this, &ViewWrapper3D::toolsAvailableSlot);
133  connect(mServices->patient()->getActiveData().get(), &ActiveData::activeImageChanged, this, &ViewWrapper3D::activeImageChangedSlot);
134  this->toolsAvailableSlot();
135 
137  this->settingsChangedSlot("View3D/annotationModel");
138  this->settingsChangedSlot("View3D/annotationModelSize");
139  mView->addRep(mAnnotationMarker);
140 
141 //Stereo
142 // mView->getRenderWindow()->StereoCapableWindowOn(); // Moved to cxView3D
143 // connect(settings(), SIGNAL(valueChangedFor(QString)), this, SLOT(globalConfigurationFileChangedSlot(QString)));
144  //Init 3D stereo from settings
145  this->setStereoType(settings()->value("View3D/stereoType").toInt());
146  this->setStereoEyeAngle(settings()->value("View3D/eyeAngle").toDouble());
147 
148  //Only try to set depth peeling if View3D/depthPeeling == true
149  if(settings()->value("View3D/depthPeeling").toBool())
150  this->setTranslucentRenderingToDepthPeeling(settings()->value("View3D/depthPeeling").toBool());
151 
152  this->updateView();
153 }
154 
156 {
157  if (mView)
158  {
159  mView->removeReps();
160  mMultiVolume3DRepProducer->removeRepsFromView();
161  }
162 }
163 
164 void ViewWrapper3D::initializeMultiVolume3DRepProducer()
165 {
166  if (!mView)
167  reportError("Missing View in initializeMultiVolume3DRepProducer");
168 
169  if (!mMultiVolume3DRepProducer)
170  {
171  mMultiVolume3DRepProducer.reset(new MultiVolume3DRepProducer());
172  connect(mMultiVolume3DRepProducer.get(), SIGNAL(imagesChanged()), this, SLOT(updateView()));
173  mMultiVolume3DRepProducer->setView(mView);
174  }
175 
176  mMultiVolume3DRepProducer->setMaxRenderSize(settings()->value("View3D/maxRenderSize").toInt());
177  mMultiVolume3DRepProducer->setVisualizerType(settings()->value("View3D/ImageRender3DVisualizer").toString());
178 }
179 
181 {
183 
184  if (key == "View3D/stereoType")
185  {
186  this->setStereoType(settings()->value("View3D/stereoType").toInt());
187  }
188  if (key == "View3D/eyeAngle")
189  {
190  this->setStereoEyeAngle(settings()->value("View3D/eyeAngle").toDouble());
191  }
192  if (key == "backgroundColor")
193  {
194  QColor background = settings()->value("backgroundColor").value<QColor>();
195  mView->setBackgroundColor(background);
196  }
197  if (( key=="View3D/ImageRender3DVisualizer" )||( key=="View3D/maxRenderSize" ))
198  {
199  this->initializeMultiVolume3DRepProducer();
200  }
201  if ((key == "View/showDataText")
202  || (key == "View/showOrientationAnnotation"))
203  {
204  this->updateView();
205  }
206  if ((key == "View3D/annotationModelSize" )||( key == "View3D/annotationModel"))
207  {
208  QString annotationFile = settings()->value("View3D/annotationModel").toString();
209  mAnnotationMarker->setMarkerFilename(DataLocations::findConfigFilePath(annotationFile, "/models"));
210  mAnnotationMarker->setSize(settings()->value("View3D/annotationModelSize").toDouble());
211  }
212  if (key == "View3D/showManualTool")
213  {
214  this->toolsAvailableSlot();
215  }
216  if ((key == "View3D/sphereRadius" )
217  ||( key == "View3D/labelSize" )
218  ||( key == "View/showLabels")
219  ||( key == "View/showMetricNamesInCorner"))
220  {
221  for (RepMap::iterator iter = mDataReps.begin(); iter != mDataReps.end(); ++iter)
222  {
223  this->readDataRepSettings(iter->second);
224  }
225 
226  this->updateMetricNamesRep();
227 
228  this->toolsAvailableSlot();
229  mLandmarkRep->setGraphicsSize(settings()->value("View3D/sphereRadius").toDouble());
230  mLandmarkRep->setLabelSize(settings()->value("View3D/labelSize").toDouble());
231  }
232  if (key == "View3D/depthPeeling")
233  this->setTranslucentRenderingToDepthPeeling(settings()->value("View3D/depthPeeling").toBool());
234 }
235 
236 void ViewWrapper3D::updateMetricNamesRep()
237 {
238  bool enabled = settings()->value("View/showMetricNamesInCorner").value<bool>();
239 
240  if (enabled)
241  {
242  if (!mMetricNames)
243  {
244  mMetricNames = MetricNamesRep::New();
245  mView->addRep(mMetricNames);
246  }
247 
248  if (mGroupData)
249  mMetricNames->setData(mGroupData->getData());
250  }
251  else
252  {
253  mView->removeRep(mMetricNames);
254  mMetricNames.reset();
255  }
256 }
257 
258 void ViewWrapper3D::pickerRepPointPickedSlot(Vector3D p_r)
259 {
260  NavigationPtr nav = this->getNavigation();
261  nav->centerToPosition(p_r, Navigation::v2D);
262 }
263 
264 void ViewWrapper3D::pickerRepDataPickedSlot(QString uid)
265 {
266  //std::cout << "picked: " << uid << std::endl;
267 }
268 
269 void ViewWrapper3D::appendToContextMenu(QMenu& contextMenu)
270 {
271  QAction* slicePlanesAction = NULL;
272  QAction* fillSlicePlanesAction = NULL;
273  if (mSlicePlanes3DRep)
274  {
275  slicePlanesAction = new QAction("Show Slice Planes", &contextMenu);
276  slicePlanesAction->setCheckable(true);
277  slicePlanesAction->setChecked(mSlicePlanes3DRep->getProxy()->getVisible());
278  connect(slicePlanesAction, SIGNAL(triggered(bool)), this, SLOT(showSlicePlanesActionSlot(bool)));
279 
280  fillSlicePlanesAction = new QAction("Fill Slice Planes", &contextMenu);
281  fillSlicePlanesAction->setCheckable(true);
282  fillSlicePlanesAction->setEnabled(mSlicePlanes3DRep->getProxy()->getVisible());
283  fillSlicePlanesAction->setChecked(mSlicePlanes3DRep->getProxy()->getDrawPlanes());
284  connect(fillSlicePlanesAction, SIGNAL(triggered(bool)), this, SLOT(fillSlicePlanesActionSlot(bool)));
285  }
286 
287  QAction* resetCameraAction = new QAction("Reset Camera (r)", &contextMenu);
288  connect(resetCameraAction, SIGNAL(triggered()), this, SLOT(resetCameraActionSlot()));
289 
290  QAction* centerImageAction = new QAction("Center to image", &contextMenu);
291  connect(centerImageAction, SIGNAL(triggered()), this, SLOT(centerImageActionSlot()));
292 
293  QAction* centerToolAction = new QAction("Center to tool", &contextMenu);
294  connect(centerToolAction, SIGNAL(triggered()), this, SLOT(centerToolActionSlot()));
295 
296  QAction* showAxesAction = new QAction("Show Coordinate Axes", &contextMenu);
297  showAxesAction->setCheckable(true);
298  showAxesAction->setChecked(mShowAxes);
299  connect(showAxesAction, SIGNAL(triggered(bool)), this, SLOT(showAxesActionSlot(bool)));
300 
301  QAction* showManualTool = new QAction("Show Manual Tool 3D", &contextMenu);
302  showManualTool->setCheckable(true);
303  showManualTool->setChecked(settings()->value("View3D/showManualTool").toBool());
304  connect(showManualTool, SIGNAL(triggered(bool)), this, SLOT(showManualToolSlot(bool)));
305 
306  QAction* showOrientation = new QAction("Show Orientation", &contextMenu);
307  showOrientation->setCheckable(true);
308  showOrientation->setChecked(mAnnotationMarker->getVisible());
309  connect(showOrientation, SIGNAL(triggered(bool)), this, SLOT(showOrientationSlot(bool)));
310 
311  QAction* showToolPath = new QAction("Show Tool Path", &contextMenu);
312  showToolPath->setCheckable(true);
313  showToolPath->setChecked(settings()->value("showToolPath").toBool());
314  connect(showToolPath, SIGNAL(triggered(bool)), this, SLOT(showToolPathSlot(bool)));
315 
316  QMenu* show3DSlicesMenu = new QMenu("Show 3D slices");
317  mShow3DSlicesInteractor->addDataActionsOfType<Image>(show3DSlicesMenu);
318 
319  QMenu* showSlicesMenu = new QMenu("Slice Type", &contextMenu);
320  this->createSlicesActions(showSlicesMenu);
321 
322  QAction* showRefTool = new QAction("Show Reference Tool", &contextMenu);
323  showRefTool->setDisabled(true);
324  showRefTool->setCheckable(true);
325  ToolPtr refTool = mServices->tracking()->getReferenceTool();
326  if (refTool)
327  {
328  showRefTool->setText("Show " + refTool->getName());
329  showRefTool->setEnabled(true);
330  showRefTool->setChecked(RepContainer(mView->getReps()).findFirst<ToolRep3D>(refTool) ? true : false);
331  connect(showRefTool, SIGNAL(toggled(bool)), this, SLOT(showRefToolSlot(bool)));
332  }
333 
334  contextMenu.addSeparator();
335  contextMenu.addMenu(show3DSlicesMenu);
336  contextMenu.addMenu(showSlicesMenu);
337  contextMenu.addSeparator();
338  contextMenu.addAction(resetCameraAction);
339  contextMenu.addAction(centerImageAction);
340  contextMenu.addAction(centerToolAction);
341  contextMenu.addAction(showAxesAction);
342  contextMenu.addAction(showOrientation);
343  contextMenu.addSeparator();
344  contextMenu.addAction(showManualTool);
345  contextMenu.addAction(showRefTool);
346  if (showToolPath)
347  contextMenu.addAction(showToolPath);
348  contextMenu.addSeparator();
349  if (slicePlanesAction)
350  contextMenu.addAction(slicePlanesAction);
351  if (fillSlicePlanesAction)
352  contextMenu.addAction(fillSlicePlanesAction);
353 }
354 
355 void ViewWrapper3D::createSlicesActions(QWidget* parent)
356 {
357  this->createSlicesAction(PlaneTypeCollection(ptAXIAL, ptCORONAL, ptSAGITTAL), parent);
358  this->createSlicesAction(PlaneTypeCollection(ptAXIAL), parent);
359  this->createSlicesAction(PlaneTypeCollection(ptCORONAL), parent);
360  this->createSlicesAction(PlaneTypeCollection(ptSAGITTAL), parent);
361  this->createSlicesAction(PlaneTypeCollection(ptANYPLANE), parent);
362  this->createSlicesAction(PlaneTypeCollection(ptRADIALPLANE), parent);
363  this->createSlicesAction(PlaneTypeCollection(ptSIDEPLANE), parent);
364  this->createSlicesAction(PlaneTypeCollection(ptTOOLSIDEPLANE), parent);
365 }
366 
367 QAction* ViewWrapper3D::createSlicesAction(PlaneTypeCollection planes, QWidget* parent)
368 {
369  QString title = planes.toString();
370  QString active = mGroupData->getSliceDefinitions().toString();
371 
372  QAction* action = new QAction(title, parent);
373  connect(action, SIGNAL(triggered()), this, SLOT(showSlices()));
374  action->setData(title);
375  action->setCheckable(true);
376  action->setChecked(active == title);
377 
378  parent->addAction(action);
379  return action;
380 }
381 
382 void ViewWrapper3D::showSlices()
383 {
384  QAction* action = dynamic_cast<QAction*>(sender());
385  if (!action)
386  return;
387 
388  PlaneTypeCollection planes = PlaneTypeCollection::fromString(action->data().toString());
389 
390  if (!action->isChecked())
391  mGroupData->setSliceDefinitions(PlaneTypeCollection());
392  else
393  mGroupData->setSliceDefinitions(planes);
394 }
395 
397 {
399 
400  connect(group.get(), &ViewGroupData::initialized, this, &ViewWrapper3D::resetCameraActionSlot);
401  connect(group.get(), &ViewGroupData::optionsChanged, this, &ViewWrapper3D::optionChangedSlot);
402  mView->getRenderer()->SetActiveCamera(mGroupData->getCamera3D()->getCamera());
403 
404  // Set eye angle after camera change. Maybe create a cameraChangedSlot instead
405  this->setStereoEyeAngle(settings()->value("View3D/eyeAngle").toDouble());
406  this->optionChangedSlot();
407 
408 }
409 
410 void ViewWrapper3D::showToolPathSlot(bool checked)
411 {
412  ToolPtr tool = mServices->tracking()->getActiveTool();
413  ToolRep3DPtr activeRep3D = RepContainer(mView->getReps()).findFirst<ToolRep3D>(tool);
414  if (activeRep3D)
415  {
416  if(checked)
417  {
418  activeRep3D->getTracer()->start();
419  }
420  else if(!checked)
421  {
422  activeRep3D->getTracer()->stop();
423  activeRep3D->getTracer()->clear();
424  }
425  }
426 
427  settings()->setValue("showToolPath", checked);
428 }
429 
430 void ViewWrapper3D::showAxesActionSlot(bool checked)
431 {
432  if (mShowAxes == checked)
433  return;
434 
435  mShowAxes = checked;
436 
437  // clear all
438  for (unsigned i=0; i<mAxis.size(); ++i)
439  mView->removeRep(mAxis[i]->mRep);
440  mAxis.clear();
441 
442  // show all
443  if (mShowAxes)
444  {
445  AxisConnectorPtr axis;
446 
447  // reference space
448  axis.reset(new AxisConnector(CoordinateSystem(csREF), mServices->spaceProvider()));
449  axis->mRep->setAxisLength(0.12);
450  axis->mRep->setShowAxesLabels(true);
451  axis->mRep->setCaption("ref", Vector3D(1, 0, 0));
452  axis->mRep->setFontSize(0.03);
453  mAxis.push_back(axis);
454 
455  // data spaces
456  std::vector<DataPtr> data = mGroupData->getData();
457  for (unsigned i = 0; i < data.size(); ++i)
458  {
459  axis.reset(new AxisConnector(CoordinateSystem(csDATA, data[i]->getUid()), mServices->spaceProvider()));
460  axis->mRep->setAxisLength(0.08);
461  axis->mRep->setShowAxesLabels(false);
462  axis->mRep->setCaption(data[i]->getName(), Vector3D(1, 0, 0));
463  axis->mRep->setFontSize(0.03);
464  mAxis.push_back(axis);
465  }
466 
467  // tool spaces
468  TrackingService::ToolMap tools = mServices->tracking()->getTools();
469  TrackingService::ToolMap::iterator iter;
470  for (iter = tools.begin(); iter != tools.end(); ++iter)
471  {
472  ToolPtr tool = iter->second;
473 
474  axis.reset(new AxisConnector(CoordinateSystem(csTOOL, tool->getUid()), mServices->spaceProvider()));
475  axis->mRep->setAxisLength(0.08);
476  axis->mRep->setShowAxesLabels(false);
477  axis->mRep->setCaption("t", Vector3D(0.7, 1, 0.7));
478  axis->mRep->setFontSize(0.03);
479  axis->connectTo(tool);
480  SpaceListenerPtr mToolListener = axis->mListener;
481 
482  mAxis.push_back(axis);
483 
484  axis.reset(new AxisConnector(CoordinateSystem(csSENSOR, tool->getUid()), mServices->spaceProvider()));
485  axis->mRep->setAxisLength(0.05);
486  axis->mRep->setShowAxesLabels(false);
487  axis->mRep->setCaption("s", Vector3D(1, 1, 0));
488  axis->mRep->setFontSize(0.03);
489  axis->connectTo(tool);
490  axis->mergeWith(mToolListener);
491  mAxis.push_back(axis);
492  }
493 
494  for (unsigned i=0; i<mAxis.size(); ++i)
495  mView->addRep(mAxis[i]->mRep);
496  }
497 }
498 
499 void ViewWrapper3D::showManualToolSlot(bool visible)
500 {
501  settings()->setValue("View3D/showManualTool", visible);
502 }
503 
504 void ViewWrapper3D::showOrientationSlot(bool visible)
505 {
506  settings()->setValue("View/showOrientationAnnotation", visible);
507  this->updateView();
508 }
509 
510 void ViewWrapper3D::resetCameraActionSlot()
511 {
512  mView->getRenderer()->ResetCamera();
513  //Update eye angle after camera is reset
514  this->setStereoEyeAngle(settings()->value("View3D/eyeAngle").toDouble());
515 }
516 
517 NavigationPtr ViewWrapper3D::getNavigation()
518 {
519  CameraControlPtr camera3D(new CameraControl());
520  camera3D->setView(mView);
521 
522  return NavigationPtr(new Navigation(mServices, camera3D));
523 }
524 
525 void ViewWrapper3D::centerImageActionSlot()
526 {
527  NavigationPtr nav = this->getNavigation();
528  nav->centerToDataInViewGroup(mGroupData, DataViewProperties::create3D());
529 }
530 
531 void ViewWrapper3D::centerToolActionSlot()
532 {
533  NavigationPtr nav = this->getNavigation();
534  nav->centerToTooltip();
535 }
536 
537 void ViewWrapper3D::showSlicePlanesActionSlot(bool checked)
538 {
539  if (!mSlicePlanes3DRep)
540  return;
541  mSlicePlanes3DRep->getProxy()->setVisible(checked);
542  settings()->setValue("showSlicePlanes", checked);
543 }
544 
545 void ViewWrapper3D::fillSlicePlanesActionSlot(bool checked)
546 {
547  if (!mSlicePlanes3DRep)
548  return;
549  mSlicePlanes3DRep->getProxy()->setDrawPlanes(checked);
550 }
551 
553 {
554  DataPtr data = mServices->patient()->getData(uid);
555  DataViewProperties properties = mGroupData->getProperties(uid);
556 
557  if (properties.hasVolume3D())
558  this->addVolumeDataRep(data);
559  else
560  this->removeVolumeDataRep(uid);
561 
562  this->updateSlices();
563 
564  this->updateView();
565 }
566 
567 void ViewWrapper3D::addVolumeDataRep(DataPtr data)
568 {
569  if (!data)
570  return;
571  ImagePtr image = boost::dynamic_pointer_cast<Image>(data);
572  if (image)
573  {
574  mMultiVolume3DRepProducer->addImage(image);
575  }
576  else
577  {
578  if (!mDataReps.count(data->getUid()))
579  {
580  RepPtr rep = this->createDataRep3D(data);
581  if (rep)
582  {
583  mDataReps[data->getUid()] = rep;
584  mView->addRep(rep);
585  }
586  }
587  }
588 }
589 
590 void ViewWrapper3D::removeVolumeDataRep(QString uid)
591 {
592  mMultiVolume3DRepProducer->removeImage(uid);
593  if (mDataReps.count(uid))
594  {
595  mView->removeRep(mDataReps[uid]);
596  mDataReps.erase(uid);
597  }
598 }
599 
603 RepPtr ViewWrapper3D::createDataRep3D(DataPtr data)
604 {
605  if (boost::dynamic_pointer_cast<Mesh>(data))
606  {
608  rep->setMesh(boost::dynamic_pointer_cast<Mesh>(data));
609  return rep;
610  }
611  else if (boost::dynamic_pointer_cast<TrackedStream>(data))
612  {
613  TrackedStreamPtr trackedStream = boost::dynamic_pointer_cast<TrackedStream>(data);
614  return this->createTrackedStreamRep(trackedStream);
615  }
616  else
617  {
618  DataMetricRepPtr rep = this->createDataMetricRep3D(data);
619  if (rep)
620  return rep;
621  }
622 
623  return RepPtr();
624 }
625 
626 RepPtr ViewWrapper3D::createTrackedStreamRep(TrackedStreamPtr trackedStream)
627 {
628  if(!trackedStream->hasVideo())
629  {
630  connect(trackedStream.get(), &TrackedStream::streamChanged, this, &ViewWrapper3D::dataViewPropertiesChangedSlot);
631  return RepPtr();
632  }
633  else
634  disconnect(trackedStream.get(), &TrackedStream::streamChanged, this, &ViewWrapper3D::dataViewPropertiesChangedSlot);
635  if(trackedStream->is3D())
636  {
637  StreamRep3DPtr rep = StreamRep3D::New(mServices->spaceProvider(), mServices->patient());
638  rep->setTrackedStream(trackedStream);
639  return rep;
640  }
641  else if (trackedStream->is2D())
642  {
643  Stream2DRep3DPtr rep = Stream2DRep3D::New(mServices->spaceProvider());
644  rep->setTrackedStream(trackedStream);
645  return rep;
646  }
647  else
648  {
649  reportWarning("ViewWrapper3D::createDataRep3D. TrackedStream is not 2D or 3D");
650  return RepPtr();
651  }
652 }
653 
654 DataMetricRepPtr ViewWrapper3D::createDataMetricRep3D(DataPtr data)
655 {
656  DataMetricRepPtr rep;
657 
658  if (boost::dynamic_pointer_cast<PointMetric>(data))
659  rep = PointMetricRep::New();
660  else if (boost::dynamic_pointer_cast<FrameMetric>(data))
661  rep = FrameMetricRep::New();
662  else if (boost::dynamic_pointer_cast<ToolMetric>(data))
663  rep = ToolMetricRep::New();
664  else if (boost::dynamic_pointer_cast<DistanceMetric>(data))
665  rep = DistanceMetricRep::New();
666  else if (boost::dynamic_pointer_cast<AngleMetric>(data))
667  rep = AngleMetricRep::New();
668  else if (boost::dynamic_pointer_cast<PlaneMetric>(data))
669  rep = PlaneMetricRep::New();
670  else if (boost::dynamic_pointer_cast<DonutMetric>(data))
671  rep = DonutMetricRep::New();
672  else if (boost::dynamic_pointer_cast<CustomMetric>(data))
673  rep = CustomMetricRep::New();
674  else if (boost::dynamic_pointer_cast<SphereMetric>(data))
675  rep = SphereMetricRep::New();
676  else if (boost::dynamic_pointer_cast<RegionOfInterestMetric>(data))
678 
679  if (rep)
680  {
681  this->readDataRepSettings(rep);
682  rep->setDataMetric(boost::dynamic_pointer_cast<DataMetric>(data));
683  }
684  return rep;
685 }
686 
690 void ViewWrapper3D::readDataRepSettings(RepPtr rep)
691 {
692  DataMetricRepPtr val = boost::dynamic_pointer_cast<DataMetricRep>(rep);
693  if (!val)
694  return;
695 
696  val->setGraphicsSize(settings()->value("View3D/sphereRadius").toDouble());
697  val->setShowLabel(settings()->value("View/showLabels").toBool());
698  val->setLabelSize(settings()->value("View3D/labelSize").toDouble());
699  val->setShowAnnotation(!settings()->value("View/showMetricNamesInCorner").toBool());
700 }
701 
703 {
704  return this->getAllDataNames(DataViewProperties::create3D()).join("\n");
705 }
706 
708 {
709  return "3D";
710 }
711 
712 void ViewWrapper3D::updateView()
713 {
714  this->ViewWrapper::updateView();
715 
716  if (!this->getView())
717  return;
718 
719  this->updateMetricNamesRep();
720 
721  mAnnotationMarker->setVisible(settings()->value("View/showOrientationAnnotation").value<bool>());
722 
723  ToolRep3DPtr manualToolRep = RepContainer(mView->getReps()).findManualToolRep<ToolRep3D>();
724  if (manualToolRep)
725  {
726  manualToolRep->setTooltipPointColor(settings()->value("View/toolTipPointColor").value<QColor>());
727  manualToolRep->setToolOffsetPointColor(settings()->value("View/toolOffsetPointColor").value<QColor>());
728  manualToolRep->setToolOffsetLineColor(settings()->value("View/toolOffsetLineColor").value<QColor>());
729  }
730 }
731 
732 void ViewWrapper3D::activeImageChangedSlot(QString uid)
733 {
734  if(!mGroupData)
735  return;
736  ImagePtr image = mServices->patient()->getData<Image>(uid);
737 
738  // only show landmarks belonging to image visible in this view:
739  std::vector<ImagePtr> images = mGroupData->getImages(DataViewProperties::create3D());
740  if (!std::count(images.begin(), images.end(), image))
741  image.reset();
742 }
743 
744 void ViewWrapper3D::showRefToolSlot(bool checked)
745 {
746  ToolPtr refTool = mServices->tracking()->getReferenceTool();
747  if (!refTool)
748  return;
749  ToolRep3DPtr refRep = RepContainer(mView->getReps()).findFirst<ToolRep3D>(refTool);
750  if (!refRep)
751  {
752  refRep = ToolRep3D::New(mServices->spaceProvider(), refTool->getUid() + "_rep3d_" + this->mView->getUid());
753  refRep->setTool(refTool);
754  }
755 
756  if (checked) //should show
757  mView->addRep(refRep);
758  else
759  //should not show
760  mView->removeRep(refRep);
761 }
762 
763 
764 void ViewWrapper3D::updateSlices()
765 {
766  if (mSlices3DRep)
767  mView->removeRep(mSlices3DRep);
768 
769  if (!mGroupData)
770  return;
771 
772  std::vector<ImagePtr> images = mGroupData->getImages(DataViewProperties::createSlice3D());
773 // std::vector<ImagePtr> images = mGroupData->get3DSliceImages();
774  if (images.empty())
775  return;
776 
777  std::vector<PLANE_TYPE> planes = mGroupData->getSliceDefinitions().get();
778  if (planes.empty())
779  return;
780  mSlices3DRep = Slices3DRep::New(mSharedOpenGLContext, "MultiSliceRep_" + mView->getName());
781  for (unsigned i=0; i<planes.size(); ++i)
782  mSlices3DRep->addPlane(planes[i], mServices->patient());
783  mSlices3DRep->setShaderPath(DataLocations::findConfigFolder("/shaders"));
784  mSlices3DRep->setImages(images);
785  mSlices3DRep->setTool(mServices->tracking()->getActiveTool());
786  mView->addRep(mSlices3DRep);
787 }
788 
790 {
791  return mView;
792 }
793 
794 void ViewWrapper3D::activeToolChangedSlot()
795 {
796  ToolPtr activeTool = mServices->tracking()->getActiveTool();
797  mPickerRep->setTool(activeTool);
798  if (mSlices3DRep)
799  mSlices3DRep->setTool(activeTool);
800 }
801 
802 void ViewWrapper3D::toolsAvailableSlot()
803 {
804  std::vector<ToolRep3DPtr> reps = RepContainer::findReps<ToolRep3D>(mView->getReps());
805 
806  TrackingService::ToolMap tools = mServices->tracking()->getTools();
807  TrackingService::ToolMap::iterator iter;
808  for (iter = tools.begin(); iter != tools.end(); ++iter)
809  {
810  ToolPtr tool = iter->second;
811  if (tool->hasType(Tool::TOOL_REFERENCE))
812  continue;
813 
814  ToolRep3DPtr toolRep = RepContainer(mView->getReps()).findFirst<ToolRep3D>(tool);
815 
816  std::vector<ToolRep3DPtr>::iterator oldRep = std::find(reps.begin(), reps.end(), toolRep);
817  if (oldRep!=reps.end())
818  reps.erase(oldRep);
819 
820  if (tool->hasType(Tool::TOOL_MANUAL) && !settings()->value("View3D/showManualTool").toBool())
821  {
822  if (toolRep)
823  mView->removeRep(toolRep);
824  continue;
825  }
826 
827  if (!toolRep)
828  {
829  toolRep = ToolRep3D::New(mServices->spaceProvider(), tool->getUid() + "_rep3d_" + this->mView->getUid());
830  if (settings()->value("showToolPath").toBool())
831  toolRep->getTracer()->start();
832  }
833 
834  toolRep->setSphereRadius(settings()->value("View3D/sphereRadius").toDouble()); // use fraction of set size
835  toolRep->setSphereRadiusInNormalizedViewport(true);
836 
837  toolRep->setTool(tool);
838  toolRep->setOffsetPointVisibleAtZeroOffset(true);
839  mView->addRep(toolRep);
840  }
841 
842  // remove reps for tools no longer present
843  for (unsigned i=0; i<reps.size(); ++i)
844  {
845  mView->removeRep(reps[i]);
846  }
847 }
848 
849 void ViewWrapper3D::optionChangedSlot()
850 {
851  ViewGroupData::Options options = mGroupData->getOptions();
852 
853  this->showLandmarks(options.mShowLandmarks);
854  this->showPointPickerProbe(options.mShowPointPickerProbe);
855  mPickerRep->setGlyph(options.mPickerGlyph);
856 
857  this->updateSlices();
858 }
859 
860 void ViewWrapper3D::showLandmarks(bool on)
861 {
862  if (mLandmarkRep->isConnectedToView(mView) == on)
863  return;
864 
865  if (on)
866  {
867  mView->addRep(mLandmarkRep);
868  }
869  else
870  {
871  mView->removeRep(mLandmarkRep);
872  }
873 }
874 
875 void ViewWrapper3D::showPointPickerProbe(bool on)
876 {
877  mPickerRep->setEnabled(on);
878 }
879 
881 {
882  mSlicePlanes3DRep = SlicePlanes3DRep::New("uid");
883  mSlicePlanes3DRep->setProxy(proxy);
884  mSlicePlanes3DRep->setDynamicLabelSize(true);
885  bool show = settings()->value("showSlicePlanes").toBool();
886  mSlicePlanes3DRep->getProxy()->setVisible(show); // init with default value
887 
888  mView->addRep(mSlicePlanes3DRep);
889 }
890 
891 void ViewWrapper3D::setStereoType(int /*STEREOTYPE*/type)
892 {
893  switch (type)
894  //STEREOTYPE
895  {
896  case stFRAME_SEQUENTIAL:
897  mView->getRenderWindow()->SetStereoTypeToCrystalEyes();
898  break;
899  case stINTERLACED:
900  mView->getRenderWindow()->SetStereoTypeToInterlaced();
901  break;
902  case stDRESDEN:
903  mView->getRenderWindow()->SetStereoTypeToDresden();
904  break;
905  case stRED_BLUE:
906  mView->getRenderWindow()->SetStereoTypeToRedBlue();
907  break;
908  }
909 }
910 
911 void ViewWrapper3D::setStereoEyeAngle(double angle)
912 {
913  mView->getRenderer()->GetActiveCamera()->SetEyeAngle(angle);
914 }
915 
916 void ViewWrapper3D::setTranslucentRenderingToDepthPeeling(bool setDepthPeeling)
917 {
918  if(setDepthPeeling)
919  {
920  bool isDPSupported = true;
921 
922  //IsDepthPeelingSupported function don't seem to work on OSX (error messages or seg. fault)
923 #ifndef __APPLE__
924  if (!IsDepthPeelingSupported(mView->getRenderWindow(), mView->getRenderer(), true))
925  {
926  reportWarning("GPU do not support depth peeling. Rendering of translucent surfaces is not supported");
927  isDPSupported = false;
928  }
929 #endif
930 
931  if (isDPSupported && SetupEnvironmentForDepthPeeling(mView->getRenderWindow(), mView->getRenderer(), 100, 0.1))
932  {
933  report("Set GPU depth peeling");
934  }
935  else
936  {
937  reportWarning("Error setting depth peeling. The GPU or operating system might not support it.");
938  settings()->setValue("View3D/depthPeeling", false);
939  }
940  }
941  else
942  {
943  TurnOffDepthPeeling(mView->getRenderWindow(), mView->getRenderer());
944  }
945 }
946 
947 //------------------------------------------------------------------------------
948 }
bool SetupEnvironmentForDepthPeeling(vtkSmartPointer< vtkRenderWindow > renderWindow, vtkSmartPointer< vtkRenderer > renderer, int maxNoOfPeels, double occlusionRatio)
virtual QString getDataDescription()
static DataViewProperties createSlice3D()
static LandmarkRepPtr New(PatientModelServicePtr dataManager, const QString &uid="")
virtual void dataViewPropertiesChangedSlot(QString uid)
boost::shared_ptr< class ViewGroupData > ViewGroupDataPtr
Definition: cxViewGroup.h:29
ptCORONAL
a slice seen from the front of the patient
Definition: cxDefinitions.h:38
void reportError(QString msg)
Definition: cxLogger.cpp:71
static DonutMetricRepPtr New(const QString &uid="")
static RepManager * getInstance()
get the only instance of this class
boost::shared_ptr< class SlicePlanesProxy > SlicePlanesProxyPtr
boost::shared_ptr< class Stream2DRep3D > Stream2DRep3DPtr
boost::shared_ptr< class CameraControl > CameraControlPtr
boost::shared_ptr< class TrackedStream > TrackedStreamPtr
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
virtual ViewPtr getView()
csSENSOR
a tools sensor space (s)
Definition: cxDefinitions.h:88
void setStereoType(int type)
static SlicePlanes3DRepPtr New(const QString &uid="")
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
Superclass for ViewWrappers.
Definition: cxViewWrapper.h:89
boost::shared_ptr< REP > getCachedRep(QString uid="")
Definition: cxRepManager.h:72
SharedOpenGLContextPtr mSharedOpenGLContext
virtual void setSlicePlanesProxy(SlicePlanesProxyPtr proxy)
csREF
the data reference space (r) using LPS (left-posterior-superior) coordinates.
Definition: cxDefinitions.h:88
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:66
static PlaneMetricRepPtr New(const QString &uid="")
boost::shared_ptr< class StreamRep3D > StreamRep3DPtr
ptAXIAL
a slice seen from the top of the patient
Definition: cxDefinitions.h:38
Base class for all Data Metric reps.
static AngleMetricRepPtr New(const QString &uid="")
boost::shared_ptr< class DataMetricRep > DataMetricRepPtr
Class for display of an orientation annotation cube in 3D.
virtual void settingsChangedSlot(QString key)
A data set for video streams (2D/3D).
boost::shared_ptr< class View > ViewPtr
stFRAME_SEQUENTIAL
csDATA
a datas space (d)
Definition: cxDefinitions.h:88
static ToolMetricRepPtr New(const QString &uid="")
Reference tool.
Definition: cxTool.h:84
static DataViewProperties create3D()
static Stream2DRep3DPtr New(SpaceProviderPtr spaceProvider, const QString &uid="")
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:58
virtual void setViewGroup(ViewGroupDataPtr group)
boost::shared_ptr< class Data > DataPtr
stINTERLACED
static MetricNamesRepPtr New(const QString &uid="")
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
void streamChanged(QString uid)
void settingsChangedSlot(QString key)
ptSAGITTAL
a slice seen from the side of the patient
Definition: cxDefinitions.h:38
static PlaneTypeCollection fromString(QString input, PlaneTypeCollection defVal=PlaneTypeCollection())
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
static FrameMetricRepPtr New(const QString &uid="")
ptTOOLSIDEPLANE
z-rotated 90* relative to anyplane like side plane, but always kept oriented like the plane defined b...
Definition: cxDefinitions.h:38
ViewGroupDataPtr mGroupData
A volumetric data set.
Definition: cxImage.h:45
Identification of a Coordinate system.
static QString findConfigFilePath(QString fileName, QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
virtual QString getViewDescription()
Representation of a mouse/keyboard-controlled virtual tool.
Definition: cxTool.h:85
static GeometricRepPtr New(const QString &uid="")
virtual void setViewGroup(ViewGroupDataPtr group)
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:21
static Slices3DRepPtr New(SharedOpenGLContextPtr context, const QString &uid)
static RegionOfInterestMetricRepPtr New(const QString &uid="")
std::map< QString, ToolPtr > ToolMap
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
boost::shared_ptr< class AxisConnector > AxisConnectorPtr
ptRADIALPLANE
y-rotated 90* relative to anyplane (bird&#39;s view)
Definition: cxDefinitions.h:38
bool hasVolume3D() const
bool TurnOffDepthPeeling(vtkSmartPointer< vtkRenderWindow > renderWindow, vtkSmartPointer< vtkRenderer > renderer)
Turn off depth peeling.
virtual void addReps()
void report(QString msg)
Definition: cxLogger.cpp:69
VisServicesPtr mServices
QStringList getAllDataNames(DataViewProperties properties) const
static PointMetricRepPtr New(const QString &uid="")
boost::shared_ptr< class SpaceListener > SpaceListenerPtr
stDRESDEN
virtual void updateView()
static StreamRep3DPtr New(SpaceProviderPtr spaceProvider, PatientModelServicePtr patientModelService, const QString &uid="")
static PickerRepPtr New(PatientModelServicePtr dataManager, const QString &uid="")
for creating new instances
Definition: cxPickerRep.cpp:54
DataViewPropertiesInteractorPtr mShow3DSlicesInteractor
static ToolRep3DPtr New(SpaceProviderPtr spaceProvider, const QString &uid="")
Definition: cxToolRep3D.cpp:74
boost::shared_ptr< class ToolRep3D > ToolRep3DPtr
ptANYPLANE
a plane aligned with the tool base plane
Definition: cxDefinitions.h:38
ViewWrapper3D(int startIndex, ViewPtr view, VisServicesPtr services)
boost::shared_ptr< class Navigation > NavigationPtr
bool IsDepthPeelingSupported(vtkSmartPointer< vtkRenderWindow > renderWindow, vtkSmartPointer< vtkRenderer > renderer, bool doItOffScreen)
void connectContextMenu(ViewPtr view)
csTOOL
a tools rspace (t)
Definition: cxDefinitions.h:88
boost::shared_ptr< class Rep > RepPtr
Definition: cxRepManager.h:24
static DistanceMetricRepPtr New(const QString &uid="")
static SphereMetricRepPtr New(const QString &uid="")
void setGraphicsSize(double size)
ptSIDEPLANE
z-rotated 90* relative to anyplane (dual anyplane)
Definition: cxDefinitions.h:38
static CustomMetricRepPtr New(const QString &uid="")
void activeImageChanged(const QString &uId)
boost::shared_ptr< class GeometricRep > GeometricRepPtr
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr