Skip to content

Commit

Permalink
external_perimeter_cut_corners setting
Browse files Browse the repository at this point in the history
it reduce the flow around corners, depending of the angle.
experimental status! not tested yet!
  • Loading branch information
supermerill committed May 23, 2020
1 parent ff40015 commit 90b129e
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 14 deletions.
1 change: 1 addition & 0 deletions resources/ui_layout/print.ui
Expand Up @@ -235,6 +235,7 @@ group:Flow
setting:fill_top_flow_ratio
setting:first_layer_flow_ratio
end_line
setting:external_perimeter_cut_corners

page:Multiple extruders:funnel
group:Extruders
Expand Down
80 changes: 69 additions & 11 deletions src/libslic3r/GCode.cpp
Expand Up @@ -3552,23 +3552,81 @@ void GCode::_write_format(FILE* file, const char* format, ...)
std::string GCode::_extrude(const ExtrusionPath &path, const std::string &description, double speed) {

std::string gcode = this->_before_extrude(path, description, speed);

// calculate extrusion length per distance unit
double e_per_mm = path.mm3_per_mm
* m_writer.extruder()->e_per_mm3()
* this->config().print_extrusion_multiplier.get_abs_value(1);
if (this->m_layer_index <= 0) e_per_mm *= this->config().first_layer_flow_ratio.get_abs_value(1);
if (m_writer.extrusion_axis().empty()) e_per_mm = 0;
double path_length = 0.;
{
std::string comment = m_config.gcode_comments ? description : "";
for (const Line &line : path.polyline.lines()) {
const double line_length = line.length() * SCALING_FACTOR;
path_length += line_length;
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(line.b),
e_per_mm * line_length,
comment);
if (path.polyline.lines().size() > 0) {
//get last direction //TODO: save it
{
std::string comment = m_config.gcode_comments ? description : "";
if (path.role() != erExternalPerimeter || config().external_perimeter_cut_corners.value == 0) {
// normal & legacy pathcode
for (const Line& line : path.polyline.lines()) {
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(line.b),
e_per_mm * unscaled(line.length()),
comment);
}
} else {
// external_perimeter_cut_corners pathcode
Point last_pos = path.polyline.lines()[0].a;
for (const Line& line : path.polyline.lines()) {
//check the angle
double angle = line.a == last_pos ? PI : line.a.ccw_angle(last_pos, line.b);
if (angle > 1) angle = 2 * PI - angle;
double coeff = std::cos(angle) + 1;
//Create extrusion mult
double mult = config().external_perimeter_cut_corners.get_abs_value(0.05375) * coeff; // 0.94625 = 3.78 / 4 = (4 - ((4 - pi) / 4)) / 4 // 4 = carre, 3.14 = disk
double length1 = scale_(path.width) / 4;

//extrude in three steps: one short with big mult, one of nozzle size with the rest and then the normal one.
//it's a very rough approx of a cos.
length1 /= (2.1 - coeff);
if (line.length() > length1 && mult > 0.001) {
//Create a point
Point inter_point1 = line.point_at(length1);
//extrude very reduced
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(inter_point1),
e_per_mm * unscaled(length1) * (1 - mult * 2.5),
comment);

double length2 = scale_(path.width);
length2 /= (2.1 - coeff);
if (line.length() > length2) {
Point inter_point2 = line.point_at(length2);
//extrude reduced
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(inter_point2),
e_per_mm * unscaled(length2 - length1) * (1 - mult / 2),
comment);

//extrude normal
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(line.b),
e_per_mm * unscaled(line.length() - length2),
comment);
} else {
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(line.b),
e_per_mm * unscaled(line.length() - length1) * (1 - mult / 2),
comment);
}
} else {
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(line.b),
e_per_mm * unscaled(line.length() - length1) * (1 - mult * path.width / unscaled(line.length())),
comment);
}

//relance
last_pos = line.a;
}
}
}
}
gcode += this->_after_extrude(path);
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/Print.cpp
Expand Up @@ -86,6 +86,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"duplicate_distance",
"end_gcode",
"end_filament_gcode",
"external_perimeter_cut_corners",
"extrusion_axis",
"extruder_clearance_height",
"extruder_clearance_radius",
Expand Down
14 changes: 12 additions & 2 deletions src/libslic3r/PrintConfig.cpp
Expand Up @@ -677,13 +677,23 @@ void PrintConfigDef::init_fff_params()
def->full_label = L("External perimeters width");
def->category = OptionCategory::width;
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for external perimeters. "
"If left zero, default extrusion width will be used if set, otherwise 1.05 x nozzle diameter will be used. "
"If expressed as percentage (for example 112.5%), it will be computed over nozzle diameter.");
"If left zero, default extrusion width will be used if set, otherwise 1.05 x nozzle diameter will be used. "
"If expressed as percentage (for example 112.5%), it will be computed over nozzle diameter.");
def->sidetext = L("mm or %");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));

def = this->add("external_perimeter_cut_corners", coPercent);
def->label = L("Cutting corners");
def->full_label = L("Ext. peri. cut corners");
def->category = OptionCategory::width;
def->tooltip = L("Activate this option to modify the flow to acknoledge that the nozzle is round and the corners will have a round shape, and so change the flow to realized that and avoid over-extrusion."
" 100% is activated, 0% is deactivated and 50% is half-activated");
def->sidetext = L("%");
def->mode = comExpert;
def->set_default_value(new ConfigOptionPercent(0));

def = this->add("external_perimeter_speed", coFloatOrPercent);
def->label = L("External");
def->full_label = L("External perimeters speed");
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Expand Up @@ -466,6 +466,7 @@ class PrintObjectConfig : public StaticPrintConfig
ConfigOptionBool clip_multipart_objects;
ConfigOptionBool dont_support_bridges;
ConfigOptionFloat elefant_foot_compensation;
ConfigOptionPercent external_perimeter_cut_corners;
ConfigOptionBool exact_last_layer_height;
ConfigOptionFloatOrPercent extrusion_width;
ConfigOptionFloatOrPercent first_layer_height;
Expand Down Expand Up @@ -525,6 +526,7 @@ class PrintObjectConfig : public StaticPrintConfig
OPT_PTR(clip_multipart_objects);
OPT_PTR(dont_support_bridges);
OPT_PTR(elefant_foot_compensation);
OPT_PTR(external_perimeter_cut_corners);
OPT_PTR(exact_last_layer_height);
OPT_PTR(extrusion_width);
OPT_PTR(first_layer_height);
Expand Down
3 changes: 2 additions & 1 deletion src/slic3r/GUI/Preset.cpp
Expand Up @@ -520,7 +520,8 @@ const std::vector<std::string>& Preset::print_options()
, "curve_smoothing_cutoff_dist"
, "curve_smoothing_angle_convex"
, "curve_smoothing_angle_concave",
"print_extrusion_multiplier"
"print_extrusion_multiplier",
"external_perimeter_cut_corners"
};
return s_opts;
}
Expand Down

0 comments on commit 90b129e

Please sign in to comment.