[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