mirror of https://github.com/CGAL/cgal
Nef_3: Fix conversion to a FaceGraph (#6727)
## Summary of Changes Fix the case of surfaces with borders. Then they may be incident to only the unbounded volume which so far was ignored. ## Release Management * Affected package(s): Nef_polyhedron_3 * Issue(s) solved (if any): fix #6423
This commit is contained in:
commit
5791f2115c
|
|
@ -25,6 +25,7 @@
|
||||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||||
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||||
#include <CGAL/Kernel/global_functions_3.h>
|
#include <CGAL/Kernel/global_functions_3.h>
|
||||||
|
#include <CGAL/Nef_S2/Generic_handle_map.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
@ -81,6 +82,7 @@ struct Shell_polygons_visitor
|
||||||
Vertex_index_map& vertex_indices;
|
Vertex_index_map& vertex_indices;
|
||||||
PolygonRange& polygons;
|
PolygonRange& polygons;
|
||||||
bool triangulate_all_faces;
|
bool triangulate_all_faces;
|
||||||
|
CGAL::Generic_handle_map<bool> Done;
|
||||||
|
|
||||||
Shell_polygons_visitor(Vertex_index_map& vertex_indices,
|
Shell_polygons_visitor(Vertex_index_map& vertex_indices,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
|
@ -88,6 +90,7 @@ struct Shell_polygons_visitor
|
||||||
: vertex_indices( vertex_indices )
|
: vertex_indices( vertex_indices )
|
||||||
, polygons(polygons)
|
, polygons(polygons)
|
||||||
, triangulate_all_faces(triangulate_all_faces)
|
, triangulate_all_faces(triangulate_all_faces)
|
||||||
|
, Done(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::size_t get_cycle_length( typename Nef_polyhedron::Halffacet_cycle_const_iterator hfc) const
|
std::size_t get_cycle_length( typename Nef_polyhedron::Halffacet_cycle_const_iterator hfc) const
|
||||||
|
|
@ -103,6 +106,14 @@ struct Shell_polygons_visitor
|
||||||
|
|
||||||
void visit(typename Nef_polyhedron::Halffacet_const_handle opposite_facet)
|
void visit(typename Nef_polyhedron::Halffacet_const_handle opposite_facet)
|
||||||
{
|
{
|
||||||
|
typename Nef_polyhedron::Halffacet_const_handle twin_facet = opposite_facet->twin();
|
||||||
|
|
||||||
|
// skip when we have to do with the unbounded volume and a surface with boundaries
|
||||||
|
if ((twin_facet->incident_volume() == opposite_facet->incident_volume()) && Done[twin_facet])
|
||||||
|
return;
|
||||||
|
|
||||||
|
Done[opposite_facet] = true;
|
||||||
|
|
||||||
bool is_marked=opposite_facet->incident_volume()->mark();
|
bool is_marked=opposite_facet->incident_volume()->mark();
|
||||||
|
|
||||||
CGAL_assertion(Nef_polyhedron::Infi_box::is_standard(opposite_facet->plane()));
|
CGAL_assertion(Nef_polyhedron::Infi_box::is_standard(opposite_facet->plane()));
|
||||||
|
|
@ -351,19 +362,51 @@ void convert_nef_polyhedron_to_polygon_soup(const Nef_polyhedron& nef,
|
||||||
typedef Cartesian_converter<Nef_Kernel, Output_kernel> Converter;
|
typedef Cartesian_converter<Nef_Kernel, Output_kernel> Converter;
|
||||||
typename Nef_polyhedron::Volume_const_iterator vol_it = nef.volumes_begin(),
|
typename Nef_polyhedron::Volume_const_iterator vol_it = nef.volumes_begin(),
|
||||||
vol_end = nef.volumes_end();
|
vol_end = nef.volumes_end();
|
||||||
|
|
||||||
if (Nef_polyhedron::Infi_box::extended_kernel()) ++vol_it; // skip Infi_box
|
if (Nef_polyhedron::Infi_box::extended_kernel()) ++vol_it; // skip Infi_box
|
||||||
CGAL_assertion ( vol_it != vol_end );
|
|
||||||
++vol_it; // skip unbounded volume
|
if ( vol_it == vol_end ) return;
|
||||||
|
|
||||||
Converter to_output;
|
Converter to_output;
|
||||||
|
bool handling_unbounded_volume = true;
|
||||||
|
|
||||||
|
auto shell_is_closed = [](typename Nef_polyhedron::Shell_entry_const_iterator sfh)
|
||||||
|
{
|
||||||
|
typename Nef_polyhedron::SFace_const_handle sf = sfh;
|
||||||
|
|
||||||
|
typename Nef_polyhedron::SFace_cycle_const_iterator fc;
|
||||||
|
for(fc = sf->sface_cycles_begin(); fc != sf->sface_cycles_end(); ++fc)
|
||||||
|
{
|
||||||
|
if (fc.is_shalfedge() ) {
|
||||||
|
typename Nef_polyhedron::SHalfedge_const_handle e(fc);
|
||||||
|
typename Nef_polyhedron::SHalfedge_around_sface_const_circulator ec(e),ee(e);
|
||||||
|
CGAL_For_all(ec,ee)
|
||||||
|
{
|
||||||
|
typename Nef_polyhedron::Halffacet_const_handle f = ec->twin()->facet();
|
||||||
|
if (f->incident_volume()==f->twin()->incident_volume())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
for (;vol_it!=vol_end;++vol_it)
|
for (;vol_it!=vol_end;++vol_it)
|
||||||
|
{
|
||||||
|
for(auto sit = vol_it->shells_begin(); sit != vol_it->shells_end(); ++sit)
|
||||||
|
{
|
||||||
|
if ( (handling_unbounded_volume || sit!=vol_it->shells_begin()) && shell_is_closed(sit)) continue;
|
||||||
nef_to_pm::collect_polygon_mesh_info(points,
|
nef_to_pm::collect_polygon_mesh_info(points,
|
||||||
polygons,
|
polygons,
|
||||||
nef,
|
nef,
|
||||||
vol_it->shells_begin(),
|
sit,
|
||||||
to_output,
|
to_output,
|
||||||
triangulate_all_faces);
|
triangulate_all_faces);
|
||||||
}
|
}
|
||||||
|
handling_unbounded_volume = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class Nef_polyhedron, class Polygon_mesh>
|
template <class Nef_polyhedron, class Polygon_mesh>
|
||||||
void convert_nef_polyhedron_to_polygon_mesh(const Nef_polyhedron& nef, Polygon_mesh& pm, bool triangulate_all_faces = false)
|
void convert_nef_polyhedron_to_polygon_mesh(const Nef_polyhedron& nef, Polygon_mesh& pm, bool triangulate_all_faces = false)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Nef_polyhedron_3.h>
|
||||||
|
#include <CGAL/IO/Nef_polyhedron_iostream_3.h>
|
||||||
|
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
|
||||||
|
#include <CGAL/boost/graph/generators.h>
|
||||||
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
|
||||||
|
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
||||||
|
typedef Kernel::Point_3 Point_3;
|
||||||
|
typedef CGAL::Surface_mesh<Point_3> SurfaceMesh;
|
||||||
|
typedef CGAL::Nef_polyhedron_3<Kernel> NefPolyhedron;
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
SurfaceMesh surfaceMesh;
|
||||||
|
SurfaceMesh::Vertex_index v0 = surfaceMesh.add_vertex(Point_3(-1, 0, 0));
|
||||||
|
SurfaceMesh::Vertex_index v1 = surfaceMesh.add_vertex(Point_3(1, 0, 0));
|
||||||
|
SurfaceMesh::Vertex_index v2 = surfaceMesh.add_vertex(Point_3(0, 1, 0));
|
||||||
|
|
||||||
|
SurfaceMesh::Vertex_index v3 = surfaceMesh.add_vertex(Point_3(-1, 0, 1));
|
||||||
|
SurfaceMesh::Vertex_index v4 = surfaceMesh.add_vertex(Point_3(1, 0, 1));
|
||||||
|
SurfaceMesh::Vertex_index v5 = surfaceMesh.add_vertex(Point_3(0, 1, 1));
|
||||||
|
|
||||||
|
surfaceMesh.add_face(v0, v1, v2);
|
||||||
|
surfaceMesh.add_face(v3, v4, v5);
|
||||||
|
|
||||||
|
make_tetrahedron(Point_3(-1, 0, 10),
|
||||||
|
Point_3(1, 0, 10),
|
||||||
|
Point_3(0, 1, 10),
|
||||||
|
Point_3(-1, 0, 11),
|
||||||
|
surfaceMesh);
|
||||||
|
|
||||||
|
std::cout << "Before conversion, number_of_faces: " << surfaceMesh.number_of_faces() << std::endl;
|
||||||
|
|
||||||
|
NefPolyhedron nefPoly(surfaceMesh);
|
||||||
|
std::cout << "NefPolyhedron, number_of_faces: " << nefPoly.number_of_facets() << std::endl;
|
||||||
|
SurfaceMesh convertedSurfaceMesh;
|
||||||
|
CGAL::convert_nef_polyhedron_to_polygon_mesh(nefPoly, convertedSurfaceMesh, true);
|
||||||
|
std::cout << "After conversion, number_of_faces: " << convertedSurfaceMesh.number_of_faces() << std::endl;
|
||||||
|
std::ofstream("out.off") << convertedSurfaceMesh;
|
||||||
|
assert(vertices(convertedSurfaceMesh).size()==10);
|
||||||
|
assert(faces(convertedSurfaceMesh).size()==6);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue