From ee88b3f0b09926122a5e984c0a6e2e4e2294696e Mon Sep 17 00:00:00 2001 From: harrierpigeon Date: Sun, 4 Oct 2026 19:16:59 -0500 Subject: [PATCH] GCode: hold the writer by value again Belt printing turned GCode::m_writer into a unique_ptr so BeltGCode could swap in a freshly built writer carrying the belt kinematics. Nothing subclasses GCodeWriter: the machine mapping lives in its MachineKinematics, which set_kinematics() installs on an existing writer. A GCode is built for every export and the only state on the writer when init_belt_writer() runs is the plate offset, which the swap had to copy across by hand. Install the belt kinematics on the writer in place, drop the copied offset, and drop the virtual markers on GCodeWriter that the old subclass needed. Every m_writer-> in GCode.cpp goes back to m_writer., which is most of the belt diff in that file and most of its conflicts with main. The pressure-advance pattern keeps its shared_ptr writer: the unique_ptr kinematics make GCodeWriter move-only and that class must stay copyable. --- src/libslic3r/BeltGCode.cpp | 8 +- src/libslic3r/GCode.cpp | 470 +++++++++++++++++----------------- src/libslic3r/GCode.hpp | 16 +- src/libslic3r/GCodeWriter.hpp | 15 +- 4 files changed, 251 insertions(+), 258 deletions(-) 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