ENH: auto-arranging allows more filaments together

Auto-arranging allows more filaments to be printed on the same plate

Only HighTemp and LowTemp filaments are not allowed on the same plate.

Jira: https://jira.bambooolab.com/browse/STUDIO-4682
Change-Id: I1bd4966e6aaa55a6dd9dff05f0bd94f2795a62b0
(cherry picked from commit 965040912af0555ca190702e7c7ac92e177a2922)
This commit is contained in:
Arthur 2023-10-08 21:06:25 +08:00 committed by Lane.Wei
parent 2bd8a0806b
commit 3d5aa9479c
7 changed files with 159 additions and 91 deletions

View File

@ -76,6 +76,7 @@ class _Item {
public: public:
int itemid_{ 0 }; int itemid_{ 0 };
std::vector<int> extrude_ids; std::vector<int> extrude_ids;
int filament_temp_type = -1; // -1 means unset. otherwise should be {0,1,2}
double height{ 0 }; double height{ 0 };
double print_temp{ 0 }; double print_temp{ 0 };
double bed_temp{ 0 }; double bed_temp{ 0 };

View File

@ -1,5 +1,5 @@
#include "Arrange.hpp" #include "Arrange.hpp"
#include "Print.hpp"
#include "BoundingBox.hpp" #include "BoundingBox.hpp"
#include <libnest2d/backends/libslic3r/geometries.hpp> #include <libnest2d/backends/libslic3r/geometries.hpp>
@ -603,9 +603,11 @@ protected:
for (int i = 0; i < m_items.size(); i++) { for (int i = 0; i < m_items.size(); i++) {
Item& p = m_items[i]; Item& p = m_items[i];
if (p.is_virt_object) continue; if (p.is_virt_object) continue;
score += lambda3 * (item.bed_temp - p.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH); //score += lambda3 * (item.bed_temp - p.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
if (!Print::is_filaments_compatible({item.filament_temp_type,p.filament_temp_type}))
score += lambda3;
} }
score += lambda3 * (item.bed_temp - item.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH); //score += lambda3 * (item.bed_temp - item.vitrify_temp > VITRIFY_TEMP_DIFF_THRSH);
score += lambda4 * hasRowHeightConflict + lambda4 * hasLidHeightConflict; score += lambda4 * hasRowHeightConflict + lambda4 * hasLidHeightConflict;
} }
else { else {
@ -625,7 +627,9 @@ protected:
// 高度接近的件尽量摆到一起 // 高度接近的件尽量摆到一起
score += (1- std::abs(item.height - p.height) / params.printable_height) score += (1- std::abs(item.height - p.height) / params.printable_height)
* norm(pl::distance(ibb.center(), p.boundingBox().center())); * norm(pl::distance(ibb.center(), p.boundingBox().center()));
score += LARGE_COST_TO_REJECT * (item.bed_temp - p.bed_temp != 0); //score += LARGE_COST_TO_REJECT * (item.bed_temp - p.bed_temp != 0);
if (!Print::is_filaments_compatible({ item.filament_temp_type,p.filament_temp_type }))
score += LARGE_COST_TO_REJECT;
} }
} }
} }
@ -760,7 +764,8 @@ public:
if (on_packed) if (on_packed)
on_packed(ap); on_packed(ap);
BOOST_LOG_TRIVIAL(debug) << "arrange " + last_packed.name + " succeed!" BOOST_LOG_TRIVIAL(debug) << "arrange " + last_packed.name + " succeed!"
<< ", plate id=" << ap.bed_idx << ", pos=" << last_packed.translation(); << ", plate id=" << ap.bed_idx << ", pos=" << last_packed.translation()
<< ", temp_type=" << last_packed.filament_temp_type;
} }
}); });
@ -1039,6 +1044,7 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
item.print_temp = arrpoly.print_temp; item.print_temp = arrpoly.print_temp;
item.vitrify_temp = arrpoly.vitrify_temp; item.vitrify_temp = arrpoly.vitrify_temp;
item.inflation(arrpoly.inflation); item.inflation(arrpoly.inflation);
item.filament_temp_type = arrpoly.filament_temp_type;
} }
template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn) template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)

View File

@ -62,6 +62,7 @@ struct ArrangePolygon {
int row{0}; int row{0};
int col{0}; int col{0};
std::vector<int> extrude_ids{}; /// extruder_id for least extruder switch std::vector<int> extrude_ids{}; /// extruder_id for least extruder switch
int filament_temp_type{ -1 };
int bed_temp{0}; ///bed temperature for different material judge int bed_temp{0}; ///bed temperature for different material judge
int print_temp{0}; ///print temperature for different material judge int print_temp{0}; ///print temperature for different material judge
int first_bed_temp{ 0 }; ///first layer bed temperature for different material judge int first_bed_temp{ 0 }; ///first layer bed temperature for different material judge

View File

@ -2,6 +2,7 @@
#include <libslic3r/Model.hpp> #include <libslic3r/Model.hpp>
#include <libslic3r/Geometry/ConvexHull.hpp> #include <libslic3r/Geometry/ConvexHull.hpp>
#include <libslic3r/Print.hpp>
#include "MTUtils.hpp" #include "MTUtils.hpp"
namespace Slic3r { namespace Slic3r {
@ -143,6 +144,18 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::
ap.vitrify_temp = config.opt_int("temperature_vitrification", ap.extrude_ids.front() - 1); ap.vitrify_temp = config.opt_int("temperature_vitrification", ap.extrude_ids.front() - 1);
} }
// get filament temp types
auto* filament_types_opt = dynamic_cast<const ConfigOptionStrings*>(config.option("filament_type"));
if (filament_types_opt) {
std::set<int> filament_temp_types;
for (auto i : ap.extrude_ids) {
std::string type_str = filament_types_opt->get_at(i-1);
int temp_type = Print::get_filament_temp_type(type_str);
filament_temp_types.insert(temp_type);
}
ap.filament_temp_type = Print::get_compatible_filament_type(filament_temp_types);
}
// get brim width // get brim width
auto obj = instance->get_object(); auto obj = instance->get_object();

View File

@ -916,6 +916,44 @@ bool Print::check_multi_filaments_compatibility(const std::vector<std::string>&
return true; return true;
} }
bool Print::is_filaments_compatible(const std::vector<int>& filament_types)
{
bool has_high_temperature_filament = false;
bool has_low_temperature_filament = false;
for (const auto& type : filament_types) {
if (type == FilamentTempType::HighTemp)
has_high_temperature_filament = true;
else if (type == FilamentTempType::LowTemp)
has_low_temperature_filament = true;
}
if (has_high_temperature_filament && has_low_temperature_filament)
return false;
return true;
}
int Print::get_compatible_filament_type(const std::set<int>& filament_types)
{
bool has_high_temperature_filament = false;
bool has_low_temperature_filament = false;
for (const auto& type : filament_types) {
if (type == FilamentTempType::HighTemp)
has_high_temperature_filament = true;
else if (type == FilamentTempType::LowTemp)
has_low_temperature_filament = true;
}
if (has_high_temperature_filament && has_low_temperature_filament)
return HighLowCompatible;
else if (has_high_temperature_filament)
return HighTemp;
else if (has_low_temperature_filament)
return LowTemp;
return HighLowCompatible;
}
//BBS: this function is used to check whether multi filament can be printed //BBS: this function is used to check whether multi filament can be printed
StringObjectException Print::check_multi_filament_valid(const Print& print) StringObjectException Print::check_multi_filament_valid(const Print& print)
{ {

View File

@ -830,6 +830,15 @@ public:
static FilamentTempType get_filament_temp_type(const std::string& filament_type); static FilamentTempType get_filament_temp_type(const std::string& filament_type);
static int get_hrc_by_nozzle_type(const NozzleType& type); static int get_hrc_by_nozzle_type(const NozzleType& type);
static bool check_multi_filaments_compatibility(const std::vector<std::string>& filament_types); static bool check_multi_filaments_compatibility(const std::vector<std::string>& filament_types);
// similar to check_multi_filaments_compatibility, but the input is int, and may be negative (means unset)
static bool is_filaments_compatible(const std::vector<int>& types);
// get the compatible filament type of a multi-material object
// Rule:
// 1. LowTemp+HighLowCompatible=LowTemp
// 2. HighTemp++HighLowCompatible=HighTemp
// 3. LowTemp+HighTemp+...=HighLowCompatible
// Unset types are just ignored.
static int get_compatible_filament_type(const std::set<int>& types);
protected: protected:
// Invalidates the step, and its depending steps in Print. // Invalidates the step, and its depending steps in Print.

View File

@ -518,9 +518,9 @@ void ArrangeJob::process()
{ {
BOOST_LOG_TRIVIAL(warning)<< "Arrange full params: "<< params.to_json(); BOOST_LOG_TRIVIAL(warning)<< "Arrange full params: "<< params.to_json();
BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected before arranging: %1%") % m_selected.size(); BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected before arranging: %1%") % m_selected.size();
for (auto selected : m_selected) for (auto selected : m_selected) {
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx<<", filemant_type:" << selected.filament_temp_type;
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp; }
BOOST_LOG_TRIVIAL(debug) << "items unselected before arrange: "; BOOST_LOG_TRIVIAL(debug) << "items unselected before arrange: ";
for (auto item : m_unselected) for (auto item : m_unselected)
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose(); BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();