clean up and add doc

This commit is contained in:
Sébastien Loriot 2022-04-06 18:01:57 +02:00
parent c9b7b76a81
commit 3c3995e54d
2 changed files with 53 additions and 17 deletions

View File

@ -127,6 +127,7 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- `CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_mesh()` - `CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_mesh()`
- `CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup()` - `CGAL::Polygon_mesh_processing::orient_triangle_soup_with_reference_triangle_soup()`
- `CGAL::Polygon_mesh_processing::merge_reversible_connected_components()` - `CGAL::Polygon_mesh_processing::merge_reversible_connected_components()`
- `CGAL::Polygon_mesh_processing::connected_components_compatible_orientations()`
\cgalCRPSection{Hole Filling Functions} \cgalCRPSection{Hole Filling Functions}
- `CGAL::Polygon_mesh_processing::triangulate_hole()` - `CGAL::Polygon_mesh_processing::triangulate_hole()`

View File

@ -1604,9 +1604,41 @@ void merge_reversible_connected_components(PolygonMesh& pm,
} }
} }
/*!
* \ingroup PMP_orientation_grp
*
* identifies possible connections between the connected components of `pm` and if re-orientable,
* assigns a bit (`false` or `true`) to each face such that
* two faces with the same bits have a compatible orientation, while
* two faces with opposite bits have an incompatible orientation.
*
* @tparam PolygonMesh a model of `HalfedgeListGraph`, `FaceGraph`.
* @tparam FaceBitMap a model of `WritablePropertyMap` with `face_descriptor` as key and `bool` as value_type
* @tparam NamedParameters a sequence of \ref bgl_namedparameters
*
* @param pm a surface mesh
* @param fbm face bit map indicating if a face orientation should be reversed to be stitchable
* (see `CGAL::Polygon_mesh_processing::stitch_borders()`) with another face. If `false` is
* returned, the map will not be filled.
* @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
*
* @return `true` if `pm` can be reoriented and `false` otherwise.
*
* \cgalNamedParamsBegin
* \cgalParamNBegin{vertex_point_map}
* \cgalParamDescription{a property map associating points to the vertices of `pm`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor`
* as key type and `%Point_3` as value type}
* \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`}
* \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
* should be available for the vertices of `pm`.}
* \cgalParamNEnd
* \cgalNamedParamsEnd
*/
template <class PolygonMesh, class FaceBitMap, class NamedParameters = parameters::Default_named_parameters> template <class PolygonMesh, class FaceBitMap, class NamedParameters = parameters::Default_named_parameters>
bool connected_components_compatible_orientations(PolygonMesh& pm, bool connected_components_compatible_orientations(PolygonMesh& pm,
FaceBitMap fbm, const FaceBitMap& fbm,
const NamedParameters& np = parameters::default_values()) const NamedParameters& np = parameters::default_values())
{ {
typedef boost::graph_traits<PolygonMesh> GrT; typedef boost::graph_traits<PolygonMesh> GrT;
@ -1638,7 +1670,7 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
border_hedges.push_back(h); border_hedges.push_back(h);
std::size_t nb_bh=border_hedges.size(); std::size_t nb_bh=border_hedges.size();
// compute the edge id of all halfedges // compute the edge id of all border halfedges
typedef std::map< std::pair<Point_3, Point_3>, E_id> E_id_map; typedef std::map< std::pair<Point_3, Point_3>, E_id> E_id_map;
E_id_map e_id_map; E_id_map e_id_map;
E_id e_id = 0; E_id e_id = 0;
@ -1662,8 +1694,6 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
for (std::size_t i=0; i<nb_bh; ++i) for (std::size_t i=0; i<nb_bh; ++i)
incident_ccs_per_edge[ eids[i] ].push_back(border_hedges[i]); incident_ccs_per_edge[ eids[i] ].push_back(border_hedges[i]);
//~ std::vector< std::pair<halfedge_descriptor, halfedge_descriptor> > compatible_hedges;
//~ std::vector< std::pair<halfedge_descriptor, halfedge_descriptor> > incompatible_hedges;
std::vector< std::vector<F_cc_id> > compatible_patches(nb_cc); std::vector< std::vector<F_cc_id> > compatible_patches(nb_cc);
std::vector< std::vector<F_cc_id> > incompatible_patches(nb_cc); std::vector< std::vector<F_cc_id> > incompatible_patches(nb_cc);
@ -1678,13 +1708,11 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
if (get(vpm, source(v.front(), pm))==get(vpm, target(v.back(), pm))) if (get(vpm, source(v.front(), pm))==get(vpm, target(v.back(), pm)))
{ {
//~ compatible_hedges.push_back( std::make_pair(v.front(), v.back()) );
compatible_patches[front_id].push_back(back_id); compatible_patches[front_id].push_back(back_id);
compatible_patches[back_id].push_back(front_id); compatible_patches[back_id].push_back(front_id);
} }
else else
{ {
//~ incompatible_hedges.push_back( std::make_pair(v.front(), v.back()) );
incompatible_patches[front_id].push_back(back_id); incompatible_patches[front_id].push_back(back_id);
incompatible_patches[back_id].push_back(front_id); incompatible_patches[back_id].push_back(front_id);
} }
@ -1699,7 +1727,7 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
// sort the connected components with potential matches using their number // sort the connected components with potential matches using their number
// of faces (sorted by decreasing number of faces) // of faces (sorted by decreasing number of faces)
std::vector<bool> cc_bits(nb_cc, false); std::vector<bool> cc_bits(nb_cc, false);
std::vector<bool> cc_bit_set(nb_cc, false); std::vector<bool> cc_handled(nb_cc, false);
std::set< F_cc_id, std::function<bool(F_cc_id,F_cc_id)> > sorted_ids( std::set< F_cc_id, std::function<bool(F_cc_id,F_cc_id)> > sorted_ids(
[&nb_faces_per_cc](F_cc_id i, F_cc_id j) [&nb_faces_per_cc](F_cc_id i, F_cc_id j)
@ -1708,10 +1736,10 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
for(F_cc_id cc_id=0; cc_id<nb_cc; ++cc_id) for(F_cc_id cc_id=0; cc_id<nb_cc; ++cc_id)
sorted_ids.insert(cc_id); sorted_ids.insert(cc_id);
// consider largest CC first, default and set bit to 0 // consider largest CC first, default and set its bit to 0
for(F_cc_id cc_id : sorted_ids) for(F_cc_id cc_id : sorted_ids)
{ {
if (cc_bit_set[cc_id]) continue; if (cc_handled[cc_id]) continue;
// extract compatible components // extract compatible components
std::set<F_cc_id> bit_0_cc_set; std::set<F_cc_id> bit_0_cc_set;
@ -1722,6 +1750,7 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
while( !stack_0.empty() || !stack_1.empty()) while( !stack_0.empty() || !stack_1.empty())
{ {
// increase the set of patches for bit 0 using compatible_patches
while( !stack_0.empty() ) while( !stack_0.empty() )
{ {
F_cc_id back=stack_0.back(); F_cc_id back=stack_0.back();
@ -1733,6 +1762,7 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
// extract incompatible components // extract incompatible components
for (F_cc_id cid : bit_0_cc_set) for (F_cc_id cid : bit_0_cc_set)
stack_1.insert(stack_1.end(), incompatible_patches[cid].begin(), incompatible_patches[cid].end()); stack_1.insert(stack_1.end(), incompatible_patches[cid].begin(), incompatible_patches[cid].end());
// increase the set of patches for bit 1 using compatible_patches
while( !stack_1.empty() ) while( !stack_1.empty() )
{ {
F_cc_id back=stack_1.back(); F_cc_id back=stack_1.back();
@ -1753,40 +1783,46 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
std::back_inserter(inter)); std::back_inserter(inter));
if (!inter.empty()) if (!inter.empty())
{ {
std::cout << "inter pas vide!\n"; #ifdef CGAL_PMP_DEBUG_ORIENTATION
std::cout << "DEBUG: Set intersection is not empty\n";
#endif
return false; return false;
} }
// set bit of compatible patches // set bit of compatible patches
for (F_cc_id id : bit_0_cc_set) for (F_cc_id id : bit_0_cc_set)
{ {
if (cc_bit_set[id]) if (cc_handled[id])
{ {
if(cc_bits[id] == true) if(cc_bits[id] == true)
{ {
std::cout << "BOOM 1!\n"; #ifdef CGAL_PMP_DEBUG_ORIENTATION
std::cout << "DEBUG: orientation bit already set to 1, incompatible with 0\n";
#endif
return false; return false;
} }
else else
continue; continue;
} }
cc_bit_set[id]=true; cc_handled[id]=true;
} }
// set bit of incompatible patches // set bit of incompatible patches
for (F_cc_id id : bit_1_cc_set) for (F_cc_id id : bit_1_cc_set)
{ {
if (cc_bit_set[id]) if (cc_handled[id])
{ {
if(cc_bits[id] == false) if(cc_bits[id] == false)
{ {
std::cout << "BOOM 2!\n"; #ifdef CGAL_PMP_DEBUG_ORIENTATION
std::cout << "DEBUG: orientation bit already set to 0, incompatible with 1\n";
#endif
return false; return false;
} }
else else
continue; continue;
} }
cc_bit_set[id]=true; cc_handled[id]=true;
cc_bits[id]=true; cc_bits[id]=true;
} }
} }
@ -1795,7 +1831,6 @@ bool connected_components_compatible_orientations(PolygonMesh& pm,
for (face_descriptor f : faces(pm)) for (face_descriptor f : faces(pm))
put(fbm, f, cc_bits[get(f_cc_ids,f)]); put(fbm, f, cc_bits[get(f_cc_ids,f)]);
return true; return true;
} }