From f0f550783febed5d34d19959bab96afcbaa7069b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 27 Feb 2017 00:38:30 +0100 Subject: [PATCH] Good bye, Perl Expat binding! --- Build.PL | 11 +-- lib/Slic3r.pm | 1 - lib/Slic3r/Format/AMF.pm | 21 ---- lib/Slic3r/Format/AMF/Parser.pm | 164 -------------------------------- lib/Slic3r/Format/OBJ.pm | 34 ------- lib/Slic3r/Format/STL.pm | 22 ----- utils/amf-to-stl.pl | 2 +- 7 files changed, 2 insertions(+), 253 deletions(-) delete mode 100644 lib/Slic3r/Format/AMF/Parser.pm delete mode 100644 lib/Slic3r/Format/OBJ.pm diff --git a/Build.PL b/Build.PL index 321a7e4dd..d220df94d 100644 --- a/Build.PL +++ b/Build.PL @@ -28,7 +28,6 @@ my %prereqs = qw( ); my %recommends = qw( Class::XSAccessor 0 - XML::SAX::ExpatXS 0 Test::Harness 0 ); @@ -125,15 +124,7 @@ EOF if $module =~ /^(?:OpenGL|Test::Harness)$/; push @cmd, "$module~$version"; - if ($module eq 'XML::SAX::ExpatXS' && $^O eq 'MSWin32') { - my $mingw = 'C:\dev\CitrusPerl\mingw64'; - $mingw = 'C:\dev\CitrusPerl\mingw32' if !-d $mingw; - if (!-d $mingw) { - print "Could not find the MinGW directory at $mingw; skipping XML::SAX::ExpatXS (only needed for faster parsing of AMF files)\n"; - } else { - push @cmd, sprintf('--configure-args="EXPATLIBPATH=%s\lib EXPATINCPATH=%s\include"', $mingw, $mingw); - } - } + my $res = system @cmd; if ($res != 0) { if (exists $prereqs{$module}) { diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 31e2c29a2..9719f1d32 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -62,7 +62,6 @@ use Slic3r::ExtrusionLoop; use Slic3r::ExtrusionPath; use Slic3r::Flow; use Slic3r::Format::AMF; -use Slic3r::Format::OBJ; use Slic3r::Format::STL; use Slic3r::GCode::ArcFitting; use Slic3r::GCode::MotionPlanner; diff --git a/lib/Slic3r/Format/AMF.pm b/lib/Slic3r/Format/AMF.pm index 9aa0ca7c1..603a4014a 100644 --- a/lib/Slic3r/Format/AMF.pm +++ b/lib/Slic3r/Format/AMF.pm @@ -3,27 +3,6 @@ use Moo; use Slic3r::Geometry qw(X Y Z); -sub read_file { - my $self = shift; - my ($file) = @_; - - eval qq{ - require Slic3r::Format::AMF::Parser; - use XML::SAX::ParserFactory; - 1; - } or die "AMF parsing requires XML::SAX\n"; - - Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n"; - - my $model = Slic3r::Model->new; - XML::SAX::ParserFactory - ->parser(Handler => Slic3r::Format::AMF::Parser->new(_model => $model)) - ->parse_file($fh); - close $fh; - - return $model; -} - sub write_file { my $self = shift; my ($file, $model, %params) = @_; diff --git a/lib/Slic3r/Format/AMF/Parser.pm b/lib/Slic3r/Format/AMF/Parser.pm deleted file mode 100644 index 0ea3affb0..000000000 --- a/lib/Slic3r/Format/AMF/Parser.pm +++ /dev/null @@ -1,164 +0,0 @@ -package Slic3r::Format::AMF::Parser; -use strict; -use warnings; - -use base 'XML::SAX::Base'; - -my %xyz_index = (x => 0, y => 1, z => 2); #= - -sub new { - my $self = shift->SUPER::new(@_); - $self->{_tree} = []; - $self->{_objects_map} = {}; # this hash maps AMF object IDs to object indexes in $model->objects - $self->{_instances} = {}; # apply these lazily to make sure all objects have been parsed - $self; -} - -sub start_element { - my $self = shift; - my $data = shift; - - if ($data->{LocalName} eq 'object') { - $self->{_object} = $self->{_model}->add_object; - $self->{_object_vertices} = []; - $self->{_objects_map}{ $self->_get_attribute($data, 'id') } = $#{ $self->{_model}->objects }; - } elsif ($data->{LocalName} eq 'vertex') { - $self->{_vertex} = ["", "", ""]; - } elsif ($self->{_vertex} && $data->{LocalName} =~ /^[xyz]$/ && $self->{_tree}[-1] eq 'coordinates') { - $self->{_coordinate} = $data->{LocalName}; - } elsif ($data->{LocalName} eq 'volume') { - $self->{_volume} = $self->{_object}->add_volume( - material_id => $self->_get_attribute($data, 'materialid') // undef, - mesh => Slic3r::TriangleMesh->new, - ); - $self->{_volume_facets} = []; - } elsif ($data->{LocalName} eq 'triangle') { - $self->{_triangle} = ["", "", ""]; - } elsif ($self->{_triangle} && $data->{LocalName} =~ /^v([123])$/ && $self->{_tree}[-1] eq 'triangle') { - $self->{_vertex_idx} = $1-1; - } elsif ($data->{LocalName} eq 'material') { - my $material_id = $self->_get_attribute($data, 'id') // '_'; - $self->{_material} = $self->{_model}->set_material($material_id); - } elsif ($data->{LocalName} eq 'metadata') { - $self->{_metadata_type} = $self->_get_attribute($data, 'type'); - $self->{_metadata_value} = ''; - } elsif ($data->{LocalName} eq 'constellation') { - $self->{_constellation} = 1; # we merge all constellations as we don't support more than one - } elsif ($data->{LocalName} eq 'instance' && $self->{_constellation}) { - my $object_id = $self->_get_attribute($data, 'objectid'); - $self->{_instances}{$object_id} ||= []; - push @{ $self->{_instances}{$object_id} }, $self->{_instance} = {}; - } elsif ($data->{LocalName} =~ /^(?:deltax|deltay|rz)$/ && $self->{_instance}) { - $self->{_instance_property} = $data->{LocalName}; - } - - push @{$self->{_tree}}, $data->{LocalName}; -} - -sub characters { - my $self = shift; - my $data = shift; - - if ($self->{_vertex} && $self->{_coordinate}) { - $self->{_vertex}[ $xyz_index{$self->{_coordinate}} ] .= $data->{Data}; - } elsif ($self->{_triangle} && defined $self->{_vertex_idx}) { - $self->{_triangle}[ $self->{_vertex_idx} ] .= $data->{Data}; - } elsif ($self->{_metadata_type}) { - $self->{_metadata_value} .= $data->{Data}; - } elsif ($self->{_instance_property}) { - $self->{_instance}{ $self->{_instance_property} } .= $data->{Data}; - } -} - -sub end_element { - my $self = shift; - my $data = shift; - - pop @{$self->{_tree}}; - - if ($data->{LocalName} eq 'object') { - $self->{_object} = undef; - $self->{_object_vertices} = undef; - } elsif ($data->{LocalName} eq 'vertex') { - push @{$self->{_object_vertices}}, $self->{_vertex}; - $self->{_vertex} = undef; - } elsif ($self->{_coordinate} && $data->{LocalName} =~ /^[xyz]$/) { - $self->{_coordinate} = undef; - } elsif ($data->{LocalName} eq 'volume') { - $self->{_volume}->mesh->ReadFromPerl($self->{_object_vertices}, $self->{_volume_facets}); - $self->{_volume}->mesh->repair; - $self->{_volume} = undef; - $self->{_volume_facets} = undef; - } elsif ($data->{LocalName} eq 'triangle') { - push @{$self->{_volume_facets}}, $self->{_triangle}; - $self->{_triangle} = undef; - } elsif (defined $self->{_vertex_idx} && $data->{LocalName} =~ /^v[123]$/) { - $self->{_vertex_idx} = undef; - } elsif ($data->{LocalName} eq 'material') { - $self->{_material} = undef; - } elsif ($data->{LocalName} eq 'metadata') { - my $value = $self->{_metadata_value}; - if ($self->{_metadata_type} eq 'slic3r.layer_height_profile') { - my @layer_height_profile = split(';', $value); - $self->{_object}->set_layer_height_profile(\@layer_height_profile) if ($self->{_object}); - } elsif ($self->{_metadata_type} =~ /^slic3r\.(.+)/) { - my $opt_key = $1; - if (exists $Slic3r::Config::Options->{$opt_key}) { - my $config; - if ($self->{_material}) { - $config = $self->{_material}->config; - } elsif ($self->{_volume}) { - $config = $self->{_volume}->config; - } elsif ($self->{_object}) { - $config = $self->{_object}->config; - } - - $config->set_deserialize($opt_key, $value) if defined $config; - } elsif ($opt_key eq 'modifier' && $self->{_volume}) { - $self->{_volume}->set_modifier($value); - } - } elsif ($self->{_metadata_type} eq 'name') { - my $obj = $self->{_volume} // $self->{_object}; - $obj->set_name($value) if $obj; - } elsif ($self->{_material}) { - $self->{_material}->set_attribute($self->{_metadata_type}, $value); - } - $self->{_metadata_type} = undef; - $self->{_metadata_value} = undef; - } elsif ($data->{LocalName} eq 'constellation') { - $self->{_constellation} = undef; - } elsif ($data->{LocalName} eq 'instance') { - $self->{_instance} = undef; - } elsif ($data->{LocalName} =~ /^(?:deltax|deltay|rz)$/ && $self->{_instance}) { - $self->{_instance_property} = undef; - } -} - -sub end_document { - my $self = shift; - - foreach my $object_id (keys %{ $self->{_instances} }) { - my $new_object_id = $self->{_objects_map}{$object_id}; - if (!defined $new_object_id) { - warn "Undefined object $object_id referenced in constellation\n"; - next; - } - - foreach my $instance (@{ $self->{_instances}{$object_id} }) { - next if !defined($instance->{deltax}) || !defined($instance->{deltay}); - $self->{_model}->objects->[$new_object_id]->add_instance( - rotation => $instance->{rz} || 0, - offset => Slic3r::Pointf->new($instance->{deltax} || 0, $instance->{deltay} || 0), - ); - } - } -} - -sub _get_attribute { - my $self = shift; - my ($data, $name) = @_; - - return +(map $_->{Value}, grep $_->{Name} eq $name, values %{$data->{Attributes}})[0]; -} - -1; diff --git a/lib/Slic3r/Format/OBJ.pm b/lib/Slic3r/Format/OBJ.pm deleted file mode 100644 index 616b38cdc..000000000 --- a/lib/Slic3r/Format/OBJ.pm +++ /dev/null @@ -1,34 +0,0 @@ -package Slic3r::Format::OBJ; -use Moo; - -use File::Basename qw(basename); - -sub read_file { - my $self = shift; - my ($file) = @_; - - Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n"; - my $vertices = []; - my $facets = []; - while (<$fh>) { - if (/^v ([^ ]+)\s+([^ ]+)\s+([^ ]+)/) { - push @$vertices, [$1, $2, $3]; - } elsif (/^f (\d+).*? (\d+).*? (\d+).*?/) { - push @$facets, [ $1-1, $2-1, $3-1 ]; - } - } - close $fh; - - my $mesh = Slic3r::TriangleMesh->new; - $mesh->ReadFromPerl($vertices, $facets); - $mesh->repair; - - my $model = Slic3r::Model->new; - - my $basename = basename($file); - my $object = $model->add_object(input_file => $file, name => $basename); - my $volume = $object->add_volume(mesh => $mesh, name => $basename); - return $model; -} - -1; diff --git a/lib/Slic3r/Format/STL.pm b/lib/Slic3r/Format/STL.pm index 11928d8b2..a6a1836e4 100644 --- a/lib/Slic3r/Format/STL.pm +++ b/lib/Slic3r/Format/STL.pm @@ -3,28 +3,6 @@ use Moo; use File::Basename qw(basename); -sub read_file { - my $self = shift; - my ($file) = @_; - - my $path = Slic3r::encode_path($file); - die "Failed to open $file\n" if !-e $path; - - my $mesh = Slic3r::TriangleMesh->new; - $mesh->ReadSTLFile($path); - $mesh->repair; - - die "This STL file couldn't be read because it's empty.\n" - if $mesh->facets_count == 0; - - my $model = Slic3r::Model->new; - - my $basename = basename($file); - my $object = $model->add_object(input_file => $file, name => $basename); - my $volume = $object->add_volume(mesh => $mesh, name => $basename); - return $model; -} - sub write_file { my $self = shift; my ($file, $mesh, %params) = @_; diff --git a/utils/amf-to-stl.pl b/utils/amf-to-stl.pl index b421dd33a..8b26cedb3 100755 --- a/utils/amf-to-stl.pl +++ b/utils/amf-to-stl.pl @@ -25,7 +25,7 @@ my %opt = (); } { - my $model = Slic3r::Format::AMF->read_file($ARGV[0]); + my $model = Slic3r::Model->load_amf(Slic3r::encode_path($ARGV[0])); my $output_file = $ARGV[0]; $output_file =~ s/\.amf(?:\.xml)?$/\.stl/i;