Move skirt smooth path generation to extrusion order

This commit is contained in:
Martin Šach 2024-06-18 13:08:33 +02:00 committed by Lukas Matena
parent a5f6da6bd5
commit 773c34f906
4 changed files with 54 additions and 26 deletions

View File

@ -2288,6 +2288,7 @@ std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorte
const ObjectsLayerToPrint &layers,
const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print,
const GCode::SmoothPathCaches &smooth_path_caches,
const bool first_layer
) {
// Map from extruder ID to <begin, end> index of skirt loops to be extruded with that extruder.
@ -2331,7 +2332,11 @@ std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorte
first_layer,
layer_tools,
instances_to_print,
smooth_path_caches.global(),
skirt_loops_per_extruder,
m_enable_loop_clipping,
m_config,
m_scaled_resolution,
this->m_writer.extruder()->id(),
place_seam,
!this->m_brim_done,
@ -2419,7 +2424,7 @@ LayerResult GCodeGenerator::process_layer(
using GCode::ExtrusionOrder::ExtruderExtrusions;
std::vector<ExtruderExtrusions> extrusions{
this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, first_layer)};
this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, smooth_path_caches, first_layer)};
std::string gcode;
assert(is_decimal_separator_point()); // for the sprintfs
@ -2544,10 +2549,10 @@ LayerResult GCodeGenerator::process_layer(
m_avoid_crossing_perimeters.use_external_mp();
Flow layer_skirt_flow = print.skirt_flow().with_height(float(m_skirt_done.back() - (m_skirt_done.size() == 1 ? 0. : m_skirt_done[m_skirt_done.size() - 2])));
double mm3_per_mm = layer_skirt_flow.mm3_per_mm();
for (const auto&[_, loop_entity] : extruder_extrusions.skirt) {
for (const auto&[_, smooth_path] : extruder_extrusions.skirt) {
// Adjust flow according to this layer's layer height.
//FIXME using the support_material_speed of the 1st object printed.
gcode += this->extrude_skirt(dynamic_cast<const ExtrusionLoop&>(*loop_entity),
gcode += this->extrude_skirt(smooth_path,
// Override of skirt extrusion parameters. extrude_skirt() will fill in the extrusion width.
ExtrusionFlow{ mm3_per_mm, 0., layer_skirt_flow.height() },
smooth_path_caches.global(), "skirt"sv, m_config.support_material_speed.value);
@ -2889,8 +2894,6 @@ static inline bool validate_smooth_path(const GCode::SmoothPath &smooth_path, bo
}
#endif //NDEBUG
static constexpr const double min_gcode_segment_length = 0.002;
std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed)
{
// Extrude all loops CCW unless CW movements are prefered.
@ -2910,7 +2913,7 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
// if polyline was shorter than the clipping distance we'd get a null polyline, so
// we discard it in that case.
if (m_enable_loop_clipping)
clip_end(smooth_path, scaled<double>(EXTRUDER_CONFIG(nozzle_diameter)) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER, scaled<double>(min_gcode_segment_length));
clip_end(smooth_path, scaled<double>(EXTRUDER_CONFIG(nozzle_diameter)) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER, scaled<double>(GCode::ExtrusionOrder::min_gcode_segment_length));
if (smooth_path.empty())
return {};
@ -2946,25 +2949,9 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
}
std::string GCodeGenerator::extrude_skirt(
const ExtrusionLoop &loop_src, const ExtrusionFlow &extrusion_flow_override,
GCode::SmoothPath smooth_path, const ExtrusionFlow &extrusion_flow_override,
const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed)
{
assert(loop_src.is_counter_clockwise());
const bool reverse_loop = m_config.prefer_clockwise_movements;
Point seam_point = this->last_position.has_value() ? *this->last_position : Point::Zero();
GCode::SmoothPath smooth_path = smooth_path_cache.resolve_or_fit_split_with_seam(loop_src, reverse_loop, m_scaled_resolution, seam_point, scaled<double>(0.0015));
// Clip the path to avoid the extruder to get exactly on the first point of the loop;
// if polyline was shorter than the clipping distance we'd get a null polyline, so
// we discard it in that case.
if (m_enable_loop_clipping)
clip_end(smooth_path, scale_(EXTRUDER_CONFIG(nozzle_diameter)) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER, scaled<double>(min_gcode_segment_length));
if (smooth_path.empty())
return {};
assert(validate_smooth_path(smooth_path, ! m_enable_loop_clipping));
// Extrude along the smooth path.
std::string gcode;

View File

@ -236,6 +236,7 @@ private:
const ObjectsLayerToPrint &layers,
const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print,
const GCode::SmoothPathCaches &smooth_path_caches,
const bool first_layer
);
@ -282,7 +283,7 @@ private:
);
std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
std::string extrude_loop(const ExtrusionLoop &loop, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
std::string extrude_skirt(const ExtrusionLoop &loop_src, const ExtrusionFlow &extrusion_flow_override,
std::string extrude_skirt(GCode::SmoothPath smooth_path, const ExtrusionFlow &extrusion_flow_override,
const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed);
std::string extrude_multi_path(const ExtrusionMultiPath &multipath, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);

View File

@ -1,4 +1,5 @@
#include "ExtrusionOrder.hpp"
#include "GCode/SmoothPath.hpp"
#include "libslic3r/ShortestPath.hpp"
namespace Slic3r::GCode::ExtrusionOrder {
@ -453,7 +454,11 @@ std::vector<ExtruderExtrusions> get_extrusions(
const bool is_first_layer,
const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print,
const GCode::SmoothPathCache &smooth_path_cache,
const std::map<unsigned int, std::pair<size_t, size_t>> &skirt_loops_per_extruder,
const bool enable_loop_clipping,
const FullPrintConfig &config,
const double scaled_resolution,
unsigned current_extruder_id,
const SeamPlacingFunciton &place_seam,
bool get_brim,
@ -477,7 +482,35 @@ std::vector<ExtruderExtrusions> get_extrusions(
if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) {
const std::pair<size_t, size_t> loops = loops_it->second;
for (std::size_t i = loops.first; i < loops.second; ++i) {
extruder_extrusions.skirt.emplace_back(i, print.skirt().entities[i]);
auto loop_src{dynamic_cast<const ExtrusionLoop *>(print.skirt().entities[i])};
if (loop_src != nullptr) {
const Point seam_point = previous_position ? get_instance_point(*previous_position, {0.0, 0.0}) : Point::Zero();
const bool reverse_loop = config.prefer_clockwise_movements;
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
// thus empty path segments will not be produced by G-code export.
GCode::SmoothPath smooth_path = smooth_path_cache.resolve_or_fit_split_with_seam(*loop_src, reverse_loop, scaled_resolution, seam_point, scaled<double>(0.0015));
// Clip the path to avoid the extruder to get exactly on the first point of the loop;
// if polyline was shorter than the clipping distance we'd get a null polyline, so
// we discard it in that case.
const auto nozzle_diameter{config.nozzle_diameter.get_at(extruder_id)};
if (enable_loop_clipping)
clip_end(smooth_path, scale_(nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER, scaled<double>(min_gcode_segment_length));
if (smooth_path.empty())
continue;
assert(validate_smooth_path(smooth_path, ! enable_loop_clipping));
for (const SmoothPathElement &element : smooth_path) {
if (!element.path.empty()) {
previous_position = get_gcode_point(element.path.back().point, {0.0, 0.0});
break;
}
}
extruder_extrusions.skirt.emplace_back(i, std::move(smooth_path));
}
}
}

View File

@ -3,6 +3,7 @@
#include <vector>
#include "libslic3r/GCode/SmoothPath.hpp"
#include "libslic3r/GCode/WipeTowerIntegration.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
#include "libslic3r/GCode/SeamPlacer.hpp"
@ -98,12 +99,14 @@ std::vector<NormalExtrusions> get_normal_extrusions(
struct ExtruderExtrusions {
unsigned extruder_id;
std::vector<std::pair<std::size_t, const ExtrusionEntity *>> skirt;
std::vector<std::pair<std::size_t, GCode::SmoothPath>> skirt;
ExtrusionEntitiesPtr brim;
std::vector<std::vector<SliceExtrusions>> overriden_extrusions;
std::vector<NormalExtrusions> normal_extrusions;
};
static constexpr const double min_gcode_segment_length = 0.002;
std::vector<ExtruderExtrusions> get_extrusions(
const Print &print,
const GCode::WipeTowerIntegration *wipe_tower,
@ -111,7 +114,11 @@ std::vector<ExtruderExtrusions> get_extrusions(
const bool is_first_layer,
const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print,
const GCode::SmoothPathCache &smooth_path_cache,
const std::map<unsigned int, std::pair<size_t, size_t>> &skirt_loops_per_extruder,
const bool enable_loop_clipping,
const FullPrintConfig &config,
const double scaled_resolution,
unsigned current_extruder_id,
const SeamPlacingFunciton &place_seam,
bool get_brim,