【VTK】三角化3D物体的表面

网友投稿 547 2022-09-01

【VTK】三角化3D物体的表面

在VTK的体系中,要正常将actor输出STL文件,需要相应的PolyData三角化。

vSPNew( triangle, vtkTriangleFilter); triangle->SetInputData( polyData ); triangle->Update();

在一些专业软件,比如Meshmixer中查看STL文件,如果有任何的“不和谐”都会被标注出来。 下图中的物体是用两个长方体拼凑而成的。因为存在共面,所以meshmixer用红线标注出来了。

相关的生成代码:

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 g_Poly = vtkSmartPointer::New();vtkSmartPointer g_Points = vtkSmartPointer::New();void CreateVol1(){ vtkSmartPointer points = vtkSmartPointer::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 points = vtkSmartPointer::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 pd = vtkSmartPointer::New(); pd->SetPoints( g_Points ); pd->SetPolys( g_Poly ); vtkSmartPointer cleanFilter = vtkSmartPointer::New(); cleanFilter->SetInputData( pd ); cleanFilter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); //mapper->SetInputConnection( normals->GetOutputPort() ); mapper->SetInputConnection( cleanFilter->GetOutputPort() ); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper( mapper ); vtkSmartPointer renderer = vtkSmartPointer::New(); renderer->AddActor( actor ); renderer->SetBackground( 0, 0, 0 ); vtkSmartPointer renderWindow = vtkSmartPointer::New(); renderWindow->AddRenderer( renderer ); vtkSmartPointer renderWindowInteractor = vtkSmartPointer::New(); renderWindowInteractor->SetRenderWindow( renderWindow ); renderer->ResetCamera(); renderWindow->Render(); vtkSmartPointer stlWriter = vtkSmartPointer::New(); stlWriter->SetFileName( "/Users/weiyang/Desktop/test.stl" ); stlWriter->SetInputData( actor->GetMapper()->GetInput() ); stlWriter->Write(); renderWindowInteractor->Start(); return 0;}

下图是一个由从左到右的四个不同三角形组成的矩形,三角形法向量不同的情况下在meshmixer中查看得到如下的结果。

重构代码,使得所有的三角形,法线方向朝里(世界坐标系Z轴负向)。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tool.h"using namespace std;int main(){ vtkSmartPointer points = vtkSmartPointer::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 poly = vtkSmartPointer::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 pd = vtkSmartPointer::New(); pd->SetPoints( points ); pd->SetPolys( poly ); vtkSmartPointer stlWriter = vtkSmartPointer::New(); stlWriter->SetFileName( "/Users/weiyang/Desktop/test.stl" ); stlWriter->SetInputData( pd ); stlWriter->Write(); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputData( pd ); //normals->GetOutput() ); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper( mapper ); vtkSmartPointer renderer = vtkSmartPointer::New(); renderer->AddActor( actor ); renderer->SetBackground( 0, 0, 0 ); vtkSmartPointer renderWindow = vtkSmartPointer::New(); renderWindow->AddRenderer( renderer ); vtkSmartPointer renderWindowInteractor = vtkSmartPointer::New(); renderWindowInteractor->SetRenderWindow( renderWindow ); renderer->ResetCamera(); renderWindow->Render(); renderWindowInteractor->Start(); return 0;}

单个矩形的三角构造:

vtkSmartPointer points = vtkSmartPointer::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 poly = vtkSmartPointer::New(); vtkIdType pts1[3] = { 0, 1, 3 }; poly->InsertNextCell( 3, pts1 ); vtkIdType pts2[3] = { 3, 1, 2 }; poly->InsertNextCell( 3, pts2 ); vtkSmartPointer pd = vtkSmartPointer::New(); pd->SetPoints( points ); pd->SetPolys( poly );

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【QT】关于Qt::WA_DeleteOnClose的使用问题
下一篇:酸奶江湖:营销玩法大于技术壁垒!(酸奶的营销方式)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~