Good bye, Perl Expat binding!
This commit is contained in:
parent
9ea570ea4e
commit
f0f550783f
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…
Reference in New Issue
Block a user