Merge branch 'master' into fs_emboss
# Conflicts: # src/libslic3r/Geometry.cpp # src/slic3r/GUI/Gizmos/GLGizmoBase.cpp # src/slic3r/GUI/Gizmos/GLGizmoMove.cpp # src/slic3r/GUI/Gizmos/GLGizmoMove.hpp # src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp # src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp # src/slic3r/GUI/Gizmos/GLGizmoScale.cpp # src/slic3r/GUI/Gizmos/GLGizmoScale.hpp # src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp # src/slic3r/GUI/ImGuiWrapper.cpp # src/slic3r/GUI/ImGuiWrapper.hpp # src/slic3r/GUI/Selection.cpp # tests/slic3rutils/slic3r_jobs_tests.cpp
This commit is contained in:
commit
a50d93cd66
327 changed files with 781602 additions and 153573 deletions
|
@ -7,6 +7,7 @@ add_executable(${_TEST_NAME}_tests
|
|||
test_fill.cpp
|
||||
test_flow.cpp
|
||||
test_gcode.cpp
|
||||
test_gcodefindreplace.cpp
|
||||
test_gcodewriter.cpp
|
||||
test_model.cpp
|
||||
test_print.cpp
|
||||
|
|
292
tests/fff_print/test_gcodefindreplace.cpp
Normal file
292
tests/fff_print/test_gcodefindreplace.cpp
Normal file
|
@ -0,0 +1,292 @@
|
|||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "libslic3r/GCode/FindReplace.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
SCENARIO("Find/Replace with plain text", "[GCodeFindReplace]") {
|
||||
GIVEN("G-code") {
|
||||
const std::string gcode =
|
||||
"G1 Z0; home\n"
|
||||
"G1 Z1; move up\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n";
|
||||
WHEN("Replace \"move up\" with \"move down\", case sensitive") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move up\" with \"move down\", case insensitive") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "i", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move UP\" with \"move down\", case insensitive") {
|
||||
GCodeFindReplace find_replace({ "move UP", "move down", "i", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move up\" with \"move down\", case sensitive") {
|
||||
GCodeFindReplace find_replace({ "move UP", "move down", "", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
|
||||
// Whole word
|
||||
WHEN("Replace \"move up\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "w", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move u\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move u", "move down", "w", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
WHEN("Replace \"ove up\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move u", "move down", "w", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
|
||||
// Multi-line replace
|
||||
WHEN("Replace \"move up\\nG1 X0 \" with \"move down\\nG0 X1 \"") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X0 ", "move down\\nG0 X1 ", "", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G0 X1 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
// Multi-line replace, whole word.
|
||||
WHEN("Replace \"move up\\nG1 X0\" with \"move down\\nG0 X1\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X0", "move down\\nG0 X1", "w", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G0 X1 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
// Multi-line replace, whole word, fails.
|
||||
WHEN("Replace \"move up\\nG1 X\" with \"move down\\nG0 X\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X", "move down\\nG0 X", "w", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("G-code with decimals") {
|
||||
const std::string gcode =
|
||||
"G1 Z0.123; home\n"
|
||||
"G1 Z1.21; move up\n"
|
||||
"G1 X0 Y.33 Z.431 E1.2; perimeter\n";
|
||||
WHEN("Regular expression NOT processed in non-regex mode") {
|
||||
GCodeFindReplace find_replace({ "( [XYZEF]-?)\\.([0-9]+)", "\\10.\\2", "", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Find/Replace with regexp", "[GCodeFindReplace]") {
|
||||
GIVEN("G-code") {
|
||||
const std::string gcode =
|
||||
"G1 Z0; home\n"
|
||||
"G1 Z1; move up\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n";
|
||||
WHEN("Replace \"move up\" with \"move down\", case sensitive") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "r", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move up\" with \"move down\", case insensitive") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "ri", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move UP\" with \"move down\", case insensitive") {
|
||||
GCodeFindReplace find_replace({ "move UP", "move down", "ri", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move up\" with \"move down\", case sensitive") {
|
||||
GCodeFindReplace find_replace({ "move UP", "move down", "r", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
|
||||
// Whole word
|
||||
WHEN("Replace \"move up\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up", "move down", "rw", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G1 X0 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
WHEN("Replace \"move u\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move u", "move down", "rw", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
WHEN("Replace \"ove up\" with \"move down\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move u", "move down", "rw", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
|
||||
// Multi-line replace
|
||||
WHEN("Replace \"move up\\nG1 X0 \" with \"move down\\nG0 X1 \"") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X0 ", "move down\\nG0 X1 ", "r", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G0 X1 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
// Multi-line replace, whole word.
|
||||
WHEN("Replace \"move up\\nG1 X0\" with \"move down\\nG0 X1\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X0", "move down\\nG0 X1", "rw", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0; home\n"
|
||||
// substituted
|
||||
"G1 Z1; move down\n"
|
||||
"G0 X1 Y1 Z1; perimeter\n"
|
||||
"G1 X13 Y32 Z1; infill\n"
|
||||
"G1 X13 Y32 Z1; wipe\n");
|
||||
}
|
||||
// Multi-line replace, whole word, fails.
|
||||
WHEN("Replace \"move up\\nG1 X\" with \"move down\\nG0 X\", whole word") {
|
||||
GCodeFindReplace find_replace({ "move up\\nG1 X", "move down\\nG0 X", "rw", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) == gcode);
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("G-code with decimals") {
|
||||
const std::string gcode =
|
||||
"G1 Z0.123; home\n"
|
||||
"G1 Z1.21; move up\n"
|
||||
"G1 X0 Y.33 Z.431 E1.2; perimeter\n";
|
||||
WHEN("Missing zeros before dot filled in") {
|
||||
GCodeFindReplace find_replace({ "( [XYZEF]-?)\\.([0-9]+)", "\\10.\\2", "r", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z0.123; home\n"
|
||||
"G1 Z1.21; move up\n"
|
||||
"G1 X0 Y0.33 Z0.431 E1.2; perimeter\n");
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Single layer G-code block with extrusion types") {
|
||||
const std::string gcode =
|
||||
// Start of a layer.
|
||||
"G1 Z1.21; move up\n"
|
||||
";TYPE:Infill\n"
|
||||
"G1 X0 Y.33 Z.431 E1.2\n"
|
||||
";TYPE:Solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Perimeter\n"
|
||||
"G1 X0 Y.2 Z.431 E0.2\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n";
|
||||
WHEN("Change extrusion rate of top solid infill, single line modifier") {
|
||||
GCodeFindReplace find_replace({ "(;TYPE:Top solid infill\\n)(.*?)(;TYPE:[^T][^o][^p][^ ][^s]|$)", "${1}M221 S98\\n${2}M221 S95\\n${3}", "rs", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z1.21; move up\n"
|
||||
";TYPE:Infill\n"
|
||||
"G1 X0 Y.33 Z.431 E1.2\n"
|
||||
";TYPE:Solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"M221 S98\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
"M221 S95\n"
|
||||
";TYPE:Perimeter\n"
|
||||
"G1 X0 Y.2 Z.431 E0.2\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"M221 S98\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
"M221 S95\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n");
|
||||
}
|
||||
WHEN("Change extrusion rate of top solid infill, no single line modifier (incorrect)") {
|
||||
GCodeFindReplace find_replace({ "(;TYPE:Top solid infill\\n)(.*?)(;TYPE:[^T][^o][^p][^ ][^s]|$)", "${1}M221 S98\\n${2}\\nM221 S95${3}", "r", "" });
|
||||
REQUIRE(find_replace.process_layer(gcode) ==
|
||||
"G1 Z1.21; move up\n"
|
||||
";TYPE:Infill\n"
|
||||
"G1 X0 Y.33 Z.431 E1.2\n"
|
||||
";TYPE:Solid infill\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"M221 S98\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
"M221 S95\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"M221 S98\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
"M221 S95\n"
|
||||
";TYPE:Perimeter\n"
|
||||
"G1 X0 Y.2 Z.431 E0.2\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
";TYPE:Top solid infill\n"
|
||||
"M221 S98\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n"
|
||||
"M221 S95\n"
|
||||
";TYPE:External perimeter\n"
|
||||
"G1 X1 Y.3 Z.431 E0.1\n");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ add_executable(${_TEST_NAME}_tests
|
|||
test_aabbindirect.cpp
|
||||
test_clipper_offset.cpp
|
||||
test_clipper_utils.cpp
|
||||
test_color.cpp
|
||||
test_config.cpp
|
||||
test_elephant_foot_compensation.cpp
|
||||
test_geometry.cpp
|
||||
|
|
37
tests/libslic3r/test_color.cpp
Normal file
37
tests/libslic3r/test_color.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <catch2/catch.hpp>
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
#include "libslic3r/Color.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
SCENARIO("Color encoding/decoding cycle", "[Color]") {
|
||||
GIVEN("Color") {
|
||||
const ColorRGB src_rgb(static_cast<unsigned char>(255), static_cast<unsigned char>(127), static_cast<unsigned char>(63));
|
||||
WHEN("apply encode/decode cycle") {
|
||||
const std::string encoded = encode_color(src_rgb);
|
||||
ColorRGB res_rgb;
|
||||
decode_color(encoded, res_rgb);
|
||||
const bool ret = res_rgb.r_uchar() == src_rgb.r_uchar() && res_rgb.g_uchar() == src_rgb.g_uchar() && res_rgb.b_uchar() == src_rgb.b_uchar();
|
||||
THEN("result matches source") {
|
||||
REQUIRE(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("Color picking encoding/decoding cycle", "[Color]") {
|
||||
GIVEN("Picking color") {
|
||||
const ColorRGB src_rgb(static_cast<unsigned char>(255), static_cast<unsigned char>(127), static_cast<unsigned char>(63));
|
||||
WHEN("apply encode/decode cycle") {
|
||||
const unsigned int encoded = picking_encode(src_rgb.r_uchar(), src_rgb.g_uchar(), src_rgb.b_uchar());
|
||||
const ColorRGBA res_rgba = picking_decode(encoded);
|
||||
const bool ret = res_rgba.r_uchar() == src_rgb.r_uchar() && res_rgba.g_uchar() == src_rgb.g_uchar() && res_rgba.b_uchar() == src_rgb.b_uchar();
|
||||
THEN("result matches source") {
|
||||
REQUIRE(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,11 +95,14 @@ TEST_CASE("cancel_all should remove all pending jobs", "[Jobs]") {
|
|||
auto pri = std::make_shared<Progress>();
|
||||
BoostThreadWorker worker{pri};
|
||||
|
||||
std::array<bool, 4> jobres = {false};
|
||||
std::array<bool, 4> jobres = {false, false, false, false};
|
||||
|
||||
queue_job(worker, [&jobres](Job::Ctl &) {
|
||||
jobres[0] = true;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
// FIXME: the long wait time is needed to prevent fail in MSVC
|
||||
// where the sleep_for function is behaving stupidly.
|
||||
// see https://developercommunity.visualstudio.com/t/bogus-stdthis-threadsleep-for-implementation/58530
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
});
|
||||
queue_job(worker, [&jobres](Job::Ctl &) {
|
||||
jobres[1] = true;
|
||||
|
@ -114,7 +117,9 @@ TEST_CASE("cancel_all should remove all pending jobs", "[Jobs]") {
|
|||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
});
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
||||
// wait until the first job's half time to be sure, the cancel is made
|
||||
// during the first job's execution.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
worker.cancel_all();
|
||||
|
||||
REQUIRE(jobres[0] == true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue