Skip to content

Commit

Permalink
ENH: Add support for volume rendering in fast picking
Browse files Browse the repository at this point in the history
Point picking (getting 3D position from 2D screen position, for example when using Shift+MouseMove) in a 3D view is slow for large meshes if vtkMRMLCrosshairNode::FastPick3D is disabled.
Fast picking is disabled by default because it cannot pick volume rendering and semi-transparent surfaces. This commit adds fast picking for volume rendering.

Fast picking is still disabled by default because semi-transparent surfaces are still ignored. A potential solution for that could be to run accurate picking selectively, just for semi-transparent
surfaces. Then picking would only be slow if there are large semi-transparent models.
  • Loading branch information
lassoan committed Apr 4, 2022
1 parent ad05346 commit 17429e3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
23 changes: 21 additions & 2 deletions Libs/MRML/DisplayableManager/vtkMRMLThreeDViewInteractorStyle.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <vtkPoints.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVolumePicker.h>
#include <vtkWorldPointPicker.h>

vtkStandardNewMacro(vtkMRMLThreeDViewInteractorStyle);
Expand All @@ -43,6 +44,7 @@ vtkMRMLThreeDViewInteractorStyle::vtkMRMLThreeDViewInteractorStyle()
this->AccuratePicker = vtkSmartPointer<vtkCellPicker>::New();
this->AccuratePicker->SetTolerance( .005 );
this->QuickPicker = vtkSmartPointer<vtkWorldPointPicker>::New();
this->QuickVolumePicker = vtkSmartPointer<vtkVolumePicker>::New();
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -126,9 +128,26 @@ bool vtkMRMLThreeDViewInteractorStyle::QuickPick(int x, int y, double pickPoint[
return false;
}

this->QuickPicker->Pick(x, y, 0, this->CurrentRenderer);

bool quickPicked = (this->QuickPicker->Pick(x, y, 0, this->CurrentRenderer) > 0);
this->QuickPicker->GetPickPosition(pickPoint);

// QuickPicker ignores volume-rendered images, do a volume picking, too.
if (this->CameraNode && this->QuickVolumePicker->Pick(x, y, 0, this->CurrentRenderer))
{
double volumePickPoint[3] = { 0.0, 0.0, 0.0 };
this->QuickVolumePicker->GetPickPosition(volumePickPoint);
double* cameraPosition = this->CameraNode->GetPosition();
// Use QuickVolumePicker result instead of QuickPicker result if picked volume point
// is closer to the camera (or QuickPicker did not find anything).
if (!quickPicked
|| vtkMath::Distance2BetweenPoints(volumePickPoint, cameraPosition)
< vtkMath::Distance2BetweenPoints(pickPoint, cameraPosition))
{
pickPoint[0] = volumePickPoint[0];
pickPoint[1] = volumePickPoint[1];
pickPoint[2] = volumePickPoint[2];
}
}

return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "vtkSmartPointer.h"

class vtkCellPicker;
class vtkVolumePicker;
class vtkWorldPointPicker;

/// \brief Interactive manipulation of the camera.
Expand Down Expand Up @@ -82,9 +83,13 @@ class VTK_MRML_DISPLAYABLEMANAGER_EXPORT vtkMRMLThreeDViewInteractorStyle :

vtkMRMLCameraNode *CameraNode;

/// For jump to slice feature (when mouse is moved while shift key is pressed)
// For jump to slice feature (when mouse is moved while shift key is pressed)
// Slow but can pick anything (volumes and semi-transparent surfaces)
vtkSmartPointer<vtkCellPicker> AccuratePicker;
// Picker that uses Z buffer. Fast but ignores volumes and semi-transparent surfaces.
vtkSmartPointer<vtkWorldPointPicker> QuickPicker;
// Picker for volume-rendered images. Fast, as it only computes a single ray.
vtkSmartPointer<vtkVolumePicker> QuickVolumePicker;

private:
vtkMRMLThreeDViewInteractorStyle(const vtkMRMLThreeDViewInteractorStyle&) = delete;
Expand Down

0 comments on commit 17429e3

Please sign in to comment.