VTK 三角剖分 Delaunay2D(五)—— 折线裁剪封闭曲面

61 篇文章 10 订阅
37 篇文章 7 订阅

引言

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

效果图如下:

在这里插入图片描述

参考

  1. VTK 三角剖分 Delaunay2D (一)
  2. VTK 三角剖分 Delaunay2D (二)
  3. VTK 三角剖分 Delaunay2D (三)—— 自定义Filter类
  4. VTK 三角剖分 Delaunay2D(四)—— 切面(cut)与切割(clip)
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值