#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Parameterization_polyhedron_adaptor_3.h>
#include <CGAL/parameterize.h>
#include <CGAL/Parameterization_mesh_patch_3.h>
#include <iostream>
#include <fstream>
Parameterization_polyhedron_adaptor;
typedef std::list<Parameterization_polyhedron_adaptor::Vertex_handle>
Seam;
static Seam cut_mesh(Parameterization_polyhedron_adaptor& mesh_adaptor)
{
Mesh_feature_extractor;
Seam seam;
Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Mesh_feature_extractor feature_extractor(mesh_adaptor);
int nb_borders = feature_extractor.get_nb_borders();
int genus = feature_extractor.get_genus();
if (genus == 0 && nb_borders > 0)
{
seam = feature_extractor.get_longest_border();
}
else
{
const int CUT_LENGTH = 6;
Polyhedron::Halfedge_handle seam_halfedges[CUT_LENGTH];
seam_halfedges[0] = mesh.halfedges_begin();
if (seam_halfedges[0] == NULL)
return seam;
int i;
for (i=1; i<CUT_LENGTH; i++)
{
seam_halfedges[i] = seam_halfedges[i-1]->next()->opposite()->next();
if (seam_halfedges[i] == NULL)
return seam;
}
for (i=0; i<CUT_LENGTH; i++)
seam.push_back(seam_halfedges[i]->vertex());
for (i=CUT_LENGTH-1; i>=0; i--)
seam.push_back(seam_halfedges[i]->opposite()->vertex());
}
return seam;
}
int main(int argc, char * argv[])
{
std::cerr << "PARAMETERIZATION" << std::endl;
std::cerr << " Floater parameterization" << std::endl;
std::cerr << " Circle border" << std::endl;
std::cerr << " Very simple cut if model is not a topological disk" << std::endl;
if (argc-1 != 1)
{
std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl;
return(EXIT_FAILURE);
}
const char* input_filename = argv[1];
std::ifstream stream(input_filename);
Polyhedron mesh;
stream >> mesh;
if(!stream || !mesh.is_valid() || mesh.empty())
{
std::cerr << "Error: cannot read OFF file " << input_filename << std::endl;
return EXIT_FAILURE;
}
Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
Seam seam = cut_mesh(mesh_adaptor);
if (seam.empty())
{
std::cerr << "Input mesh not supported: the example cutting algorithm is too simple to cut this shape" << std::endl;
return EXIT_FAILURE;
}
Mesh_patch_polyhedron;
Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end());
if (!mesh_patch.is_valid())
{
std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl;
return EXIT_FAILURE;
}
Parameterizer;
switch(err) {
case Parameterizer::OK:
break;
case Parameterizer::ERROR_EMPTY_MESH:
case Parameterizer::ERROR_NON_TRIANGULAR_MESH:
case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC:
case Parameterizer::ERROR_BORDER_TOO_SHORT:
std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl;
return EXIT_FAILURE;
break;
default:
std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl;
return EXIT_FAILURE;
break;
};
Polyhedron::Vertex_const_iterator pVertex;
for (pVertex = mesh.vertices_begin();
pVertex != mesh.vertices_end();
pVertex++)
{
double u = mesh_adaptor.info(pVertex->halfedge())->uv().x();
double v = mesh_adaptor.info(pVertex->halfedge())->uv().y();
std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl;
}
return EXIT_SUCCESS;
}