diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 88b527080..09ebd40a2 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -40,46 +40,6 @@ sub total_layer_count { return max(map $_->total_layer_count, @{$self->objects}); } -# the bounding box of objects placed in copies position -# (without taking skirt/brim/support material into account) -sub bounding_box { - my $self = shift; - - my @points = (); - foreach my $object (@{$self->objects}) { - foreach my $copy (@{$object->_shifted_copies}) { - push @points, - [ $copy->[X], $copy->[Y] ], - [ $copy->[X] + $object->size->[X], $copy->[Y] + $object->size->[Y] ]; - } - } - return Slic3r::Geometry::BoundingBox->new_from_points([ map Slic3r::Point->new(@$_), @points ]); -} - -# the total bounding box of extrusions, including skirt/brim/support material -sub total_bounding_box { - my ($self) = @_; - - # get objects bounding box - my $bb = $self->bounding_box; - - # check how much we need to increase it - my $extra = 0; - if ($self->has_support_material) { - $extra = &Slic3r::Print::SupportMaterial::MARGIN; - } - $extra = max($extra, $self->config->brim_width); - if ($self->config->skirts > 0) { - my $skirt_flow = $self->skirt_flow; - $extra = max($extra, $self->config->brim_width + $self->config->skirt_distance + ($self->config->skirts * $skirt_flow->spacing)); - } - - if ($extra > 0) { - $bb->offset(scale $extra); - } - return $bb; -} - sub size { my $self = shift; return $self->bounding_box->size; @@ -422,23 +382,6 @@ sub make_brim { $self->set_step_done(STEP_BRIM); } -sub skirt_first_layer_height { - my ($self) = @_; - return $self->objects->[0]->config->get_abs_value('first_layer_height'); -} - -sub skirt_flow { - my ($self) = @_; - - return Slic3r::Flow->new_from_width( - width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), - role => FLOW_ROLE_PERIMETER, - nozzle_diameter => $self->config->get_at('nozzle_diameter', $self->objects->[0]->config->support_material_extruder-1), - layer_height => $self->skirt_first_layer_height, - bridge_flow_ratio => 0, - ); -} - sub write_gcode { my $self = shift; my ($file) = @_; diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 596d87983..01df21a55 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -17,9 +17,6 @@ has 'interface_flow' => (is => 'rw', required => 1); use constant DEBUG_CONTACT_ONLY => 0; -# how much we extend support around the actual contact area -use constant MARGIN => 1.5; - # increment used to reach MARGIN in steps to avoid trespassing thin objects use constant MARGIN_STEP => MARGIN/3; diff --git a/xs/MANIFEST b/xs/MANIFEST index ac073b1d0..4a3907872 100644 --- a/xs/MANIFEST +++ b/xs/MANIFEST @@ -1703,6 +1703,7 @@ src/libslic3r/PrintConfig.cpp src/libslic3r/PrintConfig.hpp src/libslic3r/PrintObject.cpp src/libslic3r/PrintRegion.cpp +src/libslic3r/SupportMaterial.hpp src/libslic3r/Surface.cpp src/libslic3r/Surface.hpp src/libslic3r/SurfaceCollection.cpp @@ -1773,6 +1774,7 @@ xsp/Polygon.xsp xsp/Polyline.xsp xsp/PolylineCollection.xsp xsp/Print.xsp +xsp/SupportMaterial.xsp xsp/Surface.xsp xsp/SurfaceCollection.xsp xsp/TriangleMesh.xsp diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index c4a231c78..88e88a45a 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -1,7 +1,9 @@ #include "Print.hpp" #include "BoundingBox.hpp" #include "ClipperUtils.hpp" +#include "Flow.hpp" #include "Geometry.hpp" +#include "SupportMaterial.hpp" #include namespace Slic3r { @@ -641,6 +643,76 @@ Print::validate() const } } +// the bounding box of objects placed in copies position +// (without taking skirt/brim/support material into account) +BoundingBox +Print::bounding_box() const +{ + BoundingBox bb; + FOREACH_OBJECT(this, object) { + for (Points::const_iterator copy = (*object)->_shifted_copies.begin(); copy != (*object)->_shifted_copies.end(); ++copy) { + bb.merge(*copy); + + Point p = *copy; + p.translate((*object)->size); + bb.merge(p); + } + } + return bb; +} + +// the total bounding box of extrusions, including skirt/brim/support material +// this methods needs to be called even when no steps were processed, so it should +// only use configuration values +BoundingBox +Print::total_bounding_box() const +{ + // get objects bounding box + BoundingBox bb = this->bounding_box(); + + // check how much we need to increase it + double extra = 0; // unscaled + if (this->has_support_material()) + extra = SUPPORT_MATERIAL_MARGIN; + + extra = std::max(extra, this->config.brim_width.value); + if (this->config.skirts > 0) { + Flow skirt_flow = this->skirt_flow(); + extra = std::max( + extra, + this->config.brim_width.value + this->config.skirt_distance.value + (this->config.skirts.value * skirt_flow.spacing()) + ); + } + + if (extra > 0) + bb.offset(scale_(extra)); + + return bb; +} + +double +Print::skirt_first_layer_height() const +{ + if (this->objects.empty()) CONFESS("skirt_first_layer_height() can't be called without PrintObjects"); + return this->objects.front()->config.get_abs_value("first_layer_height"); +} + +Flow +Print::skirt_flow() const +{ + ConfigOptionFloatOrPercent width = this->config.first_layer_extrusion_width; + if (width.value == 0) width = this->regions.front()->config.perimeter_extrusion_width; + + return Flow::new_from_config_width( + frPerimeter, + width, + this->config.nozzle_diameter.get_at(this->objects.front()->config.support_material_extruder-1), + this->skirt_first_layer_height(), + 0 + ); +} + + PrintRegionConfig Print::_region_config_from_model_volume(const ModelVolume &volume) { diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 27ba83780..45e1eb25c 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -187,6 +187,10 @@ class Print bool apply_config(DynamicPrintConfig config); void init_extruders(); void validate() const; + BoundingBox bounding_box() const; + BoundingBox total_bounding_box() const; + double skirt_first_layer_height() const; + Flow skirt_flow() const; std::set extruders() const; void _simplify_slices(double distance); diff --git a/xs/src/libslic3r/SupportMaterial.hpp b/xs/src/libslic3r/SupportMaterial.hpp new file mode 100644 index 000000000..edea22695 --- /dev/null +++ b/xs/src/libslic3r/SupportMaterial.hpp @@ -0,0 +1,11 @@ +#ifndef slic3r_SupportMaterial_hpp_ +#define slic3r_SupportMaterial_hpp_ + +namespace Slic3r { + +// how much we extend support around the actual contact area +#define SUPPORT_MATERIAL_MARGIN 1.5 + +} + +#endif diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 2213a9511..7ed3d6853 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -193,6 +193,10 @@ _constant() croak("%s\n", e.what()); } %}; + Clone bounding_box(); + Clone total_bounding_box(); + double skirt_first_layer_height(); + Clone skirt_flow(); %{ double diff --git a/xs/xsp/SupportMaterial.xsp b/xs/xsp/SupportMaterial.xsp new file mode 100644 index 000000000..a0301f248 --- /dev/null +++ b/xs/xsp/SupportMaterial.xsp @@ -0,0 +1,16 @@ +%module{Slic3r::XS}; + +#include +#include "libslic3r/SupportMaterial.hpp" + +%package{Slic3r::Print::SupportMaterial}; +%{ + +SV* +MARGIN() + PROTOTYPE: + CODE: + RETVAL = newSVnv(SUPPORT_MATERIAL_MARGIN); + OUTPUT: RETVAL + +%} \ No newline at end of file