mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 06:15:58 +08:00
New options dialog for SLAPrint
This commit is contained in:
parent
c6ea0118a7
commit
92845300be
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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 // '');
|
||||
|
118
lib/Slic3r/GUI/SLAPrintOptions.pm
Normal file
118
lib/Slic3r/GUI/SLAPrintOptions.pm
Normal 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;
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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};
|
||||
|
@ -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);
|
||||
|
||||
%{
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user