Refactoring: use Slic3r::Geometry::BoundingBox objects everywhere

xs
Alessandro Ranellucci 2013-06-16 12:21:25 +02:00
parent 07407e5dbd
commit ac4a0bcdd8
20 changed files with 105 additions and 127 deletions

View File

@ -142,18 +142,7 @@ sub point_on_segment {
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::bounding_box($self->contour);
}
sub bounding_box_polygon {
my $self = shift;
my @bb = $self->bounding_box;
return Slic3r::Polygon->new([
[ $bb[0], $bb[1] ],
[ $bb[2], $bb[1] ],
[ $bb[2], $bb[3] ],
[ $bb[0], $bb[3] ],
]);
return $self->contour->bounding_box;
}
sub clip_line {

View File

@ -40,7 +40,7 @@ sub filler {
}
$self->fillers->{$filler} ||= $FillTypes{$filler}->new(
bounding_box => [ $self->object->bounding_box ],
bounding_box => $self->object->bounding_box,
);
return $self->fillers->{$filler};
}

View File

@ -5,7 +5,7 @@ use Slic3r::Geometry qw(PI);
has 'layer_id' => (is => 'rw');
has 'angle' => (is => 'rw', default => sub { $Slic3r::Config->fill_angle });
has 'bounding_box' => (is => 'ro', required => 1);
has 'bounding_box' => (is => 'ro', required => 1); # Slic3r::Geometry::BoundingBox object
sub angles () { [0, PI/2] }
@ -16,7 +16,7 @@ sub infill_direction {
# set infill angle
my (@rotate, @shift);
$rotate[0] = Slic3r::Geometry::deg2rad($self->angle);
$rotate[1] = Slic3r::Geometry::bounding_box_center($self->bounding_box);
$rotate[1] = $self->bounding_box->center_2D;
@shift = @{$rotate[1]};
if (defined $self->layer_id) {

View File

@ -3,7 +3,7 @@ use Moo;
extends 'Slic3r::Fill::Base';
use Slic3r::Geometry qw(scale unscale X1 X2);
use Slic3r::Geometry qw(scale unscale X);
use Slic3r::Geometry::Clipper qw(offset2 union_pt traverse_pt PFT_EVENODD);
sub fill_surface {
@ -13,7 +13,7 @@ sub fill_surface {
# no rotation is supported for this infill pattern
my $expolygon = $surface->expolygon;
my $bounding_box = [ $expolygon->bounding_box ];
my $bounding_box = $expolygon->bounding_box;
my $min_spacing = scale $params{flow_spacing};
my $distance = $min_spacing / $params{density};
@ -21,7 +21,7 @@ sub fill_surface {
my $flow_spacing = $params{flow_spacing};
if ($params{density} == 1 && !$params{dont_adjust}) {
$distance = $self->adjust_solid_spacing(
width => $bounding_box->[X2] - $bounding_box->[X1],
width => $bounding_box->size->[X],
distance => $distance,
);
$flow_spacing = unscale $distance;

View File

@ -4,7 +4,7 @@ use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::Flowsnake;
use Slic3r::Geometry qw(X X1 X2);
use Slic3r::Geometry qw(X);
# Sorry, this fill is currently broken.
@ -12,7 +12,7 @@ sub process_polyline {
my $self = shift;
my ($polyline, $bounding_box) = @_;
$_->[X] += ($bounding_box->[X1] + $bounding_box->[X2]/2) for @$polyline;
$_->[X] += $bounding_box->center_2D->[X] for @$polyline;
}
1;

View File

@ -5,7 +5,7 @@ extends 'Slic3r::Fill::Base';
has 'cache' => (is => 'rw', default => sub {{}});
use Slic3r::Geometry qw(PI X1 Y1 X2 Y2 X Y scale);
use Slic3r::Geometry qw(PI X Y MIN MAX scale);
use Slic3r::Geometry::Clipper qw(intersection_ex);
sub angles () { [0, PI/3, PI/3*2] }
@ -39,28 +39,28 @@ sub fill_surface {
# adjust actual bounding box to the nearest multiple of our hex pattern
# and align it so that it matches across layers
my $bounding_box = [ @{$self->bounding_box} ]; # clone
$bounding_box->[$_] = 0 for X1, Y1;
my $bounding_box = $self->bounding_box->clone;
$bounding_box->extents->[$_][MIN] = 0 for X, Y;
{
my $bb_polygon = Slic3r::Polygon->new_from_bounding_box($bounding_box);
my $bb_polygon = $bounding_box->polygon;
$bb_polygon->scale(sqrt 2);
$bb_polygon->rotate($rotate_vector->[0][0], $hex_center);
$bounding_box = [ Slic3r::Geometry::bounding_box($bb_polygon) ];
# $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
$bounding_box->[X1] -= $bounding_box->[X1] % $hex_width;
$bounding_box->[Y1] -= $bounding_box->[Y1] % $pattern_height;
$bounding_box = $bb_polygon->bounding_box;
# $bounding_box->y_min and $bounding_box->y_max represent the displacement between new bounding box offset and old one
$bounding_box->extents->[X][MIN] -= $bounding_box->x_min % $hex_width;
$bounding_box->extents->[Y][MAX] -= $bounding_box->y_min % $pattern_height;
}
my @polygons = ();
my $x = $bounding_box->[X1];
while ($x <= $bounding_box->[X2]) {
my $x = $bounding_box->x_min;
while ($x <= $bounding_box->x_max) {
my $p = [];
my @x = ($x + $x_offset, $x + $distance - $x_offset);
for (1..2) {
@$p = reverse @$p; # turn first half upside down
my @p = ();
for (my $y = $bounding_box->[Y1]; $y <= $bounding_box->[Y2]; $y += $y_short + $hex_side + $y_short + $hex_side) {
for (my $y = $bounding_box->x_min; $y <= $bounding_box->y_max; $y += $y_short + $hex_side + $y_short + $hex_side) {
push @$p,
[ $x[1], $y + $y_offset ],
[ $x[0], $y + $y_short - $y_offset ],

View File

@ -27,17 +27,11 @@ sub fill_surface {
$self->rotate_points($expolygon, $rotate_vector);
my $distance_between_lines = scale $params{flow_spacing} / $params{density} * $self->multiplier;
my $bounding_box = [ Slic3r::Geometry::bounding_box([map @$_, @$expolygon]) ];
my $bounding_box_polygon = Slic3r::Polygon->new([
[ $bounding_box->[X1], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y2] ],
[ $bounding_box->[X1], $bounding_box->[Y2] ],
]);
my $bounding_box = $expolygon->bounding_box;
(ref $self) =~ /::([^:]+)$/;
my $path = "Math::PlanePath::$1"->new;
my @n = $self->get_n($path, [map +($_ / $distance_between_lines), @$bounding_box]);
my @n = $self->get_n($path, [ map +($_ / $distance_between_lines), @{$bounding_box->bb} ]);
my $polyline = Slic3r::Polyline->new([
map [ map {$_*$distance_between_lines} $path->n_to_xy($_) ], @n,
@ -47,7 +41,7 @@ sub fill_surface {
$self->process_polyline($polyline, $bounding_box);
my @paths = map $_->clip_with_expolygon($expolygon),
$polyline->clip_with_polygon($bounding_box_polygon);
$polyline->clip_with_polygon($bounding_box->polygon);
if (0) {
require "Slic3r/SVG.pm";

View File

@ -5,7 +5,7 @@ extends 'Slic3r::Fill::Base';
has 'cache' => (is => 'rw', default => sub {{}});
use Slic3r::Geometry qw(X1 Y1 X2 Y2 A B X Y scale unscale scaled_epsilon);
use Slic3r::Geometry qw(A B X Y scale unscale scaled_epsilon);
sub fill_surface {
my $self = shift;
@ -32,26 +32,26 @@ sub fill_surface {
# compute bounding box
my $bounding_box;
{
my $bb_polygon = Slic3r::Polygon->new_from_bounding_box($self->bounding_box);
my $bb_polygon = $self->bounding_box->polygon;
$bb_polygon->scale(sqrt 2);
$self->rotate_points($bb_polygon, $rotate_vector);
$bounding_box = [ $bb_polygon->bounding_box ];
$bounding_box = $bb_polygon->bounding_box;
}
# define flow spacing according to requested density
if ($params{density} == 1 && !$params{dont_adjust}) {
$distance_between_lines = $self->adjust_solid_spacing(
width => $bounding_box->[X2] - $bounding_box->[X1],
width => $bounding_box->size->[X],
distance => $distance_between_lines,
);
$flow_spacing = unscale $distance_between_lines;
}
# generate the basic pattern
my $x = $bounding_box->[X1];
my $x = $bounding_box->x_min;
my @vertical_lines = ();
for (my $i = 0; $x <= $bounding_box->[X2] + scaled_epsilon; $i++) {
my $vertical_line = Slic3r::Line->new([$x, $bounding_box->[Y2]], [$x, $bounding_box->[Y1]]);
for (my $i = 0; $x <= $bounding_box->x_max + scaled_epsilon; $i++) {
my $vertical_line = Slic3r::Line->new([$x, $bounding_box->y_max], [$x, $bounding_box->y_min]);
if ($is_line_pattern && $i % 2) {
$vertical_line->[A][X] += $line_oscillation;
$vertical_line->[B][X] -= $line_oscillation;

View File

@ -7,7 +7,7 @@ use File::Basename qw(basename dirname);
use List::Util qw(max sum first);
use Math::Clipper qw(offset JT_ROUND);
use Math::ConvexHull::MonotoneChain qw(convex_hull);
use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX);
use Slic3r::Geometry qw(X Y Z MIN MAX);
use threads::shared qw(shared_clone);
use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window);
use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE);
@ -765,7 +765,7 @@ sub recenter {
return unless @{$self->{objects}};
# calculate displacement needed to center the print
my @print_bb = Slic3r::Geometry::bounding_box([
my $print_bb = Slic3r::Geometry::BoundingBox->new_from_points([
map {
my $obj = $_;
my $bb = $obj->transformed_bounding_box;
@ -776,9 +776,10 @@ sub recenter {
# $self->{shift} contains the offset in pixels to add to object instances in order to center them
# it is expressed in upwards Y
my $print_size = $print_bb->size;
$self->{shift} = [
$self->to_pixel(-$print_bb[X1]) + ($self->{canvas}->GetSize->GetWidth - $self->to_pixel($print_bb[X2] - $print_bb[X1])) / 2,
$self->to_pixel(-$print_bb[Y1]) + ($self->{canvas}->GetSize->GetHeight - $self->to_pixel($print_bb[Y2] - $print_bb[Y1])) / 2,
$self->to_pixel(-$print_bb->x_min) + ($self->{canvas}->GetSize->GetWidth - $self->to_pixel($print_size->[X])) / 2,
$self->to_pixel(-$print_bb->y_min) + ($self->{canvas}->GetSize->GetHeight - $self->to_pixel($print_size->[Y])) / 2,
];
}

View File

@ -36,7 +36,14 @@ sub bb {
sub polygon {
my $self = shift;
return Slic3r::Polygon->new_from_bounding_box($self->bb);
my $e = $self->extents;
return Slic3r::Polygon->new([
[ $e->[X][MIN], $e->[Y][MIN] ],
[ $e->[X][MAX], $e->[Y][MIN] ],
[ $e->[X][MAX], $e->[Y][MAX] ],
[ $e->[X][MIN], $e->[Y][MAX] ],
]);
}
# note to $self
@ -84,4 +91,24 @@ sub max_point {
return Slic3r::Point->new($self->extents->[X][MAX], $self->extents->[Y][MAX]);
}
sub x_min {
my $self = shift;
return $self->extents->[X][MIN];
}
sub x_max {
my $self = shift;
return $self->extents->[X][MAX];
}
sub y_min {
my $self = shift;
return $self->extents->[Y][MIN];
}
sub y_max {
my $self = shift;
return $self->extents->[Y][MAX];
}
1;

View File

@ -3,7 +3,7 @@ use Moo;
use List::Util qw(sum first);
use Slic3r::ExtrusionPath ':roles';
use Slic3r::Geometry qw(PI X1 X2 Y1 Y2 A B scale chained_path_items points_coincide);
use Slic3r::Geometry qw(PI A B scale chained_path_items points_coincide);
use Slic3r::Geometry::Clipper qw(safety_offset union_ex diff_ex intersection_ex
offset offset2_ex PFT_EVENODD union_pt traverse_pt diff intersection);
use Slic3r::Surface ':types';
@ -557,10 +557,10 @@ sub _detect_bridges {
$_->rotate($angle, [0,0]) for @$inset, @$anchors;
# generate lines in this direction
my $bounding_box = [ Slic3r::Geometry::bounding_box([ map @$_, map @$_, @$anchors ]) ];
my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, @$anchors ]);
my @lines = ();
for (my $x = $bounding_box->[X1]; $x <= $bounding_box->[X2]; $x += $line_increment) {
push @lines, [ [$x, $bounding_box->[Y1]], [$x, $bounding_box->[Y2]] ];
for (my $x = $bounding_box->x_min; $x <= $bounding_box->x_max; $x += $line_increment) {
push @lines, [ [$x, $bounding_box->y_min], [$x, $bounding_box->y_max] ];
}
# TODO: use a multi_polygon_multi_linestring_intersection() call

View File

@ -175,9 +175,9 @@ sub size {
return [ Slic3r::Geometry::size_3D($self->used_vertices) ];
}
sub extents {
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::bounding_box_3D($self->used_vertices);
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
}
sub align_to_origin {
@ -186,8 +186,8 @@ sub align_to_origin {
# calculate the displacements needed to
# have lowest value for each axis at coordinate 0
{
my @extents = $self->extents;
$self->move(map -$extents[$_][MIN], X,Y,Z);
my $bb = $self->bounding_box;
$self->move(map -$bb->extents->[$_][MIN], X,Y,Z);
}
# align all instances to 0,0 as well
@ -254,12 +254,12 @@ sub split_meshes {
# let's now align the new object to the origin and put its displacement
# (extents) in the instances info
my @extents = $mesh->extents;
my $bb = $mesh->bounding_box;
$new_object->align_to_origin;
# add one instance per original instance applying the displacement
$new_object->add_instance(
offset => [ $_->offset->[X] + $extents[X][MIN], $_->offset->[Y] + $extents[Y][MIN] ],
offset => [ $_->offset->[X] + $bb->x_min, $_->offset->[Y] + $bb->y_min ],
rotation => $_->rotation,
scaling_factor => $_->scaling_factor,
) for @{ $object->instances // [] };
@ -336,21 +336,14 @@ sub size {
return [ Slic3r::Geometry::size_3D($self->used_vertices) ];
}
sub extents {
my $self = shift;
return Slic3r::Geometry::bounding_box_3D($self->used_vertices);
}
sub center {
my $self = shift;
my @extents = $self->extents;
return [ map +($extents[$_][MAX] + $extents[$_][MIN])/2, X,Y,Z ];
return $self->bounding_box->center;
}
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::BoundingBox->new(extents => [ $self->extents ]);
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
}
sub align_to_origin {
@ -358,8 +351,8 @@ sub align_to_origin {
# calculate the displacements needed to
# have lowest value for each axis at coordinate 0
my @extents = $self->extents;
my @shift = map -$extents[$_][MIN], X,Y,Z;
my $bb = $self->bounding_box;
my @shift = map -$bb->extents->[$_][MIN], X,Y,Z;
$self->move(@shift);
return @shift;
}

View File

@ -10,18 +10,6 @@ use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges
X1 X2 Y1 Y2);
use Slic3r::Geometry::Clipper qw(JT_MITER);
sub new_from_bounding_box {
my $class = shift;
my ($bounding_box) = @_;
return $class->new([
[ $bounding_box->[X1], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y1] ],
[ $bounding_box->[X2], $bounding_box->[Y2] ],
[ $bounding_box->[X1], $bounding_box->[Y2] ],
]);
}
sub lines {
my $self = shift;
return polygon_lines($self);

View File

@ -123,7 +123,7 @@ sub clip_with_expolygon {
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::bounding_box($self);
return Slic3r::Geometry::BoundingBox->new_from_points($self);
}
sub size {
@ -133,8 +133,8 @@ sub size {
sub align_to_origin {
my $self = shift;
my @bb = $self->bounding_box;
return $self->translate(-$bb[X1], -$bb[Y1]);
my $bb = $self->bounding_box;
return $self->translate(-$bb->x_min, -$bb->y_min);
}
sub rotate {

View File

@ -291,19 +291,15 @@ sub bounding_box {
foreach my $copy (@{$object->copies}) {
push @points,
[ $copy->[X], $copy->[Y] ],
[ $copy->[X] + $object->size->[X], $copy->[Y] ],
[ $copy->[X] + $object->size->[X], $copy->[Y] + $object->size->[Y] ],
[ $copy->[X], $copy->[Y] + $object->size->[Y] ];
[ $copy->[X] + $object->size->[X], $copy->[Y] + $object->size->[Y] ];
}
}
return Slic3r::Geometry::bounding_box(\@points);
return Slic3r::Geometry::BoundingBox->new_from_points(\@points);
}
sub size {
my $self = shift;
my @bb = $self->bounding_box;
return [ $bb[X2] - $bb[X1], $bb[Y2] - $bb[Y1] ];
return $self->bounding_box->size;
}
sub _simplify_slices {
@ -749,10 +745,11 @@ sub write_gcode {
}
# calculate X,Y shift to center print around specified origin
my @print_bb = $self->bounding_box;
my $print_bb = $self->bounding_box;
my $print_size = $print_bb->size;
my @shift = (
$Slic3r::Config->print_center->[X] - (unscale ($print_bb[X2] - $print_bb[X1]) / 2) - unscale $print_bb[X1],
$Slic3r::Config->print_center->[Y] - (unscale ($print_bb[Y2] - $print_bb[Y1]) / 2) - unscale $print_bb[Y1],
$Slic3r::Config->print_center->[X] - unscale($print_size->[X]/2 - $print_bb->x_min),
$Slic3r::Config->print_center->[Y] - unscale($print_size->[Y]/2 - $print_bb->y_min),
);
# initialize a motion planner for object-to-object travel moves

View File

@ -138,7 +138,7 @@ sub bounding_box {
my $self = shift;
# since the object is aligned to origin, bounding box coincides with size
return Slic3r::Geometry::bounding_box([ [0,0], $self->size ]);
return Slic3r::Geometry::BoundingBox->new_from_points([ [0,0], $self->size ]);
}
sub slice {
@ -1001,7 +1001,7 @@ sub generate_support_material {
$_;
}
map $_->clip_with_expolygon($expolygon),
###map $_->clip_with_polygon($expolygon->bounding_box_polygon), # currently disabled as a workaround for Boost failing at being idempotent
###map $_->clip_with_polygon($expolygon->bounding_box->polygon), # currently disabled as a workaround for Boost failing at being idempotent
($is_interface && @$support_interface_patterns)
? @{$support_interface_patterns->[ $layer_id % @$support_interface_patterns ]}
: @{$support_patterns->[ $layer_id % @$support_patterns ]};

View File

@ -15,9 +15,9 @@ has 'height' => (is => 'rw');
sub _build_line {
my $self = shift;
my @bb = $self->print->bounding_box;
my $y = ($bb[Y2]-$bb[Y1]) * $self->y_percent;
return [ [ $bb[X1], $y ], [ $bb[X2], $y ] ]
my $bb = $self->print->bounding_box;
my $y = $bb->size->[Y] * $self->y_percent;
return [ [ $bb->x_min, $y ], [ $bb->x_max, $y ] ]
}
sub export_svg {

View File

@ -361,8 +361,8 @@ sub align_to_origin {
# calculate the displacements needed to
# have lowest value for each axis at coordinate 0
my @extents = $self->extents;
$self->move(map -$extents[$_][MIN], X,Y,Z);
my $bb = $self->bounding_box;
$self->move(map -$bb->extents->[$_][MIN], X,Y,Z);
}
sub center_around_origin {
@ -373,9 +373,7 @@ sub center_around_origin {
sub center {
my $self = shift;
my @extents = $self->extents;
return [ map +($extents[$_][MAX] + $extents[$_][MIN])/2, X,Y,Z ];
return $self->bounding_box->center;
}
sub duplicate {
@ -403,19 +401,14 @@ sub used_vertices {
return [ map $self->vertices->[$_], map @$_, @{$self->facets} ];
}
sub extents {
my $self = shift;
return Slic3r::Geometry::bounding_box_3D($self->used_vertices);
}
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::BoundingBox->new(extents => [ $self->extents ]);
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
}
sub size {
my $self = shift;
return Slic3r::Geometry::size_3D($self->used_vertices);
return $self->bounding_box->size;
}
sub slice_facet {

View File

@ -21,7 +21,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
$print->init_extruders;
my $filler = Slic3r::Fill::Rectilinear->new(
print => $print,
bounding_box => [ 0, 0, 10, 10 ],
bounding_box => Slic3r::Geometry::BoundingBox->new_from_points([ [0, 0], [10, 10] ]),
);
my $surface_width = 250;
my $distance = $filler->adjust_solid_spacing(
@ -35,7 +35,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
{
my $expolygon = Slic3r::ExPolygon->new([ scale_points [0,0], [50,0], [50,50], [0,50] ]);
my $filler = Slic3r::Fill::Rectilinear->new(
bounding_box => [ $expolygon->bounding_box ],
bounding_box => $expolygon->bounding_box,
);
my $surface = Slic3r::Surface->new(
surface_type => S_TYPE_TOP,

View File

@ -54,23 +54,19 @@ my %opt = (
});
# calculate print extents
my @bounding_box = Slic3r::Geometry::bounding_box([ map @$_, map @$_, values %paths ]);
my @size = (
($bounding_box[X2] - $bounding_box[X1]),
($bounding_box[Y2] - $bounding_box[Y1]),
);
my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, values %paths ]);
# calculate section line
my $section_y = ($bounding_box[Y2] + $bounding_box[Y1]) / 2;
my $section_y = $bounding_box->center->[Y];
my $section_line = [
[ $bounding_box[X1], $section_y ],
[ $bounding_box[X2], $section_y ],
[ $bounding_box->x_min, $section_y ],
[ $bounding_box->x_max, $section_y ],
];
# initialize output
my $max_z = max(keys %paths);
my $svg = SVG->new(
width => $opt{scale} * $size[X],
width => $opt{scale} * $bounding_box->size->[X],
height => $opt{scale} * $max_z,
);
@ -90,7 +86,7 @@ my %opt = (
) };
$g->rectangle(
'x' => $opt{scale} * ($_->[A][X] - $bounding_box[X1]),
'x' => $opt{scale} * ($_->[A][X] - $bounding_box->x_min),
'y' => $opt{scale} * ($max_z - $z),
'width' => $opt{scale} * abs($_->[B][X] - $_->[A][X]),
'height' => $opt{scale} * $opt{layer_height},