diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 279a80ecee..4710132025 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4074,15 +4074,15 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const } //BBS -std::vector GLCanvas3D::get_empty_cells(const Vec2f start_point) +std::vector GLCanvas3D::get_empty_cells(const Vec2f start_point, 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; - for (float x = bbox.min.x(); x < bbox.max.x(); x+=10) - for (float y = bbox.min.y(); y < bbox.max.y(); y += 10) + for (float x = bbox.min.x(); x < bbox.max.x(); x += step(0)) + for (float y = bbox.min.y(); y < bbox.max.y(); y += step(1)) { cells.emplace_back(x, y); } @@ -4124,9 +4124,9 @@ std::vector GLCanvas3D::get_empty_cells(const Vec2f start_point) return cells; } -Vec2f GLCanvas3D::get_nearest_empty_cell(const Vec2f start_point) +Vec2f GLCanvas3D::get_nearest_empty_cell(const Vec2f start_point, const Vec2f step) { - std::vector empty_cells = get_empty_cells(start_point); + std::vector empty_cells = get_empty_cells(start_point, step); if (!empty_cells.empty()) return empty_cells.front(); else { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a09f4333b6..186f96c22e 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -831,11 +831,11 @@ public: double get_size_proportional_to_max_bed_size(double factor) const; // BBS: get empty cells to put new object - // start_point={-1,-1} means sort from bed center - std::vector get_empty_cells(const Vec2f start_point); + // start_point={-1,-1} means sort from bed center, step is the unscaled x,y stride + std::vector get_empty_cells(const Vec2f start_point, const Vec2f step = {10, 10}); // BBS: get the nearest empty cell // start_point={-1,-1} means sort from bed center - Vec2f get_nearest_empty_cell(const Vec2f start_point); + Vec2f get_nearest_empty_cell(const Vec2f start_point, const Vec2f step = {10, 10}); void set_cursor(ECursorType type); void msw_rescale(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 6f0ecd9b02..c0abf6ba8c 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2619,6 +2619,7 @@ void Selection::paste_objects_from_clipboard() //BBS: if multiple objects are selected, move them as a whole after copy Vec2d shift_all = {0, 0}; + Vec2f empty_cell_all = {0, 0}; if (src_objects.size() > 1) { BoundingBoxf3 bbox_all; for (const ModelObject *src_object : src_objects) { @@ -2632,25 +2633,27 @@ void Selection::paste_objects_from_clipboard() shift_all = {0, bbox_all.size().y()}; } - for (const ModelObject* src_object : src_objects) + for (size_t i=0;iadd_object(*src_object); // BBS: find an empty cell to put the copied object BoundingBoxf3 bbox = src_object->instance_convex_hull_bounding_box(0); Vec3d displacement; + bool in_current = plate->intersects(bbox); + auto start_point = in_current ? bbox.center() : plate->get_build_volume().center(); if (shift_all(0) != 0 || shift_all(1) != 0) { // BBS: if multiple objects are selected, move them as a whole after copy - auto start_point = bbox.center(); - displacement = {shift_all.x() + start_point.x(), shift_all.y() + start_point.y(), start_point(2)}; + if (i == 0) empty_cell_all = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1,bbox.size()(1)+1}); + auto instance_shift = src_object->instances.front()->get_offset() - src_objects[0]->instances.front()->get_offset(); + displacement = {shift_all.x() + empty_cell_all.x()+instance_shift.x(), shift_all.y() + empty_cell_all.y()+instance_shift.y(), start_point(2)}; } else { // BBS: if only one object is copied, find an empty cell to put it - bool in_current = plate->intersects(bbox); - auto start_point = in_current ? bbox.center() : plate->get_build_volume().center(); auto start_offset = in_current ? src_object->instances.front()->get_offset() : plate->get_build_volume().center(); auto point_offset = start_offset - start_point; - auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}); + auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1, bbox.size()(1)+1}); displacement = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_point(2)}; }