Merge some BS1.7 changes:

bring back fill_bed feature, original implemention from PrusaSlicer. BS added exclusion logic.
This commit is contained in:
SoftFever 2023-08-07 23:42:27 +08:00
parent b8db25ac0e
commit 3acd89e877
20 changed files with 242 additions and 180 deletions

View file

@ -86,18 +86,21 @@ template<class PConf>
void fill_config(PConf& pcfg, const ArrangeParams &params) {
if (params.is_seq_print) {
// Align the arranged pile into the center of the bin
pcfg.alignment = PConf::Alignment::CENTER;
// Start placing the items from the center of the print bed
pcfg.starting_point = PConf::Alignment::BOTTOM_LEFT;
}
else {
// Align the arranged pile into the center of the bin
pcfg.alignment = PConf::Alignment::CENTER;
// Start placing the items from the center of the print bed
pcfg.starting_point = PConf::Alignment::TOP_RIGHT;
}
if (params.do_final_align) {
// Align the arranged pile into the center of the bin
pcfg.alignment = PConf::Alignment::CENTER;
}else
pcfg.alignment = PConf::Alignment::DONT_ALIGN;
// Try 4 angles (45 degree step) and find the one with min cost
if (params.allow_rotations)
pcfg.rotations = {0., PI / 4., PI/2, 3. * PI / 4. };
@ -452,27 +455,25 @@ protected:
}
std::set<int> extruder_ids;
int non_virt_cnt = 0;
std::set<int> first_object_extruder_ids;
for (int i = 0; i < m_items.size(); i++) {
Item& p = m_items[i];
if (p.is_virt_object) continue;
extruder_ids.insert(p.extrude_ids.begin(),p.extrude_ids.end());
non_virt_cnt++;
if (non_virt_cnt == 1) { first_object_extruder_ids.insert(p.extrude_ids.begin(), p.extrude_ids.end()); }
}
extruder_ids.insert(item.extrude_ids.begin(),item.extrude_ids.end());
// add a large cost if not multi materials on same plate is not allowed
if (!params.allow_multi_materials_on_same_plate) {
bool first_object = non_virt_cnt == 0;
bool same_color_with_first_object = std::all_of(item.extrude_ids.begin(), item.extrude_ids.end(),
[&](int color) { return first_object_extruder_ids.find(color) != first_object_extruder_ids.end(); });
// non_virt_cnt==0 means it's the first object, which can be multi-color
if (!(first_object || same_color_with_first_object)) score += LARGE_COST_TO_REJECT * 1.3;
// it's the first object, which can be multi-color
bool first_object = extruder_ids.empty();
// the two objects (previously packed items and the current item) are considered having same color if either one's colors are a subset of the other
std::set<int> item_extruder_ids(item.extrude_ids.begin(), item.extrude_ids.end());
bool same_color_with_previous_items = std::includes(item_extruder_ids.begin(), item_extruder_ids.end(), extruder_ids.begin(), extruder_ids.end())
|| std::includes(extruder_ids.begin(), extruder_ids.end(), item_extruder_ids.begin(), item_extruder_ids.end());
if (!(first_object || same_color_with_previous_items)) score += LARGE_COST_TO_REJECT * 1.3;
}
// for layered printing, we want extruder change as few as possible
// this has very weak effect, CAN NOT use a large weight
extruder_ids.insert(item.extrude_ids.begin(), item.extrude_ids.end());
if (!params.is_seq_print) {
score += 1 * std::max(0, ((int) extruder_ids.size() - 1));
}
@ -544,12 +545,6 @@ public:
if (items.empty()) return;
auto binbb = sl::boundingBox(m_bin);
// BBS: excluded region (virtual object but not wipe tower) should not affect final alignment
//bool all_is_excluded_region = std::all_of(items.begin(), items.end(), [](Item &itm) { return itm.is_virt_object && !itm.is_wipe_tower; });
//if (!all_is_excluded_region)
// cfg.alignment = PConfig::Alignment::DONT_ALIGN;
//else
// cfg.alignment = PConfig::Alignment::CENTER;
auto starting_point = cfg.starting_point == PConfig::Alignment::BOTTOM_LEFT ? binbb.minCorner() : binbb.center();
// if we have wipe tower, items should be arranged around wipe tower
@ -561,15 +556,7 @@ public:
}
cfg.object_function = [this, binbb, starting_point](const Item &item, const ItemGroup &packed_items) {
// 在我们的摆盘中,没有天然的固定对象。固定对象只有:屏蔽区域、挤出补偿区域、料塔。
// 对于屏蔽区域,摆入的对象仍然是可以向右上滑动的;
// 对挤出料塔,摆入的对象不能滑动(必须围绕料塔)
bool pack_around_wipe_tower = std::any_of(packed_items.begin(), packed_items.end(), [](Item& itm) { return itm.is_wipe_tower; });
//if(pack_around_wipe_tower)
return fixed_overfit(objfunc(item, starting_point), binbb);
//else {
// return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb, m_excluded_and_extruCali_regions);
//}
return fixed_overfit(objfunc(item, starting_point), binbb);
};
};

View file

@ -57,7 +57,7 @@ struct ArrangePolygon {
//BBS: add row/col for sudoku-style layout
int row{0};
int col{0};
std::vector<int> extrude_ids{1}; ///extruder_id for least extruder switch
std::vector<int> extrude_ids{}; /// extruder_id for least extruder switch
int bed_temp{0}; ///bed 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
@ -114,6 +114,8 @@ struct ArrangeParams {
bool allow_rotations = false;
bool do_final_align = true;
//BBS: add specific arrange params
bool allow_multi_materials_on_same_plate = true;
bool avoid_extrusion_cali_region = true;

View file

@ -807,7 +807,7 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
offset_top_surface = 0;
// don't takes into account too thin areas
// skip if the exposed area is smaller than 2x perimeter width
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), 2.0 * (double(perimeter_width)));
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), 2.5 * (double(perimeter_width)));
Polygons grown_upper_slices = offset(*this->upper_slices, min_width_top_surface);

View file

@ -685,9 +685,9 @@ bool Preset::is_custom_defined()
return false;
}
bool Preset::is_bbl_vendor_preset(PresetBundle *preset_bundle)
bool Preset::has_lidar(PresetBundle *preset_bundle)
{
bool is_bbl_vendor_preset = false;
bool has_lidar = false;
if (preset_bundle) {
auto config = &preset_bundle->printers.get_edited_preset().config;
std::string vendor_name;
@ -700,9 +700,9 @@ bool Preset::is_bbl_vendor_preset(PresetBundle *preset_bundle)
}
}
if (!vendor_name.empty())
is_bbl_vendor_preset = vendor_name.compare("BBL") == 0 ? true : false;
has_lidar = vendor_name.compare("BBL") == 0 ? true : false;
}
return is_bbl_vendor_preset;
return has_lidar;
}
static std::vector<std::string> s_Preset_print_options {

View file

@ -302,7 +302,7 @@ public:
std::string get_current_printer_type(PresetBundle *preset_bundle); // get current preset type
bool is_custom_defined();
bool is_bbl_vendor_preset(PresetBundle *preset_bundle);
bool has_lidar(PresetBundle *preset_bundle);