Improvements for bottom and top surfaces perimeters
This commit is contained in:
parent
a7d5e643ae
commit
34681af6ae
@ -4,6 +4,7 @@ use Moo;
|
|||||||
use Math::Clipper ':all';
|
use Math::Clipper ':all';
|
||||||
use Math::ConvexHull qw(convex_hull);
|
use Math::ConvexHull qw(convex_hull);
|
||||||
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines);
|
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines);
|
||||||
|
use Slic3r::Geometry::Clipper qw(union_ex);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
use constant PI => 4 * atan2(1, 1);
|
use constant PI => 4 * atan2(1, 1);
|
||||||
@ -77,7 +78,7 @@ has 'fills' => (
|
|||||||
|
|
||||||
sub z {
|
sub z {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->id * $Slic3r::layer_height / $Slic3r::resolution;
|
return ($self->id * $Slic3r::layer_height + $Slic3r::layer_height/2) / $Slic3r::resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub add_surface {
|
sub add_surface {
|
||||||
@ -209,21 +210,25 @@ sub make_surfaces {
|
|||||||
push @polylines, [@points];
|
push @polylines, [@points];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#use Slic3r::SVG;
|
||||||
#Slic3r::SVG::output(undef, "polylines.svg",
|
#Slic3r::SVG::output(undef, "polylines.svg",
|
||||||
# polylines => [ @polylines ],
|
# polylines => [ @polylines ],
|
||||||
#);
|
#);
|
||||||
|
#exit if $self->id == 30;
|
||||||
#@polylines = map Slic3r::Polyline::Closed->cast($_), @polylines;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
my $clipper = Math::Clipper->new;
|
my $expolygons = union_ex([ @polylines ]);
|
||||||
$clipper->add_subject_polygons([ @polylines ]);
|
|
||||||
my $expolygons = $clipper->ex_execute(CT_UNION, PFT_NONZERO, PFT_NONZERO);
|
|
||||||
|
|
||||||
Slic3r::debugf " %d surface(s) detected from %d polylines\n",
|
Slic3r::debugf " %d surface(s) detected from %d polylines\n",
|
||||||
scalar(@$expolygons), scalar(@polylines);
|
scalar(@$expolygons), scalar(@polylines);
|
||||||
push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons;
|
push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#use Slic3r::SVG;
|
||||||
|
#Slic3r::SVG::output(undef, "surfaces.svg",
|
||||||
|
# polygons => [ map $_->contour->p, @{$self->surfaces} ],
|
||||||
|
# red_polygons => [ map $_->p, map @{$_->holes}, @{$self->surfaces} ],
|
||||||
|
#);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub remove_small_surfaces {
|
sub remove_small_surfaces {
|
||||||
|
@ -2,6 +2,7 @@ package Slic3r::Print;
|
|||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use Math::Clipper ':all';
|
use Math::Clipper ':all';
|
||||||
|
use Slic3r::Geometry::Clipper qw(diff_ex union_ex);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
use constant X => 0;
|
use constant X => 0;
|
||||||
@ -83,10 +84,10 @@ sub detect_surfaces_type {
|
|||||||
# prepare a reusable subroutine to make surface differences
|
# prepare a reusable subroutine to make surface differences
|
||||||
my $surface_difference = sub {
|
my $surface_difference = sub {
|
||||||
my ($subject_surfaces, $clip_surfaces, $result_type) = @_;
|
my ($subject_surfaces, $clip_surfaces, $result_type) = @_;
|
||||||
$clipper->clear;
|
my $expolygons = diff_ex(
|
||||||
$clipper->add_subject_polygons([ map $_->p, @$subject_surfaces ]);
|
[ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$subject_surfaces ],
|
||||||
$clipper->add_clip_polygons([ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$clip_surfaces ]);
|
[ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$clip_surfaces ],
|
||||||
my $expolygons = $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO);
|
);
|
||||||
return grep $_->contour->is_printable,
|
return grep $_->contour->is_printable,
|
||||||
map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),
|
map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),
|
||||||
@$expolygons;
|
@$expolygons;
|
||||||
@ -94,6 +95,7 @@ sub detect_surfaces_type {
|
|||||||
|
|
||||||
for (my $i = 0; $i < $self->layer_count; $i++) {
|
for (my $i = 0; $i < $self->layer_count; $i++) {
|
||||||
my $layer = $self->layers->[$i];
|
my $layer = $self->layers->[$i];
|
||||||
|
Slic3r::debugf "Detecting solid surfaces for layer %d\n", $layer->id;
|
||||||
my $upper_layer = $self->layers->[$i+1];
|
my $upper_layer = $self->layers->[$i+1];
|
||||||
my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef;
|
my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef;
|
||||||
|
|
||||||
@ -103,13 +105,24 @@ sub detect_surfaces_type {
|
|||||||
# of current layer and upper one)
|
# of current layer and upper one)
|
||||||
if ($upper_layer) {
|
if ($upper_layer) {
|
||||||
# offset upper layer surfaces by extrusion_width * perimeters
|
# offset upper layer surfaces by extrusion_width * perimeters
|
||||||
my $upper_surfaces = offset(
|
@top = $surface_difference->($layer->surfaces, $upper_layer->surfaces, 'top');
|
||||||
[ map $_->p, @{$upper_layer->surfaces} ],
|
|
||||||
($Slic3r::flow_width / $Slic3r::resolution * $Slic3r::perimeter_offsets),
|
# now check whether each resulting top surfaces is large enough to have its
|
||||||
$Slic3r::resolution * 100,
|
# own perimeters or whether it may be sufficient to use the lower layer's
|
||||||
JT_MITER, 2,
|
# perimeters
|
||||||
);
|
|
||||||
@top = $surface_difference->($layer->surfaces, $upper_surfaces, 'top');
|
# offset upper layer's surfaces
|
||||||
|
my $upper_surfaces_offsetted;
|
||||||
|
{
|
||||||
|
my $distance = $Slic3r::flow_width * ($Slic3r::perimeter_offsets + 1) / $Slic3r::resolution;
|
||||||
|
$upper_surfaces_offsetted = offset([ map $_->p, @{$upper_layer->surfaces} ], $distance, 100, JT_MITER, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@top = grep {
|
||||||
|
my $surface = $_;
|
||||||
|
my $diff = diff_ex([ map $_->p, $surface ], $upper_surfaces_offsetted);
|
||||||
|
@$diff;
|
||||||
|
} @top;
|
||||||
} else {
|
} else {
|
||||||
# if no upper layer, all surfaces of this one are solid
|
# if no upper layer, all surfaces of this one are solid
|
||||||
@top = @{$layer->surfaces};
|
@top = @{$layer->surfaces};
|
||||||
@ -120,6 +133,7 @@ sub detect_surfaces_type {
|
|||||||
# of current layer and lower one)
|
# of current layer and lower one)
|
||||||
if ($lower_layer) {
|
if ($lower_layer) {
|
||||||
@bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom');
|
@bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom');
|
||||||
|
|
||||||
for (@bottom) {
|
for (@bottom) {
|
||||||
$_->contour->merge_continuous_lines;
|
$_->contour->merge_continuous_lines;
|
||||||
$_->contour->remove_acute_vertices;
|
$_->contour->remove_acute_vertices;
|
||||||
@ -135,6 +149,18 @@ sub detect_surfaces_type {
|
|||||||
# red_polygons => [ map $_->p, @{$lower_layer->surfaces} ],
|
# red_polygons => [ map $_->p, @{$lower_layer->surfaces} ],
|
||||||
#);
|
#);
|
||||||
|
|
||||||
|
# offset lower layer's surfaces
|
||||||
|
my $lower_surfaces_offsetted;
|
||||||
|
{
|
||||||
|
my $distance = $Slic3r::flow_width * ($Slic3r::perimeter_offsets + 1) / $Slic3r::resolution;
|
||||||
|
$lower_surfaces_offsetted = offset([ map $_->p, @{$lower_layer->surfaces} ], $distance, 100, JT_MITER, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@bottom = grep {
|
||||||
|
my $surface = $_;
|
||||||
|
my $diff = diff_ex([ map $_->p, $surface ], $lower_surfaces_offsetted);
|
||||||
|
@$diff;
|
||||||
|
} @bottom;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
# if no lower layer, all surfaces of this one are solid
|
# if no lower layer, all surfaces of this one are solid
|
||||||
|
@ -46,7 +46,7 @@ sub output {
|
|||||||
my $g = $svg->group(
|
my $g = $svg->group(
|
||||||
style => {
|
style => {
|
||||||
'stroke-width' => 2,
|
'stroke-width' => 2,
|
||||||
'stroke' => $colour || 'black',
|
'stroke' => 'black' || $colour || 'black',
|
||||||
'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
|
'fill' => ($type !~ /polygons/ ? 'none' : ($colour || 'grey')),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -58,6 +58,7 @@ sub output {
|
|||||||
);
|
);
|
||||||
$g->$method(
|
$g->$method(
|
||||||
%$path,
|
%$path,
|
||||||
|
'marker-end' => "url(#endArrow)",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user