Browse Source

#399 add an other pattern for brim ear: rectilinear with perimeter.
If you have problem with adhesion of the ear.
also some fixes about brim invalidation.

supermerill 4 years ago
parent
commit
3ec2f077e5

+ 1 - 0
resources/ui_layout/print.ui

@@ -154,6 +154,7 @@ group:Brim
 	line:Brim ears
 		setting:brim_ears
 		setting:width$3:brim_ears_max_angle
+		setting:brim_ears_pattern
 	end_line
 	setting:brim_offset
 

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

@@ -898,7 +898,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
         surface->expolygon, 
         - rotate_vector.first, 
         scale_(0 /*this->overlap*/ - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
-        scale_(0 /*this->overlap*/ - 0.5 * this->spacing));
+        scale_(0 /*this->overlap*/ - (params.full_infill() && params.fill_exactly ? 0.5 + INFILL_OVERLAP_OVER_SPACING : 0.5) * this->spacing));
     if (poly_with_offset.n_contours_inner == 0) {
         // Not a single infill line fits.
         //Prusa: maybe one shall trigger the gap fill here?
@@ -909,7 +909,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
     BoundingBox bounding_box = poly_with_offset.bounding_box_src();
 
     // define flow spacing according to requested density
-    if (params.full_infill() && !params.dont_adjust) {
+    if (params.full_infill() && !params.dont_adjust || line_spacing == 0 ) {
         //it's == this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing) because of the init_spacing
         line_spacing = scale_(this->spacing);
     } else {

+ 96 - 50
src/libslic3r/Print.cpp

@@ -5,6 +5,7 @@
 #include "ClipperUtils.hpp"
 #include "Extruder.hpp"
 #include "Flow.hpp"
+#include "Fill/FillBase.hpp"
 #include "Geometry.hpp"
 #include "I18N.hpp"
 #include "ShortestPath.hpp"
@@ -196,8 +197,11 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
         } else if (
             opt_key == "brim_inside_holes"
             || opt_key == "brim_width"
+            || opt_key == "brim_width_interior"
+            || opt_key == "brim_offset"
             || opt_key == "brim_ears"
-            || opt_key == "brim_ears_max_angle") {
+            || opt_key == "brim_ears_max_angle"
+            || opt_key == "brim_ears_pattern") {
             steps.emplace_back(psBrim);
             steps.emplace_back(psSkirt);
         } else if (
@@ -1712,6 +1716,7 @@ void Print::process()
             for (std::vector<PrintObject*> &obj_group : obj_groups) {
                 if (obj_group.front()->config().brim_ears.value == obj->config().brim_ears.value
                     && obj_group.front()->config().brim_ears_max_angle.value == obj->config().brim_ears_max_angle.value
+                    && obj_group.front()->config().brim_ears_pattern.value == obj->config().brim_ears_pattern.value
                     && obj_group.front()->config().brim_inside_holes.value == obj->config().brim_inside_holes.value
                     && obj_group.front()->config().brim_offset.value == obj->config().brim_offset.value
                     && obj_group.front()->config().brim_width.value == obj->config().brim_width.value
@@ -2281,61 +2286,102 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
     brimmable_areas = diff_ex(brimmable_areas, unbrimmable, true);
 
     this->throw_if_canceled();
-    //create loops (same as standard brim)
-    Polygons loops;
-    islands = offset_ex(islands, -0.5f * double(flow.scaled_spacing()));
-    for (size_t i = 0; i < num_loops; ++i) {
+
+    if (brim_config.brim_ears_pattern.value == InfillPattern::ipConcentric) {
+
+        //create loops (same as standard brim)
+        Polygons loops;
+        islands = offset_ex(islands, -0.5f * double(flow.scaled_spacing()));
+        for (size_t i = 0; i < num_loops; ++i) {
+            this->throw_if_canceled();
+            islands = offset_ex(islands, double(flow.scaled_spacing()), jtSquare);
+            for (ExPolygon &expoly : islands) {
+                Polygon poly = expoly.contour;
+                poly.points.push_back(poly.points.front());
+                Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
+                p.pop_back();
+                poly.points = std::move(p);
+                loops.push_back(poly);
+            }
+        }
+        //order path with least travel possible
+        loops = union_pt_chained(loops, false);
+
+        //create ear pattern
+        coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
+        Polygon point_round;
+        for (size_t i = 0; i < POLY_SIDES; i++) {
+            double angle = (2.0 * PI * i) / POLY_SIDES;
+            point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
+        }
+
+        //create ears
+        Polygons mouse_ears;
+        ExPolygons mouse_ears_ex;
+        for (Point pt : pt_ears) {
+            mouse_ears.push_back(point_round);
+            mouse_ears.back().translate(pt);
+            mouse_ears_ex.emplace_back();
+            mouse_ears_ex.back().contour = mouse_ears.back();
+        }
+
+        //intersection
+        Polylines lines = intersection_pl(loops, mouse_ears);
         this->throw_if_canceled();
-        islands = offset_ex(islands, double(flow.scaled_spacing()), jtSquare);
-        for (ExPolygon &expoly : islands) {
-            Polygon poly = expoly.contour;
-            poly.points.push_back(poly.points.front());
-            Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
-            p.pop_back();
-            poly.points = std::move(p);
-            loops.push_back(poly);
+
+        //reorder & extrude them
+        Polylines lines_sorted = _reorder_brim_polyline(lines, out, flow);
+
+        //push into extrusions
+        extrusion_entities_append_paths(
+            out.entities,
+            lines_sorted,
+            erSkirt,
+            float(flow.mm3_per_mm()),
+            float(flow.width),
+            float(this->skirt_first_layer_height())
+        );
+
+        ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
+        unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
+    } else {
+
+        
+        //create ear pattern
+        coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
+        Polygon point_round;
+        for (size_t i = 0; i < POLY_SIDES; i++) {
+            double angle = (2.0 * PI * i) / POLY_SIDES;
+            point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
         }
-    }
-    //order path with least travel possible
-    loops = union_pt_chained(loops, false);
-
-    //create ear pattern
-    coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
-    Polygon point_round;
-    for (size_t i = 0; i < POLY_SIDES; i++) {
-        double angle = (2.0 * PI * i) / POLY_SIDES;
-        point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
-    }
 
-    //create ears
-    Polygons mouse_ears;
-    ExPolygons mouse_ears_ex;
-    for (Point pt : pt_ears) {
-        mouse_ears.push_back(point_round);
-        mouse_ears.back().translate(pt);
-        mouse_ears_ex.emplace_back();
-        mouse_ears_ex.back().contour = mouse_ears.back();
-    }
+        //create ears
+        ExPolygons mouse_ears_ex;
+        for (Point pt : pt_ears) {
+            mouse_ears_ex.emplace_back();
+            mouse_ears_ex.back().contour = point_round;
+            mouse_ears_ex.back().contour.translate(pt);
+        }
 
-    //intersection
-    Polylines lines = intersection_pl(loops, mouse_ears);
-    this->throw_if_canceled();
+        ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
 
-    //reorder & extrude them
-    Polylines lines_sorted = _reorder_brim_polyline(lines, out, flow);
-
-    //push into extrusions
-    extrusion_entities_append_paths(
-        out.entities,
-        lines_sorted,
-        erSkirt,
-        float(flow.mm3_per_mm()),
-        float(flow.width),
-        float(this->skirt_first_layer_height())
-    );
+        std::unique_ptr<Fill> filler = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter));
+        filler->angle = 0;
+
+        FillParams fill_params;
+        fill_params.density = 1.f;
+        fill_params.fill_exactly = true;
+        fill_params.flow = &flow;
+        fill_params.role = erSkirt;
+        filler->init_spacing(flow.spacing(), fill_params);
+        for (const ExPolygon &expoly : new_brim_area) {
+            Surface surface(stPosInternal | stDensSparse, expoly);
+            filler->fill_surface_extrusion(&surface, fill_params, out.entities);
+        }
+
+        unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
+    }
 
-    ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
-    unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
 }
 
 void Print::_make_brim_interior(const Flow &flow, const PrintObjectPtrs &objects, ExPolygons &unbrimmable_areas, ExtrusionEntityCollection &out) {

+ 17 - 0
src/libslic3r/PrintConfig.cpp

@@ -352,6 +352,19 @@ void PrintConfigDef::init_fff_params()
     def->mode = comAdvanced;
     def->set_default_value(new ConfigOptionFloat(125));
 
+    def = this->add("brim_ears_pattern", coEnum);
+    def->label = L("Pattern");
+    def->full_label = L("Ear pattern");
+    def->category = OptionCategory::infill;
+    def->tooltip = L("Pattern for the ear. The concentric id the default one."
+                    " The rectilinear has a perimeter around it, you can try it if the concentric has too many problems to stick to the build plate.");
+    def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
+    def->enum_values.push_back("concentric");
+    def->enum_values.push_back("rectilinear");
+    def->enum_labels.push_back(L("Concentric"));
+    def->enum_labels.push_back(L("Rectilinear"));
+    def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipConcentric));
+
     def = this->add("brim_offset", coFloat);
     def->label = L("brim offset");
     def->category = OptionCategory::skirtBrim;
@@ -4736,6 +4749,10 @@ std::string FullPrintConfig::validate()
     if (!print_config_def.get("solid_fill_pattern")->has_enum_value(this->solid_fill_pattern.serialize()))
         return "Invalid value for --solid-fill-pattern";
 
+    // --brim-ears-pattern
+    if (!print_config_def.get("brim_ears_pattern")->has_enum_value(this->brim_ears_pattern.serialize()))
+        return "Invalid value for --brim-ears-pattern";
+
     // --fill-density
     if (fabs(this->fill_density.value - 100.) < EPSILON &&
         (! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())

+ 2 - 0
src/libslic3r/PrintConfig.hpp

@@ -490,6 +490,7 @@ public:
     ConfigOptionFloat               brim_width_interior;
     ConfigOptionBool                brim_ears;
     ConfigOptionFloat               brim_ears_max_angle;
+    ConfigOptionEnum<InfillPattern> brim_ears_pattern;
     ConfigOptionFloat               brim_offset;
     ConfigOptionBool                clip_multipart_objects;
     ConfigOptionBool                dont_support_bridges;
@@ -555,6 +556,7 @@ protected:
         OPT_PTR(brim_width_interior);
         OPT_PTR(brim_ears);
         OPT_PTR(brim_ears_max_angle);
+        OPT_PTR(brim_ears_pattern);
         OPT_PTR(brim_offset);
         OPT_PTR(clip_multipart_objects);
         OPT_PTR(dont_support_bridges);

+ 9 - 0
src/libslic3r/PrintObject.cpp

@@ -757,6 +757,15 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
             || opt_key == "wipe_into_objects") {
             invalidated |= m_print->invalidate_step(psWipeTower);
             invalidated |= m_print->invalidate_step(psGCodeExport);
+        } else if (
+            opt_key == "brim_inside_holes"
+            || opt_key == "brim_width"
+            || opt_key == "brim_width_interior"
+            || opt_key == "brim_offset"
+            || opt_key == "brim_ears"
+            || opt_key == "brim_ears_max_angle"
+            || opt_key == "brim_ears_pattern") {
+            invalidated |= m_print->invalidate_step(psBrim);
         } else {
             // for legacy, if we can't handle this option let's invalidate all steps
             this->invalidate_all_steps();

+ 1 - 0
src/slic3r/GUI/ConfigManipulation.cpp

@@ -376,6 +376,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
     toggle_field("brim_ears", config->opt_float("brim_width") > 0);
     toggle_field("brim_inside_holes", config->opt_float("brim_width") > 0 && config->opt_float("brim_width_interior") == 0);
     toggle_field("brim_ears_max_angle", have_brim && config->opt_bool("brim_ears"));
+    toggle_field("brim_ears_pattern", have_brim && config->opt_bool("brim_ears"));
 
     bool have_raft = config->opt_int("raft_layers") > 0;
     bool have_support_material = config->opt_bool("support_material") || have_raft;

+ 2 - 2
src/slic3r/GUI/Field.cpp

@@ -986,7 +986,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
     case coEnum: {
         int val = boost::any_cast<int>(value);
         if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "solid_fill_pattern"
-            || m_opt_id == "fill_pattern" || m_opt_id == "support_material_interface_pattern")
+            || m_opt_id == "fill_pattern" || m_opt_id == "support_material_interface_pattern" || m_opt_id == "brim_ears_pattern")
         {
             val = idx_from_enum_value<InfillPattern>(val);
         } else if (m_opt_id.compare("perimeter_loop_seam") == 0) {
@@ -1073,7 +1073,7 @@ boost::any& Choice::get_value()
     {
         int ret_enum = field->GetSelection(); 
         if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "solid_fill_pattern" 
-            || m_opt_id == "support_material_interface_pattern" || m_opt_id == "fill_pattern")
+            || m_opt_id == "support_material_interface_pattern" || m_opt_id == "fill_pattern" || m_opt_id == "brim_ears_pattern")
             convert_to_enum_value<InfillPattern>(ret_enum);
         else if (m_opt_id.compare("gcode_flavor") == 0)
             convert_to_enum_value<GCodeFlavor>(ret_enum);

+ 2 - 1
src/slic3r/GUI/GUI.cpp

@@ -187,7 +187,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
 			if (opt_key == "top_fill_pattern" ||
 				opt_key == "bottom_fill_pattern" ||
 				opt_key == "solid_fill_pattern" ||
-				opt_key == "fill_pattern")
+				opt_key == "fill_pattern" ||
+				opt_key == "brim_ears_pattern")
 				config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
 			else if (opt_key.compare("complete_objects_sort") == 0)
 				config.set_key_value(opt_key, new ConfigOptionEnum<CompleteObjectSort>(boost::any_cast<CompleteObjectSort>(value)));  

+ 2 - 1
src/slic3r/GUI/OptionsGroup.cpp

@@ -746,7 +746,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
 		if (opt_key == "top_fill_pattern" ||
 			opt_key == "bottom_fill_pattern" ||
 			opt_key == "solid_fill_pattern" ||
-			opt_key == "fill_pattern" ) {
+			opt_key == "fill_pattern" ||
+			opt_key == "brim_ears_pattern" ) {
 			ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
 		}
 		else if (opt_key.compare("complete_objects_sort") == 0 ) {

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