1.单位拾取

示例代码:

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)

#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkDataSetMapper.h>
#include <vtkCellPicker.h>
#include <vtkSelectionNode.h>
#include <vtkSelection.h>
#include <vtkRendererCollection.h>
#include <vtkExtractSelection.h>
#include <vtkObjectFactory.h>

/**************************************************************************/
class CellPickerInteractorStyle :public vtkInteractorStyleTrackballCamera
{
public:
static CellPickerInteractorStyle* New();

CellPickerInteractorStyle()
{
selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();
selectedActor = vtkSmartPointer<vtkActor>::New();
}
virtual void OnLeftButtonDown()
{
int* pos = this->GetInteractor()->GetEventPosition();
vtkSmartPointer<vtkCellPicker> picker =
vtkSmartPointer<vtkCellPicker>::New();
picker->SetTolerance(0.0005);
picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());

if (picker->GetCellId() != -1)
{
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
ids->SetNumberOfComponents(1);
ids->InsertNextValue(picker->GetCellId());

vtkSmartPointer<vtkSelectionNode> selectionNode =
vtkSmartPointer<vtkSelectionNode>::New();
selectionNode->SetFieldType(vtkSelectionNode::CELL);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);

vtkSmartPointer<vtkSelection> selection =
vtkSmartPointer<vtkSelection>::New();
selection->AddNode(selectionNode);

vtkSmartPointer<vtkExtractSelection> extractSelection =
vtkSmartPointer<vtkExtractSelection>::New();
extractSelection->SetInputData(0, polyData);
extractSelection->SetInputData(1, selection);
extractSelection->Update();

selectedMapper->SetInputData((vtkDataSet*)extractSelection->GetOutput());
selectedActor->SetMapper(selectedMapper);
selectedActor->GetProperty()->EdgeVisibilityOn();
selectedActor->GetProperty()->SetEdgeColor(1, 0, 0);
selectedActor->GetProperty()->SetLineWidth(3);

this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(selectedActor);
}
vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}
private:
vtkSmartPointer<vtkPolyData> polyData;
vtkSmartPointer<vtkDataSetMapper> selectedMapper;
vtkSmartPointer<vtkActor> selectedActor;
};
/*********************************************************************************/

vtkStandardNewMacro(CellPickerInteractorStyle);

int main()
{
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->Update();

vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(sphereSource->GetOutput());

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

vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(1, 1, 1);

vtkSmartPointer<vtkRenderWindow> rw =
vtkSmartPointer<vtkRenderWindow>::New();
rw->Render();
rw->SetWindowName("CellPicker Interaction");
rw->AddRenderer(renderer);

vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
/****************************************************************************/
vtkSmartPointer<CellPickerInteractorStyle> style =
vtkSmartPointer<CellPickerInteractorStyle>::New();
style->SetDefaultRenderer(renderer);
//style->polyData = sphereSource->GetOutput();
rwi->SetInteractorStyle(style);

rw->Render();
rwi->Initialize();
rwi->Start();
return 0;
}

输出结果如下:

VTK_Learning_交互与拾取_单位拾取_置数据

CellPickerInteractorStyle类同样派生自vtkInteraTrackballCamera,并通过重载该函数类的OnLeftButtonDown()函数来处理鼠标左键消息。PolyData为被拾取的模型数据,需要通过外部设置。在响应鼠标左键消息时,首先定义vtkCellPicker对象,使用Pick()函数实现拾取功能。拾取完毕,即可通过GetCellId()函数来得到当前拾取的单元索取号。
为了更方便地显示拾取的结果,可实现单元边的高亮显示。这里就涉及了vtkPolyData的局部数据提取功能。实现该功能时使用了几个新的类。

  • vtkIdTypeArray:对象存储当前选中的单位的索引号,每次只选取一个单元,因此每次该对象仅有一个索引号;
  • vtkSelectedNode对象与vtkSelection对象通常搭配使用,vtkSelection实际上是一个vtkSelectionNode的数组,而vtkSelectionNode则声明了要提取的数据的类型,这里SetFiledType()设置数据的类型为单元,SeiContentType()设置数据的内容为索引号。
  • vtkExtractSelection:实现了数据提取功能,其第一个输入为被提取的vtkPolyData,第二个输入为vtkSelection对象,标记要提取的数据类型。

提取完毕,即可将提取的结果保存至一个vtkActor对象,并添加至当前的vtkRenderer中显示。