引言
vtkClipClosedSurface
使用一组平面集合剪切闭合曲面。- 输入
vtkPolyData
闭合曲面和vtkPlaneCollection
一组剪裁平面。 - 输出
vtkPolyData
新多边形闭合曲面。
描述
通过画折线的方式来裁剪封闭的多边形曲面。
效果如下:
实现
模拟交互式生成折线
//裁剪多段线
double pt0[3] = { -2.0, 2.0, 2.0};
double pt1[3] = { 5.0, 2.0, 2.0 };
double pt2[3] = { 6.0,3.0, 2.0 };
double pt3[3] = { 8.0, 5.0, 2.0 };
double pt4[3] = { 8.0, 10.0, 2.0};
vtkSmartPointer<vtkPoints>polyline_pts =vtkSmartPointer<vtkPoints>::New();
polyline_pts->InsertNextPoint(pt0);
polyline_pts->InsertNextPoint(pt1);
polyline_pts->InsertNextPoint(pt2);
polyline_pts->InsertNextPoint(pt3);
polyline_pts->InsertNextPoint(pt4);
vtkSmartPointer<vtkPolyLine> polyline =vtkSmartPointer<vtkPolyLine>::New();
polyline->GetPointIds()->SetNumberOfIds(5);
for (unsigned int i = 0; i < 5; i++)
{
polyline->GetPointIds()->SetId(i, i);
}
vtkSmartPointer<vtkCellArray> cells =vtkSmartPointer<vtkCellArray>::New();
cells->InsertNextCell(polyline);
vtkSmartPointer<vtkPolyData> polylineData =vtkSmartPointer<vtkPolyData>::New();
polylineData->SetPoints(polyline_pts);
polylineData->SetLines(cells);
// Setup actor and mapper
vtkSmartPointer<vtkPolyDataMapper> polyline_mapper =vtkSmartPointer<vtkPolyDataMapper>::New();
polyline_mapper->SetInputData(polylineData);
vtkSmartPointer<vtkActor>polyline_actor =vtkSmartPointer<vtkActor>::New();
polyline_actor->SetMapper(polyline_mapper);
polyline_actor->GetProperty()->SetColor(10, 0, 0);
polyline_actor->GetProperty()->SetLineWidth(5);
效果如下:
封闭多边形曲面
/*
* 模拟生成第一个三角网
* 1. 随机生成点集
* 2. 获取生成三角网的边界环点集(有序)
*/
vtkSmartPointer<vtkPoints> ps1 =vtkSmartPointer<vtkPoints>::New();
unsigned int GridSize = 10;
for(unsigned int x = 0; x < GridSize; x++)
{
for(unsigned int y = 0; y < GridSize; y++)
{
ps1->InsertNextPoint(x, y, vtkMath::Random(-.25, .25));
}
}
/*
第一三角剖分
*/
vtkSmartPointer<vtkPolyData> polydata1 =vtkSmartPointer<vtkPolyData>::New();
polydata1->SetPoints(ps1);
vtkSmartPointer<vtkDelaunay2D> delaunay1 =vtkSmartPointer<vtkDelaunay2D>::New();
delaunay1->SetInputData(polydata1);
delaunay1->Update();
vtkSmartPointer<vtkPoints> pts2 = vtkSmartPointer<vtkPoints>::New();
GridSize =9;
for (unsigned int x =1; x < GridSize; x++)
{
for (unsigned int y =1; y < GridSize; y++)
{
pts2->InsertNextPoint(x+ vtkMath::Random(-.25, 1.25), y+
vtkMath::Random(-.25, 1.25), vtkMath::Random(1.5, 1.75));
}
}
/*
第二个三角剖分
*/
vtkSmartPointer<vtkPolyData> polydata2 = vtkSmartPointer<vtkPolyData>::New();
polydata2->SetPoints(pts2);
vtkSmartPointer<vtkDelaunay2D> delaunay2 = vtkSmartPointer<vtkDelaunay2D>::New();
delaunay2->SetInputData(polydata2);
delaunay2->Update();
// 两个三角网的合并
vtkSmartPointer<vtkTestAlgorithmFilter>testAlgorithm = vtkSmartPointer<vtkTestAlgorithmFilter>::New();
testAlgorithm->SetInputData(0, delaunay1->GetOutput()); //输入第一个三角剖分的结果
testAlgorithm->SetInputData(1, delaunay2->GetOutput());//输入第二个三角剖分的结果
testAlgorithm->Update();
效果图如下:
裁剪
//clip
vtkSmartPointer<vtkPlaneCollection> planes =vtkSmartPointer<vtkPlaneCollection>::New();
/*
由折线生成裁剪平面
*/
double p1[3], p2[3];
double n[3], v1[3], v2[3] = { 0,0,-1 };
vtkSmartPointer<vtkPlane>plane ;
vtkIdType nPoints = polylineData->GetNumberOfPoints();
for (vtkIdType i = 1; i < nPoints; ++i) {
polylineData->GetPoint(i-1, p1);
p1[2] = 0;
polylineData->GetPoint(i, p2);
p2[2] = 0;
vtkMath::Subtract(p2, p1,v1);
vtkMath::Cross(v1, v2,n);
plane = vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(p2);
plane->SetNormal(n);
planes->AddItem(plane);
}
vtkSmartPointer<vtkClipClosedSurface> clipperClosed =vtkSmartPointer<vtkClipClosedSurface>::New();
clipperClosed->SetInputData(testAlgorithm->GetOutput());
clipperClosed->SetClippingPlanes(planes);
clipperClosed->Update();
效果图如下:
剪切面的缝补
//生成裁剪几何体后,要注意clean以下
vtkSmartPointer<vtkCleanPolyData> cleanPolyDataClip = vtkSmartPointer<vtkCleanPolyData>::New();
cleanPolyDataClip->SetInputConnection(clipperClosed->GetOutputPort());
cleanPolyDataClip->Update();
vtkPoints *pt = nullptr;
unsigned int num=0;
vtkSmartPointer<vtkFeatureEdges> fEdges = vtkSmartPointer<vtkFeatureEdges>::New();
fEdges->SetInputData(cleanPolyDataClip->GetOutput());
fEdges->BoundaryEdgesOn();
fEdges->FeatureEdgesOff();
fEdges->ManifoldEdgesOff();
fEdges->NonManifoldEdgesOff();
fEdges->Update();
vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New();
stripper->SetInputConnection(fEdges->GetOutputPort());
stripper->Update();
//由线生成点
vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
cleanPolyData->SetInputConnection(stripper->GetOutputPort());
cleanPolyData->Update();
pt = cleanPolyData->GetOutput()->GetPoints();
num = pt->GetNumberOfPoints();
/*
剖面三角网的生成
*/
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(pt);
vtkSmartPointer<vtkPolyData> aPolydata = vtkSmartPointer<vtkPolyData>::New();
aPolydata->SetPoints(pt);
vtkSmartPointer<vtkCellArray> aCellArray = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPolygon> aPolygon = vtkSmartPointer<vtkPolygon>::New();
for (int i = 0; i < num;++i) {
aPolygon->GetPointIds()->InsertNextId(i);
}
aCellArray->InsertNextCell(aPolygon);
aPolydata->SetPolys(aCellArray);
vtkSmartPointer<vtkDelaunay2D> CrossSection = vtkSmartPointer<vtkDelaunay2D>::New();
CrossSection->SetInputData(polydata);
CrossSection->SetSourceData(aPolydata);
CrossSection->SetProjectionPlaneMode(VTK_BEST_FITTING_PLANE);
//CrossSection->SetTransform(delaunay3->ComputeBestFittingPlane(cutter->GetOutput()));
CrossSection->Update();
效果图如下:
组合成封闭多边形曲面
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
appendFilter->AddInputData(clipperClosed->GetOutput());
appendFilter->AddInputData(CrossSection->GetOutput());
//appendFilter->AddInputData(testAlgorithm->GetOutput());
appendFilter->Update();
效果图如下: