mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-04-06 00:32:05 +02:00
ENH: add eager lift function
1.Immediate do lift in eager_lift function jira:NONE Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: I931d22e901e2123bb886c31d8d1a5788fddeed42 (cherry picked from commit 6cea772d4f3b2f7e2a43c35a2271e4bdbba9eadd)
This commit is contained in:
@@ -789,7 +789,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
auto_lift_type = LiftType::SpiralLift;
|
||||
|
||||
// BBS: should be placed before toolchange parsing
|
||||
std::string toolchange_retract_str = gcodegen.retract(tcr.is_tool_change && !is_nozzle_change, false, auto_lift_type);
|
||||
std::string toolchange_retract_str = gcodegen.retract(tcr.is_tool_change && !is_nozzle_change, false, auto_lift_type, true);
|
||||
check_add_eol(toolchange_retract_str);
|
||||
|
||||
//BBS: if needed, write the gcode_label_objects_end then priming tower, if the retract, didn't did it.
|
||||
@@ -817,7 +817,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
gcodegen.m_wipe.reset_path();
|
||||
for (const Vec2f& wipe_pt : tcr.nozzle_change_result.wipe_path)
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt) + plate_origin_2d));
|
||||
nozzle_change_gcode_trans += gcodegen.retract(tcr.is_tool_change, false, auto_lift_type);
|
||||
nozzle_change_gcode_trans += gcodegen.retract(tcr.is_tool_change, false, auto_lift_type, true);
|
||||
end_filament_gcode_str = nozzle_change_gcode_trans + end_filament_gcode_str;
|
||||
}
|
||||
|
||||
@@ -1064,7 +1064,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
gcodegen.m_wipe.reset_path();
|
||||
for (const Vec2f &wipe_pt : tcr.wipe_path)
|
||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt)));
|
||||
gcode += gcodegen.retract(false, false, auto_lift_type);
|
||||
gcode += gcodegen.retract(false, false, auto_lift_type, true);
|
||||
}
|
||||
|
||||
// Let the planner know we are traveling between objects.
|
||||
@@ -4776,7 +4776,7 @@ LayerResult GCode::process_layer(
|
||||
|
||||
if (!need_insert_timelapse_gcode_for_traditional) { // Equivalent to the timelapse gcode placed in layer_change_gcode
|
||||
if (FILAMENT_CONFIG(retract_when_changing_layer)) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
}
|
||||
gcode += insert_timelapse_gcode();
|
||||
}
|
||||
@@ -4833,7 +4833,7 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
|
||||
if (should_insert) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
m_writer.add_object_change_labels(gcode);
|
||||
|
||||
gcode += insert_timelapse_gcode();
|
||||
@@ -4842,7 +4842,7 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
|
||||
if (print.config().enable_wrapping_detection && !has_insert_wrapping_detection_gcode) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
gcode += insert_wrapping_detection_gcode();
|
||||
has_insert_wrapping_detection_gcode = true;
|
||||
}
|
||||
@@ -4855,7 +4855,7 @@ LayerResult GCode::process_layer(
|
||||
m_config.nozzle_diameter.values.size() == 2 &&
|
||||
writer().filament() &&
|
||||
(get_extruder_id(writer().filament()->id()) == most_used_extruder)) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
m_writer.add_object_change_labels(gcode);
|
||||
|
||||
gcode += insert_timelapse_gcode();
|
||||
@@ -4863,7 +4863,7 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
|
||||
if (print.config().enable_wrapping_detection && !has_insert_wrapping_detection_gcode) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
gcode += insert_wrapping_detection_gcode();
|
||||
has_insert_wrapping_detection_gcode = true;
|
||||
}
|
||||
@@ -5068,7 +5068,7 @@ LayerResult GCode::process_layer(
|
||||
gcode += this->extrude_perimeters(print, by_region_specific, first_layer, false);
|
||||
if (!has_wipe_tower && need_insert_timelapse_gcode_for_traditional && printer_structure == PrinterStructure::psI3
|
||||
&& !has_insert_timelapse_gcode && has_infill(by_region_specific)) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
|
||||
gcode += insert_timelapse_gcode();
|
||||
has_insert_timelapse_gcode = true;
|
||||
@@ -5153,7 +5153,7 @@ LayerResult GCode::process_layer(
|
||||
m_support_traditional_timelapse = false;
|
||||
}
|
||||
if (FILAMENT_CONFIG(retract_when_changing_layer)) {
|
||||
gcode += this->retract(false, false, auto_lift_type);
|
||||
gcode += this->retract(false, false, auto_lift_type, true);
|
||||
}
|
||||
m_writer.add_object_change_labels(gcode);
|
||||
|
||||
@@ -6890,7 +6890,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
|
||||
m_wipe.reset_path();*/
|
||||
|
||||
Point last_post_before_retract = this->last_pos();
|
||||
gcode += this->retract(false, false, lift_type, role);
|
||||
gcode += this->retract(false, false, lift_type, false, role);
|
||||
// When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
|
||||
// Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
|
||||
// FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
|
||||
@@ -6969,7 +6969,7 @@ LiftType GCode::to_lift_type(ZHopType z_hop_types) {
|
||||
case ZHopType::zhtNormal:
|
||||
return LiftType::NormalLift;
|
||||
case ZHopType::zhtSlope:
|
||||
return LiftType::LazyLift;
|
||||
return LiftType::SlopeLift;
|
||||
case ZHopType::zhtSpiral:
|
||||
return LiftType::SpiralLift;
|
||||
default:
|
||||
@@ -7060,7 +7060,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
|
||||
//Better way is judging whether the travel move direction is same with last extrusion move.
|
||||
if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) {
|
||||
if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) {
|
||||
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
|
||||
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift;
|
||||
}
|
||||
else {
|
||||
lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types)));
|
||||
@@ -7094,7 +7094,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
|
||||
|
||||
// retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
|
||||
if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) {
|
||||
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
|
||||
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift;
|
||||
}
|
||||
else {
|
||||
lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types)));
|
||||
@@ -7102,7 +7102,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type, ExtrusionRole role)
|
||||
std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type, bool apply_instantly, ExtrusionRole role)
|
||||
{
|
||||
std::string gcode;
|
||||
|
||||
@@ -7151,7 +7151,10 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
|
||||
}
|
||||
|
||||
if (needs_lift && can_lift) {
|
||||
gcode += m_writer.lift(lift_type, m_spiral_vase != nullptr);
|
||||
if (apply_instantly)
|
||||
gcode += m_writer.eager_lift(lift_type);
|
||||
else
|
||||
gcode += m_writer.lazy_lift(lift_type, m_spiral_vase != nullptr);
|
||||
}
|
||||
|
||||
return gcode;
|
||||
@@ -7371,7 +7374,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
||||
std::string change_filament_gcode = m_config.change_filament_gcode.value;
|
||||
|
||||
// Move the lift gcode here which is in the change_filament_gcode originally
|
||||
change_filament_gcode = this->retract(false, false, LiftType::SpiralLift) + change_filament_gcode;
|
||||
change_filament_gcode = this->retract(false, false, LiftType::SpiralLift, true) + change_filament_gcode;
|
||||
|
||||
std::string toolchange_gcode_parsed;
|
||||
//Orca: Ignore change_filament_gcode if is the first call for a tool change and manual_filament_change is enabled
|
||||
|
||||
@@ -246,7 +246,7 @@ public:
|
||||
|
||||
std::string travel_to(const Point& point, ExtrusionRole role, std::string comment, double z = DBL_MAX);
|
||||
bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type);
|
||||
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, ExtrusionRole role = erNone);
|
||||
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, bool apply_instantly = false, ExtrusionRole role = erNone);
|
||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||
std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false);
|
||||
bool is_BBL_Printer();
|
||||
|
||||
@@ -528,6 +528,71 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
|
||||
return w.string();
|
||||
}
|
||||
|
||||
/* If this method is called more than once before calling unlift(),
|
||||
it will not perform subsequent lifts, even if Z was raised manually
|
||||
(i.e. with travel_to_z()) and thus _lifted was reduced. */
|
||||
std::string GCodeWriter::lazy_lift(LiftType lift_type, bool spiral_vase)
|
||||
{
|
||||
// check whether the above/below conditions are met
|
||||
double target_lift = 0;
|
||||
{
|
||||
//BBS
|
||||
int extruder_id = filament()->extruder_id();
|
||||
int filament_id = filament()->id();
|
||||
double above = this->config.retract_lift_above.get_at(extruder_id);
|
||||
double below = this->config.retract_lift_below.get_at(extruder_id);
|
||||
if (m_pos.z() >= above && m_pos.z() <= below)
|
||||
target_lift = this->config.z_hop.get_at(filament_id);
|
||||
}
|
||||
// BBS
|
||||
if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
|
||||
if (spiral_vase) {
|
||||
m_lifted = target_lift;
|
||||
return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
|
||||
}
|
||||
else {
|
||||
m_to_lift = target_lift;
|
||||
m_to_lift_type = lift_type;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// BBS: immediately execute an undelayed lift move with a spiral lift pattern
|
||||
// designed specifically for subsequent gcode injection (e.g. timelapse)
|
||||
std::string GCodeWriter::eager_lift(const LiftType type) {
|
||||
std::string lift_move;
|
||||
double target_lift = 0;
|
||||
{
|
||||
//BBS
|
||||
int extruder_id = filament()->extruder_id();
|
||||
int filament_id = filament()->id();
|
||||
double above = this->config.retract_lift_above.get_at(extruder_id);
|
||||
double below = this->config.retract_lift_below.get_at(extruder_id);
|
||||
if (m_pos.z() >= above && m_pos.z() <= below)
|
||||
target_lift = this->config.z_hop.get_at(filament_id);
|
||||
}
|
||||
|
||||
// BBS: spiral lift only safe with known position
|
||||
// TODO: check the arc will move within bed area
|
||||
if (type == LiftType::SpiralLift && this->is_current_position_clear()) {
|
||||
double radius = target_lift / (2 * PI * atan(filament()->travel_slope()));
|
||||
// static spiral alignment when no move in x,y plane.
|
||||
// spiral centra is a radius distance to the right (y=0)
|
||||
Vec2d ij_offset = { radius, 0 };
|
||||
if (target_lift > 0) {
|
||||
lift_move = this->_spiral_travel_to_z(m_pos(2) + target_lift, ij_offset, "spiral lift Z");
|
||||
}
|
||||
}
|
||||
//BBS: if position is unknown use normal lift
|
||||
else if (target_lift > 0) {
|
||||
lift_move = _travel_to_z(m_pos(2) + target_lift, "normal lift Z");
|
||||
}
|
||||
m_lifted = target_lift;
|
||||
m_to_lift = 0;
|
||||
return lift_move;
|
||||
}
|
||||
|
||||
std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment, bool force_z)
|
||||
{
|
||||
// FIXME: This function was not being used when travel_speed_z was separated (bd6badf).
|
||||
@@ -573,8 +638,8 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
ij_offset = { -ij_offset(1), ij_offset(0) };
|
||||
slop_move = this->_spiral_travel_to_z(target(2), ij_offset, "spiral lift Z");
|
||||
}
|
||||
//BBS: LazyLift
|
||||
else if (m_to_lift_type == LiftType::LazyLift &&
|
||||
//BBS: SlopeLift
|
||||
else if (m_to_lift_type == LiftType::SlopeLift &&
|
||||
this->is_current_position_clear() &&
|
||||
atan2(delta(2), delta_no_z.norm()) < this->filament()->travel_slope()) {
|
||||
//BBS: check whether we can make a travel like
|
||||
@@ -871,34 +936,6 @@ std::string GCodeWriter::unretract()
|
||||
return gcode;
|
||||
}
|
||||
|
||||
/* If this method is called more than once before calling unlift(),
|
||||
it will not perform subsequent lifts, even if Z was raised manually
|
||||
(i.e. with travel_to_z()) and thus _lifted was reduced. */
|
||||
std::string GCodeWriter::lift(LiftType lift_type, bool spiral_vase)
|
||||
{
|
||||
// check whether the above/below conditions are met
|
||||
double target_lift = 0;
|
||||
{
|
||||
int extruder_id = filament()->extruder_id();
|
||||
int filament_id = filament()->id();
|
||||
double above = this->config.retract_lift_above.get_at(extruder_id);
|
||||
double below = this->config.retract_lift_below.get_at(extruder_id);
|
||||
if (m_pos(2) >= above && (below == 0 || m_pos(2) <= below))
|
||||
target_lift = this->config.z_hop.get_at(filament_id);
|
||||
}
|
||||
// BBS
|
||||
if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
|
||||
if (spiral_vase) {
|
||||
m_lifted = target_lift;
|
||||
return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
|
||||
}
|
||||
else {
|
||||
m_to_lift = target_lift;
|
||||
m_to_lift_type = lift_type;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GCodeWriter::unlift()
|
||||
{
|
||||
|
||||
@@ -83,7 +83,10 @@ public:
|
||||
std::string retract(bool before_wipe = false, double retract_length = 0);
|
||||
std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0);
|
||||
std::string unretract();
|
||||
std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
|
||||
// do lift instantly
|
||||
std::string eager_lift(const LiftType type);
|
||||
// record a lift request, do realy lift in next travel
|
||||
std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
|
||||
std::string unlift();
|
||||
const Vec3d& get_position() const { return m_pos; }
|
||||
Vec3d& get_position() { return m_pos; }
|
||||
|
||||
@@ -221,7 +221,7 @@ enum GapFillTarget {
|
||||
enum LiftType {
|
||||
NormalLift,
|
||||
SpiralLift,
|
||||
LazyLift
|
||||
SlopeLift
|
||||
};
|
||||
|
||||
enum SLAMaterial {
|
||||
|
||||
Reference in New Issue
Block a user