// Copyright (c) 2009 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // 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) : Stephane Tayeb // //****************************************************************************** // File Description : // //****************************************************************************** #ifndef CGAL_MESH_3_MESH_STANDARD_CRITERIA_H #define CGAL_MESH_3_MESH_STANDARD_CRITERIA_H #include #include namespace CGAL { namespace Mesh_3 { /** * @class Abstract_criterion */ template class Abstract_criterion { typedef typename Tr::Geom_traits::FT FT; typedef Abstract_criterion Self; public: typedef FT Quality; typedef boost::optional Badness; typedef typename Visitor_::Handle Handle; /// Destructor virtual ~Abstract_criterion() {} void accept(Visitor_& v) const { do_accept(v); } Badness is_bad(const Handle& h) const { return do_is_bad(h); } Self* clone() const { return do_clone(); } protected: virtual void do_accept(Visitor_& v) const = 0; virtual Badness do_is_bad(const Handle& h) const = 0; virtual Self* do_clone() const = 0; }; // end class Abstract_criterion template inline Abstract_criterion* new_clone(const Abstract_criterion& criterion) { return criterion.clone(); } template class Criterion_visitor { typedef Criterion_visitor Self; public: typedef Handle_ Handle; protected: typedef Abstract_criterion Criterion; public: typedef std::pair Quality; typedef boost::optional Badness; // Constructor Criterion_visitor(const Handle_& h) : handle_(h) , badness_() , criterion_counter_(0) {} // Destructor ~Criterion_visitor() {} Badness badness() const { return badness_; } bool go_further() const { return !badness_; } protected: void increment_counter() { ++criterion_counter_; } void set_badness(const Badness& badness) { badness_ = badness; } template void do_visit(const Abstract_criterion& criterion) { typedef typename Abstract_criterion::Badness Badness; const Badness badness = criterion.is_bad(handle_); if ( badness ) badness_ = std::make_pair(criterion_counter_, *badness); increment_counter(); } private: Handle_ handle_; Badness badness_; int criterion_counter_; }; // end class Criterion_visitor template class Criteria { typedef Criteria Self; typedef Abstract_criterion Criterion; typedef boost::ptr_vector Criterion_vector; typedef typename Visitor_::Quality Quality; typedef typename Visitor_::Badness Badness; public: /// Constructor Criteria() {} /// Copy constructor Criteria(const Self& rhs) : criterion_vector_(rhs.criterion_vector_.clone()) { } /// Destructor ~Criteria() {} // ptr_vector do the job of criterion deleting /// Add a criterion void add(Criterion* criterion) { criterion_vector_.push_back(criterion); } Badness operator()(const typename Visitor_::Handle& h) const { Visitor_ visitor(h); typename Criterion_vector::const_iterator it = criterion_vector_.begin(); for ( ; it != criterion_vector_.end() ; ++it ) { it->accept(visitor); if ( ! visitor.go_further() ) return visitor.badness(); } return visitor.badness(); } private: Criterion_vector criterion_vector_; }; // end class Criteria } // end namespace Mesh_3 } // end namespace CGAL #endif // CGAL_MESH_3_MESH_STANDARD_CRITERIA_H