diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp
index e61f11517..00656a629 100644
--- a/src/libslic3r/Arrange.cpp
+++ b/src/libslic3r/Arrange.cpp
@@ -83,7 +83,7 @@ const double BIG_ITEM_TRESHOLD = 0.02;
 // Fill in the placer algorithm configuration with values carefully chosen for
 // Slic3r.
 template<class PConf>
-void fill_config(PConf& pcfg) {
+void fill_config(PConf& pcfg, const ArrangeParams &params) {
 
     // Align the arranged pile into the center of the bin
     pcfg.alignment = PConf::Alignment::CENTER;
@@ -93,14 +93,17 @@ void fill_config(PConf& pcfg) {
 
     // TODO cannot use rotations until multiple objects of same geometry can
     // handle different rotations.
-    pcfg.rotations = { 0.0 };
+    if (params.allow_rotations)
+        pcfg.rotations = {0., PI / 2., PI, 3. * PI / 2. };
+    else
+        pcfg.rotations = {0.};
 
     // The accuracy of optimization.
     // Goes from 0.0 to 1.0 and scales performance as well
-    pcfg.accuracy = 0.65f;
+    pcfg.accuracy = params.accuracy;
     
     // Allow parallel execution.
-    pcfg.parallel = true;
+    pcfg.parallel = params.parallel;
 }
 
 // Apply penalty to object function result. This is used only when alignment
@@ -304,15 +307,15 @@ protected:
     
 public:
     AutoArranger(const TBin &                  bin,
-                 Distance                      dist,
+                 const ArrangeParams           &params,
                  std::function<void(unsigned)> progressind,
                  std::function<bool(void)>     stopcond)
-        : m_pck(bin, dist)
+        : m_pck(bin, params.min_obj_distance)
         , m_bin(bin)
         , m_bin_area(sl::area(bin))
         , m_norm(std::sqrt(m_bin_area))
     {
-        fill_config(m_pconf);
+        fill_config(m_pconf, params);
 
         // Set up a callback that is called just before arranging starts
         // This functionality is provided by the Nester class (m_pack).
@@ -349,12 +352,6 @@ public:
         
         m_pck.configure(m_pconf);
     }
-    
-    AutoArranger(const TBin &                  bin,
-                 std::function<void(unsigned)> progressind,
-                 std::function<bool(void)>     stopcond)
-        : AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
-    {}
      
     template<class It> inline void operator()(It from, It to) {
         m_rtree.clear();
@@ -457,7 +454,7 @@ void _arrange(
         std::vector<Item> &           shapes,
         std::vector<Item> &           excludes,
         const BinT &                  bin,
-        const ArrangeParams &         params,
+        const ArrangeParams           &params,
         std::function<void(unsigned)> progressfn,
         std::function<bool()>         stopfn)
 {
@@ -467,11 +464,10 @@ void _arrange(
     
     auto corrected_bin = bin;
     sl::offset(corrected_bin, md);
-    
-    AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
-    
-    arranger.config().accuracy = params.accuracy;
-    arranger.config().parallel = params.parallel;
+    ArrangeParams mod_params = params;
+    mod_params.min_obj_distance = 0;
+
+    AutoArranger<BinT> arranger{corrected_bin, mod_params, progressfn, stopfn};
     
     auto infl = coord_t(std::ceil(params.min_obj_distance / 2.0));
     for (Item& itm : shapes) itm.inflate(infl);
diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp
index 7630ab3e8..65c3984d5 100644
--- a/src/libslic3r/Arrange.hpp
+++ b/src/libslic3r/Arrange.hpp
@@ -78,6 +78,8 @@ struct ArrangeParams {
     
     /// Allow parallel execution.
     bool parallel = true;
+
+    bool allow_rotations = false;
     
     /// Progress indicator callback called when an object gets packed. 
     /// The unsigned argument is the number of items remaining to pack.
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index cd82878c2..ae08d40d9 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -170,7 +170,7 @@ void GLCanvas3D::LayersEditing::init()
 }
 
 void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config)
-{ 
+{
     m_config = config;
     delete m_slicing_parameters;
     m_slicing_parameters = nullptr;
@@ -1325,6 +1325,9 @@ void GLCanvas3D::update_instance_printable_state_for_objects(std::vector<size_t>
 
 void GLCanvas3D::set_config(const DynamicPrintConfig* config)
 {
+    if (!m_config)
+        m_arrange_settings.distance = min_object_distance(*config);
+
     m_config = config;
     m_layers_editing.set_config(config);
 }
@@ -3847,6 +3850,30 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
     return action_taken;
 }
 
+bool GLCanvas3D::_render_arrange_popup()
+{
+    ImGuiWrapper *imgui = wxGetApp().imgui();
+
+    float x = 0.5f * (float)get_canvas_size().get_width();
+    imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+
+    imgui->begin(_(L("Arrange options")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
+    ArrangeSettings settings = m_arrange_settings;
+
+    if (imgui->slider_float(_(L("Gap size")), &settings.distance, 0.f, 100.f))
+        m_arrange_settings.distance = settings.distance;
+
+    if (imgui->slider_float(_(L("Accuracy")), &settings.accuracy, 0.f, 1.f))
+        m_arrange_settings.accuracy = settings.accuracy;
+
+    if (imgui->checkbox(_(L("Enable rotations")), settings.enable_rotation))
+        m_arrange_settings.enable_rotation = settings.enable_rotation;
+
+    imgui->end();
+
+    return false;
+}
+
 #define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
 #if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
 static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
@@ -4263,6 +4290,13 @@ bool GLCanvas3D::_init_main_toolbar()
     item.sprite_id = 3;
     item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_ARRANGE)); };
     item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); };
+    item.right.toggable = true;
+    item.right.render_callback = [this](float left, float right, float, float) {
+        if (m_canvas != nullptr)
+        {
+            _render_arrange_popup();
+        }
+    };
     if (!m_main_toolbar.add_item(item))
         return false;
 
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 0975e59a0..c760dc323 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -381,6 +381,13 @@ public:
         Cross
     };
 
+    struct ArrangeSettings
+    {
+        float distance         = 6.;
+        float accuracy         = 0.65f;
+        bool  enable_rotation  = false;
+    };
+
 private:
     wxGLCanvas* m_canvas;
     wxGLContext* m_context;
@@ -452,6 +459,8 @@ private:
     mutable bool m_tooltip_enabled{ true };
     Slope m_slope;
 
+    ArrangeSettings m_arrange_settings;
+
 public:
     explicit GLCanvas3D(wxGLCanvas* canvas);
     ~GLCanvas3D();
@@ -671,6 +680,8 @@ public:
     void use_slope(bool use) { m_slope.use(use); }
     void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
 
+    const ArrangeSettings& get_arrange_settings() const { return m_arrange_settings; }
+
 private:
     bool _is_shown_on_screen() const;
 
@@ -717,6 +728,7 @@ private:
     void _render_selection_sidebar_hints() const;
     bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
     bool _render_search_list(float pos_x) const;
+    bool _render_arrange_popup();
     void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
     // render thumbnail using an off-screen framebuffer
     void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
index 41fd717da..9bb26e096 100644
--- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp
+++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
@@ -147,11 +147,13 @@ void ArrangeJob::prepare()
 void ArrangeJob::process()
 {
     static const auto arrangestr = _(L("Arranging"));
-    
-    double dist = min_object_distance(*m_plater->config());
+
+    GLCanvas3D::ArrangeSettings settings =
+        m_plater->canvas3D()->get_arrange_settings();
     
     arrangement::ArrangeParams params;
-    params.min_obj_distance = scaled(dist);
+    params.min_obj_distance = scaled(settings.distance);
+    params.allow_rotations  = settings.enable_rotation;
     
     auto count = unsigned(m_selected.size() + m_unprintable.size());
     Points bedpts = get_bed_shape(*m_plater->config());