From ed752192152150886907a5ba05c5db559337fd51 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 2 Dec 2015 18:06:18 +0100 Subject: [PATCH] Ported mode Model methods to XS --- lib/Slic3r/Model.pm | 75 ------------------------------ xs/src/libslic3r/Geometry.cpp | 12 ++--- xs/src/libslic3r/Geometry.hpp | 2 +- xs/src/libslic3r/Model.cpp | 86 +++++++++++++++++++++++++---------- xs/src/libslic3r/Model.hpp | 12 ++--- xs/src/libslic3r/Point.cpp | 6 +++ xs/src/libslic3r/Point.hpp | 1 + xs/xsp/Geometry.xsp | 2 +- xs/xsp/Model.xsp | 15 ++---- 9 files changed, 86 insertions(+), 125 deletions(-) diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 789fbc373..9edcae501 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -67,86 +67,11 @@ sub set_material { return $material; } -sub duplicate_objects_grid { - my ($self, $grid, $distance) = @_; - - die "Grid duplication is not supported with multiple objects\n" - if @{$self->objects} > 1; - - my $object = $self->objects->[0]; - $object->clear_instances; - - my $size = $object->bounding_box->size; - for my $x_copy (1..$grid->[X]) { - for my $y_copy (1..$grid->[Y]) { - $object->add_instance( - offset => Slic3r::Pointf->new( - ($size->[X] + $distance) * ($x_copy-1), - ($size->[Y] + $distance) * ($y_copy-1), - ), - ); - } - } -} - -# this will append more instances to each object -# and then automatically rearrange everything -sub duplicate_objects { - my ($self, $copies_num, $distance, $bb) = @_; - - foreach my $object (@{$self->objects}) { - my @instances = @{$object->instances}; - foreach my $instance (@instances) { - $object->add_instance($instance) for 2..$copies_num; - } - } - - $self->arrange_objects($distance, $bb); -} - -# duplicate the entire model preserving instance relative positions -sub duplicate { - my ($self, $copies_num, $distance, $bb) = @_; - - my $model_size = Slic3r::Pointf->new(@{$self->bounding_box->size}[X,Y]); - $bb //= Slic3r::Geometry::BoundingBoxf->new; - my @positions = @{$self->_arrange([ map $model_size, 2..$copies_num ], $distance, $bb)}; - - # note that this will leave the object count unaltered - - foreach my $object (@{$self->objects}) { - my @instances = @{$object->instances}; # store separately to avoid recursion from add_instance() below - foreach my $instance (@instances) { - foreach my $pos (@positions) { - $object->add_instance( - offset => Slic3r::Pointf->new($instance->offset->[X] + $pos->[X], $instance->offset->[Y] + $pos->[Y]), - rotation => $instance->rotation, - scaling_factor => $instance->scaling_factor, - ); - } - } - $object->update_bounding_box; - } -} - sub print_info { my $self = shift; $_->print_info for @{$self->objects}; } -sub get_material_name { - my $self = shift; - my ($material_id) = @_; - - my $name; - if ($self->has_material($material_id)) { - $name //= $self->get_material($material_id) - ->attributes->{$_} for qw(Name name); - } - $name //= $material_id; - return $name; -} - package Slic3r::Model::Material; sub apply { diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp index 62a6d8f7c..f85078b92 100644 --- a/xs/src/libslic3r/Geometry.cpp +++ b/xs/src/libslic3r/Geometry.cpp @@ -168,15 +168,15 @@ linint(double value, double oldmin, double oldmax, double newmin, double newmax) } Pointfs -arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf &bb) +arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf* bb) { // use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm part.x += dist; part.y += dist; Pointf area; - if (bb.defined) { - area = bb.size(); + if (bb != NULL) { + area = bb->size(); } else { // bogus area size, large enough not to trigger the error below area.x = part.x * total_parts; @@ -278,10 +278,10 @@ arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf &bb) positions.push_back(Pointf(cx * part.x, cy * part.y)); } - if (bb.defined) { + if (bb != NULL) { for (Pointfs::iterator p = positions.begin(); p != positions.end(); ++p) { - p->x += bb.min.x; - p->y += bb.min.y; + p->x += bb->min.x; + p->y += bb->min.y; } } return positions; diff --git a/xs/src/libslic3r/Geometry.hpp b/xs/src/libslic3r/Geometry.hpp index cbc3811e2..b73480725 100644 --- a/xs/src/libslic3r/Geometry.hpp +++ b/xs/src/libslic3r/Geometry.hpp @@ -36,7 +36,7 @@ class ArrangeItemIndex { ArrangeItemIndex(coordf_t _index, ArrangeItem _item) : index(_index), item(_item) {}; }; double linint(double value, double oldmin, double oldmax, double newmin, double newmax); -Pointfs arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf &bb = BoundingBoxf()); +Pointfs arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf* bb); class MedialAxis { public: diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index 851a3b08b..8bd381dd0 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -121,29 +121,6 @@ Model::get_material(t_model_material_id material_id) } } -/* -void -Model::duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance) -{ - if (this->objects.size() > 1) throw "Grid duplication is not supported with multiple objects"; - if (this->objects.empty()) throw "No objects!"; - - ModelObject* object = this->objects.front(); - object->clear_instances(); - - BoundingBoxf3 bb = object->bounding_box(); - Sizef3 size = bb.size(); - - for (unsigned int x_copy = 1; x_copy <= x; ++x_copy) { - for (unsigned int y_copy = 1; y_copy <= y; ++y_copy) { - ModelInstance* instance = object->add_instance(); - instance->offset.x = (size.x + distance) * (x_copy-1); - instance->offset.y = (size.y + distance) * (y_copy-1); - } - } -} -*/ - bool Model::has_objects_with_no_instances() const { @@ -240,7 +217,7 @@ Model::raw_mesh() const } Pointfs -Model::_arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf &bb) const +Model::_arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb) const { // we supply unscaled data to arrange() return Slic3r::Geometry::arrange( @@ -254,7 +231,7 @@ Model::_arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf &bb) con /* arrange objects preserving their instance count but altering their instance positions */ void -Model::arrange_objects(coordf_t dist, BoundingBoxf bb) +Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb) { // get the (transformed) size of each instance so that we take // into account their different transformations when packing @@ -275,6 +252,65 @@ Model::arrange_objects(coordf_t dist, BoundingBoxf bb) } } +/* duplicate the entire model preserving instance relative positions */ +void +Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb) +{ + Pointfs model_sizes(copies_num-1, this->bounding_box().size()); + Pointfs positions = this->_arrange(model_sizes, dist, bb); + + // note that this will leave the object count unaltered + + for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) { + // make a copy of the pointers in order to avoid recursion when appending their copies + ModelInstancePtrs instances = (*o)->instances; + for (ModelInstancePtrs::const_iterator i = instances.begin(); i != instances.end(); ++i) { + for (Pointfs::const_iterator pos = positions.begin(); pos != positions.end(); ++pos) { + ModelInstance* instance = (*o)->add_instance(**i); + instance->offset.translate(*pos); + } + } + (*o)->update_bounding_box(); + } +} + +/* this will append more instances to each object + and then automatically rearrange everything */ +void +Model::duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb) +{ + for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) { + // make a copy of the pointers in order to avoid recursion when appending their copies + ModelInstancePtrs instances = (*o)->instances; + for (ModelInstancePtrs::const_iterator i = instances.begin(); i != instances.end(); ++i) { + for (size_t k = 2; k <= copies_num; ++k) + (*o)->add_instance(**i); + } + } + + this->arrange_objects(dist, bb); +} + +void +Model::duplicate_objects_grid(size_t x, size_t y, coordf_t dist) +{ + if (this->objects.size() > 1) throw "Grid duplication is not supported with multiple objects"; + if (this->objects.empty()) throw "No objects!"; + + ModelObject* object = this->objects.front(); + object->clear_instances(); + + Sizef3 size = object->bounding_box().size(); + + for (size_t x_copy = 1; x_copy <= x; ++x_copy) { + for (size_t y_copy = 1; y_copy <= y; ++y_copy) { + ModelInstance* instance = object->add_instance(); + instance->offset.x = (size.x + dist) * (x_copy-1); + instance->offset.y = (size.y + dist) * (y_copy-1); + } + } +} + #ifdef SLIC3RXS REGISTER_CLASS(Model, "Model"); #endif diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index 64b22d837..a2553f6fa 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -48,10 +48,6 @@ class Model ModelMaterial* get_material(t_model_material_id material_id); void delete_material(t_model_material_id material_id); void clear_materials(); - // void duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance); - // void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb); - // void arrange_objects(coordf_t distance, const BoundingBox &bb); - // void duplicate(size_t copies_num, coordf_t distance, const BoundingBox &bb); bool has_objects_with_no_instances() const; bool add_default_instances(); BoundingBoxf3 bounding_box() const; @@ -60,9 +56,11 @@ class Model void translate(coordf_t x, coordf_t y, coordf_t z); TriangleMesh mesh() const; TriangleMesh raw_mesh() const; - // std::string get_material_name(t_model_material_id material_id); - Pointfs _arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf &bb) const; - void arrange_objects(coordf_t dist, BoundingBoxf bb = BoundingBoxf()); + Pointfs _arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb = NULL) const; + void arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL); + void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); + void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL); + void duplicate_objects_grid(size_t x, size_t y, coordf_t dist); }; class ModelMaterial diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp index 9707cd931..51ad8b4d1 100644 --- a/xs/src/libslic3r/Point.cpp +++ b/xs/src/libslic3r/Point.cpp @@ -359,6 +359,12 @@ Pointf::translate(double x, double y) this->y += y; } +void +Pointf::translate(const Vectorf &vector) +{ + this->translate(vector.x, vector.y); +} + void Pointf::rotate(double angle, const Pointf ¢er) { diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index f9850c774..a0e382fb3 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -94,6 +94,7 @@ class Pointf }; void scale(double factor); void translate(double x, double y); + void translate(const Vectorf &vector); void rotate(double angle, const Pointf ¢er); Pointf negative() const; Vectorf vector_to(const Pointf &point) const; diff --git a/xs/xsp/Geometry.xsp b/xs/xsp/Geometry.xsp index c5442a0b6..1eebbfc8a 100644 --- a/xs/xsp/Geometry.xsp +++ b/xs/xsp/Geometry.xsp @@ -9,7 +9,7 @@ %package{Slic3r::Geometry}; Pointfs arrange(size_t total_parts, Pointf* part, coordf_t dist, BoundingBoxf* bb) - %code{% RETVAL = Slic3r::Geometry::arrange(total_parts, *part, dist, *bb); %}; + %code{% RETVAL = Slic3r::Geometry::arrange(total_parts, *part, dist, bb); %}; %{ diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp index ee54dbcb6..929ae3502 100644 --- a/xs/xsp/Model.xsp +++ b/xs/xsp/Model.xsp @@ -53,9 +53,6 @@ size_t material_count() const %code%{ RETVAL = THIS->materials.size(); %}; - // void duplicate_objects_grid(coordf_t x, coordf_t y, coordf_t distance); - // void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb); - // void duplicate(size_t copies_num, coordf_t distance, const BoundingBox &bb); bool has_objects_with_no_instances(); bool add_default_instances(); Clone bounding_box(); @@ -65,17 +62,15 @@ void translate(double x, double y, double z); Clone mesh(); Clone raw_mesh(); - // void split_meshes(); - // std::string get_material_name(t_model_material_id material_id); ModelObjectPtrs* objects() %code%{ RETVAL = &THIS->objects; %}; - Pointfs _arrange(Pointfs sizes, double dist, BoundingBoxf* bb) - %code%{ RETVAL = THIS->_arrange(sizes, dist, *bb); %}; - - void arrange_objects(double dist, BoundingBoxf* bb) - %code%{ THIS->arrange_objects(dist, *bb); %}; + Pointfs _arrange(Pointfs sizes, double dist, BoundingBoxf* bb = NULL); + void arrange_objects(double dist, BoundingBoxf* bb = NULL); + void duplicate(unsigned int copies_num, double dist, BoundingBoxf* bb = NULL); + void duplicate_objects(unsigned int copies_num, double dist, BoundingBoxf* bb = NULL); + void duplicate_objects_grid(unsigned int x, unsigned int y, double dist); };