diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index ac33c3fc4..9dec86c42 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -528,28 +528,27 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto } } -bool ToolOrdering::check_tpu_group(std::vector filament_maps) const +bool ToolOrdering::check_tpu_group(const std::vector&used_filaments,const std::vector& filament_maps,const PrintConfig* config,int master_extruder_id) { - std::vector all_filaments; - for (const auto < : m_layer_tools) { - append(all_filaments, lt.extruders); - sort_remove_duplicates(all_filaments); - } - int check_extruder_id = -1; std::map> extruder_filament_nums; - for (unsigned int filament_id : all_filaments) { + for (unsigned int filament_id : used_filaments) { int extruder_id = filament_maps[filament_id]; extruder_filament_nums[extruder_id].push_back(filament_id); - std::string filament_name = m_print->config().filament_type.get_at(filament_id); - if (filament_name == "TPU") { - check_extruder_id = filament_maps[filament_id]; + std::string filament_type = config->filament_type.get_at(filament_id); + if (filament_type == "TPU") { + // if we meet two TPU filaments, just return false + if(check_extruder_id==-1) + check_extruder_id = filament_maps[filament_id]; + else + return false; } + } - if (check_extruder_id != -1 && (extruder_filament_nums[check_extruder_id].size() > 1)) { - return false; - } + // TPU can only place in master extruder, and it should have no other filaments in the same extruder + if (check_extruder_id != -1 && (check_extruder_id!=master_extruder_id || extruder_filament_nums[check_extruder_id].size() > 1)) { + return false; } return true; @@ -1033,29 +1032,36 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first if (nozzle_nums > 1) { filament_maps = m_print->get_filament_maps(); map_mode = m_print->get_filament_map_mode(); - if (map_mode == FilamentMapMode::fmmAuto - && (print_config->print_sequence != PrintSequence::ByObject || m_print->objects().size() == 1)) { - const PrintConfig* print_config = m_print_config_ptr; - if (!print_config && m_print_object_ptr) { - print_config = &(m_print_object_ptr->print()->config()); + // only check and map in sequence mode, in by object mode, we check the map in print.cpp + if (print_config->print_sequence != PrintSequence::ByObject || m_print->objects().size() == 1) { + if (map_mode == FilamentMapMode::fmmAuto) { + const PrintConfig* print_config = m_print_config_ptr; + if (!print_config && m_print_object_ptr) { + print_config = &(m_print_object_ptr->print()->config()); + } + + filament_maps = ToolOrdering::get_recommended_filament_maps(layer_filaments, print_config, physical_unprintables, geometric_unprintables); + + if (filament_maps.empty()) + return; + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; }); + m_print->update_filament_maps_to_config(filament_maps); } + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); - filament_maps = ToolOrdering::get_recommended_filament_maps(layer_filaments, print_config, physical_unprintables, geometric_unprintables); - - if (filament_maps.empty()) - return; - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; }); - m_print->update_filament_maps_to_config(filament_maps); + // TODO: load the master extruder_id from config + if (!check_tpu_group(used_filaments, filament_maps, print_config, 1)) { + if (map_mode == FilamentMapMode::fmmManual) { + throw Slic3r::RuntimeError(std::string("Manual grouping error: TPU can only be placed in a nozzle alone.")); + } + else { + throw Slic3r::RuntimeError(std::string("Auto grouping error: TPU can only be placed in a nozzle alone.")); + } + } } - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); - - if (!check_tpu_group(filament_maps)) { - if (map_mode == FilamentMapMode::fmmManual) { - throw Slic3r::RuntimeError(std::string("Manual grouping error: TPU can only be placed in a nozzle alone.")); - } - else { - throw Slic3r::RuntimeError(std::string("Auto grouping error: TPU can only be placed in a nozzle alone.")); - } + else { + // we just need to change the map to 0 based + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); } } diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index 85a2dbfa1..903fa5891 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -229,11 +229,16 @@ public: std::vector& layer_tools() { return m_layer_tools; } bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().has_wipe_tower; } - + /* + * called in single extruder mode, the value in map are all 0 + * called in dual extruder mode, the value in map will be 0 or 1 + * 0 based group id + */ static std::vector get_recommended_filament_maps(const std::vector>& layer_filaments, const PrintConfig* print_config, const std::vector>& physical_unprintables, const std::vector>& geometric_unprintables); static std::vector> get_physical_unprintables(const std::vector& layer_filaments, const PrintConfig* config, int master_extruder_id = 1); static std::vector> get_geometrical_unprintables(const std::vector>& unprintable_arrs, const PrintConfig* config); + static bool check_tpu_group(const std::vector&used_filaments,const std::vector& filament_maps,const PrintConfig* config,int master_extruder_id); // should be called after doing reorder FilamentChangeStats get_filament_change_stats(FilamentChangeMode mode); @@ -242,7 +247,6 @@ private: void initialize_layers(std::vector &zs); void collect_extruders(const PrintObject &object, const std::vector> &per_layer_extruder_switches); void reorder_extruders(unsigned int last_extruder_id); - bool check_tpu_group(std::vector filament_maps) const; // BBS void reorder_extruders(std::vector tool_order_layer0); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 18d4ae6bd..e66caf28f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1861,23 +1861,38 @@ void Print::process(std::unordered_map* slice_time, bool if (this->config().print_sequence == PrintSequence::ByObject) { // Order object instances for sequential print. print_object_instances_ordering = sort_object_instances_by_model_order(*this); - std::vector> all_filaments; - for (print_object_instance_sequential_active = print_object_instances_ordering.begin(); print_object_instance_sequential_active != print_object_instances_ordering.end(); ++print_object_instance_sequential_active) { - tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); - for (const auto& layer_tool : tool_ordering.layer_tools()) { - all_filaments.emplace_back(layer_tool.extruders); + if (m_config.nozzle_diameter.size() > 1) { + std::vector> all_filaments; + for (print_object_instance_sequential_active = print_object_instances_ordering.begin(); print_object_instance_sequential_active != print_object_instances_ordering.end(); ++print_object_instance_sequential_active) { + tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); + for (const auto& layer_tool : tool_ordering.layer_tools()) { + all_filaments.emplace_back(layer_tool.extruders); + } } - } - auto used_filaments = collect_sorted_used_filaments(all_filaments); - auto physical_unprintables = ToolOrdering::get_physical_unprintables(used_filaments, &m_config); - auto geometric_unprintables = ToolOrdering::get_geometrical_unprintables(get_unprintable_filament_ids(), &m_config); + auto used_filaments = collect_sorted_used_filaments(all_filaments); + auto physical_unprintables = ToolOrdering::get_physical_unprintables(used_filaments, &m_config); + auto geometric_unprintables = ToolOrdering::get_geometrical_unprintables(get_unprintable_filament_ids(), &m_config); - // get recommended filament map - if (get_filament_map_mode() == FilamentMapMode::fmmAuto) { - std::vector recomended_maps = ToolOrdering::get_recommended_filament_maps(all_filaments, &config(), physical_unprintables, geometric_unprintables); - std::transform(recomended_maps.begin(), recomended_maps.end(), recomended_maps.begin(), [](int value) { return value + 1; }); - update_filament_maps_to_config(recomended_maps); + std::vectorfilament_maps = this->get_filament_maps(); + auto map_mode = get_filament_map_mode(); + // get recommended filament map + if (map_mode == FilamentMapMode::fmmAuto) { + filament_maps = ToolOrdering::get_recommended_filament_maps(all_filaments, &config(), physical_unprintables, geometric_unprintables); + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; }); + update_filament_maps_to_config(filament_maps); + } + // check map valid both in auto and mannual mode + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); + // TODO: load master extruder id from config + if (!ToolOrdering::check_tpu_group(used_filaments, filament_maps, &m_config, 1)) { + if (map_mode == FilamentMapMode::fmmManual) { + throw Slic3r::RuntimeError(std::string("Manual grouping error: TPU can only be placed in a nozzle alone.")); + } + else { + throw Slic3r::RuntimeError(std::string("Auto grouping error: TPU can only be placed in a nozzle alone.")); + } + } } // print_object_instances_ordering = sort_object_instances_by_max_z(print); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index b889b91e1..3d5babc00 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -822,6 +822,7 @@ public: const ToolOrdering& tool_ordering() const { return m_tool_ordering; } void update_filament_maps_to_config(std::vector f_maps); + // 1 based group ids std::vector get_filament_maps() const; FilamentMapMode get_filament_map_mode() const; // get the group label of filament