diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index cb8e393d5..c1822ce87 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -350,6 +350,50 @@ void Layer::export_region_fill_surfaces_to_svg_debug(const char *name) const this->export_region_fill_surfaces_to_svg(debug_out_path("Layer-fill_surfaces-%s-%d.svg", name, idx ++).c_str()); } +coordf_t Layer::get_sparse_infill_max_void_area() +{ + double max_void_area = 0.; + for (auto layerm : m_regions) { + Flow flow = layerm->flow(frInfill); + float density = layerm->region().config().sparse_infill_density; + InfillPattern pattern = layerm->region().config().sparse_infill_pattern; + if (density == 0.) + return -1; + + //BBS: rough estimation and need to be optimized + double spacing = flow.scaled_spacing() * (100 - density) / density; + switch (pattern) { + case ipConcentric: + case ipRectilinear: + case ipLine: + case ipGyroid: + case ipAlignedRectilinear: + case ipOctagramSpiral: + case ipHilbertCurve: + case ip3DHoneycomb: + case ipArchimedeanChords: + max_void_area = std::max(max_void_area, spacing * spacing); + break; + case ipGrid: + case ipHoneycomb: + case ipLightning: + max_void_area = std::max(max_void_area, 4.0 * spacing * spacing); + break; + case ipCubic: + case ipAdaptiveCubic: + case ipTriangles: + case ipStars: + case ipSupportCubic: + max_void_area = std::max(max_void_area, 4.5 * spacing * spacing); + break; + default: + max_void_area = std::max(max_void_area, spacing * spacing); + break; + } + }; + return max_void_area; +} + BoundingBox get_extents(const LayerRegion &layer_region) { BoundingBox bbox; diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 3440e404a..69b8fb99f 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -184,6 +184,8 @@ public: //BBS void simplify_extrusion_path() { for (auto layerm : m_regions) layerm->simplify_extrusion_entity();} + //BBS: this function calculate the maximum void grid area of sparse infill of this layer. Just estimated value + coordf_t get_sparse_infill_max_void_area(); protected: friend class PrintObject; diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index a0fe6dadd..f66ba002c 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -152,11 +152,20 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly { // Voids are sparse infills if infill rate is zero. Polygons voids; + + double max_grid_area = -1; + if (this->layer()->lower_layer != nullptr) + max_grid_area = this->layer()->lower_layer->get_sparse_infill_max_void_area(); for (const Surface &surface : this->fill_surfaces.surfaces) { if (surface.is_top()) { // Collect the top surfaces, inflate them and trim them by the bottom surfaces. // This gives the priority to bottom surfaces. - surfaces_append(top, offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); + if (max_grid_area < 0 || surface.expolygon.area() < max_grid_area) + surfaces_append(top, offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); + else + //BBS: Don't need to expand too much in this situation. Expand 3mm to eliminate hole and 1mm for contour + surfaces_append(top, intersection_ex(offset(surface.expolygon.contour, margin / 3.0, EXTERNAL_SURFACES_OFFSET_PARAMETERS), + offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS)), surface); } else if (surface.surface_type == stBottom || (surface.surface_type == stBottomBridge && lower_layer == nullptr)) { // Grown by 3mm. surfaces_append(bottom, offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);