|
@@ -2,25 +2,115 @@
|
|
|
|
|
|
#include "test_data.hpp"
|
|
|
#include "clipper/clipper_z.hpp"
|
|
|
+#include "libslic3r/clipper.hpp"
|
|
|
|
|
|
using namespace Slic3r;
|
|
|
|
|
|
-// Test case for an issue with duplicity vertices (same XY coordinates but differ in Z coordinates) in Clipper 6.2.9,
|
|
|
-// (related to https://sourceforge.net/p/polyclipping/bugs/160/) that was fixed in Clipper 6.4.2.
|
|
|
-SCENARIO("Clipper Z", "[ClipperZ]")
|
|
|
+// tests for ExPolygon::overlaps(const ExPolygon &other)
|
|
|
+SCENARIO("Clipper intersection with polyline", "[Clipper]")
|
|
|
{
|
|
|
- ClipperLib_Z::Path subject;
|
|
|
+ struct TestData {
|
|
|
+ ClipperLib::Path subject;
|
|
|
+ ClipperLib::Path clip;
|
|
|
+ ClipperLib::Paths result;
|
|
|
+ };
|
|
|
+
|
|
|
+ auto run_test = [](const TestData &data) {
|
|
|
+ ClipperLib::Clipper clipper;
|
|
|
+ clipper.AddPath(data.subject, ClipperLib::ptSubject, false);
|
|
|
+ clipper.AddPath(data.clip, ClipperLib::ptClip, true);
|
|
|
+
|
|
|
+ ClipperLib::PolyTree polytree;
|
|
|
+ ClipperLib::Paths paths;
|
|
|
+ clipper.Execute(ClipperLib::ctIntersection, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
|
|
+ ClipperLib::PolyTreeToPaths(polytree, paths);
|
|
|
+
|
|
|
+ REQUIRE(paths == data.result);
|
|
|
+ };
|
|
|
|
|
|
- subject.emplace_back(-2000, -1000, 10);
|
|
|
- subject.emplace_back(-2000, 1000, 10);
|
|
|
- subject.emplace_back( 2000, 1000, 10);
|
|
|
- subject.emplace_back( 2000, -1000, 10);
|
|
|
+ WHEN("Open polyline completely inside stays inside") {
|
|
|
+ run_test({
|
|
|
+ { { 10, 0 }, { 20, 0 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { 20, 0 }, { 10, 0 } } }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Closed polyline completely inside stays inside") {
|
|
|
+ run_test({
|
|
|
+ { { 10, 0 }, { 20, 0 }, { 20, 20 }, { 10, 20 }, { 10, 0 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { 10, 0 }, { 20, 0 }, { 20, 20 }, { 10, 20 }, { 10, 0 } } }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Polyline which crosses right rectangle boundary is trimmed") {
|
|
|
+ run_test({
|
|
|
+ { { 10, 0 }, { 2000, 0 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { 1000, 0 }, { 10, 0 } } }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Polyline which is outside clipping region is removed") {
|
|
|
+ run_test({
|
|
|
+ { { 1500, 0 }, { 2000, 0 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { }
|
|
|
+ });
|
|
|
+ };
|
|
|
|
|
|
- ClipperLib_Z::Path clip;
|
|
|
- clip.emplace_back(-1000, -2000, -5);
|
|
|
- clip.emplace_back(-1000, 2000, -5);
|
|
|
- clip.emplace_back( 1000, 2000, -5);
|
|
|
- clip.emplace_back( 1000, -2000, -5);
|
|
|
+ WHEN("Polyline on left vertical boundary is kept") {
|
|
|
+ run_test({
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { -1000, -1000 }, { -1000, 1000 } } }
|
|
|
+ });
|
|
|
+ run_test({
|
|
|
+ { { -1000, 1000 }, { -1000, -1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { -1000, 1000 }, { -1000, -1000 } } }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Polyline on right vertical boundary is kept") {
|
|
|
+ run_test({
|
|
|
+ { { 1000, -1000 }, { 1000, 1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { 1000, -1000 }, { 1000, 1000 } } }
|
|
|
+ });
|
|
|
+ run_test({
|
|
|
+ { { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { { { 1000, 1000 }, { 1000, -1000 } } }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Polyline on bottom horizontal boundary is removed") {
|
|
|
+ run_test({
|
|
|
+ { { -1000, -1000 }, { 1000, -1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { }
|
|
|
+ });
|
|
|
+ run_test({
|
|
|
+ { { 1000, -1000 }, { -1000, -1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ WHEN("Polyline on top horizontal boundary is removed") {
|
|
|
+ run_test({
|
|
|
+ { { -1000, 1000 }, { 1000, 1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { }
|
|
|
+ });
|
|
|
+ run_test({
|
|
|
+ { { 1000, 1000 }, { -1000, 1000 } },
|
|
|
+ { { -1000, -1000 }, { -1000, 1000 }, { 1000, 1000 }, { 1000, -1000 } },
|
|
|
+ { }
|
|
|
+ });
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+SCENARIO("Clipper Z", "[ClipperZ]")
|
|
|
+{
|
|
|
+ ClipperLib_Z::Path subject { { -2000, -1000, 10 }, { -2000, 1000, 10 }, { 2000, 1000, 10 }, { 2000, -1000, 10 } };
|
|
|
+ ClipperLib_Z::Path clip{ { -1000, -2000, -5 }, { -1000, 2000, -5 }, { 1000, 2000, -5 }, { 1000, -2000, -5 } };
|
|
|
|
|
|
ClipperLib_Z::Clipper clipper;
|
|
|
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
|
|
@@ -40,4 +130,5 @@ SCENARIO("Clipper Z", "[ClipperZ]")
|
|
|
REQUIRE(paths.front().size() == 2);
|
|
|
for (const ClipperLib_Z::IntPoint &pt : paths.front())
|
|
|
REQUIRE(pt.z() == 1);
|
|
|
-}
|
|
|
+}
|
|
|
+
|