add an operator()(Cell_handle) to Sliver_criterion

this implies changing the template parameters of Sliver_criterion,
which now needs to know the Triangulation type
This commit is contained in:
Jane Tournois 2013-10-18 12:38:21 +02:00
parent ec2b35e398
commit ca249eb5f9
5 changed files with 114 additions and 120 deletions

View File

@ -720,14 +720,12 @@ private:
if ( ! c->is_cache_valid() )
{
Sliver_criterion_value<SliverCriterion>
sc_value(c3t3_.triangulation(), criterion_);
Sliver_criterion_value<SliverCriterion> sc_value(criterion_);
FT sliver_value = sc_value(c);//updates the cache
}
else
{
CGAL_expensive_assertion(c->sliver_value() ==
criterion_(p_tr_->tetrahedron(c)));
CGAL_expensive_assertion(c->sliver_value() == criterion_(c));
}
if(bound_ > 0)
return ( c->sliver_value() <= bound_ );
@ -937,10 +935,8 @@ private:
: public std::unary_function<Cell_handle, double>
{
public:
Sliver_criterion_value(const Tr& tr,
const SliverCriterion& criterion)
: p_tr_(&tr)
, criterion_(criterion) {}
Sliver_criterion_value(const SliverCriterion& criterion)
: criterion_(criterion) {}
FT operator()(const Cell_handle& ch) const
{
@ -948,20 +944,17 @@ private:
if ( ! ch->is_cache_valid() )
{
double sliver_value = criterion_(p_tr_->tetrahedron(ch));
double sliver_value = criterion_(ch);
ch->set_sliver_value(sliver_value);
}
else
{
CGAL_expensive_assertion(ch->sliver_value() ==
criterion_(p_tr_->tetrahedron(ch)));
CGAL_expensive_assertion(ch->sliver_value() == criterion_(ch));
}
return ch->sliver_value();
}
private:
// '=' is used, so p_tr_ must be a pointer ...
const Tr* p_tr_;
SliverCriterion criterion_;
};
@ -978,15 +971,20 @@ private:
const bool use_cache = true) const
{
// Get complex cells only
Cell_vector c3t3_cells_ = c3t3_cells(cells);
return min_sliver_value(c3t3_cells_, criterion, use_cache);
}
Cell_vector c3t3_cells(const Cell_vector& cells) const
{
Cell_vector c3t3_cells;
std::remove_copy_if(cells.begin(),
cells.end(),
std::back_inserter(c3t3_cells),
std::not1(Is_in_c3t3<Cell_handle>(c3t3_)) );
return min_sliver_value(c3t3_cells,criterion,use_cache);
return c3t3_cells;
}
/**
* Removes objects of [begin,end[ range from \c c3t3_
*/
@ -1147,12 +1145,6 @@ private:
* which has not his dimension < 3
*/
bool check_no_inside_vertices(const Facet_vector& facets) const;
/**
* converts a Cell_handle vector into the corresponding
* tetrahedra vector
*/
Tet_vector c3t3_tetrahedra(const Cell_vector& cells) const;
/**
* Returns the impacted cells when moving \c vertex to \c conflict_point
@ -1606,7 +1598,7 @@ update_mesh_no_topo_change(const Point_3& new_position,
// << ")\n";
// Get old values
criterion.before_move(c3t3_tetrahedra(conflict_cells));
criterion.before_move(c3t3_cells(conflict_cells));
// std::cerr << "old_sliver_value=" << old_sliver_value << std::endl;
Point_3 old_position = vertex->point();
@ -1616,7 +1608,7 @@ update_mesh_no_topo_change(const Point_3& new_position,
// Get new criterion value (conflict_zone did not change)
// Check that mesh is still valid
if ( criterion.valid_move(c3t3_tetrahedra(conflict_cells))
if ( criterion.valid_move(c3t3_cells(conflict_cells))
&& verify_surface(conflict_cells) )
{
fill_modified_vertices(conflict_cells.begin(), conflict_cells.end(),
@ -1668,7 +1660,7 @@ update_mesh_topo_change(const Point_3& new_position,
removal_conflict_cells.begin(), removal_conflict_cells.end(),
std::back_inserter(conflict_cells));
criterion.before_move(c3t3_tetrahedra(conflict_cells));
criterion.before_move(c3t3_cells(conflict_cells));
// std::cerr << "old_sliver_value=" << old_sliver_value << std::endl;
Point_3 old_position = old_vertex->point();
@ -1705,7 +1697,7 @@ update_mesh_topo_change(const Point_3& new_position,
// Check that surface boundary does not change.
// This check ensures that vertices which are inside c3t3 stay inside.
if (criterion.valid_move(c3t3_tetrahedra(outdated_cells))
if (criterion.valid_move(c3t3_cells(outdated_cells))
&& check_surface_mesh(new_vertex,
get_facets(outdated_cells),
old_surface_boundary,
@ -2504,9 +2496,7 @@ min_sliver_value(const Cell_vector& cells,
it != cells.end();
++it)
{
boost::optional<double> sliver_value
= criterion(c3t3_.triangulation().tetrahedron(*it));
min_value = (std::min)(sliver_value.get(), min_value);
min_value = (std::min)(criterion(*it), min_value);
}
return min_value;
}
@ -2716,24 +2706,6 @@ check_no_inside_vertices(const Facet_vector& facets) const
return true;
}
template <typename C3T3, typename MD>
typename C3T3_helpers<C3T3,MD>::Tet_vector
C3T3_helpers<C3T3,MD>::
c3t3_tetrahedra(const Cell_vector& cells) const
{
Cell_vector c3t3_cells;
std::remove_copy_if(cells.begin(),
cells.end(),
std::back_inserter(c3t3_cells),
std::not1(Is_in_c3t3<Cell_handle>(c3t3_)));
Tet_vector tets(c3t3_cells.size());
for(std::size_t i = 0; i < c3t3_cells.size(); ++i)
tets[i] = c3t3_.triangulation().tetrahedron(c3t3_cells[i]);
return tets;
}
} // end namespace Mesh_3
} // end namespace CGAL

View File

@ -307,11 +307,11 @@ private:
cit != c3t3_.cells_in_complex_end() ;
++cit)
{
const boost::optional<double> value
= sliver_criteria_(tr_.tetrahedron(cit));
const double value
= sliver_criteria_(cit);
if( value < sliver_criteria_.sliver_bound() )
cells_queue_.insert(cit, value.get());
cells_queue_.insert(cit, value);
}
}
@ -452,8 +452,8 @@ private:
cit != c3t3_.cells_in_complex_end() ;
++cit)
{
const boost::optional<double> value =
sliver_criteria_(tr_.tetrahedron(cit));
const double value =
sliver_criteria_(cit);
if( value < sliver_criteria_.sliver_bound() )
return false;
@ -694,8 +694,7 @@ initialize_prestar_and_criterion_values(const Vertex_handle& v,
// Sliver criterion values initialization
if( c3t3_.is_in_complex(*cit) )
{
boost::optional<double> r = sliver_criteria_(tr_.tetrahedron(*cit));
criterion_values[f] = r.get();
criterion_values[f] = sliver_criteria_(*cit);
}
@ -798,8 +797,8 @@ expand_prestar(const Cell_handle& cell_to_add,
cell_to_add->vertex((i+2)&3)->point(),
cell_to_add->vertex((i+3)&3)->point());
boost::optional<double> new_value = sliver_criteria_(tet);
criterion_values.insert(std::make_pair(current_facet,new_value.get()));
double new_value = sliver_criteria_(tet);
criterion_values.insert(std::make_pair(current_facet,new_value));
}
}
}
@ -948,11 +947,11 @@ restore_cells_and_boundary_facets(
// the maximum, push it in the cells queue.
if( c3t3_.is_in_complex(*cit) )
{
boost::optional<double> criterion_value
= sliver_criteria_(tr_.tetrahedron(*cit));
double criterion_value
= sliver_criteria_(*cit);
if( criterion_value < sliver_criteria_.sliver_bound() )
cells_queue_.insert(*cit, criterion_value.get());
cells_queue_.insert(*cit, criterion_value);
}
}
}

View File

@ -38,11 +38,11 @@ const double exude_sliver_bound = 0.;
const double perturb_sliver_bound = 0.;
template<typename C3T3>
CGAL::Mesh_3::Min_dihedral_angle_criterion
<typename C3T3::Triangulation::Geom_traits>
default_sliver_criterion(const C3T3&, const double& bound)
<typename C3T3::Triangulation>
default_sliver_criterion(const C3T3& c3t3, const double& bound)
{
typedef typename C3T3::Triangulation::Geom_traits Gt;
return CGAL::Mesh_3::Min_dihedral_angle_criterion<Gt>(bound);
typedef typename C3T3::Triangulation Tr;
return CGAL::Mesh_3::Min_dihedral_angle_criterion<Tr>(bound, c3t3.triangulation());
}
// global optimizers

View File

@ -33,13 +33,15 @@ namespace CGAL {
namespace Mesh_3 {
template<typename K,
typename Tet_vector = std::vector<typename K::Tetrahedron_3> >
template<typename Tr, //Triangulation
typename Cell_vector = std::vector<typename Tr::Cell_handle> >
class Sliver_criterion
{
typedef typename K::Tetrahedron_3 Tetrahedron_3;
public:
typedef Tet_vector TetVector;
typedef typename Tr::Geom_traits K;
typedef typename Tr::Cell_handle Cell_handle;
typedef typename K::Tetrahedron_3 Tetrahedron_3;
typedef Cell_vector Cell_vector;
public:
virtual const double get_max_value() const = 0;
@ -48,27 +50,42 @@ public:
virtual const double get_perturbation_unit() const = 0;
// returns the value of the criterion for t
virtual double operator()(Cell_handle cell) const
{
return operator()(tr_.tetrahedron(cell));
}
virtual double operator()(const Tetrahedron_3& t) const = 0;
virtual void before_move(const TetVector& t) const = 0;
virtual bool valid_move(const TetVector& t,
virtual void before_move(const Cell_vector& cells) const = 0;
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)
: sliver_bound_(bound),
tr_(tr)
{}
protected:
const Tr& tr_;
double sliver_bound_;
};
template <typename K>
class Min_dihedral_angle_criterion : public Sliver_criterion<K>
template <typename Tr>
class Min_dihedral_angle_criterion : public Sliver_criterion<Tr>
{
typedef typename K::Tetrahedron_3 Tetrahedron_3;
typedef Min_dihedral_angle_criterion<K> Dihedral_angle_criterion;
typedef typename Sliver_criterion<K>::TetVector TetVector;
protected:
typedef Sliver_criterion<Tr> Base;
typedef typename Base::Tetrahedron_3 Tetrahedron_3;
typedef typename Base::Cell_vector Cell_vector;
typedef Min_dihedral_angle_criterion<Tr> Dihedral_angle_criterion;
public:
static double default_value;
static double max_value;
@ -77,45 +94,50 @@ public:
virtual const double get_max_value() const { return 90.; }
virtual const double get_perturbation_unit() const { return 1.; }
using Base::operator();
virtual double operator()(const Tetrahedron_3& t) const
{
return CGAL::to_double(minimum_dihedral_angle(t, K()));
}
virtual void before_move(const TetVector& tetrahedra) const
virtual void before_move(const Cell_vector& cells) const
{
Min_value<Dihedral_angle_criterion, TetVector> min_value_op(*this);
min_value_before_move_ = min_value_op(tetrahedra);
Min_value<Dihedral_angle_criterion, Cell_vector> min_value_op(*this);
min_value_before_move_ = min_value_op(cells);
}
virtual bool valid_move(const TetVector& tetrahedra,
virtual bool valid_move(const Cell_vector& cells,
const bool soft = false) const
{
Min_value<Dihedral_angle_criterion, TetVector> min_value_op(*this);
double min_val = min_value_op(tetrahedra);
Min_value<Dihedral_angle_criterion, Cell_vector> min_value_op(*this);
double min_val = min_value_op(cells);
return (min_val > min_value_before_move_)
|| (soft && min_val > sliver_bound_);
}
public:
Dihedral_angle_criterion(const double& sliver_bound)
{
set_sliver_bound(sliver_bound);
}
Dihedral_angle_criterion(const double& sliver_bound,
const Tr& tr)
: Base(sliver_bound, tr)
{}
private:
mutable double min_value_before_move_;
};
template<typename K> double Min_dihedral_angle_criterion<K>::default_value = 12.;
template<typename K> double Min_dihedral_angle_criterion<K>::max_value = 90.;
template<typename K> double Min_dihedral_angle_criterion<K>::min_value = 0.;
template<typename Tr> double Min_dihedral_angle_criterion<Tr>::default_value = 12.;
template<typename Tr> double Min_dihedral_angle_criterion<Tr>::max_value = 90.;
template<typename Tr> double Min_dihedral_angle_criterion<Tr>::min_value = 0.;
template <typename K>
class Radius_ratio_criterion : public Sliver_criterion<K>
template <typename Tr>
class Radius_ratio_criterion : public Sliver_criterion<Tr>
{
typedef typename K::Tetrahedron_3 Tetrahedron_3;
typedef Radius_ratio_criterion<K> RR_criterion;
typedef typename Sliver_criterion<K>::TetVector TetVector;
protected:
typedef Sliver_criterion<Tr> Base;
typedef typename Base::K K;
typedef typename Base::Tetrahedron_3 Tetrahedron_3;
typedef typename Base::Cell_vector Cell_vector;
typedef Radius_ratio_criterion<Tr> RR_criterion;
public:
static double default_value;
@ -125,53 +147,54 @@ public:
virtual const double get_max_value() const { return 1.; }
virtual const 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, K()));
}
virtual void before_move(const TetVector& tetrahedra) const
virtual void before_move(const Cell_vector& cells) const
{
Min_value<RR_criterion, TetVector> min_value_op(*this);
min_value_before_move_ = min_value_op(tetrahedra);
Min_value<RR_criterion, Cell_vector> min_value_op(*this);
min_value_before_move_ = min_value_op(cells);
}
virtual bool valid_move(const TetVector& tetrahedra,
virtual bool valid_move(const Cell_vector& cells,
const bool soft = false) const
{
Min_value<RR_criterion, TetVector> min_value_op(*this);
double min_val = min_value_op(tetrahedra);
Min_value<RR_criterion, Cell_vector> min_value_op(*this);
double min_val = min_value_op(cells);
return (min_val > min_value_before_move_)
|| (soft && min_val > sliver_bound_);
}
public:
RR_criterion(const double& sliver_bound)
{
set_sliver_bound(sliver_bound);
}
RR_criterion(const double& sliver_bound,
const Tr& tr)
: Base(sliver_bound, tr)
{}
private:
mutable double min_value_before_move_;
};
template<typename K> double Radius_ratio_criterion<K>::default_value = 0.25;
template<typename K> double Radius_ratio_criterion<K>::max_value = 1.;
template<typename K> double Radius_ratio_criterion<K>::min_value = 0.;
template<typename Tr> double Radius_ratio_criterion<Tr>::default_value = 0.25;
template<typename Tr> double Radius_ratio_criterion<Tr>::max_value = 1.;
template<typename Tr> double Radius_ratio_criterion<Tr>::min_value = 0.;
template<typename SliverCriterion, typename Tet_vector>
template<typename SliverCriterion, typename Cell_vector>
class Min_value
{
public:
double operator()(const Tet_vector& tetrahedra)
double operator()(const Cell_vector& cells)
{
double minimum = criterion_.get_max_value();
typename Tet_vector::const_iterator it;
for(it = tetrahedra.begin();
it != tetrahedra.end();
++it)
typename Cell_vector::const_iterator it;
for(it = cells.begin(); it != cells.end(); ++it)
{
minimum = (std::min)(minimum, criterion_(*it));
typename SliverCriterion::Cell_handle c = *it;
minimum = (std::min)(minimum, criterion_(c));
}
return minimum;
}

View File

@ -56,13 +56,13 @@ exude_mesh_3_impl(C3T3& c3t3,
const double time_limit,
const double sliver_bound)
{
typedef typename C3T3::Triangulation::Geom_traits Gt;
typedef Mesh_3::Min_dihedral_angle_criterion<Gt> Sc;
//typedef Mesh_3::Radius_radio_criterion<Gt> Sc;
typedef typename C3T3::Triangulation Tr;
typedef Mesh_3::Min_dihedral_angle_criterion<Tr> Sc;
//typedef Mesh_3::Radius_radio_criterion<Tr> Sc;
typedef typename Mesh_3::Slivers_exuder<C3T3, Sc> Exuder;
// Create exuder
Sc criterion(sliver_bound);
Sc criterion(sliver_bound, c3t3.triangulation());
Exuder exuder(c3t3, criterion);
// Set time_limit