Add a functor that allows to reject candidate faces

This commit is contained in:
Andreas Fabri 2015-06-05 11:54:30 +02:00
parent 6a724bb881
commit 7dd320c74b
7 changed files with 102 additions and 53 deletions

View File

@ -19,6 +19,25 @@ namespace std {
} }
} }
struct Perimeter {
double bound;
Perimeter(double bound)
: bound(bound)
{}
bool operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
{
double d = sqrt(squared_distance(p,q));
if(d>bound) return true;
d += sqrt(squared_distance(p,r)) ;
if(d>bound) return true;
d+= sqrt(squared_distance(q,r));
return d>bound;
}
};
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
@ -29,9 +48,11 @@ int main(int argc, char* argv[])
std::istream_iterator<Point_3>(), std::istream_iterator<Point_3>(),
std::back_inserter(points)); std::back_inserter(points));
Perimeter perimeter(0.5);
CGAL::advancing_front_surface_reconstruction(points.begin(), CGAL::advancing_front_surface_reconstruction(points.begin(),
points.end(), points.end(),
std::back_inserter(facets)); std::back_inserter(facets),
perimeter);
std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n";
std::copy(points.begin(), std::copy(points.begin(),

View File

@ -6,7 +6,7 @@
namespace CGAL { namespace CGAL {
template <class Kernel, class Triangulation> template <class Kernel, class Triangulation, class Filter>
class Advancing_front_polyhedron_reconstruction; class Advancing_front_polyhedron_reconstruction;
namespace AFSR { namespace AFSR {

View File

@ -3,15 +3,15 @@
namespace CGAL { namespace CGAL {
template <class Kernel, class Triangulation> template <class Kernel, class Triangulation, class Filter>
class Advancing_front_surface_reconstruction; class Advancing_front_surface_reconstruction;
namespace AFSR { namespace AFSR {
template <class Kernel, class Triangulation, class TDS> template <class Kernel, class Triangulation, class TDS, class Filter>
typename TDS::Vertex_handle typename TDS::Vertex_handle
construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction<Kernel,Triangulation>& surface) construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter>& surface)
{ {
typedef typename TDS::Vertex_handle Vertex_handle; typedef typename TDS::Vertex_handle Vertex_handle;

View File

@ -4,9 +4,9 @@ namespace CGAL {
namespace AFSR { namespace AFSR {
template <class Kernel, class Triangulation, class TDS> template <class Kernel, class Triangulation, class TDS, class Filter>
typename TDS::Vertex_handle typename TDS::Vertex_handle
orient(TDS& tds, const Advancing_front_surface_reconstruction<Kernel,Triangulation>& surface) orient(TDS& tds, const Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter>& surface)
{ {
typedef typename TDS::Vertex_handle Vertex_handle; typedef typename TDS::Vertex_handle Vertex_handle;

View File

@ -5,16 +5,16 @@
namespace CGAL { namespace CGAL {
template <class Kernel, class Triangulation> template <class Kernel, class Triangulation, class Filter>
class Advancing_front_surface_reconstruction; class Advancing_front_surface_reconstruction;
template <class OutputIterator, class Kernel, class Triangulation> template <class OutputIterator, class Kernel, class Triangulation, class Filter>
OutputIterator OutputIterator
write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction<Kernel,Triangulation>& S) write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter>& S)
{ {
typedef Advancing_front_surface_reconstruction<Kernel,Triangulation> Surface; typedef Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter> Surface;
typedef typename Surface::TDS_2 TDS_2; typedef typename Surface::TDS_2 TDS_2;
typedef typename TDS_2::Face_iterator Face_iterator; typedef typename TDS_2::Face_iterator Face_iterator;
typedef typename Surface::Cell_handle Cell_handle; typedef typename Surface::Cell_handle Cell_handle;

View File

@ -136,14 +136,25 @@ public:
} }
}; };
struct Always_false {
template <typename T>
bool operator()(const T&, const T&, const T&) const
{
return false;
}
};
template <class Kernel, template <class Kernel,
class Triangulation = Delaunay_triangulation_3<Kernel, Triangulation_data_structure_3<Advancing_front_surface_reconstruction_vertex_base_3<Kernel>, Advancing_front_surface_reconstruction_cell_base_3<Kernel> > > > class Triangulation = Delaunay_triangulation_3<Kernel, Triangulation_data_structure_3<Advancing_front_surface_reconstruction_vertex_base_3<Kernel>, Advancing_front_surface_reconstruction_cell_base_3<Kernel> > >,
class Reject = Always_false>
class Advancing_front_surface_reconstruction { class Advancing_front_surface_reconstruction {
public: public:
typedef Triangulation Triangulation_3; typedef Triangulation Triangulation_3;
typedef Advancing_front_surface_reconstruction<Kernel,Triangulation_3> Extract; typedef Advancing_front_surface_reconstruction<Kernel,Triangulation_3,Reject> Extract;
typedef typename Triangulation_3::Geom_traits Geom_traits; typedef typename Triangulation_3::Geom_traits Geom_traits;
typedef typename Kernel::FT coord_type; typedef typename Kernel::FT coord_type;
@ -226,9 +237,6 @@ private:
const criteria STANDBY_CANDIDATE_BIS; const criteria STANDBY_CANDIDATE_BIS;
const criteria NOT_VALID_CANDIDATE; const criteria NOT_VALID_CANDIDATE;
const double perimeter;
const double abs_perimeter;
double total_perimeter;
//--------------------------------------------------------------------- //---------------------------------------------------------------------
//Pour une visu correcte //Pour une visu correcte
//pour retenir les facettes selectionnees //pour retenir les facettes selectionnees
@ -246,6 +254,7 @@ private:
Vertex_handle added_vertex; Vertex_handle added_vertex;
bool deal_with_2d; bool deal_with_2d;
Reject reject;
std::list<Vertex_handle> interior_edges; std::list<Vertex_handle> interior_edges;
std::list< Incidence_request_elt > incidence_requests; std::list< Incidence_request_elt > incidence_requests;
typename std::list< Incidence_request_elt >::iterator sentinel; typename std::list< Incidence_request_elt >::iterator sentinel;
@ -527,14 +536,16 @@ private:
public: public:
Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) Advancing_front_surface_reconstruction(Triangulation_3& T_,
const AFSR_options& opt = AFSR_options(),
Reject reject = Reject())
: T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL),
eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps),
STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1),
NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), perimeter(opt.perimeter), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2),
abs_perimeter(opt.abs_perimeter), total_perimeter(0),
_vh_number(static_cast<int>(T.number_of_vertices())), _facet_number(0), _vh_number(static_cast<int>(T.number_of_vertices())), _facet_number(0),
_postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false) _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0),
deal_with_2d(false), reject(reject)
{ {
if(T.dimension() == 2){ if(T.dimension() == 2){
@ -1181,30 +1192,16 @@ public:
int n_i3 = 6 - n_ind - n_i1 - n_i2; int n_i3 = 6 - n_ind - n_i1 - n_i2;
coord_type tmp=0; coord_type tmp=0;
coord_type ar=0, pe=0;
// If the triangle has a high perimeter, // If the triangle has a high perimeter,
// we do not want to consider it as a good candidate. // we do not want to consider it as a good candidate.
if( (abs_perimeter != 0) || ( (_facet_number > 1000) && (perimeter != 0)) ){ if(reject(facet_it.first->vertex(n_i1)->point(),
pe = compute_perimeter(facet_it.first->vertex(n_i1)->point(),
facet_it.first->vertex(n_i2)->point(), facet_it.first->vertex(n_i2)->point(),
facet_it.first->vertex(n_i3)->point()); facet_it.first->vertex(n_i3)->point())){
}
if((abs_perimeter != 0) && (pe > abs_perimeter)){
tmp = HUGE_VAL; tmp = HUGE_VAL;
} }
if((tmp != HUGE_VAL) && (_facet_number > 1000)){
if((perimeter != 0) && (tmp != HUGE_VAL)){
coord_type avg_perimeter = total_perimeter/_facet_number;
if(pe > (perimeter * avg_perimeter)){
tmp = HUGE_VAL;
}
}
}
if(tmp != HUGE_VAL){ if(tmp != HUGE_VAL){
tmp = smallest_radius_delaunay_sphere(neigh, n_ind); tmp = smallest_radius_delaunay_sphere(neigh, n_ind);
@ -1343,15 +1340,13 @@ public:
if (c->vertex((index+3) & 3)->is_exterior()) if (c->vertex((index+3) & 3)->is_exterior())
{ {
coord_type value = smallest_radius_delaunay_sphere(c, index); coord_type value = smallest_radius_delaunay_sphere(c, index);
coord_type pe=0;
if(abs_perimeter != 0){ // we might not want the triangle, for example because it is too large
pe = compute_perimeter(c->vertex((index+1)&3)->point(), if(reject(c->vertex((index+1)&3)->point(),
c->vertex((index+2)&3)->point(), c->vertex((index+2)&3)->point(),
c->vertex((index+3)&3)->point()); c->vertex((index+3)&3)->point())){
if(pe > abs_perimeter){
value = min_value; value = min_value;
} }
}
if (value < min_value) if (value < min_value)
{ {
@ -2308,6 +2303,7 @@ struct Auto_count : public std::unary_function<const T&,std::pair<T,int> >{
}; };
} }
template <typename PointIterator, typename IndexTripleIterator> template <typename PointIterator, typename IndexTripleIterator>
IndexTripleIterator IndexTripleIterator
advancing_front_surface_reconstruction(PointIterator b, advancing_front_surface_reconstruction(PointIterator b,
@ -2338,14 +2334,46 @@ advancing_front_surface_reconstruction(PointIterator b,
return out; return out;
} }
template <typename PointIterator, typename IndexTripleIterator, typename Filter>
IndexTripleIterator
advancing_front_surface_reconstruction(PointIterator b,
PointIterator e,
IndexTripleIterator out,
Filter filter,
double radius_ratio_bound = 5,
double beta = 0.52 )
{
typedef Exact_predicates_inexact_constructions_kernel Kernel;
typedef Advancing_front_surface_reconstruction_vertex_base_3<Kernel> LVb;
typedef Advancing_front_surface_reconstruction_cell_base_3<Kernel> LCb;
typedef Triangulation_data_structure_3<LVb,LCb> Tds;
typedef Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
typedef Advancing_front_surface_reconstruction<Kernel,Triangulation_3,Filter> Reconstruction;
typedef Kernel::Point_3 Point_3;
Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count<Point_3>()),
boost::make_transform_iterator(e, AFSR::Auto_count<Point_3>() ) );
AFSR_options opt;
opt.K = radius_ratio_bound;
// TODO: What to do with beta???
Reconstruction R(dt,opt, filter);
R.run(opt);
write_triple_indices(out, R);
return out;
}
template <typename PointIterator, typename Kernel> template <typename PointIterator, typename Kernel>
void void
advancing_front_surface_reconstruction(PointIterator b, advancing_front_surface_reconstruction(PointIterator b,
PointIterator e, PointIterator e,
Polyhedron_3<Kernel>& polyhedron, Polyhedron_3<Kernel>& polyhedron,
double radius_ratio_bound = 5, double radius_ratio_bound = 5,
double beta = 0.52, double beta = 0.52)
double max_perimeter = 0)
{ {
typedef Advancing_front_surface_reconstruction_vertex_base_3<Kernel> LVb; typedef Advancing_front_surface_reconstruction_vertex_base_3<Kernel> LVb;
typedef Advancing_front_surface_reconstruction_cell_base_3<Kernel> LCb; typedef Advancing_front_surface_reconstruction_cell_base_3<Kernel> LCb;
@ -2362,7 +2390,7 @@ advancing_front_surface_reconstruction(PointIterator b,
AFSR_options opt; AFSR_options opt;
opt.K = radius_ratio_bound; opt.K = radius_ratio_bound;
// TODO: What to do with beta??? // TODO: What to do with beta???
opt.abs_perimeter = max_perimeter; //opt.abs_perimeter = max_perimeter;
Reconstruction R(dt, opt); Reconstruction R(dt, opt);
R.run(opt); R.run(opt);
AFSR::construct_polyhedron(polyhedron, R); AFSR::construct_polyhedron(polyhedron, R);

View File

@ -12,7 +12,7 @@
namespace CGAL { namespace CGAL {
template <class A, class B> class Advancing_front_surface_reconstruction; template <class A, class B, class C> class Advancing_front_surface_reconstruction;
template <class K, class VertexBase = Triangulation_vertex_base_3<K> > template <class K, class VertexBase = Triangulation_vertex_base_3<K> >
class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase
@ -26,7 +26,7 @@ public:
}; };
template <class A, class B > friend class Advancing_front_surface_reconstruction; template <class A, class B,class C> friend class Advancing_front_surface_reconstruction;
typedef VertexBase Base; typedef VertexBase Base;