From 9e889afb53949bc9ebb01d022aa8e4092a15c286 Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Sun, 19 Oct 2025 21:32:51 +0800 Subject: [PATCH] Fix issues with non-bbl multi-head printers --- src/libslic3r/Brim.cpp | 9 ++++----- src/libslic3r/Extruder.cpp | 4 ++-- src/libslic3r/Extruder.hpp | 4 ++-- src/libslic3r/GCode/GCodeProcessor.cpp | 14 +++++++------- src/libslic3r/GCode/TimelapsePosPicker.cpp | 2 +- src/libslic3r/GCode/ToolOrdering.cpp | 18 ++++++++++++++++-- src/libslic3r/GCodeWriter.hpp | 2 +- src/libslic3r/PresetBundle.cpp | 10 +++++----- src/slic3r/GUI/FilamentGroupPopup.cpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 2 ++ src/slic3r/GUI/Plater.cpp | 4 ++-- 11 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 3d77bee523..4a33063450 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -1095,11 +1095,10 @@ static ExPolygons outer_inner_brim_area(const Print& print, } int extruder_nums = print.config().nozzle_diameter.values.size(); - std::vector extruder_unprintable_area; - if (extruder_nums == 1) - extruder_unprintable_area.emplace_back(Polygons{Model::getBedPolygon()}); - else { - extruder_unprintable_area = print.get_extruder_printable_polygons(); + std::vector extruder_unprintable_area = print.get_extruder_printable_polygons(); + // Orca: if per-extruder print area is not specified, use the whole bed as printable area for all extruders + if (extruder_unprintable_area.empty()) { + extruder_unprintable_area.resize(extruder_nums, Polygons{Model::getBedPolygon()}); } std::vector filament_map = print.get_filament_maps(); diff --git a/src/libslic3r/Extruder.cpp b/src/libslic3r/Extruder.cpp index a7bc4854df..f6632c57ef 100644 --- a/src/libslic3r/Extruder.cpp +++ b/src/libslic3r/Extruder.cpp @@ -3,8 +3,8 @@ namespace Slic3r { -std::vector Extruder::m_share_E = {0.,0.}; -std::vector Extruder::m_share_retracted = {0.,0.}; +std::vector Extruder::m_share_E = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0); +std::vector Extruder::m_share_retracted = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0); Extruder::Extruder(unsigned int id, GCodeConfig *config, bool share_extruder) : m_id(id), diff --git a/src/libslic3r/Extruder.hpp b/src/libslic3r/Extruder.hpp index bd5105009a..0d76ede8c9 100644 --- a/src/libslic3r/Extruder.hpp +++ b/src/libslic3r/Extruder.hpp @@ -17,8 +17,8 @@ public: void reset() { // BBS if (m_share_extruder) { - m_share_E = { 0.,0.}; - m_share_retracted = { 0.,0. }; + m_share_E = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0); + m_share_retracted = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0); } else { m_E = 0; m_retracted = 0; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 53c246f1d5..337b25d169 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1161,7 +1161,7 @@ void GCodeProcessor::run_post_process() out += " S" + std::to_string(temperature) + "\n"; return out; } else { - const int real_tool = m_physical_extruder_map[tool_number]; + const int real_tool = tool_number < m_physical_extruder_map.size() ? m_physical_extruder_map[tool_number] : tool_number; std::string comment = "preheat T" + std::to_string(real_tool) + " time: " + std::to_string((int) std::round(time_diffs[0])) + "s"; return GCodeWriter::set_temperature(temperature, this->m_flavor, false, real_tool, comment); @@ -1176,7 +1176,7 @@ void GCodeProcessor::run_post_process() float val; if (gline.has_value('T', val) && gline.raw().find("cooldown") != std::string::npos) { - if (static_cast(val) == m_physical_extruder_map[tool_number]) + if (static_cast(val) == (tool_number < m_physical_extruder_map.size() ? m_physical_extruder_map[tool_number] : tool_number)) return std::string("; removed M104\n"); } } @@ -1781,7 +1781,7 @@ bool GCodeProcessor::check_multi_extruder_gcode_valid(const int //bbox.merge(bbox_custom); // merge the custom gcode pos with other pos*/ // check printable area // Simplified use bounding_box, Accurate calculation is not efficient - if (!unprintable_areas[extruder_id].empty()) + if ((extruder_id < unprintable_areas.size()) && !unprintable_areas[extruder_id].empty()) for (Polygon poly : unprintable_areas[extruder_id]) { poly.translate(plate_offset); if (poly.bounding_box().overlap(bbox)) { @@ -2300,7 +2300,7 @@ void GCodeProcessor::reset() m_e_local_positioning_type = EPositioningType::Absolute; m_extruder_offsets = std::vector(MIN_EXTRUDERS_COUNT, Vec3f::Zero()); m_flavor = gcfRepRapSprinter; - m_nozzle_volume = {0.f,0.f}; + m_nozzle_volume = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0.f); m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f }; m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -2310,7 +2310,7 @@ void GCodeProcessor::reset() m_flushing = false; m_virtual_flushing = false; m_wipe_tower = false; - m_remaining_volume = { 0.f,0.f }; + m_remaining_volume = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0.f); // BBS: arc move related data m_move_path_type = EMovePathType::Noop_move; m_arc_center = Vec3f::Zero(); @@ -2329,8 +2329,8 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; - m_filament_id = {static_cast(-1),static_cast(-1)}; - m_last_filament_id = {static_cast(-1),static_cast(-1) }; + m_filament_id = std::vector(MAXIMUM_EXTRUDER_NUMBER, static_cast(-1)); + m_last_filament_id = std::vector(MAXIMUM_EXTRUDER_NUMBER, static_cast(-1)); m_extruder_id = static_cast(-1); m_extruder_colors.resize(MIN_EXTRUDERS_COUNT); for (size_t i = 0; i < MIN_EXTRUDERS_COUNT; ++i) { diff --git a/src/libslic3r/GCode/TimelapsePosPicker.cpp b/src/libslic3r/GCode/TimelapsePosPicker.cpp index e4382f7a12..63569d856f 100644 --- a/src/libslic3r/GCode/TimelapsePosPicker.cpp +++ b/src/libslic3r/GCode/TimelapsePosPicker.cpp @@ -14,7 +14,7 @@ namespace Slic3r { m_nozzle_height_to_rod = print_->config().extruder_clearance_height_to_rod; m_nozzle_clearance_radius = print_->config().extruder_clearance_radius; - if (print_->config().nozzle_diameter.size() > 1) { + if (print_->config().nozzle_diameter.size() > 1 && print_->config().extruder_printable_height.size() > 1) { m_extruder_height_gap = std::abs(print_->config().extruder_printable_height.values[0] - print_->config().extruder_printable_height.values[1]); m_liftable_extruder_id = print_->config().extruder_printable_height.values[0] < print_->config().extruder_printable_height.values[1] ? 0 : 1; } diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index a42c9ca64c..e4616e07ee 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -139,7 +139,9 @@ static FilamentChangeStats calc_filament_change_info_by_toolorder(const PrintCon { FilamentChangeStats ret; std::unordered_map flush_volume_per_filament; - std::vectorlast_filament_per_extruder(2, -1); + int max_extruder_id = *std::max_element(filament_map.begin(), filament_map.end()); + assert(max_extruder_id >= 0); + std::vectorlast_filament_per_extruder(max_extruder_id + 1, -1); int total_filament_change_count = 0; float total_filament_flush_weight = 0; @@ -1081,7 +1083,7 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vectorret(filament_nums, master_extruder_id); bool ignore_ext_filament = false; // TODO: read from config // if mutli_extruder, calc group,otherwise set to 0 - if (extruder_nums == 2) { + if (extruder_nums == 2 && print->is_BBL_printer()) { std::vector extruder_ams_count_str = print_config.extruder_ams_count.values; auto extruder_ams_counts = get_extruder_ams_count(extruder_ams_count_str); std::vector group_size = calc_max_group_size(extruder_ams_counts, ignore_ext_filament); @@ -1135,6 +1137,12 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vector 1) { + // For non-bbl multi-extruder printers we don't support filament group yet, and we use filament id as extruder id + assert(extruder_nums == filament_nums); + for (int i = 0; i < filament_nums; i++) { + ret[i] = i; + } } return ret; @@ -1227,6 +1235,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first } std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); + if (m_print->is_BBL_printer()) check_filament_printable_after_group(used_filaments, filament_maps, print_config); } else { @@ -1268,6 +1277,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first return false; }; + if (m_print->is_BBL_printer() || number_of_extruders == 1){ reorder_filaments_for_minimum_flush_volume( filament_lists, filament_maps, @@ -1276,6 +1286,10 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first get_custom_seq, &filament_sequences ); + } else { + // For non-bbl multi-extruder printers we don't support filament group yet, so we keep the layer sequence because we don't flush based on order + filament_sequences = layer_filaments; + } auto curr_flush_info = calc_filament_change_info_by_toolorder(print_config, filament_maps, nozzle_flush_mtx, filament_sequences); if (nozzle_nums <= 1) diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 343fa63c4b..4fd93e3560 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -17,7 +17,7 @@ public: bool multiple_extruders; GCodeWriter() : - multiple_extruders(false), m_curr_filament_extruder{ nullptr,nullptr }, + multiple_extruders(false), m_curr_filament_extruder(MAXIMUM_EXTRUDER_NUMBER, nullptr), m_curr_extruder_id (-1), m_single_extruder_multi_material(false), m_last_acceleration(0), m_max_acceleration(0),m_last_travel_acceleration(0), m_max_travel_acceleration(0), diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 8848f55e1a..7169ac5ea9 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -1901,8 +1901,8 @@ void PresetBundle::update_selections(AppConfig &config) auto flush_volumes_vector = matrix | boost::adaptors::transformed(boost::lexical_cast); project_config.option("flush_volumes_vector")->values = std::vector(flush_volumes_vector.begin(), flush_volumes_vector.end()); } - if (config.has("app", "flush_multiplier")) { - boost::algorithm::split(matrix, config.get("app", "flush_multiplier"), boost::algorithm::is_any_of("|")); + if (config.has_printer_setting(initial_printer_profile_name, "flush_multiplier")) { + boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_multiplier"), boost::algorithm::is_any_of("|")); auto flush_multipliers = matrix | boost::adaptors::transformed(boost::lexical_cast); project_config.option("flush_multiplier")->values = std::vector(flush_multipliers.begin(), flush_multipliers.end()); } @@ -2034,8 +2034,8 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p auto flush_volumes_vector = matrix | boost::adaptors::transformed(boost::lexical_cast); project_config.option("flush_volumes_vector")->values = std::vector(flush_volumes_vector.begin(), flush_volumes_vector.end()); } - if (config.has("app", "flush_multiplier")) { - boost::algorithm::split(matrix, config.get("app", "flush_multiplier"), boost::algorithm::is_any_of("|")); + if (config.has_printer_setting(initial_printer_profile_name, "flush_multiplier")) { + boost::algorithm::split(matrix, config.get_printer_setting(initial_printer_profile_name, "flush_multiplier"), boost::algorithm::is_any_of("|")); auto flush_multipliers = matrix | boost::adaptors::transformed(boost::lexical_cast); project_config.option("flush_multiplier")->values = std::vector(flush_multipliers.begin(), flush_multipliers.end()); } @@ -2153,7 +2153,7 @@ void PresetBundle::export_selections(AppConfig &config) std::string flush_multiplier_str = boost::algorithm::join(project_config.option("flush_multiplier")->values | boost::adaptors::transformed(static_cast(std::to_string)), "|"); - config.set("flush_multiplier", flush_multiplier_str); + config.set_printer_setting(printer_name, "flush_multiplier", flush_multiplier_str); // BBS //config.set("presets", "sla_print", sla_prints.get_selected_preset_name()); diff --git a/src/slic3r/GUI/FilamentGroupPopup.cpp b/src/slic3r/GUI/FilamentGroupPopup.cpp index 5bdf379cfb..bf15990063 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.cpp +++ b/src/slic3r/GUI/FilamentGroupPopup.cpp @@ -17,6 +17,7 @@ static const wxColour BackGroundColor = wxColour("#FFFFFF"); static bool should_pop_up() { const auto &preset_bundle = wxGetApp().preset_bundle; + if (!preset_bundle->is_bbl_vendor()) return false; const auto &full_config = preset_bundle->full_config(); const auto nozzle_diameters = full_config.option("nozzle_diameter"); return nozzle_diameters->size() > 1; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index cdd273283c..8472cbe3d5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -990,6 +990,8 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr // BBS: data for rendering color arrangement recommendation m_nozzle_nums = print.config().option("nozzle_diameter")->values.size(); + // Orca hack: Hide filament group for non-bbl printers + if (!print.is_BBL_printer()) m_nozzle_nums = 1; std::vector filament_maps = print.get_filament_maps(); std::vector color_opt = print.config().option("filament_colour")->values; std::vector type_opt = print.config().option("filament_type")->values; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 63e07fdf90..58b1d05fc2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -15523,7 +15523,7 @@ void Plater::update_flush_volume_matrix(size_t old_nozzle_size, size_t new_nozzl if (first_flush_volume_mtx.size() == filament_nums * filament_nums * new_nozzle_size) { // load file set_flush_volumes_matrix(project_config->option("flush_volumes_matrix")->values, first_flush_volume_mtx, -1, new_nozzle_size); } else { - first_flush_volume_mtx.resize(filament_nums * filament_nums); + first_flush_volume_mtx.resize(filament_nums * filament_nums, 0); std::vector flush_volume_mtx; for (size_t i = 0; i < new_nozzle_size; ++i) { flush_volume_mtx.insert(flush_volume_mtx.end(), first_flush_volume_mtx.begin(), first_flush_volume_mtx.end()); @@ -15538,7 +15538,7 @@ void Plater::update_flush_volume_matrix(size_t old_nozzle_size, size_t new_nozzl std::vector new_flush_volume_mtx; for (size_t i = 0; i < new_nozzle_size; ++i) { std::vector flush_volume_mtx = get_flush_volumes_matrix(project_config->option("flush_volumes_matrix")->values, -1, old_nozzle_size); - flush_volume_mtx.resize(filament_nums * filament_nums); + flush_volume_mtx.resize(filament_nums * filament_nums, 0); new_flush_volume_mtx.insert(new_flush_volume_mtx.end(), flush_volume_mtx.begin(), flush_volume_mtx.end()); }