From 17ce5fa95506dce41dc1d9d46c85f43fc7025a4d Mon Sep 17 00:00:00 2001 From: Thomas Scheiblauer Date: Mon, 9 Dec 2024 13:33:50 +0100 Subject: [PATCH] fix FanMover ... and thus "fan speed-up time" and "fan kick-start time" Squashed commit of the following: commit 822c91b49cb718ac9bd42ff512e875f95b84d47f Author: Thomas Scheiblauer Date: Sat Dec 7 19:19:31 2024 +0100 remove "only overhangs" option from FanMover ... which could never have worked in OrcaSlicer anyway because the required overhang markers are not written into the gcode. Its use is questionable anyway because compensating for a fan delay makes sense everywhere the fan is used. commit 37f22971d36a384480861a31e3a12ca7274d9be7 Author: Thomas Scheiblauer Date: Sat Dec 7 18:48:36 2024 +0100 fix issue with FanMover modifying filament change g-code which resulted in poop chute fill ups commit 6946218564d7aad3b6f90ad9298683abefd20c11 Author: Thomas Scheiblauer Date: Fri Dec 6 21:11:51 2024 +0100 fix danglin-else warning commit 01144df3cef845a927990566dc2efe011649cccf Author: supermerill Date: Tue Feb 13 19:21:56 2024 +0100 Fix fan mover kickstart supermerill/SuperSlicer#4113 commit 14506d7f8e077786298031e5fa3e7eacbd102591 Author: supermerill Date: Mon Jan 29 19:54:49 2024 +0100 Fix fan_mover/gcodeprocessor with G2/G3 supermerill/SuperSlicer#4061 --- src/libslic3r/GCode.cpp | 133 ++++++++------- src/libslic3r/GCode/FanMover.cpp | 283 +++++++++++++++++-------------- src/libslic3r/GCode/FanMover.hpp | 31 +++- src/libslic3r/Preset.cpp | 10 +- src/libslic3r/Print.cpp | 27 ++- src/libslic3r/PrintConfig.cpp | 122 +++++++------ src/libslic3r/PrintConfig.hpp | 13 +- src/slic3r/GUI/Tab.cpp | 61 ++++--- 8 files changed, 357 insertions(+), 323 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f6c11632aa8..b7a6ef46612 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -294,7 +294,7 @@ static std::vector get_path_of_change_filament(const Print& print) ? gcodegen.config().nozzle_temperature_initial_layer.get_at(gcodegen.writer().extruder()->id()) : gcodegen.config().nozzle_temperature.get_at(gcodegen.writer().extruder()->id()); } - + // Orca: // Function to calculate the excess retraction length that should be retracted either before or after wiping // in order for the wipe operation to respect the filament retraction speed @@ -304,26 +304,26 @@ static std::vector get_path_of_change_filament(const Print& print) auto extruder = writer.extruder(); auto extruder_id = extruder->id(); auto last_pos = gcodegen.last_pos(); - + // Declare & initialize retraction lengths double retraction_length_remaining = 0, retractionBeforeWipe = 0, retractionDuringWipe = 0; - + // initialise the remaining retraction amount with the full retraction amount. retraction_length_remaining = toolchange ? extruder->retract_length_toolchange() : extruder->retraction_length(); - + // nothing to retract - return early if(retraction_length_remaining <=EPSILON) return {0.f,0.f}; - + // calculate retraction before wipe distance from the user setting. Keep adding to this variable any excess retraction needed // to be performed before the wipe. retractionBeforeWipe = retraction_length_remaining * extruder->retract_before_wipe(); retraction_length_remaining -= retractionBeforeWipe; // subtract it from the remaining retraction length - + // all of the retraction is to be done before the wipe if(retraction_length_remaining <=EPSILON) return {retractionBeforeWipe,0.f}; - + // Calculate wipe speed double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed"); wipe_speed = std::max(wipe_speed, 10.0); @@ -338,11 +338,11 @@ static std::vector get_path_of_change_filament(const Print& print) retractionDuringWipe = config.retraction_speed.get_at(extruder_id) * unscale_(wipe_path_length) / wipe_speed; // If the maximum retraction amount during wipe is too small, return 0 and retract everything prior to the wipe. if(retractionDuringWipe <= EPSILON) return {retractionBeforeWipe,0.f}; - + // If the maximum retraction amount during wipe is greater than any remaining retraction length // return the remaining retraction length to be retracted during the wipe if (retractionDuringWipe - retraction_length_remaining > EPSILON) return {retractionBeforeWipe,retraction_length_remaining}; - + // We will always proceed with incrementing the retraction amount before wiping with the difference // and return the maximum allowed wipe amount to be retracted during the wipe move retractionBeforeWipe += retraction_length_remaining - retractionDuringWipe; @@ -370,7 +370,7 @@ static std::vector get_path_of_change_filament(const Print& print) for the time needed to consume retraction_length at retraction_speed? */ // BBS double wipe_dist = scale_(gcodegen.config().wipe_distance.get_at(gcodegen.writer().extruder()->id())); - + /* Take the stored wipe path and replace first point with the current actual position (they might be different, for example, in case of loop clipping). */ Polyline wipe_path; @@ -506,10 +506,14 @@ static std::vector get_path_of_change_filament(const Print& print) // 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 toolchange_gcode_str; - const std::string &change_filament_gcode = gcodegen.config().change_filament_gcode.value; + std::string toolchange_gcode_str; + std::string change_filament_gcode = gcodegen.config().change_filament_gcode.value; // m_max_layer_z = std::max(m_max_layer_z, tcr.print_z); if (!change_filament_gcode.empty()) { + check_add_eol(change_filament_gcode); + // mark change_filament_gcode as custom gcode to protect it from fan_mover + change_filament_gcode = FanMover::custom_gcode_start_marker + '\n' + change_filament_gcode + FanMover::custom_gcode_end_marker + '\n'; + DynamicConfig config; int previous_extruder_id = gcodegen.writer().extruder() ? (int) gcodegen.writer().extruder()->id() : -1; config.set_key_value("previous_extruder", new ConfigOptionInt(previous_extruder_id)); @@ -1531,12 +1535,12 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu bool activate_long_retraction_when_cut = false; for (const auto& extruder : m_writer.extruders()) activate_long_retraction_when_cut |= ( - m_config.long_retractions_when_cut.get_at(extruder.id()) + m_config.long_retractions_when_cut.get_at(extruder.id()) && m_config.retraction_distances_when_cut.get_at(extruder.id()) > 0 ); m_processor.result().long_retraction_when_cut = activate_long_retraction_when_cut; - + { //BBS:check bed and filament compatible const ConfigOptionDef *bed_type_def = print_config_def.get("curr_bed_type"); assert(bed_type_def != nullptr); @@ -1581,7 +1585,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu BOOST_LOG_TRIVIAL(info) << "Exporting G-code finished" << log_memory_info(); print->set_done(psGCodeExport); - + if(is_BBL_Printer()) result->label_object_enabled = m_enable_exclude_object; @@ -1831,7 +1835,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING m_fan_mover.release(); - + m_writer.set_is_bbl_machine(is_bbl_printers); // How many times will be change_layer() called? @@ -1897,14 +1901,14 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato if (!print.config().small_area_infill_flow_compensation_model.empty()) m_small_area_infill_flow_compensator = make_unique(print.config()); - + // Orca: Don't output Header block if BTT thumbnail is identified in the list // Get the thumbnails value as a string std::string thumbnails_value = print.config().option("thumbnails")->value; // search string for the BTT_TFT label bool has_BTT_thumbnail = (thumbnails_value.find("BTT_TFT") != std::string::npos); - - if(!has_BTT_thumbnail){ + + if(!has_BTT_thumbnail){ file.write_format("; HEADER_BLOCK_START\n"); // Write information on the generator. file.write_format("; generated by %s on %s\n", Slic3r::header_slic3r_generated().c_str(), Slic3r::Utils::local_timestamp().c_str()); @@ -1923,9 +1927,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato for (const PrintObject *print_object : print.objects()) for (const PrintInstance &print_instance : print_object->instances()) m_label_objects_ids.push_back(print_instance.model_instance->get_labeled_id()); - + std::sort(m_label_objects_ids.begin(), m_label_objects_ids.end()); - + std::string objects_id_list = "; model label id: "; for (auto it = m_label_objects_ids.begin(); it != m_label_objects_ids.end(); it++) objects_id_list += (std::to_string(*it) + (it != m_label_objects_ids.end() - 1 ? "," : "\n")); @@ -1956,7 +1960,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write_format("; HEADER_BLOCK_END\n\n"); } - + // BBS: write global config at the beginning of gcode file because printer // need these config information // Append full config, delimited by two 'phony' configuration keys @@ -2130,7 +2134,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // In non-sequential print, the printing extruders may have been modified by the extruder switches stored in Model::custom_gcode_per_print_z. // Therefore initialize the printing extruders from there. this->set_extruders(tool_ordering.all_extruders()); - print_object_instances_ordering = + print_object_instances_ordering = // By default, order object instances using a nearest neighbor search. print.config().print_order == PrintOrder::Default ? chain_print_object_instances(print) // Otherwise same order as the object list @@ -2149,7 +2153,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_cooling_buffer = make_unique(*this); m_cooling_buffer->set_current_extruder(initial_extruder_id); - + // Orca: Initialise AdaptivePA processor filter m_pa_processor = std::make_unique(*this, tool_ordering.all_extruders()); @@ -2232,7 +2236,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato this->placeholder_parser().set("first_layer_print_max", new ConfigOptionFloats({bbox.max.x(), bbox.max.y()})); this->placeholder_parser().set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); - { + { // use first layer convex_hull union with each object's bbox to check whether in head detect zone Polygons object_projections; for (auto& obj : print.objects()) { @@ -2709,10 +2713,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write_format("; bed_shape = %s\n", print.full_print_config().opt_serialize("printable_area").c_str()); file.write_format("; first_layer_temperature = %d\n", print.config().nozzle_temperature_initial_layer.get_at(0)); file.write_format("; first_layer_height = %.3f\n", print.config().initial_layer_print_height.value); - + //SF TODO // file.write_format("; variable_layer_height = %d\n", print.ad.adaptive_layer_height ? 1 : 0); - + file.write("; CONFIG_BLOCK_END\n\n"); } @@ -2779,7 +2783,7 @@ void GCode::process_layers( [&spiral_mode = *this->m_spiral_vase.get(), &layers_to_print](LayerResult in) -> LayerResult { if (in.nop_layer_result) return in; - + spiral_mode.enable(in.spiral_vase_enable); bool last_layer = in.layer_id == layers_to_print.size() - 1; return { spiral_mode.process_layer(std::move(in.gcode), last_layer), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush}; @@ -2799,7 +2803,7 @@ void GCode::process_layers( return pa_processor.process_layer(std::move(in)); } ); - + const auto output = tbb::make_filter(slic3r_tbb_filtermode::serial_in_order, [&output_stream](std::string s) { output_stream.write(s); } ); @@ -2816,7 +2820,6 @@ void GCode::process_layers( std::abs((float)config.fan_speedup_time.value), config.fan_speedup_time.value > 0, config.use_relative_e_distances.value, - config.fan_speedup_overhangs.value, (float)config.fan_kickstart.value)); //flush as it's a whole layer return fan_mover->process_gcode(in, true); @@ -2907,7 +2910,6 @@ void GCode::process_layers( std::abs((float)config.fan_speedup_time.value), config.fan_speedup_time.value > 0, config.use_relative_e_distances.value, - config.fan_speedup_overhangs.value, (float)config.fan_kickstart.value)); //flush as it's a whole layer return fan_mover->process_gcode(in, true); @@ -2982,15 +2984,15 @@ PlaceholderParserIntegration &ppi = m_placeholder_parser_integration; if ( eid < ppi.num_extruders) { if (! m_writer.config.use_relative_e_distances && ! is_approx(ppi.e_position[eid], ppi.opt_e_position->values[eid])) const_cast(e).set_position(ppi.opt_e_position->values[eid]); - if (! is_approx(ppi.e_retracted[eid], ppi.opt_e_retracted->values[eid]) || + if (! is_approx(ppi.e_retracted[eid], ppi.opt_e_retracted->values[eid]) || ! is_approx(ppi.e_restart_extra[eid], ppi.opt_e_restart_extra->values[eid])) const_cast(e).set_retracted(ppi.opt_e_retracted->values[eid], ppi.opt_e_restart_extra->values[eid]); } } return output; - } - catch (std::runtime_error &err) + } + catch (std::runtime_error &err) { // Collect the names of failed template substitutions for error reporting. auto it = ppi.failed_templates.find(name); @@ -3499,7 +3501,7 @@ std::string GCode::generate_skirt(const Print &print, const Layer& layer, unsigned int extruder_id) { - + bool first_layer = (layer.id() == 0 && abs(layer.bottom_z()) < EPSILON); std::string gcode; // Extrude skirt at the print_z of the raft layers and normal object layers @@ -3512,7 +3514,7 @@ std::string GCode::generate_skirt(const Print &print, if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) { const std::pair loops = loops_it->second; - + set_origin(unscaled(offset)); m_avoid_crossing_perimeters.use_external_mp(); @@ -3819,7 +3821,7 @@ LayerResult GCode::process_layer( } return next_extruder; }; - + if (m_config.enable_overhang_speed && !m_config.overhang_speed_classic) { for (const auto &layer_to_print : layers) { m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object, @@ -4064,7 +4066,7 @@ LayerResult GCode::process_layer( // let analyzer tag generator aware of a role type change if (layer_tools.has_wipe_tower && m_wipe_tower) m_last_processor_extrusion_role = erWipeTower; - + if (print.config().skirt_type == stCombined && !print.skirt().empty()) gcode += generate_skirt(print, print.skirt(), Point(0,0), layer_tools, layer, extruder_id); @@ -4108,10 +4110,10 @@ LayerResult GCode::process_layer( ) { for (InstanceToPrint& instance_to_print : instances_to_print) { - + if (instance_to_print.print_object.object_skirt().empty()) continue; - + if (this->m_objSupportsWithBrim.find(instance_to_print.print_object.id()) != this->m_objSupportsWithBrim.end() && print.m_supportBrimMap.at(instance_to_print.print_object.id()).entities.size() > 0) continue; @@ -4137,7 +4139,7 @@ LayerResult GCode::process_layer( gcode+="; PURGING FINISHED\n"; for (InstanceToPrint &instance_to_print : instances_to_print) { - if (print.config().skirt_type == stPerObject && + if (print.config().skirt_type == stPerObject && !instance_to_print.print_object.object_skirt().empty() && print.config().print_sequence == PrintSequence::ByLayer && @@ -4150,7 +4152,7 @@ LayerResult GCode::process_layer( if (instances_to_print.size() > 1 && &instance_to_print != &*(instances_to_print.end() - 1)) m_skirt_done.pop_back(); } - + const auto& inst = instance_to_print.print_object.instances()[instance_to_print.instance_id]; const LayerToPrint &layer_to_print = layers[instance_to_print.layer_id]; // To control print speed of the 1st object layer printed over raft interface. @@ -4563,7 +4565,7 @@ static std::unique_ptr calculate_layer_edge_grid(const Layer& la std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed, const ExtrusionEntitiesPtr& region_perimeters) { - + // get a copy; don't modify the orientation of the original loop object otherwise // next copies (if any) would not detect the correct orientation @@ -4613,7 +4615,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou loop.clip_end(clip_length, &paths); if (paths.empty()) return ""; - // SoftFever: check loop lenght for small perimeter. + // SoftFever: check loop lenght for small perimeter. double small_peri_speed = -1; if (speed == -1 && loop.length() <= SMALL_PERIMETER_LENGTH(m_config.small_perimeter_threshold.value)) { if(m_config.small_perimeter_speed == 0) @@ -4624,7 +4626,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // extrude along the path std::string gcode; - + // Orca: // Port of "wipe inside before extruding an external perimeter" feature from super slicer // If region perimeters size not greater than or equal to 2, then skip the wipe inside move as we will extrude in mid air @@ -4671,7 +4673,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou pt.rotate(angle, current_point); pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast(); pt.rotate(angle, current_point); - + // Search region perimeters for lines that are touching the de-retraction point. // If an internal perimeter exists, we should find 2 perimeters touching the de-retraction point // 1: the currently printed external perimeter and 2: the neighbouring internal perimeter. @@ -4704,7 +4706,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou return is_small_peri ? small_peri_speed : speed; }; - + //Orca: Adaptive PA: calculate average mm3_per_mm value over the length of the loop. //This is used for adaptive PA m_multi_flow_segment_path_pa_set = false; // always emit PA on the first path of the loop @@ -4721,7 +4723,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou if (total_multipath_length > 0.0) m_multi_flow_segment_path_average_mm3_per_mm = weighted_sum_mm3_per_mm / total_multipath_length; // Orca: end of multipath average mm3_per_mm value calculation - + if (!enable_seam_slope) { for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) { gcode += this->_extrude(*path, description, speed_for_path(*path)); @@ -4836,7 +4838,7 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string { // extrude along the path std::string gcode; - + //Orca: calculate multipath average mm3_per_mm value over the length of the path. //This is used for adaptive PA m_multi_flow_segment_path_pa_set = false; // always emit PA on the first path of the multi-path @@ -4853,7 +4855,7 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string if (total_multipath_length > 0.0) m_multi_flow_segment_path_average_mm3_per_mm = weighted_sum_mm3_per_mm / total_multipath_length; // Orca: end of multipath average mm3_per_mm value calculation - + for (ExtrusionPath path : multipath.paths){ gcode += this->_extrude(path, description, speed); // Orca: Adaptive PA - dont adapt PA after the first pultipath extrusion is completed @@ -5219,7 +5221,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (sloped) { speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("outer_wall_speed"))); } - } + } else if(path.role() == erInternalBridgeInfill) { speed = m_config.get_abs_value("internal_bridge_speed"); } else if (path.role() == erOverhangPerimeter || path.role() == erSupportTransition || path.role() == erBridgeInfill) { @@ -5294,7 +5296,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, ); } - + bool variable_speed = false; std::vector new_points {}; @@ -5311,7 +5313,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (sloped) { ref_speed = std::min(ref_speed, m_config.scarf_joint_speed.get_abs_value(ref_speed)); } - + ConfigOptionPercents overhang_overlap_levels({75, 50, 25, 13, 12.99, 0}); if (m_config.slowdown_for_curled_perimeters){ @@ -5362,7 +5364,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } double F = speed * 60; // convert mm/sec to mm/min - + // Orca: Dynamic PA // If adaptive PA is enabled, by default evaluate PA on all extrusion moves bool evaluate_adaptive_pa = false; @@ -5383,7 +5385,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, evaluate_adaptive_pa = true; } // Orca: End of dynamic PA trigger flag segment - + //Orca: process custom gcode for extrusion role change if (path.role() != m_last_extrusion_role && !m_config.change_extrusion_role_gcode.value.empty()) { DynamicConfig config; @@ -5439,7 +5441,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height); gcode += buf; } - + // Orca: Dynamic PA // Post processor flag generation code segment when option to emit only at role changes is enabled // Variables published to the post processor: @@ -5481,7 +5483,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, auto overhang_fan_threshold = EXTRUDER_CONFIG(overhang_fan_threshold); auto enable_overhang_bridge_fan = EXTRUDER_CONFIG(enable_overhang_bridge_fan); - + auto supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed); @@ -5555,7 +5557,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // change for the Adaptive PA post processor. 1); }else{ // Ramping up speed - use baseline logic where max speed is used between current and upcoming extrusion - if(m_config.gcode_comments){ + if(m_config.gcode_comments){ sprintf(buf, "; Ramp up-non-variable\n"); gcode += buf; } @@ -5575,7 +5577,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } // ORCA: End of adaptive PA code segment } - + gcode += m_writer.set_speed(F, "", comment); { if (m_enable_cooling_markers) { @@ -5771,7 +5773,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, continue; path_length += line_length; double new_speed = pre_processed_point.speed * 60.0; - + if ((std::abs(last_set_speed - new_speed) > EPSILON) || (std::abs(_mm3_per_mm - m_last_mm3_mm) > EPSILON)) { // ORCA: Adaptive PA code segment when adjusting PA within the same feature // There is a speed change or flow change so emit the flag to evaluate PA for the upcomming extrusion @@ -5815,7 +5817,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, m_last_mm3_mm = _mm3_per_mm; } }// ORCA: End of adaptive PA code segment - + // Ignore small speed variations - emit speed change if the delta between current and new is greater than 60mm/min / 1mm/sec // Reset speed to F if delta to F is less than 1mm/sec if ((std::abs(last_set_speed - new_speed) > 60)) { @@ -6220,7 +6222,7 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li bool last_fill_extrusion_role_top_infill = (this->m_last_notgapfill_extrusion_role == ExtrusionRole::erTopSolidInfill || this->m_last_notgapfill_extrusion_role == ExtrusionRole::erIroning); - // assume we can lift on retraction; conditions left explicit + // assume we can lift on retraction; conditions left explicit bool can_lift = true; if (retract_lift_type == RetractLiftEnforceType::rletAllSurfaces) { @@ -6411,10 +6413,13 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z, bool b } // Process the custom change_filament_gcode. - const std::string& change_filament_gcode = m_config.change_filament_gcode.value; + std::string change_filament_gcode = m_config.change_filament_gcode.value; 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 if (!change_filament_gcode.empty() && !(m_config.manual_filament_change.value && m_toolchange_count == 1)) { + // mark change_filament_gcode as custom gcode to protect it from fan_mover + change_filament_gcode = FanMover::custom_gcode_start_marker + '\n' + change_filament_gcode + FanMover::custom_gcode_end_marker + '\n'; + dyn_config.set_key_value("toolchange_z", new ConfigOptionFloat(print_z)); toolchange_gcode_parsed = placeholder_parser_process("change_filament_gcode", change_filament_gcode, extruder_id, &dyn_config); @@ -6565,7 +6570,7 @@ Point GCode::gcode_to_point(const Vec2d &point) const // This function may be called at the very start from toolchange G-code when the extruder is not assigned yet. pt += m_config.extruder_offset.get_at(extruder->id()); return scaled(pt); - + } Vec2d GCode::point_to_gcode_quantized(const Point& point) const diff --git a/src/libslic3r/GCode/FanMover.cpp b/src/libslic3r/GCode/FanMover.cpp index 762d251b5b0..5edc53ebbcd 100644 --- a/src/libslic3r/GCode/FanMover.cpp +++ b/src/libslic3r/GCode/FanMover.cpp @@ -1,6 +1,7 @@ #include "FanMover.hpp" #include "GCodeReader.hpp" +#include "GCodeProcessor.hpp" #include /* @@ -16,9 +17,11 @@ #include */ - namespace Slic3r { +const std::string& FanMover::custom_gcode_start_marker = "; custom gcode"; +const std::string& FanMover::custom_gcode_end_marker = "; custom gcode end"; + const std::string& FanMover::process_gcode(const std::string& gcode, bool flush) { m_process_output = ""; @@ -33,8 +36,7 @@ const std::string& FanMover::process_gcode(const std::string& gcode, bool flush) if (flush) { while (!m_buffer.empty()) { - m_process_output += m_buffer.front().raw + "\n"; - remove_from_buffer(m_buffer.begin()); + write_buffer_data(); } } @@ -95,12 +97,18 @@ int16_t get_fan_speed(const std::string &line, GCodeFlavor flavor) { } -void FanMover::_put_in_middle_G1(std::list::iterator item_to_split, float nb_sec_since_itemtosplit_start, BufferData &&line_to_write) { +void FanMover::_put_in_middle_G1(std::list::iterator item_to_split, float nb_sec_since_itemtosplit_start, BufferData &&line_to_write, float max_time) { assert(item_to_split != m_buffer.end()); - if (nb_sec_since_itemtosplit_start > item_to_split->time * 0.9) { + // if the fan is at the end of the g1 and the diff is less than 10% of the delay, then don't bother + if (nb_sec_since_itemtosplit_start > item_to_split->time * 0.9 && (item_to_split->time - nb_sec_since_itemtosplit_start) < max_time * 0.1) { // doesn't really need to be split, print it after m_buffer.insert(next(item_to_split), line_to_write); - } else if (nb_sec_since_itemtosplit_start < item_to_split->time * 0.1) { + } else + // does it need to be split? + // if it's almost at the start of the g1, and the time "lost" is less than 10% + if (nb_sec_since_itemtosplit_start < item_to_split->time * 0.1 && nb_sec_since_itemtosplit_start < max_time * 0.1 && + // and the previous isn't a fan value + (item_to_split == m_buffer.begin() || std::prev(item_to_split)->fan_speed < 0)) { // doesn't really need to be split, print it before //will also print before if line_to_split.time == 0 m_buffer.insert(item_to_split, line_to_write); @@ -263,7 +271,7 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode std::string cmd(line.cmd()); double time = 0; int16_t fan_speed = -1; - if (cmd.length() > 1) { + if (cmd.length() > 1 && !m_is_custom_gcode) { if (line.has_f()) m_current_speed = line.f() / 60.0f; switch (::toupper(cmd[0])) { @@ -282,6 +290,15 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode dist = std::sqrt(dist); time = dist / m_current_speed; } + } else if (::atoi(&cmd[1]) == 2 || ::atoi(&cmd[1]) == 3) { + // TODO: compute real dist + double distx = line.dist_X(reader); + double disty = line.dist_Y(reader); + double dist = distx * distx + disty * disty; + if (dist > 0) { + dist = std::sqrt(dist); + time = dist / m_current_speed; + } } break; } @@ -291,110 +308,112 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode if (fan_speed >= 0) { const auto fan_baseline = 255.0; fan_speed = 100 * fan_speed / fan_baseline; - //speed change: stop kickstart reverting if any - m_current_kickstart.time = -1; - if (!m_is_custom_gcode) { - // if slow down => put in the queue. if not => - if (m_back_buffer_fan_speed < fan_speed) { - if (nb_seconds_delay > 0 && (!only_overhangs || current_role == ExtrusionRole::erOverhangPerimeter)) { - //don't put this command in the queue - time = -1; - // this M106 need to go in the past - //check if we have ( kickstart and not in slowdown ) - if (kickstart > 0 && fan_speed > m_front_buffer_fan_speed) { - //stop current kickstart , it's not relevant anymore - if (m_current_kickstart.time > 0) { - m_current_kickstart.time = (-1); - } + // if slow down => put in the queue. if not => + if (m_current_kickstart.time > 0) { + assert(m_back_buffer_fan_speed == m_current_kickstart.fan_speed); + } + if (m_back_buffer_fan_speed >= fan_speed) { + if (m_current_kickstart.time > 0) { + // stop kiskstart, and slow down + m_current_kickstart.time = -1; + //this fan speed will be printed, to make and end to the kickstart + } + } else { + if (nb_seconds_delay > 0) { + //don't put this command in the queue + time = -1; + // this M106 need to go in the past + //check if we have ( kickstart and not in slowdown ) + if (kickstart > 0 && fan_speed > m_front_buffer_fan_speed) { + //stop current kickstart , it's not relevant anymore + if (m_current_kickstart.time > 0) { + m_current_kickstart.time = (-1); + } - //if kickstart - // first erase everything lower that that value - _remove_slow_fan(fan_speed, m_buffer_time_size + 1); - // then erase everything lower that kickstart - _remove_slow_fan(fan_baseline, kickstart); - // print me - if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) { - _print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, _set_fan(100));//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing - remove_from_buffer(m_buffer.begin()); - } else { - m_process_output += _set_fan(100);//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing - } - //write it in the queue if possible - const float kickstart_duration = kickstart * float(fan_speed - m_front_buffer_fan_speed) / 100.f; - float time_count = kickstart_duration; - auto it = m_buffer.begin(); - while (it != m_buffer.end() && time_count > 0) { - time_count -= it->time; - if (time_count< 0) { - //found something that is lower than us - _put_in_middle_G1(it, it->time + time_count, BufferData(std::string(line.raw()), 0, fan_speed, true)); - //found, stop - break; - } - ++it; - } - if (time_count > 0) { - //can't place it in the buffer, use m_current_kickstart - m_current_kickstart.fan_speed = fan_speed; - m_current_kickstart.time = time_count; - m_current_kickstart.raw = line.raw(); - } - m_front_buffer_fan_speed = fan_speed; + //if kickstart + // first erase everything lower that that value + _remove_slow_fan(fan_speed, m_buffer_time_size + 1); + // then erase everything lower that kickstart + _remove_slow_fan(fan_baseline, kickstart); + // print me + if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) { + _print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, _set_fan(100));//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing + remove_from_buffer(m_buffer.begin()); } else { - // first erase everything lower that that value - _remove_slow_fan(fan_speed, m_buffer_time_size + 1); - // then write the fan command - if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) { - _print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, line.raw()); - remove_from_buffer(m_buffer.begin()); - } else { - m_process_output += line.raw() + "\n"; + m_process_output += _set_fan(100);//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing + } + //write it in the queue if possible + const float kickstart_duration = kickstart * float(fan_speed - m_front_buffer_fan_speed) / 100.f; + float time_count = kickstart_duration; + auto it = m_buffer.begin(); + while (it != m_buffer.end() && time_count > 0) { + time_count -= it->time; + if (time_count< 0) { + //found something that is lower than us + _put_in_middle_G1(it, it->time + time_count, BufferData(std::string(line.raw()), 0, fan_speed, true), nb_seconds_delay); + //found, stop + break; } - m_front_buffer_fan_speed = fan_speed; + ++it; } + if (time_count > 0) { + //can't place it in the buffer, use m_current_kickstart + m_current_kickstart.fan_speed = fan_speed; + m_current_kickstart.time = time_count; + m_current_kickstart.raw = line.raw(); + } + m_front_buffer_fan_speed = fan_speed; } else { - if (kickstart <= 0) { - //nothing to do - //we don't put time = -1; so it will printed in the buffer as other line are done - } else if (m_current_kickstart.time > 0) { - //cherry-pick this one - if (m_back_buffer_fan_speed >= fan_speed) { - //stop kickstart - m_current_kickstart.time = -1; - //this will print me just after as time >=0 - } else { - // add some duration to the kickstart and use it for me. - float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f; - m_current_kickstart.fan_speed = fan_speed; - m_current_kickstart.time += kickstart_duration; - m_current_kickstart.raw = line.raw(); - //i'm printed by the m_current_kickstart - time = -1; - } - } else if(m_back_buffer_fan_speed < fan_speed - 10){ //only kickstart if more than 10% change - //don't write this line, as it will need to be delayed - time = -1; - //get the duration of kickstart + // first erase everything lower that that value + _remove_slow_fan(fan_speed, m_buffer_time_size + 1); + // then write the fan command + if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) { + _print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, line.raw()); + remove_from_buffer(m_buffer.begin()); + } else { + m_process_output += line.raw() + "\n"; + } + m_front_buffer_fan_speed = fan_speed; + } + } else { + if (kickstart <= 0) { + //nothing to do + //we don't put time = -1; so it will printed in the buffer as other line are done + } else if (m_current_kickstart.time > 0) { + //cherry-pick this one + if (m_back_buffer_fan_speed >= fan_speed) { + //stop kickstart + m_current_kickstart.time = -1; + //this will print me just after as time >=0 + } else { + // add some duration to the kickstart and use it for me. float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f; - //if kickstart, write the M106 S[fan_baseline] first - //set the target speed and set the kickstart flag - put_in_buffer(BufferData(_set_fan(100)//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing - , 0, fan_speed, true)); - //kickstart! - //m_process_output += m_writer.set_fan(100, true); - //add the normal speed line for the future m_current_kickstart.fan_speed = fan_speed; - m_current_kickstart.time = kickstart_duration; + m_current_kickstart.time += kickstart_duration; m_current_kickstart.raw = line.raw(); + //i'm printed by the m_current_kickstart + time = -1; } + } else if(m_back_buffer_fan_speed < fan_speed - 10){ //only kickstart if more than 10% change + //don't write this line, as it will need to be delayed + time = -1; + //get the duration of kickstart + float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f; + //if kickstart, write the M106 S[fan_baseline] first + //set the target speed and set the kickstart flag + put_in_buffer(BufferData(_set_fan(100)//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing + , 0, fan_speed, true)); + //kickstart! + //m_process_output += m_writer.set_fan(100, true); + //add the normal speed line for the future + m_current_kickstart.fan_speed = fan_speed; + m_current_kickstart.time = kickstart_duration; + m_current_kickstart.raw = line.raw(); } } - //update back buffer fan speed - m_back_buffer_fan_speed = fan_speed; - } else { - // have to flush the buffer to avoid erasing a fan command. - need_flush = true; } + //update back buffer fan speed + m_back_buffer_fan_speed = fan_speed; } break; } @@ -402,17 +421,13 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode } else { if(!line.raw().empty() && line.raw().front() == ';') { - if (line.raw().size() > 10 && line.raw().rfind(";TYPE:", 0) == 0) { - // get the type of the next extrusions - std::string extrusion_string = line.raw().substr(6, line.raw().size() - 6); - current_role = ExtrusionEntity::string_to_role(extrusion_string); - } - if (line.raw().size() > 16) { - if (line.raw().rfind("; custom gcode", 0) != std::string::npos) - if (line.raw().rfind("; custom gcode end", 0) != std::string::npos) + if (line.raw().size() > 13) { + if (line.raw().rfind(custom_gcode_start_marker, 0) != std::string::npos) { + if (line.raw().rfind(custom_gcode_end_marker, 0) != std::string::npos) m_is_custom_gcode = false; else m_is_custom_gcode = true; + } } } } @@ -433,17 +448,24 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode } if (line.has(Axis::E)) { new_data.e = reader.e(); - if (relative_e) + if (relative_e) { + assert(new_data.e == 0); new_data.de = line.e(); - else + } else new_data.de = line.dist_E(reader); } + assert(new_data.dx == 0 || reader.x() == new_data.x); + assert(new_data.dx == 0 || reader.x() + new_data.dx == line.x()); + assert(new_data.dy == 0 ||reader.y() == new_data.y); + assert(new_data.dy == 0 || reader.y() + new_data.dy == line.y()); + assert(new_data.de == 0 || reader.e() == new_data.e); + assert(new_data.de == 0 || reader.e() + new_data.de == line.e()); if (m_current_kickstart.time > 0 && time > 0) { m_current_kickstart.time -= time; if (m_current_kickstart.time < 0) { //prev is possible because we just do a emplace_back. - _put_in_middle_G1(prev(m_buffer.end()), time + m_current_kickstart.time, BufferData{ m_current_kickstart.raw, 0, m_current_kickstart.fan_speed, true }); + _put_in_middle_G1(prev(m_buffer.end()), time + m_current_kickstart.time, BufferData{ m_current_kickstart.raw, 0, m_current_kickstart.fan_speed, true }, kickstart); } } }/* else { @@ -471,24 +493,8 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode // puts the line back into the gcode //if buffer too big, flush it. if (time >= 0) { - while (!m_buffer.empty() && (need_flush || m_buffer_time_size - m_buffer.front().time > nb_seconds_delay - EPSILON) ){ - BufferData& frontdata = m_buffer.front(); - if (frontdata.fan_speed < 0 || frontdata.fan_speed != m_front_buffer_fan_speed || frontdata.is_kickstart) { - if (frontdata.is_kickstart && frontdata.fan_speed < m_front_buffer_fan_speed) { - //you have to slow down! not kickstart! rewrite the fan speed. - m_process_output += _set_fan(frontdata.fan_speed);//m_writer.set_fan(frontdata.fan_speed,true); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing - - m_front_buffer_fan_speed = frontdata.fan_speed; - } else { - m_process_output += frontdata.raw + "\n"; - if (frontdata.fan_speed >= 0) { - //note that this is the only place where the fan_speed is set and we print from the buffer, as if the fan_speed >= 0 => time == 0 - //and as this flush all time == 0 lines from the back of the queue... - m_front_buffer_fan_speed = frontdata.fan_speed; - } - } - } - remove_from_buffer(m_buffer.begin()); + while (!m_buffer.empty() && (m_is_custom_gcode || m_buffer_time_size - m_buffer.front().time > nb_seconds_delay - EPSILON) ){ + write_buffer_data(); } } double sum = 0; @@ -496,5 +502,24 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode assert( std::abs(m_buffer_time_size - sum) < 0.01); } -} // namespace Slic3r +void FanMover::write_buffer_data() +{ + BufferData &frontdata = m_buffer.front(); + if (frontdata.fan_speed < 0 || frontdata.fan_speed != m_front_buffer_fan_speed || frontdata.is_kickstart) { + if (frontdata.is_kickstart && frontdata.fan_speed < m_front_buffer_fan_speed) { + // you have to slow down! not kickstart! rewrite the fan speed. + m_process_output += _set_fan(frontdata.fan_speed) + "\n"; + m_front_buffer_fan_speed = frontdata.fan_speed; + } else { + m_process_output += frontdata.raw + "\n"; + if (frontdata.fan_speed >= 0 || frontdata.is_kickstart) { + // note that this is the only place where the fan_speed is set and we print from the buffer, as if the + // fan_speed >= 0 => time == 0 and as this flush all time == 0 lines from the back of the queue... + m_front_buffer_fan_speed = frontdata.is_kickstart ? 100 : frontdata.fan_speed; + } + } + } + remove_from_buffer(m_buffer.begin()); +} +} // namespace Slic3r diff --git a/src/libslic3r/GCode/FanMover.hpp b/src/libslic3r/GCode/FanMover.hpp index f785e4c658a..e6e424659f3 100644 --- a/src/libslic3r/GCode/FanMover.hpp +++ b/src/libslic3r/GCode/FanMover.hpp @@ -15,11 +15,15 @@ namespace Slic3r { class BufferData { public: + //raw string, contains end position std::string raw; + // time to go from start to end float time; int16_t fan_speed; bool is_kickstart; + // start position float x = 0, y = 0, z = 0, e = 0; + // delta to go to end position float dx = 0, dy = 0, dz = 0, de = 0; BufferData(std::string line, float time = 0, int16_t fan_speed = 0, float is_kickstart = false) : raw(line), time(time), fan_speed(fan_speed), is_kickstart(is_kickstart){ //avoid double \n @@ -31,11 +35,10 @@ class FanMover { private: const std::regex regex_fan_speed; - const float nb_seconds_delay; + const float nb_seconds_delay; // in s const bool with_D_option; const bool relative_e; - const bool only_overhangs; - const float kickstart; + const float kickstart; // in s GCodeReader m_parser{}; const GCodeWriter& m_writer; @@ -61,19 +64,27 @@ class FanMover public: FanMover(const GCodeWriter& writer, const float nb_seconds_delay, const bool with_D_option, const bool relative_e, - const bool only_overhangs, const float kickstart) - : regex_fan_speed("S[0-9]+"), + const float kickstart) + : regex_fan_speed("S[0-9]+"), nb_seconds_delay(nb_seconds_delay>0 ? std::max(0.01f,nb_seconds_delay) : 0), with_D_option(with_D_option) - , relative_e(relative_e), only_overhangs(only_overhangs), kickstart(kickstart), m_writer(writer){} + , relative_e(relative_e), kickstart(kickstart), m_writer(writer){} // Adds the gcode contained in the given string to the analysis and returns it after removing the workcodes const std::string& process_gcode(const std::string& gcode, bool flush); + static const std::string& custom_gcode_start_marker; + static const std::string& custom_gcode_end_marker; + private: BufferData& put_in_buffer(BufferData&& data) { - m_buffer_time_size += data.time; - m_buffer.emplace_back(data); + m_buffer_time_size += data.time; + if (data.fan_speed >= 0 && !m_buffer.empty() && m_buffer.back().fan_speed >= 0) { + // erase last item + m_buffer.back() = data; + } else { + m_buffer.emplace_back(data); + } return m_buffer.back(); } std::list::iterator remove_from_buffer(std::list::iterator data) { @@ -83,9 +94,10 @@ class FanMover // Processes the given gcode line void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line); void _process_T(const std::string_view command); - void _put_in_middle_G1(std::list::iterator item_to_split, float nb_sec, BufferData&& line_to_write); + void _put_in_middle_G1(std::list::iterator item_to_split, float nb_sec, BufferData&& line_to_write, float max_time); void _print_in_middle_G1(BufferData& line_to_split, float nb_sec, const std::string& line_to_write); void _remove_slow_fan(int16_t min_speed, float past_sec); + void write_buffer_data(); std::string _set_fan(int16_t speed); }; @@ -93,3 +105,4 @@ class FanMover #endif /* slic3r_GCode_FanMover_hpp_ */ +; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 30c9bc230f7..ad0a995c2dc 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -796,7 +796,7 @@ static std::vector s_Preset_print_options { "detect_narrow_internal_solid_infill", "gcode_add_line_number", "enable_arc_fitting", "precise_z_height", "infill_combination","infill_combination_max_layer_height", /*"adaptive_layer_height",*/ "support_bottom_interface_spacing", "enable_overhang_speed", "slowdown_for_curled_perimeters", "overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed", - "initial_layer_infill_speed", "only_one_wall_top", + "initial_layer_infill_speed", "only_one_wall_top", "timelapse_type", "wall_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "wall_distribution_count", "min_feature_size", "min_bead_width", "post_process", "min_length_factor", @@ -805,7 +805,7 @@ static std::vector s_Preset_print_options { "top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap", "role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops", "wipe_before_external_loop", "bridge_density", "precise_outer_wall", "overhang_speed_classic", "bridge_acceleration", - "sparse_infill_acceleration", "internal_solid_infill_acceleration", "tree_support_adaptive_layer_height", "tree_support_auto_brim", + "sparse_infill_acceleration", "internal_solid_infill_acceleration", "tree_support_adaptive_layer_height", "tree_support_auto_brim", "tree_support_brim_width", "gcode_comments", "gcode_label_objects", "initial_layer_travel_speed", "exclude_object", "slow_down_layers", "infill_anchor", "infill_anchor_max","initial_layer_min_bead_width", "make_overhang_printable", "make_overhang_printable_angle", "make_overhang_printable_hole_size" ,"notes", @@ -859,7 +859,7 @@ static std::vector s_Preset_machine_limits_options { static std::vector s_Preset_printer_options { "printer_technology", "printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor", - "fan_kickstart", "fan_speedup_time", "fan_speedup_overhangs", + "fan_kickstart", "fan_speedup_time", "single_extruder_multi_material", "manual_filament_change", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "printing_by_object_gcode", "layer_change_gcode", "time_lapse_gcode", "change_filament_gcode", "change_extrusion_role_gcode", "printer_model", "printer_variant", "printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "nozzle_height", @@ -2465,7 +2465,7 @@ const std::string& PresetCollection::get_preset_name_by_alias(const std::string& it_preset->is_visible && (it_preset->is_compatible || size_t(it_preset - m_presets.begin()) == m_idx_selected)) return it_preset->name; } - + return alias; } @@ -3578,7 +3578,7 @@ namespace PresetUtils { if (!boost::filesystem::exists(boost::filesystem::path(out))) out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->hotend_model; } - + if (out.empty() ||!boost::filesystem::exists(boost::filesystem::path(out))) out = Slic3r::resources_dir() + "/profiles/hotend.stl"; return out; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index c07eaa70ac7..b4084538bd8 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -112,7 +112,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "fan_cooling_layer_time", "full_fan_speed_layer", "fan_kickstart", - "fan_speedup_overhangs", "fan_speedup_time", "filament_colour", "default_filament_colour", @@ -154,7 +153,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "z_hop", "travel_slope", "retract_lift_above", - "retract_lift_below", + "retract_lift_below", "retract_lift_enforce", "retract_restart_extra", "retract_restart_extra_toolchange", @@ -188,7 +187,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "accel_to_decel_factor", "wipe_on_loops", "gcode_comments", - "gcode_label_objects", + "gcode_label_objects", "exclude_object", "support_material_interface_fan_speed", "single_extruder_multi_material_priming", @@ -280,7 +279,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "prime_tower_brim_width" || opt_key == "first_layer_print_sequence" || opt_key == "other_layers_print_sequence" - || opt_key == "other_layers_print_sequence_nums" + || opt_key == "other_layers_print_sequence_nums" || opt_key == "wipe_tower_bridging" || opt_key == "wipe_tower_extra_flow" || opt_key == "wipe_tower_no_sparse_layers" @@ -1132,7 +1131,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* Vec3d test =this->shrinkage_compensation(); const double shrinkage_compensation_z = this->shrinkage_compensation().z(); - + if (shrinkage_compensation_z != 1. && layers.back() > (this->config().printable_height / shrinkage_compensation_z + EPSILON)) { // The object exceeds the maximum build volume height because of shrinkage compensation. return StringObjectException{ @@ -1155,14 +1154,14 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* } // Some of the objects has variable layer height applied by painting or by a table. - bool has_custom_layering = std::find_if(m_objects.begin(), m_objects.end(), - [](const PrintObject *object) { return object->model_object()->has_custom_layering(); }) + bool has_custom_layering = std::find_if(m_objects.begin(), m_objects.end(), + [](const PrintObject *object) { return object->model_object()->has_custom_layering(); }) != m_objects.end(); // Custom layering is not allowed for tree supports as of now. for (size_t print_object_idx = 0; print_object_idx < m_objects.size(); ++ print_object_idx) if (const PrintObject &print_object = *m_objects[print_object_idx]; - print_object.has_support_material() && is_tree(print_object.config().support_type.value) && (print_object.config().support_style.value == smsOrganic || + print_object.has_support_material() && is_tree(print_object.config().support_type.value) && (print_object.config().support_style.value == smsOrganic || // Orca: use organic as default print_object.config().support_style.value == smsDefault) && print_object.model_object()->has_custom_layering()) { @@ -1193,7 +1192,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* if (m_config.ooze_prevention && m_config.single_extruder_multi_material) return {L("Ooze prevention is only supported with the wipe tower when 'single_extruder_multi_material' is off.")}; - + #if 0 if (m_config.gcode_flavor != gcfRepRapSprinter && m_config.gcode_flavor != gcfRepRapFirmware && m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlinLegacy && m_config.gcode_flavor != gcfMarlinFirmware) @@ -1251,7 +1250,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* if (has_custom_layering) { std::vector> layer_z_series; layer_z_series.assign(m_objects.size(), std::vector()); - + for (size_t idx_object = 0; idx_object < m_objects.size(); ++idx_object) { layer_z_series[idx_object] = generate_object_layers(m_objects[idx_object]->slicing_parameters(), layer_height_profiles[idx_object], m_objects[idx_object]->config().precise_z_height.value); } @@ -2455,7 +2454,7 @@ std::vector Print::first_layer_wipe_tower_corners(bool check_wipe_tower_e double width = m_config.prime_tower_width + 2*m_wipe_tower_data.brim_width; double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width; Vec2d pt0(-m_wipe_tower_data.brim_width, -m_wipe_tower_data.brim_width); - + // First the corners. std::vector pts = { pt0, Vec2d(pt0.x()+width, pt0.y()), @@ -2601,9 +2600,9 @@ const WipeTowerData &Print::wipe_tower_data(size_t filaments_cnt) const max_wipe_volumes.emplace_back(*std::max_element(v.begin(), v.end())); float maximum = std::accumulate(max_wipe_volumes.begin(), max_wipe_volumes.end(), 0.f); maximum = maximum * filaments_cnt / max_wipe_volumes.size(); - + // Orca: it's overshooting a bit, so let's reduce it a bit - maximum *= 0.6; + maximum *= 0.6; const_cast(this)->m_wipe_tower_data.depth = maximum / (layer_height * width); } else { double wipe_volume = m_config.prime_volume; @@ -2956,7 +2955,7 @@ std::tuple Print::object_skirt_offset(double margin_height) const { if (config().skirt_loops == 0 || config().skirt_type != stPerObject) return std::make_tuple(0, 0); - + float max_nozzle_diameter = *std::max_element(m_config.nozzle_diameter.values.begin(), m_config.nozzle_diameter.values.end()); float max_layer_height = *std::max_element(config().max_layer_height.values.begin(), config().max_layer_height.values.end()); float line_width = m_config.initial_layer_line_width.get_abs_value(max_nozzle_diameter); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d7812e6b420..a186c234b6f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -496,7 +496,7 @@ void PrintConfigDef::init_common_params() def->sidetext = L("layers"); def->min = 1; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionInt(1)); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("layer_height", coFloat); def->label = L("Layer height"); @@ -622,7 +622,7 @@ void PrintConfigDef::init_common_params() def->mode = comAdvanced; def->cli = ConfigOptionDef::nocli; def->set_default_value(new ConfigOptionEnum(atKeyPassword)); - + // temporary workaround for compatibility with older Slicer { def = this->add("preset_name", coString); @@ -761,7 +761,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Bed types supported by the printer"); def->mode = comSimple; def->enum_keys_map = &s_keys_map_BedType; - // Orca: make sure the order of the values is the same as the BedType enum + // Orca: make sure the order of the values is the same as the BedType enum def->enum_values.emplace_back("Cool Plate"); def->enum_values.emplace_back("Engineering Plate"); def->enum_values.emplace_back("High Temp Plate"); @@ -843,7 +843,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->set_default_value(new ConfigOptionFloat(0.)); - + def = this->add("gap_fill_target", coEnum); def->label = L("Apply gap fill"); def->category = L("Strength"); @@ -872,7 +872,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Nowhere")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(gftNowhere)); - + def = this->add("enable_overhang_bridge_fan", coBools); def->label = L("Force cooling for overhang and bridge"); @@ -981,7 +981,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Improve shell precision by adjusting outer wall spacing. This also improves layer consistency.\nNote: This setting " "will only take effect if the wall sequence is configured to Inner-Outer"); def->set_default_value(new ConfigOptionBool{false}); - + def = this->add("only_one_wall_top", coBool); def->label = L("Only one wall on top surfaces"); def->category = L("Quality"); @@ -1024,7 +1024,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Extrude perimeters that have a part over an overhang in the reverse direction on even layers. This alternating pattern can drastically improve steep overhangs.\n\nThis setting can also help reduce part warping due to the reduction of stresses in the part walls."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("overhang_reverse_internal_only", coBool); def->label = L("Reverse only internal perimeters"); def->full_label = L("Reverse only internal perimeters"); @@ -1080,7 +1080,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Enable this option to slow printing down for different overhang degree"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool{ true }); - + def = this->add("slowdown_for_curled_perimeters", coBool); def->label = L("Slow down for curled perimeters"); def->category = L("Speed"); @@ -1479,7 +1479,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("All")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(EnsureVerticalShellThickness::evstAll)); - + auto def_top_fill_pattern = def = this->add("top_surface_pattern", coEnum); def->label = L("Top surface pattern"); def->category = L("Strength"); @@ -1520,7 +1520,7 @@ void PrintConfigDef::init_fff_params() def->enum_values = def_top_fill_pattern->enum_values; def->enum_labels = def_top_fill_pattern->enum_labels; def->set_default_value(new ConfigOptionEnum(ipMonotonic)); - + def = this->add("outer_wall_line_width", coFloatOrPercent); def->label = L("Outer wall"); def->category = L("Quality"); @@ -1740,7 +1740,7 @@ void PrintConfigDef::init_fff_params() def->max = 2; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0.02 }); - + // Orca: Adaptive pressure advance option and calibration values def = this->add("adaptive_pressure_advance", coBools); def->label = L("Enable adaptive pressure advance (beta)"); @@ -1756,7 +1756,7 @@ void PrintConfigDef::init_fff_params() "strongly recommended to act as a fallback and for when tool changing.\n\n"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBools{ false }); - + // Orca: Adaptive pressure advance option and calibration values def = this->add("adaptive_pressure_advance_model", coStrings); def->label = L("Adaptive pressure advance measurements (beta)"); @@ -1781,7 +1781,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 15; def->set_default_value(new ConfigOptionStrings{"0,0,0\n0,0,0"}); - + // xgettext:no-c-format, no-boost-format def = this->add("adaptive_pressure_advance_overhangs", coBools); def->label = L("Enable adaptive pressure advance for overhangs (beta)"); @@ -1789,7 +1789,7 @@ void PrintConfigDef::init_fff_params() "as if the PA profile is not set accurately, it will cause uniformity issues on the external surfaces before and after overhangs.\n"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBools{ false }); - + def = this->add("adaptive_pressure_advance_bridges", coFloats); def->label = L("Pressure advance for bridges"); def->tooltip = L("Pressure advance value for bridges. Set to 0 to disable. \n\n A lower PA value when printing bridges helps reduce the appearance of slight under extrusion " @@ -1815,7 +1815,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("If enable this setting, part cooling fan will never be stopped and will run at least " "at minimum speed to reduce the frequency of starting and stopping"); def->set_default_value(new ConfigOptionBools { false }); - + def = this->add("dont_slow_down_outer_wall", coBools); def->label = L("Don't slow down outer walls"); def->tooltip = L("If enabled, this setting will ensure external perimeters are not slowed down to meet the minimum layer time. " @@ -1912,20 +1912,20 @@ void PrintConfigDef::init_fff_params() /* Large format printers with print volumes in the order of 1m^3 generally use pellets for printing. - The overall tech is very similar to FDM printing. + The overall tech is very similar to FDM printing. It is FDM printing, but instead of filaments, it uses pellets. - The difference here is that where filaments have a filament_diameter that is used to calculate - the volume of filament ingested, pellets have a particular flow_coefficient that is empirically + The difference here is that where filaments have a filament_diameter that is used to calculate + the volume of filament ingested, pellets have a particular flow_coefficient that is empirically devised for that particular pellet. pellet_flow_coefficient is basically a measure of the packing density of a particular pellet. Shape, material and density of an individual pellet will determine the packing density and - the only thing that matters for 3d printing is how much of that pellet material is extruded by + the only thing that matters for 3d printing is how much of that pellet material is extruded by one turn of whatever feeding mehcanism/gear your printer uses. You can emperically derive that for your own pellets for a particular printer model. - We are translating the pellet_flow_coefficient into filament_diameter so that everything works just like it + We are translating the pellet_flow_coefficient into filament_diameter so that everything works just like it does already with very minor adjustments. filament_diameter = sqrt( (4 * pellet_flow_coefficient) / PI ) @@ -1954,7 +1954,7 @@ void PrintConfigDef::init_fff_params() def->min = 10; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercents{ 100 }); - + def = this->add("filament_shrinkage_compensation_z", coPercents); def->label = L("Shrinkage (Z)"); // xgettext:no-c-format, no-boost-format @@ -2090,7 +2090,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 10. }); - + def = this->add("filament_density", coFloats); def->label = L("Density"); def->tooltip = L("Filament density. For statistics only"); @@ -2317,7 +2317,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("1000 (unlimited)")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(20, false)); - + def = this->add("outer_wall_acceleration", coFloat); def->label = L("Outer wall"); def->tooltip = L("Acceleration of outer walls"); @@ -2398,7 +2398,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Klipper's max_accel_to_decel will be adjusted automatically"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); - + def = this->add("accel_to_decel_factor", coPercent); def->label = L("accel_to_decel"); def->tooltip = L("Klipper's max_accel_to_decel will be adjusted to this %% of acceleration"); @@ -2407,7 +2407,7 @@ void PrintConfigDef::init_fff_params() def->max = 100; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercent(50)); - + def = this->add("default_jerk", coFloat); def->label = L("Default"); def->tooltip = L("Default"); @@ -2549,7 +2549,7 @@ void PrintConfigDef::init_fff_params() def->max = 1000; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts { 0 }); - + def = this->add("support_material_interface_fan_speed", coInts); def->label = L("Support interface fan speed"); def->tooltip = L("This fan speed is enforced during all support interfaces, to be able to weaken their bonding with a high fan speed." @@ -2560,7 +2560,7 @@ void PrintConfigDef::init_fff_params() def->max = 100; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts{ -1 }); - + def = this->add("fuzzy_skin", coEnum); def->label = L("Fuzzy Skin"); @@ -2614,7 +2614,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("gap_infill_speed", coFloat); def->label = L("Gap infill"); def->category = L("Speed"); @@ -2735,12 +2735,6 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); - def = this->add("fan_speedup_overhangs", coBool); - def->label = L("Only overhangs"); - def->tooltip = L("Will only take into account the delay for the cooling of overhangs."); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(true)); - def = this->add("fan_kickstart", coFloat); def->label = L("Fan kick-start time"); def->tooltip = L("Emit a max fan speed command for this amount of seconds before reducing to target speed to kick-start the cooling fan." @@ -2841,7 +2835,7 @@ void PrintConfigDef::init_fff_params() "slow down."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(0)); - + //BBS def = this->add("infill_combination", coBool); def->label = L("Infill combination"); @@ -2850,7 +2844,7 @@ void PrintConfigDef::init_fff_params() "with original layer height."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - + // Orca: max layer height for combined infill def = this->add("infill_combination_max_layer_height", coFloatOrPercent); def->label = L("Infill combination - Max layer height"); @@ -2863,7 +2857,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(100., true)); - + def = this->add("sparse_infill_filament", coInt); def->gui_type = ConfigOptionDef::GUIType::i_enum_open; def->label = L("Infill"); @@ -2894,7 +2888,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "inner_wall_line_width"; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercent(15)); - + def = this->add("top_bottom_infill_wall_overlap", coPercent); def->label = L("Top/Bottom solid infill/wall overlap"); def->category = L("Strength"); @@ -2954,7 +2948,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Interlocking depth of a segmented region. It will be ignored if " "\"mmu_segmented_region_max_width\" is zero or if \"mmu_segmented_region_interlocking_depth\"" "is bigger then \"mmu_segmented_region_max_width\". Zero disables this feature."); - def->sidetext = L("mm"); + def->sidetext = L("mm"); def->min = 0; def->category = L("Advanced"); def->mode = comAdvanced; @@ -3038,7 +3032,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Rectilinear")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(ipRectilinear)); - + def = this->add("ironing_flow", coPercent); def->label = L("Ironing flow"); def->category = L("Quality"); @@ -3303,11 +3297,11 @@ void PrintConfigDef::init_fff_params() def = this->add("max_volumetric_extrusion_rate_slope", coFloat); def->label = L("Extrusion rate smoothing"); - def->tooltip = L("This parameter smooths out sudden extrusion rate changes that happen when " + def->tooltip = L("This parameter smooths out sudden extrusion rate changes that happen when " "the printer transitions from printing a high flow (high speed/larger width) " "extrusion to a lower flow (lower speed/smaller width) extrusion and vice versa.\n\n" "It defines the maximum rate by which the extruded volumetric flow in mm3/sec can change over time. " - "Higher values mean higher extrusion rate changes are allowed, resulting in faster speed transitions.\n\n" + "Higher values mean higher extrusion rate changes are allowed, resulting in faster speed transitions.\n\n" "A value of 0 disables the feature. \n\n" "For a high speed, high flow direct drive printer (like the Bambu lab or Voron) this value is usually not needed. " "However it can provide some marginal benefit in certain cases where feature speeds vary greatly. For example, " @@ -3321,7 +3315,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("max_volumetric_extrusion_rate_slope_segment_length", coInt); def->label = L("Smoothing segment length"); def->tooltip = L("A lower value results in smoother extrusion rate transitions. However, this results in a significantly larger gcode file " @@ -3422,7 +3416,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->cli = ConfigOptionDef::nocli; def->set_default_value(new ConfigOptionEnum(htOctoPrint)); - + def = this->add("nozzle_volume", coFloat); def->label = L("Nozzle volume"); @@ -3578,14 +3572,14 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 1000; def->set_default_value(new ConfigOptionInt(2)); - + def = this->add("alternate_extra_wall", coBool); def->label = L("Alternate extra wall"); def->category = L("Strength"); def->tooltip = L("This setting adds an extra wall to every other layer. This way the infill gets wedged vertically between the walls, resulting in stronger prints. \n\nWhen this option is enabled, the ensure vertical shell thickness option needs to be disabled. \n\nUsing lightning infill together with this option is not recommended as there is limited infill to anchor the extra perimeters to."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("post_process", coStrings); def->label = L("Post-processing Scripts"); def->tooltip = L("If you want to process the output G-code through custom scripts, " @@ -3598,7 +3592,7 @@ void PrintConfigDef::init_fff_params() def->height = 6; def->mode = comAdvanced; def->set_default_value(new ConfigOptionStrings()); - + def = this->add("printer_model", coString); //def->label = L("Printer type"); //def->tooltip = L("Type of the printer"); @@ -3615,7 +3609,7 @@ void PrintConfigDef::init_fff_params() def->height = 13; def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - + def = this->add("printer_variant", coString); //def->label = L("Printer variant"); def->label = L("Printer variant"); @@ -3909,7 +3903,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This option causes the inner seams to be shifted backwards based on their depth, forming a zigzag pattern."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("seam_gap", coFloatOrPercent); def->label = L("Seam gap"); def->tooltip = L("In order to reduce the visibility of the seam in a closed loop extrusion, the loop is interrupted and shortened by a specified amount.\n" @@ -4025,13 +4019,13 @@ void PrintConfigDef::init_fff_params() "e.g. if a wipe action is executed immediately following an outer wall extrusion, the speed of the outer wall extrusion will be utilized for the wipe action."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); - + def = this->add("wipe_on_loops", coBool); def->label = L("Wipe on loops"); def->tooltip = L("To minimize the visibility of the seam in a closed loop extrusion, a small inward movement is executed before the extruder leaves the loop."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - + def = this->add("wipe_before_external_loop", coBool); def->label = L("Wipe before external loop"); def->tooltip = L("To minimize visibility of potential overextrusion at the start of an external perimeter when printing with " @@ -4052,7 +4046,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(80,true)); - + def = this->add("skirt_distance", coFloat); def->label = L("Skirt distance"); def->tooltip = L("Distance from skirt to brim or object"); @@ -4106,7 +4100,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Per object")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(stCombined)); - + def = this->add("skirt_loops", coInt); def->label = L("Skirt loops"); def->full_label = L("Skirt loops"); @@ -4124,7 +4118,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(50.0)); - + def = this->add("min_skirt_length", coFloat); def->label = L("Skirt minimum extrusion length"); def->full_label = L("Skirt minimum extrusion length"); @@ -4353,7 +4347,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); - + def = this->add("enable_support", coBool); //BBS: remove material behind support def->label = L("Enable support"); @@ -4755,13 +4749,13 @@ void PrintConfigDef::init_fff_params() def->category = L("Quality"); def->tooltip = L("Enabling this option means the height of tree support layer except the first will be automatically calculated "); def->set_default_value(new ConfigOptionBool(1)); - + def = this->add("tree_support_auto_brim", coBool); def->label = L("Auto brim width"); def->category = L("Quality"); def->tooltip = L("Enabling this option means the width of the brim for tree support will be automatically calculated"); def->set_default_value(new ConfigOptionBool(1)); - + def = this->add("tree_support_brim_width", coFloat); def->label = L("Tree support brim width"); def->category = L("Quality"); @@ -4801,7 +4795,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(2.)); def = this->add("tree_support_branch_diameter_angle", coFloat); - // TRN PrintSettings: #lmFIXME + // TRN PrintSettings: #lmFIXME def->label = L("Branch Diameter Angle"); def->category = L("Support"); // TRN PrintSettings: "Organic supports" > "Branch Diameter Angle" @@ -5087,7 +5081,7 @@ void PrintConfigDef::init_fff_params() def->min = 0.; def->max = 90.; def->set_default_value(new ConfigOptionFloat(0.)); - + def = this->add("wipe_tower_max_purge_speed", coFloat); def->label = L("Maximum wipe tower print speed"); def->tooltip = L("The maximum print speed when purging in the wipe tower and printing the wipe tower sparse layers. " @@ -6220,7 +6214,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va } else if (opt_key == "sparse_infill_anchor") { opt_key = "infill_anchor"; - } + } else if (opt_key == "sparse_infill_anchor_max") { opt_key = "infill_anchor_max"; } @@ -6253,7 +6247,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va static std::set ignore = { "acceleration", "scale", "rotate", "duplicate", "duplicate_grid", "bed_size", - "print_center", "g0", "wipe_tower_per_color_wipe", + "print_center", "g0", "wipe_tower_per_color_wipe", "support_sharp_tails","support_remove_small_overhangs", "support_with_sheath", "tree_support_collision_resolution", "tree_support_with_infill", "max_volumetric_speed", "max_print_speed", @@ -6761,7 +6755,7 @@ std::map validate(const FullPrintConfig &cfg, bool und for (unsigned char wipe : cfg.wipe.values) if (wipe) error_message.emplace("use_firmware_retraction", "--use-firmware-retraction is not compatible with --wipe"); - + // --gcode-flavor if (! print_config_def.get("gcode_flavor")->has_enum_value(cfg.gcode_flavor.serialize())) { error_message.emplace("gcode_flavor", L("invalid value ") + cfg.gcode_flavor.serialize()); @@ -6796,7 +6790,7 @@ std::map validate(const FullPrintConfig &cfg, bool und if (cfg.bridge_flow <= 0) { error_message.emplace("bridge_flow", L("invalid value ") + std::to_string(cfg.bridge_flow)); } - + // --bridge-flow-ratio if (cfg.bridge_flow <= 0) { error_message.emplace("internal_bridge_flow", L("invalid value ") + std::to_string(cfg.internal_bridge_flow)); @@ -7299,7 +7293,7 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->tooltip = "the machine settings list need to do downward checking"; def->cli_params = "\"machine1.json;machine2.json;...\""; def->set_default_value(new ConfigOptionStrings()); - + def = this->add("load_assemble_list", coString); def->label = "Load assemble list"; def->tooltip = "Load assemble object list from config file"; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 18f007a40ad..e548ae17d79 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -264,7 +264,7 @@ enum BedType { // BBS enum LayerSeq { - flsAuto, + flsAuto, flsCutomize }; @@ -870,7 +870,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, initial_layer_jerk)) ((ConfigOptionFloat, travel_jerk)) ((ConfigOptionBool, precise_z_height)) - + ((ConfigOptionBool, interlocking_beam)) ((ConfigOptionFloat,interlocking_beam_width)) ((ConfigOptionFloat,interlocking_orientation)) @@ -1039,8 +1039,8 @@ PRINT_CONFIG_CLASS_DEFINE( PRINT_CONFIG_CLASS_DEFINE( GCodeConfig, - ((ConfigOptionString, before_layer_change_gcode)) - ((ConfigOptionString, printing_by_object_gcode)) + ((ConfigOptionString, before_layer_change_gcode)) + ((ConfigOptionString, printing_by_object_gcode)) ((ConfigOptionFloats, deretraction_speed)) //BBS ((ConfigOptionBool, enable_arc_fitting)) @@ -1056,7 +1056,6 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, adaptive_pressure_advance_bridges)) // ((ConfigOptionFloat, fan_kickstart)) - ((ConfigOptionBool, fan_speedup_overhangs)) ((ConfigOptionFloat, fan_speedup_time)) ((ConfigOptionFloats, filament_diameter)) ((ConfigOptionFloats, filament_density)) @@ -1076,7 +1075,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionBool, bbl_bed_temperature_gcode)) ((ConfigOptionEnum, gcode_flavor)) - ((ConfigOptionFloat, time_cost)) + ((ConfigOptionFloat, time_cost)) ((ConfigOptionString, layer_change_gcode)) ((ConfigOptionString, time_lapse_gcode)) @@ -1309,7 +1308,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionBools, activate_chamber_temp_control)) ((ConfigOptionInts , chamber_temperature)) - + // Orca: support adaptive bed mesh ((ConfigOptionFloat, preferred_orientation)) ((ConfigOptionPoint, bed_mesh_min)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 05b741bcb56..dd5a3d35fb6 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1413,7 +1413,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } - if (opt_key == "pellet_flow_coefficient") + if (opt_key == "pellet_flow_coefficient") { double double_value = Preset::convert_pellet_flow_to_filament_diameter(boost::any_cast(value)); m_config->set_key_value("filament_diameter", new ConfigOptionFloats{double_value}); @@ -1423,7 +1423,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) double double_value = Preset::convert_filament_diameter_to_pellet_flow(boost::any_cast(value)); m_config->set_key_value("pellet_flow_coefficient", new ConfigOptionFloats{double_value}); } - + if (opt_key == "single_extruder_multi_material" ){ const auto bSEMM = m_config->opt_bool("single_extruder_multi_material"); @@ -1570,7 +1570,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } } } - + if(opt_key=="layer_height"){ auto min_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option("min_layer_height")->values; auto max_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option("max_layer_height")->values; @@ -1638,7 +1638,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "filament_long_retractions_when_cut"){ unsigned char activate = boost::any_cast(value); if (activate == 1) { - MessageDialog dialog(wxGetApp().plater(), + MessageDialog dialog(wxGetApp().plater(), _L("Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush." "Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications.Please use with the latest printer firmware."), "", wxICON_WARNING | wxOK); dialog.ShowModal(); @@ -2096,7 +2096,7 @@ void TabPrint::build() option.opt.is_code = true; option.opt.height = 15; optgroup->append_single_option_line(option, "small-area-infill-flow-compensation"); - + optgroup = page->new_optgroup(L("Bridging"), L"param_bridge"); optgroup->append_single_option_line("bridge_flow"); optgroup->append_single_option_line("internal_bridge_flow"); @@ -2105,7 +2105,7 @@ void TabPrint::build() optgroup->append_single_option_line("thick_internal_bridges"); optgroup->append_single_option_line("dont_filter_internal_bridges"); optgroup->append_single_option_line("counterbore_hole_bridging","counterbore-hole-bridging"); - + optgroup = page->new_optgroup(L("Overhangs"), L"param_overhang"); optgroup->append_single_option_line("detect_overhang_wall"); optgroup->append_single_option_line("make_overhang_printable"); @@ -2211,7 +2211,7 @@ void TabPrint::build() optgroup->append_single_option_line("top_surface_jerk"); optgroup->append_single_option_line("initial_layer_jerk"); optgroup->append_single_option_line("travel_jerk"); - + optgroup = page->new_optgroup(L("Advanced"), L"param_advanced", 15); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope", "extrusion-rate-smoothing"); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_segment_length", "extrusion-rate-smoothing"); @@ -2240,7 +2240,7 @@ void TabPrint::build() //optgroup = page->new_optgroup(L("Options for support material and raft")); - // Support + // Support optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); optgroup->append_single_option_line("support_top_z_distance", "support#top-z-distance"); optgroup->append_single_option_line("support_bottom_z_distance", "support#bottom-z-distance"); @@ -2276,7 +2276,7 @@ void TabPrint::build() optgroup->append_single_option_line("tree_support_adaptive_layer_height"); optgroup->append_single_option_line("tree_support_auto_brim"); optgroup->append_single_option_line("tree_support_brim_width"); - + page = add_options_page(L("Multimaterial"), "custom-gcode_multi_material"); // ORCA: icon only visible on placeholders optgroup = page->new_optgroup(L("Prime tower"), L"param_tower"); optgroup->append_single_option_line("enable_prime_tower"); @@ -2328,7 +2328,7 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v optgroup->append_single_option_line("skirt_height"); optgroup->append_single_option_line("skirt_speed"); optgroup->append_single_option_line("draft_shield"); - + optgroup = page->new_optgroup(L("Brim"), L"param_adhension"); optgroup->append_single_option_line("brim_type", "auto-brim"); optgroup->append_single_option_line("brim_width", "auto-brim#manual"); @@ -2362,7 +2362,7 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v option.opt.multiline = true; // option.opt.height = 5; optgroup->append_single_option_line(option); - + optgroup = page->new_optgroup(L("Post-processing Scripts"), L"param_gcode", 0); option = optgroup->get_option("post_process"); option.opt.full_width = true; @@ -2375,7 +2375,7 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v option.opt.full_width = true; option.opt.height = 25;//250; optgroup->append_single_option_line(option); - + #if 0 //page = add_options_page(L("Dependencies"), "advanced.png"); // optgroup = page->new_optgroup(L("Profile dependencies")); @@ -2793,7 +2793,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("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"); @@ -2944,7 +2944,7 @@ void TabPrintPlate::notify_changed(ObjectBase* object) for (auto item : items) { if (objects_list->GetModel()->GetItemType(item) == itPlate) { ObjectDataViewModelNode* node = static_cast(item.GetID()); - if (node) + if (node) node->set_action_icon(!m_all_keys.empty()); } } @@ -2952,7 +2952,7 @@ void TabPrintPlate::notify_changed(ObjectBase* object) void TabPrintPlate::update_custom_dirty() { - for (auto k : m_null_keys) + for (auto k : m_null_keys) m_options_list[k] = 0; for (auto k : m_all_keys) { if (k == "first_layer_sequence_choice" || k == "other_layers_sequence_choice") { @@ -3197,9 +3197,9 @@ void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* print std::vector opt_keys = { "filament_retraction_length", "filament_z_hop", - "filament_z_hop_types", + "filament_z_hop_types", "filament_retract_lift_above", - "filament_retract_lift_below", + "filament_retract_lift_below", "filament_retract_lift_enforce", "filament_retraction_speed", "filament_deretraction_speed", @@ -3313,7 +3313,7 @@ void TabFilament::build() optgroup->append_single_option_line("adaptive_pressure_advance"); optgroup->append_single_option_line("adaptive_pressure_advance_overhangs"); optgroup->append_single_option_line("adaptive_pressure_advance_bridges"); - + option = optgroup->get_option("adaptive_pressure_advance_model"); option.opt.full_width = true; option.opt.is_code = true; @@ -3597,7 +3597,7 @@ void TabFilament::toggle_options() toggle_option(el, has_enable_overhang_bridge_fan); toggle_option("additional_cooling_fan_speed", cfg.opt_bool("auxiliary_fan")); - + // Orca: toggle dont slow down for external perimeters if bool has_slow_down_for_layer_cooling = m_config->opt_bool("slow_down_for_layer_cooling", 0); toggle_option("dont_slow_down_outer_wall", has_slow_down_for_layer_cooling); @@ -3611,7 +3611,7 @@ void TabFilament::toggle_options() toggle_line("textured_cool_plate_temp_initial_layer", support_multi_bed_types); toggle_line("eng_plate_temp_initial_layer", support_multi_bed_types); toggle_line("textured_plate_temp_initial_layer", support_multi_bed_types); - + // Orca: adaptive pressure advance and calibration model // If PA is not enabled, disable adaptive pressure advance and hide the model section // If adaptive PA is not enabled, hide the adaptive PA model section @@ -3791,11 +3791,10 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("use_firmware_retraction"); // optgroup->append_single_option_line("spaghetti_detector"); optgroup->append_single_option_line("time_cost"); - + optgroup = page->new_optgroup(L("Cooling Fan"), "param_cooling_fan"); Line line = Line{ L("Fan speed-up time"), optgroup->get_option("fan_speedup_time").opt.tooltip }; line.append_option(optgroup->get_option("fan_speedup_time")); - line.append_option(optgroup->get_option("fan_speedup_overhangs")); optgroup->append_line(line); optgroup->append_single_option_line("fan_kickstart"); @@ -3854,8 +3853,8 @@ void TabPrinter::build_fff() option.opt.is_code = true; option.opt.height = gcode_field_height; // 150; optgroup->append_single_option_line(option); - - + + optgroup = page->new_optgroup(L("Before layer change G-code"),"param_gcode", 0); optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { validate_custom_gcode_cb(this, optgroup_title, opt_key, value); @@ -3877,7 +3876,7 @@ void TabPrinter::build_fff() option.opt.is_code = true; option.opt.height = gcode_field_height;//150; optgroup->append_single_option_line(option); - + optgroup = page->new_optgroup(L("Time lapse G-code"), L"param_gcode", 0); optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { validate_custom_gcode_cb(this, optgroup_title, opt_key, value); @@ -4597,7 +4596,7 @@ void TabPrinter::toggle_options() toggle_option("long_retractions_when_cut", !use_firmware_retraction && m_config->opt_int("enable_long_retraction_when_cut"),i); toggle_line("retraction_distances_when_cut#0", m_config->opt_bool("long_retractions_when_cut", i)); //toggle_option("retraction_distances_when_cut", m_config->opt_bool("long_retractions_when_cut",i),i); - + toggle_option("travel_slope", m_config->opt_enum("z_hop_types", i) != ZHopType::zhtNormal, i); } @@ -5002,13 +5001,13 @@ bool Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, try { //BBS delete preset Preset ¤t_preset = m_presets->get_selected_preset(); - + // Obtain compatible filament and process presets for printers if (m_preset_bundle && m_presets->get_preset_base(current_preset) == ¤t_preset && printer_tab && !current_preset.is_system) { delete_third_printer = true; for (const Preset &preset : m_preset_bundle->filaments.get_presets()) { if (preset.is_compatible && !preset.is_default) { - if (preset.inherits() != "") + if (preset.inherits() != "") filament_presets.push_front(preset); else filament_presets.push_back(preset); @@ -5138,7 +5137,7 @@ bool Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, }); } - + } if (technology_changed) @@ -5735,7 +5734,7 @@ void Tab::delete_preset() //wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) wxID_YES == MessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())) return; - + // if we just delete preset from the physical printer if (m_presets_choice->is_selected_physical_printer()) { PhysicalPrinter& printer = physical_printers.get_selected_printer(); @@ -5944,7 +5943,7 @@ void TabPrinter::cache_extruder_cnt(const DynamicPrintConfig* config/* = nullptr if (Preset::printer_technology(cached_config) == ptSLA) return; - // get extruders count + // get extruders count auto* nozzle_diameter = dynamic_cast(cached_config.option("nozzle_diameter")); m_cache_extruder_count = nozzle_diameter->values.size(); //m_extruders_count; }