VTK三角化3D物体的表面
Posted theArcticOcean
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VTK三角化3D物体的表面相关的知识,希望对你有一定的参考价值。
在VTK的体系中,要正常将actor输出STL文件,需要相应的PolyData三角化。
vSPNew( triangle, vtkTriangleFilter);
triangle->SetInputData( polyData );
triangle->Update();
在一些专业软件,比如Meshmixer中查看STL文件,如果有任何的“不和谐”都会被标注出来。
下图中的物体是用两个长方体拼凑而成的。因为存在共面,所以meshmixer用红线标注出来了。
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkActor2D.h>
#include <vtkPoints.h>
#include <vtkSTLWriter.h>
#include <vtkAppendPolyData.h>
#include <vtkAppendFilter.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkSmoothPolyDataFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkCleanPolyData.h>
#include "tool.h"
using namespace std;
PointStruct getNormal(const PointStruct p1, const PointStruct p2, const PointStruct p3)
PointStruct normal;
PointStruct vec1( p1 - p3 );
PointStruct vec2( p2 - p3 );
vtkMath::Cross(vec1.point, vec2.point, normal.point);
vtkMath::Normalize( normal.point );
return normal;
PointStruct getNormal(const double *p1, const double *p2, const double *p3)
PointStruct normal;
PointStruct ps1( (double *)p1 );
PointStruct ps2( (double *)p2 );
PointStruct ps3( (double *)p3 );
PointStruct vec1( ps1 - ps3 );
PointStruct vec2( ps2 - ps3 );
vtkMath::Cross(vec1.point, vec2.point, normal.point);
vtkMath::Normalize( normal.point );
return normal;
vtkSmartPointer<vtkCellArray> g_Poly =
vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> g_Points =
vtkSmartPointer<vtkPoints>::New();
void CreateVol1()
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertPoint(0, 0, 0, 0);
points->InsertPoint(1, 1, 0, 0);
points->InsertPoint(2, 1, 1, 0);
points->InsertPoint(3, 0, 1, 0);
PointStruct ps0( points->GetPoint(0) );
PointStruct ps1( points->GetPoint(1) );
PointStruct ps2( points->GetPoint(2) );
PointStruct ps3( points->GetPoint(3) );
PointStruct normal = getNormal( ps1, ps2, ps3 );
PointStruct ps4 = ps0 + normal * 4;
PointStruct ps5 = ps1 + normal * 4;
PointStruct ps6 = ps2 + normal * 4;
PointStruct ps7 = ps3 + normal * 4;
points->InsertPoint(4, ps4.point);
points->InsertPoint(5, ps5.point);
points->InsertPoint(6, ps6.point);
points->InsertPoint(7, ps7.point);
vtkIdType pts1[4] = 0, 1, 2, 3 ;
g_Poly->InsertNextCell( 4, pts1 );
vtkIdType pts2[4] = 4, 5, 6, 7 ;
g_Poly->InsertNextCell( 4, pts2 );
vtkIdType pts3[4] = 1, 2, 6, 5 ;
g_Poly->InsertNextCell( 4, pts3 );
vtkIdType pts4[4] = 0, 3, 7, 4 ;
g_Poly->InsertNextCell( 4, pts4 );
vtkIdType pts5[4] = 3, 2, 6, 7 ;
g_Poly->InsertNextCell( 4, pts5 );
vtkIdType pts6[4] = 0, 1, 5, 4 ;
g_Poly->InsertNextCell( 4, pts6 );
for( int i = 0; i < points->GetNumberOfPoints(); ++i )
PointStruct pt( points->GetPoint( i ) );
g_Points->InsertNextPoint( pt.point );
void CreateVol2()
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertPoint(0, 1, 0, 0);
points->InsertPoint(1, 2, 0, 0);
points->InsertPoint(2, 2, 1, 0);
points->InsertPoint(3, 1, 1, 0);
PointStruct ps0( points->GetPoint(0) );
PointStruct ps1( points->GetPoint(1) );
PointStruct ps2( points->GetPoint(2) );
PointStruct ps3( points->GetPoint(3) );
PointStruct normal = getNormal( ps1, ps2, ps3 );
PointStruct ps4 = ps0 + normal * 4;
PointStruct ps5 = ps1 + normal * 4;
PointStruct ps6 = ps2 + normal * 4;
PointStruct ps7 = ps3 + normal * 4;
points->InsertPoint(4, ps4.point);
points->InsertPoint(5, ps5.point);
points->InsertPoint(6, ps6.point);
points->InsertPoint(7, ps7.point);
vtkIdType pts1[4] = 8, 9, 10, 11 ;
g_Poly->InsertNextCell( 4, pts1 );
vtkIdType pts2[4] = 12, 13, 14, 15 ;
g_Poly->InsertNextCell( 4, pts2 );
vtkIdType pts3[4] = 9, 10, 14, 13 ;
g_Poly->InsertNextCell( 4, pts3 );
vtkIdType pts4[4] = 8, 11, 15, 12 ;
g_Poly->InsertNextCell( 4, pts4 );
vtkIdType pts5[4] = 11, 10, 14, 15 ;
g_Poly->InsertNextCell( 4, pts5 );
vtkIdType pts6[4] = 8, 9, 13, 12 ;
g_Poly->InsertNextCell( 4, pts6 );
for( int i = 0; i < points->GetNumberOfPoints(); ++i )
PointStruct pt( points->GetPoint( i ) );
g_Points->InsertNextPoint( pt.point );
int main()
CreateVol1();
CreateVol2();
vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
pd->SetPoints( g_Points );
pd->SetPolys( g_Poly );
vtkSmartPointer<vtkCleanPolyData> cleanFilter =
vtkSmartPointer<vtkCleanPolyData>::New();
cleanFilter->SetInputData( pd );
cleanFilter->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
//mapper->SetInputConnection( normals->GetOutputPort() );
mapper->SetInputConnection( cleanFilter->GetOutputPort() );
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor( actor );
renderer->SetBackground( 0, 0, 0 );
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
vtkSmartPointer<vtkSTLWriter> stlWriter =
vtkSmartPointer<vtkSTLWriter>::New();
stlWriter->SetFileName( "/Users/weiyang/Desktop/test.stl" );
stlWriter->SetInputData( actor->GetMapper()->GetInput() );
stlWriter->Write();
renderWindowInteractor->Start();
return 0;
下图是一个由从左到右的四个不同三角形组成的矩形,三角形法向量不同的情况下在meshmixer中查看得到如下的结果。
重构代码,使得所有的三角形,法线方向朝里(世界坐标系Z轴负向)。
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkActor2D.h>
#include <vtkPoints.h>
#include <vtkSTLWriter.h>
#include <vtkAppendPolyData.h>
#include <vtkAppendFilter.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkSmoothPolyDataFilter.h>
#include <vtkPolyDataNormals.h>
#include "tool.h"
using namespace std;
int main()
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertPoint(0, 0, 0, 0);
points->InsertPoint(1, 1, 0, 0);
points->InsertPoint(2, 1, 1, 0);
points->InsertPoint(3, 0, 1, 0);
points->InsertPoint(4, 2, 0, 0);
points->InsertPoint(5, 2, 1, 0);
vtkSmartPointer<vtkCellArray> poly = vtkSmartPointer<vtkCellArray>::New();
vtkIdType pts1[3] = 3, 1, 0 ;
poly->InsertNextCell( 3, pts1 );
vtkIdType pts2[3] = 1, 3, 2 ;
poly->InsertNextCell( 3, pts2 );
vtkIdType pts3[3] = 2, 4, 1 ;
poly->InsertNextCell( 3, pts3 );
vtkIdType pts4[3] = 4, 2, 5 ;
poly->InsertNextCell( 3, pts4 );
vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
pd->SetPoints( points );
pd->SetPolys( poly );
vtkSmartPointer<vtkSTLWriter> stlWriter =
vtkSmartPointer<vtkSTLWriter>::New();
stlWriter->SetFileName( "/Users/weiyang/Desktop/test.stl" );
stlWriter->SetInputData( pd );
stlWriter->Write();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData( pd ); //normals->GetOutput() );
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor( actor );
renderer->SetBackground( 0, 0, 0 );
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
单个矩形的三角构造:
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertPoint(0, 0, 0, 0);
points->InsertPoint(1, 1, 0, 0);
points->InsertPoint(2, 1, 1, 0);
points->InsertPoint(3, 0, 1, 0);
//vtkIdType pts[8] = 0, 1, 2, 3, 4, 5, 6, 7 ;
vtkSmartPointer<vtkCellArray> poly = vtkSmartPointer<vtkCellArray>::New();
vtkIdType pts1[3] = 0, 1, 3 ;
poly->InsertNextCell( 3, pts1 );
vtkIdType pts2[3] = 3, 1, 2 ;
poly->InsertNextCell( 3, pts2 );
vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New();
pd->SetPoints( points );
pd->SetPolys( poly );
以上是关于VTK三角化3D物体的表面的主要内容,如果未能解决你的问题,请参考以下文章