标题小Tips: GetOutputPort()和 GetOutput()注意事项:GetOutput()需要使用Updata()方法 ,GetOutputPort()不需要
受约束剖分原理:可参考博客
约束条件:线
int main()
{
vtkNew<vtkNamedColors> colors;
vtkNew<vtkPoints> points;
points->InsertNextPoint(0, 0, 0);
points->InsertNextPoint(0, 10, 0);
points->InsertNextPoint(10, 0, 0);
points->InsertNextPoint(10, 10, 0);
points->InsertNextPoint(5, 0, 0);
points->InsertNextPoint(5, 10, 0);
points->InsertNextPoint(1.5, 1.5, 0);
points->InsertNextPoint(1.7, 1.7, 0);
points->InsertNextPoint(6.5, 1.5, 0);
points->InsertNextPoint(7.7, 1.7, 0);
points->InsertNextPoint(9, 9.5, 0);
points->InsertNextPoint(7.7, 6, 0);
points->InsertNextPoint(8, 5.5, 0);
points->InsertNextPoint(8.2, 4.7, 0);
points->InsertNextPoint(4, 9.5, 0);
points->InsertNextPoint(3.7, 6, 0);
points->InsertNextPoint(2, 5.5, 0);
points->InsertNextPoint(3.2, 4.7, 0);
points->InsertNextPoint(1.2, 8.6, 0);
points->InsertNextPoint(9.2, 8.6, 0);
points->InsertNextPoint(5.2, 6, 0);
points->InsertNextPoint(1.2, 4.6, 0);
points->InsertNextPoint(9.2, 4.6, 0);
vtkNew<vtkPolyData> originPolyData;
originPolyData->SetPoints(points);
vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
glyphFilter->SetInputData(originPolyData);
glyphFilter->Update();
vtkPolyDataWriter *w = vtkPolyDataWriter::New();
w->SetFileName("points.vtk");
w->SetInputData(glyphFilter->GetOutput());
w->Write();
w->Delete();
// UnConstrained Delaunay2D
vtkSmartPointer<vtkDelaunay2D> delaunay = vtkSmartPointer<vtkDelaunay2D>::New();
delaunay->SetInputData(originPolyData);
delaunay->Update();
vtkPolyDataWriter *w1 = vtkPolyDataWriter::New();
w1->SetFileName("triangle.vtk");
w1->SetInputData(delaunay->GetOutput());
w1->Write();
w1->Delete();
// Constrained Line
vtkNew<vtkCellArray> aCellArray;
vtkNew<vtkPolyLine> PolyLine;
PolyLine->GetPointIds()->InsertNextId(4);
PolyLine->GetPointIds()->InsertNextId(5);
aCellArray->InsertNextCell(PolyLine);
vtkNew<vtkPolyData> boundary;
boundary->SetPoints(originPolyData->GetPoints());
boundary->SetLines(aCellArray);
vtkPolyDataWriter *w2 = vtkPolyDataWriter::New();
w2->SetFileName("line.vtk");
w2->SetInputData(boundary);
w2->Write();
w2->Delete();
// Constrained Delaunay2D
vtkNew<vtkDelaunay2D> KMdelaunay;
KMdelaunay->SetInputData(originPolyData);
KMdelaunay->SetSourceData(boundary);
KMdelaunay->Update();
vtkPolyDataWriter *w3 = vtkPolyDataWriter::New();
w3->SetFileName("yueshudel.vtk");
w3->SetInputData(KMdelaunay->GetOutput());
w3->Write();
w3->Delete();
return;
// Visualize
vtkNew<vtkPolyDataMapper> meshMapper;
meshMapper->SetInputData(KMdelaunay->GetOutput());
vtkNew<vtkActor> meshActor;
meshActor->SetMapper(meshMapper);
meshActor->GetProperty()->EdgeVisibilityOn();
meshActor->GetProperty()->SetEdgeColor(
colors->GetColor3d("Peacock").GetData());
meshActor->GetProperty()->SetInterpolationToFlat();
vtkNew<vtkPolyDataMapper> boundaryMapper;
boundaryMapper->SetInputData(boundary);
vtkNew<vtkActor> boundaryActor;
boundaryActor->SetMapper(boundaryMapper);
boundaryActor->GetProperty()->SetColor(
colors->GetColor3d("Raspberry").GetData());
boundaryActor->GetProperty()->SetLineWidth(3);
boundaryActor->GetProperty()->EdgeVisibilityOn();
boundaryActor->GetProperty()->SetEdgeColor(
colors->GetColor3d("Red").GetData());
boundaryActor->GetProperty()->SetRepresentationToWireframe();
// Create a renderer, render window, and interactor
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actor to the scene
renderer->AddActor(meshActor);
renderer->AddActor(boundaryActor);
renderer->SetBackground(colors->GetColor3d("Mint").GetData());
// Render and interact
renderWindow->SetSize(640, 480);
renderWindow->SetWindowName("ConstrainedDelaunay2D");
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
结果输出:
红色线为约束边界线,白色点为原始点集
约束条件:洞多边形
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkDelaunay2D.h>
#include <vtkMath.h>
#include <vtkMinimalStandardRandomSequence.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
int main(int, char*[])
{
vtkNew<vtkNamedColors> colors;
// Generate a 10 x 10 grid of points
vtkNew<vtkPoints> points;
unsigned int gridSize = 10;
unsigned int seed = 0;
vtkNew<vtkMinimalStandardRandomSequence> randomSequence;
randomSequence->Initialize(seed);
for (unsigned int x = 0; x < gridSize; x++)
{
for (unsigned int y = 0; y < gridSize; y++)
{
auto d1 = randomSequence->GetValue() / 2.0 - 0.25;
randomSequence->Next();
auto d2 = randomSequence->GetValue() / 2.0 - 0.25;
randomSequence->Next();
points->InsertNextPoint(x + d1, y + d2, 0);
}
}
vtkNew<vtkPolyData> aPolyData;
aPolyData->SetPoints(points);
// Create a cell array to store the polygon in
vtkNew<vtkCellArray> aCellArray;
// Define a polygonal hole with a clockwise polygon
vtkNew<vtkPolygon> aPolygon;
aPolygon->GetPointIds()->InsertNextId(22);
aPolygon->GetPointIds()->InsertNextId(23);
aPolygon->GetPointIds()->InsertNextId(24);
aPolygon->GetPointIds()->InsertNextId(25);
aPolygon->GetPointIds()->InsertNextId(35);
aPolygon->GetPointIds()->InsertNextId(45);
aPolygon->GetPointIds()->InsertNextId(44);
aPolygon->GetPointIds()->InsertNextId(43);
aPolygon->GetPointIds()->InsertNextId(42);
aPolygon->GetPointIds()->InsertNextId(32);
aCellArray->InsertNextCell(aPolygon);
// Create a polydata to store the boundary. The points must be the
// same as the points we will triangulate.
vtkNew<vtkPolyData> boundary;
boundary->SetPoints(aPolyData->GetPoints());
boundary->SetPolys(aCellArray);
// Triangulate the grid points
vtkNew<vtkDelaunay2D> delaunay;
delaunay->SetInputData(aPolyData);
delaunay->SetSourceData(boundary);
// Visualize
vtkNew<vtkPolyDataMapper> meshMapper;
meshMapper->SetInputConnection(delaunay->GetOutputPort());
vtkNew<vtkActor> meshActor;
meshActor->SetMapper(meshMapper);
meshActor->GetProperty()->EdgeVisibilityOn();
meshActor->GetProperty()->SetEdgeColor(
colors->GetColor3d("Peacock").GetData());
meshActor->GetProperty()->SetInterpolationToFlat();
vtkNew<vtkPolyDataMapper> boundaryMapper;
boundaryMapper->SetInputData(boundary);
vtkNew<vtkActor> boundaryActor;
boundaryActor->SetMapper(boundaryMapper);
boundaryActor->GetProperty()->SetColor(
colors->GetColor3d("Raspberry").GetData());
boundaryActor->GetProperty()->SetLineWidth(3);
boundaryActor->GetProperty()->EdgeVisibilityOn();
boundaryActor->GetProperty()->SetEdgeColor(
colors->GetColor3d("Red").GetData());
boundaryActor->GetProperty()->SetRepresentationToWireframe();
// Create a renderer, render window, and interactor
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actor to the scene
renderer->AddActor(meshActor);
renderer->AddActor(boundaryActor);
renderer->SetBackground(colors->GetColor3d("Mint").GetData());
// Render and interact
renderWindow->SetSize(640, 480);
renderWindow->SetWindowName("ConstrainedDelaunay2D");
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}