AMF.pm 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package Slic3r::AMF;
  2. use Moo;
  3. use Slic3r::Geometry qw(X Y Z);
  4. use XXX;
  5. sub read_file {
  6. my $self = shift;
  7. my ($file) = @_;
  8. eval "require Slic3r::AMF::Parser; 1"
  9. or die "AMF parsing requires XML::SAX::ExpatXS\n";
  10. open my $fh, '<', $file or die "Failed to open $file\n";
  11. my $vertices = [];
  12. my $materials = {};
  13. my $meshes_by_material = {};
  14. XML::SAX::ExpatXS
  15. ->new(Handler => Slic3r::AMF::Parser->new(
  16. _vertices => $vertices,
  17. _materials => $materials,
  18. _meshes_by_material => $meshes_by_material,
  19. ))
  20. ->parse_file($fh);
  21. close $fh;
  22. $_ = Slic3r::TriangleMesh->new(vertices => $vertices, facets => $_)
  23. for values %$meshes_by_material;
  24. return $materials, $meshes_by_material;
  25. }
  26. sub write_file {
  27. my $self = shift;
  28. my ($file, $materials, $meshes_by_material) = @_;
  29. my %vertices_offset = ();
  30. open my $fh, '>', $file;
  31. binmode $fh, ':utf8';
  32. printf $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
  33. printf $fh qq{<amf unit="millimeter">\n};
  34. printf $fh qq{ <metadata type="cad">Slic3r %s</metadata>\n}, $Slic3r::VERSION;
  35. foreach my $material_id (keys %$materials) {
  36. printf $fh qq{ <material id="%s">\n}, $material_id;
  37. for (keys %{$materials->{$material_id}}) {
  38. printf $fh qq{ <metadata type=\"%s\">%s</metadata>\n}, $_, $materials->{$material_id}{$_};
  39. }
  40. printf $fh qq{ </material>\n};
  41. }
  42. printf $fh qq{ <object id="0">\n};
  43. printf $fh qq{ <mesh>\n};
  44. printf $fh qq{ <vertices>\n};
  45. my $vertices_count = 0;
  46. foreach my $mesh (values %$meshes_by_material) {
  47. $vertices_offset{$mesh} = $vertices_count;
  48. foreach my $vertex (@{$mesh->vertices}, ) {
  49. printf $fh qq{ <vertex>\n};
  50. printf $fh qq{ <coordinates>\n};
  51. printf $fh qq{ <x>%s</x>\n}, $vertex->[X];
  52. printf $fh qq{ <y>%s</y>\n}, $vertex->[Y];
  53. printf $fh qq{ <z>%s</z>\n}, $vertex->[Z];
  54. printf $fh qq{ </coordinates>\n};
  55. printf $fh qq{ </vertex>\n};
  56. $vertices_count++;
  57. }
  58. }
  59. printf $fh qq{ </vertices>\n};
  60. foreach my $material_id (sort keys %$meshes_by_material) {
  61. my $mesh = $meshes_by_material->{$material_id};
  62. printf $fh qq{ <volume%s>\n},
  63. ($material_id eq '_') ? '' : " materialid=\"$material_id\"";
  64. foreach my $facet (@{$mesh->facets}) {
  65. printf $fh qq{ <triangle>\n};
  66. printf $fh qq{ <v%d>%d</v%d>\n}, $_, $facet->[$_] + $vertices_offset{$mesh}, $_
  67. for 1..3;
  68. printf $fh qq{ </triangle>\n};
  69. }
  70. printf $fh qq{ </volume>\n};
  71. }
  72. printf $fh qq{ </mesh>\n};
  73. printf $fh qq{ </object>\n};
  74. printf $fh qq{</amf>\n};
  75. close $fh;
  76. }
  77. 1;