simplify polyline graph

This commit is contained in:
Sébastien Loriot 2022-02-24 10:14:46 +01:00
parent 763d621a9b
commit d963d70c25
1 changed files with 57 additions and 77 deletions

View File

@ -54,14 +54,10 @@ namespace Polygon_mesh {
struct PEdge { struct PEdge {
std::size_t index = std::size_t(-1); std::size_t index = std::size_t(-1);
edge_descriptor ed; edge_descriptor ed;
std::set<std::size_t> sneighbors; std::vector<std::size_t> neighbors;
std::set<std::size_t> tneighbors;
std::pair<std::size_t, std::size_t> regions; std::pair<std::size_t, std::size_t> regions;
}; };
using Face_to_index_map = internal::Item_to_index_property_map<face_descriptor>;
using Edge_to_index_map = internal::Item_to_index_property_map<edge_descriptor>;
struct Transform_pedge { struct Transform_pedge {
const edge_descriptor operator()(const PEdge& pedge) const { const edge_descriptor operator()(const PEdge& pedge) const {
return pedge.ed; return pedge.ed;
@ -112,7 +108,7 @@ namespace Polygon_mesh {
\param pmesh a polygon mesh \param pmesh a polygon mesh
\param face_to_region_map maps each face of `pmesh` to \param face_to_region_map maps each face of `pmesh` to
the corresponding planar regions id a corresponding planar region id
\param np a sequence of \ref bgl_namedparameters "Named Parameters" \param np a sequence of \ref bgl_namedparameters "Named Parameters"
among the ones listed below among the ones listed below
@ -123,12 +119,6 @@ namespace Polygon_mesh {
vertex to `Kernel::Point_3`} vertex to `Kernel::Point_3`}
\cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
\cgalParamNEnd \cgalParamNEnd
\cgalParamNBegin{edge_index_map}
\cgalParamDescription{a property map associating to each edge of `pmesh` a unique index between `0` and `num_edges(pmesh) - 1`}
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<PolygonMesh>::%edge_descriptor`
as key type and `std::size_t` as value type}
\cgalParamDefault{an automatically indexed internal map}
\cgalParamNEnd
\cgalNamedParamsEnd \cgalNamedParamsEnd
\pre `faces(pmesh).size() > 0` \pre `faces(pmesh).size() > 0`
@ -146,11 +136,8 @@ namespace Polygon_mesh {
{ {
clear(); clear();
std::vector<std::size_t> pedge_map( typedef typename boost::property_map<PolygonMesh, CGAL::dynamic_edge_property_t<std::size_t> >::const_type EdgeIndexMap;
edges(pmesh).size(), std::size_t(-1)); EdgeIndexMap eimap = get(CGAL::dynamic_edge_property_t<std::size_t>(), pmesh);
typedef typename GetInitializedEdgeIndexMap<PolygonMesh, NamedParameters>::const_type EdgeIndexMap;
EdgeIndexMap eimap = get_initialized_edge_index_map(pmesh, np);
// collect edges either on the boundary or having two different incident regions // collect edges either on the boundary or having two different incident regions
for (const auto& edge : edges(pmesh)) for (const auto& edge : edges(pmesh))
@ -168,22 +155,37 @@ namespace Polygon_mesh {
if (f2 != boost::graph_traits<PolygonMesh>::null_face()) if (f2 != boost::graph_traits<PolygonMesh>::null_face())
r2 = get(face_to_region_map, f2); r2 = get(face_to_region_map, f2);
if (r1 == r2) continue; if (r1 == r2)
add_graph_edge(edge, r1, r2, pedge_map, eimap); put(eimap, edge, std::size_t(-1));
else
add_graph_edge(edge, r1, r2, eimap);
} }
// build adjacency between edges // build adjacency between edges
for (std::size_t i = 0; i < m_pedges.size(); ++i) { typedef typename boost::property_map<PolygonMesh, CGAL::dynamic_vertex_property_t<bool> >::const_type VisitedVertexMap;
VisitedVertexMap visited_vertices = get(CGAL::dynamic_vertex_property_t<bool>(), pmesh);
for (std::size_t i = 0; i < m_pedges.size(); ++i)
{
put(visited_vertices, source(m_pedges[i].ed, pmesh), false);
put(visited_vertices, target(m_pedges[i].ed, pmesh), false);
}
for (std::size_t i = 0; i < m_pedges.size(); ++i)
{
auto& pedge = m_pedges[i]; auto& pedge = m_pedges[i];
CGAL_precondition(pedge.regions.first != pedge.regions.second); CGAL_precondition(pedge.regions.first != pedge.regions.second);
CGAL_precondition(pedge.index != std::size_t(-1)); CGAL_precondition(pedge.index != std::size_t(-1));
const edge_descriptor edge = pedge.ed; std::array<vertex_descriptor, 2> vrts = { source(pedge.ed, pmesh), target(pedge.ed, pmesh) };
const vertex_descriptor s = source(edge, pmesh);
const vertex_descriptor t = target(edge, pmesh);
add_vertex_neighbors(s, i, pedge_map, pedge.sneighbors, pmesh, eimap); for (int k=0; k<2; ++k)
add_vertex_neighbors(t, i, pedge_map, pedge.tneighbors, pmesh, eimap); {
if (!get(visited_vertices, vrts[k]))
{
add_vertex_neighbors(vrts[k], pmesh, eimap);
put(visited_vertices, vrts[k], true);
}
}
} }
} }
@ -209,15 +211,12 @@ namespace Polygon_mesh {
*/ */
void operator()( void operator()(
const std::size_t query_index, const std::size_t query_index,
std::vector<std::size_t>& neighbors) const { std::vector<std::size_t>& neighbors) const
{
neighbors.clear(); neighbors.clear();
CGAL_precondition(query_index < segment_range().size()); CGAL_precondition(query_index < segment_range().size());
const auto& pedge = m_pedges[query_index]; const auto& pedge = m_pedges[query_index];
for (const std::size_t sneighbor : pedge.sneighbors) neighbors=pedge.neighbors;
neighbors.push_back(sneighbor);
for (const std::size_t tneighbor : pedge.tneighbors)
neighbors.push_back(tneighbor);
} }
/*! /*!
@ -240,41 +239,27 @@ namespace Polygon_mesh {
/*! /*!
\brief returns indices of all edges from `segment_range()`, \brief returns indices of all edges from `segment_range()`,
which are connected to the source vertex of the edge which are connected to a vertex of the edge
with the index `query_index`. with the index `query_index`.
\pre `query_index < segment_range().size()` \pre `query_index < segment_range().size()`
*/ */
const std::set<std::size_t>& source_neighbors( const std::vector<std::size_t>& neighbors(
const std::size_t query_index) const { const std::size_t query_index) const
{
CGAL_precondition(query_index < segment_range().size()); CGAL_precondition(query_index < segment_range().size());
return m_pedges[query_index].sneighbors; return m_pedges[query_index].neighbors;
} }
/*! /*!
\brief returns indices of all edges from `segment_range()`, \brief returns the edge descriptor which
which are connected to the target vertex of the edge
with the index `query_index`.
\pre `query_index < segment_range().size()`
*/
const std::set<std::size_t>& target_neighbors(
const std::size_t query_index) const {
CGAL_precondition(query_index < segment_range().size());
return m_pedges[query_index].tneighbors;
}
/*!
\brief returns the edge index of the original polygon mesh edge, which
corresponds to the edge from `segment_range()` with the index `query_index`. corresponds to the edge from `segment_range()` with the index `query_index`.
\pre `query_index < segment_range().size()` \pre `query_index < segment_range().size()`
*/ */
std::size_t edge_index(const std::size_t query_index) const { edge_descriptor descriptor(const std::size_t query_index) const {
CGAL_precondition(query_index < segment_range().size()); CGAL_precondition(query_index < segment_range().size());
return m_pedges[query_index].index; return m_pedges[query_index].ed;
} }
/*! /*!
@ -311,43 +296,38 @@ namespace Polygon_mesh {
template <class EdgeIndexMap> template <class EdgeIndexMap>
void add_graph_edge( void add_graph_edge(
edge_descriptor edge, const std::size_t region1, const std::size_t region2, edge_descriptor edge, const std::size_t region1, const std::size_t region2,
std::vector<std::size_t>& pedge_map, EdgeIndexMap eimap)
EdgeIndexMap eimap) { {
PEdge pedge; PEdge pedge;
CGAL_precondition(region1 != region2); CGAL_precondition(region1 != region2);
const std::size_t ei = get(eimap, edge); const std::size_t ei = m_pedges.size();
CGAL_precondition(ei != std::size_t(-1)); put(eimap, edge, ei);
pedge.index = ei; pedge.index = ei;
pedge.ed = edge; pedge.ed = edge;
pedge.regions.first = region1; pedge.regions = {region1, region2};
pedge.regions.second = region2;
CGAL_precondition(pedge.index < pedge_map.size());
pedge_map[pedge.index] = m_pedges.size();
m_pedges.push_back(pedge); m_pedges.push_back(pedge);
} }
template<typename EdgeIndexMap> template<typename EdgeIndexMap>
void add_vertex_neighbors( void add_vertex_neighbors(
const vertex_descriptor vertex, const std::size_t curr_pe, const vertex_descriptor vertex,
const std::vector<std::size_t>& pedge_map,
std::set<std::size_t>& neighbors,
const PolygonMesh& pmesh, const PolygonMesh& pmesh,
EdgeIndexMap eimap) const { EdgeIndexMap eimap)
{
const auto query_hedge = halfedge(vertex, pmesh); std::vector<std::size_t> nei;
const auto hedges = halfedges_around_target(query_hedge, pmesh); for (const auto& hedge : halfedges_around_target(vertex, pmesh))
CGAL_precondition(hedges.size() > 0); {
for (const auto& hedge : hedges) {
const auto e = edge(hedge, pmesh); const auto e = edge(hedge, pmesh);
const std::size_t ei = get(eimap, e); const std::size_t ei = get(eimap, e);
CGAL_precondition(ei < pedge_map.size()); if (ei == std::size_t(-1)) continue;
const std::size_t pe = pedge_map[ei]; if (nei.size()==2) return;
if (pe == std::size_t(-1)) continue; nei.push_back(ei);
if (pe == curr_pe) continue; }
CGAL_precondition(pe < m_pedges.size()); if (nei.size()==2)
neighbors.insert(pe); {
m_pedges[nei[0]].neighbors.push_back(nei[1]);
m_pedges[nei[1]].neighbors.push_back(nei[0]);
} }
} }
}; };