avoid using a std::set and a std::vector for container storing at most 2 elements

Thanks @afabri
This commit is contained in:
Sébastien Loriot 2016-12-12 22:29:05 +01:00
parent 12fea568f0
commit 55c3e1ad61
1 changed files with 89 additions and 38 deletions

View File

@ -96,6 +96,49 @@ struct Default_surface_intersection_visitor{
static const bool do_need_vertex_graph = false;
};
struct Node_id_set {
typedef std::size_t Node_id;
Node_id first;
Node_id second;
std::size_t size_;
Node_id_set()
: size_(0)
{}
void insert(std::size_t v){
if(size_ == 0){
first = v;
++size_;
}
else if((size_ == 1) && (v != first)){
if(v < first){
second = first;
first = v;
} else {
second = v;
}
++size_;
}
else{
CGAL_assertion((size_ == 2) && ((v == first) || (v == second)));
}
}
std::size_t size() const
{
return size_;
}
std::size_t operator[](std::size_t i) const
{
CGAL_assertion( (i < size) && (i == 0 || i == 1));
return (i == 0)? first : second;
}
};
template< class TriangleMesh,
class VertexPointMap,
class Node_visitor=Default_surface_intersection_visitor<TriangleMesh>
@ -124,7 +167,7 @@ class Intersection_of_triangle_meshes
// we use Face_pair_and_int and not Face_pair to handle coplanar case.
// Indeed the boundary of the intersection of two coplanar triangles
// may contain several segments.
typedef std::map< Face_pair_and_int, std::set<Node_id> > Faces_to_nodes_map;
typedef std::map< Face_pair_and_int, Node_id_set > Faces_to_nodes_map;
// data members
@ -256,33 +299,30 @@ class Intersection_of_triangle_meshes
return std::pair<Node_id,bool>(res.first->second, false);
}
template <class Output_iterator>
void get_incident_faces(halfedge_descriptor edge,
const TriangleMesh& tm,
Output_iterator out)
{
if (!is_border(edge,tm)) *out++=face(edge,tm);
edge=opposite(edge,tm);
if (!is_border(edge,tm)) *out++=face(edge,tm);
}
void add_intersection_point_to_face_and_all_edge_incident_faces(face_descriptor f_1,
halfedge_descriptor e_2,
const TriangleMesh& tm1,
const TriangleMesh& tm2,
Node_id node_id)
{
std::vector<face_descriptor> incident_faces_2;
get_incident_faces(e_2,tm2,std::back_inserter(incident_faces_2));
BOOST_FOREACH(face_descriptor f_2, incident_faces_2)
if (!is_border(e_2, tm2))
{
face_descriptor f_2 = face(e_2, tm2);
Face_pair face_pair = &tm1<&tm2
? Face_pair(f_1,f_2)
: Face_pair(f_2,f_1);
if ( coplanar_faces.count(face_pair) ) continue;
typename Faces_to_nodes_map::iterator it_list=
f_to_node.insert( std::make_pair( Face_pair_and_int(face_pair,0),std::set<Node_id>()) ).first;
it_list->second.insert(node_id);
if ( coplanar_faces.count(face_pair)==0 )
f_to_node[Face_pair_and_int(face_pair,0)].insert(node_id);
}
e_2 = opposite(e_2, tm2);
if (!is_border(e_2, tm2))
{
face_descriptor f_2 = face(e_2, tm2);
Face_pair face_pair = &tm1<&tm2
? Face_pair(f_1,f_2)
: Face_pair(f_2,f_1);
if ( coplanar_faces.count(face_pair) == 0 )
f_to_node[Face_pair_and_int(face_pair,0)].insert(node_id);
}
}
@ -295,13 +335,20 @@ class Intersection_of_triangle_meshes
{
//associate the intersection point to all faces incident to the intersected edge using edge
std::vector<face_descriptor> incident_faces;
get_incident_faces(edge_intersected,tm2,std::back_inserter(incident_faces));
BOOST_FOREACH(face_descriptor f_2, incident_faces)
if (!is_border(edge_intersected, tm2))
{
face_descriptor f_2 = face(edge_intersected, tm2);
add_intersection_point_to_face_and_all_edge_incident_faces(f_2,e_1,tm2,tm1,node_id);
if (fset!=NULL) fset->erase(f_2);
}
edge_intersected = opposite(edge_intersected, tm2);
if (!is_border(edge_intersected, tm2))
{
face_descriptor f_2 = face(edge_intersected, tm2);
add_intersection_point_to_face_and_all_edge_incident_faces(f_2,e_1,tm2,tm1,node_id);
if (fset!=NULL) fset->erase(f_2);
}
incident_faces.clear();
//associate the intersection point to all faces incident to edge using the intersected edge
//at least one pair of faces is already handle above
@ -313,12 +360,19 @@ class Intersection_of_triangle_meshes
typename Edge_to_faces::iterator it_fset=tm2_edge_to_tm1_faces.find(edge(edge_intersected,tm2));
if (it_fset==tm2_edge_to_tm1_faces.end()) return;
Face_set& fset_bis=it_fset->second;
get_incident_faces(e_1,tm1,std::back_inserter(incident_faces));
BOOST_FOREACH(face_descriptor f_1, incident_faces)
if (!is_border(e_1, tm1))
{
//the following call is not needed, it is already done in the first loop
//add_intersection_point_to_face_and_all_edge_incident_faces(f_1,edge_intersected,tm1,tm2,node_id);
fset_bis.erase(f_1);
fset_bis.erase(face(e_1, tm1));
}
e_1 = opposite(e_1, tm1);
if (!is_border(e_1, tm1))
{
//the following call is not needed, it is already done in the first loop
//add_intersection_point_to_face_and_all_edge_incident_faces(f_1,edge_intersected,tm1,tm2,node_id);
fset_bis.erase(face(e_1, tm1));
}
}
@ -494,19 +548,16 @@ class Intersection_of_triangle_meshes
case 0: break;
case 1:
{
typename Faces_to_nodes_map::iterator it_list=
f_to_node.insert( std::make_pair( Face_pair_and_int(face_pair,1),std::set<Node_id>()) ).first;
it_list->second.insert(cpln_nodes[0]);
f_to_node[Face_pair_and_int(face_pair,1)].insert(cpln_nodes[0]);
}
break;
default:
{
std::size_t stop=nb_pts + (nb_pts<3?-1:0);
for (std::size_t k=0;k<stop;++k){
typename Faces_to_nodes_map::iterator it_list=
f_to_node.insert( std::make_pair( Face_pair_and_int(face_pair,static_cast<int>(k+1)),std::set<Node_id>()) ).first;
it_list->second.insert( cpln_nodes[k] );
it_list->second.insert( cpln_nodes[(k+1)%nb_pts] );
Node_id_set& node_id_set = f_to_node[Face_pair_and_int(face_pair,static_cast<int>(k+1))];
node_id_set.insert( cpln_nodes[k] );
node_id_set.insert( cpln_nodes[(k+1)%nb_pts] );
}
}
}
@ -692,11 +743,11 @@ class Intersection_of_triangle_meshes
//counts the number of time each node has been seen
bool isolated_point_seen=false;
for (typename Faces_to_nodes_map::iterator it=f_to_node.begin();it!=f_to_node.end();++it){
const std::set<Node_id>& segment=it->second;
const Node_id_set& segment=it->second;
CGAL_assertion(segment.size()==2 || segment.size()==1);
if (segment.size()==2){
Node_id i=*segment.begin();
Node_id j=*boost::next(segment.begin());
Node_id i=segment.first;
Node_id j=segment.second;
graph[i].insert(j);
graph[j].insert(i);
}
@ -800,12 +851,12 @@ class Intersection_of_triangle_meshes
{
if (it->second.size()==1) continue;
CGAL_precondition(it->second.size()==2);
CGAL_assertion(*(it->second.begin())<*cpp11::next(it->second.begin()));
CGAL_assertion((it->second.first)< (it->second.second));
//it->second is a set so node ids are already sorted
bool is_new=already_seen.insert( std::make_pair(
*(it->second.begin()),
*cpp11::next(it->second.begin()) )
).second;
it->second.first,
it->second.second )
).second;
if (!is_new)
to_erase.push_back(it);