Make previous position independent of the object instance (offset)

This commit is contained in:
Martin Šach 2024-06-17 13:58:46 +02:00 committed by Lukas Matena
parent 17dc776109
commit 0bc86ace2e
3 changed files with 98 additions and 106 deletions

View File

@ -2473,7 +2473,10 @@ LayerResult GCodeGenerator::process_layer(
unsigned current_extruder_id{this->m_writer.extruder()->id()}; unsigned current_extruder_id{this->m_writer.extruder()->id()};
unsigned toolchange_number{0}; unsigned toolchange_number{0};
std::optional<Point> previous_position{this->last_position}; std::optional<Vec2d> previous_position;
if (this->last_position) {
previous_position = this->point_to_gcode(*this->last_position);
}
std::vector<ExtruderExtrusions> extrusions; std::vector<ExtruderExtrusions> extrusions;
for (const unsigned int extruder_id : layer_tools.extruders) for (const unsigned int extruder_id : layer_tools.extruders)
@ -2481,7 +2484,7 @@ LayerResult GCodeGenerator::process_layer(
if (layer_tools.has_wipe_tower && m_wipe_tower) { if (layer_tools.has_wipe_tower && m_wipe_tower) {
if (is_toolchange_required(first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) { if (is_toolchange_required(first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) {
const WipeTower::ToolChangeResult tool_change{m_wipe_tower->get_toolchange(toolchange_number++)}; const WipeTower::ToolChangeResult tool_change{m_wipe_tower->get_toolchange(toolchange_number++)};
previous_position = this->gcode_to_point(m_wipe_tower->transform_wt_pt(tool_change.end_pos).cast<double>()); previous_position = m_wipe_tower->transform_wt_pt(tool_change.end_pos).cast<double>();
current_extruder_id = tool_change.new_tool; current_extruder_id = tool_change.new_tool;
} }
} }
@ -2495,14 +2498,14 @@ LayerResult GCodeGenerator::process_layer(
} }
} }
// Extrude brim with the extruder of the 1st region.
using GCode::ExtrusionOrder::get_last_position; using GCode::ExtrusionOrder::get_last_position;
if (!m_brim_done) { if (!m_brim_done) {
extruder_extrusions.brim = print.brim().entities; extruder_extrusions.brim = print.brim().entities;
previous_position = get_last_position(extruder_extrusions.brim); previous_position = get_last_position(extruder_extrusions.brim, {0.0, 0.0});
m_brim_done = true; m_brim_done = true;
} }
const auto place_seam =[&]( const auto place_seam =[&](
const Layer &layer, ExtrusionEntity *perimeter, const std::optional<Point> &previous_position const Layer &layer, ExtrusionEntity *perimeter, const std::optional<Point> &previous_position
) { ) {
@ -2581,8 +2584,6 @@ LayerResult GCodeGenerator::process_layer(
m_avoid_crossing_perimeters.disable_once(); m_avoid_crossing_perimeters.disable_once();
} }
// Extrude brim with the extruder of the 1st region.
if (!extruder_extrusions.brim.empty()) { if (!extruder_extrusions.brim.empty()) {
if (!this->m_config.complete_objects.value) { if (!this->m_config.complete_objects.value) {

View File

@ -27,6 +27,50 @@ int get_extruder_id(
return extruder_id; return extruder_id;
} }
Vec2d get_gcode_point(const Point &point, const Vec2d &offset) {
return Vec2d(unscaled<double>(point.x()), unscaled<double>(point.y())) + offset;
}
Point get_instance_point(const Vec2d &point, const Vec2d &offset) {
return Point::new_scale(point - offset);
}
std::optional<Vec2d> get_gcode_point(const std::optional<Point> &point, const Vec2d &offset) {
if (point) {
return get_gcode_point(*point, offset);
}
return std::nullopt;
}
std::optional<Point> get_instance_point(const std::optional<Vec2d> &point, const Vec2d &offset) {
if (point) {
return get_instance_point(*point, offset);
}
return std::nullopt;
}
std::optional<Vec2d> get_last_position(const ExtrusionEntityReferences &extrusions, const Vec2d &offset) {
if (!extrusions.empty()) {
const ExtrusionEntityReference &last_extrusion{extrusions.back()};
auto last_loop{dynamic_cast<const ExtrusionLoop *>(&last_extrusion.extrusion_entity())};
if (last_loop != nullptr) {
return get_gcode_point(last_loop->seam, offset);
}
const Point last_point{
last_extrusion.flipped() ? last_extrusion.extrusion_entity().first_point() :
last_extrusion.extrusion_entity().last_point()};
return get_gcode_point(last_point, offset);
}
return std::nullopt;
}
std::optional<Vec2d> get_last_position(const ExtrusionEntitiesPtr &extrusions, const Vec2d &offset){
if (!extrusions.empty()) {
return get_last_position({{*extrusions.back(), false}}, offset);
}
return std::nullopt;
}
using ExtractEntityPredicate = std::function<bool(const ExtrusionEntityCollection&, const PrintRegion&)>; using ExtractEntityPredicate = std::function<bool(const ExtrusionEntityCollection&, const PrintRegion&)>;
ExtrusionEntitiesPtr extract_infill_extrusions( ExtrusionEntitiesPtr extract_infill_extrusions(
@ -111,7 +155,8 @@ std::vector<InfillRange> extract_infill_ranges(
const Print &print, const Print &print,
const Layer &layer, const Layer &layer,
const LayerIsland &island, const LayerIsland &island,
std::optional<Point> previous_position, const Vec2d &offset,
std::optional<Vec2d> &previous_position,
const ExtractEntityPredicate &predicate const ExtractEntityPredicate &predicate
) { ) {
std::vector<InfillRange> result; std::vector<InfillRange> result;
@ -132,84 +177,29 @@ std::vector<InfillRange> extract_infill_ranges(
predicate predicate
)}; )};
const Point* start_near = previous_position ? &(*(previous_position)) : nullptr; const std::optional<Point> previous_position_scaled{get_instance_point(previous_position, offset)};
const std::vector<ExtrusionEntityReference> sorted_extrusions{sort_fill_extrusions(extrusions, start_near)}; const Point* start_near{previous_position_scaled ? &(*(previous_position_scaled)) : nullptr};
const ExtrusionEntityReferences sorted_extrusions{sort_fill_extrusions(extrusions, start_near)};
if (! sorted_extrusions.empty()) { if (!sorted_extrusions.empty()) {
result.push_back({sorted_extrusions, &region}); result.push_back({sorted_extrusions, &region});
previous_position = sorted_extrusions.back().flipped() ? }
sorted_extrusions.back().extrusion_entity().first_point() : if (const auto last_position = get_last_position(sorted_extrusions, offset)) {
sorted_extrusions.back().extrusion_entity().last_point(); previous_position = last_position;
} }
it = it_end; it = it_end;
} }
return result; return result;
} }
std::optional<Point> get_last_position(const std::vector<InfillRange> &infill_ranges) {
if (!infill_ranges.empty() && !infill_ranges.back().items.empty()) {
const ExtrusionEntityReference &last_infill{infill_ranges.back().items.back()};
return last_infill.flipped() ? last_infill.extrusion_entity().first_point() :
last_infill.extrusion_entity().last_point();
}
return std::nullopt;
}
std::optional<Point> get_last_position(const ExtrusionEntityReferences &extrusions) {
if (!extrusions.empty()) {
const ExtrusionEntityReference &last_extrusion{extrusions.back()};
return last_extrusion.flipped() ? last_extrusion.extrusion_entity().first_point() :
last_extrusion.extrusion_entity().last_point();
}
return std::nullopt;
}
std::optional<Point> get_last_position(const ExtrusionEntitiesPtr &perimeters){
if (!perimeters.empty()) {
auto last_perimeter_loop{dynamic_cast<const ExtrusionLoop *>(perimeters.back())};
if (last_perimeter_loop != nullptr) {
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;
}
std::optional<Point> get_last_position(const std::vector<SliceExtrusions> &slice_extrusions, const bool infill_first) {
if (slice_extrusions.empty()) {
return {};
}
const SliceExtrusions &last_slice{slice_extrusions.back()};
if (!last_slice.ironing_extrusions.empty()) {
return get_last_position(slice_extrusions.back().ironing_extrusions);
}
if (last_slice.common_extrusions.empty()) {
return {};
}
const IslandExtrusions last_island{last_slice.common_extrusions.back()};
if (infill_first) {
if (!last_island.perimeters.empty()) {
return get_last_position(last_island.perimeters);
}
return get_last_position(last_island.infill_ranges);
} else {
if (!last_island.infill_ranges.empty()) {
return get_last_position(last_island.infill_ranges);
}
return get_last_position(last_island.perimeters);
}
}
std::vector<IslandExtrusions> extract_island_extrusions( 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 ExtractEntityPredicate &predicate, const ExtractEntityPredicate &predicate,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position const Vec2d &offset,
std::optional<Vec2d> &previous_position
) { ) {
std::vector<IslandExtrusions> result; std::vector<IslandExtrusions> result;
for (const LayerIsland &island : lslice.islands) { for (const LayerIsland &island : lslice.islands) {
@ -230,33 +220,28 @@ std::vector<IslandExtrusions> extract_island_extrusions(
if (print.config().infill_first) { if (print.config().infill_first) {
island_extrusions.infill_ranges = extract_infill_ranges( island_extrusions.infill_ranges = extract_infill_ranges(
print, layer, island, previous_position, infill_predicate print, layer, island, offset, previous_position, infill_predicate
); );
if (const auto last_position = get_last_position(island_extrusions.infill_ranges)) {
previous_position = last_position;
}
for (ExtrusionEntity* perimeter : island_extrusions.perimeters) { for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
previous_position = place_seam(layer, perimeter, previous_position); std::optional<Point> instance_point{get_instance_point(previous_position, offset)};
} const std::optional<Point> seam_point{place_seam(layer, perimeter, instance_point)};
if (seam_point) {
if (const auto last_position = get_last_position(island_extrusions.perimeters)) { previous_position = get_gcode_point(*seam_point, offset);
previous_position = last_position; }
} }
} else { } else {
for (ExtrusionEntity* perimeter : island_extrusions.perimeters) { for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
previous_position = place_seam(layer, perimeter, previous_position); std::optional<Point> instance_point{get_instance_point(previous_position, offset)};
const std::optional<Point> seam_point{place_seam(layer, perimeter, instance_point)};
if (seam_point) {
previous_position = get_gcode_point(*seam_point, offset);
}
} }
if (const auto last_position = get_last_position(island_extrusions.perimeters)) {
previous_position = last_position;
}
island_extrusions.infill_ranges = {extract_infill_ranges( island_extrusions.infill_ranges = {extract_infill_ranges(
print, layer, island, previous_position, infill_predicate print, layer, island, offset, previous_position, infill_predicate
)}; )};
if (const auto last_position = get_last_position(island_extrusions.infill_ranges)) {
previous_position = last_position;
}
} }
} }
return result; return result;
@ -267,7 +252,8 @@ std::vector<InfillRange> extract_ironing_extrusions(
const Print &print, const Print &print,
const Layer &layer, const Layer &layer,
const ExtractEntityPredicate &predicate, const ExtractEntityPredicate &predicate,
std::optional<Point> &previous_position const Vec2d &offset,
std::optional<Vec2d> &previous_position
) { ) {
std::vector<InfillRange> result; std::vector<InfillRange> result;
@ -277,15 +263,11 @@ std::vector<InfillRange> extract_ironing_extrusions(
}; };
const std::vector<InfillRange> ironing_ranges{extract_infill_ranges( const std::vector<InfillRange> ironing_ranges{extract_infill_ranges(
print, layer, island, previous_position, ironing_predicate print, layer, island, offset, previous_position, ironing_predicate
)}; )};
result.insert( result.insert(
result.end(), ironing_ranges.begin(), ironing_ranges.end() result.end(), ironing_ranges.begin(), ironing_ranges.end()
); );
if (const auto last_position = get_last_position(ironing_ranges)) {
previous_position = last_position;
}
} }
return result; return result;
} }
@ -295,7 +277,8 @@ std::vector<SliceExtrusions> get_slices_extrusions(
const Layer &layer, const Layer &layer,
const ExtractEntityPredicate &predicate, const ExtractEntityPredicate &predicate,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> previous_position const Vec2d &offset,
std::optional<Vec2d> &previous_position
) { ) {
// Note: ironing. // Note: ironing.
// FIXME move ironing into the loop above over LayerIslands? // FIXME move ironing into the loop above over LayerIslands?
@ -309,9 +292,9 @@ 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, predicate, place_seam, previous_position lslice, print, layer, predicate, place_seam, offset, previous_position
), ),
extract_ironing_extrusions(lslice, print, layer, predicate, previous_position) extract_ironing_extrusions(lslice, print, layer, predicate, offset, previous_position)
}); });
} }
return result; return result;
@ -376,7 +359,7 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Vec2d> &previous_position
) { ) {
std::vector<std::vector<SliceExtrusions>> result; std::vector<std::vector<SliceExtrusions>> result;
@ -396,10 +379,12 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
return true; return true;
}; };
const PrintObject &print_object = instance.print_object;
const Vec2d &offset = unscale(print_object.instances()[instance.instance_id].shift);
result.emplace_back(get_slices_extrusions( result.emplace_back(get_slices_extrusions(
print, *layer, predicate, place_seam, previous_position print, *layer, predicate, place_seam, offset, previous_position
)); ));
previous_position = get_last_position(result.back(), print.config().infill_first);
} }
} }
return result; return result;
@ -412,12 +397,15 @@ std::vector<NormalExtrusions> get_normal_extrusions(
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Vec2d> &previous_position
) { ) {
std::vector<NormalExtrusions> result; std::vector<NormalExtrusions> result;
for (std::size_t i{0}; i < instances_to_print.size(); ++i) { for (std::size_t i{0}; i < instances_to_print.size(); ++i) {
const InstanceToPrint &instance{instances_to_print[i]}; const InstanceToPrint &instance{instances_to_print[i]};
const PrintObject &print_object = instance.print_object;
const Vec2d &offset = unscale(print_object.instances()[instance.instance_id].shift);
result.emplace_back(); result.emplace_back();
if (layers[instance.object_layer_to_print_id].support_layer != nullptr) { if (layers[instance.object_layer_to_print_id].support_layer != nullptr) {
@ -427,7 +415,10 @@ std::vector<NormalExtrusions> get_normal_extrusions(
translate_support_extruder(instance.print_object.config().support_material_extruder.value, layer_tools, print.config().filament_soluble), translate_support_extruder(instance.print_object.config().support_material_extruder.value, layer_tools, print.config().filament_soluble),
translate_support_extruder(instance.print_object.config().support_material_interface_extruder.value, layer_tools, print.config().filament_soluble) translate_support_extruder(instance.print_object.config().support_material_interface_extruder.value, layer_tools, print.config().filament_soluble)
); );
previous_position = get_last_position(result.back().support_extrusions);
if (const auto last_position = get_last_position(result.back().support_extrusions, offset)) {
previous_position = last_position;
}
} }
if (const Layer *layer = layers[instance.object_layer_to_print_id].object_layer; layer) { if (const Layer *layer = layers[instance.object_layer_to_print_id].object_layer; layer) {
@ -447,9 +438,9 @@ std::vector<NormalExtrusions> get_normal_extrusions(
*layer, *layer,
predicate, predicate,
place_seam, place_seam,
offset,
previous_position previous_position
); );
previous_position = get_last_position(result.back().slices_extrusions, print.config().infill_first);
} }
} }
return result; return result;

View File

@ -71,7 +71,7 @@ struct NormalExtrusions {
std::vector<SliceExtrusions> slices_extrusions; std::vector<SliceExtrusions> slices_extrusions;
}; };
std::optional<Point> get_last_position(const ExtrusionEntitiesPtr &perimeters); std::optional<Vec2d> get_last_position(const ExtrusionEntitiesPtr &extrusions, const Vec2d &offset);
using SeamPlacingFunciton = std::function<std::optional<Point>(const Layer &layer, ExtrusionEntity* perimeter, const std::optional<Point>&)>; using SeamPlacingFunciton = std::function<std::optional<Point>(const Layer &layer, ExtrusionEntity* perimeter, const std::optional<Point>&)>;
@ -82,7 +82,7 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Vec2d> &previous_position
); );
std::vector<NormalExtrusions> get_normal_extrusions( std::vector<NormalExtrusions> get_normal_extrusions(
@ -92,7 +92,7 @@ std::vector<NormalExtrusions> get_normal_extrusions(
const std::vector<InstanceToPrint> &instances_to_print, const std::vector<InstanceToPrint> &instances_to_print,
const unsigned int extruder_id, const unsigned int extruder_id,
const SeamPlacingFunciton &place_seam, const SeamPlacingFunciton &place_seam,
std::optional<Point> &previous_position std::optional<Vec2d> &previous_position
); );
} }