Commit 746dea5a authored by jean-pierre charras's avatar jean-pierre charras
Browse files

Pcbnew: fix a serious bug in ZONE_CONTAINER::HitTestFilledArea( ) which could...

Pcbnew: fix a serious bug in ZONE_CONTAINER::HitTestFilledArea( ) which could break connectivity calculations relative to copper areas.
Fix also very minor issues relative to copper zones.
Update boost::polygon from Boost svn repository.
parent 3dbae0b8
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -253,8 +253,13 @@ public:
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
          ++itrhb;
        } else {
          itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
          //in this case we have no holes so we just need the iterhib == itrhie, which
          //is always true if they were default initialized in the initial case or
          //both point to end of the previous hole processed
          //no need to explicitly reset them, and it causes an stl debug assertion to use
          //the default constructed iterator this way
          //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
          //  typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
        }
      } else {
        ++itrhib;
@@ -266,8 +271,9 @@ public:
              typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
            ++itrhb;
          } else {
            itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
              typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
            //this is the same case as above
            //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
            //  typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
          }
        }
      }
+125 −0
Original line number Diff line number Diff line

namespace boost { namespace polygon { namespace detail {

template <typename coordinate_type>
struct minkowski_offset {
  typedef point_data<coordinate_type> point;
  typedef polygon_set_data<coordinate_type> polygon_set;
  typedef polygon_with_holes_data<coordinate_type> polygon;
  typedef std::pair<point, point> edge;

  static void convolve_two_segments(std::vector<point>& figure, const edge& a, const edge& b) {
    figure.clear();
    figure.push_back(point(a.first));
    figure.push_back(point(a.first));
    figure.push_back(point(a.second));
    figure.push_back(point(a.second));
    convolve(figure[0], b.second);
    convolve(figure[1], b.first);
    convolve(figure[2], b.first);
    convolve(figure[3], b.second);
  }

  template <typename itrT1, typename itrT2>
  static void convolve_two_point_sequences(polygon_set& result, itrT1 ab, itrT1 ae, itrT2 bb, itrT2 be) {
    if(ab == ae || bb == be)
      return;
    point first_a = *ab;
    point prev_a = *ab;
    std::vector<point> vec;
    polygon poly;
    ++ab;
    for( ; ab != ae; ++ab) {
      point first_b = *bb;
      point prev_b = *bb;
      itrT2 tmpb = bb;
      ++tmpb;
      for( ; tmpb != be; ++tmpb) {
        convolve_two_segments(vec, std::make_pair(prev_b, *tmpb), std::make_pair(prev_a, *ab));
        set_points(poly, vec.begin(), vec.end());
        result.insert(poly);
        prev_b = *tmpb;
      }
      prev_a = *ab;
    }
  }

  template <typename itrT>
  static void convolve_point_sequence_with_polygons(polygon_set& result, itrT b, itrT e, const std::vector<polygon>& polygons) {
    for(std::size_t i = 0; i < polygons.size(); ++i) {
      convolve_two_point_sequences(result, b, e, begin_points(polygons[i]), end_points(polygons[i]));
      for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(polygons[i]);
          itrh != end_holes(polygons[i]); ++itrh) {
        convolve_two_point_sequences(result, b, e, begin_points(*itrh), end_points(*itrh));
      }
    }
  }

  static void convolve_two_polygon_sets(polygon_set& result, const polygon_set& a, const polygon_set& b) {
    result.clear();
    std::vector<polygon> a_polygons;
    std::vector<polygon> b_polygons;
    a.get(a_polygons);
    b.get(b_polygons);
    for(std::size_t ai = 0; ai < a_polygons.size(); ++ai) {
      convolve_point_sequence_with_polygons(result, begin_points(a_polygons[ai]), 
                                            end_points(a_polygons[ai]), b_polygons);
      for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(a_polygons[ai]);
          itrh != end_holes(a_polygons[ai]); ++itrh) {
        convolve_point_sequence_with_polygons(result, begin_points(*itrh), 
                                              end_points(*itrh), b_polygons);
      }
      for(std::size_t bi = 0; bi < b_polygons.size(); ++bi) {
        polygon tmp_poly = a_polygons[ai];
        result.insert(convolve(tmp_poly, *(begin_points(b_polygons[bi]))));
        tmp_poly = b_polygons[bi];
        result.insert(convolve(tmp_poly, *(begin_points(a_polygons[ai]))));
      }
    }
  }
};

}
  template<typename T>
  inline polygon_set_data<T>&
  polygon_set_data<T>::resize(coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments) {
    using namespace ::boost::polygon::operators;
    if(!corner_fill_arc) {
      if(resizing < 0)
        return shrink(-resizing);
      if(resizing > 0)
        return bloat(resizing);
      return *this;
    }
    if(resizing == 0) return *this;
    if(empty()) return *this;
    if(num_circle_segments < 3) num_circle_segments = 4;
    rectangle_data<coordinate_type> rect;
    extents(rect);
    if(resizing < 0) {
      ::boost::polygon::bloat(rect, 10);
      (*this) = rect - (*this); //invert
    }
    //make_arc(std::vector<point_data< T> >& return_points,  
    //point_data< double> start, point_data< double>  end,
    //point_data< double> center,  double r, unsigned int num_circle_segments)      
    std::vector<point_data<coordinate_type> > circle;
    point_data<double> center(0.0, 0.0), start(0.0, (double)resizing);
    make_arc(circle, start, start, center, std::abs((double)resizing),
             num_circle_segments);
    polygon_data<coordinate_type> poly;
    set_points(poly, circle.begin(), circle.end());
    polygon_set_data<coordinate_type> offset_set;
    offset_set += poly;
    polygon_set_data<coordinate_type> result;
    detail::minkowski_offset<coordinate_type>::convolve_two_polygon_sets
      (result, *this, offset_set);
    if(resizing < 0) {
      result = result & rect;//eliminate overhang
      result = result ^ rect;//invert
    }
    *this = result;
    return *this;
  }

}}
+1 −1
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ namespace boost { namespace polygon{
      ct counts[4];
    };

    typedef Vertex45CountT<signed char> Vertex45Count;
    typedef Vertex45CountT<int> Vertex45Count;

//     inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) {
//       o << c[0] << ", " << c[1] << ", ";
+27 −11
Original line number Diff line number Diff line
@@ -455,6 +455,10 @@ namespace boost { namespace polygon{
        //truncate downward if it went up due to negative number
        if(x < x_unit) --x_unit;
        if(y < y_unit) --y_unit;
        if(is_horizontal(he1))
          y_unit = he1.first.y();
        if(is_horizontal(he2))
          y_unit = he2.first.y();
        //if(x != exp_x || y != exp_y)
        //  std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl;
        //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
@@ -464,11 +468,11 @@ namespace boost { namespace polygon{
        if(!projected && !contains(rect1, result, true)) return false;
        if(!projected && !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)(), 
          rectangle_data<long double> inf_rect(-(long double)(std::numeric_limits<Unit>::max)(), 
                                               -(long double) (std::numeric_limits<Unit>::max)(), 
                                               (long double)(std::numeric_limits<Unit>::max)(), 
                                               (long double) (std::numeric_limits<Unit>::max)() );
          if(contains(inf_rect, intersection, true)) {
          if(contains(inf_rect, point_data<long double>(x, y), true)) {
            intersection = result;
            return true;
          } else
@@ -477,6 +481,7 @@ namespace boost { namespace polygon{
        intersection = result;
        return true;
      }

      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))
@@ -491,6 +496,13 @@ namespace boost { namespace polygon{
        } else {
          return lazy_success;
        }
        return compute_exact_intersection(intersection, he1, he2, projected, round_closest);
      }

      inline bool compute_exact_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;
        typedef rectangle_data<Unit> Rectangle;
        Rectangle rect1, rect2;
        set_points(rect1, he1.first, he1.second);
@@ -542,6 +554,7 @@ namespace boost { namespace polygon{
        y_den = (dx1 * dy2 - dx2 * dy1);
        x = x_num / x_den;
        y = y_num / y_den;
	//std::cout << x << " " << y << std::endl;
        //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << std::endl;
        //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
        //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
@@ -555,6 +568,10 @@ namespace boost { namespace polygon{
        //truncate downward if it went up due to negative number
        if(x < (high_precision)x_unit) --x_unit;
        if(y < (high_precision)y_unit) --y_unit;
        if(is_horizontal(he1))
          y_unit = he1.first.y();
        if(is_horizontal(he2))
          y_unit = he2.first.y();
        //if(x != exp_x || y != exp_y)
        //  std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl;
        //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
@@ -564,14 +581,9 @@ namespace boost { namespace polygon{
        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
          high_precision b1 = (high_precision) (std::numeric_limits<Unit>::min)();
          high_precision b2 = (high_precision) (std::numeric_limits<Unit>::max)();
          if(x > b2 || y > b2 || x < b1 || y < b1)
            return false;
        }
        intersection = result;
@@ -641,6 +653,10 @@ namespace boost { namespace polygon{
      //truncate downward if it went up due to negative number
      if(x < (high_precision)x_unit) --x_unit;
      if(y < (high_precision)y_unit) --y_unit;
      if(is_horizontal(he1))
        y_unit = he1.first.y();
      if(is_horizontal(he2))
        y_unit = he2.first.y();
      //if(x != exp_x || y != exp_y)
      //  std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl;
      //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
+1 −1
Original line number Diff line number Diff line
@@ -125,5 +125,5 @@ namespace boost { namespace polygon {

}
}

//==
#endif
Loading