mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-13 23:15:56 +08:00
Multithreaded infill generation for SLAPrint
This commit is contained in:
parent
27d41f89b8
commit
578658a2fb
@ -545,6 +545,7 @@ class SLAPrintConfig
|
|||||||
ConfigOptionBool support_material;
|
ConfigOptionBool support_material;
|
||||||
ConfigOptionFloatOrPercent support_material_extrusion_width;
|
ConfigOptionFloatOrPercent support_material_extrusion_width;
|
||||||
ConfigOptionFloat support_material_spacing;
|
ConfigOptionFloat support_material_spacing;
|
||||||
|
ConfigOptionInt threads;
|
||||||
|
|
||||||
SLAPrintConfig() : StaticPrintConfig() {
|
SLAPrintConfig() : StaticPrintConfig() {
|
||||||
this->set_defaults();
|
this->set_defaults();
|
||||||
@ -563,6 +564,7 @@ class SLAPrintConfig
|
|||||||
OPT_PTR(support_material);
|
OPT_PTR(support_material);
|
||||||
OPT_PTR(support_material_extrusion_width);
|
OPT_PTR(support_material_extrusion_width);
|
||||||
OPT_PTR(support_material_spacing);
|
OPT_PTR(support_material_spacing);
|
||||||
|
OPT_PTR(threads);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
@ -56,63 +56,19 @@ SLAPrint::slice()
|
|||||||
|
|
||||||
// generate infill
|
// generate infill
|
||||||
if (this->config.fill_density < 100) {
|
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> fill(Fill::new_from_type(this->config.fill_pattern.value));
|
||||||
std::auto_ptr<Fill> fill = 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.min.x, bb.min.y));
|
||||||
fill->bounding_box.merge(Point::new_scale(bb.max.x, bb.max.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->spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
|
||||||
fill->angle = Geometry::deg2rad(this->config.fill_angle.value);
|
fill->angle = Geometry::deg2rad(this->config.fill_angle.value);
|
||||||
fill->density = this->config.fill_density.value/100;
|
fill->density = this->config.fill_density.value/100;
|
||||||
|
|
||||||
ExtrusionPath templ(erInternalInfill);
|
parallelize<size_t>(
|
||||||
templ.width = fill->spacing;
|
0,
|
||||||
|
this->layers.size()-1,
|
||||||
for (size_t i = 0; i < this->layers.size(); ++i) {
|
boost::bind(&SLAPrint::_infill_layer, this, _1, fill.get()),
|
||||||
Layer &layer = this->layers[i];
|
this->config.threads.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()) 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))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate support material
|
// 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(_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
|
void
|
||||||
SLAPrint::write_svg(const std::string &outputfile) const
|
SLAPrint::write_svg(const std::string &outputfile) const
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include "ExPolygon.hpp"
|
#include "ExPolygon.hpp"
|
||||||
#include "ExPolygonCollection.hpp"
|
#include "ExPolygonCollection.hpp"
|
||||||
|
#include "Fill/Fill.hpp"
|
||||||
#include "Model.hpp"
|
#include "Model.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "PrintConfig.hpp"
|
#include "PrintConfig.hpp"
|
||||||
@ -45,6 +46,7 @@ class SLAPrint
|
|||||||
Model* model;
|
Model* model;
|
||||||
BoundingBoxf3 bb;
|
BoundingBoxf3 bb;
|
||||||
|
|
||||||
|
void _infill_layer(size_t i, const Fill* fill);
|
||||||
coordf_t sm_pillars_radius() const;
|
coordf_t sm_pillars_radius() const;
|
||||||
std::string _SVG_path_d(const Polygon &polygon) const;
|
std::string _SVG_path_d(const Polygon &polygon) const;
|
||||||
std::string _SVG_path_d(const ExPolygon &expolygon) const;
|
std::string _SVG_path_d(const ExPolygon &expolygon) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user