dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Mesh_3/sliver_criteria.h

240 lines
6.8 KiB
C
Raw Normal View History

// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Mesh_3/include/CGAL/Mesh_3/sliver_criteria.h $
// $Id: sliver_criteria.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Stephane Tayeb
//
//******************************************************************************
2020-10-13 12:44:25 +00:00
// File Description :
//******************************************************************************
#ifndef CGAL_MESH_3_SLIVER_CRITERIA_H
#define CGAL_MESH_3_SLIVER_CRITERIA_H
#include <CGAL/license/Mesh_3.h>
#include <CGAL/disable_warnings.h>
#include <CGAL/Mesh_3/min_dihedral_angle.h>
#include <CGAL/Mesh_3/radius_ratio.h>
#include <CGAL/FPU.h> // for CGAL::IA_force_to_double
#include <vector>
namespace CGAL {
namespace Mesh_3 {
template<typename Tr, //Triangulation
bool update_sliver_cache = true,
typename Cell_vector_ = std::vector<typename Tr::Cell_handle> >
class Sliver_criterion
{
public:
typedef typename Tr::Geom_traits Gt;
typedef typename Tr::Cell_handle Cell_handle;
typedef typename Gt::Tetrahedron_3 Tetrahedron_3;
typedef Cell_vector_ Cell_vector;
public:
virtual double get_default_value() const = 0;
virtual double get_max_value() const = 0;
//Sliver_perturber performs perturbation "unit-per-unit"
// so it needs to know how much is a unit for each criterion
virtual double get_perturbation_unit() const = 0;
// returns the value of the criterion for t
virtual double operator()(Cell_handle cell) const
{
if(update_sliver_cache)
{
if( ! cell->is_cache_valid() )
{
// cell->sliver_value() is stored in a plain 64 bits floating point
2020-10-13 12:44:25 +00:00
// number, and the value computed by operator() might be
// computed using the 80 bits floating point registers of the x87
2020-10-13 12:44:25 +00:00
// unit.
// This could cause comparisons between sliver values to be
// inconsistent when comparing caches and registers values
// (see also the comment below)
// IA_force_to_double is available in CGAL/FPU.h
2020-10-13 12:44:25 +00:00
double value
= CGAL::IA_force_to_double(operator()(tr_.tetrahedron(cell)));
cell->set_sliver_value(value);
}
return cell->sliver_value();
2020-10-13 12:44:25 +00:00
}
return operator()(tr_.tetrahedron(cell));
}
virtual double operator()(const Tetrahedron_3& t) const = 0;
virtual void before_move(const Cell_vector& cells) const = 0;
2020-10-13 12:44:25 +00:00
virtual bool valid_move(const Cell_vector& cells,
const bool soft = false) const = 0;
// Sliver bound
void set_sliver_bound(double bound) { sliver_bound_ = bound; }
double sliver_bound() const { return sliver_bound_; }
public:
Sliver_criterion(const double& bound,
const Tr& tr)
: tr_(tr)
, sliver_bound_(bound)
{}
virtual ~Sliver_criterion(){}
protected:
const Tr& tr_;
double sliver_bound_;
};
template<typename SliverCriterion, typename Cell_vector>
class Min_value;
template <typename Tr,
bool update_sliver_cache = true>
2020-10-13 12:44:25 +00:00
class Min_dihedral_angle_criterion
: public Sliver_criterion<Tr, update_sliver_cache>
{
protected:
typedef Sliver_criterion<Tr, update_sliver_cache> Base;
typedef typename Base::Tetrahedron_3 Tetrahedron_3;
typedef typename Base::Cell_vector Cell_vector;
typedef typename Base::Gt Gt;
2020-10-13 12:44:25 +00:00
public:
typedef typename Base::Cell_handle Cell_handle;
virtual double get_default_value() const { return 12.; }
virtual double get_max_value() const { return 90.; }
virtual double get_perturbation_unit() const { return 1.; }
#if ( _MSC_VER != 1800 )
using Base::operator();
#else
virtual double operator()(Cell_handle cell) const
{
return Base::operator()(cell);
}
#endif
virtual double operator()(const Tetrahedron_3& t) const
{
return CGAL::to_double(minimum_dihedral_angle(t, this->tr_.geom_traits()));
}
virtual void before_move(const Cell_vector& cells) const
{
Min_value<Min_dihedral_angle_criterion, Cell_vector> min_value_op(*this);
min_value_before_move_ = min_value_op(cells);
}
virtual bool valid_move(const Cell_vector& cells,
const bool soft = false) const
{
Min_value<Min_dihedral_angle_criterion, Cell_vector> min_value_op(*this);
double min_val = min_value_op(cells);
2020-10-13 12:44:25 +00:00
return (min_val > min_value_before_move_)
|| (soft && min_val > this->sliver_bound_);
}
public:
Min_dihedral_angle_criterion(const double& sliver_bound,
const Tr& tr)
: Base(sliver_bound, tr), min_value_before_move_(0.)
{}
2020-10-13 12:44:25 +00:00
private:
mutable double min_value_before_move_;
};
template <typename Tr,
bool update_sliver_cache = true>
2020-10-13 12:44:25 +00:00
class Radius_ratio_criterion
: public Sliver_criterion<Tr, update_sliver_cache>
{
protected:
typedef Sliver_criterion<Tr, update_sliver_cache> Base;
typedef typename Base::Gt Gt;
typedef typename Base::Tetrahedron_3 Tetrahedron_3;
typedef typename Base::Cell_vector Cell_vector;
typedef Radius_ratio_criterion<Tr, update_sliver_cache> RR_criterion;
2020-10-13 12:44:25 +00:00
public:
virtual double get_default_value() const { return 0.25; }
virtual double get_max_value() const { return 1.; }
virtual double get_perturbation_unit() const { return 0.05; }
using Base::operator();
virtual double operator()(const Tetrahedron_3& t) const
{
return CGAL::to_double(radius_ratio(t, this->tr_.geom_traits()));
}
virtual void before_move(const Cell_vector& cells) const
{
Min_value<RR_criterion, Cell_vector> min_value_op(*this);
min_value_before_move_ = min_value_op(cells);
}
virtual bool valid_move(const Cell_vector& cells,
const bool soft = false) const
{
Min_value<RR_criterion, Cell_vector> min_value_op(*this);
double min_val = min_value_op(cells);
2020-10-13 12:44:25 +00:00
return (min_val > min_value_before_move_)
|| (soft && min_val > this->sliver_bound_);
}
public:
Radius_ratio_criterion(const double& sliver_bound,
const Tr& tr)
: Base(sliver_bound, tr)
{}
2020-10-13 12:44:25 +00:00
private:
mutable double min_value_before_move_;
};
template<typename SliverCriterion, typename Cell_vector>
class Min_value
{
public:
double operator()(const Cell_vector& cells)
{
double minimum = criterion_.get_max_value();
typename Cell_vector::const_iterator it;
for(it = cells.begin(); it != cells.end(); ++it)
{
typename SliverCriterion::Cell_handle c = *it;
minimum = (std::min)(minimum, criterion_(c));
}
return minimum;
}
Min_value(const SliverCriterion& criterion)
: criterion_(criterion)
{}
private:
SliverCriterion criterion_;
};
2020-10-13 12:44:25 +00:00
} // end namespace Mesh_3
2020-10-13 12:44:25 +00:00
} // end namespace CGAL
#include <CGAL/enable_warnings.h>
#endif // CGAL_MESH_3_SLIVER_CRITERIA_H