Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deflate amf #4528

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support zip-deflated AMF files in libslic3r.
Includes basic tests.

Implements #4511
  • Loading branch information
lordofhyphens committed Sep 2, 2018
commit 7c58218149d62943e35a80dc4f01ea8b02dafc70
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ set(SLIC3R_TEST_SOURCES
${TESTDIR}/libslic3r/test_test_data.cpp
${TESTDIR}/libslic3r/test_geometry.cpp
${TESTDIR}/libslic3r/test_gcodewriter.cpp
${TESTDIR}/libslic3r/test_amf.cpp
)

add_executable(slic3r slic3r.cpp)
Expand Down
138 changes: 138 additions & 0 deletions src/test/inputs/test_amf/20mmbox.amf
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<amf unit="millimeter">
<metadata type="cad">Slic3r 1.3.1-dev</metadata>
<object id="0">
<metadata type="name">20mmbox.stl</metadata>
<mesh>
<vertices>
<vertex>
<coordinates>
<x>10</x>
<y>10</y>
<z>0</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-10</x>
<y>-10</y>
<z>0</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-10</x>
<y>10</y>
<z>0</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>10</x>
<y>-10</y>
<z>0</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>10</x>
<y>-10</y>
<z>10</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-10</x>
<y>10</y>
<z>10</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-10</x>
<y>-10</y>
<z>10</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>10</x>
<y>10</y>
<z>10</z>
</coordinates>
</vertex>
</vertices>
<volume>
<metadata type="name">20mmbox.stl</metadata>
<triangle>
<v1>0</v1>
<v2>1</v2>
<v3>2</v3>
</triangle>
<triangle>
<v1>1</v1>
<v2>0</v2>
<v3>3</v3>
</triangle>
<triangle>
<v1>4</v1>
<v2>5</v2>
<v3>6</v3>
</triangle>
<triangle>
<v1>5</v1>
<v2>4</v2>
<v3>7</v3>
</triangle>
<triangle>
<v1>0</v1>
<v2>4</v2>
<v3>3</v3>
</triangle>
<triangle>
<v1>4</v1>
<v2>0</v2>
<v3>7</v3>
</triangle>
<triangle>
<v1>4</v1>
<v2>1</v2>
<v3>3</v3>
</triangle>
<triangle>
<v1>1</v1>
<v2>4</v2>
<v3>6</v3>
</triangle>
<triangle>
<v1>5</v1>
<v2>1</v2>
<v3>6</v3>
</triangle>
<triangle>
<v1>1</v1>
<v2>5</v2>
<v3>2</v3>
</triangle>
<triangle>
<v1>5</v1>
<v2>0</v2>
<v3>2</v3>
</triangle>
<triangle>
<v1>0</v1>
<v2>5</v2>
<v3>7</v3>
</triangle>
</volume>
</mesh>
</object>
<constellation id="1">
<instance objectid="0">
<deltax>67.5</deltax>
<deltay>35</deltay>
<rz>0</rz>
<scale>1</scale>
</instance>
</constellation>
</amf>
Binary file not shown.
Binary file not shown.
Binary file added src/test/inputs/test_amf/20mmbox_deflated.amf
Binary file not shown.
60 changes: 60 additions & 0 deletions src/test/libslic3r/test_amf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <catch.hpp>
#include <test_options.hpp>
#include "IO.hpp"

using namespace Slic3r;
using namespace std::literals::string_literals;

SCENARIO("Reading deflated AMF files") {
GIVEN("Compressed AMF file of a 20mm cube") {
Model model;
WHEN("file is read") {
bool result_code = IO::AMF::read(std::string(testfile_dir) + "test_amf/20mmbox_deflated.amf"s, &model);
THEN("Does not return false.") {
REQUIRE(result_code == true);
}
THEN("Model object contains a single ModelObject.") {
REQUIRE(model.objects.size() == 1);
}
}
WHEN("single file is read with some subdirectories") {
bool result_code = IO::AMF::read(std::string(testfile_dir) + "test_amf/20mmbox_deflated-in_directories.amf"s, &model);
THEN("Read returns false.") {
REQUIRE(result_code == true);
}
THEN("Model object contains no ModelObjects.") {
REQUIRE(model.objects.size() == 1);
}
}
WHEN("file is read with unsupported file structure (multiple files)") {
bool result_code = IO::AMF::read(std::string(testfile_dir) + "test_amf/20mmbox_deflated-mult_files.amf"s, &model);
THEN("Read returns false.") {
REQUIRE(result_code == false);
}
THEN("Model object contains no ModelObjects.") {
REQUIRE(model.objects.size() == 0);
}
}
}
GIVEN("Uncompressed AMF file of a 20mm cube") {
Model model;
WHEN("file is read") {
bool result_code = IO::AMF::read(std::string(testfile_dir) + "test_amf/20mmbox.amf"s, &model);
THEN("Does not return false.") {
REQUIRE(result_code == true);
}
THEN("Model object contains a single ModelObject.") {
REQUIRE(model.objects.size() == 1);
}
}
WHEN("nonexistant file is read") {
bool result_code = IO::AMF::read(std::string(testfile_dir) + "test_amf/20mmbox-doesnotexist.amf"s, &model);
THEN("Read returns false.") {
REQUIRE(result_code == false);
}
THEN("Model object contains no ModelObject.") {
REQUIRE(model.objects.size() == 0);
}
}
}
}
26 changes: 24 additions & 2 deletions xs/src/libslic3r/IO/AMF.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "../IO.hpp"
#include "Zip/ZipArchive.hpp"
#include <iostream>
#include <fstream>
#include <string.h>
Expand Down Expand Up @@ -450,15 +451,31 @@ void AMFParserContext::endDocument()
bool
AMF::read(std::string input_file, Model* model)
{
ZipArchive zip_archive(input_file, 'R');
auto file_list = zip_archive.list_entries();
if (file_list.size() > 1) {
return false; // only support single file archives
}
std::string deflated_input_file {""};
if (file_list.size() == 1) {
// extract the file with ZipArchive
if(!zip_archive.extract_entry(file_list[0], "3dmodel.xml"))
return false;
deflated_input_file = "3dmodel.xml";
} else {
// not a deflated file
deflated_input_file = input_file;
}

XML_Parser parser = XML_ParserCreate(NULL); // encoding
if (! parser) {
printf("Couldn't allocate memory for parser\n");
return false;
}

boost::nowide::ifstream fin(input_file, std::ios::in);
boost::nowide::ifstream fin(deflated_input_file, std::ios::in);
if (!fin.is_open()) {
boost::nowide::cerr << "Cannot open file: " << input_file << std::endl;
boost::nowide::cerr << "Cannot open file: " << deflated_input_file << std::endl;
return false;
}

Expand Down Expand Up @@ -489,6 +506,11 @@ AMF::read(std::string input_file, Model* model)

XML_ParserFree(parser);
fin.close();
if (file_list.size() == 1) {
// Remove the extracted 3dmodel.xml file.
if (remove("3dmodel.xml") != 0)
return false;
}

if (result)
ctx.endDocument();
Expand Down