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/.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
|
||||
|
|
|
|||
|
|
@ -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}).
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ public:
|
|||
if (cir->opposite()->vertex() == source)
|
||||
return cir;
|
||||
|
||||
// we should not get here
|
||||
CGAL_error();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//
|
||||
|
|
|
|||
|
|
@ -354,6 +354,7 @@ public:
|
|||
if (cir->opposite()->vertex() == source)
|
||||
return cir;
|
||||
|
||||
// we should not get here
|
||||
CGAL_error();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ public:
|
|||
if (cir->opposite()->vertex() == source)
|
||||
return cir;
|
||||
|
||||
// we should not get here
|
||||
CGAL_error();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue