[vtkusers] Get point coordinates by mouse click

Anka Kochanowska anka at bic.mni.mcgill.ca
Mon May 28 09:25:19 EDT 2007


Try this:
_________________________
/*
 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 "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTextProperty.h"
#include "vtkCallbackCommand.h"
#include "vtkCamera.h"

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

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();
        }
        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)", xp, yp, zp );
            textMapper->SetInput( text );
            textActor->SetPosition(x, y);
            textActor->VisibilityOn();
        }
   
        renWin->Render();
    }
};

void PickerInteractionCallback( vtkObject* vtkNotUsed(object),
                                       unsigned long event,
                                       void* clientdata,
                                       void* vtkNotUsed(calldata) )
{
    vtkInteractorStyleTrackballCamera * style = 
(vtkInteractorStyleTrackballCamera*)clientdata;
    switch( event )
    {
    case vtkCommand::LeftButtonPressEvent:
        MouseMotion = 0;
        style->OnLeftButtonDown();
        break;
    case vtkCommand::LeftButtonReleaseEvent:
        if (MouseMotion == 0)
        {
            int *pick = iren->GetEventPosition();
            picker->Pick((double)pick[0], (double)pick[1], 0.0, ren1);
        }
        style->OnLeftButtonUp();
        break;
    case vtkCommand::MouseMoveEvent:
        MouseMotion = 1;
        style->OnMouseMove();
        break;
    }
}


int main(int argc, char* argv)
{
    MouseMotion = 0;
    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 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);
    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(300, 300);

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

    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();
//    iren->Delete();
}
___________________________

付文宇 wrote:

>Hi everyone:
>   vtk has given an example written by tcl, which can get point coordinates by
>clicking leftmousebutton directly. I converted tcl codes into C++. But  C++
>programme converted by myself only can get point coordinates by preesing 'p' key.
>I guess the problem lie in callback function. I converted following tcl codes
>"picker AddObserver EndPickEvent annotatePick"
>   "style AddObserver LeftButtonPressEvent {set MouseMotion 0; style
>OnLeftButtonDown}"
>   "style AddObserver MouseMoveEvent {set MouseMotion 1; style OnMouseMove}"
>   "style AddObserver LeftButtonReleaseEvent cbLBR" into C++ codes:
>
>class vtkMyCallback : public vtkCommand
>{
>public:
>  static vtkMyCallback *New() 
>    { return new vtkMyCallback; }
>  virtual void Execute(vtkObject *caller, unsigned long, void*)
>  { 
>    if(picker->GetCellId()<0)
>	{
>		textActor->VisibilityOff();
>	}
>	else
>	{
>		double *coordinates=new double[3];
>		coordinates=picker->GetSelectionPoint();
>		double x=coordinates[0];
>		double y=coordinates[1];
>		double *data=new double[3];
>		data=picker->GetPickPosition();
>		double xp=data[0];
>		double yp=data[1];
>		double zp=data[2];
>		textMapper->SetInput("xp+yp+zp");
>		textActor->SetPosition(x, y);
>		textActor->VisibilityOn();
>	}
>	renWin->Render();
>  }
>};
>
>class vtkMyCallback1 : public vtkCommand
>{
>public:
>  static vtkMyCallback1 *New() 
>    { return new vtkMyCallback1; }
>  virtual void Execute(vtkObject *caller, unsigned long, void*)
>  { 
>	MouseMotion=0;
>	style->OnLeftButtonDown();
>  }
>};
>
>class vtkMyCallback2 : public vtkCommand
>{
>public:
>  static vtkMyCallback2 *New() 
>    { return new vtkMyCallback2; }
>  virtual void Execute(vtkObject *caller, unsigned long, void*)
>  { 
>	MouseMotion=1;
>	style->OnMouseMove();
>  }
>};
>class cbLBR : public vtkCommand
>{
>public:
>  static cbLBR *New() 
>    { return new cbLBR; }
>  virtual void Execute(vtkObject *caller, unsigned long, void*)
>  { 
>	  	if(MouseMotion==0)
>	{
>		double *xycoordinate=new double[2];
>		xycoordinate=(double*)iren->GetEventPosition();
>		double x=xycoordinate[0];
>		double y=xycoordinate[1];
>		picker->Pick(x,y,0,ren1);
>	}
>	//#Do(the, default, things, for, the, trackball, style);
>	style->OnLeftButtonUp();
>
>  }
>};
>int main()
>{
>.....
>
>	vtkMyCallback *annotatePick = vtkMyCallback::New();
>	picker->AddObserver(vtkCommand::EndPickEvent, annotatePick);
>.....
>	// Create the Renderer, RenderWindow, and RenderWindowInteractor
>	style = vtkInteractorStyleTrackballCamera::New();
>	vtkMyCallback1 *LeftButPre = vtkMyCallback1::New();
>	style->AddObserver(vtkCommand::LeftButtonPressEvent, LeftButPre);
>	vtkMyCallback2 *mousemove = vtkMyCallback2::New();
>	style->AddObserver(vtkCommand::MouseMoveEvent,mousemove);
>	cbLBR *cblbr=cbLBR::New();
>	style->AddObserver(vtkCommand::LeftButtonReleaseEvent,cblbr);
>	ren1 = vtkRenderer::New();
>	renWin = vtkRenderWindow::New();
>	renWin->AddRenderer(ren1);
>	iren = vtkRenderWindowInteractor::New();
>	iren->SetRenderWindow(renWin);
>	iren->SetInteractorStyle(style);
>	iren->SetPicker(picker);
>.....
>} 
>
>But C++ programme converted by myself only can get point coordinates by pressing
>'p' key. It cannot get point coordinates by clicking leftmousebutton
>directly.
>
>The following are original TCL programme.
>---------------------------------------------------------
>
>package require vtk
>package require vtkinteraction
>vtkSphereSource sphere
>vtkPolyDataMapper sphereMapper
>    sphereMapper SetInput [sphere GetOutput]
>    sphereMapper GlobalImmediateModeRenderingOn
>vtkLODActor sphereActor
>    sphereActor SetMapper sphereMapper
>vtkConeSource cone
>vtkGlyph3D glyph
>    glyph SetInput [sphere GetOutput]
>    glyph SetSource [cone GetOutput]
>    glyph SetVectorModeToUseNormal
>    glyph SetScaleModeToScaleByVector
>    glyph SetScaleFactor 0.25
>vtkPolyDataMapper spikeMapper
>    spikeMapper SetInput [glyph GetOutput]
>vtkLODActor spikeActor
>    spikeActor SetMapper spikeMapper
>vtkCellPicker picker
>    picker AddObserver EndPickEvent annotatePick
>vtkTextMapper textMapper
>set tprop [textMapper GetTextProperty]
>    $tprop SetFontFamilyToArial
>    $tprop SetFontSize 10
>    $tprop BoldOn
>    $tprop ShadowOn
>    $tprop SetColor 1 0 0
>vtkActor2D textActor
>    textActor VisibilityOff
>    textActor SetMapper textMapper
>vtkInteractorStyleTrackballCamera style
>    style AddObserver LeftButtonPressEvent {set MouseMotion 0; style
>OnLeftButtonDown}
>    style AddObserver MouseMoveEvent {set MouseMotion 1; style OnMouseMove}
>    style AddObserver LeftButtonReleaseEvent cbLBR
>vtkRenderer ren1
>vtkRenderWindow renWin
>    renWin AddRenderer ren1
>vtkRenderWindowInteractor iren
>    iren SetRenderWindow renWin
>    iren SetInteractorStyle style
>    iren SetPicker picker
>ren1 AddActor2D textActor
>ren1 AddActor sphereActor
>ren1 AddActor spikeActor
>ren1 SetBackground 1 1 1
>renWin SetSize 300 300
>set cam1 [ren1 GetActiveCamera]
>$cam1 Zoom 1.4
>iren AddObserver UserEvent {wm deiconify .vtkInteract}
>iren Initialize
>wm withdraw .
>proc annotatePick {} {
>    if { [picker GetCellId] < 0 } {
>	textActor VisibilityOff
>    } else {
>	set selPt [picker GetSelectionPoint]
>	set x [lindex $selPt 0] 
>	set y [lindex $selPt 1]
>	set pickPos [picker GetPickPosition]
>	set xp [lindex $pickPos 0] 
>	set yp [lindex $pickPos 1]
>	set zp [lindex $pickPos 2]
>	textMapper SetInput "($xp, $yp, $zp)"
>	textActor SetPosition $x $y
>	textActor VisibilityOn
>    }
>    renWin Render
>}
>proc cbLBR {} {
>  global MouseMotion
>  if {$MouseMotion == 0} {
>    eval picker Pick [iren GetEventPosition] 0 ren1
>  }
>  # Do the default things for the trackball style
>  style OnLeftButtonUp 
>}
>picker Pick 85 126 0 ren1
>--------------------------------------------------------------------------
>Could someone give me some suggestions? 
>Thanks in advance.
>
> 
>Fuwenyu
>2007.05.26
>   
>
>
>_______________________________________________
>This is the private VTK discussion list. 
>Please keep messages on-topic. Check the FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>Follow this link to subscribe/unsubscribe:
>http://www.vtk.org/mailman/listinfo/vtkusers
>
>  
>



More information about the vtkusers mailing list