mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-29 19:53:44 -06: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
|
|
@ -1,48 +1,73 @@
|
|||
package Slic3r::Flow;
|
||||
use Moo;
|
||||
|
||||
use Slic3r::Geometry qw(PI scale);
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(FLOW_ROLE_PERIMETER FLOW_ROLE_INFILL FLOW_ROLE_SOLID_INFILL FLOW_ROLE_TOP_SOLID_INFILL
|
||||
FLOW_ROLE_SUPPORT_MATERIAL FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE);
|
||||
our %EXPORT_TAGS = (roles => \@EXPORT_OK);
|
||||
|
||||
has 'nozzle_diameter' => (is => 'ro', required => 1);
|
||||
has 'layer_height' => (is => 'ro', required => 1);
|
||||
has 'role' => (is => 'ro', default => sub { '' });
|
||||
use Slic3r::Geometry qw(PI);
|
||||
|
||||
has 'width' => (is => 'rwp', builder => 1);
|
||||
has 'spacing' => (is => 'lazy');
|
||||
has 'width' => (is => 'ro');
|
||||
has 'spacing' => (is => 'ro');
|
||||
has 'scaled_width' => (is => 'lazy');
|
||||
has 'scaled_spacing' => (is => 'lazy');
|
||||
|
||||
sub BUILD {
|
||||
my $self = shift;
|
||||
use constant FLOW_ROLE_PERIMETER => 1;
|
||||
use constant FLOW_ROLE_INFILL => 2;
|
||||
use constant FLOW_ROLE_SOLID_INFILL => 3;
|
||||
use constant FLOW_ROLE_TOP_SOLID_INFILL => 4;
|
||||
use constant FLOW_ROLE_SUPPORT_MATERIAL => 5;
|
||||
use constant FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE => 6;
|
||||
|
||||
sub BUILDARGS {
|
||||
my ($self, %args) = @_;
|
||||
|
||||
if ($self->width =~ /^(\d+(?:\.\d+)?)%$/) {
|
||||
$self->_set_width($self->layer_height * $1 / 100);
|
||||
# the constructor can take two sets of arguments:
|
||||
# - width (only absolute value), spacing
|
||||
# - width (abs/%/0), role, nozzle_diameter, layer_height, bridge_flow_ratio
|
||||
# (if bridge_flow_ratio == 0, we return a non-bridge flow)
|
||||
|
||||
if (exists $args{role}) {
|
||||
if ($args{width} eq '0') {
|
||||
$args{width} = $self->_width(@args{qw(role nozzle_diameter layer_height bridge_flow_ratio)});
|
||||
} elsif ($args{width} =~ /^(\d+(?:\.\d+)?)%$/) {
|
||||
$args{width} = $args{layer_height} * $1 / 100;
|
||||
}
|
||||
$args{spacing} = $self->_spacing(@args{qw(width nozzle_diameter layer_height bridge_flow_ratio)});
|
||||
%args = @args{qw(width spacing)};
|
||||
}
|
||||
$self->_set_width($self->_build_width) if $self->width == 0; # auto
|
||||
|
||||
return {%args};
|
||||
}
|
||||
|
||||
sub _build_width {
|
||||
my $self = shift;
|
||||
sub _width {
|
||||
my ($self, $role, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_;
|
||||
|
||||
if ($bridge_flow_ratio > 0) {
|
||||
return sqrt($bridge_flow_ratio * ($nozzle_diameter**2));
|
||||
}
|
||||
|
||||
# here we calculate a sane default by matching the flow speed (at the nozzle) and the feed rate
|
||||
my $volume = ($self->nozzle_diameter**2) * PI/4;
|
||||
my $shape_threshold = $self->nozzle_diameter * $self->layer_height + ($self->layer_height**2) * PI/4;
|
||||
my $volume = ($nozzle_diameter**2) * PI/4;
|
||||
my $shape_threshold = $nozzle_diameter * $layer_height + ($layer_height**2) * PI/4;
|
||||
my $width;
|
||||
if ($volume >= $shape_threshold) {
|
||||
# rectangle with semicircles at the ends
|
||||
$width = (($self->nozzle_diameter**2) * PI + ($self->layer_height**2) * (4 - PI)) / (4 * $self->layer_height);
|
||||
$width = (($nozzle_diameter**2) * PI + ($layer_height**2) * (4 - PI)) / (4 * $layer_height);
|
||||
} else {
|
||||
# rectangle with squished semicircles at the ends
|
||||
$width = $self->nozzle_diameter * ($self->nozzle_diameter/$self->layer_height - 4/PI + 1);
|
||||
$width = $nozzle_diameter * ($nozzle_diameter/$layer_height - 4/PI + 1);
|
||||
}
|
||||
|
||||
my $min = $self->nozzle_diameter * 1.05;
|
||||
my $min = $nozzle_diameter * 1.05;
|
||||
my $max;
|
||||
if ($self->role eq 'perimeter' || $self->role eq 'support_material') {
|
||||
$min = $max = $self->nozzle_diameter;
|
||||
} elsif ($self->role ne 'infill') {
|
||||
if ($role == FLOW_ROLE_PERIMETER || $role == FLOW_ROLE_SUPPORT_MATERIAL) {
|
||||
$min = $max = $nozzle_diameter;
|
||||
} elsif ($role != FLOW_ROLE_INFILL) {
|
||||
# do not limit width for sparse infill so that we use full native flow for it
|
||||
$max = $self->nozzle_diameter * 1.7;
|
||||
$max = $nozzle_diameter * 1.7;
|
||||
}
|
||||
$width = $max if defined($max) && $width > $max;
|
||||
$width = $min if $width < $min;
|
||||
|
|
@ -50,59 +75,41 @@ sub _build_width {
|
|||
return $width;
|
||||
}
|
||||
|
||||
sub _build_spacing {
|
||||
my $self = shift;
|
||||
sub _spacing {
|
||||
my ($self, $width, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_;
|
||||
|
||||
if ($bridge_flow_ratio > 0) {
|
||||
return $width + 0.05;
|
||||
}
|
||||
|
||||
my $min_flow_spacing;
|
||||
if ($self->width >= ($self->nozzle_diameter + $self->layer_height)) {
|
||||
if ($width >= ($nozzle_diameter + $layer_height)) {
|
||||
# rectangle with semicircles at the ends
|
||||
$min_flow_spacing = $self->width - $self->layer_height * (1 - PI/4);
|
||||
$min_flow_spacing = $width - $layer_height * (1 - PI/4);
|
||||
} else {
|
||||
# rectangle with shrunk semicircles at the ends
|
||||
$min_flow_spacing = $self->nozzle_diameter * (1 - PI/4) + $self->width * PI/4;
|
||||
$min_flow_spacing = $nozzle_diameter * (1 - PI/4) + $width * PI/4;
|
||||
}
|
||||
return $self->width - &Slic3r::OVERLAP_FACTOR * ($self->width - $min_flow_spacing);
|
||||
return $width - &Slic3r::OVERLAP_FACTOR * ($width - $min_flow_spacing);
|
||||
}
|
||||
|
||||
sub clone {
|
||||
my $self = shift;
|
||||
|
||||
return (ref $self)->new(
|
||||
nozzle_diameter => $self->nozzle_diameter,
|
||||
layer_height => $self->layer_height,
|
||||
@_,
|
||||
width => $self->width,
|
||||
spacing => $self->spacing,
|
||||
);
|
||||
}
|
||||
|
||||
sub _build_scaled_width {
|
||||
my $self = shift;
|
||||
return scale $self->width;
|
||||
return Slic3r::Geometry::scale($self->width);
|
||||
}
|
||||
|
||||
sub _build_scaled_spacing {
|
||||
my $self = shift;
|
||||
return scale $self->spacing;
|
||||
}
|
||||
|
||||
|
||||
package Slic3r::Flow::Bridge;
|
||||
use Moo;
|
||||
extends 'Slic3r::Flow';
|
||||
|
||||
# layer_height is not required in this case
|
||||
has '+layer_height' => (is => 'ro', required => 0);
|
||||
has 'bridge_flow_ratio' => (is => 'ro', required => 1);
|
||||
|
||||
use Slic3r::Geometry qw(PI);
|
||||
|
||||
sub _build_width {
|
||||
my $self = shift;
|
||||
return sqrt($self->bridge_flow_ratio * ($self->nozzle_diameter**2));
|
||||
}
|
||||
|
||||
sub _build_spacing {
|
||||
my $self = shift;
|
||||
return $self->width + 0.05;
|
||||
return Slic3r::Geometry::scale($self->spacing);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue