void ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const { // perform clipping Polylines clipped = intersection_pl(this->polyline, collection); return this->_inflate_collection(clipped, retval); }
void FillGyroid::_fill_surface_single( const FillParams ¶ms, unsigned int thickness_layers, const std::pair<float, Point> &direction, ExPolygon &expolygon, Polylines &polylines_out) { // no rotation is supported for this infill pattern BoundingBox bb = expolygon.contour.bounding_box(); coord_t distance = coord_t(scale_(this->spacing) / (params.density*this->scaling)); // align bounding box to a multiple of our grid module bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); // generate pattern Polylines polylines = make_gyroid_waves( scale_(this->z), params.density*this->scaling, this->spacing, ceil(bb.size().x / distance) + 1., ceil(bb.size().y / distance) + 1.); // move pattern in place for (Polyline &polyline : polylines) polyline.translate(bb.min.x, bb.min.y); // clip pattern to boundaries polylines = intersection_pl(polylines, (Polygons)expolygon); // connect lines if (! params.dont_connect && ! polylines.empty()) { // prevent calling leftmost_point() on empty collections ExPolygon expolygon_off; { ExPolygons expolygons_off = offset_ex(expolygon, (float)SCALED_EPSILON); if (! expolygons_off.empty()) { // When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island. assert(expolygons_off.size() == 1); std::swap(expolygon_off, expolygons_off.front()); } } Polylines chained = PolylineCollection::chained_path_from( std::move(polylines), PolylineCollection::leftmost_point(polylines), false); // reverse allowed bool first = true; for (Polyline &polyline : chained) { if (! first) { // Try to connect the lines. Points &pts_end = polylines_out.back().points; const Point &first_point = polyline.points.front(); const Point &last_point = pts_end.back(); // TODO: we should also check that both points are on a fill_boundary to avoid // connecting paths on the boundaries of internal regions // TODO: avoid crossing current infill path if (first_point.distance_to(last_point) <= 5 * distance && expolygon_off.contains(Line(last_point, first_point))) { // Append the polyline. pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end()); continue; } } // The lines cannot be connected. polylines_out.emplace_back(std::move(polyline)); first = false; } } }