VTK Learning Thirty-four- FrenetSerret

ExtrudePolyDataAlongLine (沿着线拉伸多变形)

  • Obtain the 2D polydata from a file( or generate a disk).
    第一步获取截面轮廓线(contours)。

  • Generates random points in 3D space and fits a spline to the points.
    第二步生成放样线,即轮廓线沿着这条线放样。

  • Computes an orientation frame at each point on the line.
    第三步计算放样线上每一点的法向量,切向量和副法向量,以便于确定截面在放样线上的空间位置(主要指的是方向)。

  • Places a copy of the 2D polydata at each point on the line, oriented by the the frame at that point.
    第四步将轮廓线放置到放样线上,并按照第三步进行旋转。

  • For each contour in the 2D polydata, appends all of the copies.
    第五步 确定轮廓线是否含有洞。

  • Creates a ruled surface for each contour.
    第六步将放样线上每一个轮廓连接成三角网。

    红色为截面轮廓,黄色为截面轮廓缩放,平移,旋转 复制到放样线上
    在这里插入图片描述
    在这里插入图片描述

FrenetSerret Fram Demo

#include <vtkFrenetSerretFrame.h>

#include <vtkSmartPointer.h>

#include <vtkParametricSpline.h>
#include <vtkParametricFunctionSource.h>

#include <vtkSphereSource.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>

#include <vtkPointSource.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>

#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkCamera.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

static void MakeGlyphs(vtkPolyData *src, double size, vtkGlyph3D *glyph);

int main(int, char *[])
{
  // Generate  some random points
  int numberOfPoints = 8;
  vtkSmartPointer<vtkPointSource> pointSource = 
    vtkSmartPointer<vtkPointSource>::New();
  pointSource->SetNumberOfPoints(numberOfPoints);
  pointSource->Update();
  
  vtkPoints* points = pointSource->GetOutput()->GetPoints();
  // 拟合
  vtkSmartPointer<vtkParametricSpline> spline = 
    vtkSmartPointer<vtkParametricSpline>::New();
  spline->SetPoints(points);
  
  vtkSmartPointer<vtkParametricFunctionSource> functionSource = 
    vtkSmartPointer<vtkParametricFunctionSource>::New();
  functionSource->SetParametricFunction(spline);
  functionSource->SetUResolution(10 * numberOfPoints);
  functionSource->SetVResolution(10 * numberOfPoints);
  functionSource->SetWResolution(10 * numberOfPoints);

  // Create the frame
  vtkSmartPointer<vtkFrenetSerretFrame> frame =
    vtkSmartPointer<vtkFrenetSerretFrame>::New();
  frame->SetInputConnection(functionSource->GetOutputPort());
  frame->ConsistentNormalsOn();
  frame->Update();

  vtkSmartPointer<vtkGlyph3D> glyph3DNormals =
    vtkSmartPointer<vtkGlyph3D>::New();
  vtkSmartPointer<vtkGlyph3D> glyph3DTangents =
    vtkSmartPointer<vtkGlyph3D>::New();
  vtkSmartPointer<vtkGlyph3D> glyph3DBinormals =
    vtkSmartPointer<vtkGlyph3D>::New();
  
  // for each vector, create a Glyph3D and DeepCopy the output
  double radius = .05;
  frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals");
  MakeGlyphs(frame->GetOutput(), radius, glyph3DNormals.GetPointer());
  vtkSmartPointer<vtkPolyData> normalsPolyData =
    vtkSmartPointer<vtkPolyData>::New();
  normalsPolyData->DeepCopy(glyph3DNormals->GetOutput());

  frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents");
  MakeGlyphs(frame->GetOutput(), radius, glyph3DTangents.GetPointer());
  vtkSmartPointer<vtkPolyData> tangentsPolyData =
    vtkSmartPointer<vtkPolyData>::New();
  tangentsPolyData->DeepCopy(glyph3DTangents->GetOutput());

  frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals");
  MakeGlyphs(frame->GetOutput(), radius, glyph3DBinormals.GetPointer());
  vtkSmartPointer<vtkPolyData> binormalsPolyData =
    vtkSmartPointer<vtkPolyData>::New();
  binormalsPolyData->DeepCopy(glyph3DBinormals->GetOutput());

// Setup actors and mappers
  vtkSmartPointer<vtkPolyDataMapper> glyph3DNormalsMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  glyph3DNormalsMapper->SetInputData(normalsPolyData);

  vtkSmartPointer<vtkActor> glyph3DNormalsActor =
    vtkSmartPointer<vtkActor>::New();
  glyph3DNormalsActor->SetMapper(glyph3DNormalsMapper);
  glyph3DNormalsActor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);

  vtkSmartPointer<vtkPolyDataMapper> glyph3DTangentsMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  glyph3DTangentsMapper->SetInputData(tangentsPolyData);

  vtkSmartPointer<vtkActor> glyph3DTangentsActor =
    vtkSmartPointer<vtkActor>::New();
  glyph3DTangentsActor->SetMapper(glyph3DTangentsMapper);
  glyph3DTangentsActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);

  vtkSmartPointer<vtkPolyDataMapper> glyph3DBinormalsMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  glyph3DBinormalsMapper->SetInputData(binormalsPolyData);

  vtkSmartPointer<vtkActor> glyph3DBinormalsActor =
    vtkSmartPointer<vtkActor>::New();
  glyph3DBinormalsActor->SetMapper(glyph3DBinormalsMapper);
  glyph3DBinormalsActor->GetProperty()->SetColor(0.1804,0.5451,0.3412);

  vtkSmartPointer<vtkPolyDataMapper> mapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(functionSource->GetOutputPort());
  
  vtkSmartPointer<vtkActor> actor = 
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  
  // Setup render window, renderer, and interactor
  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(glyph3DNormalsActor);
  renderer->AddActor(glyph3DTangentsActor);
  renderer->AddActor(glyph3DBinormalsActor);
  renderer->AddActor(actor);

  renderer->SetBackground(.4, .5, .7);

  // Pick a good view
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(120);
  renderer->GetActiveCamera()->Elevation(30);
  renderer->GetActiveCamera()->Dolly(1.8);
  renderer->ResetCameraClippingRange();

  renderWindow->SetSize(640, 480);
  renderWindow->Render();
  renderWindowInteractor->Start();
  
  return EXIT_SUCCESS;
}

void MakeGlyphs(vtkPolyData *src, double size, vtkGlyph3D *glyph)
{
  // Source for the glyph filter
  vtkSmartPointer<vtkArrowSource> arrow =
    vtkSmartPointer<vtkArrowSource>::New();
  arrow->SetTipResolution(16);
  arrow->SetTipLength(.3);
  arrow->SetTipRadius(.1);

  glyph->SetSourceConnection(arrow->GetOutputPort());
  glyph->SetInputData(src);
  glyph->SetVectorModeToUseVector();
  glyph->SetScaleModeToScaleByVector();
  glyph->SetScaleFactor(size);
  glyph->OrientOn();
  glyph->Update();
}

In the example, the normal vectors are yellow, the tangent vectors are red and the binormal vectors.
法向量黄色;切向量红色;副法向量
在这里插入图片描述

ExtrudePolyDataAlongLine

int main(int argc, char *argv[])
{
	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	// Setup render window, renderer, and interactor
	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderer->SetBackground(.4, .5, .7);

  // For testing
  vtkMath::RandomSeed(7859821);
  // Read a polydata
  // 读取或生成截面轮廓线
  vtkSmartPointer<vtkPolyData> polyData = ReadPolyData(argc > 1 ? argv[1] : "");;
  int numberOfContours = polyData->GetNumberOfLines();
  std::cout << "Number of contours: " << numberOfContours << std::endl;
  /*{
	  vtkSmartPointer<vtkPolyDataMapper> mapper =
		  vtkSmartPointer<vtkPolyDataMapper>::New();
	  mapper->SetInputData(polyData);
	  vtkSmartPointer<vtkActor> actor =
		  vtkSmartPointer<vtkActor>::New();
	  actor->GetProperty()->SetColor(1, 0, 0);
	  actor->SetMapper(mapper);
	  renderer->AddActor(actor);
  }
*/
  // Generate  some random points
  int numberOfPoints = 5 ;
  vtkSmartPointer<vtkPointSource> pointSource = 
    vtkSmartPointer<vtkPointSource>::New();
  pointSource->SetNumberOfPoints(numberOfPoints);
  pointSource->Update();
  // 随机生成十个点
  /*{
	  vtkSmartPointer<vtkPolyDataMapper> mapper =
		  vtkSmartPointer<vtkPolyDataMapper>::New();
	  mapper->SetInputConnection(pointSource->GetOutputPort());
	  vtkSmartPointer<vtkActor> actor =
		  vtkSmartPointer<vtkActor>::New();
	  actor->GetProperty()->SetPointSize(10);
	  actor->SetMapper(mapper);
	  renderer->AddActor(actor);
  }*/
  //点加密生成光滑曲线
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  points->InsertNextPoint(0, 0, 0);
  points->InsertNextPoint(0, 5, 0);
  points->InsertNextPoint(5, 5, 0);
  points->InsertNextPoint(10, 5, 0);
  points->InsertNextPoint(15, 5, 0);

  
 // vtkPoints* points = pointSource->GetOutput()->GetPoints();
  //vtkPoints* points = linepts;
  vtkSmartPointer<vtkParametricSpline> spline = 
    vtkSmartPointer<vtkParametricSpline>::New();
  spline->SetPoints(points);

  vtkSmartPointer<vtkParametricFunctionSource> functionSource = 
    vtkSmartPointer<vtkParametricFunctionSource>::New();
  functionSource->SetParametricFunction(spline);
  functionSource->SetUResolution(50 * numberOfPoints);
  functionSource->SetVResolution(50 * numberOfPoints);
  functionSource->SetWResolution(50 * numberOfPoints);

  // Create the frame
  //
  vtkSmartPointer<vtkFrenetSerretFrame> frame =
    vtkSmartPointer<vtkFrenetSerretFrame>::New();
  frame->SetInputConnection(functionSource->GetOutputPort());
  frame->ConsistentNormalsOn();
  frame->Update();
  //In the example, the normal vectors are yellow, the tangent vectors are red and the binormal vectors
  //
  frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals");
  frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents");
  frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals");

  vtkPoints *linePoints = frame->GetOutput()->GetPoints();

  std::vector<vtkSmartPointer<vtkAppendPolyData> >skeletons;
  for (int i = 0; i < numberOfContours; ++i)
  {
    skeletons.push_back(vtkSmartPointer<vtkAppendPolyData>::New());
  }
  //为每一个frame生成截面
  for (int i = 0; i < linePoints->GetNumberOfPoints(); ++i)
  {
    vtkSmartPointer<vtkTransform> transform =
      vtkSmartPointer<vtkTransform>::New();

    // Compute a basis
    double normalizedX[3];
    frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals");
    frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedX);
    double normalizedY[3];
    frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals");
    frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedY);
    double normalizedZ[3];
    frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents");
    frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedZ);

    // Create the direction cosine matrix
	// 余弦矩阵
	// 旋转
    vtkSmartPointer<vtkMatrix4x4> matrix =
      vtkSmartPointer<vtkMatrix4x4>::New();
    matrix->Identity();
    for (unsigned int j = 0; j < 3; ++j)
    {
      matrix->SetElement(j, 0, normalizedX[j]);
      matrix->SetElement(j, 1, normalizedY[j]);
      matrix->SetElement(j, 2, normalizedZ[j]);
    }
	//平移
    transform->Translate(linePoints->GetPoint(i)[0],
                         linePoints->GetPoint(i)[1],
                         linePoints->GetPoint(i)[2]);
	//缩放
    transform->Scale(.02, .02, .02);
	//旋转
    transform->Concatenate(matrix);

    vtkSmartPointer<vtkTransformPolyDataFilter> transformPD =
      vtkSmartPointer<vtkTransformPolyDataFilter>::New();
    vtkSmartPointer<vtkPolyData> polyDataCopy =
      vtkSmartPointer<vtkPolyData>::New();
    polyDataCopy->DeepCopy(polyData);

    transformPD->SetTransform(transform);
    transformPD->SetInputData(polyDataCopy);
    transformPD->Update();
	//获取连通区域
    vtkSmartPointer<vtkPolyDataConnectivityFilter> contours =
      vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
    contours->SetInputConnection(transformPD->GetOutputPort());
    contours->Update();

	/*{
		vtkSmartPointer<vtkPolyDataMapper> mapper =
			vtkSmartPointer<vtkPolyDataMapper>::New();
		mapper->SetInputConnection(contours->GetOutputPort());
		vtkSmartPointer<vtkActor> actor =
			vtkSmartPointer<vtkActor>::New();
		actor->GetProperty()->SetColor(1, 0, 1);
		actor->SetMapper(mapper);
		renderer->AddActor(actor);
	}*/

    for (int r = 0; r < contours->GetNumberOfExtractedRegions(); ++r)
    {
      contours->SetExtractionModeToSpecifiedRegions();
      contours->InitializeSpecifiedRegionList();
      contours->AddSpecifiedRegion(r);
      contours->Update();
      vtkSmartPointer<vtkPolyData> skeleton =
        vtkSmartPointer<vtkPolyData>::New();
      skeleton->DeepCopy(contours->GetOutput());
      skeletons[r]->AddInputData(skeleton);
    }
  }
 // 由截面生成三角网

  for (int i = 0; i < numberOfContours; ++i)
  {

	  {
		  vtkSmartPointer<vtkPolyDataMapper> mapper =
		  vtkSmartPointer<vtkPolyDataMapper>::New();
		  mapper->SetInputConnection(skeletons[i]->GetOutputPort());
		  vtkSmartPointer<vtkActor> actor =
		  vtkSmartPointer<vtkActor>::New();
		  actor->GetProperty()->SetColor(1, 0, 1);
		  actor->SetMapper(mapper);
		  renderer->AddActor(actor);
	  }
    vtkSmartPointer<vtkRuledSurfaceFilter> ruled = 
      vtkSmartPointer<vtkRuledSurfaceFilter>::New();
    ruled->SetRuledModeToPointWalk();
    ruled->CloseSurfaceOff();
    ruled->SetOnRatio(1);
    ruled->SetDistanceFactor(10000000);
    ruled->SetInputConnection(skeletons[i]->GetOutputPort());

    vtkSmartPointer<vtkTriangleMeshPointNormals> normals =
      vtkSmartPointer<vtkTriangleMeshPointNormals>::New();
	normals->SetInputConnection(ruled->GetOutputPort());
	 
    vtkSmartPointer<vtkPolyDataMapper> mapper = 
      vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(normals->GetOutputPort());
    vtkSmartPointer<vtkProperty> backProp = 
      vtkSmartPointer<vtkProperty>::New();
    backProp->SetColor(1.0, 0.3882, 0.278);
    vtkSmartPointer<vtkActor> actor = 
      vtkSmartPointer<vtkActor>::New();
    actor->SetBackfaceProperty(backProp);
    actor->GetProperty()->SetColor(0.8900, 0.8100, 0.3400);
    actor->SetMapper(mapper);
    renderer->AddActor(actor);

	//
	vtkSmartPointer<vtkXMLPolyDataWriter>write = vtkSmartPointer<vtkXMLPolyDataWriter>::New();
	write->SetFileName("tunel.vtp");
	write->SetInputConnection(normals->GetOutputPort());
	write->Write();
  } 
 /* {
	  vtkSmartPointer<vtkPolyDataMapper> mapper =
		  vtkSmartPointer<vtkPolyDataMapper>::New();
	  mapper->SetInputConnection(functionSource->GetOutputPort());
	  vtkSmartPointer<vtkActor> actor =
		  vtkSmartPointer<vtkActor>::New();
	  actor->SetMapper(mapper);
	  renderer->AddActor(actor);
  }
  {
	  vtkSmartPointer<vtkPolyDataMapper> mapper =
		  vtkSmartPointer<vtkPolyDataMapper>::New();
	  mapper->SetInputConnection(frame->GetOutputPort());
	  vtkSmartPointer<vtkActor> actor =
		  vtkSmartPointer<vtkActor>::New();
	  actor->GetProperty()->SetColor(1, 1, 0);
	  actor->GetProperty()->SetPointSize(10);
	  actor->SetMapper(mapper);
	  renderer->AddActor(actor);
  }*/

  // Pick a good view
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(120);
  renderer->GetActiveCamera()->Elevation(30);
  renderer->GetActiveCamera()->Dolly(1.1);
  renderer->ResetCameraClippingRange();

  renderWindow->SetSize(512, 512);
  renderWindow->Render();
  renderWindowInteractor->Start();
  
  return EXIT_SUCCESS;
}

截面轮廓线
在这里插入图片描述
生成隧道
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 《VTK用户手册--中文翻译版.pdf》是一本关于VTK(Visualization Toolkit)的用户手册的中文翻译版。VTK是一个强大的开源图像处理和可视化库,被广泛应用于科学可视化、医学图像处理、计算机辅助设计等领域。 这本手册提供了关于VTK的详细说明和使用指南,旨在帮助读者了解VTK的各种功能和特性,并学会如何使用它进行图像处理和可视化。手册内容包括VTK的基本概念、常用类和方法的介绍,以及一些实例和示例代码,以加深读者对VTK的理解和掌握。 这本手册的中文翻译版对于广大中国用户来说是非常有价值的。通过中文版,读者可以更加便捷地学习和使用VTK,避免了阅读英文文档时的语言障碍问题。无论是初学者还是有一定经验的用户,都可以通过这本手册扩展他们的VTK知识和技能。 读者可以通过这本手册学会如何利用VTK进行图像数据的加载、处理和可视化,以及如何创建各种类型的图形和视觉效果。手册中还可能涉及一些高级特性和应用,比如体数据可视化、三维重建等,对于有进一步需求的用户也提供了参考和指导。 总之,《VTK用户手册--中文翻译版.pdf》是一本重要的参考资料,对于想要学习和应用VTK的用户来说无疑是一本宝贵的学习资料。无论是在学术研究、工业应用还是个人兴趣方面,通过这本手册的学习,读者可以更好地掌握和应用VTK这一强大的图像处理和可视化工具。 ### 回答2: vtk用户手册--中文翻译版.pdf是VTK(Visualization Toolkit)的用户手册的中文翻译版本。VTK是一个用于实现可视化和图形处理的开源软件系统。该手册提供了详细的使用指南和教程,以帮助用户了解和使用VTK的各种功能和特性。 该手册首先介绍了VTK的基本概念和工作原理,包括数据结构、渲染管线和可视化过程。然后,它详细描述了VTK的各个模块和类,如滤波器、渲染器、交互器等,以及它们的使用方法和参数设置。此外,手册还提供了一些实例和示例代码,以帮助用户更好地理解和应用VTK。 通过阅读该手册,用户可以学习到如何使用VTK创建和操作各种数据类型,如点云、网格和体数据。用户还可以了解到如何应用不同的渲染技术和效果,如光照、纹理映射和体积渲染。另外,用户还可以学习到如何与VTK的交互器进行交互,以实现用户交互操作和动态效果。 总之,vtk用户手册--中文翻译版.pdf是一本指导用户学习和使用VTK的重要参考资料。它详细介绍了VTK的功能和特性,并提供了丰富的示例和实例,帮助用户快速上手和实现自己的可视化需求。无论是初学者还是有经验的用户,都可以从该手册中获得有用的信息和技巧。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值