mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-29 16:52:01 +08:00
Refactoring of the dynamic speed on overhangs.
This commit is contained in:
parent
109b36ab5e
commit
070b2af3fd
@ -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
|
||||
);
|
||||
|
||||
dynamic_speed_and_fan_speed = ExtrusionProcessor::calculate_overhang_speed(path_attr, this->m_config, m_writer.extruder()->id(),
|
||||
external_perim_reference_speed, speed);
|
||||
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;
|
||||
}
|
||||
|
||||
if (dynamic_speed_and_fan_speed.first > -1) {
|
||||
speed = dynamic_speed_and_fan_speed.first;
|
||||
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_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;
|
||||
|
@ -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,16 +146,18 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const Extru
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
std::pair<float,float> calculate_overhang_speed(const ExtrusionAttributes &attributes,
|
||||
static std::map<float, float> calc_print_speed_sections(const ExtrusionAttributes &attributes,
|
||||
const FullPrintConfig &config,
|
||||
size_t extruder_id,
|
||||
float external_perim_reference_speed,
|
||||
float default_speed)
|
||||
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},
|
||||
@ -164,7 +166,33 @@ std::pair<float,float> calculate_overhang_speed(const ExtrusionAttributes &attri
|
||||
{100, ConfigOptionFloatOrPercent{default_speed, false}}};
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, ConfigOptionInts>> overhang_with_fan_speeds = {{100, ConfigOptionInts{0}}};
|
||||
const float speed_base = external_perimeter_reference_speed > 0 ? external_perimeter_reference_speed : default_speed;
|
||||
std::map<float, float> speed_sections;
|
||||
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},
|
||||
@ -173,30 +201,29 @@ std::pair<float,float> calculate_overhang_speed(const ExtrusionAttributes &attri
|
||||
{100, ConfigOptionInts{0}}};
|
||||
}
|
||||
|
||||
float speed_base = external_perim_reference_speed > 0 ? external_perim_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)
|
||||
speed = speed_base;
|
||||
speed_sections[distance] = speed;
|
||||
}
|
||||
|
||||
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),
|
||||
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));
|
||||
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),
|
||||
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;
|
||||
overhang_speeds.print_speed = -1;
|
||||
}
|
||||
|
||||
if (!config.enable_dynamic_fan_speeds.get_at(extruder_id)) {
|
||||
fan_speed = -1;
|
||||
overhang_speeds.fan_speed = -1;
|
||||
}
|
||||
|
||||
return {final_speed, fan_speed};
|
||||
return overhang_speeds;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::ExtrusionProcessor
|
||||
} // namespace Slic3r::ExtrusionProcessor
|
||||
|
@ -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,
|
||||
OverhangSpeeds calculate_overhang_speed(const ExtrusionAttributes &attributes,
|
||||
const FullPrintConfig &config,
|
||||
size_t extruder_id,
|
||||
float external_perim_reference_speed,
|
||||
float external_perimeter_reference_speed,
|
||||
float default_speed);
|
||||
|
||||
}} // namespace Slic3r::ExtrusionProcessor
|
||||
} // namespace Slic3r::ExtrusionProcessor
|
||||
|
||||
#endif // slic3r_ExtrusionProcessor_hpp_
|
||||
|
Loading…
x
Reference in New Issue
Block a user