diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Simple_parameterization.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Simple_parameterization.cpp index 61cb448f431..81a1e6c1539 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Simple_parameterization.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Simple_parameterization.cpp @@ -1,10 +1,12 @@ #include #include #include -#include +#include #include +#include + #include #include @@ -19,7 +21,11 @@ typedef boost::graph_traits::face_descriptor face_descriptor; int main(int argc, char * argv[]) { - std::ifstream in((argc>1)?argv[1]:"data/nefertiti.off"); + std::ifstream in((argc>1)?argv[1]:"../data/mushroom_big_hole.off"); + if(!in){ + std::cerr << "Problem loading the input data" << std::endl; + return 1; + } Mesh sm; in >> sm; @@ -27,20 +33,12 @@ int main(int argc, char * argv[]) halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(sm).first; CGAL::Unique_hash_map uvhm; - boost::associative_property_map > uvpm(uvhm); + boost::associative_property_map > uvmap(uvhm); - CGAL::parameterize(sm, hd, uvpm); + CGAL::parameterize(sm, hd, uvmap); - // Write the result in the polyline format that can be loaded in the Polyhedron demo + std::ofstream out("result.off"); + CGAL::Parameterization::output_uvmap_to_off(sm, hd, uvmap, out); - BOOST_FOREACH(face_descriptor fd, faces(sm)){ - halfedge_descriptor hd = halfedge(fd,sm); - std::cout << "4 " << uvhm[target(hd,sm)] << " 0 "; - hd = next(hd,sm); - BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd,sm)){ - std::cout << uvhm[vd] << " 0 "; - } - std::cout << std::endl; - } return 0; } diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/lscm.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/lscm.cpp index f33069a9025..d97199c2ee4 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/lscm.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/lscm.cpp @@ -1,7 +1,9 @@ #include + #include #include +#include #include #include #include @@ -21,9 +23,9 @@ typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; -typedef SurfaceMesh::Property_map UV_pmap; -typedef SurfaceMesh::Property_map Seam_edge_pmap; -typedef SurfaceMesh::Property_map Seam_vertex_pmap; +typedef SurfaceMesh::Property_map UV_pmap; +typedef SurfaceMesh::Property_map Seam_edge_pmap; +typedef SurfaceMesh::Property_map Seam_vertex_pmap; typedef CGAL::Seam_mesh Mesh; @@ -31,35 +33,16 @@ typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::face_descriptor face_descriptor; -/// A helper class that writes a face as a polyline in the xy-plane -struct Face2Polyline -{ - const Mesh& mesh; - const UV_pmap uvpm; - - Face2Polyline(const Mesh& mesh, const UV_pmap& uvpm) - : mesh(mesh), uvpm(uvpm) - { } - - void operator()(face_descriptor fd) const - { - halfedge_descriptor hd = halfedge(fd,mesh); - - std::cout << "4 " << uvpm[target(hd,mesh)].x() << " " << uvpm[target(hd,mesh)].y() << " 0 "; - - hd = next(hd,mesh); - BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd,mesh)){ - std::cout << uvpm[vd].x() << " " << uvpm[vd].y() << " 0 "; - } - std::cout << std::endl; - } -}; - int main(int argc, char * argv[]) { SurfaceMesh sm; - std::ifstream in_mesh((argc>1)?argv[1]:"data/lion.off"); + std::ifstream in_mesh((argc>1) ? argv[1] : "data/lion.off"); + if(!in_mesh){ + std::cerr << "Error: problem loading the input data" << std::endl; + return 1; + } + in_mesh >> sm; // Two property maps to store the seam edges and vertices @@ -68,6 +51,7 @@ int main(int argc, char * argv[]) const char* filename = (argc>2) ? argv[2] : "data/lion.selection.txt"; + // Read the constraints on the border std::ifstream in(filename); std::string vertices; std::getline(in, vertices); @@ -90,14 +74,14 @@ int main(int argc, char * argv[]) halfedge_descriptor bhd(smhd); bhd = opposite(bhd, mesh); // a halfedge on the virtual border - typedef CGAL::Two_vertices_parameterizer_3 Border_parameterizer; - typedef CGAL::LSCM_parameterizer_3 Parameterizer; + typedef CGAL::Two_vertices_parameterizer_3 Border_parameterizer; + typedef CGAL::LSCM_parameterizer_3 Parameterizer; if(two_vertices_given){ - SM_halfedge_descriptor smhp1 = halfedge(SM_vertex_descriptor(p1),sm); + SM_halfedge_descriptor smhp1 = halfedge(SM_vertex_descriptor(p1), sm); vertex_descriptor vp1 = target(halfedge_descriptor(smhp1), mesh); - SM_halfedge_descriptor smhp2 = halfedge(SM_vertex_descriptor(p2),sm); + SM_halfedge_descriptor smhp2 = halfedge(SM_vertex_descriptor(p2), sm); vertex_descriptor vp2 = target(halfedge_descriptor(smhp2), mesh); CGAL::parameterize(mesh, Parameterizer(Border_parameterizer(vp1, vp2)), bhd, uv_pm); @@ -105,14 +89,7 @@ int main(int argc, char * argv[]) CGAL::parameterize(mesh, Parameterizer(), bhd, uv_pm); } - std::ofstream out("/home/mrouxell/asd.polylines.txt"); - Face2Polyline f2p(mesh, uv_pm, out); - - // As the seam may define a patch we write - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator(f2p)); + CGAL::Parameterization::output_uvmap_to_off(mesh, bhd, uv_pm, std::cout); return 0; } diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp index 336b4038c33..635332f5f2e 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp @@ -139,6 +139,8 @@ int main(int argc, char * argv[]) #ifdef MVC_POLY_MESH { + std::cout << "MVC POLY MESH" << std::endl; + PMesh pm; in >> pm; @@ -162,10 +164,15 @@ int main(int argc, char * argv[]) #ifdef BARY_POLY_MESH { + std::cout << "BARY POLY MESH" << std::endl; + PMesh pm; + in.clear(); + in.seekg(0, std::ios::beg); in >> pm; PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first; + assert(hd != PM_halfedge_descriptor()); // UV map CGAL::Unique_hash_map Indices; Indices indices; - CGAL::Polygon_mesh_processing::connected_component(face(opposite(hd, pm), pm), - pm, + CGAL::Polygon_mesh_processing::connected_component( + face(opposite(hd, pm), pm), + pm, boost::make_function_output_iterator( - CGAL::Parameterization::Vertices(pm, indices))); + CGAL::internal::Parameterization::Index_map_filler(pm, indices))); // Vertex parameterized map boost::unordered_set vs; @@ -198,7 +207,11 @@ int main(int argc, char * argv[]) #ifdef ARAP_POLY_MESH { + std::cout << "ARAP POLY MESH" << std::endl; + PMesh pm; + in.clear(); + in.seekg(0, std::ios::beg); in >> pm; PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first; @@ -217,8 +230,9 @@ int main(int argc, char * argv[]) face(opposite(hd, pm), pm), pm, boost::make_function_output_iterator( - CGAL::Parameterization::Vertices(pm, indices))); + CGAL::internal::Parameterization::Index_map_filler(pm, indices))); + boost::associative_property_map vipm(indices); // Vertex parameterized map @@ -247,6 +261,8 @@ int main(int argc, char * argv[]) #ifdef ARAP_SURF_MESH { + std::cout << "ARAP SURF MESH" << std::endl; + SMesh sm; in.clear(); in.seekg(0, std::ios::beg); @@ -263,14 +279,15 @@ int main(int argc, char * argv[]) boost::hash > > uv_pm(uvhm); // Indices map - typedef boost::unordered_map Vertex_index_map; - Vertex_index_map indices; + typedef boost::unordered_map Indices; + Indices indices; CGAL::Polygon_mesh_processing::connected_component( face(opposite(bhd, sm), sm), sm, boost::make_function_output_iterator( - CGAL::Parameterization::Vertices(sm, indices))); - boost::associative_property_map vipm(indices); + CGAL::internal::Parameterization::Index_map_filler(sm, indices))); + boost::associative_property_map vipm(indices); boost::unordered_set vs; CGAL::internal::Bool_property_map< boost::unordered_set > vpm(vs); @@ -286,6 +303,8 @@ int main(int argc, char * argv[]) #ifdef ARAP_SM_SEAM_MESH { + std::cout << "ARAP SURF SEAM MESH" << std::endl; + SMesh sm; in.clear(); in.seekg(0, std::ios::beg); @@ -294,7 +313,7 @@ int main(int argc, char * argv[]) SM_seam_edge_pmap seam_edge_pm = sm.add_property_map("e:on_seam", false).first; SM_seam_vertex_pmap seam_vertex_pm = - sm.add_property_map("v:on_seam",false).first; + sm.add_property_map("v:on_seam", false).first; SM_Seam_mesh mesh(sm, seam_edge_pm, seam_vertex_pm); SM_halfedge_descriptor smhd = mesh.add_seams("../data/lion.selection.txt"); @@ -312,10 +331,11 @@ int main(int argc, char * argv[]) typedef boost::unordered_map Indices; Indices indices; CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - CGAL::Parameterization::Vertices(mesh, indices))); + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator( + CGAL::internal::Parameterization::Index_map_filler(mesh, indices))); boost::associative_property_map vipm(indices); // Parameterized @@ -334,6 +354,8 @@ int main(int argc, char * argv[]) #ifdef ARAP_PM_SEAM_MESH { + std::cout << "ARAP POLY SEAM MESH" << std::endl; + PMesh pm; in.clear(); in.seekg(0, std::ios::beg); @@ -360,10 +382,11 @@ int main(int argc, char * argv[]) typedef boost::unordered_map Indices; Indices indices; CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - CGAL::Parameterization::Vertices(mesh, indices))); + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator( + CGAL::internal::Parameterization::Index_map_filler(mesh, indices))); boost::associative_property_map vipm(indices); // Parameterized diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp index dd69c1ca901..16c970b5d27 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp @@ -1,24 +1,28 @@ #include + #include +#include #include +#include + +#include #include -#include #include #include -typedef CGAL::Simple_cartesian Kernel; -typedef Kernel::Point_2 Point_2; -typedef Kernel::Point_3 Point_3; -typedef CGAL::Surface_mesh SurfaceMesh; +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_2 Point_2; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh SurfaceMesh; typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; -typedef SurfaceMesh::Property_map UV_pmap; -typedef SurfaceMesh::Property_map Seam_edge_pmap; -typedef SurfaceMesh::Property_map Seam_vertex_pmap; +typedef SurfaceMesh::Property_map UV_pmap; +typedef SurfaceMesh::Property_map Seam_edge_pmap; +typedef SurfaceMesh::Property_map Seam_vertex_pmap; typedef CGAL::Seam_mesh Mesh; @@ -26,61 +30,30 @@ typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::face_descriptor face_descriptor; -/// A helper class that writes a face as a polyline in the xy-plane -struct Face2Polyline -{ - const Mesh& mesh; - const UV_pmap uvpm; - - Face2Polyline(const Mesh& mesh, const UV_pmap& uvpm) - : mesh(mesh), uvpm(uvpm) - { } - - void operator()(face_descriptor fd) const - { - halfedge_descriptor hd = halfedge(fd,mesh); - - std::cout << "4 " << uvpm[target(hd,mesh)].x() << " " - << uvpm[target(hd,mesh)].y() << " 0 "; - - hd = next(hd,mesh); - BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd,mesh)){ - std::cout << uvpm[vd].x() << " " << uvpm[vd].y() << " 0 "; - } - std::cout << std::endl; - } -}; - int main(int argc, char * argv[]) { SurfaceMesh sm; - std::vector seam; std::ifstream in_mesh((argc>1)?argv[1]:"data/lion.off"); + if(!in_mesh){ + std::cerr << "Error: problem loading the input data" << std::endl; + return 1; + } + in_mesh >> sm; // Two property maps to store the seam edges and vertices - Seam_edge_pmap seam_edge_pm = sm.add_property_map("e:on_seam", false).first; - Seam_vertex_pmap seam_vertex_pm = sm.add_property_map("v:on_seam",false).first; - - std::ifstream in((argc>2)?argv[2]:"data/lion.selection.txt"); - int s, t; - SM_halfedge_descriptor smhd; - while(in >> s >> t){ - SM_vertex_descriptor svd(s), tvd(t); - SM_edge_descriptor ed = edge(svd, tvd,sm).first; - if(! is_border(ed,sm)){ - put(seam_edge_pm, ed, true); - put(seam_vertex_pm, svd, true); - put(seam_vertex_pm, tvd, true); - if(smhd == boost::graph_traits::null_halfedge()){ - smhd = halfedge(edge(svd,tvd,sm).first,sm); - } - } - } + Seam_edge_pmap seam_edge_pm = + sm.add_property_map("e:on_seam", false).first; + Seam_vertex_pmap seam_vertex_pm = + sm.add_property_map("v:on_seam",false).first; Mesh mesh(sm, seam_edge_pm, seam_vertex_pm); + const char* filename = (argc>2) ? argv[2] : "/data/lion.selection.txt"; + SM_halfedge_descriptor smhd = mesh.add_seams(filename); + assert(smhd != SM_halfedge_descriptor()); + // The 2D points of the uv parametrisation will be written into this map // Note that this is a halfedge property map, and that the uv // is only stored for the canonical halfedges representing a vertex @@ -91,12 +64,7 @@ int main(int argc, char * argv[]) CGAL::parameterize(mesh, bhd, uv_pm); - Face2Polyline f2p(mesh,uv_pm); - // As the seam may define a patch we write - - CGAL::Polygon_mesh_processing::connected_component(face(opposite(bhd,mesh),mesh), - mesh, - boost::make_function_output_iterator(f2p)); + CGAL::Parameterization::output_uvmap_to_off(mesh, bhd, uv_pm, std::cout); return 0; } diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam_Polyhedron_3.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam_Polyhedron_3.cpp index 5d7b72b299e..95747752183 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam_Polyhedron_3.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam_Polyhedron_3.cpp @@ -1,76 +1,53 @@ #include + #include #include #include +#include + +#include #include + #include -#include -#include + #include #include - typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_2 Point_2; typedef Kernel::Point_3 Point_3; -typedef CGAL::Polyhedron_3 SurfaceMesh; +typedef CGAL::Polyhedron_3 PolyMesh; -typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; -typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; -typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; +typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; +typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; +typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; -typedef CGAL::Unique_hash_map UV_uhm; -typedef CGAL::Unique_hash_map Seam_edge_uhm; -typedef CGAL::Unique_hash_map Seam_vertex_uhm; +typedef CGAL::Unique_hash_map UV_uhm; +typedef CGAL::Unique_hash_map Seam_edge_uhm; +typedef CGAL::Unique_hash_map Seam_vertex_uhm; typedef boost::associative_property_map UV_pmap; typedef boost::associative_property_map Seam_edge_pmap; typedef boost::associative_property_map Seam_vertex_pmap; -typedef CGAL::Seam_mesh Mesh; +typedef CGAL::Seam_mesh Mesh; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::face_descriptor face_descriptor; -/// A helper class that writes a face as a polyline in the xy-plane -struct Face2Polyline -{ - const Mesh& mesh; - const UV_pmap uvpm; - - Face2Polyline(const Mesh& mesh, const UV_pmap& uvpm) - : mesh(mesh), uvpm(uvpm) - { } - - void operator()(face_descriptor fd) const - { - halfedge_descriptor hd = halfedge(fd,mesh); - - std::cout << "4 " << uvpm[target(hd,mesh)].x() - << " " << uvpm[target(hd,mesh)].y() << " 0 "; - - hd = next(hd,mesh); - BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd,mesh)){ - std::cout << uvpm[vd].x() << " " << uvpm[vd].y() << " 0 "; - } - - std::cout << std::endl; - } -}; - int main(int argc, char * argv[]) { - SurfaceMesh sm; + PolyMesh sm; std::ifstream in_mesh((argc>1)?argv[1]:"data/lion.off"); - in_mesh >> sm; - - std::vector id2v; - BOOST_FOREACH(SM_vertex_descriptor vd, vertices(sm)){ - id2v.push_back(vd); + if(!in_mesh){ + std::cerr << "Error: problem loading the input data" << std::endl; + return 1; } + in_mesh >> sm; + // Two property maps to store the seam edges and vertices Seam_edge_uhm seam_edge_uhm(false); Seam_edge_pmap seam_edge_pm(seam_edge_uhm); @@ -78,28 +55,15 @@ int main(int argc, char * argv[]) Seam_vertex_uhm seam_vertex_uhm(false); Seam_vertex_pmap seam_vertex_pm(seam_vertex_uhm); - std::ifstream in((argc>2)?argv[2]:"data/lion.selection.txt"); - int s, t; - SM_halfedge_descriptor smhd; - while(in >> s >> t){ - SM_vertex_descriptor svd = id2v[s], tvd = id2v[t]; - SM_edge_descriptor ed = edge(svd, tvd,sm).first; - if(!is_border(ed,sm)){ - put(seam_edge_pm, ed, true); - put(seam_vertex_pm, svd, true); - put(seam_vertex_pm, tvd, true); - if(smhd == boost::graph_traits::null_halfedge()){ - smhd = halfedge(edge(svd,tvd,sm).first,sm); - } - } - } - Mesh mesh(sm, seam_edge_pm, seam_vertex_pm); + const char* filename = (argc>2) ? argv[2] : "data/lion.selection.txt"; + SM_halfedge_descriptor smhd = mesh.add_seams(filename); + assert(smhd != SM_halfedge_descriptor()); + // The 2D points of the uv parametrisation will be written into this map // Note that this is a halfedge property map, and that the uv // is only stored for the canonical halfedges representing a vertex - UV_uhm uv_uhm; UV_pmap uv_pm(uv_uhm); @@ -108,12 +72,7 @@ int main(int argc, char * argv[]) CGAL::parameterize(mesh, bhd, uv_pm); - Face2Polyline f2p(mesh,uv_pm); - // The seam may define a patch, that is we take the connected component of the border halfedge - - CGAL::Polygon_mesh_processing::connected_component(face(opposite(bhd,mesh),mesh), - mesh, - boost::make_function_output_iterator(f2p)); + CGAL::Parameterization::output_uvmap_to_off(mesh, bhd, uv_pm, std::cout); return 0; } diff --git a/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h index fd8e6dedcc6..ce84453d253 100644 --- a/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/ARAP_parameterizer_3.h @@ -63,10 +63,8 @@ // (this produces C2=0 which is problematic to compute a & b) // @todo Add to the polyhedron demo // @todo Add distortion measures -// @todo remove the requirements on the vimap from all parameterizers // @todo is_one_to_one mapping functions in all parameterizers -// @todo Use a boost array for the roots? // @todo The two systems A Xu = Bu and A Xv = BV could be merged in one system // using complex numbers? // @todo Parallelize the local phase? @@ -237,8 +235,8 @@ private: const VertexIndexMap vimap) const { std::ofstream out(filename.c_str()); - CGAL::Surface_mesh_parameterization::output_uvmap_to_off(mesh, vertices, faces, - uvmap, vimap, out); + CGAL::Parameterization::output_uvmap_to_off(mesh, vertices, faces, + uvmap, vimap, out); } /// Print the parameterized mesh. @@ -255,8 +253,8 @@ private: std::ostringstream out_ss; out_ss << filename << iter << ".off" << std::ends; std::ofstream out(out_ss.str().c_str()); - CGAL::Surface_mesh_parameterization::output_uvmap_to_off(mesh, vertices, faces, - uvmap, vimap, out); + CGAL::Parameterization::output_uvmap_to_off(mesh, vertices, faces, + uvmap, vimap, out); } /// Copy the data from two vectors to the UVmap. @@ -284,8 +282,8 @@ private: Vertex_set& vertices, Faces_vector& faces) const { - CGAL::internal::Surface_mesh_parameterization::Containers_filler - fc(mesh, faces, vertices); + CGAL::internal::Parameterization::Containers_filler + fc(mesh, vertices, &faces); CGAL::Polygon_mesh_processing::connected_component( face(opposite(bhd, mesh), mesh), mesh, @@ -1366,7 +1364,7 @@ public: output_uvmap("ARAP_final_pre_processing.off", mesh, vertices, faces, uvmap, vimap); - if(!internal::Surface_mesh_parameterization::is_one_to_one_mapping(mesh, uvmap)){ + if(!internal::Parameterization::is_one_to_one_mapping(mesh, uvmap)){ // Use post processing to handle flipped elements std::cout << "Parameterization is not valid; calling post processor" << std::endl; status = post_process(mesh, vertices, faces, bhd, uvmap, vimap); diff --git a/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h index d9b55df32ad..f67753615c3 100644 --- a/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h @@ -24,17 +24,20 @@ #include -#include -#include +#include #include #include + +#include +#include +#include + #include -#include +#include #include -#include -#include +#include /// \file Fixed_border_parameterizer_3.h @@ -287,29 +290,6 @@ private: Sparse_LA m_linearAlgebra; }; -namespace Parameterization { - -template -struct Vertices_set { - - Vertices_set(const Mesh& mesh, Set& set) - : mesh(mesh), set(&set) - {} - - void operator()(const typename boost::graph_traits::face_descriptor& fd) - { - BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vd, vertices_around_face(halfedge(fd,mesh),mesh)){ - set->insert(vd); - } - } - - const Mesh& mesh; - mutable Set* set; -}; - -} // namespace Parameterization - - // ------------------------------------------------------------------------------------ // Implementation // ------------------------------------------------------------------------------------ @@ -351,11 +331,12 @@ parameterize(TriangleMesh& mesh, typedef boost::unordered_set Vertex_set; Vertex_set vertices; + + CGAL::internal::Parameterization::Containers_filler fc(mesh, vertices); CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - Parameterization::Vertices_set(mesh, vertices))); + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator(fc)); // Count vertices int nbVertices = static_cast(num_vertices(mesh)); diff --git a/Surface_mesh_parameterization/include/CGAL/IO/Surface_mesh_parameterization/File_off.h b/Surface_mesh_parameterization/include/CGAL/IO/Surface_mesh_parameterization/File_off.h index 0f520ed65b4..85fe4f27388 100644 --- a/Surface_mesh_parameterization/include/CGAL/IO/Surface_mesh_parameterization/File_off.h +++ b/Surface_mesh_parameterization/include/CGAL/IO/Surface_mesh_parameterization/File_off.h @@ -18,11 +18,18 @@ // // Author(s) : +#include + #include +#include + +#include #include +#include #include -#include +#include +#include #include #include @@ -34,7 +41,7 @@ namespace CGAL { -namespace Surface_mesh_parameterization { +namespace Parameterization { template void output_uvmap_to_off(const TriangleMesh& mesh, + HD bhd, const VertexUVMap uvmap, std::ostream& os) { @@ -96,15 +105,24 @@ void output_uvmap_to_off(const TriangleMesh& mesh, Vertex_index_map vium; boost::associative_property_map vimap(vium); + boost::unordered_set vertices; + std::vector faces; + + CGAL::internal::Parameterization::Containers_filler fc(mesh, vertices, &faces); + CGAL::Polygon_mesh_processing::connected_component( + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator(fc)); + std::ostringstream out_vertices, out_faces; std::size_t vertices_counter = 0, faces_counter = 0; - BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ + BOOST_FOREACH(vertex_descriptor vd, vertices){ put(vimap, vd, vertices_counter++); out_vertices << get(uvmap, vd) << " 0" << '\n'; } - BOOST_FOREACH(face_descriptor fd, faces(mesh)){ + BOOST_FOREACH(face_descriptor fd, faces){ halfedge_descriptor hd = halfedge(fd, mesh); out_faces << "3"; @@ -121,7 +139,7 @@ void output_uvmap_to_off(const TriangleMesh& mesh, os << out_vertices.str() << out_faces.str(); } -} // namespace Surface_mesh_parameterization +} // namespace Parameterization } // namespace CGAL diff --git a/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h index 37e9b45b68d..362dc795370 100644 --- a/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/LSCM_parameterizer_3.h @@ -180,9 +180,6 @@ public: // Count vertices int nbVertices = num_vertices(mesh); - // Index vertices from 0 to nbVertices-1 - // TODO mesh.index_mesh_vertices(); - // Compute (u,v) for (at least two) border vertices // and mark them as "parameterized" Error_code status = get_border_parameterizer().parameterize_border(mesh,bhd,uvmap,vpmap); @@ -201,14 +198,17 @@ public: // Fill the matrix for the other vertices solver.begin_system(); - std::vector ccfaces; + boost::unordered_set ccvertices; - CGAL::internal::Surface_mesh_parameterization::Containers_filler - fc(mesh, ccfaces, ccvertices); + std::vector ccfaces; + + CGAL::internal::Parameterization::Containers_filler + fc(mesh, ccvertices, &ccfaces); CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd,mesh), mesh), + face(opposite(bhd, mesh), mesh), mesh, boost::make_function_output_iterator(fc)); + BOOST_FOREACH(face_descriptor fd, ccfaces){ // Create two lines in the linear system per triangle (one for u, one for v) status = setup_triangle_relations(solver, mesh, fd, vimap); diff --git a/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h b/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h index f4fd38713e6..74b47e4941f 100644 --- a/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h +++ b/Surface_mesh_parameterization/include/CGAL/MVC_post_processor_3.h @@ -190,8 +190,8 @@ private: Vertex_set& vertices, Faces_vector& faces) const { - CGAL::internal::Surface_mesh_parameterization::Containers_filler - fc(mesh, faces, vertices); + internal::Parameterization::Containers_filler + fc(mesh, vertices, &faces); CGAL::Polygon_mesh_processing::connected_component( face(opposite(bhd, mesh), mesh), mesh, diff --git a/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/Containers_filler.h b/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/Containers_filler.h index 7f2bd927149..da464917159 100644 --- a/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/Containers_filler.h +++ b/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/Containers_filler.h @@ -22,6 +22,7 @@ #define CGAL_INTERNAL_SURFACE_MESH_PARAMETERIZATION_CONTAINERS_FILLER_H #include +#include "boost/tuple/tuple.hpp" #include #include @@ -30,40 +31,78 @@ namespace CGAL { namespace internal { -namespace Surface_mesh_parameterization { +namespace Parameterization { // Custom output iterator that fills 'faces' and 'vertices' containers from a mesh -template +template::vertex_descriptor>, + typename Face_vector = + std::vector::face_descriptor> > class Containers_filler { - typedef typename boost::graph_traits::face_descriptor - face_descriptor; - typedef typename boost::graph_traits::vertex_descriptor - vertex_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; const TriangleMesh& mesh; - std::vector& faces; - boost::unordered_set& vertices; + + Vertex_set& vertices; + Face_vector* faces; public: - Containers_filler(const TriangleMesh& mesh, - std::vector& faces, - boost::unordered_set& vertices) - : mesh(mesh), faces(faces), vertices(vertices) + Containers_filler(const TriangleMesh& mesh_, + Vertex_set& vertices_, + Face_vector* faces_) + : mesh(mesh_), vertices(vertices_), faces(faces_) + { } + + Containers_filler(const TriangleMesh& mesh_, + Vertex_set& vertices_) + : mesh(mesh_), vertices(vertices_), faces(NULL) { } void operator()(face_descriptor fd) { - typename boost::graph_traits::halfedge_descriptor hd = - halfedge(fd,mesh); + halfedge_descriptor hd = halfedge(fd, mesh); BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd, mesh)){ vertices.insert(vd); } - faces.push_back(fd); + + if(faces != NULL) + faces->push_back(fd); } }; -} // namespace Surface_mesh_parameterization +template +struct Index_map_filler +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + Index_map_filler(const Mesh& mesh, Map& map) + : mesh(mesh), map(&map), index(0) + { } + + void operator()(const face_descriptor& fd) + { + BOOST_FOREACH(vertex_descriptor vd, + vertices_around_face(halfedge(fd, mesh), mesh)){ + typename Map::iterator it; + bool new_element; + boost::tie(it,new_element) = map->insert(std::make_pair(vd,1)); + if(new_element){ + it->second = index++; + } + } + } + + const Mesh& mesh; + mutable Map* map; + int index; +}; + +} // namespace Parameterization } // namespace internal diff --git a/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/validity.h b/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/validity.h index dbdda094a04..b9530d9640b 100644 --- a/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/validity.h +++ b/Surface_mesh_parameterization/include/CGAL/internal/Surface_mesh_parameterization/validity.h @@ -36,7 +36,7 @@ namespace CGAL { namespace internal { -namespace Surface_mesh_parameterization { +namespace Parameterization { template bool has_flips(const TriangleMesh& mesh, @@ -293,7 +293,7 @@ bool is_one_to_one_mapping(const TriangleMesh& mesh, return (counter == 0); } -} // namespace Surface_mesh_parameterization +} // namespace Parameterization } // namespace internal diff --git a/Surface_mesh_parameterization/include/CGAL/parameterize.h b/Surface_mesh_parameterization/include/CGAL/parameterize.h index 519e3a65377..053a4edc900 100644 --- a/Surface_mesh_parameterization/include/CGAL/parameterize.h +++ b/Surface_mesh_parameterization/include/CGAL/parameterize.h @@ -72,37 +72,6 @@ private: } // namespace internal - -namespace Parameterization { - -template -struct Vertices { - - Vertices(const Mesh& mesh, Map& map) - : mesh(mesh), map(&map), index(0) - { } - - void operator()(const typename boost::graph_traits::face_descriptor& fd) - { - BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vd, - vertices_around_face(halfedge(fd,mesh),mesh)){ - typename Map::iterator it; - bool new_element; - boost::tie(it,new_element) = map->insert(std::make_pair(vd,1)); - if(new_element){ - it->second = index++; - } - } - } - - const Mesh& mesh; - mutable Map* map; - int index; -}; - -} // namespace Parameterization - - /// \ingroup PkgSurfaceParameterizationMainFunction /// /// Compute a one-to-one mapping from a 3D triangle surface `mesh` to a @@ -138,20 +107,23 @@ parameterize(TriangleMesh& mesh, VertexUVmap uvm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef boost::unordered_map Indices; Indices indices; + CGAL::Polygon_mesh_processing::connected_component( + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator( + internal::Parameterization::Index_map_filler(mesh, indices))); + boost::associative_property_map vipm(indices); + boost::unordered_set vs; internal::Bool_property_map > vpm(vs); - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd,mesh),mesh), - mesh, - boost::make_function_output_iterator( - Parameterization::Vertices(mesh,indices))); - return parameterizer.parameterize(mesh, bhd, uvm, boost::make_assoc_property_map(indices), vpm); + return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm); } - /// \ingroup PkgSurfaceParameterizationMainFunction /// /// Compute a one-to-one mapping from a 3D triangle surface `mesh` to a @@ -180,53 +152,13 @@ parameterize(TriangleMesh& mesh, HD bhd, VertexUVmap uvm) { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - boost::unordered_set vs; - internal::Bool_property_map > vpm(vs); - - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - Parameterization::Vertices(mesh, indices))); - Mean_value_coordinates_parameterizer_3 parameterizer; - return parameterizer.parameterize(mesh, bhd, uvm, boost::make_assoc_property_map(indices), vpm); - - return Parameterizer_traits_3::OK; + return CGAL::parameterize(mesh, parameterizer, bhd, uvm); } - template class Seam_mesh; - -template -typename Parameterizer_traits_3 >::Error_code -parameterize(Seam_mesh& mesh, - HD bhd, - VertexUVmap uvm) -{ - typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; - boost::unordered_set vs; - internal::Bool_property_map > vpm(vs); - - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - Parameterization::Vertices, Indices>(mesh, indices))); - boost::associative_property_map vipm(indices); - - Mean_value_coordinates_parameterizer_3 > parameterizer; - return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm); -} - - template typename Parameterizer_traits_3 >::Error_code parameterize(Seam_mesh& mesh, @@ -241,15 +173,26 @@ parameterize(Seam_mesh& mesh, typedef boost::unordered_map Indices; Indices indices; CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - Parameterization::Vertices, Indices>(mesh, indices))); + face(opposite(bhd, mesh), mesh), + mesh, + boost::make_function_output_iterator( + internal::Parameterization::Index_map_filler, + Indices>(mesh, indices))); boost::associative_property_map vipm(indices); return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm); } +template +typename Parameterizer_traits_3 >::Error_code +parameterize(Seam_mesh& mesh, + HD bhd, + VertexUVmap uvm) +{ + Mean_value_coordinates_parameterizer_3 > parameterizer; + return CGAL::parameterize(mesh, parameterizer, bhd, uvm); +} + } // namespace CGAL #endif // CGAL_PARAMETERIZE_H