Merge remote-tracking branch 'upstream/main' into libvgcode
# Conflicts: # src/libslic3r/GCode/GCodeProcessor.cpp
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user