Button to split loaded objects

This commit is contained in:
Alessandro Ranellucci 2012-05-01 00:30:46 +02:00
parent 91d1b21c40
commit 61e257388a
3 changed files with 78 additions and 30 deletions

View File

@ -50,6 +50,7 @@ sub new {
$self->{btn_reset} = Wx::Button->new($self, -1, "Delete All"); $self->{btn_reset} = Wx::Button->new($self, -1, "Delete All");
$self->{btn_arrange} = Wx::Button->new($self, -1, "Autoarrange"); $self->{btn_arrange} = Wx::Button->new($self, -1, "Autoarrange");
$self->{btn_changescale} = Wx::Button->new($self, -1, "Change Scale…"); $self->{btn_changescale} = Wx::Button->new($self, -1, "Change Scale…");
$self->{btn_split} = Wx::Button->new($self, -1, "Split");
$self->{btn_export_gcode} = Wx::Button->new($self, -1, "Export G-code…"); $self->{btn_export_gcode} = Wx::Button->new($self, -1, "Export G-code…");
$self->{btn_export_gcode}->SetDefault; $self->{btn_export_gcode}->SetDefault;
$self->{btn_export_stl} = Wx::Button->new($self, -1, "Export STL…"); $self->{btn_export_stl} = Wx::Button->new($self, -1, "Export STL…");
@ -66,6 +67,7 @@ sub new {
EVT_BUTTON($self, $self->{btn_arrange}, \&arrange); EVT_BUTTON($self, $self->{btn_arrange}, \&arrange);
EVT_BUTTON($self, $self->{btn_changescale}, \&changescale); EVT_BUTTON($self, $self->{btn_changescale}, \&changescale);
EVT_BUTTON($self, $self->{btn_rotate}, sub { $_[0]->rotate(undef) }); EVT_BUTTON($self, $self->{btn_rotate}, sub { $_[0]->rotate(undef) });
EVT_BUTTON($self, $self->{btn_split}, \&split_object);
EVT_BUTTON($self, $self->{btn_export_gcode}, \&export_gcode); EVT_BUTTON($self, $self->{btn_export_gcode}, \&export_gcode);
EVT_BUTTON($self, $self->{btn_export_stl}, \&export_stl); EVT_BUTTON($self, $self->{btn_export_stl}, \&export_stl);
@ -94,7 +96,7 @@ sub new {
my $buttons2 = Wx::BoxSizer->new(wxVERTICAL); my $buttons2 = Wx::BoxSizer->new(wxVERTICAL);
$buttons2->Add($self->{"btn_$_"}) $buttons2->Add($self->{"btn_$_"})
for qw(increase decrease rotate45cw rotate45ccw rotate changescale); for qw(increase decrease rotate45cw rotate45ccw rotate changescale split);
my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$buttons_sizer->Add($_) for ($buttons1, $buttons2); $buttons_sizer->Add($_) for ($buttons1, $buttons2);
@ -135,17 +137,25 @@ sub load_file {
my $process_dialog = Wx::ProgressDialog->new('Loading...', "Processing input file...", 100, $self, 0); my $process_dialog = Wx::ProgressDialog->new('Loading...', "Processing input file...", 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);
my $object = $self->{print}->add_object_from_file($input_file); $self->{print}->add_object_from_file($input_file);
my $obj_idx = $#{$self->{print}->objects}; my $obj_idx = $#{$self->{print}->objects};
$process_dialog->Destroy; $process_dialog->Destroy;
$self->{list}->InsertStringItem($obj_idx, basename($input_file)); $self->object_loaded($obj_idx);
}
sub object_loaded {
my $self = shift;
my ($obj_idx, %params) = @_;
my $object = $self->{print}->objects->[$obj_idx];
$self->{list}->InsertStringItem($obj_idx, basename($object->input_file));
$self->{list}->SetItem($obj_idx, 1, "1"); $self->{list}->SetItem($obj_idx, 1, "1");
$self->{list}->SetItem($obj_idx, 2, "100%"); $self->{list}->SetItem($obj_idx, 2, "100%");
push @{$self->{scale}}, 1; push @{$self->{scale}}, 1;
$self->make_thumbnail($obj_idx); $self->make_thumbnail($obj_idx);
$self->arrange; $self->arrange unless $params{no_arrange};
$self->{list}->Update; $self->{list}->Update;
$self->{list}->Select($obj_idx, 1); $self->{list}->Select($obj_idx, 1);
$self->object_list_changed; $self->object_list_changed;
@ -283,6 +293,25 @@ sub changescale {
$self->arrange; $self->arrange;
} }
sub split_object {
my $self = shift;
my $obj_idx = $self->selected_object_idx;
my $current_object = $self->{print}->objects->[$obj_idx];
my $mesh = $current_object->mesh->clone;
$mesh->scale($Slic3r::scaling_factor);
foreach my $mesh ($mesh->split_mesh) {
my $object = $self->{print}->add_object_from_mesh($mesh);
$object->input_file($current_object->input_file);
$self->object_loaded($#{$self->{print}->objects}, no_arrange => 1);
}
$self->{list}->Select($obj_idx, 1);
$self->remove;
$self->arrange;
}
sub export_gcode { sub export_gcode {
my $self = shift; my $self = shift;
@ -569,8 +598,8 @@ sub object_list_changed {
my $self = shift; my $self = shift;
my $method = $self->{print} && @{$self->{print}->objects} ? 'Enable' : 'Disable'; my $method = $self->{print} && @{$self->{print}->objects} ? 'Enable' : 'Disable';
$self->{$_}->$method $self->{"btn_$_"}->$method
for qw(btn_reset btn_arrange btn_export_gcode btn_export_stl); for qw(reset arrange export_gcode export_stl);
} }
sub selection_changed { sub selection_changed {
@ -578,9 +607,8 @@ sub selection_changed {
my ($have_sel) = @_; my ($have_sel) = @_;
my $method = $have_sel ? 'Enable' : 'Disable'; my $method = $have_sel ? 'Enable' : 'Disable';
$self->{$_}->$method $self->{"btn_$_"}->$method
for qw(btn_remove btn_increase btn_decrease btn_rotate45cw btn_rotate45ccw btn_rotate for qw(remove increase decrease rotate45cw rotate45ccw rotate changescale split);
btn_changescale);
} }
sub selected_object_idx { sub selected_object_idx {

View File

@ -490,4 +490,44 @@ sub get_connected_facets {
return keys %facets; return keys %facets;
} }
sub split_mesh {
my $self = shift;
my @meshes = ();
# loop while we have remaining facets
while (1) {
# get the first facet
my @facet_queue = ();
my @facets = ();
for (my $i = 0; $i <= $#{$self->facets}; $i++) {
if (defined $self->facets->[$i]) {
push @facet_queue, $i;
last;
}
}
last if !@facet_queue;
while (defined (my $facet_id = shift @facet_queue)) {
next unless defined $self->facets->[$facet_id];
push @facets, map [ @$_ ], $self->facets->[$facet_id];
push @facet_queue, $self->get_connected_facets($facet_id);
$self->facets->[$facet_id] = undef;
}
my %vertices = map { $_ => 1 } map @$_[1,2,3], @facets;
my @new_vertices = keys %vertices;
my %new_vertices = map { $new_vertices[$_] => $_ } 0..$#new_vertices;
foreach my $facet (@facets) {
$facet->[$_] = $new_vertices{$facet->[$_]} for 1,2,3;
}
push @meshes, Slic3r::TriangleMesh->new(
facets => \@facets,
vertices => [ map $self->vertices->[$_], keys %vertices ],
);
}
return @meshes;
}
1; 1;

View File

@ -29,30 +29,10 @@ my %opt = ();
my $basename = $ARGV[0]; my $basename = $ARGV[0];
$basename =~ s/\.stl$//i; $basename =~ s/\.stl$//i;
# loop while we have remaining facets
my $part_count = 0; my $part_count = 0;
while (1) { foreach my $new_mesh ($mesh->split_mesh) {
# get the first facet
my @facet_queue = ();
my @facets = ();
for (my $i = 0; $i <= $#{$mesh->facets}; $i++) {
if (defined $mesh->facets->[$i]) {
push @facet_queue, $i;
last;
}
}
last if !@facet_queue;
while (defined (my $facet_id = shift @facet_queue)) {
next unless defined $mesh->facets->[$facet_id];
push @facets, $mesh->facets->[$facet_id];
push @facet_queue, $mesh->get_connected_facets($facet_id);
$mesh->facets->[$facet_id] = undef;
}
my $output_file = sprintf '%s_%02d.stl', $basename, ++$part_count; my $output_file = sprintf '%s_%02d.stl', $basename, ++$part_count;
printf "Writing to %s\n", basename($output_file); printf "Writing to %s\n", basename($output_file);
my $new_mesh = Slic3r::TriangleMesh->new(facets => \@facets, vertices => $mesh->vertices);
Slic3r::Format::STL->write_file($output_file, $new_mesh, !$opt{ascii}); Slic3r::Format::STL->write_file($output_file, $new_mesh, !$opt{ascii});
} }
} }