Browse Source

Fix dense infill & internal bridge expansion

supermerill 3 months ago
parent
commit
7bf30904b6

+ 61 - 15
src/libslic3r/Fill/Fill.cpp

@@ -298,13 +298,14 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
 
     // Fill in a map of a region & surface to SurfaceFillParams.
     std::set<SurfaceFillParams>                         set_surface_params;
-    std::vector<std::vector<const SurfaceFillParams*>>     region_to_surface_params(layer.regions().size(), std::vector<const SurfaceFillParams*>());
-    SurfaceFillParams                                    params;
-    bool                                                 has_internal_voids = false;
+    std::vector<std::vector<const SurfaceFillParams*>>  region_to_surface_params(layer.regions().size(), std::vector<const SurfaceFillParams*>());
+    bool                                                has_internal_voids = false;
     for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id) {
         const LayerRegion  &layerm = *layer.regions()[region_id];
-		region_to_surface_params[region_id].assign(layerm.fill_surfaces().size(), nullptr);
-	    for (const Surface &surface : layerm.fill_surfaces())
+        region_to_surface_params[region_id].assign(layerm.fill_surfaces().size(), nullptr);
+        for (size_t idx_fill_srf=0; idx_fill_srf < layerm.fill_surfaces().size(); ++idx_fill_srf) {
+            const Surface &surface = layerm.fill_surfaces().at(idx_fill_srf);
+            SurfaceFillParams params;
             if (surface.surface_type == (stPosInternal | stDensVoid)) {
                 has_internal_voids = true;
             } else {
@@ -348,6 +349,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
                     if (region_config.infill_dense.get_bool()
                         && region_config.fill_density < 40
                         && surface.maxNbSolidLayersOnTop == 1) {
+                        assert(surface.has(stPosInternal | stDensSparse | stModBridge));
                         params.density = 0.42f;
                         is_denser = true;
                         is_bridge = true;
@@ -355,6 +357,8 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
                         params.priority = surface.priority;
                         params.dont_adjust = true; // keep the 42% density
                         params.connection = InfillConnection::icConnected;
+                    } else {
+                        assert(region_config.fill_density >= 40 || !surface.has(stPosInternal | stDensSparse | stModBridge));
                     }
                     if (params.density <= 0 && !is_denser)
                         continue;
@@ -463,10 +467,12 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
                 }
 
                 auto it_params = set_surface_params.find(params);
-                if (it_params == set_surface_params.end())
+                if (it_params == set_surface_params.end()) {
                     it_params = set_surface_params.insert(it_params, params);
-		        region_to_surface_params[region_id][&surface - &layerm.fill_surfaces().surfaces.front()] = &(*it_params);
+                }
+                region_to_surface_params[region_id][idx_fill_srf] = &(*it_params);
             }
+        }
     }
 
     surface_fills.reserve(set_surface_params.size());
@@ -577,13 +583,16 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
             else if (region_some_infill != -1)
                 region_id = region_some_infill;
             const LayerRegion& layerm = *layer.regions()[region_id];
-            for (SurfaceFill &surface_fill : surface_fills)
-                if (surface_fill.surface.surface_type == (stPosInternal | stDensVoid) && std::abs(layer.height - surface_fill.params.flow.height()) < EPSILON) {
+            for (SurfaceFill &surface_fill : surface_fills) {
+                if (surface_fill.surface.surface_type == (stPosInternal | stDensVoid) &&
+                    std::abs(layer.height - surface_fill.params.flow.height()) < EPSILON) {
                     internal_solid_fill = &surface_fill;
                     break;
                 }
+            }
             if (internal_solid_fill == nullptr) {
                 // Produce another solid fill.
+                SurfaceFillParams params;
                 params.extruder = layerm.region().extruder(frSolidInfill, *layer.object());
                 params.pattern  = layerm.region().config().solid_fill_pattern.value;
                 params.density  = 100.f;
@@ -1208,19 +1217,25 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
         // expolygons are copied from surface(s) to surface_fill by group_fills
         assert_valid(surface_fill.expolygons);
         assert(surface_fill.surface.expolygon.empty());
-		if (surface_fill.surface.surface_type != (stPosInternal | stDensSparse)) {
-			continue;
-		}
+        if (!surface_fill.surface.has(stPosInternal | stDensSparse)) {
+            continue;
+        }
 
         switch (surface_fill.params.pattern) {
         case ipCount: continue; break;
         case ipSupportBase: continue; break;
         case ipEnsuring: continue; break;
+        case ipSmooth: assert(false); continue; break; // it's supposed to be solid
         case ipLightning:
-		case ipAdaptiveCubic:
+        case ipAdaptiveCubic:
         case ipSupportCubic:
         case ipRectilinear:
+        case ipRectilinearWGapFill:
+        case ipRectiWithPerimeter:
+        case ipSawtooth:
+        case ipScatteredRectilinear:
         case ipMonotonic:
+        case ipMonotonicWGapFill:
         case ipMonotonicLines:
         case ipAlignedRectilinear:
         case ipGrid:
@@ -1229,17 +1244,31 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
         case ipCubic:
         case ipLine:
         case ipConcentric:
+        case ipConcentricGapFill:
         case ipHoneycomb:
         case ip3DHoneycomb:
         case ipGyroid:
         case ipHilbertCurve:
         case ipArchimedeanChords:
         case ipOctagramSpiral: break;
+        default: {
+                // all pattern should be in this list
+                assert(false);
+                continue; break;
+            }
         }
         LayerRegion &layerm = *m_regions[surface_fill.region_id];
 
         // Create the filler object.
         std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
+        if (surface_fill.surface.has(stPosInternal | stDensSparse | stModBridge) && surface_fill.params.density < 40) {
+            assert(surface_fill.params.config);
+            assert(surface_fill.params.config->infill_dense.get_bool());
+            assert(surface_fill.surface.maxNbSolidLayersOnTop == 1);
+            assert(ipRectiWithPerimeter == surface_fill.params.pattern);
+            // dense infill : ipRectiWithPerimeter
+            //f = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter));
+        }
         f->set_bounding_box(bbox);
         f->layer_id = this->id() - this->object()->get_layer(0)->id(); // We need to subtract raft layers.
         f->z        = this->print_z;
@@ -1283,7 +1312,22 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
         for (ExPolygon &expoly : surface_fill.expolygons) {
             surface_fill.surface.expolygon = std::move(expoly);
             try {
-                Polylines polylines = f->fill_surface(&surface_fill.surface, params);
+                Polylines polylines;
+                if (f->can_fill_surface_single) {
+                    polylines = f->fill_surface(&surface_fill.surface, params);
+                } else {
+                    ExtrusionEntityCollection coll;
+                    f->fill_surface_extrusion(&surface_fill.surface, params, coll.set_entities());
+                    //extract polylines from paths
+                    GetPathsVisitor visitor;
+                    coll.visit(visitor);
+                    for (ExtrusionPath *path : visitor.paths) {
+                        polylines.push_back(path->as_polyline().to_polyline());
+                    }
+                    for (ExtrusionPath3D *path : visitor.paths3D) {
+                        polylines.push_back(path->as_polyline().to_polyline());
+                    }
+                }
                 sparse_infill_polylines.insert(sparse_infill_polylines.end(), polylines.begin(), polylines.end());
             } catch (InfillFailedException &) {}
         }
@@ -1458,7 +1502,9 @@ void Layer::make_ironing()
                     bool internal_infill_solid = region_config.fill_density.value > 95.;
 					for (const Surface &surface : ironing_params.layerm->fill_surfaces())
                         // stInternal or stInternalBridge or stInternalVoid
-                        if ((!internal_infill_solid && surface.surface_type == (stPosInternal | stDensSparse)) || surface.surface_type == (stPosInternal | stDensSolid | stModBridge) || surface.surface_type == (stPosInternal | stDensVoid)) {
+                        if ((!internal_infill_solid && surface.has(stPosInternal | stDensSparse)) ||
+                            surface.surface_type == (stPosInternal | stDensSolid | stModBridge) ||
+                            surface.has(stPosInternal | stDensVoid)) {
                             // Some fill region is not quite solid. Don't iron over the whole surface.
                             iron_completely = false;
                             break;

+ 1 - 0
src/libslic3r/Fill/Fill3DHoneycomb.hpp

@@ -17,6 +17,7 @@ namespace Slic3r {
 class Fill3DHoneycomb : public Fill
 {
 public:
+    Fill3DHoneycomb() : Fill() { can_fill_surface_single = true; }
     Fill* clone() const override { return new Fill3DHoneycomb(*this); };
     ~Fill3DHoneycomb() override {}
 

+ 1 - 0
src/libslic3r/Fill/FillAdaptive.hpp

@@ -60,6 +60,7 @@ FillAdaptive::OctreePtr         build_octree(
 class Filler : public Slic3r::Fill
 {
 public:
+    Filler() : Fill() { can_fill_surface_single = true; }
     ~Filler() override {}
 
 protected:

+ 2 - 0
src/libslic3r/Fill/FillBase.hpp

@@ -134,6 +134,8 @@ public:
     coord_t     loop_clipping;
     // In scaled coordinates. Bounding box of the 2D projection of the object.
     BoundingBox bounding_box;
+    // true if it's possibel to call fill_surface instead of fill_surface_extrusion
+    float       can_fill_surface_single = false;
 
     // Octree builds on mesh for usage in the adaptive cubic infill
     FillAdaptive::Octree* adapt_fill_octree = nullptr;

+ 1 - 0
src/libslic3r/Fill/FillConcentric.hpp

@@ -18,6 +18,7 @@ namespace Slic3r {
 class FillConcentric : public Fill
 {
 public:
+    FillConcentric() : Fill() { can_fill_surface_single = true; }
     ~FillConcentric() override = default;
 
 protected:

+ 1 - 1
src/libslic3r/Fill/FillGyroid.hpp

@@ -16,7 +16,7 @@ namespace Slic3r {
 class FillGyroid : public Fill
 {
 public:
-    FillGyroid() {}
+    FillGyroid() : Fill() { can_fill_surface_single = true; }
     Fill* clone() const override { return new FillGyroid(*this); }
 
     // Density adjustment to have a good %of weight.

+ 1 - 0
src/libslic3r/Fill/FillHoneycomb.hpp

@@ -21,6 +21,7 @@ namespace Slic3r {
 class FillHoneycomb : public Fill
 {
 public:
+    FillHoneycomb() : Fill() { can_fill_surface_single = true; }
     ~FillHoneycomb() override {}
 
 protected:

+ 1 - 0
src/libslic3r/Fill/FillLightning.hpp

@@ -23,6 +23,7 @@ GeneratorPtr build_generator(const PrintObject &print_object, const coordf_t fil
 class Filler : public Slic3r::Fill
 {
 public:
+    Filler() : Fill() { can_fill_surface_single = true; }
     ~Filler() override = default;
 
     Generator   *generator { nullptr };

+ 1 - 0
src/libslic3r/Fill/FillLine.hpp

@@ -17,6 +17,7 @@ class Surface;
 class FillLine : public Fill
 {
 public:
+    FillLine() : Fill() { can_fill_surface_single = true; }
     Fill* clone() const override { return new FillLine(*this); };
     ~FillLine() override = default;
 

+ 1 - 0
src/libslic3r/Fill/FillPlanePath.hpp

@@ -25,6 +25,7 @@ namespace Slic3r {
 class FillPlanePath : public Fill
 {
 public:
+    FillPlanePath() : Fill() { can_fill_surface_single = true; }
     ~FillPlanePath() override = default;
 
 protected:

Some files were not shown because too many files changed in this diff