Ported ModelObject::split() to XS

This commit is contained in:
Alessandro Ranellucci 2014-11-12 23:50:09 +01:00
parent 334086d605
commit a5df9fb795
4 changed files with 48 additions and 52 deletions

View file

@ -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 { sub rotate {
my ($self, $angle, $axis) = @_; my ($self, $angle, $axis) = @_;

View file

@ -44,9 +44,9 @@ Model::add_object()
} }
ModelObject* 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); this->objects.push_back(new_object);
return new_object; return new_object;
} }
@ -269,7 +269,7 @@ ModelObject::ModelObject(Model *model)
: model(model) : model(model)
{} {}
ModelObject::ModelObject(Model *model, const ModelObject &other) ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes)
: model(model), : model(model),
name(other.name), name(other.name),
input_file(other.input_file), input_file(other.input_file),
@ -281,10 +281,11 @@ ModelObject::ModelObject(Model *model, const ModelObject &other)
_bounding_box(other._bounding_box), _bounding_box(other._bounding_box),
_bounding_box_valid(other._bounding_box_valid) _bounding_box_valid(other._bounding_box_valid)
{ {
if (copy_volumes) {
this->volumes.reserve(other.volumes.size()); this->volumes.reserve(other.volumes.size());
for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i) for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i)
this->add_volume(**i); this->add_volume(**i);
}
this->instances.reserve(other.instances.size()); this->instances.reserve(other.instances.size());
for (ModelInstancePtrs::const_iterator i = other.instances.begin(); i != other.instances.end(); ++i) for (ModelInstancePtrs::const_iterator i = other.instances.begin(); i != other.instances.end(); ++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 #ifdef SLIC3RXS
REGISTER_CLASS(ModelObject, "Model::Object"); REGISTER_CLASS(ModelObject, "Model::Object");
#endif #endif

View file

@ -39,7 +39,7 @@ class Model
void swap(Model &other); void swap(Model &other);
~Model(); ~Model();
ModelObject* add_object(); 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 delete_object(size_t idx);
void clear_objects(); void clear_objects();
@ -60,7 +60,6 @@ class Model
void translate(coordf_t x, coordf_t y, coordf_t z); void translate(coordf_t x, coordf_t y, coordf_t z);
void mesh(TriangleMesh* mesh) const; void mesh(TriangleMesh* mesh) const;
void raw_mesh(TriangleMesh* mesh) const; void raw_mesh(TriangleMesh* mesh) const;
// void split_meshes();
// std::string get_material_name(t_model_material_id material_id); // std::string get_material_name(t_model_material_id material_id);
@ -133,13 +132,14 @@ class ModelObject
size_t facets_count() const; size_t facets_count() const;
bool needed_repair() const; bool needed_repair() const;
void cut(coordf_t z, Model* model) 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 void update_bounding_box(); // this is a private method but we expose it until we need to expose it via XS
private: private:
Model* model; Model* model;
ModelObject(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); ModelObject& operator= (ModelObject other);
void swap(ModelObject &other); void swap(ModelObject &other);
~ModelObject(); ~ModelObject();

View file

@ -14,8 +14,8 @@
%code%{ RETVAL = THIS; %}; %code%{ RETVAL = THIS; %};
%name{_add_object} Ref<ModelObject> add_object(); %name{_add_object} Ref<ModelObject> add_object();
Ref<ModelObject> _add_object_clone(ModelObject* other) Ref<ModelObject> _add_object_clone(ModelObject* other, bool copy_volumes = true)
%code%{ RETVAL = THIS->add_object(*other); %}; %code%{ RETVAL = THIS->add_object(*other, copy_volumes); %};
void delete_object(size_t idx); void delete_object(size_t idx);
void clear_objects(); void clear_objects();
size_t objects_count() size_t objects_count()
@ -206,6 +206,12 @@ ModelMaterial::attributes()
RETVAL = new Model(); RETVAL = new Model();
THIS->cut(z, RETVAL); THIS->cut(z, RETVAL);
%}; %};
ModelObjectPtrs* split_object()
%code%{
RETVAL = new ModelObjectPtrs(); // leak?
THIS->split(RETVAL);
%};
}; };