// Copyright (c) 2009 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v5.2/Mesh_3/include/CGAL/Mesh_3/mesh_standard_criteria.h $ // $Id: mesh_standard_criteria.h 254d60f 2019-10-19T15:23:19+02:00 Sébastien Loriot // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Stephane Tayeb // //****************************************************************************** // File Description : // //****************************************************************************** #ifndef CGAL_MESH_3_MESH_STANDARD_CRITERIA_H #define CGAL_MESH_3_MESH_STANDARD_CRITERIA_H #include #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 Is_bad; typedef typename Visitor_::Handle Handle; /// Destructor virtual ~Abstract_criterion() {} void accept(Visitor_& v) const { do_accept(v); } Is_bad is_bad(const Tr& tr, const Handle& h) const { return do_is_bad(tr, h); } Self* clone() const { return do_clone(); } protected: virtual void do_accept(Visitor_& v) const = 0; virtual Is_bad do_is_bad(const Tr& tr, 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 Is_bad; // Constructor Criterion_visitor(const Tr& tr, const Handle_& h) : tr_(tr) , handle_(h) , is_bad_() , criterion_counter_(0) {} // Destructor ~Criterion_visitor() {} Is_bad is_bad() const { return is_bad_; } bool go_further() const { return !is_bad_; } protected: void increment_counter() { ++criterion_counter_; } void set_is_bad(const Is_bad& is_bad) { is_bad_ = is_bad; } template void do_visit(const Abstract_criterion& criterion) { typedef typename Abstract_criterion::Is_bad Is_bad; const Is_bad is_bad = criterion.is_bad(tr_, handle_); if ( is_bad ) is_bad_ = std::make_pair(criterion_counter_, *is_bad); increment_counter(); } private: const Tr& tr_; Handle_ handle_; Is_bad is_bad_; 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_::Is_bad Is_bad; 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); } Is_bad operator()(const Tr& tr, const typename Visitor_::Handle& h) const { Visitor_ visitor(tr, 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.is_bad(); } return visitor.is_bad(); } private: Criterion_vector criterion_vector_; }; // end class Criteria } // end namespace Mesh_3 } // end namespace CGAL #endif // CGAL_MESH_3_MESH_STANDARD_CRITERIA_H