it seems to work with seams. need visual output next to inspect it

This commit is contained in:
Andreas Fabri 2015-05-21 16:08:36 +02:00 committed by Mael Rouxel-Labbé
parent 5327c116fe
commit e90fbb9867
5 changed files with 146 additions and 55 deletions

View File

@ -23,7 +23,7 @@
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_2 Point_2;
#if 0
#if 1
typedef CGAL::Surface_mesh<Kernel::Point_3> Polyhedron;
#else
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
@ -32,6 +32,7 @@ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
typedef boost::graph_traits<Polyhedron>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Polyhedron>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Polyhedron>::face_descriptor face_descriptor;
typedef boost::graph_traits<Polyhedron>::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<edge_descriptor> 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<Polyhedron, V_index_pmap, H_index_pmap, H_uv_pmap>
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

View File

@ -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)

View File

@ -65,14 +65,17 @@ int main(int, char* argv[])
std::vector<Point> 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;
}

View File

@ -118,6 +118,7 @@ private:
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
typedef CGAL::Vertex_around_face_circulator<TriangleMesh> vertex_around_face_circulator;
typedef CGAL::Halfedge_around_target_circulator<TriangleMesh> 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<class Adaptor, class Border_param, class Sparse_LA>
inline
void Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
@ -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);
}
}
}

View File

@ -84,6 +84,7 @@ private:
typedef typename Polyhedron_3_ TriangleMesh;
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
typedef typename boost::graph_traits<TriangleMesh>::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<edge_descriptor>& 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<halfedge_descriptor>& 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<halfedge_descriptor> m_main_border;
std::list<halfedge_descriptor> m_main_border;
int m_num_vertices;
}; // Parameterization_polyhedron_adaptor_3