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