mirror of https://github.com/CGAL/cgal
Merge pull request #4885 from MaelRL/Iterative_authalic_parameterization
This commit is contained in:
commit
a6c5402dc6
|
|
@ -24,6 +24,7 @@
|
|||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
namespace CGAL {
|
||||
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
||||
template <typename HD>
|
||||
class Seam_mesh_halfedge_descriptor
|
||||
{
|
||||
|
|
@ -86,8 +88,92 @@ public:
|
|||
return 2 * hash_value(hd.tmhd) + static_cast<std::size_t>(hd.seam);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename HD>
|
||||
class Seam_mesh_vertex_descriptor
|
||||
{
|
||||
public:
|
||||
Seam_mesh_halfedge_descriptor<HD> hd;
|
||||
|
||||
Seam_mesh_vertex_descriptor() { }
|
||||
|
||||
Seam_mesh_vertex_descriptor(const Seam_mesh_halfedge_descriptor<HD>& h)
|
||||
: hd(h)
|
||||
{ }
|
||||
|
||||
bool operator==(const Seam_mesh_vertex_descriptor& other) const
|
||||
{
|
||||
return (hd == other.hd);
|
||||
}
|
||||
|
||||
bool operator!=(const Seam_mesh_vertex_descriptor& other) const
|
||||
{
|
||||
return (hd != other.hd);
|
||||
}
|
||||
|
||||
bool operator<(const Seam_mesh_vertex_descriptor& other) const
|
||||
{
|
||||
return hd < other.hd;
|
||||
}
|
||||
|
||||
operator HD() const
|
||||
{
|
||||
return hd;
|
||||
}
|
||||
|
||||
#ifdef CGAL_SEAM_MESH_INSERT_OPERATOR
|
||||
friend std::ostream& operator<<(std::ostream& os, const Seam_mesh_vertex_descriptor vd)
|
||||
{
|
||||
os << "seam mesh vertex: " << vd.hd;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
friend std::size_t hash_value(const Seam_mesh_vertex_descriptor& vd)
|
||||
{
|
||||
return hash_value(vd.hd.tmhd);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename HD, typename SM>
|
||||
class Seam_mesh_edge_descriptor
|
||||
{
|
||||
public:
|
||||
Seam_mesh_halfedge_descriptor<HD> hd;
|
||||
const SM* mesh_;
|
||||
|
||||
Seam_mesh_edge_descriptor() : mesh_(nullptr) { }
|
||||
|
||||
Seam_mesh_edge_descriptor(const Seam_mesh_halfedge_descriptor<HD>& hd, const SM* m)
|
||||
: hd(hd), mesh_(m)
|
||||
{}
|
||||
|
||||
friend bool operator==(Seam_mesh_edge_descriptor e1, Seam_mesh_edge_descriptor e2)
|
||||
{
|
||||
return (e1.hd == e2.hd) || (e1.hd == e2.mesh_->opposite(e2.hd));
|
||||
}
|
||||
|
||||
friend bool operator!=(Seam_mesh_edge_descriptor e1, Seam_mesh_edge_descriptor e2)
|
||||
{
|
||||
return ! (e1 == e2);
|
||||
}
|
||||
|
||||
#ifdef CGAL_SEAM_MESH_INSERT_OPERATOR
|
||||
friend std::ostream& operator<<(std::ostream& os, const Seam_mesh_edge_descriptor& ed)
|
||||
{
|
||||
os << ed.hd;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
friend std::size_t hash_value(const Seam_mesh_edge_descriptor& ed)
|
||||
{
|
||||
return hash_value((std::min)(ed.hd, ed.mesh_->opposite(ed.hd)));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
/// \ingroup PkgBGLAdaptors
|
||||
///
|
||||
/// This class is a data structure that takes a triangle mesh, further refered
|
||||
|
|
@ -112,6 +198,10 @@ class Seam_mesh
|
|||
typedef Seam_mesh<TM, SEM, SVM> Self;
|
||||
|
||||
public:
|
||||
/// The underlying mesh type
|
||||
typedef TM Triangle_mesh;
|
||||
|
||||
// backward compatibility
|
||||
typedef TM TriangleMesh;
|
||||
|
||||
public:
|
||||
|
|
@ -187,23 +277,15 @@ public:
|
|||
class halfedge_descriptor
|
||||
{
|
||||
public:
|
||||
TM_halfedge_descriptor tmhd;
|
||||
bool seam;
|
||||
|
||||
/// %Default constructor
|
||||
halfedge_descriptor() : tmhd(), seam(false) { }
|
||||
halfedge_descriptor();
|
||||
|
||||
halfedge_descriptor(TM_halfedge_descriptor tmhd, bool seam = false)
|
||||
: tmhd(tmhd), seam(seam)
|
||||
{ }
|
||||
/// Constructor from a halfedge of the underlying mesh
|
||||
halfedge_descriptor(TM_halfedge_descriptor tmhd, bool seam = false);
|
||||
|
||||
#ifdef CGAL_SEAM_MESH_INSERT_OPERATOR
|
||||
/// Print the halfedge and if it is on a seam.
|
||||
friend std::ostream& operator<<(std::ostream& os, const halfedge_descriptor& hd)
|
||||
{
|
||||
os << hd.tmhd << ((hd.seam)?" on seam":"");
|
||||
return os;
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& os, const halfedge_descriptor& hd);
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
|
|
@ -265,13 +347,13 @@ public:
|
|||
return halfedge_descriptor(*hd, seam);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
/// This class represents a vertex of the seam mesh.
|
||||
///
|
||||
/// Implementation note: to properly duplicate vertices that are on seams,
|
||||
/// a vertex_descriptor is in fact represented as a halfedge of the underlying
|
||||
/// mesh.
|
||||
/// a vertex_descriptor is in fact represented as a halfedge of the seam mesh.
|
||||
///
|
||||
/// \cgalModels `Descriptor`
|
||||
/// \cgalModels `LessThanComparable`
|
||||
|
|
@ -280,48 +362,20 @@ public:
|
|||
class vertex_descriptor
|
||||
{
|
||||
public:
|
||||
halfedge_descriptor hd;
|
||||
|
||||
/// %Default constructor
|
||||
vertex_descriptor() { }
|
||||
vertex_descriptor();
|
||||
|
||||
vertex_descriptor(const halfedge_descriptor& h)
|
||||
: hd(h)
|
||||
{ }
|
||||
|
||||
bool operator==(const vertex_descriptor& other) const
|
||||
{
|
||||
return (hd == other.hd);
|
||||
}
|
||||
|
||||
bool operator!=(const vertex_descriptor& other) const
|
||||
{
|
||||
return (hd != other.hd);
|
||||
}
|
||||
|
||||
bool operator<(const vertex_descriptor& other) const
|
||||
{
|
||||
return hd < other.hd;
|
||||
}
|
||||
|
||||
operator TM_halfedge_descriptor() const
|
||||
{
|
||||
return hd;
|
||||
}
|
||||
/// Constructor from a seam mesh halfedge
|
||||
vertex_descriptor(const halfedge_descriptor& h);
|
||||
|
||||
#ifdef CGAL_SEAM_MESH_INSERT_OPERATOR
|
||||
friend std::ostream& operator<<(std::ostream& os, const vertex_descriptor vd)
|
||||
{
|
||||
os << "seam mesh vertex: " << vd.hd;
|
||||
return os;
|
||||
}
|
||||
/// Print the seam mesh vertex.
|
||||
friend std::ostream& operator<<(std::ostream& os, const vertex_descriptor vd);
|
||||
#endif
|
||||
|
||||
friend std::size_t hash_value(const vertex_descriptor& vd)
|
||||
{
|
||||
return hash_value(vd.hd.tmhd);
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef Seam_mesh_vertex_descriptor<TM_halfedge_descriptor> vertex_descriptor;
|
||||
#endif
|
||||
|
||||
// iterator
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
|
@ -403,48 +457,24 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
/// This class represents an edge of the seam mesh.
|
||||
///
|
||||
/// \cgalModels `Descriptor`
|
||||
/// \cgalModels `Hashable`
|
||||
///
|
||||
class edge_descriptor
|
||||
{
|
||||
public:
|
||||
halfedge_descriptor hd;
|
||||
const Self* mesh_;
|
||||
/// %Default constructor
|
||||
edge_descriptor();
|
||||
|
||||
#ifdef CGAL_SEAM_MESH_INSERT_OPERATOR
|
||||
friend
|
||||
std::ostream& operator<<(std::ostream& os, const edge_descriptor& ed)
|
||||
{
|
||||
os << ed.hd;
|
||||
return os;
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& os, const edge_descriptor& ed);
|
||||
#endif
|
||||
|
||||
edge_descriptor()
|
||||
: mesh_(nullptr)
|
||||
{}
|
||||
|
||||
edge_descriptor(const halfedge_descriptor& hd, const Self* m)
|
||||
: hd(hd), mesh_(m)
|
||||
{}
|
||||
|
||||
friend bool operator==(edge_descriptor e1, edge_descriptor e2)
|
||||
{
|
||||
return (e1.hd == e2.hd) || (e1.hd == e2.mesh_->opposite(e2.hd));
|
||||
}
|
||||
|
||||
friend bool operator!=(edge_descriptor e1, edge_descriptor e2)
|
||||
{
|
||||
return ! (e1 == e2);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(const edge_descriptor& ed)
|
||||
{
|
||||
return hash_value((std::min)(ed.hd, ed.mesh_->opposite(ed.hd)));
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef Seam_mesh_edge_descriptor<TM_halfedge_descriptor, Self> edge_descriptor;
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
// iterator
|
||||
|
|
@ -1120,6 +1150,46 @@ public:
|
|||
|
||||
} // namespace CGAL
|
||||
|
||||
#ifndef CGAL_CFG_NO_STD_HASH
|
||||
|
||||
namespace std {
|
||||
|
||||
template <typename HD>
|
||||
struct hash<CGAL::Seam_mesh_vertex_descriptor<HD> >
|
||||
: public CGAL::cpp98::unary_function<CGAL::Seam_mesh_vertex_descriptor<HD>, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const CGAL::Seam_mesh_vertex_descriptor<HD>& v) const
|
||||
{
|
||||
return hash_value(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename HD>
|
||||
struct hash<CGAL::Seam_mesh_halfedge_descriptor<HD> >
|
||||
: public CGAL::cpp98::unary_function<CGAL::Seam_mesh_halfedge_descriptor<HD>, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const CGAL::Seam_mesh_halfedge_descriptor<HD>& h) const
|
||||
{
|
||||
return hash_value(h);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename HD, typename SM>
|
||||
struct hash<CGAL::Seam_mesh_edge_descriptor<HD, SM> >
|
||||
: public CGAL::cpp98::unary_function<CGAL::Seam_mesh_edge_descriptor<HD, SM>, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const CGAL::Seam_mesh_edge_descriptor<HD, SM>& e) const
|
||||
{
|
||||
return hash_value(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Seam_mesh::face_descriptor is equal to TM_face_descriptor so nothing to do
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // CGAL_CFG_NO_STD_HASH
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif //CGAL_SEAM_MESH_H
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ struct Index_map_initializer<IndexPropertyMap, Graph, false>
|
|||
void operator()(const PropertyTag, IndexPropertyMap, const Graph&)
|
||||
{
|
||||
// The property map is not writable; should never be here.
|
||||
CGAL_assertion_msg(false, "You are trying to initialize a non-writable property map");
|
||||
CGAL_assertion_msg(false, "Initialization of a non-writable property map is impossible");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ IndexMap get_initialized_index_map_const(const IndexMap index_map,
|
|||
CGAL_USE(g);
|
||||
CGAL_USE(p);
|
||||
|
||||
// If you are passing a pmap via NPs, it must be initialized
|
||||
// If a pmap is passed via NPs, it must be initialized
|
||||
CGAL_assertion(is_index_map_valid(p, index_map, g));
|
||||
|
||||
return index_map;
|
||||
|
|
@ -185,7 +185,7 @@ IndexMap get_initialized_index_map(const IndexMap index_map,
|
|||
CGAL_USE(g);
|
||||
CGAL_USE(p);
|
||||
|
||||
// If you are passing a pmap via NPs, it must be initialized
|
||||
// If a pmap is passed via NPs, it must be initialized
|
||||
CGAL_assertion(is_index_map_valid(p, index_map, g));
|
||||
|
||||
return index_map;
|
||||
|
|
|
|||
|
|
@ -1153,6 +1153,12 @@ Teillaud"
|
|||
URL = {https://hal.inria.fr/hal-01568002},
|
||||
}
|
||||
|
||||
@inproceedings{cgal:j-lrsspp-19,
|
||||
title={Learning to Reconstruct Symmetric Shapes using Planar Parameterization of 3D Surface},
|
||||
author={Jain, Hardik and Wollhaf, Manuel and Hellwich, Olaf},
|
||||
booktitle={Proceedings of the IEEE International Conference on Computer Vision Workshops},
|
||||
year={2019}
|
||||
}
|
||||
|
||||
@book{ cgal:j-csl-99
|
||||
,author = "Nicolai M. Josuttis"
|
||||
|
|
@ -1964,6 +1970,14 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio
|
|||
update = "09.11 penarand"
|
||||
}
|
||||
|
||||
@inproceedings{cgal:ssgh-tmpm-01,
|
||||
title={Texture mapping progressive meshes},
|
||||
author={Sander, Pedro V and Snyder, John and Gortler, Steven J and Hoppe, Hugues},
|
||||
booktitle={Proceedings of the 28th annual conference on Computer graphics and interactive techniques},
|
||||
pages={409--416},
|
||||
year={2001}
|
||||
}
|
||||
|
||||
@inproceedings{ cgal:s-cgehd-98
|
||||
,author = "Jonathan R. Shewchuk"
|
||||
,title = "A Condition Guaranteeing the Existence of Higher-Dimensional
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ Release date: December 2020
|
|||
|
||||
- Added the functions `set_recycle_garbage()` and `does_recycle_garbage()` to the class `Surface_mesh`.
|
||||
|
||||
|
||||
### [dD Geometry Kernel](https://doc.cgal.org/5.2/Manual/packages.html#PkgKernelD)
|
||||
|
||||
- The kernels [`Epick_d`](https://doc.cgal.org/5.2/Kernel_d/structCGAL_1_1Epick__d.html)
|
||||
|
|
@ -87,6 +86,10 @@ Release date: December 2020
|
|||
to deal with weighted points.
|
||||
|
||||
|
||||
### [Surface Mesh Parameterization](https://doc.cgal.org/5.2/Manual/packages.html#PkgSurfaceMeshParameterization)
|
||||
- Added a new parameterization method, Iterative Authalic Parameterization. It is based on the work of Jain, Hardik, Manuel Wollhaf, and Olaf Hellwich,
|
||||
"Learning to Reconstruct Symmetric Shapes using Planar Parameterization of 3D Surface." (IEEE International Conference on Computer Vision Workshops, 2019).
|
||||
|
||||
[Release 5.1](https://github.com/CGAL/cgal/releases/tag/v5.1)
|
||||
-----------
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Error_code.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/LSCM_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Two_vertices_parameterizer_3.h>
|
||||
|
|
@ -342,6 +343,7 @@ public:
|
|||
QAction* actionDCP = new QAction ("Discrete Conformal Map", mw);
|
||||
QAction* actionLSC = new QAction("Least Square Conformal Map", mw);
|
||||
QAction* actionDAP = new QAction("Discrete Authalic", mw);
|
||||
QAction* actionIAP = new QAction("Iterative Authalic", mw);
|
||||
QAction* actionARAP = new QAction("As Rigid As Possible", mw);
|
||||
QAction* actionOTE = new QAction("Orbifold Tutte Embedding", mw);
|
||||
QAction* actionBTP = new QAction("Tutte Barycentric", mw);
|
||||
|
|
@ -349,6 +351,7 @@ public:
|
|||
actionDCP->setObjectName("actionDCP");
|
||||
actionLSC->setObjectName("actionLSC");
|
||||
actionDAP->setObjectName("actionDAP");
|
||||
actionIAP->setObjectName("actionIAP");
|
||||
actionARAP->setObjectName("actionARAP");
|
||||
actionOTE->setObjectName("actionOTE");
|
||||
actionBTP->setObjectName("actionBTP");
|
||||
|
|
@ -356,6 +359,7 @@ public:
|
|||
_actions << actionARAP
|
||||
<< actionBTP
|
||||
<< actionDAP
|
||||
<< actionIAP
|
||||
<< actionDCP
|
||||
<< actionLSC
|
||||
<< actionMVC
|
||||
|
|
@ -413,6 +417,7 @@ public Q_SLOTS:
|
|||
void on_actionDCP_triggered();
|
||||
void on_actionLSC_triggered();
|
||||
void on_actionDAP_triggered();
|
||||
void on_actionIAP_triggered();
|
||||
void on_actionARAP_triggered();
|
||||
void on_actionOTE_triggered();
|
||||
void on_actionBTP_triggered();
|
||||
|
|
@ -485,8 +490,8 @@ public Q_SLOTS:
|
|||
}
|
||||
|
||||
protected:
|
||||
enum Parameterization_method { PARAM_MVC, PARAM_DCP, PARAM_LSC,
|
||||
PARAM_DAP, PARAM_ARAP, PARAM_OTE, PARAM_BTP};
|
||||
enum Parameterization_method { PARAM_MVC, PARAM_DCP, PARAM_LSC, PARAM_DAP,
|
||||
PARAM_IAP, PARAM_ARAP, PARAM_OTE, PARAM_BTP};
|
||||
void parameterize(Parameterization_method method);
|
||||
|
||||
private:
|
||||
|
|
@ -804,6 +809,15 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
|||
status = SMP::parameterize(sMesh, Parameterizer(), bhd, uv_pm);
|
||||
break;
|
||||
}
|
||||
case PARAM_IAP:
|
||||
{
|
||||
new_item_name = tr("%1 (parameterized (IAP))").arg(poly_item->name());
|
||||
std::cout << "Parameterize (IAP)..." << std::endl;
|
||||
typedef SMP::Iterative_authalic_parameterizer_3<Seam_mesh> Parameterizer;
|
||||
Parameterizer parameterizer;
|
||||
status = parameterizer.parameterize(sMesh, bhd, uv_pm, 15 /*iterations*/);
|
||||
break;
|
||||
}
|
||||
case PARAM_ARAP:
|
||||
{
|
||||
new_item_name = tr("%1 (parameterized (ARAP))").arg(poly_item->name());
|
||||
|
|
@ -1014,6 +1028,12 @@ void Polyhedron_demo_parameterization_plugin::on_actionDAP_triggered()
|
|||
parameterize(PARAM_DAP);
|
||||
}
|
||||
|
||||
void Polyhedron_demo_parameterization_plugin::on_actionIAP_triggered()
|
||||
{
|
||||
std::cerr << "IAP...";
|
||||
parameterize(PARAM_IAP);
|
||||
}
|
||||
|
||||
void Polyhedron_demo_parameterization_plugin::on_actionARAP_triggered()
|
||||
{
|
||||
std::cerr << "ARAP...";
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ Construction and destruction are undefined.
|
|||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::LSCM_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Orbifold_Tutte_parameterizer_3<SeamMesh, SolverTraits>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Circular_border_parameterizer_3<TriangleMesh>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Square_border_parameterizer_3<TriangleMesh>`
|
||||
\cgalHasModel `CGAL::Surface_mesh_parameterization::Two_vertices_parameterizer_3<TriangleMesh>`
|
||||
|
||||
\sa `CGAL::Surface_mesh_parameterization::Orbifold_Tutte_parameterizer_3<SeamMesh, SolverTraits>`
|
||||
*/
|
||||
|
||||
class Parameterizer_3
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Planar Parameterization of Triangulated Surface Meshes"
|
||||
EXTRACT_ALL = false
|
||||
HIDE_UNDOC_MEMBERS = true
|
||||
HIDE_UNDOC_CLASSES = true
|
||||
WARN_IF_UNDOCUMENTED = false
|
||||
|
||||
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/nefertiti.jpg \
|
||||
${CGAL_PACKAGE_DOC_DIR}/fig/ARAP_new.jpg \
|
||||
${CGAL_PACKAGE_DOC_DIR}/fig/orbifold_new.jpg \
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
\cgalPkgDescriptionBegin{Triangulated Surface Mesh Parameterization,PkgSurfaceMeshParameterization}
|
||||
\cgalPkgPicture{bimbaDetail.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Laurent Saboret, Pierre Alliez, Bruno Lévy, Mael Rouxel-Labbé, and Andreas Fabri}
|
||||
\cgalPkgAuthors{Laurent Saboret, Pierre Alliez, Bruno Lévy, Mael Rouxel-Labbé, Andreas Fabri, and Hardik Jain}
|
||||
\cgalPkgDesc{Parameterizing a surface amounts to finding a one-to-one mapping from
|
||||
a suitable domain to the surface. In this package, we focus on triangulated surfaces
|
||||
that are homeomorphic to a disk and on piecewise linear mappings into a planar domain.
|
||||
|
|
@ -49,9 +49,10 @@ This \cgal package implements several parameterization methods:
|
|||
Conditionally guaranteed if all weights are positive and border is convex.
|
||||
- Floater Mean Value Coordinates \cgalCite{cgal:f-mvc-03} :
|
||||
One-to-one mapping is guaranteed for convex border.
|
||||
- Iterative Authalic Parameterization \cgalCite{cgal:j-lrsspp-19}.
|
||||
- Free border:
|
||||
- As Rigid As Possible Parameterization \cgalCite{liu2008local}
|
||||
- Least Squares Conformal Maps \cgalCite{cgal:lprm-lscm-02}.
|
||||
- Least Squares Conformal Maps (LSCM) \cgalCite{cgal:lprm-lscm-02}.
|
||||
- Borderless:
|
||||
- Orbifold Tutte Embeddings \cgalCite{aigerman2015orbifold}.
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ The following classes implement the methods listed above:
|
|||
- `CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
- `CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
- `CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
- `CGAL::Surface_mesh_parameterization::Iterative_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
- `CGAL::Surface_mesh_parameterization::LSCM_parameterizer_3<TriangleMesh, BorderParameterizer>`
|
||||
- `CGAL::Surface_mesh_parameterization::Mean_value_coordinates_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
- `CGAL::Surface_mesh_parameterization::Orbifold_Tutte_parameterizer_3<TriangleMesh, SolverTraits>`
|
||||
|
|
|
|||
|
|
@ -7,13 +7,7 @@ namespace CGAL {
|
|||
\anchor chapsurface_mesh_parameterization
|
||||
\cgalAutoToc
|
||||
|
||||
\authors Laurent Saboret, Pierre Alliez, Bruno Lévy, Andreas Fabri, and
|
||||
Mael Rouxel-Labbé
|
||||
|
||||
\warning The API and structure of this package have greatly changed with CGAL 4.11.
|
||||
Users who wish to use the former API must use a version prior to 4.11.
|
||||
Section \ref Surface_mesh_parameterizationBasics gives a gentle introduction to
|
||||
the new, much simpler, API.
|
||||
\authors Laurent Saboret, Pierre Alliez, Bruno Lévy, Mael Rouxel-Labbé, Andreas Fabri and Hardik Jain
|
||||
|
||||
\section Surface_mesh_parameterizationIntroduction Introduction
|
||||
|
||||
|
|
@ -218,7 +212,7 @@ convex combination condition. This algorithm amounts to solve one
|
|||
sparse linear system for each set of parameter coordinates, with a
|
||||
\#vertices x \#vertices sparse and symmetric positive definite matrix
|
||||
(if the border vertices are eliminated from the linear system).
|
||||
A coefficient \f$ (i, j)\f$ of the matrix is set to 1 for an edge linking
|
||||
A coefficient \f$ (i,j)\f$ of the matrix is set to 1 for an edge linking
|
||||
the vertex \f$ v_i\f$ to the vertex \f$ v_j\f$, to minus the degree of the
|
||||
vertex \f$ v_i\f$ for a diagonal element, and to 0 for any other matrix
|
||||
entry. Although a bijective mapping is guaranteed when the border is convex,
|
||||
|
|
@ -299,6 +293,29 @@ for both systems) is asymmetric.
|
|||
Floater Mean Value Coordinates. Rightmost: parameter space.
|
||||
\cgalFigureCaptionEnd
|
||||
|
||||
\subsubsection Surface_mesh_parameterizationIterativeAuthalic Iterative Authalic Parameterization
|
||||
|
||||
`Surface_mesh_parameterization::Iterative_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
|
||||
The Iterative Authalic parameterization method has been introduced by
|
||||
Jain et al. \cgalCite{cgal:j-lrsspp-19}. This parameterization
|
||||
is a fixed border parameterization and is part of the authalic parameterization family,
|
||||
meaning that it aims to minimize area distortion between the input surface mesh and the parameterized output.
|
||||
More precisely, the approach used by this parameterizer is to iteratively redistribute
|
||||
the \f$ L_2\f$ stretch - as defined by Sander et al. \cgalCite{cgal:ssgh-tmpm-01} - over the mesh.
|
||||
|
||||
\cgalFigureAnchor{Surface_mesh_parameterizationfigiterativeauthalic}
|
||||
<center>
|
||||
<img src="iterative_authalic.jpg" style="max-width:70%;"/>
|
||||
</center>
|
||||
\cgalFigureCaptionBegin{Surface_mesh_parameterizationfigiterativeauthalic}
|
||||
Iterative Authalic Parameterization (the blue line depicts the cut graph). Rightmost: parameter space.
|
||||
\cgalFigureCaptionEnd
|
||||
|
||||
Although this is a fixed border parameterization method, it does not guarantee a one-to-one mapping.
|
||||
However, it will in practice yield valid results with less distortion than other authalic
|
||||
parameterization methods.
|
||||
|
||||
\subsubsection secBorderParameterizationsforFixedMethods Border Parameterizations for Fixed Methods
|
||||
|
||||
Parameterization methods for borders are used as traits classes modifying the
|
||||
|
|
@ -475,55 +492,43 @@ underlying (input) mesh.
|
|||
|
||||
\subsection Surface_mesh_parameterizationParameterization Parameterization Methods and Guarantees
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>Fixed boundaries
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>One-to-one mapping
|
||||
|
||||
Tutte's theorem guarantees a one-to-one mapping provided that the weights are all positive
|
||||
and the border is convex.
|
||||
It is the case for Tutte Barycentric Mapping and Floater Mean Value Coordinates.
|
||||
It is not always the case for Discrete Conformal Map (cotangents) and
|
||||
Discrete Authalic parameterization.
|
||||
|
||||
<LI>Non-singularity of the matrix
|
||||
|
||||
Geshorgin's theorem guarantees the convergence of the solver if the matrix is diagonal dominant.
|
||||
This is the case with positive weights (Tutte Barycentric Mapping and Floater Mean Value Coordinates).
|
||||
|
||||
</UL>
|
||||
|
||||
<LI>Free boundaries
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>One-to-one mapping
|
||||
|
||||
No guarantee is provided by either LSCM or ARAP parameterizations (both global
|
||||
overlaps and triangle flips can occur).
|
||||
|
||||
<LI>Non-singularity of the matrix
|
||||
|
||||
For LSCM, the matrix of the system is the Gram matrix of a matrix with maximal rank,
|
||||
and is therefore non-singular (Gram theorem).
|
||||
|
||||
</UL>
|
||||
|
||||
<LI> Boundary-less
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>One-to-one mapping
|
||||
|
||||
The Orbifold-Tutte embedding is guaranteed to exist and to be computable
|
||||
via a sparse linear system.
|
||||
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
<ul>
|
||||
<li><b>Fixed boundaries</b>
|
||||
<ul>
|
||||
<li><em>One-to-one mapping</em><br>
|
||||
Tutte's theorem guarantees a one-to-one mapping provided that the weights are all positive
|
||||
and the border is convex.
|
||||
It is the case for Tutte Barycentric Mapping and Floater Mean Value Coordinates.
|
||||
It is not always the case for Discrete Conformal Map (cotangents), Discrete Authalic,
|
||||
and Iterative Authalic parameterizations.
|
||||
</li>
|
||||
<li><em>Non-singularity of the matrix</em><br>
|
||||
Geshorgin's theorem guarantees the convergence of the solver if the matrix is diagonal dominant.
|
||||
This is the case with positive weights (Tutte Barycentric Mapping and Floater Mean Value Coordinates).
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Free boundaries</b>
|
||||
<ul>
|
||||
<li><em>One-to-one mapping</em><br>
|
||||
No guarantee is provided by either LSCM or ARAP parameterizations (both global overlaps
|
||||
and triangle flips can occur).
|
||||
</li>
|
||||
<li><em>Non-singularity of the matrix</em><br>
|
||||
For LSCM, the matrix of the system is the Gram matrix of a matrix with maximal rank,
|
||||
and is therefore non-singular (Gram theorem).
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Boundary-less</b>
|
||||
<ul>
|
||||
<li><em>One-to-one mapping</em><br>
|
||||
The Orbifold-Tutte embedding is guaranteed to exist and to be computable
|
||||
via a sparse linear system.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
\section Surface_mesh_parameterizationExtendingthe Implementation History
|
||||
|
||||
|
|
@ -539,6 +544,9 @@ and Yaron Lipman. Finally, the class `Seam_mesh` was introduced to handle
|
|||
virtual borders. The class `Seam_mesh` is also a model of a `FaceGraph`,
|
||||
and replaces a wrapper which had a more complicated API.
|
||||
|
||||
Iterative authalic parameterization was added in CGAL 5.2 by Mael Rouxel-Labbé,
|
||||
based on a prototype developed by Hardik Jain.
|
||||
|
||||
*/
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@
|
|||
\example Surface_mesh_parameterization/seam_Polyhedron_3.cpp
|
||||
\example Surface_mesh_parameterization/simple_parameterization.cpp
|
||||
\example Surface_mesh_parameterization/square_border_parameterizer.cpp
|
||||
\example Surface_mesh_parameterization/iterative_authalic_parameterizer.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 487 KiB |
|
|
@ -63,6 +63,8 @@ if ( CGAL_FOUND )
|
|||
target_link_libraries(simple_parameterization PUBLIC CGAL::Eigen_support)
|
||||
create_single_source_cgal_program( "square_border_parameterizer.cpp" )
|
||||
target_link_libraries(square_border_parameterizer PUBLIC CGAL::Eigen_support)
|
||||
create_single_source_cgal_program( "iterative_authalic_parameterizer.cpp" )
|
||||
target_link_libraries(iterative_authalic_parameterizer PUBLIC CGAL::Eigen_support)
|
||||
|
||||
if(SuiteSparse_FOUND)
|
||||
target_link_libraries(orbifold PRIVATE ${SuiteSparse_LIBRARIES})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/IO/File_off.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Square_border_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Circular_border_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Point_2 Point_2;
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
|
||||
|
||||
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef boost::graph_traits<Surface_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
typedef CGAL::Unique_hash_map<vertex_descriptor, Point_2> UV_uhm;
|
||||
typedef boost::associative_property_map<UV_uhm> UV_pmap;
|
||||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in((argc>1) ? argv[1] : "data/nefertiti.off");
|
||||
if(!in)
|
||||
{
|
||||
std::cerr << "Error: problem loading the input data" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Surface_mesh sm;
|
||||
in >> sm;
|
||||
|
||||
halfedge_descriptor bhd = CGAL::Polygon_mesh_processing::longest_border(sm).first;
|
||||
|
||||
// The 2D points of the uv parametrisation will be written into this map
|
||||
UV_uhm uv_uhm;
|
||||
UV_pmap uv_map(uv_uhm);
|
||||
|
||||
typedef SMP::Circular_border_arc_length_parameterizer_3<Surface_mesh> Border_parameterizer;
|
||||
Border_parameterizer border_parameterizer; // the border parameterizer will automatically compute the corner vertices
|
||||
|
||||
typedef SMP::Iterative_authalic_parameterizer_3<Surface_mesh, Border_parameterizer> Parameterizer;
|
||||
Parameterizer parameterizer(border_parameterizer);
|
||||
|
||||
const unsigned int iterations = (argc > 2) ? std::atoi(argv[2]) : 15;
|
||||
SMP::Error_code err = parameterizer.parameterize(sm, bhd, uv_map, iterations);
|
||||
|
||||
if(err != SMP::OK)
|
||||
{
|
||||
std::cerr << "Error: " << SMP::get_error_message(err) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ofstream out("iterative_result.off");
|
||||
SMP::IO::output_uvmap_to_off(sm, bhd, uv_map, out);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ namespace Surface_mesh_parameterization {
|
|||
/// a random vertex is pinned.
|
||||
///
|
||||
/// If flips are present in the initial parameterization, a post-processing step
|
||||
/// is applied using `CGAL::Surface_mesh_parameterization::MVC_post_processor_3<TriangleMesh, SolverTraits_>`
|
||||
/// is applied using `CGAL::Surface_mesh_parameterization::MVC_post_processor_3<TriangleMesh_, SolverTraits_>`
|
||||
/// to attempt to obtain a valid final embedding.
|
||||
///
|
||||
/// A one-to-one mapping is *not* guaranteed.
|
||||
|
|
@ -162,6 +162,7 @@ namespace Surface_mesh_parameterization {
|
|||
/// \endcode
|
||||
///
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Fixed_border_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Iterative_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
///
|
||||
template < class TriangleMesh_,
|
||||
class BorderParameterizer_ = Default,
|
||||
|
|
@ -194,28 +195,39 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Border parameterizer type
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
|
||||
/// Number type, deduced from the internal vertex point map of `Triangle_mesh`
|
||||
typedef unspecified_type NT;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_iterator face_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_iterator vertex_iterator;
|
||||
|
||||
typedef CGAL::Halfedge_around_target_circulator<TriangleMesh> halfedge_around_target_circulator;
|
||||
typedef CGAL::Halfedge_around_face_circulator<TriangleMesh> halfedge_around_face_circulator;
|
||||
typedef CGAL::Halfedge_around_target_circulator<Triangle_mesh> halfedge_around_target_circulator;
|
||||
typedef CGAL::Halfedge_around_face_circulator<Triangle_mesh> halfedge_around_face_circulator;
|
||||
|
||||
typedef boost::unordered_set<vertex_descriptor> Vertex_set;
|
||||
typedef std::vector<face_descriptor> Faces_vector;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Point_3 Point_3;
|
||||
|
|
@ -277,7 +289,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap>
|
||||
void output_uvmap(const std::string filename,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Faces_vector& faces,
|
||||
const VertexUVMap uvmap,
|
||||
|
|
@ -292,7 +304,7 @@ private:
|
|||
typename VertexIndexMap>
|
||||
void output_uvmap(const std::string filename,
|
||||
const unsigned int iter,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Faces_vector& faces,
|
||||
const VertexUVMap uvmap,
|
||||
|
|
@ -331,12 +343,12 @@ private:
|
|||
// Private operations
|
||||
private:
|
||||
// Store the vertices and faces of the mesh in memory.
|
||||
Error_code initialize_containers(const TriangleMesh& mesh,
|
||||
Error_code initialize_containers(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
Vertex_set& vertices,
|
||||
Faces_vector& faces) const
|
||||
{
|
||||
internal::Containers_filler<TriangleMesh> fc(mesh, vertices, &faces);
|
||||
internal::Containers_filler<Triangle_mesh> fc(mesh, vertices, &faces);
|
||||
Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
|
|
@ -351,7 +363,7 @@ private:
|
|||
// Initialize the UV values with a first parameterization of the input.
|
||||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap>
|
||||
Error_code compute_initial_uv_map(TriangleMesh& mesh,
|
||||
Error_code compute_initial_uv_map(Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVMap uvmap,
|
||||
VertexIndexMap vimap) const
|
||||
|
|
@ -372,11 +384,11 @@ private:
|
|||
// According to the paper, MVC is better for single border and LSCM is better
|
||||
// when there are multiple borders
|
||||
if(number_of_borders == 1) {
|
||||
typedef Mean_value_coordinates_parameterizer_3<TriangleMesh> MVC_parameterizer;
|
||||
typedef Mean_value_coordinates_parameterizer_3<Triangle_mesh> MVC_parameterizer;
|
||||
MVC_parameterizer mvc_parameterizer;
|
||||
status = mvc_parameterizer.parameterize(mesh, bhd, uvmap, vimap, vpmap);
|
||||
} else {
|
||||
typedef LSCM_parameterizer_3<TriangleMesh, Border_parameterizer> LSCM_parameterizer;
|
||||
typedef LSCM_parameterizer_3<Triangle_mesh, Border_parameterizer> LSCM_parameterizer;
|
||||
LSCM_parameterizer lscm_parameterizer;
|
||||
status = lscm_parameterizer.parameterize(mesh, bhd, uvmap, vimap, vpmap);
|
||||
}
|
||||
|
|
@ -389,7 +401,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize_border(const TriangleMesh& mesh,
|
||||
Error_code parameterize_border(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
halfedge_descriptor bhd,
|
||||
VertexIndexMap vimap,
|
||||
|
|
@ -422,14 +434,14 @@ private:
|
|||
}
|
||||
|
||||
// Compute the cotangent of the angle between the vectors ij and ik.
|
||||
void compute_cotangent_angle(const TriangleMesh& mesh,
|
||||
void compute_cotangent_angle(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor hd,
|
||||
vertex_descriptor vi,
|
||||
vertex_descriptor vj,
|
||||
vertex_descriptor vk,
|
||||
Cot_map ctmap) const
|
||||
{
|
||||
typedef typename boost::property_map<TriangleMesh,
|
||||
typedef typename boost::property_map<Triangle_mesh,
|
||||
boost::vertex_point_t>::const_type PPmap;
|
||||
const PPmap ppmap = get(vertex_point, mesh);
|
||||
|
||||
|
|
@ -442,7 +454,7 @@ private:
|
|||
}
|
||||
|
||||
// Fill the map 'ctmap' with the cotangents of the angles of the faces of 'mesh'.
|
||||
Error_code compute_cotangent_angles(const TriangleMesh& mesh,
|
||||
Error_code compute_cotangent_angles(const Triangle_mesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
Cot_map ctmap) const
|
||||
{
|
||||
|
|
@ -468,8 +480,8 @@ private:
|
|||
return OK;
|
||||
}
|
||||
|
||||
// Compute w_ij = (i, j) coefficient of matrix A for j neighbor vertex of i.
|
||||
NT compute_w_ij(const TriangleMesh& mesh,
|
||||
// computes `w_ij`, the `(i,j)`-coefficient of matrix `A` for `j` neighbor vertex of `i`.
|
||||
NT compute_w_ij(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor hd,
|
||||
const Cot_map ctmap) const
|
||||
{
|
||||
|
|
@ -496,7 +508,7 @@ private:
|
|||
// \pre Line i of A must contain only zeros.
|
||||
template <typename VertexIndexMap>
|
||||
Error_code fill_linear_system_matrix(Matrix& A,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
vertex_descriptor vertex,
|
||||
const Cot_map ct_map,
|
||||
VertexIndexMap vimap) const
|
||||
|
|
@ -538,7 +550,7 @@ private:
|
|||
// after (at least two) border vertices parameterization.
|
||||
template <typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code initialize_matrix_A(const TriangleMesh& mesh,
|
||||
Error_code initialize_matrix_A(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Cot_map ctmap,
|
||||
VertexIndexMap vimap,
|
||||
|
|
@ -695,7 +707,7 @@ private:
|
|||
|
||||
// Compute the root that gives the lowest face energy.
|
||||
template <typename VertexUVMap>
|
||||
std::size_t compute_root_with_lowest_energy(const TriangleMesh& mesh,
|
||||
std::size_t compute_root_with_lowest_energy(const Triangle_mesh& mesh,
|
||||
face_descriptor fd,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -722,7 +734,7 @@ private:
|
|||
|
||||
// Compute the root that gives the lowest face energy.
|
||||
template <typename VertexUVMap>
|
||||
std::size_t compute_root_with_lowest_energy(const TriangleMesh& mesh,
|
||||
std::size_t compute_root_with_lowest_energy(const Triangle_mesh& mesh,
|
||||
face_descriptor fd,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -748,7 +760,7 @@ private:
|
|||
|
||||
// Compute the optimal values of the linear transformation matrices Lt.
|
||||
template <typename VertexUVMap>
|
||||
Error_code compute_optimal_Lt_matrices(const TriangleMesh& mesh,
|
||||
Error_code compute_optimal_Lt_matrices(const Triangle_mesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -874,13 +886,13 @@ private:
|
|||
}
|
||||
|
||||
// Compute the local parameterization (2D) of a face and store it in memory.
|
||||
void project_face(const TriangleMesh& mesh,
|
||||
void project_face(const Triangle_mesh& mesh,
|
||||
vertex_descriptor vi,
|
||||
vertex_descriptor vj,
|
||||
vertex_descriptor vk,
|
||||
Local_points& lp) const
|
||||
{
|
||||
typedef typename boost::property_map<TriangleMesh,
|
||||
typedef typename boost::property_map<Triangle_mesh,
|
||||
boost::vertex_point_t>::const_type PPmap;
|
||||
const PPmap ppmap = get(vertex_point, mesh);
|
||||
|
||||
|
|
@ -900,7 +912,7 @@ private:
|
|||
|
||||
// Utility for fill_linear_system_rhs():
|
||||
// Compute the local isometric parameterization (2D) of the faces of the mesh.
|
||||
Error_code compute_local_parameterization(const TriangleMesh& mesh,
|
||||
Error_code compute_local_parameterization(const Triangle_mesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
Local_points& lp,
|
||||
Lp_map lpmap) const
|
||||
|
|
@ -936,9 +948,9 @@ private:
|
|||
return OK;
|
||||
}
|
||||
|
||||
// Compute the coefficient b_ij = (i, j) of the right hand side vector B,
|
||||
// Compute the coefficient b_ij = (i,j) of the right hand side vector B,
|
||||
// for j neighbor vertex of i.
|
||||
void compute_b_ij(const TriangleMesh& mesh,
|
||||
void compute_b_ij(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor hd,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1009,7 +1021,7 @@ private:
|
|||
// \pre Vertex i musn't be already parameterized.
|
||||
// \pre Lines i of Bu and Bv must be zero.
|
||||
template <typename VertexIndexMap>
|
||||
Error_code fill_linear_system_rhs(const TriangleMesh& mesh,
|
||||
Error_code fill_linear_system_rhs(const Triangle_mesh& mesh,
|
||||
vertex_descriptor vertex,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1053,7 +1065,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code compute_rhs(const TriangleMesh& mesh,
|
||||
Error_code compute_rhs(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1091,7 +1103,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code update_solution(const TriangleMesh& mesh,
|
||||
Error_code update_solution(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1147,7 +1159,7 @@ private:
|
|||
|
||||
// Compute the current energy of a face, given a linear transformation matrix.
|
||||
template <typename VertexUVMap>
|
||||
NT compute_current_face_energy(const TriangleMesh& mesh,
|
||||
NT compute_current_face_energy(const Triangle_mesh& mesh,
|
||||
face_descriptor fd,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1190,7 +1202,7 @@ private:
|
|||
|
||||
// Compute the current energy of a face.
|
||||
template <typename VertexUVMap>
|
||||
NT compute_current_face_energy(const TriangleMesh& mesh,
|
||||
NT compute_current_face_energy(const Triangle_mesh& mesh,
|
||||
face_descriptor fd,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1207,7 +1219,7 @@ private:
|
|||
|
||||
// Compute the current energy of the parameterization.
|
||||
template <typename VertexUVMap>
|
||||
NT compute_current_energy(const TriangleMesh& mesh,
|
||||
NT compute_current_energy(const Triangle_mesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
const Cot_map ctmap,
|
||||
const Local_points& lp,
|
||||
|
|
@ -1232,14 +1244,14 @@ private:
|
|||
// the (hopefully few) flips in the result.
|
||||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap>
|
||||
Error_code post_process(const TriangleMesh& mesh,
|
||||
Error_code post_process(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Faces_vector& faces,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVMap uvmap,
|
||||
const VertexIndexMap vimap) const
|
||||
{
|
||||
typedef MVC_post_processor_3<TriangleMesh> Post_processor;
|
||||
typedef MVC_post_processor_3<Triangle_mesh> Post_processor;
|
||||
|
||||
Post_processor p;
|
||||
Error_code status = p.parameterize(mesh, vertices, faces, bhd, uvmap, vimap);
|
||||
|
|
@ -1255,28 +1267,28 @@ private:
|
|||
|
||||
// Public operations
|
||||
public:
|
||||
/// Check if the 3D -> 2D mapping is one-to-one.
|
||||
template <typename VertexUVMap>
|
||||
bool is_one_to_one_mapping(const TriangleMesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
/// returns whether the 3D -> 2D mapping is one-to-one.
|
||||
template <typename FaceRange, typename VertexUVMap>
|
||||
bool is_one_to_one_mapping(const Triangle_mesh& mesh,
|
||||
const FaceRange& faces,
|
||||
const VertexUVMap uvmap) const
|
||||
{
|
||||
return internal::is_one_to_one_mapping(mesh, faces, uvmap);
|
||||
}
|
||||
|
||||
/// Compute a mapping from a triangular 3D surface mesh to a piece of the 2D space.
|
||||
/// computes a mapping from a triangular 3D surface mesh to a piece of the 2D space.
|
||||
/// The mapping is piecewise linear (linear in each triangle).
|
||||
/// The result is the (u,v) pair image of each vertex of the 3D surface.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -1291,12 +1303,16 @@ public:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(TriangleMesh& mesh,
|
||||
Error_code parameterize(Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVMap uvmap,
|
||||
VertexIndexMap vimap,
|
||||
VertexParameterizedMap vpmap)
|
||||
{
|
||||
CGAL_precondition(is_valid_polygon_mesh(mesh));
|
||||
CGAL_precondition(is_triangle_mesh(mesh));
|
||||
CGAL_precondition(bhd != boost::graph_traits<Triangle_mesh>::null_halfedge() && is_border(bhd, mesh));
|
||||
|
||||
Error_code status = OK;
|
||||
|
||||
// vertices and faces containers
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <CGAL/Surface_mesh_parameterization/Fixed_border_parameterizer_3.h>
|
||||
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/iterator.h>
|
||||
|
||||
#if defined(CGAL_EIGEN3_ENABLED)
|
||||
#include <CGAL/Eigen_solver_traits.h>
|
||||
|
|
@ -43,8 +44,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// This class is a strategy called by the main
|
||||
/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it:
|
||||
/// - provides the template parameters `BorderParameterizer_` and `SolverTraits_`.
|
||||
/// - implements compute_w_ij() to compute `w_ij = (i,j)`, coefficient of
|
||||
/// the matrix A for `j` neighbor vertex of `i`, based on Tutte Barycentric
|
||||
/// - implements compute_w_ij() to compute `w_ij`, the `(i,j)`-coefficient of
|
||||
/// the matrix `A` for `j` neighbor vertex of `i`, based on Tutte Barycentric
|
||||
/// Mapping method.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
|
|
@ -108,24 +109,32 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Border parameterizer type
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
typedef SolverTraits_ SolverTraits;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
private:
|
||||
// Superclass
|
||||
typedef Fixed_border_parameterizer_3<TriangleMesh_,
|
||||
typedef Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits> Base;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
|
||||
|
||||
typedef typename Base::NT NT;
|
||||
|
||||
// Solver traits subtypes:
|
||||
|
|
@ -139,24 +148,24 @@ public:
|
|||
///< %Object that maps the surface's border to 2D space.
|
||||
Solver_traits sparse_la = Solver_traits())
|
||||
///< Traits object to access a sparse linear system.
|
||||
: Fixed_border_parameterizer_3<TriangleMesh,
|
||||
: Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits>(border_param, sparse_la)
|
||||
{ }
|
||||
|
||||
// Default copy constructor and operator =() are fine
|
||||
|
||||
/// Check if the 3D -> 2D mapping is one-to-one.
|
||||
/// returns whether the 3D -> 2D mapping is one-to-one.
|
||||
template <typename VertexUVMap,
|
||||
typename Faces_Container>
|
||||
bool is_one_to_one_mapping(const TriangleMesh& mesh,
|
||||
bool is_one_to_one_mapping(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
const VertexUVMap uvmap) const
|
||||
{
|
||||
/// Theorem: A one-to-one mapping is guaranteed if all w_ij coefficients
|
||||
/// are > 0 (for j vertex neighbor of i) and if the surface
|
||||
/// Theorem: A one-to-one mapping is guaranteed if all `w_ij` coefficients
|
||||
/// are > 0 (for `j` vertex neighbor of `i`) and if the surface
|
||||
/// border is mapped onto a 2D convex polygon.
|
||||
/// Here, all w_ij coefficients = 1 (for j vertex neighbor of i), thus a
|
||||
/// Here, all `w_ij` coefficients are equal to `1` (for `j` vertex neighbor of `i`), thus a
|
||||
/// valid embedding is guaranteed if the surface border is mapped
|
||||
/// onto a 2D convex polygon.
|
||||
return (Base::get_border_parameterizer().is_border_convex() ||
|
||||
|
|
@ -165,13 +174,12 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute w_ij = (i,j), coefficient of matrix A for j neighbor vertex of i.
|
||||
virtual NT compute_w_ij(const TriangleMesh& /* mesh */,
|
||||
/// computes `w_ij`, the coefficient of matrix `A` for `j` neighbor vertex of `i`.
|
||||
virtual NT compute_w_ij(const Triangle_mesh& /* mesh */,
|
||||
vertex_descriptor /* main_vertex_v_i */,
|
||||
vertex_around_target_circulator /* neighbor_vertex_v_j */ ) const
|
||||
Vertex_around_target_circulator<Triangle_mesh> /* neighbor_vertex_v_j */ ) const
|
||||
{
|
||||
/// In the Tutte Barycentric Mapping algorithm, we have w_ij = 1,
|
||||
/// for j neighbor vertex of i.
|
||||
/// In the Tutte Barycentric Mapping algorithm, we have `w_ij = 1`, for `j` neighbor vertex of `i`.
|
||||
return 1.;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,29 +62,33 @@ class Circular_border_parameterizer_3
|
|||
{
|
||||
// Public types
|
||||
public:
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Protected types
|
||||
protected:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh_>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<TriangleMesh_>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Vector_3 Vector_3;
|
||||
|
||||
// Protected operations
|
||||
protected:
|
||||
virtual NT compute_edge_length(const TriangleMesh& mesh,
|
||||
virtual NT compute_edge_length(const Triangle_mesh& mesh,
|
||||
vertex_descriptor source,
|
||||
vertex_descriptor target) const = 0;
|
||||
|
||||
// Private operations
|
||||
private:
|
||||
// Compute the total length of the border
|
||||
NT compute_border_length(const TriangleMesh& mesh,
|
||||
NT compute_border_length(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd) const
|
||||
{
|
||||
NT len = 0.0;
|
||||
|
|
@ -96,21 +100,21 @@ private:
|
|||
|
||||
// Public operations
|
||||
public:
|
||||
/// Assign to the mesh's border vertices a 2D position (i.e.\ a (u,v) pair)
|
||||
/// assigns to the mesh's border vertices a 2D position (i.e.\ a `(u,v)` pair)
|
||||
/// on the circle. Mark them as <i>parameterized</i>.
|
||||
///
|
||||
/// The distribution of vertices over the circle depends on the function
|
||||
/// `compute_edge_length()`.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -124,7 +128,7 @@ public:
|
|||
template <typename VertexUVmap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap /* vimap */,
|
||||
|
|
@ -159,7 +163,7 @@ public:
|
|||
return OK;
|
||||
}
|
||||
|
||||
/// Indicate if border's shape is convex.
|
||||
/// indicates if border's shape is convex.
|
||||
bool is_border_convex() const { return true; }
|
||||
|
||||
virtual ~Circular_border_parameterizer_3() { }
|
||||
|
|
@ -192,20 +196,18 @@ class Circular_border_uniform_parameterizer_3
|
|||
// Public types
|
||||
public:
|
||||
// We have to repeat the types exported by superclass
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
/// @endcond
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef Circular_border_parameterizer_3<TriangleMesh> Base;
|
||||
typedef Circular_border_parameterizer_3<Triangle_mesh> Base;
|
||||
typedef typename Base::NT NT;
|
||||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute the length of an edge.
|
||||
virtual NT compute_edge_length(const TriangleMesh& /* mesh */,
|
||||
/// computes the length of an edge.
|
||||
virtual NT compute_edge_length(const Triangle_mesh& /* mesh */,
|
||||
vertex_descriptor /* source */,
|
||||
vertex_descriptor /* target */) const
|
||||
{
|
||||
|
|
@ -243,24 +245,22 @@ class Circular_border_arc_length_parameterizer_3
|
|||
// Public types
|
||||
public:
|
||||
// We have to repeat the types exported by superclass
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
/// @endcond
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef Circular_border_parameterizer_3<TriangleMesh> Base;
|
||||
typedef Circular_border_parameterizer_3<Triangle_mesh> Base;
|
||||
|
||||
typedef typename Base::PPM PPM;
|
||||
typedef typename Base::NT NT;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
typedef typename Base::PPM PPM;
|
||||
typedef typename Base::NT NT;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute the length of an edge.
|
||||
virtual NT compute_edge_length(const TriangleMesh& mesh,
|
||||
/// computes the length of an edge.
|
||||
virtual NT compute_edge_length(const Triangle_mesh& mesh,
|
||||
vertex_descriptor source,
|
||||
vertex_descriptor target) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// This class is a strategy called by the main
|
||||
/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it:
|
||||
/// - provides the template parameters `BorderParameterizer_` and `SolverTraits_`.
|
||||
/// - implements `compute_w_ij()` to compute w_ij = (i, j), coefficient of the matrix A
|
||||
/// for j neighbor vertex of i, based on Discrete Authalic Parameterization algorithm.
|
||||
/// - implements `compute_w_ij()` to compute `w_ij`, the `(i,j)`-coefficient of the matrix `A`
|
||||
/// for `j` neighbor vertex of `i`, based on Discrete Authalic Parameterization algorithm.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
///
|
||||
|
|
@ -75,6 +75,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// \endcode
|
||||
///
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Fixed_border_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::ARAP_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Iterative_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
///
|
||||
template < class TriangleMesh_,
|
||||
class BorderParameterizer_ = Default,
|
||||
|
|
@ -112,23 +114,31 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Border parameterizer type
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
// Superclass
|
||||
typedef Fixed_border_parameterizer_3<TriangleMesh,
|
||||
typedef Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits> Base;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
|
||||
typedef CGAL::Vertex_around_target_circulator<Triangle_mesh> vertex_around_target_circulator;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename Base::PPM PPM;
|
||||
|
|
@ -148,7 +158,7 @@ public:
|
|||
///< %Object that maps the surface's border to 2D space.
|
||||
Solver_traits sparse_la = Solver_traits())
|
||||
///< Traits object to access a sparse linear system.
|
||||
: Fixed_border_parameterizer_3<TriangleMesh,
|
||||
: Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits>(border_param, sparse_la)
|
||||
{ }
|
||||
|
|
@ -157,14 +167,14 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute w_ij = (i, j), coefficient of matrix A for j neighbor vertex of i.
|
||||
/// computes `w_ij`, the (i,j), coefficient of matrix `A` for `j` neighbor vertex of `i`.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
/// \param main_vertex_v_i the vertex of `mesh` with index `i`
|
||||
/// \param neighbor_vertex_v_j the vertex of `mesh` with index `j`
|
||||
virtual NT compute_w_ij(const TriangleMesh& mesh,
|
||||
virtual NT compute_w_ij(const Triangle_mesh& mesh,
|
||||
vertex_descriptor main_vertex_v_i,
|
||||
vertex_around_target_circulator neighbor_vertex_v_j) const
|
||||
Vertex_around_target_circulator<Triangle_mesh> neighbor_vertex_v_j) const
|
||||
{
|
||||
const PPM ppmap = get(vertex_point, mesh);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// This class is a strategy called by the main
|
||||
/// parameterization algorithm `Fixed_border_parameterizer_3::parameterize()` and it:
|
||||
/// - provides the template parameters `BorderParameterizer_` and `SolverTraits_`.
|
||||
/// - implements `compute_w_ij()` to compute w_ij = (i, j), coefficient of matrix A
|
||||
/// for j neighbor vertex of i, based on Discrete Conformal Map method.
|
||||
/// - implements `compute_w_ij()` to compute `w_ij`, the `(i,j)`-coefficient of matrix `A`,
|
||||
/// for `j` neighbor vertex of `i`, based on Discrete Conformal Map method.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
///
|
||||
|
|
@ -112,23 +112,29 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Border parameterizer type
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
// Superclass
|
||||
typedef Fixed_border_parameterizer_3<TriangleMesh,
|
||||
typedef Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits> Base;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::Vertex_around_target_circulator<Triangle_mesh> vertex_around_target_circulator;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename Base::Kernel Kernel;
|
||||
|
|
@ -148,7 +154,7 @@ public:
|
|||
///< %Object that maps the surface's border to 2D space.
|
||||
Solver_traits sparse_la = Solver_traits())
|
||||
///< Traits object to access a sparse linear system.
|
||||
: Fixed_border_parameterizer_3<TriangleMesh,
|
||||
: Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits>(border_param, sparse_la)
|
||||
{ }
|
||||
|
|
@ -157,14 +163,14 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute w_ij = (i,j) coefficient of matrix A for j neighbor vertex of i.
|
||||
/// computes `w_ij`, the `(i,j)`-coefficient of matrix `A`, for `j` neighbor vertex of `i`.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
/// \param main_vertex_v_i the vertex of `mesh` with index `i`
|
||||
/// \param neighbor_vertex_v_j the vertex of `mesh` with index `j`
|
||||
virtual NT compute_w_ij(const TriangleMesh& mesh,
|
||||
virtual NT compute_w_ij(const Triangle_mesh& mesh,
|
||||
vertex_descriptor main_vertex_v_i,
|
||||
vertex_around_target_circulator neighbor_vertex_v_j) const // its target is main_vertex_v_i
|
||||
Vertex_around_target_circulator<Triangle_mesh> neighbor_vertex_v_j) const // its target is main_vertex_v_i
|
||||
{
|
||||
const PPM ppmap = get(vertex_point, mesh);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// Nevertheless, it implements most of the parameterization algorithm `parameterize()`.
|
||||
/// Subclasses are *Strategies* \cgalCite{cgal:ghjv-dpero-95} that modify the behavior of this algorithm:
|
||||
/// - They provide the template parameters `BorderParameterizer_` and `SolverTraits_`.
|
||||
/// - They implement `compute_w_ij()` to compute w_ij = (i, j), coefficient of matrix A
|
||||
/// for j neighbor vertex of i.
|
||||
/// - They implement `compute_w_ij()` to compute `w_ij`, the `(i,j)`-coefficient of matrix `A`
|
||||
/// for `j` neighbor vertex of `i`.
|
||||
///
|
||||
// @todo `Fixed_border_parameterizer_3` should remove border vertices
|
||||
// from the linear systems in order to have a symmetric positive definite
|
||||
|
|
@ -88,7 +88,6 @@ namespace Surface_mesh_parameterization {
|
|||
/// Eigen::IncompleteLUT< double > > >
|
||||
/// \endcode
|
||||
///
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::ARAP_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Barycentric_mapping_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Discrete_authalic_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Discrete_conformal_map_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
|
||||
|
|
@ -121,34 +120,44 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Border parameterizer type
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
/// Solver vector type
|
||||
typedef typename Solver_traits::Vector Vector;
|
||||
|
||||
/// Solver matrix type
|
||||
typedef typename Solver_traits::Matrix Matrix;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
|
||||
typedef CGAL::Vertex_around_face_circulator<TriangleMesh> vertex_around_face_circulator;
|
||||
typedef CGAL::Vertex_around_target_circulator<Triangle_mesh> vertex_around_target_circulator;
|
||||
|
||||
// Protected types
|
||||
protected:
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PPM;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Point_3 Point_3;
|
||||
typedef typename Kernel::Vector_3 Vector_3;
|
||||
|
||||
// Solver traits subtypes:
|
||||
typedef typename Solver_traits::Vector Vector;
|
||||
typedef typename Solver_traits::Matrix Matrix;
|
||||
|
||||
// Public operations
|
||||
public:
|
||||
/// Constructor
|
||||
|
|
@ -164,20 +173,20 @@ public:
|
|||
|
||||
// Default copy constructor and operator =() are fine
|
||||
|
||||
/// Compute a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// computes a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// to a piece of the 2D space.
|
||||
/// The mapping is piecewise linear (linear in each triangle).
|
||||
/// The result is the (u,v) pair image of each vertex of the 3D surface.
|
||||
/// The result is the `(u,v)` pair image of each vertex of the 3D surface.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -193,18 +202,22 @@ public:
|
|||
template <typename VertexUVmap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(TriangleMesh& mesh,
|
||||
Error_code parameterize(Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap vimap,
|
||||
VertexParameterizedMap vpmap)
|
||||
{
|
||||
CGAL_precondition(is_valid_polygon_mesh(mesh));
|
||||
CGAL_precondition(is_triangle_mesh(mesh));
|
||||
CGAL_precondition(bhd != boost::graph_traits<Triangle_mesh>::null_halfedge() && is_border(bhd, mesh));
|
||||
|
||||
Error_code status = OK;
|
||||
|
||||
typedef boost::unordered_set<vertex_descriptor> Vertex_set;
|
||||
Vertex_set vertices;
|
||||
|
||||
internal::Containers_filler<TriangleMesh> fc(mesh, vertices);
|
||||
internal::Containers_filler<Triangle_mesh> fc(mesh, vertices);
|
||||
Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
|
|
@ -294,16 +307,16 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Initialize A, Bu and Bv after border parameterization.
|
||||
/// initializes `A`, `Bu` and `Bv` after border parameterization.
|
||||
/// Fill the border vertices' lines in both linear systems:
|
||||
/// "u = constant" and "v = constant".
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
///
|
||||
/// \param A the matrix in both linear system
|
||||
|
|
@ -315,11 +328,11 @@ protected:
|
|||
/// \param vimap an instanciation of the class `VertexIndexMap`.
|
||||
///
|
||||
/// \pre Vertices must be indexed (`vimap` must be initialized).
|
||||
/// \pre A, Bu and Bv must be allocated.
|
||||
/// \pre `A`, `Bu`, and `Bv` must be allocated.
|
||||
/// \pre Border vertices must be parameterized.
|
||||
template <typename VertexUVmap, typename VertexIndexMap>
|
||||
void initialize_system_from_mesh_border(Matrix& A, Vector& Bu, Vector& Bv,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap vimap) const
|
||||
|
|
@ -337,16 +350,15 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
/// Compute w_ij, coefficient of matrix A for j neighbor vertex of i.
|
||||
/// computes `w_ij`, coefficient of matrix `A` for `j` neighbor vertex of `i`.
|
||||
/// Implementation note: Subclasses must at least implement compute_w_ij().
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
/// \param main_vertex_v_i the vertex of `mesh` with index `i`
|
||||
/// \param neighbor_vertex_v_j the vertex of `mesh` with index `j`
|
||||
virtual NT compute_w_ij(const TriangleMesh& mesh,
|
||||
virtual NT compute_w_ij(const Triangle_mesh& mesh,
|
||||
vertex_descriptor main_vertex_v_i,
|
||||
vertex_around_target_circulator neighbor_vertex_v_j) const
|
||||
= 0;
|
||||
Vertex_around_target_circulator<Triangle_mesh> neighbor_vertex_v_j) const = 0;
|
||||
|
||||
/// Compute the line i of matrix A for i inner vertex:
|
||||
/// - call compute_w_ij() to compute the A coefficient w_ij for each neighbor v_j.
|
||||
|
|
@ -361,7 +373,7 @@ protected:
|
|||
Error_code setup_inner_vertex_relations(Matrix& A,
|
||||
Vector&,
|
||||
Vector&,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
vertex_descriptor vertex,
|
||||
VertexIndexMap vimap) const
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -75,7 +75,7 @@ namespace Surface_mesh_parameterization {
|
|||
/// and `CGAL_EIGEN3_ENABLED` is defined, then an overload of `Eigen_solver_traits`
|
||||
/// is provided as default parameter:
|
||||
/// \code
|
||||
/// CGAL::Eigen_solver_traits<Eigen::BICGSTAB< Eigen::SparseMatrix<double> > >
|
||||
/// CGAL::Eigen_solver_traits<Eigen::SimplicialLDLT< Eigen::SparseMatrix<double> > >
|
||||
/// \endcode
|
||||
/// Otherwise, it uses CGAL's wrapping function to the OpenNL library:
|
||||
/// \code
|
||||
|
|
@ -100,12 +100,7 @@ public:
|
|||
#if defined(CGAL_EIGEN3_ENABLED)
|
||||
// WARNING: at the moment, the choice of SolverTraits_ is completely
|
||||
// ignored (see LeastSquaresSolver typedef) and `OpenNL::LinearSolver<SolverTraits_>`
|
||||
// is used anyway. If Eigen solver traits were to be used again, there is a bug
|
||||
// in the line below to be first fixed:
|
||||
// `Eigen_sparse_symmetric_matrix<double>::EigenType` is a NON SYMMETRIC
|
||||
// Eigen sparse matrix, and thus SolverTraits_::Matrix will be a NON SYMMETRIC matrix
|
||||
// and the whole symmetry aspect will be completely ignored.
|
||||
// @fixme
|
||||
// is always used...
|
||||
CGAL::Eigen_solver_traits<
|
||||
Eigen::SimplicialLDLT<Eigen_sparse_symmetric_matrix<double>::EigenType> >
|
||||
#else
|
||||
|
|
@ -113,24 +108,29 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// The border parameterizer
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_descriptor face_descriptor;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Point_3 Point_3;
|
||||
|
|
@ -155,29 +155,29 @@ public:
|
|||
|
||||
// Default copy constructor and operator =() are fine
|
||||
|
||||
/// Check if the 3D -> 2D mapping is one-to-one.
|
||||
/// returns whether the 3D -> 2D mapping is one-to-one.
|
||||
template <typename VertexUVMap>
|
||||
bool is_one_to_one_mapping(const TriangleMesh& mesh,
|
||||
bool is_one_to_one_mapping(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
const VertexUVMap uvmap) const
|
||||
{
|
||||
return internal::is_one_to_one_mapping(mesh, bhd, uvmap);
|
||||
}
|
||||
|
||||
/// Compute a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// computes a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// to a piece of the 2D space.
|
||||
/// The mapping is piecewise linear (linear in each triangle).
|
||||
/// The result is the (u,v) pair image of each vertex of the 3D surface.
|
||||
/// The result is the `(u,v)` pair image of each vertex of the 3D surface.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -190,17 +190,21 @@ public:
|
|||
/// \pre The vertices must be indexed (`vimap` must be initialized).
|
||||
///
|
||||
template <typename VertexUVmap, typename VertexIndexMap, typename VertexParameterizedMap>
|
||||
Error_code parameterize(TriangleMesh& mesh,
|
||||
Error_code parameterize(Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap vimap,
|
||||
VertexParameterizedMap vpmap)
|
||||
{
|
||||
CGAL_precondition(is_valid_polygon_mesh(mesh));
|
||||
CGAL_precondition(is_triangle_mesh(mesh));
|
||||
CGAL_precondition(bhd != boost::graph_traits<Triangle_mesh>::null_halfedge() && is_border(bhd, mesh));
|
||||
|
||||
// Fill containers
|
||||
boost::unordered_set<vertex_descriptor> ccvertices;
|
||||
std::vector<face_descriptor> ccfaces;
|
||||
|
||||
internal::Containers_filler<TriangleMesh> fc(mesh, ccvertices, &ccfaces);
|
||||
internal::Containers_filler<Triangle_mesh> fc(mesh, ccvertices, &ccfaces);
|
||||
Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
|
|
@ -340,7 +344,7 @@ private:
|
|||
// in presence of degenerate triangles
|
||||
template <typename VertexIndexMap >
|
||||
Error_code setup_triangle_relations(LeastSquaresSolver& solver,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
face_descriptor facet,
|
||||
VertexIndexMap vimap) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <CGAL/license/Surface_mesh_parameterization.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/internal/Bool_property_map.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/internal/Containers_filler.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/internal/kernel_traits.h>
|
||||
|
||||
|
|
@ -93,29 +94,33 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
// This class
|
||||
typedef MVC_post_processor_3<TriangleMesh, Solver_traits> Self;
|
||||
typedef MVC_post_processor_3<Triangle_mesh, Solver_traits> Self;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_iterator face_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_iterator vertex_iterator;
|
||||
|
||||
typedef boost::unordered_set<vertex_descriptor> Vertex_set;
|
||||
typedef std::vector<face_descriptor> Faces_vector;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Vector_2 Vector_2;
|
||||
|
|
@ -189,12 +194,12 @@ private:
|
|||
// Private operations
|
||||
private:
|
||||
// Store the vertices and faces of the mesh in memory.
|
||||
void initialize_containers(const TriangleMesh& mesh,
|
||||
void initialize_containers(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
Vertex_set& vertices,
|
||||
Faces_vector& faces) const
|
||||
{
|
||||
internal::Containers_filler<TriangleMesh> fc(mesh, vertices, &faces);
|
||||
internal::Containers_filler<Triangle_mesh> fc(mesh, vertices, &faces);
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
|
|
@ -203,7 +208,7 @@ private:
|
|||
|
||||
// Checks whether the polygon's border is simple.
|
||||
template <typename VertexUVMap>
|
||||
bool is_polygon_simple(const TriangleMesh& mesh,
|
||||
bool is_polygon_simple(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
const VertexUVMap uvmap) const
|
||||
{
|
||||
|
|
@ -273,7 +278,7 @@ private:
|
|||
// Triangulate the convex hull of the border of the parameterization.
|
||||
template <typename CT,
|
||||
typename VertexUVMap>
|
||||
Error_code triangulate_convex_hull(const TriangleMesh& mesh,
|
||||
Error_code triangulate_convex_hull(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
const VertexUVMap uvmap,
|
||||
CT& ct) const
|
||||
|
|
@ -506,7 +511,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
void fill_linear_system_matrix_mvc_from_mesh_halfedge(const TriangleMesh& mesh,
|
||||
void fill_linear_system_matrix_mvc_from_mesh_halfedge(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor hd,
|
||||
const VertexUVMap uvmap,
|
||||
const VertexIndexMap vimap,
|
||||
|
|
@ -539,7 +544,7 @@ private:
|
|||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
void fill_linear_system_matrix_mvc_from_mesh_face(const TriangleMesh& mesh,
|
||||
void fill_linear_system_matrix_mvc_from_mesh_face(const Triangle_mesh& mesh,
|
||||
face_descriptor fd,
|
||||
const VertexUVMap uvmap,
|
||||
const VertexIndexMap vimap,
|
||||
|
|
@ -562,7 +567,7 @@ private:
|
|||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code compute_mvc_matrix(const CT& ct,
|
||||
const TriangleMesh& mesh,
|
||||
const Triangle_mesh& mesh,
|
||||
const Faces_vector& faces,
|
||||
const VertexUVMap uvmap,
|
||||
const VertexIndexMap vimap,
|
||||
|
|
@ -660,7 +665,7 @@ private:
|
|||
typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize_convex_hull_with_MVC(const TriangleMesh& mesh,
|
||||
Error_code parameterize_convex_hull_with_MVC(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Faces_vector& faces,
|
||||
const CT& ct,
|
||||
|
|
@ -707,7 +712,7 @@ private:
|
|||
public:
|
||||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
const Vertex_set& vertices,
|
||||
const Faces_vector& faces,
|
||||
halfedge_descriptor bhd,
|
||||
|
|
@ -741,15 +746,15 @@ public:
|
|||
return OK;
|
||||
}
|
||||
|
||||
/// Compute a one-to-one mapping from a triangular 2D surface mesh
|
||||
/// computes a one-to-one mapping from a triangular 2D surface mesh
|
||||
/// that is not necessarily embedded to a piece of the 2D space.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -759,7 +764,7 @@ public:
|
|||
///
|
||||
template <typename VertexUVMap,
|
||||
typename VertexIndexMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVMap uvmap,
|
||||
const VertexIndexMap vimap)
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ namespace Surface_mesh_parameterization {
|
|||
/// `Fixed_border_parameterizer_3::parameterize()`.
|
||||
/// - It provides default `BorderParameterizer_` and `SolverTraits_` template
|
||||
/// parameters.
|
||||
/// - It implements `compute_w_ij()` to compute w_ij = (i, j) coefficient of matrix A
|
||||
/// for j neighbor vertex of i based on Floater Mean Value Coordinates parameterization.
|
||||
/// - It implements `compute_w_ij()` to compute `w_ij`, the `(i,j)` coefficient of matrix `A`
|
||||
/// for `j` neighbor vertex of `i` based on Floater Mean Value Coordinates parameterization.
|
||||
/// - It implements an optimized version of `is_one_to_one_mapping()`.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
|
|
@ -110,39 +110,48 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// The border parameterizer
|
||||
typedef Border_parameterizer_ Border_parameterizer;
|
||||
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
// Superclass
|
||||
typedef Fixed_border_parameterizer_3<TriangleMesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits> Base;
|
||||
typedef Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits> Base;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_descriptor face_descriptor;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
typedef CGAL::Vertex_around_target_circulator<TriangleMesh> vertex_around_target_circulator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_iterator vertex_iterator;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::face_iterator face_iterator;
|
||||
typedef CGAL::Vertex_around_target_circulator<Triangle_mesh> vertex_around_target_circulator;
|
||||
|
||||
// Mesh_TriangleMesh_3 subtypes:
|
||||
typedef typename Base::PPM PPM;
|
||||
typedef typename Base::Kernel Kernel;
|
||||
typedef typename Base::NT NT;
|
||||
typedef typename Base::Point_3 Point_3;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
typedef typename Base::PPM PPM;
|
||||
typedef typename Base::Kernel Kernel;
|
||||
typedef typename Base::NT NT;
|
||||
typedef typename Base::Point_3 Point_3;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
|
||||
// Solver traits subtypes:
|
||||
typedef typename Solver_traits::Vector Vector;
|
||||
typedef typename Solver_traits::Matrix Matrix;
|
||||
typedef typename Solver_traits::Vector Vector;
|
||||
typedef typename Solver_traits::Matrix Matrix;
|
||||
|
||||
// Public operations
|
||||
public:
|
||||
|
|
@ -151,16 +160,16 @@ public:
|
|||
///< Object that maps the surface's border to 2D space.
|
||||
Solver_traits sparse_la = Solver_traits())
|
||||
///< Traits object to access a sparse linear system.
|
||||
: Fixed_border_parameterizer_3<TriangleMesh,
|
||||
: Fixed_border_parameterizer_3<Triangle_mesh,
|
||||
Border_parameterizer,
|
||||
Solver_traits>(border_param, sparse_la)
|
||||
{ }
|
||||
|
||||
// Default copy constructor and operator =() are fine
|
||||
|
||||
/// Check if the 3D -> 2D mapping is one-to-one.
|
||||
/// returns whether the 3D -> 2D mapping is one-to-one.
|
||||
template <typename VertexUVMap>
|
||||
bool is_one_to_one_mapping(const TriangleMesh& mesh,
|
||||
bool is_one_to_one_mapping(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
const VertexUVMap uvmap) const
|
||||
{
|
||||
|
|
@ -176,14 +185,14 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute w_ij = (i, j) coefficient of matrix A for j neighbor vertex of i.
|
||||
/// computes `w_ij`, the `(i, j)`-coefficient of matrix A for j neighbor vertex of i.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
/// \param main_vertex_v_i the vertex of `mesh` with index `i`
|
||||
/// \param neighbor_vertex_v_j the vertex of `mesh` with index `j`
|
||||
virtual NT compute_w_ij(const TriangleMesh& mesh,
|
||||
virtual NT compute_w_ij(const Triangle_mesh& mesh,
|
||||
vertex_descriptor main_vertex_v_i,
|
||||
vertex_around_target_circulator neighbor_vertex_v_j) const
|
||||
Vertex_around_target_circulator<Triangle_mesh> neighbor_vertex_v_j) const
|
||||
{
|
||||
const PPM ppmap = get(vertex_point, mesh);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace Surface_mesh_parameterization {
|
|||
|
||||
/// \ingroup PkgSurfaceMeshParameterizationOrbifoldHelperFunctions
|
||||
///
|
||||
/// Read a serie of cones from an input stream. Cones are passed as an
|
||||
/// reads a serie of cones from an input stream. Cones are passed as an
|
||||
/// integer value that is the index of a vertex handle in the mesh tm`, using
|
||||
/// the vertex index property map `vpmap` for correspondency.
|
||||
///
|
||||
|
|
@ -192,7 +192,7 @@ Error_code read_cones(const TriangleMesh& tm, const char* filename, ConeOutputIt
|
|||
|
||||
/// \ingroup PkgSurfaceMeshParameterizationOrbifoldHelperFunctions
|
||||
///
|
||||
/// Locate the cones on the seam mesh (that is, find the corresponding seam mesh
|
||||
/// locates the cones on the seam mesh (that is, find the corresponding seam mesh
|
||||
/// `vertex_descriptor`) and mark them with a tag to indicate whether the cone is a
|
||||
/// simple cone or a duplicated cone (see \link PkgSurfaceMeshParameterizationEnums Cone_type \endlink).
|
||||
///
|
||||
|
|
@ -202,7 +202,7 @@ Error_code read_cones(const TriangleMesh& tm, const char* filename, ConeOutputIt
|
|||
/// but is passed here as a template parameter for convenience, to avoid
|
||||
/// having to pass the multiple template parameters of the class `CGAL::Seam_mesh`.
|
||||
/// \tparam ConeInputBidirectionalIterator must be a model of `BidirectionalIterator`
|
||||
/// with value type `boost::graph_traits<SeamMesh::TriangleMesh>::%vertex_descriptor`.
|
||||
/// with value type `boost::graph_traits<SeamMesh::Triangle_mesh>::%vertex_descriptor`.
|
||||
/// \tparam ConeMap must be a model of `AssociativeContainer`
|
||||
/// with `boost::graph_traits<SeamMesh>::%vertex_descriptor` as key type and
|
||||
/// \link PkgSurfaceMeshParameterizationEnums Cone_type \endlink as value type.
|
||||
|
|
@ -216,13 +216,13 @@ bool locate_cones(const SeamMesh& mesh,
|
|||
ConeInputBidirectionalIterator first, ConeInputBidirectionalIterator beyond,
|
||||
ConeMap& cones)
|
||||
{
|
||||
typedef typename SeamMesh::TriangleMesh TriangleMesh;
|
||||
typedef typename SeamMesh::Triangle_mesh Triangle_mesh;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor TM_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor TM_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<SeamMesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// property map to go from TM_vertex_descriptor to Point_3
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PM_PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PM_PPM;
|
||||
const PM_PPM pm_ppmap = get(boost::vertex_point, mesh.mesh());
|
||||
|
||||
// property map to go from vertex_descriptor to Point_3
|
||||
|
|
@ -264,9 +264,9 @@ bool locate_unordered_cones(const SeamMesh& mesh,
|
|||
CGAL_precondition(cones.empty());
|
||||
CGAL_precondition(std::distance(first, beyond) == 3 || std::distance(first, beyond) == 4);
|
||||
|
||||
typedef typename SeamMesh::TriangleMesh TriangleMesh;
|
||||
typedef typename SeamMesh::Triangle_mesh Triangle_mesh;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor TM_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor TM_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<SeamMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<SeamMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
|
|
@ -282,7 +282,7 @@ bool locate_unordered_cones(const SeamMesh& mesh,
|
|||
CGAL_assertion(vertex_on_seam != vertex_descriptor());
|
||||
|
||||
// property map to go from TM_vertex_descriptor to Point_3
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PM_PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PM_PPM;
|
||||
const PM_PPM pm_ppmap = get(boost::vertex_point, mesh.mesh());
|
||||
|
||||
// property map to go from vertex_descriptor to Point_3
|
||||
|
|
@ -358,7 +358,8 @@ bool locate_unordered_cones(const SeamMesh& mesh,
|
|||
/// shows how to select cones on the input mesh and automatically construct
|
||||
/// the seams and the cones on the `Seam_mesh`.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
/// \attention The global function `CGAL::Surface_mesh_parameterization::parameterize()` cannot be used
|
||||
/// with this parameterizer. Users should use this class's member function `parameterize()` instead.
|
||||
///
|
||||
/// \tparam SeamMesh must be a `Seam_mesh`, with underlying mesh any model of `FaceListGraph` and `HalfedgeListGraph`.
|
||||
///
|
||||
|
|
@ -405,12 +406,15 @@ public:
|
|||
#endif
|
||||
>::type Solver_traits;
|
||||
#else
|
||||
/// Solver traits type
|
||||
typedef SolverTraits_ Solver_traits;
|
||||
#endif
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<SeamMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
private:
|
||||
typedef typename boost::graph_traits<SeamMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<SeamMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<SeamMesh>::face_descriptor face_descriptor;
|
||||
|
||||
typedef typename boost::graph_traits<SeamMesh>::vertex_iterator vertex_iterator;
|
||||
|
|
@ -888,7 +892,7 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
/// Compute a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// computes a one-to-one mapping from a triangular 3D surface mesh
|
||||
/// to a piece of the 2D space.
|
||||
/// The mapping is piecewise linear (linear in each triangle).
|
||||
/// The result is the (u,v) pair image of each vertex of the 3D surface.
|
||||
|
|
@ -936,6 +940,8 @@ public:
|
|||
VertexUVMap uvmap,
|
||||
VertexIndexMap vimap) const
|
||||
{
|
||||
CGAL_precondition(is_valid_polygon_mesh(mesh));
|
||||
CGAL_precondition(is_triangle_mesh(mesh));
|
||||
CGAL_USE(bhd);
|
||||
|
||||
Error_code status;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ namespace Surface_mesh_parameterization {
|
|||
/// The user can provide four vertices on the border of the mesh, which will be
|
||||
/// mapped to the four corners of the square.
|
||||
///
|
||||
/// \attention The square border parameterizer may create degenerate faces in the parameterization:
|
||||
/// if an input border vertex has valence `1` and if it is mapped to the same edge of the square
|
||||
/// as its two adjacent (border) vertices, for example.
|
||||
///
|
||||
/// Implementation note:
|
||||
/// To simplify the implementation, the border parameterizer knows only the
|
||||
/// `TriangleMesh` class and does not know the parameterization algorithm
|
||||
|
|
@ -67,18 +71,24 @@ class Square_border_parameterizer_3
|
|||
{
|
||||
// Public types
|
||||
public:
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
typedef Halfedge_around_face_iterator<TriangleMesh> halfedge_around_face_iterator;
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Protected types
|
||||
protected:
|
||||
typedef Halfedge_around_face_iterator<Triangle_mesh> halfedge_around_face_iterator;
|
||||
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Vector_3 Vector_3;
|
||||
|
|
@ -92,14 +102,14 @@ private:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
virtual double compute_edge_length(const TriangleMesh& mesh,
|
||||
virtual double compute_edge_length(const Triangle_mesh& mesh,
|
||||
vertex_descriptor source,
|
||||
vertex_descriptor target) const = 0;
|
||||
|
||||
// Private operations
|
||||
private:
|
||||
// Compute the total length of the border.
|
||||
double compute_border_length(const TriangleMesh& mesh,
|
||||
double compute_border_length(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd) const
|
||||
{
|
||||
double len = 0.0;
|
||||
|
|
@ -111,7 +121,7 @@ private:
|
|||
|
||||
// Utility method for parameterize().
|
||||
// Compute the mesh iterator whose offset is closest to 'value'.
|
||||
halfedge_around_face_iterator closest_iterator(const TriangleMesh& mesh,
|
||||
halfedge_around_face_iterator closest_iterator(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
Offset_map& offset,
|
||||
double value) const
|
||||
|
|
@ -138,7 +148,7 @@ private:
|
|||
// Set the corners by splitting the border of the mesh in four
|
||||
// approximately equal segments.
|
||||
template<typename VertexParameterizedMap>
|
||||
halfedge_descriptor compute_offsets_without_given_vertices(const TriangleMesh& mesh,
|
||||
halfedge_descriptor compute_offsets_without_given_vertices(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexParameterizedMap vpmap,
|
||||
Offset_map& offset) const
|
||||
|
|
@ -185,7 +195,7 @@ private:
|
|||
// the mesh. The vertices between two given vertices vi and vj are
|
||||
// sent to the same side of the square.
|
||||
template<typename VertexParameterizedMap>
|
||||
halfedge_descriptor compute_offsets(const TriangleMesh& mesh,
|
||||
halfedge_descriptor compute_offsets(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexParameterizedMap vpmap,
|
||||
Offset_map& offset)
|
||||
|
|
@ -245,18 +255,18 @@ private:
|
|||
public:
|
||||
// Default constructor, copy constructor and operator =() are fine
|
||||
|
||||
/// Assign to the vertices of the border of the mesh a 2D position
|
||||
/// assigns to the vertices of the border of the mesh a 2D position
|
||||
/// (i.e.\ a (u,v) pair) on the border's shape. Mark them as <i>parameterized</i>.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -270,7 +280,7 @@ public:
|
|||
template<typename VertexUVMap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVMap uvmap,
|
||||
VertexIndexMap /* vimap */,
|
||||
|
|
@ -344,7 +354,7 @@ public:
|
|||
return OK;
|
||||
}
|
||||
|
||||
/// Indicate if the border's shape is convex.
|
||||
/// indicates if the border's shape is convex.
|
||||
bool is_border_convex() const { return true; }
|
||||
|
||||
public:
|
||||
|
|
@ -382,6 +392,10 @@ public:
|
|||
/// algorithm. This class implements only `compute_edge_length()` to compute a
|
||||
/// segment's length.
|
||||
///
|
||||
/// \attention The square border parameterizer may create degenerate faces in the parameterization:
|
||||
/// if an input border vertex has valence `1` and if it is mapped to the same edge of the square
|
||||
/// as its two adjacent (border) vertices, for example.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
///
|
||||
/// \sa `CGAL::Surface_mesh_parameterization::Square_border_parameterizer_3<TriangleMesh>`
|
||||
|
|
@ -396,15 +410,14 @@ class Square_border_uniform_parameterizer_3
|
|||
// Public types
|
||||
public:
|
||||
// We have to repeat the types exported by superclass
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
/// @endcond
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef Square_border_parameterizer_3<TriangleMesh_> Base;
|
||||
typedef typename Base::NT NT;
|
||||
typedef Square_border_parameterizer_3<TriangleMesh_> Base;
|
||||
typedef typename Base::NT NT;
|
||||
|
||||
public:
|
||||
virtual ~Square_border_uniform_parameterizer_3() { }
|
||||
|
|
@ -425,8 +438,8 @@ public:
|
|||
|
||||
// Protected operations
|
||||
protected:
|
||||
/// Compute the length of an edge.
|
||||
virtual NT compute_edge_length(const TriangleMesh& /* mesh */,
|
||||
/// computes the length of an edge.
|
||||
virtual NT compute_edge_length(const Triangle_mesh& /* mesh */,
|
||||
vertex_descriptor /* source */,
|
||||
vertex_descriptor /* target */) const
|
||||
{
|
||||
|
|
@ -449,6 +462,10 @@ protected:
|
|||
/// algorithm. This class implements only `compute_edge_length()` to compute a
|
||||
/// segment's length.
|
||||
///
|
||||
/// \attention The square border parameterizer may create degenerate faces in the parameterization:
|
||||
/// if an input border vertex has valence `1` and if it is mapped to the same edge of the square
|
||||
/// as its two adjacent (border) vertices, for example.
|
||||
///
|
||||
/// \tparam TriangleMesh_ must be a model of `FaceGraph`.
|
||||
///
|
||||
/// \cgalModels `Parameterizer_3`
|
||||
|
|
@ -462,14 +479,13 @@ class Square_border_arc_length_parameterizer_3
|
|||
{
|
||||
// Public types
|
||||
public:
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
/// @endcond
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
typedef Square_border_parameterizer_3<TriangleMesh_> Base;
|
||||
typedef Square_border_parameterizer_3<Triangle_mesh> Base;
|
||||
typedef typename Base::PPM PPM;
|
||||
typedef typename Base::NT NT;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
|
|
@ -494,7 +510,7 @@ public:
|
|||
// Protected operations
|
||||
protected:
|
||||
/// Compute the length of an edge.
|
||||
virtual NT compute_edge_length(const TriangleMesh& mesh,
|
||||
virtual NT compute_edge_length(const Triangle_mesh& mesh,
|
||||
vertex_descriptor source,
|
||||
vertex_descriptor target) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,16 +56,22 @@ class Two_vertices_parameterizer_3
|
|||
{
|
||||
// Public types
|
||||
public:
|
||||
/// Triangle mesh type
|
||||
typedef TriangleMesh_ Triangle_mesh;
|
||||
|
||||
typedef TriangleMesh_ TriangleMesh;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
/// Mesh vertex type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
/// Mesh halfedge type
|
||||
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Private types
|
||||
private:
|
||||
// Traits subtypes:
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<TriangleMesh>::Kernel Kernel;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::PPM PPM;
|
||||
typedef typename internal::Kernel_traits<Triangle_mesh>::Kernel Kernel;
|
||||
typedef typename Kernel::FT NT;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
typedef typename Kernel::Point_3 Point_3;
|
||||
|
|
@ -92,7 +98,7 @@ public:
|
|||
typename VertexUVmap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
const VertexContainer& vertices,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap /* vimap */,
|
||||
|
|
@ -267,17 +273,17 @@ public:
|
|||
return OK;
|
||||
}
|
||||
|
||||
/// Map two extreme vertices of the 3D mesh and mark them as <i>parameterized</i>.
|
||||
/// maps two extreme vertices of the 3D mesh and mark them as <i>parameterized</i>.
|
||||
///
|
||||
/// \tparam VertexUVmap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `TriangleMesh` using `Kernel_traits`)
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// %Point_2 (type deduced from `Triangle_mesh` using `Kernel_traits`)
|
||||
/// as value type.
|
||||
/// \tparam VertexIndexMap must be a model of `ReadablePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a unique integer as value type.
|
||||
/// \tparam VertexParameterizedMap must be a model of `ReadWritePropertyMap` with
|
||||
/// `boost::graph_traits<TriangleMesh>::%vertex_descriptor` as key type and
|
||||
/// `boost::graph_traits<Triangle_mesh>::%vertex_descriptor` as key type and
|
||||
/// a Boolean as value type.
|
||||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
|
|
@ -292,7 +298,7 @@ public:
|
|||
template <typename VertexUVmap,
|
||||
typename VertexIndexMap,
|
||||
typename VertexParameterizedMap>
|
||||
Error_code parameterize(const TriangleMesh& mesh,
|
||||
Error_code parameterize(const Triangle_mesh& mesh,
|
||||
halfedge_descriptor bhd,
|
||||
VertexUVmap uvmap,
|
||||
VertexIndexMap vimap,
|
||||
|
|
@ -300,7 +306,7 @@ public:
|
|||
{
|
||||
// Fill containers
|
||||
boost::unordered_set<vertex_descriptor> vertices;
|
||||
internal::Containers_filler<TriangleMesh> fc(mesh, vertices);
|
||||
internal::Containers_filler<Triangle_mesh> fc(mesh, vertices);
|
||||
Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
|
|
@ -309,7 +315,7 @@ public:
|
|||
return parameterize(mesh, vertices, uvmap, vimap, vpmap);
|
||||
}
|
||||
|
||||
/// Indicate if the border's shape is convex.
|
||||
/// indicates if the border's shape is convex.
|
||||
/// Meaningless for free border parameterization algorithms.
|
||||
bool is_border_convex() const { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@
|
|||
|
||||
#include <CGAL/license/Surface_mesh_parameterization.h>
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
#include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
|
||||
#include <CGAL/Polygon_mesh_processing/connected_components.h>
|
||||
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -56,7 +58,7 @@ public:
|
|||
: mesh(mesh_), vertices(vertices_), faces(nullptr)
|
||||
{ }
|
||||
|
||||
void operator()(face_descriptor fd)
|
||||
void operator()(const face_descriptor fd)
|
||||
{
|
||||
halfedge_descriptor hd = halfedge(fd, mesh);
|
||||
for(vertex_descriptor vd : vertices_around_face(hd, mesh)) {
|
||||
|
|
@ -78,10 +80,10 @@ struct Index_map_filler
|
|||
: mesh(mesh), map(&map), index(0)
|
||||
{ }
|
||||
|
||||
void operator()(const face_descriptor& fd)
|
||||
void operator()(const face_descriptor fd)
|
||||
{
|
||||
for(vertex_descriptor vd :
|
||||
vertices_around_face(halfedge(fd, mesh), mesh)) {
|
||||
for(vertex_descriptor vd : vertices_around_face(halfedge(fd, mesh), mesh))
|
||||
{
|
||||
typename Map::iterator it;
|
||||
bool new_element;
|
||||
boost::tie(it,new_element) = map->insert(std::make_pair(vd,1));
|
||||
|
|
@ -96,12 +98,47 @@ struct Index_map_filler
|
|||
int index;
|
||||
};
|
||||
|
||||
template <typename TriangleMesh, typename VertexIndexMap>
|
||||
void fill_index_map_of_cc(const typename boost::graph_traits<TriangleMesh>::halfedge_descriptor bhd,
|
||||
const TriangleMesh& mesh,
|
||||
VertexIndexMap vimap)
|
||||
{
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
|
||||
std::vector<face_descriptor> CC_faces;
|
||||
|
||||
// 'reserve' might cause a huge amount of memory to be used for a tiny CC,
|
||||
// but if this is a problem as a user, one could simply parameterize a Face_filtered_graph instead.
|
||||
CC_faces.reserve(num_faces(mesh));
|
||||
|
||||
PMP::connected_component(face(opposite(bhd, mesh), mesh), mesh, std::back_inserter(CC_faces));
|
||||
|
||||
// If all vertices are involved, avoid walking all the faces
|
||||
if(CC_faces.size() == faces(mesh).size())
|
||||
{
|
||||
BGL::internal::Index_map_initializer<VertexIndexMap, TriangleMesh> id_initializer;
|
||||
id_initializer(CGAL::internal_np::vertex_index, vimap, mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(vertex_descriptor v : vertices(mesh))
|
||||
put(vimap, v, -1);
|
||||
|
||||
int index = 0;
|
||||
for(face_descriptor f : CC_faces)
|
||||
for(vertex_descriptor v : vertices_around_face(halfedge(f, mesh), mesh))
|
||||
if(get(vimap, v) == -1)
|
||||
put(vimap, v, index++);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace Surface_mesh_parameterization
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_CONTAINERS_FILLER_H
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
/// Check if the 3D -> 2D mapping is one-to-one.
|
||||
/// returns whether the 3D -> 2D mapping is one-to-one.
|
||||
/// This function is stronger than "has_flips()" because the parameterized
|
||||
/// surface can loop over itself without creating any flips.
|
||||
template <typename TriangleMesh,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright (c) 2020 GeometryFactory (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Mael Rouxel-Labbé
|
||||
|
||||
#ifndef CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_DISTORTION_H
|
||||
#define CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_DISTORTION_H
|
||||
|
||||
#include <CGAL/license/Surface_mesh_parameterization.h>
|
||||
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
#include <CGAL/circulator.h>
|
||||
#include <CGAL/Kernel/global_functions.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Surface_mesh_parameterization {
|
||||
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
||||
// Measure L2 stretch
|
||||
template <typename VertexRange, typename FaceRange, typename TriangleMesh, typename VertexUVmap>
|
||||
double compute_L2_stretch(const VertexRange& vertex_range,
|
||||
const FaceRange& face_range,
|
||||
const TriangleMesh& tmesh,
|
||||
const VertexUVmap uvmap)
|
||||
{
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
|
||||
typedef typename boost::property_map<TriangleMesh, boost::vertex_point_t>::const_type VertexPointMap;
|
||||
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3;
|
||||
typedef typename CGAL::Kernel_traits<Point_3>::Kernel Kernel;
|
||||
typedef typename Kernel::Point_2 Point_2;
|
||||
|
||||
typedef CGAL::dynamic_face_property_t<double> Face_double_tag;
|
||||
typedef typename boost::property_map<TriangleMesh, Face_double_tag>::const_type Face_double_map;
|
||||
|
||||
Face_double_map area_2D = get(Face_double_tag(), tmesh);
|
||||
Face_double_map area_3D = get(Face_double_tag(), tmesh);
|
||||
|
||||
// iterate fpr all inner vertices and for each vertex
|
||||
std::vector<double> area_dist;
|
||||
|
||||
double A_3D = 0.;
|
||||
double A_2D = 0.;
|
||||
|
||||
for(face_descriptor f : face_range)
|
||||
{
|
||||
std::vector<Point_2> uv_points;
|
||||
for(vertex_descriptor v : vertices_around_face(halfedge(f, tmesh), tmesh))
|
||||
uv_points.push_back(get(uvmap, v));
|
||||
|
||||
const double a_2D = abs(CGAL::area(get(uvmap, target(halfedge(f, tmesh), tmesh)),
|
||||
get(uvmap, source(halfedge(f, tmesh), tmesh)),
|
||||
get(uvmap, target(next(halfedge(f, tmesh), tmesh), tmesh))));
|
||||
const double a_3D = Polygon_mesh_processing::face_area(f, tmesh);
|
||||
|
||||
put(area_2D, f, a_2D);
|
||||
put(area_3D, f, a_3D);
|
||||
|
||||
A_2D += a_2D;
|
||||
A_3D += a_3D;
|
||||
}
|
||||
|
||||
for(vertex_descriptor v : vertex_range)
|
||||
{
|
||||
// inner vertices only
|
||||
if(CGAL::is_border(v, tmesh))
|
||||
continue;
|
||||
|
||||
double a_2D = 0.;
|
||||
double a_3D = 0.;
|
||||
|
||||
// find the area of all the adjacent faces to this vertex
|
||||
CGAL::Face_around_target_circulator<TriangleMesh> f_j(halfedge(v, tmesh), tmesh), end = f_j;
|
||||
CGAL_For_all(f_j, end)
|
||||
{
|
||||
if(*f_j == boost::graph_traits<TriangleMesh>::null_face())
|
||||
continue;
|
||||
|
||||
a_2D += get(area_2D, *f_j);
|
||||
a_3D += get(area_3D, *f_j);
|
||||
}
|
||||
|
||||
a_2D /= A_2D;
|
||||
a_3D /= A_3D;
|
||||
|
||||
area_dist.push_back(square((a_3D/a_2D) - 1.));
|
||||
}
|
||||
|
||||
return sqrt(std::accumulate(area_dist.begin(), area_dist.end(), 0.));
|
||||
}
|
||||
|
||||
template <typename TriangleMesh, typename VertexUVmap>
|
||||
double compute_L2_stretch(const TriangleMesh& tmesh,
|
||||
const VertexUVmap uvmap)
|
||||
{
|
||||
return compute_L2_stretch(vertices(tmesh), faces(tmesh), tmesh, uvmap);
|
||||
}
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
} // namespace Surface_mesh_parameterization
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_SURFACE_MESH_PARAMETERIZATION_INTERNAL_DISTORTION_H
|
||||
|
|
@ -103,7 +103,7 @@ public:
|
|||
|
||||
/// \ingroup PkgSurfaceMeshParameterizationOrbifoldHelperFunctions
|
||||
///
|
||||
/// Compute the shortest path between `source` and `target` over `mesh`, using
|
||||
/// computes the shortest path between `source` and `target` over `mesh`, using
|
||||
/// <a href="https://www.boost.org/doc/libs/release/libs/graph/doc/dijkstra_shortest_paths.html">
|
||||
/// boost::dijkstra_shortest_paths()</a>.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -15,19 +15,10 @@
|
|||
|
||||
#include <CGAL/license/Surface_mesh_parameterization.h>
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/internal/Bool_property_map.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/Error_code.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/connected_components.h>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
/// \file parameterize.h
|
||||
|
||||
|
|
@ -37,7 +28,7 @@ namespace Surface_mesh_parameterization {
|
|||
|
||||
/// \ingroup PkgSurfaceMeshParameterizationMainFunction
|
||||
///
|
||||
/// Compute a one-to-one mapping from a 3D triangle surface `mesh` to a
|
||||
/// computes a one-to-one mapping from a 3D triangle surface `mesh` to a
|
||||
/// simple 2D domain.
|
||||
/// The mapping is piecewise linear on the triangle mesh.
|
||||
/// The result is a pair `(u,v)` of parameter coordinates for each vertex of the input mesh.
|
||||
|
|
@ -57,7 +48,7 @@ namespace Surface_mesh_parameterization {
|
|||
/// \param mesh a triangulated surface.
|
||||
/// \param parameterizer a parameterizer.
|
||||
/// \param bhd a halfedge descriptor on the boundary of `mesh`.
|
||||
/// \param uvm an instanciation of the class `VertexUVmap`.
|
||||
/// \param uvmap an instanciation of the class `VertexUVmap`.
|
||||
///
|
||||
/// \pre `mesh` must be a triangular mesh.
|
||||
/// \pre The mesh border must be mapped onto a convex polygon
|
||||
|
|
@ -68,28 +59,26 @@ template <class TriangleMesh, class Parameterizer, class HD, class VertexUVmap>
|
|||
Error_code parameterize(TriangleMesh& mesh,
|
||||
Parameterizer parameterizer,
|
||||
HD bhd,
|
||||
VertexUVmap uvm)
|
||||
VertexUVmap uvmap)
|
||||
{
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
CGAL_precondition(is_valid_polygon_mesh(mesh));
|
||||
CGAL_precondition(bhd != boost::graph_traits<TriangleMesh>::null_halfedge() && is_border(bhd, mesh));
|
||||
|
||||
typedef boost::unordered_map<vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
boost::make_function_output_iterator(
|
||||
internal::Index_map_filler<TriangleMesh, Indices>(mesh, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
typedef CGAL::dynamic_vertex_property_t<int> Vertex_int_tag;
|
||||
typedef typename boost::property_map<TriangleMesh, Vertex_int_tag>::type Vertex_int_map;
|
||||
Vertex_int_map vimap = get(Vertex_int_tag(), mesh);
|
||||
internal::fill_index_map_of_cc(bhd, mesh, vimap);
|
||||
|
||||
boost::unordered_set<vertex_descriptor> vs;
|
||||
internal::Bool_property_map<boost::unordered_set<vertex_descriptor> > vpm(vs);
|
||||
typedef CGAL::dynamic_vertex_property_t<bool> Vertex_bool_tag;
|
||||
typedef typename boost::property_map<TriangleMesh, Vertex_bool_tag>::type Vertex_bool_map;
|
||||
Vertex_bool_map vpmap = get(Vertex_bool_tag(), mesh);
|
||||
|
||||
return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm);
|
||||
return parameterizer.parameterize(mesh, bhd, uvmap, vimap, vpmap);
|
||||
}
|
||||
|
||||
/// \ingroup PkgSurfaceMeshParameterizationMainFunction
|
||||
///
|
||||
/// Compute a one-to-one mapping from a 3D triangle surface `mesh` to a
|
||||
/// computes a one-to-one mapping from a 3D triangle surface `mesh` to a
|
||||
/// 2D circle, using Floater Mean Value Coordinates algorithm.
|
||||
/// A one-to-one mapping is guaranteed.
|
||||
///
|
||||
|
|
@ -106,7 +95,7 @@ Error_code parameterize(TriangleMesh& mesh,
|
|||
///
|
||||
/// \param mesh a triangulated surface.
|
||||
/// \param bhd a halfedge descriptor on the boundary of `mesh`.
|
||||
/// \param uvm an instanciation of the class `VertexUVmap`.
|
||||
/// \param uvmap an instanciation of the class `VertexUVmap`.
|
||||
///
|
||||
/// \pre `mesh` must be a triangular mesh.
|
||||
/// \pre The vertices must be indexed (vimap must be initialized).
|
||||
|
|
@ -114,51 +103,14 @@ Error_code parameterize(TriangleMesh& mesh,
|
|||
template <class TriangleMesh, class HD, class VertexUVmap>
|
||||
Error_code parameterize(TriangleMesh& mesh,
|
||||
HD bhd,
|
||||
VertexUVmap uvm)
|
||||
VertexUVmap uvmap)
|
||||
{
|
||||
Mean_value_coordinates_parameterizer_3<TriangleMesh> parameterizer;
|
||||
return parameterize(mesh, parameterizer, bhd, uvm);
|
||||
}
|
||||
|
||||
template <class TM, class SEM, class SVM>
|
||||
class Seam_mesh;
|
||||
|
||||
template <class TM, class SEM, class SVM, class Parameterizer, class HD, class VertexUVmap>
|
||||
Error_code parameterize(Seam_mesh<TM, SEM, SVM>& mesh,
|
||||
Parameterizer parameterizer,
|
||||
HD bhd,
|
||||
VertexUVmap uvm)
|
||||
{
|
||||
typedef typename boost::graph_traits<Seam_mesh<TM, SEM, SVM> >::vertex_descriptor vertex_descriptor;
|
||||
boost::unordered_set<vertex_descriptor> vs;
|
||||
internal::Bool_property_map<boost::unordered_set<vertex_descriptor> > vpm(vs);
|
||||
|
||||
typedef boost::unordered_map<vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(bhd, mesh), mesh),
|
||||
mesh,
|
||||
boost::make_function_output_iterator(
|
||||
internal::Index_map_filler<Seam_mesh<TM, SEM, SVM>,
|
||||
Indices>(mesh, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm);
|
||||
}
|
||||
|
||||
template <class TM, class SEM, class SVM, class HD, class VertexUVmap>
|
||||
Error_code parameterize(Seam_mesh<TM, SEM, SVM>& mesh,
|
||||
HD bhd,
|
||||
VertexUVmap uvm)
|
||||
{
|
||||
Mean_value_coordinates_parameterizer_3<Seam_mesh<TM, SEM, SVM> > parameterizer;
|
||||
return parameterize(mesh, parameterizer, bhd, uvm);
|
||||
return parameterize(mesh, parameterizer, bhd, uvmap);
|
||||
}
|
||||
|
||||
} // namespace Surface_mesh_parameterization
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_PARAMETERIZE_H
|
||||
|
|
|
|||
|
|
@ -22,12 +22,14 @@
|
|||
#include <CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/LSCM_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/MVC_post_processor_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/parameterize.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/measure_distortion.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_parameterization/Circular_border_parameterizer_3.h>
|
||||
#include <CGAL/Surface_mesh_parameterization/Square_border_parameterizer_3.h>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <CGAL/surface_mesh_parameterization.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
#include <CGAL/Polygon_mesh_processing/connected_components.h>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
#include <fstream>
|
||||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Point_2 Point_2;
|
||||
|
|
@ -29,6 +31,7 @@ typedef Kernel::Point_3 Point_3;
|
|||
#define DCM_PM_SEAM_MESH
|
||||
#define DAC_SM_SEAM_MESH
|
||||
#define ORBIFOLD_SM_MESH
|
||||
#define ITERATIVE_SURF_MESH
|
||||
|
||||
// POLYHEDRON_MESH
|
||||
typedef CGAL::Polyhedron_3<Kernel> PMesh;
|
||||
|
|
@ -94,7 +97,7 @@ int main(int, char**)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first;
|
||||
PM_halfedge_descriptor hd = PMP::longest_border(pm).first;
|
||||
|
||||
CGAL::Unique_hash_map<PM_vertex_descriptor, Point_2,
|
||||
boost::hash<PM_vertex_descriptor> > uvhm;
|
||||
|
|
@ -113,7 +116,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with MVC (POLY)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // MVC_POLYHEDRON_MESH
|
||||
|
||||
// ***************************************************************************
|
||||
// ARAP WITH POLYHEDRON_MESH
|
||||
|
|
@ -131,7 +134,7 @@ int main(int, char**)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first;
|
||||
PM_halfedge_descriptor hd = PMP::longest_border(pm).first;
|
||||
|
||||
// UV map
|
||||
CGAL::Unique_hash_map<PM_vertex_descriptor, Point_2,
|
||||
|
|
@ -141,25 +144,21 @@ int main(int, char**)
|
|||
boost::hash<PM_vertex_descriptor> > > uvpm(uvhm);
|
||||
|
||||
// Indices map
|
||||
typedef boost::unordered_map<PM_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(hd, pm), pm),
|
||||
pm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<PMesh, Indices>(pm, indices)));
|
||||
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
typedef CGAL::dynamic_vertex_property_t<int> Vertex_int_tag;
|
||||
typedef typename boost::property_map<PMesh, Vertex_int_tag>::type Vertex_int_map;
|
||||
Vertex_int_map vipm = get(Vertex_int_tag(), pm);
|
||||
CGAL::Surface_mesh_parameterization::internal::fill_index_map_of_cc(hd, pm, vipm);
|
||||
|
||||
// Vertex parameterized map
|
||||
boost::unordered_set<PM_vertex_descriptor> vs;
|
||||
SMP::internal::Bool_property_map<boost::unordered_set<PM_vertex_descriptor> > vpm(vs);
|
||||
typedef CGAL::dynamic_vertex_property_t<bool> Vertex_bool_tag;
|
||||
typedef typename boost::property_map<PMesh, Vertex_bool_tag>::type Vertex_bool_map;
|
||||
Vertex_bool_map vpm = get(Vertex_bool_tag(), pm);
|
||||
|
||||
// Parameterizer
|
||||
SMP::ARAP_parameterizer_3<PMesh> parameterizer;
|
||||
SMP::Error_code status = parameterizer.parameterize(pm, hd, uvpm, vipm, vpm);
|
||||
|
||||
if(status != SMP::OK) {
|
||||
SMP::Error_code status_bis = SMP::parameterize(pm, parameterizer, hd, uvpm);
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -167,7 +166,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with ARAP (POLY)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ARAP_POLYHEDRON_MESH
|
||||
|
||||
// ***************************************************************************
|
||||
// Barycentric mapping
|
||||
|
|
@ -185,7 +184,7 @@ int main(int, char**)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(sm).first;
|
||||
SM_halfedge_descriptor hd = PMP::longest_border(sm).first;
|
||||
assert(hd != SM_halfedge_descriptor());
|
||||
|
||||
// UV map
|
||||
|
|
@ -195,11 +194,9 @@ int main(int, char**)
|
|||
// Indices map
|
||||
typedef boost::unordered_map<SM_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(hd, sm), sm),
|
||||
sm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SMesh, Indices>(sm, indices)));
|
||||
PMP::connected_component(face(opposite(hd, sm), sm), sm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SMesh, Indices>(sm, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
// Vertex parameterized map
|
||||
|
|
@ -210,8 +207,9 @@ int main(int, char**)
|
|||
SMP::Barycentric_mapping_parameterizer_3<SMesh> parameterizer;
|
||||
|
||||
SMP::Error_code status = parameterizer.parameterize(sm, hd, uvpm, vipm, vpm);
|
||||
SMP::Error_code status_bis = SMP::parameterize(sm, parameterizer, hd, uvpm);
|
||||
|
||||
if(status != SMP::OK) {
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -219,7 +217,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with Barycentric (SM)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // BARY_SURF_MESH
|
||||
|
||||
// ***************************************************************************
|
||||
// ARAP WITH SURF_MESH
|
||||
|
|
@ -238,8 +236,7 @@ int main(int, char**)
|
|||
}
|
||||
|
||||
// halfedge on the longest border
|
||||
SM_halfedge_descriptor hd =
|
||||
CGAL::Polygon_mesh_processing::longest_border(sm).first;
|
||||
SM_halfedge_descriptor hd = PMP::longest_border(sm).first;
|
||||
|
||||
CGAL::Unique_hash_map<SM_vertex_descriptor, Point_2,
|
||||
boost::hash<SM_vertex_descriptor> > uvhm;
|
||||
|
|
@ -251,11 +248,9 @@ int main(int, char**)
|
|||
// Indices map
|
||||
typedef boost::unordered_map<SM_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(hd, sm), sm),
|
||||
sm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SMesh, Indices>(sm, indices)));
|
||||
PMP::connected_component(face(opposite(hd, sm), sm), sm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SMesh, Indices>(sm, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
// Parameterized bool pmap
|
||||
|
|
@ -266,7 +261,9 @@ int main(int, char**)
|
|||
SMP::ARAP_parameterizer_3<SMesh> parameterizer;
|
||||
|
||||
SMP::Error_code status = parameterizer.parameterize(sm, hd, uv_pm, vipm, vpm);
|
||||
if(status != SMP::OK) {
|
||||
SMP::Error_code status_bis = SMP::parameterize(sm, parameterizer, hd, uv_pm);
|
||||
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -274,7 +271,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with ARAP (SM)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ARAP_SURF_MESH
|
||||
|
||||
#ifdef DCM_PM_SEAM_MESH
|
||||
{
|
||||
|
|
@ -307,16 +304,14 @@ int main(int, char**)
|
|||
PM_UV_pmap uv_pm(uv_hm);
|
||||
|
||||
// a halfedge on the (possibly virtual) border
|
||||
PM_SE_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(mesh).first;
|
||||
PM_SE_halfedge_descriptor hd = PMP::longest_border(mesh).first;
|
||||
|
||||
// Indices
|
||||
typedef boost::unordered_map<PM_SE_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(hd, mesh), mesh),
|
||||
mesh,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<PM_Seam_mesh, Indices>(mesh, indices)));
|
||||
PMP::connected_component(face(opposite(hd, mesh), mesh), mesh,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<PM_Seam_mesh, Indices>(mesh, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
// Parameterized
|
||||
|
|
@ -326,8 +321,9 @@ int main(int, char**)
|
|||
SMP::Discrete_conformal_map_parameterizer_3<PM_Seam_mesh> parameterizer;
|
||||
|
||||
SMP::Error_code status = parameterizer.parameterize(mesh, hd, uv_pm, vipm, vpm);
|
||||
SMP::Error_code status_bis = SMP::parameterize(mesh, parameterizer, hd, uv_pm);
|
||||
|
||||
if(status != SMP::OK) {
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -335,7 +331,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with DCM (SEAM POLY)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // DCM_PM_SEAM_MESH
|
||||
|
||||
// ***************************************************************************
|
||||
// DAC WITH SEAM_MESH (SM)
|
||||
|
|
@ -373,16 +369,14 @@ int main(int, char**)
|
|||
Point_2>("h:uv").first;
|
||||
|
||||
// a halfedge on the (possibly virtual) border
|
||||
SM_SE_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(mesh).first;
|
||||
SM_SE_halfedge_descriptor hd = PMP::longest_border(mesh).first;
|
||||
|
||||
// Indices
|
||||
typedef boost::unordered_map<SM_SE_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
CGAL::Polygon_mesh_processing::connected_component(
|
||||
face(opposite(hd, mesh), mesh),
|
||||
mesh,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SM_Seam_mesh, Indices>(mesh, indices)));
|
||||
PMP::connected_component(face(opposite(hd, mesh), mesh), mesh,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SM_Seam_mesh, Indices>(mesh, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
// Parameterized
|
||||
|
|
@ -392,7 +386,9 @@ int main(int, char**)
|
|||
SMP::Discrete_authalic_parameterizer_3<SM_Seam_mesh> parameterizer;
|
||||
|
||||
SMP::Error_code status = parameterizer.parameterize(mesh, hd, uv_pm, vipm, vpm);
|
||||
if(status != SMP::OK) {
|
||||
SMP::Error_code status_bis = SMP::parameterize(mesh, parameterizer, hd, uv_pm);
|
||||
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -400,7 +396,7 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with DAC (SEAM SM)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // DAC_SM_SEAM_MESH
|
||||
|
||||
#ifdef ORBIFOLD_SM_MESH
|
||||
{
|
||||
|
|
@ -464,10 +460,10 @@ int main(int, char**)
|
|||
|
||||
// a halfedge on the (possibly virtual) border
|
||||
// only used in output (will also be used to handle multiple connected components in the future)
|
||||
SM_SE_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(mesh,
|
||||
CGAL::Polygon_mesh_processing::parameters::all_default()).first;
|
||||
SM_SE_halfedge_descriptor hd = PMP::longest_border(mesh, PMP::parameters::all_default()).first;
|
||||
|
||||
SMP::Error_code status = parameterizer.parameterize(mesh, hd, cmap, uvmap, vimap);
|
||||
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
|
|
@ -476,7 +472,60 @@ int main(int, char**)
|
|||
std::cout << "Parameterized with Orbifold (SEAM SM)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ORBIFOLD_SM_MESH
|
||||
|
||||
// ***************************************************************************
|
||||
// ITERATIVE AUTHALIC WITH SURFACE_MESH
|
||||
// ***************************************************************************
|
||||
|
||||
#ifdef ITERATIVE_SURF_MESH
|
||||
{
|
||||
std::cout << " ----------- ITERATIVE AUTHALIC SURFACE MESH ----------- " << std::endl;
|
||||
|
||||
std::ifstream in("data/oni.off");
|
||||
SMesh sm;
|
||||
in >> sm;
|
||||
if(!in || num_vertices(sm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SM_halfedge_descriptor hd = PMP::longest_border(sm).first;
|
||||
assert(hd != SM_halfedge_descriptor());
|
||||
|
||||
// UV map
|
||||
typedef SMesh::Property_map<SM_vertex_descriptor, Point_2> UV_pmap;
|
||||
UV_pmap uvpm = sm.add_property_map<SM_vertex_descriptor, Point_2>("h:uv").first;
|
||||
|
||||
// Indices map
|
||||
typedef boost::unordered_map<SM_vertex_descriptor, int> Indices;
|
||||
Indices indices;
|
||||
PMP::connected_component(face(opposite(hd, sm), sm), sm,
|
||||
boost::make_function_output_iterator(
|
||||
SMP::internal::Index_map_filler<SMesh, Indices>(sm, indices)));
|
||||
boost::associative_property_map<Indices> vipm(indices);
|
||||
|
||||
// Vertex parameterized map
|
||||
boost::unordered_set<SM_vertex_descriptor> vs;
|
||||
SMP::internal::Bool_property_map<boost::unordered_set<SM_vertex_descriptor> > vpm(vs);
|
||||
|
||||
// Parameterizer
|
||||
SMP::Iterative_authalic_parameterizer_3<SMesh> parameterizer;
|
||||
|
||||
double error = 0;
|
||||
unsigned int iterations = 15;
|
||||
SMP::Error_code status = parameterizer.parameterize(sm, hd, uvpm, vipm, vpm, iterations, error);
|
||||
SMP::Error_code status_bis = parameterizer.parameterize(sm, uvpm, 10);
|
||||
|
||||
if(status != SMP::OK || status_bis != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with Barycentric (SM)!" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif // DAC_SM_SEAM_MESH
|
||||
|
||||
std::cout << "Done!" << std::endl;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue