123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #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");
- }
- }
- }
|