diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm
index 1949a83a0..d3bbae030 100644
--- a/lib/Slic3r/Model.pm
+++ b/lib/Slic3r/Model.pm
@@ -259,45 +259,6 @@ sub add_instance {
     }
 }
 
-sub split_object {
-    my ($self) = @_;
-    
-    if (@{$self->volumes} > 1) {
-        # We can't split meshes if there's more than one volume, because
-        # we can't group the resulting meshes by object afterwards
-        my $o = $self->model->_add_object($self);
-        return [$o];
-    }
-    
-    my @new_objects = ();
-    my $volume = $self->volumes->[0];
-    foreach my $mesh (@{$volume->mesh->split}) {
-        $mesh->repair;
-        
-        push @new_objects, my $new_object = $self->model->add_object(
-            input_file          => $self->input_file,
-            config              => $self->config->clone,
-            layer_height_ranges => $self->layer_height_ranges,   # TODO: this needs to be cloned
-            origin_translation  => $self->origin_translation,
-        );
-        $new_object->add_volume(
-            mesh        => $mesh,
-            name        => $volume->name,
-            material_id => $volume->material_id,
-            config      => $volume->config,
-        );
-        
-        # add one instance per original instance
-        $new_object->add_instance(
-            offset          => Slic3r::Pointf->new(@{$_->offset}),
-            rotation        => $_->rotation,
-            scaling_factor  => $_->scaling_factor,
-        ) for @{ $self->instances };
-    }
-    
-    return [@new_objects];
-}
-
 sub rotate {
     my ($self, $angle, $axis) = @_;
     
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index dad84cf63..d5e9aa6ee 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -44,9 +44,9 @@ Model::add_object()
 }
 
 ModelObject*
-Model::add_object(const ModelObject &other)
+Model::add_object(const ModelObject &other, bool copy_volumes)
 {
-    ModelObject* new_object = new ModelObject(this, other);
+    ModelObject* new_object = new ModelObject(this, other, copy_volumes);
     this->objects.push_back(new_object);
     return new_object;
 }
@@ -269,7 +269,7 @@ ModelObject::ModelObject(Model *model)
     : model(model)
 {}
 
-ModelObject::ModelObject(Model *model, const ModelObject &other)
+ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes)
 :   model(model),
     name(other.name),
     input_file(other.input_file),
@@ -281,11 +281,12 @@ ModelObject::ModelObject(Model *model, const ModelObject &other)
     _bounding_box(other._bounding_box),
     _bounding_box_valid(other._bounding_box_valid)
 {
-
-    this->volumes.reserve(other.volumes.size());
-    for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i)
-        this->add_volume(**i);
-
+    if (copy_volumes) {
+        this->volumes.reserve(other.volumes.size());
+        for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i)
+            this->add_volume(**i);
+    }
+    
     this->instances.reserve(other.instances.size());
     for (ModelInstancePtrs::const_iterator i = other.instances.begin(); i != other.instances.end(); ++i)
         this->add_instance(**i);
@@ -589,6 +590,34 @@ ModelObject::cut(coordf_t z, Model* model) const
     }
 }
 
+void
+ModelObject::split(ModelObjectPtrs* new_objects)
+{
+    if (this->volumes.size() > 1) {
+        // We can't split meshes if there's more than one volume, because
+        // we can't group the resulting meshes by object afterwards
+        new_objects->push_back(this);
+        return;
+    }
+    
+    ModelVolume* volume = this->volumes.front();
+    TriangleMeshPtrs meshptrs = volume->mesh.split();
+    for (TriangleMeshPtrs::iterator mesh = meshptrs.begin(); mesh != meshptrs.end(); ++mesh) {
+        (*mesh)->repair();
+        
+        ModelObject* new_object = this->model->add_object(*this, false);
+        ModelVolume* new_volume = new_object->add_volume(**mesh);
+        new_volume->name        = volume->name;
+        new_volume->config      = volume->config;
+        new_volume->modifier    = volume->modifier;
+        new_volume->material_id(volume->material_id());
+        
+        new_objects->push_back(new_object);
+    }
+    
+    return;
+}
+
 #ifdef SLIC3RXS
 REGISTER_CLASS(ModelObject, "Model::Object");
 #endif
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index c5123e5fc..9cbe6be40 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -39,7 +39,7 @@ class Model
     void swap(Model &other);
     ~Model();
     ModelObject* add_object();
-    ModelObject* add_object(const ModelObject &other);
+    ModelObject* add_object(const ModelObject &other, bool copy_volumes = true);
     void delete_object(size_t idx);
     void clear_objects();
     
@@ -60,7 +60,6 @@ class Model
     void translate(coordf_t x, coordf_t y, coordf_t z);
     void mesh(TriangleMesh* mesh) const;
     void raw_mesh(TriangleMesh* mesh) const;
-    // void split_meshes();
     // std::string get_material_name(t_model_material_id material_id);
 
     
@@ -133,13 +132,14 @@ class ModelObject
     size_t facets_count() const;
     bool needed_repair() const;
     void cut(coordf_t z, Model* model) const;
+    void split(ModelObjectPtrs* new_objects);
     void update_bounding_box();   // this is a private method but we expose it until we need to expose it via XS
     
     private:
     Model* model;
     
     ModelObject(Model *model);
-    ModelObject(Model *model, const ModelObject &other);
+    ModelObject(Model *model, const ModelObject &other, bool copy_volumes = true);
     ModelObject& operator= (ModelObject other);
     void swap(ModelObject &other);
     ~ModelObject();
diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp
index 43d03e9cf..fd31a93d4 100644
--- a/xs/xsp/Model.xsp
+++ b/xs/xsp/Model.xsp
@@ -14,8 +14,8 @@
         %code%{ RETVAL = THIS; %};
     
     %name{_add_object} Ref<ModelObject> add_object();
-    Ref<ModelObject> _add_object_clone(ModelObject* other)
-        %code%{ RETVAL = THIS->add_object(*other); %};
+    Ref<ModelObject> _add_object_clone(ModelObject* other, bool copy_volumes = true)
+        %code%{ RETVAL = THIS->add_object(*other, copy_volumes); %};
     void delete_object(size_t idx);
     void clear_objects();
     size_t objects_count()
@@ -206,6 +206,12 @@ ModelMaterial::attributes()
             RETVAL = new Model();
             THIS->cut(z, RETVAL);
         %};
+
+    ModelObjectPtrs* split_object()
+        %code%{
+            RETVAL = new ModelObjectPtrs();  // leak?
+            THIS->split(RETVAL);
+        %};
 };