Implements loading of multi-part objects as a bunch of STLs
for a multi-material printer. Also only a single pop-up dialog is open when loading multiple files.
This commit is contained in:
parent
a7153c67e6
commit
32213ce679
@ -690,44 +690,75 @@ sub filament_presets {
|
|||||||
|
|
||||||
sub add {
|
sub add {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my @input_files = wxTheApp->open_model($self);
|
my @input_files = wxTheApp->open_model($self);
|
||||||
$self->load_file($_) for @input_files;
|
$self->load_files(\@input_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub load_file {
|
sub load_files {
|
||||||
my $self = shift;
|
my ($self, $input_files) = @_;
|
||||||
my ($input_file) = @_;
|
|
||||||
|
|
||||||
$Slic3r::GUI::Settings->{recent}{skein_directory} = dirname($input_file);
|
return if ! defined($input_files) || ! scalar(@$input_files);
|
||||||
wxTheApp->save_settings;
|
|
||||||
|
|
||||||
my $process_dialog = Wx::ProgressDialog->new('Loading…', "Processing input file…", 100, $self, 0);
|
my $nozzle_dmrs = $self->{config}->get('nozzle_diameter');
|
||||||
|
# One of the files is potentionally a bundle of files. Don't bundle them, but load them one by one.
|
||||||
|
# Only bundle .stls or .objs if the printer has multiple extruders.
|
||||||
|
my $one_by_one = (@$nozzle_dmrs <= 1) || (@$input_files == 1) ||
|
||||||
|
defined(first { $_ =~ /.amf$/i || $_ =~ /.3mf$/i || $_ =~ /.prusa$/i } @$input_files);
|
||||||
|
|
||||||
|
my $process_dialog = Wx::ProgressDialog->new('Loading…', "Processing input file\n" . basename($input_files->[0]), 100, $self, 0);
|
||||||
$process_dialog->Pulse;
|
$process_dialog->Pulse;
|
||||||
|
|
||||||
local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self);
|
local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self);
|
||||||
|
|
||||||
|
# new_model to collect volumes, if all of them come from .stl or .obj and there is a chance, that they will be
|
||||||
|
# possibly merged into a single multi-part object.
|
||||||
|
my $new_model = $one_by_one ? undef : Slic3r::Model->new;
|
||||||
|
# Object indices for the UI.
|
||||||
|
my @obj_idx = ();
|
||||||
|
# Collected file names to display the final message on the status bar.
|
||||||
|
my @loaded_files = ();
|
||||||
|
# For all input files.
|
||||||
|
for (my $i = 0; $i < @$input_files; $i += 1) {
|
||||||
|
my $input_file = $input_files->[$i];
|
||||||
|
$process_dialog->Update(100. * $i / @$input_files, "Processing input file\n" . basename($input_file));
|
||||||
|
|
||||||
my $model = eval { Slic3r::Model->read_from_file($input_file, 0) };
|
my $model = eval { Slic3r::Model->read_from_file($input_file, 0) };
|
||||||
Slic3r::GUI::show_error($self, $@) if $@;
|
Slic3r::GUI::show_error($self, $@) if $@;
|
||||||
|
|
||||||
my @obj_idx = ();
|
next if ! defined $model;
|
||||||
if (defined $model) {
|
|
||||||
if ($model->looks_like_multipart_object) {
|
if ($model->looks_like_multipart_object) {
|
||||||
my $dialog = Wx::MessageDialog->new($self,
|
my $dialog = Wx::MessageDialog->new($self,
|
||||||
"This file contains several objects positioned at multiple heights. "
|
"This file contains several objects positioned at multiple heights. "
|
||||||
. "Instead of considering them as multiple objects, should I consider\n"
|
. "Instead of considering them as multiple objects, should I consider\n"
|
||||||
. "this file as a single object having multiple parts?\n",
|
. "this file as a single object having multiple parts?\n",
|
||||||
'Multi-part object detected', wxICON_WARNING | wxYES | wxNO);
|
'Multi-part object detected', wxICON_WARNING | wxYES | wxNO);
|
||||||
if ($dialog->ShowModal() == wxID_YES) {
|
$model->convert_multipart_object if $dialog->ShowModal() == wxID_YES;
|
||||||
$model->convert_multipart_object;
|
}
|
||||||
|
|
||||||
|
if ($one_by_one) {
|
||||||
|
push @obj_idx, $self->load_model_objects(@{$model->objects});
|
||||||
|
} else {
|
||||||
|
# This must be an .stl or .obj file, which may contain a maximum of one volume.
|
||||||
|
$new_model->add_object($_) for (@{$model->objects});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@obj_idx = $self->load_model_objects(@{$model->objects});
|
|
||||||
$self->statusbar->SetStatusText("Loaded " . basename($input_file));
|
if ($new_model) {
|
||||||
|
my $dialog = Wx::MessageDialog->new($self,
|
||||||
|
"Multiple objects were loaded for a multi-material printer.\n"
|
||||||
|
. "Instead of considering them as multiple objects, should I consider\n"
|
||||||
|
. "these files to represent a single object having multiple parts?\n",
|
||||||
|
'Multi-part object detected', wxICON_WARNING | wxYES | wxNO);
|
||||||
|
$new_model->convert_multipart_object if $dialog->ShowModal() == wxID_YES;
|
||||||
|
push @obj_idx, $self->load_model_objects(@{$new_model->objects});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Note the current directory for the file open dialog.
|
||||||
|
$Slic3r::GUI::Settings->{recent}{skein_directory} = dirname($input_files->[-1]);
|
||||||
|
wxTheApp->save_settings;
|
||||||
|
|
||||||
$process_dialog->Destroy;
|
$process_dialog->Destroy;
|
||||||
|
$self->statusbar->SetStatusText("Loaded " . join(',', @loaded_files));
|
||||||
return @obj_idx;
|
return @obj_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1579,7 +1610,7 @@ sub reload_from_disk {
|
|||||||
return if !$model_object->input_file
|
return if !$model_object->input_file
|
||||||
|| !-e $model_object->input_file;
|
|| !-e $model_object->input_file;
|
||||||
|
|
||||||
my @new_obj_idx = $self->load_file($model_object->input_file);
|
my @new_obj_idx = $self->load_files([$model_object->input_file]);
|
||||||
return if !@new_obj_idx;
|
return if !@new_obj_idx;
|
||||||
|
|
||||||
foreach my $new_obj_idx (@new_obj_idx) {
|
foreach my $new_obj_idx (@new_obj_idx) {
|
||||||
@ -2165,7 +2196,7 @@ sub OnDropFiles {
|
|||||||
# only accept STL, OBJ and AMF files
|
# only accept STL, OBJ and AMF files
|
||||||
return 0 if grep !/\.(?:stl|obj|amf(?:\.xml)?|prusa)$/i, @$filenames;
|
return 0 if grep !/\.(?:stl|obj|amf(?:\.xml)?|prusa)$/i, @$filenames;
|
||||||
|
|
||||||
$self->{window}->load_file($_) for @$filenames;
|
$self->{window}->load_files($filenames);
|
||||||
}
|
}
|
||||||
|
|
||||||
# 2D preview of an object. Each object is previewed by its convex hull.
|
# 2D preview of an object. Each object is previewed by its convex hull.
|
||||||
|
@ -111,10 +111,8 @@ if ((!@ARGV || $opt{gui}) && !$opt{save} && eval "require Slic3r::GUI; 1") {
|
|||||||
setlocale(LC_NUMERIC, 'C');
|
setlocale(LC_NUMERIC, 'C');
|
||||||
$gui->{mainframe}->load_config_file($_) for @{$opt{load}};
|
$gui->{mainframe}->load_config_file($_) for @{$opt{load}};
|
||||||
$gui->{mainframe}->load_config($cli_config);
|
$gui->{mainframe}->load_config($cli_config);
|
||||||
foreach my $input_file (@ARGV) {
|
my @input_files = map Slic3r::decode_path($_), @ARGV;
|
||||||
$input_file = Slic3r::decode_path($input_file);
|
$gui->{mainframe}{plater}->load_files(\@input_files) unless $opt{no_plater};
|
||||||
$gui->{mainframe}{plater}->load_file($input_file) unless $opt{no_plater};
|
|
||||||
}
|
|
||||||
$gui->MainLoop;
|
$gui->MainLoop;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user