New options dialog for SLAPrint

This commit is contained in:
Alessandro Ranellucci 2016-12-01 15:53:29 +01:00
parent c6ea0118a7
commit 92845300be
10 changed files with 171 additions and 14 deletions

View File

@ -421,5 +421,6 @@ sub Slic3r::Config::Print::new { Slic3r::Config::Static::new_PrintConfig }
sub Slic3r::Config::PrintObject::new { Slic3r::Config::Static::new_PrintObjectConfig }
sub Slic3r::Config::PrintRegion::new { Slic3r::Config::Static::new_PrintRegionConfig }
sub Slic3r::Config::Full::new { Slic3r::Config::Static::new_FullPrintConfig }
sub Slic3r::Config::SLAPrint::new { Slic3r::Config::Static::new_SLAPrintConfig }
1;

View File

@ -31,6 +31,7 @@ use Slic3r::GUI::Projector;
use Slic3r::GUI::OptionsGroup;
use Slic3r::GUI::OptionsGroup::Field;
use Slic3r::GUI::SimpleTab;
use Slic3r::GUI::SLAPrintOptions;
use Slic3r::GUI::Tab;
our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1";

View File

@ -253,11 +253,7 @@ sub _init_menubar {
$plater->export_amf;
}, undef, 'brick_go.png');
$self->_append_menu_item($self->{plater_menu}, "Open DLP Projector…\tCtrl+L", 'Open projector window for DLP printing', sub {
my $projector = Slic3r::GUI::Projector->new($self);
# this double invocation is needed for properly hiding the MainFrame
$projector->Show;
$projector->ShowModal;
Slic3r::GUI::SLAPrintOptions->new($self)->ShowModal;
}, undef, 'film.png');
$self->{object_menu} = $self->{plater}->object_menu;

View File

@ -3,7 +3,8 @@
package Slic3r::GUI::Projector;
use strict;
use warnings;
use Wx qw(:dialog :id :misc :sizer :systemsettings :bitmap :button :icon wxTheApp);
use File::Basename qw(basename dirname);
use Wx qw(:dialog :id :misc :sizer :systemsettings :bitmap :button :icon :filedialog wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_CLOSE EVT_TEXT_ENTER EVT_SPINCTRL EVT_SLIDER);
use base qw(Wx::Dialog Class::Accessor);
use utf8;
@ -378,10 +379,23 @@ sub new {
{
# should be wxCLOSE but it crashes on Linux, maybe it's a Wx bug
my $buttons = $self->CreateStdDialogButtonSizer(wxOK);
EVT_BUTTON($self, wxID_OK, sub {
$self->_close;
});
my $buttons = Wx::BoxSizer->new(wxHORIZONTAL);
{
my $btn = Wx::Button->new($self, -1, "Export SVG…");
EVT_BUTTON($self, $btn, sub {
$self->_export_svg;
});
$buttons->Add($btn, 0);
}
$buttons->AddStretchSpacer(1);
{
my $btn = Wx::Button->new($self, -1, "Close");
$btn->SetDefault;
EVT_BUTTON($self, $btn, sub {
$self->_close;
});
$buttons->Add($btn, 0);
}
$sizer->Add($buttons, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
}
EVT_CLOSE($self, sub {
@ -457,6 +471,27 @@ sub _update_buttons {
$self->Layout;
}
sub _export_svg {
my ($self) = @_;
my $output_file = 'print.svg';
my $dlg = Wx::FileDialog->new(
$self,
'Save SVG file as:',
wxTheApp->output_path(dirname($output_file)),
basename($output_file),
&Slic3r::GUI::FILE_WILDCARDS->{svg},
wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
);
if ($dlg->ShowModal != wxID_OK) {
$dlg->Destroy;
return;
}
$output_file = Slic3r::decode_path($dlg->GetPath);
$self->controller->_print->write_svg($output_file);
}
sub _set_status {
my ($self, $status) = @_;
$self->{status_text}->SetLabel($status // '');

View File

@ -0,0 +1,118 @@
package Slic3r::GUI::SLAPrintOptions;
use Wx qw(:dialog :id :misc :sizer :systemsettings wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_TEXT_ENTER);
use base qw(Wx::Dialog Class::Accessor);
__PACKAGE__->mk_accessors(qw(config));
sub new {
my ($class, $parent) = @_;
my $self = $class->SUPER::new($parent, -1, "SLA/DLP Print", wxDefaultPosition, wxDefaultSize);
$self->config(Slic3r::Config::SLAPrint->new);
$self->config->apply_dynamic(wxTheApp->{mainframe}->config);
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
my $new_optgroup = sub {
my ($title) = @_;
my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
parent => $self,
title => $title,
config => $self->config,
label_width => 200,
);
$sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
return $optgroup;
};
{
my $optgroup = $new_optgroup->('Layers');
$optgroup->append_single_option_line('layer_height');
$optgroup->append_single_option_line('first_layer_height');
}
{
my $optgroup = $new_optgroup->('Infill');
$optgroup->append_single_option_line('fill_density');
$optgroup->append_single_option_line('fill_pattern');
{
my $line = $optgroup->create_single_option_line('perimeter_extrusion_width');
$line->label('Shell thickness');
my $opt = $line->get_options->[0];
$opt->sidetext('mm');
$opt->tooltip('Thickness of the external shell (both horizontal and vertical).');
$optgroup->append_line($line);
}
{
my $line = $optgroup->create_single_option_line('infill_extrusion_width');
$line->label('Infill thickness');
my $opt = $line->get_options->[0];
$opt->sidetext('mm');
$opt->tooltip('Thickness of the infill lines.');
$optgroup->append_line($line);
}
$optgroup->append_single_option_line('fill_angle');
}
{
my $optgroup = $new_optgroup->('Raft');
$optgroup->append_single_option_line('raft_layers');
$optgroup->append_single_option_line('raft_offset');
}
{
my $optgroup = $new_optgroup->('Support Material');
$optgroup->append_single_option_line('support_material');
{
my $line = $optgroup->create_single_option_line('support_material_spacing');
$line->label('Pillars spacing');
my $opt = $line->get_options->[0];
$opt->tooltip('Max spacing between support material pillars.');
$optgroup->append_line($line);
}
{
my $line = $optgroup->create_single_option_line('support_material_extrusion_width');
$line->label('Pillars diameter');
my $opt = $line->get_options->[0];
$opt->sidetext('mm');
$opt->tooltip('Diameter of the cylindrical support pillars.');
$optgroup->append_line($line);
}
}
my $buttons = $self->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
EVT_BUTTON($self, wxID_OK, sub { $self->_accept });
$sizer->Add($buttons, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->SetSizer($sizer);
$sizer->SetSizeHints($self);
return $self;
}
sub _accept {
my $self = shift;
# validate config
eval {
die "Invalid shell thickness (must be greater than 0).\n"
if $self->config->fill_density < 100 && $self->config->perimeter_extrusion_width == 0;
die "Invalid infill thickness (must be greater than 0).\n"
if $self->config->fill_density < 100 && $self->config->infill_extrusion_width == 0;
};
if ($@) {
Slic3r::GUI::show_error($self, $@);
return;
}
wxTheApp->{mainframe}->load_config($self->config->dynamic);
$self->EndModal(wxID_OK);
$self->Close; # needed on Linux
my $projector = Slic3r::GUI::Projector->new($self->GetParent);
# this double invocation is needed for properly hiding the MainFrame
$projector->Show;
$projector->ShowModal;
}
1;

View File

@ -78,7 +78,7 @@ void FillRectilinear::_fill_surface_single(
}
size_t n_polylines_out_old = polylines_out->size();
// connect lines
if (!this->dont_connect && !polylines.empty()) { // prevent calling leftmost_point() on empty collections
// offset the expolygon by max(min_spacing/2, extra)

View File

@ -311,6 +311,7 @@ _align_to_grid(const coord_t coord, const coord_t spacing) {
// Current C++ standard defines the result of integer division to be rounded to zero,
// for both positive and negative numbers. Here we want to round down for negative
// numbers as well.
assert(spacing > 0);
coord_t aligned = (coord < 0) ?
((coord - spacing + 1) / spacing) * spacing :
(coord / spacing) * spacing;

View File

@ -55,11 +55,12 @@ SLAPrint::slice()
}
// generate infill
if (this->config.fill_density < 100) {
const float infill_spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
if (this->config.fill_density < 100 && infill_spacing > 0) {
std::auto_ptr<Fill> fill(Fill::new_from_type(this->config.fill_pattern.value));
fill->bounding_box.merge(Point::new_scale(bb.min.x, bb.min.y));
fill->bounding_box.merge(Point::new_scale(bb.max.x, bb.max.y));
fill->spacing = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
fill->spacing = infill_spacing;
fill->angle = Geometry::deg2rad(this->config.fill_angle.value);
fill->density = this->config.fill_density.value/100;
@ -189,7 +190,6 @@ SLAPrint::_infill_layer(size_t i, const Fill* _fill)
ExtrusionPath templ(erInternalInfill);
templ.width = fill->spacing;
const ExPolygons internal_ex = intersection_ex(infill, internal);
for (ExPolygons::const_iterator it = internal_ex.begin(); it != internal_ex.end(); ++it) {
Polylines polylines = fill->fill_surface(Surface(stInternal, *it));

View File

@ -53,6 +53,8 @@
%code{% RETVAL = new PrintRegionConfig (); %};
static StaticPrintConfig* new_FullPrintConfig()
%code{% RETVAL = new FullPrintConfig (); %};
static StaticPrintConfig* new_SLAPrintConfig()
%code{% RETVAL = new SLAPrintConfig (); %};
~StaticPrintConfig();
bool has(t_config_option_key opt_key);
SV* as_hash()
@ -88,6 +90,8 @@
double min_object_distance();
%name{_load} void load(std::string file);
%name{_save} void save(std::string file);
DynamicPrintConfig* dynamic()
%code{% RETVAL = new DynamicPrintConfig (); RETVAL->apply(*THIS, true); %};
};
%package{Slic3r::Config};

View File

@ -28,6 +28,7 @@
%code%{ RETVAL = &THIS->layers[i].infill; %};
bool layer_solid(size_t i)
%code%{ RETVAL = THIS->layers[i].solid; %};
void write_svg(std::string file);
%{