diff --git a/CMakeLists.txt b/CMakeLists.txt index 094b1ff27..c0dc352a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -504,7 +504,7 @@ endif() if (WIN32) install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources") elseif (SLIC3R_FHS) - set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/slic3r++") + set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/SuperSlicer") install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${SLIC3R_FHS_RESOURCES}") else () install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources") diff --git a/resources/profiles/BIBO.idx b/resources/profiles/BIBO.idx index 1c26b7d36..6df0efcc8 100644 --- a/resources/profiles/BIBO.idx +++ b/resources/profiles/BIBO.idx @@ -1,4 +1,5 @@ min_slic3r_version = 2.2.0-alpha3 +0.0.4 superslicer: remove top_fan_speed 0.0.3 slic3r++ adaptation: overlapping & top pattern. 0.0.2 changed flow ratio from float to % 0.0.1 Multiple Print models were unified into a single one. diff --git a/resources/profiles/BIBO.ini b/resources/profiles/BIBO.ini index dca2b49de..50b658089 100644 --- a/resources/profiles/BIBO.ini +++ b/resources/profiles/BIBO.ini @@ -5,7 +5,7 @@ name = BIBO # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 0.0.3 +config_version = 0.0.4 # Where to get the updates from? config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/BIBO/ @@ -468,7 +468,6 @@ fan_always_on = 0 max_fan_speed = 0 min_fan_speed = 0 bridge_fan_speed = 25 -top_fan_speed = 0 temperature = 245 [filament:*FLEX*] diff --git a/resources/profiles/Basic.ini b/resources/profiles/Basic.ini index d86c76460..dcb379cd0 100644 --- a/resources/profiles/Basic.ini +++ b/resources/profiles/Basic.ini @@ -5,7 +5,7 @@ name = Custom # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the Slic3r configuration to be downgraded. -config_version = 0.1.1 +config_version = 0.1.2 # Where to get the updates from? config_update_url = @@ -694,5 +694,4 @@ fan_always_on = 0 max_fan_speed = 0 min_fan_speed = 0 bridge_fan_speed = 30 -top_fan_speed = 0 temperature = 240 \ No newline at end of file diff --git a/resources/profiles/Creality.idx b/resources/profiles/Creality.idx index 1465084ba..69bf1866b 100644 --- a/resources/profiles/Creality.idx +++ b/resources/profiles/Creality.idx @@ -1,4 +1,5 @@ min_slic3r_version = 2.2.0-alpha3 +0.2.5 superslicer: remove top_fan_speed 0.2.4 slic3r++ adaptation: overlapping & top pattern. 0.2.3 changed flow ratio from float to % 0.2.2 version diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini index 8c89f34f9..5e8c8f91a 100644 --- a/resources/profiles/Creality.ini +++ b/resources/profiles/Creality.ini @@ -5,7 +5,7 @@ name = Creality # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 0.2.4 +config_version = 0.2.5 # Where to get the updates from? config_update_url = @@ -690,5 +690,4 @@ fan_always_on = 0 max_fan_speed = 0 min_fan_speed = 0 bridge_fan_speed = 30 -top_fan_speed = 0 temperature = 245 diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index 1a89538dc..5169445a5 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,5 +1,5 @@ min_slic3r_version = 2.2.0-alpha3 -1.1.6 superslicer: thumbnails. +1.1.6 superslicer: thumbnails & remove top_fan_speed 1.1.5 slic3r++ adaptation: overlapping & top pattern. 1.1.4 changed flow ratio from float to % 1.1.3 slic3r++ version diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index daf2fce89..f9fba9b42 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -1980,7 +1980,7 @@ filament_colour = #FFF2EC first_layer_bed_temperature = 100 first_layer_temperature = 270 temperature = 270 -bridge_fan_speed = 0 +bridge_fan_speed = -1 filament_max_volumetric_speed = 8 [filament:PrimaSelect PVA+] @@ -2912,7 +2912,7 @@ filament_colour = #FFF2EC first_layer_bed_temperature = 100 first_layer_temperature = 270 temperature = 270 -bridge_fan_speed = 0 +bridge_fan_speed = -1 filament_cost = 77.3 filament_density = 1.20 diff --git a/resources/profiles/Voron.idx b/resources/profiles/Voron.idx index 6d6884c11..0b758c42a 100644 --- a/resources/profiles/Voron.idx +++ b/resources/profiles/Voron.idx @@ -1,3 +1,4 @@ min_slic3r_version = 2.2.0 +0.0.3 superslicer: remove top_fan_speed 0.0.2 Update from DocJeeves settings, adding afterburner / mobius difference 0.0.1 Initial version diff --git a/resources/profiles/Voron.ini b/resources/profiles/Voron.ini index 26389bf56..5abb61048 100644 --- a/resources/profiles/Voron.ini +++ b/resources/profiles/Voron.ini @@ -5,7 +5,7 @@ name = Voron # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 0.0.2 +config_version = 0.0.3 # Where to get the updates from? config_update_url = @@ -1037,7 +1037,6 @@ max_fan_speed = 0 min_fan_speed = 0 bridge_fan_speed = 30 slowdown_below_layer_time = 15 -top_fan_speed = 0 temperature = 250 [filament:Basic ABS @VORON] diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index ff4e8a775..66961f27a 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -238,6 +238,7 @@ group:Extrusion width setting:top_infill_extrusion_width setting:support_material_extrusion_width setting:skirt_extrusion_width + recommended_extrusion_width_description group:Overlap line:Perimeter overlap setting:label$External:external_perimeter_overlap diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index a2ac3db49..710008ca7 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -417,7 +417,7 @@ int CLI::run(int argc, char **argv) PrintBase *print = (printer_technology == ptFFF) ? static_cast(&fff_print) : static_cast(&sla_print); if (! m_config.opt_bool("dont_arrange")) { //FIXME make the min_object_distance configurable. - model.arrange_objects(fff_print); + model.arrange_objects(print); model.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ? BoundingBoxf(m_print_config.opt("bed_shape")->values).center() : m_config.option("center")->value); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f6f11b13c..07661246a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1191,6 +1191,51 @@ std::vector sort_object_instances_by_model_order(const Pri return instances; } +// set standby temp for extruders +// Parse the custom G-code, try to find T, and add it if not present +static void init_multiextruders(FILE *file, Print &print, GCodeWriter & writer, ToolOrdering &tool_ordering, const std::string &custom_gcode ) +{ + + //set standby temp for reprap + if (std::set{gcfRepRap}.count(print.config().gcode_flavor.value) > 0) { + for (uint16_t tool_id : tool_ordering.all_extruders()) { + fprintf(file, "G10 P%d R%d S%d ; sets the standby temperature\n", + tool_id, + int(print.config().filament_toolchange_temp.get_at(tool_id)), + int(print.config().temperature.get_at(tool_id))); + } + } + //activate first extruder is multi-extruder and not in start-gcode + if (writer.multiple_extruders) { + if (std::set{gcfRepRap}.count(print.config().gcode_flavor.value) > 0) { + //if not in gcode + bool find = false; + if (!custom_gcode.empty()) { + const char *ptr = custom_gcode.data(); + while (*ptr != 0) { + // Skip whitespaces. + for (; *ptr == ' ' || *ptr == '\t'; ++ptr); + if (*ptr == 'T') { + find = true; + break; + } else if (*ptr == 'A') { + //TODO: ACTIVATE_EXTRUDER for klipper (if used) + } + // Skip the rest of the line. + for (; *ptr != 0 && *ptr != '\r' && *ptr != '\n'; ++ptr); + // Skip the end of line indicators. + for (; *ptr == '\r' || *ptr == '\n'; ++ptr); + } + } + if (!find) { + fprintf(file, writer.toolchange(tool_ordering.first_extruder()).c_str()); + } + } + writer.toolchange(tool_ordering.first_extruder()); + } +} + + #if ENABLE_THUMBNAIL_GENERATOR void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thumbnail_cb) #else @@ -1437,6 +1482,10 @@ void GCode::_do_export(Print &print, FILE *file) std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id); // Set bed temperature if the start G-code does not contain any bed temp control G-codes. this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true); + + //init extruders + init_multiextruders(file, print, m_writer, tool_ordering, start_gcode); + // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index c1a47446f..236941e26 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -726,9 +726,17 @@ std::string CoolingBuffer::apply_layer_cooldown( top_fan_speed = EXTRUDER_CONFIG(top_fan_speed); ext_peri_fan_speed = EXTRUDER_CONFIG(external_perimeter_fan_speed); #undef EXTRUDER_CONFIG - bridge_fan_control = bridge_fan_speed > fan_speed_new && bridge_fan_speed != 0; - top_fan_control = top_fan_speed != fan_speed_new && top_fan_speed != 0; - ext_peri_fan_control = ext_peri_fan_speed != fan_speed_new && ext_peri_fan_speed != 0; + // 0 is deprecated for diable: take care of temp settings. + if (bridge_fan_speed == 0) bridge_fan_speed = -1; + if (ext_peri_fan_speed == 0) ext_peri_fan_speed = -1; + if (top_fan_speed == 0) top_fan_speed = -1; + if (bridge_fan_speed == 1) bridge_fan_speed = 0; + if (ext_peri_fan_speed == 1) ext_peri_fan_speed = 0; + if (top_fan_speed == 1) top_fan_speed = 0; + // end deprecation + bridge_fan_control = bridge_fan_speed > fan_speed_new && bridge_fan_speed >= 0; + top_fan_control = top_fan_speed != fan_speed_new && top_fan_speed >= 0; + ext_peri_fan_control = ext_peri_fan_speed != fan_speed_new && ext_peri_fan_speed >= 0; } else { bridge_fan_control = false; bridge_fan_speed = 0; diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 70a2b677d..7c3dd05cf 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -330,12 +330,13 @@ public: //add toolchange_temp -skinnydip WipeTowerWriter& wait_for_toolchange_temp(int tc_temp, bool fan_on, int fan_speed, bool fast) { - char all[128]; + //char all[128]; if (fan_on == true){ set_fan(fan_speed, " ;Part fan on to cool hotend"); } - sprintf(all, "M109 S%d ;SKINNYDIP TOOLCHANGE WAIT FOR TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); - this->append(all); + //sprintf(all, "M109 S%d ;SKINNYDIP TOOLCHANGE WAIT FOR TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); + //this->append(all); + set_extruder_temp(tc_temp, this->m_current_tool, true, ";SKINNYDIP TOOLCHANGE WAIT FOR TEMP " + fast ? "FAST MODE" : "NORMAL MODE"); if (fan_on == true){ set_fan(m_last_fan_speed, " ;restore cooling"); } @@ -345,25 +346,65 @@ public: //begin toolchange_temp -skinnydip WipeTowerWriter& begin_toolchange_temp(int tc_temp, bool fast) { - char tdbuf[128]; - sprintf(tdbuf, "M104 S%d ;SKINNYDIP BEGIN TOOLCHANGE TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); - m_gcode += tdbuf; - return *this; + //char tdbuf[128]; + //sprintf(tdbuf, "M104 S%d ;SKINNYDIP BEGIN TOOLCHANGE TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); + //m_gcode += tdbuf; + set_extruder_temp(tc_temp, this->m_current_tool, false, ";SKINNYDIP BEGIN TOOLCHANGE TEMP " + fast ? "FAST MODE" : "NORMAL MODE"); + return *this; } //restore toolchange_temp -skinnydip WipeTowerWriter& restore_pre_toolchange_temp(int tc_temp, bool fast) { - char tdbuf[128]; - sprintf(tdbuf, "M104 S%d ;RESTORE PRE-TOOLCHANGE TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); - m_gcode += tdbuf; - return *this; + //char tdbuf[128]; + //sprintf(tdbuf, "M104 S%d ;RESTORE PRE-TOOLCHANGE TEMP %s\n", tc_temp, fast ? "FAST MODE":"NORMAL MODE"); + //m_gcode += tdbuf; + set_extruder_temp(tc_temp, this->m_current_tool , false, ";RESTORE PRE-TOOLCHANGE TEMP " + fast ? "FAST MODE" : "NORMAL MODE"); + return *this; } // Set extruder temperature, don't wait by default. - WipeTowerWriter& set_extruder_temp(int temperature, bool wait = false) - { - m_gcode += "M" + std::to_string(wait ? 109 : 104) + " S" + std::to_string(temperature) + "\n"; + WipeTowerWriter& set_extruder_temp(unsigned int temperature, size_t tool, bool wait = false, std::string comment = "") + { + if (wait && (this->m_gcode_flavor == gcfMakerWare || this->m_gcode_flavor == (gcfSailfish))) + return *this; + + std::string code; + if (wait && this->m_gcode_flavor != (gcfTeacup) && this->m_gcode_flavor != (gcfRepRap) && this->m_gcode_flavor != (gcfSprinter)) { + code = "M109"; + } else { + if (this->m_gcode_flavor == (gcfRepRap)) { // M104 is deprecated on RepRapFirmware + code = "G10"; + } else { + code = "M104"; + } + } + + std::ostringstream gcode; + gcode << code << " "; + if (this->m_gcode_flavor == (gcfMach3) || this->m_gcode_flavor == (gcfMachinekit)) { + gcode << "P"; + } else if (this->m_gcode_flavor == (gcfRepRap)) { + gcode << "P" << tool << " S"; + } else { + gcode << "S"; + } + gcode << temperature; + bool multiple_tools = false; // ? + if (this->m_current_tool != -1 && (multiple_tools || this->m_gcode_flavor == (gcfMakerWare) || this->m_gcode_flavor == (gcfSailfish))) { + if (this->m_gcode_flavor != (gcfRepRap)) { + gcode << " T" << tool; + } + } + + if(!comment.empty()) + gcode << " ; " << comment << "\n"; + + if ((this->m_gcode_flavor == (gcfTeacup) || this->m_gcode_flavor == (gcfRepRap)) && wait) + gcode << "M116 ; wait for temperature to be reached\n"; + + gcode << "\n"; + m_gcode += gcode.str(); return *this; } @@ -685,7 +726,7 @@ std::vector WipeTower::prime( toolchange_Wipe(writer, cleaning_box , 20.f); box_coordinates box = cleaning_box; box.translate(0.f, writer.y() - cleaning_box.ld.y() + m_perimeter_width); - toolchange_Unload(writer, box , m_filpar[m_current_tool].material, m_filpar[tools[idx_tool + 1]].first_layer_temperature); + toolchange_Unload(writer, box , m_filpar[m_current_tool].material, m_filpar[tools[idx_tool + 1]].first_layer_temperature, idx_tool + 1); cleaning_box.translate(prime_section_width, 0.f); writer.travel(cleaning_box.ld, 7200); } @@ -793,14 +834,14 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool. if (tool != (unsigned int)-1){ // This is not the last change. toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, - m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature); + m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature, tool); toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials. toolchange_Load(writer, cleaning_box); writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road toolchange_Wipe(writer, cleaning_box, wipe_volume); // Wipe the newly loaded filament until the end of the assigned wipe area. ++ m_num_tool_changes; } else - toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, m_filpar[m_current_tool].temperature); + toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, m_filpar[m_current_tool].temperature, m_current_tool); m_depth_traversed += wipe_area; @@ -912,7 +953,8 @@ void WipeTower::toolchange_Unload( WipeTowerWriter &writer, const box_coordinates &cleaning_box, const std::string& current_material, - const int new_temperature) + const int new_temperature, + const size_t next_tool) { float xl = cleaning_box.ld.x() + 1.f * m_perimeter_width; float xr = cleaning_box.rd.x() - 1.f * m_perimeter_width; @@ -1039,7 +1081,7 @@ void WipeTower::toolchange_Unload( if (new_temperature != 0 && (new_temperature != m_old_temperature || m_is_first_layer)) { // Set the extruder temperature, but don't wait. // If the required temperature is the same as last time, don't emit the M104 again (if user adjusted the value, it would be reset) // However, always change temperatures on the first layer (this is to avoid issues with priming lines turned off). - writer.set_extruder_temp(new_temperature, false); + writer.set_extruder_temp(new_temperature, next_tool, false); m_old_temperature = new_temperature; } } diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 1cfea50e5..08d4c2c58 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -367,7 +367,8 @@ private: WipeTowerWriter &writer, const box_coordinates &cleaning_box, const std::string& current_material, - const int new_temperature); + const int new_temperature, + const size_t temp_tool); void toolchange_Change( WipeTowerWriter &writer, diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 3c2444b51..3ca9b62b2 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -111,15 +111,15 @@ std::string GCodeWriter::set_temperature(unsigned int temperature, bool wait, in gcode << code << " "; if (FLAVOR_IS(gcfMach3) || FLAVOR_IS(gcfMachinekit)) { gcode << "P"; + } else if (FLAVOR_IS(gcfRepRap)) { + gcode << "P" << tool << " S"; } else { gcode << "S"; } gcode << temperature; bool multiple_tools = this->multiple_extruders && ! m_single_extruder_multi_material; if (tool != -1 && (multiple_tools || FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)) ) { - if (FLAVOR_IS(gcfRepRap)) { - gcode << " P" << tool; - } else { + if (FLAVOR_IS_NOT(gcfRepRap)) { gcode << " T" << tool; } } @@ -227,7 +227,7 @@ std::string GCodeWriter::write_acceleration(){ if (FLAVOR_IS(gcfRepetier)) { // M201: Set max printing acceleration gcode << "M201 X" << m_current_acceleration << " Y" << m_current_acceleration; - } else if(FLAVOR_IS(gcfMarlin) || FLAVOR_IS(gcfLerdge)){ + } else if(FLAVOR_IS(gcfMarlin) || FLAVOR_IS(gcfLerdge) || FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfSprinter)){ // M204: Set printing acceleration gcode << "M204 P" << m_current_acceleration; } else { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 7a7eef86b..681c93aec 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -389,7 +389,7 @@ static bool _arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb /* arrange objects preserving their instance count but altering their instance positions */ -bool Model::arrange_objects(const Print &print, const BoundingBoxf* bb) +bool Model::arrange_objects(const PrintBase *print, const BoundingBoxf* bb) { size_t count = 0; for (auto obj : objects) count += obj->instances.size(); @@ -1823,7 +1823,7 @@ void ModelInstance::transform_polygon(Polygon* polygon) const polygon->scale(get_scaling_factor(X), get_scaling_factor(Y)); // scale around polygon origin } -arrangement::ArrangePolygon ModelInstance::get_arrange_polygon(const Print& print) const +arrangement::ArrangePolygon ModelInstance::get_arrange_polygon(const PrintBase *print_base) const { static const double SIMPLIFY_TOLERANCE_MM = 0.1; @@ -1841,13 +1841,17 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon(const Print& prin // https://github.com/prusa3d/PrusaSlicer/issues/2209 if (!p.points.empty()) { Polygons pp{p}; - //grow - double dist = print.config().min_object_distance(&print.full_print_config()); - std::cout << "min_object_distance = " << dist << "\n"; - pp = offset(pp, scale_(dist)); - //simplify - if (!pp.empty()) - pp = pp.front().simplify(scaled(SIMPLIFY_TOLERANCE_MM)); + if (const Print* print = dynamic_cast(print_base)) + { + //grow + double dist = print->config().min_object_distance(&print->full_print_config()); + std::cout << "min_object_distance = " << dist << "\n"; + pp = offset(pp, scale_(dist)); + //simplify + if (!pp.empty()) + pp = pp.front().simplify(scaled(SIMPLIFY_TOLERANCE_MM)); + }else + pp = p.simplify(scaled(SIMPLIFY_TOLERANCE_MM)); if (!pp.empty()) p = pp.front(); } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 52a5e94d2..92767b855 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -37,6 +37,7 @@ class ModelMaterial; class ModelObject; class ModelVolume; class ModelWipeTower; +class PrintBase; class Print; class SLAPrint; @@ -667,7 +668,7 @@ public: bool is_printable() const { return object->printable && printable && (print_volume_state == PVS_Inside); } // Getting the input polygon for arrange - arrangement::ArrangePolygon get_arrange_polygon(const Print& print) const; + arrangement::ArrangePolygon get_arrange_polygon(const PrintBase* print) const; // Apply the arrange result on the ModelInstance void apply_arrange_result(const Vec2crd& offs, double rotation) @@ -804,7 +805,7 @@ public: bool center_instances_around_point(const Vec2d &point); void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); } TriangleMesh mesh() const; - bool arrange_objects(const Print& print, const BoundingBoxf* bb = NULL); + bool arrange_objects(const PrintBase* print, const BoundingBoxf* bb = NULL); // Croaks if the duplicated objects do not fit the print bed. void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 311935ca9..df094a92c 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -900,13 +900,20 @@ void PerimeterGenerator::process() this->fill_surfaces->append(infill_exp, stPosInternal | stDensSparse); if (infill_peri_overlap != 0) { - ExPolygons polyWithoutOverlap = offset2_ex( - not_filled_exp, - -inset - infill_gap - min_perimeter_infill_spacing / 2, - (float) min_perimeter_infill_spacing / 2); + ExPolygons polyWithoutOverlap; + if (min_perimeter_infill_spacing / 2 > infill_peri_overlap) + polyWithoutOverlap = offset2_ex( + not_filled_exp, + -inset - infill_gap - min_perimeter_infill_spacing / 2 + infill_peri_overlap, + (float)min_perimeter_infill_spacing / 2 - infill_peri_overlap); + else + polyWithoutOverlap = offset_ex( + not_filled_exp, + -inset - infill_gap); if (!top_fills.empty()) { polyWithoutOverlap = union_ex(polyWithoutOverlap, top_infill_exp); - this->fill_no_overlap.insert(this->fill_no_overlap.end(), polyWithoutOverlap.begin(), polyWithoutOverlap.end()); + } + this->fill_no_overlap.insert(this->fill_no_overlap.end(), polyWithoutOverlap.begin(), polyWithoutOverlap.end()); /*{ std::stringstream stri; stri << this->layer->id() << "_2_end_makeperimeter_" << this->layer->id() << ".svg"; @@ -919,7 +926,6 @@ void PerimeterGenerator::process() svg.draw(to_polylines(top_infill_exp), "orange"); svg.Close(); }*/ - } } } // for each island } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5a4330033..bdc05ae78 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -270,9 +270,11 @@ void PrintConfigDef::init_fff_params() def->label = L("Bridges fan speed"); def->category = OptionCategory::cooling; def->tooltip = L("This fan speed is enforced during all bridges and overhangs. It won't slow down the fan if it's currently running at a higher speed." - "\nSet to 0 to disable this override. Can only be overriden by disable_fan_first_layers."); + "\nSet to 1 to disable the fan." + "\nSet to -1 to disable this override." + "\nCan only be overriden by disable_fan_first_layers."); def->sidetext = L("%"); - def->min = 0; + def->min = -1; def->max = 100; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts { 100 }); @@ -281,12 +283,14 @@ void PrintConfigDef::init_fff_params() def->label = L("Top fan speed"); def->category = OptionCategory::cooling; def->tooltip = L("This fan speed is enforced during all top fills." - "\nSet to 0 to disable this override. Can only be overriden by disable_fan_first_layers."); + "\nSet to 1 to disable the fan." + "\nSet to -1 to disable this override." + "\nCan only be overriden by disable_fan_first_layers."); def->sidetext = L("%"); - def->min = 0; + def->min = -1; def->max = 100; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionInts{ 0 }); + def->set_default_value(new ConfigOptionInts{ -1 }); def = this->add("bridge_flow_ratio", coPercent); def->label = L("Bridge"); @@ -764,14 +768,15 @@ void PrintConfigDef::init_fff_params() def = this->add("external_perimeter_fan_speed", coInts); def->label = L("External perimeter fan speed"); def->tooltip = L("When set to a non-zero value this fan speed is used only for external perimeters (visible ones). " - "When set to zero the normal fan speed is used on external perimeters. " + "\nSet to 1 to disable the fan." + "\nSet to -1 to use the normal fan speed on external perimeters." "External perimeters can benefit from higher fan speed to improve surface finish, " "while internal perimeters, infill, etc. benefit from lower fan speed to improve layer adhesion."); def->sidetext = L("%"); - def->min = 0; + def->min = -1; def->max = 100; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionInts { 0 }); + def->set_default_value(new ConfigOptionInts { -1 }); def = this->add("external_perimeter_overlap", coPercent); def->label = L("external perimeter overlap"); @@ -1293,7 +1298,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloats{ 1.75 }); def = this->add("filament_shrink", coPercents); - def->label = L("Shrikage"); + def->label = L("Shrinkage"); def->tooltip = L("Enter the shrinkage percentage that the filament will get after cooling (94% if you measure 94mm instead of 100mm)." " The part will be scaled in xy to conpensate." " Only the filament used for the perimeter is taken into account." @@ -1491,7 +1496,9 @@ void PrintConfigDef::init_fff_params() def->full_label = L("First layer flow ratio"); def->sidetext = L("%"); def->category = OptionCategory::width; - def->tooltip = L("You can increase this to over-extrude on the first layer if there are not enough plastic because your bed isn't levelled."); + def->tooltip = L("You can increase this to over-extrude on the first layer if there are not enough plastic because your bed isn't levelled." + "\nNote: DON'T USE THIS if your only problem is bed levelling, LEVEL YOUR BED!" + " Use this setting only as last resort after all calibrations failed."); def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionPercent(100)); @@ -4544,6 +4551,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va float v = boost::lexical_cast(value); if (v > 0) value = boost::lexical_cast(-v); + } else if (opt_key == "thumbnails") { + if (value.empty()) + value = "0x0,0x0"; } else if (opt_key == "z_steps_per_mm") { opt_key = "z_step"; float v = boost::lexical_cast(value); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 095d19224..645adb694 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -48,8 +48,19 @@ enum WipeAlgo { }; enum GCodeFlavor : uint8_t { - gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfKlipper, gcfSailfish, gcfMach3, gcfMachinekit, - gcfSmoothie, gcfSprinter, gcfNoExtrusion, gcfLerdge, + gcfRepRap, + gcfRepetier, + gcfTeacup, + gcfMakerWare, + gcfMarlin, + gcfKlipper, + gcfSailfish, + gcfMach3, + gcfMachinekit, + gcfSmoothie, + gcfSprinter, + gcfNoExtrusion, + gcfLerdge, }; enum PrintHostType { diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index f45984bd5..82eafcf3b 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -32,7 +32,7 @@ coordf_t check_z_step(const coordf_t val, const coordf_t z_step) { //return int((val + z_step * 0.5) / z_step) * z_step; } inline bool test_z_step(const coordf_t val, const coordf_t z_step) { - if (z_step <= EPSILON) return val; + if (z_step <= EPSILON) return true; uint64_t valint = uint64_t(val * 100000000. + 0.1); uint64_t stepint = uint64_t(z_step * 100000000. + 0.1); return valint % stepint == 0; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f5019d80c..e2a316454 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1522,7 +1522,7 @@ struct Plater::priv apply_wipe_tower(); } - ArrangePolygon get_arrange_polygon(const Print &print) const + ArrangePolygon get_arrange_polygon(const PrintBase *print) const { Polygon p({ {coord_t(0), coord_t(0)}, @@ -1627,7 +1627,8 @@ struct Plater::priv // Set up arrange polygon for a ModelInstance and Wipe tower template ArrangePolygon get_arrange_poly(T *obj) const { - ArrangePolygon ap = obj->get_arrange_polygon(this->plater().fff_print); + ArrangePolygon ap = obj->get_arrange_polygon( + this->plater().printer_technology == ptFFF ? (PrintBase*)&this->plater().fff_print : (PrintBase*)&this->plater().sla_print); ap.priority = 0; ap.bed_idx = ap.translation.x() / bed_stride(); ap.setter = [obj, this](const ArrangePolygon &p) { @@ -2888,7 +2889,8 @@ void Plater::priv::find_new_position(const ModelInstancePtrs &instances, for (const ModelObject *mo : model.objects) for (const ModelInstance *inst : mo->instances) { auto it = std::find(instances.begin(), instances.end(), inst); - auto arrpoly = inst->get_arrange_polygon(this->fff_print); + arrangement::ArrangePolygon arrpoly = inst->get_arrange_polygon( + this->printer_technology == ptFFF ? (PrintBase*)&this->fff_print : (PrintBase*)&this->sla_print); if (it == instances.end()) fixed.emplace_back(std::move(arrpoly)); @@ -2897,7 +2899,8 @@ void Plater::priv::find_new_position(const ModelInstancePtrs &instances, } if (updated_wipe_tower()) - fixed.emplace_back(wipetower.get_arrange_polygon(this->fff_print)); + fixed.emplace_back(wipetower.get_arrange_polygon( + this->printer_technology == ptFFF ? (PrintBase*)&this->fff_print : (PrintBase*)&this->sla_print)); arrangement::arrange(movable, fixed, min_d, get_bed_shape_hint()); @@ -4660,6 +4663,9 @@ const Print& Plater::fff_print() const { return p->fff_print; } Print& Plater::fff_print() { return p->fff_print; } const SLAPrint& Plater::sla_print() const { return p->sla_print; } SLAPrint& Plater::sla_print() { return p->sla_print; } +const PrintBase* Plater::current_print() const { + return printer_technology() == ptFFF ? (PrintBase*)&p->fff_print : (PrintBase*)&p->sla_print; +} void Plater::new_project() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 0837d88fe..41069546c 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -25,6 +25,7 @@ namespace Slic3r { class Model; class ModelObject; +class PrintBase; class Print; class SLAPrint; enum SLAPrintObjectStep : unsigned int; @@ -150,6 +151,7 @@ public: Print& fff_print(); const SLAPrint& sla_print() const; SLAPrint& sla_print(); + const PrintBase* current_print() const; void new_project(); void load_project(); diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index 9a3e8fee5..18bc228b3 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -29,19 +29,27 @@ std::string PresetHints::cooling_description(const Preset &preset) int max_speed_reduc = int(preset.config.opt_float("max_speed_reduction", 0)); int fan_below_layer_time = preset.config.opt_int("fan_below_layer_time", 0); + //for the time being, -1 shoudl eb for disabel, but it's 0 from legacy. + if (top_fan_speed == 0) top_fan_speed = -1; + if (bridge_fan_speed == 0) bridge_fan_speed = -1; + if (ext_peri_fan_speed == 0) ext_peri_fan_speed = -1; + if (top_fan_speed == 1) top_fan_speed = 0; + if (bridge_fan_speed == 1) bridge_fan_speed = 0; + if (ext_peri_fan_speed == 1) ext_peri_fan_speed = 0; + //if (preset.config.opt_bool("cooling", 0)) { out = _utf8(L("Fan")); if (preset.config.opt_bool("fan_always_on", 0)) { out += " " + (boost::format(_utf8(L("will run at %1%%% by default"))) % min_fan_speed).str() ; - if (ext_peri_fan_speed > 0 && ext_peri_fan_speed != min_fan_speed) { + if (ext_peri_fan_speed >= 0 && ext_peri_fan_speed != min_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over external perimeters"))) % ext_peri_fan_speed).str(); } - if (top_fan_speed > 0 && top_fan_speed != min_fan_speed) { + if (top_fan_speed >= 0 && top_fan_speed != min_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over top fill surfaces"))) % top_fan_speed).str(); } - if (bridge_fan_speed > 0 && bridge_fan_speed > min_fan_speed) { + if (bridge_fan_speed >= 0 && bridge_fan_speed > min_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over bridges"))) % bridge_fan_speed).str(); } if (disable_fan_first_layers > 1) @@ -66,7 +74,7 @@ std::string PresetHints::cooling_description(const Preset &preset) } else if (ext_peri_fan_speed > min_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over external perimeters"))) % ext_peri_fan_speed).str() + " " + L("if it's above the current computed fan speed value"); } - if (top_fan_speed > 0) { + if (top_fan_speed >= 0) { out += ", " + (boost::format(_utf8(L("at %1%%% over top fill surfaces"))) % top_fan_speed).str(); } if (bridge_fan_speed > max_fan_speed) { @@ -108,6 +116,17 @@ std::string PresetHints::cooling_description(const Preset &preset) % min_print_speed).str(); } + //tooltip for Depractaed values + bridge_fan_speed = preset.config.opt_int("bridge_fan_speed", 0); + ext_peri_fan_speed = preset.config.opt_int("external_perimeter_fan_speed", 0); + top_fan_speed = preset.config.opt_int("top_fan_speed", 0); + if (top_fan_speed == 0) + out += "\n\n!!! 0 for the Top fan speed is Deprecated, please set it to -1 to disable it !!!"; + if (ext_peri_fan_speed == 0) + out += "\n\n!!! 0 for the External perimeters fan speed is Deprecated, please set it to -1 to disable it !!!"; + if (bridge_fan_speed == 0) + out += "\n\n!!! 0 for the Bridge fan speed is Deprecated, please set it to -1 to disable it !!!"; + return out; } @@ -294,53 +313,81 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle return out; } -std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &preset_bundle) +std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& preset_bundle) { - const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config; - const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config; + const DynamicPrintConfig& print_config = preset_bundle.prints.get_edited_preset().config; + const DynamicPrintConfig& printer_config = preset_bundle.printers.get_edited_preset().config; + + float layer_height = float(print_config.opt_float("layer_height")); + int num_perimeters = print_config.opt_int("perimeters"); + bool thin_walls = print_config.opt_bool("thin_walls"); + float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0)); - float layer_height = float(print_config.opt_float("layer_height")); - int num_perimeters = print_config.opt_int("perimeters"); - bool thin_walls = print_config.opt_bool("thin_walls"); - float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0)); - std::string out; - if (layer_height <= 0.f) { - out += _utf8(L("Recommended object min thin wall thickness: Not available due to invalid layer height.")); - return out; - } + if (layer_height <= 0.f) { + out += _utf8(L("Recommended object min thin wall thickness: Not available due to invalid layer height.")); + return out; + } - Flow external_perimeter_flow = Flow::new_from_config_width( - frExternalPerimeter, - *print_config.opt("external_perimeter_extrusion_width"), + Flow external_perimeter_flow = Flow::new_from_config_width( + frExternalPerimeter, + *print_config.opt("external_perimeter_extrusion_width"), nozzle_diameter, layer_height, false); - Flow perimeter_flow = Flow::new_from_config_width( - frPerimeter, - *print_config.opt("perimeter_extrusion_width"), + Flow perimeter_flow = Flow::new_from_config_width( + frPerimeter, + *print_config.opt("perimeter_extrusion_width"), nozzle_diameter, layer_height, false); //set spacing external_perimeter_flow.spacing_ratio = print_config.opt("external_perimeter_overlap")->get_abs_value(1); perimeter_flow.spacing_ratio = print_config.opt("perimeter_overlap")->get_abs_value(1); - + if (num_perimeters > 0) { int num_lines = std::min(num_perimeters, 6); out += (boost::format(_utf8(L("Recommended object min (thick) wall thickness for layer height %.2f and"))) % layer_height).str() + " "; out += (boost::format(_utf8(L("%d perimeter: %.2f mm"))) % 1 % (external_perimeter_flow.width + external_perimeter_flow.spacing())).str() + " "; // Start with the width of two closely spaced try { - double width = 2*(external_perimeter_flow.width + external_perimeter_flow.spacing(perimeter_flow)); - for (int i = 2; i <= num_lines; thin_walls ? ++ i : i ++) { - out += ", " + (boost::format(_utf8(L("%d perimeter: %.2f mm"))) % i % width).str() + " "; + double width = 2 * (external_perimeter_flow.width + external_perimeter_flow.spacing(perimeter_flow)); + for (int i = 2; i <= num_lines; thin_walls ? ++i : i++) { + out += ", " + (boost::format(_utf8(L("%d perimeter: %.2f mm"))) % i % width).str() + " "; width += perimeter_flow.spacing() * 2; } - } catch (const FlowErrorNegativeSpacing &) { + } + catch (const FlowErrorNegativeSpacing&) { out = _utf8(L("Recommended object thin wall thickness: Not available due to excessively small extrusion width.")); } } return out; } +std::string PresetHints::recommended_extrusion_width(const PresetBundle& preset_bundle) +{ + const DynamicPrintConfig& print_config = preset_bundle.prints.get_edited_preset().config; + const DynamicPrintConfig& printer_config = preset_bundle.printers.get_edited_preset().config; + + int nb_nozzles = printer_config.option("nozzle_diameter")->values.size(); + + double nozzle_diameter = 0; + for(int i=0; i< nb_nozzles; i++) + nozzle_diameter = std::max(nozzle_diameter, printer_config.opt_float("nozzle_diameter", i)); + double layer_height = print_config.opt_float("layer_height"); + double first_layer_height = print_config.option("first_layer_height")->get_abs_value(nozzle_diameter); + + std::string out; + + Flow first_layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, first_layer_height, false); + Flow layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, layer_height, false); + + out += _utf8(L("Ideally, the spacing between two extrusions shouldn't be lower than the nozzle diameter. Below are the extrusion widths for a spacing equal to the nozzle diameter.\n")); + out += (boost::format(_utf8(L("Recommended min extrusion width for the first layer (with a first layer height of %1%) is %2$.3f mm (or %3%%%)\n"))) + % first_layer_height % first_layer_flow.width % int(first_layer_flow.width * 100. / nozzle_diameter)).str(); + out += (boost::format(_utf8(L("Recommended min extrusion width for other layers (with a layer height of %1%) is %2$.3f mm (or %3%%%).\n"))) + % layer_height % layer_flow.width % int(layer_flow.width * 100. / nozzle_diameter)).str(); + + return out; +} + // Produce a textual explanation of the combined effects of the top/bottom_solid_layers // versus top/bottom_min_shell_thickness. Which of the two values wins depends diff --git a/src/slic3r/GUI/PresetHints.hpp b/src/slic3r/GUI/PresetHints.hpp index be049c2c8..64152a720 100644 --- a/src/slic3r/GUI/PresetHints.hpp +++ b/src/slic3r/GUI/PresetHints.hpp @@ -22,12 +22,16 @@ public: // Produce a textual description of a recommended thin wall thickness // from the provided number of perimeters and the external / internal perimeter width. - static std::string recommended_thin_wall_thickness(const PresetBundle &preset_bundle); + static std::string recommended_thin_wall_thickness(const PresetBundle& preset_bundle); + + // Produce a textual description of a recommended extrusion width + // from the provided layer height + static std::string recommended_extrusion_width(const PresetBundle& preset_bundle); // Produce a textual explanation of the combined effects of the top/bottom_solid_layers // versus top/bottom_min_shell_thickness. Which of the two values wins depends // on the active layer height. - static std::string top_bottom_shell_thickness_explanation(const PresetBundle &preset_bundle); + static std::string top_bottom_shell_thickness_explanation(const PresetBundle& preset_bundle); }; } // namespace Slic3r diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e6625effa..146ae66ce 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1313,13 +1313,7 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page) TabPrinter* tab = nullptr; if ((tab = dynamic_cast(this)) == nullptr) continue; current_group->m_on_change = set_or_add(current_group->m_on_change, [this, tab](t_config_option_key opt_key, boost::any value) { - if (opt_key == "silent_mode") { - bool val = boost::any_cast(value); - if (tab->m_use_silent_mode != val) { - tab->m_rebuild_kinematics_page = true; - tab->m_use_silent_mode = val; - } - } + tab->update_fff(); //check for kinematic rebuild tab->build_unregular_pages(); }); } @@ -1499,6 +1493,16 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page) }; current_group->append_line(current_line); } + else if (boost::starts_with(full_line, "recommended_extrusion_width_description")) { + TabPrint* tab = nullptr; + if ((tab = dynamic_cast(this)) == nullptr) continue; + current_line = { "", "" }; + current_line.full_width = 1; + current_line.widget = [this, tab](wxWindow* parent) { + return description_line_widget(parent, &(tab->m_recommended_extrusion_width_description_line)); + }; + current_group->append_line(current_line); + } else if (boost::starts_with(full_line, "top_bottom_shell_thickness_explanation")) { TabPrint* tab = nullptr; if ((tab = dynamic_cast(this)) == nullptr) continue; @@ -1706,6 +1710,9 @@ void TabPrint::update() if (m_recommended_thin_wall_thickness_description_line) m_recommended_thin_wall_thickness_description_line->SetText( from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); + if (m_recommended_extrusion_width_description_line) + m_recommended_extrusion_width_description_line->SetText( + from_u8(PresetHints::recommended_extrusion_width(*m_preset_bundle))); if(m_top_bottom_shell_thickness_explanation) m_top_bottom_shell_thickness_explanation->SetText( from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle))); @@ -1731,6 +1738,9 @@ void TabPrint::OnActivate() if (m_recommended_thin_wall_thickness_description_line) m_recommended_thin_wall_thickness_description_line->SetText( from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); + if (m_recommended_extrusion_width_description_line) + m_recommended_extrusion_width_description_line->SetText( + from_u8(PresetHints::recommended_extrusion_width(*m_preset_bundle))); if(m_top_bottom_shell_thickness_explanation) m_top_bottom_shell_thickness_explanation->SetText( from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle))); @@ -2150,14 +2160,18 @@ void TabPrinter::milling_count_changed(size_t milling_count) //} } -void TabPrinter::append_option_line_kinematics(ConfigOptionsGroupShp optgroup, const std::string opt_key) +void TabPrinter::append_option_line_kinematics(ConfigOptionsGroupShp optgroup, const std::string opt_key, const std::string override_sidetext) { Option option = optgroup->get_option(opt_key, 0); + if (!override_sidetext.empty()) + option.opt.sidetext = override_sidetext; Line line = Line{ _(option.opt.full_label), "" }; option.opt.width = 10; line.append_option(option); if (m_use_silent_mode) { option = optgroup->get_option(opt_key, 1); + if (!override_sidetext.empty()) + option.opt.sidetext = override_sidetext; option.opt.width = 10; line.append_option(option); } @@ -2169,7 +2183,7 @@ PageShp TabPrinter::build_kinematics_page() auto page = add_options_page(_(L("Machine limits")), "cog", true); ConfigOptionsGroupShp optgroup; if (m_config->option>("gcode_flavor")->value != gcfMarlin && m_config->option>("gcode_flavor")->value != gcfLerdge) { - optgroup = page->new_optgroup(_(L("not-marlin/lerdge firmware compensation"))); + optgroup = page->new_optgroup(_(L("not-marlin/lerdge firmware compensation"))); optgroup->append_single_option_line("time_estimation_compensation"); } optgroup = page->new_optgroup(_(L("Machine Limits"))); @@ -2214,27 +2228,34 @@ PageShp TabPrinter::build_kinematics_page() std::vector axes{ "x", "y", "z", "e" }; optgroup = page->new_optgroup(_(L("Maximum feedrates"))); - for (const std::string &axis : axes) { + for (const std::string& axis : axes) { + if (m_config->option>("gcode_flavor")->value == gcfRepRap) + append_option_line_kinematics(optgroup, "machine_max_feedrate_" + axis, "mm/min"); + else append_option_line_kinematics(optgroup, "machine_max_feedrate_" + axis); - } + } optgroup = page->new_optgroup(_(L("Maximum accelerations"))); - for (const std::string &axis : axes) { - append_option_line_kinematics(optgroup, "machine_max_acceleration_" + axis); - } - append_option_line_kinematics(optgroup, "machine_max_acceleration_extruding"); - append_option_line_kinematics(optgroup, "machine_max_acceleration_retracting"); - append_option_line_kinematics(optgroup, "machine_max_acceleration_travel"); + for (const std::string& axis : axes) { + append_option_line_kinematics(optgroup, "machine_max_acceleration_" + axis); + } + append_option_line_kinematics(optgroup, "machine_max_acceleration_extruding"); + append_option_line_kinematics(optgroup, "machine_max_acceleration_retracting"); + append_option_line_kinematics(optgroup, "machine_max_acceleration_travel"); optgroup = page->new_optgroup(_(L("Jerk limits"))); - for (const std::string &axis : axes) { - append_option_line_kinematics(optgroup, "machine_max_jerk_" + axis); - } + for (const std::string& axis : axes) { + append_option_line_kinematics(optgroup, "machine_max_jerk_" + axis); + } optgroup = page->new_optgroup(_(L("Minimum feedrates"))); - append_option_line_kinematics(optgroup, "machine_min_extruding_rate"); - append_option_line_kinematics(optgroup, "machine_min_travel_rate"); - + if (m_config->option>("gcode_flavor")->value == gcfRepRap){ + append_option_line_kinematics(optgroup, "machine_min_extruding_rate", "mm/min"); + append_option_line_kinematics(optgroup, "machine_min_travel_rate", "mm/min"); + } else { + append_option_line_kinematics(optgroup, "machine_min_extruding_rate"); + append_option_line_kinematics(optgroup, "machine_min_travel_rate"); + } return page; } @@ -2491,8 +2512,8 @@ void TabPrinter::update_fff() else GCodeWriter::PausePrintCode = "M601"; - if (m_is_marlin != is_marlin_flavor) { - m_is_marlin = is_marlin_flavor; + if (m_last_gcode_flavor != uint8_t(m_config->option>("gcode_flavor")->value)) { + m_last_gcode_flavor = uint8_t(m_config->option>("gcode_flavor")->value); m_rebuild_kinematics_page = true; } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index c0b1bdd98..1122fbdfb 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -336,8 +336,9 @@ public: // Tab(parent, _(L("Print Settings")), L("print")) {} Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_PRINT) {} ~TabPrint() {} - + ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr; + ogStaticText* m_recommended_extrusion_width_description_line = nullptr; ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr; bool m_support_material_overhangs_queried = false; @@ -383,9 +384,9 @@ public: void build_printhost(ConfigOptionsGroup *optgroup); bool m_has_single_extruder_MM_page = false; - bool m_is_marlin = false; + uint8_t m_last_gcode_flavor = uint8_t(255); bool m_use_silent_mode = false; - void append_option_line_kinematics(ConfigOptionsGroupShp optgroup, const std::string opt_key); + void append_option_line_kinematics(ConfigOptionsGroupShp optgroup, const std::string opt_key, const std::string override_units = ""); bool m_rebuild_kinematics_page = false; wxButton* m_serial_test_btn = nullptr; diff --git a/tests/fff_print/test_data.cpp b/tests/fff_print/test_data.cpp index efc4579f4..3330cb09a 100644 --- a/tests/fff_print/test_data.cpp +++ b/tests/fff_print/test_data.cpp @@ -174,7 +174,7 @@ void init_print(std::vector &&meshes, Slic3r::Print &print, Slic3r } print.apply(model, config); - model.arrange_objects(print); + model.arrange_objects(&print); print.apply(model, config); print.validate(); print.set_status_silent(); diff --git a/tests/fff_print/test_model.cpp b/tests/fff_print/test_model.cpp index 71fbd1699..1b29b4b1e 100644 --- a/tests/fff_print/test_model.cpp +++ b/tests/fff_print/test_model.cpp @@ -42,7 +42,7 @@ SCENARIO("Model construction", "[Model]") { } model_object->add_instance(); print.apply(model, config); // apply config for arrange_objects - model.arrange_objects(print); + model.arrange_objects(&print); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); model_object->ensure_on_bed(); print.auto_assign_extruders(model_object); diff --git a/tests/superslicerlibslic3r/test_complete_objects.cpp b/tests/superslicerlibslic3r/test_complete_objects.cpp index 28ba64a28..485e6170f 100644 --- a/tests/superslicerlibslic3r/test_complete_objects.cpp +++ b/tests/superslicerlibslic3r/test_complete_objects.cpp @@ -37,7 +37,7 @@ std::unique_ptr init_print_with_dist(DynamicPrintConfig &config, float di if (distance <= 0) { print->apply(model, config); - model.arrange_objects(*print);// print->config().min_object_distance(&print->config(), 999999)); + model.arrange_objects(&*print);// print->config().min_object_distance(&print->config(), 999999)); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); } diff --git a/tests/superslicerlibslic3r/test_data.cpp b/tests/superslicerlibslic3r/test_data.cpp index c697fb76e..9553882c1 100644 --- a/tests/superslicerlibslic3r/test_data.cpp +++ b/tests/superslicerlibslic3r/test_data.cpp @@ -287,7 +287,7 @@ void init_print(Print& print, std::initializer_list meshes, Slic3r::Mo } print.apply(model, config); // apply config for the arrange_objects - model.arrange_objects(print); + model.arrange_objects(&print); model.center_instances_around_point(Slic3r::Vec2d(100,100)); for (auto* mo : model.objects) { print.auto_assign_extruders(mo); @@ -323,7 +323,7 @@ void init_print(Print& print, std::vector meshes, Slic3r::Model& m } print.apply(model, config); // apply config for the arrange_objects - model.arrange_objects(print); + model.arrange_objects(&print); model.center_instances_around_point(Slic3r::Vec2d(100,100)); print.apply(model, config); for (ModelObject* mo : model.objects) {