From de07c1cc3a078f3c1046d833ef000b62301d34fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bartoletti?= Date: Fri, 29 Sep 2023 10:17:53 +0200 Subject: [PATCH] [capi] add visibility to capi --- src/capi/sfcgal_c.cpp | 85 ++++++++++++++++++++++++++++++++++++++++--- src/capi/sfcgal_c.h | 33 ++++++++++++++++- 2 files changed, 111 insertions(+), 7 deletions(-) diff --git a/src/capi/sfcgal_c.cpp b/src/capi/sfcgal_c.cpp index 350bbf4c..695feb75 100644 --- a/src/capi/sfcgal_c.cpp +++ b/src/capi/sfcgal_c.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1259,7 +1260,6 @@ sfcgal_geometry_optimal_alpha_shapes(const sfcgal_geometry_t *geom, return result.release(); } - extern "C" sfcgal_geometry_t * sfcgal_y_monotone_partition_2(const sfcgal_geometry_t *geom) { @@ -1267,7 +1267,8 @@ sfcgal_y_monotone_partition_2(const sfcgal_geometry_t *geom) std::unique_ptr result; try { - result = SFCGAL::algorithm::partition_2(g1->as(), SFCGAL::algorithm::y_monotone); + result = SFCGAL::algorithm::partition_2(g1->as(), + SFCGAL::algorithm::y_monotone); } catch (std::exception &e) { SFCGAL_WARNING("During y_monotone_partition_2(A):"); SFCGAL_WARNING(" with A: %s", @@ -1286,7 +1287,8 @@ sfcgal_approx_convex_partition_2(const sfcgal_geometry_t *geom) std::unique_ptr result; try { - result = SFCGAL::algorithm::partition_2(g1->as(), SFCGAL::algorithm::approx_convex); + result = SFCGAL::algorithm::partition_2(g1->as(), + SFCGAL::algorithm::approx_convex); } catch (std::exception &e) { SFCGAL_WARNING("During approx_convex_partition_2(A):"); SFCGAL_WARNING(" with A: %s", @@ -1305,7 +1307,9 @@ sfcgal_greene_approx_convex_partition_2(const sfcgal_geometry_t *geom) std::unique_ptr result; try { - result = SFCGAL::algorithm::partition_2(g1->as(), SFCGAL::algorithm::greene_approx_convex); + result = + SFCGAL::algorithm::partition_2(g1->as(), + SFCGAL::algorithm::greene_approx_convex); } catch (std::exception &e) { SFCGAL_WARNING("During greene_approx_convex_partition_2(A):"); SFCGAL_WARNING(" with A: %s", @@ -1323,7 +1327,8 @@ sfcgal_optimal_convex_partition_2(const sfcgal_geometry_t *geom) std::unique_ptr result; try { - result = SFCGAL::algorithm::partition_2(g1->as(), SFCGAL::algorithm::optimal_convex); + result = SFCGAL::algorithm::partition_2(g1->as(), + SFCGAL::algorithm::optimal_convex); } catch (std::exception &e) { SFCGAL_WARNING("During optimal_convex_partition_2(A):"); SFCGAL_WARNING(" with A: %s", @@ -1334,3 +1339,73 @@ sfcgal_optimal_convex_partition_2(const sfcgal_geometry_t *geom) return result.release(); } + +extern "C" sfcgal_geometry_t * +sfcgal_geometry_visibility_point(const sfcgal_geometry_t *polygon, + const sfcgal_geometry_t *point) +{ + + const auto *poly = reinterpret_cast(polygon); + const auto *pt = reinterpret_cast(point); + std::unique_ptr result; + + if (poly->geometryTypeId() != SFCGAL::TYPE_POLYGON) { + SFCGAL_ERROR("visibility() only applies to polygons"); + return result.release(); + } + + if (pt->geometryTypeId() != SFCGAL::TYPE_POINT) { + SFCGAL_ERROR("second argument must be a point"); + return result.release(); + } + + try { + result = SFCGAL::algorithm::visibility(poly->as(), + pt->as()); + } catch (std::exception &e) { + SFCGAL_WARNING("During visibility(A, B) :"); + SFCGAL_WARNING(" with A: %s", poly->asText().c_str()); + SFCGAL_WARNING(" and B: %s", pt->asText().c_str()); + SFCGAL_ERROR("%s", e.what()); + return result.release(); + } + + return result.release(); +} + +extern "C" sfcgal_geometry_t * +sfcgal_geometry_visibility_segment(const sfcgal_geometry_t *polygon, + const sfcgal_geometry_t *pointA, + const sfcgal_geometry_t *pointB) +{ + const auto *poly = reinterpret_cast(polygon); + const auto *ptA = reinterpret_cast(pointA); + const auto *ptB = reinterpret_cast(pointB); + std::unique_ptr result; + + if (poly->geometryTypeId() != SFCGAL::TYPE_POLYGON) { + SFCGAL_ERROR("visibility() only applies to polygons"); + return result.release(); + } + + if ((ptA->geometryTypeId() != SFCGAL::TYPE_POINT) || + (ptB->geometryTypeId() != SFCGAL::TYPE_POINT)) { + SFCGAL_ERROR("second and third argument must be a point"); + return result.release(); + } + + try { + result = SFCGAL::algorithm::visibility(poly->as(), + ptA->as(), + ptB->as()); + } catch (std::exception &e) { + SFCGAL_WARNING("During visibility(A, B, C) :"); + SFCGAL_WARNING(" with A: %s", poly->asText().c_str()); + SFCGAL_WARNING(" and B: %s", ptA->asText().c_str()); + SFCGAL_WARNING(" and C: %s", ptB->asText().c_str()); + SFCGAL_ERROR("%s", e.what()); + return result.release(); + } + + return result.release(); +} diff --git a/src/capi/sfcgal_c.h b/src/capi/sfcgal_c.h index 5d386425..b92f63ec 100644 --- a/src/capi/sfcgal_c.h +++ b/src/capi/sfcgal_c.h @@ -57,7 +57,7 @@ typedef enum { // TYPE_SURFACE = 14, //abstract SFCGAL_TYPE_POLYHEDRALSURFACE = 15, SFCGAL_TYPE_TRIANGULATEDSURFACE = 16, - SFCGAL_TYPE_TRIANGLE = 17, + SFCGAL_TYPE_TRIANGLE = 17, //-- not official codes SFCGAL_TYPE_SOLID = 101, @@ -1064,7 +1064,8 @@ SFCGAL_API sfcgal_geometry_t * sfcgal_approx_convex_partition_2(const sfcgal_geometry_t *geom); /** - * Returns the greene approximal convex partition of a geometry (polygon without hole) + * Returns the greene approximal convex partition of a geometry (polygon without + * hole) * @pre isValid(geom) == true * @post isValid(return) == true * @ingroup capi @@ -1081,6 +1082,34 @@ sfcgal_greene_approx_convex_partition_2(const sfcgal_geometry_t *geom); SFCGAL_API sfcgal_geometry_t * sfcgal_optimal_convex_partition_2(const sfcgal_geometry_t *geom); +/** + * Returns the visibility polygon of a Point inside a Polygon + * @param polygon input geometry + * @param point input geometry + * @ingroup capi + * @pre polygon is a valid geometry + * @pre point must be inside polygon or on the boundary + */ +SFCGAL_API sfcgal_geometry_t * +sfcgal_geometry_visibility_point(const sfcgal_geometry_t *polygon, + const sfcgal_geometry_t *point); + +/** + * @brief build the visibility polygon of the segment [pointA ; pointB] on a + * Polygon + * @param polygon input geometry + * @param pointA input geometry + * @param pointB input geometry + * @ingroup public_api + * @pre polygon is a valid geometry + * @pre pointA and pointB must be vertices of poly, adjacents and respect the + * direction + */ +SFCGAL_API sfcgal_geometry_t * +sfcgal_geometry_visibility_segment(const sfcgal_geometry_t *polygon, + const sfcgal_geometry_t *pointA, + const sfcgal_geometry_t *pointB); + /*--------------------------------------------------------------------------------------* * * Error handling