CGAL。凹面船体3d(Alpha_Shapes_3)

时间:2016-08-08 12:38:43

标签: c++ cgal

有一组点(3D空间)。我想根据给定的点集构建一个3Dconсave船体。因此,我想获得一个点的子集,计算出的conсave船体由其组成。 期待您的帮助。提前致谢。

enter image here

1 个答案:

答案 0 :(得分:1)

I did this job.

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Triangulation_hierarchy_3.h>
#include <CGAL/Alpha_shape_3.h>
#include <CGAL/IO/io.h>
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <CGAL/IO/Writer_OFF.h>
#include <CGAL/Simple_cartesian.h>

using namespace std;


typedef CGAL::Exact_predicates_inexact_constructions_kernel  K;


typedef CGAL::Alpha_shape_vertex_base_3<K>                  Vb;
typedef CGAL::Triangulation_hierarchy_vertex_base_3<Vb>     Vbh;
typedef CGAL::Alpha_shape_cell_base_3<K>                    Fb;
typedef CGAL::Triangulation_data_structure_3<Vbh, Fb>       Tds;
typedef CGAL::Delaunay_triangulation_3<K, Tds>              Delaunay;
typedef CGAL::Triangulation_hierarchy_3<Delaunay>           Delaunay_hierarchy;
typedef CGAL::Alpha_shape_3<Delaunay_hierarchy>             Alpha_shape_3;

typedef Alpha_shape_3::Facet                                Facet;
typedef Alpha_shape_3::Edge                                 Edges;
typedef Alpha_shape_3::Vertex                               Vertex;

typedef Alpha_shape_3::Vertex_handle                        Vertex_handle;


typedef Alpha_shape_3::Alpha_iterator                       Alpha_iterator;
typedef Alpha_shape_3::NT                                   NT;
typedef Alpha_shape_3::Vertex_iterator                      Vertex_iterator;                

typedef CGAL::Simple_cartesian<double>                      Kernel;
typedef K::Point_3                                          Point_3;


int main(int argc, const char* const argv[])
{
    if (argc != 3)
    {
        std::cerr << "\n There have to be three parameters (name of program, file with coordinates, coefficient )" << std::endl;
        exit(1);
    }
    int mode = static_cast<int>(atoi(argv[1]));
    std::fstream is(argv[1], std::ios::in);
    if (!is)
    {
        std::cerr << "\n Could not open file " << argv[1] << " for reading, exiting \n";
        exit(1);
    }
    double coefficient = atof(argv[2]);


    std::vector<std::vector<Point_3>> points;
    std::vector<Point_3> coord;
    char szTempString[1024];
    std::string str = "----------End of agglomerate----------";
    double dPosX, dPosY, dPosZ;
    while (is.getline(szTempString, 1024))
    {
        if (szTempString == str)
        {
            points.push_back(coord);
            coord.clear();
        }
        else
        {
            sscanf_s(szTempString, "%lf %lf %lf", &dPosX, &dPosY, &dPosZ);
            coord.push_back(Point_3(dPosX, dPosY, dPosZ));
        }
    }
    is.close();

    for (size_t i = 0; i < points.size(); i++)
    {
        Alpha_shape_3 as(points[i].begin(), points[i].end(), 0.001, Alpha_shape_3::GENERAL);
        Alpha_iterator opt = as.find_optimal_alpha(1);
        std::cout << "Optimal alpha value to get one connected component is " << std::fixed << std::setprecision(12) << *opt * coefficient << std::endl;
        as.set_alpha(*opt * coefficient);
        assert(as.number_of_solid_components() == 1);

        // collect all regular facets
        std::vector<Facet> Facets;
        as.get_alpha_shape_facets(std::back_inserter(Facets), Alpha_shape_3::REGULAR);

        std::stringstream pts;
        std::stringstream ind;

        for (size_t i = 0; i < Facets.size(); i++)
        {
            Facet f = Facets[i];
            //To have a consistent orientation of the facet, always consider an exterior cell
            if (as.classify(Facets[i].first) != Alpha_shape_3::EXTERIOR)
            {
                Facets[i] = as.mirror_facet(Facets[i]);
            }

            CGAL_assertion(as.classify(Facets[i].first) == Alpha_shape_3::EXTERIOR);

            int indices[3] = { (Facets[i].second + 1) % 4, (Facets[i].second + 2) % 4, (Facets[i].second + 3) % 4 };

            /// according to the encoding of vertex indices, this is needed to get a consistent orientation

            if (Facets[i].second % 2 == 0)
            {
                std::swap(indices[0], indices[1]);
            }
            pts << Facets[i].first->vertex(indices[0])->point() << "\n" <<
                   Facets[i].first->vertex(indices[1])->point() << "\n" <<
                   Facets[i].first->vertex(indices[2])->point() << "\n";

            ind << "3 " << 3 * i << " " << 3 * i + 1 << " " << 3 * i + 2 << "\n";

        }
            std::ofstream off_file;
            std::stringstream ss;
            ss << "agglomerate[" << i << "].off";
            off_file.open(ss.str(), std::ios::out);

            off_file << "OFF " << "\n" << 3 * Facets.size() << " " << Facets.size() << " 0\n";
            off_file << pts.str();
            off_file << ind.str();

    }
    return 0;
}