vtkSelectPolyData
vtkSelectPolyData是一个Filter,它基于定义“循环”并指示循环内的区域来选择多边形数据。Loop循环中的网格由完整的单元组成(单元未被切割)。vtkSelectPolyData可以用来生成标量。这些标量值是到Loop循环的距离度量,可用于剪裁、绘制轮廓。或者提取数据(即隐式函数可以做的任何事情)。
Loop循环由x-y-z点坐标数组定义(坐标应与输入的多边形数据位于同一坐标空间。)回路可以是凹面和非平面的,但不能是自交的。
Filter输入是:多边形网格(仅曲面基本体,如三角形条带和多边形);
Filter输出是:
a)原始网格的一部分在选择循环中(GenerateSelectionScalarsOff)。
b)添加标量值的相同多边形网格(GenerateSelectionScalarsOn)。
算法的工作原理如下:
对于循环中的每个点坐标,将找到网格中最近的点。结果是网格中最近点ids的循环。然后,在网格中找到连接最近点(并沿形成回路的线排列)的边。贪婪的边缘跟踪过程如下所示。在当前点,将选择朝向的方向且其终点最接近直线的网格边。沿着边到达新的端点,然后重复该过程。此过程将继续,直到创建了整个循环。
要确定网格的哪个部分在循环的内部和外部,可以使用三个选项:1) 最小连通区域,2)最大连通区域,3)最接近用户指定点的连通区域(设置ivar选择模式SelectionMode)。
循环按上述方式计算后,GenerateSelectionScalars将控制过滤器的输出。如果启用,则基于到环线的距离生成标量值。否则,将输出位于选择循环内的单元格。默认情况下,输出在循环中铺设的网格;但是,如果“InsideOut”处于启用状态,则输出位于循环外部的网格部分。
通过设置GenerateUnselectedOutput,可以将过滤器配置为生成网格的未选定部分作为输出。使用GetUnselectedOutput()方法访问此输出(注意:仅当GenerateSelectionScalars处于禁用状态时,此标志才相关)。
注意:要确保拾取的点位于连接的曲面上。否则,Filter将生成一个空的或部分的结果。此外,自交Loop将产生不可预测的结果,所以输入闭合点集不要自相交;在数据处理过程中,如果禁用GenerateSelectionScalars,则非三角形单元将转换为三角形。
注意:vtkImplicitSelectionLoop类是隐函数,用来做裁剪的,vtkSelectPolyDatas是数据集,使用SetLoop设置隐函数用来裁剪多边形数据,vtkSelectPolyDatas是选择多边形表面区域,vtkClipPolyData类使用SetClipFunction设置隐函数裁剪多边形,不同的是vtkClipPolyData裁剪的是贯穿了多边形的区域;
接口
输入源
vtkSelectPolyData使用SetInputConnection和SetInputData函数,输入源为vtkPolyData指针;
闭合点集
由三个点以上构成的vtkPoints集合,点与点之间不可自交;
vtkPoints* Loop;
virtual void SetLoop(vtkPoints*);
vtkGetObjectMacro(Loop, vtkPoints);
输出
vtkSelectPolyData使用GetOutputPort()方法获取到裁剪出的数据集;
可以设置GenerateUnselectedOutputx选择是否启用“输出裁剪后剩余区域的数据集”,如果开启后,就可以使用方法GetUnselectedOutput()来获得被选择后其他剩余数据;
使用GetSelectionEdges()方法选择区域的(网格)边。
vtkTypeBool GenerateUnselectedOutput;
vtkSetMacro(GenerateUnselectedOutput, vtkTypeBool);
vtkGetMacro(GenerateUnselectedOutput, vtkTypeBool);
vtkBooleanMacro(GenerateUnselectedOutput, vtkTypeBool);
vtkPolyData* GetUnselectedOutput();
vtkPolyData* GetSelectionEdges();
被选择部分模式
要确定网格的哪个部分在循环的内部和外部,可以使用三个选项:1) 最小连通区域,2)最大连通区域,3)最接近用户指定点的连通区域(设置ivar选择模式SelectionMode)
#define VTK_INSIDE_SMALLEST_REGION 0
#define VTK_INSIDE_LARGEST_REGION 1
#define VTK_INSIDE_CLOSEST_POINT_REGION 2
可以使用下面的接口进行设置:
vtkSetClampMacro(SelectionMode, int, VTK_INSIDE_SMALLEST_REGION, VTK_INSIDE_CLOSEST_POINT_REGION);
vtkGetMacro(SelectionMode, int);
void SetSelectionModeToSmallestRegion() { this->SetSelectionMode(VTK_INSIDE_SMALLEST_REGION); }
void SetSelectionModeToLargestRegion() { this->SetSelectionMode(VTK_INSIDE_LARGEST_REGION); }
void SetSelectionModeToClosestPointRegion()
{
this->SetSelectionMode(VTK_INSIDE_CLOSEST_POINT_REGION);
}
const char* GetSelectionModeAsString();
示例
在圆球表面,选择一个闭合区域,将选中的区域和剩余区域分别显示在窗口的两个渲染器上;
#include <vtkProperty.h>
#include <vtkSelectPolyData.h>
#include <vtkSphereSource.h>
#include <vtkClipPolyData.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkLODActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkNamedColors.h>
class Test_vtkSelectPolyData {
public:
static void Test() {
vtkNew<vtkNamedColors> colors;
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetPhiResolution(50);
sphereSource->SetThetaResolution(100);
sphereSource->Update();
vtkNew<vtkPoints> loopPoints;
loopPoints->InsertNextPoint(-0.16553, 0.135971, 0.451972);
loopPoints->InsertNextPoint(-0.0880123, -0.134952, 0.4747);
loopPoints->InsertNextPoint(0.00292618, -0.134604, 0.482459);
loopPoints->InsertNextPoint(0.0641941, 0.067112, 0.490947);
loopPoints->InsertNextPoint(0.15577, 0.0734765, 0.469245);
loopPoints->InsertNextPoint(0.166667, -0.129217, 0.454622);
loopPoints->InsertNextPoint(0.241259, -0.123363, 0.420581);
loopPoints->InsertNextPoint(0.240334, 0.0727106, 0.432555);
loopPoints->InsertNextPoint(0.308529, 0.0844311, 0.384357);
loopPoints->InsertNextPoint(0.32672, -0.121674, 0.359187);
loopPoints->InsertNextPoint(0.380721, -0.117342, 0.302527);
loopPoints->InsertNextPoint(0.387804, 0.0455074, 0.312375);
loopPoints->InsertNextPoint(0.43943, -0.111673, 0.211707);
loopPoints->InsertNextPoint(0.470984, -0.0801913, 0.147919);
loopPoints->InsertNextPoint(0.436777, 0.0688872, 0.233021);
loopPoints->InsertNextPoint(0.44874, 0.188852, 0.109882);
loopPoints->InsertNextPoint(0.391352, 0.254285, 0.176943);
loopPoints->InsertNextPoint(0.373274, 0.154162, 0.294296);
loopPoints->InsertNextPoint(0.274659, 0.311654, 0.276609);
loopPoints->InsertNextPoint(0.206068, 0.31396, 0.329702);
loopPoints->InsertNextPoint(0.263789, 0.174982, 0.387308);
loopPoints->InsertNextPoint(0.213034, 0.175485, 0.417142);
loopPoints->InsertNextPoint(0.169113, 0.261974, 0.390286);
loopPoints->InsertNextPoint(0.102552, 0.25997, 0.414814);
loopPoints->InsertNextPoint(0.131512, 0.161254, 0.454705);
loopPoints->InsertNextPoint(0.000192443, 0.156264, 0.475307);
loopPoints->InsertNextPoint(-0.0392091, 0.000251724, 0.499943);
loopPoints->InsertNextPoint(-0.096161, 0.159646, 0.46438);
vtkNew<vtkSelectPolyData> selectPolyData;
selectPolyData->SetInputConnection(sphereSource->GetOutputPort());
selectPolyData->SetLoop(loopPoints);
selectPolyData->GenerateUnselectedOutputOn();
selectPolyData->SetSelectionModeToSmallestRegion();
selectPolyData->Update();
vtkNew<vtkProperty> backProp;
backProp->SetColor(colors->GetColor3d("tomato").GetData());
vtkNew<vtkPolyDataMapper> selectMapper;
selectMapper->SetInputData(selectPolyData->GetUnselectedOutput());
vtkNew<vtkLODActor> selectActor;
selectActor->SetMapper(selectMapper);
selectActor->SetBackfaceProperty(backProp);
selectActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());
vtkNew<vtkPolyDataMapper> unselectMapper;
unselectMapper->SetInputConnection(selectPolyData->GetOutputPort());
vtkNew<vtkLODActor> unselectActor;
unselectActor->SetMapper(unselectMapper);
unselectActor->SetBackfaceProperty(backProp);
unselectActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());
vtkNew<vtkRenderer> renderer1;
vtkNew<vtkRenderer> renderer2;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer1);
renderWindow->AddRenderer(renderer2);
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
renderer1->AddActor(selectActor);
renderer1->SetBackground(colors->GetColor3d("slate_grey").GetData());
renderer1->SetViewport(0, 0, 0.5, 1);
renderer2->AddActor(unselectActor);
renderer2->SetBackground(colors->GetColor3d("slate_blue").GetData());
renderer2->SetViewport(0.5, 0, 1, 1);
renderWindow->SetSize(800, 400);
renderWindow->Render();
interactor->Start();
}
};