[vtkusers] Selecting a point by clicking on it

Juan Pablo Hernandez Vogt jphv at open-engineering.com
Tue Sep 9 08:39:49 EDT 2014


Hello,

While I wait for the book arrive, I tried to create basic selection from
examples.

In the following example you can do:
click + Shift over sphere --> creates a small sphere on it
click + Alt over small spheres --> select the actor. In the second
selection creates a line between its centers.

click + Shift on empty space --> creates a point (green, there are 3 blue
points by default)


My problem: I can not create a line between points because I do not know
how to select the actor of my new points.

Why a sphere is "selectable" and a point is not in this context?


As I said, I'm waiting the VTK book arrive and from help I could not get
what I misunderstood.



I saw HighlightSelectedPoints, but I do not want a rectangular area, I want
to select only one point by clicking.

My idea is a basic editor for add/remove point, line, arc., so the first
thing is how to select a point to gets its coordinates.


Thanks in advance for play with this code and tell me any example that
drives this task.


Best Regards,

Juan Pablo



[code from Internet]

/*
 This example demonstrates cell picking using vtkCellPicker.  It displays the
results of picking using a vtkTextMapper.

 converted from TCL
*/
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkLODActor.h"
#include "vtkConeSource.h"
#include "vtkGlyph3D.h"
#include "vtkCellPicker.h"
#include "vtkTextMapper.h"
#include "vtkActor2D.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkInteractorStyleRubberBand2D.h"

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTextProperty.h"
#include "vtkCallbackCommand.h"
#include "vtkCamera.h"

#include "vtkSmartPointer.h"
#include "vtkProperty.h"
#include "vtkLineSource.h"
#include "vtkCellArray.h"
#include "vtkLine.h"

vtkPoints* points;
vtkCellArray* vertices;

int MouseMotion;
int SelectLine;
vtkRenderer *ren1;
vtkRenderWindow *renWin;
vtkRenderWindowInteractor *iren;
vtkCellPicker *picker;
vtkActor2D *textActor;
vtkTextMapper *textMapper;

vtkActor* selectionActor1;
vtkActor* selectionActor2;
vtkCellPicker *pickerPointActor;

vtkPolyData* pointPolyData;

#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()


void addPointActor(double p[3], vtkRenderer* renderer)
{
// Create the geometry of a point (the coordinate)
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

// Create the topology of the point (a vertex)
vtkSmartPointer<vtkCellArray> vertices =
vtkSmartPointer<vtkCellArray>::New();
vtkIdType pid, cid;
pid = points->InsertNextPoint(p);
cid = vertices->InsertNextCell(1, &pid);

cout<<"addPointActor: pid="<<pid<<endl;
cout<<"addPointActor: cid="<<cid<<endl;

// Create a polydata object
vtkSmartPointer<vtkPolyData> point = vtkSmartPointer<vtkPolyData>::New();

// Set the points and vertices we created as the geometry and topology of
the polydata
point->SetPoints(points);
point->SetVerts(vertices);

// Visualize
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(point);
#else
mapper->SetInputData(point);
#endif

vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(10);
actor->GetProperty()->SetColor(0,0.5,0);

renderer->AddActor(actor);
}

void addShpereActor(double p[3], vtkRenderer* renderer)
{
vtkSmartPointer<vtkSphereSource> SphereSource =
vtkSmartPointer<vtkSphereSource>::New();
SphereSource->SetCenter(p);
SphereSource->SetRadius(0.01);
SphereSource->Update();

vtkSmartPointer<vtkPolyDataMapper> Mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
Mapper->SetInput(SphereSource->GetOutput());

vtkSmartPointer<vtkActor> Actor = vtkSmartPointer<vtkActor>::New();
Actor->SetMapper(Mapper);
Actor->GetProperty()->SetColor(255,0,0);

renderer->AddActor(Actor);
}


class PickCommand : public vtkCommand
{
public:

    static PickCommand *New() { return new PickCommand; }
    void Delete() { delete this; }

    virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
    {
        if (picker->GetCellId() < 0 )
        {
            textActor->VisibilityOff();

double selpt[3];
            picker->GetSelectionPoint(selpt); // Coordinates in the window
space
            double x = selpt[0];
            double y = selpt[1];
            double pickPos[3];
            picker->GetPickPosition( pickPos ); // Coordinates in
geometrical space
            double xp = pickPos[0];
            double yp = pickPos[1];
            double zp = pickPos[2];

            char text[120];
            sprintf( text, "(%5.5f,  %5.5f,  %5.5f)", selpt[0], selpt[1],
selpt[2] );
cout <<"Click outside, selpt: "<< text << endl;

sprintf( text, "(%5.5f,  %5.5f,  %5.5f)", xp, yp, zp );
cout <<"Click outside, pickPos: "<< text << endl;

#define ADD_OUTSIDE_ACTOR
#ifdef ADD_OUTSIDE_ACTOR
addPointActor(pickPos, ren1);
/*
vtkSmartPointer<vtkSphereSource> SphereSource =
vtkSmartPointer<vtkSphereSource>::New();
SphereSource->SetCenter(xp, yp, zp);
SphereSource->SetRadius(0.01);
SphereSource->Update();

vtkSmartPointer<vtkPolyDataMapper> Mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
Mapper->SetInput(SphereSource->GetOutput());

vtkSmartPointer<vtkActor> Actor = vtkSmartPointer<vtkActor>::New();
Actor->SetMapper(Mapper);
//vtkProperty* color = Actor->GetProperty();
//color->
Actor->GetProperty()->SetColor(255,0,0);

ren1->AddActor(Actor);
*/
#else

pointPolyData->BuildLinks();
pointPolyData->DeleteCell(0);
pointPolyData->RemoveDeletedCells();

//vertices->rem
vtkIdType pid,cid;
pid = points->InsertNextPoint(xp, yp, zp);
cid = vertices->InsertNextCell(1,&pid);



int a = 2* cid;
#endif
        }
        else
        {
            double selpt[3];
            picker->GetSelectionPoint(selpt);
            double x = selpt[0];
            double y = selpt[1];
            double pickPos[3];
            picker->GetPickPosition( pickPos );
            double xp = pickPos[0];
            double yp = pickPos[1];
            double zp = pickPos[2];

            char text[120];
sprintf( text, "(%5.5f,  %5.5f,  %5.5f)", selpt[0], selpt[1], selpt[2] );
cout <<"Click inside, selpt: "<< text << endl;

sprintf( text, "(%5.5f,  %5.5f,  %5.5f)", xp, yp, zp );
cout <<"Click inside, pickPos: "<< text << endl;

            textMapper->SetInput( text );
            textActor->SetPosition(x, y);
            textActor->VisibilityOn();



vtkSmartPointer<vtkSphereSource> SphereSource =
vtkSmartPointer<vtkSphereSource>::New();
SphereSource->SetCenter(xp, yp, zp);
SphereSource->SetRadius(0.01);
SphereSource->Update();

vtkSmartPointer<vtkPolyDataMapper> Mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
Mapper->SetInput(SphereSource->GetOutput());

vtkSmartPointer<vtkActor> Actor = vtkSmartPointer<vtkActor>::New();
Actor->SetMapper(Mapper);
 ren1->AddActor(Actor);
        }

        renWin->Render();
    }
};


class PickPointActorCommand : public vtkCommand
{
public:

    static PickPointActorCommand *New() { return new PickPointActorCommand;
}
    void Delete() { delete this; }

    virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
    {
vtkPicker* currentPicker = (vtkPicker*) caller;

vtkProp* prop = currentPicker->GetViewProp();
vtkProp3D* prop3d = currentPicker->GetProp3D();
cout<<"prop="<<prop<<endl;
cout<<"prop3D="<<prop3d<<endl;

cout<<"currentCellId="<<picker->GetCellId()<<endl;

vtkActor* actor = currentPicker->GetActor();
if (actor)
        {
cout<<"PickPointActorCommand: there is actor" <<endl;

if (selectionActor1==0)
{
// Mark start point
selectionActor1 = actor;
}
else
{
// Mark end point
selectionActor2 = actor;

// Create line:

// Get center of actors
double bounds[6], center1[3], center2[3];

selectionActor1->GetBounds(bounds);
center1[0] = (bounds[1]+bounds[0])/2;
center1[1] = (bounds[3]+bounds[2])/2;
center1[2] = (bounds[5]+bounds[4])/2;

selectionActor2->GetBounds(bounds);
center2[0] = (bounds[1]+bounds[0])/2;
center2[1] = (bounds[3]+bounds[2])/2;
center2[2] = (bounds[5]+bounds[4])/2;

// Create source
vtkSmartPointer<vtkLineSource> lineSource =
vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(center1);
lineSource->SetPoint2(center2);
lineSource->Update();

// Visualize
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(lineSource->GetOutputPort());
 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetLineWidth(2);
actor->GetProperty()->SetColor(255,0,255);

// Activate
ren1->AddActor(actor);
 // remove prvious selection
selectionActor1 = selectionActor2 = 0;

SelectLine = 0; // stop selection
}
        }
        else
        {
            // No actor selected
cout<<"PickPointActorCommand: there is NO actor" <<endl;
        }

        renWin->Render();
    }
};


void PickerInteractionCallback( vtkObject* vtkNotUsed(object),
                                       unsigned long event,
                                       void* clientdata,
                                       void* vtkNotUsed(calldata) )
{
    vtkInteractorStyleTrackballCamera * style =
(vtkInteractorStyleTrackballCamera*)clientdata;
    switch( event )
    {
    case vtkCommand::LeftButtonPressEvent:
//cout<<"PickerInteractionCallback::LeftButtonPressEvent"<<endl;

if (iren->GetAltKey())
{
SelectLine = 1;
//cout<<"SelectLine = 1"<<endl;
}
else
{
selectionActor1 = selectionActor2 = 0;
SelectLine = 0; // stop selection
//cout<<"SelectLine = 0"<<endl;
}

MouseMotion = 0;
        style->OnLeftButtonDown();

        break;
    case vtkCommand::LeftButtonReleaseEvent:
//cout<<"PickerInteractionCallback::LeftButtonReleaseEvent"<<endl;

if (SelectLine == 1)
{
int *pick = iren->GetEventPosition();
            pickerPointActor->Pick((double)pick[0], (double)pick[1], 0.0,
ren1);
}
else if (MouseMotion == 0)
        {
if (iren->GetShiftKey())
{
int *pick = iren->GetEventPosition();
picker->Pick((double)pick[0], (double)pick[1], 0.0, ren1);
}
        }

        style->OnLeftButtonUp();
        break;
    case vtkCommand::MouseMoveEvent:
//cout<<"PickerInteractionCallback::MouseMoveEvent"<<endl;
        MouseMotion = 1;
        style->OnMouseMove();
        break;
    }
}


int main(int argc, char* argv)
{
    MouseMotion = 0;
SelectLine = 0;

// Original code:
vtkSphereSource *sphere = vtkSphereSource::New();

    vtkPolyDataMapper *sphereMapper = vtkPolyDataMapper::New();
    sphereMapper->SetInput(sphere->GetOutput());
    sphereMapper->GlobalImmediateModeRenderingOn();
    vtkLODActor *sphereActor = vtkLODActor::New();
    sphereActor->SetMapper(sphereMapper);

// create the spikes by glyphing the sphere with a cone.  Create the mapper
// and actor for the glyphs.
    vtkConeSource *cone = vtkConeSource::New();
    vtkGlyph3D *glyph = vtkGlyph3D::New();
    glyph->SetInput(sphere->GetOutput());
    glyph->SetSource(cone->GetOutput());
    glyph->SetVectorModeToUseNormal();
    glyph->SetScaleModeToScaleByVector();
    glyph->SetScaleFactor(0.25);
    vtkPolyDataMapper *spikeMapper = vtkPolyDataMapper::New();
    spikeMapper->SetInput(glyph->GetOutput());
    vtkLODActor *spikeActor = vtkLODActor::New();
    spikeActor->SetMapper(spikeMapper);

// Create a cell picker.
    PickCommand* pickObserver = PickCommand::New();
    picker = vtkCellPicker::New();
    picker->AddObserver( vtkCommand::EndPickEvent, pickObserver );

// Create a Actor picker.
PickPointActorCommand* pickPointActorObserver =
PickPointActorCommand::New();
    pickerPointActor = vtkCellPicker::New();
    pickerPointActor->AddObserver( vtkCommand::EndPickEvent,
pickPointActorObserver );

// Create a text mapper and actor to display the results of picking.
    textMapper = vtkTextMapper::New();
    vtkTextProperty *tprop = textMapper->GetTextProperty();
    tprop->SetFontFamilyToArial();
    tprop->SetFontSize(12);
    tprop->BoldOn();
//    tprop->ShadowOn();
    tprop->SetColor(1, 0, 0);
    textActor = vtkActor2D::New();
    textActor->VisibilityOff();
    textActor->SetMapper(textMapper);

// Create the Renderer, RenderWindow, and RenderWindowInteractor


    vtkInteractorStyleTrackballCamera *style =
vtkInteractorStyleTrackballCamera::New();
    vtkCallbackCommand * pickerCommand = vtkCallbackCommand::New();
    pickerCommand->SetClientData(style);
    pickerCommand->SetCallback(PickerInteractionCallback);
    style->AddObserver(vtkCommand::LeftButtonPressEvent, pickerCommand);
    style->AddObserver(vtkCommand::MouseMoveEvent, pickerCommand);
    style->AddObserver(vtkCommand::LeftButtonReleaseEvent, pickerCommand);
    ren1 = vtkRenderer::New();
    renWin = vtkRenderWindow::New();
    renWin->AddRenderer(ren1);
    iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);
    iren->SetInteractorStyle(style); // Is who calls the picker
    //iren->SetPicker(picker);

// Add the actors to the renderer, set the background and size
    ren1->AddActor2D(textActor);
    ren1->AddActor(sphereActor);
    ren1->AddActor(spikeActor);
    ren1->SetBackground(1, 1, 1);
    renWin->SetSize(500, 500);

// Get the camera and zoom in closer to the image.
    vtkCamera *cam1 = ren1->GetActiveCamera();
    //cam1->Zoom(1);



// Create the geometry of a point (the coordinate), 3 points:

//vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points = vtkPoints::New();

// Create the topology of the point (a vertex)
//vtkSmartPointer<vtkCellArray> vertices =
 vtkSmartPointer<vtkCellArray>::New();
vertices = vtkCellArray::New();

vtkIdType pid;
pid = points->InsertNextPoint(1,1,0);
vertices->InsertNextCell(1,&pid);

pid = points->InsertNextPoint(1,-1,0);
vertices->InsertNextCell(1,&pid);

pid = points->InsertNextPoint(1,1,1);
vertices->InsertNextCell(1,&pid);

//vtkSmartPointer<vtkLine> line0 = vtkSmartPointer<vtkLine>::New();
//line0->GetPointIds()->SetId(0, 0);
//line0->GetPointIds()->SetId(1, 1);
//vertices->InsertNextCell(line0);

// Create a polydata object
pointPolyData = vtkPolyData::New();

// Set the points and vertices we created as the geometry and topology of
the polydata
pointPolyData->SetPoints(points);
pointPolyData->SetVerts(vertices);


// Visualize
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(pointPolyData);
#else
mapper->SetInputData(pointPolyData);
#endif

vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(10);
actor->GetProperty()->SetColor(0,0,255);
actor->GetProperty()->SetLineWidth(5);
ren1->AddActor(actor);





    iren->Initialize();
    iren->Start();

    picker->RemoveObserver( pickObserver );
    sphere->Delete();
    sphereMapper->Delete();
    sphereActor->Delete();
    cone->Delete();
    glyph->Delete();
    spikeMapper->Delete();
    spikeActor->Delete();
    picker->Delete();
    textMapper->Delete();
    textActor->Delete();
    pickerCommand->Delete();
    style->Delete();
    ren1->Delete();
    renWin->Delete();
    pickObserver->Delete();

vertices->Delete();
points->Delete();

    iren->Delete();
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20140909/0e0db179/attachment-0001.html>


More information about the vtkusers mailing list