Chris@16: /* Chris@16: Copyright 2008 Intel Corporation Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: */ Chris@16: #ifndef BOOST_POLYGON_POLYGON_SET_VIEW_HPP Chris@16: #define BOOST_POLYGON_POLYGON_SET_VIEW_HPP Chris@16: namespace boost { namespace polygon{ Chris@16: Chris@16: Chris@16: template Chris@16: inline void polygon_set_data::clean() const { Chris@16: if(dirty_) { Chris@16: //polygon_45_set_data tmp; Chris@16: //very important: Chris@16: //the 45 degree algorithm does not satisfy Chris@16: //the precondition of arbitrary polygon formation Chris@16: //that vertices be "linearly consistent" Chris@16: //therefore it doesn't work to fall back on 45-degree Chris@16: //booleans for arbitrary angle polygons Chris@16: //if(0) { //downcast(tmp) ) { Chris@16: // tmp.clean(); Chris@16: // data_.clear(); Chris@16: // is_45_ = true; Chris@16: // polygon_set_data tmp2; Chris@16: // tmp2.insert(tmp); Chris@16: // data_.swap(tmp2.data_); Chris@16: // dirty_ = false; Chris@16: // sort(); Chris@16: //} else { Chris@16: sort(); Chris@16: arbitrary_boolean_op abo; Chris@16: polygon_set_data tmp2; Chris@16: abo.execute(tmp2, begin(), end(), end(), end(), 0); Chris@16: data_.swap(tmp2.data_); Chris@16: is_45_ = tmp2.is_45_; Chris@16: dirty_ = false; Chris@16: //} Chris@16: } Chris@16: } Chris@16: Chris@16: template <> Chris@16: inline void polygon_set_data::clean() const { Chris@16: if(dirty_) { Chris@16: sort(); Chris@16: arbitrary_boolean_op abo; Chris@16: polygon_set_data tmp2; Chris@16: abo.execute(tmp2, begin(), end(), end(), end(), 0); Chris@16: data_.swap(tmp2.data_); Chris@16: is_45_ = tmp2.is_45_; Chris@16: dirty_ = false; Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: inline void insert_into_view_arg(value_type& dest, const arg_type& arg); Chris@16: Chris@16: template Chris@16: class polygon_set_view; Chris@16: Chris@16: template Chris@16: struct polygon_set_traits > { Chris@16: typedef typename polygon_set_view::coordinate_type coordinate_type; Chris@16: typedef typename polygon_set_view::iterator_type iterator_type; Chris@16: typedef typename polygon_set_view::operator_arg_type operator_arg_type; Chris@16: Chris@16: static inline iterator_type begin(const polygon_set_view& polygon_set); Chris@16: static inline iterator_type end(const polygon_set_view& polygon_set); Chris@16: Chris@16: static inline bool clean(const polygon_set_view& polygon_set); Chris@16: Chris@16: static inline bool sort(const polygon_set_view& polygon_set); Chris@16: }; Chris@16: Chris@16: //template Chris@16: //void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_, Chris@16: // double coord) { Chris@16: // typedef geometry_type_1 ltype; Chris@16: // typedef geometry_type_2 rtype; Chris@16: // typedef typename polygon_set_traits::coordinate_type coordinate_type; Chris@16: // value_type linput_; Chris@16: // value_type rinput_; Chris@16: // insert_into_view_arg(linput_, lvalue_); Chris@16: // insert_into_view_arg(rinput_, rvalue_); Chris@16: // arbitrary_boolean_op abo; Chris@16: // abo.execute(output_, linput_.begin(), linput_.end(), Chris@16: // rinput_.begin(), rinput_.end(), op_type); Chris@16: //} Chris@16: Chris@16: template Chris@16: void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { Chris@16: typedef geometry_type_1 ltype; Chris@101: //typedef geometry_type_2 rtype; Chris@16: typedef typename polygon_set_traits::coordinate_type coordinate_type; Chris@16: value_type linput_; Chris@16: value_type rinput_; Chris@16: insert_into_view_arg(linput_, lvalue_); Chris@16: insert_into_view_arg(rinput_, rvalue_); Chris@16: polygon_45_set_data l45, r45, o45; Chris@16: // if(linput_.downcast(l45) && rinput_.downcast(r45)) { Chris@16: // //the op codes are screwed up between 45 and arbitrary Chris@16: //#ifdef BOOST_POLYGON_MSVC Chris@16: //#pragma warning (push) Chris@16: //#pragma warning (disable: 4127) Chris@16: //#endif Chris@16: // if(op_type < 2) Chris@16: // l45.template applyAdaptiveBoolean_(o45, r45); Chris@16: // else if(op_type == 2) Chris@16: // l45.template applyAdaptiveBoolean_<3>(o45, r45); Chris@16: // else Chris@16: // l45.template applyAdaptiveBoolean_<2>(o45, r45); Chris@16: //#ifdef BOOST_POLYGON_MSVC Chris@16: //#pragma warning (pop) Chris@16: //#endif Chris@16: // output_.insert(o45); Chris@16: // } else { Chris@16: arbitrary_boolean_op abo; Chris@16: abo.execute(output_, linput_.begin(), linput_.end(), Chris@16: rinput_.begin(), rinput_.end(), op_type); Chris@16: // } Chris@16: } Chris@16: Chris@16: template Chris@16: class polygon_set_view { Chris@16: public: Chris@16: typedef typename polygon_set_traits::coordinate_type coordinate_type; Chris@16: typedef polygon_set_data value_type; Chris@16: typedef typename value_type::iterator_type iterator_type; Chris@16: typedef polygon_set_view operator_arg_type; Chris@16: private: Chris@16: const ltype& lvalue_; Chris@16: const rtype& rvalue_; Chris@16: mutable value_type output_; Chris@16: mutable bool evaluated_; Chris@16: polygon_set_view& operator=(const polygon_set_view&); Chris@16: public: Chris@16: polygon_set_view(const ltype& lvalue, Chris@16: const rtype& rvalue ) : Chris@16: lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} Chris@16: Chris@16: // get iterator to begin vertex data Chris@16: public: Chris@16: const value_type& value() const { Chris@16: if(!evaluated_) { Chris@16: evaluated_ = true; Chris@16: execute_boolean_op(output_, lvalue_, rvalue_); Chris@16: } Chris@16: return output_; Chris@16: } Chris@16: public: Chris@16: iterator_type begin() const { return value().begin(); } Chris@16: iterator_type end() const { return value().end(); } Chris@16: Chris@16: bool dirty() const { return false; } //result of a boolean is clean Chris@16: bool sorted() const { return true; } //result of a boolean is sorted Chris@16: Chris@16: void sort() const {} //is always sorted Chris@16: }; Chris@16: Chris@16: template Chris@16: typename polygon_set_traits >::iterator_type Chris@16: polygon_set_traits >:: Chris@16: begin(const polygon_set_view& polygon_set) { Chris@16: return polygon_set.begin(); Chris@16: } Chris@16: template Chris@16: typename polygon_set_traits >::iterator_type Chris@16: polygon_set_traits >:: Chris@16: end(const polygon_set_view& polygon_set) { Chris@16: return polygon_set.end(); Chris@16: } Chris@16: template Chris@16: bool polygon_set_traits >:: Chris@16: clean(const polygon_set_view& ) { Chris@16: return true; } Chris@16: template Chris@16: bool polygon_set_traits >:: Chris@16: sort(const polygon_set_view& ) { Chris@16: return true; } Chris@16: Chris@16: template Chris@16: inline void insert_into_view_arg(value_type& dest, const arg_type& arg) { Chris@16: typedef typename polygon_set_traits::iterator_type literator; Chris@16: literator itr1, itr2; Chris@16: itr1 = polygon_set_traits::begin(arg); Chris@16: itr2 = polygon_set_traits::end(arg); Chris@16: dest.insert(itr1, itr2); Chris@16: } Chris@16: Chris@16: template Chris@16: geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { Chris@16: typedef geometry_type_1 ltype; Chris@16: typedef typename polygon_set_traits::coordinate_type coordinate_type; Chris@16: typedef polygon_set_data value_type; Chris@16: value_type output_; Chris@16: execute_boolean_op(output_, lvalue_, rvalue_); Chris@16: polygon_set_mutable_traits::set(lvalue_, output_.begin(), output_.end()); Chris@16: return lvalue_; Chris@16: } Chris@16: Chris@16: // copy constructor Chris@16: template Chris@16: template Chris@16: polygon_set_data::polygon_set_data(const polygon_set_view& that) : Chris@16: data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {} Chris@16: Chris@16: // equivalence operator Chris@16: template Chris@16: inline bool polygon_set_data::operator==(const polygon_set_data& p) const { Chris@16: typedef polygon_set_data value_type; Chris@16: value_type output_; Chris@16: execute_boolean_op(output_, (*this), p); Chris@16: return output_.data_.empty(); Chris@16: } Chris@16: Chris@16: template Chris@16: struct geometry_concept > { typedef polygon_set_concept type; }; Chris@16: } Chris@16: } Chris@16: #endif