diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 86daf7d17..00b4a1cce 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -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(get_extents(m_selected.front().poly).size()) + Vec2f(m_selected.front().brim_width, m_selected.front().brim_width); + std::vector 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(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() ? diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fb733cfd2..3d1d3e6b7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -12550,6 +12550,38 @@ void Plater::clone_selection() selection.clone(res); } +std::vector 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 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 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) { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 82fb1f5cd..3d1b12964 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -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 get_empty_cells(const Vec2f step); //BBS: void fill_color(int extruder_id);