From c2bc4082e7b8ac81fb96f444c710505950e0a281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 21 Feb 2017 13:41:52 +0100 Subject: [PATCH] Removed or untracked irrelevant files Also fixed some data paths. --- .../CMakeLists.txt | 1 - .../include/Mesh_cutter.h | 269 ----- .../include/Polyhedron_ex.h | 596 ------------ .../orbifold.cpp | 4 +- .../orbifold_mapping.cpp | 240 ----- .../parameterization_tests.cpp | 401 -------- .../Orbifold_Tutte_sphere_mapping.h | 920 ------------------ .../include/Mesh_cutter.h | 271 ------ .../include/Polyhedron_ex.h | 596 ------------ 9 files changed, 2 insertions(+), 3296 deletions(-) delete mode 100644 Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Mesh_cutter.h delete mode 100644 Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Polyhedron_ex.h delete mode 100644 Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold_mapping.cpp delete mode 100644 Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp delete mode 100644 Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_sphere_mapping.h delete mode 100644 Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Mesh_cutter.h delete mode 100644 Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Polyhedron_ex.h diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt index 72fa45534f3..8bbd9e69dc6 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/CMakeLists.txt @@ -56,7 +56,6 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "discrete_authalic.cpp" ) create_single_source_cgal_program( "lscm.cpp" ) create_single_source_cgal_program( "orbifold.cpp" ) - create_single_source_cgal_program( "orbifold_mapping.cpp" ) create_single_source_cgal_program( "seam_Polyhedron_3.cpp" ) create_single_source_cgal_program( "simple_parameterization.cpp" ) create_single_source_cgal_program( "square_border_parameterizer.cpp" ) diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Mesh_cutter.h b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Mesh_cutter.h deleted file mode 100644 index 5d96126157d..00000000000 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Mesh_cutter.h +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************** - begin : jan 02 - copyright : (C) 2002 by Pierre Alliez - email : pierre.alliez@sophia.inria.fr - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef MESH_CUTTER_H -#define MESH_CUTTER_H - -#include "Polyhedron_ex.h" - -#include -#include - - -class Mesh_cutter -{ -// Public types -public: - - typedef std::list - Backbone; - -// Private types -private: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - enum {FREE,DONE,FIXED}; - -// Public operations -public: - - // life cycle - Mesh_cutter(Polyhedron_ex& polyhedron) - { - m_pPolyhedron = &polyhedron; - m_pBackbone = NULL; - } - ~Mesh_cutter() {} - - void cut(Backbone& backbone); - void cut_genus(Backbone& backbone); - -// Private operations -private: - - // genus > 0 - bool init(); - bool simplify(); - bool extend(); - void precompute_distances(); - Polyhedron_ex::Halfedge_handle pick_best_halfedge( - std::list::iterator &pos); - void recursive_tag(Polyhedron_ex::Facet_handle pFacet,int index); - -// Fields -private: - - Polyhedron_ex* m_pPolyhedron; // the model to cut - Backbone* m_pBackbone; // the backbone to fill - Polyhedron_ex::Facet_handle m_pSeedFacet; - Polyhedron_ex::Vertex_handle m_pSeedVertex; -}; - - -//*************************************************** -// simple cut for genus 0 mesh -//*************************************************** -inline void Mesh_cutter::cut(Backbone& backbone) -{ - m_pBackbone = &backbone; - - // special init -> tag all vertices, but two - m_pPolyhedron->tag_vertices(FREE); - Polyhedron_ex::Vertex_handle pVertexMin,pVertexMax; - m_pPolyhedron->farthest_point_aligned(pVertexMin,pVertexMax); - pVertexMin->tag(FIXED); - pVertexMax->tag(FIXED); - init(); - - // cutting - while(extend()) {} -} - -///////////////////////////////////////////////////// -// GENUS > 0 -///////////////////////////////////////////////////// - -//*************************************************** -// cut for genus>0 mesh -//*************************************************** -inline void Mesh_cutter::cut_genus(Backbone& backbone) -{ - m_pBackbone = &backbone; - - // init - m_pPolyhedron->tag_vertices(FREE); // all free - init(); - - // cutting - while(extend()) {} -} - -//*************************************************** -// init -//*************************************************** -inline bool Mesh_cutter::init() -{ - // tag facets - m_pPolyhedron->tag_facets(FREE); - - // compute bounding box and center - double xmin = m_pPolyhedron->minimum(0); - double ymin = m_pPolyhedron->minimum(1); - double zmin = m_pPolyhedron->minimum(2); - double xmax = m_pPolyhedron->maximum(0); - double ymax = m_pPolyhedron->maximum(1); - double zmax = m_pPolyhedron->maximum(2); - double xcenter = 0.5*(xmin+xmax); - double ycenter = 0.5*(ymin+ymax); - double zcenter = 0.5*(zmin+zmax); - Point_3 center(xcenter,ycenter,zcenter); - - // get closest facet - m_pSeedFacet = m_pPolyhedron->get_closest_inner_facet(center); - assert(m_pSeedFacet != NULL); - - Polyhedron_ex::Halfedge_handle he = m_pSeedFacet->halfedge(); - assert(he != NULL); - assert(m_pBackbone != NULL); - m_pBackbone->push_back(he); - m_pBackbone->push_back(he->next()); - m_pBackbone->push_back(he->next()->next()); - - precompute_distances(); - m_pSeedFacet->tag(DONE); - - return true; -} - -//*************************************************** -// extend -//*************************************************** -inline bool Mesh_cutter::extend() -{ - std::list::iterator pos; - Polyhedron_ex::Halfedge_handle pHalfedge = pick_best_halfedge(pos); - if(pHalfedge == NULL) - return false; - - // flag facet - pHalfedge->opposite()->facet()->tag(DONE); - - // insert halfedge - std::list::iterator tmp = - m_pBackbone->insert(pos,pHalfedge->opposite()->next()->next()); - m_pBackbone->insert(tmp,pHalfedge->opposite()->next()); - - // remove this one - m_pBackbone->remove(pHalfedge); - - // simplify current backbone - while(simplify()) {} - return true; -} - -//*************************************************** -// simplify -//*************************************************** -inline bool Mesh_cutter::simplify() -{ - // cleanup - std::list::iterator iter; - for(iter = m_pBackbone->begin(); - iter != m_pBackbone->end(); - iter++) - { - Polyhedron_ex::Halfedge_handle pHalfedge = (*iter); - Polyhedron_ex::Halfedge_handle opposite = pHalfedge->opposite(); - - // get next halfedge in the list - iter++; - Polyhedron_ex::Halfedge_handle pNext = NULL; - if(iter == m_pBackbone->end()) // loop - pNext = (*m_pBackbone->begin()); - else - pNext = (*iter); - - if(pNext == opposite && - pHalfedge->vertex()->tag() == FREE) - { - m_pBackbone->remove(pHalfedge); - m_pBackbone->remove(opposite); - return true; - } - - iter--; // restore - } - return false; -} - -//*************************************************** -// precompute_distances -//*************************************************** -inline void Mesh_cutter::precompute_distances() -{ - Polyhedron_ex::Halfedge_iterator pHalfedge; - for(pHalfedge = m_pPolyhedron->halfedges_begin(); - pHalfedge != m_pPolyhedron->halfedges_end(); - pHalfedge++) - pHalfedge->distance(m_pPolyhedron->distance(m_pSeedFacet,pHalfedge)); -} - -//*************************************************** -// pick_best_halfedge -//*************************************************** -inline Polyhedron_ex::Halfedge_handle Mesh_cutter::pick_best_halfedge( - std::list::iterator &pos) -{ - Polyhedron_ex::Halfedge_handle pBest = NULL; - double min_distance = 1e308; // - - // cleanup - std::list::iterator iter; - for(iter = m_pBackbone->begin(); - iter != m_pBackbone->end(); - iter++) - { - Polyhedron_ex::Halfedge_handle pHalfedge = (*iter); - Polyhedron_ex::Halfedge_handle opposite = pHalfedge->opposite(); - Polyhedron_ex::Facet_handle pFacet = opposite->facet(); - - // check - if(pHalfedge->is_border() || - pFacet == NULL) - continue; - - if(pFacet->tag() == DONE) - continue; - - // no border vertex - Polyhedron_ex::Vertex_handle pVertex = opposite->next()->vertex(); - if(m_pPolyhedron->is_border(pVertex)) - continue; - - // precomputed distance - double distance = pHalfedge->distance(); - if(distance < min_distance) - { - pos = iter; - pBest = pHalfedge; - min_distance = distance; - } - } - return pBest; -} - - -#endif // MESH_CUTTER_H diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Polyhedron_ex.h b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Polyhedron_ex.h deleted file mode 100644 index 402db914954..00000000000 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/include/Polyhedron_ex.h +++ /dev/null @@ -1,596 +0,0 @@ -#ifndef POLYHEDRON_EX_H_INCLUDED -#define POLYHEDRON_EX_H_INCLUDED - -#include -#include -#include - -#include -#include -#include -#include -#include - - -// CGAL kernel -typedef CGAL::Simple_cartesian My_kernel; - - -// compute facet center -struct Facet_center -{ - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - template - void operator()(Facet& f) - { - Vector_3 vec(0.0,0.0,0.0); - int degree = 0; - typedef typename Facet::Halfedge_around_facet_const_circulator circ; - circ h = f.facet_begin(); - do - { - vec = vec + (h->vertex()->point()-CGAL::ORIGIN); - degree++; - } - while (++h != f.facet_begin()); - f.center() = CGAL::ORIGIN + (vec/degree); - } -}; - -template -class My_facet : public CGAL::HalfedgeDS_face_base -{ -public: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - // life cycle - // no constructors to repeat, since only - // default constructor mandatory - My_facet() - { - m_tag = -1; // uninitialized - } - - // center - Point_3& center() { return m_center; } - const Point_3& center() const { return m_center; } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // distance - double distance(Point_3& point) const - { - Vector_3 vec = (point-m_center); - return std::sqrt(vec*vec); - } - -// Fields -private: - - // facet data - int m_tag; - Point_3 m_center; -}; - -template -class My_halfedge - : public CGAL::HalfedgeDS_halfedge_base -{ -private: - int m_tag; - - // parameterization - bool m_is_parameterized; - int m_seaming; // seaming status - double m_u; // texture coordinates - double m_v; - int m_index; // for parameterization - - // surface cutting - double m_distance; - -public: - // life cycle - // no constructors to repeat, since only - // default constructor mandatory - My_halfedge() - { - m_tag = -1; // uninitialized - m_u = 0.0; - m_v = 0.0; - m_index = -1; // uninitialized - m_seaming = -1; // uninitialized - m_is_parameterized = false; - } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // seaming status - int seaming() const { return m_seaming; } - void seaming(int seaming) { m_seaming = seaming; } - - // precomputed distance - double distance() const { return m_distance; } - void distance(double distance) { m_distance = distance; } - - // texture coordinates - double u() const { return m_u; } - double v() const { return m_v; } - void uv(double u, double v) { m_u = u; m_v = v; } - - // param. - bool is_parameterized() const { return m_is_parameterized; } - void is_parameterized(bool is) { m_is_parameterized = is; } - - // index - int index() const { return m_index; } - void index(int i) { m_index = i; } -}; - - -// A redefined vertex class for the Polyhedron_3 -template -class My_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // index - int m_index; - - // misc - int m_tag; - - // seaming status - int m_seaming; - -public: - // life cycle - My_vertex() { init(); } - // repeat mandatory constructors - My_vertex(const P& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - init(); - } - - void init() - { - m_index = -1; // uninitialized - m_tag = -1; // uninitialized - m_seaming = -1; // uninitialized - } - - // index - int index() const { return m_index; } - void index(int i) { m_index = i; } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // seaming status - int seaming() const { return m_seaming; } - void seaming(int seaming) { m_seaming = seaming; } -}; - - -// A redefined items class for the Polyhedron_3 with a refined vertex, facet and halfedge classes -struct My_items : public CGAL::Polyhedron_items_3 -{ - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point_3; - typedef My_vertex Vertex; - }; - - // wrap facet - template - struct Face_wrapper - { - typedef My_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef My_halfedge Halfedge; - }; -}; - - -class Polyhedron_ex : public CGAL::Polyhedron_3 -{ -public: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - public: - - // life cycle - Polyhedron_ex() {} - virtual ~Polyhedron_ex() {} - - // facet centers - void compute_facet_centers() - { - std::for_each(facets_begin(),facets_end(),Facet_center()); - } - - // tag all facets - void tag_facets(const int tag) - { - Facet_iterator pFace; - for(pFace = facets_begin(); - pFace != facets_end(); - pFace++) - pFace->tag(tag); - } - - // get closest inner facet - Facet_handle get_closest_inner_facet(Point_3& point) - { - Facet_iterator pFace = facets_begin(); - Facet_handle pClosest = pFace; - double minimum = pFace->distance(point); - for(;pFace != facets_end(); - pFace++) - { - if(is_inner(pFace)) - { - double distance = pFace->distance(point); - if(distance < minimum) - { - pClosest = pFace; - minimum = distance; - } - } - } - return pClosest; - } - - bool is_inner(Facet_handle pFace) - { - typedef Halfedge_around_facet_const_circulator circ; - circ h = pFace->facet_begin(); - do - { - if(h->opposite()->is_border()) - return false; - } - while(++h != pFace->facet_begin()); - return true; - } - - // tag all vertices - void tag_vertices(const int tag) - { - Vertex_iterator iter; - for(iter = vertices_begin(); iter != vertices_end(); iter++) - iter->tag(tag); - } - - // tag all halfedges - void tag_halfedges(const int tag) - { - Halfedge_iterator iter; - for(iter = halfedges_begin(); iter != halfedges_end(); iter++) - iter->tag(tag); - } - - // compute bounding interval - double minimum (int coord) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - double minimum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - minimum = (std::min)(minimum,pVertex->point()[coord]); - return minimum; - } - double maximum (int coord) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - double maximum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - maximum = (std::max)(maximum,pVertex->point()[coord]); - return maximum; - } - Vertex_handle vertex_min(int coord, - double &minimum) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - Vertex_handle pBest = pVertex; - minimum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - { - double value = pVertex->point()[coord]; - if(value < minimum) - { - minimum = (std::min)(minimum,value); - pBest = pVertex; - } - } - return pBest; - } - Vertex_handle vertex_max(int coord, - double &maximum) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - Vertex_handle pBest = pVertex; - maximum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - { - double value = pVertex->point()[coord]; - if(value > maximum) - { - maximum = (std::max)(maximum,value); - pBest = pVertex; - } - } - return pBest; - } - - // Index all mesh vertices following the order of the vertices_begin() iterator - void precompute_vertex_indices() - { - Vertex_iterator pVertex; - unsigned int i = 0; - for(pVertex = vertices_begin(); - pVertex != vertices_end(); - pVertex++) - pVertex->index(i++); - } - - // Index all mesh half edges following the order of the halfedges_begin() iterator - void precompute_halfedge_indices() - { - Halfedge_iterator pHalfedge; - unsigned int i = 0; - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - pHalfedge->index(i++); - } - - -#ifdef DEBUG_TRUNCATE_OUTPUT - // Debug: write coordinates with 2 digits precision - #define FORMAT_EPS_COORD(x) (int(x/10.0+0.5)*10) -#else - #define FORMAT_EPS_COORD(x) (x) -#endif - - // Dump parameterized mesh to an eps file - bool write_file_eps(const char *pFilename, - double scale = 500.0) - { - assert(pFilename != NULL); - - std::ofstream out(pFilename); - if(!out) - return false; - CGAL::set_ascii_mode(out); - - // compute bounding box - double xmin,xmax,ymin,ymax; - xmin = ymin = xmax = ymax = 0; - Halfedge_iterator pHalfedge; - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - { - double x1 = scale * pHalfedge->prev()->u(); - double y1 = scale * pHalfedge->prev()->v(); - double x2 = scale * pHalfedge->u(); - double y2 = scale * pHalfedge->v(); - xmin = (std::min)(xmin,x1); - xmin = (std::min)(xmin,x2); - xmax = (std::max)(xmax,x1); - xmax = (std::max)(xmax,x2); - ymax = (std::max)(ymax,y1); - ymax = (std::max)(ymax,y2); - ymin = (std::min)(ymin,y1); - ymin = (std::min)(ymin,y2); - } - - out << "%!PS-Adobe-2.0 EPSF-2.0" << std::endl; - out << "%%BoundingBox: " << int(xmin+0.5) << " " - << int(ymin+0.5) << " " - << int(xmax+0.5) << " " - << int(ymax+0.5) << std::endl; - out << "%%HiResBoundingBox: " << xmin << " " - << ymin << " " - << xmax << " " - << ymax << std::endl; - out << "%%EndComments" << std::endl; - out << "gsave" << std::endl; - out << "0.1 setlinewidth" << std::endl; - - // color macros - out << std::endl; - out << "% RGB color command - r g b C" << std::endl; - out << "/C { setrgbcolor } bind def" << std::endl; - out << "/white { 1 1 1 C } bind def" << std::endl; - out << "/black { 0 0 0 C } bind def" << std::endl; - - // edge macro -> E - out << std::endl; - out << "% Black stroke - x1 y1 x2 y2 E" << std::endl; - out << "/E {moveto lineto stroke} bind def" << std::endl; - out << "black" << std::endl << std::endl; - - // output edge coordinates - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - { - double x1 = scale * pHalfedge->prev()->u(); - double y1 = scale * pHalfedge->prev()->v(); - double x2 = scale * pHalfedge->u(); - double y2 = scale * pHalfedge->v(); - out << FORMAT_EPS_COORD(x1) << " " - << FORMAT_EPS_COORD(y1) << " " - << FORMAT_EPS_COORD(x2) << " " - << FORMAT_EPS_COORD(y2) << " E" << std::endl; - } - - /* Emit EPS trailer. */ - out << "grestore" << std::endl; - out << std::endl; - out << "showpage" << std::endl; - - return true; - } - -#ifdef DEBUG_TRUNCATE_OUTPUT - // Debug: write coordinates with 2 digits precision - #define FORMAT_UV(x) (float(int(x*100.0+0.5))/100.0) -#else - #define FORMAT_UV(x) (x) -#endif - - // Dump parameterized mesh to a Wavefront OBJ file - // v x y z - // f 1 2 3 4 (1-based) - // - // Implementation note: the UV is meaningless for a NON parameterized halfedge - bool write_file_obj(const char *pFilename) - { - assert(pFilename != NULL); - - std::ofstream out(pFilename); - if(!out) - return false; - CGAL::set_ascii_mode(out); - - // Index all mesh vertices following the order of vertices_begin() iterator - precompute_vertex_indices(); - // Index all mesh half edges following the order of halfedges_begin() iterator - precompute_halfedge_indices(); - - // write the name of material file - out << "mtllib parameterization.mtl" << std::endl ; - - // output coordinates - out << "# vertices" << std::endl ; - Vertex_iterator pVertex; - for(pVertex = vertices_begin(); pVertex != vertices_end(); pVertex++) - out << "v " << pVertex->point().x() << " " - << pVertex->point().y() << " " - << pVertex->point().z() << std::endl; - - // Write UVs (1 UV / halfedge) - out << "# uv coordinates" << std::endl ; - Halfedge_iterator pHalfedge; - for(pHalfedge = halfedges_begin(); pHalfedge != halfedges_end(); pHalfedge++) - { - if (pHalfedge->is_parameterized()) - out << "vt " << FORMAT_UV(pHalfedge->u()) << " " << FORMAT_UV(pHalfedge->v()) << std::endl; - else - out << "vt " << 0.0 << " " << 0.0 << std::endl; - } - - // Write facets using the unique material # 1 - out << "# facets" << std::endl; - out << "usemtl Mat_1" << std::endl; - Facet_const_iterator pFacet; - for(pFacet = facets_begin(); pFacet != facets_end(); pFacet++) - { - Halfedge_around_facet_const_circulator h = pFacet->facet_begin(); - out << "f"; - do { - out << " " << h->vertex()->index()+1; - if (h->is_parameterized()) - out << "/" << h->index()+1; - } - while(++h != pFacet->facet_begin()); - out << std::endl; - } - - return true; - } - - // is vertex on border ? - static bool is_border(Vertex_const_handle pVertex) - { - Halfedge_around_vertex_const_circulator pHalfedge = pVertex->vertex_begin(); - Halfedge_around_vertex_const_circulator end = pHalfedge; - if(pHalfedge == NULL) // isolated vertex - return true; - CGAL_For_all(pHalfedge,end) - if(pHalfedge->is_border()) - return true; - return false; - } - - // compute distance from facet center to halfedge center - double distance(Facet_handle pFacet, - Halfedge_handle pHalfedge) - { - // we assume - Point_3 center_facet = pFacet->center(); - - Vector_3 v = (pHalfedge->opposite()->vertex()->point() - - pHalfedge->vertex()->point()); - Point_3 center_halfedge = pHalfedge->vertex()->point() + (v/2); - Vector_3 d = center_facet-center_halfedge; - return std::sqrt(d*d); - } - - void farthest_point_aligned(Vertex_handle &pVertexMin, - Vertex_handle &pVertexMax) - { - double xmin,xmax,ymin,ymax,zmin,zmax; - Vertex_handle pVertex_xMin = vertex_min(0,xmin); - Vertex_handle pVertex_xMax = vertex_max(0,xmax); - Vertex_handle pVertex_yMin = vertex_min(1,ymin); - Vertex_handle pVertex_yMax = vertex_max(1,ymax); - Vertex_handle pVertex_zMin = vertex_min(2,zmin); - Vertex_handle pVertex_zMax = vertex_max(2,zmax); - double xdiff = xmax-xmin; - double ydiff = ymax-ymin; - double zdiff = zmax-zmin; - if (xdiff >= (std::max)(ydiff,zdiff)) - { - pVertexMin = pVertex_xMin; - pVertexMax = pVertex_xMax; - } - else if (ydiff >= (std::max)(xdiff,zdiff)) - { - pVertexMin = pVertex_yMin; - pVertexMax = pVertex_yMax; - } - else - { - pVertexMin = pVertex_zMin; - pVertexMax = pVertex_zMax; - } - } - -}; // end class PolyhedronEx - - -#endif // POLYHEDRON_EX_H_INCLUDED - diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold.cpp index e99ef229c17..3ffe25e1707 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold.cpp @@ -53,7 +53,7 @@ int main(int argc, char * argv[]) CGAL::Timer task_timer; task_timer.start(); - const char* mesh_filename = (argc>1) ? argv[1] : "../data/bear.off"; + const char* mesh_filename = (argc>1) ? argv[1] : "data/bear.off"; std::ifstream in_mesh(mesh_filename); if(!in_mesh) { std::cerr << "Error: problem loading the input data" << std::endl; @@ -67,7 +67,7 @@ int main(int argc, char * argv[]) // -- the first line for the cones indices // -- the second line must be empty // -- the third line optionally provides the seam edges indices as 'e11 e12 e21 e22 e31 e32' etc. - const char* cone_filename = (argc>2) ? argv[2] : "../data/bear.selection.txt"; + const char* cone_filename = (argc>2) ? argv[2] : "data/bear.selection.txt"; // Read the cones and find the corresponding vertex_descriptor in the underlying mesh 'sm' typedef std::vector Cones_in_smesh_container; diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold_mapping.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold_mapping.cpp deleted file mode 100644 index 055a6bf0005..00000000000 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/orbifold_mapping.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#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::Surface_mesh SurfaceMesh; - -typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; -typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; - -typedef SurfaceMesh::Property_map Seam_edge_pmap; -typedef SurfaceMesh::Property_map Seam_vertex_pmap; - -typedef CGAL::Seam_mesh Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; - -namespace SMP = CGAL::Surface_mesh_parameterization; - -// Cones -typedef boost::unordered_map ConeMap; - -// VertexIndexMap -typedef boost::unordered_map Indices; -typedef boost::associative_property_map VertexIndexMap; - -// VertexUVMap -typedef SurfaceMesh::Property_map VertexUVMap; - -// Embedded_mesh type to regroup all the info in one class -typedef SMP::internal::Embedded_mesh Embedded_mesh; - -int main(int argc, char * argv[]) -{ - CGAL::Timer task_timer; - task_timer.start(); - - // Selection file that contains the cones and possibly the path between cones - // -- the first line for the cones indices - // -- the second line must be empty - // -- the third line optionally provides the seam edges indices as 'e11 e12 e21 e22 e31 e32' etc. - - const char* mesh_filename_A = (argc>1) ? argv[1] : "../data/bear.off"; - const char* cone_filename_A = (argc>2) ? argv[2] : "../data/bear.selection.txt"; - - const char* mesh_filename_B = (argc>3) ? argv[3] : "../data/sphere.off"; - const char* cone_filename_B = (argc>4) ? argv[4] : "../data/sphere2.selection.txt"; - - const SMP::Orbifold_type orb_type = SMP::Triangle; - - // Parameterizer - typedef SMP::Orbifold_Tutte_parameterizer_3 Parameterizer; - Parameterizer parameterizer(orb_type, SMP::Cotangent); - - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - // Parameterization of the first domain - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - SurfaceMesh sm_A; // underlying mesh of the seam mesh - std::ifstream in_mesh_A(mesh_filename_A); - if(!in_mesh_A) { - std::cerr << "Error: problem loading the input data" << std::endl; - } - in_mesh_A >> sm_A; - - // Read the cones and find the corresponding vertex_descriptor in the underlying mesh 'sm' - typedef std::vector Cones_in_smesh_container; - Cones_in_smesh_container cone_vds_in_sm_A; - SMP::internal::read_cones(sm_A, cone_filename_A, cone_vds_in_sm_A); - - // Two property maps to store the seam edges and vertices - Seam_edge_pmap seam_edge_pm_A = sm_A.add_property_map("e:on_seam", false).first; - Seam_vertex_pmap seam_vertex_pm_A = sm_A.add_property_map("v:on_seam",false).first; - - // The seam mesh - Mesh mesh_A(sm_A, seam_edge_pm_A, seam_vertex_pm_A); - - // Use the path provided between cones to create a seam mesh - SM_halfedge_descriptor smhd_A = mesh_A.add_seams(cone_filename_A); - if(smhd_A == SM_halfedge_descriptor() ) { - std::cout << "No seams were given in input, computing shortest paths between cones" << std::endl; - std::list seam_edges_A; - SMP::internal::compute_shortest_paths_between_cones(sm_A, cone_vds_in_sm_A, seam_edges_A); - - // Add the seams to the seam mesh - BOOST_FOREACH(SM_edge_descriptor e, seam_edges_A) { - mesh_A.add_seam(source(e, sm_A), target(e, sm_A)); - } - } - std::cout << mesh_A.number_of_seam_edges() << " seam edges" << std::endl; - - // Index map of the seam mesh (assuming a single connected component so far) - Indices indices_A; - VertexIndexMap vimap_A(indices_A); - int counter_A = 0; - BOOST_FOREACH(vertex_descriptor vd, vertices(mesh_A)) { - put(vimap_A, vd, counter_A++); - } - - // Mark the cones in the seam mesh - ConeMap cmap_A; - SMP::internal::locate_cones(mesh_A, cone_vds_in_sm_A, cmap_A); - - // The 2D points of the uv parametrisation will be written into this map - // Note that this is a halfedge property map, and that uv values - // are only stored for the canonical halfedges representing a vertex - VertexUVMap uvmap_A = sm_A.add_property_map("h:uv").first; - - // a halfedge on the (possibly virtual) border - // only used in output (will also be used to handle multiple connected components in the future) - halfedge_descriptor bhd_A = CGAL::Polygon_mesh_processing::longest_border(mesh_A, - CGAL::Polygon_mesh_processing::parameters::all_default()).first; - - parameterizer.parameterize(mesh_A, bhd_A, cmap_A, uvmap_A, vimap_A); - std::cout << "Parameterized the first domain in " << task_timer.time() << " seconds" << std::endl; - - std::ofstream out_A("orbifold_source.off"); - SMP::IO::output_uvmap_to_off(mesh_A, bhd_A, uvmap_A, out_A); - - Embedded_mesh emesh_A(mesh_A, cmap_A, vimap_A, uvmap_A, orb_type); - - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - // Parameterization of the second domain - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - - SurfaceMesh sm_B; // underlying mesh of the seam mesh - std::ifstream in_mesh_B(mesh_filename_B); - if(!in_mesh_B) { - std::cerr << "Error: problem loading the input data" << std::endl; - } - in_mesh_B >> sm_B; - - // Read the cones and find the corresponding vertex_descriptor in the underlying mesh 'sm' - typedef std::vector Cones_in_smesh_container; - Cones_in_smesh_container cone_vds_in_sm_B; - SMP::internal::read_cones(sm_B, cone_filename_B, cone_vds_in_sm_B); - - // Two property maps to store the seam edges and vertices - Seam_edge_pmap seam_edge_pm_B = sm_B.add_property_map("e:on_seam", false).first; - Seam_vertex_pmap seam_vertex_pm_B = sm_B.add_property_map("v:on_seam",false).first; - - // The seam mesh - Mesh mesh_B(sm_B, seam_edge_pm_B, seam_vertex_pm_B); - - // Use the path provided between cones to create a seam mesh - SM_halfedge_descriptor smhd_B = mesh_B.add_seams(cone_filename_B); - if(smhd_B == SM_halfedge_descriptor() ) { - std::cout << "No seams were given in input, computing shortest paths between cones" << std::endl; - std::list seam_edges_B; - SMP::internal::compute_shortest_paths_between_cones(sm_B, cone_vds_in_sm_B, seam_edges_B); - - // Add the seams to the seam mesh - BOOST_FOREACH(SM_edge_descriptor e, seam_edges_B) { - mesh_B.add_seam(source(e, sm_B), target(e, sm_B)); - } - } - std::cout << mesh_B.number_of_seam_edges() << " seam edges" << std::endl; - - // Index map of the seam mesh (assuming a single connected component so far) - Indices indices_B; - VertexIndexMap vimap_B(indices_B); - int counter_B = 0; - BOOST_FOREACH(vertex_descriptor vd, vertices(mesh_B)) { - put(vimap_B, vd, counter_B++); - } - - // Mark the cones in the seam mesh - ConeMap cmap_B; - SMP::internal::locate_cones(mesh_B, cone_vds_in_sm_B, cmap_B); - - // The 2D points of the uv parametrisation will be written into this map - // Note that this is a halfedge property map, and that uv values - // are only stored for the canonical halfedges representing a vertex - VertexUVMap uvmap_B = sm_B.add_property_map("h:uv").first; - - // a halfedge on the (possibly virtual) border - // only used in output (will also be used to handle multiple connected components in the future) - halfedge_descriptor bhd_B = CGAL::Polygon_mesh_processing::longest_border(mesh_B, - CGAL::Polygon_mesh_processing::parameters::all_default()).first; - - parameterizer.parameterize(mesh_B, bhd_B, cmap_B, uvmap_B, vimap_B); - std::cout << "Parameterized the second domain in " << task_timer.time() << " seconds" << std::endl; - - std::ofstream out_B("orbifold_target.off"); - SMP::IO::output_uvmap_to_off(mesh_B, bhd_B, uvmap_B, out_B); - - Embedded_mesh emesh_B(mesh_B, cmap_B, vimap_B, uvmap_B, orb_type); - - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - // Mapping - // *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* - - typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; -// typedef CGAL::Arr_segment_traits_2 Traits_2; - typedef CGAL::Arr_non_caching_segment_traits_2 Traits_2; - typedef CGAL::Arrangement_2 Arrangement_2; - typedef SMP::Orbifold_sphere_mapper Orb_sphere_mapper; - - Orb_sphere_mapper mapper; - mapper.compute_map_from_sphere_embeddings(emesh_A, emesh_B); - std::cout << "Finished mapping in " << task_timer.time() << " seconds" << std::endl; -} diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp deleted file mode 100644 index 69f92205dfd..00000000000 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/parameterization_tests.cpp +++ /dev/null @@ -1,401 +0,0 @@ -#define CGAL_CHECK_EXPENSIVE - -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include - -#include -#include - -namespace SMP = CGAL::Surface_mesh_parameterization; - -typedef CGAL::Simple_cartesian Kernel; -typedef Kernel::Point_2 Point_2; -typedef Kernel::Point_3 Point_3; - -#define POLY_MESH // Polyhedron mesh -#ifdef POLY_MESH -#define MVC_POLY_MESH -#define BARY_POLY_MESH -#define ARAP_POLY_MESH -#endif - -#define SURF_MESH // Surface_mesh -#ifdef SURF_MESH -#define ARAP_SURF_MESH -#endif - -#define PM_SEAM_MESH // Polyhedron-based seam mesh -#ifdef PM_SEAM_MESH -#define POLY_MESH -#define ARAP_PM_SEAM_MESH -#endif - -#define SM_SEAM_MESH // Surface_mesh-based seam mesh -#ifdef SM_SEAM_MESH -#define SURF_MESH -#define ARAP_SM_SEAM_MESH -#endif - -// #define REDIRECT_OUTPUT - -#ifdef POLY_MESH -typedef CGAL::Polyhedron_3 PMesh; - -typedef boost::graph_traits::vertex_descriptor PM_vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor PM_halfedge_descriptor; - -typedef CGAL::Unique_hash_map PM_UV_hmap; -typedef boost::associative_property_map PM_UV_pmap; -#endif - -#ifdef SURF_MESH -typedef CGAL::Surface_mesh SMesh; - -typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; - -typedef SMesh::Property_map SM_UV_pmap; -#endif - -#ifdef SM_SEAM_MESH -typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; - -typedef SMesh::Property_map SM_seam_edge_pmap; -typedef SMesh::Property_map SM_seam_vertex_pmap; - -typedef CGAL::Seam_mesh - SM_Seam_mesh; - -typedef boost::graph_traits::vertex_descriptor SM_SE_vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor SM_SE_halfedge_descriptor; -#endif - -#ifdef PM_SEAM_MESH -typedef boost::graph_traits::edge_descriptor PM_edge_descriptor; - -typedef CGAL::Unique_hash_map PM_seam_edge_hmap; -typedef boost::associative_property_map PM_seam_edge_pmap; -typedef CGAL::Unique_hash_map PM_seam_vertex_hmap; -typedef boost::associative_property_map PM_seam_vertex_pmap; - -typedef CGAL::Seam_mesh - PM_Seam_mesh; - -typedef boost::graph_traits::vertex_descriptor PM_SE_vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor PM_SE_halfedge_descriptor; -#endif - -int main(int argc, char * argv[]) -{ - std::cout.precision(17); - CGAL::set_pretty_mode(std::cout); - -#ifdef REDIRECT_OUTPUT - std::freopen("/home/mrouxell/POLY_MESH.txt", "w", stdout); -#endif - -// std::ifstream in((argc>1)?argv[1]:"../data/tiny_nef.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/nefertiti.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/lion.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/blob.off"); - std::ifstream in((argc>1)?argv[1]:"/home/mrouxell/Data/OFF/mushroom.off"); -// std::ifstream in((argc>1)?argv[1]:"/home/mrouxell/Data/OFF/lion-head.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/three_peaks.off"); -// std::ifstream in((argc>1)?argv[1]:"/home/mrouxell/Data/OFF/three_peaks_dense.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/cow_with_hole.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/cow_dense.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/cow_densified.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/mushroom_big_hole.off"); -// std::ifstream in((argc>1)?argv[1]:"../data/mushroom_hole_1.off"); - -// const char* selection = "../data/lion.selection.txt"; - const char* selection = "/home/mrouxell/mushroom.selection.txt"; - - if(!in) { - std::cerr << "Problem loading the input data" << std::endl; - return 1; - } - - // *************************************************************************** - // Default case - // *************************************************************************** - -#ifdef MVC_POLY_MESH - { - std::cout << "MVC POLY MESH" << std::endl; - - PMesh pm; - in >> pm; - - PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first; - - CGAL::Unique_hash_map > uvhm; - boost::associative_property_map< - CGAL::Unique_hash_map > > uvpm(uvhm); - // Go to default (aka Mean values) - SMP::parameterize(pm, hd, uvpm); - - std::cout << "Parameterized with Default (Mean Values)!" << std::endl; - } -#endif - - // *************************************************************************** - // Barycentric mapping - // *************************************************************************** - -#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 > uvhm; - boost::associative_property_map< - CGAL::Unique_hash_map > > uvpm(uvhm); - // Indices map - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(hd, pm), pm), - pm, - boost::make_function_output_iterator( - SMP::internal::Index_map_filler(pm, indices))); - - // Vertex parameterized map - boost::unordered_set vs; - SMP::internal::Bool_property_map > vpm(vs); - typename SMP::Barycentric_mapping_parameterizer_3 parameterizer; - - parameterizer.parameterize(pm, hd, uvpm, boost::make_assoc_property_map(indices), vpm); - - std::cout << "Parameterized with Barycentric!" << std::endl; - } -#endif - - // *************************************************************************** - // ARAP WITH POLY_MESH - // *************************************************************************** - -#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; - - // UV map - CGAL::Unique_hash_map > uvhm; - boost::associative_property_map< - CGAL::Unique_hash_map > > uvpm(uvhm); - - // Indices map - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(hd, pm), pm), - pm, - boost::make_function_output_iterator( - SMP::internal::Index_map_filler(pm, indices))); - - boost::associative_property_map vipm(indices); - - // Vertex parameterized map - boost::unordered_set vs; - SMP::internal::Bool_property_map > vpm(vs); - - // Parameterizer - typename SMP::ARAP_parameterizer_3 parameterizer; - SMP::Error_code status = parameterizer.parameterize(pm, hd, uvpm, vipm, vpm); - - if(status != SMP::OK) - std::cout << "Encountered a problem: " << status << std::endl; - else - std::cout << "Parameterized with ARAP!" << std::endl; - } -#endif - - // *************************************************************************** - // ARAP WITH SURF_MESH - // *************************************************************************** - -#ifdef REDIRECT_OUTPUT - std::freopen("/home/mrouxell/SURF_MESH.txt", "w", stdout); -#endif - -#ifdef ARAP_SURF_MESH - { - std::cout << "ARAP SURF MESH" << std::endl; - - SMesh sm; - in.clear(); - in.seekg(0, std::ios::beg); - in >> sm; - - SM_halfedge_descriptor bhd = - CGAL::Polygon_mesh_processing::longest_border(sm).first; - - CGAL::Unique_hash_map > uvhm; - boost::associative_property_map< - CGAL::Unique_hash_map > > uv_pm(uvhm); - - // Indices map - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, sm), sm), - sm, - boost::make_function_output_iterator( - SMP::internal::Index_map_filler(sm, indices))); - boost::associative_property_map vipm(indices); - - boost::unordered_set vs; - SMP::internal::Bool_property_map< boost::unordered_set > vpm(vs); - - typename SMP::ARAP_parameterizer_3 parameterizer; - parameterizer.parameterize(sm, bhd, uv_pm, vipm, vpm); - } -#endif - - // *************************************************************************** - // ARAP WITH SEAM_MESH (SM) - // *************************************************************************** - -#ifdef ARAP_SM_SEAM_MESH - { - std::cout << "ARAP SURF SEAM MESH" << std::endl; - - SMesh sm; - in.clear(); - in.seekg(0, std::ios::beg); - in >> sm; - - 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_Seam_mesh mesh(sm, seam_edge_pm, seam_vertex_pm); - SM_halfedge_descriptor smhd = mesh.add_seams(selection); - if(smhd == SM_halfedge_descriptor() ) { - std::cerr << "Warning: No seams in input" << std::endl; - } - - // 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 - SM_UV_pmap uv_pm = sm.add_property_map("h:uv").first; - - // a halfedge on the (possibly virtual) border - SM_SE_halfedge_descriptor bhd = CGAL::Polygon_mesh_processing::longest_border(mesh).first; - - // Indices - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - SMP::internal::Index_map_filler(mesh, indices))); - boost::associative_property_map vipm(indices); - - // Parameterized - boost::unordered_set vs; - SMP::internal::Bool_property_map > vpm(vs); - - typename SMP::ARAP_parameterizer_3 parameterizer; - parameterizer.parameterize(mesh, bhd, uv_pm, vipm, vpm); - - } -#endif - - // *************************************************************************** - // ARAP WITH SEAM_MESH (POLY) - // *************************************************************************** - -#ifdef ARAP_PM_SEAM_MESH - { - std::cout << "ARAP POLY SEAM MESH" << std::endl; - - PMesh pm; - in.clear(); - in.seekg(0, std::ios::beg); - in >> pm; - - PM_seam_edge_hmap seam_edge_hm(false); - PM_seam_edge_pmap seam_edge_pm(seam_edge_hm); - PM_seam_vertex_hmap seam_vertex_hm(false); - PM_seam_vertex_pmap seam_vertex_pm(seam_vertex_hm); - - PM_Seam_mesh mesh(pm, seam_edge_pm, seam_vertex_pm); - PM_halfedge_descriptor pmhd = mesh.add_seams(selection); - if(pmhd == PM_halfedge_descriptor() ) { - std::cerr << "Warning: No seams in input" << std::endl; - } - - // 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 - PM_UV_hmap uv_hm; - PM_UV_pmap uv_pm(uv_hm); - - // a halfedge on the (possibly virtual) border - PM_SE_halfedge_descriptor bhd = CGAL::Polygon_mesh_processing::longest_border(mesh).first; - - // Indices - typedef boost::unordered_map Indices; - Indices indices; - CGAL::Polygon_mesh_processing::connected_component( - face(opposite(bhd, mesh), mesh), - mesh, - boost::make_function_output_iterator( - SMP::internal::Index_map_filler(mesh, indices))); - boost::associative_property_map vipm(indices); - - // Parameterized - boost::unordered_set vs; - SMP::internal::Bool_property_map > vpm(vs); - - typename SMP::ARAP_parameterizer_3 parameterizer; - parameterizer.parameterize(mesh, bhd, uv_pm, vipm, vpm); - } -#endif - - return 0; -} diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_sphere_mapping.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_sphere_mapping.h deleted file mode 100644 index f7d09310798..00000000000 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_sphere_mapping.h +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright (c) 2016 GeometryFactory (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Mael Rouxel-Labbé - -#ifndef CGAL_SURFACE_MESH_PARAMETERIZATION_ORBIFOLD_TUTTE_SPHERE_MAPPING_H -#define CGAL_SURFACE_MESH_PARAMETERIZATION_ORBIFOLD_TUTTE_SPHERE_MAPPING_H - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace Surface_mesh_parameterization { - -namespace internal { - -/// Output a container of triangles as a .off file. -template -void output_triangle_set(Triangle_container& triangles, - const char* filename) -{ - typedef typename Triangle_container::value_type Triangle_2; - typedef typename Triangle_2::R Kernel; - typedef typename Kernel::Point_2 Point_2; - - const std::size_t triangles_n = triangles.size(); - - std::map points_to_indices; - std::vector ids_to_print; - ids_to_print.reserve(3 * triangles_n); - - std::ofstream out(filename); - std::ostringstream faces_ss; - - int counter = 0; - typename Triangle_container::const_iterator trit = triangles.begin(), - trend = triangles.end(); - for(; trit!=trend; ++trit) { - const Triangle_2& tr = *trit; - std::vector ids(3); - - for(std::size_t i=0; i<3; ++i) { - std::pair::iterator, bool> is_insert_successful = - points_to_indices.insert(std::make_pair(tr[i], counter)); - if(!is_insert_successful.second) { - ids[i] = is_insert_successful.first->second; - } else { - ids[i] = counter; - ids_to_print.push_back(tr[i]); - ++counter; - } - } - - faces_ss << "3 " << ids[0] << " "<< ids[1] << " " << ids[2] << '\n'; - } - - // OFF header - out << "OFF" << '\n'; - out << points_to_indices.size() << " " << triangles_n << " 0" << '\n'; - - // outputs points - typename std::vector::iterator it = ids_to_print.begin(), - end = ids_to_print.end(); - for(; it!=end; ++it) { - out << *it << " 0" << '\n'; - } - - // outputs faces - out << faces_ss.str() << std::endl; -} - -/// Outputs an arrangement as a .off file. -template -void output_arrangement_to_off(const Arrangement& arr, - std::ofstream& out) -{ - typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator; - typedef typename Arrangement::Edge_const_iterator Edge_const_iterator; - typedef typename Arrangement::Point_2 Exact_point_2; - - std::cout << "Arrangement with " << arr.number_of_vertices() << " vertices and " - << arr.number_of_edges() << " edges" << std::endl; - - std::map indices; - - std::ostringstream out_vertices; - std::size_t vertices_counter = 0; - - // arrangement vertices - Vertex_const_iterator vit = arr.vertices_begin(), vend = arr.vertices_end(); - for(; vit!=vend; ++vit) { - std::pair::iterator, bool> is_insert_successful = - indices.insert(std::make_pair(vit->point(), vertices_counter)); - if(is_insert_successful.second) { - out_vertices << vit->point() << " 0" << '\n'; - ++vertices_counter; - } - } - CGAL_assertion(arr.number_of_vertices() == vertices_counter); - - out << "OFF" << "\n" << std::endl; - out << vertices_counter << " " << arr.number_of_edges() << " 0" << '\n'; - out << out_vertices.str(); - - // arrangement edges - Edge_const_iterator eit = arr.edges_begin(), eend = arr.edges_end(); - for(; eit!=eend; ++eit) { - out << "3 " << indices[eit->curve().source()] << " " - << indices[eit->curve().target()] << " " - << indices[eit->curve().source()] << '\n'; - } - - out << std::endl; -} - -// A type to regroup all the info and avoid having to pass it all in each function. -template -class Embedded_mesh -{ -public: - typedef SeamMesh_ SeamMesh; - typedef ConeMap_ ConeMap; - typedef VertexIndexMap_ VertexIndexMap; - typedef VertexUVMap_ VertexUVMap; - - const SeamMesh& mesh; - const ConeMap& cmap; - const VertexIndexMap vimap; - const VertexUVMap uvmap; - const Orbifold_type orb_type; - - Embedded_mesh(const SeamMesh& mesh, - const ConeMap& cmap, - const VertexIndexMap vimap, - const VertexUVMap uvmap, - const Orbifold_type orb_type) - : - mesh(mesh), - cmap(cmap), - vimap(vimap), - uvmap(uvmap), - orb_type(orb_type) - { } -}; - -// Affine transformation to express A = T*B + V -// @fixme transf needs a translation component too (for orb type IV) -template -class Affine_transformation -{ -public: - typedef typename Kernel::FT NT; - typedef typename Kernel::Point_2 Point_2; - - // rotation of 'angle' around 'center' - Eigen::Matrix3d transformation_matrix; - -public: - /// Apply the affine transformation to the point `p`. - Point_2 transform(const Point_2& p) const - { - Eigen::Vector3d v, res; - v(0) = p.x(); v(1) = p.y(); v(2) = 1; - res = transformation_matrix * v; - Point_2 newp(res(0), res(1)); -// std::cout << "------------------------------ transformed " << p << " in " << newp << std::endl; - return newp; - } - - const Eigen::Matrix3d& get_tr() const - { - return transformation_matrix; - } - - /// Multiply the current transformation by `new_rot` to get a single transformation matrix. - void combine_transformations(const Eigen::Matrix3d& new_transf) - { - transformation_matrix = transformation_matrix * new_transf; - } - - /// Create a transformation matrix based on the translation [tx, ty]. - Affine_transformation(const NT tx, const NT& ty) - { - transformation_matrix << 1, 0, tx, - 0, 1, ty, - 0, 0, 1; - - std::cout << "built (translation) matrix for " << tx << " and " << ty << std::endl; - std::cout << transformation_matrix << std::endl; - } - - /// Create a transformation matrix based on the rotation around `center` of `angle`. - Affine_transformation(const NT angle, const Point_2& center) - { - const NT c = std::cos(angle); - const NT s = std::sin(angle); - const NT center_x = center.x(); - const NT center_y = center.y(); - transformation_matrix << c, -s, center_x - c * center_x + s * center_y, - s, c, center_y - s * center_x - c * center_y, - 0, 0, 1; - - std::cout << "built matrix for " << center << " and angle: " << angle << std::endl; - std::cout << transformation_matrix << std::endl; - } - - Affine_transformation() - { - transformation_matrix << 1, 0, 0, - 0, 1, 0, - 0, 0, 1; - } -}; - -// halfedge that carries a transformation that is used to compute the coordinates -// of the incident faces in the tiled space. -template -class halfedge_with_transformation -{ - typedef halfedge_with_transformation Self; - -public: - typedef SeamMesh Seam_mesh; - typedef typename internal::Kernel_traits::Kernel Kernel; - typedef Affine_transformation Transformation; - - typedef typename Seam_mesh::TriangleMesh TriangleMesh; - typedef typename boost::graph_traits::halfedge_descriptor TM_halfedge_descriptor; - - TM_halfedge_descriptor tmhd; - Transformation transformation; - - halfedge_with_transformation(TM_halfedge_descriptor tmhd, - const Transformation& transformation) - : - tmhd(tmhd), transformation(transformation) - { } -}; - -} // namespace internal - - -template -class Orbifold_sphere_mapper -{ - // Types related to the embedded mesh - typedef typename EmbeddedMesh::ConeMap ConeMap; - typedef typename EmbeddedMesh::SeamMesh Seam_mesh; - typedef typename EmbeddedMesh::VertexIndexMap VertexIndexMap; - typedef typename EmbeddedMesh::VertexUVMap VertexUVMap; - - // Graph types for the seam mesh - 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::vertex_iterator vertex_iterator; - - // Graph types for the underlying mesh - typedef typename Seam_mesh::TriangleMesh TriangleMesh; - typedef typename boost::graph_traits::vertex_descriptor TM_vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor TM_halfedge_descriptor; - - // Kernel types - typedef typename internal::Kernel_traits::Kernel Kernel; - typedef typename Kernel::FT NT; - typedef typename Kernel::Point_2 Point_2; - typedef typename Kernel::Segment_2 Segment_2; - typedef typename Kernel::Vector_2 Vector_2; - typedef typename Kernel::Triangle_2 Triangle_2; - - // Arrangement types - typedef typename Arrangement::Geometry_traits_2 Arr_traits; - typedef CGAL::Arr_default_overlay_traits Overlay_traits; - - // Exact kernel types - typedef typename Arr_traits::Kernel Exact_kernel; - typedef typename Arr_traits::X_monotone_curve_2 Arr_segment_2; - - typedef typename Exact_kernel::FT Exact_NT; - typedef typename Exact_kernel::Point_2 Exact_point_2; - typedef typename Exact_kernel::Segment_2 Exact_segment_2; - typedef CGAL::Cartesian_converter IK_to_EK; - - // Transformation types - typedef internal::Affine_transformation Aff_tr; - typedef internal::halfedge_with_transformation halfedge_w_tr; - - // Triangulation type - typedef CGAL::Triangulation_2 Triangulation; - - const IK_to_EK to_exact; - - /// For all seam edges, mark both halfedges with the transformation to apply - /// to obtain the next tile's coordinates from the previous tile. - template - void tag_seam_segment(const EmbeddedMesh& emesh, - const Seam_halfedges_segment& seam_segment, - SeamTransformationMap& seam_transformations, - BorderHalfedges& border_halfedges, - NT ang) const - { - std::cout << "Segment of length " << seam_segment.size() << std::endl; - - const Seam_mesh& mesh = emesh.mesh; - const VertexIndexMap vimap = emesh.vimap; - const VertexUVMap uvmap = emesh.uvmap; - - // s and t are the two sides of the seam - vertex_descriptor vf_s = target(seam_segment.front().first, mesh); - vertex_descriptor vf_t = source(seam_segment.front().second, mesh); - vertex_descriptor ve_s = source(seam_segment.back().first, mesh); - vertex_descriptor ve_t = target(seam_segment.back().second, mesh); - - const bool is_reversed = (get(vimap, ve_s) == get(vimap, ve_t)); - - if(is_reversed) { - ang *= -1; - } - - const Aff_tr identity; - Aff_tr trs, trt; - - if(ang == 1) { // translation - trs = Aff_tr(-2., 0.); - trt = Aff_tr( 2., 0.); - } - else { - const Point_2& pb = is_reversed ? get(uvmap, ve_s) : get(uvmap, vf_s); - const Point_2& pe = is_reversed ? get(uvmap, ve_t) : get(uvmap, vf_t); - - trs = Aff_tr(+ 2 * CGAL_PI / ang /*angle*/, pb /*center*/); - trt = Aff_tr(- 2 * CGAL_PI / ang /*angle*/, pe /*center*/); - } - - typename Seam_halfedges_segment::const_iterator it = seam_segment.begin(), - end = seam_segment.end(); - for(; it!=end; ++it) { - // Associate to the halfedges on the seam a transformation that can be - // thought of as: - // "if I cross this border, which affine transformation must I apply to - // a triangle of the initial mesh to obtain the coordinates of this triangle - // in the next tile" - const halfedge_descriptor hd1 = it->first; - const TM_halfedge_descriptor base_hd1 = hd1.tmhd; - seam_transformations[base_hd1] = trs; - - const halfedge_descriptor hd2 = it->second; - const TM_halfedge_descriptor base_hd2 = hd2.tmhd; - seam_transformations[base_hd2] = trt; - - // The initial border edges are by definition in the initial mesh so they - // do not have a transformation at the beginning - const halfedge_w_tr hdt1(base_hd1, identity); - const halfedge_w_tr hdt2(base_hd2, identity); - border_halfedges.push_back(hdt1); - border_halfedges.push_back(hdt2); - } - } - - /// Go through the seam edges to collect the initial border halfedges and mark the - /// transformations on the seam. - template - void compute_initial_border(const EmbeddedMesh& emesh, - SeamTransformationMap& seam_transformations, - BorderHalfedges& border_halfedges) const - { - const Seam_mesh& mesh = emesh.mesh; - - // the angles at the cones - typedef std::vector Angle_container; - const Angle_container& angs = get_angles_at_cones(emesh.orb_type); - - // Find the cone tagged 'First_unique_cone' - int start_cone_index = -1; // index of the beginning of the seam (useless here) - vertex_descriptor start_cone; - internal::find_start_cone(emesh.cmap, emesh.vimap, start_cone, start_cone_index); - - // By property of the seam mesh, the canonical halfedge that points to start_cone - // is on the seam, and is not on the border - const halfedge_descriptor hd = halfedge(start_cone, mesh); - CGAL_precondition(mesh.has_on_seam(hd)); - halfedge_descriptor bhd = opposite(hd, mesh); - CGAL_precondition(is_border(bhd, mesh)); - - // To count the segments of the seam (a segment is a set of edges between two cones) - // there are 3 segment max in orb types I, II, III and IV - std::size_t segment_index = 0; - - // The segments between cones - typedef std::vector > Seam_halfedges_segment; - Seam_halfedges_segment seam_segment; - - // Walk the border till we find the first cone again, while tagging the seam edges - // with the correct transformation (such that if we go over the seam, we unfold - // properly in the plane - while(true) { // breaking at the last cone - // get the two halfedges that are not on the border - const halfedge_descriptor hd1 = opposite(bhd, mesh); - - // The non-border halfedge with same vertices (in the underlying mesh of the seam - // mesh) as bhd is simply bhd with the 'seam' boolean set to false - const halfedge_descriptor hd2(bhd, false /*not on seam*/); - - CGAL_assertion(segment_index < angs.size()); - NT ang = angs[segment_index]; - - seam_segment.push_back(std::make_pair(hd1, hd2)); - - // Check if we have reached the end of the seam - vertex_descriptor bhd_target = target(bhd, mesh); - typename ConeMap::const_iterator is_in_map = emesh.cmap.find(bhd_target); - if(is_in_map != emesh.cmap.end()) { - tag_seam_segment(emesh, - seam_segment, - seam_transformations, - border_halfedges, - ang); - - // reached the end of the seam - if(is_in_map->second == Second_unique_cone) { - break; - } - - std::cout << "-------------------------" << std::endl; - seam_segment.clear(); - ++segment_index; - } - - // move to the next halfedge couple (walking on the border of the seam) - bhd = next(bhd, mesh); - CGAL_postcondition(mesh.has_on_seam(bhd) && is_border(bhd, mesh)); - } - - std::cout << "built border & tags" << std::endl; - std::cout << border_halfedges.size() << " border halfedges" << std::endl; - CGAL_postcondition(border_halfedges.size() == 2 * mesh.number_of_seam_edges()); - } - - /// Insert all the base faces in the set of unique faces. - template - void mark_base_mesh_faces(const EmbeddedMesh& emesh, - Face_set& inserted_faces, - Face_container& faces_to_draw) const - { - const Seam_mesh& mesh = emesh.mesh; - const VertexUVMap uvmap = emesh.uvmap; - - BOOST_FOREACH(face_descriptor fd, faces(mesh)) { - const halfedge_descriptor hd = halfedge(fd, mesh); - const vertex_descriptor vda = source(hd, mesh); - const vertex_descriptor vdb = target(hd, mesh); - const vertex_descriptor vdc = target(next(hd, mesh), mesh); - - const Point_2& tpa = get(uvmap, vda); - const Point_2& tpb = get(uvmap, vdb); - const Point_2& tpc = get(uvmap, vdc); - -// std::cout << "add " << tpa << " " << tpb << " " << tpc << std::endl; - - const Triangle_2 tr(tpa, tpb, tpc); - faces_to_draw.push_back(tr); - - const Point_2 bar = CGAL::barycenter(tpa, 1., tpb, 1., tpc, 1.); - - // ugly hack to get rid of imprecisions @fixme - // uv values are close to 1 so *1e7 is not too dangerous - NT barx = 1e7 * bar.x(); - NT bary = 1e7 * bar.y(); - barx = static_cast(barx >= 0 ? barx + 0.5 : barx - 0.5); - bary = static_cast(bary >= 0 ? bary + 0.5 : bary - 0.5); - inserted_faces.insert(std::make_pair(barx, bary)); - } - } - - template - void expand_border(const EmbeddedMesh& source_embedded_mesh, - const Triangulation& tr, - const SeamTransformationMap& seam_transformations, - const BorderHalfedges& current_border_halfedges, - BorderHalfedges& next_border_halfedges, - Face_container& faces_to_draw, - Barycenter_set& inserted_faces, - Arr_segments& arr_segments) const - { - const Seam_mesh& mesh = source_embedded_mesh.mesh; - const VertexUVMap uvmap = source_embedded_mesh.uvmap; - const TriangleMesh& tm = mesh.mesh(); - - typename BorderHalfedges::const_iterator bhit = current_border_halfedges.begin(), - bhend = current_border_halfedges.end(); - for(; bhit!=bhend; ++bhit) { - // Get the next border edge - const halfedge_w_tr hdt = *bhit; - const TM_halfedge_descriptor hd = hdt.tmhd; - -// std::cout << "at halfedge " << source(hd, tm) << " " << target(hd, tm) << std::endl; -// halfedge_descriptor shd(hd); -// std::cout << "that is " << get(uvmap, (source(shd, mesh))) << " || " -// << get(uvmap, (target(shd, mesh))) << std::endl; - - // the transformation stocked in the halfedge - Aff_tr hd_transformation = hdt.transformation; - -// std::cout << "base transformation: " << std::endl; -// std::cout << hd_transformation.get_tr() << std::endl; - - // check if [ab] with the current transformation intersects, otherwise stops - const Point_2& tpa = hd_transformation.transform(get(uvmap, target(hd, mesh))); - const Point_2& tpb = hd_transformation.transform(get(uvmap, source(hd, mesh))); - const Segment_2 es_ab(tpa, tpb); - if(!is_intersecting(tr, es_ab)) { -// std::cout << "no intersection" << std::endl; - continue; - } - - // There is an intersection and we must insert the face incident to ohd. - // Get the opposite halfedge, which is incident to the triangle that we will add - // (with transformed coordinates) - const TM_halfedge_descriptor ohd = opposite(hd, tm); -// TM_vertex_descriptor tmvdc = target(next(ohd, tm), tm); // third point -// std::cout << "third " << tmvdc; -// std::cout<< " with pos: " << get(uvmap, target(halfedge_descriptor(next(ohd, tm)), mesh)) << std::endl; - - // if the edge is on a seam, we combine the current transformation - // with the transformation assigned to the seam halfedge to obtain the transformation - if(mesh.has_on_seam(hd)) { - typename SeamTransformationMap::const_iterator it = seam_transformations.find(hd); - CGAL_assertion(it != seam_transformations.end()); - Aff_tr seam_transf = it->second; - hd_transformation.combine_transformations(seam_transf.get_tr()); - } - - const TM_halfedge_descriptor hd_bc = next(ohd, tm); - const vertex_descriptor vdc = target(halfedge_descriptor(hd_bc), mesh); - const Point_2& tpc = hd_transformation.transform(get(uvmap, vdc)); - - const Exact_point_2& etpa = to_exact(tpa); - const Exact_point_2& etpb = to_exact(tpb); - const Exact_point_2& etpc = to_exact(tpc); - - // Check if we have already inserted the face incident to ohd in the arrangement - const Point_2& bar = CGAL::barycenter(tpa, 1., tpb, 1., tpc, 1.); - - // ugly hack to get rid of imprecisions @fixme - NT barx = 1e7 * bar.x(); - NT bary = 1e7 * bar.y(); - barx = static_cast(barx >= 0 ? barx + 0.5 : barx - 0.5); - bary = static_cast(bary >= 0 ? bary + 0.5 : bary - 0.5); - - std::pair is_insert_successful = - inserted_faces.insert(std::make_pair(barx, bary)); - if(!is_insert_successful.second) // triangle has already been considered - continue; - - // std::cout.precision(20); - // std::cout << "new triangle with bar: " << barx << " || " << bary << std::endl; - -// std::cout << "tps: " << tpa << " " << tpb << " " << tpc << std::endl; - - const Triangle_2 tr(tpa, tpb, tpc); - faces_to_draw.push_back(tr); - - // Add the new segments - const Exact_segment_2 es_ac(etpa, etpc); - const Exact_segment_2 es_bc(etpb, etpc); - // There is no need to insert ab because we have already inserted it - // at previous steps. Leaving it here for clarity. -// arr_segments.push_back(Exact_segment_2(etpa, etpb)) - arr_segments.push_back(es_ac); - arr_segments.push_back(es_bc); - - // Insert the (other) edges of the face incident to ohd - // there are two "new" border edges: ac and bc - const TM_halfedge_descriptor hd_ac = prev(ohd, tm); - - const halfedge_w_tr hdt_ac(hd_ac, hd_transformation); - next_border_halfedges.push_back(hdt_ac); - - const halfedge_w_tr hdt_bc(hd_bc, hd_transformation); - next_border_halfedges.push_back(hdt_bc); - } - } - - /// Check if a given segment intersects the target mesh (actually, a triangulation - /// of the -- slightly grown -- convex hull of the target mesh) - bool is_intersecting(const Triangulation& tr, - const Segment_2& segment) const - { - typename Kernel::Construct_triangle_2 triangle_functor; - typename Kernel::Do_intersect_2 do_intersect_2_functor; - - // Brute force, but the triangulation _should_ have very few faces - typedef typename Triangulation::Finite_faces_iterator Finite_faces_iterator; - Finite_faces_iterator fit = tr.finite_faces_begin(), end = tr.finite_faces_end(); - for(; fit!=end; fit++) { - const Triangle_2 tr = triangle_functor(fit->vertex(0)->point(), - fit->vertex(1)->point(), - fit->vertex(2)->point()); - if(do_intersect_2_functor(segment, tr)) - return true; - } - - return false; - } - - /// Functor used to offer dereferencing vertex_iterator to UV values - struct Vd_to_uv - { - typedef vertex_iterator argument_type; - typedef Point_2 result_type; - - const VertexUVMap uvmap; - - result_type operator()(vertex_iterator vit) const - { - vertex_descriptor vd = *vit; - return get(uvmap, vd); - } - - result_type operator()(vertex_descriptor vd) const - { - return get(uvmap, vd); - } - - Vd_to_uv(const VertexUVMap uvmap) : uvmap(uvmap) { } - }; - - /// Compute the convex hull of a mesh, and triangulate the convex hull. - void triangulate_convex_hull(const EmbeddedMesh& emesh, - Triangulation& tr) const - { - const Seam_mesh& mesh = emesh.mesh; - const VertexUVMap uvmap = emesh.uvmap; - - // compute the convex hull of the mesh - std::vector convex_hull_pts; - const Vd_to_uv vd_to_uv(uvmap); - CGAL::convex_hull_2(boost::make_transform_iterator(mesh.vertices_begin(), vd_to_uv), - boost::make_transform_iterator(mesh.vertices_end(), vd_to_uv), - std::back_inserter(convex_hull_pts)); - - std::cout << convex_hull_pts.size() << " pts on the convex hull" << std::endl; - - /// Trick: slightly grow the convex hull so that the source mesh will completely - /// englobe the target mesh - - // compute the center point (ish) - const NT weight = 1. / convex_hull_pts.size(); - NT bx = 0., by = 0.; - for(std::size_t i=0; i SeamTransformationMap; - SeamTransformationMap seam_transformations; - - // Border_halfedes is the border of the expending border of the source mesh. - // We grow it until the border does not intersect the target mesh anymore. - // note: ideally, it'd be a set, but I don't have a good hash function for it - // and in practice it's not slower to use a vector. - typedef std::vector BorderHalfedges; - BorderHalfedges current_border_halfedges, next_border_halfedges; - current_border_halfedges.reserve(2 * mesh.number_of_seam_edges()); - - compute_initial_border(source_embedded_mesh, seam_transformations, current_border_halfedges); - - CGAL_postcondition(seam_transformations.size() == 2 * mesh.number_of_seam_edges()); - CGAL_postcondition(current_border_halfedges.size() == 2 * mesh.number_of_seam_edges()); - - // Segments that will form the arrangement obtained by growing the source mesh - std::vector arr_segments; - arr_segments.reserve(num_edges(mesh)); - - // Fill the arrangement with the edges of the source mesh - BOOST_FOREACH(edge_descriptor ed, edges(mesh)) { - const vertex_descriptor vds = source(ed, mesh); - const vertex_descriptor vdt = target(ed, mesh); - arr_segments.push_back(Exact_segment_2(to_exact(get(uvmap, vds)), - to_exact(get(uvmap, vdt)))); - } - -// -------------- INFO & OUTPUT - std::cout << num_edges(mesh.mesh()) << " edges in the base mesh" << std::endl; - std::cout << mesh.number_of_seam_edges() << " seams" << std::endl; - std::cout << num_edges(mesh) << " edges in the source seam mesh" << std::endl; - std::cout << arr_segments.size() << " segments in the base arrangement" << std::endl; - CGAL_postcondition(arr_segments.size() == num_edges(mesh)); - - Arrangement source_arrangement; - CGAL::insert(source_arrangement, arr_segments.begin(), arr_segments.end()); - - // Write the arrangement to a file. - std::ofstream arr_out("arr_source.off"); - internal::output_arrangement_to_off(source_arrangement, arr_out); -// -------------------- - - // Keep a set of faces. Can't sort by IDs, so using a set of barycenters instead... - // Problem is that rotations introduce imprecisions so we can't just get a point - // Some (super) ugly hack is to only consider part of the mantissa - typedef std::set > Barycenter_set; - Barycenter_set inserted_faces; - std::vector faces_to_draw; // just for output - mark_base_mesh_faces(source_embedded_mesh, inserted_faces, faces_to_draw); - - // The target mesh is a dense mesh, which makes it expensive to check for intersections. - // Instead, build a triangulation of the convex hull, which is "close enough" - // since the parameterisations give somewhat convex results - Triangulation tr; - triangulate_convex_hull(target_embedded_mesh, tr); - - // Expand the border until it doesn't intersect the target mesh - std::cout << "initial border of length: " << current_border_halfedges.size() << std::endl; - int counter = 0; - while(true) { - // For all halfedges in the current border (non-continuous), add the incident - // triangle if the shared edge intersects the target mesh - expand_border(source_embedded_mesh, tr, seam_transformations, - current_border_halfedges, next_border_halfedges, - faces_to_draw, inserted_faces, arr_segments); - ++counter; - - std::cout << "iteration: " << counter << std::endl; - std::cout << arr_segments.size() << " segments in the arrangement" << std::endl; - std::cout << next_border_halfedges.size() << " in the next loop" << std::endl; - - if(next_border_halfedges.empty()) - break; - - current_border_halfedges = next_border_halfedges; - next_border_halfedges.clear(); - } - - std::cout << "Finished growing in " << task_timer.time() << " seconds" << std::endl; - - // visualize the grown mesh - internal::output_triangle_set >(faces_to_draw, "arr_grown.off"); - - Arrangement grown_arrangement; - std::cout << "building grown arrangement with " << arr_segments.size() << " segments" << std::endl; - CGAL::insert(grown_arrangement, arr_segments.begin(), arr_segments.end()); - - // Write the arrangement to a file. - std::ofstream arr_grown_out("arr_grown_old.off"); - internal::output_arrangement_to_off(grown_arrangement, arr_grown_out); - - return grown_arrangement; - } - - /// Build an arrangement from a two-dimensional mesh. - Arrangement get_arrangement_from_embedded_mesh(const EmbeddedMesh& emesh) const - { - const Seam_mesh& mesh = emesh.mesh; - const VertexUVMap uvmap = emesh.uvmap; - - std::vector arr_segments; - arr_segments.reserve(num_edges(mesh)); - - BOOST_FOREACH(edge_descriptor ed, edges(mesh)) { - vertex_descriptor vds = source(ed, mesh); - vertex_descriptor vdt = target(ed, mesh); - arr_segments.push_back(Exact_segment_2(to_exact(get(uvmap, vds)), - to_exact(get(uvmap, vdt)))); - } - - // Build the arrangement - Arrangement arrangement; - CGAL::insert(arrangement, arr_segments.begin(), arr_segments.end()); - - // Write the arrangement to a file. - std::ofstream arr_out("arr_target.off"); - internal::output_arrangement_to_off(arrangement, arr_out); - - return arrangement; - } - - /// Overlay the source and target arrangements. - void overlay_arrangements(const Arrangement& source_arrangement, - const Arrangement& target_arrangement) const - { - std::cout << "The source arrangement size:" << std::endl - << " V = " << source_arrangement.number_of_vertices() - << ", E = " << source_arrangement.number_of_edges() - << ", F = " << source_arrangement.number_of_faces() << std::endl; - - std::cout << "The target arrangement size:" << std::endl - << " V = " << target_arrangement.number_of_vertices() - << ", E = " << target_arrangement.number_of_edges() - << ", F = " << target_arrangement.number_of_faces() << std::endl; - - Arrangement overlay_arrangement; - Overlay_traits overlay_traits; - CGAL::overlay(source_arrangement, target_arrangement, - overlay_arrangement, overlay_traits); - - // Write the arrangement to a file - std::ofstream arr_out("arr_overlay.off"); - internal::output_arrangement_to_off(overlay_arrangement, arr_out); - - std::cout << "The overlaid arrangement size:" << std::endl - << " V = " << overlay_arrangement.number_of_vertices() - << ", E = " << overlay_arrangement.number_of_edges() - << ", F = " << overlay_arrangement.number_of_faces() << std::endl; - } - -public: - /// Compute the map between the source and the target mesh. - void compute_map_from_sphere_embeddings(const EmbeddedMesh& source_embedded_mesh, - const EmbeddedMesh& target_embedded_mesh) const - { - // Grow the source mesh until it covers the target mesh and convert it to arrangement - const Arrangement& source_arrangement = - grow_source_embedding(source_embedded_mesh, target_embedded_mesh); - - const Arrangement& target_arrangement = - get_arrangement_from_embedded_mesh(target_embedded_mesh); - - // Overlay the two arrangements - overlay_arrangements(source_arrangement, target_arrangement); - - // Compute the one-to-one mapping - // @todo - } - - /// Constructor. - Orbifold_sphere_mapper() : to_exact() { } -}; - -} // namespace Surface_mesh_parameterization - -} // namespace CGAL - -#endif // CGAL_SURFACE_MESH_PARAMETERIZATION_ORBIFOLD_TUTTE_SPHERE_MAPPING_H diff --git a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Mesh_cutter.h b/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Mesh_cutter.h deleted file mode 100644 index 0158ee33cba..00000000000 --- a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Mesh_cutter.h +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************** - begin : jan 02 - copyright : (C) 2002 by Pierre Alliez - email : pierre.alliez@sophia.inria.fr - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef MESH_CUTTER_H -#define MESH_CUTTER_H - -#include - -#include "Polyhedron_ex.h" - -#include -#include - - -class Mesh_cutter -{ -// Public types -public: - - typedef std::list - Backbone; - -// Private types -private: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - enum {FREE,DONE,FIXED}; - -// Public operations -public: - - // life cycle - Mesh_cutter(Polyhedron_ex& polyhedron) - { - m_pPolyhedron = &polyhedron; - m_pBackbone = NULL; - } - ~Mesh_cutter() {} - - void cut(Backbone& backbone); - void cut_genus(Backbone& backbone); - -// Private operations -private: - - // genus > 0 - bool init(); - bool simplify(); - bool extend(); - void precompute_distances(); - Polyhedron_ex::Halfedge_handle pick_best_halfedge( - std::list::iterator &pos); - void recursive_tag(Polyhedron_ex::Facet_handle pFacet,int index); - -// Fields -private: - - Polyhedron_ex* m_pPolyhedron; // the model to cut - Backbone* m_pBackbone; // the backbone to fill - Polyhedron_ex::Facet_handle m_pSeedFacet; - Polyhedron_ex::Vertex_handle m_pSeedVertex; -}; - - -//*************************************************** -// simple cut for genus 0 mesh -//*************************************************** -inline void Mesh_cutter::cut(Backbone& backbone) -{ - m_pBackbone = &backbone; - - // special init -> tag all vertices, but two - m_pPolyhedron->tag_vertices(FREE); - Polyhedron_ex::Vertex_handle pVertexMin,pVertexMax; - m_pPolyhedron->farthest_point_aligned(pVertexMin,pVertexMax); - pVertexMin->tag(FIXED); - pVertexMax->tag(FIXED); - init(); - - // cutting - while(extend()) {} -} - -///////////////////////////////////////////////////// -// GENUS > 0 -///////////////////////////////////////////////////// - -//*************************************************** -// cut for genus>0 mesh -//*************************************************** -inline void Mesh_cutter::cut_genus(Backbone& backbone) -{ - m_pBackbone = &backbone; - - // init - m_pPolyhedron->tag_vertices(FREE); // all free - init(); - - // cutting - while(extend()) {} -} - -//*************************************************** -// init -//*************************************************** -inline bool Mesh_cutter::init() -{ - // tag facets - m_pPolyhedron->tag_facets(FREE); - - // compute bounding box and center - double xmin = m_pPolyhedron->minimum(0); - double ymin = m_pPolyhedron->minimum(1); - double zmin = m_pPolyhedron->minimum(2); - double xmax = m_pPolyhedron->maximum(0); - double ymax = m_pPolyhedron->maximum(1); - double zmax = m_pPolyhedron->maximum(2); - double xcenter = 0.5*(xmin+xmax); - double ycenter = 0.5*(ymin+ymax); - double zcenter = 0.5*(zmin+zmax); - Point_3 center(xcenter,ycenter,zcenter); - - // get closest facet - m_pSeedFacet = m_pPolyhedron->get_closest_inner_facet(center); - assert(m_pSeedFacet != NULL); - - Polyhedron_ex::Halfedge_handle he = m_pSeedFacet->halfedge(); - assert(he != NULL); - assert(m_pBackbone != NULL); - m_pBackbone->push_back(he); - m_pBackbone->push_back(he->next()); - m_pBackbone->push_back(he->next()->next()); - - precompute_distances(); - m_pSeedFacet->tag(DONE); - - return true; -} - -//*************************************************** -// extend -//*************************************************** -inline bool Mesh_cutter::extend() -{ - std::list::iterator pos; - Polyhedron_ex::Halfedge_handle pHalfedge = pick_best_halfedge(pos); - if(pHalfedge == NULL) - return false; - - // flag facet - pHalfedge->opposite()->facet()->tag(DONE); - - // insert halfedge - std::list::iterator tmp = - m_pBackbone->insert(pos,pHalfedge->opposite()->next()->next()); - m_pBackbone->insert(tmp,pHalfedge->opposite()->next()); - - // remove this one - m_pBackbone->remove(pHalfedge); - - // simplify current backbone - while(simplify()) {} - return true; -} - -//*************************************************** -// simplify -//*************************************************** -inline bool Mesh_cutter::simplify() -{ - // cleanup - std::list::iterator iter; - for(iter = m_pBackbone->begin(); - iter != m_pBackbone->end(); - iter++) - { - Polyhedron_ex::Halfedge_handle pHalfedge = (*iter); - Polyhedron_ex::Halfedge_handle opposite = pHalfedge->opposite(); - - // get next halfedge in the list - iter++; - Polyhedron_ex::Halfedge_handle pNext = NULL; - if(iter == m_pBackbone->end()) // loop - pNext = (*m_pBackbone->begin()); - else - pNext = (*iter); - - if(pNext == opposite && - pHalfedge->vertex()->tag() == FREE) - { - m_pBackbone->remove(pHalfedge); - m_pBackbone->remove(opposite); - return true; - } - - iter--; // restore - } - return false; -} - -//*************************************************** -// precompute_distances -//*************************************************** -inline void Mesh_cutter::precompute_distances() -{ - Polyhedron_ex::Halfedge_iterator pHalfedge; - for(pHalfedge = m_pPolyhedron->halfedges_begin(); - pHalfedge != m_pPolyhedron->halfedges_end(); - pHalfedge++) - pHalfedge->distance(m_pPolyhedron->distance(m_pSeedFacet,pHalfedge)); -} - -//*************************************************** -// pick_best_halfedge -//*************************************************** -inline Polyhedron_ex::Halfedge_handle Mesh_cutter::pick_best_halfedge( - std::list::iterator &pos) -{ - Polyhedron_ex::Halfedge_handle pBest = NULL; - double min_distance = 1e308; // - - // cleanup - std::list::iterator iter; - for(iter = m_pBackbone->begin(); - iter != m_pBackbone->end(); - iter++) - { - Polyhedron_ex::Halfedge_handle pHalfedge = (*iter); - Polyhedron_ex::Halfedge_handle opposite = pHalfedge->opposite(); - Polyhedron_ex::Facet_handle pFacet = opposite->facet(); - - // check - if(pHalfedge->is_border() || - pFacet == NULL) - continue; - - if(pFacet->tag() == DONE) - continue; - - // no border vertex - Polyhedron_ex::Vertex_handle pVertex = opposite->next()->vertex(); - if(m_pPolyhedron->is_border(pVertex)) - continue; - - // precomputed distance - double distance = pHalfedge->distance(); - if(distance < min_distance) - { - pos = iter; - pBest = pHalfedge; - min_distance = distance; - } - } - return pBest; -} - - -#endif // MESH_CUTTER_H diff --git a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Polyhedron_ex.h b/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Polyhedron_ex.h deleted file mode 100644 index c2f8213c96b..00000000000 --- a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/include/Polyhedron_ex.h +++ /dev/null @@ -1,596 +0,0 @@ -#ifndef POLYHEDRON_EX_H_INCLUDED -#define POLYHEDRON_EX_H_INCLUDED - -#include -#include -#include - -#include -#include -#include -#include -#include - - -// CGAL kernel -typedef CGAL::Cartesian My_kernel; - - -// compute facet center -struct Facet_center -{ - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - template - void operator()(Facet& f) - { - Vector_3 vec(0.0,0.0,0.0); - int degree = 0; - typedef typename Facet::Halfedge_around_facet_const_circulator circ; - circ h = f.facet_begin(); - do - { - vec = vec + (h->vertex()->point()-CGAL::ORIGIN); - degree++; - } - while (++h != f.facet_begin()); - f.center() = CGAL::ORIGIN + (vec/degree); - } -}; - -template -class My_facet : public CGAL::HalfedgeDS_face_base -{ -public: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - // life cycle - // no constructors to repeat, since only - // default constructor mandatory - My_facet() - { - m_tag = -1; // uninitialized - } - - // center - Point_3& center() { return m_center; } - const Point_3& center() const { return m_center; } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // distance - double distance(Point_3& point) const - { - Vector_3 vec = (point-m_center); - return std::sqrt(vec*vec); - } - -// Fields -private: - - // facet data - int m_tag; - Point_3 m_center; -}; - -template -class My_halfedge - : public CGAL::HalfedgeDS_halfedge_base -{ -private: - int m_tag; - - // parameterization - bool m_is_parameterized; - int m_seaming; // seaming status - double m_u; // texture coordinates - double m_v; - int m_index; // for parameterization - - // surface cutting - double m_distance; - -public: - // life cycle - // no constructors to repeat, since only - // default constructor mandatory - My_halfedge() - { - m_tag = -1; // uninitialized - m_u = 0.0; - m_v = 0.0; - m_index = -1; // uninitialized - m_seaming = -1; // uninitialized - m_is_parameterized = false; - } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // seaming status - int seaming() const { return m_seaming; } - void seaming(int seaming) { m_seaming = seaming; } - - // precomputed distance - double distance() const { return m_distance; } - void distance(double distance) { m_distance = distance; } - - // texture coordinates - double u() const { return m_u; } - double v() const { return m_v; } - void uv(double u, double v) { m_u = u; m_v = v; } - - // param. - bool is_parameterized() const { return m_is_parameterized; } - void is_parameterized(bool is) { m_is_parameterized = is; } - - // index - int index() const { return m_index; } - void index(int i) { m_index = i; } -}; - - -// A redefined vertex class for the Polyhedron_3 -template -class My_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // index - int m_index; - - // misc - int m_tag; - - // seaming status - int m_seaming; - -public: - // life cycle - My_vertex() { init(); } - // repeat mandatory constructors - My_vertex(const P& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - init(); - } - - void init() - { - m_index = -1; // uninitialized - m_tag = -1; // uninitialized - m_seaming = -1; // uninitialized - } - - // index - int index() const { return m_index; } - void index(int i) { m_index = i; } - - // tag - int tag() const { return m_tag; } - void tag(int tag) { m_tag = tag; } - - // seaming status - int seaming() const { return m_seaming; } - void seaming(int seaming) { m_seaming = seaming; } -}; - - -// A redefined items class for the Polyhedron_3 with a refined vertex, facet and halfedge classes -struct My_items : public CGAL::Polyhedron_items_3 -{ - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point_3; - typedef My_vertex Vertex; - }; - - // wrap facet - template - struct Face_wrapper - { - typedef My_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef My_halfedge Halfedge; - }; -}; - - -class Polyhedron_ex : public CGAL::Polyhedron_3 -{ -public: - - typedef My_kernel::Vector_3 Vector_3; - typedef My_kernel::Point_3 Point_3; - - public: - - // life cycle - Polyhedron_ex() {} - virtual ~Polyhedron_ex() {} - - // facet centers - void compute_facet_centers() - { - std::for_each(facets_begin(),facets_end(),Facet_center()); - } - - // tag all facets - void tag_facets(const int tag) - { - Facet_iterator pFace; - for(pFace = facets_begin(); - pFace != facets_end(); - pFace++) - pFace->tag(tag); - } - - // get closest inner facet - Facet_handle get_closest_inner_facet(Point_3& point) - { - Facet_iterator pFace = facets_begin(); - Facet_handle pClosest = pFace; - double minimum = pFace->distance(point); - for(;pFace != facets_end(); - pFace++) - { - if(is_inner(pFace)) - { - double distance = pFace->distance(point); - if(distance < minimum) - { - pClosest = pFace; - minimum = distance; - } - } - } - return pClosest; - } - - bool is_inner(Facet_handle pFace) - { - typedef Halfedge_around_facet_const_circulator circ; - circ h = pFace->facet_begin(); - do - { - if(h->opposite()->is_border()) - return false; - } - while(++h != pFace->facet_begin()); - return true; - } - - // tag all vertices - void tag_vertices(const int tag) - { - Vertex_iterator iter; - for(iter = vertices_begin(); iter != vertices_end(); iter++) - iter->tag(tag); - } - - // tag all halfedges - void tag_halfedges(const int tag) - { - Halfedge_iterator iter; - for(iter = halfedges_begin(); iter != halfedges_end(); iter++) - iter->tag(tag); - } - - // compute bounding interval - double minimum (int coord) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - double minimum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - minimum = (std::min)(minimum,pVertex->point()[coord]); - return minimum; - } - double maximum (int coord) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - double maximum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - maximum = (std::max)(maximum,pVertex->point()[coord]); - return maximum; - } - Vertex_handle vertex_min(int coord, - double &minimum) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - Vertex_handle pBest = pVertex; - minimum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - { - double value = pVertex->point()[coord]; - if(value < minimum) - { - minimum = (std::min)(minimum,value); - pBest = pVertex; - } - } - return pBest; - } - Vertex_handle vertex_max(int coord, - double &maximum) - { - assert(size_of_vertices() > 0); - Vertex_iterator pVertex = vertices_begin(); - Vertex_handle pBest = pVertex; - maximum = pVertex->point()[coord]; - for(;pVertex != vertices_end();pVertex++) - { - double value = pVertex->point()[coord]; - if(value > maximum) - { - maximum = (std::max)(maximum,value); - pBest = pVertex; - } - } - return pBest; - } - - // Index all mesh vertices following the order of the vertices_begin() iterator - void precompute_vertex_indices() - { - Vertex_iterator pVertex; - unsigned int i = 0; - for(pVertex = vertices_begin(); - pVertex != vertices_end(); - pVertex++) - pVertex->index(i++); - } - - // Index all mesh half edges following the order of the halfedges_begin() iterator - void precompute_halfedge_indices() - { - Halfedge_iterator pHalfedge; - unsigned int i = 0; - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - pHalfedge->index(i++); - } - - -#ifdef DEBUG_TRUNCATE_OUTPUT - // Debug: write coordinates with 2 digits precision - #define FORMAT_EPS_COORD(x) (int(x/10.0+0.5)*10) -#else - #define FORMAT_EPS_COORD(x) (x) -#endif - - // Dump parameterized mesh to an eps file - bool write_file_eps(const char *pFilename, - double scale = 500.0) - { - assert(pFilename != NULL); - - std::ofstream out(pFilename); - if(!out) - return false; - CGAL::set_ascii_mode(out); - - // compute bounding box - double xmin,xmax,ymin,ymax; - xmin = ymin = xmax = ymax = 0; - Halfedge_iterator pHalfedge; - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - { - double x1 = scale * pHalfedge->prev()->u(); - double y1 = scale * pHalfedge->prev()->v(); - double x2 = scale * pHalfedge->u(); - double y2 = scale * pHalfedge->v(); - xmin = (std::min)(xmin,x1); - xmin = (std::min)(xmin,x2); - xmax = (std::max)(xmax,x1); - xmax = (std::max)(xmax,x2); - ymax = (std::max)(ymax,y1); - ymax = (std::max)(ymax,y2); - ymin = (std::min)(ymin,y1); - ymin = (std::min)(ymin,y2); - } - - out << "%!PS-Adobe-2.0 EPSF-2.0" << std::endl; - out << "%%BoundingBox: " << int(xmin+0.5) << " " - << int(ymin+0.5) << " " - << int(xmax+0.5) << " " - << int(ymax+0.5) << std::endl; - out << "%%HiResBoundingBox: " << xmin << " " - << ymin << " " - << xmax << " " - << ymax << std::endl; - out << "%%EndComments" << std::endl; - out << "gsave" << std::endl; - out << "0.1 setlinewidth" << std::endl; - - // color macros - out << std::endl; - out << "% RGB color command - r g b C" << std::endl; - out << "/C { setrgbcolor } bind def" << std::endl; - out << "/white { 1 1 1 C } bind def" << std::endl; - out << "/black { 0 0 0 C } bind def" << std::endl; - - // edge macro -> E - out << std::endl; - out << "% Black stroke - x1 y1 x2 y2 E" << std::endl; - out << "/E {moveto lineto stroke} bind def" << std::endl; - out << "black" << std::endl << std::endl; - - // output edge coordinates - for(pHalfedge = halfedges_begin(); - pHalfedge != halfedges_end(); - pHalfedge++) - { - double x1 = scale * pHalfedge->prev()->u(); - double y1 = scale * pHalfedge->prev()->v(); - double x2 = scale * pHalfedge->u(); - double y2 = scale * pHalfedge->v(); - out << FORMAT_EPS_COORD(x1) << " " - << FORMAT_EPS_COORD(y1) << " " - << FORMAT_EPS_COORD(x2) << " " - << FORMAT_EPS_COORD(y2) << " E" << std::endl; - } - - /* Emit EPS trailer. */ - out << "grestore" << std::endl; - out << std::endl; - out << "showpage" << std::endl; - - return true; - } - -#ifdef DEBUG_TRUNCATE_OUTPUT - // Debug: write coordinates with 2 digits precision - #define FORMAT_UV(x) (float(int(x*100.0+0.5))/100.0) -#else - #define FORMAT_UV(x) (x) -#endif - - // Dump parameterized mesh to a Wavefront OBJ file - // v x y z - // f 1 2 3 4 (1-based) - // - // Implementation note: the UV is meaningless for a NON parameterized halfedge - bool write_file_obj(const char *pFilename) - { - assert(pFilename != NULL); - - std::ofstream out(pFilename); - if(!out) - return false; - CGAL::set_ascii_mode(out); - - // Index all mesh vertices following the order of vertices_begin() iterator - precompute_vertex_indices(); - // Index all mesh half edges following the order of halfedges_begin() iterator - precompute_halfedge_indices(); - - // write the name of material file - out << "mtllib parameterization.mtl" << std::endl ; - - // output coordinates - out << "# vertices" << std::endl ; - Vertex_iterator pVertex; - for(pVertex = vertices_begin(); pVertex != vertices_end(); pVertex++) - out << "v " << pVertex->point().x() << " " - << pVertex->point().y() << " " - << pVertex->point().z() << std::endl; - - // Write UVs (1 UV / halfedge) - out << "# uv coordinates" << std::endl ; - Halfedge_iterator pHalfedge; - for(pHalfedge = halfedges_begin(); pHalfedge != halfedges_end(); pHalfedge++) - { - if (pHalfedge->is_parameterized()) - out << "vt " << FORMAT_UV(pHalfedge->u()) << " " << FORMAT_UV(pHalfedge->v()) << std::endl; - else - out << "vt " << 0.0 << " " << 0.0 << std::endl; - } - - // Write facets using the unique material # 1 - out << "# facets" << std::endl; - out << "usemtl Mat_1" << std::endl; - Facet_const_iterator pFacet; - for(pFacet = facets_begin(); pFacet != facets_end(); pFacet++) - { - Halfedge_around_facet_const_circulator h = pFacet->facet_begin(); - out << "f"; - do { - out << " " << h->vertex()->index()+1; - if (h->is_parameterized()) - out << "/" << h->index()+1; - } - while(++h != pFacet->facet_begin()); - out << std::endl; - } - - return true; - } - - // is vertex on border ? - static bool is_border(Vertex_const_handle pVertex) - { - Halfedge_around_vertex_const_circulator pHalfedge = pVertex->vertex_begin(); - Halfedge_around_vertex_const_circulator end = pHalfedge; - if(pHalfedge == NULL) // isolated vertex - return true; - CGAL_For_all(pHalfedge,end) - if(pHalfedge->is_border()) - return true; - return false; - } - - // compute distance from facet center to halfedge center - double distance(Facet_handle pFacet, - Halfedge_handle pHalfedge) - { - // we assume - Point_3 center_facet = pFacet->center(); - - Vector_3 v = (pHalfedge->opposite()->vertex()->point() - - pHalfedge->vertex()->point()); - Point_3 center_halfedge = pHalfedge->vertex()->point() + (v/2); - Vector_3 d = center_facet-center_halfedge; - return std::sqrt(d*d); - } - - void farthest_point_aligned(Vertex_handle &pVertexMin, - Vertex_handle &pVertexMax) - { - double xmin,xmax,ymin,ymax,zmin,zmax; - Vertex_handle pVertex_xMin = vertex_min(0,xmin); - Vertex_handle pVertex_xMax = vertex_max(0,xmax); - Vertex_handle pVertex_yMin = vertex_min(1,ymin); - Vertex_handle pVertex_yMax = vertex_max(1,ymax); - Vertex_handle pVertex_zMin = vertex_min(2,zmin); - Vertex_handle pVertex_zMax = vertex_max(2,zmax); - double xdiff = xmax-xmin; - double ydiff = ymax-ymin; - double zdiff = zmax-zmin; - if (xdiff >= (std::max)(ydiff,zdiff)) - { - pVertexMin = pVertex_xMin; - pVertexMax = pVertex_xMax; - } - else if (ydiff >= (std::max)(xdiff,zdiff)) - { - pVertexMin = pVertex_yMin; - pVertexMax = pVertex_yMax; - } - else - { - pVertexMin = pVertex_zMin; - pVertexMax = pVertex_zMax; - } - } - -}; // end class PolyhedronEx - - -#endif // POLYHEDRON_EX_H_INCLUDED -