More incomplete work for using bed_shape in plater
This commit is contained in:
parent
f4e4640c73
commit
7a20c4d52a
4 changed files with 77 additions and 61 deletions
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue