mirror of https://github.com/CGAL/cgal
avoid using a std::set and a std::vector for container storing at most 2 elements
Thanks @afabri
This commit is contained in:
parent
12fea568f0
commit
55c3e1ad61
|
|
@ -96,6 +96,49 @@ struct Default_surface_intersection_visitor{
|
||||||
static const bool do_need_vertex_graph = false;
|
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,
|
template< class TriangleMesh,
|
||||||
class VertexPointMap,
|
class VertexPointMap,
|
||||||
class Node_visitor=Default_surface_intersection_visitor<TriangleMesh>
|
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.
|
// we use Face_pair_and_int and not Face_pair to handle coplanar case.
|
||||||
// Indeed the boundary of the intersection of two coplanar triangles
|
// Indeed the boundary of the intersection of two coplanar triangles
|
||||||
// may contain several segments.
|
// 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
|
// data members
|
||||||
|
|
@ -256,33 +299,30 @@ class Intersection_of_triangle_meshes
|
||||||
return std::pair<Node_id,bool>(res.first->second, false);
|
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,
|
void add_intersection_point_to_face_and_all_edge_incident_faces(face_descriptor f_1,
|
||||||
halfedge_descriptor e_2,
|
halfedge_descriptor e_2,
|
||||||
const TriangleMesh& tm1,
|
const TriangleMesh& tm1,
|
||||||
const TriangleMesh& tm2,
|
const TriangleMesh& tm2,
|
||||||
Node_id node_id)
|
Node_id node_id)
|
||||||
{
|
{
|
||||||
std::vector<face_descriptor> incident_faces_2;
|
if (!is_border(e_2, tm2))
|
||||||
get_incident_faces(e_2,tm2,std::back_inserter(incident_faces_2));
|
|
||||||
BOOST_FOREACH(face_descriptor f_2, incident_faces_2)
|
|
||||||
{
|
{
|
||||||
|
face_descriptor f_2 = face(e_2, tm2);
|
||||||
Face_pair face_pair = &tm1<&tm2
|
Face_pair face_pair = &tm1<&tm2
|
||||||
? Face_pair(f_1,f_2)
|
? Face_pair(f_1,f_2)
|
||||||
: Face_pair(f_2,f_1);
|
: Face_pair(f_2,f_1);
|
||||||
if ( coplanar_faces.count(face_pair) ) continue;
|
if ( coplanar_faces.count(face_pair)==0 )
|
||||||
typename Faces_to_nodes_map::iterator it_list=
|
f_to_node[Face_pair_and_int(face_pair,0)].insert(node_id);
|
||||||
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);
|
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
|
//associate the intersection point to all faces incident to the intersected edge using edge
|
||||||
std::vector<face_descriptor> incident_faces;
|
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);
|
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);
|
if (fset!=NULL) fset->erase(f_2);
|
||||||
}
|
}
|
||||||
incident_faces.clear();
|
|
||||||
|
|
||||||
//associate the intersection point to all faces incident to edge using the intersected edge
|
//associate the intersection point to all faces incident to edge using the intersected edge
|
||||||
//at least one pair of faces is already handle above
|
//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));
|
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;
|
if (it_fset==tm2_edge_to_tm1_faces.end()) return;
|
||||||
Face_set& fset_bis=it_fset->second;
|
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
|
//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);
|
//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 0: break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
typename Faces_to_nodes_map::iterator it_list=
|
f_to_node[Face_pair_and_int(face_pair,1)].insert(cpln_nodes[0]);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
std::size_t stop=nb_pts + (nb_pts<3?-1:0);
|
std::size_t stop=nb_pts + (nb_pts<3?-1:0);
|
||||||
for (std::size_t k=0;k<stop;++k){
|
for (std::size_t k=0;k<stop;++k){
|
||||||
typename Faces_to_nodes_map::iterator it_list=
|
Node_id_set& node_id_set = f_to_node[Face_pair_and_int(face_pair,static_cast<int>(k+1))];
|
||||||
f_to_node.insert( std::make_pair( Face_pair_and_int(face_pair,static_cast<int>(k+1)),std::set<Node_id>()) ).first;
|
node_id_set.insert( cpln_nodes[k] );
|
||||||
it_list->second.insert( cpln_nodes[k] );
|
node_id_set.insert( cpln_nodes[(k+1)%nb_pts] );
|
||||||
it_list->second.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
|
//counts the number of time each node has been seen
|
||||||
bool isolated_point_seen=false;
|
bool isolated_point_seen=false;
|
||||||
for (typename Faces_to_nodes_map::iterator it=f_to_node.begin();it!=f_to_node.end();++it){
|
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);
|
CGAL_assertion(segment.size()==2 || segment.size()==1);
|
||||||
if (segment.size()==2){
|
if (segment.size()==2){
|
||||||
Node_id i=*segment.begin();
|
Node_id i=segment.first;
|
||||||
Node_id j=*boost::next(segment.begin());
|
Node_id j=segment.second;
|
||||||
graph[i].insert(j);
|
graph[i].insert(j);
|
||||||
graph[j].insert(i);
|
graph[j].insert(i);
|
||||||
}
|
}
|
||||||
|
|
@ -800,11 +851,11 @@ class Intersection_of_triangle_meshes
|
||||||
{
|
{
|
||||||
if (it->second.size()==1) continue;
|
if (it->second.size()==1) continue;
|
||||||
CGAL_precondition(it->second.size()==2);
|
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
|
//it->second is a set so node ids are already sorted
|
||||||
bool is_new=already_seen.insert( std::make_pair(
|
bool is_new=already_seen.insert( std::make_pair(
|
||||||
*(it->second.begin()),
|
it->second.first,
|
||||||
*cpp11::next(it->second.begin()) )
|
it->second.second )
|
||||||
).second;
|
).second;
|
||||||
|
|
||||||
if (!is_new)
|
if (!is_new)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue