Adapt plater to new convex hull
This commit is contained in:
parent
9cf138574c
commit
3fca0956bc
4 changed files with 57 additions and 42 deletions
|
@ -6,7 +6,7 @@ use utf8;
|
|||
use File::Basename qw(basename dirname);
|
||||
use List::Util qw(max sum first);
|
||||
use Slic3r::Geometry::Clipper qw(offset JT_ROUND);
|
||||
use Slic3r::Geometry qw(X Y Z MIN MAX convex_hull);
|
||||
use Slic3r::Geometry qw(X Y Z MIN MAX convex_hull scale unscale);
|
||||
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);
|
||||
|
@ -395,7 +395,7 @@ sub load_file {
|
|||
instances => [
|
||||
$model->objects->[$i]->instances
|
||||
? (map $_->offset, @{$model->objects->[$i]->instances})
|
||||
: [0,0],
|
||||
: Slic3r::Point->new(0,0),
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -466,7 +466,8 @@ sub increase {
|
|||
|
||||
my ($obj_idx, $object) = $self->selected_object;
|
||||
my $instances = $object->instances;
|
||||
push @$instances, [ $instances->[-1]->[X] + 10, $instances->[-1]->[Y] + 10 ];
|
||||
push @$instances, my $new_instance = $instances->[-1]->clone;
|
||||
$new_instance->translate(scale(10), scale(10));
|
||||
$self->{list}->SetItem($obj_idx, 1, $object->instances_count);
|
||||
$self->arrange;
|
||||
}
|
||||
|
@ -865,18 +866,19 @@ sub recenter {
|
|||
return unless @{$self->{objects}};
|
||||
|
||||
# calculate displacement needed to center the print
|
||||
my $print_bb = Slic3r::Geometry::BoundingBox->new_from_points([
|
||||
map {
|
||||
my $obj = $_;
|
||||
my $bb = $obj->transformed_bounding_box;
|
||||
my @points = ($bb->min_point, $bb->max_point);
|
||||
map Slic3r::Geometry::move_points($_, @points), @{$obj->instances};
|
||||
} @{$self->{objects}},
|
||||
]);
|
||||
my @bbs = ();
|
||||
foreach my $plobj (@{$self->{objects}}) {
|
||||
my $bb = $plobj->transformed_bounding_box; # in scaled coordinates
|
||||
foreach my $inst (@{$plobj->instances}) {
|
||||
push @bbs, my $inst_bb = $bb->clone;
|
||||
$inst_bb->translate(@$inst, 0);
|
||||
}
|
||||
}
|
||||
my $print_bb = Slic3r::Geometry::BoundingBox->merge(@bbs);
|
||||
my $print_size = $print_bb->size;
|
||||
|
||||
# $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->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,
|
||||
|
@ -915,6 +917,7 @@ sub _update_bed_size {
|
|||
# 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
|
||||
# scaling_factor is expressed in pixel / mm
|
||||
$self->{scaling_factor} = CANVAS_SIZE->[X] / max(@{ $self->{config}->bed_size });
|
||||
$_->thumbnail_scaling_factor($self->{scaling_factor}) for @{ $self->{objects} };
|
||||
$self->recenter;
|
||||
|
@ -974,9 +977,9 @@ sub repaint {
|
|||
my $instance = $object->instances->[$instance_idx];
|
||||
|
||||
my $thumbnail = $object->transformed_thumbnail->clone;
|
||||
$thumbnail->translate(map $parent->to_pixel($instance->[$_]) + $parent->{shift}[$_], (X,Y));
|
||||
|
||||
push @{$parent->{object_previews}}, [ $obj_idx, $instance_idx, $thumbnail ];
|
||||
$thumbnail->translate(map $_ * $parent->{scaling_factor}, @$instance);
|
||||
$thumbnail->translate(map scale($parent->{shift}[$_]), (X,Y));
|
||||
push @{$parent->{object_previews}}, [ $obj_idx, $instance_idx, $thumbnail ]; # $thumbnail has scaled coordinates
|
||||
|
||||
my $drag_object = $self->{drag_object};
|
||||
if (defined $drag_object && $obj_idx == $drag_object->[0] && $instance_idx == $drag_object->[1]) {
|
||||
|
@ -986,26 +989,39 @@ sub repaint {
|
|||
} else {
|
||||
$dc->SetBrush($parent->{objects_brush});
|
||||
}
|
||||
$dc->DrawPolygon($parent->_y($_), 0, 0) for map $_->contour->pp, @{ $parent->{object_previews}->[-1][2] };
|
||||
foreach my $expolygon (@$thumbnail) {
|
||||
my $points = $expolygon->contour->pp;
|
||||
foreach my $point (@$points) {
|
||||
$point->[X] *= &Slic3r::SCALING_FACTOR;
|
||||
$point->[Y] *= &Slic3r::SCALING_FACTOR;
|
||||
}
|
||||
$dc->DrawPolygon($parent->_y($points), 0, 0);
|
||||
}
|
||||
|
||||
# if sequential printing is enabled and we have more than one object
|
||||
if ($parent->{config}->complete_objects && (map @{$_->instances}, @{$parent->{objects}}) > 1) {
|
||||
my $convex_hull = convex_hull([ map @{$_->contour}, @{$parent->{object_previews}->[-1][2]} ]);
|
||||
my ($clearance) = @{offset([$convex_hull], $parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 100, JT_ROUND)};
|
||||
$dc->SetPen($parent->{clearance_pen});
|
||||
$dc->SetBrush($parent->{transparent_brush});
|
||||
$dc->DrawPolygon($parent->_y($clearance), 0, 0);
|
||||
my @points = map @{$_->contour}, @{$parent->{object_previews}->[-1][2]};
|
||||
if (@points >= 3) {
|
||||
my ($clearance) = @{offset([convex_hull(\@points)], scale($parent->{config}->extruder_clearance_radius / 2) * $parent->{scaling_factor}, 100, JT_ROUND)};
|
||||
$clearance->scale(&Slic3r::SCALING_FACTOR);
|
||||
$dc->SetPen($parent->{clearance_pen});
|
||||
$dc->SetBrush($parent->{transparent_brush});
|
||||
$dc->DrawPolygon($parent->_y($clearance), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# draw skirt
|
||||
if (@{$parent->{object_previews}} && $parent->{config}->skirts) {
|
||||
my $convex_hull = convex_hull([ map @{$_->contour}, map @{$_->[2]}, @{$parent->{object_previews}} ]);
|
||||
($convex_hull) = @{offset([$convex_hull], $parent->{config}->skirt_distance * $parent->{scaling_factor}, 100, JT_ROUND)};
|
||||
$dc->SetPen($parent->{skirt_pen});
|
||||
$dc->SetBrush($parent->{transparent_brush});
|
||||
$dc->DrawPolygon($parent->_y($convex_hull), 0, 0) if $convex_hull;
|
||||
my @points = map @{$_->contour}, map @{$_->[2]}, @{$parent->{object_previews}};
|
||||
if (@points >= 3) {
|
||||
my ($convex_hull) = @{offset([convex_hull(\@points)], scale($parent->{config}->skirt_distance) * $parent->{scaling_factor}, 1, JT_ROUND)};
|
||||
$convex_hull->scale(&Slic3r::SCALING_FACTOR);
|
||||
$dc->SetPen($parent->{skirt_pen});
|
||||
$dc->SetBrush($parent->{transparent_brush});
|
||||
$dc->DrawPolygon($parent->_y($convex_hull), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
$event->Skip;
|
||||
|
@ -1016,7 +1032,7 @@ sub mouse_event {
|
|||
my $parent = $self->GetParent;
|
||||
|
||||
my $point = $event->GetPosition;
|
||||
my $pos = Slic3r::Point->new(map @$_, map @$_, $parent->_y([[$point->x, $point->y]])); #]]
|
||||
my $pos = Slic3r::Point->new_scale(@{$parent->_y([[$point->x, $point->y]])->[0]}); #]] in scaled pixels
|
||||
if ($event->ButtonDown(&Wx::wxMOUSE_BTN_LEFT)) {
|
||||
$parent->{selected_objects} = [];
|
||||
$parent->{list}->Select($parent->{list}->GetFirstSelected, 0);
|
||||
|
@ -1028,7 +1044,7 @@ sub mouse_event {
|
|||
$parent->{list}->Select($obj_idx, 1);
|
||||
$parent->selection_changed(1);
|
||||
my $instance = $parent->{objects}[$obj_idx]->instances->[$instance_idx];
|
||||
$self->{drag_start_pos} = [ map $pos->[$_] - $parent->{shift}[$_] - $parent->to_pixel($instance->[$_]), X,Y ]; # displacement between the click and the instance origin
|
||||
$self->{drag_start_pos} = [ map $pos->[$_] - scale($parent->{shift}[$_]) - scale($parent->to_pixel($instance->[$_])), X,Y ]; # displacement between the click and the instance origin
|
||||
$self->{drag_object} = $preview;
|
||||
}
|
||||
}
|
||||
|
@ -1045,8 +1061,9 @@ sub mouse_event {
|
|||
return if !$self->{drag_start_pos}; # concurrency problems
|
||||
for my $preview ($self->{drag_object}) {
|
||||
my ($obj_idx, $instance_idx, $thumbnail) = @$preview;
|
||||
my $instance = $parent->{objects}[$obj_idx]->instances->[$instance_idx];
|
||||
$instance->[$_] = $parent->to_units($pos->[$_] - $self->{drag_start_pos}[$_] - $parent->{shift}[$_]) for X,Y;
|
||||
$parent->{objects}[$obj_idx]->instances->[$instance_idx] = Slic3r::Point->new(
|
||||
map { $parent->to_units(unscale($pos->[$_] - $self->{drag_start_pos}[$_]) - $parent->{shift}[$_]) } (X,Y),
|
||||
);
|
||||
$parent->Refresh;
|
||||
}
|
||||
} elsif ($event->Moving) {
|
||||
|
@ -1155,7 +1172,7 @@ sub selection_changed {
|
|||
if ($self->{object_info_size}) { # have we already loaded the info pane?
|
||||
if ($have_sel) {
|
||||
my ($obj_idx, $object) = $self->selected_object;
|
||||
$self->{object_info_size}->SetLabel(sprintf("%.2f x %.2f x %.2f", @{$object->transformed_size}));
|
||||
$self->{object_info_size}->SetLabel(sprintf("%.2f x %.2f x %.2f", map unscale($_), @{$object->transformed_size}));
|
||||
$self->{object_info_materials}->SetLabel($object->materials);
|
||||
|
||||
if (my $stats = $object->mesh_stats) {
|
||||
|
@ -1209,12 +1226,12 @@ sub statusbar {
|
|||
|
||||
sub to_pixel {
|
||||
my $self = shift;
|
||||
return $_[0] * $self->{scaling_factor};
|
||||
return $_[0] * $self->{scaling_factor} * &Slic3r::SCALING_FACTOR;
|
||||
}
|
||||
|
||||
sub to_units {
|
||||
my $self = shift;
|
||||
return $_[0] / $self->{scaling_factor};
|
||||
return $_[0] / $self->{scaling_factor} / &Slic3r::SCALING_FACTOR;
|
||||
}
|
||||
|
||||
sub _y {
|
||||
|
@ -1261,8 +1278,8 @@ has 'input_file' => (is => 'rw', required => 1);
|
|||
has 'input_file_object_id' => (is => 'rw'); # undef means keep model object
|
||||
has 'model' => (is => 'rw', required => 1, trigger => \&_trigger_model_object);
|
||||
has 'model_object_idx' => (is => 'rw', required => 1, trigger => \&_trigger_model_object);
|
||||
has 'bounding_box' => (is => 'rw'); # 3D bb of original object (aligned to origin) with no rotation or scaling
|
||||
has 'convex_hull' => (is => 'rw'); # 2D convex hull of original object (aligned to origin) with no rotation or scaling
|
||||
has 'bounding_box' => (is => 'rw'); # scaled 3D bb of original object (aligned to origin) with no rotation or scaling
|
||||
has 'convex_hull' => (is => 'rw'); # scaled 2D convex hull of original object (aligned to origin) with no rotation or scaling
|
||||
has 'scale' => (is => 'rw', default => sub { 1 }, trigger => \&_transform_thumbnail);
|
||||
has 'rotate' => (is => 'rw', default => sub { 0 }, trigger => \&_transform_thumbnail); # around object center point
|
||||
has 'instances' => (is => 'rw', default => sub { [] }); # upward Y axis
|
||||
|
@ -1286,6 +1303,7 @@ sub _trigger_model_object {
|
|||
my $model_object = $self->model->objects->[$self->model_object_idx];
|
||||
$model_object->align_to_origin;
|
||||
$self->bounding_box($model_object->bounding_box);
|
||||
$self->bounding_box->scale(1 / &Slic3r::SCALING_FACTOR);
|
||||
|
||||
my $mesh = $model_object->mesh;
|
||||
$mesh->repair;
|
||||
|
@ -1363,13 +1381,10 @@ sub make_thumbnail {
|
|||
);
|
||||
$self->thumbnail->simplify(0.5);
|
||||
} else {
|
||||
my $convex_hull = Slic3r::ExPolygon->new($self->convex_hull)->clone;
|
||||
$convex_hull->scale(1/&Slic3r::SCALING_FACTOR);
|
||||
my $convex_hull = Slic3r::ExPolygon->new($self->convex_hull);
|
||||
$self->thumbnail->append($convex_hull);
|
||||
}
|
||||
|
||||
$self->thumbnail->scale(&Slic3r::SCALING_FACTOR);
|
||||
|
||||
return $self->thumbnail;
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,6 @@ use Moo;
|
|||
has 'object' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'rotation' => (is => 'rw', default => sub { 0 }); # around mesh center point
|
||||
has 'scaling_factor' => (is => 'rw', default => sub { 1 });
|
||||
has 'offset' => (is => 'rw'); # must be Slic3r::Point object
|
||||
has 'offset' => (is => 'rw'); # must be Slic3r::Point object in scaled coordinates
|
||||
|
||||
1;
|
||||
|
|
|
@ -17,7 +17,7 @@ sort_points (Point a, Point b)
|
|||
void
|
||||
convex_hull(Points points, Polygon &hull)
|
||||
{
|
||||
assert(points.size() >= 2);
|
||||
assert(points.size() >= 3);
|
||||
// sort input points
|
||||
std::sort(points.begin(), points.end(), sort_points);
|
||||
|
||||
|
|
|
@ -606,7 +606,7 @@ TriangleMesh::convex_hull(Polygon &hull)
|
|||
Points pp;
|
||||
pp.reserve(this->stl.stats.shared_vertices);
|
||||
for (int i = 0; i < this->stl.stats.shared_vertices; i++) {
|
||||
stl_vertex* v = this->stl.v_shared;
|
||||
stl_vertex* v = &this->stl.v_shared[i];
|
||||
pp.push_back(Point(v->x / SCALING_FACTOR, v->y / SCALING_FACTOR));
|
||||
}
|
||||
Slic3r::Geometry::convex_hull(pp, hull);
|
||||
|
|
Loading…
Reference in a new issue