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:
Laurent Saboret 2008-08-19 15:50:40 +00:00
parent 87462368ca
commit fa30accac8
8 changed files with 43 additions and 56 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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}).

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;

View File

@ -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
// //

View File

@ -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;
} }

View File

@ -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;
} }