Refactored configuration handling.

Slic3r::Config is now an object. Multiple partial config objects are used throughout the codebase as local repositories, then merged and serialized when necessary.
This commit is contained in:
Alessandro Ranellucci 2012-07-27 21:13:03 +02:00
parent f0579e59bd
commit 7e34244b05
23 changed files with 918 additions and 833 deletions

View file

@ -20,7 +20,7 @@ has 'slice_z' => (is => 'lazy');
has 'print_z' => (is => 'lazy');
has 'height' => (is => 'lazy');
has 'flow' => (is => 'lazy');
has 'perimeters_flow' => (is => 'lazy');
has 'perimeter_flow' => (is => 'lazy');
has 'infill_flow' => (is => 'lazy');
# collection of spare segments generated by slicing the original geometry;
@ -61,21 +61,21 @@ sub _build_slice_z {
my $self = shift;
if ($self->id == 0) {
return $Slic3r::_first_layer_height / 2 / $Slic3r::scaling_factor;
return $Slic3r::Config->get_value('first_layer_height') / 2 / &Slic3r::SCALING_FACTOR;
}
return ($Slic3r::_first_layer_height + (($self->id-1) * $Slic3r::layer_height) + ($Slic3r::layer_height/2))
/ $Slic3r::scaling_factor; #/
return ($Slic3r::Config->get_value('first_layer_height') + (($self->id-1) * $Slic3r::Config->layer_height) + ($Slic3r::Config->layer_height/2))
/ &Slic3r::SCALING_FACTOR; #/
}
# Z used for printing
sub _build_print_z {
my $self = shift;
return ($Slic3r::_first_layer_height + ($self->id * $Slic3r::layer_height)) / $Slic3r::scaling_factor;
return ($Slic3r::Config->get_value('first_layer_height') + ($self->id * $Slic3r::Config->layer_height)) / &Slic3r::SCALING_FACTOR;
}
sub _build_height {
my $self = shift;
return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height;
return $self->id == 0 ? $Slic3r::Config->get_value('first_layer_height') : $Slic3r::Config->layer_height;
}
sub _build_flow {
@ -85,11 +85,11 @@ sub _build_flow {
: $Slic3r::flow;
}
sub _build_perimeters_flow {
sub _build_perimeter_flow {
my $self = shift;
return $self->id == 0 && $Slic3r::first_layer_flow
? $Slic3r::first_layer_flow
: $Slic3r::perimeters_flow;
: $Slic3r::perimeter_flow;
}
sub _build_infill_flow {
@ -120,7 +120,7 @@ sub make_surfaces {
# the contours must be offsetted by half extrusion width inwards
{
my $distance = scale $self->perimeters_flow->width / 2;
my $distance = scale $self->perimeter_flow->width / 2;
my @surfaces = @{$self->slices};
@{$self->slices} = ();
foreach my $surface (@surfaces) {
@ -141,10 +141,10 @@ sub make_surfaces {
$self->thin_walls([]);
if (@$diff) {
my $area_threshold = scale($self->perimeters_flow->spacing) ** 2;
my $area_threshold = scale($self->perimeter_flow->spacing) ** 2;
@$diff = grep $_->area > ($area_threshold), @$diff;
@{$self->thin_walls} = map $_->medial_axis(scale $self->perimeters_flow->width), @$diff;
@{$self->thin_walls} = map $_->medial_axis(scale $self->perimeter_flow->width), @$diff;
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
}
@ -163,7 +163,7 @@ sub make_perimeters {
my $self = shift;
Slic3r::debugf "Making perimeters for layer %d\n", $self->id;
my $gap_area_threshold = scale($self->perimeters_flow->width)** 2;
my $gap_area_threshold = scale($self->perimeter_flow->width)** 2;
# this array will hold one arrayref per original surface (island);
# each item of this arrayref is an arrayref representing a depth (from outer
@ -197,7 +197,7 @@ sub make_perimeters {
if (0) {
foreach my $hole ($last_offsets[0]->holes) {
my $circumference = abs($hole->length);
next unless $circumference <= $Slic3r::small_perimeter_length;
next unless $circumference <= &Slic3r::SMALL_PERIMETER_LENGTH;
# this compensation only works for circular holes, while it would
# overcompensate for hexagons and other shapes having straight edges.
# so we require a minimum number of vertices.
@ -205,8 +205,8 @@ sub make_perimeters {
# revert the compensation done in make_surfaces() and get the actual radius
# of the hole
my $radius = ($circumference / PI / 2) - scale $self->perimeters_flow->spacing/2;
my $new_radius = (scale($self->perimeters_flow->width) + sqrt((scale($self->perimeters_flow->width)**2) + (4*($radius**2)))) / 2;
my $radius = ($circumference / PI / 2) - scale $self->perimeter_flow->spacing/2;
my $new_radius = (scale($self->perimeter_flow->width) + sqrt((scale($self->perimeter_flow->width)**2) + (4*($radius**2)))) / 2;
# holes are always turned to contours, so reverse point order before and after
$hole->reverse;
my @offsetted = $hole->offset(+ ($new_radius - $radius));
@ -219,7 +219,7 @@ sub make_perimeters {
my @gaps = ();
# generate perimeters inwards
my $loop_number = $Slic3r::perimeters + ($surface->additional_inner_perimeters || 0);
my $loop_number = $Slic3r::Config->perimeters + ($surface->additional_inner_perimeters || 0);
push @perimeters, [];
for (my $loop = 0; $loop < $loop_number; $loop++) {
# offsetting a polygon can result in one or many offset polygons
@ -241,19 +241,19 @@ sub make_perimeters {
push @{ $perimeters[-1] }, [@last_offsets];
# offset distance for inner loops
$distance = scale $self->perimeters_flow->spacing;
$distance = scale $self->perimeter_flow->spacing;
}
# create one more offset to be used as boundary for fill
{
my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets;
$_->simplify(scale $Slic3r::resolution) for @fill_boundaries;
$_->simplify(scale &Slic3r::RESOLUTION) for @fill_boundaries;
push @{ $self->surfaces }, @fill_boundaries;
# detect the small gaps that we need to treat like thin polygons,
# thus generating the skeleton and using it to fill them
push @{ $self->thin_fills },
map $_->medial_axis(scale $self->perimeters_flow->width),
map $_->medial_axis(scale $self->perimeter_flow->width),
@gaps;
Slic3r::debugf " %d gaps filled\n", scalar @{ $self->thin_fills }
if @{ $self->thin_fills };
@ -323,7 +323,7 @@ sub make_perimeters {
my @thin_paths = ();
my %properties = (
role => EXTR_ROLE_PERIMETER,
flow_spacing => $self->perimeters_flow->spacing,
flow_spacing => $self->perimeter_flow->spacing,
);
for (@{ $self->thin_walls }) {
push @thin_paths, $_->isa('Slic3r::Polygon')
@ -339,11 +339,11 @@ sub _add_perimeter {
my $self = shift;
my ($polygon, $role) = @_;
return unless $polygon->is_printable($self->perimeters_flow->width);
return unless $polygon->is_printable($self->perimeter_flow->width);
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->pack(
polygon => $polygon,
role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
flow_spacing => $self->perimeters_flow->spacing,
role => (abs($polygon->length) <= &Slic3r::SMALL_PERIMETER_LENGTH) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
flow_spacing => $self->perimeter_flow->spacing,
);
}
@ -354,18 +354,18 @@ sub prepare_fill_surfaces {
# if no solid layers are requested, turn top/bottom surfaces to internal
# note that this modifies $self->surfaces in place
if ($Slic3r::solid_layers == 0) {
if ($Slic3r::Config->solid_layers == 0) {
$_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type != S_TYPE_INTERNAL, @surfaces;
}
# if hollow object is requested, remove internal surfaces
if ($Slic3r::fill_density == 0) {
if ($Slic3r::Config->fill_density == 0) {
@surfaces = grep $_->surface_type != S_TYPE_INTERNAL, @surfaces;
}
# turn too small internal regions into solid regions
{
my $min_area = ((7 * $self->infill_flow->spacing / $Slic3r::scaling_factor)**2) * PI;
my $min_area = ((7 * $self->infill_flow->spacing / &Slic3r::SCALING_FACTOR)**2) * PI;
my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @surfaces;
$_->surface_type(S_TYPE_INTERNALSOLID) for @small;
Slic3r::debugf "identified %d small surfaces at layer %d\n", scalar(@small), $self->id if @small > 0;
@ -379,7 +379,7 @@ sub process_bridges {
my $self = shift;
# no bridges are possible if we have no internal surfaces
return if $Slic3r::fill_density == 0;
return if $Slic3r::Config->fill_density == 0;
my @bridges = ();