diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 78ff619cb..168f78bb3 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -335,39 +335,6 @@ sub slice { $self->set_step_done(STEP_SLICE); } -# called from slice() -sub _slice_region { - my ($self, $region_id, $z, $modifier) = @_; - - return [] if !@{$self->get_region_volumes($region_id)}; - - # compose mesh - my $mesh; - foreach my $volume_id (@{ $self->get_region_volumes($region_id) }) { - my $volume = $self->model_object->volumes->[$volume_id]; - next if $volume->modifier && !$modifier; - next if !$volume->modifier && $modifier; - - if (defined $mesh) { - $mesh->merge($volume->mesh); - } else { - $mesh = $volume->mesh->clone; - } - } - return if !defined $mesh; - - # transform mesh - # we ignore the per-instance transformations currently and only - # consider the first one - $self->model_object->instances->[0]->transform_mesh($mesh, 1); - - # align mesh to Z = 0 (it should be already aligned actually) and apply XY shift - $mesh->translate((map unscale(-$_), @{$self->_copies_shift}), -$self->model_object->bounding_box->z_min); - - # perform actual slicing - return $mesh->slice($z); -} - sub make_perimeters { my ($self) = @_; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 4b586a2f4..65f61f3fb 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -100,7 +100,7 @@ class PrintObject PrintState state; Print* print(); - ModelObject* model_object(); + ModelObject* model_object() { return this->_model_object; }; Points copies() const; bool add_copy(const Pointf &point); @@ -136,6 +136,7 @@ class PrintObject void detect_surfaces_type(); void process_external_surfaces(); void bridge_over_infill(); + std::vector _slice_region(size_t region_id, std::vector z, bool modifier); void _make_perimeters(); void _infill(); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 90752461e..97263036d 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -40,12 +40,6 @@ PrintObject::print() return this->_print; } -ModelObject* -PrintObject::model_object() -{ - return this->_model_object; -} - Points PrintObject::copies() const { @@ -665,6 +659,45 @@ PrintObject::bridge_over_infill() } } +// called from slice() +std::vector +PrintObject::_slice_region(size_t region_id, std::vector z, bool modifier) +{ + std::vector layers; + std::vector ®ion_volumes = this->region_volumes[region_id]; + if (region_volumes.empty()) return layers; + + ModelObject &object = *this->model_object(); + + // compose mesh + TriangleMesh mesh; + for (std::vector::const_iterator it = region_volumes.begin(); + it != region_volumes.end(); ++it) { + + const ModelVolume &volume = *object.volumes[*it]; + if (volume.modifier != modifier) continue; + + mesh.merge(volume.mesh); + } + if (mesh.facets_count() == 0) return layers; + + // transform mesh + // we ignore the per-instance transformations currently and only + // consider the first one + object.instances[0]->transform_mesh(&mesh, true); + + // align mesh to Z = 0 (it should be already aligned actually) and apply XY shift + mesh.translate( + unscale(this->_copies_shift.x), + unscale(this->_copies_shift.y), + -object.bounding_box().min.z + ); + + // perform actual slicing + TriangleMeshSlicer(&mesh).slice(z, &layers); + return layers; +} + void PrintObject::_make_perimeters() { diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 9da32d674..0cd8e01f4 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -110,6 +110,25 @@ _constant() void detect_surfaces_type(); void process_external_surfaces(); void bridge_over_infill(); + SV* _slice_region(size_t region_id, std::vector z, bool modifier) + %code%{ + std::vector z_f(z.begin(), z.end()); + std::vector layers = THIS->_slice_region(region_id, z_f, modifier); + AV* layers_av = newAV(); + size_t len = layers.size(); + if (len > 0) av_extend(layers_av, len-1); + for (unsigned int i = 0; i < layers.size(); i++) { + AV* expolygons_av = newAV(); + len = layers[i].size(); + if (len > 0) av_extend(expolygons_av, len-1); + unsigned int j = 0; + for (ExPolygons::iterator it = layers[i].begin(); it != layers[i].end(); ++it) { + av_store(expolygons_av, j++, perl_to_SV_clone_ref(*it)); + } + av_store(layers_av, i, newRV_noinc((SV*)expolygons_av)); + } + RETVAL = (SV*)newRV_noinc((SV*)layers_av); + %}; void _make_perimeters(); void _infill();