static VALUE rbclipper_execute_internal(VALUE self, TClipType cliptype, VALUE subjfill, VALUE clipfill) { if (NIL_P(subjfill)) subjfill = ID2SYM(id_even_odd); if (NIL_P(clipfill)) clipfill = ID2SYM(id_even_odd); TPolyPolygon solution; XCLIPPER(self)->Execute((TClipType) cliptype, solution, sym_to_filltype(subjfill), sym_to_filltype(clipfill)); VALUE r = rb_ary_new(); for(TPolyPolygon::iterator i = solution.begin(); i != solution.end(); ++i) { VALUE sub = rb_ary_new(); for(TPolygon::iterator p = i->begin(); p != i->end(); ++p) { rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X), DBL2NUM(p->Y))); } rb_ary_push(r, sub); } return r; }
static void SetFromResult( CArea& area, const TPolyPolygon& pp, bool reverse = true ) { // delete existing geometry area.m_curves.clear(); for(unsigned int i = 0; i < pp.size(); i++) { const TPolygon& p = pp[i]; area.m_curves.push_back(CCurve()); CCurve &curve = area.m_curves.back(); SetFromResult(curve, p, reverse); } }
static void MakePolyPoly( const CArea& area, TPolyPolygon &pp, bool reverse = true ){ pp.clear(); for(std::list<CCurve>::const_iterator It = area.m_curves.begin(); It != area.m_curves.end(); It++) { pts_for_AddVertex.clear(); const CCurve& curve = *It; const CVertex* prev_vertex = NULL; for(std::list<CVertex>::const_iterator It2 = curve.m_vertices.begin(); It2 != curve.m_vertices.end(); It2++) { const CVertex& vertex = *It2; if(prev_vertex)AddVertex(vertex, prev_vertex); prev_vertex = &vertex; } TPolygon p; p.resize(pts_for_AddVertex.size()); if(reverse) { std::size_t i = pts_for_AddVertex.size() - 1;// clipper wants them the opposite way to CArea for(std::list<DoubleAreaPoint>::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++, i--) { p[i] = It->int_point(); } } else { unsigned int i = 0; for(std::list<DoubleAreaPoint>::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++, i++) { p[i] = It->int_point(); } } pp.push_back(p); } }
static void OffsetSpansWithObrounds(const CArea& area, TPolyPolygon &pp_new, double radius) { Clipper c; for(std::list<CCurve>::const_iterator It = area.m_curves.begin(); It != area.m_curves.end(); It++) { pts_for_AddVertex.clear(); const CCurve& curve = *It; const CVertex* prev_vertex = NULL; for(std::list<CVertex>::const_iterator It2 = curve.m_vertices.begin(); It2 != curve.m_vertices.end(); It2++) { const CVertex& vertex = *It2; if(prev_vertex) { MakeObround(prev_vertex->m_p, vertex, radius); TPolygon loopy_polygon; loopy_polygon.reserve(pts_for_AddVertex.size()); for(std::list<DoubleAreaPoint>::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++) { loopy_polygon.push_back(It->int_point()); } c.AddPath(loopy_polygon, ptSubject, true); pts_for_AddVertex.clear(); } prev_vertex = &vertex; } } pp_new.clear(); c.Execute(ctUnion, pp_new, pftNonZero, pftNonZero); // reverse all the resulting polygons TPolyPolygon copy = pp_new; pp_new.clear(); pp_new.resize(copy.size()); for(unsigned int i = 0; i < copy.size(); i++) { const TPolygon& p = copy[i]; TPolygon p_new; p_new.resize(p.size()); std::size_t size_minus_one = p.size() - 1; for(unsigned int j = 0; j < p.size(); j++)p_new[j] = p[size_minus_one - j]; pp_new[i] = p_new; } }
static void OffsetWithLoops(const TPolyPolygon &pp, TPolyPolygon &pp_new, double inwards_value) { Clipper c; bool inwards = (inwards_value > 0); bool reverse = false; double radius = -fabs(inwards_value); if(inwards) { // add a large square on the outside, to be removed later TPolygon p; p.push_back(DoubleAreaPoint(-10000.0, -10000.0).int_point()); p.push_back(DoubleAreaPoint(-10000.0, 10000.0).int_point()); p.push_back(DoubleAreaPoint(10000.0, 10000.0).int_point()); p.push_back(DoubleAreaPoint(10000.0, -10000.0).int_point()); c.AddPath(p, ptSubject, true); } else { reverse = true; } for(unsigned int i = 0; i < pp.size(); i++) { const TPolygon& p = pp[i]; pts_for_AddVertex.clear(); if(p.size() > 2) { if(reverse) { for(std::size_t j = p.size()-1; j > 1; j--)MakeLoop(p[j], p[j-1], p[j-2], radius); MakeLoop(p[1], p[0], p[p.size()-1], radius); MakeLoop(p[0], p[p.size()-1], p[p.size()-2], radius); } else { MakeLoop(p[p.size()-2], p[p.size()-1], p[0], radius); MakeLoop(p[p.size()-1], p[0], p[1], radius); for(unsigned int j = 2; j < p.size(); j++)MakeLoop(p[j-2], p[j-1], p[j], radius); } TPolygon loopy_polygon; loopy_polygon.reserve(pts_for_AddVertex.size()); for(std::list<DoubleAreaPoint>::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++) { loopy_polygon.push_back(It->int_point()); } c.AddPath(loopy_polygon, ptSubject, true); pts_for_AddVertex.clear(); } } //c.ForceOrientation(false); c.Execute(ctUnion, pp_new, pftNonZero, pftNonZero); if(inwards) { // remove the large square if(pp_new.size() > 0) { pp_new.erase(pp_new.begin()); } } else { // reverse all the resulting polygons TPolyPolygon copy = pp_new; pp_new.clear(); pp_new.resize(copy.size()); for(unsigned int i = 0; i < copy.size(); i++) { const TPolygon& p = copy[i]; TPolygon p_new; p_new.resize(p.size()); std::size_t size_minus_one = p.size() - 1; for(unsigned int j = 0; j < p.size(); j++)p_new[j] = p[size_minus_one - j]; pp_new[i] = p_new; } } }