mirror of https://github.com/CGAL/cgal
Merge pull request #3843 from sloriot/PMP-speed_orient_soup
Speed-up polygon soup orientation
This commit is contained in:
commit
fdc8d79a69
|
|
@ -32,6 +32,7 @@
|
|||
#include <CGAL/assertions.h>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
|
@ -60,9 +61,11 @@ struct Polygon_soup_orienter
|
|||
/// Container types
|
||||
typedef PointRange Points;
|
||||
typedef PolygonRange Polygons;
|
||||
typedef std::map<V_ID_pair, boost::container::flat_set<P_ID> > Edge_map;
|
||||
typedef typename Edge_map::iterator Edge_map_iterator;
|
||||
|
||||
typedef std::set<V_ID_pair> Marked_edges;
|
||||
typedef boost::container::flat_map< V_ID, boost::container::flat_set<P_ID> > Internal_map_type;
|
||||
typedef std::vector< Internal_map_type > Edge_map;
|
||||
typedef typename Internal_map_type::iterator Edge_map_iterator;
|
||||
|
||||
/// Data members
|
||||
Points& points; //< the set of input points
|
||||
|
|
@ -108,8 +111,8 @@ struct Polygon_soup_orienter
|
|||
{
|
||||
typedef std::pair<V_ID,P_ID> VID_and_PID;
|
||||
if ( is_edge_marked(src,tgt,marked_edges) ) return VID_and_PID(src,300612);
|
||||
Edge_map_iterator em_it=edges.find(V_ID_pair(tgt, src));
|
||||
if ( em_it==edges.end() ) return VID_and_PID(src,300612);// the vertex is on the border
|
||||
Edge_map_iterator em_it=edges[tgt].find(src);
|
||||
if ( em_it==edges[tgt].end() ) return VID_and_PID(src,300612);// the vertex is on the border
|
||||
CGAL_assertion(em_it->second.size()==1);
|
||||
P_ID p_id = *(em_it->second.begin());
|
||||
return VID_and_PID(get_neighbor_vertices(src, p_id, polygons)[2], p_id);
|
||||
|
|
@ -120,8 +123,8 @@ struct Polygon_soup_orienter
|
|||
{
|
||||
typedef std::pair<V_ID,P_ID> VID_and_PID;
|
||||
if ( is_edge_marked(src,tgt,marked_edges) ) return VID_and_PID(tgt,300612);
|
||||
Edge_map_iterator em_it=edges.find(V_ID_pair(tgt, src));
|
||||
if ( em_it==edges.end() ) return VID_and_PID(tgt,300612);// the vertex is on the border
|
||||
Edge_map_iterator em_it=edges[tgt].find(src);
|
||||
if ( em_it==edges[tgt].end() ) return VID_and_PID(tgt,300612);// the vertex is on the border
|
||||
CGAL_assertion(em_it->second.size()==1);
|
||||
P_ID p_id = *(em_it->second.begin());
|
||||
return VID_and_PID(get_neighbor_vertices(tgt, p_id, polygons)[0], p_id);
|
||||
|
|
@ -155,20 +158,19 @@ struct Polygon_soup_orienter
|
|||
}
|
||||
|
||||
Polygon_soup_orienter(Points& points, Polygons& polygons)
|
||||
: points(points), polygons(polygons)
|
||||
: points(points), polygons(polygons), edges(points.size())
|
||||
{}
|
||||
|
||||
//filling containers
|
||||
static void fill_edge_map(Edge_map& edges, Marked_edges& marked_edges, const Polygons& polygons) {
|
||||
// Fill edges
|
||||
edges.clear();
|
||||
for (P_ID i = 0; i < polygons.size(); ++i)
|
||||
{
|
||||
const P_ID size = polygons[i].size();
|
||||
for (P_ID j = 0; j < size; ++j) {
|
||||
V_ID i0 = polygons[i][j];
|
||||
V_ID i1 = polygons[i][(j + 1) % size];
|
||||
edges[V_ID_pair(i0, i1)].insert(i);
|
||||
edges[i0][i1].insert(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,10 +184,10 @@ struct Polygon_soup_orienter
|
|||
V_ID i1 = polygons[i][(j + 1) % size];
|
||||
|
||||
std::size_t nb_edges = 0;
|
||||
Edge_map_iterator em_it = edges.find(V_ID_pair(i0, i1));
|
||||
if (em_it != edges.end()) nb_edges += em_it->second.size();
|
||||
em_it = edges.find(V_ID_pair(i1, i0));
|
||||
if (em_it != edges.end()) nb_edges += em_it->second.size();
|
||||
Edge_map_iterator em_it = edges[i0].find(i1);
|
||||
if (em_it != edges[i0].end()) nb_edges += em_it->second.size();
|
||||
em_it = edges[i1].find(i0);
|
||||
if (em_it != edges[i1].end()) nb_edges += em_it->second.size();
|
||||
|
||||
if (nb_edges > 2) set_edge_marked(i0, i1, marked_edges);
|
||||
}
|
||||
|
|
@ -249,17 +251,17 @@ struct Polygon_soup_orienter
|
|||
if( is_edge_marked(i1,i2,marked_edges) ) continue;
|
||||
|
||||
// edge (i1,i2)
|
||||
Edge_map_iterator it_same_orient = edges.find(V_ID_pair(i1, i2));
|
||||
Edge_map_iterator it_same_orient = edges[i1].find(i2);
|
||||
// edges (i2,i1)
|
||||
Edge_map_iterator it_other_orient = edges.find(V_ID_pair(i2, i1));
|
||||
Edge_map_iterator it_other_orient = edges[i2].find(i1);
|
||||
|
||||
CGAL_assertion(it_same_orient != edges.end());
|
||||
CGAL_assertion(it_other_orient == edges.end() ||
|
||||
CGAL_assertion(it_same_orient != edges[i1].end());
|
||||
CGAL_assertion(it_other_orient == edges[i2].end() ||
|
||||
it_other_orient->second.size()==1);
|
||||
|
||||
if (it_same_orient->second.size() > 1)
|
||||
{
|
||||
CGAL_assertion(it_other_orient == edges.end());
|
||||
CGAL_assertion(it_other_orient == edges[i2].end());
|
||||
// one neighbor but with the same orientation
|
||||
P_ID index = *(it_same_orient->second.begin());
|
||||
if(index == to_be_oriented_index)
|
||||
|
|
@ -276,25 +278,25 @@ struct Polygon_soup_orienter
|
|||
for(P_ID j = 0; j < size; ++j) {
|
||||
V_ID i0 = polygons[index][j];
|
||||
V_ID i1 = polygons[index][(j+1)%size];
|
||||
Edge_map_iterator em_it = edges.find(V_ID_pair(i0, i1));
|
||||
Edge_map_iterator em_it = edges[i0].find(i1);
|
||||
CGAL_assertion_code(const bool r = )
|
||||
em_it->second.erase(index)
|
||||
CGAL_assertion_code(!= 0);
|
||||
CGAL_assertion(r);
|
||||
if ( em_it->second.empty() ) edges.erase(em_it);
|
||||
if ( em_it->second.empty() ) edges[i0].erase(em_it);
|
||||
}
|
||||
inverse_orientation(index);
|
||||
for(P_ID j = 0; j < size; ++j) {
|
||||
V_ID i0 = polygons[index][j];
|
||||
V_ID i1 = polygons[index][(j+1)%size];
|
||||
edges[V_ID_pair(i0, i1)].insert(index);
|
||||
edges[i0][i1].insert(index);
|
||||
}
|
||||
// "inverse the orientation of polygon #index
|
||||
oriented[index] = true;
|
||||
stack.push(index);
|
||||
}
|
||||
else{
|
||||
if( it_other_orient != edges.end() ){
|
||||
if( it_other_orient != edges[i2].end() ){
|
||||
CGAL_assertion(it_same_orient->second.size() == 1);
|
||||
CGAL_assertion(it_other_orient->second.size() == 1);
|
||||
// one polygon, same orientation
|
||||
|
|
@ -377,6 +379,7 @@ struct Polygon_soup_orienter
|
|||
|
||||
/// now duplicate the vertices
|
||||
typedef std::pair<V_ID, std::vector<P_ID> > V_ID_and_Polygon_ids;
|
||||
edges.resize(edges.size()+vertices_to_duplicate.size());
|
||||
BOOST_FOREACH(const V_ID_and_Polygon_ids& vid_and_pids, vertices_to_duplicate)
|
||||
{
|
||||
V_ID new_index = static_cast<V_ID>(points.size());
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ public:
|
|||
//check manifoldness
|
||||
typedef std::vector<V_ID> PointRange;
|
||||
typedef internal::Polygon_soup_orienter<PointRange, PolygonRange> Orienter;
|
||||
typename Orienter::Edge_map edges;
|
||||
typename Orienter::Edge_map edges(max_id+1);
|
||||
typename Orienter::Marked_edges marked_edges;
|
||||
Orienter::fill_edge_map(edges, marked_edges, polygons);
|
||||
//returns false if duplication is necessary
|
||||
|
|
|
|||
|
|
@ -300,10 +300,10 @@ void Polyhedron_demo_orient_soup_plugin::getNMPoints(
|
|||
Scene_polygon_soup_item* item)
|
||||
{
|
||||
typedef std::pair<std::size_t, std::size_t> V_ID_pair;
|
||||
typedef std::map<V_ID_pair, boost::container::flat_set<std::size_t> > Edge_map;
|
||||
typedef std::set<V_ID_pair> Marked_edges;
|
||||
typedef CGAL::Polygon_mesh_processing::internal::Polygon_soup_orienter<Polygon_soup::Points,
|
||||
Polygon_soup::Polygons> PSO;
|
||||
typedef PSO::Edge_map Edge_map;
|
||||
typedef std::set<V_ID_pair> Marked_edges;
|
||||
|
||||
Edge_map edges;
|
||||
Marked_edges m_edges;
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
|
|||
|
||||
Mesh& mesh = output[i];
|
||||
|
||||
PMP::internal::Polygon_soup_to_polygon_mesh<Mesh, Point_3, Triangle_ind>
|
||||
PMP::internal::Polygon_soup_to_polygon_mesh<Mesh, std::vector<Point_3>, std::vector<Triangle_ind>>
|
||||
converter(points, polygons);
|
||||
converter(mesh, false/*insert_isolated_vertices*/);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue