VTK Notes - Use the vtkHull class to obtain the convex hull of polygon data

1. vtkHull class

  vtkHull is a filter that will generate an n-sided convex hull given a set of n planes. (Convex hulls limit the input polygon data.) The hull is generated by extruding a plane against the input vtkPolyData until the plane just touches the vtkPolyData. The resulting planes are then used to generate polyhedra (i.e., shells) represented by triangles.
  The n planes can be defined in a number of ways, including
    1) manually specifying each plane;
    2) selecting the six face planes of the input bounding box;
    3) selecting the eight vertex planes of the input
    bounding box; 4) selecting the 12 edge planes; and/or 5) octahedra using recursive subdivision.
Note that when specifying a plane, the plane normal should point out of the convex area.
The output of this filter can be used in conjunction with vtkLODActor to represent the level of detail in the LOD hierarchy. Another use of this class is to manually specify a plane and then generate a polyhedron from the plane (without extruding the plane in the input direction). The method GenerateHull() is used to do this.

1.1 External interface

1.1.1 Designated plane

void RemoveAllPlanes(void);  

Removes all planes from the current set of planes.

int AddPlane(double A, double B, double C);
int AddPlane(double plane[3]);

Function function: add the plane to the current plane set.
It will be added to the end of the list and return an index which can later be used to set the normal of this plane. The values ​​A, B, C come from the plane equation Ax+By+Cz+D=0. This vector need not have unit length (but must have nonzero length!). If the return value is 0>i>=-NumberOfPlanes, the plane is parallel to the previously inserted plane, and |-i-1| is the index of the previously inserted plane. If the return value i<-NumberOfPlanes, the plane normal length is zero.

void SetPlane(int i, double A, double B, double C);
void SetPlane(int i, double plane[3]);

Set the normal value corresponding to plane i.
This is a plane that has been added to the current set of planes using AddPlane() and is now being modified. The values ​​A, B, C come from the plane equation Ax+By+Cz+D=0. The vector does not have to have unit length. Note that D is set to zero, except for methods that take vtkPlanes* parameters, where D is set to the D value defined here.

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);

Variants of AddPlane()/SetPlane() that allow setting D (function overloading).
Use these methods when using GenerateHull().

void SetPlanes(vtkPlanes* planes);

Use the vtkPlanes implicit function to set all planes at once.
This also sets the D value, so it can be used with GenerateHull().

vtkGetMacro(NumberOfPlanes, int); 

Get the number of planes in the current plane set;

void AddCubeVertexPlanes();  

Add 8 planes representing the vertices of the cube - the combination of the three face planes connected to the vertices
(1,1,1), (1,1,-1), (1,-1,1), (1,-1 ,1),
(-1,1,1), (-1,1,-1), (-1,-1,1), (-1,-1-1)
from the diagonal vertices as The normal of the plane, a diagonal produces two planes from two directions, and the normal direction is opposite;
insert image description here

void AddCubeEdgePlanes();  

Add 12 planes representing the sides of the cube - in the middle of the two connecting face planes
(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)
The diagonal on each plane is used as the normal, 6 planes, there will be 6 different diagonal connections Lines (6 of which are the same as other diagonal lines), 6 straight lines can determine 12 vectors in different directions, thus forming 12 planes;
insert image description here

void AddCubeFacePlanes();  

Add the six planes that make up the faces of the cube;
(1,0,0), (-1, 0, 0), (0,1,0),
(0,-1,0), (0,0,1) , (0,0,-1)
6 faces parallel to the 6 planes of the cube, you can find 6 vectors with different vectors from the 12 sides as the plane normal vector;
insert image description here

void AddRecursiveSpherePlanes(int level);    

Adds planes representing the vertex normals of polygonal spheres formed by recursively subdividing triangles in an octahedron.
insert image description hereinsert image description here

Each triangle is subdivided by connecting the midpoints of the sides, resulting in 4 smaller triangles.
The level indicates how many subdivisions were made;
level 0 is used to add 6 planes from the original octahedron, i.e. one refinement from the octahedron with the midpoint on each edge equal to the midpoint on the adjacent edge on the plane Connection; one vertex becomes 4 vertices, and the previous 6 vertices become 24 vertices;
insert image description here

Level 1 will add 18 planes, one more refinement from the tetradecahedron; and so on.
insert image description here

void GenerateHull(vtkPolyData* pd, double* bounds);  
void GenerateHull(
      vtkPolyData* pd,
double xmin, double xmax,
double ymin, double ymax, 
double zmin, double zmax);

A special method for generating polyhedra directly from a set of n planes.
A user-supplied plane is not extruded to the input data (in fact the user does not need to specify the input). To use this method, an instance of vtkPolyData must be provided in which the points and cells defining the polyhedron will be placed. You must also provide a bounding box within which the resulting multipatch is expected to lie. This can be a very generous fit, and it's only used to create the initial polygons for the final clipping.

1.2 sample code

#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;
}

The calculation result is as follows:

insert image description hereinsert image description hereinsert image description here

Guess you like

Origin blog.csdn.net/liushao1031177/article/details/122214077