mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-07 14:58:59 +08:00
Move get_sorted_extrusions to a gcode generator method
This commit is contained in:
parent
40da8d7336
commit
a5f6da6bd5
@ -2283,6 +2283,66 @@ std::string GCodeGenerator::generate_ramping_layer_change_gcode(
|
|||||||
return travel_gcode;
|
return travel_gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorted_extrusions(
|
||||||
|
const Print &print,
|
||||||
|
const ObjectsLayerToPrint &layers,
|
||||||
|
const LayerTools &layer_tools,
|
||||||
|
const std::vector<InstanceToPrint> &instances_to_print,
|
||||||
|
const bool first_layer
|
||||||
|
) {
|
||||||
|
// Map from extruder ID to <begin, end> index of skirt loops to be extruded with that extruder.
|
||||||
|
// Extrude skirt at the print_z of the raft layers and normal object layers
|
||||||
|
// not at the print_z of the interlaced support material layers.
|
||||||
|
std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder{
|
||||||
|
first_layer ?
|
||||||
|
Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) :
|
||||||
|
Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done)};
|
||||||
|
|
||||||
|
const auto place_seam =[&](
|
||||||
|
const Layer &layer, ExtrusionEntity *perimeter, const std::optional<Point> &previous_position
|
||||||
|
) {
|
||||||
|
auto loop{dynamic_cast<ExtrusionLoop *>(perimeter)};
|
||||||
|
|
||||||
|
Point seam_point{previous_position ? *previous_position : Point::Zero()};
|
||||||
|
if (!this->m_config.spiral_vase && loop != nullptr) {
|
||||||
|
seam_point = this->m_seam_placer.place_seam(&layer, *loop, seam_point);
|
||||||
|
loop->seam = seam_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto path{dynamic_cast<const ExtrusionMultiPath *>(perimeter)};
|
||||||
|
if (path != nullptr) {
|
||||||
|
return path->last_point();
|
||||||
|
} else {
|
||||||
|
return seam_point;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using GCode::ExtrusionOrder::ExtruderExtrusions;
|
||||||
|
using GCode::ExtrusionOrder::get_extrusions;
|
||||||
|
|
||||||
|
const std::optional<Vec2d> previous_position{
|
||||||
|
this->last_position ? std::optional{this->point_to_gcode(*this->last_position)} :
|
||||||
|
std::nullopt};
|
||||||
|
std::vector<ExtruderExtrusions> extrusions{
|
||||||
|
get_extrusions(
|
||||||
|
print,
|
||||||
|
this->m_wipe_tower.get(),
|
||||||
|
layers,
|
||||||
|
first_layer,
|
||||||
|
layer_tools,
|
||||||
|
instances_to_print,
|
||||||
|
skirt_loops_per_extruder,
|
||||||
|
this->m_writer.extruder()->id(),
|
||||||
|
place_seam,
|
||||||
|
!this->m_brim_done,
|
||||||
|
previous_position
|
||||||
|
)
|
||||||
|
};
|
||||||
|
this->m_brim_done = true;
|
||||||
|
|
||||||
|
return extrusions;
|
||||||
|
}
|
||||||
|
|
||||||
// In sequential mode, process_layer is called once per each object and its copy,
|
// In sequential mode, process_layer is called once per each object and its copy,
|
||||||
// therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object.
|
// therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object.
|
||||||
// In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated.
|
// In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated.
|
||||||
@ -2357,6 +2417,9 @@ LayerResult GCodeGenerator::process_layer(
|
|||||||
m_enable_loop_clipping = !enable;
|
m_enable_loop_clipping = !enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using GCode::ExtrusionOrder::ExtruderExtrusions;
|
||||||
|
std::vector<ExtruderExtrusions> extrusions{
|
||||||
|
this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, first_layer)};
|
||||||
|
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
assert(is_decimal_separator_point()); // for the sprintfs
|
assert(is_decimal_separator_point()); // for the sprintfs
|
||||||
@ -2424,15 +2487,6 @@ LayerResult GCodeGenerator::process_layer(
|
|||||||
m_second_layer_things_done = true;
|
m_second_layer_things_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map from extruder ID to <begin, end> index of skirt loops to be extruded with that extruder.
|
|
||||||
std::map<unsigned int, std::pair<size_t, size_t>> skirt_loops_per_extruder;
|
|
||||||
|
|
||||||
// Extrude skirt at the print_z of the raft layers and normal object layers
|
|
||||||
// not at the print_z of the interlaced support material layers.
|
|
||||||
skirt_loops_per_extruder = first_layer ?
|
|
||||||
Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) :
|
|
||||||
Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done);
|
|
||||||
|
|
||||||
if (this->config().avoid_crossing_curled_overhangs) {
|
if (this->config().avoid_crossing_curled_overhangs) {
|
||||||
m_avoid_crossing_curled_overhangs.clear();
|
m_avoid_crossing_curled_overhangs.clear();
|
||||||
for (const ObjectLayerToPrint &layer_to_print : layers) {
|
for (const ObjectLayerToPrint &layer_to_print : layers) {
|
||||||
@ -2462,52 +2516,6 @@ LayerResult GCodeGenerator::process_layer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::NormalExtrusions;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const auto place_seam =[&](
|
|
||||||
const Layer &layer, ExtrusionEntity *perimeter, const std::optional<Point> &previous_position
|
|
||||||
) {
|
|
||||||
auto loop{dynamic_cast<ExtrusionLoop *>(perimeter)};
|
|
||||||
|
|
||||||
Point seam_point{previous_position ? *previous_position : Point::Zero()};
|
|
||||||
if (!this->m_config.spiral_vase && loop != nullptr) {
|
|
||||||
seam_point = this->m_seam_placer.place_seam(&layer, *loop, seam_point);
|
|
||||||
loop->seam = seam_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto path{dynamic_cast<const ExtrusionMultiPath *>(perimeter)};
|
|
||||||
if (path != nullptr) {
|
|
||||||
return path->last_point();
|
|
||||||
} else {
|
|
||||||
return seam_point;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::optional<Vec2d> previous_position;
|
|
||||||
if (this->last_position) {
|
|
||||||
previous_position = this->point_to_gcode(*this->last_position);
|
|
||||||
}
|
|
||||||
using GCode::ExtrusionOrder::ExtruderExtrusions;
|
|
||||||
using GCode::ExtrusionOrder::get_extrusions;
|
|
||||||
const std::vector<ExtruderExtrusions> extrusions{
|
|
||||||
get_extrusions(
|
|
||||||
print,
|
|
||||||
m_wipe_tower.get(),
|
|
||||||
layers,
|
|
||||||
first_layer,
|
|
||||||
layer_tools,
|
|
||||||
instances_to_print,
|
|
||||||
skirt_loops_per_extruder,
|
|
||||||
this->m_writer.extruder()->id(),
|
|
||||||
place_seam,
|
|
||||||
!m_brim_done,
|
|
||||||
previous_position
|
|
||||||
)
|
|
||||||
};
|
|
||||||
m_brim_done = true;
|
|
||||||
|
|
||||||
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
||||||
for (const ExtruderExtrusions &extruder_extrusions : extrusions)
|
for (const ExtruderExtrusions &extruder_extrusions : extrusions)
|
||||||
{
|
{
|
||||||
|
@ -231,6 +231,14 @@ private:
|
|||||||
const GCode::Impl::Travels::ElevatedTravelParams &elevation_params
|
const GCode::Impl::Travels::ElevatedTravelParams &elevation_params
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> get_sorted_extrusions(
|
||||||
|
const Print &print,
|
||||||
|
const ObjectsLayerToPrint &layers,
|
||||||
|
const LayerTools &layer_tools,
|
||||||
|
const std::vector<InstanceToPrint> &instances_to_print,
|
||||||
|
const bool first_layer
|
||||||
|
);
|
||||||
|
|
||||||
LayerResult process_layer(
|
LayerResult process_layer(
|
||||||
const Print &print,
|
const Print &print,
|
||||||
// Set of object & print layers of the same PrintObject and with the same print_z.
|
// Set of object & print layers of the same PrintObject and with the same print_z.
|
||||||
@ -243,6 +251,7 @@ private:
|
|||||||
// If set to size_t(-1), then print all copies of all objects.
|
// If set to size_t(-1), then print all copies of all objects.
|
||||||
// Otherwise print a single copy of a single object.
|
// Otherwise print a single copy of a single object.
|
||||||
const size_t single_object_idx = size_t(-1));
|
const size_t single_object_idx = size_t(-1));
|
||||||
|
|
||||||
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
||||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||||
// and export G-code into file.
|
// and export G-code into file.
|
||||||
|
@ -446,4 +446,66 @@ std::vector<NormalExtrusions> get_normal_extrusions(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ExtruderExtrusions> get_extrusions(
|
||||||
|
const Print &print,
|
||||||
|
const GCode::WipeTowerIntegration *wipe_tower,
|
||||||
|
const GCode::ObjectsLayerToPrint &layers,
|
||||||
|
const bool is_first_layer,
|
||||||
|
const LayerTools &layer_tools,
|
||||||
|
const std::vector<InstanceToPrint> &instances_to_print,
|
||||||
|
const std::map<unsigned int, std::pair<size_t, size_t>> &skirt_loops_per_extruder,
|
||||||
|
unsigned current_extruder_id,
|
||||||
|
const SeamPlacingFunciton &place_seam,
|
||||||
|
bool get_brim,
|
||||||
|
std::optional<Vec2d> previous_position
|
||||||
|
) {
|
||||||
|
unsigned toolchange_number{0};
|
||||||
|
|
||||||
|
std::vector<ExtruderExtrusions> extrusions;
|
||||||
|
for (const unsigned int extruder_id : layer_tools.extruders)
|
||||||
|
{
|
||||||
|
if (layer_tools.has_wipe_tower && wipe_tower != nullptr) {
|
||||||
|
if (is_toolchange_required(is_first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) {
|
||||||
|
const WipeTower::ToolChangeResult tool_change{wipe_tower->get_toolchange(toolchange_number++)};
|
||||||
|
previous_position = wipe_tower->transform_wt_pt(tool_change.end_pos).cast<double>();
|
||||||
|
current_extruder_id = tool_change.new_tool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtruderExtrusions extruder_extrusions{extruder_id};
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extrude brim with the extruder of the 1st region.
|
||||||
|
using GCode::ExtrusionOrder::get_last_position;
|
||||||
|
if (get_brim) {
|
||||||
|
extruder_extrusions.brim = print.brim().entities;
|
||||||
|
previous_position = get_last_position(extruder_extrusions.brim, {0.0, 0.0});
|
||||||
|
get_brim = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using GCode::ExtrusionOrder::get_overriden_extrusions;
|
||||||
|
bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden();
|
||||||
|
if (is_anything_overridden) {
|
||||||
|
extruder_extrusions.overriden_extrusions = get_overriden_extrusions(
|
||||||
|
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
||||||
|
previous_position
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
using GCode::ExtrusionOrder::get_normal_extrusions;
|
||||||
|
extruder_extrusions.normal_extrusions = get_normal_extrusions(
|
||||||
|
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
||||||
|
previous_position
|
||||||
|
);
|
||||||
|
extrusions.push_back(std::move(extruder_extrusions));
|
||||||
|
}
|
||||||
|
return extrusions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ struct ExtruderExtrusions {
|
|||||||
std::vector<NormalExtrusions> normal_extrusions;
|
std::vector<NormalExtrusions> normal_extrusions;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::vector<ExtruderExtrusions> get_extrusions(
|
std::vector<ExtruderExtrusions> get_extrusions(
|
||||||
const Print &print,
|
const Print &print,
|
||||||
const GCode::WipeTowerIntegration *wipe_tower,
|
const GCode::WipeTowerIntegration *wipe_tower,
|
||||||
const GCode::ObjectsLayerToPrint &layers,
|
const GCode::ObjectsLayerToPrint &layers,
|
||||||
@ -116,55 +116,7 @@ inline std::vector<ExtruderExtrusions> get_extrusions(
|
|||||||
const SeamPlacingFunciton &place_seam,
|
const SeamPlacingFunciton &place_seam,
|
||||||
bool get_brim,
|
bool get_brim,
|
||||||
std::optional<Vec2d> previous_position
|
std::optional<Vec2d> previous_position
|
||||||
) {
|
|
||||||
unsigned toolchange_number{0};
|
|
||||||
|
|
||||||
std::vector<ExtruderExtrusions> extrusions;
|
|
||||||
for (const unsigned int extruder_id : layer_tools.extruders)
|
|
||||||
{
|
|
||||||
if (layer_tools.has_wipe_tower && wipe_tower != nullptr) {
|
|
||||||
if (is_toolchange_required(is_first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) {
|
|
||||||
const WipeTower::ToolChangeResult tool_change{wipe_tower->get_toolchange(toolchange_number++)};
|
|
||||||
previous_position = wipe_tower->transform_wt_pt(tool_change.end_pos).cast<double>();
|
|
||||||
current_extruder_id = tool_change.new_tool;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtruderExtrusions extruder_extrusions{extruder_id};
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extrude brim with the extruder of the 1st region.
|
|
||||||
using GCode::ExtrusionOrder::get_last_position;
|
|
||||||
if (get_brim) {
|
|
||||||
extruder_extrusions.brim = print.brim().entities;
|
|
||||||
previous_position = get_last_position(extruder_extrusions.brim, {0.0, 0.0});
|
|
||||||
get_brim = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::get_overriden_extrusions;
|
|
||||||
bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden();
|
|
||||||
if (is_anything_overridden) {
|
|
||||||
extruder_extrusions.overriden_extrusions = get_overriden_extrusions(
|
|
||||||
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
|
||||||
previous_position
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::get_normal_extrusions;
|
|
||||||
extruder_extrusions.normal_extrusions = get_normal_extrusions(
|
|
||||||
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
|
||||||
previous_position
|
|
||||||
);
|
|
||||||
extrusions.push_back(std::move(extruder_extrusions));
|
|
||||||
}
|
|
||||||
return extrusions;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user