Merge remote-tracking branch 'upstream/main' into libvgcode

# Conflicts:
#	src/libslic3r/GCode/GCodeProcessor.cpp
This commit is contained in:
Andrew Sun
2025-11-18 19:53:58 -05:00
1153 changed files with 385954 additions and 2728 deletions

View File

@@ -748,8 +748,6 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcode += gcodegen.unretract();
}
// BBS: if needed, write the gcode_label_objects_end then priming tower, if the retract, didn't did it.
gcodegen.m_writer.add_object_end_labels(gcode);
double current_z = gcodegen.writer().get_position().z();
if (z == -1.) // in case no specific z was provided, print at current_z pos
@@ -761,6 +759,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
}
// Process the end filament gcode.
bool add_change_filament_624 = false;
std::string end_filament_gcode_str;
if (gcodegen.writer().filament() != nullptr) {
// Process the custom filament_end_gcode in case of single_extruder_multi_material.
@@ -769,7 +768,12 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
if (gcodegen.writer().filament() != nullptr && !filament_end_gcode.empty()) {
DynamicConfig config;
config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index));
end_filament_gcode_str = gcodegen.placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
if (!gcodegen.m_filament_instances_code.empty()) {
end_filament_gcode_str += ("M624 " + gcodegen.m_filament_instances_code + "\n");
gcodegen.m_filament_instances_code = "";
add_change_filament_624 = true;
}
end_filament_gcode_str += gcodegen.placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
check_add_eol(end_filament_gcode_str);
}
}
@@ -785,9 +789,13 @@ 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.
std::string object_end_label_temp;
gcodegen.m_writer.add_object_end_labels(object_end_label_temp);
// Process the custom change_filament_gcode. If it is empty, provide a simple Tn command to change the filament.
// Otherwise, leave control to the user completely.
std::string change_filament_gcode = gcodegen.config().change_filament_gcode.value;
@@ -809,12 +817,14 @@ 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;
}
end_filament_gcode_str = toolchange_retract_str + end_filament_gcode_str;
end_filament_gcode_str = toolchange_retract_str + object_end_label_temp + end_filament_gcode_str;
std::string wipe_next_start_point_str;
bool need_travel_after_change_filament_gcode = false; // travel need be after the filament changed to get the correct "m_curr_extruder_id"
if (! change_filament_gcode.empty()) {
DynamicConfig config;
int old_filament_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->id() : -1;
@@ -934,48 +944,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcodegen.writer().set_position(pos);
}
}
// move to start_pos for wiping after toolchange
if (!is_used_travel_avoid_perimeter) {
std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos");
check_add_eol(start_pos_str);
toolchange_gcode_str += start_pos_str;
} else {
// BBS:change travel_path
Vec3f gcode_last_pos;
GCodeProcessor::get_last_position_from_gcode(toolchange_gcode_str, gcode_last_pos);
Vec2f gcode_last_pos2d{gcode_last_pos[0], gcode_last_pos[1]};
Point gcode_last_pos2d_object = gcodegen.gcode_to_point(gcode_last_pos2d.cast<double>() + plate_origin_2d.cast<double>());
Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d);
BoundingBox avoid_bbx, printer_bbx;
{
//set printer_bbx
Pointfs bed_pointsf = gcodegen.m_config.printable_area.values;
Points bed_points;
for (auto p : bed_pointsf) {
bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast<float>() + plate_origin_2d));
}
printer_bbx = BoundingBox(bed_points);
}
{
//set avoid_bbx
avoid_bbx = scaled(m_wipe_tower_bbx);
Polygon avoid_points = avoid_bbx.polygon();
for (auto& p : avoid_points.points) {
Vec2f pp = transform_wt_pt(unscale(p).cast<float>());
p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d);
}
avoid_bbx = BoundingBox(avoid_points.points);
}
std::string travel_to_wipe_tower_gcode;
Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx);
for (const auto &p : travel_polyline.points) {
travel_to_wipe_tower_gcode += gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(travel_to_wipe_tower_gcode);
}
toolchange_gcode_str += travel_to_wipe_tower_gcode;
gcodegen.set_last_pos(start_wipe_pos);
}
need_travel_after_change_filament_gcode = true;
}
std::string toolchange_command;
@@ -987,6 +956,55 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
// We have informed the m_writer about the current extruder_id, we can ignore the generated G-code.
}
if (need_travel_after_change_filament_gcode) {
// move to start_pos for wiping after toolchange
if (!is_used_travel_avoid_perimeter) {
std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos");
check_add_eol(start_pos_str);
wipe_next_start_point_str = start_pos_str;
} else {
// BBS:change travel_path
Vec3f gcode_last_pos;
GCodeProcessor::get_last_position_from_gcode(toolchange_gcode_str, gcode_last_pos);
Vec2f gcode_last_pos2d{gcode_last_pos[0], gcode_last_pos[1]};
Point gcode_last_pos2d_object = gcodegen.gcode_to_point(gcode_last_pos2d.cast<double>() + plate_origin_2d.cast<double>());
Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d);
BoundingBox avoid_bbx, printer_bbx;
{
// set printer_bbx
Pointfs bed_pointsf = gcodegen.m_config.printable_area.values;
Points bed_points;
for (auto p : bed_pointsf) { bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast<float>() + plate_origin_2d)); }
printer_bbx = BoundingBox(bed_points);
}
{
// set avoid_bbx
avoid_bbx = scaled(m_wipe_tower_bbx);
Polygon avoid_points = avoid_bbx.polygon();
for (auto &p : avoid_points.points) {
Vec2f pp = transform_wt_pt(unscale(p).cast<float>());
p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d);
}
avoid_bbx = BoundingBox(avoid_points.points);
}
std::string travel_to_wipe_tower_gcode;
Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx);
for (size_t i = 0; i < travel_polyline.points.size(); ++i) {
const auto &p = travel_polyline.points[i];
if (i == travel_polyline.points.size() - 1) {
wipe_next_start_point_str = gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(wipe_next_start_point_str);
break;
}
travel_to_wipe_tower_gcode += gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(travel_to_wipe_tower_gcode);
}
toolchange_gcode_str += travel_to_wipe_tower_gcode;
gcodegen.set_last_pos(start_wipe_pos);
}
}
// do unretract after setting current extruder_id
std::string toolchange_unretract_str = gcodegen.unretract();
check_add_eol(toolchange_unretract_str);
@@ -1005,10 +1023,14 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
DynamicConfig config;
config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_filament_id));
start_filament_gcode_str = gcodegen.placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config);
if (add_change_filament_624) {
start_filament_gcode_str += "M625\n";
add_change_filament_624 = false;
}
check_add_eol(start_filament_gcode_str);
}
start_filament_gcode_str = start_filament_gcode_str + toolchange_unretract_str;
start_filament_gcode_str = start_filament_gcode_str + wipe_next_start_point_str + toolchange_unretract_str;
// Insert the end filament, toolchange, and start filament gcode into the generated gcode.
DynamicConfig config;
@@ -1042,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.
@@ -1972,7 +1994,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
if(is_BBL_Printer())
result->label_object_enabled = m_enable_exclude_object;
// Write the profiler measurements to file
PROFILE_UPDATE();
PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str());
@@ -2274,6 +2295,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_enable_cooling_markers = true;
this->apply_print_config(print.config());
m_config.apply(print.default_object_config());
m_config.apply(print.default_region_config());
//m_volumetric_speed = DoExport::autospeed_volumetric_limit(print);
print.throw_if_canceled();
@@ -2452,7 +2475,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
//resize
first_non_support_filaments.resize(print.config().nozzle_diameter.size(), -1);
first_filaments.resize(print.config().nozzle_diameter.size(), -1);
float max_additional_fan = 0.f;
if (print.config().print_sequence == PrintSequence::ByObject) {
// Order object instances for sequential print.
print_object_instances_ordering = sort_object_instances_by_model_order(print);
@@ -2465,6 +2488,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id);
tool_ordering.sort_and_build_data(*(*print_object_instance_sequential_active)->print_object,initial_extruder_id);
float temp_max_additional_fan = tool_ordering.cal_max_additional_fan(print.config());
if(temp_max_additional_fan > max_additional_fan )
max_additional_fan = temp_max_additional_fan;
if (!find_fist_non_support_filament && tool_ordering.first_extruder() != (unsigned int) -1) {
//BBS: try to find the non-support filament extruder if is multi color and initial_extruder is support filament
if (initial_extruder_id == (unsigned int) -1) {
@@ -2488,6 +2514,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
tool_ordering = print.tool_ordering();
tool_ordering.assign_custom_gcodes(print);
float temp_max_additional_fan = tool_ordering.cal_max_additional_fan(print.config());
if(temp_max_additional_fan > max_additional_fan )
max_additional_fan = temp_max_additional_fan;
if (tool_ordering.all_extruders().empty())
// No object to print was found, cancel the G-code export.
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
@@ -2585,6 +2614,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->placeholder_parser().set("retraction_distances_when_ec", new ConfigOptionFloatsNullable(m_config.retraction_distances_when_ec));
this->placeholder_parser().set("long_retractions_when_ec",new ConfigOptionBoolsNullable(m_config.long_retractions_when_ec));
this->placeholder_parser().set("max_additional_fan", max_additional_fan);
this->placeholder_parser().set("first_x_layer_fan_speed", 0); // TODO: Orca hack to support BBL profiles
auto flush_v_speed = m_config.filament_flush_volumetric_speed.values;
auto flush_temps = m_config.filament_flush_temp.values;
for (size_t idx = 0; idx < flush_v_speed.size(); ++idx) {
@@ -2783,6 +2815,46 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->placeholder_parser().set("scan_first_layer", new ConfigOptionBool(false));
}
}
{ // hold chamber temp for flat print: Flag
double print_area_sum_threshold = 40000.0, pring_hight_threshold = 0.3; // thresholds in mm^2 and mm as units
double area_sum_temp = 0.0;
coordf_t max_hight_temp = -1.0;
for (ObjectID print_object_ID_t : print.print_object_ids()) {
const PrintObject *print_object = print.get_object(print_object_ID_t);
// object hight
if (!print_object->layers().empty() && print_object->layers().back()->print_z > max_hight_temp) max_hight_temp = print_object->layers().back()->print_z;
// object area
if (!print_object->layers().empty() && print_object->layers().front()->print_z < print.config().initial_layer_print_height + EPSILON &&
!print_object->layers().front()->lslices.empty()) {
ExPolygons temp_Expolys = print_object->layers().front()->lslices;
for (ExPolygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
// suport area
if (!print_object->support_layers().empty() && print_object->support_layers().front()->print_z < print.config().initial_layer_print_height + EPSILON &&
!print_object->support_layers().front()->support_islands.empty()) {
ExPolygons temp_Expolys = print_object->support_layers().front()->support_islands;
for (ExPolygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
// brim area
if (print.m_brimMap.find(print_object_ID_t) != print.m_brimMap.end() && !print.m_brimMap.at(print_object_ID_t).entities.empty()) { // contain brim
for (const ExtrusionEntity *entities_temp : print.m_brimMap.at(print_object_ID_t).entities) {
Polygons temp_Expolys;
entities_temp->polygons_covered_by_spacing(temp_Expolys, 0.0f);
for (Polygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
}
}
// wipe tower area
if (has_wipe_tower) {
Polygon temp_Expoly = print.wipe_tower_data().wipe_tower_mesh_data->bottom;
area_sum_temp += temp_Expoly.area();
}
bool hold_chamber_temp_for_flat_print = max_hight_temp > 0 && max_hight_temp < pring_hight_threshold && area_sum_temp > print_area_sum_threshold * 1.0e10;
this->placeholder_parser().set("hold_chamber_temp_for_flat_print", new ConfigOptionBool(hold_chamber_temp_for_flat_print));
}
std::string machine_start_gcode = this->placeholder_parser_process("machine_start_gcode", print.config().machine_start_gcode.value, initial_extruder_id);
if (print.config().gcode_flavor != gcfKlipper) {
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
@@ -2964,10 +3036,14 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (m_writer.need_toolchange(initial_extruder_id)) {
const PrintObjectConfig& object_config = object.config();
coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value;
if (m_enable_exclude_object && print.config().support_object_skip_flush.value) {
m_filament_instances_code = _encode_label_ids_to_base64({(*print_object_instance_sequential_active)->model_instance->get_labeled_id()});
}
file.write(this->set_extruder(initial_extruder_id, initial_layer_print_height, true));
prime_extruder = true;
}
else {
} else {
file.write(this->retract());
}
file.write(m_writer.travel_to_z(m_max_layer_z + m_writer.config.z_hop.get_at(initial_extruder_id)));
@@ -3132,6 +3208,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
//BBS
config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value));
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
if (print.config().single_extruder_multi_material) {
// Process the filament_end_gcode for the active filament only.
int extruder_id = m_writer.filament()->id();
@@ -3371,6 +3448,7 @@ void GCode::process_layers(
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
else
tbb::parallel_pipeline(12, generator & cooling & fan_mover & pa_processor_filter & output);
}
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
@@ -4612,27 +4690,25 @@ LayerResult GCode::process_layer(
auto objects_by_extruder_it = by_extruder.find(filament_id);
if (objects_by_extruder_it == by_extruder.end()) continue;
bool has_prime_tower = print.config().enable_prime_tower && print.extruders().size() > 1 &&
((print.config().print_sequence == PrintSequence::ByLayer && print.config().print_order == PrintOrder::Default) ||
(print.config().print_sequence == PrintSequence::ByObject && print.objects().size() == 1));
if (has_prime_tower) {
int plate_idx = print.get_plate_index();
Point wt_pos(print.config().wipe_tower_x.get_at(plate_idx), print.config().wipe_tower_y.get_at(plate_idx));
int plate_idx = print.get_plate_index();
Point wt_pos(print.config().wipe_tower_x.get_at(plate_idx), print.config().wipe_tower_y.get_at(plate_idx));
std::vector<GCode::ObjectByExtruder> &objects_by_extruder = objects_by_extruder_it->second;
std::vector<const PrintObject *> print_objects;
for (int obj_idx = 0; obj_idx < objects_by_extruder.size(); obj_idx++) {
auto &object_by_extruder = objects_by_extruder[obj_idx];
if (object_by_extruder.islands.empty() && (object_by_extruder.support == nullptr || object_by_extruder.support->empty())) continue;
std::vector<GCode::ObjectByExtruder> &objects_by_extruder = objects_by_extruder_it->second;
std::vector<const PrintObject *> print_objects;
for (int obj_idx = 0; obj_idx < objects_by_extruder.size(); obj_idx++) {
auto &object_by_extruder = objects_by_extruder[obj_idx];
if (object_by_extruder.islands.empty() && (object_by_extruder.support == nullptr || object_by_extruder.support->empty())) continue;
print_objects.push_back(print.get_object(obj_idx));
}
print_objects.push_back(print.get_object(obj_idx));
}
std::vector<const PrintInstance *> new_ordering = chain_print_object_instances(print_objects, &wt_pos);
std::reverse(new_ordering.begin(), new_ordering.end());
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, &new_ordering, single_object_instance_idx);
} else {
std::vector<const PrintInstance *> new_ordering = chain_print_object_instances(print_objects, &wt_pos);
std::reverse(new_ordering.begin(), new_ordering.end());
if (print.config().print_sequence == PrintSequence::ByObject) {
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, ordering, single_object_instance_idx);
} else {
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, &new_ordering, single_object_instance_idx);
}
}
}
@@ -4705,7 +4781,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();
}
@@ -4744,6 +4820,12 @@ LayerResult GCode::process_layer(
gcode += generate_skirt(print, print.skirt(), Point(0, 0), layer.object()->config().skirt_start_angle, layer_tools, layer,
extruder_id);
if (print.config().print_sequence == PrintSequence::ByLayer && m_enable_exclude_object && print.config().support_object_skip_flush.value) {
std::vector<size_t> filament_instances_id;
for (InstanceToPrint &instance : filament_to_print_instances[extruder_id]) filament_instances_id.emplace_back(instance.label_object_id);
m_filament_instances_code = _encode_label_ids_to_base64(filament_instances_id);
}
std::string gcode_toolchange;
if (has_wipe_tower) {
if (!m_wipe_tower->is_empty_wipe_tower_gcode(*this, extruder_id, extruder_id == layer_tools.extruders.back())) {
@@ -4756,7 +4838,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();
@@ -4765,17 +4847,20 @@ 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;
}
gcode_toolchange = m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back());
}
} else {
if (m_writer.need_toolchange(extruder_id) &&
m_config.nozzle_diameter.values.size() == 2 && writer().filament() &&
if (need_insert_timelapse_gcode_for_traditional &&
!has_insert_timelapse_gcode &&
m_writer.need_toolchange(extruder_id) &&
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();
@@ -4783,7 +4868,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;
}
@@ -4858,6 +4943,7 @@ LayerResult GCode::process_layer(
// To control print speed of the 1st object layer printed over raft interface.
bool object_layer_over_raft = layer_to_print.object_layer && layer_to_print.object_layer->id() > 0 &&
instance_to_print.print_object.slicing_parameters().raft_layers() == layer_to_print.object_layer->id();
m_config.apply(print.default_region_config());
m_config.apply(instance_to_print.print_object.config(), true);
m_layer = layer_to_print.layer();
m_object_layer_over_raft = object_layer_over_raft;
@@ -4987,7 +5073,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;
@@ -5072,7 +5158,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);
@@ -6801,7 +6887,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.
@@ -6880,7 +6966,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:
@@ -6971,7 +7057,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)));
@@ -7005,7 +7091,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)));
@@ -7013,7 +7099,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;
@@ -7062,7 +7148,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;
@@ -7121,6 +7210,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
if (by_object)
m_writer.add_object_change_labels(gcode);
bool add_change_filament_624 = false;
if (m_writer.filament() != nullptr) {
// Process the custom filament_end_gcode. set_extruder() is only called if there is no wipe tower
// so it should not be injected twice.
@@ -7132,6 +7222,11 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position().z() - m_config.z_offset.value));
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(get_extruder_id(old_filament_id))));
if (!m_filament_instances_code.empty()) {
gcode += ("M624 " + m_filament_instances_code + "\n");
m_filament_instances_code = "";
add_change_filament_624 = true;
}
gcode += placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
check_add_eol(gcode);
}
@@ -7276,7 +7371,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
@@ -7343,6 +7438,10 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(new_filament_id)));
gcode += this->placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config);
if (add_change_filament_624) {
gcode += "M625\n";
add_change_filament_624 = false;
}
check_add_eol(gcode);
}
// Set the new extruder to the operating temperature.