mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 06:35:57 +08:00
Infill for SLAPrint
This commit is contained in:
parent
2dbc5d6e07
commit
3f3f696502
@ -521,7 +521,6 @@ has 'sender' => (is => 'rw');
|
||||
has 'timer' => (is => 'rw');
|
||||
has 'is_printing' => (is => 'rw', default => sub { 0 });
|
||||
has '_print' => (is => 'rw');
|
||||
has '_layers' => (is => 'rw');
|
||||
has '_heights' => (is => 'rw');
|
||||
has '_layer_num' => (is => 'rw');
|
||||
has '_timer_cb' => (is => 'rw');
|
||||
@ -545,8 +544,7 @@ sub BUILD {
|
||||
$print->slice;
|
||||
$progress_dialog->Destroy;
|
||||
}
|
||||
|
||||
$self->_layers([ map $print->slices($_), 0..($print->layer_count-1) ]);
|
||||
|
||||
$self->_heights($print->heights);
|
||||
}
|
||||
|
||||
@ -639,7 +637,7 @@ sub print_completed {
|
||||
sub is_projecting {
|
||||
my ($self) = @_;
|
||||
|
||||
return defined $self->screen->layer;
|
||||
return defined $self->screen->layer_num;
|
||||
}
|
||||
|
||||
sub project_layer {
|
||||
@ -650,7 +648,7 @@ sub project_layer {
|
||||
return;
|
||||
}
|
||||
|
||||
$self->screen->project_layer($self->_layers->[$layer_num], $layer_num);
|
||||
$self->screen->project_layer($layer_num);
|
||||
}
|
||||
|
||||
sub project_next_layer {
|
||||
@ -719,7 +717,7 @@ sub total_resin {
|
||||
|
||||
for my $i (0..($self->_print->layer_count-1)) {
|
||||
my $lh = $self->_heights->[$i] - ($i == 0 ? 0 : $self->_heights->[$i-1]);
|
||||
$vol += unscale(unscale($_->area)) * $lh for @{ $self->_print->slices($i) };
|
||||
$vol += unscale(unscale($_->area)) * $lh for @{ $self->_print->layer_slices($i) };
|
||||
}
|
||||
|
||||
return $vol/1000/1000; # liters
|
||||
@ -742,7 +740,7 @@ use List::Util qw(min);
|
||||
use Slic3r::Geometry qw(X Y unscale scale);
|
||||
use Slic3r::Geometry::Clipper qw(intersection_pl);
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(config config2 scaling_factor bed_origin layer print layer_num));
|
||||
__PACKAGE__->mk_accessors(qw(config config2 scaling_factor bed_origin print layer_num));
|
||||
|
||||
sub new {
|
||||
my ($class, $parent, $config, $config2) = @_;
|
||||
@ -803,9 +801,8 @@ sub _resize {
|
||||
}
|
||||
|
||||
sub project_layer {
|
||||
my ($self, $layer, $layer_num) = @_;
|
||||
my ($self, $layer_num) = @_;
|
||||
|
||||
$self->layer($layer);
|
||||
$self->layer_num($layer_num);
|
||||
$self->Refresh;
|
||||
}
|
||||
@ -873,20 +870,19 @@ sub _repaint {
|
||||
}
|
||||
}
|
||||
|
||||
return if !defined $self->layer;
|
||||
|
||||
# get layers at this height
|
||||
# draw layers
|
||||
$dc->SetPen(Wx::Pen->new(wxWHITE, 1, wxSOLID));
|
||||
|
||||
my @polygons = sort { $a->contains_point($b->first_point) ? -1 : 1 } map @$_, @{$self->layer};
|
||||
foreach my $polygon (@polygons) {
|
||||
if ($polygon->is_counter_clockwise) {
|
||||
$dc->SetBrush(Wx::Brush->new(wxWHITE, wxSOLID));
|
||||
} else {
|
||||
$dc->SetBrush(Wx::Brush->new(wxBLACK, wxSOLID));
|
||||
}
|
||||
$dc->DrawPolygon($self->scaled_points_to_pixel($polygon->pp), 0, 0);
|
||||
return if !$self->print || !defined $self->layer_num;
|
||||
|
||||
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)};
|
||||
}
|
||||
|
||||
# draw support material
|
||||
@ -908,6 +904,24 @@ sub _repaint {
|
||||
}
|
||||
}
|
||||
|
||||
sub _paint_expolygon {
|
||||
my ($self, $expolygon, $dc) = @_;
|
||||
|
||||
my @polygons = sort { $a->contains_point($b->first_point) ? -1 : 1 } @$expolygon;
|
||||
$self->_paint_polygon($_, $dc) for @polygons;
|
||||
}
|
||||
|
||||
sub _paint_polygon {
|
||||
my ($self, $polygon, $dc) = @_;
|
||||
|
||||
if ($polygon->is_counter_clockwise) {
|
||||
$dc->SetBrush(Wx::Brush->new(wxWHITE, wxSOLID));
|
||||
} else {
|
||||
$dc->SetBrush(Wx::Brush->new(wxBLACK, wxSOLID));
|
||||
}
|
||||
$dc->DrawPolygon($self->scaled_points_to_pixel($polygon->pp), 0, 0);
|
||||
}
|
||||
|
||||
# convert a model coordinate into a pixel coordinate
|
||||
sub unscaled_point_to_pixel {
|
||||
my ($self, $point) = @_;
|
||||
|
@ -155,7 +155,7 @@ offset(const Polygons &polygons, const float delta,
|
||||
// perform offset
|
||||
ClipperLib::Paths output = _offset(polygons, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
// convert into Polygons
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ offset(const Polylines &polylines, const float delta,
|
||||
// perform offset
|
||||
ClipperLib::Paths output = _offset(polylines, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
// convert into Polygons
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
|
@ -533,8 +533,13 @@ class SLAPrintConfig
|
||||
: public virtual StaticPrintConfig
|
||||
{
|
||||
public:
|
||||
ConfigOptionFloat fill_angle;
|
||||
ConfigOptionPercent fill_density;
|
||||
ConfigOptionEnum<InfillPattern> fill_pattern;
|
||||
ConfigOptionFloatOrPercent first_layer_height;
|
||||
ConfigOptionFloatOrPercent infill_extrusion_width;
|
||||
ConfigOptionFloat layer_height;
|
||||
ConfigOptionFloatOrPercent perimeter_extrusion_width;
|
||||
ConfigOptionInt raft_layers;
|
||||
ConfigOptionFloat raft_offset;
|
||||
ConfigOptionBool support_material;
|
||||
@ -546,8 +551,13 @@ class SLAPrintConfig
|
||||
};
|
||||
|
||||
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
|
||||
OPT_PTR(fill_angle);
|
||||
OPT_PTR(fill_density);
|
||||
OPT_PTR(fill_pattern);
|
||||
OPT_PTR(first_layer_height);
|
||||
OPT_PTR(infill_extrusion_width);
|
||||
OPT_PTR(layer_height);
|
||||
OPT_PTR(perimeter_extrusion_width);
|
||||
OPT_PTR(raft_layers);
|
||||
OPT_PTR(raft_offset);
|
||||
OPT_PTR(support_material);
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "SLAPrint.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "Fill/FillBase.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Surface.hpp"
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
@ -47,7 +51,73 @@ SLAPrint::slice()
|
||||
TriangleMeshSlicer(&mesh).slice(slice_z, &slices);
|
||||
|
||||
for (size_t i = 0; i < slices.size(); ++i)
|
||||
this->layers[i].slices = ExPolygonCollection(slices[i]);
|
||||
this->layers[i].slices.expolygons = slices[i];
|
||||
}
|
||||
|
||||
// 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> fill = std::auto_ptr<Fill>(Fill::new_from_type(this->config.fill_pattern.value));
|
||||
//fill->bounding_box = this->bb;
|
||||
fill->spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
|
||||
fill->angle = Geometry::deg2rad(this->config.fill_angle.value);
|
||||
FillParams fill_params;
|
||||
fill_params.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.append(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), fill_params);
|
||||
layer.infill.append(polylines, templ);
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate support material
|
||||
@ -154,23 +224,31 @@ SLAPrint::write_svg(const std::string &outputfile) const
|
||||
layer.print_z - (i == 0 ? 0 : this->layers[i-1].print_z)
|
||||
);
|
||||
|
||||
const ExPolygons &slices = layer.slices.expolygons;
|
||||
for (ExPolygons::const_iterator it = slices.begin(); it != slices.end(); ++it) {
|
||||
std::string pd;
|
||||
Polygons pp = *it;
|
||||
for (Polygons::const_iterator mp = pp.begin(); mp != pp.end(); ++mp) {
|
||||
std::ostringstream d;
|
||||
d << "M ";
|
||||
for (Points::const_iterator p = mp->points.begin(); p != mp->points.end(); ++p) {
|
||||
d << unscale(p->x) - this->bb.min.x << " ";
|
||||
d << size.y - (unscale(p->y) - this->bb.min.y) << " "; // mirror Y coordinates as SVG uses downwards Y
|
||||
}
|
||||
d << "z";
|
||||
pd += d.str() + " ";
|
||||
if (layer.solid) {
|
||||
const ExPolygons &slices = layer.slices.expolygons;
|
||||
for (ExPolygons::const_iterator it = slices.begin(); it != slices.end(); ++it) {
|
||||
std::string pd = this->_SVG_path_d(*it);
|
||||
|
||||
fprintf(f,"\t\t<path d=\"%s\" style=\"fill: %s; stroke: %s; stroke-width: %s; fill-type: evenodd\" slic3r:area=\"%0.4f\" />\n",
|
||||
pd.c_str(), "white", "black", "0", unscale(unscale(it->area()))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Solid infill.
|
||||
const ExPolygons &solid_infill = layer.solid_infill.expolygons;
|
||||
for (ExPolygons::const_iterator it = solid_infill.begin(); it != solid_infill.end(); ++it) {
|
||||
std::string pd = this->_SVG_path_d(*it);
|
||||
|
||||
fprintf(f,"\t\t<path d=\"%s\" style=\"fill: %s; stroke: %s; stroke-width: %s; fill-type: evenodd\" slic3r:type=\"infill\" />\n",
|
||||
pd.c_str(), "white", "black", "0"
|
||||
);
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
fprintf(f,"\t\t<path d=\"%s\" style=\"fill: %s; stroke: %s; stroke-width: %s; fill-type: evenodd\" slic3r:area=\"%0.4f\" />\n",
|
||||
pd.c_str(), "white", "black", "0", unscale(unscale(it->area()))
|
||||
);
|
||||
}
|
||||
|
||||
// don't print support material in raft layers
|
||||
@ -206,4 +284,28 @@ SLAPrint::sm_pillars_radius() const
|
||||
return radius;
|
||||
}
|
||||
|
||||
std::string
|
||||
SLAPrint::_SVG_path_d(const Polygon &polygon) const
|
||||
{
|
||||
const Sizef3 size = this->bb.size();
|
||||
std::ostringstream d;
|
||||
d << "M ";
|
||||
for (Points::const_iterator p = polygon.points.begin(); p != polygon.points.end(); ++p) {
|
||||
d << unscale(p->x) - this->bb.min.x << " ";
|
||||
d << size.y - (unscale(p->y) - this->bb.min.y) << " "; // mirror Y coordinates as SVG uses downwards Y
|
||||
}
|
||||
d << "z";
|
||||
return d.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
SLAPrint::_SVG_path_d(const ExPolygon &expolygon) const
|
||||
{
|
||||
std::string pd;
|
||||
const Polygons pp = expolygon;
|
||||
for (Polygons::const_iterator mp = pp.begin(); mp != pp.end(); ++mp)
|
||||
pd += this->_SVG_path_d(*mp) + " ";
|
||||
return pd;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,14 @@ class SLAPrint
|
||||
class Layer {
|
||||
public:
|
||||
ExPolygonCollection slices;
|
||||
ExtrusionEntityCollection perimeters;
|
||||
ExtrusionEntityCollection infill;
|
||||
ExPolygonCollection solid_infill;
|
||||
float slice_z, print_z;
|
||||
bool solid;
|
||||
|
||||
Layer(float _slice_z, float _print_z) : slice_z(_slice_z), print_z(_print_z) {};
|
||||
Layer(float _slice_z, float _print_z)
|
||||
: slice_z(_slice_z), print_z(_print_z), solid(true) {};
|
||||
};
|
||||
std::vector<Layer> layers;
|
||||
|
||||
@ -41,6 +46,8 @@ class SLAPrint
|
||||
BoundingBoxf3 bb;
|
||||
|
||||
coordf_t sm_pillars_radius() const;
|
||||
std::string _SVG_path_d(const Polygon &polygon) const;
|
||||
std::string _SVG_path_d(const ExPolygon &expolygon) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,16 +18,19 @@
|
||||
DynamicPrintConfig* config()
|
||||
%code%{ RETVAL = new DynamicPrintConfig; RETVAL->apply(THIS->config); %};
|
||||
|
||||
ExPolygons layer_slices(size_t i)
|
||||
%code%{ RETVAL = THIS->layers[i].slices; %};
|
||||
ExPolygons layer_solid_infill(size_t i)
|
||||
%code%{ RETVAL = THIS->layers[i].solid_infill.expolygons; %};
|
||||
Ref<ExtrusionEntityCollection> layer_perimeters(size_t i)
|
||||
%code%{ RETVAL = &THIS->layers[i].perimeters; %};
|
||||
Ref<ExtrusionEntityCollection> layer_infill(size_t i)
|
||||
%code%{ RETVAL = &THIS->layers[i].infill; %};
|
||||
bool layer_solid(size_t i)
|
||||
%code%{ RETVAL = THIS->layers[i].solid; %};
|
||||
|
||||
%{
|
||||
|
||||
ExPolygons
|
||||
SLAPrint::slices(i)
|
||||
size_t i;
|
||||
CODE:
|
||||
RETVAL = THIS->layers[i].slices;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
std::vector<double>
|
||||
SLAPrint::heights()
|
||||
CODE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user