diff --git a/BGL/doc/BGL/Concepts/MutableFaceGraph.h b/BGL/doc/BGL/Concepts/MutableFaceGraph.h index eb7c5c915b2..7df4f7b4b5b 100644 --- a/BGL/doc/BGL/Concepts/MutableFaceGraph.h +++ b/BGL/doc/BGL/Concepts/MutableFaceGraph.h @@ -47,4 +47,4 @@ Indicates the expected size of vertices (`nv`), edges (`ed`) and faces (`nf`). */ template void -reserve(MutableFaceGraph& g, boost::graph_traits::vertices_size_type nv, boost::graph_traits::vertices_size_type ne, boost::graph_traits::vertices_size_type nf); +reserve(MutableFaceGraph& g, boost::graph_traits::vertices_size_type nv, boost::graph_traits::edges_size_type ne, boost::graph_traits::faces_size_type nf); diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph.h b/BGL/include/CGAL/boost/graph/copy_face_graph.h index 311a5c28cac..9a2cb628825 100644 --- a/BGL/include/CGAL/boost/graph/copy_face_graph.h +++ b/BGL/include/CGAL/boost/graph/copy_face_graph.h @@ -71,6 +71,10 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm, tm_face_descriptor tm_null_face = boost::graph_traits::null_face(); + reserve(tm, static_cast::vertices_size_type>(vertices(sm).size()), + static_cast::edges_size_type>(edges(sm).size()), + static_cast::faces_size_type>(faces(sm).size()) ); + //insert halfedges and create each vertex when encountering its halfedge for(sm_edge_descriptor sm_e : edges(sm)) { diff --git a/Convex_hull_3/include/CGAL/Extreme_points_traits_adapter_3.h b/Convex_hull_3/include/CGAL/Extreme_points_traits_adapter_3.h index 8991774adc3..8c84e567ca7 100644 --- a/Convex_hull_3/include/CGAL/Extreme_points_traits_adapter_3.h +++ b/Convex_hull_3/include/CGAL/Extreme_points_traits_adapter_3.h @@ -221,16 +221,17 @@ public: Orientation_2 orientation_2_object ()const{return Orientation_2(vpm_,static_cast(this)->orientation_2_object() );} }; - typedef Proj_traits_3 Traits_xy_3; - typedef Proj_traits_3 Traits_yz_3; - typedef Proj_traits_3 Traits_xz_3; + typedef internal::Convex_hull_3::Projection_traits Base_PTraits; + typedef Proj_traits_3 Traits_xy_3; + typedef Proj_traits_3 Traits_yz_3; + typedef Proj_traits_3 Traits_xz_3; Traits_xy_3 construct_traits_xy_3_object()const - {return Traits_xy_3(vpm_, static_cast(this)->construct_traits_xy_3_object());} + {return Traits_xy_3(vpm_, Base_PTraits(static_cast(*this)).construct_traits_xy_3_object());} Traits_yz_3 construct_traits_yz_3_object()const - {return Traits_yz_3(vpm_, static_cast(this)->construct_traits_yz_3_object());} + {return Traits_yz_3(vpm_, Base_PTraits(static_cast(*this)).construct_traits_yz_3_object());} Traits_xz_3 construct_traits_xz_3_object()const - {return Traits_xz_3(vpm_, static_cast(this)->construct_traits_xz_3_object());} + {return Traits_xz_3(vpm_, Base_PTraits(static_cast(*this)).construct_traits_xz_3_object());} typename boost::property_traits::reference get_point(const typename boost::property_traits::key_type& k) const diff --git a/HalfedgeDS/include/CGAL/boost/graph/graph_traits_HalfedgeDS_default.h b/HalfedgeDS/include/CGAL/boost/graph/graph_traits_HalfedgeDS_default.h index 05346c0aac7..1f84f085c02 100644 --- a/HalfedgeDS/include/CGAL/boost/graph/graph_traits_HalfedgeDS_default.h +++ b/HalfedgeDS/include/CGAL/boost/graph/graph_traits_HalfedgeDS_default.h @@ -470,7 +470,16 @@ struct HDS_property_map typename T::Point_3, const typename T::Point_3&> const_type; }; }; - + +template +void reserve(HalfedgeDS_default& p, + typename boost::graph_traits< HalfedgeDS_default const>::vertices_size_type nv, + typename boost::graph_traits< HalfedgeDS_default const>::edges_size_type ne, + typename boost::graph_traits< HalfedgeDS_default const>::faces_size_type nf) +{ + p.reserve(nv, 2*ne, nf); +} + }// namespace CGAL namespace boost { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orient_polygon_soup.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orient_polygon_soup.h index 3f3209aa029..a1e38dee24a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orient_polygon_soup.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orient_polygon_soup.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -59,9 +60,11 @@ struct Polygon_soup_orienter /// Container types typedef PointRange Points; typedef PolygonRange Polygons; - typedef std::map > Edge_map; - typedef typename Edge_map::iterator Edge_map_iterator; + typedef std::set Marked_edges; + typedef boost::container::flat_map< V_ID, boost::container::flat_set > 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 @@ -107,8 +110,8 @@ struct Polygon_soup_orienter { typedef std::pair 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); @@ -119,8 +122,8 @@ struct Polygon_soup_orienter { typedef std::pair 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); @@ -154,20 +157,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); } } @@ -181,10 +183,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); } @@ -248,17 +250,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) @@ -275,25 +277,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 @@ -376,6 +378,7 @@ struct Polygon_soup_orienter /// now duplicate the vertices typedef std::pair > V_ID_and_Polygon_ids; + edges.resize(edges.size()+vertices_to_duplicate.size()); for(const V_ID_and_Polygon_ids& vid_and_pids : vertices_to_duplicate) { V_ID new_index = static_cast(points.size()); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h index c64834abc5a..d25399730fb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h @@ -74,6 +74,10 @@ public: void operator()(PM& pmesh, const bool insert_isolated_vertices = true) { + reserve(pmesh, static_cast::vertices_size_type>(_points.size()), + static_cast::edges_size_type>(2*_polygons.size()), + static_cast::faces_size_type>(_polygons.size()) ); + Vpmap vpmap = get(CGAL::vertex_point, pmesh); boost::dynamic_bitset<> not_isolated; @@ -182,7 +186,7 @@ public: //check manifoldness typedef std::vector PointRange; typedef internal::Polygon_soup_orienter 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 diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp index fb61d03bb8a..e1a9573b8f7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Orient_soup_plugin.cpp @@ -309,10 +309,10 @@ void Polyhedron_demo_orient_soup_plugin::getNMPoints( Scene_polygon_soup_item* item) { typedef std::pair V_ID_pair; - typedef std::map > Edge_map; - typedef std::set Marked_edges; typedef CGAL::Polygon_mesh_processing::internal::Polygon_soup_orienter PSO; + typedef PSO::Edge_map Edge_map; + typedef std::set Marked_edges; Edge_map edges; Marked_edges m_edges; diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h b/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h index de21e33785d..89d2c192879 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h @@ -286,7 +286,7 @@ bool read_surf(std::istream& input, std::vector& output, Mesh& mesh = output[i]; - PMP::internal::Polygon_soup_to_polygon_mesh + PMP::internal::Polygon_soup_to_polygon_mesh, std::vector> converter(points, polygons); converter(mesh, false/*insert_isolated_vertices*/); diff --git a/Polyhedron/demo/Polyhedron/include/id_printing.h b/Polyhedron/demo/Polyhedron/include/id_printing.h index 9f4ede9b528..9d4399f4a53 100644 --- a/Polyhedron/demo/Polyhedron/include/id_printing.h +++ b/Polyhedron/demo/Polyhedron/include/id_printing.h @@ -562,12 +562,18 @@ int zoomToId(const Mesh& mesh, bool found = false; for(vertex_descriptor vh : vertices(mesh)) { - if(get(vidmap, vh) == id) + std::size_t cur_id = get(vidmap, vh); + if( cur_id == id) { p = Point(get(ppmap, vh).x() + offset.x, get(ppmap, vh).y() + offset.y, get(ppmap, vh).z() + offset.z); - selected_fh = face(halfedge(vh, mesh), mesh); + typename boost::graph_traits::halfedge_descriptor hf = halfedge(vh, mesh); + if(CGAL::is_border_edge(hf, mesh)) + { + hf = opposite(hf, mesh); + } + selected_fh = face(hf, mesh); normal = CGAL::Polygon_mesh_processing::compute_vertex_normal(vh, mesh); found = true; break; @@ -585,17 +591,27 @@ int zoomToId(const Mesh& mesh, { if(get(eidmap, halfedge(e, mesh))/2 == id) { + typename boost::graph_traits::halfedge_descriptor hf = halfedge(e, mesh); const Point& p1 = get(ppmap, source(e, mesh)); const Point& p2 = get(ppmap, target(e, mesh)); p = Point((float)(p1.x() + p2.x()) / 2 + offset.x, (float)(p1.y() + p2.y()) / 2 + offset.y, (float)(p1.z() + p2.z()) / 2 + offset.z ); - typename Traits::Vector_3 normal1 = CGAL::Polygon_mesh_processing::compute_face_normal(face(halfedge(e, mesh),mesh), - mesh); - typename Traits::Vector_3 normal2 = CGAL::Polygon_mesh_processing::compute_face_normal(face(opposite(halfedge(e, mesh), mesh), mesh), - mesh); + typename Traits::Vector_3 normal1(0,0,0); + if(!is_border(hf, mesh)) + { + normal1= CGAL::Polygon_mesh_processing::compute_face_normal(face(hf,mesh), + mesh); + selected_fh = face(hf, mesh); + } + typename Traits::Vector_3 normal2(0,0,0); + if(!is_border(opposite(hf, mesh), mesh)) + { + normal2 = CGAL::Polygon_mesh_processing::compute_face_normal(face(opposite(hf, mesh), mesh), + mesh); + selected_fh = face(hf, mesh); + } normal = 0.5*normal1+0.5*normal2; - selected_fh = face(halfedge(e, mesh), mesh); found = true; break; } diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h index 8f73fc9dd9a..c18f2c58b21 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h @@ -271,7 +271,7 @@ public: return Constraint_id(NULL); } // protects against inserting twice the same constraint - Constraint_id cid = hierarchy.insert_constraint(va, vb); + Constraint_id cid = hierarchy.insert_constraint_old_API(va, vb); if (va != vb && (cid != Constraint_id(NULL)) ) insert_subconstraint(va,vb); return cid; diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h index 2c1654cece4..1f3071db44e 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h @@ -247,6 +247,7 @@ public: // insert/remove void add_Steiner(T va, T vb, T vx); + Vertex_list* insert_constraint_old_API(T va, T vb); Vertex_list* insert_constraint(T va, T vb); void append_constraint(Constraint_id cid, T va, T vb); void swap(Constraint_id first, Constraint_id second); @@ -868,6 +869,34 @@ typename Polyline_constraint_hierarchy_2::Vertex_list* Polyline_constraint_hierarchy_2:: insert_constraint(T va, T vb){ Edge he = make_edge(va, vb); + Vertex_list* children = new Vertex_list; + Context_list* fathers; + + typename Sc_to_c_map::iterator scit = sc_to_c_map.find(he); + if(scit == sc_to_c_map.end()){ + fathers = new Context_list; + sc_to_c_map.insert(std::make_pair(he,fathers)); + } else { + fathers = scit->second; + } + + children->push_front(Node(va, true)); // was he.first + children->push_back(Node(vb, true)); // was he.second + constraint_set.insert(children); + Context ctxt; + ctxt.enclosing = children; + ctxt.pos = children->skip_begin(); + fathers->push_front(ctxt); + + return children; +} + + +template +typename Polyline_constraint_hierarchy_2::Vertex_list* +Polyline_constraint_hierarchy_2:: +insert_constraint_old_API(T va, T vb){ + Edge he = make_edge(va, vb); // First, check if the constraint was already inserted. // If it was not, then the iterator to the lower bound will serve as diff --git a/Triangulation_2/test/Triangulation_2/issue_3447.cpp b/Triangulation_2/test/Triangulation_2/issue_3447.cpp new file mode 100644 index 00000000000..de0a47601d0 --- /dev/null +++ b/Triangulation_2/test/Triangulation_2/issue_3447.cpp @@ -0,0 +1,34 @@ +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Exact_predicates_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 Triangulation; +typedef CGAL::Constrained_triangulation_plus_2 Delaunay; + +typedef K::Point_2 Point_2; + +int main() +{ + Delaunay dt; + + dt.insert(Point_2(0,0)); + dt.insert(Point_2(10,0)); + dt.insert(Point_2(0,10)); + dt.insert(Point_2(10,10)); + + std::vector vec_constraint; + + vec_constraint.push_back(Point_2(1, 2)); + vec_constraint.push_back(Point_2(2, 2)); + vec_constraint.push_back(Point_2(3, 2)); + + dt.insert_constraint(vec_constraint.begin(), vec_constraint.end()); + + dt.insert_constraint(vec_constraint.begin(), vec_constraint.end()); + + return 0; +}