Refactoring of the dynamic speed on overhangs.

This commit is contained in:
Lukáš Hejl 2024-06-24 10:19:02 +02:00 committed by Lukas Matena
parent 109b36ab5e
commit 070b2af3fd
4 changed files with 110 additions and 70 deletions

View File

@ -3217,21 +3217,20 @@ std::string GCodeGenerator::_extrude(
else if (this->object_layer_over_raft())
speed = m_config.get_abs_value("first_layer_speed_over_raft", speed);
std::pair<float, float> dynamic_speed_and_fan_speed{-1, -1};
ExtrusionProcessor::OverhangSpeeds dynamic_print_and_fan_speeds = {-1.f, -1.f};
if (path_attr.overhang_attributes.has_value()) {
double external_perim_reference_speed = m_config.get_abs_value("external_perimeter_speed");
if (external_perim_reference_speed == 0)
external_perim_reference_speed = m_volumetric_speed / path_attr.mm3_per_mm;
external_perim_reference_speed = cap_speed(
external_perim_reference_speed, m_config, m_writer.extruder()->id(), path_attr
);
double external_perimeter_reference_speed = m_config.get_abs_value("external_perimeter_speed");
if (external_perimeter_reference_speed == 0) {
external_perimeter_reference_speed = m_volumetric_speed / path_attr.mm3_per_mm;
}
dynamic_speed_and_fan_speed = ExtrusionProcessor::calculate_overhang_speed(path_attr, this->m_config, m_writer.extruder()->id(),
external_perim_reference_speed, speed);
external_perimeter_reference_speed = cap_speed(external_perimeter_reference_speed, m_config, m_writer.extruder()->id(), path_attr);
dynamic_print_and_fan_speeds = ExtrusionProcessor::calculate_overhang_speed(path_attr, this->m_config, m_writer.extruder()->id(),
float(external_perimeter_reference_speed), float(speed));
}
if (dynamic_speed_and_fan_speed.first > -1) {
speed = dynamic_speed_and_fan_speed.first;
if (dynamic_print_and_fan_speeds.print_speed > -1) {
speed = dynamic_print_and_fan_speeds.print_speed;
}
// cap speed with max_volumetric_speed anyway (even if user is not using autospeed)
@ -3292,8 +3291,10 @@ std::string GCodeGenerator::_extrude(
// F is mm per minute.
gcode += m_writer.set_speed(F, "", cooling_marker_setspeed_comments);
if (dynamic_speed_and_fan_speed.second >= 0)
gcode += ";_SET_FAN_SPEED" + std::to_string(int(dynamic_speed_and_fan_speed.second)) + "\n";
if (dynamic_print_and_fan_speeds.fan_speed >= 0) {
gcode += ";_SET_FAN_SPEED" + std::to_string(int(dynamic_print_and_fan_speeds.fan_speed)) + "\n";
}
std::string comment;
if (m_config.gcode_comments) {
@ -3343,11 +3344,13 @@ std::string GCodeGenerator::_extrude(
}
}
if (m_enable_cooling_markers)
if (m_enable_cooling_markers) {
gcode += path_attr.role.is_bridge() ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
}
if (dynamic_speed_and_fan_speed.second >= 0)
if (dynamic_print_and_fan_speeds.fan_speed >= 0) {
gcode += ";_RESET_FAN_SPEED\n";
}
this->last_position = path.back().point;
return gcode;

View File

@ -11,7 +11,7 @@
#include "libslic3r/Line.hpp"
#include "libslic3r/Polygon.hpp"
namespace Slic3r { namespace ExtrusionProcessor {
namespace Slic3r::ExtrusionProcessor {
ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath &path,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
@ -146,57 +146,84 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const Extru
return result;
};
std::pair<float,float> calculate_overhang_speed(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
size_t extruder_id,
float external_perim_reference_speed,
float default_speed)
static std::map<float, float> calc_print_speed_sections(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
const float external_perimeter_reference_speed,
const float default_speed)
{
assert(attributes.overhang_attributes.has_value());
std::vector<std::pair<int, ConfigOptionFloatOrPercent>> overhangs_with_speeds = {
{100, ConfigOptionFloatOrPercent{default_speed, false}}};
struct OverhangWithSpeed
{
int percent;
ConfigOptionFloatOrPercent print_speed;
};
std::vector<OverhangWithSpeed> overhangs_with_speeds = {{100, ConfigOptionFloatOrPercent{default_speed, false}}};
if (config.enable_dynamic_overhang_speeds) {
overhangs_with_speeds = {{0, config.overhang_speed_0},
{25, config.overhang_speed_1},
{50, config.overhang_speed_2},
{75, config.overhang_speed_3},
overhangs_with_speeds = {{ 0, config.overhang_speed_0},
{ 25, config.overhang_speed_1},
{ 50, config.overhang_speed_2},
{ 75, config.overhang_speed_3},
{100, ConfigOptionFloatOrPercent{default_speed, false}}};
}
std::vector<std::pair<int, ConfigOptionInts>> overhang_with_fan_speeds = {{100, ConfigOptionInts{0}}};
if (config.enable_dynamic_fan_speeds.get_at(extruder_id)) {
overhang_with_fan_speeds = {{0, config.overhang_fan_speed_0},
{25, config.overhang_fan_speed_1},
{50, config.overhang_fan_speed_2},
{75, config.overhang_fan_speed_3},
{100, ConfigOptionInts{0}}};
}
float speed_base = external_perim_reference_speed > 0 ? external_perim_reference_speed : default_speed;
const float speed_base = external_perimeter_reference_speed > 0 ? external_perimeter_reference_speed : default_speed;
std::map<float, float> speed_sections;
for (size_t i = 0; i < overhangs_with_speeds.size(); i++) {
float distance = attributes.width * (1.0 - (overhangs_with_speeds[i].first / 100.0));
float speed = overhangs_with_speeds[i].second.percent ? (speed_base * overhangs_with_speeds[i].second.value / 100.0) :
overhangs_with_speeds[i].second.value;
if (speed < EPSILON)
for (OverhangWithSpeed &overhangs_with_speed : overhangs_with_speeds) {
const float distance = attributes.width * (1.f - (float(overhangs_with_speed.percent) / 100.f));
float speed = float(overhangs_with_speed.print_speed.get_abs_value(speed_base));
if (speed < EPSILON) {
speed = speed_base;
}
speed_sections[distance] = speed;
}
return speed_sections;
}
static std::map<float, float> calc_fan_speed_sections(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
const size_t extruder_id)
{
struct OverhangWithFanSpeed
{
int percent;
ConfigOptionInts fan_speed;
};
std::vector<OverhangWithFanSpeed> overhang_with_fan_speeds = {{100, ConfigOptionInts{0}}};
if (config.enable_dynamic_fan_speeds.get_at(extruder_id)) {
overhang_with_fan_speeds = {{ 0, config.overhang_fan_speed_0},
{ 25, config.overhang_fan_speed_1},
{ 50, config.overhang_fan_speed_2},
{ 75, config.overhang_fan_speed_3},
{100, ConfigOptionInts{0}}};
}
std::map<float, float> fan_speed_sections;
for (size_t i = 0; i < overhang_with_fan_speeds.size(); i++) {
float distance = attributes.width * (1.0 - (overhang_with_fan_speeds[i].first / 100.0));
float fan_speed = overhang_with_fan_speeds[i].second.get_at(extruder_id);
for (OverhangWithFanSpeed &overhang_with_fan_speed : overhang_with_fan_speeds) {
float distance = attributes.width * (1.f - (float(overhang_with_fan_speed.percent) / 100.f));
float fan_speed = float(overhang_with_fan_speed.fan_speed.get_at(extruder_id));
fan_speed_sections[distance] = fan_speed;
}
return fan_speed_sections;
}
OverhangSpeeds calculate_overhang_speed(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
const size_t extruder_id,
const float external_perimeter_reference_speed,
const float default_speed)
{
assert(attributes.overhang_attributes.has_value());
auto interpolate_speed = [](const std::map<float, float> &values, float distance) {
auto upper_dist = values.lower_bound(distance);
if (upper_dist == values.end()) {
return values.rbegin()->second;
}
if (upper_dist == values.begin()) {
} else if (upper_dist == values.begin()) {
return upper_dist->second;
}
@ -205,22 +232,26 @@ std::pair<float,float> calculate_overhang_speed(const ExtrusionAttributes &attri
return (1.0f - t) * lower_dist->second + t * upper_dist->second;
};
float extrusion_speed = std::min(interpolate_speed(speed_sections, attributes.overhang_attributes->start_distance_from_prev_layer),
interpolate_speed(speed_sections, attributes.overhang_attributes->end_distance_from_prev_layer));
float curled_base_speed = interpolate_speed(speed_sections,
attributes.width * attributes.overhang_attributes->proximity_to_curled_lines);
float final_speed = std::min(curled_base_speed, extrusion_speed);
float fan_speed = std::min(interpolate_speed(fan_speed_sections, attributes.overhang_attributes->start_distance_from_prev_layer),
interpolate_speed(fan_speed_sections, attributes.overhang_attributes->end_distance_from_prev_layer));
const std::map<float, float> speed_sections = calc_print_speed_sections(attributes, config, external_perimeter_reference_speed, default_speed);
const std::map<float, float> fan_speed_sections = calc_fan_speed_sections(attributes, config, extruder_id);
const float extrusion_speed = std::min(interpolate_speed(speed_sections, attributes.overhang_attributes->start_distance_from_prev_layer),
interpolate_speed(speed_sections, attributes.overhang_attributes->end_distance_from_prev_layer));
const float curled_base_speed = interpolate_speed(speed_sections, attributes.width * attributes.overhang_attributes->proximity_to_curled_lines);
const float fan_speed = std::min(interpolate_speed(fan_speed_sections, attributes.overhang_attributes->start_distance_from_prev_layer),
interpolate_speed(fan_speed_sections, attributes.overhang_attributes->end_distance_from_prev_layer));
OverhangSpeeds overhang_speeds = {std::min(curled_base_speed, extrusion_speed), fan_speed};
if (!config.enable_dynamic_overhang_speeds) {
final_speed = -1;
}
if (!config.enable_dynamic_fan_speeds.get_at(extruder_id)) {
fan_speed = -1;
overhang_speeds.print_speed = -1;
}
return {final_speed, fan_speed};
if (!config.enable_dynamic_fan_speeds.get_at(extruder_id)) {
overhang_speeds.fan_speed = -1;
}
return overhang_speeds;
}
}} // namespace Slic3r::ExtrusionProcessor
} // namespace Slic3r::ExtrusionProcessor

View File

@ -42,7 +42,7 @@ class CurledLine;
class Linef;
} // namespace Slic3r
namespace Slic3r { namespace ExtrusionProcessor {
namespace Slic3r::ExtrusionProcessor {
struct ExtendedPoint
{
@ -51,6 +51,12 @@ struct ExtendedPoint
float curvature;
};
struct OverhangSpeeds
{
float print_speed;
float fan_speed;
};
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
std::vector<ExtendedPoint> estimate_points_properties(const POINTS &input_points,
const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer,
@ -266,12 +272,12 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
const AABBTreeLines::LinesDistancer<CurledLine> &prev_layer_curled_lines);
std::pair<float, float> calculate_overhang_speed(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
size_t extruder_id,
float external_perim_reference_speed,
float default_speed);
OverhangSpeeds calculate_overhang_speed(const ExtrusionAttributes &attributes,
const FullPrintConfig &config,
size_t extruder_id,
float external_perimeter_reference_speed,
float default_speed);
}} // namespace Slic3r::ExtrusionProcessor
} // namespace Slic3r::ExtrusionProcessor
#endif // slic3r_ExtrusionProcessor_hpp_

View File

@ -2389,7 +2389,7 @@ void TabFilament::toggle_options()
bool dynamic_fan_speeds = m_config->opt_bool("enable_dynamic_fan_speeds", 0);
for (int i = 0; i < 4; i++) {
toggle_option("overhang_fan_speed_"+std::to_string(i),dynamic_fan_speeds);
toggle_option("overhang_fan_speed_"+std::to_string(i),dynamic_fan_speeds);
}
}