不知道为什么对于vtkBoxWidget 实例 boxWidget,通过AddObserver添加LeftButtonPressEvent类型事件,不能响应。但改为InteractionEvent类型的就可以。我试了下,似乎vtkRenderWindowInteractor 会响应LeftButtonPressEvent类型事件。
于是为了能给物体添加点的拾取功能,先通过为 vtkRenderWindowInteractor * iren 添加消息响应类
class vtkLeftButtonPress :
public vtkCommand
{
public:
static vtkLeftButtonPress* New(){return new vtkLeftButtonPress;}
void Delete(){delete this;};
void SetParameters(vtkRenderer* r){m_ren = r;}
virtual void Execute(vtkObject * caller, unsigned long l, void *callData)
{
// if(!m_picker) return;
vtkRenderWindowInteractor* iren = reinterpret_cast<vtkRenderWindowInteractor*>(caller);
vtkAbstractPicker * picker = iren->GetPicker();
int *pickPos = iren->GetEventPosition();
picker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, m_ren);
}
protected:
vtkRenderer* m_ren;
};
然后 lbp->SetParameters(ren);把vtkRenderer传递进来,再添加事件处理
iren->AddObserver(vtkCommand::LeftButtonPressEvent, lbp); iren得到鼠标左击事件,并对vktPointPick进行PicK.
这样pointPicker就能收到EndPickEvent命令,并进行相应的处理,
我们为vtkPointPicker *pointPicker添加消息响应类
class vtkPrintPointID :
public vtkCommand
{
public:
static vtkPrintPointID* New(){return new vtkPrintPointID;}
void Delete(){delete this;};
virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
{
vtkPointPicker* ptPicker = reinterpret_cast<vtkPointPicker*>(caller);
std::cout<<ptPicker->GetPointId()<<endl;
}
};
最终就能显示点击顶点的索引号
主要源码:
// Arrays.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: Arrays.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// This example demonstrate the use of VTK data arrays as attribute
// data as well as field data. It creates geometry (vtkPolyData) as
// well as attribute data explicitly.
// first include the required header files for the vtk classes we are using
#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkPointPicker.h"
#include <iostream>
#include "vtkCommand.h"
class vtkLeftButtonPress :
public vtkCommand
{
public:
static vtkLeftButtonPress* New(){return new vtkLeftButtonPress;}
void Delete(){delete this;};
void SetParameters(vtkRenderer* r){m_ren = r;}
virtual void Execute(vtkObject * caller, unsigned long l, void *callData)
{
// if(!m_picker) return;
vtkRenderWindowInteractor* iren = reinterpret_cast<vtkRenderWindowInteractor*>(caller);
vtkAbstractPicker * picker = iren->GetPicker();
int *pickPos = iren->GetEventPosition();
picker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, m_ren);
}
protected:
vtkRenderer* m_ren;
};
class vtkPrintPointID :
public vtkCommand
{
public:
static vtkPrintPointID* New(){return new vtkPrintPointID;}
void Delete(){delete this;};
virtual void Execute(vtkObject *caller, unsigned long l, void *callData)
{
vtkPointPicker* ptPicker = reinterpret_cast<vtkPointPicker*>(caller);
// ptPicker->Pick((double)pickPos[0], (double)pickPos[1], 0.0, g_ren1);//触发了EndPickEvent:在CHoleRepairDlg::OnLandmark()中的g_picker->AddObserver( vtkCommand::EndPickEvent, landmarkObserver );
std::cout<<ptPicker->GetPointId()<<endl;
}
};
int main()
{
int i;
// Create a float array which represents the points.
vtkFloatArray* pcoords = vtkFloatArray::New();
// Note that by default, an array has 1 component.
// We have to change it to 3 for points
pcoords->SetNumberOfComponents(3);
// We ask pcoords to allocate room for at least 4 tuples
// and set the number of tuples to 4.
pcoords->SetNumberOfTuples(4);
// Assign each tuple. There are 5 specialized versions of SetTuple:
// SetTuple1 SetTuple2 SetTuple3 SetTuple4 SetTuple9
// These take 1, 2, 3, 4 and 9 components respectively.
float pts[4][3] = { {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, 1.0, 0.0}, {1.0, 1.0, 0.0} };
for (i=0; i<4; i++)
{
pcoords->SetTuple(i, pts[i]);
}
// Create vtkPoints and assign pcoords as the internal data array.
vtkPoints* points = vtkPoints::New();
points->SetData(pcoords);
// Create the cells. In this case, a triangle strip with 2 triangles
// (which can be represented by 4 points)
vtkCellArray* strips = vtkCellArray::New();
strips->InsertNextCell(4);
strips->InsertCellPoint(0);
strips->InsertCellPoint(1);
strips->InsertCellPoint(2);
strips->InsertCellPoint(3);
// Create an integer array with 4 tuples. Note that when using
// InsertNextValue (or InsertNextTuple1 which is equivalent in
// this situation), the array will expand automatically
vtkIntArray* temperature = vtkIntArray::New();
temperature->SetName("Temperature");
temperature->InsertNextValue(10);
temperature->InsertNextValue(200);
temperature->InsertNextValue(10);
temperature->InsertNextValue(10);
// Create a double array.
vtkDoubleArray * vorticity = vtkDoubleArray::New();
vorticity->SetName("Vorticity");
vorticity->InsertNextValue(2.7);
vorticity->InsertNextValue(4.1);
vorticity->InsertNextValue(5.3);
vorticity->InsertNextValue(3.4);
// Create the dataset. In this case, we create a vtkPolyData
vtkPolyData* polydata = vtkPolyData::New();
// Assign points and cells
polydata->SetPoints(points);
polydata->SetStrips(strips);
// Assign scalars
polydata->GetPointData()->SetScalars(temperature);
// Add the vorticity array. In this example, this field
// is not used.
polydata->GetPointData()->AddArray(vorticity);
// Create the mapper and set the appropriate scalar range
// (default is (0,1)
vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
mapper->SetInput(polydata);
mapper->SetScalarRange(0, 250);
// Create an actor.
vtkActor* actor = vtkActor::New();
actor->SetMapper(mapper);
// Create the rendering objects.
vtkRenderer* ren = vtkRenderer::New();
ren->AddActor(actor);
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
vtkPointPicker * pointPicker = vtkPointPicker::New();
vtkLeftButtonPress * lbp = vtkLeftButtonPress::New();
lbp->SetParameters(ren);
iren->AddObserver(vtkCommand::LeftButtonPressEvent, lbp);
vtkPrintPointID *ppID = vtkPrintPointID::New();
pointPicker->AddObserver(vtkCommand::EndPickEvent, ppID);
iren->SetPicker(pointPicker); //设置picker
iren->Initialize();
iren->Start();
ppID->Delete();
pcoords->Delete();
points->Delete();
strips->Delete();
temperature->Delete();
vorticity->Delete();
polydata->Delete();
mapper->Delete();
actor->Delete();
ren->Delete();
renWin->Delete();
pointPicker->Delete();
iren->Delete();
return 0;
}