diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 25e1a5ee5..babb8ed5c 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1003,14 +1003,13 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
     const bool mult_sel = multiple_selection();
 
     if ((mult_sel && !selected_instances_of_same_object()) ||
-        (!mult_sel && (GetSelection() != item)) ||
-        m_objects_model->GetParent(item) == wxDataViewItem(nullptr) ) {
+        (!mult_sel && (GetSelection() != item)) ) {
         event.Veto();
         return;
     }
    
     const ItemType& type = m_objects_model->GetItemType(item);
-    if (!(type & (itVolume | itInstance))) {
+    if (!(type & (itVolume | itObject | itInstance))) {
         event.Veto();
         return;
     }
@@ -1024,11 +1023,13 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
         for (auto sel : sels )
             sub_obj_idxs.insert(m_objects_model->GetInstanceIdByItem(sel));
     }
-    else 
+    else if (type & itObject)
+        m_dragged_data.init(m_objects_model->GetIdByItem(item), type);
+    else
         m_dragged_data.init(m_objects_model->GetObjectIdByItem(item), 
-                        type&itVolume ? m_objects_model->GetVolumeIdByItem(item) :
+                            type&itVolume ? m_objects_model->GetVolumeIdByItem(item) :
                                         m_objects_model->GetInstanceIdByItem(item), 
-                        type);
+                            type);
 
     /* Under MSW or OSX, DnD moves an item to the place of another selected item
     * But under GTK, DnD moves an item between another two items.
@@ -1049,10 +1050,20 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
 
 bool ObjectList::can_drop(const wxDataViewItem& item) const 
 {
-    return (m_dragged_data.type() == itInstance && !item.IsOk())     ||
-           (m_dragged_data.type() == itVolume && item.IsOk() &&
-            m_objects_model->GetItemType(item) == itVolume &&
-            m_dragged_data.obj_idx() == m_objects_model->GetObjectIdByItem(item));
+    // move instance(s) or object on "empty place" of ObjectList
+    if ( (m_dragged_data.type() & (itInstance | itObject)) && !item.IsOk() )
+        return true;
+
+    // type of moved item should be the same as a "destination" item
+    if (!item.IsOk() || !(m_dragged_data.type() & (itVolume|itObject)) || 
+        m_objects_model->GetItemType(item) != m_dragged_data.type() )
+        return false;
+
+    // move volumes inside one object only
+    if (m_dragged_data.type() & itVolume)
+        return m_dragged_data.obj_idx() == m_objects_model->GetObjectIdByItem(item);
+
+    return true;
 }
 
 void ObjectList::OnDropPossible(wxDataViewEvent &event)
@@ -1082,9 +1093,6 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
         return;
     }
 
-    const int from_volume_id = m_dragged_data.sub_obj_idx();
-    int to_volume_id = m_objects_model->GetVolumeIdByItem(item);
-
 // It looks like a fixed in current version of the wxWidgets
 // #ifdef __WXGTK__
 //     /* Under GTK, DnD moves an item between another two items.
@@ -1096,14 +1104,33 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
 
     take_snapshot(_((m_dragged_data.type() == itVolume) ? L("Volumes in Object reordered") : L("Object reordered")));
 
-    auto& volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes;
-    auto delta = to_volume_id < from_volume_id ? -1 : 1;
-    int cnt = 0;
-    for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id += delta, cnt++)
-        std::swap(volumes[id], volumes[id + delta]);
+    if (m_dragged_data.type() & itVolume)
+    {
+        int from_volume_id = m_dragged_data.sub_obj_idx();
+        int to_volume_id   = m_objects_model->GetVolumeIdByItem(item);
+        int delta = to_volume_id < from_volume_id ? -1 : 1;
 
-    select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id,
-                                                    m_objects_model->GetParent(item)));
+        auto& volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes;
+
+        int cnt = 0;
+        for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id += delta, cnt++)
+            std::swap(volumes[id], volumes[id + delta]);
+
+        select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, m_objects_model->GetParent(item)));
+
+    }
+    else if (m_dragged_data.type() & itObject)
+    {
+        int from_obj_id = m_dragged_data.obj_idx();
+        int to_obj_id   = item.IsOk() ? m_objects_model->GetIdByItem(item) : ((int)m_objects->size()-1);
+        int delta = to_obj_id < from_obj_id ? -1 : 1;
+
+        int cnt = 0;
+        for (int id = from_obj_id; cnt < abs(from_obj_id - to_obj_id); id += delta, cnt++)
+            std::swap((*m_objects)[id], (*m_objects)[id + delta]);
+
+        select_item(m_objects_model->ReorganizeObjects(from_obj_id, to_obj_id));
+    }
 
     changed_object(m_dragged_data.obj_idx());
 
diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp
index b710d2cd7..a867ca0ec 100644
--- a/src/slic3r/GUI/wxExtensions.cpp
+++ b/src/slic3r/GUI/wxExtensions.cpp
@@ -1726,9 +1726,6 @@ wxDataViewItem ObjectDataViewModel::ReorganizeChildren( const int current_volume
     ItemDeleted(parent, wxDataViewItem(deleted_node));
     node_parent->Insert(deleted_node, new_volume_id+shift);
     ItemAdded(parent, wxDataViewItem(deleted_node));
-    const auto settings_item = GetSettingsItem(wxDataViewItem(deleted_node));
-    if (settings_item)
-        ItemAdded(wxDataViewItem(deleted_node), settings_item);
 
     //update volume_id value for child-nodes
     auto children = node_parent->GetChildren();
@@ -1740,6 +1737,21 @@ wxDataViewItem ObjectDataViewModel::ReorganizeChildren( const int current_volume
     return wxDataViewItem(node_parent->GetNthChild(new_volume_id+shift));
 }
 
+wxDataViewItem ObjectDataViewModel::ReorganizeObjects(  const int current_id, const int new_id)
+{
+    if (current_id == new_id)
+        return wxDataViewItem(nullptr);
+
+    ObjectDataViewModelNode* deleted_node = m_objects[current_id];
+    m_objects.erase(m_objects.begin() + current_id);
+    ItemDeleted(wxDataViewItem(nullptr), wxDataViewItem(deleted_node));
+
+    m_objects.emplace(m_objects.begin() + new_id, deleted_node);
+    ItemAdded(wxDataViewItem(nullptr), wxDataViewItem(deleted_node));
+
+    return wxDataViewItem(deleted_node);
+}
+
 bool ObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const
 {
     wxASSERT(item.IsOk());
diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp
index c3d26c8be..8cd144dc5 100644
--- a/src/slic3r/GUI/wxExtensions.hpp
+++ b/src/slic3r/GUI/wxExtensions.hpp
@@ -481,6 +481,7 @@ public:
     wxDataViewItem  ReorganizeChildren( const int cur_volume_id,
                                         const int new_volume_id,
                                         const wxDataViewItem &parent);
+    wxDataViewItem  ReorganizeObjects( int current_id, int new_id);
 
     virtual bool    IsEnabled(const wxDataViewItem &item, unsigned int col) const override;