diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 864f2da7af..37e3761145 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -545,6 +545,7 @@ class SLAPrintConfig ConfigOptionBool support_material; ConfigOptionFloatOrPercent support_material_extrusion_width; ConfigOptionFloat support_material_spacing; + ConfigOptionInt threads; SLAPrintConfig() : StaticPrintConfig() { this->set_defaults(); @@ -563,6 +564,7 @@ class SLAPrintConfig OPT_PTR(support_material); OPT_PTR(support_material_extrusion_width); OPT_PTR(support_material_spacing); + OPT_PTR(threads); return NULL; }; diff --git a/xs/src/libslic3r/SLAPrint.cpp b/xs/src/libslic3r/SLAPrint.cpp index a3bfc43410..d57cf71bb1 100644 --- a/xs/src/libslic3r/SLAPrint.cpp +++ b/xs/src/libslic3r/SLAPrint.cpp @@ -56,63 +56,19 @@ SLAPrint::slice() // generate infill if (this->config.fill_density < 100) { - const float shell_thickness = this->config.get_abs_value("perimeter_extrusion_width", this->config.layer_height.value); - std::auto_ptr fill = std::auto_ptr(Fill::new_from_type(this->config.fill_pattern.value)); + std::auto_ptr fill(Fill::new_from_type(this->config.fill_pattern.value)); fill->bounding_box.merge(Point::new_scale(bb.min.x, bb.min.y)); fill->bounding_box.merge(Point::new_scale(bb.max.x, bb.max.y)); fill->spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value); fill->angle = Geometry::deg2rad(this->config.fill_angle.value); fill->density = this->config.fill_density.value/100; - ExtrusionPath templ(erInternalInfill); - templ.width = fill->spacing; - - for (size_t i = 0; i < this->layers.size(); ++i) { - Layer &layer = this->layers[i]; - - // In order to detect what regions of this layer need to be solid, - // perform an intersection with layers within the requested shell thickness. - Polygons internal = layer.slices; - for (size_t j = 0; j < this->layers.size(); ++j) { - const Layer &other = this->layers[j]; - if (abs(other.print_z - layer.print_z) > shell_thickness) continue; - - if (j == 0 || j == this->layers.size()-1) { - internal.clear(); - break; - } else if (i != j) { - internal = intersection(internal, other.slices); - if (internal.empty()) break; - } - } - - // If we have no internal infill, just print the whole layer as a solid slice. - if (internal.empty()) continue; - layer.solid = false; - - const Polygons infill = offset(layer.slices, -scale_(shell_thickness)); - - // Generate solid infill. - layer.solid_infill << diff_ex(infill, internal, true); - - // Generate internal infill. - { - fill->layer_id = i; - fill->z = layer.print_z; - - const ExPolygons internal_ex = intersection_ex(infill, internal); - for (ExPolygons::const_iterator it = internal_ex.begin(); it != internal_ex.end(); ++it) { - Polylines polylines = fill->fill_surface(Surface(stInternal, *it)); - layer.infill.append(polylines, templ); - } - } - - // Generate perimeter(s). - layer.perimeters << diff_ex( - layer.slices, - offset(layer.slices, -scale_(shell_thickness)) - ); - } + parallelize( + 0, + this->layers.size()-1, + boost::bind(&SLAPrint::_infill_layer, this, _1, fill.get()), + this->config.threads.value + ); } // generate support material @@ -193,6 +149,61 @@ SLAPrint::slice() } } +void +SLAPrint::_infill_layer(size_t i, const Fill* _fill) +{ + Layer &layer = this->layers[i]; + + const float shell_thickness = this->config.get_abs_value("perimeter_extrusion_width", this->config.layer_height.value); + + // In order to detect what regions of this layer need to be solid, + // perform an intersection with layers within the requested shell thickness. + Polygons internal = layer.slices; + for (size_t j = 0; j < this->layers.size(); ++j) { + const Layer &other = this->layers[j]; + if (abs(other.print_z - layer.print_z) > shell_thickness) continue; + + if (j == 0 || j == this->layers.size()-1) { + internal.clear(); + break; + } else if (i != j) { + internal = intersection(internal, other.slices); + if (internal.empty()) break; + } + } + + // If we have no internal infill, just print the whole layer as a solid slice. + if (internal.empty()) return; + layer.solid = false; + + const Polygons infill = offset(layer.slices, -scale_(shell_thickness)); + + // Generate solid infill + layer.solid_infill << diff_ex(infill, internal, true); + + // Generate internal infill + { + std::auto_ptr fill(_fill->clone()); + fill->layer_id = i; + fill->z = layer.print_z; + + ExtrusionPath templ(erInternalInfill); + templ.width = fill->spacing; + + const ExPolygons internal_ex = intersection_ex(infill, internal); + for (ExPolygons::const_iterator it = internal_ex.begin(); it != internal_ex.end(); ++it) { + Polylines polylines = fill->fill_surface(Surface(stInternal, *it)); + layer.infill.append(polylines, templ); + } + } + + // Generate perimeter(s). + layer.perimeters << diff_ex( + layer.slices, + offset(layer.slices, -scale_(shell_thickness)) + ); +} + void SLAPrint::write_svg(const std::string &outputfile) const { diff --git a/xs/src/libslic3r/SLAPrint.hpp b/xs/src/libslic3r/SLAPrint.hpp index e3373b508e..6c6028abb6 100644 --- a/xs/src/libslic3r/SLAPrint.hpp +++ b/xs/src/libslic3r/SLAPrint.hpp @@ -4,6 +4,7 @@ #include "libslic3r.h" #include "ExPolygon.hpp" #include "ExPolygonCollection.hpp" +#include "Fill/Fill.hpp" #include "Model.hpp" #include "Point.hpp" #include "PrintConfig.hpp" @@ -45,6 +46,7 @@ class SLAPrint Model* model; BoundingBoxf3 bb; + void _infill_layer(size_t i, const Fill* fill); coordf_t sm_pillars_radius() const; std::string _SVG_path_d(const Polygon &polygon) const; std::string _SVG_path_d(const ExPolygon &expolygon) const;