// 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/Implicit_to_labeling_function_wrapper.h $ // $Id: Implicit_to_labeling_function_wrapper.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) : Stéphane Tayeb, Aymeric PELLE // //****************************************************************************** // File Description : // Implicit_to_labeling_function_wrapper and // Implicit_vector_to_labeling_function_wrapper class declaration // and implementation. // // See classes description to have more information. //****************************************************************************** #ifndef CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H #define CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H #include #include #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored #endif #include #include #include #include #include #include #include namespace CGAL { /** * @class Implicit_to_labeling_function_wrapper * * This class is designed to wrap an implicit function which describes a domain * by [p is inside if f(p)<0] to a function which takes its values into {0,1}. * f(p)=0 means that p is outside the domain. */ template class Implicit_to_labeling_function_wrapper { public: // Types typedef int return_type; typedef typename BGT::Point_3 Point_3; /// Constructor Implicit_to_labeling_function_wrapper(Function_ f) : f_(f) {} // Default copy constructor, assignment operator, and destructor are ok /// Operator () return_type operator()(const Point_3& p) const { return ( (f_(p)<0) ? 1 : 0 ); } private: typedef typename boost::mpl::if_, Function_*, Function_>::type Stored_function; /// Function to wrap Stored_function f_; }; // end class Implicit_to_labeling_function_wrapper template Implicit_to_labeling_function_wrapper make_implicit_to_labeling_function_wrapper(Function f) { return Implicit_to_labeling_function_wrapper(f); } /** * \deprecated * * @class Implicit_vector_to_labeling_function_wrapper * * Wraps a set of implicit function [f1,f2,...] to one function F which * takes its values into N. * * Let p be a point. * F(p) = 0b000000(f2(p)<0)(f1(p)<0) * * It can handle at most 8 functions. */ template class Implicit_vector_to_labeling_function_wrapper { public: // Types typedef int return_type; typedef std::vector Function_vector; typedef typename BGT::Point_3 Point_3; /// Constructor Implicit_vector_to_labeling_function_wrapper(const std::vector& v) : function_vector_(v) { if ( v.size() > 8 ) { CGAL_error_msg("We support at most 8 functions !"); } } // Default copy constructor and assignment operator are ok /// Destructor ~Implicit_vector_to_labeling_function_wrapper() {} /// Operator () return_type operator()(const Point_3& p) const { const int nb_func = static_cast(function_vector_.size()); char bits = 0; for ( int i = 0 ; i < nb_func ; ++i ) { // Insert value into bits : we compute fi(p) and insert result at // bit i of bits bits = char(bits | ( ((*function_vector_[i])(p) < 0) << i )); } return ( static_cast(bits) ); } private: /// Functions to wrap const Function_vector function_vector_; }; // end class Implicit_to_labeling_function_wrapper template class Implicit_multi_domain_to_labeling_function_wrapper { template class Implicit_function_traits { public: typedef typename T_::Point Point; }; template class Implicit_function_traits { public: typedef typename boost::remove_reference< typename boost::remove_cv< Point_ >::type>::type Point; }; public: typedef int return_type; typedef ImplicitFunction Function; typedef typename Implicit_function_traits::Point Point_3; typedef std::vector Function_vector; private: std::vector funcs; typedef boost::dynamic_bitset Bmask; std::vector bmasks; public: Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector >& vps) : funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false)) { CGAL_assertion(funcs.size() != 0); std::size_t mask_index = 0; for (std::vector >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); mask_iter != mask_end_iter; ++mask_iter) { const std::vector& mask = *mask_iter; CGAL_assertion(funcs.size() == mask.size()); Bmask& bmask = bmasks[mask_index++]; typename Bmask::size_type bit_index = 0; for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) { Sign character = *iter; CGAL_assertion(character == POSITIVE || character == NEGATIVE); bmask[bit_index] = (character == POSITIVE); ++bit_index; bmask[bit_index] = (character == NEGATIVE); ++bit_index; } } std::sort(bmasks.begin(), bmasks.end()); } Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf) : funcs(vf) { CGAL_assertion(funcs.size() != 0); bmasks.reserve((1 << funcs.size()) - 1); bmasks.push_back(Bmask(std::string("10"))); bmasks.push_back(Bmask(std::string("01"))); for (std::size_t i = 0; i < funcs.size()-1; ++i) { std::size_t c_size = bmasks.size(); for (std::size_t index = 0; index < c_size; ++index) { Bmask aux = bmasks[index]; aux.push_back(true); aux.push_back(false); bmasks.push_back(aux); bmasks[index].push_back(false); bmasks[index].push_back(true); } } bmasks.pop_back(); std::sort(bmasks.begin(), bmasks.end()); } Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector& vps) : funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false)) { CGAL_assertion(funcs.size() != 0); std::size_t mask_index = 0; for (std::vector::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); mask_iter != mask_end_iter; ++mask_iter) { const std::string& mask_str = *mask_iter; CGAL_assertion(funcs.size() == mask_str.length()); Bmask& bmask = bmasks[mask_index++]; typename Bmask::size_type bit_index = 0; for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter) { std::string::value_type character = *iter; CGAL_assertion(character == '+' || character == '-'); bmask[bit_index] = (character == '+'); ++bit_index; bmask[bit_index] = (character == '-'); ++bit_index; } } std::sort(bmasks.begin(), bmasks.end()); } return_type operator() (const Point_3& p) const { Bmask bmask(funcs.size() * 2, false); std::size_t i = 0; for (typename std::vector::const_iterator iter = funcs.begin(), endIter = funcs.end(); iter != endIter; ++iter) { const Function& function = *iter; double fres = function(p); bmask[i] = fres > 0; ++i; bmask[i] = fres < 0; ++i; } typename std::vector::const_iterator iter = std::lower_bound(bmasks.begin(), bmasks.end(), bmask); if (iter != bmasks.end() && *iter == bmask) return static_cast(1 + (iter - bmasks.begin())); return 0; } }; } // end namespace CGAL #if defined(BOOST_MSVC) # pragma warning(pop) #endif #include #endif // CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H