updating the gcode extrude to support new overhang attributes

This commit is contained in:
Pavel 2023-07-20 10:59:14 +02:00 committed by Vojtech Bubnik
parent 4ad4ae2754
commit bf6a8dc0b0
4 changed files with 90 additions and 49 deletions

View File

@ -2047,10 +2047,6 @@ LayerResult GCodeGenerator::process_layer(
}
}
for (const ObjectLayerToPrint &layer_to_print : layers) {
m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.object_layer);
}
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
for (unsigned int extruder_id : layer_tools.extruders)
{
@ -2182,8 +2178,6 @@ void GCodeGenerator::process_layer_single_object(
const PrintObject &print_object = print_instance.print_object;
const Print &print = *print_object.print();
m_extrusion_quality_estimator.set_current_object(&print_object);
if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr)
if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) {
ExtrusionRole role = support_layer.support_fills.role();
@ -2781,10 +2775,7 @@ std::string GCodeGenerator::_extrude(
);
}
bool variable_speed_or_fan_speed = false;
std::vector<ProcessedPoint> new_points{};
if ((this->m_config.enable_dynamic_overhang_speeds || this->config().enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) &&
!this->on_first_layer() && path_attr.role.is_perimeter()) {
if (path_attr.overhang_attributes.has_value()) {
std::vector<std::pair<int, ConfigOptionFloatOrPercent>> overhangs_with_speeds = {{100, ConfigOptionFloatOrPercent{speed, false}}};
if (this->m_config.enable_dynamic_overhang_speeds) {
overhangs_with_speeds = {{0, m_config.overhang_speed_0},
@ -2807,22 +2798,66 @@ std::string GCodeGenerator::_extrude(
if (external_perim_reference_speed == 0)
external_perim_reference_speed = m_volumetric_speed / path_attr.mm3_per_mm;
if (m_config.max_volumetric_speed.value > 0)
external_perim_reference_speed = std::min(external_perim_reference_speed, m_config.max_volumetric_speed.value / path_attr.mm3_per_mm);
external_perim_reference_speed = std::min(external_perim_reference_speed,
m_config.max_volumetric_speed.value / path_attr.mm3_per_mm);
if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
external_perim_reference_speed = std::min(external_perim_reference_speed,
EXTRUDER_CONFIG(filament_max_volumetric_speed) / path_attr.mm3_per_mm);
}
ExtrusionProcessor::calculate_overhang_speed();
new_points = m_extrusion_quality_estimator.estimate_speed_from_extrusion_quality(
//FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation.
Points{},
path_attr, overhangs_with_speeds, overhang_w_fan_speeds,
m_writer.extruder()->id(), external_perim_reference_speed,
// FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation.
Points{}, path_attr, overhangs_with_speeds, overhang_w_fan_speeds, m_writer.extruder()->id(), external_perim_reference_speed,
speed);
variable_speed_or_fan_speed = std::any_of(new_points.begin(), new_points.end(),
[speed](const ProcessedPoint &p) { return p.speed != speed || p.fan_speed != 0; });
}
// bool variable_speed_or_fan_speed = false;
// std::vector<ProcessedPoint> new_points{};
// if ((this->m_config.enable_dynamic_overhang_speeds || this->config().enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) &&
// !this->on_first_layer() && path_attr.role.is_perimeter()) {
// std::vector<std::pair<int, ConfigOptionFloatOrPercent>> overhangs_with_speeds = {{100, ConfigOptionFloatOrPercent{speed, false}}};
// if (this->m_config.enable_dynamic_overhang_speeds) {
// overhangs_with_speeds = {{0, m_config.overhang_speed_0},
// {25, m_config.overhang_speed_1},
// {50, m_config.overhang_speed_2},
// {75, m_config.overhang_speed_3},
// {100, ConfigOptionFloatOrPercent{speed, false}}};
// }
// std::vector<std::pair<int, ConfigOptionInts>> overhang_w_fan_speeds = {{100, ConfigOptionInts{0}}};
// if (this->m_config.enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())) {
// overhang_w_fan_speeds = {{0, m_config.overhang_fan_speed_0},
// {25, m_config.overhang_fan_speed_1},
// {50, m_config.overhang_fan_speed_2},
// {75, m_config.overhang_fan_speed_3},
// {100, ConfigOptionInts{0}}};
// }
// 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;
// if (m_config.max_volumetric_speed.value > 0)
// external_perim_reference_speed = std::min(external_perim_reference_speed, m_config.max_volumetric_speed.value / path_attr.mm3_per_mm);
// if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
// external_perim_reference_speed = std::min(external_perim_reference_speed,
// EXTRUDER_CONFIG(filament_max_volumetric_speed) / path_attr.mm3_per_mm);
// }
// new_points = m_extrusion_quality_estimator.estimate_speed_from_extrusion_quality(
// //FIXME convert estimate_speed_from_extrusion_quality() to smooth paths or move it before smooth path interpolation.
// Points{},
// path_attr, overhangs_with_speeds, overhang_w_fan_speeds,
// m_writer.extruder()->id(), external_perim_reference_speed,
// speed);
// variable_speed_or_fan_speed = std::any_of(new_points.begin(), new_points.end(),
// [speed](const ProcessedPoint &p) { return p.speed != speed || p.fan_speed != 0; });
// }
double F = speed * 60; // convert mm/sec to mm/min
// extrude arc or line

View File

@ -293,8 +293,6 @@ private:
// Cache for custom seam enforcers/blockers for each layer.
SeamPlacer m_seam_placer;
ExtrusionQualityEstimator m_extrusion_quality_estimator;
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude*() and travel_to()
methods. */

View File

@ -1,6 +1,7 @@
#include "ExtrusionProcessor.hpp"
#include <string>
namespace Slic3r {
namespace Slic3r { namespace ExtrusionProcessor {
ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath &path,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
@ -83,6 +84,8 @@ ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath
result.back().polyline.append(Point::new_scale(extended_points[i].position));
}
std::cout << "ExtrusionPath " << std::to_string(size_t(&path)) << " split to " << result.size() << " paths";
return result;
};
@ -126,4 +129,4 @@ ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const Extru
return result;
};
} // namespace Slic3r
}} // namespace Slic3r::ExtrusionProcessor

View File

@ -28,13 +28,13 @@
#include <utility>
#include <vector>
namespace Slic3r {
namespace Slic3r { namespace ExtrusionProcessor {
struct ExtendedPoint
{
Vec2d position;
float distance;
float curvature;
Vec2d position;
float distance;
float curvature;
};
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
@ -48,27 +48,30 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
using AABBScalar = typename AABBTreeLines::LinesDistancer<L>::Scalar;
if (input_points.empty())
return {};
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
auto maybe_unscale = [](const P &p) { return SCALED_INPUT ? unscaled(p) : p.template cast<double>(); };
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
auto maybe_unscale = [](const P &p) { return SCALED_INPUT ? unscaled(p) : p.template cast<double>(); };
std::vector<ExtendedPoint> points;
points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1));
{
ExtendedPoint start_point{maybe_unscale(input_points.front())};
auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(start_point.position.cast<AABBScalar>());
start_point.distance = distance + boundary_offset;
auto [distance, nearest_line,
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(start_point.position.cast<AABBScalar>());
start_point.distance = distance + boundary_offset;
points.push_back(start_point);
}
for (size_t i = 1; i < input_points.size(); i++) {
ExtendedPoint next_point{maybe_unscale(input_points[i])};
auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.cast<AABBScalar>());
next_point.distance = distance + boundary_offset;
auto [distance, nearest_line,
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.cast<AABBScalar>());
next_point.distance = distance + boundary_offset;
if (ADD_INTERSECTIONS &&
((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) {
const ExtendedPoint &prev_point = points.back();
auto intersections = unscaled_prev_layer.template intersections_with_line<true>(L{prev_point.position.cast<AABBScalar>(), next_point.position.cast<AABBScalar>()});
const ExtendedPoint &prev_point = points.back();
auto intersections = unscaled_prev_layer.template intersections_with_line<true>(
L{prev_point.position.cast<AABBScalar>(), next_point.position.cast<AABBScalar>()});
for (const auto &intersection : intersections) {
ExtendedPoint p{};
p.position = intersection.first.template cast<double>();
@ -81,7 +84,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS) {
std::vector<ExtendedPoint> new_points;
new_points.reserve(points.size()*2);
new_points.reserve(points.size() * 2);
new_points.push_back(points.front());
for (int point_idx = 0; point_idx < int(points.size()) - 1; ++point_idx) {
const ExtendedPoint &curr = points[point_idx];
@ -97,19 +100,21 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
double t1 = std::max(a0, a1);
if (t0 < 1.0) {
auto p0 = curr.position + t0 * (next.position - curr.position);
auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p0.cast<AABBScalar>());
auto p0 = curr.position + t0 * (next.position - curr.position);
auto [p0_dist, p0_near_l,
p0_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p0.cast<AABBScalar>());
ExtendedPoint new_p{};
new_p.position = p0;
new_p.distance = float(p0_dist + boundary_offset);
new_p.position = p0;
new_p.distance = float(p0_dist + boundary_offset);
new_points.push_back(new_p);
}
if (t1 > 0.0) {
auto p1 = curr.position + t1 * (next.position - curr.position);
auto [p1_dist, p1_near_l, p1_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p1.cast<AABBScalar>());
auto p1 = curr.position + t1 * (next.position - curr.position);
auto [p1_dist, p1_near_l,
p1_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p1.cast<AABBScalar>());
ExtendedPoint new_p{};
new_p.position = p1;
new_p.distance = float(p1_dist + boundary_offset);
new_p.position = p1;
new_p.distance = float(p1_dist + boundary_offset);
new_points.push_back(new_p);
}
}
@ -121,7 +126,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
if (max_line_length > 0) {
std::vector<ExtendedPoint> new_points;
new_points.reserve(points.size()*2);
new_points.reserve(points.size() * 2);
{
for (size_t i = 0; i + 1 < points.size(); i++) {
const ExtendedPoint &curr = points[i];
@ -135,8 +140,8 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
auto [p_dist, p_near_l,
p_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(pos.cast<AABBScalar>());
ExtendedPoint new_p{};
new_p.position = pos;
new_p.distance = float(p_dist + boundary_offset);
new_p.position = pos;
new_p.distance = float(p_dist + boundary_offset);
new_points.push_back(new_p);
}
}
@ -213,14 +218,14 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
return points;
}
ExtrusionPaths calculate_and_split_overhanging_extrusions(const ExtrusionPath &path,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
const AABBTreeLines::LinesDistancer<CurledLine> &prev_layer_curled_lines);
ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(const ExtrusionEntityCollection *ecc,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
const AABBTreeLines::LinesDistancer<CurledLine> &prev_layer_curled_lines);
ExtrusionEntityCollection calculate_and_split_overhanging_extrusions(
const ExtrusionEntityCollection *ecc,
const AABBTreeLines::LinesDistancer<Linef> &unscaled_prev_layer,
const AABBTreeLines::LinesDistancer<CurledLine> &prev_layer_curled_lines);
struct ProcessedPoint
{
@ -364,6 +369,6 @@ public:
}
};
} // namespace Slic3r
}} // namespace Slic3r::ExtrusionProcessor
#endif // slic3r_ExtrusionProcessor_hpp_