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 all commits
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
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ set(SLIC3R_TEST_SOURCES
${TESTDIR}/libslic3r/test_printobject.cpp
${TESTDIR}/libslic3r/test_skirt_brim.cpp
${TESTDIR}/libslic3r/test_test_data.cpp
${TESTDIR}/libslic3r/test_geometry.cpp
${TESTDIR}/libslic3r/test_gcodewriter.cpp
${TESTDIR}/libslic3r/test_transformationmatrix.cpp
${TESTDIR}/libslic3r/test_trianglemesh.cpp
${TESTDIR}/libslic3r/test_extrusion_entity.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.
53 changes: 52 additions & 1 deletion src/test/libslic3r/test_amf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,59 @@
#include "Model.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);


SCENARIO("Reading AMF file") {
GIVEN("badly formed AMF file (missing vertices)") {
Expand Down
26 changes: 26 additions & 0 deletions xs/src/Zip/ZipArchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ZipArchive::ZipArchive (std::string zip_archive_name, char zip_mode) : archive(m
stats = mz_zip_reader_init_file(&archive, zip_name.c_str(), 0);
} else {
std::cout << "Error:: Unknown zip mode" << std::endl;
stats = 0;
}
}

Expand Down Expand Up @@ -61,6 +62,31 @@ ZipArchive::finalize()
return stats;
}

std::vector<std::string>
ZipArchive::list_entries() {
std::vector<std::string> files = {};
stats = 0;
int file_count = (int)mz_zip_reader_get_num_files(&archive);
if (file_count == 0) {
return files;
std::cerr << "Error:: No files in zip archive" << std::endl;
}
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&archive, 0, &file_stat))
{
std::cerr << "Error:: No files in zip archive or not a zip archive." << std::endl;
return files;
}

for (int i = 0; i < file_count; i++)
{
if (!mz_zip_reader_file_stat(&archive, i, &file_stat)) continue;
if (mz_zip_reader_is_file_a_directory(&archive, i)) continue; // skip directories for now

files.emplace_back(file_stat.m_filename);
}
}

ZipArchive::~ZipArchive() {
if(!finalized)
this->finalize();
Expand Down
5 changes: 5 additions & 0 deletions xs/src/Zip/ZipArchive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <string>
#include <iostream>
#include <vector>
#include "miniz/miniz.h"

namespace Slic3r {
Expand Down Expand Up @@ -40,6 +41,10 @@ class ZipArchive
/// \return mz_bool 0: failure 1: success.
mz_bool finalize();

/// Get list of file names contained in this archive.
/// On failure, sets stats to 0 and returns an empty vector
std::vector<std::string> list_entries();

~ZipArchive();

private:
Expand Down
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 @@ -454,15 +455,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 @@ -493,6 +510,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