diff --git a/src/libslic3r/BeltGCode.cpp b/src/libslic3r/BeltGCode.cpp index 4082db66e9..20b19e41b0 100644 --- a/src/libslic3r/BeltGCode.cpp +++ b/src/libslic3r/BeltGCode.cpp @@ -8,14 +8,10 @@ namespace Slic3r { void BeltGCode::init_belt_writer(Print &print) { - auto belt_writer = std::make_unique(); // Axis remap and build volume max are set by base GCode after init_belt_writer // returns; set_kinematics() replays them, so install order does not matter. - install_belt_kinematics(*belt_writer, print.config()); - belt_writer->set_force_normal_lift(true); - // The plate origin was stored on the writer this one replaces. - belt_writer->set_xy_offset(m_gcode_offset.x(), m_gcode_offset.y()); - m_writer = std::move(belt_writer); + install_belt_kinematics(m_writer, print.config()); + m_writer.set_force_normal_lift(true); } void BeltGCode::write_belt_header(GCodeOutputStream &file, const Print &print) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index d2fbea5742..677b115530 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1069,7 +1069,7 @@ static std::vector get_path_of_change_filament(const Print& print) //BBS: if needed, write the gcode_label_objects_end then priming tower, if the retract, didn't did it. std::string object_end_label_temp; - gcodegen.m_writer->add_object_end_labels(object_end_label_temp); + gcodegen.m_writer.add_object_end_labels(object_end_label_temp); // Process the custom change_filament_gcode. If it is empty, provide a simple Tn command to change the filament. // Otherwise, leave control to the user completely. @@ -1138,7 +1138,7 @@ static std::vector get_path_of_change_filament(const Print& print) // config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); // BBS { - GCodeWriter& gcode_writer = *gcodegen.m_writer; + GCodeWriter& gcode_writer = gcodegen.m_writer; FullPrintConfig& full_config = gcodegen.m_config; // Per-variant filament arrays can hold one column per variant a filament uses @@ -2002,9 +2002,9 @@ static std::vector get_path_of_change_filament(const Print& print) const std::vector ColorPrintColors::Colors = { "#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6" }; -#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer->filament()->extruder_id()) -#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(get_filament_config_index(m_writer->filament()->id())) -#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(get_nozzle_config_index(m_writer->filament()->id())) +#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->extruder_id()) +#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(get_filament_config_index(m_writer.filament()->id())) +#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(get_nozzle_config_index(m_writer.filament()->id())) void GCode::PlaceholderParserIntegration::reset() { @@ -2492,7 +2492,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu BOOST_LOG_TRIVIAL(info) << boost::format("Will export G-code to %1% soon")%path; GCodeProcessor::s_IsBBLPrinter = print->is_BBL_printer(); - m_writer->set_is_bbl_machine(print->is_BBL_printer()); + m_writer.set_is_bbl_machine(print->is_BBL_printer()); print->set_started(psGCodeExport); // check if any custom gcode contains keywords used by the gcode processor to @@ -2589,7 +2589,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu m_processor.result().support_traditional_timelapse = m_support_traditional_timelapse; bool activate_long_retraction_when_cut = false; - for (const auto& filament : m_writer->extruders()) { + for (const auto& filament : m_writer.extruders()) { size_t fi = get_filament_config_index((int)filament.id()); activate_long_retraction_when_cut |= ( m_config.long_retractions_when_cut.get_at(fi) @@ -2629,7 +2629,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu m_processor.finalize(true); // DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics); - DoExport::update_print_estimated_stats(m_processor, m_writer->extruders(), print->m_print_statistics, print->config()); + DoExport::update_print_estimated_stats(m_processor, m_writer.extruders(), print->m_print_statistics, print->config()); // Printed-mass safety check. Flushed filament leaves the bed, so subtract it // from the total to get the mass actually resting on the plate. Gated on machine_max_printed_mass // (>0 only for A2L machines), so no existing printer's gcode_check_result changes. @@ -2637,8 +2637,8 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu double mass_on_bed_total = print->m_print_statistics.total_weight; for (auto volume : m_processor.get_result().print_statistics.flush_per_filament) { size_t extruder_id = volume.first; - auto extruder = std::find_if(m_writer->extruders().begin(), m_writer->extruders().end(), [extruder_id](const Extruder &extr) { return extr.id() == extruder_id; }); - if (extruder == m_writer->extruders().end()) continue; + auto extruder = std::find_if(m_writer.extruders().begin(), m_writer.extruders().end(), [extruder_id](const Extruder &extr) { return extr.id() == extruder_id; }); + if (extruder == m_writer.extruders().end()) continue; mass_on_bed_total -= (volume.second * extruder->filament_density() * 0.001); } // flushed weight will not be keeped on the hot bed, exclude it if (mass_on_bed_total > m_print->config().machine_max_printed_mass.value) { @@ -2939,7 +2939,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato PROFILE_FUNC(); m_print = &print; - m_timelapse_pos_picker.init(&print,m_writer->get_xy_offset().cast()); + m_timelapse_pos_picker.init(&print,m_writer.get_xy_offset().cast()); // init as filament map update_layer_related_config(0); @@ -2964,7 +2964,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Belt printer: initialize belt-specific writer via virtual hook. this->init_belt_writer(print); - m_writer->set_is_bbl_machine(is_bbl_printers); + m_writer.set_is_bbl_machine(is_bbl_printers); // Standalone axis remap (works with or without belt mode). // Sync the writer's remap state to the current export UNCONDITIONALLY — even at @@ -2975,9 +2975,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato int rx = int(print.config().gcode_remap_x.value); int ry = int(print.config().gcode_remap_y.value); int rz = int(print.config().gcode_remap_z.value); - m_writer->set_axis_remap(rx, ry, rz); + m_writer.set_axis_remap(rx, ry, rz); BoundingBoxf bbox_bed(print.config().printable_area.values); - m_writer->set_build_volume_max(Vec3d(bbox_bed.max.x(), bbox_bed.max.y(), + m_writer.set_build_volume_max(Vec3d(bbox_bed.max.x(), bbox_bed.max.y(), print.config().printable_height.value)); } @@ -2990,7 +2990,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // per-point (see GCodeWriter::uses_pointwise_travel_speed()), which must not // change for non-belt printers. if (print.config().belt_printer.value) { - m_writer->set_first_layer_plane( + m_writer.set_first_layer_plane( m_first_layer_plane.get(), print.config().initial_layer_print_height.value); } @@ -3362,13 +3362,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Disable fan. if (m_config.auxiliary_fan.value && print.config().close_fan_the_first_x_layers.get_at(initial_extruder_id)) { - file.write(m_writer->set_fan(0)); + file.write(m_writer.set_fan(0)); //BBS: disable additional fan - file.write(m_writer->set_additional_fan(0)); + file.write(m_writer.set_additional_fan(0)); } // Update output variables after the extruders were initialized. - m_placeholder_parser_integration.init(*m_writer); + m_placeholder_parser_integration.init(m_writer); // Let the start-up script prime the 1st printing tool. @@ -3482,7 +3482,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato { BoundingBoxf bbox_bed(print.config().printable_area.values); - Vec2f plate_offset = m_writer->get_xy_offset(); + Vec2f plate_offset = m_writer.get_xy_offset(); this->placeholder_parser().set("print_bed_min", new ConfigOptionFloats({ bbox_bed.min.x(), bbox_bed.min.y()})); this->placeholder_parser().set("print_bed_max", new ConfigOptionFloats({ bbox_bed.max.x(), bbox_bed.max.y()})); this->placeholder_parser().set("print_bed_size", new ConfigOptionFloats({ bbox_bed.size().x(), bbox_bed.size().y() })); @@ -3601,7 +3601,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } bool activate_chamber_temp_control = false; auto max_chamber_temp = 0; - for (const auto &extruder : m_writer->extruders()) { + for (const auto &extruder : m_writer.extruders()) { activate_chamber_temp_control |= m_config.activate_chamber_temp_control.get_at(extruder.id()); max_chamber_temp = std::max(max_chamber_temp, m_config.chamber_temperature.get_at(extruder.id())); } @@ -3609,7 +3609,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato BedType curr_bed_type = m_config.curr_bed_type; int min_temperature_vitrification = std::numeric_limits::max(); - for (const auto& extruder : m_writer->extruders()) + for (const auto& extruder : m_writer.extruders()) min_temperature_vitrification = std::min(min_temperature_vitrification, m_config.temperature_vitrification.get_at(extruder.id())); @@ -3729,7 +3729,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato if (activate_chamber_temp_control && max_chamber_temp > 0){ int temp_out =0; if(!custom_gcode_sets_temperature(machine_start_gcode,141,191,false,temp_out)) - file.write(m_writer->set_chamber_temperature(max_chamber_temp, true)); // set chamber_temperature + file.write(m_writer.set_chamber_temperature(max_chamber_temp, true)); // set chamber_temperature } // Write the custom start G-code @@ -3743,11 +3743,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write_format(";%s\n", GCodeProcessor::Machine_Start_GCode_End_Tag.c_str()); //BBS: gcode writer doesn't know where the real position of extruder is after inserting custom gcode - m_writer->set_current_position_clear(false); + m_writer.set_current_position_clear(false); m_start_gcode_filament = GCodeProcessor::get_gcode_last_filament(machine_start_gcode); if (is_bbl_printers) { - m_writer->init_extruder(initial_non_support_extruder_id); + m_writer.init_extruder(initial_non_support_extruder_id); // add the missing filament start gcode in machine start gcode { DynamicConfig config; @@ -3776,7 +3776,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } // Orca: add missing PA settings for initial filament if (m_config.enable_pressure_advance.get_at(initial_non_support_extruder_id)) { - file.write(m_writer->set_pressure_advance(m_config.pressure_advance.get_at(initial_non_support_extruder_id))); + file.write(m_writer.set_pressure_advance(m_config.pressure_advance.get_at(initial_non_support_extruder_id))); // Orca: Adaptive PA // Reset Adaptive PA processor last PA value m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(initial_non_support_extruder_id)); @@ -3806,7 +3806,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato int during_print_exhaust_fan_speed = 0; // Orca: when activate_air_filtration is set on any extruder, find and set the highest during_print_exhaust_fan_speed - for (const auto &extruder : m_writer->extruders()) { + for (const auto &extruder : m_writer.extruders()) { size_t fi = get_filament_config_index((int)extruder.id()); if (m_config.activate_air_filtration.get_at(fi) && m_config.activate_air_filtration_during_print.get_at(fi)) { activate_air_filtration_during_print = true; @@ -3816,7 +3816,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } if (activate_air_filtration_during_print) - file.write(m_writer->set_exhaust_fan(during_print_exhaust_fan_speed)); + file.write(m_writer.set_exhaust_fan(during_print_exhaust_fan_speed)); } print.throw_if_canceled(); @@ -3833,7 +3833,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_seam_placer.init(print, throw_if_canceled_func); // BBS: get path for change filament - if (m_writer->multiple_extruders) { + if (m_writer.multiple_extruders) { std::vector points = get_path_of_change_filament(print); if (points.size() == 3) { travel_point_1 = points[0]; @@ -3870,12 +3870,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato std::string gcode; gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n"; if ((NOZZLE_CONFIG(outer_wall_acceleration) > 0 && NOZZLE_CONFIG(outer_wall_acceleration) > 0)) { - gcode += m_writer->set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5)); + gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5)); } if (NOZZLE_CONFIG(outer_wall_jerk) > 0) { double jerk = NOZZLE_CONFIG(outer_wall_jerk); - gcode += m_writer->set_jerk_xy(jerk); + gcode += m_writer.set_jerk_xy(jerk); } auto params = print.calib_params(); @@ -3895,10 +3895,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // belt plane, not the slicing plane. const bool belt_world_coords = print.config().belt_printer.value; if (belt_world_coords) - install_belt_kinematics(*m_writer, print.config(), /*world_coordinates=*/true); + install_belt_kinematics(m_writer, print.config(), /*world_coordinates=*/true); gcode += pa_test.generate_test(params.start, params.step, std::llround(std::ceil((params.end - params.start) / params.step)) + 1); if (belt_world_coords) - install_belt_kinematics(*m_writer, print.config(), /*world_coordinates=*/false); + install_belt_kinematics(m_writer, print.config(), /*world_coordinates=*/false); file.write(gcode); } else { @@ -3946,7 +3946,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer m_avoid_crossing_perimeters.use_external_mp_once(); // BBS. change tool before moving to origin point. - if (m_writer->need_toolchange(initial_extruder_id)) { + if (m_writer.need_toolchange(initial_extruder_id)) { const PrintObjectConfig& object_config = object.config(); coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value; @@ -3959,7 +3959,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } else { file.write(this->retract()); } - file.write(m_writer->travel_to_z(m_max_layer_z + m_writer->config.z_hop.get_at(get_filament_config_index((int)initial_extruder_id)))); + file.write(m_writer.travel_to_z(m_max_layer_z + m_writer.config.z_hop.get_at(get_filament_config_index((int)initial_extruder_id)))); file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); m_enable_cooling_markers = true; // Disable motion planner when traveling to first object point. @@ -3999,7 +3999,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato { const auto plr_mode = print.config().enable_power_loss_recovery.value; if (m_second_layer_things_done && plr_mode == PowerLossRecoveryMode::Enable) { - file.write(m_writer->enable_power_loss_recovery(PowerLossRecoveryMode::Disable)); + file.write(m_writer.enable_power_loss_recovery(PowerLossRecoveryMode::Disable)); } } ++ finished_objects; @@ -4020,7 +4020,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_wipe_tower->set_wipe_tower_bbx(print.get_wipe_tower_bbx()); m_wipe_tower->set_rib_offset(print.get_rib_offset()); //BBS - file.write(m_writer->travel_to_z(initial_layer_print_height + m_config.z_offset.value, "Move to the first layer height")); + file.write(m_writer.travel_to_z(initial_layer_print_height + m_config.z_offset.value, "Move to the first layer height")); if (wipe_tower_type == WipeTowerType::Type2 && print.config().single_extruder_multi_material_priming) { file.write(m_wipe_tower->prime(*this)); @@ -4079,7 +4079,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Orca: disable power loss recovery if (m_second_layer_things_done && print.config().enable_power_loss_recovery.value == PowerLossRecoveryMode::Enable) { - file.write(m_writer->enable_power_loss_recovery(PowerLossRecoveryMode::Disable)); + file.write(m_writer.enable_power_loss_recovery(PowerLossRecoveryMode::Disable)); } if (m_wipe_tower) // Purge the extruder, pull out the active filament. @@ -4093,14 +4093,14 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // if needed, write the gcode_label_objects_end { std::string gcode; - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); file.write(gcode); } - file.write(m_writer->set_fan(0)); + file.write(m_writer.set_fan(0)); //BBS: make sure the additional fan is closed when end if(m_config.auxiliary_fan.value) - file.write(m_writer->set_additional_fan(0)); + file.write(m_writer.set_additional_fan(0)); if (is_bbl_printers) { //BBS: close spaghetti detector //Note: M981 is also used to tell xcam the last layer is finished, so we need always send it even if spaghetti option is disabled. @@ -4122,14 +4122,14 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato DynamicConfig config; config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); //BBS - config.set_key_value("layer_z", new ConfigOptionFloat(m_writer->get_position()(2) - m_config.z_offset.value)); + config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); if (print.config().single_extruder_multi_material) { // Process the filament_end_gcode for the active filament only. - int extruder_id = m_writer->filament()->id(); + int extruder_id = m_writer.filament()->id(); config.set_key_value("filament_extruder_id", new ConfigOptionInt(extruder_id)); config.set_key_value("current_filament_id", new ConfigOptionInt(extruder_id)); config.set_key_value("current_extruder_id", new ConfigOptionInt((int) get_extruder_id(extruder_id))); @@ -4145,13 +4145,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.writeln(this->placeholder_parser_process("filament_end_gcode", end_gcode, extruder_id, &config)); } } - file.writeln(this->placeholder_parser_process("machine_end_gcode", print.config().machine_end_gcode, m_writer->filament()->id(), &config)); + file.writeln(this->placeholder_parser_process("machine_end_gcode", print.config().machine_end_gcode, m_writer.filament()->id(), &config)); } - file.write(m_writer->update_progress(m_layer_count, m_layer_count, true)); // 100% - file.write(m_writer->postamble()); + file.write(m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% + file.write(m_writer.postamble()); if (activate_chamber_temp_control && max_chamber_temp > 0) - file.write(m_writer->set_chamber_temperature(0, false)); //close chamber_temperature + file.write(m_writer.set_chamber_temperature(0, false)); //close chamber_temperature // Orca: when air filtration is supported, check if it needs to be activated after print completion and set the exhaust fan speed accordingly if (m_config.support_air_filtration.value) { @@ -4159,7 +4159,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato int complete_print_exhaust_fan_speed = 0; // Orca: when activate_air_filtration is set on any extruder, find and set the highest complete_print_exhaust_fan_speed - for (const auto& extruder : m_writer->extruders()) { + for (const auto& extruder : m_writer.extruders()) { size_t fi = get_filament_config_index((int)extruder.id()); if (m_config.activate_air_filtration.get_at(fi) && m_config.activate_air_filtration_on_completion.get_at(fi)) { activate_air_filtration_on_completion = true; @@ -4168,7 +4168,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } if (activate_air_filtration_on_completion) - file.write(m_writer->set_exhaust_fan(complete_print_exhaust_fan_speed)); + file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed)); } // adds tags for time estimators @@ -4181,7 +4181,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write(DoExport::update_print_stats_and_format_filament_stats( // Const inputs has_wipe_tower, print.wipe_tower_data(), - m_writer->extruders(), + m_writer.extruders(), // Modifies print.m_print_statistics, // Const input (tool-change fallback for non-wipe-tower prints) @@ -4320,8 +4320,8 @@ void GCode::check_placeholder_parser_failed() size_t GCode::cur_extruder_index() const { //TODO: check if the function is duplicated - //just return m_writer->filament()->extruder_id() - return get_extruder_id(m_writer->filament()->id()); + //just return m_writer.filament()->extruder_id() + return get_extruder_id(m_writer.filament()->id()); } size_t GCode::get_extruder_id(unsigned int filament_id) const @@ -4422,7 +4422,7 @@ void GCode::process_layers( ); const auto fan_mover = tbb::make_filter(slic3r_tbb_filtermode::serial_in_order, - [&fan_mover = this->m_fan_mover, &config = this->config(), &writer = *this->m_writer](std::string in)->std::string { + [&fan_mover = this->m_fan_mover, &config = this->config(), &writer = this->m_writer](std::string in)->std::string { CNumericLocalesSetter locales_setter; @@ -4522,7 +4522,7 @@ void GCode::process_layers( ); const auto fan_mover = tbb::make_filter(slic3r_tbb_filtermode::serial_in_order, - [&fan_mover = this->m_fan_mover, &config = this->config(), &writer = *this->m_writer](std::string in)->std::string { + [&fan_mover = this->m_fan_mover, &config = this->config(), &writer = this->m_writer](std::string in)->std::string { if (config.fan_speedup_time.value != 0 || config.fan_kickstart.value > 0) { if (fan_mover.get() == nullptr) @@ -4590,26 +4590,26 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std PlaceholderParserIntegration &ppi = m_placeholder_parser_integration; try { - ppi.update_from_gcodewriter(*m_writer); + ppi.update_from_gcodewriter(m_writer); std::string output = ppi.parser.process(templ, current_filament_id, config_override, &ppi.output_config, &ppi.context); ppi.validate_output_vector_variables(); const CustomGCodeMotionStateChanges motion_state_changes = custom_gcode_motion_state_changes(output); if (motion_state_changes.acceleration) - m_writer->invalidate_acceleration(); + m_writer.invalidate_acceleration(); if (motion_state_changes.jerk) - m_writer->invalidate_jerk(); + m_writer.invalidate_jerk(); if (const std::vector &pos = ppi.opt_position->values; ppi.position != pos) { // Update G-code writer. - m_writer->set_position({ pos[0], pos[1], pos[2] }); + m_writer.set_position({ pos[0], pos[1], pos[2] }); this->set_last_pos(this->gcode_to_point({ pos[0], pos[1] })); } - for (const Extruder &e : m_writer->extruders()) { + for (const Extruder &e : m_writer.extruders()) { unsigned int eid = e.id(); assert(eid < ppi.num_extruders); 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])) + 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]) || ! is_approx(ppi.e_restart_extra[eid], ppi.opt_e_restart_extra->values[eid])) @@ -4646,7 +4646,7 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print) // Get all physical tool ids current print will use std::unordered_set used_extruders; - for (const auto& extruder : m_writer->extruders()) { + for (const auto& extruder : m_writer.extruders()) { used_extruders.insert(extruder.extruder_id()); } @@ -4770,9 +4770,9 @@ void GCode::_print_first_layer_bed_temperature(GCodeOutputStream &file, Print &p temp = temp_by_gcode; #endif - // Always call m_writer->set_bed_temperature() so it will set the internal "current" state of the bed temp as if + // Always call m_writer.set_bed_temperature() so it will set the internal "current" state of the bed temp as if // the custom start G-code emited these. - std::string set_temp_gcode = m_writer->set_bed_temperature(bed_temp, wait); + std::string set_temp_gcode = m_writer.set_bed_temperature(bed_temp, wait); if (! temp_set_by_gcode) file.write(set_temp_gcode); } @@ -4792,14 +4792,14 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr int temp = print.config().nozzle_temperature_initial_layer.get_at(get_filament_config_index((int)first_printing_extruder_id)); if (temp_by_gcode >= 0 && temp_by_gcode < 1000) temp = temp_by_gcode; - m_writer->set_temperature(temp, wait, first_printing_extruder_id); + m_writer.set_temperature(temp, wait, first_printing_extruder_id); } else { // Custom G-code does not set the extruder temperature. Do it now. if (print.config().single_extruder_multi_material.value) { // Set temperature of the first printing extruder only. int temp = print.config().nozzle_temperature_initial_layer.get_at(get_filament_config_index((int)first_printing_extruder_id)); if (temp > 0) - file.write(m_writer->set_temperature(temp, wait, first_printing_extruder_id)); + file.write(m_writer.set_temperature(temp, wait, first_printing_extruder_id)); } else { // Set temperatures of all the printing extruders. for (unsigned int tool_id : print.extruders()) { @@ -4811,7 +4811,7 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr temp = print.config().idle_temperature.get_at(tool_id); } if (temp > 0) - file.write(m_writer->set_temperature(temp, wait, tool_id)); + file.write(m_writer.set_temperature(temp, wait, tool_id)); } } } @@ -5343,7 +5343,7 @@ LayerResult GCode::process_belt_brim_layer( std::string gcode; const unsigned int extruder_id = layer_tools.extruders.front(); - if (m_writer->filament() == nullptr || m_writer->filament()->id() != extruder_id) + if (m_writer.filament() == nullptr || m_writer.filament()->id() != extruder_id) gcode += this->set_extruder(extruder_id, print_z); // An apron band is a real printed layer: it is counted in m_layer_count, it advances @@ -5370,7 +5370,7 @@ LayerResult GCode::process_belt_brim_layer( config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); gcode += this->placeholder_parser_process("before_layer_change_gcode", - print.config().before_layer_change_gcode.value, m_writer->filament()->id(), &config) + "\n"; + print.config().before_layer_change_gcode.value, m_writer.filament()->id(), &config) + "\n"; } gcode += this->change_layer(print_z); @@ -5381,12 +5381,12 @@ LayerResult GCode::process_belt_brim_layer( config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); gcode += this->placeholder_parser_process("layer_change_gcode", - print.config().layer_change_gcode.value, m_writer->filament()->id(), &config) + "\n"; + print.config().layer_change_gcode.value, m_writer.filament()->id(), &config) + "\n"; } // Objects sharing this apron Z may use different brim filaments; print each in its own tool. for (const unsigned int brim_extruder : layer_tools.extruders) { - if (m_writer->filament() == nullptr || m_writer->filament()->id() != brim_extruder) + if (m_writer.filament() == nullptr || m_writer.filament()->id() != brim_extruder) gcode += this->set_extruder(brim_extruder, print_z); gcode += this->emit_belt_brim_bands(print, layers, single_object_instance_idx, brim_extruder); } @@ -5647,13 +5647,13 @@ std::string GCode::generate_timelapse_gcode(const Print &print, coordf_t print_z const std::vector *printed_objects, bool skip_pos_pick) { - if (!m_writer->filament()) + if (!m_writer.filament()) return {}; PosPickCtx ctx; - ctx.curr_pos = { (coord_t)(scale_(m_writer->get_position().x())),(coord_t)(scale_(m_writer->get_position().y())) }; + ctx.curr_pos = { (coord_t)(scale_(m_writer.get_position().x())),(coord_t)(scale_(m_writer.get_position().y())) }; ctx.curr_layer = this->layer(); - ctx.curr_extruder_id = m_writer->filament()->extruder_id(); + ctx.curr_extruder_id = m_writer.filament()->extruder_id(); ctx.picture_extruder_id = most_used_extruder; if (m_farthest_point_timelapse.enabled) { // farthest_point is stored in the global print frame (includes plate origin); the picker works in @@ -5684,17 +5684,17 @@ std::string GCode::generate_timelapse_gcode(const Print &print, coordf_t print_z // that leaves the toggle off, so their template evaluates to the pre-existing +0.4 lift byte-for-byte. config.set_key_value("farthest_point_timelapse_enabled", new ConfigOptionBool(m_farthest_point_timelapse.enabled)); config.set_key_value("clear_to_x0", new ConfigOptionBool(m_timelapse_pos_picker.get_is_clear_to_x0(ctx))); - timelapse_gcode = this->placeholder_parser_process("timelapse_gcode", print.config().time_lapse_gcode.value, m_writer->filament()->id(), &config) + "\n"; + timelapse_gcode = this->placeholder_parser_process("timelapse_gcode", print.config().time_lapse_gcode.value, m_writer.filament()->id(), &config) + "\n"; } if (!timelapse_gcode.empty()) { - m_writer->set_current_position_clear(false); + m_writer.set_current_position_clear(false); double temp_z_after_tool_change; if (GCodeProcessor::get_last_z_from_gcode(timelapse_gcode, temp_z_after_tool_change)) { - Vec3d pos = m_writer->get_position(); + Vec3d pos = m_writer.get_position(); pos(2) = temp_z_after_tool_change; - m_writer->set_position(pos); + m_writer.set_position(pos); } } @@ -5778,7 +5778,7 @@ LayerResult GCode::process_layer( m_cur_layer_idx = layer.id(); // A per-layer nozzle grouping can move the active filament to another variant column on a // layer boundary without a toolchange, so re-resolve the writer's config column here. - if (Extruder *cur_filament = m_writer->filament()) + if (Extruder *cur_filament = m_writer.filament()) cur_filament->set_config_index((int)get_filament_config_index((int)cur_filament->id())); LayerResult result { {}, layer.id(), false, last_layer }; if (layer_tools.extruders.empty()) @@ -5791,7 +5791,7 @@ LayerResult GCode::process_layer( //support is attached above the object, and support layers has independent layer height, then the lowest support //interface layer id is 0. bool first_layer = (layer.id() == 0 && abs(layer.bottom_z()) < EPSILON); - m_writer->set_is_first_layer(first_layer); + m_writer.set_is_first_layer(first_layer); unsigned int first_extruder_id = layer_tools.extruders.front(); // Initialize config with the 1st object to be printed at this layer. @@ -5841,7 +5841,7 @@ LayerResult GCode::process_layer( config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); gcode += this->placeholder_parser_process("before_layer_change_gcode", - print.config().before_layer_change_gcode.value, m_writer->filament()->id(), &config) + print.config().before_layer_change_gcode.value, m_writer.filament()->id(), &config) + "\n"; } @@ -5886,7 +5886,7 @@ LayerResult GCode::process_layer( config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); gcode += this->placeholder_parser_process("timelapse_gcode", - print.config().time_lapse_gcode.value, m_writer->filament()->id(), &config) + print.config().time_lapse_gcode.value, m_writer.filament()->id(), &config) + "\n"; } @@ -5896,11 +5896,11 @@ LayerResult GCode::process_layer( config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); { - const int cur_filament_id = (int) m_writer->filament()->id(); + const int cur_filament_id = (int) m_writer.filament()->id(); const auto group_result = m_print->get_layered_nozzle_group_result(); config.set_key_value("current_filament_id", new ConfigOptionInt(cur_filament_id)); config.set_key_value("current_nozzle_id", new ConfigOptionInt( - nozzle_id_for_gcode_placeholder(group_result, cur_filament_id, (int) m_writer->filament()->extruder_id(), m_layer_index))); + nozzle_id_for_gcode_placeholder(group_result, cur_filament_id, (int) m_writer.filament()->extruder_id(), m_layer_index))); } // Bedslinger mass model. Compute the running printed mass at this layer (same weight calc as @@ -5909,7 +5909,7 @@ LayerResult GCode::process_layer( // returns the plain min Y accel unless the A2L force/bed-mass keys are set, so this is inert for every // existing printer. PrintStatistics curr_print_statistics; - for (const Extruder &extruder : m_writer->extruders()) { + for (const Extruder &extruder : m_writer.extruders()) { double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter double filament_weight = extruded_volume * extruder.filament_density() * 0.001; if (filament_weight > 0.) @@ -5925,7 +5925,7 @@ LayerResult GCode::process_layer( config.set_key_value("curr_layer_mass", new ConfigOptionFloat(curr_layer_mass)); gcode += this->placeholder_parser_process("layer_change_gcode", - print.config().layer_change_gcode.value, m_writer->filament()->id(), &config) + print.config().layer_change_gcode.value, m_writer.filament()->id(), &config) + "\n"; config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); } @@ -6004,7 +6004,7 @@ LayerResult GCode::process_layer( case CalibMode::Calib_Input_shaping_freq: { if (m_layer_index == 1){ gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f, print.calib_params().shaper_type); - if (m_writer->get_gcode_flavor() == gcfKlipper) { + if (m_writer.get_gcode_flavor() == gcfKlipper) { // Disable minimum cruise ratio to ensure consistent motion for calibration gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n"; } @@ -6020,7 +6020,7 @@ LayerResult GCode::process_layer( } case CalibMode::Calib_Input_shaping_damp: { if (m_layer_index == 1){ - if (m_writer->get_gcode_flavor() == gcfKlipper) { + if (m_writer.get_gcode_flavor() == gcfKlipper) { // Disable minimum cruise ratio to ensure consistent motion for calibration gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n"; } @@ -6032,7 +6032,7 @@ LayerResult GCode::process_layer( break; } case CalibMode::Calib_Cornering: { - if (m_writer->get_gcode_flavor() == gcfMarlinFirmware && + if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && !m_config.machine_max_junction_deviation.values.empty() && m_config.machine_max_junction_deviation.values.front() > 0) { gcode += writer().set_junction_deviation(this->interpolate_value_across_layers(print.calib_params().start, print.calib_params().end)); @@ -6047,15 +6047,15 @@ LayerResult GCode::process_layer( if (first_layer) { // Orca: we don't need to optimize the Klipper as only set once if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) { - gcode += m_writer->set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(initial_layer_acceleration) + 0.5)); + gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(initial_layer_acceleration) + 0.5)); } if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) { - gcode += m_writer->set_jerk_xy(NOZZLE_CONFIG(initial_layer_jerk)); + gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(initial_layer_jerk)); } - if (m_writer->get_gcode_flavor() == gcfMarlinFirmware && NOZZLE_CONFIG(default_junction_deviation) > 0) { - gcode += m_writer->set_junction_deviation(NOZZLE_CONFIG(default_junction_deviation)); + if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && NOZZLE_CONFIG(default_junction_deviation) > 0) { + gcode += m_writer.set_junction_deviation(NOZZLE_CONFIG(default_junction_deviation)); } } @@ -6093,7 +6093,7 @@ LayerResult GCode::process_layer( if (past_first_layer_band && !m_second_layer_things_done) { // Orca: set power loss recovery const auto plr_mode = print.config().enable_power_loss_recovery.value; - gcode += m_writer->enable_power_loss_recovery(plr_mode); + gcode += m_writer.enable_power_loss_recovery(plr_mode); if (print.is_BBL_printer()) { // BBS: open first layer inspection at second layer @@ -6108,24 +6108,24 @@ LayerResult GCode::process_layer( // Reset acceleration at sencond layer // Orca: only set once, don't need to call set_accel_and_jerk if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) { - gcode += m_writer->set_print_acceleration((unsigned int) floor(NOZZLE_CONFIG(default_acceleration) + 0.5)); + gcode += m_writer.set_print_acceleration((unsigned int) floor(NOZZLE_CONFIG(default_acceleration) + 0.5)); } if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) { - gcode += m_writer->set_jerk_xy(NOZZLE_CONFIG(default_jerk)); + gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(default_jerk)); } // Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent // nozzle_temperature_initial_layer vs. temperature settings. - for (const Extruder& extruder : m_writer->extruders()) { + for (const Extruder& extruder : m_writer.extruders()) { if ((print.config().single_extruder_multi_material.value || m_ooze_prevention.enable) && - extruder.id() != m_writer->filament()->id()) + extruder.id() != m_writer.filament()->id()) // In single extruder multi material mode, set the temperature for the current extruder only. continue; size_t fi = get_filament_config_index((int)extruder.id()); int temperature = print.config().nozzle_temperature.get_at(fi); if (temperature > 0 && temperature != print.config().nozzle_temperature_initial_layer.get_at(fi)) - gcode += m_writer->set_temperature(temperature, false, extruder.id()); + gcode += m_writer.set_temperature(temperature, false, extruder.id()); } // BBS @@ -6134,14 +6134,14 @@ LayerResult GCode::process_layer( bed_temp = get_highest_bed_temperature(false,print); else bed_temp = get_bed_temperature(first_extruder_id, false, m_config.curr_bed_type); - gcode += m_writer->set_bed_temperature(bed_temp); + gcode += m_writer.set_bed_temperature(bed_temp); // Mark the temperature transition from 1st to 2nd layer to be finished. m_second_layer_things_done = true; } if (single_object_instance_idx == size_t(-1)) { // Normal (non-sequential) print. - gcode += ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer->filament()->id(), first_extruder_id, print.config()); + gcode += ProcessLayer::emit_custom_gcode_per_print_z(*this, layer_tools.custom_gcode, m_writer.filament()->id(), first_extruder_id, print.config()); } // BBS: get next extruder according to flush and soluble @@ -6172,7 +6172,7 @@ LayerResult GCode::process_layer( return r->has_extrusions(); }); const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) { - return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer->filament()->id())); + return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer.filament()->id())); }); const bool enable_overhang_fan = m_enable_cooling_markers && has_extrusions && std::any_of(m_config.enable_overhang_bridge_fan.values.begin(), @@ -6622,16 +6622,16 @@ LayerResult GCode::process_layer( config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); config.set_key_value("most_used_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(most_used_extruder))); - config.set_key_value("curr_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(m_writer->filament()->extruder_id()))); - wrapping_gcode = this->placeholder_parser_process("wrapping_detection_gcode", print.config().wrapping_detection_gcode.value, m_writer->filament()->id(), &config) +"\n"; + config.set_key_value("curr_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(m_writer.filament()->extruder_id()))); + wrapping_gcode = this->placeholder_parser_process("wrapping_detection_gcode", print.config().wrapping_detection_gcode.value, m_writer.filament()->id(), &config) +"\n"; } - m_writer->set_current_position_clear(false); + m_writer.set_current_position_clear(false); double temp_z_after_tool_change; if (GCodeProcessor::get_last_z_from_gcode(wrapping_gcode, temp_z_after_tool_change)) { - Vec3d pos = m_writer->get_position(); + Vec3d pos = m_writer.get_position(); pos(2) = temp_z_after_tool_change; - m_writer->set_position(pos); + m_writer.set_position(pos); } return wrapping_gcode; }; @@ -6716,7 +6716,7 @@ LayerResult GCode::process_layer( if (should_insert) { gcode += this->retract(false, false, auto_lift_type, true); - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); gcode += insert_timelapse_gcode(); has_insert_timelapse_gcode = true; @@ -6736,7 +6736,7 @@ LayerResult GCode::process_layer( if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode && !(m_farthest_point_timelapse.enabled && m_farthest_point_timelapse.farthest_is_photo_head) && - m_writer->need_toolchange(extruder_id) && + m_writer.need_toolchange(extruder_id) && m_config.nozzle_diameter.values.size() == 2 && writer().filament()) { bool curr_is_photo_head = get_extruder_id(writer().filament()->id()) == most_used_extruder; @@ -6744,7 +6744,7 @@ LayerResult GCode::process_layer( bool should_insert = is_case_b ? !curr_is_photo_head : curr_is_photo_head; if (should_insert) { gcode += this->retract(false, false, auto_lift_type, true); - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); gcode += insert_timelapse_gcode(); has_insert_timelapse_gcode = true; @@ -6831,19 +6831,19 @@ LayerResult GCode::process_layer( // exclude objects if (m_enable_exclude_object) { if (is_BBL_Printer()) { - m_writer->set_object_start_str( + m_writer.set_object_start_str( std::string("; start printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n" + "M624 " + _encode_label_ids_to_base64({instance_to_print.label_object_id}) + "\n"); } else { const auto gflavor = print.config().gcode_flavor.value; if (gflavor == gcfKlipper) { - m_writer->set_object_start_str(std::string("EXCLUDE_OBJECT_START NAME=") + + m_writer.set_object_start_str(std::string("EXCLUDE_OBJECT_START NAME=") + get_instance_name(&instance_to_print.print_object, inst.id) + "\n"); } else if (gflavor == gcfMarlinLegacy || gflavor == gcfMarlinFirmware || gflavor == gcfRepRapFirmware) { std::string str = std::string("M486 S") + std::to_string(inst.unique_id) + "\n"; - m_writer->set_object_start_str(str); + m_writer.set_object_start_str(str); } } } @@ -6984,20 +6984,20 @@ LayerResult GCode::process_layer( } // exclude objects // Don't set m_gcode_label_objects_end if you don't had to write the m_gcode_label_objects_start. - if (!m_writer->is_object_start_str_empty()) { - m_writer->set_object_start_str(""); + if (!m_writer.is_object_start_str_empty()) { + m_writer.set_object_start_str(""); } else if (m_enable_exclude_object) { if (is_BBL_Printer()) { - m_writer->set_object_end_str(std::string("; stop printing object, unique label id: ") + + m_writer.set_object_end_str(std::string("; stop printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n" + "M625\n"); } else { const auto gflavor = print.config().gcode_flavor.value; if (gflavor == gcfKlipper) { - m_writer->set_object_end_str(std::string("EXCLUDE_OBJECT_END NAME=") + + m_writer.set_object_end_str(std::string("EXCLUDE_OBJECT_END NAME=") + get_instance_name(&instance_to_print.print_object, inst.id) + "\n"); } else if (gflavor == gcfMarlinLegacy || gflavor == gcfMarlinFirmware || gflavor == gcfRepRapFirmware) { - m_writer->set_object_end_str(std::string("M486 S-1\n")); + m_writer.set_object_end_str(std::string("M486 S-1\n")); } } } @@ -7062,17 +7062,17 @@ LayerResult GCode::process_layer( } if (m_enable_exclude_object) { if (is_BBL_Printer()) { - m_writer->set_object_start_str( + m_writer.set_object_start_str( std::string("; start printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n" + "M624 " + _encode_label_ids_to_base64({instance_to_print.label_object_id}) + "\n"); } else { const auto gflavor = print.config().gcode_flavor.value; if (gflavor == gcfKlipper) { - m_writer->set_object_start_str(std::string("EXCLUDE_OBJECT_START NAME=") + + m_writer.set_object_start_str(std::string("EXCLUDE_OBJECT_START NAME=") + get_instance_name(&instance_to_print.print_object, inst.id) + "\n"); } else if (gflavor == gcfMarlinLegacy || gflavor == gcfMarlinFirmware || gflavor == gcfRepRapFirmware) { - m_writer->set_object_start_str(std::string("M486 S") + std::to_string(inst.unique_id) + "\n"); + m_writer.set_object_start_str(std::string("M486 S") + std::to_string(inst.unique_id) + "\n"); } } } @@ -7284,20 +7284,20 @@ LayerResult GCode::process_layer( } // --- Shared instance footer (mirrors Orca's main instance loop) --- - if (!m_writer->is_object_start_str_empty()) { - m_writer->set_object_start_str(""); + if (!m_writer.is_object_start_str_empty()) { + m_writer.set_object_start_str(""); } else if (m_enable_exclude_object) { if (is_BBL_Printer()) { - m_writer->set_object_end_str(std::string("; stop printing object, unique label id: ") + + m_writer.set_object_end_str(std::string("; stop printing object, unique label id: ") + std::to_string(instance_to_print.label_object_id) + "\n" + "M625\n"); } else { const auto gflavor = print.config().gcode_flavor.value; if (gflavor == gcfKlipper) { - m_writer->set_object_end_str(std::string("EXCLUDE_OBJECT_END NAME=") + + m_writer.set_object_end_str(std::string("EXCLUDE_OBJECT_END NAME=") + get_instance_name(&instance_to_print.print_object, inst.id) + "\n"); } else if (gflavor == gcfMarlinLegacy || gflavor == gcfMarlinFirmware || gflavor == gcfRepRapFirmware) { - m_writer->set_object_end_str(std::string("M486 S-1\n")); + m_writer.set_object_end_str(std::string("M486 S-1\n")); } } } @@ -7310,7 +7310,7 @@ LayerResult GCode::process_layer( // wipe tower's add_object_end_labels may consume it into a local temp string and the // M625 would be lost for BBL printers. if (!layer_tools.mixed_sub_layer_groups.empty()) { - m_writer->add_object_end_labels(gcode); + m_writer.add_object_end_labels(gcode); m_nominal_z = print_z; m_need_change_layer_lift_z = true; } @@ -7339,7 +7339,7 @@ LayerResult GCode::process_layer( for (size_t instance_id = i_begin; instance_id < i_end && instance_id < obj->instances().size(); ++ instance_id) { if (! belt_brim_emitted.insert({ ltp_idx, instance_id }).second) continue; - if (m_writer->filament() == nullptr || m_writer->filament()->id() != brim0) + if (m_writer.filament() == nullptr || m_writer.filament()->id() != brim0) gcode += this->set_extruder(brim0, print_z); gcode += generate_object_brim(print, *obj, instance_id, first_layer, ltp.object_layer); } @@ -7386,7 +7386,7 @@ LayerResult GCode::process_layer( if (FILAMENT_CONFIG(retract_when_changing_layer)) { gcode += this->retract(false, false, auto_lift_type, true); } - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); gcode += insert_timelapse_gcode(); has_insert_timelapse_gcode = true; } @@ -7408,7 +7408,7 @@ LayerResult GCode::process_layer( if (FILAMENT_CONFIG(retract_when_changing_layer)) { gcode += this->retract(false, false, auto_lift_type, true); } - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); gcode += insert_timelapse_gcode(); } @@ -7420,7 +7420,7 @@ LayerResult GCode::process_layer( void GCode::apply_print_config(const PrintConfig &print_config) { - m_writer->apply_print_config(print_config); + m_writer.apply_print_config(print_config); m_config.apply(print_config); m_scaled_resolution = scaled(print_config.resolution.value); m_enable_exclude_object = m_config.exclude_object; @@ -7544,7 +7544,7 @@ void GCode::append_full_config(const Print &print, std::string &str) void GCode::set_extruders(const std::vector &extruder_ids) { - m_writer->set_extruders(extruder_ids); + m_writer.set_extruders(extruder_ids); // enable wipe path generation if any extruder has wipe enabled m_wipe.enable = false; @@ -7569,13 +7569,13 @@ void GCode::set_origin(const Vec2d &pointf) std::string GCode::preamble() { - std::string gcode = m_writer->preamble(); + std::string gcode = m_writer.preamble(); /* Perform a *silent* move to z_offset: we need this to initialize the Z position of our writer object so that any initial lift taking place before the first layer change will raise the extruder from the correct initial Z instead of 0. */ - m_writer->travel_to_z(m_config.z_offset.value); + m_writer.travel_to_z(m_config.z_offset.value); return gcode; } @@ -7586,28 +7586,28 @@ std::string GCode::change_layer(coordf_t print_z) std::string gcode; if (m_layer_count > 0) // Increment a progress bar indicator. - gcode += m_writer->update_progress(++ m_layer_index, m_layer_count); + gcode += m_writer.update_progress(++ m_layer_index, m_layer_count); //BBS coordf_t z = print_z + m_config.z_offset.value; // in unscaled coordinates - if (FILAMENT_CONFIG(retract_when_changing_layer) && m_writer->will_move_z(z)) { + if (FILAMENT_CONFIG(retract_when_changing_layer) && m_writer.will_move_z(z)) { LiftType lift_type = this->to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types))); //BBS: force to use SpiralLift when change layer if lift type is auto gcode += this->retract(false, false, ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto ? LiftType::SpiralLift : lift_type); } - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); if (m_spiral_vase) { //BBS: force to normal lift immediately in spiral vase mode std::ostringstream comment; comment << "move to next layer (" << m_layer_index << ")"; - gcode += m_writer->travel_to_z(z, comment.str()); + gcode += m_writer.travel_to_z(z, comment.str()); } m_need_change_layer_lift_z = true; m_nominal_z = z; - m_writer->get_position().z() = z; + m_writer.get_position().z() = z; // forget last wiping path as wiping after raising Z is pointless // BBS. Dont forget wiping path to reduce stringing. @@ -7933,7 +7933,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref, const Point3 ¢er3 = paths.front().polyline.points.front(); pt.rotate(angle, Point(center3.x(), center3.y())); // generate the travel move - gcode += m_writer->extrude_to_xy(this->point_to_gcode(pt), 0, "move inwards before travel", true); + gcode += m_writer.extrude_to_xy(this->point_to_gcode(pt), 0, "move inwards before travel", true); } return gcode; @@ -8295,7 +8295,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, bool slope_need_z_travel = false; if (sloped != nullptr && !sloped->is_flat()) { auto target_z = get_sloped_z(sloped->slope_begin.z_ratio); - slope_need_z_travel = m_writer->will_move_z(target_z); + slope_need_z_travel = m_writer.will_move_z(target_z); } // Move to first point of extrusion path // path is 2D. But in slope lift case, lift z is done in travel_to function. @@ -8323,14 +8323,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } if (path.z_contoured && !path.polyline.lines().empty()) { - double current_z = m_writer->get_position().z(); + double current_z = m_writer.get_position().z(); double first_z = unscale_(path.polyline.lines().begin()->a.z()) + m_nominal_z; if (GCodeFormatter::quantize_xyzf(first_z) != GCodeFormatter::quantize_xyzf(current_z)) { - gcode += m_writer->travel_to_z(first_z, "set Z for contouring", true); + gcode += m_writer.travel_to_z(first_z, "set Z for contouring", true); } } if (!path.z_contoured && sloped == nullptr) { - double current_z = m_writer->get_position().z(); + double current_z = m_writer.get_position().z(); if (GCodeFormatter::quantize_xyzf(current_z) != GCodeFormatter::quantize_xyzf(m_nominal_z)) { gcode += this->writer().travel_to_z(m_nominal_z, "reset Z after contouring", true); } @@ -8338,7 +8338,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // if needed, write the gcode_label_objects_end then gcode_label_objects_start // should be already done by travel_to, but just in case - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); // compensate retraction gcode += this->unretract(); @@ -8356,12 +8356,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) { acceleration = m_config.first_layer_acceleration_over_raft.value; #endif - } else if (m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer->filament()->id())) > 0 && is_bridge(path.role())) { - acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer->filament()->id())); - } else if (m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer->filament()->id())) > 0 && (path.role() == erInternalInfill)) { - acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer->filament()->id())); - } else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer->filament()->id())) > 0 && (path.role() == erSolidInfill)) { - acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer->filament()->id())); + } else if (m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && is_bridge(path.role())) { + acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + } else if (m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && (path.role() == erInternalInfill)) { + acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + } else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && (path.role() == erSolidInfill)) { + acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())); } else if (NOZZLE_CONFIG(outer_wall_acceleration) > 0 && is_external_perimeter(path.role())) { acceleration = NOZZLE_CONFIG(outer_wall_acceleration); } else if (NOZZLE_CONFIG(inner_wall_acceleration) > 0 && is_internal_perimeter(path.role())) { @@ -8392,12 +8392,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } } - if (m_writer->get_gcode_flavor() == gcfKlipper) { - gcode += m_writer->set_accel_and_jerk(acceleration_i, jerk); + if (m_writer.get_gcode_flavor() == gcfKlipper) { + gcode += m_writer.set_accel_and_jerk(acceleration_i, jerk); } else { - gcode += m_writer->set_print_acceleration(acceleration_i); - gcode += m_writer->set_jerk_xy(jerk); + gcode += m_writer.set_print_acceleration(acceleration_i); + gcode += m_writer.set_jerk_xy(jerk); } // calculate effective extrusion length per distance unit (e_per_mm) @@ -8453,8 +8453,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } // Effective extrusion length per distance unit = (filament_flow_ratio/cross_section) * mm3_per_mm / print flow ratio - // m_writer->extruder()->e_per_mm3() below is (filament flow ratio / cross-sectional area) - double e_per_mm = m_writer->filament()->e_per_mm3() * _mm3_per_mm; + // m_writer.extruder()->e_per_mm3() below is (filament flow ratio / cross-sectional area) + double e_per_mm = m_writer.filament()->e_per_mm3() * _mm3_per_mm; e_per_mm /= filament_flow_ratio; // set speed @@ -8470,7 +8470,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed)); } } else if(path.role() == erInternalBridgeInfill) { - speed = m_config.get_abs_value_at("internal_bridge_speed", get_nozzle_config_index(m_writer->filament()->id())); + speed = m_config.get_abs_value_at("internal_bridge_speed", get_nozzle_config_index(m_writer.filament()->id())); } else if (path.role() == erOverhangPerimeter || path.role() == erSupportTransition || path.role() == erBridgeInfill) { speed = NOZZLE_CONFIG(bridge_speed); } else if (path.role() == erInternalInfill) { @@ -8480,7 +8480,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } else if (path.role() == erTopSolidInfill) { speed = NOZZLE_CONFIG(top_surface_speed); } else if (path.role() == erIroning) { - const size_t filament_idx = get_filament_config_index(m_writer->filament()->id()); + const size_t filament_idx = get_filament_config_index(m_writer.filament()->id()); speed = m_config.filament_ironing_speed.is_nil(filament_idx) ? m_config.get_abs_value("ironing_speed") : m_config.filament_ironing_speed.get_at(filament_idx); @@ -8513,7 +8513,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // "first layers" the fan stays off for are a band along the belt. Mark where the // extrusion enters and leaves it, per segment, for the cooling buffer. const bool belt_band_tags = m_enable_cooling_markers && m_config.belt_printer.value; - const int belt_band_layers = belt_band_tags ? m_config.close_fan_the_first_x_layers.get_at(m_writer->filament()->id()) : 0; + const int belt_band_layers = belt_band_tags ? m_config.close_fan_the_first_x_layers.get_at(m_writer.filament()->id()) : 0; auto tag_belt_band = [this, &gcode, belt_band_tags, belt_band_layers, z = path_point_mm.z()](coord_t x, coord_t y) { if (! belt_band_tags) return; @@ -8713,7 +8713,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, //Orca: process custom gcode for extrusion role change if (path.role() != m_last_extrusion_role) { - const auto current_filament_id = m_writer->filament()->id(); + const auto current_filament_id = m_writer.filament()->id(); const std::string& machine_role_change_gcode = m_config.change_extrusion_role_gcode.value; const std::string& filament_role_change_gcode = m_config.filament_change_extrusion_role_gcode.get_at(current_filament_id); const std::string& process_role_change_gcode = m_config.process_change_extrusion_role_gcode.value; @@ -8788,7 +8788,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (m_multi_flow_segment_path_average_mm3_per_mm > 0) { sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), m_multi_flow_segment_path_average_mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8801,7 +8801,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // to issue a zero flow PA change command for this sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8900,7 +8900,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, return; // Inline M971 only when current extruder is the photo head; other nozzles may pass through nearby // coordinates but their physical position differs. - if (!m_writer->filament() || get_extruder_id(m_writer->filament()->id()) != m_farthest_point_timelapse.most_used_extruder) + if (!m_writer.filament() || get_extruder_id(m_writer.filament()->id()) != m_farthest_point_timelapse.most_used_extruder) return; // Compare in the global print frame to match farthest_gcode_pos, which is unscale(farthest_point) // without the per-extruder nozzle offset. Using point_to_gcode() here would subtract extruder_offset @@ -8939,7 +8939,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8954,7 +8954,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -8969,7 +8969,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); + gcode += m_writer.set_speed(F, "", comment); { if (m_enable_cooling_markers) { if (enable_overhang_bridge_fan) { @@ -8990,7 +8990,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (!m_config.enable_arc_fitting || path.polyline.fitting_result.empty() || m_config.spiral_mode || sloped != nullptr || path.z_contoured || this->should_disable_arc_fitting()) { double path_length = 0.; double total_length = sloped == nullptr ? 0. : path.polyline.length() * SCALING_FACTOR; - double saved_z = m_writer->get_position().z(); + double saved_z = m_writer.get_position().z(); for (const Line3& line : path.polyline.lines()) { std::string tempDescription = description; @@ -9024,12 +9024,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (z < 0.1) { throw RuntimeError("GCode: very low z"); } - gcode += m_writer->extrude_to_xyz(Vec3d(dest2d.x(), dest2d.y(), z), e, + gcode += m_writer.extrude_to_xyz(Vec3d(dest2d.x(), dest2d.y(), z), e, GCodeWriter::full_gcode_comment ? tempDescription : ""); } else if (sloped == nullptr) { // Normal extrusion - gcode += m_writer->extrude_to_xy( + gcode += m_writer.extrude_to_xy( this->point_to_gcode(line.b.to_point()), dE, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); @@ -9038,7 +9038,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, const auto [z_ratio, e_ratio] = sloped->interpolate(path_length / total_length); Vec2d dest2d = this->point_to_gcode(line.b.to_point()); Vec3d dest3d(dest2d(0), dest2d(1), get_sloped_z(z_ratio)); - gcode += m_writer->extrude_to_xyz( + gcode += m_writer.extrude_to_xyz( dest3d, dE * e_ratio, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); @@ -9069,7 +9069,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, tempDescription += Slic3r::format(" | Old Flow Value: %0.5f Length: %0.5f",oldE, line_length); } } - gcode += m_writer->extrude_to_xy( + gcode += m_writer.extrude_to_xy( this->point_to_gcode(line.b), dE, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); @@ -9093,7 +9093,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, tempDescription += Slic3r::format(" | Old Flow Value: %0.5f Length: %0.5f",oldE, arc_length); } } - gcode += m_writer->extrude_arc_to_xy( + gcode += m_writer.extrude_arc_to_xy( this->point_to_gcode(arc.end_point), center_offset, dE, @@ -9122,7 +9122,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, Polyline3 l(p); total_length = l.length() * SCALING_FACTOR; } - gcode += m_writer->set_speed(last_set_speed, "", comment); + gcode += m_writer.set_speed(last_set_speed, "", comment); Vec3d prev = this->point_to_gcode_quantized(new_points[0].p); bool pre_fan_enabled = false; bool cur_fan_enabled = false; @@ -9173,7 +9173,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -9188,7 +9188,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } sprintf(buf, ";%sT%u MM3MM:%g ACCEL:%u BR:%d RC:%d OV:%d\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::PA_Change).c_str(), - m_writer->filament()->id(), + m_writer.filament()->id(), _mm3_per_mm, acceleration_i, ((path.role() == erBridgeInfill) ||(path.role() == erOverhangPerimeter)), @@ -9205,10 +9205,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // 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)) { - gcode += m_writer->set_speed(new_speed, "", comment); + gcode += m_writer.set_speed(new_speed, "", comment); last_set_speed = new_speed; } else if ((std::abs(F - new_speed) <= 60)) { - gcode += m_writer->set_speed(F, "", comment); + gcode += m_writer.set_speed(F, "", comment); last_set_speed = F; } auto dE = e_per_mm * line_length; @@ -9235,16 +9235,16 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (z < 0.1) { throw RuntimeError("GCode: very low z"); } - gcode += m_writer->extrude_to_xyz(Vec3d(dest2d.x(), dest2d.y(), z), e, + gcode += m_writer.extrude_to_xyz(Vec3d(dest2d.x(), dest2d.y(), z), e, GCodeWriter::full_gcode_comment ? tempDescription : ""); } else if (sloped == nullptr) { // Normal extrusion - gcode += m_writer->extrude_to_xy(p.head<2>(), dE, GCodeWriter::full_gcode_comment ? tempDescription : ""); + gcode += m_writer.extrude_to_xy(p.head<2>(), dE, GCodeWriter::full_gcode_comment ? tempDescription : ""); } else { // Sloped extrusion const auto [z_ratio, e_ratio] = sloped->interpolate(path_length / total_length); Vec3d dest3d(p(0), p(1), get_sloped_z(z_ratio)); - gcode += m_writer->extrude_to_xyz(dest3d, dE * e_ratio, GCodeWriter::full_gcode_comment ? tempDescription : ""); + gcode += m_writer.extrude_to_xyz(dest3d, dE * e_ratio, GCodeWriter::full_gcode_comment ? tempDescription : ""); } // Inline farthest-point snapshot on the variable-speed emission path. Inert unless the @@ -9384,8 +9384,8 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string unsigned int acceleration_to_set = 0; if (this->on_first_layer()) { - unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", get_nozzle_config_index(m_writer->filament()->id())); - double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", get_nozzle_config_index(m_writer->filament()->id())); + unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", get_nozzle_config_index(m_writer.filament()->id())); if (NOZZLE_CONFIG(default_acceleration) > 0 && initial_layer_travel_acceleration > 0) { acceleration_to_set = (unsigned int) floor(initial_layer_travel_acceleration + 0.5); @@ -9398,7 +9398,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (NOZZLE_CONFIG(default_acceleration) > 0) { if (role == erOverhangPerimeter && is_short_travel) { - const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer->filament()->id())); + const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())); if (bridge_acceleration > 0) acceleration_to_set = (unsigned int) floor(bridge_acceleration + 0.5); @@ -9422,11 +9422,11 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string } } - if (m_writer->get_gcode_flavor() == gcfKlipper) { - gcode += m_writer->set_accel_and_jerk(acceleration_to_set, jerk_to_set); + if (m_writer.get_gcode_flavor() == gcfKlipper) { + gcode += m_writer.set_accel_and_jerk(acceleration_to_set, jerk_to_set); } else { - gcode += m_writer->set_travel_acceleration(acceleration_to_set); - gcode += m_writer->set_jerk_xy(jerk_to_set); + gcode += m_writer.set_travel_acceleration(acceleration_to_set); + gcode += m_writer.set_jerk_xy(jerk_to_set); } // if a retraction would be needed, try to use reduce_crossing_wall to plan a @@ -9434,7 +9434,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (m_config.reduce_crossing_wall && !m_avoid_crossing_perimeters.disabled_once() && m_layer != nullptr // A brim apron layer has no Layer to avoid crossing - && m_writer->is_current_position_clear()) + && m_writer.is_current_position_clear()) //BBS: don't generate detour travel paths when current position is unclea { travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled); @@ -9482,7 +9482,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string // if needed, write the gcode_label_objects_end then gcode_label_objects_start - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); // use G1 because we rely on paths being straight (G0 may make round paths) if (travel.size() >= 2) { @@ -9490,14 +9490,14 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (false/*m_spiral_vase*/) { // No lazy z lift for spiral vase mode for (size_t i = 1; i < travel.size(); ++i) { - gcode += m_writer->travel_to_xy(this->point_to_gcode(travel.points[i]), comment); + gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment); } } else { if (travel.size() == 2) { // No extra movements emitted by avoid_crossing_perimeters, simply move to the end point with z change const auto& dest2d = this->point_to_gcode(travel.points.back()); Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_nominal_z : z); - gcode += m_writer->travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); + gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); m_need_change_layer_lift_z = false; } else { // Extra movements emitted by avoid_crossing_perimeters, lift the z to normal height at the beginning, then apply the z @@ -9507,16 +9507,16 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string // Lift to normal z at beginning Vec2d dest2d = this->point_to_gcode(travel.points[i]); Vec3d dest3d(dest2d(0), dest2d(1), m_nominal_z); - gcode += m_writer->travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); + gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z); m_need_change_layer_lift_z = false; } else if (z != DBL_MAX && i == travel.size() - 1) { // Apply z_ratio for the very last point Vec2d dest2d = this->point_to_gcode(travel.points[i]); Vec3d dest3d(dest2d(0), dest2d(1), z); - gcode += m_writer->travel_to_xyz(dest3d, comment); + gcode += m_writer.travel_to_xyz(dest3d, comment); } else { // For all points in between, no z change - gcode += m_writer->travel_to_xy(this->point_to_gcode(travel.points[i]), comment); + gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment); } } } @@ -9619,7 +9619,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp if (clipped_travel.length() > travel_len_thresh) clipped_travel.points.back() = clipped_travel.points.front()+(clipped_travel.points.back() - clipped_travel.points.front()) * (travel_len_thresh / clipped_travel.length()); //BBS: translate to current plate coordinate system - clipped_travel.translate(Point::new_scale(double(m_origin.x() - m_writer->get_xy_offset().x()), double(m_origin.y() - m_writer->get_xy_offset().y()))); + clipped_travel.translate(Point::new_scale(double(m_origin.x() - m_writer.get_xy_offset().x()), double(m_origin.y() - m_writer.get_xy_offset().y()))); //BBS: force to retract when leave from external perimeter for a long travel //Better way is judging whether the travel move direction is same with last extrusion move. @@ -9671,18 +9671,18 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li { std::string gcode; - if (m_writer->filament() == nullptr) + if (m_writer.filament() == nullptr) return gcode; // wipe (if it's enabled for this extruder and we have a stored wipe path and no-zero wipe distance) if (FILAMENT_CONFIG(wipe) && m_wipe.has_path() && scale_(FILAMENT_CONFIG(wipe_distance)) > SCALED_EPSILON) { Wipe::RetractionValues wipeRetractions = m_wipe.calculateWipeRetractionLengths(*this, toolchange); - gcode += toolchange ? m_writer->retract_for_toolchange(true, wipeRetractions.retraction_length_before_wipe) : - m_writer->retract(true, wipeRetractions.retraction_length_before_wipe); + gcode += toolchange ? m_writer.retract_for_toolchange(true, wipeRetractions.retraction_length_before_wipe) : + m_writer.retract(true, wipeRetractions.retraction_length_before_wipe); gcode += m_wipe.wipe(*this, wipeRetractions.retraction_length_during_wipe, toolchange, is_last_retraction); // Orca: wipeRetractions.retraction_length_after_wipe is not being used explicitly, - // the remaining retraction after wipe is handled by the subsequent m_writer->retract() call + // the remaining retraction after wipe is handled by the subsequent m_writer.retract() call } /* The parent class will decide whether we need to perform an actual retraction @@ -9691,14 +9691,14 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li length is honored in case wipe path was too short. */ if ((!this->on_first_layer() || this->config().bottom_surface_pattern != InfillPattern::ipHilbertCurve) && (role != erTopSolidInfill || this->config().top_surface_pattern != InfillPattern::ipHilbertCurve)) - gcode += toolchange ? m_writer->retract_for_toolchange() : m_writer->retract(); + gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract(); - gcode += m_writer->reset_e(); + gcode += m_writer.reset_e(); // Orca: check if should + can lift (roughly from SuperSlicer) RetractLiftEnforceType retract_lift_type = RetractLiftEnforceType(EXTRUDER_CONFIG(retract_lift_enforce)); bool needs_lift = toolchange - || m_writer->filament()->retraction_length() > 0 + || m_writer.filament()->retraction_length() > 0 || m_config.use_firmware_retraction; bool last_fill_extrusion_role_top_infill = (this->m_last_notgapfill_extrusion_role == ExtrusionRole::erTopSolidInfill || this->m_last_notgapfill_extrusion_role == ExtrusionRole::erIroning); @@ -9721,9 +9721,9 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li if (needs_lift && can_lift) { if (apply_instantly) - gcode += m_writer->eager_lift(lift_type); + gcode += m_writer.eager_lift(lift_type); else - gcode += m_writer->lazy_lift(lift_type, m_spiral_vase != nullptr); + gcode += m_writer.lazy_lift(lift_type, m_spiral_vase != nullptr); } return gcode; @@ -9744,9 +9744,9 @@ void GCode::update_layer_related_config(int layer_id){ m_config.filament_volume_map.values = volume_map; m_config.filament_nozzle_map.values = nozzle_map; - m_writer->config.filament_map.values = extruder_map; - m_writer->config.filament_volume_map.values = volume_map; - m_writer->config.filament_nozzle_map.values = nozzle_map; + m_writer.config.filament_map.values = extruder_map; + m_writer.config.filament_volume_map.values = volume_map; + m_writer.config.filament_nozzle_map.values = nozzle_map; } @@ -9813,11 +9813,11 @@ void GCode::update_placeholder_parser_with_variant_params() std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bool by_object, int toolchange_temp_override, bool defer_temp_wait) { int new_extruder_id = get_extruder_id(new_filament_id); - if (!m_writer->need_toolchange(new_filament_id)) + if (!m_writer.need_toolchange(new_filament_id)) return ""; // if we are running a single-extruder setup, just set the extruder and return nothing - if (!m_writer->multiple_extruders) { + if (!m_writer.multiple_extruders) { this->placeholder_parser().set("current_extruder", new_filament_id); // Orca: keep the global current-tool identity coherent even on the single-extruder path (see append_tcr). this->placeholder_parser().set("current_filament_id", (int) new_filament_id); @@ -9851,14 +9851,14 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo check_add_eol(gcode); } if (m_config.enable_pressure_advance.get_at(new_filament_id)) { - gcode += m_writer->set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); + gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); // Orca: Adaptive PA // Reset Adaptive PA processor last PA value m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id)); } - gcode += m_writer->toolchange(new_filament_id, new_extruder_id); - if (Extruder *fil = m_writer->filament()) + gcode += m_writer.toolchange(new_filament_id, new_extruder_id); + if (Extruder *fil = m_writer.filament()) fil->set_config_index((int)get_filament_config_index((int)fil->id())); return gcode; } @@ -9874,18 +9874,18 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo // BBS: insert skip object label before change filament while by object if (by_object) - m_writer->add_object_change_labels(gcode); + m_writer.add_object_change_labels(gcode); bool add_change_filament_624 = false; - if (m_writer->filament() != nullptr) { + if (m_writer.filament() != nullptr) { // Process the custom filament_end_gcode. set_extruder() is only called if there is no wipe tower // so it should not be injected twice. - unsigned int old_filament_id = m_writer->filament()->id(); + unsigned int old_filament_id = m_writer.filament()->id(); const std::string &filament_end_gcode = m_config.filament_end_gcode.get_at(old_filament_id); if (! filament_end_gcode.empty()) { DynamicConfig config; config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); - config.set_key_value("layer_z", new ConfigOptionFloat(m_writer->get_position().z() - m_config.z_offset.value)); + config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position().z() - m_config.z_offset.value)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(get_extruder_id(old_filament_id)))); if (!m_filament_instances_code.empty()) { @@ -9901,7 +9901,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo // If ooze prevention is enabled, park current extruder in the nearest // standby point and set it to the standby temperature. - if (m_ooze_prevention.enable && m_writer->filament() != nullptr) + if (m_ooze_prevention.enable && m_writer.filament() != nullptr) gcode += m_ooze_prevention.pre_toolchange(*this); // BBS @@ -9932,10 +9932,10 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo if (toolchange_temp_override <= 0 && (m_layer == nullptr || preheat_temp <= 0)) preheat_temp = m_config.nozzle_temperature_initial_layer.get_at(new_fi); if (preheat_temp > 0) - gcode += m_writer->set_temperature(preheat_temp, false, new_filament_id); + gcode += m_writer.set_temperature(preheat_temp, false, new_filament_id); } - Vec3d nozzle_pos = m_writer->get_position(); + Vec3d nozzle_pos = m_writer.get_position(); float old_retract_length, old_retract_length_toolchange, wipe_volume; int old_filament_temp, old_filament_e_feedrate; @@ -9943,16 +9943,16 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo //BBS: add handling for filament change in start gcode int old_filament_id = -1; int old_extruder_id = -1; - if (m_writer->filament() != nullptr || m_start_gcode_filament != -1) { + if (m_writer.filament() != nullptr || m_start_gcode_filament != -1) { std::vector flush_matrix(cast(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, new_extruder_id, m_config.nozzle_diameter.values.size()))); const unsigned int number_of_extruders = (unsigned int) (m_config.filament_colour.values.size()); // if is multi_extruder only use the fist extruder matrix - if (m_writer->filament() != nullptr) - assert(m_writer->filament()->id() < number_of_extruders); + if (m_writer.filament() != nullptr) + assert(m_writer.filament()->id() < number_of_extruders); else assert(m_start_gcode_filament < number_of_extruders); - old_filament_id = m_writer->filament() != nullptr ? m_writer->filament()->id() : m_start_gcode_filament; - old_extruder_id = m_writer->filament() != nullptr ? m_writer->filament()->extruder_id() : get_extruder_id(m_start_gcode_filament); + old_filament_id = m_writer.filament() != nullptr ? m_writer.filament()->id() : m_start_gcode_filament; + old_extruder_id = m_writer.filament() != nullptr ? m_writer.filament()->extruder_id() : get_extruder_id(m_start_gcode_filament); // Resolving the old filament at the current layer is safe: the per-layer nozzle maps are // gap-filled carry-forward, so its current-layer column matches the nozzle it occupies. @@ -9965,7 +9965,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo float grab_purge_volume = m_config.grab_length.get_at(new_extruder_id) * 2.4; if (old_extruder_id != new_extruder_id) { //calc flush volume between the same extruder id - int old_filament_id_in_new_extruder = m_writer->filament(new_extruder_id) != nullptr ? m_writer->filament(new_extruder_id)->id() : -1; + int old_filament_id_in_new_extruder = m_writer.filament(new_extruder_id) != nullptr ? m_writer.filament(new_extruder_id)->id() : -1; if (old_filament_id_in_new_extruder == -1) wipe_volume = 0; else { @@ -10030,7 +10030,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo (old_filament_id != -1) ? (float) m_config.filament_retract_length_nc.get_at(get_filament_config_index(old_filament_id)) : 0.f)); // Current parked-retract length of the incoming filament's extruder. dyn_config.set_key_value("new_extruder_retracted_length", - new ConfigOptionFloat(m_writer->get_extruder_retracted_length((int) new_filament_id))); + new ConfigOptionFloat(m_writer.get_extruder_retracted_length((int) new_filament_id))); dyn_config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); dyn_config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); dyn_config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); @@ -10149,13 +10149,13 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo //BBS: gcode writer doesn't know where the extruder is and whether fan speed is changed after inserting tool change gcode //Set this flag so that normal lift will be used the first time after tool change. gcode += ";_FORCE_RESUME_FAN_SPEED\n"; - m_writer->set_current_position_clear(false); + m_writer.set_current_position_clear(false); //BBS: check whether custom gcode changes the z position. Update if changed double temp_z_after_tool_change; if (GCodeProcessor::get_last_z_from_gcode(toolchange_gcode_parsed, temp_z_after_tool_change)) { - Vec3d pos = m_writer->get_position(); + Vec3d pos = m_writer.get_position(); pos(2) = temp_z_after_tool_change; - m_writer->set_position(pos); + m_writer.set_position(pos); } } } @@ -10163,15 +10163,15 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo // BBS. Reset old extruder E-value. // Keep retract length because Custom GCode will guarantee retract length be the same as toolchange if (m_config.single_extruder_multi_material) { - m_writer->reset_e(); + m_writer.reset_e(); } //BBS: don't add T[next extruder] if there is no T cmd on filament change //We inform the writer about what is happening, but we may not use the resulting gcode. - std::string toolchange_command = m_writer->toolchange(new_filament_id, next_nozzle_id); - if (Extruder *fil = m_writer->filament()) + std::string toolchange_command = m_writer.toolchange(new_filament_id, next_nozzle_id); + if (Extruder *fil = m_writer.filament()) fil->set_config_index((int)get_filament_config_index((int)fil->id())); - if (!custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer->toolchange_prefix(), new_filament_id)) + if (!custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer.toolchange_prefix(), new_filament_id)) gcode += toolchange_command; else { // user provided his own toolchange gcode, no need to do anything @@ -10183,7 +10183,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo int temp = (m_layer_index <= 0 ? m_config.nozzle_temperature_initial_layer.get_at(new_fi) : m_config.nozzle_temperature.get_at(new_fi)); - gcode += m_writer->set_temperature(temp, false); + gcode += m_writer.set_temperature(temp, false); } this->placeholder_parser().set("current_extruder", new_filament_id); @@ -10245,7 +10245,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo gcode += m_ooze_prevention.post_toolchange(*this); if (m_config.enable_pressure_advance.get_at(new_filament_id)) { - gcode += m_writer->set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); + gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id)); // Orca: Adaptive PA // Reset Adaptive PA processor last PA value m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id)); @@ -10386,7 +10386,7 @@ Vec3d GCode::point_to_gcode(const Point3& point) const Point GCode::gcode_to_point(const Vec2d &point) const { Vec2d pt = point - m_origin; - if (const Extruder *extruder = m_writer->filament(); extruder) + if (const Extruder *extruder = m_writer.filament(); extruder) // 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->extruder_id()); return scaled(pt); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 17221101fd..80b95d2937 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -218,8 +218,7 @@ public: m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())), // BBS m_toolchange_count(0), - m_nominal_z(0.), - m_writer(std::make_unique()) + m_nominal_z(0.) {} virtual ~GCode() = default; @@ -229,7 +228,7 @@ public: void do_export(Print* print, const char* path, GCodeProcessorResult* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); void export_layer_filaments(GCodeProcessorResult* result); //BBS: set offset for gcode writer - void set_gcode_offset(double x, double y) { m_gcode_offset = Vec2d(x, y); m_writer->set_xy_offset(x, y); m_processor.set_xy_offset(x, y);} + void set_gcode_offset(double x, double y) { m_writer.set_xy_offset(x, y); m_processor.set_xy_offset(x, y);} // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -243,8 +242,8 @@ public: Vec3d point_to_gcode_quantized(const Point3& point) const; const FullPrintConfig &config() const { return m_config; } const Layer* layer() const { return m_layer; } - GCodeWriter& writer() { return *m_writer; } - const GCodeWriter& writer() const { return *m_writer; } + GCodeWriter& writer() { return m_writer; } + const GCodeWriter& writer() const { return m_writer; } PlaceholderParser& placeholder_parser() { return m_placeholder_parser_integration.parser; } const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser_integration.parser; } // Process a template through the placeholder parser, collect error messages to be reported @@ -267,7 +266,7 @@ public: bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type); std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, bool apply_instantly = false, ExtrusionRole role = erNone); // extra_retract forwards a PETG pre-extrusion over-extrusion; default 0 -> identical to the plain deretract. - std::string unretract(float extra_retract = 0.f) { return m_writer->unlift() + m_writer->unretract(extra_retract); } + std::string unretract(float extra_retract = 0.f) { return m_writer.unlift() + m_writer.unretract(extra_retract); } std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false, int toolchange_temp_override = -1, bool defer_temp_wait = false); bool is_BBL_Printer(); WipeTowerType wipe_tower_type(); @@ -384,7 +383,7 @@ protected: // represent a G2/G3 arc. Belt printers get this through BeltKinematics // rather than through an override of their own. virtual bool should_disable_arc_fitting() const - { return ! m_writer->kinematics().supports_arc_moves(); } + { return ! m_writer.kinematics().supports_arc_moves(); } void _do_export(Print &print, GCodeOutputStream &file, ThumbnailsGeneratorCallback thumbnail_cb); @@ -660,7 +659,7 @@ protected: DynamicConfig m_calib_config; // scaled G-code resolution double m_scaled_resolution; - std::unique_ptr m_writer; + GCodeWriter m_writer; struct PlaceholderParserIntegration { void reset(); @@ -786,7 +785,6 @@ protected: // checks short-circuit to the legacy Layer::id() == 0 path. std::unique_ptr m_first_layer_plane; // Plate origin, kept so a writer replaced during export can be given it again. - Vec2d m_gcode_offset{ Vec2d::Zero() }; std::unique_ptr m_pressure_equalizer; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 20357a1d9e..526ef0898d 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -17,7 +17,6 @@ class FirstLayerPlane; class GCodeWriter { public: - virtual ~GCodeWriter() = default; GCodeConfig config; bool multiple_extruders; @@ -84,27 +83,27 @@ public: std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()); // SoftFever NOTE: the returned speed is mm/minute double get_current_speed() const { return m_current_speed;} - virtual std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string()); - virtual std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false); + std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string()); + std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false); std::string travel_to_z(double z, const std::string &comment = std::string(), bool force = false); bool will_move_z(double z) const; - virtual std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); + std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); //BBS: generate G2 or G3 extrude which moves by arc std::string extrude_arc_to_xy(const Vec2d &point, const Vec2d ¢er_offset, double dE, const bool is_ccw, const std::string &comment = std::string(), bool force_no_extrusion = false); // Linear approximation of an arc, used when the machine mapping cannot // express a G2/G3. Must be called before m_pos is updated: center_offset is // relative to the current position. std::string extrude_arc_as_polyline(const Vec2d &point, const Vec2d ¢er_offset, double dE, const bool is_ccw, const std::string &comment = std::string(), bool force_no_extrusion = false); - virtual std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); + std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); std::string retract(bool before_wipe = false, double retract_length = 0); std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0); // extra_retract adds a small over-extrusion to the deretract move (PETG pre-extrusion). // Default 0 -> byte-identical to the plain deretract. std::string unretract(float extra_retract = 0.f); // do lift instantly - virtual std::string eager_lift(const LiftType type); + std::string eager_lift(const LiftType type); // record a lift request, do realy lift in next travel - virtual std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false); + std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false); std::string unlift(); const Vec3d& get_position() const { return m_pos; } Vec3d& get_position() { return m_pos; } @@ -184,7 +183,7 @@ protected: bool m_is_current_pos_clear = false; double m_current_speed; - virtual std::string _travel_to_z(double z, const std::string &comment); + std::string _travel_to_z(double z, const std::string &comment); // Whether a destination gets first-layer treatment. With an active plane // evaluator, distance from the plane decides; otherwise the layer-coarse