mirror of https://github.com/CGAL/cgal
Changed pointers to mesh to references all over the package (as requested by MK)
This commit is contained in:
parent
aadd6d748c
commit
d2777b879a
|
|
@ -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 ();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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(¢er);
|
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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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>,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue