FIX: auto-arrange unable to arrage a large number of small items
1. Should start from bottom left if there is excluded regions 2. avoid exclusion regions in fixed_overfit_topright_sliding Jira: STUDIO-1422 Change-Id: If88ecf86a0485bd478a77df8cfd4942df8ca27ac (cherry picked from commit a8393de51bd178b731ef4c7201a5fe3247d97a1f)
This commit is contained in:
parent
d152b4d235
commit
f6fed97b9d
2 changed files with 32 additions and 17 deletions
|
@ -84,7 +84,7 @@ const double BIG_ITEM_TRESHOLD = 0.02;
|
||||||
template<class PConf>
|
template<class PConf>
|
||||||
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
||||||
|
|
||||||
if (params.is_seq_print) {
|
if (params.is_seq_print || params.excluded_regions.empty()==false) {
|
||||||
// Align the arranged pile into the center of the bin
|
// Align the arranged pile into the center of the bin
|
||||||
pcfg.alignment = PConf::Alignment::CENTER;
|
pcfg.alignment = PConf::Alignment::CENTER;
|
||||||
// Start placing the items from the center of the print bed
|
// Start placing the items from the center of the print bed
|
||||||
|
@ -137,7 +137,8 @@ static double fixed_overfit(const std::tuple<double, Box>& result, const Box &bi
|
||||||
}
|
}
|
||||||
|
|
||||||
// useful for arranging big circle objects
|
// useful for arranging big circle objects
|
||||||
static double fixed_overfit_topright_sliding(const std::tuple<double, Box>& result, const Box& binbb)
|
template<class PConf>
|
||||||
|
static double fixed_overfit_topright_sliding(const std::tuple<double, Box> &result, const Box &binbb, const PConf &config)
|
||||||
{
|
{
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
Box pilebb = std::get<1>(result);
|
Box pilebb = std::get<1>(result);
|
||||||
|
@ -152,6 +153,18 @@ static double fixed_overfit_topright_sliding(const std::tuple<double, Box>& resu
|
||||||
auto diff = double(fullbb.area()) - binbb.area();
|
auto diff = double(fullbb.area()) - binbb.area();
|
||||||
if (diff > 0) score += diff;
|
if (diff > 0) score += diff;
|
||||||
|
|
||||||
|
// excluded regions and nonprefered regions should not intersect the translated pilebb
|
||||||
|
for (auto ®ion : config.m_excluded_regions) {
|
||||||
|
Box bb = region.boundingBox();
|
||||||
|
auto area_ = bb.intersection(pilebb).area();
|
||||||
|
if (area_ > 0) score += area_;
|
||||||
|
}
|
||||||
|
for (auto ®ion : config.m_nonprefered_regions) {
|
||||||
|
Box bb = region.boundingBox();
|
||||||
|
auto area_ = bb.intersection(pilebb).area();
|
||||||
|
if (area_ > 0) score += area_;
|
||||||
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +558,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.object_function = [this, binbb, starting_point](const Item& item, const ItemGroup& packed_items) {
|
cfg.object_function = [this, binbb, starting_point, &cfg](const Item &item, const ItemGroup &packed_items) {
|
||||||
// 在我们的摆盘中,没有天然的固定对象。固定对象只有:屏蔽区域、挤出补偿区域、料塔。
|
// 在我们的摆盘中,没有天然的固定对象。固定对象只有:屏蔽区域、挤出补偿区域、料塔。
|
||||||
// 对于屏蔽区域,摆入的对象仍然是可以向右上滑动的;
|
// 对于屏蔽区域,摆入的对象仍然是可以向右上滑动的;
|
||||||
// 对挤出料塔,摆入的对象不能滑动(必须围绕料塔)
|
// 对挤出料塔,摆入的对象不能滑动(必须围绕料塔)
|
||||||
|
@ -553,7 +566,7 @@ public:
|
||||||
if(pack_around_wipe_tower)
|
if(pack_around_wipe_tower)
|
||||||
return fixed_overfit(objfunc(item, starting_point), binbb);
|
return fixed_overfit(objfunc(item, starting_point), binbb);
|
||||||
else {
|
else {
|
||||||
return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb);
|
return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb, cfg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -157,7 +157,7 @@ void ArrangeJob::prepare_selected() {
|
||||||
m_locked.emplace_back(std::move(ap));
|
m_locked.emplace_back(std::move(ap));
|
||||||
if (inst_sel[i])
|
if (inst_sel[i])
|
||||||
selected_is_locked = true;
|
selected_is_locked = true;
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % i;
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%, name %3%") % oidx % i % mo->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,9 @@ void ArrangeJob::prepare_all() {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_wipe_tower();
|
prepare_wipe_tower();
|
||||||
|
|
||||||
|
// add the virtual object into unselect list if has
|
||||||
|
plate_list.preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 准备料塔。逻辑如下:
|
// 准备料塔。逻辑如下:
|
||||||
|
@ -346,17 +349,18 @@ void ArrangeJob::prepare_partplate() {
|
||||||
ArrangePolygons& cont = mo->instances[inst_idx]->printable ?
|
ArrangePolygons& cont = mo->instances[inst_idx]->printable ?
|
||||||
(in_plate ? m_selected : m_unselected) :
|
(in_plate ? m_selected : m_unselected) :
|
||||||
m_unprintable;
|
m_unprintable;
|
||||||
ap.itemid = cont.size();
|
|
||||||
bool locked = plate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate);
|
bool locked = plate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate);
|
||||||
if (!locked)
|
if (!locked)
|
||||||
{
|
{
|
||||||
|
ap.itemid = cont.size();
|
||||||
cont.emplace_back(std::move(ap));
|
cont.emplace_back(std::move(ap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//skip this object due to be not in current plate, treated as locked
|
//skip this object due to be not in current plate, treated as locked
|
||||||
|
ap.itemid = m_locked.size();
|
||||||
m_locked.emplace_back(std::move(ap));
|
m_locked.emplace_back(std::move(ap));
|
||||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx;
|
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,11 +371,8 @@ void ArrangeJob::prepare_partplate() {
|
||||||
m_unselected.emplace_back(std::move(ap));
|
m_unselected.emplace_back(std::move(ap));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The strides have to be removed from the fixed items. For the
|
// add the virtual object into unselect list if has
|
||||||
// arrangeable (selected) items bed_idx is ignored and the
|
plate_list.preprocess_exclude_areas(m_unselected, current_plate_index + 1);
|
||||||
// translation is irrelevant.
|
|
||||||
//BBS: remove logic for unselected object
|
|
||||||
//for (auto& p : m_unselected) p.translation(X) -= p.bed_idx * stride;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: add partplate logic
|
//BBS: add partplate logic
|
||||||
|
@ -410,8 +411,6 @@ void ArrangeJob::prepare()
|
||||||
prepare_partplate();
|
prepare_partplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
//add the virtual object into unselect list if has
|
|
||||||
m_plater->get_partplate_list().preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
|
|
||||||
|
|
||||||
#if SAVE_ARRANGE_POLY
|
#if SAVE_ARRANGE_POLY
|
||||||
if (1)
|
if (1)
|
||||||
|
@ -498,13 +497,14 @@ void ArrangeJob::process()
|
||||||
{
|
{
|
||||||
const GLCanvas3D::ArrangeSettings &settings =
|
const GLCanvas3D::ArrangeSettings &settings =
|
||||||
static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings();
|
static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings();
|
||||||
|
auto & partplate_list = m_plater->get_partplate_list();
|
||||||
auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||||
|
|
||||||
if (params.is_seq_print)
|
if (params.is_seq_print)
|
||||||
params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius));
|
params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius));
|
||||||
|
|
||||||
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
||||||
m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
||||||
|
|
||||||
double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0;
|
double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0;
|
||||||
double brim_max = 0;
|
double brim_max = 0;
|
||||||
|
@ -547,7 +547,8 @@ void ArrangeJob::process()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
m_plater->get_partplate_list().preprocess_exclude_areas(params.excluded_regions, 1);
|
partplate_list.preprocess_exclude_areas(params.excluded_regions, 1);
|
||||||
|
partplate_list.preprocess_exclude_areas(params.nonprefered_regions, 1);
|
||||||
|
|
||||||
// shrink bed by moving to center by dist
|
// shrink bed by moving to center by dist
|
||||||
Points bedpts = get_bed_shape(*m_plater->config());
|
Points bedpts = get_bed_shape(*m_plater->config());
|
||||||
|
@ -589,7 +590,8 @@ void ArrangeJob::process()
|
||||||
BOOST_LOG_TRIVIAL(debug) << "items selected after arrange: ";
|
BOOST_LOG_TRIVIAL(debug) << "items selected after arrange: ";
|
||||||
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
|
||||||
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp;
|
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp
|
||||||
|
<< ", 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)
|
if (!item.is_virt_object)
|
||||||
|
|
Loading…
Reference in a new issue