mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 23:23:59 -06:00
Merge branch 'region-config'
Conflicts: lib/Slic3r/Format/AMF/Parser.pm
This commit is contained in:
commit
0bdea60b53
62 changed files with 2164 additions and 1432 deletions
|
@ -387,59 +387,65 @@ sub load_file {
|
|||
my $model = eval { Slic3r::Model->read_from_file($input_file) };
|
||||
Slic3r::GUI::show_error($self, $@) if $@;
|
||||
|
||||
$self->load_model_object($_) for @{$model->objects};
|
||||
$self->load_model_objects(@{$model->objects});
|
||||
|
||||
$process_dialog->Destroy;
|
||||
$self->statusbar->SetStatusText("Loaded " . basename($input_file));
|
||||
}
|
||||
|
||||
sub load_model_object {
|
||||
my ($self, $model_object) = @_;
|
||||
|
||||
my $o = $self->{model}->add_object($model_object);
|
||||
|
||||
push @{ $self->{objects} }, Slic3r::GUI::Plater::Object->new(
|
||||
name => basename($model_object->input_file),
|
||||
);
|
||||
sub load_model_objects {
|
||||
my ($self, @model_objects) = @_;
|
||||
|
||||
my $need_arrange = 0;
|
||||
if (!defined $model_object->instances) {
|
||||
# if object has no defined position(s) we need to rearrange everything after loading
|
||||
$need_arrange = 1;
|
||||
my @obj_idx = ();
|
||||
foreach my $model_object (@model_objects) {
|
||||
my $o = $self->{model}->add_object($model_object);
|
||||
|
||||
# add a default instance and center object around origin
|
||||
$o->center_around_origin;
|
||||
$o->add_instance(offset => [ @{$self->{config}->print_center} ]);
|
||||
}
|
||||
push @{ $self->{objects} }, Slic3r::GUI::Plater::Object->new(
|
||||
name => basename($model_object->input_file),
|
||||
);
|
||||
push @obj_idx, $#{ $self->{objects} };
|
||||
|
||||
$self->{print}->add_model_object($o);
|
||||
if (!defined $model_object->instances) {
|
||||
# if object has no defined position(s) we need to rearrange everything after loading
|
||||
$need_arrange = 1;
|
||||
|
||||
# add a default instance and center object around origin
|
||||
$o->center_around_origin;
|
||||
$o->add_instance(offset => [ @{$self->{config}->print_center} ]);
|
||||
}
|
||||
|
||||
$self->{print}->add_model_object($o);
|
||||
}
|
||||
|
||||
# if user turned autocentering off, automatic arranging would disappoint them
|
||||
if (!$Slic3r::GUI::Settings->{_}{autocenter}) {
|
||||
$need_arrange = 0;
|
||||
}
|
||||
|
||||
$self->object_loaded($#{ $self->{objects} }, no_arrange => !$need_arrange);
|
||||
$self->objects_loaded(\@obj_idx, no_arrange => !$need_arrange);
|
||||
}
|
||||
|
||||
sub object_loaded {
|
||||
sub objects_loaded {
|
||||
my $self = shift;
|
||||
my ($obj_idx, %params) = @_;
|
||||
my ($obj_idxs, %params) = @_;
|
||||
|
||||
my $object = $self->{objects}[$obj_idx];
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
$self->{list}->InsertStringItem($obj_idx, $object->name);
|
||||
$self->{list}->SetItemFont($obj_idx, Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL))
|
||||
if $self->{list}->can('SetItemFont'); # legacy code for wxPerl < 0.9918 not supporting SetItemFont()
|
||||
foreach my $obj_idx (@$obj_idxs) {
|
||||
my $object = $self->{objects}[$obj_idx];
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
$self->{list}->InsertStringItem($obj_idx, $object->name);
|
||||
$self->{list}->SetItemFont($obj_idx, Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL))
|
||||
if $self->{list}->can('SetItemFont'); # legacy code for wxPerl < 0.9918 not supporting SetItemFont()
|
||||
|
||||
$self->{list}->SetItem($obj_idx, 1, $model_object->instances_count);
|
||||
$self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%");
|
||||
$self->{list}->SetItem($obj_idx, 1, $model_object->instances_count);
|
||||
$self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%");
|
||||
|
||||
$self->make_thumbnail($obj_idx);
|
||||
$self->make_thumbnail($obj_idx);
|
||||
}
|
||||
$self->arrange unless $params{no_arrange};
|
||||
$self->update;
|
||||
$self->{list}->Update;
|
||||
$self->{list}->Select($obj_idx, 1);
|
||||
$self->{list}->Select($obj_idxs->[-1], 1);
|
||||
$self->object_list_changed;
|
||||
}
|
||||
|
||||
|
@ -638,7 +644,6 @@ sub split_object {
|
|||
input_file => $current_model_object->input_file,
|
||||
config => $current_model_object->config->clone,
|
||||
layer_height_ranges => $current_model_object->layer_height_ranges, # TODO: clone this
|
||||
material_mapping => $current_model_object->material_mapping, # TODO: clone this
|
||||
);
|
||||
$model_object->add_volume(
|
||||
mesh => $mesh,
|
||||
|
@ -658,7 +663,7 @@ sub split_object {
|
|||
}
|
||||
# we need to center this single object around origin
|
||||
$model_object->center_around_origin;
|
||||
$self->load_model_object($model_object);
|
||||
$self->load_model_objects($model_object);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,11 +760,15 @@ sub export_gcode2 {
|
|||
} if $Slic3r::have_threads;
|
||||
|
||||
my $print = $self->{print};
|
||||
$print->apply_config($config);
|
||||
$print->apply_extra_variables($extra_variables);
|
||||
|
||||
|
||||
eval {
|
||||
$print->config->validate;
|
||||
# this will throw errors if config is not valid
|
||||
$config->validate;
|
||||
|
||||
$print->apply_config($config);
|
||||
$print->apply_extra_variables($extra_variables);
|
||||
|
||||
$print->validate;
|
||||
|
||||
{
|
||||
|
|
|
@ -114,7 +114,7 @@ sub update_optgroup {
|
|||
|
||||
my $config = $self->model_object->config;
|
||||
my %categories = ();
|
||||
foreach my $opt_key (keys %$config) {
|
||||
foreach my $opt_key (@{$config->get_keys}) {
|
||||
my $category = $Slic3r::Config::Options->{$opt_key}{category};
|
||||
$categories{$category} ||= [];
|
||||
push @{$categories{$category}}, $opt_key;
|
||||
|
@ -288,31 +288,41 @@ sub new {
|
|||
# get unique materials used in this object
|
||||
$self->{materials} = [ $self->model_object->unique_materials ];
|
||||
|
||||
# build an OptionsGroup
|
||||
$self->{mapping} = {
|
||||
(map { $self->{materials}[$_] => $_+1 } 0..$#{ $self->{materials} }), # defaults
|
||||
%{$self->model_object->material_mapping},
|
||||
};
|
||||
my $optgroup = Slic3r::GUI::OptionsGroup->new(
|
||||
parent => $self,
|
||||
title => 'Extruders',
|
||||
label_width => 300,
|
||||
options => [
|
||||
map {
|
||||
my $i = $_;
|
||||
my $material_id = $self->{materials}[$i];
|
||||
{
|
||||
opt_key => "material_extruder_$_",
|
||||
type => 'i',
|
||||
label => $self->model_object->model->get_material_name($material_id),
|
||||
min => 1,
|
||||
default => $self->{mapping}{$material_id},
|
||||
on_change => sub { $self->{mapping}{$material_id} = $_[0] },
|
||||
}
|
||||
} 0..$#{ $self->{materials} }
|
||||
],
|
||||
);
|
||||
$self->{sizer}->Add($optgroup->sizer, 0, wxEXPAND | wxALL, 10);
|
||||
# get the current mapping
|
||||
$self->{mapping} = {};
|
||||
foreach my $material_id (@{ $self->{materials}}) {
|
||||
my $config = $self->model_object->model->materials->{ $material_id }->config;
|
||||
$self->{mapping}{$material_id} = ($config->perimeter_extruder // 0) + 1;
|
||||
}
|
||||
|
||||
if (@{$self->{materials}} > 0) {
|
||||
# build an OptionsGroup
|
||||
my $optgroup = Slic3r::GUI::OptionsGroup->new(
|
||||
parent => $self,
|
||||
title => 'Extruders',
|
||||
label_width => 300,
|
||||
options => [
|
||||
map {
|
||||
my $i = $_;
|
||||
my $material_id = $self->{materials}[$i];
|
||||
{
|
||||
opt_key => "material_extruder_$_",
|
||||
type => 'i',
|
||||
label => $self->model_object->model->get_material_name($material_id),
|
||||
min => 1,
|
||||
default => $self->{mapping}{$material_id} // 1,
|
||||
on_change => sub { $self->{mapping}{$material_id} = $_[0] },
|
||||
}
|
||||
} 0..$#{ $self->{materials} }
|
||||
],
|
||||
);
|
||||
$self->{sizer}->Add($optgroup->sizer, 0, wxEXPAND | wxALL, 10);
|
||||
} else {
|
||||
my $label = Wx::StaticText->new($self, -1, "This object does not contain named materials.",
|
||||
wxDefaultPosition, [-1, 25]);
|
||||
$label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
||||
$self->{sizer}->Add($label, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10);
|
||||
}
|
||||
|
||||
$self->SetSizer($self->{sizer});
|
||||
$self->{sizer}->SetSizeHints($self);
|
||||
|
@ -324,7 +334,12 @@ sub Closing {
|
|||
my $self = shift;
|
||||
|
||||
# save mappings into the plater object
|
||||
$self->model_object->material_mapping($self->{mapping});
|
||||
foreach my $volume (@{$self->model_object->volumes}) {
|
||||
if (defined $volume->material_id) {
|
||||
my $config = $self->model_object->model->materials->{ $volume->material_id }->config;
|
||||
$config->set('extruder', $self->{mapping}{ $volume->material_id }-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -88,25 +88,15 @@ sub quick_slice {
|
|||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $process_dialog;
|
||||
my $progress_dialog;
|
||||
eval {
|
||||
# validate configuration
|
||||
my $config = $self->config;
|
||||
$config->validate;
|
||||
|
||||
# confirm slicing of more than one copies
|
||||
my $copies = $config->duplicate_grid->[X] * $config->duplicate_grid->[Y];
|
||||
$copies = $config->duplicate if $config->duplicate > 1;
|
||||
if ($copies > 1) {
|
||||
my $confirmation = Wx::MessageDialog->new($self, "Are you sure you want to slice $copies copies?",
|
||||
'Multiple Copies', wxICON_QUESTION | wxOK | wxCANCEL);
|
||||
return unless $confirmation->ShowModal == wxID_OK;
|
||||
}
|
||||
|
||||
# select input file
|
||||
my $dir = $Slic3r::GUI::Settings->{recent}{skein_directory} || $Slic3r::GUI::Settings->{recent}{config_directory} || '';
|
||||
|
||||
my $input_file;
|
||||
my $dir = $Slic3r::GUI::Settings->{recent}{skein_directory} || $Slic3r::GUI::Settings->{recent}{config_directory} || '';
|
||||
if (!$params{reslice}) {
|
||||
my $dialog = Wx::FileDialog->new($self, 'Choose a file to slice (STL/OBJ/AMF):', $dir, "", MODEL_WILDCARD, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if ($dialog->ShowModal != wxID_OK) {
|
||||
|
@ -133,28 +123,23 @@ sub quick_slice {
|
|||
$Slic3r::GUI::Settings->{recent}{skein_directory} = dirname($input_file);
|
||||
Slic3r::GUI->save_settings;
|
||||
|
||||
my $print = $self->init_print;
|
||||
my $model = eval { Slic3r::Model->read_from_file($input_file) };
|
||||
Slic3r::GUI::show_error($self, $@) if $@;
|
||||
my $sprint = Slic3r::Print::Simple->new(
|
||||
status_cb => sub {
|
||||
my ($percent, $message) = @_;
|
||||
return if &Wx::wxVERSION_STRING !~ / 2\.(8\.|9\.[2-9])/;
|
||||
$progress_dialog->Update($percent, "$message…");
|
||||
},
|
||||
);
|
||||
|
||||
if ($model->has_objects_with_no_instances) {
|
||||
# apply a default position to all objects not having one
|
||||
foreach my $object (@{$model->objects}) {
|
||||
$object->add_instance(offset => [0,0]) if !defined $object->instances;
|
||||
}
|
||||
$model->arrange_objects($config->min_object_distance);
|
||||
}
|
||||
$model->center_instances_around_point($config->print_center);
|
||||
$sprint->apply_config($config);
|
||||
$sprint->set_model(Slic3r::Model->read_from_file($input_file));
|
||||
|
||||
$print->add_model_object($_) for @{ $model->objects };
|
||||
$print->validate;
|
||||
|
||||
# select output file
|
||||
my $output_file = $main::opt{output};
|
||||
my $output_file;
|
||||
if ($params{reslice}) {
|
||||
$output_file = $last_output_file if defined $last_output_file;
|
||||
} elsif ($params{save_as}) {
|
||||
$output_file = $print->expanded_output_filepath($output_file);
|
||||
$output_file = $sprint->expanded_output_filepath;
|
||||
$output_file =~ s/\.gcode$/.svg/i if $params{export_svg};
|
||||
my $dlg = Wx::FileDialog->new($self, 'Save ' . ($params{export_svg} ? 'SVG' : 'G-code') . ' file as:',
|
||||
Slic3r::GUI->output_path(dirname($output_file)),
|
||||
|
@ -171,40 +156,32 @@ sub quick_slice {
|
|||
}
|
||||
|
||||
# show processbar dialog
|
||||
$process_dialog = Wx::ProgressDialog->new('Slicing…', "Processing $input_file_basename…",
|
||||
$progress_dialog = Wx::ProgressDialog->new('Slicing…', "Processing $input_file_basename…",
|
||||
100, $self, 0);
|
||||
$process_dialog->Pulse;
|
||||
$progress_dialog->Pulse;
|
||||
|
||||
{
|
||||
my @warnings = ();
|
||||
local $SIG{__WARN__} = sub { push @warnings, $_[0] };
|
||||
my %export_params = (
|
||||
output_file => $output_file,
|
||||
);
|
||||
$print->status_cb(sub {
|
||||
my ($percent, $message) = @_;
|
||||
if (&Wx::wxVERSION_STRING =~ / 2\.(8\.|9\.[2-9])/) {
|
||||
$process_dialog->Update($percent, "$message…");
|
||||
}
|
||||
});
|
||||
|
||||
$sprint->output_file($output_file);
|
||||
if ($params{export_svg}) {
|
||||
$print->export_svg(%export_params);
|
||||
$sprint->export_svg;
|
||||
} else {
|
||||
$print->process;
|
||||
$print->export_gcode(%export_params);
|
||||
$sprint->export_gcode;
|
||||
}
|
||||
$print->status_cb(undef);
|
||||
$sprint->status_cb(undef);
|
||||
Slic3r::GUI::warning_catcher($self)->($_) for @warnings;
|
||||
}
|
||||
$process_dialog->Destroy;
|
||||
undef $process_dialog;
|
||||
$progress_dialog->Destroy;
|
||||
undef $progress_dialog;
|
||||
|
||||
my $message = "$input_file_basename was successfully sliced.";
|
||||
&Wx::wxTheApp->notify($message);
|
||||
Wx::MessageDialog->new($self, $message, 'Slicing Done!',
|
||||
wxOK | wxICON_INFORMATION)->ShowModal;
|
||||
};
|
||||
Slic3r::GUI::catch_error($self, sub { $process_dialog->Destroy if $process_dialog });
|
||||
Slic3r::GUI::catch_error($self, sub { $progress_dialog->Destroy if $progress_dialog });
|
||||
}
|
||||
|
||||
sub repair_stl {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue