Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62812 - in trunk/boost/polygon: . detail
From: lucanus.j.simonson_at_[hidden]
Date: 2010-06-11 14:55:45


Author: ljsimons
Date: 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
New Revision: 62812
URL: http://svn.boost.org/trac/boost/changeset/62812

Log:
fixing general polygon resizing bug, performance enhancement for manhattan resizing and inspect error report for apple macro verify collision
Text files modified:
   trunk/boost/polygon/detail/iterator_geometry_to_set.hpp | 14
   trunk/boost/polygon/detail/polygon_45_formation.hpp | 6
   trunk/boost/polygon/detail/polygon_arbitrary_formation.hpp | 31 +++
   trunk/boost/polygon/detail/polygon_formation.hpp | 2
   trunk/boost/polygon/detail/scan_arbitrary.hpp | 18 +-
   trunk/boost/polygon/point_data.hpp | 18 +
   trunk/boost/polygon/polygon_45_data.hpp | 2
   trunk/boost/polygon/polygon_45_set_data.hpp | 6
   trunk/boost/polygon/polygon_45_with_holes_data.hpp | 4
   trunk/boost/polygon/polygon_90_set_data.hpp | 304 +++++++++++++++++++++++++++++++++++++++
   trunk/boost/polygon/polygon_data.hpp | 2
   trunk/boost/polygon/polygon_set_data.hpp | 213 +++++++++++++++++++++++----
   trunk/boost/polygon/polygon_with_holes_data.hpp | 2
   13 files changed, 552 insertions(+), 70 deletions(-)

Modified: trunk/boost/polygon/detail/iterator_geometry_to_set.hpp
==============================================================================
--- trunk/boost/polygon/detail/iterator_geometry_to_set.hpp (original)
+++ trunk/boost/polygon/detail/iterator_geometry_to_set.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -29,7 +29,7 @@
 public:
   iterator_geometry_to_set() : rectangle_(), vertex_(), corner_(4), orient_(), is_hole_() {}
   iterator_geometry_to_set(const rectangle_type& rectangle, direction_1d dir,
- orientation_2d orient = HORIZONTAL, bool is_hole = false) :
+ orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) :
     rectangle_(), vertex_(), corner_(0), orient_(orient), is_hole_(is_hole) {
     assign(rectangle_, rectangle);
     if(dir == HIGH) corner_ = 4;
@@ -93,7 +93,7 @@
   int polygon_index;
 public:
   iterator_geometry_to_set() : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {}
- iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false) :
+ iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool winding_override = false, direction_1d w = CLOCKWISE) :
     vertex_(), itrb(), itre(), last_vertex_(),
     is_hole_(is_hole), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(),
     orient_(orient), polygon_index(0) {
@@ -103,7 +103,9 @@
     if(itrb == itre || dir == HIGH || size(polygon) < 4) {
       polygon_index = -1;
     } else {
- direction_1d wdir = winding(polygon);
+ direction_1d wdir = w;
+ if(!winding_override)
+ wdir = winding(polygon);
       multiplier_ = wdir == LOW ? -1 : 1;
       if(is_hole_) multiplier_ *= -1;
       first_pt = pts[0] = *itrb;
@@ -182,9 +184,7 @@
     vertex_.second.first =pts[1].get(orient_);
     if(pts[1] == pts[2]) {
       vertex_.second.second = 0;
- return;
- }
- if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) {
+ } else if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) {
       vertex_.second.second = -1;
     } else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) {
       vertex_.second.second = 1;
@@ -214,7 +214,7 @@
 public:
   iterator_geometry_to_set() : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {}
   iterator_geometry_to_set(const polygon_with_holes_type& polygon, direction_1d dir,
- orientation_2d orient = HORIZONTAL, bool is_hole = false) :
+ orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) :
     itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(orient), is_hole_(is_hole), started_holes() {
     itre = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, HIGH, orient, is_hole_);
     itrhe = end_holes(polygon);

Modified: trunk/boost/polygon/detail/polygon_45_formation.hpp
==============================================================================
--- trunk/boost/polygon/detail/polygon_45_formation.hpp (original)
+++ trunk/boost/polygon/detail/polygon_45_formation.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -474,7 +474,7 @@
       ct counts[4];
     };
 
- typedef Vertex45CountT<int> Vertex45Count;
+ typedef Vertex45CountT<signed char> Vertex45Count;
 
 // inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) {
 // o << c[0] << ", " << c[1] << ", ";
@@ -492,7 +492,8 @@
       inline Vertex45CompactT(const Point& point, int riseIn, int countIn) : pt(point), count() {
         count[riseIn+1] = countIn;
       }
- inline Vertex45CompactT(const Vertex45T& vertex) : pt(vertex.pt), count() {
+ template <typename ct2>
+ inline Vertex45CompactT(const typename boolean_op_45<Unit>::template Vertex45T<ct2>& vertex) : pt(vertex.pt), count() {
         count[vertex.rise+1] = vertex.count;
       }
       inline Vertex45CompactT(const Vertex45CompactT& vertex) : pt(vertex.pt), count(vertex.count) {}
@@ -2244,6 +2245,7 @@
   struct geometry_concept<PolyLine45PolygonData<T> > { typedef polygon_45_with_holes_concept type; };
   template <typename T>
   struct geometry_concept<PolyLine45HoleData<T> > { typedef polygon_45_concept type; };
+
 }
 }
 #endif

Modified: trunk/boost/polygon/detail/polygon_arbitrary_formation.hpp
==============================================================================
--- trunk/boost/polygon/detail/polygon_arbitrary_formation.hpp (original)
+++ trunk/boost/polygon/detail/polygon_arbitrary_formation.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -388,7 +388,8 @@
     struct compute_intersection_pack {
       typedef typename high_precision_type<Unit>::type high_precision;
       high_precision y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
- static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, bool projected = false) {
+ static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2,
+ bool projected = false, bool round_closest = false) {
         long double y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
         typedef rectangle_data<Unit> Rectangle;
         Rectangle rect1, rect2;
@@ -445,6 +446,10 @@
         //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
         //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
         //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
+ if(round_closest) {
+ x = x + 0.5;
+ y = y + 0.5;
+ }
         Unit x_unit = (Unit)(x);
         Unit y_unit = (Unit)(y);
         //truncate downward if it went up due to negative number
@@ -463,12 +468,17 @@
                                                (long double) (std::numeric_limits<Unit>::min)(),
                                                (long double)(std::numeric_limits<Unit>::max)(),
                                                (long double) (std::numeric_limits<Unit>::max)() );
- return contains(inf_rect, intersection, true);
+ if(contains(inf_rect, intersection, true)) {
+ intersection = result;
+ return true;
+ } else
+ return false;
         }
         intersection = result;
         return true;
       }
- inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, bool projected = false) {
+ inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2,
+ bool projected = false, bool round_closest = false) {
         if(!projected && !intersects(he1, he2))
            return false;
         bool lazy_success = compute_lazy_intersection(intersection, he1, he2, projected);
@@ -536,6 +546,10 @@
         //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
         //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
         //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
+ if(round_closest) {
+ x = x + (high_precision)0.5;
+ y = y + (high_precision)0.5;
+ }
         Unit x_unit = convert_high_precision_type<Unit>(x);
         Unit y_unit = convert_high_precision_type<Unit>(y);
         //truncate downward if it went up due to negative number
@@ -549,6 +563,17 @@
         Point result(x_unit, y_unit);
         if(!contains(rect1, result, true)) return false;
         if(!contains(rect2, result, true)) return false;
+ if(projected) {
+ rectangle_data<long double> inf_rect((long double)(std::numeric_limits<Unit>::min)(),
+ (long double) (std::numeric_limits<Unit>::min)(),
+ (long double)(std::numeric_limits<Unit>::max)(),
+ (long double) (std::numeric_limits<Unit>::max)() );
+ if(contains(inf_rect, intersection, true)) {
+ intersection = result;
+ return true;
+ } else
+ return false;
+ }
         intersection = result;
         return true;
       }

Modified: trunk/boost/polygon/detail/polygon_formation.hpp
==============================================================================
--- trunk/boost/polygon/detail/polygon_formation.hpp (original)
+++ trunk/boost/polygon/detail/polygon_formation.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -1721,7 +1721,7 @@
   unsigned int get_polygons(output_container& container, iterator_type begin, iterator_type end,
                     orientation_2d orient, bool fracture_holes, concept_type ) {
     typedef typename output_container::value_type polygon_type;
- typedef typename iterator_type::value_type::first_type coordinate_type;
+ typedef typename std::iterator_traits<iterator_type>::value_type::first_type coordinate_type;
     polygon_type poly;
     unsigned int countPolygons = 0;
     typedef typename geometry_concept<polygon_type>::type polygon_concept_type;

Modified: trunk/boost/polygon/detail/scan_arbitrary.hpp
==============================================================================
--- trunk/boost/polygon/detail/scan_arbitrary.hpp (original)
+++ trunk/boost/polygon/detail/scan_arbitrary.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -502,10 +502,10 @@
       std::map<Unit, std::set<iterator> > sloping_elements;
       std::set<iterator> merge_elements;
       for(typename std::vector<std::pair<Unit, iterator> >::iterator slop_iter = sloping_ends.begin();
- slop_iter = sloping_ends.end(); ++slop_iter) {
+ slop_iter == sloping_ends.end(); ++slop_iter) {
         //merge into sloping elements
         typename std::set<iterator>::iterator merge_iterator = merge_elements.find((*slop_iter).second);
- if(merge_iterator = merge_elements.end()) {
+ if(merge_iterator == merge_elements.end()) {
           merge_elements.insert((*slop_iter).second);
         } else {
           merge_elements.erase(merge_iterator);
@@ -517,7 +517,7 @@
       typename std::map<Unit, std::set<segment_id> >::iterator vertical_iter = vertical_data_.begin();
       typename std::map<Unit, std::set<iterator> >::iterator sloping_iter = sloping_elements.begin();
       for(typename std::set<Unit>::iterator position_iter = intersection_locations.begin();
- position_iter = intersection_locations.end(); ++position_iter) {
+ position_iter == intersection_locations.end(); ++position_iter) {
         //look for vertical segments that intersect this point and update them
         Unit y = *position_iter;
         Point pt(x_, y);
@@ -892,23 +892,23 @@
         return false;
       }
       edges.pop_back();
- edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), edges.size()));
+ edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), (segment_id)edges.size()));
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail3\n";
         return false;
       }
- edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), edges.size()));
+ edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), (segment_id)edges.size()));
       if(verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail4\n";
         return false;
       }
       edges.pop_back();
- edges.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), edges.size()));
+ edges.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), (segment_id)edges.size()));
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail5 " << result.first << " " << result.second << "\n";
         return false;
       }
- edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), edges.size()));
+ edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), (segment_id)edges.size()));
       if(verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail6 " << result.first << " " << result.second << "\n";
         return false;
@@ -1556,7 +1556,7 @@
       sl.scan(result, mof, pmd.begin(), pmd.end());
     }
 
- inline bool verify() {
+ inline bool verify1() {
       std::pair<int, int> offenders;
       std::vector<std::pair<half_edge, int> > lines;
       int count = 0;
@@ -2154,7 +2154,7 @@
       si.insert(poly, 444);
       result.clear();
       si.merge(result);
- si.verify();
+ si.verify1();
       print(stdcout, si.pmd) << std::endl;
       if(!result.empty()) {
         psd = (*(result.begin())).second;

Modified: trunk/boost/polygon/point_data.hpp
==============================================================================
--- trunk/boost/polygon/point_data.hpp (original)
+++ trunk/boost/polygon/point_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -34,17 +34,29 @@
 #endif
     { (*this) = that; }
     template <typename other>
- point_data(const other& that) : coords_() { (*this) = that; }
+ point_data(const other& that)
+#ifndef BOOST_POLYGON_MSVC
+ :coords_()
+#endif
+ { (*this) = that; }
     inline point_data& operator=(const point_data& that) {
       coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this;
     }
     template<typename T1, typename T2>
- inline point_data(const T1& x, const T2& y):coords_() {
+ inline point_data(const T1& x, const T2& y)
+#ifndef BOOST_POLYGON_MSVC
+ :coords_()
+#endif
+ {
       coords_[HORIZONTAL] = (coordinate_type)x;
       coords_[VERTICAL] = (coordinate_type)y;
     }
     template <typename T2>
- inline point_data(const point_data<T2>& rvalue):coords_() {
+ inline point_data(const point_data<T2>& rvalue)
+#ifndef BOOST_POLYGON_MSVC
+ :coords_()
+#endif
+ {
       coords_[HORIZONTAL] = (coordinate_type)(rvalue.x());
       coords_[VERTICAL] = (coordinate_type)(rvalue.y());
     }

Modified: trunk/boost/polygon/polygon_45_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_45_data.hpp (original)
+++ trunk/boost/polygon/polygon_45_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -62,7 +62,7 @@
 
   inline std::size_t size() const { return coords_.size(); }
 
-private:
+public:
   std::vector<point_data<coordinate_type> > coords_;
 };
 

Modified: trunk/boost/polygon/polygon_45_set_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_45_set_data.hpp (original)
+++ trunk/boost/polygon/polygon_45_set_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -1541,11 +1541,11 @@
       polygon_90_set_data<Unit> l90sd(VERTICAL), r90sd(VERTICAL), output(VERTICAL);
       for(typename value_type::const_iterator itr = data_.begin(); itr != data_.end(); ++itr) {
         if((*itr).count[3] == 0) continue; //skip all non vertical edges
- l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
+ l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
       }
       for(typename value_type::const_iterator itr = rvalue.data_.begin(); itr != rvalue.data_.end(); ++itr) {
         if((*itr).count[3] == 0) continue; //skip all non vertical edges
- r90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
+ r90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
       }
       l90sd.sort();
       r90sd.sort();
@@ -1673,7 +1673,7 @@
       polygon_90_set_data<Unit> l90sd(VERTICAL);
       for(typename value_type::const_iterator itr = data_.begin(); itr != data_.end(); ++itr) {
         if((*itr).count[3] == 0) continue; //skip all non vertical edges
- l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
+ l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL);
       }
       l90sd.sort();
 #ifdef BOOST_POLYGON_MSVC

Modified: trunk/boost/polygon/polygon_45_with_holes_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_45_with_holes_data.hpp (original)
+++ trunk/boost/polygon/polygon_45_with_holes_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -96,10 +96,12 @@
     return holes_.size();
   }
 
-private:
+public:
   polygon_45_data<coordinate_type> self_;
   std::list<hole_type> holes_;
 };
+
+
 }
 }
 #endif

Modified: trunk/boost/polygon/polygon_90_set_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_90_set_data.hpp (original)
+++ trunk/boost/polygon/polygon_90_set_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -244,6 +244,38 @@
     // get the scanline orientation of the polygon set
     inline orientation_2d orient() const { return orient_; }
 
+ polygon_90_set_data<coordinate_type>& operator-=(const polygon_90_set_data& that) {
+ sort();
+ that.sort();
+ value_type data;
+ std::swap(data, data_);
+ applyBooleanBinaryOp(data.begin(), data.end(),
+ that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryNot>());
+ return *this;
+ }
+ polygon_90_set_data<coordinate_type>& operator^=(const polygon_90_set_data& that) {
+ sort();
+ that.sort();
+ value_type data;
+ std::swap(data, data_);
+ applyBooleanBinaryOp(data.begin(), data.end(),
+ that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryXor>());
+ return *this;
+ }
+ polygon_90_set_data<coordinate_type>& operator&=(const polygon_90_set_data& that) {
+ sort();
+ that.sort();
+ value_type data;
+ std::swap(data, data_);
+ applyBooleanBinaryOp(data.begin(), data.end(),
+ that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryAnd>());
+ return *this;
+ }
+ polygon_90_set_data<coordinate_type>& operator|=(const polygon_90_set_data& that) {
+ insert(that);
+ return *this;
+ }
+
     void clean() const {
       sort();
       if(dirty_) {
@@ -297,7 +329,7 @@
     }
 
     polygon_90_set_data&
- bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
+ bloat2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) {
@@ -318,11 +350,257 @@
       return *this;
     }
 
+ static void modify_pt(point_data<coordinate_type>& pt, const point_data<coordinate_type>& prev_pt,
+ const point_data<coordinate_type>& current_pt, const point_data<coordinate_type>& next_pt,
+ coordinate_type west_bloating,
+ coordinate_type east_bloating,
+ coordinate_type south_bloating,
+ coordinate_type north_bloating) {
+ bool pxl = prev_pt.x() < current_pt.x();
+ bool pyl = prev_pt.y() < current_pt.y();
+ bool nxl = next_pt.x() < current_pt.x();
+ bool nyl = next_pt.y() < current_pt.y();
+ bool pxg = prev_pt.x() > current_pt.x();
+ bool pyg = prev_pt.y() > current_pt.y();
+ bool nxg = next_pt.x() > current_pt.x();
+ bool nyg = next_pt.y() > current_pt.y();
+ //two of the four if statements will execute
+ if(pxl)
+ pt.y(current_pt.y() - south_bloating);
+ if(pxg)
+ pt.y(current_pt.y() + north_bloating);
+ if(nxl)
+ pt.y(current_pt.y() + north_bloating);
+ if(nxg)
+ pt.y(current_pt.y() - south_bloating);
+ if(pyl)
+ pt.x(current_pt.x() + east_bloating);
+ if(pyg)
+ pt.x(current_pt.x() - west_bloating);
+ if(nyl)
+ pt.x(current_pt.x() - west_bloating);
+ if(nyg)
+ pt.x(current_pt.x() + east_bloating);
+ }
+ static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly,
+ coordinate_type west_bloating,
+ coordinate_type east_bloating,
+ coordinate_type south_bloating,
+ coordinate_type north_bloating) {
+ point_data<int> first_pt = poly[0];
+ point_data<int> second_pt = poly[1];
+ point_data<int> prev_pt = poly[0];
+ point_data<int> current_pt = poly[1];
+ for(int i = 2; i < poly.size(); ++i) {
+ point_data<int> next_pt = poly[i];
+ modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ }
+ point_data<int> next_pt = first_pt;
+ modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ next_pt = second_pt;
+ modify_pt(poly[0], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
+ remove_colinear_pts(poly);
+ }
+ static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly,
+ coordinate_type west_shrinking,
+ coordinate_type east_shrinking,
+ coordinate_type south_shrinking,
+ coordinate_type north_shrinking) {
+ rectangle_data<coordinate_type> extents_rectangle;
+ set_points(extents_rectangle, poly[0], poly[0]);
+ point_data<int> first_pt = poly[0];
+ point_data<int> second_pt = poly[1];
+ point_data<int> prev_pt = poly[0];
+ point_data<int> current_pt = poly[1];
+ encompass(extents_rectangle, current_pt);
+ for(int i = 2; i < poly.size(); ++i) {
+ point_data<int> next_pt = poly[i];
+ encompass(extents_rectangle, next_pt);
+ modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ }
+ if(delta(extents_rectangle, HORIZONTAL) < std::abs(west_shrinking + east_shrinking))
+ return false;
+ if(delta(extents_rectangle, VERTICAL) < std::abs(north_shrinking + south_shrinking))
+ return false;
+ point_data<int> next_pt = first_pt;
+ modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ next_pt = second_pt;
+ modify_pt(poly[0], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
+ return remove_colinear_pts(poly);
+ }
+
+ static bool remove_colinear_pts(std::vector<point_data<coordinate_type> >& poly) {
+ bool found_colinear = true;
+ while(found_colinear) {
+ found_colinear = false;
+ typename std::vector<point_data<coordinate_type> >::iterator itr = poly.begin();
+ itr += poly.size() - 1; //get last element position
+ typename std::vector<point_data<coordinate_type> >::iterator itr2 = poly.begin();
+ typename std::vector<point_data<coordinate_type> >::iterator itr3 = itr2;
+ ++itr3;
+ std::size_t count = 0;
+ for( ; itr3 < poly.end(); ++itr3) {
+ if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) ||
+ ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) {
+ ++count;
+ found_colinear = true;
+ } else {
+ itr = itr2;
+ ++itr2;
+ }
+ *itr2 = *itr3;
+ }
+ itr3 = poly.begin();
+ if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) ||
+ ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) {
+ ++count;
+ found_colinear = true;
+ }
+ poly.erase(poly.end() - count, poly.end());
+ }
+ return poly.size() >= 4;
+ }
+
+ polygon_90_set_data&
+ bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) {
+ std::list<polygon_45_with_holes_data<coordinate_type> > polys;
+ get(polys);
+ clear();
+ for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
+ itr != polys.end(); ++itr) {
+ //polygon_90_set_data<coordinate_type> psref;
+ //psref.insert(view_as<polygon_90_concept>((*itr).self_));
+ //rectangle_data<coordinate_type> prerect;
+ //psref.extents(prerect);
+ resize_poly_up((*itr).self_.coords_, west_bloating, east_bloating, south_bloating, north_bloating);
+ iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE),
+ end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE);
+ insert(begin_input, end_input, orient_);
+ //polygon_90_set_data<coordinate_type> pstest;
+ //pstest.insert(view_as<polygon_90_concept>((*itr).self_));
+ //psref.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
+ //if(!equivalence(psref, pstest)) {
+ // std::cout << "test failed\n";
+ //}
+ for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
+ itrh != (*itr).holes_.end(); ++itrh) {
+ //rectangle_data<coordinate_type> rect;
+ //psref.extents(rect);
+ //polygon_90_set_data<coordinate_type> psrefhole;
+ //psrefhole.insert(prerect);
+ //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
+ //polygon_45_data<coordinate_type> testpoly(*itrh);
+ if(resize_poly_down((*itrh).coords_, west_bloating, east_bloating, south_bloating, north_bloating)) {
+ iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ begin_input(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true),
+ end_input(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true);
+ insert(begin_input, end_input, orient_);
+ //polygon_90_set_data<coordinate_type> pstesthole;
+ //pstesthole.insert(rect);
+ //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ // begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true);
+ //pstesthole.insert(begin_input2, end_input, orient_);
+ //psrefhole.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
+ //if(!equivalence(psrefhole, pstesthole)) {
+ // std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
+ // std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
+ // polygon_90_set_data<coordinate_type> c(psrefhole);
+ // c.clean();
+ // polygon_90_set_data<coordinate_type> a(pstesthole);
+ // polygon_90_set_data<coordinate_type> b(pstesthole);
+ // a.sort();
+ // b.clean();
+ // std::cout << "test hole failed\n";
+ // //std::cout << testpoly << std::endl;
+ //}
+ }
+ }
+ }
+ return *this;
+ }
+
     polygon_90_set_data&
     shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) {
+ std::list<polygon_45_with_holes_data<coordinate_type> > polys;
+ get(polys);
+ clear();
+ for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
+ itr != polys.end(); ++itr) {
+ //polygon_90_set_data<coordinate_type> psref;
+ //psref.insert(view_as<polygon_90_concept>((*itr).self_));
+ //rectangle_data<coordinate_type> prerect;
+ //psref.extents(prerect);
+ //polygon_45_data<coordinate_type> testpoly((*itr).self_);
+ if(resize_poly_down((*itr).self_.coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking)) {
+ iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE),
+ end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE);
+ insert(begin_input, end_input, orient_);
+ //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ // begin_input2(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE);
+ //polygon_90_set_data<coordinate_type> pstest;
+ //pstest.insert(begin_input2, end_input, orient_);
+ //psref.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
+ //if(!equivalence(psref, pstest)) {
+ // std::cout << "test failed\n";
+ //}
+ for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
+ itrh != (*itr).holes_.end(); ++itrh) {
+ //rectangle_data<coordinate_type> rect;
+ //psref.extents(rect);
+ //polygon_90_set_data<coordinate_type> psrefhole;
+ //psrefhole.insert(prerect);
+ //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
+ //polygon_45_data<coordinate_type> testpoly(*itrh);
+ resize_poly_up((*itrh).coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking);
+ iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ begin_input(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true),
+ end_input(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true);
+ insert(begin_input, end_input, orient_);
+ //polygon_90_set_data<coordinate_type> pstesthole;
+ //pstesthole.insert(rect);
+ //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
+ // begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true);
+ //pstesthole.insert(begin_input2, end_input, orient_);
+ //psrefhole.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
+ //if(!equivalence(psrefhole, pstesthole)) {
+ // std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
+ // std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
+ // polygon_90_set_data<coordinate_type> c(psrefhole);
+ // c.clean();
+ // polygon_90_set_data<coordinate_type> a(pstesthole);
+ // polygon_90_set_data<coordinate_type> b(pstesthole);
+ // a.sort();
+ // b.clean();
+ // std::cout << "test hole failed\n";
+ // //std::cout << testpoly << std::endl;
+ //}
+ }
+ }
+ }
+ return *this;
+ }
+
+ polygon_90_set_data&
+ shrink2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking,
+ typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) {
       rectangle_data<coordinate_type> externalBoundary;
       if(!extents(externalBoundary)) return *this;
       ::boost::polygon::bloat(externalBoundary, 10); //bloat by diferential ammount
@@ -353,6 +631,30 @@
     }
 
     polygon_90_set_data&
+ shrink(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) {
+ if(dir == WEST)
+ return shrink(shrinking, 0, 0, 0);
+ if(dir == EAST)
+ return shrink(0, shrinking, 0, 0);
+ if(dir == SOUTH)
+ return shrink(0, 0, shrinking, 0);
+ if(dir == NORTH)
+ return shrink(0, 0, 0, shrinking);
+ }
+
+ polygon_90_set_data&
+ bloat(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) {
+ if(dir == WEST)
+ return bloat(shrinking, 0, 0, 0);
+ if(dir == EAST)
+ return bloat(0, shrinking, 0, 0);
+ if(dir == SOUTH)
+ return bloat(0, 0, shrinking, 0);
+ if(dir == NORTH)
+ return bloat(0, 0, 0, shrinking);
+ }
+
+ polygon_90_set_data&
     resize(coordinate_type west, coordinate_type east, coordinate_type south, coordinate_type north);
 
     polygon_90_set_data& move(coordinate_type x_delta, coordinate_type y_delta) {

Modified: trunk/boost/polygon/polygon_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_data.hpp (original)
+++ trunk/boost/polygon/polygon_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -60,7 +60,7 @@
 
   inline std::size_t size() const { return coords_.size(); }
 
-private:
+public:
   std::vector<point_data<coordinate_type> > coords_;
 };
 

Modified: trunk/boost/polygon/polygon_set_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_set_data.hpp (original)
+++ trunk/boost/polygon/polygon_set_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -120,38 +120,7 @@
 
     template <typename polygon_type>
     inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_concept ) {
- bool first_iteration = true;
- point_type first_point;
- point_type previous_point;
- point_type current_point;
- direction_1d winding_dir = winding(polygon_object);
- int multiplier = winding_dir == COUNTERCLOCKWISE ? 1 : -1;
- if(is_hole) multiplier *= -1;
- for(typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon_object);
- itr != end_points(polygon_object); ++itr) {
- assign(current_point, *itr);
- if(first_iteration) {
- first_iteration = false;
- first_point = previous_point = current_point;
- } else {
- if(previous_point != current_point) {
- element_type elem(edge_type(previous_point, current_point),
- ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
- insert_clean(elem);
- }
- }
- previous_point = current_point;
- }
- current_point = first_point;
- if(!first_iteration) {
- if(previous_point != current_point) {
- element_type elem(edge_type(previous_point, current_point),
- ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
- insert_clean(elem);
- }
- dirty_ = true;
- unsorted_ = true;
- }
+ insert_vertex_sequence(begin_points(polygon_object), end_points(polygon_object), winding(polygon_object), is_hole);
     }
 
     inline void insert(const polygon_set_data& ps, bool is_hole = false) {
@@ -229,13 +198,41 @@
 
     template <class iT>
     inline void insert_vertex_sequence(iT begin_vertex, iT end_vertex, direction_1d winding, bool is_hole) {
- polygon_data<coordinate_type> poly;
- poly.set(begin_vertex, end_vertex);
- insert(poly, is_hole);
+ bool first_iteration = true;
+ point_type first_point;
+ point_type previous_point;
+ point_type current_point;
+ direction_1d winding_dir = winding;
+ int multiplier = winding_dir == COUNTERCLOCKWISE ? 1 : -1;
+ if(is_hole) multiplier *= -1;
+ for( ; begin_vertex != end_vertex; ++begin_vertex) {
+ assign(current_point, *begin_vertex);
+ if(first_iteration) {
+ first_iteration = false;
+ first_point = previous_point = current_point;
+ } else {
+ if(previous_point != current_point) {
+ element_type elem(edge_type(previous_point, current_point),
+ ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
+ insert_clean(elem);
+ }
+ }
+ previous_point = current_point;
+ }
+ current_point = first_point;
+ if(!first_iteration) {
+ if(previous_point != current_point) {
+ element_type elem(edge_type(previous_point, current_point),
+ ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier);
+ insert_clean(elem);
+ }
+ dirty_ = true;
+ unsorted_ = true;
+ }
     }
 
     template <typename output_container>
- inline void get(output_container& output) {
+ inline void get(output_container& output) const {
       get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type());
     }
 
@@ -363,6 +360,13 @@
 
     inline polygon_set_data&
     resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0) {
+ if(!corner_fill_arc) {
+ if(resizing < 0)
+ return shrink(-resizing);
+ if(resizing > 0)
+ return bloat(-resizing);
+ return *this;
+ }
       if(resizing == 0) return *this;
       std::list<polygon_with_holes_data<coordinate_type> > pl;
       get(pl);
@@ -421,6 +425,139 @@
       return *this;
     }
 
+ static inline void compute_offset_edge(point_data<coordinate_type>& pt1, point_data<coordinate_type>& pt2,
+ const point_data<coordinate_type>& prev_pt,
+ const point_data<coordinate_type>& current_pt,
+ coordinate_type distance, int multiplier) {
+ coordinate_type dx = current_pt.x() - prev_pt.x();
+ coordinate_type dy = current_pt.y() - prev_pt.y();
+ double ddx = (double)dx;
+ double ddy = (double)dy;
+ double edge_length = std::sqrt(ddx*ddx + ddy*ddy);
+ double dnx = dy;
+ double dny = -dx;
+ dnx = dnx * (double)distance / edge_length;
+ dny = dny * (double)distance / edge_length;
+ dnx = std::floor(dnx+0.5);
+ dny = std::floor(dny+0.5);
+ pt1.x(prev_pt.x() + (coordinate_type)dnx * (coordinate_type)multiplier);
+ pt2.x(current_pt.x() + (coordinate_type)dnx * (coordinate_type)multiplier);
+ pt1.y(prev_pt.y() + (coordinate_type)dny * (coordinate_type)multiplier);
+ pt2.y(current_pt.y() + (coordinate_type)dny * (coordinate_type)multiplier);
+ }
+
+ static inline void modify_pt(point_data<coordinate_type>& pt, const point_data<coordinate_type>& prev_pt,
+ const point_data<coordinate_type>& current_pt, const point_data<coordinate_type>& next_pt,
+ coordinate_type distance, coordinate_type multiplier) {
+ std::pair<point_data<coordinate_type>, point_data<coordinate_type> > he1(prev_pt, current_pt), he2(current_pt, next_pt);
+ compute_offset_edge(he1.first, he1.second, prev_pt, current_pt, distance, multiplier);
+ compute_offset_edge(he2.first, he2.second, current_pt, next_pt, distance, multiplier);
+ typename scanline_base<coordinate_type>::compute_intersection_pack pack;
+ if(!pack.compute_lazy_intersection(pt, he1, he2, true, true)) {
+ pt = he1.second; //colinear offset edges use shared point
+ }
+ }
+
+ static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, coordinate_type distance, coordinate_type multiplier) {
+ point_data<int> first_pt = poly[0];
+ point_data<int> second_pt = poly[1];
+ point_data<int> prev_pt = poly[0];
+ point_data<int> current_pt = poly[1];
+ for(std::size_t i = 2; i < poly.size()-1; ++i) {
+ point_data<int> next_pt = poly[i];
+ modify_pt(poly[i-1], prev_pt, current_pt, next_pt, distance, multiplier);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ }
+ point_data<int> next_pt = first_pt;
+ modify_pt(poly[poly.size()-2], prev_pt, current_pt, next_pt, distance, multiplier);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ next_pt = second_pt;
+ modify_pt(poly[0], prev_pt, current_pt, next_pt, distance, multiplier);
+ poly.back() = poly.front();
+ }
+ static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly, coordinate_type distance, coordinate_type multiplier) {
+ std::vector<point_data<coordinate_type> > orig_poly(poly);
+ rectangle_data<coordinate_type> extents_rectangle;
+ set_points(extents_rectangle, poly[0], poly[0]);
+ point_data<int> first_pt = poly[0];
+ point_data<int> second_pt = poly[1];
+ point_data<int> prev_pt = poly[0];
+ point_data<int> current_pt = poly[1];
+ encompass(extents_rectangle, current_pt);
+ for(std::size_t i = 2; i < poly.size()-1; ++i) {
+ point_data<int> next_pt = poly[i];
+ encompass(extents_rectangle, next_pt);
+ modify_pt(poly[i-1], prev_pt, current_pt, next_pt, distance, multiplier);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ }
+ if(delta(extents_rectangle, HORIZONTAL) <= std::abs(2*distance))
+ return false;
+ if(delta(extents_rectangle, VERTICAL) <= std::abs(2*distance))
+ return false;
+ point_data<int> next_pt = first_pt;
+ modify_pt(poly[poly.size()-2], prev_pt, current_pt, next_pt, distance, multiplier);
+ prev_pt = current_pt;
+ current_pt = next_pt;
+ next_pt = second_pt;
+ modify_pt(poly[0], prev_pt, current_pt, next_pt, distance, multiplier);
+ poly.back() = poly.front();
+ //if the line segments formed between orignial and new points cross for an edge that edge inverts
+ //if all edges invert the polygon should be discarded
+ //if even one edge does not invert return true because the polygon is valid
+ bool non_inverting_edge = false;
+ for(std::size_t i = 1; i < poly.size(); ++i) {
+ std::pair<point_data<coordinate_type>, point_data<coordinate_type> >
+ he1(poly[i], orig_poly[i]),
+ he2(poly[i-1], orig_poly[i-1]);
+ if(!scanline_base<coordinate_type>::intersects(he1, he2)) {
+ non_inverting_edge = true;
+ break;
+ }
+ }
+ return non_inverting_edge;
+ }
+
+ polygon_set_data&
+ bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type distance) {
+ std::list<polygon_with_holes_data<coordinate_type> > polys;
+ get(polys);
+ clear();
+ for(typename std::list<polygon_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
+ itr != polys.end(); ++itr) {
+ resize_poly_up((*itr).self_.coords_, (coordinate_type)distance, (coordinate_type)1);
+ insert_vertex_sequence((*itr).self_.begin(), (*itr).self_.end(), COUNTERCLOCKWISE, false); //inserts without holes
+ for(typename std::list<polygon_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
+ itrh != (*itr).holes_.end(); ++itrh) {
+ if(resize_poly_down((*itrh).coords_, (coordinate_type)distance, (coordinate_type)1)) {
+ insert_vertex_sequence((*itrh).coords_.begin(), (*itrh).coords_.end(), CLOCKWISE, true);
+ }
+ }
+ }
+ return *this;
+ }
+
+ polygon_set_data&
+ shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type distance) {
+ std::list<polygon_with_holes_data<coordinate_type> > polys;
+ get(polys);
+ clear();
+ for(typename std::list<polygon_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
+ itr != polys.end(); ++itr) {
+ if(resize_poly_down((*itr).self_.coords_, (coordinate_type)distance, (coordinate_type)-1)) {
+ insert_vertex_sequence((*itr).self_.begin(), (*itr).self_.end(), COUNTERCLOCKWISE, false); //inserts without holes
+ for(typename std::list<polygon_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
+ itrh != (*itr).holes_.end(); ++itrh) {
+ resize_poly_up((*itrh).coords_, (coordinate_type)distance, (coordinate_type)-1);
+ insert_vertex_sequence((*itrh).coords_.begin(), (*itrh).coords_.end(), CLOCKWISE, true);
+ }
+ }
+ }
+ return *this;
+ }
+
     // TODO:: should be private
     template <typename geometry_type>
     inline polygon_set_data&
@@ -495,7 +632,9 @@
         double direction = normal1.x()*normal2.y()- normal2.x()*normal1.y();
         bool convex = direction>0;
  
- bool treat_as_concave = convex ^ sizing_sign ;
+ bool treat_as_concave = !convex;
+ if(sizing_sign)
+ treat_as_concave = convex;
         point_data<double> v;
         assign(v, normal1);
         double s2 = (v.x()*v.x()+v.y()*v.y());

Modified: trunk/boost/polygon/polygon_with_holes_data.hpp
==============================================================================
--- trunk/boost/polygon/polygon_with_holes_data.hpp (original)
+++ trunk/boost/polygon/polygon_with_holes_data.hpp 2010-06-11 14:55:42 EDT (Fri, 11 Jun 2010)
@@ -96,7 +96,7 @@
     return holes_.size();
   }
 
-private:
+public:
   polygon_data<coordinate_type> self_;
   std::list<hole_type> holes_;
   };


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk