Browse Source

Fix too detailed gapfill
* add resolution_internal to control it (and gyroid)
* disallow gapfill lines to be split

supermerill 3 years ago
parent
commit
49e4e20a1b

+ 1 - 0
resources/ui_layout/print.ui

@@ -83,6 +83,7 @@ group:Layer height
 	setting:first_layer_height
 group:Filtering
 	setting:resolution
+	setting:resolution_internal
 	setting:model_precision
 	setting:slice_closing_radius
 group:Modifying slices

+ 1 - 1
src/libslic3r/ClipperUtils.cpp

@@ -231,7 +231,7 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
         co.ArcTolerance = miterLimit;
     else
         co.MiterLimit = miterLimit;
-    double delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
+    double delta_scaled = delta * double(CLIPPER_OFFSET_SCALE);
     co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
     co.AddPaths(input, joinType, endType);
     ClipperLib::Paths retval;

+ 1 - 1
src/libslic3r/ExtrusionEntity.cpp

@@ -376,7 +376,7 @@ void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) {
         if (i != 0) ss << ",";
         collection.entities[i]->visit(*this);
     }
-    if(collection.no_sort) ss<<", no_sort=true";
+    if(!collection.can_sort()) ss<<", no_sort=true";
     ss << "}";
 }
 

+ 2 - 2
src/libslic3r/ExtrusionEntityCollection.cpp

@@ -61,7 +61,7 @@ void ExtrusionEntityCollection::reverse()
     {
         // Don't reverse it if it's a loop, as it doesn't change anything in terms of elements ordering
         // and caller might rely on winding order
-        if (!ptr->can_reverse())
+        if (ptr->can_reverse() && !ptr->is_loop())
             ptr->reverse();
     }
     std::reverse(this->entities.begin(), this->entities.end());
@@ -151,7 +151,7 @@ ExtrusionEntityCollection ExtrusionEntityCollection::flatten(bool preserve_order
 }
 void
 FlatenEntities::use(const ExtrusionEntityCollection &coll) {
-    if ((coll.no_sort || this->to_fill.no_sort) && preserve_ordering) {
+    if ((!coll.can_sort() || !this->to_fill.can_sort()) && preserve_ordering) {
         FlatenEntities unsortable(coll, preserve_ordering);
         for (const ExtrusionEntity* entity : coll.entities) {
             entity->visit(unsortable);

+ 13 - 7
src/libslic3r/ExtrusionEntityCollection.hpp

@@ -24,6 +24,11 @@ inline ExtrusionEntitiesPtr filter_by_extrusion_role(const ExtrusionEntitiesPtr
 
 class ExtrusionEntityCollection : public ExtrusionEntity
 {
+private:
+    // set to tru to forbit to reorder and reverse all entities indie us.
+    bool no_sort;
+    // even if no_sort, allow to reverse() us (and our entities if they allow it, but they should) 
+    bool no_reverse;
 public:
     virtual ExtrusionEntityCollection* clone() const override { return new ExtrusionEntityCollection(*this); }
     // Create a new object, initialize it with this object using the move semantics.
@@ -33,14 +38,13 @@ public:
     /// Owned ExtrusionEntities and descendent ExtrusionEntityCollections.
     /// Iterating over this needs to check each child to see if it, too is a collection.
     ExtrusionEntitiesPtr entities;     // we own these entities
-    bool no_sort;
-    ExtrusionEntityCollection(): no_sort(false) {}
-    ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort) { this->append(other.entities); }
-    ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort) {}
+    ExtrusionEntityCollection(): no_sort(false), no_reverse(false) {}
+    ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort), no_reverse(other.no_reverse) { this->append(other.entities); }
+    ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort), no_reverse(other.no_reverse) {}
     explicit ExtrusionEntityCollection(const ExtrusionPaths &paths);
     ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other);
     ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
-        { this->entities = std::move(other.entities); this->no_sort = other.no_sort; return *this; }
+        { this->entities = std::move(other.entities); this->no_sort = other.no_sort; this->no_reverse = other.no_reverse; return *this; }
     ~ExtrusionEntityCollection() { clear(); }
 
     /// Operator to convert and flatten this collection to a single vector of ExtrusionPaths.
@@ -55,7 +59,9 @@ public:
         }
         return out;
     }
-    bool can_reverse() const override { return !this->no_sort; }
+    void set_can_sort_reverse(bool sort, bool reverse) { this->no_sort = !sort; this->no_reverse = !reverse; }
+    bool can_sort() const { return !this->no_sort; }
+    bool can_reverse() const override { return can_sort() || !this->no_reverse; }
     bool empty() const { return this->entities.empty(); }
     void clear();
     void swap (ExtrusionEntityCollection &c);
@@ -152,7 +158,7 @@ class FlatenEntities : public ExtrusionVisitorConst {
 public:
     FlatenEntities(bool preserve_ordering) : preserve_ordering(preserve_ordering) {}
     FlatenEntities(ExtrusionEntityCollection pattern, bool preserve_ordering) : preserve_ordering(preserve_ordering) {
-        to_fill.no_sort = pattern.no_sort;
+        to_fill.set_can_sort_reverse(pattern.can_sort(), pattern.can_reverse());
     }
     ExtrusionEntityCollection get() {
         return to_fill;

+ 7 - 7
src/libslic3r/Fill/Fill.cpp

@@ -413,9 +413,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
             m_regions[region_id]->fills.append(fills_by_priority[0]->entities);
             delete fills_by_priority[0];
         } else {
-            m_regions[region_id]->fills.no_sort = true;
+            m_regions[region_id]->fills.set_can_sort_reverse(false, false);
             ExtrusionEntityCollection* eec = new ExtrusionEntityCollection();
-            eec->no_sort = true;
+            eec->set_can_sort_reverse(false, false);
             m_regions[region_id]->fills.entities.push_back(eec);
             for (ExtrusionEntityCollection* per_priority : fills_by_priority) {
                 if (!per_priority->entities.empty())
@@ -580,9 +580,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
     for (LayerRegion *layerm : m_regions)
         for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) {
             ExtrusionEntityCollection *collection = new ExtrusionEntityCollection();
-            if (layerm->fills.no_sort && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
+            if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
                 ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
-                if (no_sort_fill->no_sort && no_sort_fill->entities.size() > 0 && no_sort_fill->entities[0]->is_collection())
+                if (!no_sort_fill->can_sort() && no_sort_fill->entities.size() > 0 && no_sort_fill->entities[0]->is_collection())
                     static_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[0])->entities.push_back(collection);
             } else
                 layerm->fills.entities.push_back(collection);
@@ -593,7 +593,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
     for (LayerRegion *layerm : m_regions)
         for (size_t i1 = 0; i1 < layerm->fills.entities.size(); ++i1) {
             assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i1]) != nullptr);
-            if (layerm->fills.no_sort && layerm->fills.entities.size() > 0 && i1 == 0){
+            if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && i1 == 0){
                 ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
                 assert(no_sort_fill != nullptr);
                 assert(!no_sort_fill->empty());
@@ -601,7 +601,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
                     ExtrusionEntityCollection* priority_fill = dynamic_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[i2]);
                     assert(priority_fill != nullptr);
                     assert(!priority_fill->empty());
-                    if (no_sort_fill->no_sort) {
+                    if (!no_sort_fill->can_sort()) {
                         for (size_t i3 = 0; i3 < priority_fill->entities.size(); ++i3)
                             assert(dynamic_cast<ExtrusionEntityCollection*>(priority_fill->entities[i3]) != nullptr);
                     }
@@ -780,7 +780,7 @@ void Layer::make_ironing()
                 ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
                 ironing_params.layerm->ironings.entities.push_back(eec);
                 // Don't sort the ironing infill lines as they are monotonicly ordered.
-                eec->no_sort = true;
+                eec->set_can_sort_reverse(false, false);
                 extrusion_entities_append_paths(
                     eec->entities, std::move(polylines),
                     erIroning,

+ 3 - 3
src/libslic3r/Fill/FillBase.cpp

@@ -211,7 +211,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
     // Save into layer.
     auto *eec = new ExtrusionEntityCollection();
     /// pass the no_sort attribute to the extrusion path
-    eec->no_sort = this->no_sort();
+    eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
     /// add it into the collection
     out.push_back(eec);
     //get the role
@@ -269,7 +269,7 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
         }
 #endif
 
-        ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, params.flow);
+        ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, params.flow, scale_t(params.config->get_computed_value("resolution_internal")));
         //set role if needed
         /*if (params.role != erSolidInfill) {
             ExtrusionSetRole set_good_role(params.role);
@@ -278,7 +278,7 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
         //move them into the collection
         if (!gap_fill.entities.empty()) {
             ExtrusionEntityCollection* coll_gapfill = new ExtrusionEntityCollection();
-            coll_gapfill->no_sort = this->no_sort();
+            coll_gapfill->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
             coll_gapfill->append(std::move(gap_fill.entities));
             coll_out.push_back(coll_gapfill);
         }

+ 2 - 2
src/libslic3r/Fill/FillConcentric.cpp

@@ -128,7 +128,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
         ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
 
         ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
-        coll_nosort->no_sort = true; //can be sorted inside the pass
+        coll_nosort->set_can_sort_reverse(false, false); //can be sorted inside the pass
         extrusion_entities_append_loops(
             coll_nosort->entities, loops,
             good_role,
@@ -154,7 +154,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
                 }
             }
             if (!polylines.empty() && !is_bridge(good_role)) {
-                ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, params.flow);
+                ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, params.flow, scale_t(params.config->get_computed_value("resolution_internal")));
                 //set role if needed
                 if (good_role != erSolidInfill) {
                     ExtrusionSetRole set_good_role(good_role);

+ 14 - 10
src/libslic3r/Fill/FillGyroid.cpp

@@ -101,13 +101,8 @@ static std::vector<Vec2d> make_one_period(double width, double scaleFactor, doub
     return points;
 }
 
-static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height)
+static Polylines make_gyroid_waves(coordf_t gridZ, coordf_t scaleFactor, double width, double height, double tolerance)
 {
-    const double scaleFactor = scale_(line_spacing) / density_adjusted;
-
-    // tolerance in scaled units. clamp the maximum tolerance as there's
-    // no processing-speed benefit to do so beyond a certain point
-    const double tolerance = std::min(line_spacing / 2, FillGyroid::PatternTolerance) / unscale<double>(scaleFactor);
 
     //scale factor for 5% : 8 712 388
     // 1z = 10^-6 mm ?
@@ -167,13 +162,22 @@ void FillGyroid::_fill_surface_single(
     // 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)));
 
+    // tolerance in scaled units. clamp the maximum tolerance as there's
+    // no processing-speed benefit to do so beyond a certain point
+    const coordf_t scaleFactor = scale_d(this->get_spacing()) / density_adjusted;
+    const double tolerance_old = std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) / unscaled(scaleFactor);
+    const double tolerance_old2 = std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) * density_adjusted  / this->get_spacing();
+    const double tolerance = params.config->get_computed_value("resolution_internal") * density_adjusted / this->get_spacing();
+    std::cout << "gyroid tolerance: " << tolerance_old << " == " << tolerance_old2 << " ? "<< tolerance << "\n";
+    std::cout << "this->get_spacing(): " << this->get_spacing() << " , scaleFactor= " << unscaled(scaleFactor) << " , min(spa, 0.2)= " << std::min(this->get_spacing() / 2, FillGyroid::PatternTolerance) << "\n";
+
     // generate pattern
     Polylines polylines = make_gyroid_waves(
-        (double)scale_(this->z),
-        density_adjusted,
-        this->get_spacing(),
+        scale_d(this->z),
+        scaleFactor,
         ceil(bb.size()(0) / distance) + 1.,
-        ceil(bb.size()(1) / distance) + 1.);
+        ceil(bb.size()(1) / distance) + 1.,
+        tolerance);
 
     // shift the polyline to the grid origin
     for (Polyline &pl : polylines)

+ 7 - 7
src/libslic3r/Fill/FillRectilinear.cpp

@@ -3208,7 +3208,7 @@ FillRectilinearPeri::fill_surface_extrusion(const Surface *surface, const FillPa
 {
     ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
     //you don't want to sort the extrusions: big infill first, small second
-    eecroot->no_sort = true;
+    eecroot->set_can_sort_reverse(false, false);
 
     // === extrude perimeter ===
     Polylines polylines_1;
@@ -3231,7 +3231,7 @@ FillRectilinearPeri::fill_surface_extrusion(const Surface *surface, const FillPa
         // Save into layer.
         ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
         /// pass the no_sort attribute to the extrusion path
-        eec->no_sort = this->no_sort();
+        eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
         /// add it into the collection
         eecroot->entities.push_back(eec);
         //get the role
@@ -3263,7 +3263,7 @@ FillRectilinearPeri::fill_surface_extrusion(const Surface *surface, const FillPa
         // Save into layer.
         ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
         /// pass the no_sort attribute to the extrusion path
-        eec->no_sort = this->no_sort();
+        eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
         /// add it into the collection
         eecroot->entities.push_back(eec);
         //get the role
@@ -3365,7 +3365,7 @@ FillRectilinearSawtooth::fill_surface_extrusion(const Surface *surface, const Fi
     if (!polylines_out.empty()) {
         ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
         /// pass the no_sort attribute to the extrusion path
-        eec->no_sort = this->no_sort();
+        eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
 
         ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
 
@@ -3489,7 +3489,7 @@ FillRectilinearWGapFill::split_polygon_gap_fill(const Surface &surface, const Fi
 void
 FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const FillParams &params, ExtrusionEntitiesPtr &out) const {
     ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
-    coll_nosort->no_sort = true; //can be sorted inside the pass
+    coll_nosort->set_can_sort_reverse(false, false); //can be sorted inside the pass but thew two pass need to be done one after the other
     ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
 
     //// remove areas for gapfill 
@@ -3558,9 +3558,9 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi
         /// pass the no_sort attribute to the extrusion path
         //don't force monotonic if not top or bottom
         if (is_monotonic())
-            eec->no_sort = true;
+            eec->set_can_sort_reverse(false, false);
         else
-            eec->no_sort = this->no_sort();
+            eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
 
         extrusion_entities_append_paths(
             eec->entities, polylines_rectilinear,

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