From f460c53d86c4427fd15350e401bcfb05d8511e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Thu, 9 Jun 2022 09:22:40 +0200 Subject: [PATCH] Backported a fix from Clipper 6.4.2 for the issue that Clipper Z coordinated has incorrect value because ZFillFunction wasn't called in all cases (https://sourceforge.net/p/polyclipping/bugs/160/). Also, this issue led to duplicity vertices with the same XY coordinates but differ in Z coordinates. --- src/clipper/clipper.cpp | 9 +++++++ tests/fff_print/CMakeLists.txt | 1 + tests/fff_print/test_clipper.cpp | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/fff_print/test_clipper.cpp diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index 84d68b1e6..84109398a 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -2290,6 +2290,12 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) if (horzEdge->OutIdx >= 0 && !IsOpen) //note: may be done multiple times { +#ifdef CLIPPERLIB_USE_XYZ + if (dir == dLeftToRight) + SetZ(e->Curr, *horzEdge, *e); + else + SetZ(e->Curr, *e, *horzEdge); +#endif op1 = AddOutPt(horzEdge, e->Curr); TEdge* eNextHorz = m_SortedEdges; while (eNextHorz) @@ -2614,6 +2620,9 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) { e->Curr.x() = TopX( *e, topY ); e->Curr.y() = topY; +#ifdef CLIPPERLIB_USE_XYZ + e->Curr.z() = topY == e->Top.y() ? e->Top.z() : (topY == e->Bot.y() ? e->Bot.z() : 0); +#endif } //When StrictlySimple and 'e' is being touched by another edge, then diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 50b45e384..8ea989855 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -1,6 +1,7 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp + test_clipper.cpp test_data.cpp test_data.hpp test_extrusion_entity.cpp diff --git a/tests/fff_print/test_clipper.cpp b/tests/fff_print/test_clipper.cpp new file mode 100644 index 000000000..dc49ce0f1 --- /dev/null +++ b/tests/fff_print/test_clipper.cpp @@ -0,0 +1,43 @@ +#include + +#include "test_data.hpp" +#include "clipper/clipper_z.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]") +{ + ClipperLib_Z::Path subject; + + subject.emplace_back(-2000, -1000, 10); + subject.emplace_back(-2000, 1000, 10); + subject.emplace_back( 2000, 1000, 10); + subject.emplace_back( 2000, -1000, 10); + + 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); + + ClipperLib_Z::Clipper clipper; + clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot, + const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) { + pt.z() = 1; + }); + + clipper.AddPath(subject, ClipperLib_Z::ptSubject, false); + clipper.AddPath(clip, ClipperLib_Z::ptClip, true); + + ClipperLib_Z::PolyTree polytree; + ClipperLib_Z::Paths paths; + clipper.Execute(ClipperLib_Z::ctIntersection, polytree, ClipperLib_Z::pftNonZero, ClipperLib_Z::pftNonZero); + ClipperLib_Z::PolyTreeToPaths(polytree, paths); + + REQUIRE(paths.size() == 1); + REQUIRE(paths.front().size() == 2); + for (const ClipperLib_Z::IntPoint &pt : paths.front()) + REQUIRE(pt.z() == 1); +} \ No newline at end of file