Merge pull request #5033 from janetournois/Heat_method-degenerate_faces-GF

Heat_method_3 - avoid degenerate faces
This commit is contained in:
Laurent Rineau 2020-11-13 15:31:59 +01:00
commit 429f1ea8e7
1 changed files with 43 additions and 1 deletions

View File

@ -35,6 +35,7 @@
#include <set> #include <set>
namespace CGAL { namespace CGAL {
namespace Heat_method_3 { namespace Heat_method_3 {
/** /**
@ -49,6 +50,12 @@ struct Direct
struct Intrinsic_Delaunay struct Intrinsic_Delaunay
{}; {};
namespace internal {
template<typename TriangleMesh, typename Traits>
bool has_degenerate_faces(const TriangleMesh& tm, const Traits& traits);
}
namespace internal { namespace internal {
template <typename TriangleMesh, template <typename TriangleMesh,
typename Traits, typename Traits,
@ -478,6 +485,9 @@ public:
template<class VertexDistanceMap> template<class VertexDistanceMap>
void estimate_geodesic_distances(VertexDistanceMap vdm) void estimate_geodesic_distances(VertexDistanceMap vdm)
{ {
CGAL_precondition(
!CGAL::Heat_method_3::internal::has_degenerate_faces(triangle_mesh(), Traits()));
if(is_empty(tm)){ if(is_empty(tm)){
return; return;
} }
@ -676,6 +686,32 @@ struct Idt_storage
{} {}
}; };
template<typename TriangleMesh, typename Traits>
bool has_degenerate_faces(const TriangleMesh& tm, const Traits& traits)
{
typedef typename Traits::Point_3 Point;
typedef typename Traits::Vector_3 Vector_3;
typename Traits::Construct_vector_3
construct_vector = traits.construct_vector_3_object();
typename Traits::Compute_scalar_product_3
scalar_product = traits.compute_scalar_product_3_object();
typename Traits::Construct_cross_product_vector_3
cross_product = traits.construct_cross_product_vector_3_object();
typename boost::property_map< TriangleMesh, boost::vertex_point_t>::const_type
vpm = get(boost::vertex_point, tm);
for (typename boost::graph_traits<TriangleMesh>::face_descriptor f : faces(tm))
{
const Point p1 = get(vpm, target(halfedge(f, tm), tm));
const Point p2 = get(vpm, target(next(halfedge(f, tm), tm), tm));
const Point p3 = get(vpm, target(next(next(halfedge(f, tm), tm), tm), tm));
Vector_3 v = cross_product(construct_vector(p1, p2), construct_vector(p1, p3));
if(scalar_product(v, v) == 0.)
return true;
}
return false;
}
template <typename TriangleMesh, template <typename TriangleMesh,
typename Traits, typename Traits,
typename LA, typename LA,
@ -715,6 +751,9 @@ struct Base_helper<TriangleMesh, Traits, Intrinsic_Delaunay, LA, VertexPointMap>
template <class VertexDistanceMap> template <class VertexDistanceMap>
void estimate_geodesic_distances(VertexDistanceMap vdm) void estimate_geodesic_distances(VertexDistanceMap vdm)
{ {
CGAL_precondition(
!CGAL::Heat_method_3::internal::has_degenerate_faces(
this->m_idt.triangle_mesh(), Traits()));
base().estimate_geodesic_distances(this->m_idt.vertex_distance_map(vdm)); base().estimate_geodesic_distances(this->m_idt.vertex_distance_map(vdm));
} }
}; };
@ -730,6 +769,7 @@ struct Base_helper<TriangleMesh, Traits, Intrinsic_Delaunay, LA, VertexPointMap>
* time after changes to the set of sources. * time after changes to the set of sources.
* *
* \tparam TriangleMesh a triangulated surface mesh, model of `FaceListGraph` and `HalfedgeListGraph` * \tparam TriangleMesh a triangulated surface mesh, model of `FaceListGraph` and `HalfedgeListGraph`
* with no degenerate faces
* \tparam Mode must be `Intrinsic_Delaunay` to indicate that an intrinsic Delaunay triangulation is internally constructed * \tparam Mode must be `Intrinsic_Delaunay` to indicate that an intrinsic Delaunay triangulation is internally constructed
* or `Direct` to indicate that the input mesh should be used as is. * or `Direct` to indicate that the input mesh should be used as is.
* If `Intrinsic_Delaunay`, then the type `TriangleMesh` must have an internal property for `vertex_point` * If `Intrinsic_Delaunay`, then the type `TriangleMesh` must have an internal property for `vertex_point`
@ -743,7 +783,6 @@ struct Base_helper<TriangleMesh, Traits, Intrinsic_Delaunay, LA, VertexPointMap>
* is used as default * is used as default
* \tparam Traits a model of `HeatMethodTraits_3`. The default is the Kernel of the value type * \tparam Traits a model of `HeatMethodTraits_3`. The default is the Kernel of the value type
* of the vertex point map (extracted using `Kernel_traits`). * of the vertex point map (extracted using `Kernel_traits`).
*
*/ */
template <typename TriangleMesh, template <typename TriangleMesh,
typename Mode = Direct, typename Mode = Direct,
@ -901,6 +940,7 @@ public:
* \tparam VertexDistanceMap a property map model of `WritablePropertyMap` * \tparam VertexDistanceMap a property map model of `WritablePropertyMap`
* with `vertex_descriptor` as key type and `double` as value type. * with `vertex_descriptor` as key type and `double` as value type.
* \param vdm the vertex distance map to be filled * \param vdm the vertex distance map to be filled
* \pre the support triangle mesh does not have any degenerate faces
* \warning The key type is `double` even when used with an exact kernel. * \warning The key type is `double` even when used with an exact kernel.
**/ **/
template <class VertexDistanceMap> template <class VertexDistanceMap>
@ -921,6 +961,7 @@ public:
/// \tparam Mode either the tag `Direct` or `Intrinsic_Delaunay`, which determines if the geodesic distance /// \tparam Mode either the tag `Direct` or `Intrinsic_Delaunay`, which determines if the geodesic distance
/// is computed directly on the mesh or if the intrinsic Delaunay triangulation is applied first. /// is computed directly on the mesh or if the intrinsic Delaunay triangulation is applied first.
/// The default is `Intrinsic_Delaunay`. /// The default is `Intrinsic_Delaunay`.
/// \pre `tm` does not have any degenerate faces
/// \warning The return type is `double` even when used with an exact kernel. /// \warning The return type is `double` even when used with an exact kernel.
/// ///
/// \sa `CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3` /// \sa `CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3`
@ -962,6 +1003,7 @@ estimate_geodesic_distances(const TriangleMesh& tm,
/// \tparam Mode either the tag `Direct` or `Intrinsic_Delaunay`, which determines if the geodesic distance /// \tparam Mode either the tag `Direct` or `Intrinsic_Delaunay`, which determines if the geodesic distance
/// is computed directly on the mesh or if the intrinsic Delaunay triangulation is applied first. /// is computed directly on the mesh or if the intrinsic Delaunay triangulation is applied first.
/// The default is `Intrinsic_Delaunay`. /// The default is `Intrinsic_Delaunay`.
/// \pre `tm` does not have any degenerate faces
/// \warning The return type is `double` even when used with an exact kernel. /// \warning The return type is `double` even when used with an exact kernel.
/// \sa `CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3` /// \sa `CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3`
template <typename TriangleMesh, typename VertexDistanceMap, typename VertexConstRange, typename Mode> template <typename TriangleMesh, typename VertexDistanceMap, typename VertexConstRange, typename Mode>