Merge remote-tracking branch 'cgal/releases/CGAL-4.14-branch'

This commit is contained in:
Sébastien Loriot 2019-04-23 10:46:32 +02:00
commit 564a6c72f4
12 changed files with 142 additions and 42 deletions

View File

@ -47,4 +47,4 @@ Indicates the expected size of vertices (`nv`), edges (`ed`) and faces (`nf`).
*/ */
template <typename MutableFaceGraph> template <typename MutableFaceGraph>
void void
reserve(MutableFaceGraph& g, boost::graph_traits<MutableFaceGraph>::vertices_size_type nv, boost::graph_traits<MutableFaceGraph>::vertices_size_type ne, boost::graph_traits<MutableFaceGraph>::vertices_size_type nf); reserve(MutableFaceGraph& g, boost::graph_traits<MutableFaceGraph>::vertices_size_type nv, boost::graph_traits<MutableFaceGraph>::edges_size_type ne, boost::graph_traits<MutableFaceGraph>::faces_size_type nf);

View File

@ -71,6 +71,10 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
tm_face_descriptor tm_null_face = boost::graph_traits<TargetMesh>::null_face(); tm_face_descriptor tm_null_face = boost::graph_traits<TargetMesh>::null_face();
reserve(tm, static_cast<typename boost::graph_traits<TargetMesh>::vertices_size_type>(vertices(sm).size()),
static_cast<typename boost::graph_traits<TargetMesh>::edges_size_type>(edges(sm).size()),
static_cast<typename boost::graph_traits<TargetMesh>::faces_size_type>(faces(sm).size()) );
//insert halfedges and create each vertex when encountering its halfedge //insert halfedges and create each vertex when encountering its halfedge
for(sm_edge_descriptor sm_e : edges(sm)) for(sm_edge_descriptor sm_e : edges(sm))
{ {

View File

@ -221,16 +221,17 @@ public:
Orientation_2 orientation_2_object ()const{return Orientation_2(vpm_,static_cast<const Btt*>(this)->orientation_2_object() );} Orientation_2 orientation_2_object ()const{return Orientation_2(vpm_,static_cast<const Btt*>(this)->orientation_2_object() );}
}; };
typedef Proj_traits_3<typename Base_traits::Traits_xy_3> Traits_xy_3; typedef internal::Convex_hull_3::Projection_traits<Base_traits> Base_PTraits;
typedef Proj_traits_3<typename Base_traits::Traits_yz_3> Traits_yz_3; typedef Proj_traits_3<typename Base_PTraits::Traits_xy_3> Traits_xy_3;
typedef Proj_traits_3<typename Base_traits::Traits_xz_3> Traits_xz_3; typedef Proj_traits_3<typename Base_PTraits::Traits_yz_3> Traits_yz_3;
typedef Proj_traits_3<typename Base_PTraits::Traits_xz_3> Traits_xz_3;
Traits_xy_3 construct_traits_xy_3_object()const Traits_xy_3 construct_traits_xy_3_object()const
{return Traits_xy_3(vpm_, static_cast<const Base_traits*>(this)->construct_traits_xy_3_object());} {return Traits_xy_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xy_3_object());}
Traits_yz_3 construct_traits_yz_3_object()const Traits_yz_3 construct_traits_yz_3_object()const
{return Traits_yz_3(vpm_, static_cast<const Base_traits*>(this)->construct_traits_yz_3_object());} {return Traits_yz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_yz_3_object());}
Traits_xz_3 construct_traits_xz_3_object()const Traits_xz_3 construct_traits_xz_3_object()const
{return Traits_xz_3(vpm_, static_cast<const Base_traits*>(this)->construct_traits_xz_3_object());} {return Traits_xz_3(vpm_, Base_PTraits(static_cast<const Base_traits&>(*this)).construct_traits_xz_3_object());}
typename boost::property_traits<PointPropertyMap>::reference typename boost::property_traits<PointPropertyMap>::reference
get_point(const typename boost::property_traits<PointPropertyMap>::key_type& k) const get_point(const typename boost::property_traits<PointPropertyMap>::key_type& k) const

View File

@ -470,7 +470,16 @@ struct HDS_property_map<vertex_point_t>
typename T::Point_3, const typename T::Point_3&> const_type; typename T::Point_3, const typename T::Point_3&> const_type;
}; };
}; };
template<class T, class I, class A>
void reserve(HalfedgeDS_default<T,I,A>& p,
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::vertices_size_type nv,
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::edges_size_type ne,
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::faces_size_type nf)
{
p.reserve(nv, 2*ne, nf);
}
}// namespace CGAL }// namespace CGAL
namespace boost { namespace boost {

View File

@ -31,6 +31,7 @@
#include <CGAL/array.h> #include <CGAL/array.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <boost/container/flat_set.hpp> #include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include <set> #include <set>
#include <map> #include <map>
@ -59,9 +60,11 @@ struct Polygon_soup_orienter
/// Container types /// Container types
typedef PointRange Points; typedef PointRange Points;
typedef PolygonRange Polygons; 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 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 /// Data members
Points& points; //< the set of input points Points& points; //< the set of input points
@ -107,8 +110,8 @@ struct Polygon_soup_orienter
{ {
typedef std::pair<V_ID,P_ID> VID_and_PID; typedef std::pair<V_ID,P_ID> VID_and_PID;
if ( is_edge_marked(src,tgt,marked_edges) ) return VID_and_PID(src,300612); 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)); Edge_map_iterator em_it=edges[tgt].find(src);
if ( em_it==edges.end() ) return VID_and_PID(src,300612);// the vertex is on the border 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); CGAL_assertion(em_it->second.size()==1);
P_ID p_id = *(em_it->second.begin()); P_ID p_id = *(em_it->second.begin());
return VID_and_PID(get_neighbor_vertices(src, p_id, polygons)[2], p_id); 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<V_ID,P_ID> VID_and_PID; typedef std::pair<V_ID,P_ID> VID_and_PID;
if ( is_edge_marked(src,tgt,marked_edges) ) return VID_and_PID(tgt,300612); 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)); Edge_map_iterator em_it=edges[tgt].find(src);
if ( em_it==edges.end() ) return VID_and_PID(tgt,300612);// the vertex is on the border 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); CGAL_assertion(em_it->second.size()==1);
P_ID p_id = *(em_it->second.begin()); P_ID p_id = *(em_it->second.begin());
return VID_and_PID(get_neighbor_vertices(tgt, p_id, polygons)[0], p_id); 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) Polygon_soup_orienter(Points& points, Polygons& polygons)
: points(points), polygons(polygons) : points(points), polygons(polygons), edges(points.size())
{} {}
//filling containers //filling containers
static void fill_edge_map(Edge_map& edges, Marked_edges& marked_edges, const Polygons& polygons) { static void fill_edge_map(Edge_map& edges, Marked_edges& marked_edges, const Polygons& polygons) {
// Fill edges // Fill edges
edges.clear();
for (P_ID i = 0; i < polygons.size(); ++i) for (P_ID i = 0; i < polygons.size(); ++i)
{ {
const P_ID size = polygons[i].size(); const P_ID size = polygons[i].size();
for (P_ID j = 0; j < size; ++j) { for (P_ID j = 0; j < size; ++j) {
V_ID i0 = polygons[i][j]; V_ID i0 = polygons[i][j];
V_ID i1 = polygons[i][(j + 1) % size]; 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]; V_ID i1 = polygons[i][(j + 1) % size];
std::size_t nb_edges = 0; std::size_t nb_edges = 0;
Edge_map_iterator em_it = edges.find(V_ID_pair(i0, i1)); Edge_map_iterator em_it = edges[i0].find(i1);
if (em_it != edges.end()) nb_edges += em_it->second.size(); if (em_it != edges[i0].end()) nb_edges += em_it->second.size();
em_it = edges.find(V_ID_pair(i1, i0)); em_it = edges[i1].find(i0);
if (em_it != edges.end()) nb_edges += em_it->second.size(); if (em_it != edges[i1].end()) nb_edges += em_it->second.size();
if (nb_edges > 2) set_edge_marked(i0, i1, marked_edges); 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; if( is_edge_marked(i1,i2,marked_edges) ) continue;
// edge (i1,i2) // 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) // 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_same_orient != edges[i1].end());
CGAL_assertion(it_other_orient == edges.end() || CGAL_assertion(it_other_orient == edges[i2].end() ||
it_other_orient->second.size()==1); it_other_orient->second.size()==1);
if (it_same_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 // one neighbor but with the same orientation
P_ID index = *(it_same_orient->second.begin()); P_ID index = *(it_same_orient->second.begin());
if(index == to_be_oriented_index) if(index == to_be_oriented_index)
@ -275,25 +277,25 @@ struct Polygon_soup_orienter
for(P_ID j = 0; j < size; ++j) { for(P_ID j = 0; j < size; ++j) {
V_ID i0 = polygons[index][j]; V_ID i0 = polygons[index][j];
V_ID i1 = polygons[index][(j+1)%size]; 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 = ) CGAL_assertion_code(const bool r = )
em_it->second.erase(index) em_it->second.erase(index)
CGAL_assertion_code(!= 0); CGAL_assertion_code(!= 0);
CGAL_assertion(r); 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); inverse_orientation(index);
for(P_ID j = 0; j < size; ++j) { for(P_ID j = 0; j < size; ++j) {
V_ID i0 = polygons[index][j]; V_ID i0 = polygons[index][j];
V_ID i1 = polygons[index][(j+1)%size]; 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 // "inverse the orientation of polygon #index
oriented[index] = true; oriented[index] = true;
stack.push(index); stack.push(index);
} }
else{ 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_same_orient->second.size() == 1);
CGAL_assertion(it_other_orient->second.size() == 1); CGAL_assertion(it_other_orient->second.size() == 1);
// one polygon, same orientation // one polygon, same orientation
@ -376,6 +378,7 @@ struct Polygon_soup_orienter
/// now duplicate the vertices /// now duplicate the vertices
typedef std::pair<V_ID, std::vector<P_ID> > V_ID_and_Polygon_ids; typedef std::pair<V_ID, std::vector<P_ID> > 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) for(const V_ID_and_Polygon_ids& vid_and_pids : vertices_to_duplicate)
{ {
V_ID new_index = static_cast<V_ID>(points.size()); V_ID new_index = static_cast<V_ID>(points.size());

View File

@ -74,6 +74,10 @@ public:
void operator()(PM& pmesh, const bool insert_isolated_vertices = true) void operator()(PM& pmesh, const bool insert_isolated_vertices = true)
{ {
reserve(pmesh, static_cast<typename boost::graph_traits<PM>::vertices_size_type>(_points.size()),
static_cast<typename boost::graph_traits<PM>::edges_size_type>(2*_polygons.size()),
static_cast<typename boost::graph_traits<PM>::faces_size_type>(_polygons.size()) );
Vpmap vpmap = get(CGAL::vertex_point, pmesh); Vpmap vpmap = get(CGAL::vertex_point, pmesh);
boost::dynamic_bitset<> not_isolated; boost::dynamic_bitset<> not_isolated;
@ -182,7 +186,7 @@ public:
//check manifoldness //check manifoldness
typedef std::vector<V_ID> PointRange; typedef std::vector<V_ID> PointRange;
typedef internal::Polygon_soup_orienter<PointRange, PolygonRange> Orienter; 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; typename Orienter::Marked_edges marked_edges;
Orienter::fill_edge_map(edges, marked_edges, polygons); Orienter::fill_edge_map(edges, marked_edges, polygons);
//returns false if duplication is necessary //returns false if duplication is necessary

View File

@ -309,10 +309,10 @@ void Polyhedron_demo_orient_soup_plugin::getNMPoints(
Scene_polygon_soup_item* item) Scene_polygon_soup_item* item)
{ {
typedef std::pair<std::size_t, std::size_t> V_ID_pair; 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, typedef CGAL::Polygon_mesh_processing::internal::Polygon_soup_orienter<Polygon_soup::Points,
Polygon_soup::Polygons> PSO; Polygon_soup::Polygons> PSO;
typedef PSO::Edge_map Edge_map;
typedef std::set<V_ID_pair> Marked_edges;
Edge_map edges; Edge_map edges;
Marked_edges m_edges; Marked_edges m_edges;

View File

@ -286,7 +286,7 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
Mesh& mesh = output[i]; 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(points, polygons);
converter(mesh, false/*insert_isolated_vertices*/); converter(mesh, false/*insert_isolated_vertices*/);

View File

@ -562,12 +562,18 @@ int zoomToId(const Mesh& mesh,
bool found = false; bool found = false;
for(vertex_descriptor vh : vertices(mesh)) 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, p = Point(get(ppmap, vh).x() + offset.x,
get(ppmap, vh).y() + offset.y, get(ppmap, vh).y() + offset.y,
get(ppmap, vh).z() + offset.z); get(ppmap, vh).z() + offset.z);
selected_fh = face(halfedge(vh, mesh), mesh); typename boost::graph_traits<Mesh>::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); normal = CGAL::Polygon_mesh_processing::compute_vertex_normal(vh, mesh);
found = true; found = true;
break; break;
@ -585,17 +591,27 @@ int zoomToId(const Mesh& mesh,
{ {
if(get(eidmap, halfedge(e, mesh))/2 == id) if(get(eidmap, halfedge(e, mesh))/2 == id)
{ {
typename boost::graph_traits<Mesh>::halfedge_descriptor hf = halfedge(e, mesh);
const Point& p1 = get(ppmap, source(e, mesh)); const Point& p1 = get(ppmap, source(e, mesh));
const Point& p2 = get(ppmap, target(e, mesh)); const Point& p2 = get(ppmap, target(e, mesh));
p = Point((float)(p1.x() + p2.x()) / 2 + offset.x, p = Point((float)(p1.x() + p2.x()) / 2 + offset.x,
(float)(p1.y() + p2.y()) / 2 + offset.y, (float)(p1.y() + p2.y()) / 2 + offset.y,
(float)(p1.z() + p2.z()) / 2 + offset.z ); (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), typename Traits::Vector_3 normal1(0,0,0);
mesh); if(!is_border(hf, mesh))
typename Traits::Vector_3 normal2 = CGAL::Polygon_mesh_processing::compute_face_normal(face(opposite(halfedge(e, mesh), mesh), mesh), {
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; normal = 0.5*normal1+0.5*normal2;
selected_fh = face(halfedge(e, mesh), mesh);
found = true; found = true;
break; break;
} }

View File

@ -271,7 +271,7 @@ public:
return Constraint_id(NULL); return Constraint_id(NULL);
} }
// protects against inserting twice the same constraint // 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); if (va != vb && (cid != Constraint_id(NULL)) ) insert_subconstraint(va,vb);
return cid; return cid;

View File

@ -247,6 +247,7 @@ public:
// insert/remove // insert/remove
void add_Steiner(T va, T vb, T vx); 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); Vertex_list* insert_constraint(T va, T vb);
void append_constraint(Constraint_id cid, T va, T vb); void append_constraint(Constraint_id cid, T va, T vb);
void swap(Constraint_id first, Constraint_id second); void swap(Constraint_id first, Constraint_id second);
@ -868,6 +869,34 @@ typename Polyline_constraint_hierarchy_2<T,Compare,Data>::Vertex_list*
Polyline_constraint_hierarchy_2<T,Compare,Data>:: Polyline_constraint_hierarchy_2<T,Compare,Data>::
insert_constraint(T va, T vb){ insert_constraint(T va, T vb){
Edge he = make_edge(va, 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 <class T, class Compare, class Data>
typename Polyline_constraint_hierarchy_2<T,Compare,Data>::Vertex_list*
Polyline_constraint_hierarchy_2<T,Compare,Data>::
insert_constraint_old_API(T va, T vb){
Edge he = make_edge(va, vb);
// First, check if the constraint was already inserted. // First, check if the constraint was already inserted.
// If it was not, then the iterator to the lower bound will serve as // If it was not, then the iterator to the lower bound will serve as

View File

@ -0,0 +1,34 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_2<K> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag> Triangulation;
typedef CGAL::Constrained_triangulation_plus_2<Triangulation> 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<Point_2> 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;
}