diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp
index afdde1852..5003c67d7 100644
--- a/src/libslic3r/Layer.cpp
+++ b/src/libslic3r/Layer.cpp
@@ -32,9 +32,8 @@ void Layer::make_slices()
         slices = m_regions.front()->slices;
     } else {
         Polygons slices_p;
-        FOREACH_LAYERREGION(this, layerm) {
-            polygons_append(slices_p, to_polygons((*layerm)->slices));
-        }
+        for (LayerRegion *layerm : m_regions)
+            polygons_append(slices_p, to_polygons(layerm->slices));
         slices = union_ex(slices_p);
     }
     
@@ -53,7 +52,7 @@ void Layer::make_slices()
     
     // populate slices vector
     for (size_t i : order)
-        this->slices.expolygons.push_back(STDMOVE(slices[i]));
+        this->slices.expolygons.push_back(std::move(slices[i]));
 }
 
 void Layer::merge_slices()
@@ -63,10 +62,9 @@ void Layer::merge_slices()
         // but use the non-split islands of a layer. For a single region print, these shall be equal.
         m_regions.front()->slices.set(this->slices.expolygons, stInternal);
     } else {
-        FOREACH_LAYERREGION(this, layerm) {
+        for (LayerRegion *layerm : m_regions)
             // without safety offset, artifacts are generated (GH #2494)
-            (*layerm)->slices.set(union_ex(to_polygons(STDMOVE((*layerm)->slices.surfaces)), true), stInternal);
-        }
+            layerm->slices.set(union_ex(to_polygons(std::move(layerm->slices.surfaces)), true), stInternal);
     }
 }
 
@@ -80,7 +78,7 @@ void Layer::make_perimeters()
     // keep track of regions whose perimeters we have already generated
     std::set<size_t> done;
     
-    FOREACH_LAYERREGION(this, layerm) {
+    for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm) {
         size_t region_id = layerm - m_regions.begin();
         if (done.find(region_id) != done.end()) continue;
         BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
index adc1f3406..cfa6ed25b 100644
--- a/src/libslic3r/Model.hpp
+++ b/src/libslic3r/Model.hpp
@@ -256,7 +256,6 @@ protected:
 
 private:
     ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
-    ModelObject(Model *model, const ModelObject &rhs) { this->assign_copy(rhs); m_model = model; }
     ~ModelObject();
 
     /* To be able to return an object from own copy / clone methods. Hopefully the compiler will do the "Copy elision" */
@@ -281,8 +280,6 @@ private:
 // ModelVolume instances are owned by a ModelObject.
 class ModelVolume : public ModelBase
 {
-    friend class ModelObject;
-
 public:
     std::string         name;
     // The triangular model.
@@ -299,9 +296,6 @@ public:
         SUPPORT_BLOCKER,
     };
 
-    // Clone this ModelVolume, keep the ID identical, set the parent to the cloned volume.
-    ModelVolume*        clone(ModelObject *parent) { return new ModelVolume(parent, *this); }
-
     // A parent object owning this modifier volume.
     ModelObject*        get_object() const { return this->object; };
     Type                type() const { return m_type; }
@@ -363,7 +357,10 @@ public:
 #endif // ENABLE_MODELVOLUME_TRANSFORM
 
 protected:
-    explicit ModelVolume(ModelVolume &rhs) = default;
+	friend class Print;
+	friend class ModelObject;
+
+	explicit ModelVolume(ModelVolume &rhs) = default;
     void     set_model_object(ModelObject *model_object) { object = model_object; }
 
 private:
@@ -517,13 +514,13 @@ private:
 
 #if ENABLE_MODELVOLUME_TRANSFORM
     // Constructor, which assigns a new unique ID.
-    ModelInstance(ModelObject *object) : object(object), print_volume_state(PVS_Inside) {}
+    explicit ModelInstance(ModelObject *object) : object(object), print_volume_state(PVS_Inside) {}
     // Constructor, which assigns a new unique ID.
-    ModelInstance(ModelObject *object, const ModelInstance &other) :
+    explicit ModelInstance(ModelObject *object, const ModelInstance &other) :
         m_transformation(other.m_transformation), object(object), print_volume_state(PVS_Inside) {}
 #else
-    ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {}
-    ModelInstance(ModelObject *object, const ModelInstance &other) :
+    explicit ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {}
+    explicit ModelInstance(ModelObject *object, const ModelInstance &other) :
         m_offset(other.m_offset), m_rotation(other.m_rotation), m_scaling_factor(other.m_scaling_factor), m_mirror(other.m_mirror), object(object), print_volume_state(PVS_Inside) {}
 #endif // ENABLE_MODELVOLUME_TRANSFORM
 
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 4052c79ac..1eacb50b1 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -634,7 +634,7 @@ static inline bool model_volume_list_changed(const ModelObject &model_object_old
     return false;
 }
 
-static inline void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src)
+void Print::model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src)
 {
     // 1) Delete the support volumes from model_object_dst.
     {
@@ -650,8 +650,10 @@ static inline void model_volume_list_update_supports(ModelObject &model_object_d
     }
     // 2) Copy the support volumes from model_object_src to the end of model_object_dst.
     for (ModelVolume *vol : model_object_src.volumes) {
-        if (vol->is_support_modifier())
-            model_object_dst.volumes.emplace_back(vol->clone(&model_object_dst));
+		if (vol->is_support_modifier()) {
+			model_object_dst.volumes.emplace_back(new ModelVolume(*vol));
+			model_object_dst.volumes.back()->set_model_object(&model_object_dst);
+		}
     }
 }
 
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 3c2a87c74..705c41458 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -564,6 +564,9 @@ private:
     void                _make_wipe_tower();
     void                _simplify_slices(double distance);
 
+    // Declared here to have access to Model / ModelObject / ModelInstance
+    static void         model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
+
     PrintState<PrintStep, psCount>          m_state;
     // Mutex used for synchronization of the worker thread with the UI thread:
     // The mutex will be used to guard the worker thread against entering a stage
@@ -601,12 +604,6 @@ private:
     friend class PrintObject;
 };
 
-
-#define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator)
-#define FOREACH_OBJECT(print, object)       FOREACH_BASE(PrintObjectPtrs, (print)->m_objects, object)
-#define FOREACH_LAYER(object, layer)        FOREACH_BASE(LayerPtrs, (object)->m_layers, layer)
-#define FOREACH_LAYERREGION(layer, layerm)  FOREACH_BASE(LayerRegionPtrs, (layer)->m_regions, layerm)
-
 }
 
 #endif
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 8f9146766..8ca9c37ae 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -170,8 +170,8 @@ void PrintObject::make_perimeters()
     
     // merge slices if they were split into types
     if (this->typed_slices) {
-        FOREACH_LAYER(this, layer_it) {
-            (*layer_it)->merge_slices();
+        for (Layer *layer : m_layers) {
+            layer->merge_slices();
             m_print->throw_if_canceled();
         }
         this->typed_slices = false;
@@ -1243,9 +1243,10 @@ void PrintObject::bridge_over_infill()
             *this
         );
         
-        FOREACH_LAYER(this, layer_it) {
+		for (LayerPtrs::iterator layer_it = m_layers.begin(); layer_it != m_layers.end(); ++ layer_it) {
             // skip first layer
-            if (layer_it == m_layers.begin()) continue;
+			if (layer_it == m_layers.begin())
+                continue;
             
             Layer* layer        = *layer_it;
             LayerRegion* layerm = layer->m_regions[region_id];
@@ -1271,8 +1272,8 @@ void PrintObject::bridge_over_infill()
                     
                     // iterate through regions and collect internal surfaces
                     Polygons lower_internal;
-                    FOREACH_LAYERREGION(lower_layer, lower_layerm_it)
-                        (*lower_layerm_it)->fill_surfaces.filter_by_type(stInternal, &lower_internal);
+                    for (LayerRegion *lower_layerm : lower_layer->m_regions)
+                        lower_layerm->fill_surfaces.filter_by_type(stInternal, &lower_internal);
                     
                     // intersect such lower internal surfaces with the candidate solid surfaces
                     to_bridge_pp = intersection(to_bridge_pp, lower_internal);
@@ -1734,8 +1735,8 @@ void PrintObject::_make_perimeters()
     
     // merge slices if they were split into types
     if (this->typed_slices) {
-        FOREACH_LAYER(this, layer_it)
-            (*layer_it)->merge_slices();
+        for (Layer *layer : m_layers)
+            layer->merge_slices();
         this->typed_slices = false;
         this->invalidate_step(posPrepareInfill);
     }