More incomplete work for using bed_shape in plater

This commit is contained in:
Alessandro Ranellucci 2014-06-16 14:05:22 +02:00
parent f4e4640c73
commit 7a20c4d52a
4 changed files with 77 additions and 61 deletions

View file

@ -50,7 +50,7 @@ sub new {
my ($parent) = @_; my ($parent) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
$self->{config} = Slic3r::Config->new_from_defaults(qw( $self->{config} = Slic3r::Config->new_from_defaults(qw(
bed_size print_center complete_objects extruder_clearance_radius skirts skirt_distance bed_size bed_shape print_center complete_objects extruder_clearance_radius skirts skirt_distance
)); ));
$self->{model} = Slic3r::Model->new; $self->{model} = Slic3r::Model->new;
$self->{print} = Slic3r::Print->new; $self->{print} = Slic3r::Print->new;
@ -676,12 +676,7 @@ sub changescale {
sub arrange { sub arrange {
my $self = shift; my $self = shift;
# get the bounding box of the model area shown in the viewport my $bb = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape})->bounding_box;
my $bb = Slic3r::Geometry::BoundingBox->new_from_points([
Slic3r::Point->new(@{ $self->{canvas}->point_to_model_units([0,0]) }),
Slic3r::Point->new(@{ $self->{canvas}->point_to_model_units([ map { $_->GetWidth, $_->GetHeight } $self->{canvas}->GetSize ]) }),
]);
eval { eval {
$self->{model}->arrange_objects($self->GetFrame->config->min_object_distance, $bb); $self->{model}->arrange_objects($self->GetFrame->config->min_object_distance, $bb);
}; };

View file

@ -3,11 +3,11 @@ use strict;
use warnings; use warnings;
use utf8; use utf8;
use List::Util qw(max first); use List::Util qw(min max first);
use Slic3r::Geometry qw(X Y scale unscale convex_hull); use Slic3r::Geometry qw(X Y scale unscale convex_hull);
use Slic3r::Geometry::Clipper qw(offset JT_ROUND); use Slic3r::Geometry::Clipper qw(offset JT_ROUND);
use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL); use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT); use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE);
use base 'Wx::Panel'; use base 'Wx::Panel';
use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8' use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8'
@ -40,6 +40,9 @@ sub new {
EVT_PAINT($self, \&repaint); EVT_PAINT($self, \&repaint);
EVT_MOUSE_EVENTS($self, \&mouse_event); EVT_MOUSE_EVENTS($self, \&mouse_event);
EVT_SIZE($self, sub {
$self->update_bed_size;
});
return $self; return $self;
} }
@ -71,25 +74,27 @@ sub repaint {
my $size = $self->GetSize; my $size = $self->GetSize;
my @size = ($size->GetWidth, $size->GetHeight); my @size = ($size->GetWidth, $size->GetHeight);
# draw grid # draw bed
$dc->SetPen($self->{grid_pen}); {
my $step = 10 * $self->{scaling_factor}; $dc->SetPen($self->{print_center_pen});
for (my $x = $step; $x <= $size[X]; $x += $step) { $dc->SetBrush($self->{transparent_brush});
$dc->DrawLine($x, 0, $x, $size[Y]); $dc->DrawPolygon($self->scaled_points_to_pixel($self->{bed_polygon}, 1), 0, 0);
}
for (my $y = $step; $y <= $size[Y]; $y += $step) {
$dc->DrawLine(0, $y, $size[X], $y);
} }
# draw grid
$dc->SetPen($self->{grid_pen});
$dc->DrawLine(map @$_, @$_) for @{$self->{grid}};
# draw print center # draw print center
if (@{$self->{objects}}) { if (@{$self->{objects}} && $Slic3r::GUI::Settings->{_}{autocenter}) {
my $center = $self->unscaled_point_to_pixel($self->{config}->print_center);
$dc->SetPen($self->{print_center_pen}); $dc->SetPen($self->{print_center_pen});
$dc->DrawLine($size[X]/2, 0, $size[X]/2, $size[Y]); $dc->DrawLine($center->[X], 0, $center->[X], $size[Y]);
$dc->DrawLine(0, $size[Y]/2, $size[X], $size[Y]/2); $dc->DrawLine(0, $center->[Y], $size[X], $center->[Y]);
$dc->SetTextForeground(Wx::Colour->new(0,0,0)); $dc->SetTextForeground(Wx::Colour->new(0,0,0));
$dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)); $dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL));
$dc->DrawLabel("X = " . $self->{config}->print_center->[X], Wx::Rect->new(0, 0, $self->GetSize->GetWidth, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM); $dc->DrawLabel("X = " . $self->{config}->print_center->[X], Wx::Rect->new(0, 0, $center->[X]*2, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM);
$dc->DrawRotatedText("Y = " . $self->{config}->print_center->[Y], 0, $size[Y]/2+15, 90); $dc->DrawRotatedText("Y = " . $self->{config}->print_center->[Y], 0, $center->[Y]+15, 90);
} }
# draw frame # draw frame
@ -131,7 +136,7 @@ sub repaint {
} }
foreach my $expolygon (@$thumbnail) { foreach my $expolygon (@$thumbnail) {
foreach my $points (@{$expolygon->pp}) { foreach my $points (@{$expolygon->pp}) {
$dc->DrawPolygon($self->points_to_pixel($points, 1), 0, 0); $dc->DrawPolygon($self->scaled_points_to_pixel($points, 1), 0, 0);
} }
} }
@ -151,7 +156,7 @@ sub repaint {
my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), 1, JT_ROUND, scale(0.1))}; my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), 1, JT_ROUND, scale(0.1))};
$dc->SetPen($self->{clearance_pen}); $dc->SetPen($self->{clearance_pen});
$dc->SetBrush($self->{transparent_brush}); $dc->SetBrush($self->{transparent_brush});
$dc->DrawPolygon($self->points_to_pixel($clearance, 1), 0, 0); $dc->DrawPolygon($self->scaled_points_to_pixel($clearance, 1), 0, 0);
} }
} }
} }
@ -163,7 +168,7 @@ sub repaint {
my ($convex_hull) = @{offset([convex_hull(\@points)], scale($self->{config}->skirt_distance), 1, JT_ROUND, scale(0.1))}; my ($convex_hull) = @{offset([convex_hull(\@points)], scale($self->{config}->skirt_distance), 1, JT_ROUND, scale(0.1))};
$dc->SetPen($self->{skirt_pen}); $dc->SetPen($self->{skirt_pen});
$dc->SetBrush($self->{transparent_brush}); $dc->SetBrush($self->{transparent_brush});
$dc->DrawPolygon($self->points_to_pixel($convex_hull, 1), 0, 0); $dc->DrawPolygon($self->scaled_points_to_pixel($convex_hull, 1), 0, 0);
} }
} }
@ -173,16 +178,15 @@ sub repaint {
sub mouse_event { sub mouse_event {
my ($self, $event) = @_; my ($self, $event) = @_;
my $point = $event->GetPosition; my $pos = $event->GetPosition;
my $pos = $self->point_to_model_units([ $point->x, $point->y ]); #]] my $point = $self->point_to_model_units([ $pos->x, $pos->y ]); #]]
$pos = Slic3r::Point->new_scale(@$pos);
if ($event->ButtonDown) { if ($event->ButtonDown) {
$self->{on_select_object}->(undef); $self->{on_select_object}->(undef);
OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) { OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) {
my $object = $self->{objects}->[$obj_idx]; my $object = $self->{objects}->[$obj_idx];
for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) { for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) {
my $thumbnail = $object->instance_thumbnails->[$instance_idx]; my $thumbnail = $object->instance_thumbnails->[$instance_idx];
if (defined first { $_->contour->contains_point($pos) } @$thumbnail) { if (defined first { $_->contour->contains_point($point) } @$thumbnail) {
$self->{on_select_object}->($obj_idx); $self->{on_select_object}->($obj_idx);
if ($event->LeftDown) { if ($event->LeftDown) {
@ -190,12 +194,12 @@ sub mouse_event {
my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx]; my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx];
my $instance_origin = [ map scale($_), @{$instance->offset} ]; my $instance_origin = [ map scale($_), @{$instance->offset} ];
$self->{drag_start_pos} = [ # displacement between the click and the instance origin in scaled model units $self->{drag_start_pos} = [ # displacement between the click and the instance origin in scaled model units
$pos->x - $instance_origin->[X], $point->x - $instance_origin->[X],
$pos->y - $instance_origin->[Y], #- $point->y - $instance_origin->[Y], #-
]; ];
$self->{drag_object} = [ $obj_idx, $instance_idx ]; $self->{drag_object} = [ $obj_idx, $instance_idx ];
} elsif ($event->RightDown) { } elsif ($event->RightDown) {
$self->{on_right_click}->($point); $self->{on_right_click}->($pos);
} }
last OBJECTS; last OBJECTS;
@ -224,7 +228,7 @@ sub mouse_event {
$self->Refresh; $self->Refresh;
} elsif ($event->Moving) { } elsif ($event->Moving) {
my $cursor = wxSTANDARD_CURSOR; my $cursor = wxSTANDARD_CURSOR;
if (defined first { $_->contour->contains_point($pos) } map @$_, map @{$_->instance_thumbnails}, @{ $self->{objects} }) { if (defined first { $_->contour->contains_point($point) } map @$_, map @{$_->instance_thumbnails}, @{ $self->{objects} }) {
$cursor = Wx::Cursor->new(wxCURSOR_HAND); $cursor = Wx::Cursor->new(wxCURSOR_HAND);
} }
$self->SetCursor($cursor); $self->SetCursor($cursor);
@ -234,13 +238,37 @@ sub mouse_event {
sub update_bed_size { sub update_bed_size {
my $self = shift; my $self = shift;
# supposing the preview canvas is square, calculate the scaling factor
# to constrain print bed area inside preview
# when the canvas is not rendered yet, its GetSize() method returns 0,0 # when the canvas is not rendered yet, its GetSize() method returns 0,0
my $canvas_size = $self->GetSize;
my ($canvas_w, $canvas_h) = ($canvas_size->GetWidth, $canvas_size->GetHeight);
return if $canvas_w == 0;
# get bed shape polygon
$self->{bed_polygon} = my $polygon = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape});
my $bb = $polygon->bounding_box;
my $size = $bb->size;
# calculate the scaling factor needed for constraining print bed area inside preview
# scaling_factor is expressed in pixel / mm # scaling_factor is expressed in pixel / mm
my $width = $self->GetSize->GetWidth; $self->{scaling_factor} = min($canvas_w / unscale($size->x), $canvas_h / unscale($size->y)); #)
$self->{scaling_factor} = $width / max(@{ $self->{config}->bed_size })
if $width != 0; # calculate the displacement needed to center bed
$self->{bed_origin} = [
$self->GetSize->GetWidth/2 - (unscale($bb->x_max + $bb->x_min)/2 * $self->{scaling_factor}),
$canvas_h - ($self->GetSize->GetHeight/2 - (unscale($bb->y_max + $bb->y_min)/2 * $self->{scaling_factor})),
];
# cache bed contours and grid
{
my $step = scale 10; # 1cm grid
$self->{grid} = my $grid = []; # arrayref of lines
for (my $x = $bb->x_min + $step; $x < $bb->x_max; $x += $step) {
push @$grid, $self->scaled_points_to_pixel([[$x, $bb->y_min], [$x, $bb->y_max]], 1);
}
for (my $y = $bb->y_min + $step; $y < $bb->y_max; $y += $step) {
push @$grid, $self->scaled_points_to_pixel([[$bb->x_min, $y], [$bb->x_max, $y]], 1);
}
}
} }
sub clean_instance_thumbnails { sub clean_instance_thumbnails {
@ -251,35 +279,25 @@ sub clean_instance_thumbnails {
} }
} }
# coordinates of the model origin (0,0) in pixels # convert a model coordinate into a pixel coordinate
sub model_origin_to_pixel { sub unscaled_point_to_pixel {
my ($self) = @_;
return [
$self->GetSize->GetWidth/2 - ($self->{config}->print_center->[X] * $self->{scaling_factor}),
$self->GetSize->GetHeight/2 - ($self->{config}->print_center->[Y] * $self->{scaling_factor}),
];
}
# convert a model coordinate into a pixel coordinate, assuming preview has square shape
sub point_to_pixel {
my ($self, $point) = @_; my ($self, $point) = @_;
my $canvas_height = $self->GetSize->GetHeight; my $canvas_height = $self->GetSize->GetHeight;
my $zero = $self->model_origin_to_pixel; my $zero = $self->{bed_origin};
return [ return [
$point->[X] * $self->{scaling_factor} + $zero->[X], $point->[X] * $self->{scaling_factor} + $zero->[X],
$canvas_height - ($point->[Y] * $self->{scaling_factor} + $zero->[Y]), $canvas_height - $point->[Y] * $self->{scaling_factor} + ($zero->[Y] - $canvas_height),
]; ];
} }
sub points_to_pixel { sub scaled_points_to_pixel {
my ($self, $points, $unscale) = @_; my ($self, $points, $unscale) = @_;
my $result = []; my $result = [];
foreach my $point (@$points) { foreach my $point (@$points) {
$point = [ map unscale($_), @$point ] if $unscale; $point = [ map unscale($_), @$point ] if $unscale;
push @$result, $self->point_to_pixel($point); push @$result, $self->unscaled_point_to_pixel($point);
} }
return $result; return $result;
} }
@ -288,11 +306,13 @@ sub point_to_model_units {
my ($self, $point) = @_; my ($self, $point) = @_;
my $canvas_height = $self->GetSize->GetHeight; my $canvas_height = $self->GetSize->GetHeight;
my $zero = $self->model_origin_to_pixel; my $zero = $self->{bed_origin};
return [ my $p = Slic3r::Point->new(
($point->[X] - $zero->[X]) / $self->{scaling_factor}, scale ($point->[X] - $zero->[X]) / $self->{scaling_factor},
(($canvas_height - $point->[Y] - $zero->[Y]) / $self->{scaling_factor}), scale ($point->[Y] - $zero->[Y]) / $self->{scaling_factor},
]; );
use XXX; YYY $p->pp;
return $p;
} }
1; 1;

View file

@ -146,6 +146,7 @@ sub duplicate {
sub _arrange { sub _arrange {
my ($self, $sizes, $distance, $bb) = @_; my ($self, $sizes, $distance, $bb) = @_;
# we supply unscaled data to arrange()
return Slic3r::Geometry::arrange( return Slic3r::Geometry::arrange(
scalar(@$sizes), # number of parts scalar(@$sizes), # number of parts
max(map $_->x, @$sizes), # cell width max(map $_->x, @$sizes), # cell width

View file

@ -427,7 +427,7 @@ Print::invalidate_state_by_config_options(const std::vector<t_config_option_key>
} else if (*opt_key == "nozzle_diameter") { } else if (*opt_key == "nozzle_diameter") {
steps.insert(psInitExtruders); steps.insert(psInitExtruders);
} else if (*opt_key == "avoid_crossing_perimeters" } else if (*opt_key == "avoid_crossing_perimeters"
|| *opt_key == "bed_size" || *opt_key == "bed_shape"
|| *opt_key == "bed_temperature" || *opt_key == "bed_temperature"
|| *opt_key == "bridge_acceleration" || *opt_key == "bridge_acceleration"
|| *opt_key == "bridge_fan_speed" || *opt_key == "bridge_fan_speed"