[vtkusers] vtkPointPicker / vtkGlyph3D problem
Allan James
ar.james at qut.edu.au
Mon May 3 22:34:05 EDT 2010
Hi Alberto,
I could not fix the problem with point picker not producing correct results. After much banging of head against wall I tried cellpicker instead which is now working correctly. I would love to know what I was doing wrong with point picker!
Below is some code snippets for using cellpicker to select a glyph generated using vtkGlyph3D. This code has been hacked a bit from a larger project so it's a bit messy and I havent tested it as is. However it should work by left-clicking on a glyph.
If anyone has suggestions on making this code better, please let me know.
////////////////////////////////////////////////////////
// Make sure GeneratePointIdsOn() called on vtkGlyph3D
// This generates an array on the output dataset called
// "InputPointIds" which generates pointIDs in the glyphs
// that match the original input pointIDs.
////////////////////////////////////////////////////////
_glyphs->GeneratePointIdsOn();
///////////////////////////////////////////
// Setup pick callback (ScenePickCallback)
///////////////////////////////////////////
_scenePickCallback = ScenePickCallback::New();
_scenePickCallback->actorToPick = _glyphActor;
_scenePickCallback->glyphsToPick = _glyphs;
_scenePickCallback->sceneRenderWindowInteractor = _sceneRenderWindowInteractor;
_sceneRenderWindowInteractor->GetInteractorStyle()->AddObserver(vtkCommand::LeftButtonReleaseEvent, _scenePickCallback);
class ScenePickCallback : public vtkCommand
{
public:
static ScenePickCallback *New();
virtual void Execute(vtkObject *caller, unsigned long eventId, void* data);
vtkSmartPointer<vtkActor> actorToPick;
vtkSmartPointer<vtkGlyph3D> glyphsToPick;
vtkSmartPointer<vtkRenderWindowInteractor> sceneRenderWindowInteractor;
private:
ScenePickCallback();
};
void ScenePickCallback::Execute(vtkObject *caller, unsigned long eventId, void* data)
{
if(eventId == vtkCommand::LeftButtonReleaseEvent)
{
int pickPosition[2];
sceneRenderWindowInteractor->GetEventPosition(pickPosition);
sceneRenderWindowInteractor->GetPicker()->Pick(pickPosition[0], pickPosition[1], 0, sceneRenderer);
vtkCellPicker *cellPicker = reinterpret_cast<vtkCellPicker*>(picker.GetPointer());
if(cellPicker)
{
// Check if correct actor was picked
if(cellPicker->GetActor() == actorToPick.GetPointer())
{
vtkDataArray *inputIds = glyphsToPick->GetOutput()->GetPointData()->GetArray("InputPointIds");
if(inputIds)
{
vtkCell *cell = glyphsToPick->GetOutput()->GetCell(cellPicker->GetCellId());
if(cell && cell->GetNumberOfPoints() > 0)
{
// get first PointId from picked cell
vtkIdType inputId = cell->GetPointId(0);
// get matching Id from "InputPointIds" array
vtkIdType selectedPointId = inputIds->GetTuple1(inputId);
if(selectedPointId >= 0)
{
// POINT PICKED!
// selectedPointId = Picked PointID (original input points)
}
}
}
}
else
{
// NONE PICKED
}
}
}
}
Allan James
High Performance Computing & Research Support
Queensland University of Technology
(07) 3138 9264
ar.james at qut.edu.au
http://www.qut.edu.au/its/hpc
><(((º> ._.·´¯`·.. >++(((º> ._.·´¯`·.. >++(((º>
> -----Original Message-----
> From: Gomez, Alberto [mailto:alberto.gomez at kcl.ac.uk]
> Sent: Friday, 30 April 2010 8:53 PM
> To: Allan James
> Cc: vtkusers at vtk.org
> Subject: Re: [vtkusers] vtkPointPicker / vtkGlyph3D problem
>
> Hi all,
>
> I am trying to select a vector from a vector field with the
> mouse. The
> vector field is a glyph of vectors and it is generated in the
> following
> way (1). Then I use a custom interaction (subclassing
> vtkInteractionStyleTrackballCamera) so that I pick points
> when I press
> the mouse button (2). When I click the left button, a
> callback (3) does
> some processing. The problem is that the position I get does
> not match
> the real vector position (i.e. I plot a vector at the 3D point I get
> with the picker through the method picker->GetPickPosition()
> and it does
> not match). Anyone has a clue on why? I have played around with the
> tolerance with no success.
>
> Another question, how can I get the point information (vector and
> position) from the point id??
>
> Thanks,
>
> Alberto
>
>
> (1) Vector field generation :
>
> //positions
> vtkSmartPointer<vtkPoints> pts =
> vtkSmartPointer<vtkPoints>::New();
> pts->SetNumberOfPoints(num_pts);
> //directions
> vtkSmartPointer<vtkDoubleArray> vecArr =
> vtkSmartPointer<vtkDoubleArray>::New();
> vecArr->SetNumberOfComponents(3);
> vecArr->SetNumberOfTuples(num_pts);
> for (int i = 0; i < num_pts; i++) {
> pts->InsertNextPoint(positions[i][0], positions[i][1],
> positions[i][2]);
> float tuple[3] = {(float) directions[i][0] , (float)
> directions[i][1], (float) directions[i][2]};
> vecArr->InsertNextTuple(tuple);
> }
>
> // put vectors and positions into a grid which will be the
> glyph's input
> vtkSmartPointer<vtkUnstructuredGrid> uGrid = vtkSmartPointer<
> vtkUnstructuredGrid>::New();
> uGrid->SetPoints(pts);
> uGrid->GetPointData()->SetVectors(vecArr);
>
> // glyph construction
> vtkSmartPointer<vtkArrowSource> arrow =
> vtkSmartPointer<vtkArrowSource>::New();
> vtkSmartPointer<vtkGlyph3D> glyph =
> vtkSmartPointer<vtkGlyph3D>::New();
> glyph->SetInput(uGrid);
> glyph->SetSource(arrow->GetOutput());
> glyph->SetScaleModeToScaleByVector();
> glyph->GeneratePointIdsOn();
> //Mapper and actor
> vtkSmartPointer<vtkPolyDataMapper> gMapper =
> vtkSmartPointer<vtkPolyDataMapper>::New();
> gMapper->SetInput(glyph->GetOutput());
> gMapper->ScalarVisibilityOff();
> gMapper->SetScalarRange(uGrid->GetScalarRange());
>
> vtkSmartPointer<vtkActor> gactor = vtkSmartPointer<vtkActor>::New();
> gactor->SetMapper(gMapper);
> gactor->GetProperty()->SetColor(color);
> ren->AddActor(gactor);
>
> (2) Detail of my subclass for custom interactor style:
> virtual void OnLeftButtonDown()
> {
> if (this->Interactor->GetControlKey() ){
> int* pos = this->GetInteractor()->GetEventPosition();
> pointPicker->Pick(pos[0], pos[1], 0,
> this->GetDefaultRenderer());
> } else{
>
> vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
> }
> }
>
> (3) Callback class (detail)
>
> // Callback thats get called for a picking event.
> class PickCallback : public vtkCommand
> {
> public:
> static PickCallback* New()
> {
> return new PickCallback();
> }
>
> void Execute(vtkObject* caller, unsigned long eventId,
> void* callData)
> {
> vtkPointPicker *picker = static_cast< vtkPointPicker* >(caller);
> if(picker->GetPointId() < 1)
> {
> // Nothing is picked.
> }
> else
> {
> double* pos = picker->GetPickPosition();
> std::cout << pos[0]<< ","<< pos[1]<< ","<< pos[2]<< std::endl;
>
> actor = generateVectorActor(picker);
>
>
> ren->AddViewProp(actor);
>
>
> }
>
>
>
> }
>
> Allan James wrote:
> > Hi all,
> >
> > I have an issue with code that is using vtkPointPicker to
> pick points displayed using vtkGlyph3D.
> >
> > Now I have the picking working great for most of the glyphs
> - using vtkGlyph3D->GeneratePointIdsOn(); and I am able to
> select glyphs and display a sphere at the selected glyph location.
> >
> > My problem is that while this works perfectly 99% of the
> time - there are certain glyphs that are either very
> difficult to pick (sometimes impossible it seems) or I have
> to click about 20 pixels or so above or next to the glyph for
> the pick to work. Has anyone seen this issue and/or can suggest a fix?
> >
> > Why would picking work perfectly for most glyphs but not
> for some others - when all of the glyphs are generated from
> the same simple pointset using the same vtkGlyph3D filter?
> >
> > Any help would be muchly appreciated - thanks
> >
> > Allan James
> > High Performance Computing & Research Support
> > Queensland University of Technology
> > (07) 3138 9264
> > ar.james at qut.edu.au<mailto:ar.james at qut.edu.au>
> > http://www.qut.edu.au/its/hpc
> >
> >
> >> <(((º> ._.·´¯`·.. >++(((º> ._.·´¯`·.. >++(((º>
> >>
> >
> >
> >
>
>
> --
>
> Alberto Gómez
>
> /Division of Imaging Sciences
> The Rayne Institute
> 4th Floor, Lambeth Wing
> St Thomas' Hospital
> London SE1 7EH /
>
> phone: +44 (0) 20 718 88364
> email: alberto.gomez at kcl.ac.uk <mailto:alberto.gomez at kcl.ac.uk>
>
>
More information about the vtkusers
mailing list