From abf38d4027277ef56f4d48722b18c5ecb0f6d04b Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 17 Jun 2014 00:25:52 +0200 Subject: [PATCH] Add support for custom bed shapes --- lib/Slic3r/GUI/BedShapeDialog.pm | 49 ++++++++++++++++++++++++++++++-- lib/Slic3r/Model.pm | 9 ++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/BedShapeDialog.pm b/lib/Slic3r/GUI/BedShapeDialog.pm index bfc5a844e..010b9d0f7 100644 --- a/lib/Slic3r/GUI/BedShapeDialog.pm +++ b/lib/Slic3r/GUI/BedShapeDialog.pm @@ -42,8 +42,8 @@ package Slic3r::GUI::BedShapePanel; use List::Util qw(min max sum first); use Slic3r::Geometry qw(PI X Y unscale scaled_epsilon); -use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL); -use Wx::Event qw(EVT_CLOSE EVT_CHOICEBOOK_PAGE_CHANGED); +use Wx qw(:dialog :id :misc :sizer :choicebook :filedialog wxTAB_TRAVERSAL); +use Wx::Event qw(EVT_CLOSE EVT_CHOICEBOOK_PAGE_CHANGED EVT_BUTTON); use base 'Wx::Panel'; use constant SHAPE_RECTANGULAR => 0; @@ -94,6 +94,20 @@ sub new { }, ]); + my $custom = sub { + my ($parent) = @_; + + my $btn = Wx::Button->new($parent, -1, "Load shape from STL...", wxDefaultPosition, wxDefaultSize); + EVT_BUTTON($self, $btn, sub { $self->_load_stl }); + return $btn; + }; + $self->_init_shape_options_page('Custom', [], [ + { + full_width => 1, + widget => $custom, + }, + ]); + EVT_CHOICEBOOK_PAGE_CHANGED($self, -1, sub { $self->_update_shape; }); @@ -215,7 +229,7 @@ sub _update_preview { } sub _init_shape_options_page { - my ($self, $title, $options) = @_; + my ($self, $title, $options, $lines) = @_; my $on_change = sub { my ($opt_key, $value) = @_; @@ -228,6 +242,7 @@ sub _init_shape_options_page { parent => $panel, title => 'Settings', options => $options, + $lines ? (lines => $lines) : (), on_change => $on_change, label_width => 100, ); @@ -236,6 +251,34 @@ sub _init_shape_options_page { $self->{shape_options_book}->AddPage($panel, $title); } +sub _load_stl { + my ($self) = @_; + + my $dialog = Wx::FileDialog->new($self, 'Choose a file to import bed shape from (STL/OBJ/AMF):', "", "", &Slic3r::GUI::MODEL_WILDCARD, wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if ($dialog->ShowModal != wxID_OK) { + $dialog->Destroy; + return; + } + my $input_file = $dialog->GetPaths; + $dialog->Destroy; + + my $model = Slic3r::Model->read_from_file($input_file); + my $mesh = $model->raw_mesh; + my $expolygons = $mesh->horizontal_projection; + + if (@$expolygons == 0) { + Slic3r::GUI::show_error($self, "The selected file contains no geometry."); + return; + } + if (@$expolygons > 1) { + Slic3r::GUI::show_error($self, "The selected file contains several disjoint areas. This is not supported."); + return; + } + + my $polygon = $expolygons->[0]->contour; + $self->{bed_shape} = [ map [ unscale($_->x), unscale($_->y) ], @$polygon ]; #)) +} + sub GetValue { my ($self) = @_; return $self->{bed_shape}; diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index c4c80e1f9..9f406bedb 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -237,6 +237,15 @@ sub mesh { return $mesh; } +# flattens everything to a single mesh +sub raw_mesh { + my $self = shift; + + my $mesh = Slic3r::TriangleMesh->new; + $mesh->merge($_->raw_mesh) for @{$self->objects}; + return $mesh; +} + # this method splits objects into multiple distinct objects by walking their meshes sub split_meshes { my $self = shift;