Skip to content

Commit

Permalink
Quick port amf (#5068)
Browse files Browse the repository at this point in the history
* Ports the basic deflate and related items from prusa3d/PrusaSlicer for AMF deflate.

Implements #4511

* Actually add the tests to read files.

* Push all  the utils into one header.

* Revise slightly to ensure we end up in the logic and just rely on strcmp to check the buffer against the magic key.

* Use more compatible CMake construction?

* Build using cmake3 on travis.

* Fix use of strcmp; remove unused config definition

* throw an exception if bad zip file

* Use correct string header for cstrings; terminate buffer.

* Insist on CMake >= 3.9, actually install it on Travis

* Use VERSION_STRING instead for boost

* Use VERSION_GREATER_EQUAL to look for 1.74 or higher when attempting to include nowide

* invert logic to do what we want

* All build systems are terrible in their own way.
  • Loading branch information
lordofhyphens authored Mar 21, 2021
1 parent 18ddd3a commit 8c69278
Show file tree
Hide file tree
Showing 19 changed files with 10,220 additions and 4,930 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions package/linux/travis-build-cpp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
11 changes: 9 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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})
Expand Down Expand Up @@ -398,6 +404,7 @@ set(LIBSLIC3R_DEPENDS
polypartition
poly2tri
ZipArchive
miniz
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
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.
59 changes: 58 additions & 1 deletion src/test/libslic3r/test_amf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
31 changes: 31 additions & 0 deletions xs/src/libslic3r/Exception.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef _libslic3r_Exception_h_
#define _libslic3r_Exception_h_

#include <stdexcept>

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_
Loading

0 comments on commit 8c69278

Please sign in to comment.