Remove ExtrusionOrder dependency on seam placer

This commit is contained in:
Martin Šach 2024-06-14 10:59:20 +02:00 committed by Lukas Matena
parent dbe9355672
commit fe1b8134d6
3 changed files with 57 additions and 139 deletions

View File

@ -2497,21 +2497,41 @@ LayerResult GCodeGenerator::process_layer(
previous_position = get_last_position(brim); previous_position = get_last_position(brim);
} }
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::get_overriden_extrusions; using GCode::ExtrusionOrder::get_overriden_extrusions;
bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden(); bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden();
std::vector<std::vector<SliceExtrusions>> overriden_extrusions; std::vector<std::vector<SliceExtrusions>> overriden_extrusions;
if (is_anything_overridden) { if (is_anything_overridden) {
overriden_extrusions = get_overriden_extrusions( overriden_extrusions = get_overriden_extrusions(
print, layers, layer_tools, instances_to_print, this->m_seam_placer, print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
this->m_config.spiral_vase, extruder_id, previous_position previous_position
); );
} }
using GCode::ExtrusionOrder::get_normal_extrusions; using GCode::ExtrusionOrder::get_normal_extrusions;
using GCode::ExtrusionOrder::NormalExtrusions; using GCode::ExtrusionOrder::NormalExtrusions;
const std::vector<NormalExtrusions> normal_extrusions{get_normal_extrusions( const std::vector<NormalExtrusions> normal_extrusions{get_normal_extrusions(
print, layers, layer_tools, instances_to_print, this->m_seam_placer, print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
this->m_config.spiral_vase, extruder_id, previous_position previous_position
)}; )};
if (!skirt.empty()) { if (!skirt.empty()) {
@ -2559,7 +2579,6 @@ LayerResult GCodeGenerator::process_layer(
} }
this->m_label_objects.update(first_instance); this->m_label_objects.update(first_instance);
// We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature):
if (!overriden_extrusions.empty()) { if (!overriden_extrusions.empty()) {
// Extrude wipes. // Extrude wipes.
size_t gcode_size_old = gcode.size(); size_t gcode_size_old = gcode.size();

View File

@ -1,4 +1,5 @@
#include "ExtrusionOrder.hpp" #include "ExtrusionOrder.hpp"
#include "libslic3r/ShortestPath.hpp"
namespace Slic3r::GCode::ExtrusionOrder { namespace Slic3r::GCode::ExtrusionOrder {
@ -26,6 +27,8 @@ int get_extruder_id(
return extruder_id; return extruder_id;
} }
using ExtractEntityPredicate = std::function<bool(const ExtrusionEntityCollection&, const PrintRegion&)>;
ExtrusionEntitiesPtr extract_infill_extrusions( ExtrusionEntitiesPtr extract_infill_extrusions(
const PrintRegion &region, const PrintRegion &region,
const ExtrusionEntityCollection &fills, const ExtrusionEntityCollection &fills,
@ -121,8 +124,6 @@ std::vector<InfillRange> extract_infill_ranges(
// identify the content of PrintRegion accross the whole print uniquely. Translate to a Print specific PrintRegion. // identify the content of PrintRegion accross the whole print uniquely. Translate to a Print specific PrintRegion.
const PrintRegion &region = print.get_print_region(layerm.region().print_region_id()); const PrintRegion &region = print.get_print_region(layerm.region().print_region_id());
const Point* start_near = previous_position ? &(*(previous_position)) : nullptr;
ExtrusionEntitiesPtr extrusions{extract_infill_extrusions( ExtrusionEntitiesPtr extrusions{extract_infill_extrusions(
region, region,
layerm.fills(), layerm.fills(),
@ -131,6 +132,7 @@ std::vector<InfillRange> extract_infill_ranges(
predicate predicate
)}; )};
const Point* start_near = previous_position ? &(*(previous_position)) : nullptr;
const std::vector<ExtrusionEntityReference> sorted_extrusions{sort_fill_extrusions(extrusions, start_near)}; const std::vector<ExtrusionEntityReference> sorted_extrusions{sort_fill_extrusions(extrusions, start_near)};
if (! sorted_extrusions.empty()) { if (! sorted_extrusions.empty()) {
@ -144,25 +146,6 @@ std::vector<InfillRange> extract_infill_ranges(
return result; return result;
} }
void place_seams(
const Layer &layer, const Seams::Placer &seam_placer, const std::vector<ExtrusionEntity *> &perimeters, std::optional<Point> previous_position, const bool spiral_vase
) {
std::vector<const ExtrusionEntity *> result;
result.reserve(perimeters.size());
for (ExtrusionEntity* perimeter : perimeters) {
auto loop{dynamic_cast<ExtrusionLoop *>(perimeter)};
Point seam_point{previous_position ? *previous_position : Point::Zero()};
if (!spiral_vase && loop != nullptr) {
assert(m_layer != nullptr);
seam_point = seam_placer.place_seam(&layer, *loop, seam_point);
loop->seam = seam_point;
}
previous_position = seam_point;
}
}
std::optional<Point> get_last_position(const std::vector<InfillRange> &infill_ranges) { std::optional<Point> get_last_position(const std::vector<InfillRange> &infill_ranges) {
if (!infill_ranges.empty() && !infill_ranges.back().items.empty()) { if (!infill_ranges.empty() && !infill_ranges.back().items.empty()) {
const ExtrusionEntityReference &last_infill{infill_ranges.back().items.back()}; const ExtrusionEntityReference &last_infill{infill_ranges.back().items.back()};
@ -181,11 +164,15 @@ std::optional<Point> get_last_position(const ExtrusionEntityReferences &extrusio
return std::nullopt; return std::nullopt;
} }
std::optional<Point> get_last_position(const std::vector<ExtrusionEntity *> &perimeters){ std::optional<Point> get_last_position(const ExtrusionEntitiesPtr &perimeters){
if (!perimeters.empty()) { if (!perimeters.empty()) {
auto last_perimeter{dynamic_cast<const ExtrusionLoop *>(perimeters.back())}; auto last_perimeter_loop{dynamic_cast<const ExtrusionLoop *>(perimeters.back())};
if (last_perimeter != nullptr) { if (last_perimeter_loop != nullptr) {
return last_perimeter->seam; return last_perimeter_loop->seam;
}
auto last_perimeter_multi_path{dynamic_cast<const ExtrusionMultiPath *>(perimeters.back())};
if (last_perimeter_multi_path != nullptr) {
return last_perimeter_multi_path->last_point();
} }
} }
return std::nullopt; return std::nullopt;
@ -220,9 +207,8 @@ std::vector<IslandExtrusions> extract_island_extrusions(
const LayerSlice &lslice, const LayerSlice &lslice,
const Print &print, const Print &print,
const Layer &layer, const Layer &layer,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const ExtractEntityPredicate &predicate, const ExtractEntityPredicate &predicate,
const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Point> &previous_position
) { ) {
std::vector<IslandExtrusions> result; std::vector<IslandExtrusions> result;
@ -250,13 +236,17 @@ std::vector<IslandExtrusions> extract_island_extrusions(
previous_position = last_position; previous_position = last_position;
} }
place_seams(layer, seam_placer, island_extrusions.perimeters, previous_position, spiral_vase); for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
previous_position = place_seam(layer, perimeter, previous_position);
}
if (const auto last_position = get_last_position(island_extrusions.perimeters)) { if (const auto last_position = get_last_position(island_extrusions.perimeters)) {
previous_position = last_position; previous_position = last_position;
} }
} else { } else {
place_seams(layer, seam_placer, island_extrusions.perimeters, previous_position, spiral_vase); for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
previous_position = place_seam(layer, perimeter, previous_position);
}
if (const auto last_position = get_last_position(island_extrusions.perimeters)) { if (const auto last_position = get_last_position(island_extrusions.perimeters)) {
previous_position = last_position; previous_position = last_position;
@ -303,10 +293,9 @@ std::vector<InfillRange> extract_ironing_extrusions(
std::vector<SliceExtrusions> get_slices_extrusions( std::vector<SliceExtrusions> get_slices_extrusions(
const Print &print, const Print &print,
const Layer &layer, const Layer &layer,
const Seams::Placer &seam_placer, const ExtractEntityPredicate &predicate,
std::optional<Point> previous_position, const SeamPlacingFunciton &place_seam,
const bool spiral_vase, std::optional<Point> previous_position
const ExtractEntityPredicate &predicate
) { ) {
// Note: ironing. // Note: ironing.
// FIXME move ironing into the loop above over LayerIslands? // FIXME move ironing into the loop above over LayerIslands?
@ -320,7 +309,7 @@ std::vector<SliceExtrusions> get_slices_extrusions(
const LayerSlice &lslice = layer.lslices_ex[idx]; const LayerSlice &lslice = layer.lslices_ex[idx];
result.emplace_back(SliceExtrusions{ result.emplace_back(SliceExtrusions{
extract_island_extrusions( extract_island_extrusions(
lslice, print, layer, seam_placer, spiral_vase, predicate, previous_position lslice, print, layer, predicate, place_seam, previous_position
), ),
extract_ironing_extrusions(lslice, print, layer, predicate, previous_position) extract_ironing_extrusions(lslice, print, layer, predicate, previous_position)
}); });
@ -385,9 +374,8 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
const GCode::ObjectsLayerToPrint &layers, const GCode::ObjectsLayerToPrint &layers,
const LayerTools &layer_tools, const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Point> &previous_position
) { ) {
std::vector<std::vector<SliceExtrusions>> result; std::vector<std::vector<SliceExtrusions>> result;
@ -409,7 +397,7 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
}; };
result.emplace_back(get_slices_extrusions( result.emplace_back(get_slices_extrusions(
print, *layer, seam_placer, previous_position, spiral_vase, predicate print, *layer, predicate, place_seam, previous_position
)); ));
previous_position = get_last_position(result.back(), print.config().infill_first); previous_position = get_last_position(result.back(), print.config().infill_first);
} }
@ -422,9 +410,8 @@ std::vector<NormalExtrusions> get_normal_extrusions(
const GCode::ObjectsLayerToPrint &layers, const GCode::ObjectsLayerToPrint &layers,
const LayerTools &layer_tools, const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Point> &previous_position
) { ) {
std::vector<NormalExtrusions> result; std::vector<NormalExtrusions> result;
@ -458,10 +445,9 @@ std::vector<NormalExtrusions> get_normal_extrusions(
result.back().slices_extrusions = get_slices_extrusions( result.back().slices_extrusions = get_slices_extrusions(
print, print,
*layer, *layer,
seam_placer, predicate,
previous_position, place_seam,
spiral_vase, previous_position
predicate
); );
previous_position = get_last_position(result.back().slices_extrusions, print.config().infill_first); previous_position = get_last_position(result.back().slices_extrusions, print.config().infill_first);
} }

View File

@ -71,103 +71,17 @@ struct NormalExtrusions {
std::vector<SliceExtrusions> slices_extrusions; std::vector<SliceExtrusions> slices_extrusions;
}; };
bool is_overriden(const ExtrusionEntityCollection &eec, const LayerTools &layer_tools, const std::size_t instance_id); std::optional<Point> get_last_position(const ExtrusionEntitiesPtr &perimeters);
int get_extruder_id( using SeamPlacingFunciton = std::function<std::optional<Point>(const Layer &layer, ExtrusionEntity* perimeter, const std::optional<Point>&)>;
const ExtrusionEntityCollection &eec,
const LayerTools &layer_tools,
const PrintRegion &region,
const std::size_t instance_id
);
using ExtractEntityPredicate = std::function<bool(const ExtrusionEntityCollection&, const PrintRegion&)>;
ExtrusionEntitiesPtr extract_infill_extrusions(
const Layer *layer,
const PrintRegion &region,
const ExtrusionEntityCollection &fills,
LayerExtrusionRanges::const_iterator begin,
LayerExtrusionRanges::const_iterator end,
const ExtractEntityPredicate &predicate
);
std::vector<ExtrusionEntity *> extract_perimeter_extrusions(
const Print &print,
const Layer *layer,
const LayerIsland &island,
const ExtractEntityPredicate &predicate
);
std::vector<ExtrusionEntityReference> sort_fill_extrusions(const ExtrusionEntitiesPtr &fills, const Point* start_near);
std::vector<InfillRange> extract_infill_ranges(
const Print &print,
const Layer *layer,
const LayerIsland island,
std::optional<Point> previous_position,
const ExtractEntityPredicate &predicate
);
void place_seams(
const Layer *layer, const Seams::Placer &seam_placer, const std::vector<ExtrusionEntity *> &perimeters, std::optional<Point> previous_position, const bool spiral_vase
);
std::optional<Point> get_last_position(const std::vector<InfillRange> &infill_ranges);
std::optional<Point> get_last_position(const ExtrusionEntityReferences &extrusions);
std::optional<Point> get_last_position(const std::vector<ExtrusionEntity *> &perimeters);
std::optional<Point> get_last_position(const std::vector<SliceExtrusions> &slice_extrusions, const bool infill_first);
std::vector<IslandExtrusions> extract_island_extrusions(
const LayerSlice &lslice,
const Print &print,
const Layer &layer,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const ExtractEntityPredicate &predicate,
std::optional<Point> &previous_position
);
std::vector<InfillRange> extract_ironing_extrusions(
const LayerSlice &lslice,
const Print &print,
const Layer &layer,
const ExtractEntityPredicate &predicate,
std::optional<Point> &previous_position
);
std::vector<SliceExtrusions> get_slices_extrusions(
const Print &print,
const Layer &layer,
const Seams::Placer &seam_placer,
std::optional<Point> previous_position,
const bool spiral_vase,
const ExtractEntityPredicate &predicate
);
unsigned translate_support_extruder(
const int configured_extruder,
const LayerTools &layer_tools,
const ConfigOptionBools &is_soluable
);
ExtrusionEntityReferences get_support_extrusions(
const unsigned int extruder_id,
const GCode::ObjectLayerToPrint &layer_to_print,
unsigned int support_extruder,
unsigned int interface_extruder
);
std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions( std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
const Print &print, const Print &print,
const GCode::ObjectsLayerToPrint &layers, const GCode::ObjectsLayerToPrint &layers,
const LayerTools &layer_tools, const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Point> &previous_position
); );
@ -176,9 +90,8 @@ std::vector<NormalExtrusions> get_normal_extrusions(
const GCode::ObjectsLayerToPrint &layers, const GCode::ObjectsLayerToPrint &layers,
const LayerTools &layer_tools, const LayerTools &layer_tools,
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const Seams::Placer &seam_placer,
const bool spiral_vase,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Point> &previous_position
); );