From a9609a6dd5a0b08a53131f3702ce2cec89e3ee46 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 30 Nov 2016 17:43:58 +0100 Subject: [PATCH] Finished infill implementation for SLAPrint --- lib/Slic3r/GUI/Projector.pm | 12 +++--- src/CMakeLists.txt | 8 ++++ xs/src/libslic3r/ExPolygon.hpp | 6 +++ xs/src/libslic3r/ExPolygonCollection.hpp | 6 +++ xs/src/libslic3r/Fill/FillConcentric.cpp | 6 +-- xs/src/libslic3r/Point.hpp | 12 ++++++ xs/src/libslic3r/Polygon.hpp | 12 ++++++ xs/src/libslic3r/SLAPrint.cpp | 54 ++++++++++++++---------- xs/src/libslic3r/SLAPrint.hpp | 2 +- xs/xsp/SLAPrint.xsp | 4 +- 10 files changed, 89 insertions(+), 33 deletions(-) diff --git a/lib/Slic3r/GUI/Projector.pm b/lib/Slic3r/GUI/Projector.pm index e75ac7e09..760484231 100644 --- a/lib/Slic3r/GUI/Projector.pm +++ b/lib/Slic3r/GUI/Projector.pm @@ -738,7 +738,7 @@ use base qw(Wx::Dialog Class::Accessor); use List::Util qw(min); use Slic3r::Geometry qw(X Y unscale scale); -use Slic3r::Geometry::Clipper qw(intersection_pl); +use Slic3r::Geometry::Clipper qw(intersection_pl union_ex); __PACKAGE__->mk_accessors(qw(config config2 scaling_factor bed_origin print layer_num)); @@ -879,10 +879,12 @@ sub _repaint { if ($self->print->layer_solid($self->layer_num)) { $self->_paint_expolygon($_, $dc) for @{$self->print->layer_slices($self->layer_num)}; } else { - $self->_paint_expolygon($_, $dc) for @{$self->print->layer_solid_infill($self->layer_num)}; - $self->_paint_polygon($_, $dc) for map @{$_->grow}, - @{$self->print->layer_perimeters($self->layer_num)}, - @{$self->print->layer_infill($self->layer_num)}; + $self->_paint_expolygon($_, $dc) for + @{$self->print->layer_solid_infill($self->layer_num)}, + @{$self->print->layer_perimeters($self->layer_num)}; + + $self->_paint_expolygon($_, $dc) + for @{union_ex($self->print->layer_infill($self->layer_num)->grow)}; } # draw support material diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9b704d5b0..dfd5ce3f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,14 @@ add_library(libslic3r STATIC ${LIBDIR}/libslic3r/Extruder.cpp ${LIBDIR}/libslic3r/ExtrusionEntity.cpp ${LIBDIR}/libslic3r/ExtrusionEntityCollection.cpp + ${LIBDIR}/libslic3r/Fill/Fill.cpp + ${LIBDIR}/libslic3r/Fill/Fill3DHoneycomb.cpp + ${LIBDIR}/libslic3r/Fill/FillBase.cpp + ${LIBDIR}/libslic3r/Fill/FillConcentric.cpp + ${LIBDIR}/libslic3r/Fill/FillHoneycomb.cpp + ${LIBDIR}/libslic3r/Fill/FillPlanePath.cpp + ${LIBDIR}/libslic3r/Fill/FillRectilinear.cpp + ${LIBDIR}/libslic3r/Fill/FillRectilinear2.cpp ${LIBDIR}/libslic3r/Flow.cpp ${LIBDIR}/libslic3r/GCode.cpp ${LIBDIR}/libslic3r/GCodeSender.cpp diff --git a/xs/src/libslic3r/ExPolygon.hpp b/xs/src/libslic3r/ExPolygon.hpp index 0b4140e90..4289eb390 100644 --- a/xs/src/libslic3r/ExPolygon.hpp +++ b/xs/src/libslic3r/ExPolygon.hpp @@ -55,6 +55,12 @@ to_polygons(const ExPolygons &expolygons) return pp; } +inline ExPolygons +operator+(ExPolygons src1, const ExPolygons &src2) { + append_to(src1, src2); + return src1; +}; + } // start Boost diff --git a/xs/src/libslic3r/ExPolygonCollection.hpp b/xs/src/libslic3r/ExPolygonCollection.hpp index ec3cb9522..e63dd9142 100644 --- a/xs/src/libslic3r/ExPolygonCollection.hpp +++ b/xs/src/libslic3r/ExPolygonCollection.hpp @@ -34,6 +34,12 @@ class ExPolygonCollection void append(const ExPolygons &expolygons); }; +inline ExPolygonCollection& +operator <<(ExPolygonCollection &coll, const ExPolygons &expolygons) { + coll.append(expolygons); + return coll; +}; + } #endif diff --git a/xs/src/libslic3r/Fill/FillConcentric.cpp b/xs/src/libslic3r/Fill/FillConcentric.cpp index d31efcafc..4bec2bb7d 100644 --- a/xs/src/libslic3r/Fill/FillConcentric.cpp +++ b/xs/src/libslic3r/Fill/FillConcentric.cpp @@ -29,7 +29,7 @@ FillConcentric::_fill_surface_single( Polygons last = loops; while (!last.empty()) { last = offset2(last, -(distance + min_spacing/2), +min_spacing/2); - loops.insert(loops.end(), last.begin(), last.end()); + append_to(loops, last); } // generate paths from the outermost to the innermost, to avoid @@ -37,7 +37,7 @@ FillConcentric::_fill_surface_single( loops = union_pt_chained(loops, false); // split paths using a nearest neighbor search - size_t iPathFirst = polylines_out->size(); + const size_t iPathFirst = polylines_out->size(); Point last_pos(0, 0); for (Polygons::const_iterator it_loop = loops.begin(); it_loop != loops.end(); ++ it_loop) { polylines_out->push_back(it_loop->split_at_index(last_pos.nearest_point_index(*it_loop))); @@ -47,7 +47,7 @@ FillConcentric::_fill_surface_single( // clip the paths to prevent the extruder from getting exactly on the first point of the loop // Keep valid paths only. size_t j = iPathFirst; - for (size_t i = iPathFirst; i < polylines_out->size(); ++ i) { + for (size_t i = iPathFirst; i < polylines_out->size(); ++i) { (*polylines_out)[i].clip_end(this->loop_clipping); if ((*polylines_out)[i].is_valid()) { if (j < i) diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index c6c340446..7fd05ff48 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -79,6 +79,18 @@ Point operator+(const Point& point1, const Point& point2); Point operator-(const Point& point1, const Point& point2); Point operator*(double scalar, const Point& point2); +inline Points& +operator+=(Points &dst, const Points &src) { + append_to(dst, src); + return dst; +}; + +inline Points& +operator+=(Points &dst, const Point &p) { + dst.push_back(p); + return dst; +}; + class Point3 : public Point { public: diff --git a/xs/src/libslic3r/Polygon.hpp b/xs/src/libslic3r/Polygon.hpp index 415aa404e..1b9887218 100644 --- a/xs/src/libslic3r/Polygon.hpp +++ b/xs/src/libslic3r/Polygon.hpp @@ -48,6 +48,18 @@ class Polygon : public MultiPoint { Points convex_points(double angle = PI) const; }; +inline Polygons +operator+(Polygons src1, const Polygons &src2) { + append_to(src1, src2); + return src1; +}; + +inline Polygons& +operator+=(Polygons &dst, const Polygons &src2) { + append_to(dst, src2); + return dst; +}; + } // start Boost diff --git a/xs/src/libslic3r/SLAPrint.cpp b/xs/src/libslic3r/SLAPrint.cpp index 35244f560..77122057b 100644 --- a/xs/src/libslic3r/SLAPrint.cpp +++ b/xs/src/libslic3r/SLAPrint.cpp @@ -94,7 +94,7 @@ SLAPrint::slice() const Polygons infill = offset(layer.slices, -scale_(shell_thickness)); // Generate solid infill. - layer.solid_infill.append(diff_ex(infill, internal, true)); + layer.solid_infill << diff_ex(infill, internal, true); // Generate internal infill. { @@ -109,15 +109,10 @@ SLAPrint::slice() } // Generate perimeter(s). - { - const Polygons perimeters = offset(layer.slices, -scale_(shell_thickness)/2); - for (Polygons::const_iterator it = perimeters.begin(); it != perimeters.end(); ++it) { - ExtrusionPath ep(erPerimeter); - ep.polyline = *it; - ep.width = shell_thickness; - layer.perimeters.append(ExtrusionLoop(ep)); - } - } + layer.perimeters << diff_ex( + layer.slices, + offset(layer.slices, -scale_(shell_thickness)) + ); } } @@ -128,10 +123,8 @@ SLAPrint::slice() // flatten and merge all the overhangs { Polygons pp; - for (std::vector::const_iterator it = this->layers.begin()+1; it != this->layers.end(); ++it) { - Polygons oh = diff(it->slices, (it - 1)->slices); - pp.insert(pp.end(), oh.begin(), oh.end()); - } + for (std::vector::const_iterator it = this->layers.begin()+1; it != this->layers.end(); ++it) + pp += diff(it->slices, (it - 1)->slices); overhangs = union_ex(pp); } @@ -188,8 +181,7 @@ SLAPrint::slice() // generate a solid raft if requested // (do this after support material because we take support material shape into account) if (this->config.raft_layers > 0) { - ExPolygons raft = this->layers.front().slices; - raft.insert(raft.end(), overhangs.begin(), overhangs.end()); // take support material into account + ExPolygons raft = this->layers.front().slices + overhangs; // take support material into account raft = offset_ex(raft, scale_(this->config.raft_offset)); for (int i = this->config.raft_layers; i >= 1; --i) { this->layers.insert(this->layers.begin(), Layer(0, first_lh + lh * (i-1))); @@ -235,9 +227,19 @@ SLAPrint::write_svg(const std::string &outputfile) const ); } } else { + // Perimeters. + for (ExPolygons::const_iterator it = layer.perimeters.expolygons.begin(); + it != layer.perimeters.expolygons.end(); ++it) { + std::string pd = this->_SVG_path_d(*it); + + fprintf(f,"\t\t\n", + pd.c_str(), "white", "black", "0" + ); + } + // Solid infill. - const ExPolygons &solid_infill = layer.solid_infill.expolygons; - for (ExPolygons::const_iterator it = solid_infill.begin(); it != solid_infill.end(); ++it) { + for (ExPolygons::const_iterator it = layer.solid_infill.expolygons.begin(); + it != layer.solid_infill.expolygons.end(); ++it) { std::string pd = this->_SVG_path_d(*it); fprintf(f,"\t\t\n", @@ -245,10 +247,18 @@ SLAPrint::write_svg(const std::string &outputfile) const ); } - // Generate perimeters. - for (ExtrusionEntitiesPtr::const_iterator it = layer.perimeters.entities.begin(); - it != layer.perimeters.entities.end(); ++it) { - //std::string pd = this->_SVG_path_d(it->polygon()); + // Internal infill. + for (ExtrusionEntitiesPtr::const_iterator it = layer.infill.entities.begin(); + it != layer.infill.entities.end(); ++it) { + const ExPolygons infill = union_ex((*it)->grow()); + + for (ExPolygons::const_iterator e = infill.begin(); e != infill.end(); ++e) { + std::string pd = this->_SVG_path_d(*e); + + fprintf(f,"\t\t\n", + pd.c_str(), "white", "black", "0" + ); + } } } diff --git a/xs/src/libslic3r/SLAPrint.hpp b/xs/src/libslic3r/SLAPrint.hpp index 99d3c2f8e..e3373b508 100644 --- a/xs/src/libslic3r/SLAPrint.hpp +++ b/xs/src/libslic3r/SLAPrint.hpp @@ -19,7 +19,7 @@ class SLAPrint class Layer { public: ExPolygonCollection slices; - ExtrusionEntityCollection perimeters; + ExPolygonCollection perimeters; ExtrusionEntityCollection infill; ExPolygonCollection solid_infill; float slice_z, print_z; diff --git a/xs/xsp/SLAPrint.xsp b/xs/xsp/SLAPrint.xsp index 3788d3d14..559d2973d 100644 --- a/xs/xsp/SLAPrint.xsp +++ b/xs/xsp/SLAPrint.xsp @@ -22,8 +22,8 @@ %code%{ RETVAL = THIS->layers[i].slices; %}; ExPolygons layer_solid_infill(size_t i) %code%{ RETVAL = THIS->layers[i].solid_infill.expolygons; %}; - Ref layer_perimeters(size_t i) - %code%{ RETVAL = &THIS->layers[i].perimeters; %}; + ExPolygons layer_perimeters(size_t i) + %code%{ RETVAL = THIS->layers[i].perimeters; %}; Ref layer_infill(size_t i) %code%{ RETVAL = &THIS->layers[i].infill; %}; bool layer_solid(size_t i)