[CGAL]带岛多边形三角化

2023-07-06 14:20:45 浏览数 (3)

[CGAL]带岛多边形三角化 CGAL带岛多边形三角化,并输出(*.ply)格式的模型

模型输出的关键是节点和索引

#include <CGAL/Triangulation_vertex_base_with_id_2.h> #include <CGAL/Triangulation_face_base_with_info_2.h>

因此注意这两个泛型,对比不带信息的

#include <CGAL/Triangulation_vertex_base_2.h> #include <CGAL/Triangulation_face_base_2.h>,这两个增加了部分信息作为拓展。

这样Vertex_handle就可以读取这部分拓展的信息。

心得:CGAL的泛型机制真的很强大,拓展性很好。

代码语言:javascript复制
// AxModelDelaunay.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "shapefil.h"

#include "CGAL/exceptions.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_id_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Polygon_2.h>
#include <iostream>
struct FaceInfo2
{
    FaceInfo2(){}
    int nesting_level;
    bool in_domain()
    {
        return nesting_level % 2 == 1;
    }
};

typedef CGAL::Exact_predicates_inexact_constructions_kernel       K;
typedef CGAL::Triangulation_vertex_base_with_id_2<K>        Vb;
typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2, K>    Fbb;
typedef CGAL::Constrained_triangulation_face_base_2<K, Fbb>        Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb>               TDS;
typedef CGAL::Exact_predicates_tag                                Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag>  CDT;
typedef CDT::Point                                                Point;
typedef CGAL::Polygon_2<K>                                        Polygon_2;
typedef CDT::Vertex_handle    Vertex_handle;

void mark_domains(CDT& ct, CDT::Face_handle start, int index, std::list<CDT::Edge>& border)
{
    if (start->info().nesting_level != -1){
        return;
    }
    std::list<CDT::Face_handle> queue;
    queue.push_back(start);
    while (!queue.empty()){
        CDT::Face_handle fh = queue.front();
        queue.pop_front();
        if (fh->info().nesting_level == -1){
            fh->info().nesting_level = index;
            for (int i = 0; i < 3; i  ){
                CDT::Edge e(fh, i);
                CDT::Face_handle n = fh->neighbor(i);
                if (n->info().nesting_level == -1){
                    if (ct.is_constrained(e)) border.push_back(e);
                    else queue.push_back(n);
                }
            }
        }
    }
}
//explore set of facets connected with non constrained edges,
//and attribute to each such set a nesting level.
//We start from facets incident to the infinite vertex, with a nesting
//level of 0. Then we recursively consider the non-explored facets incident 
//to constrained edges bounding the former set and increase the nesting level by 1.
//Facets in the domain are those with an odd nesting level.
void mark_domains(CDT& cdt)
{
    for (CDT::All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end();   it){
        it->info().nesting_level = -1;
    }
    std::list<CDT::Edge> border;
    mark_domains(cdt, cdt.infinite_face(), 0, border);
    while (!border.empty()){
        CDT::Edge e = border.front();
        border.pop_front();
        CDT::Face_handle n = e.first->neighbor(e.second);
        if (n->info().nesting_level == -1){
            mark_domains(cdt, n, e.first->info().nesting_level   1, border);
        }
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    //读取shp
    const char * pszShapeFile = "data\walltest.shp";
    SHPHandle hShp = SHPOpen(pszShapeFile, "r");
    int nShapeType, nVertices;
    int nEntities = 0;
    double* minB = new double[4];
    double* maxB = new double[4];
    SHPGetInfo(hShp, &nEntities, &nShapeType, minB, maxB);
    printf("ShapeType:%dn", nShapeType);
    printf("Entities:%dn", nEntities);
    CDT cdt;
    for (int i = 0; i < nEntities; i  )
    {
        int iShape = i;
        SHPObject *obj = SHPReadObject(hShp, iShape);
        printf("--------------Feature:%d------------n", iShape);
        int parts = obj->nParts;
        int* partStart = obj->panPartStart;
        int verts = obj->nVertices;
        printf("nParts:%dn", parts);
        printf("nVertices:%dn", verts);
        for (int k = 0; k < parts; k  )
        {
            Polygon_2 polygon1;
            int fromIdx = partStart[k];
            int toIdx = fromIdx;
            if (k<parts-1)
            {
                toIdx = partStart[k   1];
            }
            else
            {
                toIdx = verts;
            }
            
            for (size_t j = fromIdx; j < toIdx; j  )
            {
                double x = obj->padfX[j];
                double y = obj->padfY[j];
                //Point_2 pt(x, y);
                printf("%f,%f;", x, y);
                polygon1.push_back(Point(x, y));

            }
            cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(), true);
        }
        printf("n");
    }

    //construct two non-intersecting nested polygons  
    //Polygon_2 polygon1;
    //polygon1.push_back(Point(0, 0));
    //polygon1.push_back(Point(2, 0));
    //polygon1.push_back(Point(2, 2));
    //polygon1.push_back(Point(0, 2));
    //Polygon_2 polygon2;
    //polygon2.push_back(Point(0.5, 0.5));
    //polygon2.push_back(Point(1.5, 0.5));
    //polygon2.push_back(Point(1.5, 1.5));
    //polygon2.push_back(Point(0.5, 1.5));

    Insert the polygons into a constrained triangulation
    //CDT cdt;
    //cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(), true);
    //cdt.insert_constraint(polygon2.vertices_begin(), polygon2.vertices_end(), true);

    //Mark facets that are inside the domain bounded by the polygon
    mark_domains(cdt);
    FILE *ply = fopen("data\floorpeint.ply", "w");
    
    int idx = 0;
    for (CDT::Vertex_iterator v = cdt.vertices_begin(); v != cdt.vertices_end();   v)
    {
        Vertex_handle vv = v->handle();
        vv->id() = idx;
        idx  ;
    }

    int count = 0;
    for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
        fit != cdt.finite_faces_end();   fit)
    {
        if (fit->info().in_domain())
        {
              count;
            for (int i = 0; i < 3; i  )
            {
                Vertex_handle vert = fit->vertex(i);
                int x=vert->id();
                std::cout << "The Id is " << x << std::endl;
                CDT::Edge ed(fit, i);
                ed.second;
            }
        }
            
    }
    if (ply)
    {
        fprintf(ply, "plynformat %s 1.0n", "ascii");
        fprintf(ply, "element vertex %dn",idx );
        fprintf(ply, "property float xn");
        fprintf(ply, "property float yn");
        fprintf(ply, "property float zn");
        fprintf(ply, "element face %dn", count);
        fprintf(ply, "property list uint8 int32 vertex_indicesn");
        fprintf(ply, "end_headern");

        for (CDT::Vertex_iterator v = cdt.vertices_begin(); v != cdt.vertices_end();   v)
        {
            Vertex_handle vv = v->handle();
            double x = vv->point().x();
            double y = vv->point().y();
            fprintf(ply, "%f %f %fn", x, y, 0.0);
        }
        for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();    fit != cdt.finite_faces_end();   fit)
        {
            if (fit->info().in_domain())
            {

                Vertex_handle vertId0 = fit->vertex(0);
                Vertex_handle vertId1 = fit->vertex(1);
                Vertex_handle vertId2 = fit->vertex(2);
                int id0 = vertId0->id();
                int id1 = vertId1->id();
                int id2 = vertId2->id();
                fprintf(ply, "%d %d %d %dn", 3, id0, id1, id2);
            }

        }
    }

    std::cout << "There are " << count << " facets in the domain." << std::endl;
    system("pause");
    return 0;
}

效果图

0 人点赞