diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
index b8f165c02..7a8c21365 100644
--- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp
+++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp
@@ -41,7 +41,8 @@ public:
         ret.poly.contour = std::move(ap);
         ret.translation  = scaled(m_pos);
         ret.rotation     = m_rotation;
-        ret.priority++;
+        ++ret.priority;
+
         return ret;
     }
 };
@@ -74,11 +75,11 @@ void ArrangeJob::prepare_all() {
     for (ModelObject *obj: m_plater->model().objects)
         for (ModelInstance *mi : obj->instances) {
             ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
-            cont.emplace_back(get_arrange_poly(mi, m_plater));
+            cont.emplace_back(get_arrange_poly(PtrWrapper{mi}, m_plater));
         }
 
-    if (auto wti = get_wipe_tower(*m_plater))
-        m_selected.emplace_back(wti.get_arrange_polygon());
+    if (auto wti = get_wipe_tower_arrangepoly(*m_plater))
+        m_selected.emplace_back(std::move(*wti));
 }
 
 void ArrangeJob::prepare_selected() {
@@ -106,8 +107,9 @@ void ArrangeJob::prepare_selected() {
                 inst_sel[size_t(inst_id)] = true;
         
         for (size_t i = 0; i < inst_sel.size(); ++i) {
-            ArrangePolygon &&ap = get_arrange_poly(mo->instances[i], m_plater);
-            
+            ArrangePolygon &&ap =
+                get_arrange_poly(PtrWrapper{mo->instances[i]}, m_plater);
+
             ArrangePolygons &cont = mo->instances[i]->printable ?
                         (inst_sel[i] ? m_selected :
                                        m_unselected) :
@@ -118,11 +120,11 @@ void ArrangeJob::prepare_selected() {
     }
     
     if (auto wti = get_wipe_tower(*m_plater)) {
-        ArrangePolygon &&ap = get_arrange_poly(&wti, m_plater);
-        
-        m_plater->get_selection().is_wipe_tower() ?
-                    m_selected.emplace_back(std::move(ap)) :
-                    m_unselected.emplace_back(std::move(ap));
+        ArrangePolygon &&ap = get_arrange_poly(wti, m_plater);
+
+        auto &cont = m_plater->get_selection().is_wipe_tower() ? m_selected :
+                                                                 m_unselected;
+        cont.emplace_back(std::move(ap));
     }
     
     // If the selection was empty arrange everything
@@ -212,18 +214,11 @@ std::optional<arrangement::ArrangePolygon>
 get_wipe_tower_arrangepoly(const Plater &plater)
 {
     if (auto wti = get_wipe_tower(plater))
-        return wti.get_arrange_polygon();
+        return get_arrange_poly(wti, &plater);
 
     return {};
 }
 
-void apply_wipe_tower_arrangepoly(Plater &                           plater,
-                                  const arrangement::ArrangePolygon &ap)
-{
-    WipeTower{plater.canvas3D()->get_wipe_tower_info()}
-        .apply_arrange_result(ap.translation.cast<double>(), ap.rotation);
-}
-
 double bed_stride(const Plater *plater) {
     double bedwidth = plater->bed_shape_bb().size().x();
     return scaled<double>((1. + LOGICAL_BED_GAP) * bedwidth);
diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp
index f178711e9..73540c230 100644
--- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp
+++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp
@@ -47,7 +47,6 @@ public:
 };
 
 std::optional<arrangement::ArrangePolygon> get_wipe_tower_arrangepoly(const Plater &);
-void apply_wipe_tower_arrangepoly(Plater &plater, const arrangement::ArrangePolygon &ap);
 
 // The gap between logical beds in the x axis expressed in ratio of
 // the current bed width.
@@ -56,20 +55,36 @@ static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
 // Stride between logical beds
 double bed_stride(const Plater *plater);
 
+template<class T> struct PtrWrapper
+{
+    T *ptr;
+
+    explicit PtrWrapper(T *p) : ptr{p} {}
+
+    arrangement::ArrangePolygon get_arrange_polygon() const
+    {
+        return ptr->get_arrange_polygon();
+    }
+
+    void apply_arrange_result(const Vec2d &t, double rot)
+    {
+        ptr->apply_arrange_result(t, rot);
+    }
+};
+
 // Set up arrange polygon for a ModelInstance and Wipe tower
 template<class T>
-arrangement::ArrangePolygon get_arrange_poly(T *obj, const Plater *plater)
+arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater)
 {
     using ArrangePolygon = arrangement::ArrangePolygon;
 
-    ArrangePolygon ap = obj->get_arrange_polygon();
-    ap.priority       = 0;
+    ArrangePolygon ap = obj.get_arrange_polygon();
     ap.bed_idx        = ap.translation.x() / bed_stride(plater);
     ap.setter         = [obj, plater](const ArrangePolygon &p) {
         if (p.is_arranged()) {
             Vec2d t = p.translation.cast<double>();
             t.x() += p.bed_idx * bed_stride(plater);
-            obj->apply_arrange_result(t, p.rotation);
+            T{obj}.apply_arrange_result(t, p.rotation);
         }
     };
 
diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp
index 8c7b3c418..060528006 100644
--- a/src/slic3r/GUI/Jobs/FillBedJob.cpp
+++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp
@@ -28,7 +28,7 @@ void FillBedJob::prepare()
     m_selected.reserve(model_object->instances.size());
     for (ModelInstance *inst : model_object->instances)
         if (inst->printable) {
-            ArrangePolygon ap = get_arrange_poly(inst, m_plater);
+            ArrangePolygon ap = get_arrange_poly(PtrWrapper{inst}, m_plater);
             ++ap.priority; // need to be included in the result
             m_selected.emplace_back(ap);
         }
@@ -40,8 +40,8 @@ void FillBedJob::prepare()
     auto &objects = m_plater->model().objects;
     for (size_t idx = 0; idx < objects.size(); ++idx)
         if (int(idx) != m_object_idx)
-            for (const ModelInstance *mi : objects[idx]->instances) {
-                m_unselected.emplace_back(mi->get_arrange_polygon());
+            for (ModelInstance *mi : objects[idx]->instances) {
+                m_unselected.emplace_back(get_arrange_poly(PtrWrapper{mi}, m_plater));
                 m_unselected.back().bed_idx = 0;
             }