diff --git a/resources/ui_layout/printer_fff.ui b/resources/ui_layout/printer_fff.ui index b362632ac..934381697 100644 --- a/resources/ui_layout/printer_fff.ui +++ b/resources/ui_layout/printer_fff.ui @@ -20,6 +20,7 @@ group:Advanced setting:use_relative_e_distances setting:use_firmware_retraction setting:use_volumetric_e + setting:min_length setting:variable_layer_height page:Custom G-code:cog diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 95d4a2c12..d88f07e4b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3540,11 +3540,59 @@ void GCode::use(const ExtrusionEntityCollection &collection) { } } +std::string extrusion_role_2_string(const ExtrusionRole &er) { + switch (er) { + case erNone: return " none"; + case erPerimeter: return " perimeter"; + case erExternalPerimeter: return " external_perimeter"; + case erOverhangPerimeter: return " overhang_perimeter"; + case erInternalInfill: return " internal_infill"; + case erSolidInfill: return " solid_infill"; + case erTopSolidInfill: return " top_solid_infill"; + case erBridgeInfill: return " bridge_infill"; + case erThinWall: return " thin_wall"; + case erGapFill: return " gap_fill"; + case erSkirt: return " skirt"; + case erSupportMaterial: return " support_material"; + case erSupportMaterialInterface: return " support_material_interface"; + case erWipeTower: return " wipe_tower"; + case erMilling: return " milling"; + case erCustom: return " custom"; + case erMixed: return " mixed"; + case erCount: return " count"; + } + return " unkown"; +} + std::string GCode::extrude_path(const ExtrusionPath &path, const std::string &description, double speed) { - // description += ExtrusionRole2String(path.role()); + + std::string descr = extrusion_role_2_string(path.role()); ExtrusionPath simplifed_path = path; - simplifed_path.simplify(SCALED_RESOLUTION); - std::string gcode = this->_extrude(simplifed_path, description, speed); + if (this->config().min_length.value != 0 && !m_last_too_small.empty()) { + //descr += " trys fusion " + std::to_string(unscaled(m_last_too_small.last_point().x())) + " , " + std::to_string(unscaled(path.first_point().x())); + //ensure that it's a continous thing + if (m_last_too_small.last_point().distance_to_square(path.first_point()) < scale_(this->config().min_length)) { + //descr += " ! fusion " + std::to_string(simplifed_path.polyline.points.size()); + simplifed_path.height = (m_last_too_small.height * m_last_too_small.length() + path.height * path.length()) / (m_last_too_small.length() + path.length()); + simplifed_path.mm3_per_mm = (m_last_too_small.mm3_per_mm * m_last_too_small.length() + path.mm3_per_mm * path.length()) / (m_last_too_small.length() + path.length()); + simplifed_path.polyline.points.insert(simplifed_path.polyline.points.begin(), m_last_too_small.polyline.points.begin(), m_last_too_small.polyline.points.end()-1); + } + m_last_too_small.polyline.points.clear(); + } + simplifed_path.simplify(this->config().min_length.value != 0 ? scale_(this->config().min_length) : SCALED_RESOLUTION); + if (this->config().min_length.value != 0 && simplifed_path.length() < scale_(this->config().min_length)) { + m_last_too_small = simplifed_path; + return ""; + //"; "+ descr+" .... too small for extrude: "+std::to_string(simplifed_path.length())+" < "+ std::to_string(scale_(this->config().min_length)) + //+ " ; " + std::to_string(unscaled(path.first_point().x())) + " : " + std::to_string(unscaled(path.last_point().x())) + //+" =;=> " + std::to_string(unscaled(simplifed_path.first_point().x())) + " : " + std::to_string(unscaled(simplifed_path.last_point().x())) + //+ "\n"; + } + + std::string gcode = this->_extrude(simplifed_path, description + descr, speed); + + //gcode += " ; " + std::to_string(unscaled(path.first_point().x())) + " : " + std::to_string(unscaled(path.last_point().x())); + //gcode += " =;=> " + std::to_string(unscaled(simplifed_path.first_point().x())) + " : " + std::to_string(unscaled(simplifed_path.last_point().x())); if (m_wipe.enable) { m_wipe.path = std::move(simplifed_path.polyline); @@ -3556,9 +3604,9 @@ std::string GCode::extrude_path(const ExtrusionPath &path, const std::string &de } std::string GCode::extrude_path_3D(const ExtrusionPath3D &path, const std::string &description, double speed) { - // description += ExtrusionRole2String(path.role()); + std::string descr = extrusion_role_2_string(path.role()); //path.simplify(SCALED_RESOLUTION); - std::string gcode = this->_before_extrude(path, description, speed); + std::string gcode = this->_before_extrude(path, description + descr, speed); // calculate extrusion length per distance unit double e_per_mm = path.mm3_per_mm diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 68f634ff4..ded150a69 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -161,7 +161,8 @@ public: m_normal_time_estimator(GCodeTimeEstimator::Normal), m_silent_time_estimator(GCodeTimeEstimator::Silent), m_silent_time_estimator_enabled(false), - m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) + m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())), + m_last_too_small(ExtrusionRole::erNone) {} ~GCode() {} @@ -380,6 +381,9 @@ private: Point m_last_pos; bool m_last_pos_defined; + // a previous extrusion path that is too small to be extruded, have to fusion it into the next call. + ExtrusionPath m_last_too_small; + std::unique_ptr m_cooling_buffer; std::unique_ptr m_spiral_vase; #ifdef HAS_PRESSURE_EQUALIZER diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d98ebaaaa..2396ca1cb 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2061,6 +2061,16 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionFloats { 0.07 }); + def = this->add("min_length", coFloat); + def->label = L("minimum extrusion length"); + def->category = OptionCategory::speed; + def->tooltip = L("Too many too small commands may overload the firmware / connection. Put a higher value here if you see strange slowdown." + "\n0 to disable."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0.035)); + def = this->add("min_width_top_surface", coFloatOrPercent); def->label = L("minimum top width for infill"); def->category = OptionCategory::speed; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ac8e01b4c..750c5cf03 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -886,11 +886,12 @@ public: ConfigOptionString feature_gcode; ConfigOptionFloat max_print_speed; ConfigOptionFloat max_volumetric_speed; - ConfigOptionFloats milling_z_lift; #ifdef HAS_PRESSURE_EQUALIZER ConfigOptionFloat max_volumetric_extrusion_rate_slope_positive; ConfigOptionFloat max_volumetric_extrusion_rate_slope_negative; #endif + ConfigOptionFloats milling_z_lift; + ConfigOptionFloat min_length; ConfigOptionPercents retract_before_wipe; ConfigOptionFloats retract_length; ConfigOptionFloats retract_length_toolchange; @@ -983,6 +984,7 @@ protected: OPT_PTR(max_print_speed); OPT_PTR(max_volumetric_speed); OPT_PTR(milling_z_lift); + OPT_PTR(min_length); #ifdef HAS_PRESSURE_EQUALIZER OPT_PTR(max_volumetric_extrusion_rate_slope_positive); OPT_PTR(max_volumetric_extrusion_rate_slope_negative); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 7ce78f25e..20363f1dc 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -596,6 +596,7 @@ const std::vector& Preset::printer_options() "printer_technology", "bed_shape", "bed_custom_texture", "bed_custom_model", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height", + "min_length", "host_type", "print_host", "printhost_apikey", "printhost_cafile", "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode", "feature_gcode",