1 /* 2 Copyright 2008 Intel Corporation 3 4 Use, modification and distribution are subject to the Boost Software License, 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7 */ 8 #ifndef BOOST_POLYGON_POLYGON_SET_VIEW_HPP 9 #define BOOST_POLYGON_POLYGON_SET_VIEW_HPP 10 namespace boost { namespace polygon{ 11 12 13 template <typename coordinate_type> clean() const14 inline void polygon_set_data<coordinate_type>::clean() const { 15 if(dirty_) { 16 polygon_45_set_data<coordinate_type> tmp; 17 //very important: 18 //the 45 degree algorithm does not satisfy 19 //the precondition of arbitrary polygon formation 20 //that vertices be "linearly consistent" 21 //therefore it doesn't work to fall back on 45-degree 22 //booleans for arbitrary angle polygons 23 if(0) { //downcast(tmp) ) { 24 tmp.clean(); 25 data_.clear(); 26 is_45_ = true; 27 polygon_set_data<coordinate_type> tmp2; 28 tmp2.insert(tmp); 29 data_.swap(tmp2.data_); 30 dirty_ = false; 31 sort(); 32 } else { 33 sort(); 34 arbitrary_boolean_op<coordinate_type> abo; 35 polygon_set_data<coordinate_type> tmp2; 36 abo.execute(tmp2, begin(), end(), end(), end(), 0); 37 data_.swap(tmp2.data_); 38 is_45_ = tmp2.is_45_; 39 dirty_ = false; 40 } 41 } 42 } 43 44 template <> clean() const45 inline void polygon_set_data<double>::clean() const { 46 if(dirty_) { 47 sort(); 48 arbitrary_boolean_op<double> abo; 49 polygon_set_data<double> tmp2; 50 abo.execute(tmp2, begin(), end(), end(), end(), 0); 51 data_.swap(tmp2.data_); 52 is_45_ = tmp2.is_45_; 53 dirty_ = false; 54 } 55 } 56 57 template <typename value_type, typename arg_type> 58 inline void insert_into_view_arg(value_type& dest, const arg_type& arg); 59 60 template <typename ltype, typename rtype, int op_type> 61 class polygon_set_view; 62 63 template <typename ltype, typename rtype, int op_type> 64 struct polygon_set_traits<polygon_set_view<ltype, rtype, op_type> > { 65 typedef typename polygon_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type; 66 typedef typename polygon_set_view<ltype, rtype, op_type>::iterator_type iterator_type; 67 typedef typename polygon_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type; 68 69 static inline iterator_type begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set); 70 static inline iterator_type end(const polygon_set_view<ltype, rtype, op_type>& polygon_set); 71 72 static inline bool clean(const polygon_set_view<ltype, rtype, op_type>& polygon_set); 73 74 static inline bool sort(const polygon_set_view<ltype, rtype, op_type>& polygon_set); 75 }; 76 77 //template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type> 78 //void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_, 79 // double coord) { 80 // typedef geometry_type_1 ltype; 81 // typedef geometry_type_2 rtype; 82 // typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; 83 // value_type linput_; 84 // value_type rinput_; 85 // insert_into_view_arg(linput_, lvalue_); 86 // insert_into_view_arg(rinput_, rvalue_); 87 // arbitrary_boolean_op<coordinate_type> abo; 88 // abo.execute(output_, linput_.begin(), linput_.end(), 89 // rinput_.begin(), rinput_.end(), op_type); 90 //} 91 92 template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type> execute_boolean_op(value_type & output_,const geometry_type_1 & lvalue_,const geometry_type_2 & rvalue_)93 void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { 94 typedef geometry_type_1 ltype; 95 typedef geometry_type_2 rtype; 96 typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; 97 value_type linput_; 98 value_type rinput_; 99 insert_into_view_arg(linput_, lvalue_); 100 insert_into_view_arg(rinput_, rvalue_); 101 polygon_45_set_data<coordinate_type> l45, r45, o45; 102 if(linput_.downcast(l45) && rinput_.downcast(r45)) { 103 //the op codes are screwed up between 45 and arbitrary 104 #ifdef BOOST_POLYGON_MSVC 105 #pragma warning (disable: 4127) 106 #endif 107 if(op_type < 2) 108 l45.template applyAdaptiveBoolean_<op_type>(o45, r45); 109 else if(op_type == 2) 110 l45.template applyAdaptiveBoolean_<3>(o45, r45); 111 else 112 l45.template applyAdaptiveBoolean_<2>(o45, r45); 113 #ifdef BOOST_POLYGON_MSVC 114 #pragma warning (default: 4127) 115 #endif 116 output_.insert(o45); 117 } else { 118 arbitrary_boolean_op<coordinate_type> abo; 119 abo.execute(output_, linput_.begin(), linput_.end(), 120 rinput_.begin(), rinput_.end(), op_type); 121 } 122 } 123 124 template <typename ltype, typename rtype, int op_type> 125 class polygon_set_view { 126 public: 127 typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; 128 typedef polygon_set_data<coordinate_type> value_type; 129 typedef typename value_type::iterator_type iterator_type; 130 typedef polygon_set_view operator_arg_type; 131 private: 132 const ltype& lvalue_; 133 const rtype& rvalue_; 134 mutable value_type output_; 135 mutable bool evaluated_; 136 polygon_set_view& operator=(const polygon_set_view&); 137 public: polygon_set_view(const ltype & lvalue,const rtype & rvalue)138 polygon_set_view(const ltype& lvalue, 139 const rtype& rvalue ) : 140 lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} 141 142 // get iterator to begin vertex data 143 public: value() const144 const value_type& value() const { 145 if(!evaluated_) { 146 evaluated_ = true; 147 execute_boolean_op<value_type, ltype, rtype, op_type>(output_, lvalue_, rvalue_); 148 } 149 return output_; 150 } 151 public: begin() const152 iterator_type begin() const { return value().begin(); } end() const153 iterator_type end() const { return value().end(); } 154 dirty() const155 bool dirty() const { return false; } //result of a boolean is clean sorted() const156 bool sorted() const { return true; } //result of a boolean is sorted 157 sort() const158 void sort() const {} //is always sorted 159 }; 160 161 template <typename ltype, typename rtype, int op_type> 162 typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type 163 polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: begin(const polygon_set_view<ltype,rtype,op_type> & polygon_set)164 begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { 165 return polygon_set.begin(); 166 } 167 template <typename ltype, typename rtype, int op_type> 168 typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type 169 polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: end(const polygon_set_view<ltype,rtype,op_type> & polygon_set)170 end(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { 171 return polygon_set.end(); 172 } 173 template <typename ltype, typename rtype, int op_type> 174 bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: clean(const polygon_set_view<ltype,rtype,op_type> &)175 clean(const polygon_set_view<ltype, rtype, op_type>& ) { 176 return true; } 177 template <typename ltype, typename rtype, int op_type> 178 bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: sort(const polygon_set_view<ltype,rtype,op_type> &)179 sort(const polygon_set_view<ltype, rtype, op_type>& ) { 180 return true; } 181 182 template <typename value_type, typename arg_type> insert_into_view_arg(value_type & dest,const arg_type & arg)183 inline void insert_into_view_arg(value_type& dest, const arg_type& arg) { 184 typedef typename polygon_set_traits<arg_type>::iterator_type literator; 185 literator itr1, itr2; 186 itr1 = polygon_set_traits<arg_type>::begin(arg); 187 itr2 = polygon_set_traits<arg_type>::end(arg); 188 dest.insert(itr1, itr2); 189 } 190 191 template <typename geometry_type_1, typename geometry_type_2, int op_type> 192 geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { 193 typedef geometry_type_1 ltype; 194 typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; 195 typedef polygon_set_data<coordinate_type> value_type; 196 value_type output_; 197 execute_boolean_op<value_type, geometry_type_1, geometry_type_2, op_type>(output_, lvalue_, rvalue_); 198 polygon_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end()); 199 return lvalue_; 200 } 201 202 // copy constructor 203 template <typename coordinate_type> 204 template <typename ltype, typename rtype, int op_type> polygon_set_data(const polygon_set_view<ltype,rtype,op_type> & that)205 polygon_set_data<coordinate_type>::polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that) : 206 data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {} 207 208 template <typename ltype, typename rtype, int op_type> 209 struct geometry_concept<polygon_set_view<ltype, rtype, op_type> > { typedef polygon_set_concept type; }; 210 } 211 } 212 #endif 213 214