mirror of https://github.com/CGAL/cgal
it seems to work with seams. need visual output next to inspect it
This commit is contained in:
parent
5327c116fe
commit
e90fbb9867
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,6 +530,7 @@ set_mesh_uv_from_system(Adaptor& amesh,
|
|||
{
|
||||
int index = amesh.get_vertex_index(vd);
|
||||
|
||||
if(index != -1){
|
||||
NT u = Xu[index];
|
||||
NT v = Xv[index];
|
||||
|
||||
|
|
@ -539,6 +539,7 @@ set_mesh_uv_from_system(Adaptor& amesh,
|
|||
amesh.set_vertex_parameterized(vd, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check parameterize() postconditions:
|
||||
// - 3D -> 2D mapping is one-to-one.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -855,9 +925,7 @@ private:
|
|||
|
||||
/// Main border of a topological disc inside m_polyhedron (may be empty).
|
||||
std::list<halfedge_descriptor> m_main_border;
|
||||
|
||||
|
||||
|
||||
int m_num_vertices;
|
||||
|
||||
}; // Parameterization_polyhedron_adaptor_3
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue