1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
#define CGAL_SURFACE_MESHER_VERBOSE 1
#include "generate_surface_mesh.hpp"
#include <CGAL/Surface_mesh_default_triangulation_3.h>
#include <CGAL/Complex_2_in_triangulation_3.h>
#include <CGAL/make_surface_mesh.h>
#include <fstream>
#include <CGAL/IO/Complex_2_in_triangulation_3_file_writer.h>
#include <CGAL/Implicit_surface_3.h>
namespace pygalmesh {
// default triangulation for Surface_mesher
typedef CGAL::Surface_mesh_default_triangulation_3 Tr;
// c2t3
typedef CGAL::Complex_2_in_triangulation_3<Tr> C2t3;
typedef Tr::Geom_traits GT;
// Wrapper for DomainBase for translating to GT.
class CgalDomainWrapper
{
public:
explicit CgalDomainWrapper(const std::shared_ptr<DomainBase> & domain):
domain_(domain)
{
}
virtual ~CgalDomainWrapper() = default;
virtual
GT::FT
operator()(GT::Point_3 p) const
{
return domain_->eval({p.x(), p.y(), p.z()});
}
private:
const std::shared_ptr<DomainBase> domain_;
};
typedef CGAL::Implicit_surface_3<GT, CgalDomainWrapper> Surface_3;
void
generate_surface_mesh(
const std::shared_ptr<pygalmesh::DomainBase> & domain,
const std::string & outfile,
const double bounding_sphere_radius,
const double min_facet_angle,
const double max_radius_surface_delaunay_ball,
const double max_facet_distance,
const bool verbose,
const int seed
)
{
CGAL::get_default_random() = CGAL::Random(seed);
const double bounding_sphere_radius2 = bounding_sphere_radius > 0 ?
bounding_sphere_radius*bounding_sphere_radius :
// add a little wiggle room
1.01 * domain->get_bounding_sphere_squared_radius();
Tr tr; // 3D-Delaunay triangulation
C2t3 c2t3 (tr); // 2D-complex in 3D-Delaunay triangulation
const auto d = CgalDomainWrapper(domain);
Surface_3 surface(
d,
GT::Sphere_3(CGAL::ORIGIN, bounding_sphere_radius2)
);
CGAL::Surface_mesh_default_criteria_3<Tr> criteria(
min_facet_angle,
max_radius_surface_delaunay_ball,
max_facet_distance
);
if (!verbose) {
// suppress output
std::cout.setstate(std::ios_base::failbit);
std::cerr.setstate(std::ios_base::failbit);
}
CGAL::make_surface_mesh(
c2t3,
surface,
criteria,
CGAL::Non_manifold_tag()
);
if (!verbose) {
std::cout.clear();
std::cerr.clear();
}
// Output
std::ofstream off_file(outfile);
CGAL::output_surface_facets_to_off(off_file, c2t3);
off_file.close();
return;
}
} // namespace pygalmesh
|