OpenCASCADE网格和CGAL网格互转

在做一些网格相关的算法时(如曲线包覆算法),可以直接从OCC的TopoDS_Face得到对应的网格模型(获取TopoDS_Face网格)。OCC的中网格是Poly_Triangulation相关的类,用来显示等简单任务是很方便的,但做一些复杂的算法就比较累了。CGAL是一个很强大的网格算法库,开源但不友好,有很完备的数据结构,里面很多算法是很不错的,非常值得借鉴学习,CGAL是只有头文件的,使用起来很方便,只是大量使用模板,使用和理解起来有些费劲。

 

 

从occ切换到CGAL,最基本的是OCC的网格数据与CGAL的网格间的转换。代码如下:

1.Poly_Triangulation  <=> Surface_mesh


typedef CGAL::Simple_cartesian<double> clKernel;

typedef CGAL::Point_3<clKernel> clPoint; //点

typedef CGAL::Surface_mesh<clPoint>  clMesh;//网格

void MMesh_MeshFuns_Cgal::occMeshToClMesh(const Handle(Poly_Triangulation)& T, clMesh& sm)
    {
        sm.clear();//清空
        if (T.IsNull())
            return;
        try
        {
            //顶点数量、边的数量(不知)、面的数量
            Standard_Integer nbNodes = T->NbNodes();
            Standard_Integer nbTriangles = T->NbTriangles();
            if (nbNodes == 0 || nbTriangles == 0)
                return;
            const TColgp_Array1OfPnt& nodes = T->Nodes();
            const Poly_Array1OfTriangle& triangles = T->Triangles();
            
            sm.reserve(nbNodes, 0, nbTriangles);
            //顶点
            std::vector<cgalVertex_index> vertexmap(nbNodes);
            for (int i = 1; i <= nodes.Length(); i++) {
              const gp_Pnt& pnt = nodes.Value(i);
              cgalVertex_index vi = sm.add_vertex(clPoint(pnt.X(), pnt.Y(), pnt.Z()));
              vertexmap[i - 1] = vi;
            }
            //三角面
           int n1, n2, n3;
           for (int i = 1; i <= triangles.Length(); i++) {
              const Poly_Triangle& tri = triangles.Value(i);
              tri.Get(n1, n2, n3);
              cgalFace_index fi = sm.add_face(std::vector<cgalVertex_index>{vertexmap[n1 - 1], vertexmap[n2 - 1], vertexmap[n3 - 1]});
           }
        }
        catch (...)
        {

        }
    }

2.Surface_mesh  <=> Poly_Triangulation

Handle(Poly_Triangulation) MMesh_MeshFuns_Cgal::clMeshToOccMesh(const clMesh& sm)
    {
        Handle_Poly_Triangulation T;
        if (sm.is_empty())
            return T;
        try
        {
            Standard_Integer nbNodes = sm.number_of_vertices();
            Standard_Integer nbTriangles = sm.number_of_faces();
            if (nbNodes == 0 || nbTriangles == 0)
                return T;
            TColgp_Array1OfPnt nodes(1, nbNodes);
            Poly_Array1OfTriangle triangles(1, nbTriangles);
            //顶点
            for (clMesh::Vertex_index vd : vertices(sm)) {
                const clPoint& p = sm.point(vd);
                nodes(vd.idx() + 1).SetCoord(p.x(), p.y(), p.z());
            }
            //三角面
            int vi = 1;
            for (clMesh::Face_index fd : sm.faces()) {
                vi = 1;
                for (clMesh::Vertex_index vd : vertices_around_face(sm.halfedge(fd), sm)) {
                    triangles(fd.idx() + 1).Set(vi, vd.idx() + 1);
                    if (vi == 3)
                        break;
                    vi++;
                }
            }
            //occ三角网格
            T = new Poly_Triangulation(nodes, triangles);
        }
        catch (...)
        {
            
        }

        return T;
    }

 

更多精彩请关注公众号

posted @ 2021-03-15 22:47  YiShan-CADCAM  阅读(2212)  评论(0)    收藏  举报