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 $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
$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->{print} = Slic3r::Print->new;
@ -676,12 +676,7 @@ sub changescale {
sub arrange {
my $self = shift;
# get the bounding box of the model area shown in the viewport
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 ]) }),
]);
my $bb = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape})->bounding_box;
eval {
$self->{model}->arrange_objects($self->GetFrame->config->min_object_distance, $bb);
};

View file

@ -3,11 +3,11 @@ use strict;
use warnings;
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::Clipper qw(offset JT_ROUND);
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 constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8'
@ -40,6 +40,9 @@ sub new {
EVT_PAINT($self, \&repaint);
EVT_MOUSE_EVENTS($self, \&mouse_event);
EVT_SIZE($self, sub {
$self->update_bed_size;
});
return $self;
}
@ -71,25 +74,27 @@ sub repaint {
my $size = $self->GetSize;
my @size = ($size->GetWidth, $size->GetHeight);
# draw grid
$dc->SetPen($self->{grid_pen});
my $step = 10 * $self->{scaling_factor};
for (my $x = $step; $x <= $size[X]; $x += $step) {
$dc->DrawLine($x, 0, $x, $size[Y]);
}
for (my $y = $step; $y <= $size[Y]; $y += $step) {
$dc->DrawLine(0, $y, $size[X], $y);
# draw bed
{
$dc->SetPen($self->{print_center_pen});
$dc->SetBrush($self->{transparent_brush});
$dc->DrawPolygon($self->scaled_points_to_pixel($self->{bed_polygon}, 1), 0, 0);
}
# draw grid
$dc->SetPen($self->{grid_pen});
$dc->DrawLine(map @$_, @$_) for @{$self->{grid}};
# 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->DrawLine($size[X]/2, 0, $size[X]/2, $size[Y]);
$dc->DrawLine(0, $size[Y]/2, $size[X], $size[Y]/2);
$dc->DrawLine($center->[X], 0, $center->[X], $size[Y]);
$dc->DrawLine(0, $center->[Y], $size[X], $center->[Y]);
$dc->SetTextForeground(Wx::Colour->new(0,0,0));
$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->DrawRotatedText("Y = " . $self->{config}->print_center->[Y], 0, $size[Y]/2+15, 90);
$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, $center->[Y]+15, 90);
}
# draw frame
@ -131,7 +136,7 @@ sub repaint {
}
foreach my $expolygon (@$thumbnail) {
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))};
$dc->SetPen($self->{clearance_pen});
$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))};
$dc->SetPen($self->{skirt_pen});
$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 {
my ($self, $event) = @_;
my $point = $event->GetPosition;
my $pos = $self->point_to_model_units([ $point->x, $point->y ]); #]]
$pos = Slic3r::Point->new_scale(@$pos);
my $pos = $event->GetPosition;
my $point = $self->point_to_model_units([ $pos->x, $pos->y ]); #]]
if ($event->ButtonDown) {
$self->{on_select_object}->(undef);
OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) {
my $object = $self->{objects}->[$obj_idx];
for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) {
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);
if ($event->LeftDown) {
@ -190,12 +194,12 @@ sub mouse_event {
my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx];
my $instance_origin = [ map scale($_), @{$instance->offset} ];
$self->{drag_start_pos} = [ # displacement between the click and the instance origin in scaled model units
$pos->x - $instance_origin->[X],
$pos->y - $instance_origin->[Y], #-
$point->x - $instance_origin->[X],
$point->y - $instance_origin->[Y], #-
];
$self->{drag_object} = [ $obj_idx, $instance_idx ];
} elsif ($event->RightDown) {
$self->{on_right_click}->($point);
$self->{on_right_click}->($pos);
}
last OBJECTS;
@ -224,7 +228,7 @@ sub mouse_event {
$self->Refresh;
} elsif ($event->Moving) {
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);
}
$self->SetCursor($cursor);
@ -234,13 +238,37 @@ sub mouse_event {
sub update_bed_size {
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
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
my $width = $self->GetSize->GetWidth;
$self->{scaling_factor} = $width / max(@{ $self->{config}->bed_size })
if $width != 0;
$self->{scaling_factor} = min($canvas_w / unscale($size->x), $canvas_h / unscale($size->y)); #)
# 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 {
@ -251,35 +279,25 @@ sub clean_instance_thumbnails {
}
}
# coordinates of the model origin (0,0) in pixels
sub model_origin_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 {
# convert a model coordinate into a pixel coordinate
sub unscaled_point_to_pixel {
my ($self, $point) = @_;
my $canvas_height = $self->GetSize->GetHeight;
my $zero = $self->model_origin_to_pixel;
my $zero = $self->{bed_origin};
return [
$point->[X] * $self->{scaling_factor} + $zero->[X],
$canvas_height - ($point->[Y] * $self->{scaling_factor} + $zero->[Y]),
$point->[X] * $self->{scaling_factor} + $zero->[X],
$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 $result = [];
foreach my $point (@$points) {
$point = [ map unscale($_), @$point ] if $unscale;
push @$result, $self->point_to_pixel($point);
push @$result, $self->unscaled_point_to_pixel($point);
}
return $result;
}
@ -288,11 +306,13 @@ sub point_to_model_units {
my ($self, $point) = @_;
my $canvas_height = $self->GetSize->GetHeight;
my $zero = $self->model_origin_to_pixel;
return [
($point->[X] - $zero->[X]) / $self->{scaling_factor},
(($canvas_height - $point->[Y] - $zero->[Y]) / $self->{scaling_factor}),
];
my $zero = $self->{bed_origin};
my $p = Slic3r::Point->new(
scale ($point->[X] - $zero->[X]) / $self->{scaling_factor},
scale ($point->[Y] - $zero->[Y]) / $self->{scaling_factor},
);
use XXX; YYY $p->pp;
return $p;
}
1;

View file

@ -146,6 +146,7 @@ sub duplicate {
sub _arrange {
my ($self, $sizes, $distance, $bb) = @_;
# we supply unscaled data to arrange()
return Slic3r::Geometry::arrange(
scalar(@$sizes), # number of parts
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") {
steps.insert(psInitExtruders);
} else if (*opt_key == "avoid_crossing_perimeters"
|| *opt_key == "bed_size"
|| *opt_key == "bed_shape"
|| *opt_key == "bed_temperature"
|| *opt_key == "bridge_acceleration"
|| *opt_key == "bridge_fan_speed"