Changed pointers to mesh to references all over the package (as requested by MK)

This commit is contained in:
Laurent Saboret 2006-03-03 09:33:29 +00:00
parent aadd6d748c
commit d2777b879a
26 changed files with 514 additions and 574 deletions

View File

@ -47,7 +47,7 @@ public:
/// Assign to mesh's border vertices a 2D position (ie a (u,v) pair) /// Assign to mesh's border vertices a 2D position (ie a (u,v) pair)
/// on border's shape. Mark them as "parameterized". /// on border's shape. Mark them as "parameterized".
/// Return false on error. /// Return false on error.
Error_code parameterize_border (Adaptor* mesh); Error_code parameterize_border (Adaptor& mesh);
/// Indicate if border's shape is convex. /// Indicate if border's shape is convex.
bool is_border_convex (); bool is_border_convex ();

View File

@ -57,6 +57,6 @@ public:
/// Preconditions: /// Preconditions:
/// - 'mesh' must be a surface with 1 connected component and no hole. /// - 'mesh' must be a surface with 1 connected component and no hole.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
Error_code parameterize (Adaptor* mesh); Error_code parameterize (Adaptor& mesh);
}; };

View File

@ -71,7 +71,7 @@ int main(int argc,char * argv[])
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron>
Parameterization_polyhedron_adaptor; Parameterization_polyhedron_adaptor;
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
//*************************************** //***************************************
// Discrete Authalic Parameterization // Discrete Authalic Parameterization
@ -80,7 +80,7 @@ int main(int argc,char * argv[])
typedef CGAL::Discrete_authalic_parameterizer_3<Parameterization_polyhedron_adaptor> typedef CGAL::Discrete_authalic_parameterizer_3<Parameterization_polyhedron_adaptor>
Parameterizer; Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_adaptor, Parameterizer()); Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer());
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;

View File

@ -52,7 +52,7 @@ typedef std::list<Parameterization_polyhedron_adaptor::Vertex_handle>
// CAUTION: // CAUTION:
// This method is provided "as is". It is very buggy and simply part of this example. // This method is provided "as is". It is very buggy and simply part of this example.
// Developers using this package should implement a more robust cut algorithm! // Developers using this package should implement a more robust cut algorithm!
static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor) static Seam cut_mesh(Parameterization_polyhedron_adaptor& mesh_adaptor)
{ {
// Helper class to compute genus or extract borders // Helper class to compute genus or extract borders
typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor> typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor>
@ -60,10 +60,8 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Seam seam; // returned list Seam seam; // returned list
// Get pointer to Polyhedron_3 mesh // Get reference to Polyhedron_3 mesh
assert(mesh_adaptor != NULL); Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Polyhedron* mesh = mesh_adaptor->get_adapted_mesh();
assert(mesh != NULL);
// Extract mesh borders and compute genus // Extract mesh borders and compute genus
Mesh_feature_extractor feature_extractor(mesh_adaptor); Mesh_feature_extractor feature_extractor(mesh_adaptor);
@ -74,8 +72,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
if (genus == 0 && nb_borders > 0) if (genus == 0 && nb_borders > 0)
{ {
// Pick the longest border // Pick the longest border
const Mesh_feature_extractor::Border* pBorder = feature_extractor.get_longest_border(); seam = feature_extractor.get_longest_border();
seam = *pBorder;
} }
else // if mesh is NOT a topological disk, create a virtual cut else // if mesh is NOT a topological disk, create a virtual cut
{ {
@ -83,7 +80,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
// Build consecutive halfedges array // Build consecutive halfedges array
Polyhedron::Halfedge_handle seam_halfedges[CUT_LENGTH]; Polyhedron::Halfedge_handle seam_halfedges[CUT_LENGTH];
seam_halfedges[0] = mesh->halfedges_begin(); seam_halfedges[0] = mesh.halfedges_begin();
if (seam_halfedges[0] == NULL) if (seam_halfedges[0] == NULL)
return seam; // return empty list return seam; // return empty list
int i; int i;
@ -109,12 +106,10 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
// f 1 2 3 4 (1-based) // f 1 2 3 4 (1-based)
// //
// Implementation note: the UV is meaningless for a NON parameterized halfedge // Implementation note: the UV is meaningless for a NON parameterized halfedge
static bool write_file_obj(Parameterization_polyhedron_adaptor* mesh_adaptor, static bool write_file_obj(Parameterization_polyhedron_adaptor& mesh_adaptor,
const char *pFilename) const char *pFilename)
{ {
assert(mesh_adaptor != NULL); Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Polyhedron* mesh = mesh_adaptor->get_adapted_mesh();
assert(mesh != NULL);
assert(pFilename != NULL); assert(pFilename != NULL);
std::ofstream out(pFilename); std::ofstream out(pFilename);
@ -125,30 +120,30 @@ static bool write_file_obj(Parameterization_polyhedron_adaptor* mesh_adaptor,
// Index all mesh vertices following the order of vertices_begin() iterator // Index all mesh vertices following the order of vertices_begin() iterator
Polyhedron::Vertex_const_iterator pVertex; Polyhedron::Vertex_const_iterator pVertex;
unsigned int i = 0; unsigned int i = 0;
for(pVertex = mesh->vertices_begin(); pVertex != mesh->vertices_end(); pVertex++) for(pVertex = mesh.vertices_begin(); pVertex != mesh.vertices_end(); pVertex++)
mesh_adaptor->info(pVertex)->index(i++); mesh_adaptor.info(pVertex)->index(i++);
// Index all mesh half edges following the order of halfedges_begin() iterator // Index all mesh half edges following the order of halfedges_begin() iterator
Polyhedron::Halfedge_const_iterator pHalfedge; Polyhedron::Halfedge_const_iterator pHalfedge;
i = 0; i = 0;
for(pHalfedge = mesh->halfedges_begin(); pHalfedge != mesh->halfedges_end(); pHalfedge++) for(pHalfedge = mesh.halfedges_begin(); pHalfedge != mesh.halfedges_end(); pHalfedge++)
mesh_adaptor->info(pHalfedge)->index(i++); mesh_adaptor.info(pHalfedge)->index(i++);
// write the name of material file // write the name of material file
out << "mtllib parameterization.mtl" << std::endl ; out << "mtllib parameterization.mtl" << std::endl ;
// output coordinates // output coordinates
out << "# vertices" << std::endl ; out << "# vertices" << std::endl ;
for(pVertex = mesh->vertices_begin(); pVertex != mesh->vertices_end(); pVertex++) for(pVertex = mesh.vertices_begin(); pVertex != mesh.vertices_end(); pVertex++)
out << "v " << pVertex->point().x() << " " out << "v " << pVertex->point().x() << " "
<< pVertex->point().y() << " " << pVertex->point().y() << " "
<< pVertex->point().z() << std::endl; << pVertex->point().z() << std::endl;
// Write UVs (1 UV / halfedge) // Write UVs (1 UV / halfedge)
out << "# uv coordinates" << std::endl ; out << "# uv coordinates" << std::endl ;
for(pHalfedge = mesh->halfedges_begin(); pHalfedge != mesh->halfedges_end(); pHalfedge++) for(pHalfedge = mesh.halfedges_begin(); pHalfedge != mesh.halfedges_end(); pHalfedge++)
{ {
Parameterization_polyhedron_adaptor::Halfedge_info* he_info = mesh_adaptor->info(pHalfedge); Parameterization_polyhedron_adaptor::Halfedge_info* he_info = mesh_adaptor.info(pHalfedge);
if (he_info->is_parameterized()) if (he_info->is_parameterized())
out << "vt " << he_info->uv().x() << " " << he_info->uv().y() << std::endl; out << "vt " << he_info->uv().x() << " " << he_info->uv().y() << std::endl;
else else
@ -159,13 +154,13 @@ static bool write_file_obj(Parameterization_polyhedron_adaptor* mesh_adaptor,
out << "# facets" << std::endl; out << "# facets" << std::endl;
out << "usemtl Mat_1" << std::endl; out << "usemtl Mat_1" << std::endl;
Polyhedron::Facet_const_iterator pFacet; Polyhedron::Facet_const_iterator pFacet;
for(pFacet = mesh->facets_begin(); pFacet != mesh->facets_end(); pFacet++) for(pFacet = mesh.facets_begin(); pFacet != mesh.facets_end(); pFacet++)
{ {
Polyhedron::Halfedge_around_facet_const_circulator h = pFacet->facet_begin(); Polyhedron::Halfedge_around_facet_const_circulator h = pFacet->facet_begin();
out << "f"; out << "f";
do { do {
Parameterization_polyhedron_adaptor::Halfedge_info* he_info = mesh_adaptor->info(h); Parameterization_polyhedron_adaptor::Halfedge_info* he_info = mesh_adaptor.info(h);
Parameterization_polyhedron_adaptor::Vertex_info* vtx_info = mesh_adaptor->info(h->vertex()); Parameterization_polyhedron_adaptor::Vertex_info* vtx_info = mesh_adaptor.info(h->vertex());
out << " " << vtx_info->index()+1; out << " " << vtx_info->index()+1;
if (he_info->is_parameterized()) if (he_info->is_parameterized())
out << "/" << he_info->index()+1; out << "/" << he_info->index()+1;
@ -224,12 +219,12 @@ int main(int argc,char * argv[])
//*************************************** //***************************************
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
// The parameterization methods support only meshes that // The parameterization methods support only meshes that
// are topological disks => we need to compute a "cutting" of the mesh // are topological disks => we need to compute a "cutting" of the mesh
// that makes it it homeomorphic to a disk // that makes it it homeomorphic to a disk
Seam seam = cut_mesh(&mesh_adaptor); Seam seam = cut_mesh(mesh_adaptor);
if (seam.empty()) if (seam.empty())
{ {
fprintf(stderr, "\nFATAL ERROR: an unexpected error occurred while cutting the shape!\n\n"); fprintf(stderr, "\nFATAL ERROR: an unexpected error occurred while cutting the shape!\n\n");
@ -237,7 +232,7 @@ int main(int argc,char * argv[])
} }
// Create adaptor that virtually "cuts" the mesh following the 'seam' path // Create adaptor that virtually "cuts" the mesh following the 'seam' path
Mesh_patch_polyhedron mesh_patch(&mesh_adaptor, seam.begin(), seam.end()); Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end());
//*************************************** //***************************************
// Discrete Authalic Parameterization (square border) // Discrete Authalic Parameterization (square border)
@ -256,7 +251,7 @@ int main(int argc,char * argv[])
Border_parameterizer, Border_parameterizer,
Solver> Parameterizer; Solver> Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_patch, Parameterizer()); Parameterizer::Error_code err = CGAL::parameterize(mesh_patch, Parameterizer());
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;
@ -267,7 +262,7 @@ int main(int argc,char * argv[])
// Write Wavefront OBJ file // Write Wavefront OBJ file
if (err == Parameterizer::OK) if (err == Parameterizer::OK)
{ {
if ( ! write_file_obj(&mesh_adaptor, output_filename) ) if ( ! write_file_obj(mesh_adaptor, output_filename) )
{ {
std::cerr << "FATAL ERROR: cannot write file " << output_filename << std::endl; std::cerr << "FATAL ERROR: cannot write file " << output_filename << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -22,10 +22,9 @@
//*************************************************** //***************************************************
// simple cut for genus 0 mesh // simple cut for genus 0 mesh
//*************************************************** //***************************************************
void Mesh_cutter::cut(Backbone *pBackbone) void Mesh_cutter::cut(Backbone& backbone)
{ {
m_pBackbone = pBackbone; m_pBackbone = &backbone;
CGAL_assertion(pBackbone != NULL);
// special init -> tag all vertices, but two // special init -> tag all vertices, but two
m_pPolyhedron->tag_vertices(FREE); m_pPolyhedron->tag_vertices(FREE);
@ -46,10 +45,9 @@ void Mesh_cutter::cut(Backbone *pBackbone)
//*************************************************** //***************************************************
// cut for genus>0 mesh // cut for genus>0 mesh
//*************************************************** //***************************************************
void Mesh_cutter::cut_genus(Backbone *pBackbone) void Mesh_cutter::cut_genus(Backbone& backbone)
{ {
m_pBackbone = pBackbone; m_pBackbone = &backbone;
CGAL_assertion(pBackbone != NULL);
// init // init
m_pPolyhedron->tag_vertices(FREE); // all free m_pPolyhedron->tag_vertices(FREE); // all free
@ -80,7 +78,7 @@ bool Mesh_cutter::init()
Point_3 center(xcenter,ycenter,zcenter); Point_3 center(xcenter,ycenter,zcenter);
// get closest facet // get closest facet
m_pSeedFacet = m_pPolyhedron->get_closest_inner_facet(&center); m_pSeedFacet = m_pPolyhedron->get_closest_inner_facet(center);
CGAL_assertion(m_pSeedFacet != NULL); CGAL_assertion(m_pSeedFacet != NULL);
Polyhedron_ex::Halfedge_handle he = m_pSeedFacet->halfedge(); Polyhedron_ex::Halfedge_handle he = m_pSeedFacet->halfedge();

View File

@ -45,7 +45,7 @@ typedef std::list<Parameterization_polyhedron_adaptor::Vertex_handle>
// CAUTION: // CAUTION:
// This method is provided "as is". It is very buggy and simply part of this example. // This method is provided "as is". It is very buggy and simply part of this example.
// Developers using this package should implement a more robust cut algorithm! // Developers using this package should implement a more robust cut algorithm!
static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor) static Seam cut_mesh(Parameterization_polyhedron_adaptor& mesh_adaptor)
{ {
// Helper class to compute genus or extract borders // Helper class to compute genus or extract borders
typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor> typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor>
@ -53,10 +53,8 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Seam seam; // returned list Seam seam; // returned list
// Get pointer to Polyhedron_3 mesh // Get refererence to Polyhedron_3 mesh
assert(mesh_adaptor != NULL); Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Polyhedron* mesh = mesh_adaptor->get_adapted_mesh();
assert(mesh != NULL);
// Extract mesh borders and compute genus // Extract mesh borders and compute genus
Mesh_feature_extractor feature_extractor(mesh_adaptor); Mesh_feature_extractor feature_extractor(mesh_adaptor);
@ -67,8 +65,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
if (genus == 0 && nb_borders > 0) if (genus == 0 && nb_borders > 0)
{ {
// Pick the longest border // Pick the longest border
const Mesh_feature_extractor::Border* pBorder = feature_extractor.get_longest_border(); seam = feature_extractor.get_longest_border();
seam = *pBorder;
} }
else // if mesh is NOT a topological disk, create a virtual cut else // if mesh is NOT a topological disk, create a virtual cut
{ {
@ -76,7 +73,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
// Build consecutive halfedges array // Build consecutive halfedges array
Polyhedron::Halfedge_handle seam_halfedges[CUT_LENGTH]; Polyhedron::Halfedge_handle seam_halfedges[CUT_LENGTH];
seam_halfedges[0] = mesh->halfedges_begin(); seam_halfedges[0] = mesh.halfedges_begin();
if (seam_halfedges[0] == NULL) if (seam_halfedges[0] == NULL)
return seam; // return empty list return seam; // return empty list
int i; int i;
@ -142,12 +139,12 @@ int main(int argc,char * argv[])
//*************************************** //***************************************
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
// The parameterization methods support only meshes that // The parameterization methods support only meshes that
// are topological disks => we need to compute a "cutting" of the mesh // are topological disks => we need to compute a "cutting" of the mesh
// that makes it it homeomorphic to a disk // that makes it it homeomorphic to a disk
Seam seam = cut_mesh(&mesh_adaptor); Seam seam = cut_mesh(mesh_adaptor);
if (seam.empty()) if (seam.empty())
{ {
fprintf(stderr, "\nFATAL ERROR: an unexpected error occurred while cutting the shape!\n\n"); fprintf(stderr, "\nFATAL ERROR: an unexpected error occurred while cutting the shape!\n\n");
@ -155,7 +152,7 @@ int main(int argc,char * argv[])
} }
// Create adaptor that virtually "cuts" the mesh following the 'seam' path // Create adaptor that virtually "cuts" the mesh following the 'seam' path
Mesh_patch_polyhedron mesh_patch(&mesh_adaptor, seam.begin(), seam.end()); Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end());
//*************************************** //***************************************
// Floater Mean Value Coordinates parameterization // Floater Mean Value Coordinates parameterization
@ -165,7 +162,7 @@ int main(int argc,char * argv[])
typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron> typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron>
Parameterizer; Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_patch); Parameterizer::Error_code err = CGAL::parameterize(mesh_patch);
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;

View File

@ -70,7 +70,7 @@ int main(int argc,char * argv[])
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron>
Parameterization_polyhedron_adaptor; Parameterization_polyhedron_adaptor;
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
//*************************************** //***************************************
// Floater Mean Value Coordinates parameterization // Floater Mean Value Coordinates parameterization
@ -80,7 +80,7 @@ int main(int argc,char * argv[])
typedef CGAL::Parameterizer_traits_3<Parameterization_polyhedron_adaptor> typedef CGAL::Parameterizer_traits_3<Parameterization_polyhedron_adaptor>
Parameterizer; Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_adaptor); Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor);
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;

View File

@ -182,10 +182,10 @@
RelativePath="..\..\include\Cgal\parameterize.h"> RelativePath="..\..\include\Cgal\parameterize.h">
</File> </File>
<File <File
RelativePath="..\..\include\Cgal\surface_mesh_parameterization_assertions.h"> RelativePath="..\..\include\Cgal\Parameterizer_traits_3.h">
</File> </File>
<File <File
RelativePath="..\..\include\Cgal\Parameterizer_traits_3.h"> RelativePath="..\..\include\Cgal\surface_mesh_parameterization_assertions.h">
</File> </File>
</Filter> </Filter>
<Filter <Filter

View File

@ -72,7 +72,7 @@ int main(int argc,char * argv[])
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron>
Parameterization_polyhedron_adaptor; Parameterization_polyhedron_adaptor;
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
//*************************************** //***************************************
@ -89,7 +89,7 @@ int main(int argc,char * argv[])
Border_parameterizer> Border_parameterizer>
Parameterizer; Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_adaptor, Parameterizer()); Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer());
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;

View File

@ -41,8 +41,7 @@ static bool write_file_eps(const Parameterization_polyhedron_adaptor& mesh_adapt
const char *pFilename, const char *pFilename,
double scale = 500.0) double scale = 500.0)
{ {
const Polyhedron* mesh = mesh_adaptor.get_adapted_mesh(); const Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
assert(mesh != NULL);
assert(pFilename != NULL); assert(pFilename != NULL);
std::ofstream out(pFilename); std::ofstream out(pFilename);
@ -54,8 +53,8 @@ static bool write_file_eps(const Parameterization_polyhedron_adaptor& mesh_adapt
double xmin,xmax,ymin,ymax; double xmin,xmax,ymin,ymax;
xmin = ymin = xmax = ymax = 0; xmin = ymin = xmax = ymax = 0;
Polyhedron::Halfedge_const_iterator pHalfedge; Polyhedron::Halfedge_const_iterator pHalfedge;
for (pHalfedge = mesh->halfedges_begin(); for (pHalfedge = mesh.halfedges_begin();
pHalfedge != mesh->halfedges_end(); pHalfedge != mesh.halfedges_end();
pHalfedge++) pHalfedge++)
{ {
double x1 = scale * mesh_adaptor.info(pHalfedge->prev())->uv().x(); double x1 = scale * mesh_adaptor.info(pHalfedge->prev())->uv().x();
@ -99,8 +98,8 @@ static bool write_file_eps(const Parameterization_polyhedron_adaptor& mesh_adapt
out << "black" << std::endl << std::endl; out << "black" << std::endl << std::endl;
// for each halfedge // for each halfedge
for (pHalfedge = mesh->halfedges_begin(); for (pHalfedge = mesh.halfedges_begin();
pHalfedge != mesh->halfedges_end(); pHalfedge != mesh.halfedges_end();
pHalfedge++) pHalfedge++)
{ {
double x1 = scale * mesh_adaptor.info(pHalfedge->prev())->uv().x(); double x1 = scale * mesh_adaptor.info(pHalfedge->prev())->uv().x();
@ -166,7 +165,7 @@ int main(int argc,char * argv[])
//*************************************** //***************************************
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_3 meshes
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
//*************************************** //***************************************
// Floater Mean Value Coordinates parameterizer (circular border) // Floater Mean Value Coordinates parameterizer (circular border)
@ -186,7 +185,7 @@ int main(int argc,char * argv[])
Solver> Solver>
Parameterizer; Parameterizer;
Parameterizer::Error_code err = CGAL::parameterize(&mesh_adaptor, Parameterizer()); Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer());
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;

View File

@ -41,16 +41,15 @@ private:
public: public:
// life cycle // life cycle
Mesh_cutter(Polyhedron_ex *pPolyhedron) Mesh_cutter(Polyhedron_ex& polyhedron)
{ {
CGAL_assertion(pPolyhedron != NULL); m_pPolyhedron = &polyhedron;
m_pPolyhedron = pPolyhedron;
m_pBackbone = NULL; m_pBackbone = NULL;
} }
~Mesh_cutter() {} ~Mesh_cutter() {}
void cut(Backbone *pBackbone); void cut(Backbone& backbone);
void cut_genus(Backbone *pBackbone); void cut_genus(Backbone& backbone);
// Private operations // Private operations
private: private:
@ -67,8 +66,8 @@ private:
// Fields // Fields
private: private:
Polyhedron_ex *m_pPolyhedron; // the model to cut Polyhedron_ex* m_pPolyhedron; // the model to cut
Backbone *m_pBackbone; // the backbone to fill Backbone* m_pBackbone; // the backbone to fill
Polyhedron_ex::Facet_handle m_pSeedFacet; Polyhedron_ex::Facet_handle m_pSeedFacet;
Polyhedron_ex::Vertex_handle m_pSeedVertex; Polyhedron_ex::Vertex_handle m_pSeedVertex;
}; };

View File

@ -162,13 +162,10 @@ public:
// The input mesh can be of any genus. // The input mesh can be of any genus.
// It can have have any number of borders. Its "main border" // It can have have any number of borders. Its "main border"
// will be the mesh's longest border (if there is at least one border). // will be the mesh's longest border (if there is at least one border).
Parameterization_polyhedron_adaptor_ex(Polyhedron_ex* mesh) Parameterization_polyhedron_adaptor_ex(Polyhedron_ex& mesh)
// Store reference to adapted mesh
: m_polyhedron(mesh)
{ {
assert(mesh != NULL);
// Store adapted mesh pointer
m_polyhedron = mesh;
// Extract mesh's longest border // Extract mesh's longest border
m_main_border = extract_longest_border(mesh); m_main_border = extract_longest_border(mesh);
@ -181,8 +178,8 @@ public:
// Default destructor, copy constructor and operator =() are fine // Default destructor, copy constructor and operator =() are fine
// Get the adapted mesh // Get the adapted mesh
Polyhedron_ex* get_adapted_mesh() { return m_polyhedron; } Polyhedron_ex& get_adapted_mesh() { return m_polyhedron; }
const Polyhedron_ex* get_adapted_mesh() const { return m_polyhedron; } const Polyhedron_ex& get_adapted_mesh() const { return m_polyhedron; }
// Get halfedge from source and target vertices // Get halfedge from source and target vertices
// Will assert if such an halfedge doesn't exist // Will assert if such an halfedge doesn't exist
@ -218,18 +215,18 @@ public:
// Get iterator over first vertex of mesh // Get iterator over first vertex of mesh
Vertex_iterator mesh_vertices_begin() { Vertex_iterator mesh_vertices_begin() {
return m_polyhedron->vertices_begin(); return m_polyhedron.vertices_begin();
} }
Vertex_const_iterator mesh_vertices_begin() const { Vertex_const_iterator mesh_vertices_begin() const {
return m_polyhedron->vertices_begin(); return m_polyhedron.vertices_begin();
} }
// Get iterator over past-the-end vertex of mesh // Get iterator over past-the-end vertex of mesh
Vertex_iterator mesh_vertices_end() { Vertex_iterator mesh_vertices_end() {
return m_polyhedron->vertices_end(); return m_polyhedron.vertices_end();
} }
Vertex_const_iterator mesh_vertices_end() const { Vertex_const_iterator mesh_vertices_end() const {
return m_polyhedron->vertices_end(); return m_polyhedron.vertices_end();
} }
// Count the number of vertices of the mesh // Count the number of vertices of the mesh
@ -327,30 +324,20 @@ public:
return border; return border;
} }
//// Compute the genus of the mesh
//int get_mesh_genus() const {
// return m_polyhedron->genus();
//}
//// Count the number of borders of the mesh
//int count_mesh_borders() const {
// return m_polyhedron->nb_borders();
//}
// Get iterator over first facet of mesh // Get iterator over first facet of mesh
Facet_iterator mesh_facets_begin() { Facet_iterator mesh_facets_begin() {
return m_polyhedron->facets_begin(); return m_polyhedron.facets_begin();
} }
Facet_const_iterator mesh_facets_begin() const { Facet_const_iterator mesh_facets_begin() const {
return m_polyhedron->facets_begin(); return m_polyhedron.facets_begin();
} }
// Get iterator over past-the-end facet of mesh // Get iterator over past-the-end facet of mesh
Facet_iterator mesh_facets_end() { Facet_iterator mesh_facets_end() {
return m_polyhedron->facets_end(); return m_polyhedron.facets_end();
} }
Facet_const_iterator mesh_facets_end() const { Facet_const_iterator mesh_facets_end() const {
return m_polyhedron->facets_end(); return m_polyhedron.facets_end();
} }
// Count the number of facets of the mesh // Count the number of facets of the mesh
@ -372,8 +359,8 @@ public:
// Count the number of halfedges of the mesh // Count the number of halfedges of the mesh
int count_mesh_halfedges() const { int count_mesh_halfedges() const {
int index = 0; int index = 0;
for (Halfedge_iterator pHalfedge = m_polyhedron->halfedges_begin(); for (Halfedge_iterator pHalfedge = m_polyhedron.halfedges_begin();
pHalfedge != m_polyhedron->halfedges_end(); pHalfedge != m_polyhedron.halfedges_end();
pHalfedge++) pHalfedge++)
{ {
index++; index++;
@ -449,7 +436,7 @@ public:
// Return true if a vertex belongs to ANY mesh's border // Return true if a vertex belongs to ANY mesh's border
bool is_vertex_on_border(Vertex_const_handle vertex) const { bool is_vertex_on_border(Vertex_const_handle vertex) const {
return m_polyhedron->is_border(vertex); return m_polyhedron.is_border(vertex);
} }
// Return true if a vertex belongs to the UNIQUE mesh's main border, // Return true if a vertex belongs to the UNIQUE mesh's main border,
@ -755,13 +742,11 @@ public:
private: private:
// Extract mesh's longest border // Extract mesh's longest border
std::list<Vertex_handle> extract_longest_border(Polyhedron_ex* mesh) std::list<Vertex_handle> extract_longest_border(Polyhedron_ex& mesh)
{ {
std::list<Vertex_handle> longest_border; // returned list std::list<Vertex_handle> longest_border; // returned list
double max_len = 0; // length of longest_border double max_len = 0; // length of longest_border
assert(mesh != NULL);
// Tag all vertices as unprocessed // Tag all vertices as unprocessed
const int tag_free = 0; const int tag_free = 0;
const int tag_done = 1; const int tag_done = 1;
@ -841,7 +826,7 @@ private:
private: private:
// The adapted mesh (cannot be NULL) // The adapted mesh (cannot be NULL)
Polyhedron_ex* m_polyhedron; Polyhedron_ex& m_polyhedron;
// Main border of a topological disc inside m_polyhedron (may be empty) // Main border of a topological disc inside m_polyhedron (may be empty)
std::list<Vertex_handle> m_main_border; std::list<Vertex_handle> m_main_border;

View File

@ -80,9 +80,9 @@ public:
void tag(int tag) { m_tag = tag; } void tag(int tag) { m_tag = tag; }
// distance // distance
double distance(Point_3 *pPoint) const double distance(Point_3& point) const
{ {
Vector_3 vec = (*pPoint-m_center); Vector_3 vec = (point-m_center);
return std::sqrt(vec*vec); return std::sqrt(vec*vec);
} }
@ -262,17 +262,17 @@ public:
} }
// get closest inner facet // get closest inner facet
Facet_handle get_closest_inner_facet(Point_3 *pPoint) Facet_handle get_closest_inner_facet(Point_3& point)
{ {
Facet_iterator pFace = facets_begin(); Facet_iterator pFace = facets_begin();
Facet_handle pClosest = pFace; Facet_handle pClosest = pFace;
double min = pFace->distance(pPoint); double min = pFace->distance(point);
for(;pFace != facets_end(); for(;pFace != facets_end();
pFace++) pFace++)
{ {
if(is_inner(pFace)) if(is_inner(pFace))
{ {
double distance = pFace->distance(pPoint); double distance = pFace->distance(point);
if(distance < min) if(distance < min)
{ {
pClosest = pFace; pClosest = pFace;

View File

@ -104,7 +104,7 @@ typedef std::list<Parameterization_polyhedron_adaptor::Vertex_handle>
// CAUTION: // CAUTION:
// This method is provided "as is". It is very buggy and simply part of this example. // This method is provided "as is". It is very buggy and simply part of this example.
// Developers using this package should implement a more robust cut algorithm! // Developers using this package should implement a more robust cut algorithm!
static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor) static Seam cut_mesh(Parameterization_polyhedron_adaptor& mesh_adaptor)
{ {
// Helper class to compute genus or extract borders // Helper class to compute genus or extract borders
typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor_ex> typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor_ex>
@ -114,10 +114,8 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Seam seam; // returned list Seam seam; // returned list
// Get pointer to Polyhedron_3 mesh // Get refererence to Polyhedron_3 mesh
assert(mesh_adaptor != NULL); Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Polyhedron* mesh = mesh_adaptor->get_adapted_mesh();
assert(mesh != NULL);
// Extract mesh borders and compute genus // Extract mesh borders and compute genus
Mesh_feature_extractor feature_extractor(mesh_adaptor); Mesh_feature_extractor feature_extractor(mesh_adaptor);
@ -128,8 +126,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
if (genus == 0 && nb_borders > 0) if (genus == 0 && nb_borders > 0)
{ {
// Pick the longest border // Pick the longest border
const Border* pBorder = feature_extractor.get_longest_border(); seam = feature_extractor.get_longest_border();
seam = *pBorder;
} }
else // if mesh is NOT a topological disk, create a virtual cut else // if mesh is NOT a topological disk, create a virtual cut
{ {
@ -137,17 +134,17 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Backbone::iterator he; Backbone::iterator he;
// Virtually "cut" mesh to make it a topological disk // Virtually "cut" mesh to make it a topological disk
mesh->compute_facet_centers(); mesh.compute_facet_centers();
Mesh_cutter cutter(mesh); Mesh_cutter cutter(mesh);
if (genus == 0) if (genus == 0)
{ {
// no border, we need to cut the mesh // no border, we need to cut the mesh
assert (nb_borders == 0); assert (nb_borders == 0);
cutter.cut(&seamingBackbone); // simple cut cutter.cut(seamingBackbone); // simple cut
} }
else // genus > 0 -> cut the mesh else // genus > 0 -> cut the mesh
{ {
cutter.cut_genus(&seamingBackbone); cutter.cut_genus(seamingBackbone);
} }
// The Mesh_cutter class is quite buggy // The Mesh_cutter class is quite buggy
@ -159,7 +156,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
// //
// 2) Check that seamingBackbone is a loop and // 2) Check that seamingBackbone is a loop and
// count occurences of seam halfedges // count occurences of seam halfedges
mesh->tag_halfedges(0); // Reset counters mesh.tag_halfedges(0); // Reset counters
for (he = seamingBackbone.begin(); he != seamingBackbone.end(); he++) for (he = seamingBackbone.begin(); he != seamingBackbone.end(); he++)
{ {
// Get next halfedge iterator (looping) // Get next halfedge iterator (looping)
@ -198,7 +195,7 @@ template<class ParameterizationMesh_3, // 3D surface
class SparseLinearAlgebraTraits_d> class SparseLinearAlgebraTraits_d>
// Traits class to solve a sparse linear system // Traits class to solve a sparse linear system
typename CGAL::Parameterizer_traits_3<ParameterizationMesh_3>::Error_code typename CGAL::Parameterizer_traits_3<ParameterizationMesh_3>::Error_code
parameterize(ParameterizationMesh_3* mesh, // Mesh parameterization adaptor parameterize(ParameterizationMesh_3& mesh, // Mesh parameterization adaptor
const char *type, // type of parameterization (see usage) const char *type, // type of parameterization (see usage)
const char *border) // type of border parameterization (see usage) const char *border) // type of border parameterization (see usage)
{ {
@ -474,14 +471,14 @@ int main(int argc,char * argv[])
//*************************************** //***************************************
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_ex meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_ex meshes
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
// The parameterization methods support only meshes that // The parameterization methods support only meshes that
// are topological disks => we need to virtually "cut" the mesh // are topological disks => we need to virtually "cut" the mesh
// to make it homeomorphic to a disk // to make it homeomorphic to a disk
// //
// 1) Cut the mesh // 1) Cut the mesh
Seam seam = cut_mesh(&mesh_adaptor); Seam seam = cut_mesh(mesh_adaptor);
if (seam.empty()) if (seam.empty())
{ {
std::cerr << "FATAL ERROR: an unexpected error occurred while cutting the shape" << std::endl; std::cerr << "FATAL ERROR: an unexpected error occurred while cutting the shape" << std::endl;
@ -489,7 +486,7 @@ int main(int argc,char * argv[])
} }
// //
// 2) Create adaptor that virtually "cuts" a patch in a Polyhedron_ex mesh // 2) Create adaptor that virtually "cuts" a patch in a Polyhedron_ex mesh
Mesh_patch_polyhedron mesh_patch(&mesh_adaptor, Mesh_patch_polyhedron mesh_patch(mesh_adaptor,
seam.begin(), seam.begin(),
seam.end()); seam.end());
@ -509,7 +506,7 @@ int main(int argc,char * argv[])
if (CGAL_CLIB_STD::strcmp(solver,"opennl") == 0) if (CGAL_CLIB_STD::strcmp(solver,"opennl") == 0)
{ {
err = parameterize<Mesh_patch_polyhedron, err = parameterize<Mesh_patch_polyhedron,
OpenNL::DefaultLinearSolverTraits<double> >(&mesh_patch, type, border); OpenNL::DefaultLinearSolverTraits<double> >(mesh_patch, type, border);
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;
} }
@ -517,7 +514,7 @@ int main(int argc,char * argv[])
{ {
#ifdef CGAL_USE_TAUCS #ifdef CGAL_USE_TAUCS
err = parameterize<Mesh_patch_polyhedron, err = parameterize<Mesh_patch_polyhedron,
CGAL::Taucs_solver_traits<double> >(&mesh_patch, type, border); CGAL::Taucs_solver_traits<double> >(mesh_patch, type, border);
if (err != Parameterizer::OK) if (err != Parameterizer::OK)
std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl; std::cerr << "FATAL ERROR: " << Parameterizer::get_error_message(err) << std::endl;
#else #else

View File

@ -102,7 +102,7 @@ public:
/// Assign to mesh's border vertices a 2D position (ie a (u,v) pair) /// Assign to mesh's border vertices a 2D position (ie a (u,v) pair)
/// on border's shape. Mark them as "parameterized". /// on border's shape. Mark them as "parameterized".
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
parameterize_border(Adaptor* mesh); parameterize_border(Adaptor& mesh);
/// Indicate if border's shape is convex. /// Indicate if border's shape is convex.
bool is_border_convex () { return true; } bool is_border_convex () { return true; }
@ -151,50 +151,48 @@ double Circular_border_parameterizer_3<Adaptor>::compute_border_length(
template<class Adaptor> template<class Adaptor>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Circular_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh) Circular_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor& mesh)
{ {
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " map on a circle" << std::endl; std::cerr << " map on a circle" << std::endl;
#endif #endif
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
// Nothing to do if no border // Nothing to do if no border
if (mesh->mesh_main_border_vertices_begin() == mesh->mesh_main_border_vertices_end()) if (mesh.mesh_main_border_vertices_begin() == mesh.mesh_main_border_vertices_end())
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
// Compute the total border length // Compute the total border length
double total_len = compute_border_length(*mesh); double total_len = compute_border_length(mesh);
if (total_len == 0) if (total_len == 0)
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
const double PI = 3.14159265359; const double PI = 3.14159265359;
const double tmp = 2*PI/total_len; const double tmp = 2*PI/total_len;
double len = 0.0; // current position on circle in [0, total_len] double len = 0.0; // current position on circle in [0, total_len]
for(Border_vertex_iterator it = mesh->mesh_main_border_vertices_begin(); for(Border_vertex_iterator it = mesh.mesh_main_border_vertices_begin();
it != mesh->mesh_main_border_vertices_end(); it != mesh.mesh_main_border_vertices_end();
it++) it++)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh->is_vertex_on_main_border(it)); CGAL_surface_mesh_parameterization_assertion(mesh.is_vertex_on_main_border(it));
double angle = len*tmp; // current position on the circle in radians double angle = len*tmp; // current position on the circle in radians
// map vertex on unit circle // map vertex on unit circle
Point_2 uv; Point_2 uv;
uv = Point_2(0.5+0.5*CGAL_CLIB_STD::cos(-angle),0.5+0.5*CGAL_CLIB_STD::sin(-angle)); uv = Point_2(0.5+0.5*CGAL_CLIB_STD::cos(-angle),0.5+0.5*CGAL_CLIB_STD::sin(-angle));
mesh->set_vertex_uv(it, uv); mesh.set_vertex_uv(it, uv);
// Mark vertex as "parameterized" // Mark vertex as "parameterized"
mesh->set_vertex_parameterized(it, true); mesh.set_vertex_parameterized(it, true);
// Get next iterator (looping) // Get next iterator (looping)
Border_vertex_iterator next = it; Border_vertex_iterator next = it;
next++; next++;
if(next == mesh->mesh_main_border_vertices_end()) if(next == mesh.mesh_main_border_vertices_end())
next = mesh->mesh_main_border_vertices_begin(); next = mesh.mesh_main_border_vertices_begin();
// Add 'length' of it -> next vector to 'len' // Add 'length' of it -> next vector to 'len'
len += compute_edge_length(*mesh, it, next); len += compute_edge_length(mesh, it, next);
} }
return Parameterizer_traits_3<Adaptor>::OK; return Parameterizer_traits_3<Adaptor>::OK;

View File

@ -155,7 +155,7 @@ public:
/// - 'mesh' must be a surface with 1 connected component. /// - 'mesh' must be a surface with 1 connected component.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
/// - the mesh border must be mapped onto a convex polygon. /// - the mesh border must be mapped onto a convex polygon.
virtual Error_code parameterize(Adaptor* mesh); virtual Error_code parameterize(Adaptor& mesh);
// Protected operations // Protected operations
protected: protected:
@ -163,7 +163,7 @@ protected:
/// - 'mesh' must be a surface with 1 connected component. /// - 'mesh' must be a surface with 1 connected component.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
/// - the mesh border must be mapped onto a convex polygon. /// - the mesh border must be mapped onto a convex polygon.
virtual Error_code check_parameterize_preconditions(Adaptor* mesh); virtual Error_code check_parameterize_preconditions(Adaptor& mesh);
/// Initialize A, Bu and Bv after border parameterization. /// Initialize A, Bu and Bv after border parameterization.
/// Fill the border vertices' lines in both linear systems: /// Fill the border vertices' lines in both linear systems:
@ -173,7 +173,7 @@ protected:
/// - vertices must be indexed. /// - vertices must be indexed.
/// - A, Bu and Bv must be allocated. /// - A, Bu and Bv must be allocated.
/// - border vertices must be parameterized. /// - border vertices must be parameterized.
void initialize_system_from_mesh_border (Matrix* A, Vector* Bu, Vector* Bv, void initialize_system_from_mesh_border (Matrix& A, Vector& Bu, Vector& Bv,
const Adaptor& mesh); const Adaptor& mesh);
/// Compute w_ij = (i,j) coefficient of matrix A for j neighbor vertex of i. /// Compute w_ij = (i,j) coefficient of matrix A for j neighbor vertex of i.
@ -191,14 +191,14 @@ protected:
/// - vertices must be indexed. /// - vertices must be indexed.
/// - vertex i musn't be already parameterized. /// - vertex i musn't be already parameterized.
/// - line i of A must contain only zeros. /// - line i of A must contain only zeros.
virtual Error_code setup_inner_vertex_relations(Matrix* A, virtual Error_code setup_inner_vertex_relations(Matrix& A,
Vector* Bu, Vector& Bu,
Vector* Bv, Vector& Bv,
const Adaptor& mesh, const Adaptor& mesh,
Vertex_const_handle vertex); Vertex_const_handle vertex);
/// Copy Xu and Xv coordinates into the (u,v) pair of each surface vertex. /// Copy Xu and Xv coordinates into the (u,v) pair of each surface vertex.
void set_mesh_uv_from_system (Adaptor* mesh, void set_mesh_uv_from_system (Adaptor& mesh,
const Vector& Xu, const Vector& Xv); const Vector& Xu, const Vector& Xv);
/// Check parameterize() postconditions: /// Check parameterize() postconditions:
@ -251,10 +251,8 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
parameterize(Adaptor* mesh) parameterize(Adaptor& mesh)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
// Create timer for traces // Create timer for traces
CGAL::Timer timer; CGAL::Timer timer;
@ -271,18 +269,18 @@ parameterize(Adaptor* mesh)
return status; return status;
// Count vertices // Count vertices
int nbVertices = mesh->count_mesh_vertices(); int nbVertices = mesh.count_mesh_vertices();
// Index vertices from 0 to nbVertices-1 // Index vertices from 0 to nbVertices-1
mesh->index_mesh_vertices(); mesh.index_mesh_vertices();
// Mark all vertices as NOT "parameterized" // Mark all vertices as NOT "parameterized"
Vertex_iterator vertexIt; Vertex_iterator vertexIt;
for (vertexIt = mesh->mesh_vertices_begin(); for (vertexIt = mesh.mesh_vertices_begin();
vertexIt != mesh->mesh_vertices_end(); vertexIt != mesh.mesh_vertices_end();
vertexIt++) vertexIt++)
{ {
mesh->set_vertex_parameterized(vertexIt, false); mesh.set_vertex_parameterized(vertexIt, false);
} }
// Compute (u,v) for border vertices // Compute (u,v) for border vertices
@ -305,23 +303,23 @@ parameterize(Adaptor* mesh)
// //
// Implementation note: the current implementation does not remove // Implementation note: the current implementation does not remove
// border vertices from the linear systems => A cannot be symmetric // border vertices from the linear systems => A cannot be symmetric
initialize_system_from_mesh_border (&A, &Bu, &Bv, *mesh); initialize_system_from_mesh_border (A, Bu, Bv, mesh);
// Fill the matrix for the inner vertices v_i: compute A's coefficient // Fill the matrix for the inner vertices v_i: compute A's coefficient
// w_ij for each neighbor j; then w_ii = - sum of w_ijs // w_ij for each neighbor j; then w_ii = - sum of w_ijs
for (vertexIt = mesh->mesh_vertices_begin(); for (vertexIt = mesh.mesh_vertices_begin();
vertexIt != mesh->mesh_vertices_end(); vertexIt != mesh.mesh_vertices_end();
vertexIt++) vertexIt++)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh->is_vertex_on_main_border(vertexIt) CGAL_surface_mesh_parameterization_assertion(mesh.is_vertex_on_main_border(vertexIt)
== mesh->is_vertex_parameterized(vertexIt)); == mesh.is_vertex_parameterized(vertexIt));
// inner vertices only // inner vertices only
if( ! mesh->is_vertex_on_main_border(vertexIt) ) if( ! mesh.is_vertex_on_main_border(vertexIt) )
{ {
// Compute the line i of matrix A for i inner vertex // Compute the line i of matrix A for i inner vertex
status = setup_inner_vertex_relations(&A, &Bu, &Bv, status = setup_inner_vertex_relations(A, Bu, Bv,
*mesh, mesh,
vertexIt); vertexIt);
if (status != Base::OK) if (status != Base::OK)
return status; return status;
@ -363,7 +361,7 @@ parameterize(Adaptor* mesh)
// Check postconditions // Check postconditions
status = check_parameterize_postconditions(*mesh, A, Bu, Bv); status = check_parameterize_postconditions(mesh, A, Bu, Bv);
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " parameterization postconditions: " << timer.time() << " seconds." << std::endl; std::cerr << " parameterization postconditions: " << timer.time() << " seconds." << std::endl;
#endif #endif
@ -382,7 +380,7 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
check_parameterize_preconditions(Adaptor* mesh) check_parameterize_preconditions(Adaptor& mesh)
{ {
Error_code status = Base::OK; // returned value Error_code status = Base::OK; // returned value
@ -392,14 +390,14 @@ check_parameterize_preconditions(Adaptor* mesh)
Mesh_feature_extractor feature_extractor(mesh); Mesh_feature_extractor feature_extractor(mesh);
// Allways check that mesh is not empty // Allways check that mesh is not empty
if (mesh->mesh_vertices_begin() == mesh->mesh_vertices_end()) if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
status = Base::ERROR_EMPTY_MESH; status = Base::ERROR_EMPTY_MESH;
if (status != Base::OK) if (status != Base::OK)
return status; return status;
// The whole surface parameterization package is restricted to triangular meshes // The whole surface parameterization package is restricted to triangular meshes
CGAL_surface_mesh_parameterization_expensive_precondition_code( \ CGAL_surface_mesh_parameterization_expensive_precondition_code( \
status = mesh->is_mesh_triangular() ? Base::OK \ status = mesh.is_mesh_triangular() ? Base::OK \
: Base::ERROR_NON_TRIANGULAR_MESH; \ : Base::ERROR_NON_TRIANGULAR_MESH; \
); );
if (status != Base::OK) if (status != Base::OK)
@ -441,13 +439,9 @@ check_parameterize_preconditions(Adaptor* mesh)
template<class Adaptor, class Border_param, class Sparse_LA> template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
void Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: void Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
initialize_system_from_mesh_border (Matrix* A, Vector* Bu, Vector* Bv, initialize_system_from_mesh_border (Matrix& A, Vector& Bu, Vector& Bv,
const Adaptor& mesh) const Adaptor& mesh)
{ {
CGAL_surface_mesh_parameterization_assertion(A != NULL);
CGAL_surface_mesh_parameterization_assertion(Bu != NULL);
CGAL_surface_mesh_parameterization_assertion(Bv != NULL);
for (Border_vertex_const_iterator it = mesh.mesh_main_border_vertices_begin(); for (Border_vertex_const_iterator it = mesh.mesh_main_border_vertices_begin();
it != mesh.mesh_main_border_vertices_end(); it != mesh.mesh_main_border_vertices_end();
it++) it++)
@ -458,12 +452,12 @@ initialize_system_from_mesh_border (Matrix* A, Vector* Bu, Vector* Bv,
int index = mesh.get_vertex_index(it); int index = mesh.get_vertex_index(it);
// Write 1 as diagonal coefficient of A // Write 1 as diagonal coefficient of A
A->set_coef(index, index, 1); A.set_coef(index, index, 1);
// Write constant in Bu and Bv // Write constant in Bu and Bv
Point_2 uv = mesh.get_vertex_uv(it); Point_2 uv = mesh.get_vertex_uv(it);
(*Bu)[index] = uv.x(); Bu[index] = uv.x();
(*Bv)[index] = uv.y(); Bv[index] = uv.y();
} }
} }
@ -479,9 +473,9 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
setup_inner_vertex_relations(Matrix* A, setup_inner_vertex_relations(Matrix& A,
Vector* Bu, Vector& Bu,
Vector* Bv, Vector& Bv,
const Adaptor& mesh, const Adaptor& mesh,
Vertex_const_handle vertex) Vertex_const_handle vertex)
{ {
@ -507,7 +501,7 @@ setup_inner_vertex_relations(Matrix* A,
int j = mesh.get_vertex_index(v_j); int j = mesh.get_vertex_index(v_j);
// Set w_ij in matrix // Set w_ij in matrix
A->set_coef(i,j, w_ij); A.set_coef(i,j, w_ij);
vertexIndex++; vertexIndex++;
} }
@ -515,7 +509,7 @@ setup_inner_vertex_relations(Matrix* A,
return Base::ERROR_NON_TRIANGULAR_MESH; return Base::ERROR_NON_TRIANGULAR_MESH;
// Set w_ii in matrix // Set w_ii in matrix
A->set_coef(i,i, w_ii); A.set_coef(i,i, w_ii);
return Base::OK; return Base::OK;
} }
@ -524,22 +518,22 @@ setup_inner_vertex_relations(Matrix* A,
template<class Adaptor, class Border_param, class Sparse_LA> template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
void Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: void Fixed_border_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
set_mesh_uv_from_system(Adaptor* mesh, set_mesh_uv_from_system(Adaptor& mesh,
const Vector& Xu, const Vector& Xv) const Vector& Xu, const Vector& Xv)
{ {
Vertex_iterator vertexIt; Vertex_iterator vertexIt;
for (vertexIt = mesh->mesh_vertices_begin(); for (vertexIt = mesh.mesh_vertices_begin();
vertexIt != mesh->mesh_vertices_end(); vertexIt != mesh.mesh_vertices_end();
vertexIt++) vertexIt++)
{ {
int index = mesh->get_vertex_index(vertexIt); int index = mesh.get_vertex_index(vertexIt);
NT u = Xu[index]; NT u = Xu[index];
NT v = Xv[index]; NT v = Xv[index];
// Fill vertex (u,v) and mark it as "parameterized" // Fill vertex (u,v) and mark it as "parameterized"
mesh->set_vertex_uv(vertexIt, Point_2(u,v)); mesh.set_vertex_uv(vertexIt, Point_2(u,v));
mesh->set_vertex_parameterized(vertexIt, true); mesh.set_vertex_parameterized(vertexIt, true);
} }
} }

View File

@ -156,14 +156,14 @@ public:
/// Preconditions: /// Preconditions:
/// - 'mesh' must be a surface with 1 connected component. /// - 'mesh' must be a surface with 1 connected component.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
virtual Error_code parameterize(Adaptor* mesh); virtual Error_code parameterize(Adaptor& mesh);
// Protected operations // Protected operations
protected: protected:
/// Check parameterize() preconditions: /// Check parameterize() preconditions:
/// - 'mesh' must be a surface with 1 connected component. /// - 'mesh' must be a surface with 1 connected component.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
virtual Error_code check_parameterize_preconditions(Adaptor* mesh); virtual Error_code check_parameterize_preconditions(Adaptor& mesh);
/// Initialize "A*X = B" linear system after /// Initialize "A*X = B" linear system after
/// (at least 2) border vertices are parameterized. /// (at least 2) border vertices are parameterized.
@ -172,25 +172,25 @@ protected:
/// - vertices must be indexed. /// - vertices must be indexed.
/// - X and B must be allocated and empty. /// - X and B must be allocated and empty.
/// - (at least 2) border vertices must be parameterized. /// - (at least 2) border vertices must be parameterized.
void initialize_system_from_mesh_border(LeastSquaresSolver* solver, void initialize_system_from_mesh_border(LeastSquaresSolver& solver,
const Adaptor& mesh) ; const Adaptor& mesh) ;
/// Utility for setup_triangle_relations(): /// Utility for setup_triangle_relations():
/// Computes the coordinates of the vertices of a triangle /// Computes the coordinates of the vertices of a triangle
/// in a local 2D orthonormal basis of the triangle's plane. /// in a local 2D orthonormal basis of the triangle's plane.
void project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2, void project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2, // in
Point_2* z0, Point_2* z1, Point_2* z2) ; Point_2& z0, Point_2& z1, Point_2& z2); // out
/// Create 2 lines in the linear system per triangle (1 for u, 1 for v). /// Create 2 lines in the linear system per triangle (1 for u, 1 for v).
/// ///
/// Preconditions: /// Preconditions:
/// - vertices must be indexed. /// - vertices must be indexed.
Error_code setup_triangle_relations(LeastSquaresSolver* solver, Error_code setup_triangle_relations(LeastSquaresSolver& solver,
const Adaptor& mesh, const Adaptor& mesh,
Facet_const_handle facet) ; Facet_const_handle facet) ;
/// Copy X coordinates into the (u,v) pair of each vertex /// Copy X coordinates into the (u,v) pair of each vertex
void set_mesh_uv_from_system(Adaptor* mesh, void set_mesh_uv_from_system(Adaptor& mesh,
const LeastSquaresSolver& solver) ; const LeastSquaresSolver& solver) ;
/// Check parameterize() postconditions: /// Check parameterize() postconditions:
@ -246,10 +246,8 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
parameterize(Adaptor* mesh) parameterize(Adaptor& mesh)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
// Create timer for traces // Create timer for traces
CGAL::Timer timer; CGAL::Timer timer;
@ -266,18 +264,18 @@ parameterize(Adaptor* mesh)
return status; return status;
// Count vertices // Count vertices
int nbVertices = mesh->count_mesh_vertices(); int nbVertices = mesh.count_mesh_vertices();
// Index vertices from 0 to nbVertices-1 // Index vertices from 0 to nbVertices-1
mesh->index_mesh_vertices(); mesh.index_mesh_vertices();
// Mark all vertices as NOT "parameterized" // Mark all vertices as NOT "parameterized"
Vertex_iterator vertexIt; Vertex_iterator vertexIt;
for (vertexIt = mesh->mesh_vertices_begin(); for (vertexIt = mesh.mesh_vertices_begin();
vertexIt != mesh->mesh_vertices_end(); vertexIt != mesh.mesh_vertices_end();
vertexIt++) vertexIt++)
{ {
mesh->set_vertex_parameterized(vertexIt, false); mesh.set_vertex_parameterized(vertexIt, false);
} }
// Compute (u,v) for (at least 2) border vertices // Compute (u,v) for (at least 2) border vertices
@ -297,22 +295,22 @@ parameterize(Adaptor* mesh)
// Initialize the "A*X = B" linear system after // Initialize the "A*X = B" linear system after
// (at least 2) border vertices parameterization // (at least 2) border vertices parameterization
initialize_system_from_mesh_border(&solver, *mesh); initialize_system_from_mesh_border(solver, mesh);
// Fill the matrix for the other vertices // Fill the matrix for the other vertices
solver.begin_system() ; solver.begin_system() ;
for (Facet_iterator facetIt = mesh->mesh_facets_begin(); for (Facet_iterator facetIt = mesh.mesh_facets_begin();
facetIt != mesh->mesh_facets_end(); facetIt != mesh.mesh_facets_end();
facetIt++) facetIt++)
{ {
// Create 2 lines in the linear system per triangle (1 for u, 1 for v) // Create 2 lines in the linear system per triangle (1 for u, 1 for v)
status = setup_triangle_relations(&solver, *mesh, facetIt); status = setup_triangle_relations(solver, mesh, facetIt);
if (status != Base::OK) if (status != Base::OK)
return status; return status;
} }
solver.end_system() ; solver.end_system() ;
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " matrix filling (" << 2*mesh->count_mesh_facets() << " x " << nbVertices << "): " std::cerr << " matrix filling (" << 2*mesh.count_mesh_facets() << " x " << nbVertices << "): "
<< timer.time() << " seconds." << std::endl; << timer.time() << " seconds." << std::endl;
timer.reset(); timer.reset();
#endif #endif
@ -337,7 +335,7 @@ parameterize(Adaptor* mesh)
#endif #endif
// Check postconditions // Check postconditions
status = check_parameterize_postconditions(*mesh, solver); status = check_parameterize_postconditions(mesh, solver);
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " parameterization postconditions: " << timer.time() << " seconds." << std::endl; std::cerr << " parameterization postconditions: " << timer.time() << " seconds." << std::endl;
#endif #endif
@ -355,7 +353,7 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
check_parameterize_preconditions(Adaptor* mesh) check_parameterize_preconditions(Adaptor& mesh)
{ {
Error_code status = Base::OK; // returned value Error_code status = Base::OK; // returned value
@ -365,14 +363,14 @@ check_parameterize_preconditions(Adaptor* mesh)
Mesh_feature_extractor feature_extractor(mesh); Mesh_feature_extractor feature_extractor(mesh);
// Allways check that mesh is not empty // Allways check that mesh is not empty
if (mesh->mesh_vertices_begin() == mesh->mesh_vertices_end()) if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
status = Base::ERROR_EMPTY_MESH; status = Base::ERROR_EMPTY_MESH;
if (status != Base::OK) if (status != Base::OK)
return status; return status;
// The whole surface parameterization package is restricted to triangular meshes // The whole surface parameterization package is restricted to triangular meshes
CGAL_surface_mesh_parameterization_expensive_precondition_code( \ CGAL_surface_mesh_parameterization_expensive_precondition_code( \
status = mesh->is_mesh_triangular() ? Base::OK \ status = mesh.is_mesh_triangular() ? Base::OK \
: Base::ERROR_NON_TRIANGULAR_MESH; \ : Base::ERROR_NON_TRIANGULAR_MESH; \
); );
if (status != Base::OK) if (status != Base::OK)
@ -404,12 +402,9 @@ check_parameterize_preconditions(Adaptor* mesh)
template<class Adaptor, class Border_param, class Sparse_LA> template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
void LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: void LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
initialize_system_from_mesh_border(LeastSquaresSolver* solver, initialize_system_from_mesh_border(LeastSquaresSolver& solver,
const Adaptor& mesh) const Adaptor& mesh)
{ {
CGAL_surface_mesh_parameterization_assertion(solver != NULL);
CGAL_surface_mesh_parameterization_assertion(solver != NULL);
for (Vertex_const_iterator it = mesh.mesh_vertices_begin(); for (Vertex_const_iterator it = mesh.mesh_vertices_begin();
it != mesh.mesh_vertices_end(); it != mesh.mesh_vertices_end();
it++) it++)
@ -423,13 +418,13 @@ initialize_system_from_mesh_border(LeastSquaresSolver* solver,
// Write (u,v) in X (meaningless if vertex is not parameterized) // Write (u,v) in X (meaningless if vertex is not parameterized)
// Note : 2*index --> u // Note : 2*index --> u
// 2*index + 1 --> v // 2*index + 1 --> v
solver->variable(2*index ).set_value(uv.x()) ; solver.variable(2*index ).set_value(uv.x()) ;
solver->variable(2*index + 1).set_value(uv.y()) ; solver.variable(2*index + 1).set_value(uv.y()) ;
// Copy (u,v) in B if vertex is parameterized // Copy (u,v) in B if vertex is parameterized
if (mesh.is_vertex_parameterized(it)) { if (mesh.is_vertex_parameterized(it)) {
solver->variable(2*index ).lock() ; solver.variable(2*index ).lock() ;
solver->variable(2*index + 1).lock() ; solver.variable(2*index + 1).lock() ;
} }
} }
} }
@ -441,8 +436,8 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
void void
LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2, project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2, // in
Point_2* z0, Point_2* z1, Point_2* z2) Point_2& z0, Point_2& z1, Point_2& z2) // out
{ {
Vector_3 X = p1 - p0 ; Vector_3 X = p1 - p0 ;
NT X_norm = std::sqrt(X*X); NT X_norm = std::sqrt(X*X);
@ -465,9 +460,9 @@ project_triangle(const Point_3& p0, const Point_3& p1, const Point_3& p2,
NT x2 = (p2 - O) * X ; NT x2 = (p2 - O) * X ;
NT y2 = (p2 - O) * Y ; NT y2 = (p2 - O) * Y ;
*z0 = Point_2(x0,y0) ; z0 = Point_2(x0,y0) ;
*z1 = Point_2(x1,y1) ; z1 = Point_2(x1,y1) ;
*z2 = Point_2(x2,y2) ; z2 = Point_2(x2,y2) ;
} }
@ -486,12 +481,10 @@ template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
setup_triangle_relations(LeastSquaresSolver* solver, setup_triangle_relations(LeastSquaresSolver& solver,
const Adaptor& mesh, const Adaptor& mesh,
Facet_const_handle facet) Facet_const_handle facet)
{ {
CGAL_surface_mesh_parameterization_assertion(solver != NULL);
// Get the 3 vertices of the triangle // Get the 3 vertices of the triangle
Vertex_const_handle v0, v1, v2; Vertex_const_handle v0, v1, v2;
int vertexIndex = 0; int vertexIndex = 0;
@ -524,7 +517,8 @@ setup_triangle_relations(LeastSquaresSolver* solver,
// Computes the coordinates of the vertices of a triangle // Computes the coordinates of the vertices of a triangle
// in a local 2D orthonormal basis of the triangle's plane. // in a local 2D orthonormal basis of the triangle's plane.
Point_2 z0,z1,z2 ; Point_2 z0,z1,z2 ;
project_triangle(p0,p1,p2, &z0,&z1,&z2) ; project_triangle(p0,p1,p2, //in
z0,z1,z2); // out
Vector_2 z01 = z1 - z0 ; Vector_2 z01 = z1 - z0 ;
Vector_2 z02 = z2 - z0 ; Vector_2 z02 = z2 - z0 ;
NT a = z01.x() ; NT a = z01.x() ;
@ -550,23 +544,23 @@ setup_triangle_relations(LeastSquaresSolver* solver,
// //
// Real part // Real part
// Note: b = 0 // Note: b = 0
solver->begin_row() ; solver.begin_row() ;
solver->add_coefficient(u0_id, -a+c) ; solver.add_coefficient(u0_id, -a+c) ;
solver->add_coefficient(v0_id, b-d) ; solver.add_coefficient(v0_id, b-d) ;
solver->add_coefficient(u1_id, -c) ; solver.add_coefficient(u1_id, -c) ;
solver->add_coefficient(v1_id, d) ; solver.add_coefficient(v1_id, d) ;
solver->add_coefficient(u2_id, a) ; solver.add_coefficient(u2_id, a) ;
solver->end_row() ; solver.end_row() ;
// //
// Imaginary part // Imaginary part
// Note: b = 0 // Note: b = 0
solver->begin_row() ; solver.begin_row() ;
solver->add_coefficient(u0_id, -b+d) ; solver.add_coefficient(u0_id, -b+d) ;
solver->add_coefficient(v0_id, -a+c) ; solver.add_coefficient(v0_id, -a+c) ;
solver->add_coefficient(u1_id, -d) ; solver.add_coefficient(u1_id, -d) ;
solver->add_coefficient(v1_id, -c) ; solver.add_coefficient(v1_id, -c) ;
solver->add_coefficient(v2_id, a) ; solver.add_coefficient(v2_id, a) ;
solver->end_row() ; solver.end_row() ;
return Base::OK; return Base::OK;
} }
@ -575,15 +569,15 @@ setup_triangle_relations(LeastSquaresSolver* solver,
template<class Adaptor, class Border_param, class Sparse_LA> template<class Adaptor, class Border_param, class Sparse_LA>
inline inline
void LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>:: void LSCM_parameterizer_3<Adaptor, Border_param, Sparse_LA>::
set_mesh_uv_from_system(Adaptor* mesh, set_mesh_uv_from_system(Adaptor& mesh,
const LeastSquaresSolver& solver) const LeastSquaresSolver& solver)
{ {
Vertex_iterator vertexIt; Vertex_iterator vertexIt;
for (vertexIt = mesh->mesh_vertices_begin(); for (vertexIt = mesh.mesh_vertices_begin();
vertexIt != mesh->mesh_vertices_end(); vertexIt != mesh.mesh_vertices_end();
vertexIt++) vertexIt++)
{ {
int index = mesh->get_vertex_index(vertexIt); int index = mesh.get_vertex_index(vertexIt);
// Note : 2*index --> u // Note : 2*index --> u
// 2*index + 1 --> v // 2*index + 1 --> v
@ -591,8 +585,8 @@ set_mesh_uv_from_system(Adaptor* mesh,
NT v = solver.variable(2*index + 1).value() ; NT v = solver.variable(2*index + 1).value() ;
// Fill vertex (u,v) and mark it as "parameterized" // Fill vertex (u,v) and mark it as "parameterized"
mesh->set_vertex_uv(vertexIt, Point_2(u,v)); mesh.set_vertex_uv(vertexIt, Point_2(u,v));
mesh->set_vertex_parameterized(vertexIt, true); mesh.set_vertex_parameterized(vertexIt, true);
} }
} }

View File

@ -37,7 +37,7 @@ CGAL_BEGIN_NAMESPACE
/// Class Mesh_patch_vertex_around_vertex_cir /// Class Mesh_patch_vertex_around_vertex_cir
/// represents a (clockwise) circulator around a vertex /// represents a (clockwise) circulator around a vertex
/// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh /// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh
template<class MeshPatchPtrType, ///< = [const] Parameterization_mesh_patch_3* template<class MeshPatchType, ///< = [const] Parameterization_mesh_patch_3
class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle
class AdaptorVertexAroundVertexCirculatorType, class AdaptorVertexAroundVertexCirculatorType,
///< = Adaptor::Vertex_around_vertex_[const_]circulator ///< = Adaptor::Vertex_around_vertex_[const_]circulator
@ -53,10 +53,8 @@ class Mesh_patch_vertex_around_vertex_cir
typedef VertexHandleType Base; typedef VertexHandleType Base;
typedef Mesh_patch_vertex_around_vertex_cir Self; typedef Mesh_patch_vertex_around_vertex_cir Self;
/// Mesh_patch types /// Type of the patched mesh
typedef typename std::iterator_traits<MeshPatchPtrType>::value_type typedef typename MeshPatchType::Adaptor Adaptor;
Mesh_patch;
typedef typename Mesh_patch::Adaptor Adaptor;
public: public:
@ -64,38 +62,39 @@ public:
// ------------ // ------------
// Export template parameter types // Export template parameter types
typedef MeshPatchPtrType Mesh_patch_c_ptr; typedef MeshPatchType Parameterization_mesh_patch_3;
typedef VertexHandleType Vertex_c_handle; typedef VertexHandleType Vertex_handle;
typedef AdaptorVertexAroundVertexCirculatorType typedef AdaptorVertexAroundVertexCirculatorType
Adaptor_vertex_around_vertex_c_cir; Adaptor_vertex_around_vertex_circulator;
typedef AdaptorVertexHandleType Adaptor_vertex_c_handle; typedef AdaptorVertexHandleType Adaptor_vertex_handle;
// Iterator types // Iterator types
typedef typename Adaptor_vertex_around_vertex_c_cir::iterator_category typedef typename Adaptor_vertex_around_vertex_circulator::iterator_category
iterator_category; iterator_category;
typedef typename Vertex_c_handle::value_type value_type; typedef typename Vertex_handle::value_type value_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type; typedef std::size_t size_type;
typedef typename Vertex_c_handle::reference reference; typedef typename Vertex_handle::reference reference;
typedef typename Vertex_c_handle::pointer pointer; typedef typename Vertex_handle::pointer pointer;
/// CREATION /// CREATION
/// -------- /// --------
/// Circulator pointing to NULL /// Circulator pointing to NULL
Mesh_patch_vertex_around_vertex_cir() {} Mesh_patch_vertex_around_vertex_cir()
{
m_mesh_patch = NULL;
}
/// Get circulator over the vertices incident to 'vertex' /// Get circulator over the vertices incident to 'vertex'
/// 'start_position' defines the initial position of the circulator [required} /// 'start_position' defines the initial position of the circulator [required}
Mesh_patch_vertex_around_vertex_cir(Mesh_patch_c_ptr mesh, Mesh_patch_vertex_around_vertex_cir(Parameterization_mesh_patch_3& mesh,
Vertex_c_handle vertex, Vertex_handle vertex,
Vertex_c_handle start_position) Vertex_handle start_position)
: Base(start_position), : Base(start_position),
m_mesh_patch(mesh), m_mesh_patch(&mesh),
m_center(vertex) m_center(vertex)
{ {
CGAL_surface_mesh_parameterization_assertion(m_mesh_patch != NULL);
CGAL_surface_mesh_parameterization_assertion(m_mesh_patch->m_mesh_adaptor != NULL);
CGAL_surface_mesh_parameterization_assertion(m_mesh_patch->is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(m_mesh_patch->is_valid(vertex));
CGAL_surface_mesh_parameterization_assertion(m_mesh_patch->is_valid(start_position)); CGAL_surface_mesh_parameterization_assertion(m_mesh_patch->is_valid(start_position));
@ -107,8 +106,8 @@ public:
// Construct an adaptor circulator over the vertices // Construct an adaptor circulator over the vertices
// incident to vertex->vertex() // incident to vertex->vertex()
m_adaptor_circulator = m_mesh_patch->m_mesh_adaptor->vertices_around_vertex_begin( m_adaptor_circulator = m_mesh_patch->m_mesh_adaptor.vertices_around_vertex_begin(
vertex->vertex(), start_position->vertex()); vertex->vertex(), start_position->vertex());
} }
/// Copy constructor /// Copy constructor
@ -199,9 +198,9 @@ public:
{ {
// Update directly the inherited vertex handle // Update directly the inherited vertex handle
// because this case is ambiguous for update_inherited_handle() // because this case is ambiguous for update_inherited_handle()
Vertex_c_handle current_decorated_vertex((*this)->vertex(), Vertex_handle current_decorated_vertex((*this)->vertex(),
(*this)->first_cw_neighbor(), // order... (*this)->first_cw_neighbor(), // order...
(*this)->last_cw_neighbor()); // ...inverted! (*this)->last_cw_neighbor()); // ...inverted!
//#ifdef DEBUG_TRACE //#ifdef DEBUG_TRACE
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = ("; // std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ","; // std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
@ -225,7 +224,7 @@ public:
// because this case is ambiguous for update_inherited_handle() // because this case is ambiguous for update_inherited_handle()
if (m_center->last_cw_neighbor() == m_adaptor_circulator) if (m_center->last_cw_neighbor() == m_adaptor_circulator)
{ {
Vertex_c_handle current_decorated_vertex Vertex_handle current_decorated_vertex
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator, = m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
NULL, NULL,
m_center->vertex()); m_center->vertex());
@ -315,9 +314,9 @@ public:
{ {
// Update directly the inherited vertex handle // Update directly the inherited vertex handle
// because this case is ambiguous for update_inherited_handle() // because this case is ambiguous for update_inherited_handle()
Vertex_c_handle current_decorated_vertex((*this)->vertex(), Vertex_handle current_decorated_vertex((*this)->vertex(),
(*this)->first_cw_neighbor(), // order... (*this)->first_cw_neighbor(), // order...
(*this)->last_cw_neighbor()); // ...inverted! (*this)->last_cw_neighbor()); // ...inverted!
//#ifdef DEBUG_TRACE //#ifdef DEBUG_TRACE
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = ("; // std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ","; // std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
@ -341,7 +340,7 @@ public:
// because this case is ambiguous for update_inherited_handle() // because this case is ambiguous for update_inherited_handle()
if (m_center->last_cw_neighbor() == m_adaptor_circulator) if (m_center->last_cw_neighbor() == m_adaptor_circulator)
{ {
Vertex_c_handle current_decorated_vertex Vertex_handle current_decorated_vertex
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator, = m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
m_center->vertex(), m_center->vertex(),
NULL); NULL);
@ -376,14 +375,14 @@ private:
/// Precondition: m_adaptor_circulator and m_center are valid /// Precondition: m_adaptor_circulator and m_center are valid
void update_inherited_handle() void update_inherited_handle()
{ {
Vertex_c_handle current_decorated_vertex = NULL; Vertex_handle current_decorated_vertex = NULL;
// Easy case: if m_adaptor_circulator is an inner vertex // Easy case: if m_adaptor_circulator is an inner vertex
if (m_mesh_patch->m_mesh_adaptor->get_vertex_seaming( if (m_mesh_patch->m_mesh_adaptor.get_vertex_seaming(
m_adaptor_circulator) != Mesh_patch::BORDER) m_adaptor_circulator) != Parameterization_mesh_patch_3::BORDER)
{ {
// No extra information needed if inner vertex // No extra information needed if inner vertex
current_decorated_vertex = Vertex_c_handle(m_adaptor_circulator); current_decorated_vertex = Vertex_handle(m_adaptor_circulator);
} }
else // if seam vertex else // if seam vertex
{ {
@ -393,8 +392,8 @@ private:
|| m_center->first_cw_neighbor() != m_adaptor_circulator); || m_center->first_cw_neighbor() != m_adaptor_circulator);
// Get next vertex on facet // Get next vertex on facet
Adaptor_vertex_c_handle next_vertex = NULL; Adaptor_vertex_handle next_vertex = NULL;
Adaptor_vertex_around_vertex_c_cir ccw_neighbor = m_adaptor_circulator; Adaptor_vertex_around_vertex_circulator ccw_neighbor = m_adaptor_circulator;
ccw_neighbor--; ccw_neighbor--;
if (m_center->first_cw_neighbor() == NULL) // if inner vertex if (m_center->first_cw_neighbor() == NULL) // if inner vertex
{ {
@ -409,14 +408,14 @@ private:
} }
// If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge // If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge
if (m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming( if (m_mesh_patch->m_mesh_adaptor.get_halfedge_seaming(
m_adaptor_circulator, next_vertex) != Mesh_patch::BORDER m_adaptor_circulator, next_vertex) != Parameterization_mesh_patch_3::BORDER
|| m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming( || m_mesh_patch->m_mesh_adaptor.get_halfedge_seaming(
next_vertex, m_adaptor_circulator) != Mesh_patch::BORDER) next_vertex, m_adaptor_circulator) != Parameterization_mesh_patch_3::BORDER)
{ {
current_decorated_vertex current_decorated_vertex
= m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator, = m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator,
next_vertex); next_vertex);
} }
// Special case: both vertices belong to the seam // Special case: both vertices belong to the seam
else else
@ -442,13 +441,13 @@ private:
private: private:
/// The mesh that we are circulating on: /// The mesh that we are circulating on:
Mesh_patch_c_ptr m_mesh_patch; Parameterization_mesh_patch_3* m_mesh_patch;
/// Vertex center of the circulation (+ circulator range for a border vertex) /// Vertex center of the circulation (+ circulator range for a border vertex)
Vertex_c_handle m_center; Vertex_handle m_center;
/// Internal circulator /// Internal circulator
Adaptor_vertex_around_vertex_c_cir m_adaptor_circulator; Adaptor_vertex_around_vertex_circulator m_adaptor_circulator;
}; // Mesh_patch_vertex_around_vertex_cir }; // Mesh_patch_vertex_around_vertex_cir
@ -457,7 +456,7 @@ private:
/// represents a (clockwise) circulator around a facet /// represents a (clockwise) circulator around a facet
/// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh /// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh
template<class MeshPatchPtrType, ///< = [const] Parameterization_mesh_patch_3* template<class MeshPatchType, ///< = [const] Parameterization_mesh_patch_3
class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle
class AdaptorVertexAroundFacetCirculatorType> class AdaptorVertexAroundFacetCirculatorType>
///< = Adaptor::Vertex_around_facet_[const_]circulator ///< = Adaptor::Vertex_around_facet_[const_]circulator
@ -471,10 +470,8 @@ class Mesh_patch_vertex_around_facet_cir
typedef VertexHandleType Base; typedef VertexHandleType Base;
typedef Mesh_patch_vertex_around_facet_cir Self; typedef Mesh_patch_vertex_around_facet_cir Self;
/// Mesh_patch types /// Type of the patched mesh
typedef typename std::iterator_traits<MeshPatchPtrType>::value_type typedef typename MeshPatchType::Adaptor Adaptor;
Mesh_patch;
typedef typename Mesh_patch::Adaptor Adaptor;
public: public:
@ -482,32 +479,34 @@ public:
// ------------ // ------------
// Export template parameter types // Export template parameter types
typedef MeshPatchPtrType Mesh_patch_c_ptr; typedef MeshPatchType Parameterization_mesh_patch_3;
typedef VertexHandleType Vertex_c_handle; typedef VertexHandleType Vertex_handle;
typedef AdaptorVertexAroundFacetCirculatorType typedef AdaptorVertexAroundFacetCirculatorType
Adaptor_vertex_around_facet_c_cir; Adaptor_vertex_around_facet_circulator;
// Iterator types // Iterator types
typedef typename Adaptor_vertex_around_facet_c_cir::iterator_category typedef typename Adaptor_vertex_around_facet_circulator::iterator_category
iterator_category; iterator_category;
typedef typename Vertex_c_handle::value_type value_type; typedef typename Vertex_handle::value_type value_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type; typedef std::size_t size_type;
typedef typename Vertex_c_handle::reference reference; typedef typename Vertex_handle::reference reference;
typedef typename Vertex_c_handle::pointer pointer; typedef typename Vertex_handle::pointer pointer;
/// CREATION /// CREATION
/// -------- /// --------
/// Circulator pointing to NULL /// Circulator pointing to NULL
Mesh_patch_vertex_around_facet_cir() {} Mesh_patch_vertex_around_facet_cir()
{
m_mesh_patch = NULL;
}
Mesh_patch_vertex_around_facet_cir(Mesh_patch_c_ptr mesh, Mesh_patch_vertex_around_facet_cir(Parameterization_mesh_patch_3& mesh,
Adaptor_vertex_around_facet_c_cir adaptor_circulator) Adaptor_vertex_around_facet_circulator adaptor_circulator)
: m_mesh_patch(mesh), : m_mesh_patch(&mesh),
m_adaptor_circulator(adaptor_circulator) m_adaptor_circulator(adaptor_circulator)
{ {
CGAL_surface_mesh_parameterization_assertion(m_mesh_patch != NULL);
CGAL_surface_mesh_parameterization_assertion(adaptor_circulator != NULL); CGAL_surface_mesh_parameterization_assertion(adaptor_circulator != NULL);
// Update the inherited vertex handle // Update the inherited vertex handle
@ -590,17 +589,17 @@ private:
/// Precondition: m_adaptor_circulator is valid /// Precondition: m_adaptor_circulator is valid
void update_inherited_handle() void update_inherited_handle()
{ {
Vertex_c_handle current_decorated_vertex = NULL; Vertex_handle current_decorated_vertex = NULL;
// Get next vertex on facet // Get next vertex on facet
Adaptor_vertex_around_facet_c_cir next_vertex = m_adaptor_circulator; Adaptor_vertex_around_facet_circulator next_vertex = m_adaptor_circulator;
next_vertex++; next_vertex++;
// If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge // If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge
if (m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming( if (m_mesh_patch->m_mesh_adaptor.get_halfedge_seaming(
m_adaptor_circulator, next_vertex) != Mesh_patch::BORDER m_adaptor_circulator, next_vertex) != Parameterization_mesh_patch_3::BORDER
|| m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming( || m_mesh_patch->m_mesh_adaptor.get_halfedge_seaming(
next_vertex, m_adaptor_circulator) != Mesh_patch::BORDER) next_vertex, m_adaptor_circulator) != Parameterization_mesh_patch_3::BORDER)
{ {
current_decorated_vertex current_decorated_vertex
= m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator, = m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator,
@ -622,10 +621,10 @@ private:
private: private:
/// The mesh that we are circulating on: /// The mesh that we are circulating on:
Mesh_patch_c_ptr m_mesh_patch; Parameterization_mesh_patch_3* m_mesh_patch;
/// Internal circulator /// Internal circulator
Adaptor_vertex_around_facet_c_cir m_adaptor_circulator; Adaptor_vertex_around_facet_circulator m_adaptor_circulator;
}; // Mesh_patch_vertex_around_facet_cir }; // Mesh_patch_vertex_around_facet_cir

View File

@ -90,11 +90,10 @@ public:
/// CAUTION: This class caches the result of feature extractions /// CAUTION: This class caches the result of feature extractions
/// => The caller must NOT modify 'mesh' during the /// => The caller must NOT modify 'mesh' during the
/// Parameterization_mesh_feature_extractor life cycle. /// Parameterization_mesh_feature_extractor life cycle.
Parameterization_mesh_feature_extractor(Adaptor *mesh) Parameterization_mesh_feature_extractor(Adaptor& mesh)
// Store reference to adapted mesh
: m_mesh_adaptor(mesh)
{ {
m_mesh_adaptor = mesh;
CGAL_surface_mesh_parameterization_assertion(m_mesh_adaptor != NULL);
// m_mesh_adaptor features are not yet computed // m_mesh_adaptor features are not yet computed
m_nb_connex_components = -1; m_nb_connex_components = -1;
m_nb_borders = -1; m_nb_borders = -1;
@ -122,13 +121,13 @@ public:
return m_skeleton; return m_skeleton;
} }
/// Get longest border. /// Get longest border.
const Border* get_longest_border() const Border& get_longest_border()
{ {
// At first call, extract borders and put longest one first // At first call, extract borders and put longest one first
if (m_nb_borders == -1) if (m_nb_borders == -1)
extract_borders(); extract_borders();
return m_skeleton[0]; return *(m_skeleton[0]);
} }
/// Get # of connected components. /// Get # of connected components.
@ -163,11 +162,11 @@ private:
// Tag all vertices as unprocessed // Tag all vertices as unprocessed
const int tag_free = 0; const int tag_free = 0;
const int tag_done = 1; const int tag_done = 1;
for (Vertex_iterator it = m_mesh_adaptor->mesh_vertices_begin(); for (Vertex_iterator it = m_mesh_adaptor.mesh_vertices_begin();
it != m_mesh_adaptor->mesh_vertices_end(); it != m_mesh_adaptor.mesh_vertices_end();
it++) it++)
{ {
m_mesh_adaptor->set_vertex_tag(it, tag_free); m_mesh_adaptor.set_vertex_tag(it, tag_free);
} }
// find all closed borders // find all closed borders
@ -211,12 +210,12 @@ private:
// get any border vertex with "free" tag // get any border vertex with "free" tag
Vertex_handle seed_vertex = NULL; Vertex_handle seed_vertex = NULL;
for (Vertex_iterator pVertex = m_mesh_adaptor->mesh_vertices_begin(); for (Vertex_iterator pVertex = m_mesh_adaptor.mesh_vertices_begin();
pVertex != m_mesh_adaptor->mesh_vertices_end(); pVertex != m_mesh_adaptor.mesh_vertices_end();
pVertex++) pVertex++)
{ {
if (m_mesh_adaptor->is_vertex_on_border(pVertex) && if (m_mesh_adaptor.is_vertex_on_border(pVertex) &&
m_mesh_adaptor->get_vertex_tag(pVertex) == tag_free) m_mesh_adaptor.get_vertex_tag(pVertex) == tag_free)
{ {
seed_vertex = pVertex; seed_vertex = pVertex;
break; break;
@ -226,12 +225,12 @@ private:
return border; // return empty list return border; // return empty list
// Get the border containing seed_vertex // Get the border containing seed_vertex
border = m_mesh_adaptor->get_border(seed_vertex); border = m_mesh_adaptor.get_border(seed_vertex);
// Tag border vertices as "processed" // Tag border vertices as "processed"
typename std::list<Vertex_handle>::iterator it; typename std::list<Vertex_handle>::iterator it;
for(it = border.begin(); it != border.end(); it++) for(it = border.begin(); it != border.end(); it++)
m_mesh_adaptor->set_vertex_tag(*it, tag_done); m_mesh_adaptor.set_vertex_tag(*it, tag_done);
return border; return border;
} }
@ -248,7 +247,7 @@ private:
for(int i=0;i<nb;i++) for(int i=0;i<nb;i++)
{ {
const Border *pBorder = m_skeleton[i]; const Border *pBorder = m_skeleton[i];
double length = len(pBorder); double length = len(*pBorder);
if (length > max) if (length > max)
{ {
index = i; index = i;
@ -260,20 +259,20 @@ private:
} }
/// Compute total len of a border. /// Compute total len of a border.
double len(const Border* pBorder) const double len(const Border& border) const
{ {
double len = 0.0; double len = 0.0;
typename std::list<typename Adaptor::Vertex_handle>::const_iterator it; typename std::list<typename Adaptor::Vertex_handle>::const_iterator it;
for(it = pBorder->begin(); it != pBorder->end(); it++) for(it = border.begin(); it != border.end(); it++)
{ {
// Get next iterator (looping) // Get next iterator (looping)
typename std::list<typename Adaptor::Vertex_handle>::const_iterator next = it; typename std::list<typename Adaptor::Vertex_handle>::const_iterator next = it;
next++; next++;
if (next == pBorder->end()) if (next == border.end())
next = pBorder->begin(); next = border.begin();
Vector_3 v = m_mesh_adaptor->get_vertex_position(*next) Vector_3 v = m_mesh_adaptor.get_vertex_position(*next)
- m_mesh_adaptor->get_vertex_position(*it); - m_mesh_adaptor.get_vertex_position(*it);
len += std::sqrt(v*v); len += std::sqrt(v*v);
} }
return len; return len;
@ -287,11 +286,11 @@ private:
const int tag_free = 0; const int tag_free = 0;
const int tag_done = 1; const int tag_done = 1;
for (Vertex_iterator it = m_mesh_adaptor->mesh_vertices_begin(); for (Vertex_iterator it = m_mesh_adaptor.mesh_vertices_begin();
it != m_mesh_adaptor->mesh_vertices_end(); it != m_mesh_adaptor.mesh_vertices_end();
it++) it++)
{ {
m_mesh_adaptor->set_vertex_tag(it, tag_free); m_mesh_adaptor.set_vertex_tag(it, tag_free);
} }
Vertex_handle seed_vertex = NULL; Vertex_handle seed_vertex = NULL;
@ -305,11 +304,11 @@ private:
/// Get any vertex with tag. /// Get any vertex with tag.
Vertex_handle get_any_vertex_tag(int tag) Vertex_handle get_any_vertex_tag(int tag)
{ {
for (Vertex_iterator it = m_mesh_adaptor->mesh_vertices_begin(); for (Vertex_iterator it = m_mesh_adaptor.mesh_vertices_begin();
it != m_mesh_adaptor->mesh_vertices_end(); it != m_mesh_adaptor.mesh_vertices_end();
it++) it++)
{ {
if (m_mesh_adaptor->get_vertex_tag(it) == tag) if (m_mesh_adaptor.get_vertex_tag(it) == tag)
return it; return it;
} }
@ -321,7 +320,7 @@ private:
const int tag_free, const int tag_free,
const int tag_done) const int tag_done)
{ {
assert(m_mesh_adaptor->get_vertex_tag(pSeedVertex) == tag_free); assert(m_mesh_adaptor.get_vertex_tag(pSeedVertex) == tag_free);
std::list<Vertex_handle> vertices; std::list<Vertex_handle> vertices;
vertices.push_front(pSeedVertex); vertices.push_front(pSeedVertex);
@ -332,16 +331,16 @@ private:
vertices.pop_front(); vertices.pop_front();
// Stop if already done // Stop if already done
if (m_mesh_adaptor->get_vertex_tag(pVertex) == tag_done) if (m_mesh_adaptor.get_vertex_tag(pVertex) == tag_done)
continue; continue;
m_mesh_adaptor->set_vertex_tag(pVertex, tag_done); m_mesh_adaptor.set_vertex_tag(pVertex, tag_done);
Vertex_around_vertex_circulator cir, cir_end; Vertex_around_vertex_circulator cir, cir_end;
cir = m_mesh_adaptor->vertices_around_vertex_begin(pVertex); cir = m_mesh_adaptor.vertices_around_vertex_begin(pVertex);
cir_end = cir; cir_end = cir;
CGAL_For_all(cir,cir_end) CGAL_For_all(cir,cir_end)
if (m_mesh_adaptor->get_vertex_tag(cir) == tag_free) if (m_mesh_adaptor.get_vertex_tag(cir) == tag_free)
vertices.push_front(cir); vertices.push_front(cir);
} }
} }
@ -360,9 +359,9 @@ private:
{ {
int c = get_nb_connex_components(); int c = get_nb_connex_components();
int b = get_nb_borders(); int b = get_nb_borders();
int v = m_mesh_adaptor->count_mesh_vertices(); int v = m_mesh_adaptor.count_mesh_vertices();
int e = m_mesh_adaptor->count_mesh_halfedges()/2; int e = m_mesh_adaptor.count_mesh_halfedges()/2;
int f = m_mesh_adaptor->count_mesh_facets(); int f = m_mesh_adaptor.count_mesh_facets();
m_genus = (2*c+e-b-f-v)/2; m_genus = (2*c+e-b-f-v)/2;
} }
@ -371,7 +370,7 @@ private:
private: private:
/// Pointer to mesh to parse /// Pointer to mesh to parse
Adaptor* m_mesh_adaptor; Adaptor& m_mesh_adaptor;
/// m_mesh_adaptor features: /// m_mesh_adaptor features:
int m_nb_borders; int m_nb_borders;

View File

@ -129,22 +129,22 @@ public:
typedef Vertex_const_iterator Border_vertex_const_iterator; typedef Vertex_const_iterator Border_vertex_const_iterator;
/// Counter-clockwise circulator over a facet's vertices. /// Counter-clockwise circulator over a facet's vertices.
/// Model of the BidirectionalCirculator concept. /// Model of the BidirectionalCirculator concept.
typedef Mesh_patch_vertex_around_facet_cir<Parameterization_mesh_patch_3*, typedef Mesh_patch_vertex_around_facet_cir<Parameterization_mesh_patch_3,
Vertex_handle, Vertex_handle,
typename Adaptor::Vertex_around_facet_circulator> typename Adaptor::Vertex_around_facet_circulator>
Vertex_around_facet_circulator; Vertex_around_facet_circulator;
typedef Mesh_patch_vertex_around_facet_cir<const Parameterization_mesh_patch_3*, typedef Mesh_patch_vertex_around_facet_cir<const Parameterization_mesh_patch_3,
Vertex_const_handle, Vertex_const_handle,
typename Adaptor::Vertex_around_facet_const_circulator> typename Adaptor::Vertex_around_facet_const_circulator>
Vertex_around_facet_const_circulator; Vertex_around_facet_const_circulator;
/// Clockwise circulator over the vertices incident to a vertex. /// Clockwise circulator over the vertices incident to a vertex.
/// Model of the BidirectionalCirculator concept. /// Model of the BidirectionalCirculator concept.
typedef Mesh_patch_vertex_around_vertex_cir<Parameterization_mesh_patch_3*, typedef Mesh_patch_vertex_around_vertex_cir<Parameterization_mesh_patch_3,
Vertex_handle, Vertex_handle,
typename Adaptor::Vertex_around_vertex_circulator, typename Adaptor::Vertex_around_vertex_circulator,
typename Adaptor::Vertex_handle> typename Adaptor::Vertex_handle>
Vertex_around_vertex_circulator; Vertex_around_vertex_circulator;
typedef Mesh_patch_vertex_around_vertex_cir<const Parameterization_mesh_patch_3*, typedef Mesh_patch_vertex_around_vertex_cir<const Parameterization_mesh_patch_3,
Vertex_const_handle, Vertex_const_handle,
typename Adaptor::Vertex_around_vertex_const_circulator, typename Adaptor::Vertex_around_vertex_const_circulator,
typename Adaptor::Vertex_const_handle> typename Adaptor::Vertex_const_handle>
@ -170,13 +170,12 @@ public:
/// ie Parameterization_mesh_patch_3 will export the "right" of the seam. /// ie Parameterization_mesh_patch_3 will export the "right" of the seam.
/// - the "seam" is given as a container of Adaptor::Vertex_handle elements. /// - the "seam" is given as a container of Adaptor::Vertex_handle elements.
template<class InputIterator> template<class InputIterator>
Parameterization_mesh_patch_3(Adaptor* mesh, Parameterization_mesh_patch_3(Adaptor& mesh,
InputIterator first_seam_vertex, InputIterator first_seam_vertex,
InputIterator end_seam_vertex) InputIterator end_seam_vertex)
// Store reference to adapted mesh
: m_mesh_adaptor(mesh)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
m_mesh_adaptor = mesh;
// Set seaming flag of all vertices and edges to INNER, BORDER or OUTER // Set seaming flag of all vertices and edges to INNER, BORDER or OUTER
// wrt the first_seam_vertex -> end_seam_vertex border // wrt the first_seam_vertex -> end_seam_vertex border
set_mesh_seaming(first_seam_vertex, end_seam_vertex); set_mesh_seaming(first_seam_vertex, end_seam_vertex);
@ -184,11 +183,11 @@ public:
// Construct the list of all exported vertices, ie INNER and BORDER vertices // Construct the list of all exported vertices, ie INNER and BORDER vertices
// //
// 1) add inner vertices // 1) add inner vertices
for (typename Adaptor::Vertex_iterator it = mesh->mesh_vertices_begin(); for (typename Adaptor::Vertex_iterator it = mesh.mesh_vertices_begin();
it != mesh->mesh_vertices_end(); it != mesh.mesh_vertices_end();
it++) it++)
{ {
if (m_mesh_adaptor->get_vertex_seaming(it) == INNER) if (m_mesh_adaptor.get_vertex_seaming(it) == INNER)
m_inner_and_border_vertices.push_back( Vertex(it) ); m_inner_and_border_vertices.push_back( Vertex(it) );
} }
// 2) add seam vertices, wrt outer seam/border order // 2) add seam vertices, wrt outer seam/border order
@ -200,7 +199,7 @@ public:
// Get outer border vertex // Get outer border vertex
Vertex v; Vertex v;
// if border vertex // if border vertex
if (m_mesh_adaptor->get_halfedge_seaming(*border_it, *prev_border_it) != BORDER) if (m_mesh_adaptor.get_halfedge_seaming(*border_it, *prev_border_it) != BORDER)
v = Vertex(*border_it, *prev_border_it, *next_border_it); v = Vertex(*border_it, *prev_border_it, *next_border_it);
else // if seam vertex else // if seam vertex
v = Vertex(*border_it, *next_border_it, *prev_border_it); // order inverted! v = Vertex(*border_it, *next_border_it, *prev_border_it); // order inverted!
@ -237,8 +236,8 @@ public:
} }
/// Get the decorated mesh. /// Get the decorated mesh.
Adaptor* get_decorated_mesh() { return m_mesh_adaptor; } Adaptor& get_decorated_mesh() { return *m_mesh_adaptor; }
const Adaptor* get_decorated_mesh() const { return m_mesh_adaptor; } const Adaptor& get_decorated_mesh() const { return *m_mesh_adaptor; }
//@} // end of INTERFACE SPECIFIC TO Parameterization_mesh_patch_3 //@} // end of INTERFACE SPECIFIC TO Parameterization_mesh_patch_3
@ -326,7 +325,7 @@ public:
{ {
// Get list of vertices on this border // Get list of vertices on this border
std::list<typename Adaptor::Vertex_handle> adaptor_border = std::list<typename Adaptor::Vertex_handle> adaptor_border =
m_mesh_adaptor->get_border(seed_vertex->vertex()); m_mesh_adaptor.get_border(seed_vertex->vertex());
// Copy them into 'border' // Copy them into 'border'
for (typename std::list<typename Adaptor::Vertex_handle>::iterator it = adaptor_border.begin(); for (typename std::list<typename Adaptor::Vertex_handle>::iterator it = adaptor_border.begin();
@ -334,7 +333,7 @@ public:
it++) it++)
{ {
// Check that vertex is inner // Check that vertex is inner
assert(m_mesh_adaptor->get_vertex_seaming(*it) == INNER); assert(m_mesh_adaptor.get_vertex_seaming(*it) == INNER);
border.push_back( Vertex_handle(*it) ); border.push_back( Vertex_handle(*it) );
} }
} }
@ -344,24 +343,24 @@ public:
/// Get iterator over first facet of mesh. /// Get iterator over first facet of mesh.
Facet_iterator mesh_facets_begin() { Facet_iterator mesh_facets_begin() {
return Facet_iterator(m_mesh_adaptor->mesh_facets_end(), return Facet_iterator(m_mesh_adaptor.mesh_facets_end(),
Inner_facets_filter(this), Inner_facets_filter(*this),
m_mesh_adaptor->mesh_facets_begin()); m_mesh_adaptor.mesh_facets_begin());
} }
Facet_const_iterator mesh_facets_begin() const { Facet_const_iterator mesh_facets_begin() const {
return Facet_const_iterator(m_mesh_adaptor->mesh_facets_end(), return Facet_const_iterator(m_mesh_adaptor.mesh_facets_end(),
Inner_facets_filter(this), Inner_facets_filter(*this),
m_mesh_adaptor->mesh_facets_begin()); m_mesh_adaptor.mesh_facets_begin());
} }
/// Get iterator over past-the-end facet of mesh. /// Get iterator over past-the-end facet of mesh.
Facet_iterator mesh_facets_end() { Facet_iterator mesh_facets_end() {
return Facet_iterator(m_mesh_adaptor->mesh_facets_end(), return Facet_iterator(m_mesh_adaptor.mesh_facets_end(),
Inner_facets_filter(this)); Inner_facets_filter(*this));
} }
Facet_const_iterator mesh_facets_end() const { Facet_const_iterator mesh_facets_end() const {
return Facet_const_iterator(m_mesh_adaptor->mesh_facets_end(), return Facet_const_iterator(m_mesh_adaptor.mesh_facets_end(),
Inner_facets_filter(this)); Inner_facets_filter(*this));
} }
/// Count the number of facets of the mesh. /// Count the number of facets of the mesh.
@ -399,11 +398,11 @@ public:
/// Get circulator over facet's vertices. /// Get circulator over facet's vertices.
Vertex_around_facet_circulator facet_vertices_begin(Facet_handle facet) { Vertex_around_facet_circulator facet_vertices_begin(Facet_handle facet) {
CGAL_surface_mesh_parameterization_assertion(is_valid(facet)); CGAL_surface_mesh_parameterization_assertion(is_valid(facet));
return Vertex_around_facet_circulator(this, m_mesh_adaptor->facet_vertices_begin(facet)); return Vertex_around_facet_circulator(*this, m_mesh_adaptor.facet_vertices_begin(facet));
} }
Vertex_around_facet_const_circulator facet_vertices_begin(Facet_const_handle facet) const { Vertex_around_facet_const_circulator facet_vertices_begin(Facet_const_handle facet) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(facet)); CGAL_surface_mesh_parameterization_assertion(is_valid(facet));
return Vertex_around_facet_const_circulator(this, m_mesh_adaptor->facet_vertices_begin(facet)); return Vertex_around_facet_const_circulator(*this, m_mesh_adaptor.facet_vertices_begin(facet));
} }
/// Count the number of vertices of a facet. /// Count the number of vertices of a facet.
@ -422,75 +421,75 @@ public:
/// Get the 3D position of a vertex. /// Get the 3D position of a vertex.
Point_3 get_vertex_position(Vertex_const_handle vertex) const { Point_3 get_vertex_position(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->get_vertex_position(vertex->vertex()); return m_mesh_adaptor.get_vertex_position(vertex->vertex());
} }
/// Get/set the 2D position (u/v pair) of a vertex. Default value is undefined. /// Get/set the 2D position (u/v pair) of a vertex. Default value is undefined.
Point_2 get_vertex_uv(Vertex_const_handle vertex) const { Point_2 get_vertex_uv(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->get_corners_uv(vertex->vertex(), return m_mesh_adaptor.get_corners_uv(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor()); vertex->first_cw_neighbor());
} }
void set_vertex_uv(Vertex_handle vertex, const Point_2& uv) void set_vertex_uv(Vertex_handle vertex, const Point_2& uv)
{ {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->set_corners_uv(vertex->vertex(), return m_mesh_adaptor.set_corners_uv(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor(), vertex->first_cw_neighbor(),
uv); uv);
} }
/// Get/set "is parameterized" field of vertex. Default value is undefined. /// Get/set "is parameterized" field of vertex. Default value is undefined.
bool is_vertex_parameterized(Vertex_const_handle vertex) const { bool is_vertex_parameterized(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->are_corners_parameterized(vertex->vertex(), return m_mesh_adaptor.are_corners_parameterized(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor()); vertex->first_cw_neighbor());
} }
void set_vertex_parameterized(Vertex_handle vertex, bool parameterized) void set_vertex_parameterized(Vertex_handle vertex, bool parameterized)
{ {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->set_corners_parameterized(vertex->vertex(), return m_mesh_adaptor.set_corners_parameterized(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor(), vertex->first_cw_neighbor(),
parameterized); parameterized);
} }
/// Get/set vertex index. Default value is undefined. /// Get/set vertex index. Default value is undefined.
int get_vertex_index(Vertex_const_handle vertex) const { int get_vertex_index(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->get_corners_index(vertex->vertex(), return m_mesh_adaptor.get_corners_index(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor()); vertex->first_cw_neighbor());
} }
void set_vertex_index(Vertex_handle vertex, int index) { void set_vertex_index(Vertex_handle vertex, int index) {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->set_corners_index(vertex->vertex(), return m_mesh_adaptor.set_corners_index(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor(), vertex->first_cw_neighbor(),
index); index);
} }
/// Get/set vertex' all purpose tag. Default value is undefined. /// Get/set vertex' all purpose tag. Default value is undefined.
int get_vertex_tag(Vertex_const_handle vertex) const { int get_vertex_tag(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return m_mesh_adaptor->get_corners_tag(vertex->vertex(), return m_mesh_adaptor.get_corners_tag(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor()); vertex->first_cw_neighbor());
} }
void set_vertex_tag(Vertex_handle vertex, int tag) { void set_vertex_tag(Vertex_handle vertex, int tag) {
return m_mesh_adaptor->set_corners_tag(vertex->vertex(), return m_mesh_adaptor.set_corners_tag(vertex->vertex(),
vertex->last_cw_neighbor(), vertex->last_cw_neighbor(),
vertex->first_cw_neighbor(), vertex->first_cw_neighbor(),
tag); tag);
} }
/// Return true if a vertex belongs to ANY mesh's border. /// Return true if a vertex belongs to ANY mesh's border.
bool is_vertex_on_border(Vertex_const_handle vertex) const { bool is_vertex_on_border(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return is_vertex_on_main_border(vertex) || return is_vertex_on_main_border(vertex) ||
m_mesh_adaptor->is_vertex_on_border(vertex->vertex()); m_mesh_adaptor.is_vertex_on_border(vertex->vertex());
} }
/// Return true if a vertex belongs to the UNIQUE mesh's main border /// Return true if a vertex belongs to the UNIQUE mesh's main border
@ -517,7 +516,7 @@ public:
if (vertex->last_cw_neighbor() == NULL) if (vertex->last_cw_neighbor() == NULL)
{ {
typename Adaptor::Vertex_around_vertex_circulator adaptor_circulator typename Adaptor::Vertex_around_vertex_circulator adaptor_circulator
= m_mesh_adaptor->vertices_around_vertex_begin(vertex->vertex()); = m_mesh_adaptor.vertices_around_vertex_begin(vertex->vertex());
start_position = get_decorated_inner_vertex(adaptor_circulator, start_position = get_decorated_inner_vertex(adaptor_circulator,
vertex->vertex()); vertex->vertex());
} }
@ -529,7 +528,7 @@ public:
} }
} }
return Vertex_around_vertex_circulator(this, vertex, start_position); return Vertex_around_vertex_circulator(*this, vertex, start_position);
} }
Vertex_around_vertex_const_circulator vertices_around_vertex_begin( Vertex_around_vertex_const_circulator vertices_around_vertex_begin(
Vertex_const_handle vertex, Vertex_const_handle vertex,
@ -546,7 +545,7 @@ public:
if (vertex->last_cw_neighbor() == NULL) if (vertex->last_cw_neighbor() == NULL)
{ {
typename Adaptor::Vertex_around_vertex_const_circulator adaptor_circulator typename Adaptor::Vertex_around_vertex_const_circulator adaptor_circulator
= m_mesh_adaptor->vertices_around_vertex_begin(vertex->vertex()); = m_mesh_adaptor.vertices_around_vertex_begin(vertex->vertex());
start_position = get_decorated_inner_vertex(adaptor_circulator, start_position = get_decorated_inner_vertex(adaptor_circulator,
vertex->vertex()); vertex->vertex());
} }
@ -558,7 +557,7 @@ public:
} }
} }
return Vertex_around_vertex_const_circulator(this, vertex, start_position); return Vertex_around_vertex_const_circulator(*this, vertex, start_position);
} }
//@} // end of ParameterizationMesh_3 INTERFACE //@} // end of ParameterizationMesh_3 INTERFACE
@ -584,24 +583,24 @@ private:
InputIterator end_seam_vertex) InputIterator end_seam_vertex)
{ {
// Initialize the seaming flag of all vertices to OUTER // Initialize the seaming flag of all vertices to OUTER
for (typename Adaptor::Vertex_iterator it = m_mesh_adaptor->mesh_vertices_begin(); for (typename Adaptor::Vertex_iterator it = m_mesh_adaptor.mesh_vertices_begin();
it != m_mesh_adaptor->mesh_vertices_end(); it != m_mesh_adaptor.mesh_vertices_end();
it++) it++)
{ {
m_mesh_adaptor->set_vertex_seaming(it, OUTER); m_mesh_adaptor.set_vertex_seaming(it, OUTER);
} }
// Initialize the seaming flag of all halfedges to OUTER // Initialize the seaming flag of all halfedges to OUTER
for (typename Adaptor::Vertex_iterator it = m_mesh_adaptor->mesh_vertices_begin(); for (typename Adaptor::Vertex_iterator it = m_mesh_adaptor.mesh_vertices_begin();
it != m_mesh_adaptor->mesh_vertices_end(); it != m_mesh_adaptor.mesh_vertices_end();
it++) it++)
{ {
// For each neighbor vertex // For each neighbor vertex
typename Adaptor::Vertex_around_vertex_circulator cir, cir_end; typename Adaptor::Vertex_around_vertex_circulator cir, cir_end;
cir = m_mesh_adaptor->vertices_around_vertex_begin(it); cir = m_mesh_adaptor.vertices_around_vertex_begin(it);
cir_end = cir; cir_end = cir;
CGAL_For_all(cir, cir_end) CGAL_For_all(cir, cir_end)
m_mesh_adaptor->set_halfedge_seaming(it, cir, OUTER); m_mesh_adaptor.set_halfedge_seaming(it, cir, OUTER);
} }
// Set seaming flag of seam vertices to BORDER. // Set seaming flag of seam vertices to BORDER.
@ -612,8 +611,7 @@ private:
border_it++) border_it++)
{ {
// Set vertex seaming flag // Set vertex seaming flag
m_mesh_adaptor->set_vertex_seaming(*border_it, m_mesh_adaptor.set_vertex_seaming(*border_it, BORDER);
BORDER);
// Get next iterator (looping) // Get next iterator (looping)
InputIterator next_border_it = border_it; InputIterator next_border_it = border_it;
@ -622,14 +620,14 @@ private:
next_border_it = first_seam_vertex; next_border_it = first_seam_vertex;
// Set outer seam edge to BORDER // Set outer seam edge to BORDER
m_mesh_adaptor->set_halfedge_seaming(*border_it, *next_border_it, m_mesh_adaptor.set_halfedge_seaming(*border_it, *next_border_it,
BORDER); BORDER);
// Set inner seam edge to INNER (except if also BORDER) // Set inner seam edge to INNER (except if also BORDER)
if (m_mesh_adaptor->get_halfedge_seaming(*next_border_it, if (m_mesh_adaptor.get_halfedge_seaming(*next_border_it,
*border_it) != BORDER) { *border_it) != BORDER) {
m_mesh_adaptor->set_halfedge_seaming(*next_border_it, *border_it, m_mesh_adaptor.set_halfedge_seaming(*next_border_it, *border_it,
INNER); INNER);
} }
} }
@ -647,12 +645,12 @@ private:
// Get inner point at the "right" of *border_it // Get inner point at the "right" of *border_it
// by a counter-clockwise rotation around the next seam vertex // by a counter-clockwise rotation around the next seam vertex
typename Adaptor::Vertex_around_vertex_circulator cir = typename Adaptor::Vertex_around_vertex_circulator cir =
m_mesh_adaptor->vertices_around_vertex_begin(*next_border_it, m_mesh_adaptor.vertices_around_vertex_begin(*next_border_it,
*border_it); *border_it);
cir--; cir--;
// Fill topological disk // Fill topological disk
if (m_mesh_adaptor->get_vertex_seaming(cir) != BORDER) if (m_mesh_adaptor.get_vertex_seaming(cir) != BORDER)
set_inner_region_seaming(cir); set_inner_region_seaming(cir);
} }
} }
@ -688,23 +686,23 @@ private:
CGAL_surface_mesh_parameterization_assertion(pVertex != NULL); CGAL_surface_mesh_parameterization_assertion(pVertex != NULL);
// Flag this vertex as INNER // Flag this vertex as INNER
if (m_mesh_adaptor->get_vertex_seaming(pVertex) == OUTER) if (m_mesh_adaptor.get_vertex_seaming(pVertex) == OUTER)
m_mesh_adaptor->set_vertex_seaming(pVertex, INNER); m_mesh_adaptor.set_vertex_seaming(pVertex, INNER);
else else
continue; // Skip this vertex if it is already done continue; // Skip this vertex if it is already done
// For each neighbor vertex // For each neighbor vertex
typename Adaptor::Vertex_around_vertex_circulator cir, cir_end; typename Adaptor::Vertex_around_vertex_circulator cir, cir_end;
cir = m_mesh_adaptor->vertices_around_vertex_begin(pVertex); cir = m_mesh_adaptor.vertices_around_vertex_begin(pVertex);
cir_end = cir; cir_end = cir;
CGAL_For_all(cir, cir_end) CGAL_For_all(cir, cir_end)
{ {
// Flag both oriented edges pVertex <-> cir // Flag both oriented edges pVertex <-> cir
m_mesh_adaptor->set_halfedge_seaming(pVertex, cir, INNER); m_mesh_adaptor.set_halfedge_seaming(pVertex, cir, INNER);
m_mesh_adaptor->set_halfedge_seaming(cir, pVertex, INNER); m_mesh_adaptor.set_halfedge_seaming(cir, pVertex, INNER);
// Add surrounding vertices to list without crossing the border // Add surrounding vertices to list without crossing the border
if (m_mesh_adaptor->get_vertex_seaming(cir) == OUTER) if (m_mesh_adaptor.get_vertex_seaming(cir) == OUTER)
vertices.push_front(cir); vertices.push_front(cir);
} }
} }
@ -717,9 +715,9 @@ private:
CGAL_surface_mesh_parameterization_assertion(facet != NULL); CGAL_surface_mesh_parameterization_assertion(facet != NULL);
typename Adaptor::Vertex_around_facet_const_circulator typename Adaptor::Vertex_around_facet_const_circulator
cir = m_mesh_adaptor->facet_vertices_begin(facet); cir = m_mesh_adaptor.facet_vertices_begin(facet);
CGAL_surface_mesh_parameterization_assertion(cir != NULL); CGAL_surface_mesh_parameterization_assertion(cir != NULL);
return (m_mesh_adaptor->get_vertex_seaming(cir) == OUTER) ? return (m_mesh_adaptor.get_vertex_seaming(cir) == OUTER) ?
OUTER : OUTER :
INNER; INNER;
} }
@ -728,11 +726,11 @@ private:
/// ie position of the vertex wrt to the UNIQUE main border. /// ie position of the vertex wrt to the UNIQUE main border.
Seaming_status get_vertex_seaming(Vertex_const_handle vertex) const { Seaming_status get_vertex_seaming(Vertex_const_handle vertex) const {
CGAL_surface_mesh_parameterization_assertion(is_valid(vertex)); CGAL_surface_mesh_parameterization_assertion(is_valid(vertex));
return (Seaming_status) m_mesh_adaptor->get_vertex_seaming( return (Seaming_status) m_mesh_adaptor.get_vertex_seaming(
vertex->vertex()); vertex->vertex());
} }
void set_vertex_seaming(Vertex_handle vertex, Seaming_status seaming) { void set_vertex_seaming(Vertex_handle vertex, Seaming_status seaming) {
m_mesh_adaptor->set_vertex_seaming(vertex->vertex(), seaming); m_mesh_adaptor.set_vertex_seaming(vertex->vertex(), seaming);
} }
/// Create a patch vertex from an adaptor vertex + one of its neighbors. /// Create a patch vertex from an adaptor vertex + one of its neighbors.
@ -745,13 +743,13 @@ private:
typename Adaptor::Vertex_const_handle adaptor_neighbor) const typename Adaptor::Vertex_const_handle adaptor_neighbor) const
{ {
// We need at least an inner neighbor as input // We need at least an inner neighbor as input
assert(m_mesh_adaptor->get_halfedge_seaming(adaptor_vertex, assert(m_mesh_adaptor.get_halfedge_seaming(adaptor_vertex,
adaptor_neighbor) != BORDER adaptor_neighbor) != BORDER
|| m_mesh_adaptor->get_halfedge_seaming(adaptor_neighbor, || m_mesh_adaptor.get_halfedge_seaming(adaptor_neighbor,
adaptor_vertex) != BORDER); adaptor_vertex) != BORDER);
// if inner vertex // if inner vertex
if (m_mesh_adaptor->get_vertex_seaming(adaptor_vertex) != BORDER) if (m_mesh_adaptor.get_vertex_seaming(adaptor_vertex) != BORDER)
{ {
// No extra information needed if inner vertex // No extra information needed if inner vertex
return Vertex_const_handle(adaptor_vertex); return Vertex_const_handle(adaptor_vertex);
@ -760,20 +758,20 @@ private:
{ {
// find last neighbor (on seam) for a clockwise rotation // find last neighbor (on seam) for a clockwise rotation
typename Adaptor::Vertex_around_vertex_const_circulator last_cw_neighbor_cir typename Adaptor::Vertex_around_vertex_const_circulator last_cw_neighbor_cir
= m_mesh_adaptor->vertices_around_vertex_begin(adaptor_vertex, = m_mesh_adaptor.vertices_around_vertex_begin(adaptor_vertex,
adaptor_neighbor); adaptor_neighbor);
while (m_mesh_adaptor->get_halfedge_seaming(last_cw_neighbor_cir, while (m_mesh_adaptor.get_halfedge_seaming(last_cw_neighbor_cir,
adaptor_vertex) != BORDER) adaptor_vertex) != BORDER)
{ {
last_cw_neighbor_cir++; last_cw_neighbor_cir++;
} }
// find first clockwise neighbor (on seam) by a counter-clockwise rotation // find first clockwise neighbor (on seam) by a counter-clockwise rotation
typename Adaptor::Vertex_around_vertex_const_circulator first_cw_neighbor_cir typename Adaptor::Vertex_around_vertex_const_circulator first_cw_neighbor_cir
= m_mesh_adaptor->vertices_around_vertex_begin(adaptor_vertex, = m_mesh_adaptor.vertices_around_vertex_begin(adaptor_vertex,
adaptor_neighbor); adaptor_neighbor);
while (m_mesh_adaptor->get_halfedge_seaming(adaptor_vertex, while (m_mesh_adaptor.get_halfedge_seaming(adaptor_vertex,
first_cw_neighbor_cir) != BORDER) first_cw_neighbor_cir) != BORDER)
{ {
first_cw_neighbor_cir--; first_cw_neighbor_cir--;
} }
@ -812,15 +810,15 @@ private:
assert(last_cw_neighbor != NULL || first_cw_neighbor != NULL); assert(last_cw_neighbor != NULL || first_cw_neighbor != NULL);
assert(last_cw_neighbor == NULL assert(last_cw_neighbor == NULL
|| m_mesh_adaptor->get_halfedge_seaming(adaptor_vertex, || m_mesh_adaptor.get_halfedge_seaming(adaptor_vertex,
last_cw_neighbor) == BORDER last_cw_neighbor) == BORDER
|| m_mesh_adaptor->get_halfedge_seaming(last_cw_neighbor, || m_mesh_adaptor.get_halfedge_seaming(last_cw_neighbor,
adaptor_vertex) == BORDER); adaptor_vertex) == BORDER);
assert(first_cw_neighbor == NULL assert(first_cw_neighbor == NULL
|| m_mesh_adaptor->get_halfedge_seaming(adaptor_vertex, || m_mesh_adaptor.get_halfedge_seaming(adaptor_vertex,
first_cw_neighbor) == BORDER first_cw_neighbor) == BORDER
|| m_mesh_adaptor->get_halfedge_seaming(first_cw_neighbor, || m_mesh_adaptor.get_halfedge_seaming(first_cw_neighbor,
adaptor_vertex) == BORDER); adaptor_vertex) == BORDER);
// If both first_cw_neighbor and last_cw_neighbor are provided // If both first_cw_neighbor and last_cw_neighbor are provided
if (last_cw_neighbor != NULL && first_cw_neighbor != NULL) if (last_cw_neighbor != NULL && first_cw_neighbor != NULL)
@ -881,14 +879,14 @@ private:
if (vertex == NULL) if (vertex == NULL)
return false; return false;
// outer vertices are not exported // outer vertices are not exported
if (m_mesh_adaptor->get_vertex_seaming(vertex->vertex()) == OUTER) if (m_mesh_adaptor.get_vertex_seaming(vertex->vertex()) == OUTER)
return false; return false;
// prev/next vertices must be on the main border // prev/next vertices must be on the main border
if (vertex->last_cw_neighbor() != NULL && if (vertex->last_cw_neighbor() != NULL &&
m_mesh_adaptor->get_vertex_seaming(vertex->last_cw_neighbor()) != BORDER) m_mesh_adaptor.get_vertex_seaming(vertex->last_cw_neighbor()) != BORDER)
return false; return false;
if (vertex->first_cw_neighbor() != NULL && if (vertex->first_cw_neighbor() != NULL &&
m_mesh_adaptor->get_vertex_seaming(vertex->first_cw_neighbor()) != BORDER) m_mesh_adaptor.get_vertex_seaming(vertex->first_cw_neighbor()) != BORDER)
return false; return false;
// eventually: ok // eventually: ok
return true; return true;
@ -901,7 +899,7 @@ private:
return std::string("-"); return std::string("-");
} else { } else {
char index_as_string[64]; char index_as_string[64];
CGAL_CLIB_STD::sprintf(index_as_string, "%d", (int)m_mesh_adaptor->get_vertex_index(vertex)); CGAL_CLIB_STD::sprintf(index_as_string, "%d", (int)m_mesh_adaptor.get_vertex_index(vertex));
return std::string(index_as_string); return std::string(index_as_string);
} }
} }
@ -910,7 +908,7 @@ private:
private: private:
/// The decorated mesh. /// The decorated mesh.
Adaptor* m_mesh_adaptor; Adaptor& m_mesh_adaptor;
/// List of all exported vertices. /// List of all exported vertices.
/// Order is: inner vertices, then seam/main border ones. /// Order is: inner vertices, then seam/main border ones.
@ -925,19 +923,19 @@ private:
/// Utility class to generate the Facet_iterator type. /// Utility class to generate the Facet_iterator type.
struct Inner_facets_filter struct Inner_facets_filter
{ {
Inner_facets_filter(const Parameterization_mesh_patch_3* mesh) : m_mesh_patch(mesh) {} Inner_facets_filter(const Parameterization_mesh_patch_3& mesh) : m_mesh_patch(mesh) {}
/// Return TRUE <=> the facet IS NOT EXPORTED by Parameterization_mesh_patch_3, /// Return TRUE <=> the facet IS NOT EXPORTED by Parameterization_mesh_patch_3,
/// ie is out of the topological disc. /// ie is out of the topological disc.
bool operator()(const typename Adaptor::Facet_iterator& f) const { bool operator()(const typename Adaptor::Facet_iterator& f) const {
return m_mesh_patch->get_facet_seaming(f) == OUTER; return m_mesh_patch.get_facet_seaming(f) == OUTER;
} }
bool operator()(const typename Adaptor::Facet_const_iterator& f) const { bool operator()(const typename Adaptor::Facet_const_iterator& f) const {
return m_mesh_patch->get_facet_seaming(f) == OUTER; return m_mesh_patch.get_facet_seaming(f) == OUTER;
} }
private: private:
const Parameterization_mesh_patch_3* m_mesh_patch; const Parameterization_mesh_patch_3& m_mesh_patch;
}; };
// Friends // Friends
@ -946,17 +944,17 @@ private:
friend class Param_mesh_patch_vertex_const_handle<Adaptor>; friend class Param_mesh_patch_vertex_const_handle<Adaptor>;
friend class Param_mesh_patch_vertex_list_iterator<Adaptor>; friend class Param_mesh_patch_vertex_list_iterator<Adaptor>;
friend class Param_mesh_patch_vertex_list_const_iterator<Adaptor>; friend class Param_mesh_patch_vertex_list_const_iterator<Adaptor>;
friend class Mesh_patch_vertex_around_facet_cir<Parameterization_mesh_patch_3*, friend class Mesh_patch_vertex_around_facet_cir<Parameterization_mesh_patch_3,
Vertex_handle, Vertex_handle,
typename Adaptor::Vertex_around_facet_circulator>; typename Adaptor::Vertex_around_facet_circulator>;
friend class Mesh_patch_vertex_around_facet_cir<const Parameterization_mesh_patch_3*, friend class Mesh_patch_vertex_around_facet_cir<const Parameterization_mesh_patch_3,
Vertex_const_handle, Vertex_const_handle,
typename Adaptor::Vertex_around_facet_const_circulator>; typename Adaptor::Vertex_around_facet_const_circulator>;
friend class Mesh_patch_vertex_around_vertex_cir<Parameterization_mesh_patch_3*, friend class Mesh_patch_vertex_around_vertex_cir<Parameterization_mesh_patch_3,
Vertex_handle, Vertex_handle,
typename Adaptor::Vertex_around_vertex_circulator, typename Adaptor::Vertex_around_vertex_circulator,
typename Adaptor::Vertex_handle>; typename Adaptor::Vertex_handle>;
friend class Mesh_patch_vertex_around_vertex_cir<const Parameterization_mesh_patch_3*, friend class Mesh_patch_vertex_around_vertex_cir<const Parameterization_mesh_patch_3,
Vertex_const_handle, Vertex_const_handle,
typename Adaptor::Vertex_around_vertex_const_circulator, typename Adaptor::Vertex_around_vertex_const_circulator,
typename Adaptor::Vertex_const_handle>; typename Adaptor::Vertex_const_handle>;

View File

@ -308,24 +308,21 @@ public:
/// The input mesh can be of any genus. /// The input mesh can be of any genus.
/// It can have have any number of borders. Its "main border" /// It can have have any number of borders. Its "main border"
/// will be the mesh's longest border (if there is at least one border). /// will be the mesh's longest border (if there is at least one border).
Parameterization_polyhedron_adaptor_3(Polyhedron* mesh) Parameterization_polyhedron_adaptor_3(Polyhedron& mesh)
// Store reference to adapted mesh
: m_polyhedron(mesh)
{ {
typedef typename Halfedge_info_map::value_type Halfedge_info_pair; typedef typename Halfedge_info_map::value_type Halfedge_info_pair;
typedef typename Vertex_info_map::value_type Vertex_info_pair; typedef typename Vertex_info_map::value_type Vertex_info_pair;
assert(mesh != NULL);
// Store adapted mesh pointer
m_polyhedron = mesh;
// Allocate extra info for each halfedge // Allocate extra info for each halfedge
Halfedge_iterator he; Halfedge_iterator he;
for (he = m_polyhedron->halfedges_begin(); he != m_polyhedron->halfedges_end(); he++) for (he = m_polyhedron.halfedges_begin(); he != m_polyhedron.halfedges_end(); he++)
m_halfedge_info.insert( Halfedge_info_pair(he, Halfedge_info()) ); m_halfedge_info.insert( Halfedge_info_pair(he, Halfedge_info()) );
// Allocate extra info for each vertex // Allocate extra info for each vertex
Vertex_iterator vtx; Vertex_iterator vtx;
for (vtx = m_polyhedron->vertices_begin(); vtx != m_polyhedron->vertices_end(); vtx++) for (vtx = m_polyhedron.vertices_begin(); vtx != m_polyhedron.vertices_end(); vtx++)
m_vertex_info.insert( Vertex_info_pair(vtx, Vertex_info()) ); m_vertex_info.insert( Vertex_info_pair(vtx, Vertex_info()) );
// Extract mesh's longest border // Extract mesh's longest border
@ -340,8 +337,8 @@ public:
// Default destructor, copy constructor and operator =() are fine // Default destructor, copy constructor and operator =() are fine
/// Get the adapted mesh. /// Get the adapted mesh.
Polyhedron* get_adapted_mesh() { return m_polyhedron; } Polyhedron& get_adapted_mesh() { return m_polyhedron; }
const Polyhedron* get_adapted_mesh() const { return m_polyhedron; } const Polyhedron& get_adapted_mesh() const { return m_polyhedron; }
/// Get halfedge from source and target vertices. /// Get halfedge from source and target vertices.
/// Will assert if such an halfedge doesn't exist. /// Will assert if such an halfedge doesn't exist.
@ -407,18 +404,18 @@ public:
/// Get iterator over first vertex of mesh. /// Get iterator over first vertex of mesh.
Vertex_iterator mesh_vertices_begin() { Vertex_iterator mesh_vertices_begin() {
return m_polyhedron->vertices_begin(); return m_polyhedron.vertices_begin();
} }
Vertex_const_iterator mesh_vertices_begin() const { Vertex_const_iterator mesh_vertices_begin() const {
return m_polyhedron->vertices_begin(); return m_polyhedron.vertices_begin();
} }
/// Get iterator over past-the-end vertex of mesh. /// Get iterator over past-the-end vertex of mesh.
Vertex_iterator mesh_vertices_end() { Vertex_iterator mesh_vertices_end() {
return m_polyhedron->vertices_end(); return m_polyhedron.vertices_end();
} }
Vertex_const_iterator mesh_vertices_end() const { Vertex_const_iterator mesh_vertices_end() const {
return m_polyhedron->vertices_end(); return m_polyhedron.vertices_end();
} }
/// Count the number of vertices of the mesh. /// Count the number of vertices of the mesh.
@ -518,18 +515,18 @@ public:
/// Get iterator over first facet of mesh. /// Get iterator over first facet of mesh.
Facet_iterator mesh_facets_begin() { Facet_iterator mesh_facets_begin() {
return m_polyhedron->facets_begin(); return m_polyhedron.facets_begin();
} }
Facet_const_iterator mesh_facets_begin() const { Facet_const_iterator mesh_facets_begin() const {
return m_polyhedron->facets_begin(); return m_polyhedron.facets_begin();
} }
/// Get iterator over past-the-end facet of mesh. /// Get iterator over past-the-end facet of mesh.
Facet_iterator mesh_facets_end() { Facet_iterator mesh_facets_end() {
return m_polyhedron->facets_end(); return m_polyhedron.facets_end();
} }
Facet_const_iterator mesh_facets_end() const { Facet_const_iterator mesh_facets_end() const {
return m_polyhedron->facets_end(); return m_polyhedron.facets_end();
} }
/// Count the number of facets of the mesh. /// Count the number of facets of the mesh.
@ -551,8 +548,8 @@ public:
/// Count the number of halfedges of the mesh. /// Count the number of halfedges of the mesh.
int count_mesh_halfedges() const { int count_mesh_halfedges() const {
int index = 0; int index = 0;
for (Halfedge_iterator pHalfedge = m_polyhedron->halfedges_begin(); for (Halfedge_iterator pHalfedge = m_polyhedron.halfedges_begin();
pHalfedge != m_polyhedron->halfedges_end(); pHalfedge != m_polyhedron.halfedges_end();
pHalfedge++) pHalfedge++)
{ {
index++; index++;
@ -943,13 +940,11 @@ public:
private: private:
/// Extract mesh's longest border. /// Extract mesh's longest border.
std::list<Vertex_handle> extract_longest_border(Polyhedron* mesh) std::list<Vertex_handle> extract_longest_border(Polyhedron& mesh)
{ {
std::list<Vertex_handle> longest_border; // returned list std::list<Vertex_handle> longest_border; // returned list
double max_len = 0; // length of longest_border double max_len = 0; // length of longest_border
assert(mesh != NULL);
// Tag all vertices as unprocessed // Tag all vertices as unprocessed
const int tag_free = 0; const int tag_free = 0;
const int tag_done = 1; const int tag_done = 1;
@ -1029,7 +1024,7 @@ private:
private: private:
/// The adapted mesh (cannot be NULL). /// The adapted mesh (cannot be NULL).
Polyhedron* m_polyhedron; Polyhedron& m_polyhedron;
/// Additional info attached to halfedges. /// Additional info attached to halfedges.
Halfedge_info_map m_halfedge_info; Halfedge_info_map m_halfedge_info;

View File

@ -115,7 +115,7 @@ public:
/// Preconditions: /// Preconditions:
/// - 'mesh' must be a surface with 1 connected component. /// - 'mesh' must be a surface with 1 connected component.
/// - 'mesh' must be a triangular mesh. /// - 'mesh' must be a triangular mesh.
virtual Error_code parameterize (Adaptor* mesh) = 0; virtual Error_code parameterize (Adaptor& mesh) = 0;
/// Get message (in english) corresponding to an error code /// Get message (in english) corresponding to an error code
/// \param error_code The code returned by parameterize() /// \param error_code The code returned by parameterize()

View File

@ -109,7 +109,7 @@ public:
/// Assign to mesh's border vertices a 2D position (ie a (u,v) pair) /// Assign to mesh's border vertices a 2D position (ie a (u,v) pair)
/// on border's shape. Mark them as "parameterized". /// on border's shape. Mark them as "parameterized".
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
parameterize_border(Adaptor* mesh); parameterize_border(Adaptor& mesh);
/// Indicate if border's shape is convex. /// Indicate if border's shape is convex.
bool is_border_convex () { return true; } bool is_border_convex () { return true; }
@ -127,7 +127,7 @@ private:
double compute_border_length(const Adaptor& mesh); double compute_border_length(const Adaptor& mesh);
/// Get mesh iterator whose offset is closest to 'value'. /// Get mesh iterator whose offset is closest to 'value'.
Border_vertex_iterator closest_iterator(Adaptor* mesh, Border_vertex_iterator closest_iterator(Adaptor& mesh,
const Offset_map& offsets, const Offset_map& offsets,
double value); double value);
}; };
@ -163,50 +163,48 @@ double Square_border_parameterizer_3<Adaptor>::compute_border_length(
template<class Adaptor> template<class Adaptor>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Square_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh) Square_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor& mesh)
{ {
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " map on a square" << std::endl; std::cerr << " map on a square" << std::endl;
#endif #endif
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
// Nothing to do if no border // Nothing to do if no border
if (mesh->mesh_main_border_vertices_begin() == mesh->mesh_main_border_vertices_end()) if (mesh.mesh_main_border_vertices_begin() == mesh.mesh_main_border_vertices_end())
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
// Compute the total border length // Compute the total border length
double total_len = compute_border_length(*mesh); double total_len = compute_border_length(mesh);
if (total_len == 0) if (total_len == 0)
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
// map to [0,4[ // map to [0,4[
double len = 0.0; // current position on square in [0, total_len[ double len = 0.0; // current position on square in [0, total_len[
Offset_map offset; // vertex index -> offset map Offset_map offset; // vertex index -> offset map
offset.reserve(mesh->count_mesh_vertices()); offset.reserve(mesh.count_mesh_vertices());
Border_vertex_iterator it; Border_vertex_iterator it;
for(it = mesh->mesh_main_border_vertices_begin(); for(it = mesh.mesh_main_border_vertices_begin();
it != mesh->mesh_main_border_vertices_end(); it != mesh.mesh_main_border_vertices_end();
it++) it++)
{ {
CGAL_surface_mesh_parameterization_assertion(mesh->is_vertex_on_main_border(it)); CGAL_surface_mesh_parameterization_assertion(mesh.is_vertex_on_main_border(it));
offset[mesh->get_vertex_index(it)] = 4.0f*len/total_len; offset[mesh.get_vertex_index(it)] = 4.0f*len/total_len;
// current position on square in [0,4[ // current position on square in [0,4[
// Get next iterator (looping) // Get next iterator (looping)
Border_vertex_iterator next = it; Border_vertex_iterator next = it;
next++; next++;
if(next == mesh->mesh_main_border_vertices_end()) if(next == mesh.mesh_main_border_vertices_end())
next = mesh->mesh_main_border_vertices_begin(); next = mesh.mesh_main_border_vertices_begin();
// Add edge "length" to 'len' // Add edge "length" to 'len'
len += compute_edge_length(*mesh, it, next); len += compute_edge_length(mesh, it, next);
} }
// First square corner is mapped to first vertex. // First square corner is mapped to first vertex.
// Then find closest points for three other corners. // Then find closest points for three other corners.
Border_vertex_iterator it0 = mesh->mesh_main_border_vertices_begin(); Border_vertex_iterator it0 = mesh.mesh_main_border_vertices_begin();
Border_vertex_iterator it1 = closest_iterator(mesh, offset, 1.0); Border_vertex_iterator it1 = closest_iterator(mesh, offset, 1.0);
Border_vertex_iterator it2 = closest_iterator(mesh, offset, 2.0); Border_vertex_iterator it2 = closest_iterator(mesh, offset, 2.0);
Border_vertex_iterator it3 = closest_iterator(mesh, offset, 3.0); Border_vertex_iterator it3 = closest_iterator(mesh, offset, 3.0);
@ -216,35 +214,35 @@ Square_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
// //
// Snap these vertices to corners // Snap these vertices to corners
offset[mesh->get_vertex_index(it0)] = 0.0; offset[mesh.get_vertex_index(it0)] = 0.0;
offset[mesh->get_vertex_index(it1)] = 1.0; offset[mesh.get_vertex_index(it1)] = 1.0;
offset[mesh->get_vertex_index(it2)] = 2.0; offset[mesh.get_vertex_index(it2)] = 2.0;
offset[mesh->get_vertex_index(it3)] = 3.0; offset[mesh.get_vertex_index(it3)] = 3.0;
// Set vertices along square's sides and mark them as "parameterized" // Set vertices along square's sides and mark them as "parameterized"
for(it = it0; it != it1; it++) // 1st side for(it = it0; it != it1; it++) // 1st side
{ {
Point_2 uv(offset[mesh->get_vertex_index(it)], 0.0); Point_2 uv(offset[mesh.get_vertex_index(it)], 0.0);
mesh->set_vertex_uv(it, uv); mesh.set_vertex_uv(it, uv);
mesh->set_vertex_parameterized(it, true); mesh.set_vertex_parameterized(it, true);
} }
for(it = it1; it != it2; it++) // 2nd side for(it = it1; it != it2; it++) // 2nd side
{ {
Point_2 uv(1.0, offset[mesh->get_vertex_index(it)]-1); Point_2 uv(1.0, offset[mesh.get_vertex_index(it)]-1);
mesh->set_vertex_uv(it, uv); mesh.set_vertex_uv(it, uv);
mesh->set_vertex_parameterized(it, true); mesh.set_vertex_parameterized(it, true);
} }
for(it = it2; it != it3; it++) // 3rd side for(it = it2; it != it3; it++) // 3rd side
{ {
Point_2 uv(3-offset[mesh->get_vertex_index(it)], 1.0); Point_2 uv(3-offset[mesh.get_vertex_index(it)], 1.0);
mesh->set_vertex_uv(it, uv); mesh.set_vertex_uv(it, uv);
mesh->set_vertex_parameterized(it, true); mesh.set_vertex_parameterized(it, true);
} }
for(it = it3; it != mesh->mesh_main_border_vertices_end(); it++) // 4th side for(it = it3; it != mesh.mesh_main_border_vertices_end(); it++) // 4th side
{ {
Point_2 uv(0.0, 4-offset[mesh->get_vertex_index(it)]); Point_2 uv(0.0, 4-offset[mesh.get_vertex_index(it)]);
mesh->set_vertex_uv(it, uv); mesh.set_vertex_uv(it, uv);
mesh->set_vertex_parameterized(it, true); mesh.set_vertex_parameterized(it, true);
} }
return Parameterizer_traits_3<Adaptor>::OK; return Parameterizer_traits_3<Adaptor>::OK;
@ -255,18 +253,18 @@ Square_border_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
template<class Adaptor> template<class Adaptor>
inline inline
typename Adaptor::Border_vertex_iterator typename Adaptor::Border_vertex_iterator
Square_border_parameterizer_3<Adaptor>::closest_iterator(Adaptor* mesh, Square_border_parameterizer_3<Adaptor>::closest_iterator(Adaptor& mesh,
const Offset_map& offset, const Offset_map& offset,
double value) double value)
{ {
Border_vertex_iterator best; Border_vertex_iterator best;
double min = DBL_MAX; // distance for 'best' double min = DBL_MAX; // distance for 'best'
for (Border_vertex_iterator it = mesh->mesh_main_border_vertices_begin(); for (Border_vertex_iterator it = mesh.mesh_main_border_vertices_begin();
it != mesh->mesh_main_border_vertices_end(); it != mesh.mesh_main_border_vertices_end();
it++) it++)
{ {
double d = CGAL_CLIB_STD::fabs(offset[mesh->get_vertex_index(it)] - value); double d = CGAL_CLIB_STD::fabs(offset[mesh.get_vertex_index(it)] - value);
if (d < min) if (d < min)
{ {
best = it; best = it;

View File

@ -98,7 +98,7 @@ public:
/// Map 2 extreme vertices of the 3D mesh and mark them as "parameterized". /// Map 2 extreme vertices of the 3D mesh and mark them as "parameterized".
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
parameterize_border(Adaptor* mesh); parameterize_border(Adaptor& mesh);
/// Indicate if border's shape is convex. /// Indicate if border's shape is convex.
/// Meaningless for free border parameterization algorithms. /// Meaningless for free border parameterization algorithms.
@ -115,14 +115,12 @@ public:
template<class Adaptor> template<class Adaptor>
inline inline
typename Parameterizer_traits_3<Adaptor>::Error_code typename Parameterizer_traits_3<Adaptor>::Error_code
Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh) Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor& mesh)
{ {
Vertex_iterator it; Vertex_iterator it;
CGAL_surface_mesh_parameterization_assertion(mesh != NULL);
// Nothing to do if no border // Nothing to do if no border
if (mesh->mesh_main_border_vertices_begin() == mesh->mesh_main_border_vertices_end()) if (mesh.mesh_main_border_vertices_begin() == mesh.mesh_main_border_vertices_end())
return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER; return Parameterizer_traits_3<Adaptor>::ERROR_INVALID_BORDER;
// Get mesh's bounding box // Get mesh's bounding box
@ -132,9 +130,9 @@ Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
double xmax = -1e30 ; double xmax = -1e30 ;
double ymax = -1e30 ; double ymax = -1e30 ;
double zmax = -1e30 ; double zmax = -1e30 ;
for (it = mesh->mesh_vertices_begin(); it != mesh->mesh_vertices_end(); it++) for (it = mesh.mesh_vertices_begin(); it != mesh.mesh_vertices_end(); it++)
{ {
Point_3 position = mesh->get_vertex_position(it); Point_3 position = mesh.get_vertex_position(it);
xmin = std::min(position.x(), xmin) ; xmin = std::min(position.x(), xmin) ;
ymin = std::min(position.y(), ymin) ; ymin = std::min(position.y(), ymin) ;
@ -226,9 +224,9 @@ Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
double umin = DBL_MAX ; double umin = DBL_MAX ;
Vertex_handle vxmax = NULL ; Vertex_handle vxmax = NULL ;
double umax = DBL_MIN ; double umax = DBL_MIN ;
for (it = mesh->mesh_vertices_begin(); it != mesh->mesh_vertices_end(); it++) for (it = mesh.mesh_vertices_begin(); it != mesh.mesh_vertices_end(); it++)
{ {
Point_3 position = mesh->get_vertex_position(it); Point_3 position = mesh.get_vertex_position(it);
Vector_3 position_as_vector = position - Point_3(0,0,0); Vector_3 position_as_vector = position - Point_3(0,0,0);
// coordinate along the bounding box' main axes // coordinate along the bounding box' main axes
@ -241,7 +239,7 @@ Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
u = (u - V1_min) / (V1_max - V1_min); u = (u - V1_min) / (V1_max - V1_min);
v = (v - V2_min) / (V2_max - V2_min); v = (v - V2_min) / (V2_max - V2_min);
mesh->set_vertex_uv(it, Point_2(u,v)) ; // useful only for vxmin and vxmax mesh.set_vertex_uv(it, Point_2(u,v)) ; // useful only for vxmin and vxmax
if(u < umin) { if(u < umin) {
vxmin = it ; vxmin = it ;
@ -252,13 +250,13 @@ Two_vertices_parameterizer_3<Adaptor>::parameterize_border(Adaptor* mesh)
umax = u ; umax = u ;
} }
} }
mesh->set_vertex_parameterized(vxmin, true) ; mesh.set_vertex_parameterized(vxmin, true) ;
mesh->set_vertex_parameterized(vxmax, true) ; mesh.set_vertex_parameterized(vxmax, true) ;
#ifdef DEBUG_TRACE #ifdef DEBUG_TRACE
std::cerr << " map 2 vertices..." << std::endl; std::cerr << " map 2 vertices..." << std::endl;
std::cerr << " #" << mesh->get_vertex_index(vxmin) << "(" << vxmin->vertex()->index() << ") parameterized " << std::endl; std::cerr << " #" << mesh.get_vertex_index(vxmin) << "(" << vxmin->vertex()->index() << ") parameterized " << std::endl;
std::cerr << " #" << mesh->get_vertex_index(vxmax) << "(" << vxmax->vertex()->index() << ") parameterized " << std::endl; std::cerr << " #" << mesh.get_vertex_index(vxmax) << "(" << vxmax->vertex()->index() << ") parameterized " << std::endl;
#endif #endif
return Parameterizer_traits_3<Adaptor>::OK; return Parameterizer_traits_3<Adaptor>::OK;

View File

@ -44,7 +44,7 @@ CGAL_BEGIN_NAMESPACE
/// ///
template <class ParameterizationMesh_3> template <class ParameterizationMesh_3>
typename Parameterizer_traits_3<ParameterizationMesh_3>::Error_code typename Parameterizer_traits_3<ParameterizationMesh_3>::Error_code
parameterize(ParameterizationMesh_3* mesh) ///< 3D mesh, model of ParameterizationMesh_3 concept parameterize(ParameterizationMesh_3& mesh) ///< 3D mesh, model of ParameterizationMesh_3 concept
{ {
Mean_value_coordinates_parameterizer_3<ParameterizationMesh_3> parameterizer; Mean_value_coordinates_parameterizer_3<ParameterizationMesh_3> parameterizer;
return parameterizer.parameterize(mesh); return parameterizer.parameterize(mesh);
@ -67,7 +67,7 @@ parameterize(ParameterizationMesh_3* mesh) ///< 3D mesh, model of Parameterizat
/// ///
template <class ParameterizationMesh_3, class ParameterizerTraits_3> template <class ParameterizationMesh_3, class ParameterizerTraits_3>
typename Parameterizer_traits_3<ParameterizationMesh_3>::Error_code typename Parameterizer_traits_3<ParameterizationMesh_3>::Error_code
parameterize(ParameterizationMesh_3* mesh, ///< 3D mesh, model of ParameterizationMesh_3 parameterize(ParameterizationMesh_3& mesh, ///< 3D mesh, model of ParameterizationMesh_3
ParameterizerTraits_3 parameterizer) ///< Parameterization method for 'mesh' ParameterizerTraits_3 parameterizer) ///< Parameterization method for 'mesh'
{ {
return parameterizer.parameterize(mesh); return parameterizer.parameterize(mesh);

View File

@ -89,7 +89,7 @@ const char* Solver1_name = "Open
// CAUTION: // CAUTION:
// This method is provided "as is". It is very buggy and simply part of this example. // This method is provided "as is". It is very buggy and simply part of this example.
// Developers using this package should implement a more robust cut algorithm! // Developers using this package should implement a more robust cut algorithm!
static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor) static Seam cut_mesh(Parameterization_polyhedron_adaptor& mesh_adaptor)
{ {
// Helper class to compute genus or extract borders // Helper class to compute genus or extract borders
typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor_ex> typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor_ex>
@ -99,10 +99,8 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Seam seam; // returned list Seam seam; // returned list
// Get pointer to Polyhedron_3 mesh // Get refererence to Polyhedron_3 mesh
assert(mesh_adaptor != NULL); Polyhedron& mesh = mesh_adaptor.get_adapted_mesh();
Polyhedron* mesh = mesh_adaptor->get_adapted_mesh();
assert(mesh != NULL);
// Extract mesh borders and compute genus // Extract mesh borders and compute genus
Mesh_feature_extractor feature_extractor(mesh_adaptor); Mesh_feature_extractor feature_extractor(mesh_adaptor);
@ -113,8 +111,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
if (genus == 0 && nb_borders > 0) if (genus == 0 && nb_borders > 0)
{ {
// Pick the longest border // Pick the longest border
const Border* pBorder = feature_extractor.get_longest_border(); seam = feature_extractor.get_longest_border();
seam = *pBorder;
} }
else // if mesh is NOT a topological disk, create a virtual cut else // if mesh is NOT a topological disk, create a virtual cut
{ {
@ -122,17 +119,17 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
Backbone::iterator he; Backbone::iterator he;
// Virtually "cut" mesh to make it a topological disk // Virtually "cut" mesh to make it a topological disk
mesh->compute_facet_centers(); mesh.compute_facet_centers();
Mesh_cutter cutter(mesh); Mesh_cutter cutter(mesh);
if (genus == 0) if (genus == 0)
{ {
// no border, we need to cut the mesh // no border, we need to cut the mesh
assert (nb_borders == 0); assert (nb_borders == 0);
cutter.cut(&seamingBackbone); // simple cut cutter.cut(seamingBackbone); // simple cut
} }
else // genus > 0 -> cut the mesh else // genus > 0 -> cut the mesh
{ {
cutter.cut_genus(&seamingBackbone); cutter.cut_genus(seamingBackbone);
} }
// The Mesh_cutter class is quite buggy // The Mesh_cutter class is quite buggy
@ -144,7 +141,7 @@ static Seam cut_mesh(Parameterization_polyhedron_adaptor* mesh_adaptor)
// //
// 2) Check that seamingBackbone is a loop and // 2) Check that seamingBackbone is a loop and
// count occurences of seam halfedges // count occurences of seam halfedges
mesh->tag_halfedges(0); // Reset counters mesh.tag_halfedges(0); // Reset counters
for (he = seamingBackbone.begin(); he != seamingBackbone.end(); he++) for (he = seamingBackbone.begin(); he != seamingBackbone.end(); he++)
{ {
// Get next halfedge iterator (looping) // Get next halfedge iterator (looping)
@ -239,14 +236,14 @@ int main(int argc,char * argv[])
//*************************************** //***************************************
// The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_ex meshes // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_ex meshes
Parameterization_polyhedron_adaptor mesh_adaptor(&mesh); Parameterization_polyhedron_adaptor mesh_adaptor(mesh);
// The parameterization methods support only meshes that // The parameterization methods support only meshes that
// are topological disks => we need to virtually "cut" the mesh // are topological disks => we need to virtually "cut" the mesh
// to make it homeomorphic to a disk // to make it homeomorphic to a disk
// //
// 1) Cut the mesh // 1) Cut the mesh
Seam seam = cut_mesh(&mesh_adaptor); Seam seam = cut_mesh(mesh_adaptor);
if (seam.empty()) if (seam.empty())
{ {
std::cerr << "Minor Error: an unexpected error occurred while cutting the shape" << std::endl; std::cerr << "Minor Error: an unexpected error occurred while cutting the shape" << std::endl;
@ -254,7 +251,7 @@ int main(int argc,char * argv[])
} }
// //
// 2) Create adaptor that virtually "cuts" a patch in a Polyhedron_ex mesh // 2) Create adaptor that virtually "cuts" a patch in a Polyhedron_ex mesh
Mesh_patch_polyhedron mesh_patch(&mesh_adaptor, seam.begin(), seam.end()); Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end());
std::cerr << "Mesh cutting: " << task_timer.time() << " seconds." << std::endl; std::cerr << "Mesh cutting: " << task_timer.time() << " seconds." << std::endl;
std::cerr << std::endl; std::cerr << std::endl;
@ -273,7 +270,7 @@ int main(int argc,char * argv[])
std::cerr << Solver1_name << " solver" << std::endl; std::cerr << Solver1_name << " solver" << std::endl;
err = CGAL::parameterize( err = CGAL::parameterize(
&mesh_patch, mesh_patch,
CGAL::Barycentric_mapping_parameterizer_3< CGAL::Barycentric_mapping_parameterizer_3<
Mesh_patch_polyhedron, Mesh_patch_polyhedron,
CGAL::Square_border_uniform_parameterizer_3<Mesh_patch_polyhedron>, CGAL::Square_border_uniform_parameterizer_3<Mesh_patch_polyhedron>,
@ -297,7 +294,7 @@ int main(int argc,char * argv[])
std::cerr << Solver2_name << " solver" << std::endl; std::cerr << Solver2_name << " solver" << std::endl;
err = CGAL::parameterize( err = CGAL::parameterize(
&mesh_patch, mesh_patch,
CGAL::Mean_value_coordinates_parameterizer_3< CGAL::Mean_value_coordinates_parameterizer_3<
Mesh_patch_polyhedron, Mesh_patch_polyhedron,
CGAL::Circular_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>, CGAL::Circular_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>,
@ -321,7 +318,7 @@ int main(int argc,char * argv[])
std::cerr << Solver2_name << " solver" << std::endl; std::cerr << Solver2_name << " solver" << std::endl;
err = CGAL::parameterize( err = CGAL::parameterize(
&mesh_patch, mesh_patch,
CGAL::Discrete_conformal_map_parameterizer_3< CGAL::Discrete_conformal_map_parameterizer_3<
Mesh_patch_polyhedron, Mesh_patch_polyhedron,
CGAL::Circular_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>, CGAL::Circular_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>,
@ -345,7 +342,7 @@ int main(int argc,char * argv[])
std::cerr << Solver2_name << " solver" << std::endl; std::cerr << Solver2_name << " solver" << std::endl;
err = CGAL::parameterize( err = CGAL::parameterize(
&mesh_patch, mesh_patch,
CGAL::Discrete_authalic_parameterizer_3< CGAL::Discrete_authalic_parameterizer_3<
Mesh_patch_polyhedron, Mesh_patch_polyhedron,
CGAL::Square_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>, CGAL::Square_border_arc_length_parameterizer_3<Mesh_patch_polyhedron>,
@ -367,7 +364,7 @@ int main(int argc,char * argv[])
std::cerr << Solver2_name << " solver" << std::endl; std::cerr << Solver2_name << " solver" << std::endl;
err = CGAL::parameterize( err = CGAL::parameterize(
&mesh_patch, mesh_patch,
CGAL::LSCM_parameterizer_3< CGAL::LSCM_parameterizer_3<
Mesh_patch_polyhedron, Mesh_patch_polyhedron,
CGAL::Two_vertices_parameterizer_3<Mesh_patch_polyhedron>, CGAL::Two_vertices_parameterizer_3<Mesh_patch_polyhedron>,