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 {
std::size_t index = std::size_t(-1);
edge_descriptor ed;
std::set<std::size_t> sneighbors;
std::set<std::size_t> tneighbors;
std::vector<std::size_t> neighbors;
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 {
const edge_descriptor operator()(const PEdge& pedge) const {
return pedge.ed;
@ -112,7 +108,7 @@ namespace Polygon_mesh {
\param pmesh a polygon mesh
\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"
among the ones listed below
@ -123,12 +119,6 @@ namespace Polygon_mesh {
vertex to `Kernel::Point_3`}
\cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
\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
\pre `faces(pmesh).size() > 0`
@ -146,11 +136,8 @@ namespace Polygon_mesh {
{
clear();
std::vector<std::size_t> pedge_map(
edges(pmesh).size(), std::size_t(-1));
typedef typename GetInitializedEdgeIndexMap<PolygonMesh, NamedParameters>::const_type EdgeIndexMap;
EdgeIndexMap eimap = get_initialized_edge_index_map(pmesh, np);
typedef typename boost::property_map<PolygonMesh, CGAL::dynamic_edge_property_t<std::size_t> >::const_type EdgeIndexMap;
EdgeIndexMap eimap = get(CGAL::dynamic_edge_property_t<std::size_t>(), pmesh);
// collect edges either on the boundary or having two different incident regions
for (const auto& edge : edges(pmesh))
@ -168,22 +155,37 @@ namespace Polygon_mesh {
if (f2 != boost::graph_traits<PolygonMesh>::null_face())
r2 = get(face_to_region_map, f2);
if (r1 == r2) continue;
add_graph_edge(edge, r1, r2, pedge_map, eimap);
if (r1 == r2)
put(eimap, edge, std::size_t(-1));
else
add_graph_edge(edge, r1, r2, eimap);
}
// 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];
CGAL_precondition(pedge.regions.first != pedge.regions.second);
CGAL_precondition(pedge.index != std::size_t(-1));
const edge_descriptor edge = pedge.ed;
const vertex_descriptor s = source(edge, pmesh);
const vertex_descriptor t = target(edge, pmesh);
std::array<vertex_descriptor, 2> vrts = { source(pedge.ed, pmesh), target(pedge.ed, pmesh) };
add_vertex_neighbors(s, i, pedge_map, pedge.sneighbors, pmesh, eimap);
add_vertex_neighbors(t, i, pedge_map, pedge.tneighbors, pmesh, eimap);
for (int k=0; k<2; ++k)
{
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()(
const std::size_t query_index,
std::vector<std::size_t>& neighbors) const {
std::vector<std::size_t>& neighbors) const
{
neighbors.clear();
CGAL_precondition(query_index < segment_range().size());
const auto& pedge = m_pedges[query_index];
for (const std::size_t sneighbor : pedge.sneighbors)
neighbors.push_back(sneighbor);
for (const std::size_t tneighbor : pedge.tneighbors)
neighbors.push_back(tneighbor);
neighbors=pedge.neighbors;
}
/*!
@ -240,41 +239,27 @@ namespace Polygon_mesh {
/*!
\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`.
\pre `query_index < segment_range().size()`
*/
const std::set<std::size_t>& source_neighbors(
const std::size_t query_index) const {
const std::vector<std::size_t>& neighbors(
const std::size_t query_index) const
{
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()`,
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
\brief returns the edge descriptor which
corresponds to the edge from `segment_range()` with the index `query_index`.
\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());
return m_pedges[query_index].index;
return m_pedges[query_index].ed;
}
/*!
@ -311,43 +296,38 @@ namespace Polygon_mesh {
template <class EdgeIndexMap>
void add_graph_edge(
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;
CGAL_precondition(region1 != region2);
const std::size_t ei = get(eimap, edge);
CGAL_precondition(ei != std::size_t(-1));
const std::size_t ei = m_pedges.size();
put(eimap, edge, ei);
pedge.index = ei;
pedge.ed = edge;
pedge.regions.first = region1;
pedge.regions.second = region2;
CGAL_precondition(pedge.index < pedge_map.size());
pedge_map[pedge.index] = m_pedges.size();
pedge.regions = {region1, region2};
m_pedges.push_back(pedge);
}
template<typename EdgeIndexMap>
void add_vertex_neighbors(
const vertex_descriptor vertex, const std::size_t curr_pe,
const std::vector<std::size_t>& pedge_map,
std::set<std::size_t>& neighbors,
const vertex_descriptor vertex,
const PolygonMesh& pmesh,
EdgeIndexMap eimap) const {
const auto query_hedge = halfedge(vertex, pmesh);
const auto hedges = halfedges_around_target(query_hedge, pmesh);
CGAL_precondition(hedges.size() > 0);
for (const auto& hedge : hedges) {
EdgeIndexMap eimap)
{
std::vector<std::size_t> nei;
for (const auto& hedge : halfedges_around_target(vertex, pmesh))
{
const auto e = edge(hedge, pmesh);
const std::size_t ei = get(eimap, e);
CGAL_precondition(ei < pedge_map.size());
const std::size_t pe = pedge_map[ei];
if (pe == std::size_t(-1)) continue;
if (pe == curr_pe) continue;
CGAL_precondition(pe < m_pedges.size());
neighbors.insert(pe);
if (ei == std::size_t(-1)) continue;
if (nei.size()==2) return;
nei.push_back(ei);
}
if (nei.size()==2)
{
m_pedges[nei[0]].neighbors.push_back(nei[1]);
m_pedges[nei[1]].neighbors.push_back(nei[0]);
}
}
};