ENH: improve auto arranging's wipe tower logic
1. If there is already a wipe tower on current plate, leave it there regardless need_wipe_tower flag. This is useful when we have toolchange custom gcodes. 2. Correct wipe tower pos to prevent it outside bed. Jira: STUDIO-4426 Change-Id: Iedecc7c5fe7ced01533d0a302253841046a7fb42 (cherry picked from commit e8d728e46b12baaf9fb0e87e3d14197ae3616826)
This commit is contained in:
parent
845a397e37
commit
76d073a9ea
|
@ -725,6 +725,7 @@ public:
|
||||||
for (Item itm : items) {
|
for (Item itm : items) {
|
||||||
if (itm.is_wipe_tower) {
|
if (itm.is_wipe_tower) {
|
||||||
starting_point = itm.boundingBox().center();
|
starting_point = itm.boundingBox().center();
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "arrange we have wipe tower, change starting point to: " << starting_point;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -749,15 +750,13 @@ 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;
|
<< ", plate id=" << ap.bed_idx << ", pos=" << last_packed.translation();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (progressind) {
|
m_pck.unfitIndicator([this](std::string name) {
|
||||||
m_pck.unfitIndicator([this, progressind](std::string name) {
|
BOOST_LOG_TRIVIAL(debug) << "arrange progress: " + name;
|
||||||
BOOST_LOG_TRIVIAL(debug) << "arrange not fit: " + name;
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stopcond) m_pck.stopCondition(stopcond);
|
if (stopcond) m_pck.stopCondition(stopcond);
|
||||||
|
|
||||||
|
|
|
@ -4910,6 +4910,12 @@ GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info(int plate_idx) const
|
||||||
float brim_width = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("prime_tower_brim_width");
|
float brim_width = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("prime_tower_brim_width");
|
||||||
wti.m_bb.offset((brim_width));
|
wti.m_bb.offset((brim_width));
|
||||||
|
|
||||||
|
// BBS: the wipe tower pos might be outside bed
|
||||||
|
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||||
|
BoundingBoxf3 build_volume = plate->get_build_volume();
|
||||||
|
wti.m_pos.x() = std::clamp(wti.m_pos.x(), 0.0, build_volume.max.x() - wti.m_bb.size().x());
|
||||||
|
wti.m_pos.y() = std::clamp(wti.m_pos.y(), 0.0, build_volume.max.y() - wti.m_bb.size().y());
|
||||||
|
|
||||||
// BBS: add partplate logic
|
// BBS: add partplate logic
|
||||||
wti.m_plate_idx = plate_idx;
|
wti.m_plate_idx = plate_idx;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -255,18 +255,19 @@ void ArrangeJob::prepare_wipe_tower()
|
||||||
bool need_wipe_tower = false;
|
bool need_wipe_tower = false;
|
||||||
|
|
||||||
// if wipe tower is explicitly disabled, no need to estimate
|
// if wipe tower is explicitly disabled, no need to estimate
|
||||||
DynamicPrintConfig ¤t_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
DynamicPrintConfig& current_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||||
auto op = current_config.option("enable_prime_tower");
|
auto op = current_config.option("enable_prime_tower");
|
||||||
if (op && op->getBool() == false || params.is_seq_print) return;
|
bool enable_prime_tower = op && op->getBool();
|
||||||
|
if (!enable_prime_tower || params.is_seq_print) return;
|
||||||
|
|
||||||
bool smooth_timelapse = false;
|
bool smooth_timelapse = false;
|
||||||
auto sop = current_config.option("timelapse_type");
|
auto sop = current_config.option("timelapse_type");
|
||||||
if (sop) { smooth_timelapse = sop->getInt() == TimelapseType::tlSmooth; }
|
if (sop) { smooth_timelapse = sop->getInt() == TimelapseType::tlSmooth; }
|
||||||
if (smooth_timelapse) { need_wipe_tower = true; }
|
if (smooth_timelapse) { need_wipe_tower = true; }
|
||||||
|
|
||||||
// estimate if we need wipe tower for all plates:
|
// estimate if we need wipe tower for all plates:
|
||||||
// need wipe tower if some object has multiple extruders (has paint-on colors or support material)
|
// need wipe tower if some object has multiple extruders (has paint-on colors or support material)
|
||||||
for (const auto &item : m_selected) {
|
for (const auto& item : m_selected) {
|
||||||
std::set<int> obj_extruders;
|
std::set<int> obj_extruders;
|
||||||
obj_extruders.insert(item.extrude_ids.begin(), item.extrude_ids.end());
|
obj_extruders.insert(item.extrude_ids.begin(), item.extrude_ids.end());
|
||||||
if (obj_extruders.size() > 1) {
|
if (obj_extruders.size() > 1) {
|
||||||
|
@ -278,11 +279,11 @@ void ArrangeJob::prepare_wipe_tower()
|
||||||
|
|
||||||
// if multile extruders have same bed temp, we need wipe tower
|
// if multile extruders have same bed temp, we need wipe tower
|
||||||
// 允许不同材料落在相同盘,且所有选定对象中使用了多种热床温度相同的材料
|
// 允许不同材料落在相同盘,且所有选定对象中使用了多种热床温度相同的材料
|
||||||
if (params.allow_multi_materials_on_same_plate) {
|
if (params.allow_multi_materials_on_same_plate) {
|
||||||
std::map<int, std::set<int>> bedTemp2extruderIds;
|
std::map<int, std::set<int>> bedTemp2extruderIds;
|
||||||
for (const auto &item : m_selected)
|
for (const auto& item : m_selected)
|
||||||
for (auto id : item.extrude_ids) { bedTemp2extruderIds[item.bed_temp].insert(id); }
|
for (auto id : item.extrude_ids) { bedTemp2extruderIds[item.bed_temp].insert(id); }
|
||||||
for (const auto &be : bedTemp2extruderIds) {
|
for (const auto& be : bedTemp2extruderIds) {
|
||||||
if (be.second.size() > 1) {
|
if (be.second.size() > 1) {
|
||||||
need_wipe_tower = true;
|
need_wipe_tower = true;
|
||||||
BOOST_LOG_TRIVIAL(info) << "arrange: need wipe tower because allow_multi_materials_on_same_plate=true and we have multiple extruders of same type";
|
BOOST_LOG_TRIVIAL(info) << "arrange: need wipe tower because allow_multi_materials_on_same_plate=true and we have multiple extruders of same type";
|
||||||
|
@ -292,35 +293,24 @@ void ArrangeJob::prepare_wipe_tower()
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "arrange: need_wipe_tower=" << need_wipe_tower;
|
BOOST_LOG_TRIVIAL(info) << "arrange: need_wipe_tower=" << need_wipe_tower;
|
||||||
|
|
||||||
if (need_wipe_tower) {
|
|
||||||
// check all plates to see if wipe tower is already there
|
|
||||||
ArrangePolygon wipe_tower_ap;
|
|
||||||
std::vector<bool> plates_have_wipe_tower(MAX_NUM_PLATES, false);
|
|
||||||
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++)
|
|
||||||
if (auto wti = get_wipe_tower(*m_plater, bedid)) {
|
|
||||||
ArrangePolygon &&ap = get_wipetower_arrange_poly(&wti);
|
|
||||||
wipe_tower_ap = ap;
|
|
||||||
ap.bed_idx = bedid;
|
|
||||||
m_unselected.emplace_back(std::move(ap));
|
|
||||||
plates_have_wipe_tower[bedid] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if wipe tower is not init yet (no wipe tower in any plate before arrangement)
|
ArrangePolygon wipe_tower_ap;
|
||||||
//if (wipe_tower_ap.poly.empty()) {
|
wipe_tower_ap.name = "WipeTower";
|
||||||
// auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
wipe_tower_ap.is_virt_object = true;
|
||||||
// wipe_tower_ap.poly.contour.points = print.first_layer_wipe_tower_corners(false);
|
wipe_tower_ap.is_wipe_tower = true;
|
||||||
wipe_tower_ap.name = "WipeTower";
|
const GLCanvas3D* canvas3D = static_cast<const GLCanvas3D*>(m_plater->canvas3D());
|
||||||
wipe_tower_ap.is_virt_object = true;
|
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++) {
|
||||||
wipe_tower_ap.is_wipe_tower = true;
|
if (auto wti = get_wipe_tower(*m_plater, bedid)) {
|
||||||
//}
|
// wipe tower is already there
|
||||||
const GLCanvas3D* canvas3D=static_cast<const GLCanvas3D *>(m_plater->canvas3D());
|
wipe_tower_ap = get_wipetower_arrange_poly(&wti);
|
||||||
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++) {
|
wipe_tower_ap.bed_idx = bedid;
|
||||||
if (!plates_have_wipe_tower[bedid]) {
|
m_unselected.emplace_back(wipe_tower_ap);
|
||||||
wipe_tower_ap.translation = {0, 0};
|
}
|
||||||
wipe_tower_ap.poly.contour.points = canvas3D->estimate_wipe_tower_points(bedid, !only_on_partplate);
|
else if (need_wipe_tower) {
|
||||||
wipe_tower_ap.bed_idx = bedid;
|
wipe_tower_ap.translation = { 0, 0 };
|
||||||
m_unselected.emplace_back(wipe_tower_ap);
|
wipe_tower_ap.poly.contour.points = canvas3D->estimate_wipe_tower_points(bedid, !only_on_partplate);
|
||||||
}
|
wipe_tower_ap.bed_idx = bedid;
|
||||||
|
m_unselected.emplace_back(wipe_tower_ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,8 +510,7 @@ void ArrangeJob::process()
|
||||||
double scaled_exclusion_gap = scale_(1);
|
double scaled_exclusion_gap = scale_(1);
|
||||||
partplate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap);
|
partplate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap);
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "arrange bed_shrink_x=" << params.bed_shrink_x
|
BOOST_LOG_TRIVIAL(debug) << "arrange bedpts:" << bedpts[0].transpose() << ", " << bedpts[1].transpose() << ", " << bedpts[2].transpose() << ", " << bedpts[3].transpose();
|
||||||
<< "; bedpts:" << bedpts[0].transpose() << ", " << bedpts[1].transpose() << ", " << bedpts[2].transpose() << ", " << bedpts[3].transpose();
|
|
||||||
|
|
||||||
params.stopcondition = [this]() { return was_canceled(); };
|
params.stopcondition = [this]() { return was_canceled(); };
|
||||||
|
|
||||||
|
@ -537,8 +526,7 @@ void ArrangeJob::process()
|
||||||
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp;
|
<< ", 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)
|
||||||
if (!item.is_virt_object)
|
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();
|
||||||
BOOST_LOG_TRIVIAL(debug) << item.name << ", extruder: " << item.extrude_ids.back() << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arrangement::arrange(m_selected, m_unselected, bedpts, params);
|
arrangement::arrange(m_selected, m_unselected, bedpts, params);
|
||||||
|
@ -553,9 +541,7 @@ void ArrangeJob::process()
|
||||||
<< ", trans: " << unscale<double>(selected.translation(X)) << ","<< unscale<double>(selected.translation(Y));
|
<< ", trans: " << unscale<double>(selected.translation(X)) << ","<< unscale<double>(selected.translation(Y));
|
||||||
BOOST_LOG_TRIVIAL(debug) << "items unselected after arrange: ";
|
BOOST_LOG_TRIVIAL(debug) << "items unselected after arrange: ";
|
||||||
for (auto item : m_unselected)
|
for (auto item : m_unselected)
|
||||||
if (!item.is_virt_object)
|
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();
|
||||||
BOOST_LOG_TRIVIAL(debug) << item.name << ", extruder: " << item.extrude_ids.back() << ", bed: " << item.bed_idx
|
|
||||||
<< ", trans: " << item.translation.transpose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arrangement::arrange(m_unprintable, {}, bedpts, params);
|
arrangement::arrange(m_unprintable, {}, bedpts, params);
|
||||||
|
|
Loading…
Reference in New Issue