mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-11 14:59:00 +08:00
updating the gcode extrude to support new overhang attributes
This commit is contained in:
parent
4ad4ae2754
commit
bf6a8dc0b0
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
@ -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_
|
||||
|
Loading…
x
Reference in New Issue
Block a user