vtk框选实现-vtkInteractorStyleRubberBand3D

1。先看效果图吧

在这里插入图片描述

2。实现的方式

1)利用vtk是观察者模式,事件回调函数实现后续的框选操作
定义回调函数
void fCallback(vtkObject *obj, unsigned long eid, void *clientdata, void *calldata)//定义自己的callback函数
caller事件的发出者,用来获取vtkRenderWindowInteractor等
QVTKInteractor interactor = QVTKInteractor::SafeDownCast( caller );
eid—事件的id用来匹配是否是你所需要的鼠标或者键盘事件
if(eid == vtkCommand::LeftButtonPressEvent)
在这里插入图片描述
设置回调函数
vtkCallbackCommand
result = vtkCallbackCommand::New();
result->SetCallback(fCallback);

添加到观察者上
this->m_RubberBandStyle = vtkSmartPointer::New();
this->m_RubberBandStyle->RenderOnMouseMoveOff();
this->m_RubberBandStyle->AddObserver(vtkCommand::SelectionChangedEvent, result);
设置当前的样式–做选取操作
m_CurVtkWgt->GetRenderWindow()->GetInteractor()->SetInteractorStyle(m_RubberBandStyle);
3.实现回调函数

int region[4];//获取左上右下4个点
this->m_RubberBandStyle->GetStartPosition(&region[0]);
this->m_RubberBandStyle->GetEndPosition(&region[2]);


// selection is a data-selection (not geometry selection).
int ordered_region[4];
ordered_region[0] = region[0] < region[2] ? region[0] : region[2];
ordered_region[2] = region[0] > region[2] ? region[0] : region[2];
ordered_region[1] = region[1] < region[3] ? region[1] : region[3];
ordered_region[3] = region[1] > region[3] ? region[1] : region[3];



int displayRectangle[4] = { ordered_region[0], ordered_region[1], ordered_region[2], ordered_region[3] };
if (displayRectangle[0] == displayRectangle[2])
{
    displayRectangle[2] += 1;
}
if (displayRectangle[1] == displayRectangle[3])
{
    displayRectangle[3] += 1;
}

// 1) Create frustum selection
// convert screen rectangle to world frustum
vtkRenderer* renderer = m_CurVtkWgt->defaultRenderer();
double frustum[32];
int index = 0;
renderer->SetDisplayPoint(displayRectangle[0], displayRectangle[1], 0);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[0], displayRectangle[1], 1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[0], displayRectangle[3], 0);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[0], displayRectangle[3], 1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[2], displayRectangle[1], 0);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[2], displayRectangle[1], 1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[2], displayRectangle[3], 0);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);
index++;
renderer->SetDisplayPoint(displayRectangle[2], displayRectangle[3], 1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(&frustum[index * 4]);

vtkSmartPointer<vtkExtractSelectedFrustum> extractor = vtkSmartPointer<vtkExtractSelectedFrustum>::New();
extractor->CreateFrustum(frustum);
extractor->SetInputData(m_pointActor->GetMapper()->GetInput());//所有点的信息



vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =
        vtkSmartPointer<vtkVertexGlyphFilter>::New();
glyphFilter->SetInputConnection(extractor->GetOutputPort());//获取选择点
glyphFilter->Update();

//获取选择的区块
vtkSmartPointer extractPolyDataGeometry = vtkSmartPointer::New();
vtkPlanes* pl = extractor->GetFrustum();
extractPolyDataGeometry->SetInputData(m_Actor->GetMapper()->GetInput());//区块信息
extractPolyDataGeometry->SetImplicitFunction(pl);
extractPolyDataGeometry->ExtractBoundaryCellsOff();
extractPolyDataGeometry->Update();

vtkPolyData* selected = nullptr;
switch(this->m_PickActionType)
{
case eAction_pickVertex:
case eAction_pickNode:
    selected= glyphFilter->GetOutput();
    m_selectionActor->GetProperty()->SetPointSize(3);
    break;
case eAction_pickFace:
case eAction_pickFaceMesh:
    selected= extractPolyDataGeometry->GetOutput();
    m_selectionActor->GetProperty()->SetLineWidth(1);
    break;
}

if(selected == nullptr)
    return;
VTK_CREATE(vtkDataSetMapper, selectedMapper);
selectedMapper->SetInputData(selected);

selectedMapper->ScalarVisibilityOff();
double p[3]={0,0,0};
m_selectionActor->SetPosition(p);
m_selectionActor->SetMapper(selectedMapper);
// m_selectionActor->GetProperty();//->EdgeVisibilityOn();
//  m_selectionActor->GetProperty()->SetEdgeColor(1,0,0);
m_selectionActor->SetScale(1);
m_selectionActor->GetProperty()->SetColor(1,0,0);

m_CurVtkWgt->defaultRenderer()->AddActor(m_selectionActor);
m_CurVtkWgt->GetRenderWindow()->Render();