Implement get_first_point for extrusions

This commit is contained in:
Martin Šach 2024-06-21 12:50:47 +02:00 committed by Lukas Matena
parent 131f05c3c4
commit 796eddd971
3 changed files with 126 additions and 5 deletions

View File

@ -2308,7 +2308,7 @@ std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorte
GCode::SmoothPath result;
if (auto loop = dynamic_cast<const ExtrusionLoop *>(extrusion_entity)) {
Point seam_point = previous_position ? previous_position->value : Point::Zero();
Point seam_point = previous_position ? previous_position->local_point : Point::Zero();
if (loop->role().is_perimeter() && layer != nullptr) {
seam_point = this->m_seam_placer.place_seam(layer, *loop, seam_point);
}
@ -2457,6 +2457,8 @@ LayerResult GCodeGenerator::process_layer(
const std::vector<ExtruderExtrusions> extrusions{
this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, smooth_path_caches, first_layer)};
const std::optional<Point> first_point{GCode::ExtrusionOrder::get_first_point(extrusions)};
std::string gcode;
assert(is_decimal_separator_point()); // for the sprintfs
@ -2552,6 +2554,7 @@ LayerResult GCodeGenerator::process_layer(
}
}
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
for (const ExtruderExtrusions &extruder_extrusions : extrusions)
{

View File

@ -29,7 +29,7 @@ int get_extruder_id(
}
Point get_gcode_point(const InstancePoint &point, const Point &offset) {
return point.value + offset;
return point.local_point + offset;
}
InstancePoint get_instance_point(const Point &point, const Point &offset) {
@ -173,7 +173,7 @@ std::vector<InfillRange> extract_infill_ranges(
)};
const std::optional<InstancePoint> previous_instance_point{get_instance_point(previous_position, offset)};
const Point* start_near{previous_instance_point ? &(previous_instance_point->value) : nullptr};
const Point* start_near{previous_instance_point ? &(previous_instance_point->local_point) : nullptr};
const ExtrusionEntityReferences sorted_extrusions{sort_fill_extrusions(extrusions, start_near)};
std::vector<SmoothPath> paths;
@ -501,15 +501,17 @@ std::vector<ExtruderExtrusions> get_extrusions(
std::vector<ExtruderExtrusions> extrusions;
for (const unsigned int extruder_id : layer_tools.extruders)
{
ExtruderExtrusions extruder_extrusions{extruder_id};
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 = Point::new_scale(wipe_tower->transform_wt_pt(tool_change.end_pos));
current_extruder_id = tool_change.new_tool;
extruder_extrusions.wipe_tower_start = Point::new_scale(wipe_tower->transform_wt_pt(tool_change.start_pos));
}
}
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;

View File

@ -92,7 +92,7 @@ struct OverridenExtrusions {
};
struct InstancePoint {
Point value;
Point local_point;
};
using PathSmoothingFunction = std::function<SmoothPath(
@ -110,6 +110,7 @@ struct ExtruderExtrusions {
std::vector<BrimPath> brim;
std::vector<OverridenExtrusions> overriden_extrusions;
std::vector<NormalExtrusions> normal_extrusions;
std::optional<Point> wipe_tower_start;
};
static constexpr const double min_gcode_segment_length = 0.002;
@ -129,6 +130,121 @@ std::vector<ExtruderExtrusions> get_extrusions(
bool get_brim,
std::optional<Point> previous_position
);
inline std::optional<InstancePoint> get_first_point(const SmoothPath &path) {
for (const SmoothPathElement & element : path) {
if (!element.path.empty()) {
return InstancePoint{element.path.front().point};
}
}
return std::nullopt;
}
inline std::optional<InstancePoint> get_first_point(const std::vector<SmoothPath> &smooth_paths) {
for (const SmoothPath &path : smooth_paths) {
if (auto result = get_first_point(path)) {
return result;
}
}
return std::nullopt;
}
inline std::optional<InstancePoint> get_first_point(const std::vector<InfillRange> &infill_ranges) {
for (const InfillRange &infill_range : infill_ranges) {
if (auto result = get_first_point(infill_range.items)) {
return result;
}
}
return std::nullopt;
}
inline std::optional<InstancePoint> get_first_point(const std::vector<Perimeter> &perimeters) {
for (const Perimeter &perimeter : perimeters) {
if (auto result = get_first_point(perimeter.smooth_path)) {
return result;
}
}
return std::nullopt;
}
inline std::optional<InstancePoint> get_first_point(const std::vector<IslandExtrusions> &extrusions) {
for (const IslandExtrusions &island : extrusions) {
if (island.infill_first) {
if (auto result = get_first_point(island.infill_ranges)) {
return result;
}
if (auto result = get_first_point(island.perimeters)) {
return result;
}
} else {
if (auto result = get_first_point(island.perimeters)) {
return result;
}
if (auto result = get_first_point(island.infill_ranges)) {
return result;
}
}
}
return std::nullopt;
}
inline std::optional<InstancePoint> get_first_point(const std::vector<SliceExtrusions> &extrusions) {
for (const SliceExtrusions &slice : extrusions) {
if (auto result = get_first_point(slice.common_extrusions)) {
return result;
}
}
return std::nullopt;
}
inline std::optional<Point> get_first_point(const ExtruderExtrusions &extrusions) {
for (const BrimPath &brim_path : extrusions.brim) {
if (auto result = get_first_point(brim_path.path)) {
return result->local_point;
};
}
for (const auto&[_, path] : extrusions.skirt) {
if (auto result = get_first_point(path)) {
return result->local_point;
};
}
for (const OverridenExtrusions &overriden_extrusions : extrusions.overriden_extrusions) {
if (auto result = get_first_point(overriden_extrusions.slices_extrusions)) {
return result->local_point - overriden_extrusions.instance_offset;
}
}
for (const NormalExtrusions &normal_extrusions : extrusions.normal_extrusions) {
for (const SupportPath &support_path : normal_extrusions.support_extrusions) {
if (auto result = get_first_point(support_path.path)) {
return result->local_point + normal_extrusions.instance_offset;
}
}
if (auto result = get_first_point(normal_extrusions.slices_extrusions)) {
return result->local_point + normal_extrusions.instance_offset;
}
}
return std::nullopt;
}
inline std::optional<Point> get_first_point(const std::vector<ExtruderExtrusions> &extrusions) {
if (extrusions.empty()) {
return std::nullopt;
}
if (extrusions.front().wipe_tower_start) {
return extrusions.front().wipe_tower_start;
}
for (const ExtruderExtrusions &extruder_extrusions : extrusions) {
if (auto result = get_first_point(extruder_extrusions)) {
return result;
}
}
return std::nullopt;
}
}
#endif // slic3r_GCode_ExtrusionOrder_hpp_