From f7c431cd1f721ba8321a4be1673af7839cf6b8a9 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sat, 21 Jul 2018 20:56:50 -0500 Subject: [PATCH] Fixed tests and init_print (using shared_ptr) --- src/test/libslic3r/test_flow.cpp | 8 +- src/test/libslic3r/test_model.cpp | 50 ++++++++++++ src/test/libslic3r/test_printgcode.cpp | 14 +++- src/test/libslic3r/test_skirt_brim.cpp | 11 ++- src/test/test_data.cpp | 102 ++++++++----------------- src/test/test_data.hpp | 19 +---- xs/src/libslic3r/Print.hpp | 3 + 7 files changed, 111 insertions(+), 96 deletions(-) create mode 100644 src/test/libslic3r/test_model.cpp diff --git a/src/test/libslic3r/test_flow.cpp b/src/test/libslic3r/test_flow.cpp index d74f2e84c..178f0d886 100644 --- a/src/test/libslic3r/test_flow.cpp +++ b/src/test/libslic3r/test_flow.cpp @@ -25,8 +25,10 @@ SCENARIO("Extrusion width specifics") { config->set("first_layer_height", "100%"); WHEN("first layer width set to 2mm") { - config->set("first_layer_extrusion_width", 2); - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + Slic3r::Model model; + config->set("first_layer_extrusion_width", 1.3); + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; + std::vector E_per_mm_bottom; auto gcode {std::stringstream("")}; Slic3r::Test::gcode(gcode, print); @@ -46,7 +48,7 @@ SCENARIO("Extrusion width specifics") { pass = std::count_if(E_per_mm_bottom.cbegin(), E_per_mm_bottom.cend(), [avg_E] (double v) { return _equiv(v, avg_E, 0.015); }) == 0; REQUIRE(pass == true); - REQUIRE(E_per_mm_bottom.size() > 0); + REQUIRE(E_per_mm_bottom.size() > 0); // make sure it actually passed because of extrusion } THEN(" First layer width does not apply to upper layer.") { } diff --git a/src/test/libslic3r/test_model.cpp b/src/test/libslic3r/test_model.cpp new file mode 100644 index 000000000..009c5255f --- /dev/null +++ b/src/test/libslic3r/test_model.cpp @@ -0,0 +1,50 @@ +#include +#include "Model.hpp" +#include "test_data.hpp" // get access to init_print, etc + +using namespace Slic3r::Test; + +SCENARIO("Model construction") { + GIVEN("A Slic3r Model") { + auto model {Slic3r::Model()}; + auto sample_mesh {Slic3r::TriangleMesh::make_cube(20,20,20)}; + sample_mesh.repair(); + + auto config {Slic3r::Config::new_from_defaults()}; + std::shared_ptr print = std::make_shared(); + print->apply_config(config); + + WHEN("Model object is added") { + ModelObject* mo {model.add_object()}; + THEN("Model object list == 1") { + REQUIRE(model.objects.size() == 1); + } + + mo->add_volume(sample_mesh); + THEN("Model volume list == 1") { + REQUIRE(mo->volumes.size() == 1); + } + THEN("Model volume modifier is false") { + REQUIRE(mo->volumes.front()->modifier == false); + } + THEN("Mesh is equivalent to input mesh.") { + REQUIRE(sample_mesh.vertices() == mo->volumes.front()->mesh.vertices()); + } + ModelInstance* inst {mo->add_instance()}; + inst->rotation = 0; + inst->scaling_factor = 1.0; + model.arrange_objects(print->config.min_object_distance()); + model.center_instances_around_point(Slic3r::Pointf(100,100)); + print->auto_assign_extruders(mo); + print->add_model_object(mo); + THEN("Print works?") { + print->process(); + auto gcode {std::stringstream("")}; + print->export_gcode(gcode, true); + REQUIRE(gcode.str().size() > 0); + } + + } + } + +} diff --git a/src/test/libslic3r/test_printgcode.cpp b/src/test/libslic3r/test_printgcode.cpp index 5c554d209..732e9ffa5 100644 --- a/src/test/libslic3r/test_printgcode.cpp +++ b/src/test/libslic3r/test_printgcode.cpp @@ -4,6 +4,8 @@ #include "test_data.hpp" #include "libslic3r.h" +using namespace Slic3r::Test; + SCENARIO( "PrintGCode basic functionality", "[!mayfail]") { GIVEN("A default configuration and a print test object") { auto config {Slic3r::Config::new_from_defaults()}; @@ -11,7 +13,8 @@ SCENARIO( "PrintGCode basic functionality", "[!mayfail]") { WHEN("the output is executed with no support material") { config->set("first_layer_extrusion_width", 0); - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + Slic3r::Model model; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; Slic3r::Test::gcode(gcode, print); auto exported {gcode.str()}; THEN("Some text output is generated.") { @@ -45,10 +48,11 @@ SCENARIO( "PrintGCode basic functionality", "[!mayfail]") { } } WHEN("the output is executed with support material") { + Slic3r::Model model; config->set("first_layer_extrusion_width", 0); config->set("support_material", true); config->set("raft_layers", 3); - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; Slic3r::Test::gcode(gcode, print); auto exported {gcode.str()}; THEN("Some text output is generated.") { @@ -65,8 +69,9 @@ SCENARIO( "PrintGCode basic functionality", "[!mayfail]") { } } WHEN("the output is executed with a separate first layer extrusion width") { + Slic3r::Model model; config->set("first_layer_extrusion_width", 0.5); - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; Slic3r::Test::gcode(gcode, print); auto exported {gcode.str()}; THEN("Some text output is generated.") { @@ -85,7 +90,8 @@ SCENARIO( "PrintGCode basic functionality", "[!mayfail]") { WHEN("Cooling is enabled and the fan is disabled.") { config->set("cooling", true); config->set("disable_fan_first_layers", 5); - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + Slic3r::Model model; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; Slic3r::Test::gcode(gcode, print); auto exported {gcode.str()}; THEN("GCode to disable fan is emitted."){ diff --git a/src/test/libslic3r/test_skirt_brim.cpp b/src/test/libslic3r/test_skirt_brim.cpp index 990f7a758..6af9aeda0 100644 --- a/src/test/libslic3r/test_skirt_brim.cpp +++ b/src/test/libslic3r/test_skirt_brim.cpp @@ -19,7 +19,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { WHEN("multiple objects are printed") { auto gcode {std::stringstream("")}; - auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, config)}; + Slic3r::Model model; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, model, config)}; std::map layers_with_skirt; Slic3r::Test::gcode(gcode, print); auto parser {Slic3r::GCodeReader()}; @@ -96,8 +97,9 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { config->set("cooling", 0); // to prevent speeds to be altered config->set("first_layer_speed", "100%"); // to prevent speeds to be altered - auto print {Slic3r::Test::init_print({TestMesh::overhang}, config)}; - print.process(); + Slic3r::Model model; + auto print {Slic3r::Test::init_print({TestMesh::overhang}, model, config)}; + print->process(); config->set("support_material", true); // to prevent speeds to be altered @@ -108,7 +110,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { WHEN("Large minimum skirt length is used.") { config->set("min_skirt_length", 20); auto gcode {std::stringstream("")}; - auto print {Slic3r::Test::init_print(std::make_tuple(20,20,20), config)}; + Slic3r::Model model; + auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)}; THEN("Gcode generation doesn't crash") { Slic3r::Test::gcode(gcode, print); auto exported {gcode.str()}; diff --git a/src/test/test_data.cpp b/src/test/test_data.cpp index 43de785af..23be026df 100644 --- a/src/test/test_data.cpp +++ b/src/test/test_data.cpp @@ -18,6 +18,7 @@ const std::unordered_map mesh_names { std::make_pair(TestMesh::V,"V"), std::make_pair(TestMesh::_40x10,"40x10"), std::make_pair(TestMesh::cube_20x20x20,"cube_20x20x20"), + std::make_pair(TestMesh::sphere_50mm,"sphere_50mm"), std::make_pair(TestMesh::bridge,"bridge"), std::make_pair(TestMesh::bridge_with_hole,"bridge_with_hole"), std::make_pair(TestMesh::cube_with_concave_hole,"cube_with_concave_hole"), @@ -175,83 +176,51 @@ TriangleMesh mesh(TestMesh m) { Point3(2,3,10) , Point3(9,10,12) , Point3(13,9,12) , Point3(3,1,8) , Point3(11,3,8) , Point3(10,11,8) , Point3(4,10,8) , Point3(6,12,10) , Point3(4,6,10) , Point3(7,13,12) , Point3(6,7,12) , Point3(7,5,9) , Point3(13,7,9) }); + break; default: - return TriangleMesh(); + break; } - auto _mesh {TriangleMesh(vertices, facets)}; + TriangleMesh _mesh; + if (vertices.size() == 0) { + switch(m) { + case TestMesh::cube_20x20x20: + _mesh = Slic3r::TriangleMesh::make_cube(20,20,20); + break; + case TestMesh::sphere_50mm: + _mesh = Slic3r::TriangleMesh::make_sphere(50, PI / 243.0); + break; + default: + break; + } + } else { + _mesh = TriangleMesh(vertices, facets); + } + _mesh.repair(); return _mesh; } -TriangleMesh mesh(TestMesh m, Pointf3 translate, double scale) { - return mesh(m, translate, Pointf3(scale, scale, scale)); -} -TriangleMesh mesh(TestMesh m, Pointf3 translate, Pointf3 scale) { - TriangleMesh _mesh; - switch(TestMesh) { - case TestMesh::cube_20x20x20: - _mesh = Slic3r::TriangleMesh::make_cube(20, 20, 20); - break; - default: - _mesh = mesh(m); - } - - _mesh.scale(scale); - _mesh.translate(translate); - return _mesh; -} -/* -Slic3r::Model model(const std::string& model_name, TestMesh m, Pointf3 translate = Pointf3(0,0,0), double scale = 1.0) { - return model(model_name, m, translate, Pointf3(scale, scale, scale)); -} -*/ -Slic3r::Test::Print init_print(std::initializer_list meshes, config_ptr _config) { - auto config {Slic3r::Config::new_from_defaults()}; +shared_Print init_print(std::initializer_list meshes, Slic3r::Model& model, config_ptr _config, bool comments) { + auto config {Slic3r::Config::new_from_defaults()}; config->apply(_config); + const char* v {std::getenv("SLIC3R_TESTS_GCODE")}; auto tests_gcode {(v == nullptr ? ""s : std::string(v))}; if (tests_gcode != ""s) config->set("gcode_comments", 1); - std::shared_ptr print = std::make_shared(); + shared_Print print {std::make_shared()}; print->apply_config(config); + for (auto t : meshes) { + auto* object {model.add_object()}; + object->name += std::string(mesh_names.at(t)) + ".stl"s; + object->add_volume(mesh(t)); - auto model {Slic3r::Test::model(s.str(), Slic3r::TriangleMesh::make_cube(get<0>(cube), get<1>(cube), get<1>(cube))) }; - - model.arrange_objects(print->config.min_object_distance()); - model.center_instances_around_point(Slic3r::Pointf(100,100)); - for (auto* mo : model.objects) { - print->auto_assign_extruders(mo); - print->add_model_object(mo); - } - - print->validate(); - - std::vector models {}; - models.emplace_back(model); - return Slic3r::Test::Print(print, models); -} -Slic3r::Test::Print init_print(std::tuple cube, config_ptr _config) { - std::stringstream s; - s << "cube_" << get<0>(cube) << "x" << get<1>(cube) << "x" << get<2>(cube); - - auto config {Slic3r::Config::new_from_defaults()}; - - config->apply(_config); - const char* v {std::getenv("SLIC3R_TESTS_GCODE")}; - auto tests_gcode {(v == nullptr ? ""s : std::string(v))}; - - if (tests_gcode != ""s) - config->set("gcode_comments", 1); - - std::shared_ptr print = std::make_shared(); - print->apply_config(config); - Slic3r::Model model; - - for (const auto& testm : meshes) { - add_testmesh_to_model(model, mesh_names[testm], mesh(testm, Pointf3(0,0,0), 1.0)); + auto* inst {object->add_instance()}; + inst->rotation = 0; + inst->scaling_factor = 1.0; } model.arrange_objects(print->config.min_object_distance()); @@ -263,14 +232,11 @@ Slic3r::Test::Print init_print(std::tuple cube, config_ptr _config) print->validate(); - std::vector models {}; - models.emplace_back(model); - return Slic3r::Test::Print(print, models); + return print; } -void gcode(std::stringstream& gcode, Slic3r::Test::Print& _print) { - Slic3r::Print& print {_print.print()}; - print.export_gcode(gcode, true); +void gcode(std::stringstream& gcode, shared_Print _print) { + _print->export_gcode(gcode, true); } Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh) { @@ -294,8 +260,6 @@ void add_testmesh_to_model(Slic3r::Model& result, const std::string& model_name, auto* inst {object->add_instance()}; inst->rotation = 0; inst->scaling_factor = 1.0; - - return result; } } } // namespace Slic3r::Test diff --git a/src/test/test_data.hpp b/src/test/test_data.hpp index c560082ad..02f160cbd 100644 --- a/src/test/test_data.hpp +++ b/src/test/test_data.hpp @@ -17,6 +17,7 @@ enum class TestMesh { V, _40x10, cube_20x20x20, + sphere_50mm, bridge, bridge_with_hole, cube_with_concave_hole, @@ -32,19 +33,6 @@ enum class TestMesh { two_hollow_squares }; -class Print { -public: - Print(std::shared_ptr _print, std::vector _models) : models(_models), _print(_print) {} - void process() { _print->process(); } - void apply_config(config_ptr _config) { _print->apply_config(_config); } - Slic3r::Print& print() { return *(_print); } - - const std::vector models {}; -private: - std::shared_ptr _print {nullptr}; -}; - - /// Mesh enumeration to name mapping extern const std::unordered_map mesh_names; @@ -67,10 +55,9 @@ bool _equiv(const T& a, const U& b, double epsilon) { return abs(a - b) < epsilo Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh); -Slic3r::Test::Print init_print(std::tuple cube, config_ptr _config = Slic3r::Config::new_from_defaults()); -Slic3r::Test::Print init_print(std::initializer_list meshes, config_ptr _config = Slic3r::Config::new_from_defaults()); +shared_Print init_print(std::initializer_list meshes, Slic3r::Model& model, config_ptr _config = Slic3r::Config::new_from_defaults(), bool comments = false); -void gcode(std::stringstream& gcode, Slic3r::Test::Print& print); +void gcode(std::stringstream& gcode, shared_Print print); } } // namespace Slic3r::Test diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 36fead648..2f15491a0 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "BoundingBox.hpp" #include "Flow.hpp" @@ -325,6 +326,8 @@ class Print PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume); }; +using shared_Print = std::shared_ptr; + #define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator) #define FOREACH_REGION(print, region) FOREACH_BASE(PrintRegionPtrs, (print)->regions, region) #define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->objects, object)