1.vtkHull类
vtkHull是一个过滤器,它将在给定一组n个平面的情况下生成一个n边凸包。(凸面外壳限制输入多边形数据。)外壳是通过向输入vtkPolyData挤压平面生成的,直到平面刚好接触vtkPolyData。然后,生成的平面用于生成由三角形表示的多面体(即外壳)。
n个平面可通过多种方式定义,包括
1)手动指定每个平面;
2)选择输入边界框的六个面平面;
3)选择输入边界框的八个顶点平面;
4)选择输入边界框的12个边平面;和/或5)使用递归细分的八面体。
请注意,指定平面时,平面法线应指向凸面区域之外。
此过滤器的输出可与vtkLODActor结合使用,以表示LOD层次结构中的详细级别。此类的另一个用途是手动指定平面,然后从平面生成多面体(不向输入方向挤压平面)。方法GenerateHull()用于执行此操作。
1.1对外接口
1.1.1指定平面
void RemoveAllPlanes(void);
从当前平面集中删除所有平面。
int AddPlane(double A, double B, double C);
int AddPlane(double plane[3]);
函数功能:将平面添加到当前平面集。
它将被添加到列表的末尾,并返回一个稍后可用于设置此平面法线的索引。值A、B、C来自平面方程Ax+By+Cz+D=0。此向量不必具有单位长度(但必须具有非零长度!)。如果返回值0>i>=-NumberOfPlanes,则该平面与先前插入的平面平行,|-i-1|是先前插入的平面的索引。如果返回值i<-NumberOfPlanes,则平面法线长度为零。
void SetPlane(int i, double A, double B, double C);
void SetPlane(int i, double plane[3]);
设置平面i对应的法线值。
这是一个已使用AddPlane()添加到当前平面集的平面,现在正在修改。值A、B、C来自平面方程Ax+By+Cz+D=0。该向量不必具有单位长度。请注意,D被设置为零,但采用vtkPlanes*参数的方法除外,其中D被设置为此处定义的D值。
int AddPlane(double A, double B, double C, double D);
int AddPlane(double plane[3], double D);
void SetPlane(int i, double A, double B, double C, double D);
void SetPlane(int i, double plane[3], double D);
允许设置D的AddPlane()/SetPlane()的变体(函数重载)。
使用GenerateHull()时使用这些方法。
void SetPlanes(vtkPlanes* planes);
使用vtkPlanes隐式函数一次设置所有平面。
这还设置了D值,因此可以与GenerateHull()一起使用。
vtkGetMacro(NumberOfPlanes, int);
获取当前平面集的平面个数;
void AddCubeVertexPlanes();
添加表示立方体顶点的8个平面-连接到顶点的三个面平面的组合
(1,1,1), (1,1,-1), (1,-1,1), (1,-1,1),
(-1,1,1), (-1,1,-1), (-1,-1,1), (-1,-1-1)
从对角顶点的连线作为平面的法线,一根对角线从两个方向产生两个平面,法线方向相反;
void AddCubeEdgePlanes();
添加表示立方体边的12个平面-位于两个连接面平面的中间
(1,1,0), (-1,-1,0), (-1,1,0), (1,-1,0),
(0,1,1), (0,-1,-1), (0,1,-1), (0,-1,1),
(1,0,1), (-1,0,-1), (1,0,-1), (-1,0,1)
每个平面上的对角线作为法线,6个平面,会有6个不相同的对角连线(其中有6个对角连线是和其他相同的对角连线),6根直线可以确定12个不同方向的向量,从而构成12个平面;
void AddCubeFacePlanes();
添加构成立方体面的六个平面;
(1,0,0), (-1, 0, 0), (0,1,0),
(0,-1,0), (0,0,1), (0,0,-1)
与立方体6个平面平行的6个面,可以从12条边中,找到向量不相同的6个向量作为平面法向量;
void AddRecursiveSpherePlanes(int level);
添加表示通过在八面体中递归细分三角形而形成的多边形球体顶点法线的平面。
每个三角形通过连接边的中点进行细分,从而形成4个较小的三角形。
级别表示进行了多少次细分;
级别0表示用于从原始八面体添加6个平面,即从八面体进行一次细化,每条边上的中点与平面上相邻边上的中点相连接;一个顶点变成了4个顶点,则从之前的6个顶点变为24个顶点;
级别1将添加18个平面,从十四面体再进行一次细化;依此类推。
void GenerateHull(vtkPolyData* pd, double* bounds);
void GenerateHull(
vtkPolyData* pd,
double xmin, double xmax,
double ymin, double ymax,
double zmin, double zmax);
一种特殊方法,用于直接从一组n个平面生成多面体。
用户提供的平面不会挤压到输入数据(实际上用户不需要指定输入)。若要使用此方法,必须提供vtkPolyData的实例,定义多面体的点和单元将放置在该实例中。您还必须提供一个边界框,期望生成的多面体位于该边界框中。这可能是一个非常慷慨的配合,它只用于创建最终剪裁的初始多边形。
1.2示例代码
#include <vtkActor.h>
#include <vtkDataSetMapper.h>
#include <vtkHull.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkXMLPolyDataReader.h>
int main(int argc, char* argv[]){
// Parse command line arguments
if (argc != 2) {
std::cout << "Required arguments: Filename e.g. cowHead.vtp" << std::endl;
return EXIT_FAILURE;
}
vtkNew<vtkNamedColors> namedColors;
vtkNew<vtkXMLPolyDataReader> reader;
reader->SetFileName(argv[1]);
vtkNew<vtkHull> hullFilter;
hullFilter->SetInputConnection(reader->GetOutputPort());
hullFilter->AddCubeFacePlanes();
hullFilter->AddRecursiveSpherePlanes(5);
vtkNew<vtkDataSetMapper> originalMapper;
originalMapper->SetInputConnection(reader->GetOutputPort());
originalMapper->ScalarVisibilityOff();
// Create an actor for the surface
vtkNew<vtkActor> originalActor;
originalActor->SetMapper(originalMapper);
originalActor->GetProperty()->SetDiffuseColor(namedColors->GetColor3d("Banana").GetData());
vtkNew<vtkDataSetMapper> mapper;
mapper->SetInputConnection(hullFilter->GetOutputPort());
mapper->ScalarVisibilityOff();
// Create an actor for the surface
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetDiffuseColor(namedColors->GetColor3d("Tomato").GetData());
actor->GetProperty()->SetEdgeColor(namedColors->GetColor3d("IvoryBlack").GetData());
actor->GetProperty()->SetOpacity(0.5);
actor->GetProperty()->EdgeVisibilityOff();
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("ConvexHull");
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
renderer->AddActor(originalActor);
renderer->AddActor(actor);
renderer->SetBackground(namedColors->GetColor3d("SlateGray").GetData());
renderWindow->Render();
interactor->Start();
return EXIT_SUCCESS;
}
计算结果,如下: