diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index b6618e75d9b..1ca8570763e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4490,8 +4490,7 @@ LayerResult GCode::process_layer( break; } case CalibMode::Calib_Temp_Tower: { - auto offset = static_cast(print_z / 10.001) * 5; - gcode += writer().set_temperature(print.calib_params().start - offset); + gcode += writer().set_temperature(this->interpolate_value_across_layers(static_cast(print.calib_params().start), static_cast(print.calib_params().end), 5.0f)); break; } case CalibMode::Calib_VFA_Tower: { @@ -7066,14 +7065,29 @@ std::string GCode::extrusion_role_to_string_for_parser(const ExtrusionRole & rol } } -// Calculate the interpolated value for the current layer between start_value and end_value -float GCode::interpolate_value_across_layers(float start_value, float end_value) const { - if (m_layer_index == 1) { +// Calculate the interpolated value for the current layer between start_value and end_value. +// Step will create equal layers steps from first to last value. +// Step = 0 means gradual interpolation finishing at last value. +float GCode::interpolate_value_across_layers(float start_value, float end_value, float step) const +{ + if (m_layer_index <= 1) { return start_value; - } else { - float ratio = (m_layer_index - 2.0f) / (m_layer_count - 3.0f); - ratio = std::max(0.0f, std::min(1.0f, ratio)); // clamp - return start_value + ratio * (end_value - start_value); + } + else { + bool use_steps = step > 0.f; + if (use_steps) { + if (start_value > end_value) { + start_value += step; + } else { + end_value += step; + } + } + float ratio = m_layer_index / (m_layer_count - 1.f); + float value = start_value + ratio * (end_value - start_value); + if (use_steps) { + value = trunc(value / step) * step; + } + return value; } } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index d379300bad1..1971415286e 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -237,8 +237,10 @@ public: bool enable_cooling_markers() const { return m_enable_cooling_markers; } std::string extrusion_role_to_string_for_parser(const ExtrusionRole &); - // Calculate the interpolated value for the current layer between start_value and end_value - float interpolate_value_across_layers(float start_value, float end_value) const; + // Calculate the interpolated value for the current layer between start_value and end_value. + // Step will create equal layers steps from first to last value. + // Step = 0 means gradual interpolation finishing at last value. + float interpolate_value_across_layers(float start_value, float end_value, float step = 0.0f) const; // For Perl bindings, to be used exclusively by unit tests. unsigned int layer_count() const { return m_layer_count; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 532540fa72d..4f6406d9b47 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12423,6 +12423,7 @@ void Plater::calib_pa(const Calib_Params& params) auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; print_config->set_key_value("overhang_reverse", new ConfigOptionBool(false)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false}); switch (params.mode) { case CalibMode::Calib_PA_Line: @@ -12931,6 +12932,10 @@ void Plater::calib_flowrate(bool is_linear, int pass, InfillPattern pattern) { void Plater::calib_temp(const Calib_Params& params) { + constexpr double base_temp_tower_nozzle_diameter = 0.4; + constexpr double base_temp_tower_block_height = 10.0; + constexpr int base_temp_tower_temp_step = 5; + const auto calib_temp_name = wxString::Format(L"Nozzle temperature test"); new_project(false, false, calib_temp_name); wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); @@ -12941,18 +12946,61 @@ void Plater::calib_temp(const Calib_Params& params) { auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; auto start_temp = lround(params.start); + const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); + size_t nozzle_id = static_cast(std::max(params.extruder_id, 0)); + double nozzle_diameter = base_temp_tower_nozzle_diameter; + if (nozzle_diameter_config && !nozzle_diameter_config->values.empty()) { + nozzle_id = std::min(nozzle_id, nozzle_diameter_config->values.size() - 1); + nozzle_diameter = nozzle_diameter_config->values[nozzle_id]; + } + if (nozzle_diameter <= 0.0) + nozzle_diameter = base_temp_tower_nozzle_diameter; + + const double nozzle_scale = nozzle_diameter / base_temp_tower_nozzle_diameter; + const double block_height = base_temp_tower_block_height; + + // cut upper + auto obj_bb = model().objects[0]->bounding_box_exact(); + auto block_count = lround((500 - params.end) / base_temp_tower_temp_step + 1); + if (block_count > 0) { + // subtract EPSILON offset to avoid cutting at the exact location where the flat surface is + auto new_height = block_count * block_height - EPSILON; + if (new_height < obj_bb.size().z()) { + cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepLower); + } + } + + // cut bottom + obj_bb = model().objects[0]->bounding_box_exact(); + block_count = lround((500 - params.start) / base_temp_tower_temp_step); + if (block_count > 0) { + auto new_height = block_count * block_height + EPSILON; + if (new_height < obj_bb.size().z()) { + cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepUpper); + } + } + + if (std::abs(nozzle_scale - 1.0) > EPSILON) + model().objects[0]->scale(nozzle_scale, nozzle_scale, nozzle_scale); + + model().objects[0]->ensure_on_bed(); + printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false}); filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1,(int)start_temp)); filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1,(int)start_temp)); + model().objects[0]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter/2)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(5.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); model().objects[0]->config.set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); model().objects[0]->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); model().objects[0]->config.set_key_value("overhang_reverse", new ConfigOptionBool(false)); + model().objects[0]->config.set_key_value("precise_z_height", new ConfigOptionBool(false)); auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false)); + print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(nozzle_diameter/2)); + changed_objects({ 0 }); wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); @@ -12960,27 +13008,6 @@ void Plater::calib_temp(const Calib_Params& params) { wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); - // cut upper - auto obj_bb = model().objects[0]->bounding_box_exact(); - auto block_count = lround((500 - params.end) / 5 + 1); - if(block_count > 0){ - // subtract EPSILON offset to avoid cutting at the exact location where the flat surface is - auto new_height = block_count * 10.0 - EPSILON; - if (new_height < obj_bb.size().z()) { - cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepLower); - } - } - - // cut bottom - obj_bb = model().objects[0]->bounding_box_exact(); - block_count = lround((500 - params.start) / 5); - if(block_count > 0){ - auto new_height = block_count * 10.0 + EPSILON; - if (new_height < obj_bb.size().z()) { - cut_horizontal(0, 0, new_height, ModelObjectCutAttribute::KeepUpper); - } - } - p->background_process.fff_print()->set_calib_params(params); } @@ -13029,6 +13056,7 @@ void Plater::calib_max_vol_speed(const Calib_Params& params) obj_cfg.set_key_value("brim_type", new ConfigOptionEnum(btOuterAndInner)); obj_cfg.set_key_value("brim_width", new ConfigOptionFloat(5.0)); obj_cfg.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); + obj_cfg.set_key_value("precise_z_height", new ConfigOptionBool(false)); print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); print_config->set_key_value("spiral_mode", new ConfigOptionBool(true)); print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); @@ -13101,6 +13129,7 @@ void Plater::calib_retraction(const Calib_Params& params) obj->config.set_key_value("seam_position", new ConfigOptionEnum(spAligned)); obj->config.set_key_value("wall_sequence", new ConfigOptionEnum(WallSequence::InnerOuter)); obj->config.set_key_value("overhang_reverse", new ConfigOptionBool(false)); + obj->config.set_key_value("precise_z_height", new ConfigOptionBool(false)); changed_objects({ 0 }); @@ -13139,6 +13168,7 @@ void Plater::calib_VFA(const Calib_Params& params) print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false)); print_config->set_key_value("spiral_mode", new ConfigOptionBool(true)); print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); @@ -13206,6 +13236,7 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(20000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(20000)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); @@ -13266,6 +13297,7 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(20000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(20000)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0)); @@ -13328,6 +13360,7 @@ void Plater::Calib_Cornering(const Calib_Params& params) print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(200)); print_config->set_key_value("default_acceleration", new ConfigOptionFloat(2000)); print_config->set_key_value("outer_wall_acceleration", new ConfigOptionFloat(2000)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum(btOuterOnly)); model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0)); model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));