diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Authalic_parameterization.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Authalic_parameterization.cpp index a220d5c3daf..8a39e294a94 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Authalic_parameterization.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Authalic_parameterization.cpp @@ -23,7 +23,7 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_2 Point_2; -#if 0 +#if 1 typedef CGAL::Surface_mesh Polyhedron; #else typedef CGAL::Polyhedron_3 Polyhedron; @@ -32,6 +32,7 @@ typedef CGAL::Polyhedron_3 Polyhedron; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; // ---------------------------------------------------------------------------- // main() @@ -47,9 +48,9 @@ int main(int argc, char * argv[]) // decode parameters //*************************************** - if (argc-1 != 1) + if (argc-1 != 2) { - std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl; + std::cerr << "Usage: " << argv[0] << " input_file.off input_file.seams" << std::endl; return(EXIT_FAILURE); } @@ -71,6 +72,22 @@ int main(int argc, char * argv[]) return EXIT_FAILURE; } */ + + std::ifstream index_pair_stream(argv[2]); + + std::vector edges; + { + std::size_t i,j; + while(index_pair_stream >> i >> j){ + edge_descriptor e; + bool found; + boost::tie(e,found) = edge(vertex_descriptor(i),vertex_descriptor(j), mesh); + assert(found); + edges.push_back(e); + std::cout << std::size_t(e) << std::endl; + } + } + //*************************************** // Create Polyhedron adaptor // Note: no cutting => we support only @@ -101,7 +118,8 @@ int main(int argc, char * argv[]) typedef CGAL::Parameterization_polyhedron_adaptor_3 Parameterization_polyhedron_adaptor; - Parameterization_polyhedron_adaptor mesh_adaptor(mesh, border, vipm,hipm,huvpm); + // Parameterization_polyhedron_adaptor mesh_adaptor(mesh, border, vipm,hipm,huvpm); + Parameterization_polyhedron_adaptor mesh_adaptor(mesh, edges, vipm,hipm,huvpm); //*************************************** // Discrete Authalic Parameterization diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt index 4883644fb55..ec4e5e8ff11 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt @@ -49,6 +49,7 @@ if ( CGAL_FOUND ) endif() # Executables that do *not* require Eigen + create_single_source_cgal_program( "seam.cpp" ) create_single_source_cgal_program( "LSCM_parameterization.cpp" ) find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp index c46b398c5ee..c2c09c4073c 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp @@ -65,14 +65,17 @@ int main(int, char* argv[]) std::vector points; do { - points.push_back(get(ppmap,tv)); + std::cout << std::size_t(tv) << " " << std::size_t(predecessor[tv]) << std::endl; + //points.push_back(get(ppmap,tv)); tv = predecessor[tv]; } while(predecessor[tv]!=tv); + /* points.push_back(get(ppmap,sv)); std::cout << points.size() << std::endl; BOOST_FOREACH(Point p, points){ std::cout << p << std::endl; } + */ return 0; } 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 e109d456064..2f0499a1c0d 100644 --- a/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Fixed_border_parameterizer_3.h @@ -118,6 +118,7 @@ private: typedef typename boost::graph_traits::vertex_iterator vertex_iterator; typedef CGAL::Vertex_around_target_circulator vertex_around_target_circulator; + typedef CGAL::Vertex_around_face_circulator vertex_around_face_circulator; typedef CGAL::Halfedge_around_target_circulator halfedge_around_target_circulator; // Mesh_Adaptor_3 subtypes: @@ -272,9 +273,6 @@ parameterize(Adaptor& amesh) // Count vertices int nbVertices = amesh.count_mesh_vertices(); - // Index vertices from 0 to nbVertices-1 - amesh.index_mesh_vertices(); - // AF: mark all halfedges as not parameterized // Mark all vertices as *not* "parameterized" BOOST_FOREACH(vertex_descriptor v, vertices(mesh)) @@ -310,8 +308,8 @@ parameterize(Adaptor& amesh) // w_ij for each neighbor j; then w_ii = - sum of w_ijs BOOST_FOREACH(vertex_descriptor v, vertices(mesh)) { - CGAL_surface_mesh_parameterization_assertion(amesh.is_vertex_on_main_border(v) - == amesh.is_vertex_parameterized(v)); + // CGAL_surface_mesh_parameterization_assertion(amesh.is_vertex_on_main_border(v) + // == amesh.is_vertex_parameterized(v)); // inner vertices only if( ! amesh.is_vertex_on_main_border(v) ) @@ -444,7 +442,7 @@ initialize_system_from_mesh_border (Matrix& A, Vector& Bu, Vector& Bv, // AF: loop over border halfedges BOOST_FOREACH(halfedge_descriptor hd, mesh.main_border()) { - CGAL_surface_mesh_parameterization_assertion(mesh.is_vertex_parameterized(target(hd,tmesh))); + // AF not written for halfedge CGAL_surface_mesh_parameterization_assertion(mesh.is_vertex_parameterized(target(hd,tmesh))); // AF: get the halfedge-as-vertex index // Get vertex index in sparse linear system @@ -518,6 +516,7 @@ setup_inner_vertex_relations(Matrix& A, } // Copy Xu and Xv coordinates into the (u,v) pair of each surface vertex. +// AF: this only concerns vertices NOT on the border template inline void Fixed_border_parameterizer_3:: @@ -531,12 +530,14 @@ set_mesh_uv_from_system(Adaptor& amesh, { int index = amesh.get_vertex_index(vd); - NT u = Xu[index]; - NT v = Xv[index]; - - // Fill vertex (u,v) and mark it as "parameterized" - amesh.set_vertex_uv(vd, Point_2(u,v)); - amesh.set_vertex_parameterized(vd, true); + if(index != -1){ + NT u = Xu[index]; + NT v = Xv[index]; + + // Fill vertex (u,v) and mark it as "parameterized" + amesh.set_vertex_uv(vd, Point_2(u,v)); + amesh.set_vertex_parameterized(vd, true); + } } } diff --git a/Surface_mesh_parameterization/include/CGAL/Parameterization_polyhedron_adaptor_3.h b/Surface_mesh_parameterization/include/CGAL/Parameterization_polyhedron_adaptor_3.h index 28513322b10..090b1e2d93c 100644 --- a/Surface_mesh_parameterization/include/CGAL/Parameterization_polyhedron_adaptor_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Parameterization_polyhedron_adaptor_3.h @@ -84,6 +84,7 @@ private: typedef typename Polyhedron_3_ TriangleMesh; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename boost::graph_traits::face_iterator face_iterator; typedef typename boost::graph_traits::vertex_iterator vertex_iterator; @@ -130,7 +131,7 @@ public: { m_tag = -1; // uninitialized m_index = -1; // uninitialized - m_seaming = -1; // uninitialized + m_seaming = 0; // uninitialized m_is_parameterized = false; m_vindex = -1; m_on_border = 0; @@ -177,7 +178,7 @@ public: { m_index = -1; // uninitialized m_tag = -1; // uninitialized - m_seaming = -1; // uninitialized + m_seaming = 0; // uninitialized m_on_border = 0; } @@ -258,19 +259,12 @@ public: typedef typename Vertex_info_map::value_type Vertex_info_pair; m_halfedge_info.resize(num_halfedges(mesh)); - // Allocate extra info for each halfedge - Halfedge_info hinfo; - BOOST_FOREACH(halfedge_descriptor hd, halfedges(mesh)){ - m_halfedge_info[get(m_him,hd)] = hinfo; - } - m_vertex_info.resize(num_vertices(mesh)); + // Allocate extra info for each vertex - Vertex_info vinfo; - int index = 0; + m_num_vertices = 0; BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ - m_vertex_info[get(m_vim, vd)] = vinfo; - set_vertex_index(vd, index++); + set_vertex_index(vd, m_num_vertices++); } BOOST_FOREACH(halfedge_descriptor hd, halfedges(mesh)){ @@ -282,13 +276,94 @@ public: info(hd)->on_border(2); info(target(hd,mesh))->on_border(2); } - -#ifndef CGAL_NDEBUG - // Index vertices right away to ease debugging - // index_mesh_vertices(); -#endif } + + + /// Create an adaptator for an existing Polyhedron_3 mesh. + /// The input mesh can be of any genus. + /// It can have have any number of borders. + /// the seam will be the main border + + /// + Parameterization_polyhedron_adaptor_3(Polyhedron& mesh, + std::vector& seam, + VertexIndexMap vim, + HalfedgeIndexMap him, + HalfedgeUvMap huvm) + // Store reference to adapted mesh + : m_polyhedron(mesh), m_vim(vim), m_him(him), m_huvm(huvm) + { + typedef typename Halfedge_info_map::value_type Halfedge_info_pair; + typedef typename Vertex_info_map::value_type Vertex_info_pair; + + m_halfedge_info.resize(num_halfedges(mesh)); + m_vertex_info.resize(num_vertices(mesh)); + + // each vertex shall know on how many seaming edges it is + BOOST_FOREACH(edge_descriptor e, seam){ + info(halfedge(e,mesh))->seaming(1); + info(opposite(halfedge(e,mesh),mesh))->seaming(1); + vertex_descriptor vd = target(e,mesh); + info(vd)->seaming(info(vd)->seaming()+1); + vd = source(e,mesh); + info(vd)->seaming(info(vd)->seaming()+1); + } + + // we only want to use the index stored in info if it is not inside a seam + m_num_vertices = 0; + BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ + if(info(vd)->seaming() == 0){ + set_vertex_index(vd, m_num_vertices++); + } else { + assert(get_vertex_index(vd) == -1); + } + } + BOOST_FOREACH(edge_descriptor e, seam){ + halfedge_descriptor hd = halfedge(e,mesh); + info(target(hd,mesh))->on_border(2); + set_vertex_index(hd,m_num_vertices); + while(info(next(hd,mesh))->seaming()==0){ + hd = opposite(next(hd,mesh),mesh); + set_vertex_index(hd,m_num_vertices); + } + ++m_num_vertices; + hd = opposite(halfedge(e,mesh),mesh); + info(target(hd,mesh))->on_border(2); + set_vertex_index(hd,m_num_vertices); + while(info(next(hd,mesh))->seaming()==0){ + hd = opposite(next(hd,mesh),mesh); + set_vertex_index(hd,m_num_vertices); + + } + ++m_num_vertices; + } + + // all halfedges where target is not on a seam will get it from the target + BOOST_FOREACH(halfedge_descriptor hd, halfedges(mesh)){ + if(info(target(hd,mesh))->seaming()==0){ + assert(info(hd)->seaming()==0); + assert(info(target(hd,mesh))->index() != -1); + set_vertex_index(hd, info(target(hd,mesh))->index()); + } + assert(get_vertex_index(hd)!= -1); + } + + + // to get started deal with a polyline border + for(int i=0; i < seam.size(); i++){ + m_main_border.push_back(halfedge(seam[i],mesh)); + } + for(int i=seam.size(); i>0 ; i--){ + m_main_border.push_back(opposite(halfedge(seam[i-1],mesh),mesh)); + } + + // We do not set on_border for vinfo or hinfo + + } + + + // Default destructor, copy constructor and operator =() are fine /// Get the adapted mesh. @@ -342,25 +417,11 @@ public: return m_polyhedron.is_valid(); } - /// TODO: check if num_vertices would be ok /// Count the number of vertices of the mesh. int count_mesh_vertices() const { - - vertex_iterator b, e; - boost::tie(b,e) = vertices(m_polyhedron); - - return std::distance(b,e); + return m_num_vertices; } - // Index vertices of the mesh from 0 to count_mesh_vertices()-1 - void index_mesh_vertices () - { - int index = 0; - BOOST_FOREACH (vertex_descriptor vd, vertices(m_polyhedron)) - { - set_vertex_index(vd, index++); - } - } const std::list& main_border() const { return m_main_border; } @@ -455,17 +516,26 @@ public: put(m_huvm, hd, uv); } }else { - std::cerr << "todo\n"; + put(m_huvm, halfedge, uv); + while(info(next(halfedge,m_polyhedron))->seaming()>0){ + halfedge = opposite(next(halfedge,m_polyhedron),m_polyhedron); + put(m_huvm, halfedge, uv); + } } } void set_vertex_parameterized(halfedge_descriptor halfedge, bool b) { + std::cerr << "set_vertex_parameterized\n"; if(is_border(halfedge,m_polyhedron)){ BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(halfedge,m_polyhedron)){ info(hd)->is_parameterized(b); } }else { - std::cerr << "todo\n"; + info(halfedge)->is_parameterized(true); + while(info(next(halfedge,m_polyhedron))->seaming()>0){ + halfedge = opposite(next(halfedge,m_polyhedron),m_polyhedron); + info(halfedge)->is_parameterized(true); + } } } Point_2 get_vertex_uv(halfedge_descriptor halfedge) const { @@ -854,10 +924,8 @@ private: Vertex_info_map m_vertex_info; /// Main border of a topological disc inside m_polyhedron (may be empty). - std::list m_main_border; - - - + std::list m_main_border; + int m_num_vertices; }; // Parameterization_polyhedron_adaptor_3