diff --git a/.travis.yml b/.travis.yml
index 87f1d3e1b..a437ef3d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,6 +33,8 @@ addons:
apt:
sources:
- ubuntu-toolchain-r-test
+ - sourceline: 'deb http://download.opensuse.org/repositories/science:/dlr/xUbuntu_14.04/ /'
+ key_url: 'https://download.opensuse.org/repositories/science:dlr/xUbuntu_14.04/Release.key'
packages:
- g++-7
- gcc-7
diff --git a/package/linux/travis-build-cpp.sh b/package/linux/travis-build-cpp.sh
index 7c45c81fe..afa96ec6d 100755
--- a/package/linux/travis-build-cpp.sh
+++ b/package/linux/travis-build-cpp.sh
@@ -6,6 +6,12 @@ export CC=gcc-7
export CXX=g++-7
export DISPLAY=:99.0
+if [ -f "$(which cmake3)" ]; then
+ export CMAKE=$(which cmake3)
+else
+ export CMAKE=$(which cmake)
+fi
+
mkdir -p $CACHE
if [[ "$WXVERSION" != "pkg" ]]; then
@@ -25,6 +31,6 @@ fi
tar -C$HOME -xjf $CACHE/boost-compiled.tar.bz2
mkdir build && cd build
-cmake -DBOOST_ROOT=$HOME/boost_1_63_0 -DSLIC3R_STATIC=ON -DCMAKE_BUILD_TYPE=Release ../src
-cmake --build .
+${CMAKE} -DBOOST_ROOT=$HOME/boost_1_63_0 -DSLIC3R_STATIC=ON -DCMAKE_BUILD_TYPE=Release ../src
+${CMAKE} --build .
./slic3r_test -s
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7c78c782d..5b3ad7ed8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 3.9)
+cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project (slic3r)
option(Enable_GUI "Use the wxWidgets code in slic3r.cpp" OFF)
@@ -122,7 +122,8 @@ find_package(Threads REQUIRED)
set(Boost_NO_BOOST_CMAKE ON)
find_package(Boost REQUIRED COMPONENTS system thread filesystem)
-if (${Boost_VERSION_MACRO} VERSION_GREATER_EQUAL "1.73.0")
+if (NOT (${Boost_VERSION_STRING} VERSION_LESS "1.74.0"))
+ MESSAGE("Adding in boost::nowide")
find_package(Boost REQUIRED COMPONENTS system thread filesystem OPTIONAL_COMPONENTS nowide)
endif()
@@ -171,6 +172,10 @@ set(LIBSLIC3R_INCLUDES
add_library(ZipArchive STATIC
${LIBDIR}/Zip/ZipArchive.cpp
)
+
+add_library(miniz STATIC
+ ${LIBDIR}/miniz/miniz.c
+)
target_compile_features(ZipArchive PUBLIC cxx_std_11)
target_include_directories(ZipArchive PUBLIC ${COMMON_INCLUDES})
target_compile_options(ZipArchive PUBLIC -w)
@@ -236,6 +241,7 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/TransformationMatrix.cpp
${LIBDIR}/libslic3r/SupportMaterial.cpp
${LIBDIR}/libslic3r/utils.cpp
+ ${LIBDIR}/libslic3r/miniz_extension.cpp
)
target_compile_features(libslic3r PUBLIC cxx_std_11)
target_include_directories(libslic3r SYSTEM PUBLIC ${SLIC3R_INCLUDES})
@@ -398,6 +404,7 @@ set(LIBSLIC3R_DEPENDS
polypartition
poly2tri
ZipArchive
+ miniz
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
diff --git a/src/test/inputs/test_amf/20mmbox.amf b/src/test/inputs/test_amf/20mmbox.amf
new file mode 100644
index 000000000..c945a45cd
--- /dev/null
+++ b/src/test/inputs/test_amf/20mmbox.amf
@@ -0,0 +1,138 @@
+
+
+ Slic3r 1.3.1-dev
+
+
+
+ 67.5
+ 35
+ 0
+ 1
+
+
+
diff --git a/src/test/inputs/test_amf/20mmbox_deflated-in_directories.amf b/src/test/inputs/test_amf/20mmbox_deflated-in_directories.amf
new file mode 100644
index 000000000..4f8a63607
Binary files /dev/null and b/src/test/inputs/test_amf/20mmbox_deflated-in_directories.amf differ
diff --git a/src/test/inputs/test_amf/20mmbox_deflated-mult_files.amf b/src/test/inputs/test_amf/20mmbox_deflated-mult_files.amf
new file mode 100644
index 000000000..f334baf9d
Binary files /dev/null and b/src/test/inputs/test_amf/20mmbox_deflated-mult_files.amf differ
diff --git a/src/test/inputs/test_amf/20mmbox_deflated.amf b/src/test/inputs/test_amf/20mmbox_deflated.amf
new file mode 100644
index 000000000..f0293fcd1
Binary files /dev/null and b/src/test/inputs/test_amf/20mmbox_deflated.amf differ
diff --git a/src/test/libslic3r/test_amf.cpp b/src/test/libslic3r/test_amf.cpp
index 72f0d8641..6d137db4f 100644
--- a/src/test/libslic3r/test_amf.cpp
+++ b/src/test/libslic3r/test_amf.cpp
@@ -5,8 +5,65 @@
using namespace Slic3r;
+using namespace std::literals::string_literals;
-SCENARIO("Reading AMF file") {
+SCENARIO("Reading deflated AMF files", "[AMF]") {
+ GIVEN("Compressed AMF file of a 20mm cube") {
+ auto model {new Slic3r::Model()};
+ WHEN("file is read") {
+ bool result_code = Slic3r::IO::AMF::read(testfile("test_amf/20mmbox_deflated.amf"), 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 = Slic3r::IO::AMF::read(testfile("test_amf/20mmbox_deflated-in_directories.amf"), 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 multiple files in the archive") {
+ bool result_code = Slic3r::IO::AMF::read(testfile("test_amf/20mmbox_deflated-mult_files.amf"), model);;
+ THEN("Read returns true.") {
+ REQUIRE(result_code == true);
+ }
+ THEN("Model object contains one ModelObject.") {
+ REQUIRE(model->objects.size() == 1);
+ }
+ }
+ delete model;
+ }
+ GIVEN("Uncompressed AMF file of a 20mm cube") {
+ auto model {new Slic3r::Model()};
+ WHEN("file is read") {
+ bool result_code = Slic3r::IO::AMF::read(testfile("test_amf/20mmbox.amf"), 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 = Slic3r::IO::AMF::read(testfile("test_amf/20mmbox-doesnotexist.amf"), model);;
+ THEN("Read returns false.") {
+ REQUIRE(result_code == false);
+ }
+ THEN("Model object contains no ModelObject.") {
+ REQUIRE(model->objects.size() == 0);
+ }
+ }
+ delete model;
+ }
+}
+
+SCENARIO("Reading AMF file", "[AMF]") {
GIVEN("badly formed AMF file (missing vertices)") {
auto model {new Slic3r::Model()};
WHEN("AMF model is read") {
diff --git a/xs/src/libslic3r/Exception.hpp b/xs/src/libslic3r/Exception.hpp
new file mode 100644
index 000000000..fababa47d
--- /dev/null
+++ b/xs/src/libslic3r/Exception.hpp
@@ -0,0 +1,31 @@
+#ifndef _libslic3r_Exception_h_
+#define _libslic3r_Exception_h_
+
+#include
+
+namespace Slic3r {
+
+// PrusaSlicer's own exception hierarchy is derived from std::runtime_error.
+// Base for Slicer's own exceptions.
+class Exception : public std::runtime_error { using std::runtime_error::runtime_error; };
+#define SLIC3R_DERIVE_EXCEPTION(DERIVED_EXCEPTION, PARENT_EXCEPTION) \
+ class DERIVED_EXCEPTION : public PARENT_EXCEPTION { using PARENT_EXCEPTION::PARENT_EXCEPTION; }
+// Critical exception produced by Slicer, such exception shall never propagate up to the UI thread.
+// If that happens, an ugly fat message box with an ugly fat exclamation mark is displayed.
+SLIC3R_DERIVE_EXCEPTION(CriticalException, Exception);
+SLIC3R_DERIVE_EXCEPTION(RuntimeError, CriticalException);
+SLIC3R_DERIVE_EXCEPTION(LogicError, CriticalException);
+SLIC3R_DERIVE_EXCEPTION(InvalidArgument, LogicError);
+SLIC3R_DERIVE_EXCEPTION(OutOfRange, LogicError);
+SLIC3R_DERIVE_EXCEPTION(IOError, CriticalException);
+SLIC3R_DERIVE_EXCEPTION(FileIOError, IOError);
+SLIC3R_DERIVE_EXCEPTION(HostNetworkError, IOError);
+SLIC3R_DERIVE_EXCEPTION(ExportError, CriticalException);
+SLIC3R_DERIVE_EXCEPTION(PlaceholderParserError, RuntimeError);
+// Runtime exception produced by Slicer. Such exception cancels the slicing process and it shall be shown in notifications.
+SLIC3R_DERIVE_EXCEPTION(SlicingError, Exception);
+#undef SLIC3R_DERIVE_EXCEPTION
+
+} // namespace Slic3r
+
+#endif // _libslic3r_Exception_h_
diff --git a/xs/src/libslic3r/IO/AMF.cpp b/xs/src/libslic3r/IO/AMF.cpp
index 69280a5a4..4c60ca1c0 100644
--- a/xs/src/libslic3r/IO/AMF.cpp
+++ b/xs/src/libslic3r/IO/AMF.cpp
@@ -1,15 +1,22 @@
#include "../IO.hpp"
#include
#include
-#include
+#include
#include