Refactoring: new Slic3r::Model class to represent files
This commit is contained in:
parent
c0322ec703
commit
f90520ed06
1
MANIFEST
1
MANIFEST
@ -15,6 +15,7 @@ lib/Slic3r/Fill/Flowsnake.pm
|
||||
lib/Slic3r/Fill/HilbertCurve.pm
|
||||
lib/Slic3r/Fill/Honeycomb.pm
|
||||
lib/Slic3r/Fill/Line.pm
|
||||
lib/Slic3r/Fill/Model.pm
|
||||
lib/Slic3r/Fill/OctagramSpiral.pm
|
||||
lib/Slic3r/Fill/PlanePath.pm
|
||||
lib/Slic3r/Fill/Rectilinear.pm
|
||||
|
@ -41,6 +41,7 @@ use Slic3r::GCode;
|
||||
use Slic3r::Geometry qw(PI);
|
||||
use Slic3r::Layer;
|
||||
use Slic3r::Line;
|
||||
use Slic3r::Model;
|
||||
use Slic3r::Point;
|
||||
use Slic3r::Polygon;
|
||||
use Slic3r::Polyline;
|
||||
|
@ -25,15 +25,21 @@ sub read_file {
|
||||
|
||||
close $fh;
|
||||
|
||||
$_ = Slic3r::TriangleMesh->new(vertices => $vertices, facets => $_)
|
||||
for values %$meshes_by_material;
|
||||
|
||||
return $materials, $meshes_by_material;
|
||||
my $model = Slic3r::Model->new;
|
||||
my $object = $model->add_object(vertices => $vertices);
|
||||
foreach my $material (keys %$meshes_by_material) {
|
||||
push @{$model->materials}, $material; # TODO: we should not add duplicate materials
|
||||
$object->add_volume(
|
||||
material_id => $#{$model->materials},
|
||||
facets => $meshes_by_material->{$material},
|
||||
);
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
|
||||
sub write_file {
|
||||
my $self = shift;
|
||||
my ($file, $materials, $meshes_by_material) = @_;
|
||||
my ($file, $model, %params) = @_;
|
||||
|
||||
my %vertices_offset = ();
|
||||
|
||||
@ -42,20 +48,20 @@ sub write_file {
|
||||
printf $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
|
||||
printf $fh qq{<amf unit="millimeter">\n};
|
||||
printf $fh qq{ <metadata type="cad">Slic3r %s</metadata>\n}, $Slic3r::VERSION;
|
||||
foreach my $material_id (keys %$materials) {
|
||||
printf $fh qq{ <material id="%s">\n}, $material_id;
|
||||
for (keys %{$materials->{$material_id}}) {
|
||||
printf $fh qq{ <metadata type=\"%s\">%s</metadata>\n}, $_, $materials->{$material_id}{$_};
|
||||
for my $material_id (0 .. $#{ $model->materials }) {
|
||||
my $material = $model->materials->[$material_id];
|
||||
printf $fh qq{ <material id="%d">\n}, $material_id;
|
||||
for (keys %$material) {
|
||||
printf $fh qq{ <metadata type=\"%s\">%s</metadata>\n}, $_, $material->{$_};
|
||||
}
|
||||
printf $fh qq{ </material>\n};
|
||||
}
|
||||
printf $fh qq{ <object id="0">\n};
|
||||
printf $fh qq{ <mesh>\n};
|
||||
printf $fh qq{ <vertices>\n};
|
||||
my $vertices_count = 0;
|
||||
foreach my $mesh (values %$meshes_by_material) {
|
||||
$vertices_offset{$mesh} = $vertices_count;
|
||||
foreach my $vertex (@{$mesh->vertices}, ) {
|
||||
for my $object_id (0 .. $#{ $model->objects }) {
|
||||
my $object = $model->objects->[$object_id];
|
||||
printf $fh qq{ <object id="%d">\n}, $object_id;
|
||||
printf $fh qq{ <mesh>\n};
|
||||
printf $fh qq{ <vertices>\n};
|
||||
foreach my $vertex (@{$object->vertices}, ) {
|
||||
printf $fh qq{ <vertex>\n};
|
||||
printf $fh qq{ <coordinates>\n};
|
||||
printf $fh qq{ <x>%s</x>\n}, $vertex->[X];
|
||||
@ -63,24 +69,21 @@ sub write_file {
|
||||
printf $fh qq{ <z>%s</z>\n}, $vertex->[Z];
|
||||
printf $fh qq{ </coordinates>\n};
|
||||
printf $fh qq{ </vertex>\n};
|
||||
$vertices_count++;
|
||||
}
|
||||
}
|
||||
printf $fh qq{ </vertices>\n};
|
||||
foreach my $material_id (sort keys %$meshes_by_material) {
|
||||
my $mesh = $meshes_by_material->{$material_id};
|
||||
printf $fh qq{ <volume%s>\n},
|
||||
($material_id eq '_') ? '' : " materialid=\"$material_id\"";
|
||||
foreach my $facet (@{$mesh->facets}) {
|
||||
printf $fh qq{ <triangle>\n};
|
||||
printf $fh qq{ <v%d>%d</v%d>\n}, $_, $facet->[$_] + $vertices_offset{$mesh}, $_
|
||||
for -3..-1;
|
||||
printf $fh qq{ </triangle>\n};
|
||||
printf $fh qq{ </vertices>\n};
|
||||
foreach my $volume (@{ $object->volumes }) {
|
||||
printf $fh qq{ <volume%s>\n},
|
||||
(!defined $volume->material_id) ? '' : (sprintf ' materialid="%s"', $volume->material_id);
|
||||
foreach my $facet (@{$volume->facets}) {
|
||||
printf $fh qq{ <triangle>\n};
|
||||
printf $fh qq{ <v%d>%d</v%d>\n}, $_, $facet->[$_], $_ for -3..-1;
|
||||
printf $fh qq{ </triangle>\n};
|
||||
}
|
||||
printf $fh qq{ </volume>\n};
|
||||
}
|
||||
printf $fh qq{ </volume>\n};
|
||||
printf $fh qq{ </mesh>\n};
|
||||
printf $fh qq{ </object>\n};
|
||||
}
|
||||
printf $fh qq{ </mesh>\n};
|
||||
printf $fh qq{ </object>\n};
|
||||
printf $fh qq{</amf>\n};
|
||||
close $fh;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ sub end_element {
|
||||
} elsif ($data->{LocalName} eq 'triangle') {
|
||||
push @{$self->{_volume}}, $self->{_triangle};
|
||||
$self->{_triangle} = undef;
|
||||
} elsif ($self->{_vertex_idx} && $data->{LocalName} =~ /^v[123]$/) {
|
||||
} elsif (defined $self->{_vertex_idx} && $data->{LocalName} =~ /^v[123]$/) {
|
||||
$self->{_vertex_idx} = undef;
|
||||
} elsif ($data->{LocalName} eq 'material') {
|
||||
$self->{_materials}{ $self->{_material_id} } = $self->{_material};
|
||||
|
@ -17,7 +17,10 @@ sub read_file {
|
||||
}
|
||||
close $fh;
|
||||
|
||||
return Slic3r::TriangleMesh->new(vertices => $vertices, facets => $facets);
|
||||
my $model = Slic3r::Model->new;
|
||||
my $object = $model->add_object(vertices => $vertices);
|
||||
my $volume = $object->add_volume(facets => $facets);
|
||||
return $model;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -117,7 +117,10 @@ sub read_file {
|
||||
}
|
||||
}
|
||||
|
||||
return Slic3r::TriangleMesh->new(vertices => $vertices, facets => $facets);
|
||||
my $model = Slic3r::Model->new;
|
||||
my $object = $model->add_object(vertices => $vertices);
|
||||
my $volume = $object->add_volume(facets => $facets);
|
||||
return $model;
|
||||
}
|
||||
|
||||
sub _read_ascii {
|
||||
@ -161,13 +164,13 @@ sub _read_binary {
|
||||
|
||||
sub write_file {
|
||||
my $self = shift;
|
||||
my ($file, $mesh, $binary) = @_;
|
||||
my ($file, $model, %params) = @_;
|
||||
|
||||
open my $fh, '>', $file;
|
||||
|
||||
$binary
|
||||
? _write_binary($fh, $mesh)
|
||||
: _write_ascii($fh, $mesh);
|
||||
$params{binary}
|
||||
? _write_binary($fh, $model->mesh)
|
||||
: _write_ascii($fh, $model->mesh);
|
||||
|
||||
close $fh;
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ sub load_file {
|
||||
my $process_dialog = Wx::ProgressDialog->new('Loading…', "Processing input file…", 100, $self, 0);
|
||||
$process_dialog->Pulse;
|
||||
local $SIG{__WARN__} = Slic3r::GUI::warning_catcher($self);
|
||||
$self->{print}->add_object_from_file($input_file);
|
||||
$self->{print}->add_objects_from_file($input_file);
|
||||
my $obj_idx = $#{$self->{print}->objects};
|
||||
$process_dialog->Destroy;
|
||||
|
||||
@ -630,13 +630,11 @@ sub on_export_failed {
|
||||
|
||||
sub export_stl {
|
||||
my $self = shift;
|
||||
|
||||
my $print = $self->{print};
|
||||
|
||||
# select output file
|
||||
my $output_file = $main::opt{output};
|
||||
{
|
||||
$output_file = $print->expanded_output_filepath($output_file);
|
||||
$output_file = $self->{print}->expanded_output_filepath($output_file);
|
||||
$output_file =~ s/\.gcode$/.stl/i;
|
||||
my $dlg = Wx::FileDialog->new($self, 'Save STL file as:', dirname($output_file),
|
||||
basename($output_file), $Slic3r::GUI::SkeinPanel::model_wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||
@ -648,21 +646,26 @@ sub export_stl {
|
||||
$dlg->Destroy;
|
||||
}
|
||||
|
||||
my $mesh = Slic3r::TriangleMesh->new(facets => [], vertices => []);
|
||||
for my $obj_idx (0 .. $#{$print->objects}) {
|
||||
for my $copy (@{$print->copies->[$obj_idx]}) {
|
||||
my $cloned_mesh = $print->objects->[$obj_idx]->mesh->clone;
|
||||
$cloned_mesh->move(@$copy);
|
||||
my $vertices_offset = scalar @{$mesh->vertices};
|
||||
push @{$mesh->vertices}, @{$cloned_mesh->vertices};
|
||||
push @{$mesh->facets}, map [ $_->[0], map $vertices_offset + $_, @$_[-3..-1] ], @{$cloned_mesh->facets};
|
||||
Slic3r::Format::STL->write_file($output_file, $self->make_model, binary => 1);
|
||||
$self->statusbar->SetStatusText("STL file exported to $output_file");
|
||||
}
|
||||
|
||||
sub make_model {
|
||||
my $self = shift;
|
||||
|
||||
my $model = Slic3r::Model->new;
|
||||
for my $obj_idx (0 .. $#{$self->{print}->objects}) {
|
||||
my $mesh = $self->{print}->objects->[$obj_idx]->mesh->clone;
|
||||
$mesh->scale(&Slic3r::SCALING_FACTOR);
|
||||
my $object = $model->add_object(vertices => $mesh->vertices);
|
||||
$object->add_volume(facets => $mesh->facets);
|
||||
for my $copy (@{$self->{print}->copies->[$obj_idx]}) {
|
||||
$object->add_instance(rotation => 0, offset => [ map unscale $_, @$copy ]);
|
||||
}
|
||||
}
|
||||
$mesh->scale(&Slic3r::SCALING_FACTOR);
|
||||
$mesh->align_to_origin;
|
||||
# TODO: $model->align_to_origin;
|
||||
|
||||
Slic3r::Format::STL->write_file($output_file, $mesh, 1);
|
||||
$self->statusbar->SetStatusText("STL file exported to $output_file");
|
||||
return $model;
|
||||
}
|
||||
|
||||
sub make_thumbnail {
|
||||
|
@ -96,7 +96,7 @@ sub do_slice {
|
||||
Slic3r::GUI->save_settings;
|
||||
|
||||
my $print = Slic3r::Print->new(config => $config);
|
||||
$print->add_object_from_file($input_file);
|
||||
$print->add_objects_from_file($input_file);
|
||||
$print->validate;
|
||||
|
||||
# select output file
|
||||
|
112
lib/Slic3r/Model.pm
Normal file
112
lib/Slic3r/Model.pm
Normal file
@ -0,0 +1,112 @@
|
||||
package Slic3r::Model;
|
||||
use Moo;
|
||||
|
||||
use Slic3r::Geometry qw(X Y Z);
|
||||
|
||||
has 'materials' => (is => 'ro', default => sub { [] });
|
||||
has 'objects' => (is => 'ro', default => sub { [] });
|
||||
|
||||
sub add_object {
|
||||
my $self = shift;
|
||||
|
||||
my $object = Slic3r::Model::Object->new(model => $self, @_);
|
||||
push @{$self->objects}, $object;
|
||||
return $object;
|
||||
}
|
||||
|
||||
# flattens everything to a single mesh
|
||||
sub mesh {
|
||||
my $self = shift;
|
||||
|
||||
my $vertices = [];
|
||||
my $facets = [];
|
||||
foreach my $object (@{$self->objects}) {
|
||||
my @instances = $object->instances ? @{$object->instances} : (undef);
|
||||
foreach my $instance (@instances) {
|
||||
my @vertices = @{$object->vertices};
|
||||
if ($instance) {
|
||||
# save Z coordinates, as rotation and translation discard them
|
||||
my @z = map $_->[Z], @vertices;
|
||||
|
||||
if ($instance->rotation) {
|
||||
# transform vertex coordinates
|
||||
my $rad = Slic3r::Geometry::deg2rad($instance->rotation);
|
||||
@vertices = Slic3r::Geometry::rotate_points($rad, undef, @vertices);
|
||||
}
|
||||
@vertices = Slic3r::Geometry::move_points($instance->offset, @vertices);
|
||||
|
||||
# reapply Z coordinates
|
||||
$vertices[$_][Z] = $z[$_] for 0 .. $#z;
|
||||
}
|
||||
|
||||
my $v_offset = @$vertices;
|
||||
push @$vertices, @vertices;
|
||||
foreach my $volume (@{$object->volumes}) {
|
||||
push @$facets, map {
|
||||
my $f = [@$_];
|
||||
$f->[$_] += $v_offset for -3..-1;
|
||||
$f;
|
||||
} @{$volume->facets};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Slic3r::TriangleMesh->new(
|
||||
vertices => $vertices,
|
||||
facets => $facets,
|
||||
);
|
||||
}
|
||||
|
||||
package Slic3r::Model::Material;
|
||||
use Moo;
|
||||
|
||||
has 'model' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'attributes' => (is => 'rw', default => sub { {} });
|
||||
|
||||
package Slic3r::Model::Object;
|
||||
use Moo;
|
||||
|
||||
has 'model' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'vertices' => (is => 'ro', default => sub { [] });
|
||||
has 'volumes' => (is => 'ro', default => sub { [] });
|
||||
has 'instances' => (is => 'rw');
|
||||
|
||||
sub add_volume {
|
||||
my $self = shift;
|
||||
|
||||
my $volume = Slic3r::Model::Volume->new(object => $self, @_);
|
||||
push @{$self->volumes}, $volume;
|
||||
return $volume;
|
||||
}
|
||||
|
||||
sub add_instance {
|
||||
my $self = shift;
|
||||
|
||||
$self->instances([]) if !defined $self->instances;
|
||||
push @{$self->instances}, Slic3r::Model::Instance->new(object => $self, @_);
|
||||
return $self->instances->[-1];
|
||||
}
|
||||
|
||||
package Slic3r::Model::Volume;
|
||||
use Moo;
|
||||
|
||||
has 'object' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'material_id' => (is => 'rw');
|
||||
has 'facets' => (is => 'rw', default => sub { [] });
|
||||
|
||||
sub mesh {
|
||||
my $self = shift;
|
||||
return Slic3r::TriangleMesh->new(
|
||||
vertices => $self->object->vertices,
|
||||
facets => $self->facets,
|
||||
);
|
||||
}
|
||||
|
||||
package Slic3r::Model::Instance;
|
||||
use Moo;
|
||||
|
||||
has 'object' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'rotation' => (is => 'rw', default => sub { 0 });
|
||||
has 'offset' => (is => 'rw');
|
||||
|
||||
1;
|
@ -79,28 +79,43 @@ sub _trigger_config {
|
||||
$self->config->set_ifndef('top_solid_infill_speed', $self->config->solid_infill_speed);
|
||||
}
|
||||
|
||||
sub add_object_from_file {
|
||||
sub add_objects_from_file {
|
||||
my $self = shift;
|
||||
my ($input_file) = @_;
|
||||
|
||||
my $object;
|
||||
if ($input_file =~ /\.stl$/i) {
|
||||
my $mesh = Slic3r::Format::STL->read_file($input_file);
|
||||
my $model = $input_file =~ /\.stl$/i ? Slic3r::Format::STL->read_file($input_file)
|
||||
: $input_file =~ /\.obj$/i ? Slic3r::Format::OBJ->read_file($input_file)
|
||||
: $input_file =~ /\.amf(\.xml)?$/i ? Slic3r::Format::AMF->read_file($input_file)
|
||||
: die "Input file must have .stl, .obj or .amf(.xml) extension\n";
|
||||
|
||||
my @print_objects = $self->add_model($model);
|
||||
$_->input_file($input_file) for @print_objects;
|
||||
}
|
||||
|
||||
sub add_model {
|
||||
my $self = shift;
|
||||
my ($model) = @_;
|
||||
|
||||
my @print_objects = ();
|
||||
foreach my $object (@{ $model->objects }) {
|
||||
my $mesh = $object->volumes->[0]->mesh;
|
||||
$mesh->check_manifoldness;
|
||||
$object = $self->add_object_from_mesh($mesh);
|
||||
} elsif ($input_file =~ /\.obj$/i) {
|
||||
my $mesh = Slic3r::Format::OBJ->read_file($input_file);
|
||||
$mesh->check_manifoldness;
|
||||
$object = $self->add_object_from_mesh($mesh);
|
||||
} elsif ( $input_file =~ /\.amf(\.xml)?$/i) {
|
||||
my ($materials, $meshes_by_material) = Slic3r::Format::AMF->read_file($input_file);
|
||||
$_->check_manifoldness for values %$meshes_by_material;
|
||||
$object = $self->add_object_from_mesh($meshes_by_material->{_} || +(values %$meshes_by_material)[0]);
|
||||
} else {
|
||||
die "Input file must have .stl, .obj or .amf(.xml) extension\n";
|
||||
|
||||
if ($object->instances) {
|
||||
# we ignore the per-instance rotation currently and only
|
||||
# consider the first one
|
||||
$mesh->rotate($object->instances->[0]->rotation);
|
||||
}
|
||||
|
||||
push @print_objects, $self->add_object_from_mesh($mesh);
|
||||
|
||||
if ($object->instances) {
|
||||
# replace the default [0,0] instance with the custom ones
|
||||
@{$self->copies->[-1]} = map [ scale $_->offset->[X], scale $_->offset->[X] ], @{$object->instances};
|
||||
}
|
||||
}
|
||||
$object->input_file($input_file);
|
||||
return $object;
|
||||
|
||||
return @print_objects;
|
||||
}
|
||||
|
||||
sub add_object_from_mesh {
|
||||
|
@ -88,9 +88,9 @@ if (@ARGV) { # slicing from command line
|
||||
|
||||
while (my $input_file = shift @ARGV) {
|
||||
my $print = Slic3r::Print->new(config => $config);
|
||||
$print->add_object_from_file($input_file);
|
||||
$print->add_objects_from_file($input_file);
|
||||
if ($opt{merge}) {
|
||||
$print->add_object_from_file($_) for splice @ARGV, 0;
|
||||
$print->add_objects_from_file($_) for splice @ARGV, 0;
|
||||
}
|
||||
$print->duplicate;
|
||||
$print->arrange_objects if @{$print->objects} > 1;
|
||||
|
@ -25,12 +25,12 @@ my %opt = ();
|
||||
}
|
||||
|
||||
{
|
||||
my $mesh = Slic3r::Format::AMF->read_file($ARGV[0]);
|
||||
my $model = Slic3r::Format::AMF->read_file($ARGV[0]);
|
||||
my $output_file = $ARGV[0];
|
||||
$output_file =~ s/\.amf(?:\.xml)?$/\.stl/i;
|
||||
|
||||
printf "Writing to %s\n", basename($output_file);
|
||||
Slic3r::Format::STL->write_file($output_file, $mesh, !$opt{ascii});
|
||||
Slic3r::Format::STL->write_file($output_file, $model, binary => !$opt{ascii});
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,15 +25,20 @@ my %opt = ();
|
||||
}
|
||||
|
||||
{
|
||||
my $mesh = Slic3r::Format::STL->read_file($ARGV[0]);
|
||||
my $model = Slic3r::Format::STL->read_file($ARGV[0]);
|
||||
my $basename = $ARGV[0];
|
||||
$basename =~ s/\.stl$//i;
|
||||
|
||||
my $part_count = 0;
|
||||
foreach my $new_mesh ($mesh->split_mesh) {
|
||||
foreach my $new_mesh ($model->mesh->split_mesh) {
|
||||
my $new_model = Slic3r::Model->new;
|
||||
$new_model
|
||||
->add_object(vertices => $new_mesh->vertices)
|
||||
->add_volume(facets => $new_mesh->facets);
|
||||
|
||||
my $output_file = sprintf '%s_%02d.stl', $basename, ++$part_count;
|
||||
printf "Writing to %s\n", basename($output_file);
|
||||
Slic3r::Format::STL->write_file($output_file, $new_mesh, !$opt{ascii});
|
||||
Slic3r::Format::STL->write_file($output_file, $new_model, binary => !$opt{ascii});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,29 +18,49 @@ my %opt = ();
|
||||
{
|
||||
my %options = (
|
||||
'help' => sub { usage() },
|
||||
'distinct-materials' => \$opt{distinct_materials},
|
||||
);
|
||||
GetOptions(%options) or usage(1);
|
||||
$ARGV[0] or usage(1);
|
||||
}
|
||||
|
||||
{
|
||||
my @meshes = map Slic3r::Format::STL->read_file($_), @ARGV;
|
||||
my @models = map Slic3r::Format::STL->read_file($_), @ARGV;
|
||||
my $output_file = $ARGV[0];
|
||||
$output_file =~ s/\.stl$/.amf.xml/i;
|
||||
|
||||
my $materials = {};
|
||||
my $meshes_by_material = {};
|
||||
if (@meshes == 1) {
|
||||
$meshes_by_material->{_} = $meshes[0];
|
||||
my $new_model = Slic3r::Model->new;
|
||||
|
||||
if ($opt{distinct_materials} && @models > 1) {
|
||||
my $new_object = $new_model->add_object;
|
||||
for my $m (0 .. $#models) {
|
||||
my $model = $models[$m];
|
||||
my $v_offset = @{$new_object->vertices};
|
||||
push @{$new_object->vertices}, @{$model->objects->[0]->vertices};
|
||||
my @new_facets = map {
|
||||
my $f = [@$_];
|
||||
$f->[$_] += $v_offset for -3..-1;
|
||||
$f;
|
||||
} @{ $model->objects->[0]->volumes->[0]->facets };
|
||||
|
||||
push @{$new_model->materials}, { Name => basename($ARGV[$m]) };
|
||||
$new_object->add_volume(
|
||||
material_id => $#{$new_model->materials},
|
||||
facets => [@new_facets],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (0..$#meshes) {
|
||||
$materials->{$_+1} = { Name => basename($ARGV[$_]) };
|
||||
$meshes_by_material->{$_+1} = $meshes[$_];
|
||||
foreach my $model (@models) {
|
||||
$new_model->add_object(
|
||||
vertices => $model->objects->[0]->vertices,
|
||||
)->add_volume(
|
||||
facets => $model->objects->[0]->volumes->[0]->facets,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
printf "Writing to %s\n", basename($output_file);
|
||||
Slic3r::Format::AMF->write_file($output_file, $materials, $meshes_by_material);
|
||||
Slic3r::Format::AMF->write_file($output_file, $new_model);
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +71,7 @@ sub usage {
|
||||
Usage: amf-to-stl.pl [ OPTIONS ] file.stl [ file2.stl [ file3.stl ] ]
|
||||
|
||||
--help Output this usage screen and exit
|
||||
--distinct-materials Assign each STL file to a different material
|
||||
|
||||
EOF
|
||||
exit ($exit_code || 0);
|
||||
|
Loading…
Reference in New Issue
Block a user