ENH: find grid empty cells for fill bed if the item is too small

jira: STUDIO-6015
Change-Id: I4e5eafdadd77482a27a8903d32bb83325283088d
(cherry picked from commit 8df4da4a863cdc42c790a9d5da37f8633423e406)
This commit is contained in:
Arthur 2024-02-18 11:48:32 +08:00 committed by Lane.Wei
parent 8caaf230df
commit 2839439cb3
3 changed files with 49 additions and 1 deletions

View File

@ -229,7 +229,21 @@ void FillBedJob::process()
// final align用的是凸包在有fixed item的情况下可能找到的参考点位置是错的这里就不做了。见STUDIO-3265
params.do_final_align = false;
arrangement::arrange(m_selected, m_unselected, m_bedpts, params);
if (m_selected.size() > 100){
// too many items, just find grid empty cells to put them
Vec2f step = unscaled<float>(get_extents(m_selected.front().poly).size()) + Vec2f(m_selected.front().brim_width, m_selected.front().brim_width);
std::vector<Vec2f> empty_cells = Plater::get_empty_cells(step);
size_t n=std::min(m_selected.size(), empty_cells.size());
for (size_t i = 0; i < n; i++) {
m_selected[i].translation = scaled<coord_t>(empty_cells[i]);
m_selected[i].bed_idx= 0;
}
for (size_t i = n; i < m_selected.size(); i++) {
m_selected[i].bed_idx = -1;
}
}
else
arrangement::arrange(m_selected, m_unselected, m_bedpts, params);
// finalize just here.
update_status(m_status_range, was_canceled() ?

View File

@ -12550,6 +12550,38 @@ void Plater::clone_selection()
selection.clone(res);
}
std::vector<Vec2f> Plater::get_empty_cells(const Vec2f step)
{
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
BoundingBoxf3 build_volume = plate->get_build_volume();
Vec2d vmin(build_volume.min.x(), build_volume.min.y()), vmax(build_volume.max.x(), build_volume.max.y());
BoundingBoxf bbox(vmin, vmax);
std::vector<Vec2f> cells;
auto min_x = step(0)/2;// start_point.x() - step(0) * int((start_point.x() - bbox.min.x()) / step(0));
auto min_y = step(1)/2;// start_point.y() - step(1) * int((start_point.y() - bbox.min.y()) / step(1));
auto& exclude_box3s = plate->get_exclude_areas();
std::vector<BoundingBoxf> exclude_boxs;
for (auto& box : exclude_box3s) {
Vec2d vmin(box.min.x(), box.min.y()), vmax(box.max.x(), box.max.y());
exclude_boxs.emplace_back(vmin, vmax);
}
for (float x = min_x; x < bbox.max.x() - step(0) / 2; x += step(0))
for (float y = min_y; y < bbox.max.y() - step(1) / 2; y += step(1)) {
bool in_exclude = false;
BoundingBoxf cell(Vec2d(x - step(0) / 2, y - step(1) / 2), Vec2d(x + step(0) / 2, y + step(1) / 2));
for (auto& box : exclude_boxs) {
if (box.overlap(cell)) {
in_exclude = true;
break;
}
}
if(in_exclude)
continue;
cells.emplace_back(x, y);
}
return cells;
}
void Plater::search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag)
{
if (plater_is_active) {

View File

@ -485,6 +485,8 @@ public:
void split_object();
void split_volume();
void optimize_rotation();
// find all empty cells on the plate and won't overlap with exclusion areas
static std::vector<Vec2f> get_empty_cells(const Vec2f step);
//BBS:
void fill_color(int extruder_id);