mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-11-02 20:51:23 -07:00
Incomplete work for refactoring regions and flows
This commit is contained in:
parent
231bffa99b
commit
beb1baa096
13 changed files with 297 additions and 148 deletions
|
|
@ -3,6 +3,7 @@ use Moo;
|
|||
|
||||
use List::Util qw(sum first);
|
||||
use Slic3r::ExtrusionPath ':roles';
|
||||
use Slic3r::Flow ':roles';
|
||||
use Slic3r::Geometry qw(PI A B scale unscale chained_path points_coincide);
|
||||
use Slic3r::Geometry::Clipper qw(union_ex diff_ex intersection_ex
|
||||
offset offset2 offset2_ex union_pt diff intersection
|
||||
|
|
@ -17,10 +18,6 @@ has 'layer' => (
|
|||
handles => [qw(id slice_z print_z height flow config)],
|
||||
);
|
||||
has 'region' => (is => 'ro', required => 1, handles => [qw(extruders)]);
|
||||
has 'perimeter_flow' => (is => 'rw');
|
||||
has 'infill_flow' => (is => 'rw');
|
||||
has 'solid_infill_flow' => (is => 'rw');
|
||||
has 'top_infill_flow' => (is => 'rw');
|
||||
has 'infill_area_threshold' => (is => 'lazy');
|
||||
has 'overhang_width' => (is => 'lazy');
|
||||
|
||||
|
|
@ -40,43 +37,26 @@ has 'perimeters' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collect
|
|||
# ordered collection of extrusion paths to fill surfaces
|
||||
has 'fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
|
||||
|
||||
sub BUILD {
|
||||
my $self = shift;
|
||||
$self->_update_flows;
|
||||
}
|
||||
|
||||
sub _trigger_layer {
|
||||
my $self = shift;
|
||||
$self->_update_flows;
|
||||
}
|
||||
|
||||
sub _update_flows {
|
||||
my $self = shift;
|
||||
return if !$self->region;
|
||||
|
||||
if ($self->id == 0) {
|
||||
for (qw(perimeter infill solid_infill top_infill)) {
|
||||
my $method = "${_}_flow";
|
||||
$self->$method
|
||||
($self->region->first_layer_flows->{$_} || $self->region->flows->{$_});
|
||||
}
|
||||
} else {
|
||||
$self->perimeter_flow($self->region->flows->{perimeter});
|
||||
$self->infill_flow($self->region->flows->{infill});
|
||||
$self->solid_infill_flow($self->region->flows->{solid_infill});
|
||||
$self->top_infill_flow($self->region->flows->{top_infill});
|
||||
}
|
||||
}
|
||||
|
||||
sub _build_overhang_width {
|
||||
my $self = shift;
|
||||
my $threshold_rad = PI/2 - atan2($self->perimeter_flow->width / $self->height / 2, 1);
|
||||
my $threshold_rad = PI/2 - atan2($self->flow(FLOW_ROLE_PERIMETER)->width / $self->height / 2, 1);
|
||||
return scale($self->height * ((cos $threshold_rad) / (sin $threshold_rad)));
|
||||
}
|
||||
|
||||
sub _build_infill_area_threshold {
|
||||
my $self = shift;
|
||||
return $self->solid_infill_flow->scaled_spacing ** 2;
|
||||
return $self->flow(FLOW_ROLE_SOLID_INFILL)->scaled_spacing ** 2;
|
||||
}
|
||||
|
||||
sub flow {
|
||||
my ($self, $role, $bridge, $width) = @_;
|
||||
return $self->region->flow(
|
||||
$role,
|
||||
$self->layer->height,
|
||||
$bridge // 0,
|
||||
$self->layer->id == 0,
|
||||
$width,
|
||||
);
|
||||
}
|
||||
|
||||
# build polylines from lines
|
||||
|
|
@ -145,10 +125,11 @@ sub _merge_loops {
|
|||
sub make_perimeters {
|
||||
my $self = shift;
|
||||
|
||||
my $pwidth = $self->perimeter_flow->scaled_width;
|
||||
my $pspacing = $self->perimeter_flow->scaled_spacing;
|
||||
my $ispacing = $self->solid_infill_flow->scaled_spacing;
|
||||
my $gap_area_threshold = $self->perimeter_flow->scaled_width ** 2;
|
||||
my $perimeter_flow = $self->flow(FLOW_ROLE_PERIMETER);
|
||||
my $pwidth = $perimeter_flow->scaled_width;
|
||||
my $pspacing = $perimeter_flow->scaled_spacing;
|
||||
my $ispacing = $self->flow(FLOW_ROLE_SOLID_INFILL)->scaled_spacing;
|
||||
my $gap_area_threshold = $pwidth ** 2;
|
||||
|
||||
$self->perimeters->clear;
|
||||
$self->fill_surfaces->clear;
|
||||
|
|
@ -284,7 +265,7 @@ sub make_perimeters {
|
|||
push @loops, Slic3r::ExtrusionLoop->new(
|
||||
polygon => $polygon,
|
||||
role => $role,
|
||||
flow_spacing => $self->perimeter_flow->spacing,
|
||||
flow_spacing => $perimeter_flow->spacing,
|
||||
);
|
||||
}
|
||||
return @loops;
|
||||
|
|
@ -311,7 +292,7 @@ sub make_perimeters {
|
|||
next if $p->length <= $pspacing * 2;
|
||||
my %params = (
|
||||
role => EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
flow_spacing => $self->perimeter_flow->spacing,
|
||||
flow_spacing => $perimeter_flow->spacing,
|
||||
);
|
||||
push @paths, $p->isa('Slic3r::Polygon')
|
||||
? Slic3r::ExtrusionLoop->new(polygon => $p, %params)
|
||||
|
|
@ -345,10 +326,10 @@ sub _fill_gaps {
|
|||
# we could try with 1.5*$w for example, but that doesn't work well for zigzag fill
|
||||
# because it tends to create very sparse points along the gap when the infill direction
|
||||
# is not parallel to the gap (1.5*$w thus may only work well with a straight line)
|
||||
my $w = $self->perimeter_flow->width;
|
||||
my $w = $self->flow(FLOW_ROLE_PERIMETER)->width;
|
||||
my @widths = ($w, 0.4 * $w); # worth trying 0.2 too?
|
||||
foreach my $width (@widths) {
|
||||
my $flow = $self->perimeter_flow->clone(width => $width);
|
||||
my $flow = $self->flow(FLOW_ROLE_PERIMETER, 0, $width);
|
||||
|
||||
# extract the gaps having this width
|
||||
my @this_width = map @{$_->offset_ex(+0.5*$flow->scaled_width)},
|
||||
|
|
@ -499,7 +480,10 @@ sub process_external_surfaces {
|
|||
sub _detect_bridge_direction {
|
||||
my ($self, $expolygon, $lower_layer) = @_;
|
||||
|
||||
my $grown = $expolygon->offset_ex(+$self->perimeter_flow->scaled_width);
|
||||
my $perimeter_flow = $self->flow(FLOW_ROLE_PERIMETER);
|
||||
my $infill_flow = $self->flow(FLOW_ROLE_INFILL);
|
||||
|
||||
my $grown = $expolygon->offset_ex(+$perimeter_flow->scaled_width);
|
||||
my @lower = @{$lower_layer->slices}; # expolygons
|
||||
|
||||
# detect what edges lie on lower slices
|
||||
|
|
@ -554,7 +538,7 @@ sub _detect_bridge_direction {
|
|||
}
|
||||
} elsif (@edges) {
|
||||
# inset the bridge expolygon; we'll use this one to clip our test lines
|
||||
my $inset = $expolygon->offset_ex($self->infill_flow->scaled_width);
|
||||
my $inset = $expolygon->offset_ex($infill_flow->scaled_width);
|
||||
|
||||
# detect anchors as intersection between our bridge expolygon and the lower slices
|
||||
my $anchors = intersection_ex(
|
||||
|
|
@ -568,7 +552,7 @@ sub _detect_bridge_direction {
|
|||
# endpoints within anchors
|
||||
my %directions = (); # angle => score
|
||||
my $angle_increment = PI/36; # 5°
|
||||
my $line_increment = $self->infill_flow->scaled_width;
|
||||
my $line_increment = $infill_flow->scaled_width;
|
||||
for (my $angle = 0; $angle <= PI; $angle += $angle_increment) {
|
||||
# rotate everything - the center point doesn't matter
|
||||
$_->rotate($angle, [0,0]) for @$inset, @$anchors;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue