From 87c9b92a1c5b9743cf93bf755c3b1040bc182fcb Mon Sep 17 00:00:00 2001 From: Cory Cross Date: Mon, 29 Sep 2025 11:32:10 -0700 Subject: [PATCH] Get libslic3r tests closer to passing I can't get geometry tests to do anything useful. I've added extra output, but it hasn't helped me figure out why they don't work yet. That's also probably the last broken 3mf test doesn't work. The config tests were mostly broken because of config name changes. The placeholder_parser tests have some things that may-or-may-not still apply to Orca. --- src/libslic3r/PrintConfig.cpp | 7 +- src/libslic3r/PrintConfig.hpp | 2 +- src/libslic3r/PrintConfigConstants.hpp | 7 ++ tests/libslic3r/test_3mf.cpp | 26 +++-- tests/libslic3r/test_config.cpp | 113 ++++++++++++-------- tests/libslic3r/test_geometry.cpp | 46 +++++--- tests/libslic3r/test_placeholder_parser.cpp | 68 ++++++------ 7 files changed, 157 insertions(+), 112 deletions(-) create mode 100644 src/libslic3r/PrintConfigConstants.hpp diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3ef21ee41f..c2133066f6 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1,4 +1,5 @@ #include "PrintConfig.hpp" +#include "PrintConfigConstants.hpp" #include "ClipperUtils.hpp" #include "Config.hpp" #include "MaterialType.hpp" @@ -686,7 +687,7 @@ void PrintConfigDef::init_common_params() def->tooltip = L("Slicing height for each layer. Smaller layer height means more accurate and more printing time."); def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; - def->set_default_value(new ConfigOptionFloat(0.2)); + def->set_default_value(new ConfigOptionFloat(INITIAL_LAYER_HEIGHT)); def = this->add("printable_height", coFloat); def->label = L("Printable height"); @@ -833,7 +834,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Quality"); def->tooltip = L("Detour to avoid traveling across walls, which may cause blobs on the surface."); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(false)); + def->set_default_value(new ConfigOptionBool(INITIAL_REDUCE_CROSSING_WALL)); def = this->add("max_travel_detour_distance", coFloatOrPercent); def->label = L("Avoid crossing walls - Max detour length"); @@ -4540,7 +4541,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 100; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionInt(0)); + def->set_default_value(new ConfigOptionInt(INITIAL_RAFT_LAYERS)); def = this->add("resolution", coFloat); def->label = L("Resolution"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 807ce56b36..e3cbc37291 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -510,7 +510,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType) class DynamicPrintConfig; -// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs. +// Defines each and every configuration option of Slic3r, including the properties of the GUI dialogs. // Does not store the actual values, but defines default values. class PrintConfigDef : public ConfigDef { diff --git a/src/libslic3r/PrintConfigConstants.hpp b/src/libslic3r/PrintConfigConstants.hpp new file mode 100644 index 0000000000..5520fbc72e --- /dev/null +++ b/src/libslic3r/PrintConfigConstants.hpp @@ -0,0 +1,7 @@ +#pragma once + +// These are here just for unit testing. + +#define INITIAL_LAYER_HEIGHT 0.2 +#define INITIAL_RAFT_LAYERS 0 +#define INITIAL_REDUCE_CROSSING_WALL false diff --git a/tests/libslic3r/test_3mf.cpp b/tests/libslic3r/test_3mf.cpp index 3602d6972d..8d389253aa 100644 --- a/tests/libslic3r/test_3mf.cpp +++ b/tests/libslic3r/test_3mf.cpp @@ -12,8 +12,8 @@ SCENARIO("Reading 3mf file", "[3mf]") { GIVEN("umlauts in the path of the file") { Model model; WHEN("3mf model is read") { - std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf"; - DynamicPrintConfig config; + std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf"; + DynamicPrintConfig config; ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; bool ret = load_3mf(path.c_str(), config, ctxt, &model, false); THEN("load should succeed") { @@ -85,7 +85,7 @@ SCENARIO("2D convex hull of sinking object", "[3mf]") { // load a model Model model; std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl"; - load_stl(src_file.c_str(), &model); + REQUIRE(load_stl(src_file.c_str(), &model)); model.add_default_instances(); WHEN("model is rotated, scaled and set as sinking") { @@ -112,22 +112,20 @@ SCENARIO("2D convex hull of sinking object", "[3mf]") { { -91501496, 4243 } }; - // Allow 1um error due to floating point rounding. - bool res = hull_2d.points.size() == result.size(); - if (res) - for (size_t i = 0; i < result.size(); ++ i) { - const Point &p1 = result[i]; - const Point &p2 = hull_2d.points[i]; - if (std::abs(p1.x() - p2.x()) > 1 || std::abs(p1.y() - p2.y()) > 1) { - res = false; - break; + THEN("2D convex hull should match with reference") { + // Allow 1um error due to floating point rounding. + bool res = hull_2d.points.size() == result.size(); + if (res) { + for (size_t i = 0; i < result.size(); ++ i) { + const Point &p1 = result[i]; + const Point &p2 = hull_2d.points[i]; + CHECK((std::abs(p1.x() - p2.x()) > 1 || std::abs(p1.y() - p2.y()) > 1)); } } - THEN("2D convex hull should match with reference") { + CAPTURE(hull_2d.points); REQUIRE(res); } } } } - diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp index 025459d689..f98dbcab5d 100644 --- a/tests/libslic3r/test_config.cpp +++ b/tests/libslic3r/test_config.cpp @@ -1,6 +1,7 @@ #include #include "libslic3r/PrintConfig.hpp" +#include "libslic3r/PrintConfigConstants.hpp" #include "libslic3r/LocalesUtils.hpp" #include @@ -13,23 +14,23 @@ using namespace Slic3r; SCENARIO("Generic config validation performs as expected.", "[Config]") { GIVEN("A config generated from default options") { Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); - WHEN( "perimeter_extrusion_width is set to 250%, a valid value") { - config.set_deserialize_strict("perimeter_extrusion_width", "250%"); + WHEN( "outer_wall_line_width is set to 250%, a valid value") { + config.set_deserialize_strict("outer_wall_line_width", "250%"); THEN( "The config is read as valid.") { REQUIRE(config.validate().empty()); } } - WHEN( "perimeter_extrusion_width is set to -10, an invalid value") { - config.set("perimeter_extrusion_width", -10); + WHEN( "outer_wall_line_width is set to -10, an invalid value") { + config.set("outer_wall_line_width", -10); THEN( "Validate returns error") { - REQUIRE(! config.validate().empty()); + REQUIRE_FALSE(config.validate().empty()); } } - WHEN( "perimeters is set to -10, an invalid value") { - config.set("perimeters", -10); + WHEN( "wall_loops is set to -10, an invalid value") { + config.set("wall_loops", -10); THEN( "Validate returns error") { - REQUIRE(! config.validate().empty()); + REQUIRE_FALSE(config.validate().empty()); } } } @@ -64,95 +65,115 @@ SCENARIO("Config accessor functions perform as expected.", "[Config]") { } } WHEN("A numeric option is set from serialized string") { - config.set_deserialize_strict("bed_temperature", "100"); + config.set_deserialize_strict("raft_layers", "20"); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("bed_temperature")->get_at(0) == 100); + REQUIRE(config.opt("raft_layers")->getInt() == 20); } } -#if 0 - //FIXME better design accessors for vector elements. - WHEN("An integer-based option is set through the integer interface") { - config.set("bed_temperature", 100); - THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("bed_temperature")->get_at(0) == 100); - } + WHEN("An integer-based option is set through the integer interface") { + config.set("raft_layers", 100); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("raft_layers")->getInt() == 100); + } } -#endif WHEN("An floating-point option is set through the integer interface") { - config.set("perimeter_speed", 10); + config.set("default_acceleration", 10); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("perimeter_speed")->getFloat() == 10.0); + REQUIRE(config.opt("default_acceleration")->getFloat() == 10.0); } } WHEN("A floating-point option is set through the double interface") { - config.set("perimeter_speed", 5.5); + config.set("default_acceleration", 5.5); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("perimeter_speed")->getFloat() == 5.5); + REQUIRE(config.opt("default_acceleration")->getFloat() == 5.5); } } WHEN("An integer-based option is set through the double interface") { THEN("A BadOptionTypeException exception is thrown.") { - REQUIRE_THROWS_AS(config.set("bed_temperature", 5.5), BadOptionTypeException); + REQUIRE_THROWS_AS(config.set("top_shell_layers", 5.5), BadOptionTypeException); } } WHEN("A numeric option is set to a non-numeric value.") { - THEN("A BadOptionTypeException exception is thown.") { - REQUIRE_THROWS_AS(config.set_deserialize_strict("perimeter_speed", "zzzz"), BadOptionValueException); + auto prev_value = config.opt("default_acceleration")->getFloat(); + THEN("A BadOptionTypeException exception is thrown.") { + REQUIRE_THROWS_AS(config.set_deserialize_strict("default_acceleration", "zzzz"), BadOptionValueException); } THEN("The value does not change.") { - REQUIRE(config.opt("perimeter_speed")->getFloat() == 60.0); + REQUIRE(config.opt("default_acceleration")->getFloat() == prev_value); } } WHEN("A string option is set through the string interface") { - config.set("end_gcode", "100"); + config.set("machine_end_gcode", "100"); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("end_gcode")->value == "100"); + REQUIRE(config.opt("machine_end_gcode")->value == "100"); } } WHEN("A string option is set through the integer interface") { - config.set("end_gcode", 100); + config.set("machine_end_gcode", 100); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("end_gcode")->value == "100"); + REQUIRE(config.opt("machine_end_gcode")->value == "100"); } } WHEN("A string option is set through the double interface") { - config.set("end_gcode", 100.5); + config.set("machine_end_gcode", 100.5); THEN("The underlying value is set correctly.") { - REQUIRE(config.opt("end_gcode")->value == float_to_string_decimal_point(100.5)); + REQUIRE(config.opt("machine_end_gcode")->value == float_to_string_decimal_point(100.5)); } } WHEN("A float or percent is set as a percent through the string interface.") { - config.set_deserialize_strict("first_layer_extrusion_width", "100%"); + config.set_deserialize_strict("initial_layer_line_width", "100%"); THEN("Value and percent flag are 100/true") { - auto tmp = config.opt("first_layer_extrusion_width"); + auto tmp = config.opt("initial_layer_line_width"); REQUIRE(tmp->percent == true); REQUIRE(tmp->value == 100); } } WHEN("A float or percent is set as a float through the string interface.") { - config.set_deserialize_strict("first_layer_extrusion_width", "100"); + config.set_deserialize_strict("initial_layer_line_width", "100"); THEN("Value and percent flag are 100/false") { - auto tmp = config.opt("first_layer_extrusion_width"); + auto tmp = config.opt("initial_layer_line_width"); REQUIRE(tmp->percent == false); REQUIRE(tmp->value == 100); } } WHEN("A float or percent is set as a float through the int interface.") { - config.set("first_layer_extrusion_width", 100); + config.set("initial_layer_line_width", 100); THEN("Value and percent flag are 100/false") { - auto tmp = config.opt("first_layer_extrusion_width"); + auto tmp = config.opt("initial_layer_line_width"); REQUIRE(tmp->percent == false); REQUIRE(tmp->value == 100); } } WHEN("A float or percent is set as a float through the double interface.") { - config.set("first_layer_extrusion_width", 100.5); + config.set("initial_layer_line_width", 100.5); THEN("Value and percent flag are 100.5/false") { - auto tmp = config.opt("first_layer_extrusion_width"); + auto tmp = config.opt("initial_layer_line_width"); REQUIRE(tmp->percent == false); REQUIRE(tmp->value == 100.5); } } + WHEN("A numeric vector is set from serialized string") { + config.set_deserialize_strict("temperature_vitrification", "10,20"); + THEN("The underlying value is set correctly.") { + CHECK(config.opt("temperature_vitrification")->get_at(0) == 10); + CHECK(config.opt("temperature_vitrification")->get_at(1) == 20); + } + } + // FIXME: Design better accessors for vector elements + // The following isn't supported and probably shouldn't be: + // WHEN("An integer-based vector option is set through the integer interface") { + // config.set("temperature_vitrification", 100); + // THEN("The underlying value is set correctly.") { + // REQUIRE(config.opt("temperature_vitrification")->get_at(0) == 100); + // } + // } + WHEN("An integer-based vector option is set through the set_key_value interface") { + config.set_key_value("temperature_vitrification", new ConfigOptionInts{10,20}); + THEN("The underlying value is set correctly.") { + CHECK(config.opt("temperature_vitrification")->get_at(0) == 10); + CHECK(config.opt("temperature_vitrification")->get_at(1) == 20); + } + } WHEN("An invalid option is requested during set.") { THEN("A BadOptionTypeException exception is thrown.") { REQUIRE_THROWS_AS(config.set("deadbeef_invalid_option", 1), UnknownOptionException); @@ -181,16 +202,16 @@ SCENARIO("Config accessor functions perform as expected.", "[Config]") { WHEN("getX called on an unset option.") { THEN("The default is returned.") { - REQUIRE(config.opt_float("layer_height") == 0.3); - REQUIRE(config.opt_int("raft_layers") == 0); - REQUIRE(config.opt_bool("support_material") == false); + REQUIRE(config.opt_float("layer_height") == INITIAL_LAYER_HEIGHT); + REQUIRE(config.opt_int("raft_layers") == INITIAL_RAFT_LAYERS); + REQUIRE(config.opt_bool("reduce_crossing_wall") == INITIAL_REDUCE_CROSSING_WALL); } } - WHEN("getFloat called on an option that has been set.") { - config.set("layer_height", 0.5); + WHEN("opt_float called on an option that has been set.") { + config.set("layer_height", INITIAL_LAYER_HEIGHT*2); THEN("The set value is returned.") { - REQUIRE(config.opt_float("layer_height") == 0.5); + REQUIRE(config.opt_float("layer_height") == INITIAL_LAYER_HEIGHT*2); } } } diff --git a/tests/libslic3r/test_geometry.cpp b/tests/libslic3r/test_geometry.cpp index 75832771b1..6be0479c1a 100644 --- a/tests/libslic3r/test_geometry.cpp +++ b/tests/libslic3r/test_geometry.cpp @@ -33,7 +33,7 @@ TEST_CASE("Line::parallel_to", "[Geometry]"){ Line l4(l2); l4.rotate(1.1 * EPSILON, { 0, 0 }); - REQUIRE(! l.parallel_to(l4)); + REQUIRE_FALSE(l.parallel_to(l4)); // The angle epsilon is so low that vectors shorter than 100um rotated by epsilon radians are not rotated at all. Line l5{ { 20000, 0 }, { 0, 0 } }; @@ -48,13 +48,13 @@ TEST_CASE("Line::parallel_to", "[Geometry]"){ l4.rotate(1., { 0, 0 }); l4.translate(offset); REQUIRE(l.parallel_to(l3)); - REQUIRE(!l.parallel_to(l4)); + REQUIRE_FALSE(l.parallel_to(l4)); } TEST_CASE("Line::perpendicular_to", "[Geometry]") { Line l{ { 100000, 0 }, { 0, 0 } }; Line l2{ { 0, 200000 }, { 0, 0 } }; - REQUIRE(! l.perpendicular_to(l)); + REQUIRE_FALSE(l.perpendicular_to(l)); REQUIRE(l.perpendicular_to(l2)); Line l3(l2); @@ -63,7 +63,7 @@ TEST_CASE("Line::perpendicular_to", "[Geometry]") { Line l4(l2); l4.rotate(1.1 * EPSILON, { 0, 0 }); - REQUIRE(! l.perpendicular_to(l4)); + REQUIRE_FALSE(l.perpendicular_to(l4)); // The angle epsilon is so low that vectors shorter than 100um rotated by epsilon radians are not rotated at all. Line l5{ { 0, 20000 }, { 0, 0 } }; @@ -78,7 +78,7 @@ TEST_CASE("Line::perpendicular_to", "[Geometry]") { l4.rotate(1., { 0, 0 }); l4.translate(offset); REQUIRE(l.perpendicular_to(l3)); - REQUIRE(! l.perpendicular_to(l4)); + REQUIRE_FALSE(l.perpendicular_to(l4)); } TEST_CASE("Polygon::contains works properly", "[Geometry]"){ @@ -125,7 +125,7 @@ SCENARIO("polygon_is_convex works") { WHEN("Polygon is convex clockwise") { Polygon cw_square { { {0, 0}, {0,10}, {10,10}, {10,0} } }; THEN("it is not convex") { - REQUIRE(! polygon_is_convex(cw_square)); + REQUIRE_FALSE(polygon_is_convex(cw_square)); } } WHEN("Polygon is convex counter-clockwise") { @@ -138,7 +138,7 @@ SCENARIO("polygon_is_convex works") { GIVEN("A concave polygon") { Polygon concave = { {0,0}, {10,0}, {10,10}, {0,10}, {0,6}, {4,6}, {4,4}, {0,4} }; THEN("It is not convex") { - REQUIRE(! polygon_is_convex(concave)); + REQUIRE_FALSE(polygon_is_convex(concave)); } } } @@ -380,14 +380,30 @@ SCENARIO("Polygon convex/concave detection", "[Geometry]"){ Point(200,100), Point(200,200), Point(100,200)})); - THEN("It has 4 convex points counterclockwise"){ - REQUIRE(square.concave_points(PI*4/3).size() == 0); - REQUIRE(square.convex_points(PI*2/3).size() == 4); + THEN("It has 4 convex points counterclockwise no angle limit"){ + auto cave_pts = square.concave_points(0); + auto vex_pts = square.convex_points(0); + CAPTURE(cave_pts); + CAPTURE(vex_pts); + REQUIRE(cave_pts.size() == 0); + REQUIRE(vex_pts.size() == 4); + } + THEN("It has 4 convex points counterclockwise with angle limit"){ + auto cave_pts = square.concave_points(PI*4/3); + auto vex_pts = square.convex_points(PI*4/3); + CAPTURE(cave_pts); + CAPTURE(vex_pts); + REQUIRE(cave_pts.size() == 0); + REQUIRE(vex_pts.size() == 4); } THEN("It has 4 concave points clockwise"){ square.make_clockwise(); - REQUIRE(square.concave_points(PI*4/3).size() == 4); - REQUIRE(square.convex_points(PI*2/3).size() == 0); + auto cave_pts = square.concave_points(0); + auto vex_pts = square.convex_points(0); + CAPTURE(cave_pts); + CAPTURE(vex_pts); + REQUIRE(cave_pts.size() == 4); + REQUIRE(vex_pts.size() == 0); } } GIVEN("A Square with an extra colinearvertex"){ @@ -399,7 +415,7 @@ SCENARIO("Polygon convex/concave detection", "[Geometry]"){ Point(100,100)})); THEN("It has 4 convex points counterclockwise"){ REQUIRE(square.concave_points(PI*4/3).size() == 0); - REQUIRE(square.convex_points(PI*2/3).size() == 4); + REQUIRE(square.convex_points(PI*4/3).size() == 4); } } GIVEN("A Square with an extra collinear vertex in different order"){ @@ -482,8 +498,8 @@ SCENARIO("Ported from xs/t/14_geometry.t", "[Geometry]"){ REQUIRE(Slic3r::Geometry::directions_parallel(0, M_PI, 0)); REQUIRE(Slic3r::Geometry::directions_parallel(0, 0, M_PI / 180)); REQUIRE(Slic3r::Geometry::directions_parallel(0, M_PI, M_PI / 180)); - REQUIRE(! Slic3r::Geometry::directions_parallel(M_PI /2, M_PI, 0)); - REQUIRE(! Slic3r::Geometry::directions_parallel(M_PI /2, PI, M_PI /180)); + REQUIRE_FALSE(Slic3r::Geometry::directions_parallel(M_PI /2, M_PI, 0)); + REQUIRE_FALSE(Slic3r::Geometry::directions_parallel(M_PI /2, PI, M_PI /180)); } } diff --git a/tests/libslic3r/test_placeholder_parser.cpp b/tests/libslic3r/test_placeholder_parser.cpp index 8c2408fe7b..f7b6748bff 100644 --- a/tests/libslic3r/test_placeholder_parser.cpp +++ b/tests/libslic3r/test_placeholder_parser.cpp @@ -6,33 +6,48 @@ using namespace Slic3r; SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { - PlaceholderParser parser; - auto config = DynamicPrintConfig::full_print_config(); + PlaceholderParser parser; + auto config = DynamicPrintConfig::full_print_config(); - config.set_deserialize_strict( { - { "printer_notes", " PRINTER_VENDOR_PRUSA3D PRINTER_MODEL_MK2 " }, + config.set_deserialize_strict( { + { "printer_notes", " PRINTER_VENDOR_PRUSA3D PRINTER_MODEL_MK2 " }, { "nozzle_diameter", "0.6;0.6;0.6;0.6" }, - { "temperature", "357;359;363;378" } + { "nozzle_temperature", "357;359;363;378" } }); - // To test the "first_layer_extrusion_width" over "first_layer_heigth". - // "first_layer_heigth" over "layer_height" is no more supported after first_layer_height was moved from PrintObjectConfig to PrintConfig. -// config.option("first_layer_height")->value = 150.; -// config.option("first_layer_height")->percent = true; - config.option("first_layer_height")->value = 1.5 * config.opt_float("layer_height"); - config.option("first_layer_height")->percent = false; - // To let the PlaceholderParser throw when referencing first_layer_speed if it is set to percent, as the PlaceholderParser does not know + // To let the PlaceholderParser throw when referencing initial_layer_line_width if it is set to percent, as the PlaceholderParser does not know // a percent to what. - config.option("first_layer_speed")->value = 50.; - config.option("first_layer_speed")->percent = true; + config.option("initial_layer_line_width")->value = 50.; + config.option("initial_layer_line_width")->percent = true; parser.apply_config(config); - parser.set("foo", 0); - parser.set("bar", 2); - parser.set("num_extruders", 4); + parser.set("foo", 0); + parser.set("bar", 2); + parser.set("num_extruders", 4); - SECTION("nested config options (legacy syntax)") { REQUIRE(parser.process("[temperature_[foo]]") == "357"); } - SECTION("array reference") { REQUIRE(parser.process("{temperature[foo]}") == "357"); } - SECTION("whitespaces and newlines are maintained") { REQUIRE(parser.process("test [ temperature_ [foo] ] \n hu") == "test 357 \n hu"); } + SECTION("nested config options (legacy syntax)") { REQUIRE(parser.process("[nozzle_temperature_[foo]]") == "357"); } + SECTION("array reference") { REQUIRE(parser.process("{nozzle_temperature[foo]}") == "357"); } + SECTION("whitespaces and newlines are maintained") { REQUIRE(parser.process("test [ nozzle_temperature_ [foo] ] \n hu") == "test 357 \n hu"); } + + // Test the "coFloatOrPercent" and "xxx_width" substitutions. + + // 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)); } + // 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)); } + // small_perimeter_speed ratio over outer_wall_speed + SECTION("small_perimeter_speed") { REQUIRE(std::stod(parser.process("{small_perimeter_speed}")) == 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)); } + + // 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. + SECTION("initial_layer_line_width throws failed to resolve the ratio_over dependencies") { REQUIRE_THROWS(parser.process("{initial_layer_line_width}")); } // Test the math expressions. SECTION("math: 2*3") { REQUIRE(parser.process("{2*3}") == "6"); } @@ -69,19 +84,6 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { 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.)); } - // Test the "coFloatOrPercent" and "xxx_extrusion_width" substitutions. - // first_layer_extrusion_width ratio_over first_layer_heigth. - SECTION("perimeter_extrusion_width") { REQUIRE(std::stod(parser.process("{perimeter_extrusion_width}")) == Approx(0.67500001192092896)); } - SECTION("first_layer_extrusion_width") { REQUIRE(std::stod(parser.process("{first_layer_extrusion_width}")) == Approx(0.9)); } - SECTION("support_material_xy_spacing") { REQUIRE(std::stod(parser.process("{support_material_xy_spacing}")) == Approx(0.3375)); } - // external_perimeter_speed over perimeter_speed - SECTION("external_perimeter_speed") { REQUIRE(std::stod(parser.process("{external_perimeter_speed}")) == Approx(30.)); } - // infill_overlap over perimeter_extrusion_width - SECTION("infill_overlap") { REQUIRE(std::stod(parser.process("{infill_overlap}")) == Approx(0.16875)); } - // If first_layer_speed 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. - SECTION("first_layer_speed") { REQUIRE_THROWS(parser.process("{first_layer_speed}")); } - // Test the boolean expression parser. auto boolean_expression = [&parser](const std::string& templ) { return parser.evaluate_boolean_expression(templ, parser.config()); };