mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-13 21:26:01 +08:00
failed arc welder in path ordering
This commit is contained in:
parent
773c34f906
commit
d54f20a12c
@ -2299,24 +2299,59 @@ std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorte
|
|||||||
Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) :
|
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)};
|
Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done)};
|
||||||
|
|
||||||
const auto place_seam =[&](
|
const auto smooth_path{
|
||||||
const Layer &layer, ExtrusionEntity *perimeter, const std::optional<Point> &previous_position
|
[&](const Layer *layer, const ExtrusionEntityReference &extrusion_reference,
|
||||||
) {
|
const unsigned extruder_id, std::optional<Point> &previous_position) {
|
||||||
auto loop{dynamic_cast<ExtrusionLoop *>(perimeter)};
|
const ExtrusionEntity *extrusion_entity{&extrusion_reference.extrusion_entity()};
|
||||||
|
|
||||||
Point seam_point{previous_position ? *previous_position : Point::Zero()};
|
GCode::SmoothPath result;
|
||||||
if (!this->m_config.spiral_vase && loop != nullptr) {
|
|
||||||
seam_point = this->m_seam_placer.place_seam(&layer, *loop, seam_point);
|
if (auto loop = dynamic_cast<const ExtrusionLoop *>(extrusion_entity)) {
|
||||||
loop->seam = seam_point;
|
Point seam_point = previous_position ? *previous_position : Point::Zero();
|
||||||
|
if (loop->role().is_perimeter() && layer != nullptr) {
|
||||||
|
seam_point = this->m_seam_placer.place_seam(layer, *loop, seam_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path{dynamic_cast<const ExtrusionMultiPath *>(perimeter)};
|
const GCode::SmoothPathCache &smooth_path_cache{loop->role().is_perimeter() ? smooth_path_caches.layer_local() : smooth_path_caches.global()};
|
||||||
if (path != nullptr) {
|
// Because the G-code export has 1um resolution, don't generate segments shorter
|
||||||
return path->last_point();
|
// than 1.5 microns, thus empty path segments will not be produced by G-code export.
|
||||||
} else {
|
GCode::SmoothPath smooth_path =
|
||||||
return seam_point;
|
smooth_path_cache.resolve_or_fit_split_with_seam(
|
||||||
|
*loop, extrusion_reference.flipped(), 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.
|
||||||
|
const auto nozzle_diameter{m_config.nozzle_diameter.get_at(extruder_id)};
|
||||||
|
if (m_enable_loop_clipping) {
|
||||||
|
clip_end(
|
||||||
|
smooth_path,
|
||||||
|
scale_(nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER,
|
||||||
|
scaled<double>(GCode::ExtrusionOrder::min_gcode_segment_length)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
assert(validate_smooth_path(smooth_path, !enable_loop_clipping));
|
||||||
|
|
||||||
|
|
||||||
|
result = smooth_path;
|
||||||
|
} else if (auto multipath = dynamic_cast<const ExtrusionMultiPath *>(extrusion_entity)) {
|
||||||
|
result = smooth_path_caches.layer_local().resolve_or_fit(*multipath, extrusion_reference.flipped(), m_scaled_resolution);
|
||||||
|
} else if (auto path = dynamic_cast<const ExtrusionPath *>(extrusion_entity)) {
|
||||||
|
result = smooth_path_caches.layer_local().resolve_or_fit(*path, extrusion_reference.flipped(), m_scaled_resolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
using GCode::SmoothPathElement;
|
||||||
|
for (const SmoothPathElement &element : result) {
|
||||||
|
if (!element.path.empty()) {
|
||||||
|
previous_position = element.path.back().point;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}};
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::ExtruderExtrusions;
|
using GCode::ExtrusionOrder::ExtruderExtrusions;
|
||||||
using GCode::ExtrusionOrder::get_extrusions;
|
using GCode::ExtrusionOrder::get_extrusions;
|
||||||
@ -2332,13 +2367,9 @@ std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> GCodeGenerator::get_sorte
|
|||||||
first_layer,
|
first_layer,
|
||||||
layer_tools,
|
layer_tools,
|
||||||
instances_to_print,
|
instances_to_print,
|
||||||
smooth_path_caches.global(),
|
|
||||||
skirt_loops_per_extruder,
|
skirt_loops_per_extruder,
|
||||||
m_enable_loop_clipping,
|
|
||||||
m_config,
|
|
||||||
m_scaled_resolution,
|
|
||||||
this->m_writer.extruder()->id(),
|
this->m_writer.extruder()->id(),
|
||||||
place_seam,
|
smooth_path,
|
||||||
!this->m_brim_done,
|
!this->m_brim_done,
|
||||||
previous_position
|
previous_position
|
||||||
)
|
)
|
||||||
@ -2894,6 +2925,38 @@ static inline bool validate_smooth_path(const GCode::SmoothPath &smooth_path, bo
|
|||||||
}
|
}
|
||||||
#endif //NDEBUG
|
#endif //NDEBUG
|
||||||
|
|
||||||
|
std::string GCodeGenerator::extrude_perimeter(
|
||||||
|
const GCode::ExtrusionOrder::Perimeter &perimeter, const std::string_view description
|
||||||
|
) {
|
||||||
|
double speed{-1};
|
||||||
|
// Apply the small perimeter speed.
|
||||||
|
if (perimeter.extrusion_entity->length() <= SMALL_PERIMETER_LENGTH)
|
||||||
|
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
||||||
|
|
||||||
|
// Extrude along the smooth path.
|
||||||
|
std::string gcode;
|
||||||
|
for (const GCode::SmoothPathElement &el : perimeter.smooth_path)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
|
||||||
|
|
||||||
|
// reset acceleration
|
||||||
|
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
|
||||||
|
|
||||||
|
if (m_wipe.enabled()) {
|
||||||
|
// Wipe will hide the seam.
|
||||||
|
m_wipe.set_path(GCode::SmoothPath{perimeter.smooth_path});
|
||||||
|
} else if (perimeter.extrusion_entity->role().is_external_perimeter() && m_layer != nullptr && m_config.perimeters.value > 1) {
|
||||||
|
// Only wipe inside if the wipe along the perimeter is disabled.
|
||||||
|
// Make a little move inwards before leaving loop.
|
||||||
|
if (std::optional<Point> pt = wipe_hide_seam(perimeter.smooth_path, perimeter.reversed, scale_(EXTRUDER_CONFIG(nozzle_diameter))); pt) {
|
||||||
|
// Generate the seam hiding travel move.
|
||||||
|
gcode += m_writer.travel_to_xy(this->point_to_gcode(*pt), "move inwards before travel");
|
||||||
|
this->last_position = *pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gcode;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed)
|
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.
|
// Extrude all loops CCW unless CW movements are prefered.
|
||||||
@ -2973,17 +3036,27 @@ std::string GCodeGenerator::extrude_skirt(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GCodeGenerator::extrude_infill_range(
|
std::string GCodeGenerator::extrude_infill_range(
|
||||||
const std::vector<ExtrusionEntityReference> &sorted_extrusions,
|
const std::vector<GCode::SmoothPath> &sorted_paths,
|
||||||
const PrintRegion ®ion,
|
const PrintRegion ®ion,
|
||||||
const std::string &extrusion_name,
|
const std::string &extrusion_name,
|
||||||
const GCode::SmoothPathCache &smooth_path_cache
|
const GCode::SmoothPathCache &smooth_path_cache
|
||||||
) {
|
) {
|
||||||
std::string gcode{};
|
std::string gcode{};
|
||||||
if (!sorted_extrusions.empty()) {
|
if (!sorted_paths.empty()) {
|
||||||
this->m_config.apply(region.config());
|
this->m_config.apply(region.config());
|
||||||
|
|
||||||
for (const ExtrusionEntityReference &ee : sorted_extrusions) {
|
for (const GCode::SmoothPath &smooth_path : sorted_paths) {
|
||||||
gcode += this->extrude_entity(ee, smooth_path_cache, extrusion_name);
|
// extrude along the path
|
||||||
|
std::string gcode;
|
||||||
|
for (const GCode::SmoothPathElement &el : smooth_path)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, extrusion_name);
|
||||||
|
|
||||||
|
GCode::SmoothPath reversed_smooth_path{smooth_path};
|
||||||
|
GCode::reverse(reversed_smooth_path);
|
||||||
|
m_wipe.set_path(std::move(reversed_smooth_path));
|
||||||
|
|
||||||
|
// reset acceleration
|
||||||
|
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gcode;
|
return gcode;
|
||||||
@ -3006,7 +3079,7 @@ std::string GCodeGenerator::extrude_infill_ranges(
|
|||||||
std::string GCodeGenerator::extrude_perimeters(
|
std::string GCodeGenerator::extrude_perimeters(
|
||||||
const Print &print,
|
const Print &print,
|
||||||
const PrintRegion ®ion,
|
const PrintRegion ®ion,
|
||||||
const std::vector<ExtrusionEntity *> &perimeters,
|
const std::vector<GCode::ExtrusionOrder::Perimeter> &perimeters,
|
||||||
const InstanceToPrint &print_instance,
|
const InstanceToPrint &print_instance,
|
||||||
const GCode::SmoothPathCache &smooth_path_cache
|
const GCode::SmoothPathCache &smooth_path_cache
|
||||||
) {
|
) {
|
||||||
@ -3016,13 +3089,11 @@ std::string GCodeGenerator::extrude_perimeters(
|
|||||||
|
|
||||||
std::string gcode{};
|
std::string gcode{};
|
||||||
|
|
||||||
for (const ExtrusionEntity *ee : perimeters) {
|
for (const GCode::ExtrusionOrder::Perimeter &perimeter : perimeters) {
|
||||||
// Don't reorder, don't flip.
|
// Don't reorder, don't flip.
|
||||||
gcode += this->extrude_entity(
|
gcode += this->extrude_perimeter(perimeter, comment_perimeter);
|
||||||
{*ee, false}, smooth_path_cache, comment_perimeter, -1.
|
|
||||||
);
|
|
||||||
this->m_travel_obstacle_tracker.mark_extruded(
|
this->m_travel_obstacle_tracker.mark_extruded(
|
||||||
ee, print_instance.object_layer_to_print_id, print_instance.instance_id
|
perimeter.extrusion_entity, print_instance.object_layer_to_print_id, print_instance.instance_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return gcode;
|
return gcode;
|
||||||
|
@ -282,6 +282,8 @@ private:
|
|||||||
bool vase_mode
|
bool vase_mode
|
||||||
);
|
);
|
||||||
std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
||||||
|
|
||||||
|
std::string extrude_perimeter(const GCode::ExtrusionOrder::Perimeter &perimeter, const std::string_view description);
|
||||||
std::string extrude_loop(const ExtrusionLoop &loop, 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(GCode::SmoothPath smooth_path, 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);
|
const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed);
|
||||||
@ -300,13 +302,13 @@ private:
|
|||||||
std::string extrude_perimeters(
|
std::string extrude_perimeters(
|
||||||
const Print &print,
|
const Print &print,
|
||||||
const PrintRegion ®ion,
|
const PrintRegion ®ion,
|
||||||
const std::vector<ExtrusionEntity *> &perimeters,
|
const std::vector<GCode::ExtrusionOrder::Perimeter> &perimeters,
|
||||||
const InstanceToPrint &print_instance,
|
const InstanceToPrint &print_instance,
|
||||||
const GCode::SmoothPathCache &smooth_path_cache
|
const GCode::SmoothPathCache &smooth_path_cache
|
||||||
);
|
);
|
||||||
|
|
||||||
std::string extrude_infill_range(
|
std::string extrude_infill_range(
|
||||||
const std::vector<ExtrusionEntityReference> &sorted_extrusions,
|
const std::vector<GCode::SmoothPath> &sorted_paths,
|
||||||
const PrintRegion ®ion,
|
const PrintRegion ®ion,
|
||||||
const std::string &extrusion_name,
|
const std::string &extrusion_name,
|
||||||
const GCode::SmoothPathCache &smooth_path_cache
|
const GCode::SmoothPathCache &smooth_path_cache
|
||||||
|
@ -106,13 +106,17 @@ ExtrusionEntitiesPtr extract_infill_extrusions(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ExtrusionEntity *> extract_perimeter_extrusions(
|
std::vector<Perimeter> extract_perimeter_extrusions(
|
||||||
const Print &print,
|
const Print &print,
|
||||||
const Layer &layer,
|
const Layer &layer,
|
||||||
const LayerIsland &island,
|
const LayerIsland &island,
|
||||||
const ExtractEntityPredicate &predicate
|
const ExtractEntityPredicate &predicate,
|
||||||
|
const unsigned extruder_id,
|
||||||
|
const Vec2d &offset,
|
||||||
|
std::optional<Vec2d> &previous_position,
|
||||||
|
const PathSmoothingFunction &smooth_path
|
||||||
) {
|
) {
|
||||||
std::vector<ExtrusionEntity *> result;
|
std::vector<Perimeter> result;
|
||||||
|
|
||||||
const LayerRegion &layerm = *layer.get_region(island.perimeters.region());
|
const LayerRegion &layerm = *layer.get_region(island.perimeters.region());
|
||||||
const PrintRegion ®ion = print.get_print_region(layerm.region().print_region_id());
|
const PrintRegion ®ion = print.get_print_region(layerm.region().print_region_id());
|
||||||
@ -127,7 +131,17 @@ std::vector<ExtrusionEntity *> extract_perimeter_extrusions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ExtrusionEntity *ee : *eec) {
|
for (ExtrusionEntity *ee : *eec) {
|
||||||
result.push_back(ee);
|
if (ee != nullptr) {
|
||||||
|
std::optional<Point> last_position{get_instance_point(previous_position, offset)};
|
||||||
|
bool reverse_loop{false};
|
||||||
|
if (auto loop = dynamic_cast<const ExtrusionLoop *>(ee)) {
|
||||||
|
const bool is_hole = loop->is_clockwise();
|
||||||
|
reverse_loop = print.config().prefer_clockwise_movements ? !is_hole : is_hole;
|
||||||
|
}
|
||||||
|
SmoothPath path{smooth_path(&layer, ExtrusionEntityReference{*ee, reverse_loop}, extruder_id, last_position)};
|
||||||
|
previous_position = get_gcode_point(last_position, offset);
|
||||||
|
result.push_back(Perimeter{std::move(path), reverse_loop, ee});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +172,9 @@ std::vector<InfillRange> extract_infill_ranges(
|
|||||||
const LayerIsland &island,
|
const LayerIsland &island,
|
||||||
const Vec2d &offset,
|
const Vec2d &offset,
|
||||||
std::optional<Vec2d> &previous_position,
|
std::optional<Vec2d> &previous_position,
|
||||||
const ExtractEntityPredicate &predicate
|
const ExtractEntityPredicate &predicate,
|
||||||
|
const PathSmoothingFunction &smooth_path,
|
||||||
|
const unsigned extruder_id
|
||||||
) {
|
) {
|
||||||
std::vector<InfillRange> result;
|
std::vector<InfillRange> result;
|
||||||
for (auto it = island.fills.begin(); it != island.fills.end();) {
|
for (auto it = island.fills.begin(); it != island.fills.end();) {
|
||||||
@ -182,12 +198,13 @@ std::vector<InfillRange> extract_infill_ranges(
|
|||||||
const Point* start_near{previous_position_scaled ? &(*(previous_position_scaled)) : nullptr};
|
const Point* start_near{previous_position_scaled ? &(*(previous_position_scaled)) : nullptr};
|
||||||
const ExtrusionEntityReferences sorted_extrusions{sort_fill_extrusions(extrusions, start_near)};
|
const ExtrusionEntityReferences sorted_extrusions{sort_fill_extrusions(extrusions, start_near)};
|
||||||
|
|
||||||
if (!sorted_extrusions.empty()) {
|
std::vector<SmoothPath> paths;
|
||||||
result.push_back({sorted_extrusions, ®ion});
|
for (const ExtrusionEntityReference &extrusion_reference : sorted_extrusions) {
|
||||||
}
|
std::optional<Point> last_position{get_instance_point(previous_position, offset)};
|
||||||
if (const auto last_position = get_last_position(sorted_extrusions, offset)) {
|
paths.push_back(smooth_path(&layer, extrusion_reference, extruder_id, last_position));
|
||||||
previous_position = last_position;
|
previous_position = get_gcode_point(previous_position, offset);
|
||||||
}
|
}
|
||||||
|
result.push_back({std::move(paths), ®ion});
|
||||||
it = it_end;
|
it = it_end;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -198,8 +215,9 @@ std::vector<IslandExtrusions> extract_island_extrusions(
|
|||||||
const Print &print,
|
const Print &print,
|
||||||
const Layer &layer,
|
const Layer &layer,
|
||||||
const ExtractEntityPredicate &predicate,
|
const ExtractEntityPredicate &predicate,
|
||||||
const SeamPlacingFunciton &place_seam,
|
const PathSmoothingFunction &smooth_path,
|
||||||
const Vec2d &offset,
|
const Vec2d &offset,
|
||||||
|
const unsigned extruder_id,
|
||||||
std::optional<Vec2d> &previous_position
|
std::optional<Vec2d> &previous_position
|
||||||
) {
|
) {
|
||||||
std::vector<IslandExtrusions> result;
|
std::vector<IslandExtrusions> result;
|
||||||
@ -217,31 +235,17 @@ std::vector<IslandExtrusions> extract_island_extrusions(
|
|||||||
result.push_back(IslandExtrusions{®ion});
|
result.push_back(IslandExtrusions{®ion});
|
||||||
IslandExtrusions &island_extrusions{result.back()};
|
IslandExtrusions &island_extrusions{result.back()};
|
||||||
|
|
||||||
island_extrusions.perimeters = extract_perimeter_extrusions(print, layer, island, predicate);
|
|
||||||
|
|
||||||
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, offset, previous_position, infill_predicate
|
print, layer, island, offset, previous_position, infill_predicate, smooth_path, extruder_id
|
||||||
);
|
);
|
||||||
|
|
||||||
for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
|
island_extrusions.perimeters = extract_perimeter_extrusions(print, layer, island, predicate, extruder_id, offset, previous_position, smooth_path);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (ExtrusionEntity* perimeter : island_extrusions.perimeters) {
|
island_extrusions.perimeters = extract_perimeter_extrusions(print, layer, island, predicate, extruder_id, offset, previous_position, smooth_path);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
island_extrusions.infill_ranges = {extract_infill_ranges(
|
island_extrusions.infill_ranges = {extract_infill_ranges(
|
||||||
print, layer, island, offset, previous_position, infill_predicate
|
print, layer, island, offset, previous_position, infill_predicate, smooth_path, extruder_id
|
||||||
)};
|
)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,7 +257,9 @@ std::vector<InfillRange> extract_ironing_extrusions(
|
|||||||
const Print &print,
|
const Print &print,
|
||||||
const Layer &layer,
|
const Layer &layer,
|
||||||
const ExtractEntityPredicate &predicate,
|
const ExtractEntityPredicate &predicate,
|
||||||
|
const PathSmoothingFunction &smooth_path,
|
||||||
const Vec2d &offset,
|
const Vec2d &offset,
|
||||||
|
const unsigned extruder_id,
|
||||||
std::optional<Vec2d> &previous_position
|
std::optional<Vec2d> &previous_position
|
||||||
) {
|
) {
|
||||||
std::vector<InfillRange> result;
|
std::vector<InfillRange> result;
|
||||||
@ -264,7 +270,7 @@ 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, offset, previous_position, ironing_predicate
|
print, layer, island, offset, previous_position, ironing_predicate, smooth_path, extruder_id
|
||||||
)};
|
)};
|
||||||
result.insert(
|
result.insert(
|
||||||
result.end(), ironing_ranges.begin(), ironing_ranges.end()
|
result.end(), ironing_ranges.begin(), ironing_ranges.end()
|
||||||
@ -277,8 +283,9 @@ std::vector<SliceExtrusions> get_slices_extrusions(
|
|||||||
const Print &print,
|
const Print &print,
|
||||||
const Layer &layer,
|
const Layer &layer,
|
||||||
const ExtractEntityPredicate &predicate,
|
const ExtractEntityPredicate &predicate,
|
||||||
const SeamPlacingFunciton &place_seam,
|
const PathSmoothingFunction &smooth_path,
|
||||||
const Vec2d &offset,
|
const Vec2d &offset,
|
||||||
|
const unsigned extruder_id,
|
||||||
std::optional<Vec2d> &previous_position
|
std::optional<Vec2d> &previous_position
|
||||||
) {
|
) {
|
||||||
// Note: ironing.
|
// Note: ironing.
|
||||||
@ -293,9 +300,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, offset, previous_position
|
lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position
|
||||||
),
|
),
|
||||||
extract_ironing_extrusions(lslice, print, layer, predicate, offset, previous_position)
|
extract_ironing_extrusions(lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -359,7 +366,7 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
|
|||||||
const LayerTools &layer_tools,
|
const LayerTools &layer_tools,
|
||||||
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 PathSmoothingFunction &smooth_path,
|
||||||
std::optional<Vec2d> &previous_position
|
std::optional<Vec2d> &previous_position
|
||||||
) {
|
) {
|
||||||
std::vector<std::vector<SliceExtrusions>> result;
|
std::vector<std::vector<SliceExtrusions>> result;
|
||||||
@ -384,7 +391,7 @@ std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
|
|||||||
const Vec2d &offset = unscale(print_object.instances()[instance.instance_id].shift);
|
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, offset, previous_position
|
print, *layer, predicate, smooth_path, offset, extruder_id, previous_position
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +404,7 @@ std::vector<NormalExtrusions> get_normal_extrusions(
|
|||||||
const LayerTools &layer_tools,
|
const LayerTools &layer_tools,
|
||||||
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 PathSmoothingFunction &smooth_path,
|
||||||
std::optional<Vec2d> &previous_position
|
std::optional<Vec2d> &previous_position
|
||||||
) {
|
) {
|
||||||
std::vector<NormalExtrusions> result;
|
std::vector<NormalExtrusions> result;
|
||||||
@ -438,8 +445,9 @@ std::vector<NormalExtrusions> get_normal_extrusions(
|
|||||||
print,
|
print,
|
||||||
*layer,
|
*layer,
|
||||||
predicate,
|
predicate,
|
||||||
place_seam,
|
smooth_path,
|
||||||
offset,
|
offset,
|
||||||
|
extruder_id,
|
||||||
previous_position
|
previous_position
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -454,13 +462,9 @@ std::vector<ExtruderExtrusions> get_extrusions(
|
|||||||
const bool is_first_layer,
|
const bool is_first_layer,
|
||||||
const LayerTools &layer_tools,
|
const LayerTools &layer_tools,
|
||||||
const std::vector<InstanceToPrint> &instances_to_print,
|
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 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,
|
unsigned current_extruder_id,
|
||||||
const SeamPlacingFunciton &place_seam,
|
const PathSmoothingFunction &smooth_path,
|
||||||
bool get_brim,
|
bool get_brim,
|
||||||
std::optional<Vec2d> previous_position
|
std::optional<Vec2d> previous_position
|
||||||
) {
|
) {
|
||||||
@ -482,35 +486,11 @@ std::vector<ExtruderExtrusions> get_extrusions(
|
|||||||
if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) {
|
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;
|
const std::pair<size_t, size_t> loops = loops_it->second;
|
||||||
for (std::size_t i = loops.first; i < loops.second; ++i) {
|
for (std::size_t i = loops.first; i < loops.second; ++i) {
|
||||||
auto loop_src{dynamic_cast<const ExtrusionLoop *>(print.skirt().entities[i])};
|
const ExtrusionEntityReference entity{*print.skirt().entities[i], false};
|
||||||
if (loop_src != nullptr) {
|
std::optional<Point> last_position{get_instance_point(previous_position, {0.0, 0.0})};
|
||||||
const Point seam_point = previous_position ? get_instance_point(*previous_position, {0.0, 0.0}) : Point::Zero();
|
SmoothPath path{smooth_path(nullptr, entity, extruder_id, last_position)};
|
||||||
const bool reverse_loop = config.prefer_clockwise_movements;
|
previous_position = get_gcode_point(last_position, {0.0, 0.0});
|
||||||
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
|
extruder_extrusions.skirt.emplace_back(i, std::move(path));
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,14 +506,14 @@ std::vector<ExtruderExtrusions> get_extrusions(
|
|||||||
bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden();
|
bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden();
|
||||||
if (is_anything_overridden) {
|
if (is_anything_overridden) {
|
||||||
extruder_extrusions.overriden_extrusions = get_overriden_extrusions(
|
extruder_extrusions.overriden_extrusions = get_overriden_extrusions(
|
||||||
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
print, layers, layer_tools, instances_to_print, extruder_id, smooth_path,
|
||||||
previous_position
|
previous_position
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::get_normal_extrusions;
|
using GCode::ExtrusionOrder::get_normal_extrusions;
|
||||||
extruder_extrusions.normal_extrusions = get_normal_extrusions(
|
extruder_extrusions.normal_extrusions = get_normal_extrusions(
|
||||||
print, layers, layer_tools, instances_to_print, extruder_id, place_seam,
|
print, layers, layer_tools, instances_to_print, extruder_id, smooth_path,
|
||||||
previous_position
|
previous_position
|
||||||
);
|
);
|
||||||
extrusions.push_back(std::move(extruder_extrusions));
|
extrusions.push_back(std::move(extruder_extrusions));
|
||||||
|
@ -53,13 +53,19 @@ struct InstanceToPrint
|
|||||||
namespace Slic3r::GCode::ExtrusionOrder {
|
namespace Slic3r::GCode::ExtrusionOrder {
|
||||||
|
|
||||||
struct InfillRange {
|
struct InfillRange {
|
||||||
std::vector<ExtrusionEntityReference> items;
|
std::vector<SmoothPath> items;
|
||||||
const PrintRegion *region;
|
const PrintRegion *region;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Perimeter {
|
||||||
|
GCode::SmoothPath smooth_path;
|
||||||
|
bool reversed;
|
||||||
|
const ExtrusionEntity *extrusion_entity;
|
||||||
|
};
|
||||||
|
|
||||||
struct IslandExtrusions {
|
struct IslandExtrusions {
|
||||||
const PrintRegion *region;
|
const PrintRegion *region;
|
||||||
std::vector<ExtrusionEntity *> perimeters;
|
std::vector<Perimeter> perimeters;
|
||||||
std::vector<InfillRange> infill_ranges;
|
std::vector<InfillRange> infill_ranges;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,27 +81,9 @@ struct NormalExtrusions {
|
|||||||
|
|
||||||
std::optional<Vec2d> get_last_position(const ExtrusionEntitiesPtr &extrusions, const Vec2d &offset);
|
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 PathSmoothingFunction = std::function<SmoothPath(
|
||||||
|
const Layer *, const ExtrusionEntityReference &, const unsigned extruder_id, std::optional<Point> &previous_position
|
||||||
std::vector<std::vector<SliceExtrusions>> get_overriden_extrusions(
|
)>;
|
||||||
const Print &print,
|
|
||||||
const GCode::ObjectsLayerToPrint &layers,
|
|
||||||
const LayerTools &layer_tools,
|
|
||||||
const std::vector<InstanceToPrint> &instances_to_print,
|
|
||||||
const unsigned int extruder_id,
|
|
||||||
const SeamPlacingFunciton &place_seam,
|
|
||||||
std::optional<Vec2d> &previous_position
|
|
||||||
);
|
|
||||||
|
|
||||||
std::vector<NormalExtrusions> get_normal_extrusions(
|
|
||||||
const Print &print,
|
|
||||||
const GCode::ObjectsLayerToPrint &layers,
|
|
||||||
const LayerTools &layer_tools,
|
|
||||||
const std::vector<InstanceToPrint> &instances_to_print,
|
|
||||||
const unsigned int extruder_id,
|
|
||||||
const SeamPlacingFunciton &place_seam,
|
|
||||||
std::optional<Vec2d> &previous_position
|
|
||||||
);
|
|
||||||
|
|
||||||
struct ExtruderExtrusions {
|
struct ExtruderExtrusions {
|
||||||
unsigned extruder_id;
|
unsigned extruder_id;
|
||||||
@ -114,13 +102,9 @@ std::vector<ExtruderExtrusions> get_extrusions(
|
|||||||
const bool is_first_layer,
|
const bool is_first_layer,
|
||||||
const LayerTools &layer_tools,
|
const LayerTools &layer_tools,
|
||||||
const std::vector<InstanceToPrint> &instances_to_print,
|
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 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,
|
unsigned current_extruder_id,
|
||||||
const SeamPlacingFunciton &place_seam,
|
const PathSmoothingFunction &smooth_path,
|
||||||
bool get_brim,
|
bool get_brim,
|
||||||
std::optional<Vec2d> previous_position
|
std::optional<Vec2d> previous_position
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user