Parse and write multi-material AMF files. Convert multiple STL files into a single multi-material AMF

This commit is contained in:
Alessandro Ranellucci 2012-02-20 16:43:45 +01:00
parent aa98a9deb2
commit b6bffacb9d
5 changed files with 97 additions and 33 deletions

View file

@ -3,6 +3,8 @@ use strict;
use warnings;
use XML::SAX::ExpatXS;
use XXX;
use base 'XML::SAX::Base';
my %xyz_index = (x => 0, y => 1, z => 2); #=
@ -21,10 +23,19 @@ sub start_element {
$self->{_vertex} = ["", "", ""];
} elsif ($self->{_vertex} && $data->{LocalName} =~ /^[xyz]$/ && $self->{_tree}[-1] eq 'coordinates') {
$self->{_coordinate} = $data->{LocalName};
} elsif ($data->{LocalName} eq 'volume') {
$self->{_volume_materialid} = $self->_get_attribute($data, 'materialid');
$self->{_volume} = [];
} elsif ($data->{LocalName} eq 'triangle') {
$self->{_triangle} = [[], "", "", ""]; # empty normal
} elsif ($self->{_triangle} && $data->{LocalName} =~ /^v([123])$/ && $self->{_tree}[-1] eq 'triangle') {
$self->{_vertex_idx} = $1;
} elsif ($data->{LocalName} eq 'material') {
$self->{_material_id} = $self->_get_attribute($data, 'id') || '_';
$self->{_material} = {};
} elsif ($data->{LocalName} eq 'metadata' && $self->{_tree}[-1] eq 'material') {
$self->{_material_metadata_type} = $self->_get_attribute($data, 'type');
$self->{_material}{ $self->{_material_metadata_type} } = "";
}
push @{$self->{_tree}}, $data->{LocalName};
@ -38,6 +49,8 @@ sub characters {
$self->{_vertex}[ $xyz_index{$self->{_coordinate}} ] .= $data->{Data};
} elsif ($self->{_triangle} && defined $self->{_vertex_idx}) {
$self->{_triangle}[ $self->{_vertex_idx} ] .= $data->{Data};
} elsif ($self->{_material_metadata_type}) {
$self->{_material}{ $self->{_material_metadata_type} } .= $data->{Data};
}
}
@ -52,13 +65,29 @@ sub end_element {
$self->{_vertex} = undef;
} elsif ($self->{_coordinate} && $data->{LocalName} =~ /^[xyz]$/) {
$self->{_coordinate} = undef;
} elsif ($data->{LocalName} eq 'volume') {
$self->{_meshes_by_material}{ $self->{_volume_materialid} } ||= [];
push @{ $self->{_meshes_by_material}{ $self->{_volume_materialid} } }, @{$self->{_volume}};
$self->{_volume} = undef;
} elsif ($data->{LocalName} eq 'triangle') {
push @{$self->{_facets}}, $self->{_triangle};
push @{$self->{_volume}}, $self->{_triangle};
$self->{_triangle} = undef;
} elsif ($self->{_vertex_idx} && $data->{LocalName} =~ /^v[123]$/) {
$self->{_vertex_idx} = undef;
} elsif ($data->{LocalName} eq 'material') {
$self->{_materials}{ $self->{_material_id} } = $self->{_material};
$self->{_material_id} = undef;
$self->{_material} = undef;
} elsif ($data->{LocalName} eq 'metadata' && $self->{_material}) {
$self->{_material_metadata_type} = undef;
}
}
sub _get_attribute {
my $self = shift;
my ($data, $name) = @_;
return +(map $_->{Value}, grep $_->{Name} eq $name, values %{$data->{Attributes}})[0];
}
1;