mirror of https://github.com/CGAL/cgal
simplify polyline graph
This commit is contained in:
parent
763d621a9b
commit
d963d70c25
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue