libslic3r tests converted to Catch2 v3

Still has 3 failing tests, but builds and runs.
This commit is contained in:
Cory Cross
2025-11-03 20:12:56 -08:00
parent c2250c1967
commit c7f6520d1a
23 changed files with 153 additions and 98 deletions

View File

@@ -1,26 +1,18 @@
# TODO Add individual tests as executables in separate directories
# add_subirectory(<testcase>)
# Add individual tests as executables in separate directories at the bottom of this file
add_subdirectory(catch2)
set(TEST_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
file(TO_NATIVE_PATH "${TEST_DATA_DIR}" TEST_DATA_DIR)
add_library(Catch2 INTERFACE)
list (APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/Catch2)
target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_LIST_DIR})
add_library(Catch2::Catch2 ALIAS Catch2)
target_compile_definitions(Catch2 INTERFACE -DCATCH_CONFIG_ENABLE_BENCHMARKING)
if (APPLE)
# OSX builds targeting OSX 10.9 do not support new std::uncought_exception()
# see https://github.com/catchorg/Catch2/issues/1218
target_compile_definitions(Catch2 INTERFACE -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS)
endif()
include(CTest)
include(Catch)
set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.")
set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.") # Unknown if this still works and/or should be replaced with something else.
add_library(test_common INTERFACE)
target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE)
target_link_libraries(test_common INTERFACE Catch2::Catch2)
target_include_directories(test_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
if (APPLE)
target_link_libraries(test_common INTERFACE "-liconv -framework IOKit" "-framework CoreFoundation" -lc++)
@@ -28,10 +20,9 @@ endif()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
add_subdirectory(libnest2d)
# add_subdirectory(libnest2d)
add_subdirectory(libslic3r)
add_subdirectory(slic3rutils)
add_subdirectory(fff_print)
# add_subdirectory(sla_print)
add_subdirectory(cpp17 EXCLUDE_FROM_ALL) # does not have to be built all the time
# add_subdirectory(example)
# add_subdirectory(slic3rutils)
# add_subdirectory(fff_print)
# add_subdirectory(cpp17 EXCLUDE_FROM_ALL) # does not have to be built all the time

View File

@@ -28,7 +28,7 @@ if (TARGET OpenVDB::openvdb)
target_sources(${_TEST_NAME}_tests PRIVATE test_hollowing.cpp)
endif()
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r)
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r Catch2::Catch2WithMain)
set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests")
if (WIN32)
@@ -41,5 +41,4 @@ if (WIN32)
endif()
endif()
catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")
# add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS})
catch_discover_tests(${_TEST_NAME}_tests)

View File

@@ -1,4 +1,4 @@
#include <catch_main.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Utils.hpp"
#define NANOSVG_IMPLEMENTATION

View File

@@ -1,4 +1,3 @@
#include <catch2/catch.hpp>
#include "libslic3r/Model.hpp"
#include "libslic3r/Format/3mf.hpp"
@@ -6,8 +5,62 @@
#include <boost/filesystem/operations.hpp>
#include <catch2/catch_tostring.hpp>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <type_traits> // for std::enable_if_t
#include <typeinfo> // for typeid
namespace Catch {
template <typename T>
struct is_eigen_matrix : std::is_base_of<Eigen::MatrixBase<T>, T> {};
template <typename T>
struct StringMaker<T, std::enable_if_t<is_eigen_matrix<T>::value>> {
static std::string convert(const T& eigen_obj) {
// Newline at end of rows
Eigen::IOFormat fmt(4, 0, ", ", "\n", "[", "]");
std::stringstream ss;
ss << "Matrix<" << typeid(eigen_obj).name() << "> = \n";
ss << eigen_obj.format(fmt);
return ss.str();
}
};
// We must manually specialize for Eigen::Transform as it doesn't derive from MatrixBase.
// It's defined as: Eigen::Transform<Scalar, Dim, Mode, Options>
template <typename Scalar, int Dim, int Mode, int Options>
struct StringMaker<Eigen::Transform<Scalar, Dim, Mode, Options>> {
static std::string convert(const Eigen::Transform<Scalar, Dim, Mode, Options>& trafo) {
// We print the underlying matrix
const auto& matrix = trafo.matrix();
// Newline at end of rows
Eigen::IOFormat fmt(4, 0, ", ", "\n", "[", "]");
std::stringstream ss;
ss << "Transform<Mode=" << Mode << ", Dim=" << Dim << "> = \n";
ss << matrix.format(fmt);
return ss.str();
}
};
// Quaternions also need an explicit specialization
template <typename Scalar, int Options>
struct StringMaker<Eigen::Quaternion<Scalar, Options>> {
static std::string convert(const Eigen::Quaternion<Scalar, Options>& quat) {
std::stringstream ss;
ss << "Quaternion(w=" << quat.w() << ", x=" << quat.x() << ", y=" << quat.y() << ", z=" << quat.z() << ")";
return ss.str();
}
};
} // end namespace Catch
#include <catch2/catch_all.hpp>
using namespace Slic3r;
SCENARIO("Reading 3mf file", "[3mf]") {
GIVEN("umlauts in the path of the file") {
Model model;
@@ -89,17 +142,26 @@ SCENARIO("2D convex hull of sinking object", "[3mf]") {
model.add_default_instances();
WHEN("model is rotated, scaled and set as sinking") {
ModelObject* object = model.objects.front();
ModelObject* object = model.objects[0];
object->center_around_origin(false);
// set instance's attitude so that it is rotated, scaled and sinking
ModelInstance* instance = object->instances.front();
// This outputs the same exact data as the Prusaslicer test
object->volumes[0]->mesh().write_ascii("/tmp/orca.ascii");
// set instance's attitude so that it is rotated, scaled (and sinking? how is it sinking? the rotation? does it matter if it's sinking?)
ModelInstance* instance = object->instances[0];
instance->set_rotation(X, -M_PI / 4.0);
instance->set_offset(Vec3d::Zero());
instance->set_scaling_factor({ 2.0, 2.0, 2.0 });
// calculate 2D convex hull
Polygon hull_2d = object->convex_hull_2d(instance->get_transformation().get_matrix());
auto trafo = instance->get_transformation().get_matrix();
// This matrix is the same exact matrix as the Prusaslicer test
CAPTURE(trafo);
Polygon hull_2d = object->convex_hull_2d(trafo);
// But we get different hull_2d.points here (and somehow decimal numbers despite being int64_t values, but that's probabaly printing configuration somewhere -- Prusaslicer's prints out with newlines between the X&Y and not one between coordinates, which is about the worse possible output).
// verify result
Points result = {

View File

@@ -1,5 +1,5 @@
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <libslic3r/TriangleMesh.hpp>
#include <libslic3r/AABBTreeIndirect.hpp>
@@ -22,7 +22,7 @@ TEST_CASE("Building a tree over a box, ray caster and closest query", "[AABBIndi
hit);
REQUIRE(intersected);
REQUIRE(hit.t == Approx(5.));
REQUIRE(hit.t == Catch::Approx(5.));
std::vector<igl::Hit> hits;
bool intersected2 = AABBTreeIndirect::intersect_ray_all_hits(
@@ -33,8 +33,8 @@ TEST_CASE("Building a tree over a box, ray caster and closest query", "[AABBIndi
hits);
REQUIRE(intersected2);
REQUIRE(hits.size() == 2);
REQUIRE(hits.front().t == Approx(5.));
REQUIRE(hits.back().t == Approx(6.));
REQUIRE(hits.front().t == Catch::Approx(5.));
REQUIRE(hits.back().t == Catch::Approx(6.));
size_t hit_idx;
Vec3d closest_point;
@@ -43,18 +43,18 @@ TEST_CASE("Building a tree over a box, ray caster and closest query", "[AABBIndi
tree,
Vec3d(0.3, 0.5, -5.),
hit_idx, closest_point);
REQUIRE(squared_distance == Approx(5. * 5.));
REQUIRE(closest_point.x() == Approx(0.3));
REQUIRE(closest_point.y() == Approx(0.5));
REQUIRE(closest_point.z() == Approx(0.));
REQUIRE(squared_distance == Catch::Approx(5. * 5.));
REQUIRE(closest_point.x() == Catch::Approx(0.3));
REQUIRE(closest_point.y() == Catch::Approx(0.5));
REQUIRE(closest_point.z() == Catch::Approx(0.));
squared_distance = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(
tmesh.its.vertices, tmesh.its.indices,
tree,
Vec3d(0.3, 0.5, 5.),
hit_idx, closest_point);
REQUIRE(squared_distance == Approx(4. * 4.));
REQUIRE(closest_point.x() == Approx(0.3));
REQUIRE(closest_point.y() == Approx(0.5));
REQUIRE(closest_point.z() == Approx(1.));
REQUIRE(squared_distance == Catch::Approx(4. * 4.));
REQUIRE(closest_point.x() == Catch::Approx(0.3));
REQUIRE(closest_point.y() == Catch::Approx(0.5));
REQUIRE(closest_point.z() == Catch::Approx(1.));
}

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include <iostream>
#include <boost/filesystem.hpp>
@@ -32,7 +32,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 22^2mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(22. * 22. * s * s));
REQUIRE(output.front().area() == Catch::Approx(22. * 22. * s * s));
}
}
DYNAMIC_SECTION("minus 1mm, miter " << miter << "x") {
@@ -46,7 +46,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 18^2mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(18. * 18. * s * s));
REQUIRE(output.front().area() == Catch::Approx(18. * 18. * s * s));
}
}
}
@@ -64,7 +64,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 22^2mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(22. * 22. * s * s));
REQUIRE(output.front().area() == Catch::Approx(22. * 22. * s * s));
}
}
DYNAMIC_SECTION("minus 1mm, miter " << miter << "x") {
@@ -78,7 +78,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 18^2mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(18. * 18. * s * s));
REQUIRE(output.front().area() == Catch::Approx(18. * 18. * s * s));
}
}
}
@@ -106,7 +106,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 22^2-8^2 mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx((22. * 22. - 8. * 8.) * s * s));
REQUIRE(output.front().area() == Catch::Approx((22. * 22. - 8. * 8.) * s * s));
}
}
WHEN("minus 1mm") {
@@ -120,7 +120,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 18^2-12^2 mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx((18. * 18. - 12. * 12.) * s * s));
REQUIRE(output.front().area() == Catch::Approx((18. * 18. - 12. * 12.) * s * s));
}
}
}
@@ -140,7 +140,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 22^2-8^2 mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx((22. * 22. - 8. * 8.) * s * s));
REQUIRE(output.front().area() == Catch::Approx((22. * 22. - 8. * 8.) * s * s));
}
}
WHEN("minus 1mm") {
@@ -154,7 +154,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area is 18^2-12^2 mm2") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx((18. * 18. - 12. * 12.) * s * s));
REQUIRE(output.front().area() == Catch::Approx((18. * 18. - 12. * 12.) * s * s));
}
}
}
@@ -186,7 +186,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area matches") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(area_offsetted));
REQUIRE(output.front().area() == Catch::Approx(area_offsetted));
}
}
}
@@ -205,7 +205,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
#endif
THEN("Area matches") {
REQUIRE(output.size() == 1);
REQUIRE(output.front().area() == Approx(area_offsetted));
REQUIRE(output.front().area() == Catch::Approx(area_offsetted));
}
}
}

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include <numeric>
#include <iostream>
@@ -122,7 +122,7 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") {
REQUIRE(result.size() == 1);
}
THEN("intersection_pl - result has same length as subject polyline") {
REQUIRE(result.front().length() == Approx(subject.length()));
REQUIRE(result.front().length() == Catch::Approx(subject.length()));
}
}
@@ -185,7 +185,7 @@ SCENARIO("Various Clipper operations - t/clipper.t", "[ClipperUtils]") {
ExPolygon match({ { 20, 18 }, { 10, 18 }, { 10, 12 }, { 20, 12 } },
{ { 14, 16 }, { 16, 16 }, { 16, 14 }, { 14, 14 } });
REQUIRE(intersection.size() == 1);
REQUIRE(intersection.front().area() == Approx(match.area()));
REQUIRE(intersection.front().area() == Catch::Approx(match.area()));
}
}
}
@@ -206,7 +206,7 @@ SCENARIO("Various Clipper operations - t/clipper.t", "[ClipperUtils]") {
ExPolygons diff = Slic3r::diff_ex(Polygons{ square, square2 }, Polygons{ hole });
THEN("difference of a cw from two ccw is a contour with one hole") {
REQUIRE(diff.size() == 1);
REQUIRE(diff.front().area() == Approx(ExPolygon({ {40, 40}, {0, 40}, {0, 0}, {40, 0} }, { {15, 25}, {25, 25}, {25, 15}, {15, 15} }).area()));
REQUIRE(diff.front().area() == Catch::Approx(ExPolygon({ {40, 40}, {0, 40}, {0, 0}, {40, 0} }, { {15, 25}, {25, 25}, {25, 15}, {15, 15} }).area()));
}
}
}
@@ -277,25 +277,25 @@ TEST_CASE("Traversing Clipper PolyTree", "[ClipperUtils]") {
SECTION("Traverse into Polygons WITHOUT spatial ordering") {
Polygons output;
REQUIRE(area_sum == Approx(polytree_area(tree.GetFirst(), &output)));
REQUIRE(area_sum == Catch::Approx(polytree_area(tree.GetFirst(), &output)));
REQUIRE(output.size() == reference.size());
}
SECTION("Traverse into ExPolygons WITHOUT spatial ordering") {
ExPolygons output;
REQUIRE(area_sum == Approx(polytree_area(tree.GetFirst(), &output)));
REQUIRE(area_sum == Catch::Approx(polytree_area(tree.GetFirst(), &output)));
REQUIRE(count_polys(output) == reference.size());
}
SECTION("Traverse into Polygons WITH spatial ordering") {
Polygons output;
REQUIRE(area_sum == Approx(polytree_area<e_ordering::ON>(tree.GetFirst(), &output)));
REQUIRE(area_sum == Catch::Approx(polytree_area<e_ordering::ON>(tree.GetFirst(), &output)));
REQUIRE(output.size() == reference.size());
}
SECTION("Traverse into ExPolygons WITH spatial ordering") {
ExPolygons output;
REQUIRE(area_sum == Approx(polytree_area<e_ordering::ON>(tree.GetFirst(), &output)));
REQUIRE(area_sum == Catch::Approx(polytree_area<e_ordering::ON>(tree.GetFirst(), &output)));
REQUIRE(count_polys(output) == reference.size());
}
}

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/PrintConfigConstants.hpp"

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include <iostream>
#include <boost/filesystem.hpp>

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Point.hpp"
#include "libslic3r/BoundingBox.hpp"

View File

@@ -1,6 +1,6 @@
#include <iostream>
#include <fstream>
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/SLA/Hollowing.hpp"

View File

@@ -1,6 +1,7 @@
#include <iostream>
#include <fstream>
#include <catch2/catch.hpp>
#include <random>
#include <catch2/catch_all.hpp>
#include "libslic3r/TriangleMesh.hpp"

View File

@@ -1,7 +1,7 @@
#define NOMINMAX
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <fstream>

View File

@@ -1,5 +1,5 @@
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <libslic3r/TriangleMesh.hpp>
#include <libslic3r/MeshBoolean.hpp>
@@ -19,7 +19,7 @@ TEST_CASE("CGAL and TriangleMesh conversions", "[MeshBoolean]") {
REQUIRE(M.its.vertices.size() == sphere.its.vertices.size());
REQUIRE(M.its.indices.size() == sphere.its.indices.size());
REQUIRE(M.volume() == Approx(sphere.volume()));
REQUIRE(M.volume() == Catch::Approx(sphere.volume()));
REQUIRE(! MeshBoolean::cgal::does_self_intersect(M));
}

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Point.hpp"
#include "libslic3r/MutablePolygon.hpp"

View File

@@ -1,6 +1,7 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include <queue>
#include <random>
#include "libslic3r/MutablePriorityQueue.hpp"

View File

@@ -1,5 +1,5 @@
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <libslic3r/Optimize/BruteforceOptimizer.hpp>

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/PlaceholderParser.hpp"
#include "libslic3r/PrintConfig.hpp"
@@ -33,17 +33,17 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
// FIXME: Don't know what exactly this referred to in Prusaslicer or
// whether it should apply to Orca or not.
// {outer_wall_line_width} returns as its default value, 0.
// SECTION("outer_wall_line_width") { REQUIRE(std::stod(parser.process("{outer_wall_line_width}")) == Approx(0.67500001192092896)); }
SECTION("support_object_xy_distance") { REQUIRE(std::stod(parser.process("{support_object_xy_distance}")) == Approx(0.35)); }
// SECTION("outer_wall_line_width") { REQUIRE(std::stod(parser.process("{outer_wall_line_width}")) == Catch::Approx(0.67500001192092896)); }
SECTION("support_object_xy_distance") { REQUIRE(std::stod(parser.process("{support_object_xy_distance}")) == Catch::Approx(0.35)); }
// initial_layer_line_width ratio over nozzle_diameter.
// FIXME: either something else which correctly calculates a ratio should be here,
// or something else should be found for for the REQUIRE_THROWS
// SECTION("initial_layer_line_width") { REQUIRE(std::stod(parser.process("{initial_layer_line_width}")) == Approx(0.9)); }
// SECTION("initial_layer_line_width") { REQUIRE(std::stod(parser.process("{initial_layer_line_width}")) == Catch::Approx(0.9)); }
// small_perimeter_speed ratio over outer_wall_speed
SECTION("small_perimeter_speed") { REQUIRE(std::stod(parser.process("{small_perimeter_speed}")) == Approx(30.)); }
SECTION("small_perimeter_speed") { REQUIRE(std::stod(parser.process("{small_perimeter_speed}")) == Catch::Approx(30.)); }
// infill_wall_overlap over inner_wall_line_width
// FIXME: Shouldn't this return the calculated value and not the percentage 15?
// SECTION("infill_wall_overlap") { REQUIRE(std::stod(parser.process("{infill_wall_overlap}")) == Approx(0.16875)); }
// SECTION("infill_wall_overlap") { REQUIRE(std::stod(parser.process("{infill_wall_overlap}")) == Catch::Approx(0.16875)); }
// If initial_layer_line_width is set to percent, then it is applied over respective extrusion types by overriding their respective speeds.
// The PlaceholderParser has no way to know which extrusion type the caller has in mind, therefore it throws.
@@ -53,17 +53,17 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
SECTION("math: 2*3") { REQUIRE(parser.process("{2*3}") == "6"); }
SECTION("math: 2*3/6") { REQUIRE(parser.process("{2*3/6}") == "1"); }
SECTION("math: 2*3/12") { REQUIRE(parser.process("{2*3/12}") == "0"); }
SECTION("math: 2.*3/12") { REQUIRE(std::stod(parser.process("{2.*3/12}")) == Approx(0.5)); }
SECTION("math: 10 % 2.5") { REQUIRE(std::stod(parser.process("{10%2.5}")) == Approx(0.)); }
SECTION("math: 11 % 2.5") { REQUIRE(std::stod(parser.process("{11%2.5}")) == Approx(1.)); }
SECTION("math: 2.*3/12") { REQUIRE(std::stod(parser.process("{2.*3/12}")) == Catch::Approx(0.5)); }
SECTION("math: 10 % 2.5") { REQUIRE(std::stod(parser.process("{10%2.5}")) == Catch::Approx(0.)); }
SECTION("math: 11 % 2.5") { REQUIRE(std::stod(parser.process("{11%2.5}")) == Catch::Approx(1.)); }
SECTION("math: 2*(3-12)") { REQUIRE(parser.process("{2*(3-12)}") == "-18"); }
SECTION("math: 2*foo*(3-12)") { REQUIRE(parser.process("{2*foo*(3-12)}") == "0"); }
SECTION("math: 2*bar*(3-12)") { REQUIRE(parser.process("{2*bar*(3-12)}") == "-36"); }
SECTION("math: 2.5*bar*(3-12)") { REQUIRE(std::stod(parser.process("{2.5*bar*(3-12)}")) == Approx(-45)); }
SECTION("math: 2.5*bar*(3-12)") { REQUIRE(std::stod(parser.process("{2.5*bar*(3-12)}")) == Catch::Approx(-45)); }
SECTION("math: min(12, 14)") { REQUIRE(parser.process("{min(12, 14)}") == "12"); }
SECTION("math: max(12, 14)") { REQUIRE(parser.process("{max(12, 14)}") == "14"); }
SECTION("math: min(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{min(13.4, -1238.1)}")) == Approx(-1238.1)); }
SECTION("math: max(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{max(13.4, -1238.1)}")) == Approx(13.4)); }
SECTION("math: min(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{min(13.4, -1238.1)}")) == Catch::Approx(-1238.1)); }
SECTION("math: max(13.4, -1238.1)") { REQUIRE(std::stod(parser.process("{max(13.4, -1238.1)}")) == Catch::Approx(13.4)); }
SECTION("math: int(13.4)") { REQUIRE(parser.process("{int(13.4)}") == "13"); }
SECTION("math: int(-13.4)") { REQUIRE(parser.process("{int(-13.4)}") == "-13"); }
SECTION("math: round(13.4)") { REQUIRE(parser.process("{round(13.4)}") == "13"); }
@@ -80,9 +80,9 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
SECTION("math: zdigits(5., 15, 8)") { REQUIRE(parser.process("{zdigits(5, 15, 8)}") == "000005.00000000"); }
SECTION("math: digits(13.84375892476, 15, 8)") { REQUIRE(parser.process("{digits(13.84375892476, 15, 8)}") == " 13.84375892"); }
SECTION("math: zdigits(13.84375892476, 15, 8)") { REQUIRE(parser.process("{zdigits(13.84375892476, 15, 8)}") == "000013.84375892"); }
SECTION("math: interpolate_table(13.84375892476, (0, 0), (20, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13.84375892476, (0, 0), (20, 20))}")) == Approx(13.84375892476)); }
SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Approx(13.)); }
SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Approx(20.)); }
SECTION("math: interpolate_table(13.84375892476, (0, 0), (20, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13.84375892476, (0, 0), (20, 20))}")) == Catch::Approx(13.84375892476)); }
SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(13.)); }
SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(20.)); }
// Test the boolean expression parser.
auto boolean_expression = [&parser](const std::string& templ) { return parser.evaluate_boolean_expression(templ, parser.config()); };

View File

@@ -1,5 +1,5 @@
#define NOMINMAX
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include <numeric>

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Point.hpp"
#include "libslic3r/Polygon.hpp"

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Model.hpp"
#include "libslic3r/Format/STL.hpp"

View File

@@ -1,4 +1,4 @@
#include <catch2/catch.hpp>
#include <catch2/catch_all.hpp>
#include "libslic3r/Time.hpp"

View File

@@ -1,5 +1,5 @@
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <libslic3r/Polygon.hpp>
#include <libslic3r/Polyline.hpp>
@@ -10,6 +10,7 @@
#include <libslic3r/Geometry/VoronoiVisualUtils.hpp>
#include <numeric>
#include <random>
// #define VORONOI_DEBUG_OUT
@@ -70,7 +71,7 @@ TEST_CASE("Voronoi missing edges - points 12067", "[Voronoi]")
vd, pts, Lines());
#endif
// REQUIRE(closest_point.z() == Approx(1.));
// REQUIRE(closest_point.z() == Catch::Approx(1.));
}
// https://svn.boost.org/trac10/ticket/12707
@@ -341,7 +342,7 @@ TEST_CASE("Voronoi division by zero 12903", "[Voronoi]")
// Funny sample from a dental industry?
// Vojtech confirms this test fails and rightly so, because the input data contain self intersections.
// This test is suppressed.
TEST_CASE("Voronoi NaN coordinates 12139", "[Voronoi][!hide][!mayfail]")
TEST_CASE("Voronoi NaN coordinates 12139", "[Voronoi][.][!mayfail]")
{
Lines lines = {
{ { 260500,1564400 }, { 261040,1562960 } },