]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
14 | 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 <> | |
45 | 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> | |
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 (push) | |
106 | //#pragma warning (disable: 4127) | |
107 | //#endif | |
108 | // if(op_type < 2) | |
109 | // l45.template applyAdaptiveBoolean_<op_type>(o45, r45); | |
110 | // else if(op_type == 2) | |
111 | // l45.template applyAdaptiveBoolean_<3>(o45, r45); | |
112 | // else | |
113 | // l45.template applyAdaptiveBoolean_<2>(o45, r45); | |
114 | //#ifdef BOOST_POLYGON_MSVC | |
115 | //#pragma warning (pop) | |
116 | //#endif | |
117 | // output_.insert(o45); | |
118 | // } else { | |
119 | arbitrary_boolean_op<coordinate_type> abo; | |
120 | abo.execute(output_, linput_.begin(), linput_.end(), | |
121 | rinput_.begin(), rinput_.end(), op_type); | |
122 | // } | |
123 | } | |
124 | ||
125 | template <typename ltype, typename rtype, int op_type> | |
126 | class polygon_set_view { | |
127 | public: | |
128 | typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; | |
129 | typedef polygon_set_data<coordinate_type> value_type; | |
130 | typedef typename value_type::iterator_type iterator_type; | |
131 | typedef polygon_set_view operator_arg_type; | |
132 | private: | |
133 | const ltype& lvalue_; | |
134 | const rtype& rvalue_; | |
135 | mutable value_type output_; | |
136 | mutable bool evaluated_; | |
137 | polygon_set_view& operator=(const polygon_set_view&); | |
138 | public: | |
139 | polygon_set_view(const ltype& lvalue, | |
140 | const rtype& rvalue ) : | |
141 | lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} | |
142 | ||
143 | // get iterator to begin vertex data | |
144 | public: | |
145 | const value_type& value() const { | |
146 | if(!evaluated_) { | |
147 | evaluated_ = true; | |
148 | execute_boolean_op<value_type, ltype, rtype, op_type>(output_, lvalue_, rvalue_); | |
149 | } | |
150 | return output_; | |
151 | } | |
152 | public: | |
153 | iterator_type begin() const { return value().begin(); } | |
154 | iterator_type end() const { return value().end(); } | |
155 | ||
156 | bool dirty() const { return false; } //result of a boolean is clean | |
157 | bool sorted() const { return true; } //result of a boolean is sorted | |
158 | ||
159 | void sort() const {} //is always sorted | |
160 | }; | |
161 | ||
162 | template <typename ltype, typename rtype, int op_type> | |
163 | typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type | |
164 | polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: | |
165 | begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { | |
166 | return polygon_set.begin(); | |
167 | } | |
168 | template <typename ltype, typename rtype, int op_type> | |
169 | typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type | |
170 | polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: | |
171 | end(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { | |
172 | return polygon_set.end(); | |
173 | } | |
174 | template <typename ltype, typename rtype, int op_type> | |
175 | bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: | |
176 | clean(const polygon_set_view<ltype, rtype, op_type>& ) { | |
177 | return true; } | |
178 | template <typename ltype, typename rtype, int op_type> | |
179 | bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: | |
180 | sort(const polygon_set_view<ltype, rtype, op_type>& ) { | |
181 | return true; } | |
182 | ||
183 | template <typename value_type, typename arg_type> | |
184 | inline void insert_into_view_arg(value_type& dest, const arg_type& arg) { | |
185 | typedef typename polygon_set_traits<arg_type>::iterator_type literator; | |
186 | literator itr1, itr2; | |
187 | itr1 = polygon_set_traits<arg_type>::begin(arg); | |
188 | itr2 = polygon_set_traits<arg_type>::end(arg); | |
189 | dest.insert(itr1, itr2); | |
190 | } | |
191 | ||
192 | template <typename geometry_type_1, typename geometry_type_2, int op_type> | |
193 | geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { | |
194 | typedef geometry_type_1 ltype; | |
195 | typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; | |
196 | typedef polygon_set_data<coordinate_type> value_type; | |
197 | value_type output_; | |
198 | execute_boolean_op<value_type, geometry_type_1, geometry_type_2, op_type>(output_, lvalue_, rvalue_); | |
199 | polygon_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end()); | |
200 | return lvalue_; | |
201 | } | |
202 | ||
203 | // copy constructor | |
204 | template <typename coordinate_type> | |
205 | template <typename ltype, typename rtype, int op_type> | |
206 | polygon_set_data<coordinate_type>::polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that) : | |
207 | data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {} | |
208 | ||
209 | // equivalence operator | |
210 | template <typename coordinate_type> | |
211 | inline bool polygon_set_data<coordinate_type>::operator==(const polygon_set_data<coordinate_type>& p) const { | |
212 | typedef polygon_set_data<coordinate_type> value_type; | |
213 | value_type output_; | |
214 | execute_boolean_op<value_type, value_type, value_type, 2>(output_, (*this), p); | |
215 | return output_.data_.empty(); | |
216 | } | |
217 | ||
218 | template <typename ltype, typename rtype, int op_type> | |
219 | struct geometry_concept<polygon_set_view<ltype, rtype, op_type> > { typedef polygon_set_concept type; }; | |
220 | } | |
221 | } | |
222 | #endif |