[vtkusers] vtkPointPicker / vtkGlyph3D problem

Gomez, Alberto alberto.gomez at kcl.ac.uk
Wed May 5 09:03:00 EDT 2010


On 04/05/10 17:40, Henrik Westerberg wrote:

Hi,

thanks for the answers. I achieved successful picking with
vtkPointPicker doing the following:


        double *vector = new double[3];
        double *pos = new double[3];
        //vectors
        vector =
glyph->GetOutput()->GetPointData()->GetVectors()->GetTuple(picker->GetPointId());
        //points
        pos = glyph->GetOutput()->GetPoint(picker->GetPointId());
        //pos  =
glyph->GetOutput()->GetPoints()->GetPoint(picker->GetPointId());//This
gives the same result

However, this picks any point in the polydata, which is not what I want.
I will explain through an example:
    Lets say I have two vectors. They are displayed through the pipeline
vtkPolyData->vtkGlyph3D->vtkPolyDataMapper->vtkActor, where my polydata
contains two points and two vector tuples. The picker selects any point,
i.e. any vertex of the vectors, so I can pick like 10 different points
for each vector. What I want is to pick each vector itself, i.e. If I
click anywhere in the vector, to get the position where the vector is
placed, this is, the position of one point of the original polydata.
Would this be possible?

Thanks for your help,

Alberto

> Hi,
>
> Be sure to have GeneratePointIdsOn() as this make like a lot easier on your vtkGlyph3D (which you do, just writing it for the general situation)
>
> glyphs = vtkGlyph3D()
> glyphs.GeneratePointIdsOn()
>
>
> In my case I have a scalar associated with each point.
>
> Then you should be able to do something like the following:
>
> picker = vtkPointPicker()
> def handlePick(object, event):
>      pid = picker.GetPointId()
>      inputIds = glyphs.GetOutput().GetPointData().GetArray("InputPointIds")
>      app = int(inputIds.GetTuple1(pid))
>      
>      if (app < tf_scale.GetOutput().GetPoints().GetNumberOfPoints()):
>           print tf_scale.GetOutput().GetPoints().GetPoint(app)
>           print scalars.GetValue(app)
>
> where iren is a vtkRenderWindowInteractor
>
> iren.SetPicker(picker)
>
> And you can pick with 'p' key without having to write your own observer.
>
> bye,
> Henrik
>
>
> ________________________________________
> From: vtkusers-bounces at vtk.org [vtkusers-bounces at vtk.org] On Behalf Of Allan James [ar.james at qut.edu.au]
> Sent: 04 May 2010 04:34
> To: Gomez, Alberto
> Cc: vtkusers at vtk.org
> Subject: Re: [vtkusers] vtkPointPicker / vtkGlyph3D problem
>
> 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>
>>
>>
>>     
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>   


-- 

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>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100505/686e0272/attachment.htm>


More information about the vtkusers mailing list