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/.settings
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/data/extras
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/debug
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/error.txt
Surface_mesh_parameterization/examples/Surface_mesh_parameterization/release
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/*.ncb
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>} \\
\ccHeading{Assertions}
\ccHeading{Checks and Assertions}
The assertion flags for the package
use \ccc{SURFACE_MESH_PARAMETERIZATION} in their names (\textit{e.g.},
\ccc{CGAL_SURFACE_MESH_PARAMETERIZATION_NO_ASSERTIONS}).
The package performs the next checks:
For \emph{fixed} border parameterizations:
\begin{itemize}
\item Preconditions:
\begin{itemize}
\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 a surface with one connected component (expensive check).
\item check that the input mesh is triangular.
\item check that the input mesh is a surface with one connected component.
\end{itemize}
\item Postconditions:
\begin{itemize}
@ -224,8 +222,8 @@ For \emph{free} border parameterizations:
\begin{itemize}
\item Preconditions:
\begin{itemize}
\item check that the input mesh is triangular (expensive check).
\item check that the input mesh is a surface with one connected component (expensive check).
\item check that the input mesh is triangular.
\item check that the input mesh is a surface with one connected component.
\end{itemize}
\item Postconditions:
\begin{itemize}
@ -233,7 +231,9 @@ For \emph{free} border parameterizations:
\end{itemize}
\end{itemize}
Expensive checking is off by default. It can be enabled by
defining \ccc{CGAL_SURFACE_MESH_PARAMETERIZATION_CHECK_EXPENSIVE}.
Assertions are optional checks. The assertion flags for the package
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)
return cir;
// we should not get here
CGAL_error();
return NULL;
}

View File

@ -359,7 +359,6 @@ parameterize(Adaptor& mesh)
timer.reset();
#endif
// Check postconditions
status = check_parameterize_postconditions(mesh, A, Bu, Bv);
#ifdef DEBUG_TRACE
@ -389,40 +388,34 @@ check_parameterize_preconditions(Adaptor& mesh)
Mesh_feature_extractor;
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())
status = Base::ERROR_EMPTY_MESH;
if (status != Base::OK)
return status;
// The whole surface parameterization package is restricted to triangular meshes
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
status = mesh.is_mesh_triangular() ? Base::OK \
: Base::ERROR_NON_TRIANGULAR_MESH; \
);
status = mesh.is_mesh_triangular() ? Base::OK
: Base::ERROR_NON_TRIANGULAR_MESH;
if (status != Base::OK)
return status;
// The whole package is restricted to surfaces: genus = 0,
// one connected component and at least one border
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
int genus = feature_extractor.get_genus(); \
int nb_borders = feature_extractor.get_nb_borders(); \
int nb_components = feature_extractor.get_nb_connex_components(); \
status = (genus == 0 && nb_borders >= 1 && nb_components == 1) \
? Base::OK \
: Base::ERROR_NO_SURFACE_MESH; \
);
int genus = feature_extractor.get_genus();
int nb_borders = feature_extractor.get_nb_borders();
int nb_components = feature_extractor.get_nb_connex_components();
status = (genus == 0 && nb_borders >= 1 && nb_components == 1)
? Base::OK
: Base::ERROR_NO_SURFACE_MESH;
if (status != Base::OK)
return status;
// 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
CGAL_surface_mesh_parameterization_precondition_code( \
status = get_border_parameterizer().is_border_convex() \
? Base::OK \
: Base::ERROR_INVALID_BORDER; \
);
status = get_border_parameterizer().is_border_convex()
? Base::OK
: Base::ERROR_INVALID_BORDER;
if (status != Base::OK)
return status;
@ -551,11 +544,9 @@ check_parameterize_postconditions(const Adaptor& mesh,
Error_code status = Base::OK;
// 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) \
? Base::OK \
: Base::ERROR_NO_1_TO_1_MAPPING; \
);
status = is_one_to_one_mapping(mesh, A, Bu, Bv)
? Base::OK
: Base::ERROR_NO_1_TO_1_MAPPING;
if (status != Base::OK)
return status;

View File

@ -355,30 +355,26 @@ check_parameterize_preconditions(Adaptor& mesh)
Mesh_feature_extractor;
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())
status = Base::ERROR_EMPTY_MESH;
if (status != Base::OK)
return status;
// The whole surface parameterization package is restricted to triangular meshes
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
status = mesh.is_mesh_triangular() ? Base::OK \
: Base::ERROR_NON_TRIANGULAR_MESH; \
);
status = mesh.is_mesh_triangular() ? Base::OK
: Base::ERROR_NON_TRIANGULAR_MESH;
if (status != Base::OK)
return status;
// The whole package is restricted to surfaces: genus = 0,
// one connected component and at least one border
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
int genus = feature_extractor.get_genus(); \
int nb_borders = feature_extractor.get_nb_borders(); \
int nb_components = feature_extractor.get_nb_connex_components(); \
status = (genus == 0 && nb_borders >= 1 && nb_components == 1) \
? Base::OK \
: Base::ERROR_NO_SURFACE_MESH; \
);
int genus = feature_extractor.get_genus();
int nb_borders = feature_extractor.get_nb_borders();
int nb_components = feature_extractor.get_nb_connex_components();
status = (genus == 0 && nb_borders >= 1 && nb_components == 1)
? Base::OK
: Base::ERROR_NO_SURFACE_MESH;
if (status != Base::OK)
return status;
@ -595,11 +591,9 @@ check_parameterize_postconditions(const Adaptor& mesh,
Error_code status = Base::OK;
// Check if 3D -> 2D mapping is one-to-one
CGAL_surface_mesh_parameterization_postcondition_code( \
status = is_one_to_one_mapping(mesh, solver) \
? Base::OK \
: Base::ERROR_NO_1_TO_1_MAPPING; \
);
status = is_one_to_one_mapping(mesh, solver)
? Base::OK
: Base::ERROR_NO_1_TO_1_MAPPING;
if (status != Base::OK)
return status;

View File

@ -184,10 +184,7 @@ public:
set_mesh_seaming(first_seam_vertex, end_seam_vertex);
// Check that the cut mesh is 2-manifold
m_is_valid = true;
CGAL_surface_mesh_parameterization_expensive_precondition_code( \
m_is_valid = mesh.is_valid() && check_seam(first_seam_vertex, end_seam_vertex); \
);
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
//

View File

@ -354,6 +354,7 @@ public:
if (cir->opposite()->vertex() == source)
return cir;
// we should not get here
CGAL_error();
return NULL;
}

View File

@ -194,6 +194,7 @@ public:
if (cir->opposite()->vertex() == source)
return cir;
// we should not get here
CGAL_error();
return NULL;
}