void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_) { // convert Lines to Polylines Slic3r::Polylines polylines; polylines.reserve(subject.size()); for (Slic3r::Lines::const_iterator line = subject.begin(); line != subject.end(); ++line) polylines.push_back(*line); // perform operation _clipper(clipType, polylines, clip, &polylines, safety_offset_); // convert Polylines to Lines for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) retval->push_back(*polyline); }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_) { // transform input polygons into polylines Slic3r::Polylines polylines; polylines.reserve(subject.size()); for (Slic3r::Polygons::const_iterator polygon = subject.begin(); polygon != subject.end(); ++polygon) polylines.push_back(*polygon); // implicit call to split_at_first_point() // perform clipping _clipper(clipType, polylines, clip, retval, safety_offset_); /* If the split_at_first_point() call above happens to split the polygon inside the clipping area we would get two consecutive polylines instead of a single one, so we go through them in order to recombine continuous polylines. */ for (size_t i = 0; i < retval->size(); ++i) { for (size_t j = i+1; j < retval->size(); ++j) { if ((*retval)[i].points.back().coincides_with((*retval)[j].points.front())) { /* If last point of i coincides with first point of j, append points of j to i and delete j */ (*retval)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end()); retval->erase(retval->begin() + j); --j; } else if ((*retval)[i].points.front().coincides_with((*retval)[j].points.back())) { /* If first point of i coincides with last point of j, prepend points of j to i and delete j */ (*retval)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1); retval->erase(retval->begin() + j); --j; } else if ((*retval)[i].points.front().coincides_with((*retval)[j].points.front())) { /* Since Clipper does not preserve orientation of polylines, also check the case when first point of i coincides with first point of j. */ (*retval)[j].reverse(); (*retval)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1); retval->erase(retval->begin() + j); --j; } else if ((*retval)[i].points.back().coincides_with((*retval)[j].points.back())) { /* Since Clipper does not preserve orientation of polylines, also check the case when last point of i coincides with last point of j. */ (*retval)[j].reverse(); (*retval)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end()); retval->erase(retval->begin() + j); --j; } } } }