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