Skip to content

Commit

Permalink
Variable perimeters and solid infill extrusion width on even layers.
Browse files Browse the repository at this point in the history
  • Loading branch information
Vovodroid authored and vovodroid committed Aug 5, 2023
1 parent 287e1e2 commit bfcd8e1
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 24 deletions.
6 changes: 5 additions & 1 deletion src/libslic3r/Flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ double Flow::extrusion_width(const std::string& opt_key, const ConfigOptionResol

// This constructor builds a Flow object from an extrusion width config setting
// and other context properties.
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height)
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float width_delta, float nozzle_diameter, float height)
{
if (height <= 0)
throw Slic3r::InvalidArgument("Invalid flow height supplied to new_from_config_width()");
Expand All @@ -125,6 +125,7 @@ Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent
// If user set a manual value, use it.
w = float(width.get_abs_value(height));
}
w += width_delta;

return Flow(w, height, rounded_rectangle_extrusion_spacing(w, height), nozzle_diameter, false);
}
Expand Down Expand Up @@ -221,6 +222,7 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(object->config().support_material_extrusion_width.value > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
0,
// if object->config().support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value));
Expand All @@ -234,6 +236,7 @@ Flow support_material_1st_layer_flow(const PrintObject *object, float layer_heig
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(width.value > 0) ? width : object->config().extrusion_width,
0,
float(print_config.nozzle_diameter.get_at(object->config().support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(print_config.first_layer_height.get_abs_value(object->config().layer_height.value)));
}
Expand All @@ -244,6 +247,7 @@ Flow support_material_interface_flow(const PrintObject *object, float layer_heig
frSupportMaterialInterface,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(object->config().support_material_extrusion_width > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
0,
// if object->config().support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_interface_extruder-1)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value));
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Flow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class Flow

static Flow bridging_flow(float dmr, float nozzle_diameter) { return Flow { dmr, dmr, bridge_extrusion_spacing(dmr), nozzle_diameter, true }; }

static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height);
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float width_delta, float nozzle_diameter, float height);

// Spacing of extrusions with rounded extrusion model.
static float rounded_rectangle_extrusion_spacing(float width, float height);
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/LayerRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Flow LayerRegion::flow(FlowRole role) const

Flow LayerRegion::flow(FlowRole role, double layer_height) const
{
return m_region->flow(*m_layer->object(), role, layer_height, m_layer->id() == 0);
return m_region->flow(*m_layer->object(), role, layer_height, m_layer->id());
}

Flow LayerRegion::bridging_flow(FlowRole role, bool force_thick_bridges) const
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ static std::vector<std::string> s_Preset_print_options {
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"perimeter_extrusion_width", "perimeter_extrusion_width_even_layers", "external_perimeter_extrusion_width", "external_perimeter_extrusion_width_even_layers", "infill_extrusion_width", "solid_infill_extrusion_width", "solid_infill_extrusion_width_even_layers",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ Flow Print::brim_flow() const
return Flow::new_from_config_width(
frPerimeter,
width,
0,
(float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().perimeter_extruder-1),
(float)this->skirt_first_layer_height());
}
Expand All @@ -865,6 +866,7 @@ Flow Print::skirt_flow() const
return Flow::new_from_config_width(
frPerimeter,
width,
0,
(float)m_config.nozzle_diameter.get_at(m_objects.front()->config().support_material_extruder-1),
(float)this->skirt_first_layer_height());
}
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class PrintRegion
int print_object_region_id() const throw() { return m_print_object_region_id; }
// 1-based extruder identifier for this region and role.
unsigned int extruder(FlowRole role) const;
Flow flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer = false) const;
Flow flow(const PrintObject &object, FlowRole role, double layer_height, int layer_id = -1) const;
// Average diameter of nozzles participating on extruding this region.
coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const;
// Average diameter of nozzles participating on extruding this region.
Expand Down
39 changes: 36 additions & 3 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipMonotonic));

def = this->add("external_perimeter_extrusion_width", coFloatOrPercent);
def->label = L("External perimeters");
def->label = L("");
def->category = L("Extrusion 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.125 x nozzle diameter will be used. "
Expand All @@ -845,6 +845,17 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));

def = this->add("external_perimeter_extrusion_width_even_layers", coFloat);
def->label = L("Odd layers delta");
def->category = L("Extrusion Width");
def->tooltip = L("External perimeter change on even layers. It overlaps perimeters border and increase interlayer strength. "
"Choose value about ±40-60% of layer height and opposite sign to internal perimeters and soild infill change.");
def->sidetext = L("mm");
def->min = -0.3f;
def->max = 0.3f;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));

def = this->add("external_perimeter_speed", coFloatOrPercent);
def->label = L("External perimeters");
def->category = L("Speed");
Expand Down Expand Up @@ -2040,7 +2051,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionInt(1));

def = this->add("perimeter_extrusion_width", coFloatOrPercent);
def->label = L("Perimeters");
def->label = L("");
def->category = L("Extrusion Width");
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for perimeters. "
"You may want to use thinner extrudates to get more accurate surfaces. "
Expand All @@ -2053,6 +2064,17 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));

def = this->add("perimeter_extrusion_width_even_layers", coFloat);
def->label = L("Odd layers delta");
def->category = L("Extrusion Width");
def->tooltip = L("Perimeter change on even layers. It overlaps perimeters border and increase with interlayer strength. "
"Choose value about ±40-60% of layer height.");
def->sidetext = L("mm");
def->min = -0.3f;
def->max = 0.3f;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));

def = this->add("perimeter_speed", coFloat);
def->label = L("Perimeters");
def->category = L("Speed");
Expand Down Expand Up @@ -2429,7 +2451,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionInt(0));

def = this->add("solid_infill_extrusion_width", coFloatOrPercent);
def->label = L("Solid infill");
def->label = L("");
def->category = L("Extrusion Width");
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for infill for solid surfaces. "
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
Expand All @@ -2440,6 +2462,17 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));

def = this->add("solid_infill_extrusion_width_even_layers", coFloat);
def->label = L("Odd layers delta");
def->category = L("Extrusion Width");
def->tooltip = L("Solid infill change on odd layers. It overlaps perimeters border and increase with interlayer strength. Could be useful for concentric infill. "
"Choose value about ±40-60% of layer height.");
def->sidetext = L("mm");
def->min = -0.3f;
def->max = 0.3f;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));

def = this->add("solid_infill_speed", coFloatOrPercent);
def->label = L("Solid infill");
def->category = L("Speed");
Expand Down
3 changes: 3 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionEnum<InfillPattern>, top_fill_pattern))
((ConfigOptionEnum<InfillPattern>, bottom_fill_pattern))
((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width))
((ConfigOptionFloat, external_perimeter_extrusion_width_even_layers))
((ConfigOptionFloatOrPercent, external_perimeter_speed))
((ConfigOptionBool, enable_dynamic_overhang_speeds))
((ConfigOptionFloatOrPercent, overhang_speed_0))
Expand Down Expand Up @@ -609,13 +610,15 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, overhangs))
((ConfigOptionInt, perimeter_extruder))
((ConfigOptionFloatOrPercent, perimeter_extrusion_width))
((ConfigOptionFloat, perimeter_extrusion_width_even_layers))
((ConfigOptionFloat, perimeter_speed))
// Total number of perimeters.
((ConfigOptionInt, perimeters))
((ConfigOptionFloatOrPercent, small_perimeter_speed))
((ConfigOptionFloat, solid_infill_below_area))
((ConfigOptionInt, solid_infill_extruder))
((ConfigOptionFloatOrPercent, solid_infill_extrusion_width))
((ConfigOptionFloat, solid_infill_extrusion_width_even_layers))
((ConfigOptionInt, solid_infill_every_layers))
((ConfigOptionFloatOrPercent, solid_infill_speed))
// Detect thin walls.
Expand Down
6 changes: 5 additions & 1 deletion src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "extra_perimeters_on_overhangs"
|| opt_key == "first_layer_extrusion_width"
|| opt_key == "perimeter_extrusion_width"
|| opt_key == "perimeter_extrusion_width_even_layers"
|| opt_key == "infill_overlap"
|| opt_key == "external_perimeters_first") {
steps.emplace_back(posPerimeters);
Expand Down Expand Up @@ -769,12 +770,15 @@ bool PrintObject::invalidate_state_by_config_options(
is_approx(new_density->value, 0.) || is_approx(new_density->value, 100.))
steps.emplace_back(posPerimeters);
steps.emplace_back(posPrepareInfill);
} else if (opt_key == "solid_infill_extrusion_width") {
} else if (
opt_key == "solid_infill_extrusion_width"
|| opt_key == "solid_infill_extrusion_width_even_layers") {
// This value is used for calculating perimeter - infill overlap, thus perimeters need to be recalculated.
steps.emplace_back(posPerimeters);
steps.emplace_back(posPrepareInfill);
} else if (
opt_key == "external_perimeter_extrusion_width"
|| opt_key == "external_perimeter_extrusion_width_even_layers"
|| opt_key == "perimeter_extruder"
|| opt_key == "fuzzy_skin"
|| opt_key == "fuzzy_skin_thickness"
Expand Down
11 changes: 8 additions & 3 deletions src/libslic3r/PrintRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@ unsigned int PrintRegion::extruder(FlowRole role) const
return extruder;
}

Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer) const
Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_height, int layer_id) const
{
const PrintConfig &print_config = object.print()->config();
ConfigOptionFloatOrPercent config_width;
float width_delta = 0;
// Get extrusion width from configuration.
// (might be an absolute value, or a percent value, or zero for auto)
if (first_layer && print_config.first_layer_extrusion_width.value > 0) {
if (layer_id == 0 && print_config.first_layer_extrusion_width.value > 0) {
config_width = print_config.first_layer_extrusion_width;
} else if (role == frExternalPerimeter) {
config_width = m_config.external_perimeter_extrusion_width;
width_delta = (layer_id % 2 == 1) ? m_config.external_perimeter_extrusion_width_even_layers.value : 0;
} else if (role == frPerimeter) {
config_width = m_config.perimeter_extrusion_width;
width_delta = (layer_id % 2 == 1) ? m_config.perimeter_extrusion_width_even_layers.value : 0;
} else if (role == frInfill) {
config_width = m_config.infill_extrusion_width;
width_delta = (layer_id % 2 == 1) ? 0.2 : 0;
} else if (role == frSolidInfill) {
config_width = m_config.solid_infill_extrusion_width;
width_delta = (layer_id % 2 == 1) ? m_config.solid_infill_extrusion_width_even_layers.value : 0;
} else if (role == frTopSolidInfill) {
config_width = m_config.top_infill_extrusion_width;
} else {
Expand All @@ -46,7 +51,7 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
// Get the configured nozzle_diameter for the extruder associated to the flow role requested.
// Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
auto nozzle_diameter = float(print_config.nozzle_diameter.get_at(this->extruder(role) - 1));
return Flow::new_from_config_width(role, config_width, nozzle_diameter, float(layer_height));
return Flow::new_from_config_width(role, config_width, width_delta, nozzle_diameter, float(layer_height));
}

coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
Expand Down
5 changes: 3 additions & 2 deletions src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
{
bool have_perimeters = config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters","extra_perimeters_on_overhangs", "thin_walls", "overhangs",
"seam_position","staggered_inner_seams", "external_perimeters_first", "external_perimeter_extrusion_width",
"seam_position","staggered_inner_seams", "external_perimeters_first", "external_perimeter_extrusion_width", "external_perimeter_extrusion_width_even_layers",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds"})
toggle_field(el, have_perimeters);

Expand All @@ -238,7 +238,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill;
// solid_infill_extruder uses the same logic as in Print::extruders()
for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder",
"solid_infill_extrusion_width", "solid_infill_speed" })
"solid_infill_extrusion_width", "solid_infill_extrusion_width_even_layers", "solid_infill_speed" })
toggle_field(el, has_solid_infill);

for (auto el : { "fill_angle", "bridge_angle", "infill_extrusion_width",
Expand Down Expand Up @@ -301,6 +301,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("support_material_synchronize_layers", have_support_soluble);

toggle_field("perimeter_extrusion_width", have_perimeters || have_skirt || have_brim);
toggle_field("perimeter_extrusion_width_even_layers", have_perimeters);
toggle_field("support_material_extruder", have_support_material || have_skirt);
toggle_field("support_material_speed", have_support_material || have_brim || have_skirt);

Expand Down
4 changes: 3 additions & 1 deletion src/slic3r/GUI/PresetHints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
[first_layer_extrusion_width_ptr, extrusion_width, nozzle_diameter, lh, bridging, bridge_speed, bridge_flow_ratio, limit_by_first_layer_speed, max_print_speed, &max_flow, &max_flow_extrusion_type]
(FlowRole flow_role, const ConfigOptionFloatOrPercent &this_extrusion_width, double speed, const char *err_msg) {
Flow flow = bridging ?
Flow::new_from_config_width(flow_role, first_positive(first_layer_extrusion_width_ptr, this_extrusion_width, extrusion_width), nozzle_diameter, lh) :
Flow::new_from_config_width(flow_role, first_positive(first_layer_extrusion_width_ptr, this_extrusion_width, extrusion_width), 0, nozzle_diameter, lh) :
Flow::bridging_flow(nozzle_diameter * bridge_flow_ratio, nozzle_diameter);
double volumetric_flow = flow.mm3_per_mm() * (bridging ? bridge_speed : limit_by_first_layer_speed(speed, max_print_speed));
if (max_flow < volumetric_flow) {
Expand Down Expand Up @@ -224,10 +224,12 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
Flow external_perimeter_flow = Flow::new_from_config_width(
frExternalPerimeter,
*print_config.opt<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"),
0,
nozzle_diameter, layer_height);
Flow perimeter_flow = Flow::new_from_config_width(
frPerimeter,
*print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"),
0,
nozzle_diameter, layer_height);
double width = external_perimeter_flow.width() + external_perimeter_flow.spacing();
for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) {
Expand Down
Loading

0 comments on commit bfcd8e1

Please sign in to comment.