mirror of https://github.com/CGAL/cgal
Surface_mesh_parameterization pre-conditions and post-conditions are now always checked,
in order to catch input meshes that do not respect them and avoid crashes in Release mode:
- For fixed border parameterizations:
Preconditions:
check that the border is mapped onto a convex polygon.
check that the input mesh is triangular (expensive check).
check that the input mesh is a surface with one connected component (expensive check).
Postconditions:
check one-to-one mapping.
- For free border parameterizations:
Preconditions:
check that the input mesh is triangular (expensive check).
check that the input mesh is a surface with one connected component (expensive check).
Postconditions:
check one-to-one mapping.
This commit is contained in:
parent
87462368ca
commit
fa30accac8
|
|
@ -320,12 +320,14 @@ Surface_mesh_parameterization/examples/Surface_mesh_parameterization/.cdtproject
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/.project
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/.project
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/.settings
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/.settings
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Complete_parameterization_example
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Complete_parameterization_example
|
||||||
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/Polyhedron_parameterization5.C.star
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/ProgramOutput.*
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/ProgramOutput.*
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/data/extras
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/data/extras
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/debug
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/debug
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/error.txt
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/error.txt
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/release
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/release
|
||||||
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/test
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/test
|
||||||
|
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/test[!!-~](release)
|
||||||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.kdev*
|
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.kdev*
|
||||||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.ncb
|
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.ncb
|
||||||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.suo
|
Surface_mesh_parameterization/test/Surface_mesh_parameterization/*.suo
|
||||||
|
|
|
||||||
|
|
@ -200,19 +200,17 @@ sparse linear solvers:
|
||||||
\ccRefIdfierPage{CGAL::Parameterization_mesh_feature_extractor<ParameterizationMesh_3>} \\
|
\ccRefIdfierPage{CGAL::Parameterization_mesh_feature_extractor<ParameterizationMesh_3>} \\
|
||||||
|
|
||||||
|
|
||||||
\ccHeading{Assertions}
|
\ccHeading{Checks and Assertions}
|
||||||
|
|
||||||
The assertion flags for the package
|
The package performs the next checks:
|
||||||
use \ccc{SURFACE_MESH_PARAMETERIZATION} in their names (\textit{e.g.},
|
|
||||||
\ccc{CGAL_SURFACE_MESH_PARAMETERIZATION_NO_ASSERTIONS}).
|
|
||||||
|
|
||||||
For \emph{fixed} border parameterizations:
|
For \emph{fixed} border parameterizations:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Preconditions:
|
\item Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item check that the border is mapped onto a convex polygon.
|
\item check that the border is mapped onto a convex polygon.
|
||||||
\item check that the input mesh is triangular (expensive check).
|
\item check that the input mesh is triangular.
|
||||||
\item check that the input mesh is a surface with one connected component (expensive check).
|
\item check that the input mesh is a surface with one connected component.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Postconditions:
|
\item Postconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
|
@ -224,8 +222,8 @@ For \emph{free} border parameterizations:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Preconditions:
|
\item Preconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item check that the input mesh is triangular (expensive check).
|
\item check that the input mesh is triangular.
|
||||||
\item check that the input mesh is a surface with one connected component (expensive check).
|
\item check that the input mesh is a surface with one connected component.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Postconditions:
|
\item Postconditions:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
|
@ -233,7 +231,9 @@ For \emph{free} border parameterizations:
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
Expensive checking is off by default. It can be enabled by
|
Assertions are optional checks. The assertion flags for the package
|
||||||
defining \ccc{CGAL_SURFACE_MESH_PARAMETERIZATION_CHECK_EXPENSIVE}.
|
use \ccc{SURFACE_MESH_PARAMETERIZATION} in their names (\textit{e.g.},
|
||||||
|
\ccc{CGAL_SURFACE_MESH_PARAMETERIZATION_NO_ASSERTIONS}).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ public:
|
||||||
if (cir->opposite()->vertex() == source)
|
if (cir->opposite()->vertex() == source)
|
||||||
return cir;
|
return cir;
|
||||||
|
|
||||||
|
// we should not get here
|
||||||
CGAL_error();
|
CGAL_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,6 @@ parameterize(Adaptor& mesh)
|
||||||
timer.reset();
|
timer.reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Check postconditions
|
// Check postconditions
|
||||||
status = check_parameterize_postconditions(mesh, A, Bu, Bv);
|
status = check_parameterize_postconditions(mesh, A, Bu, Bv);
|
||||||
#ifdef DEBUG_TRACE
|
#ifdef DEBUG_TRACE
|
||||||
|
|
@ -389,40 +388,34 @@ check_parameterize_preconditions(Adaptor& mesh)
|
||||||
Mesh_feature_extractor;
|
Mesh_feature_extractor;
|
||||||
Mesh_feature_extractor feature_extractor(mesh);
|
Mesh_feature_extractor feature_extractor(mesh);
|
||||||
|
|
||||||
// Allways check that mesh is not empty
|
// Check that mesh is not empty
|
||||||
if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
|
if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
|
||||||
status = Base::ERROR_EMPTY_MESH;
|
status = Base::ERROR_EMPTY_MESH;
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// The whole surface parameterization package is restricted to triangular meshes
|
// The whole surface parameterization package is restricted to triangular meshes
|
||||||
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
|
status = mesh.is_mesh_triangular() ? Base::OK
|
||||||
status = mesh.is_mesh_triangular() ? Base::OK \
|
: Base::ERROR_NON_TRIANGULAR_MESH;
|
||||||
: Base::ERROR_NON_TRIANGULAR_MESH; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// The whole package is restricted to surfaces: genus = 0,
|
// The whole package is restricted to surfaces: genus = 0,
|
||||||
// one connected component and at least one border
|
// one connected component and at least one border
|
||||||
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
|
int genus = feature_extractor.get_genus();
|
||||||
int genus = feature_extractor.get_genus(); \
|
int nb_borders = feature_extractor.get_nb_borders();
|
||||||
int nb_borders = feature_extractor.get_nb_borders(); \
|
int nb_components = feature_extractor.get_nb_connex_components();
|
||||||
int nb_components = feature_extractor.get_nb_connex_components(); \
|
status = (genus == 0 && nb_borders >= 1 && nb_components == 1)
|
||||||
status = (genus == 0 && nb_borders >= 1 && nb_components == 1) \
|
? Base::OK
|
||||||
? Base::OK \
|
: Base::ERROR_NO_SURFACE_MESH;
|
||||||
: Base::ERROR_NO_SURFACE_MESH; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// One-to-one mapping is guaranteed if all w_ij coefficients are > 0 (for j vertex neighbor of i)
|
// 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
|
// and if the surface border is mapped onto a 2D convex polygon
|
||||||
CGAL_surface_mesh_parameterization_precondition_code( \
|
status = get_border_parameterizer().is_border_convex()
|
||||||
status = get_border_parameterizer().is_border_convex() \
|
? Base::OK
|
||||||
? Base::OK \
|
: Base::ERROR_INVALID_BORDER;
|
||||||
: Base::ERROR_INVALID_BORDER; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -551,11 +544,9 @@ check_parameterize_postconditions(const Adaptor& mesh,
|
||||||
Error_code status = Base::OK;
|
Error_code status = Base::OK;
|
||||||
|
|
||||||
// Check if 3D -> 2D mapping is one-to-one
|
// Check if 3D -> 2D mapping is one-to-one
|
||||||
CGAL_surface_mesh_parameterization_postcondition_code( \
|
status = is_one_to_one_mapping(mesh, A, Bu, Bv)
|
||||||
status = is_one_to_one_mapping(mesh, A, Bu, Bv) \
|
? Base::OK
|
||||||
? Base::OK \
|
: Base::ERROR_NO_1_TO_1_MAPPING;
|
||||||
: Base::ERROR_NO_1_TO_1_MAPPING; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,30 +355,26 @@ check_parameterize_preconditions(Adaptor& mesh)
|
||||||
Mesh_feature_extractor;
|
Mesh_feature_extractor;
|
||||||
Mesh_feature_extractor feature_extractor(mesh);
|
Mesh_feature_extractor feature_extractor(mesh);
|
||||||
|
|
||||||
// Allways check that mesh is not empty
|
// Check that mesh is not empty
|
||||||
if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
|
if (mesh.mesh_vertices_begin() == mesh.mesh_vertices_end())
|
||||||
status = Base::ERROR_EMPTY_MESH;
|
status = Base::ERROR_EMPTY_MESH;
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// The whole surface parameterization package is restricted to triangular meshes
|
// The whole surface parameterization package is restricted to triangular meshes
|
||||||
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
|
status = mesh.is_mesh_triangular() ? Base::OK
|
||||||
status = mesh.is_mesh_triangular() ? Base::OK \
|
: Base::ERROR_NON_TRIANGULAR_MESH;
|
||||||
: Base::ERROR_NON_TRIANGULAR_MESH; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// The whole package is restricted to surfaces: genus = 0,
|
// The whole package is restricted to surfaces: genus = 0,
|
||||||
// one connected component and at least one border
|
// one connected component and at least one border
|
||||||
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
|
int genus = feature_extractor.get_genus();
|
||||||
int genus = feature_extractor.get_genus(); \
|
int nb_borders = feature_extractor.get_nb_borders();
|
||||||
int nb_borders = feature_extractor.get_nb_borders(); \
|
int nb_components = feature_extractor.get_nb_connex_components();
|
||||||
int nb_components = feature_extractor.get_nb_connex_components(); \
|
status = (genus == 0 && nb_borders >= 1 && nb_components == 1)
|
||||||
status = (genus == 0 && nb_borders >= 1 && nb_components == 1) \
|
? Base::OK
|
||||||
? Base::OK \
|
: Base::ERROR_NO_SURFACE_MESH;
|
||||||
: Base::ERROR_NO_SURFACE_MESH; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -595,11 +591,9 @@ check_parameterize_postconditions(const Adaptor& mesh,
|
||||||
Error_code status = Base::OK;
|
Error_code status = Base::OK;
|
||||||
|
|
||||||
// Check if 3D -> 2D mapping is one-to-one
|
// Check if 3D -> 2D mapping is one-to-one
|
||||||
CGAL_surface_mesh_parameterization_postcondition_code( \
|
status = is_one_to_one_mapping(mesh, solver)
|
||||||
status = is_one_to_one_mapping(mesh, solver) \
|
? Base::OK
|
||||||
? Base::OK \
|
: Base::ERROR_NO_1_TO_1_MAPPING;
|
||||||
: Base::ERROR_NO_1_TO_1_MAPPING; \
|
|
||||||
);
|
|
||||||
if (status != Base::OK)
|
if (status != Base::OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,10 +184,7 @@ public:
|
||||||
set_mesh_seaming(first_seam_vertex, end_seam_vertex);
|
set_mesh_seaming(first_seam_vertex, end_seam_vertex);
|
||||||
|
|
||||||
// Check that the cut mesh is 2-manifold
|
// Check that the cut mesh is 2-manifold
|
||||||
m_is_valid = true;
|
m_is_valid = mesh.is_valid() && check_seam(first_seam_vertex, end_seam_vertex);
|
||||||
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
|
|
||||||
m_is_valid = mesh.is_valid() && check_seam(first_seam_vertex, end_seam_vertex); \
|
|
||||||
);
|
|
||||||
|
|
||||||
// Construct the list of all exported vertices, i.e. INNER and BORDER vertices
|
// Construct the list of all exported vertices, i.e. INNER and BORDER vertices
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -354,6 +354,7 @@ public:
|
||||||
if (cir->opposite()->vertex() == source)
|
if (cir->opposite()->vertex() == source)
|
||||||
return cir;
|
return cir;
|
||||||
|
|
||||||
|
// we should not get here
|
||||||
CGAL_error();
|
CGAL_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ public:
|
||||||
if (cir->opposite()->vertex() == source)
|
if (cir->opposite()->vertex() == source)
|
||||||
return cir;
|
return cir;
|
||||||
|
|
||||||
|
// we should not get here
|
||||||
CGAL_error();
|
CGAL_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue