From 8d60a553361b3a1219311f021da81d67752d256e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bartoletti?= Date: Fri, 12 Jul 2024 16:05:57 +0200 Subject: [PATCH] ForceOrderPoints: also allow for 3D geometries Follow-up https://gitlab.com/sfcgal/SFCGAL/-/merge_requests/324 Fix https://gitlab.com/sfcgal/SFCGAL/-/issues/268 --- src/detail/transform/ForceOrderPoints.cpp | 59 +++++++++++------------ test/unit/SFCGAL/capi/sfcgal_cTest.cpp | 23 +++++++++ 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/detail/transform/ForceOrderPoints.cpp b/src/detail/transform/ForceOrderPoints.cpp index 1317c08b..af2020ed 100644 --- a/src/detail/transform/ForceOrderPoints.cpp +++ b/src/detail/transform/ForceOrderPoints.cpp @@ -29,50 +29,45 @@ ForceOrderPoints::transform(Point & /*p*/) void ForceOrderPoints::visit(Triangle &t) { - if (!t.is3D()) { - if (!algorithm::isCounterClockWiseOriented(t)) { - // not pointing up, reverse - if (_orientCCW) { - t.reverse(); - } - } else { - if (!_orientCCW) { - t.reverse(); - } + if (!algorithm::isCounterClockWiseOriented(t)) { + // not pointing up, reverse + if (_orientCCW) { + t.reverse(); + } + } else { + if (!_orientCCW) { + t.reverse(); } - - Transform::visit(t); } + + Transform::visit(t); } void ForceOrderPoints::visit(Polygon &p) { - if (!p.is3D()) { - LineString &ext = p.exteriorRing(); + LineString &ext = p.exteriorRing(); - if (!algorithm::isCounterClockWiseOriented(p.exteriorRing())) { - // exterior ring not pointing up, reverse - if (_orientCCW) { - ext.reverse(); - } - } else { - if (!_orientCCW) { - ext.reverse(); - } + if (!algorithm::isCounterClockWiseOriented(p.exteriorRing())) { + // exterior ring not pointing up, reverse + if (_orientCCW) { + ext.reverse(); } - - const bool isCCWO{algorithm::isCounterClockWiseOriented(ext)}; - for (size_t i = 0; i < p.numInteriorRings(); ++i) { - LineString &inter = p.interiorRingN(i); - - if (algorithm::isCounterClockWiseOriented(inter) == isCCWO) { - inter.reverse(); - } + } else { + if (!_orientCCW) { + ext.reverse(); } + } + const bool isCCWO{algorithm::isCounterClockWiseOriented(ext)}; + for (size_t i = 0; i < p.numInteriorRings(); ++i) { + LineString &inter = p.interiorRingN(i); - Transform::visit(p); + if (algorithm::isCounterClockWiseOriented(inter) == isCCWO) { + inter.reverse(); + } } + + Transform::visit(p); } } // namespace SFCGAL::transform diff --git a/test/unit/SFCGAL/capi/sfcgal_cTest.cpp b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp index 82faaac3..43c37e2b 100644 --- a/test/unit/SFCGAL/capi/sfcgal_cTest.cpp +++ b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp @@ -214,4 +214,27 @@ BOOST_AUTO_TEST_CASE(testForceLHR) delete[] wkbApi; } +BOOST_AUTO_TEST_CASE(testForceRHR_3D) +{ + sfcgal_set_error_handlers(printf, on_error); + + std::string strGeom{"POLYGON((0 5 1,0 0 2,5 0 3,5 5 4,0 5 1),(2 1 1,1 1 2,1 " + "2 3,2 2 4,2 1 1),(4 3 1,3 3 2,3 4 3,4 4 4,4 3 1))"}; + std::string expectedGeom{ + "POLYGON Z((0 5 1,5 5 4,5 0 3,0 0 2,0 5 1),(2 1 1,2 2 4,1 2 3,1 1 2,2 1 " + "1),(4 3 1,4 4 4,3 4 3,3 3 2,4 3 1))"}; + + std::unique_ptr const geom(io::readWkt(strGeom)); + + sfcgal_geometry_t *rhr = sfcgal_geometry_force_rhr(geom.get()); + // retrieve wkb from C api + char *wkbApi; + size_t wkbLen; + sfcgal_geometry_as_text_decim(rhr, 0, &wkbApi, &wkbLen); + std::string strApi(wkbApi, wkbLen); + + // check + BOOST_CHECK_EQUAL(expectedGeom, strApi); + delete[] wkbApi; +} BOOST_AUTO_TEST_SUITE_END()