Enabling object skirt. (#6487)

Implements individual object skirts, as requested in  **Individual skirts when printing by object. #3486** and  **Skirt around each object when using "by object" sequence #2652**

Now skirt type could be
![image](https://github.com/user-attachments/assets/532ecd91-fe3e-4bdb-b22f-ef28439ab7a6)

This PR based on several refactorings, including  **Configure skirt start point #6490** PR. To make review more easy each step was committed individually. Obviously them could be separated to different PRs or dropped.

I removed `prime_extruder && first_layer && extruder_id == first_extruder_id` as explicit object skirt is available.

Open question : do we need both common and object skirt together, probably with separate loop number?


All four combinations are possible.

Print by layer, common skirt:
![image](https://github.com/user-attachments/assets/5509f10b-ed3b-4243-8763-7ddcb101c67a)

Print by layer, object skirt:
![image](https://github.com/user-attachments/assets/deca3ca6-8bf7-4e5b-a356-2f5dd6e81566)

Print by object , object skirt:
![image](https://github.com/user-attachments/assets/7d1b2ddc-e61f-4d77-9ed4-e33fdd62d290)

Print by object , common skirt (any meaning?):
![image](https://github.com/user-attachments/assets/e7883eb4-b1a3-4158-a7f4-ce0658bc1939)
This commit is contained in:
SoftFever 2024-09-07 23:46:54 +08:00 committed by GitHub
commit 415bedef94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 342 additions and 381 deletions

View file

@ -449,17 +449,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
}
if (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject && config->opt_int("skirt_height") > 1 && config->opt_int("skirt_loops") > 0) {
const wxString msg_text = _(L("While printing by Object, the extruder may collide skirt.\nThus, reset the skirt layer to 1 to avoid that."));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
dialog.ShowModal();
new_conf.set_key_value("skirt_height", new ConfigOptionInt(1));
apply(config, &new_conf);
is_msg_dlg_already_exist = false;
}
if (config->opt_enum<SeamScarfType>("seam_slope_type") != SeamScarfType::None &&
config->get_abs_value("seam_slope_start_height") >= layer_height) {
const wxString msg_text = _(L("seam_slope_start_height need to be smaller than layer_height.\nReset to 0."));
@ -572,7 +561,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool have_skirt = config->opt_int("skirt_loops") > 0;
toggle_field("skirt_height", have_skirt && config->opt_enum<DraftShield>("draft_shield") != dsEnabled);
for (auto el : { "skirt_distance", "draft_shield"})
for (auto el : {"skirt_type", "skirt_distance", "skirt_start_angle", "draft_shield"})
toggle_field(el, have_skirt);
bool have_brim = (config->opt_enum<BrimType>("brim_type") != btNoBrim);

View file

@ -5227,13 +5227,12 @@ void GLCanvas3D::update_sequential_clearance()
// the results are then cached for following displacements
if (m_sequential_print_clearance_first_displacement) {
m_sequential_print_clearance.m_hull_2d_cache.clear();
bool all_objects_are_short = std::all_of(fff_print()->objects().begin(), fff_print()->objects().end(), \
[&](PrintObject* obj) { return obj->height() < scale_(fff_print()->config().nozzle_height.value - MARGIN_HEIGHT); });
auto [object_skirt_offset, _] = fff_print()->object_skirt_offset();
float shrink_factor;
if (all_objects_are_short)
shrink_factor = scale_(0.5 * MAX_OUTER_NOZZLE_DIAMETER - 0.1);
if (fff_print()->is_all_objects_are_short())
shrink_factor = scale_(std::max(0.5f * MAX_OUTER_NOZZLE_DIAMETER, object_skirt_offset) - 0.1);
else
shrink_factor = static_cast<float>(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value - EPSILON));
shrink_factor = static_cast<float>(scale_(0.5 * fff_print()->config().extruder_clearance_radius.value + object_skirt_offset - 0.1));
double mitter_limit = scale_(0.1);
m_sequential_print_clearance.m_hull_2d_cache.reserve(m_model->objects.size());

View file

@ -766,17 +766,21 @@ arrangement::ArrangeParams init_arrange_params(Plater *p)
auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
const PrintConfig &print_config = print.config();
auto [object_skirt_offset, object_skirt_witdh] = print.object_skirt_offset();
params.clearance_height_to_rod = print_config.extruder_clearance_height_to_rod.value;
params.clearance_height_to_lid = print_config.extruder_clearance_height_to_lid.value;
params.cleareance_radius = print_config.extruder_clearance_radius.value;
params.clearance_radius = print_config.extruder_clearance_radius.value + object_skirt_offset * 2;
params.object_skirt_offset = object_skirt_offset;
params.printable_height = print_config.printable_height.value;
params.allow_rotations = settings.enable_rotation;
params.nozzle_height = print.config().nozzle_height.value;
params.nozzle_height = print_config.nozzle_height.value;
params.all_objects_are_short = print.is_all_objects_are_short();
params.align_center = print_config.best_object_pos.value;
params.allow_multi_materials_on_same_plate = settings.allow_multi_materials_on_same_plate;
params.avoid_extrusion_cali_region = settings.avoid_extrusion_cali_region;
params.is_seq_print = settings.is_seq_print;
params.min_obj_distance = scaled(settings.distance);
params.min_obj_distance = settings.distance;
params.align_to_y_axis = settings.align_to_y_axis;
int state = p->get_prepare_state();

View file

@ -2770,7 +2770,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
"printable_area", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "print_sequence",
"extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"nozzle_height", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance",
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
"brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume",
"extruder_colour", "filament_colour", "material_colour", "printable_height", "printer_model", "printer_technology",

View file

@ -61,7 +61,7 @@ namespace GUI {
#define DISABLE_UNDO_SYS
static const std::vector<std::string> plate_keys = { "curr_bed_type", "first_layer_print_sequence", "first_layer_sequence_choice", "other_layers_print_sequence", "other_layers_sequence_choice", "print_sequence", "spiral_mode"};
static const std::vector<std::string> plate_keys = { "curr_bed_type", "skirt_start_angle", "first_layer_print_sequence", "first_layer_sequence_choice", "other_layers_print_sequence", "other_layers_sequence_choice", "print_sequence", "spiral_mode"};
void Tab::Highlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
{
@ -2312,9 +2312,11 @@ void TabPrint::build()
page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only visible on placeholders
optgroup = page->new_optgroup(L("Skirt"), L"param_skirt");
optgroup->append_single_option_line("skirt_type");
optgroup->append_single_option_line("skirt_loops");
optgroup->append_single_option_line("min_skirt_length");
optgroup->append_single_option_line("skirt_distance");
optgroup->append_single_option_line("skirt_start_angle");
optgroup->append_single_option_line("skirt_height");
optgroup->append_single_option_line("skirt_speed");
optgroup->append_single_option_line("draft_shield");
@ -2783,6 +2785,7 @@ void TabPrintPlate::build()
auto page = add_options_page(L("Plate Settings"), "empty");
auto optgroup = page->new_optgroup("");
optgroup->append_single_option_line("curr_bed_type");
optgroup->append_single_option_line("skirt_start_angle");
optgroup->append_single_option_line("print_sequence");
optgroup->append_single_option_line("spiral_mode");
optgroup->append_single_option_line("first_layer_sequence_choice");
@ -2831,6 +2834,8 @@ void TabPrintPlate::on_value_change(const std::string& opt_key, const boost::any
auto plate = dynamic_cast<PartPlate*>(plate_item.first);
if (k == "curr_bed_type")
plate->reset_bed_type();
if (k == "skirt_start_angle")
plate->config()->erase("skirt_start_angle");
if (k == "print_sequence")
plate->set_print_seq(PrintSequence::ByDefault);
if (k == "first_layer_sequence_choice")
@ -2854,6 +2859,10 @@ void TabPrintPlate::on_value_change(const std::string& opt_key, const boost::any
bed_type = m_config->opt_enum<BedType>("curr_bed_type");
plate->set_bed_type(BedType(bed_type));
}
if (k == "skirt_start_angle") {
float angle = m_config->opt_float("skirt_start_angle");
plate->config()->set_key_value("skirt_start_angle", new ConfigOptionFloat(angle));
}
if (k == "print_sequence") {
print_seq = m_config->opt_enum<PrintSequence>("print_sequence");
plate->set_print_seq(print_seq);