mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Good bye, Perl Expat binding!
This commit is contained in:
		
							parent
							
								
									9ea570ea4e
								
							
						
					
					
						commit
						f0f550783f
					
				
					 7 changed files with 2 additions and 253 deletions
				
			
		
							
								
								
									
										11
									
								
								Build.PL
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								Build.PL
									
										
									
									
									
								
							|  | @ -28,7 +28,6 @@ my %prereqs = qw( | ||||||
| ); | ); | ||||||
| my %recommends = qw( | my %recommends = qw( | ||||||
|     Class::XSAccessor               0 |     Class::XSAccessor               0 | ||||||
|     XML::SAX::ExpatXS               0 |  | ||||||
|     Test::Harness                   0 |     Test::Harness                   0 | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|  | @ -125,15 +124,7 @@ EOF | ||||||
|             if $module =~ /^(?:OpenGL|Test::Harness)$/; |             if $module =~ /^(?:OpenGL|Test::Harness)$/; | ||||||
|          |          | ||||||
|         push @cmd, "$module~$version"; |         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; |         my $res = system @cmd; | ||||||
|         if ($res != 0) { |         if ($res != 0) { | ||||||
|             if (exists $prereqs{$module}) { |             if (exists $prereqs{$module}) { | ||||||
|  |  | ||||||
|  | @ -62,7 +62,6 @@ use Slic3r::ExtrusionLoop; | ||||||
| use Slic3r::ExtrusionPath; | use Slic3r::ExtrusionPath; | ||||||
| use Slic3r::Flow; | use Slic3r::Flow; | ||||||
| use Slic3r::Format::AMF; | use Slic3r::Format::AMF; | ||||||
| use Slic3r::Format::OBJ; |  | ||||||
| use Slic3r::Format::STL; | use Slic3r::Format::STL; | ||||||
| use Slic3r::GCode::ArcFitting; | use Slic3r::GCode::ArcFitting; | ||||||
| use Slic3r::GCode::MotionPlanner; | use Slic3r::GCode::MotionPlanner; | ||||||
|  |  | ||||||
|  | @ -3,27 +3,6 @@ use Moo; | ||||||
| 
 | 
 | ||||||
| use Slic3r::Geometry qw(X Y Z); | 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 { | sub write_file { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my ($file, $model, %params) = @_; |     my ($file, $model, %params) = @_; | ||||||
|  |  | ||||||
|  | @ -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; |  | ||||||
|  | @ -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; |  | ||||||
|  | @ -3,28 +3,6 @@ use Moo; | ||||||
| 
 | 
 | ||||||
| use File::Basename qw(basename); | 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 { | sub write_file { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|     my ($file, $mesh, %params) = @_; |     my ($file, $mesh, %params) = @_; | ||||||
|  |  | ||||||
|  | @ -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]; |     my $output_file = $ARGV[0]; | ||||||
|     $output_file =~ s/\.amf(?:\.xml)?$/\.stl/i; |     $output_file =~ s/\.amf(?:\.xml)?$/\.stl/i; | ||||||
|      |      | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv