mirror of https://github.com/CGAL/cgal
162 lines
4.4 KiB
C++
162 lines
4.4 KiB
C++
// Copyright (c) 2004-2005 INRIA Sophia-Antipolis (France).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
// the terms of the Q Public License version 1.0.
|
|
// See the file LICENSE.QPL distributed with CGAL.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
//
|
|
// Author(s) : Laurent RINEAU
|
|
|
|
#ifndef CGAL_MESH_CRITERIA_3_H
|
|
#define CGAL_MESH_CRITERIA_3_H
|
|
|
|
namespace CGAL {
|
|
|
|
template <typename Tr>
|
|
class Mesh_criteria_3
|
|
{
|
|
double squared_radius_bound_;
|
|
double radius_edge_bound_;
|
|
public:
|
|
typedef typename Tr::Cell_handle Cell_handle;
|
|
|
|
Mesh_criteria_3(const double radius_edge_bound = 2,
|
|
const double squared_radius_bound = 0)
|
|
: squared_radius_bound_(squared_radius_bound),
|
|
radius_edge_bound_(radius_edge_bound)
|
|
{
|
|
};
|
|
|
|
struct Quality : public std::pair<double, double>
|
|
{
|
|
typedef std::pair<double, double> Base;
|
|
|
|
Quality() : Base() {};
|
|
Quality(double _aspect, double _sq_size) : Base(_aspect, _sq_size) {};
|
|
|
|
const double& sq_size() const { return second; }
|
|
const double& aspect() const { return first; }
|
|
|
|
// q1<q2 means q1 is prioritised over q2
|
|
// ( q1 == *this, q2 == q )
|
|
bool operator<(const Quality& q) const
|
|
{
|
|
if( sq_size() > 1 )
|
|
if( q.sq_size() > 1 )
|
|
return ( sq_size() > q.sq_size() );
|
|
else
|
|
return true; // *this is big but not q
|
|
else
|
|
if( q.sq_size() > 1 )
|
|
return false; // q is big but not *this
|
|
return( aspect() > q.aspect() );
|
|
}
|
|
};
|
|
|
|
inline
|
|
double squared_radius_bound() const
|
|
{
|
|
return squared_radius_bound_;
|
|
};
|
|
|
|
inline
|
|
void set_squared_radius_bound(const double squared_radius_bound)
|
|
{
|
|
squared_radius_bound_ = squared_radius_bound;
|
|
};
|
|
|
|
inline
|
|
double radius_edge_bound() const
|
|
{
|
|
return radius_edge_bound_;
|
|
};
|
|
|
|
inline
|
|
void set_radius_edge_bound(const double radius_edge_bound)
|
|
{
|
|
radius_edge_bound_ = radius_edge_bound;
|
|
};
|
|
|
|
class Is_bad
|
|
{
|
|
protected:
|
|
const double radius_edge_bound_;
|
|
const double squared_radius_bound_;
|
|
public:
|
|
typedef typename Tr::Point Point_3;
|
|
|
|
Is_bad(const double radius_edge_bound,
|
|
const double squared_radius_bound)
|
|
: radius_edge_bound_(radius_edge_bound),
|
|
squared_radius_bound_(squared_radius_bound) {};
|
|
|
|
bool operator()(const Cell_handle& c,
|
|
Quality& qual) const
|
|
{
|
|
const Point_3& p = c->vertex(0)->point();
|
|
const Point_3& q = c->vertex(1)->point();
|
|
const Point_3& r = c->vertex(2)->point();
|
|
const Point_3& s = c->vertex(3)->point();
|
|
|
|
typedef typename Tr::Geom_traits Geom_traits;
|
|
typedef typename Geom_traits::Compute_squared_radius_3 Radius;
|
|
typedef typename Geom_traits::Compute_squared_distance_3 Distance;
|
|
typedef typename Geom_traits::FT FT;
|
|
|
|
Radius radius = Geom_traits().compute_squared_radius_3_object();
|
|
Distance distance = Geom_traits().compute_squared_distance_3_object();
|
|
|
|
double size = to_double(radius(p, q, r, s));
|
|
|
|
if( squared_radius_bound_ != 0 )
|
|
{
|
|
qual.second = size / squared_radius_bound_;
|
|
// normalized by size bound to deal
|
|
// with size field
|
|
if( qual.sq_size() > 1 )
|
|
{
|
|
qual.first = 1; // (do not compute aspect)
|
|
return true;
|
|
}
|
|
}
|
|
if( radius_edge_bound_ == 0 )
|
|
{
|
|
qual = Quality(0,1);
|
|
return false;
|
|
}
|
|
|
|
double min_sq_length = CGAL::to_double(distance(p, q));
|
|
min_sq_length = CGAL::min(min_sq_length, to_double(distance(p, r)));
|
|
min_sq_length = CGAL::min(min_sq_length, to_double(distance(p, s)));
|
|
min_sq_length = CGAL::min(min_sq_length, to_double(distance(q, r)));
|
|
min_sq_length = CGAL::min(min_sq_length, to_double(distance(q, s)));
|
|
min_sq_length = CGAL::min(min_sq_length, to_double(distance(r, s)));
|
|
|
|
qual.first = size / min_sq_length;
|
|
|
|
return (qual.first > radius_edge_bound_);
|
|
}
|
|
|
|
}; // end Is_bad
|
|
|
|
|
|
Is_bad is_bad_object() const
|
|
{ return Is_bad(radius_edge_bound_, squared_radius_bound_); }
|
|
|
|
}; // end Mesh_criteria_3
|
|
|
|
|
|
} // end namespace CGAL
|
|
|
|
#endif // CGAL_MESH_CRITERIA_3_H
|