From d5b1bfe199be7a299769bf7c9465121d08d9b785 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Mon, 13 May 2024 16:45:27 +0200 Subject: [PATCH 01/16] Adding straight skeleton with holes --- CHANGELOG.md | 1 + .../cgal_straight_skeleton_2_holes.png | Bin 0 -> 73090 bytes docs/api/compas_cgal.straight_skeleton_2.rst | 1 + docs/examples/straight_skeleton_2.rst | 9 +++ docs/examples/straight_skeleton_2_holes.py | 42 ++++++++++++++ src/compas_cgal/straight_skeleton_2.py | 36 ++++++++++++ src/straight_skeleton_2.cpp | 52 ++++++++++++++++++ src/straight_skeleton_2.h | 5 ++ tests/test_straight_skeleton_2.py | 20 ++++++- 9 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 docs/_images/cgal_straight_skeleton_2_holes.png create mode 100644 docs/examples/straight_skeleton_2_holes.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e15869f..01e70c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added * Added `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton`. +* Added `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton_with_holes`. ### Changed diff --git a/docs/_images/cgal_straight_skeleton_2_holes.png b/docs/_images/cgal_straight_skeleton_2_holes.png new file mode 100644 index 0000000000000000000000000000000000000000..b535e924e449bb5c84c5e4b127e8284277036b20 GIT binary patch literal 73090 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 PolylinesNumpy: raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") V = np.asarray(points, dtype=np.float64) return straight_skeleton_2.create_interior_straight_skeleton(V) + + +def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNumpy: + """Compute the skeleton of a polygon with holes. + + Parameters + ---------- + points : list of point coordinates or :class:`compas.geometry.Polygon` + The points of the polygon. + holes : list of list of point coordinates or list of :class:`compas.geometry.Polygon` + The holes of the polygon. + + Returns + ------- + :attr:`compas_cgal.types.PolylinesNumpy` + The skeleton of the polygon. + + Raises + ------ + ValueError + If the normal of the polygon is not [0, 0, 1]. + If the normal of a hole is not [0, 0, -1]. + """ + points = list(points) + if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): + raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + H = [] + for hole in holes: + points = list(hole) + if not TOL.is_allclose(normal_polygon(points, True), [0, 0, -1]): + raise ValueError("Please pass a hole with a normal vector of [0, 0, -1].") + hole = np.asarray(points, dtype=np.float64) + H.append(hole) + + V = np.asarray(points, dtype=np.float64) + return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) diff --git a/src/straight_skeleton_2.cpp b/src/straight_skeleton_2.cpp index 5194546..02f1697 100644 --- a/src/straight_skeleton_2.cpp +++ b/src/straight_skeleton_2.cpp @@ -2,10 +2,12 @@ #include "straight_skeleton_2.h" #include #include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_2 Point; typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::Polygon_with_holes_2 Polygon_with_holes; typedef CGAL::Straight_skeleton_2 Ss; typedef boost::shared_ptr SsPtr; typedef CGAL::Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle; @@ -39,6 +41,50 @@ compas::Edges pmp_create_interior_straight_skeleton( return edgelist; }; +compas::Edges pmp_create_interior_straight_skeleton_with_holes( + Eigen::Ref &V, + std::vector> &holes) +{ + Polygon_2 outer; + for (int i = 0; i < V.rows(); i++) + { + outer.push_back(Point(V(i, 0), V(i, 1))); + } + Polygon_with_holes poly(outer); + + + for (auto hit : holes) + { + compas::RowMatrixXd H = hit; + Polygon_2 hole; + for (int i = 0; i < H.rows(); i++) + { + hole.push_back(Point(H(i, 0), H(i, 1))); + } + poly.add_hole(hole); + + } + + SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly); + compas::Edges edgelist; + for(auto hit = iss->halfedges_begin(); hit != iss->halfedges_end(); ++hit){ + const Halfedge_const_handle h = hit; + if(!h->is_bisector()){ + continue; + } + const Vertex_const_handle& v1 = h->vertex(); + const Vertex_const_handle& v2 = h->opposite()->vertex(); + if(&*v1 < &*v2){ + std::vector s_vec = {v1->point().x(), v1->point().y(), 0}; + std::vector t_vec = {v2->point().x(), v2->point().y(), 0}; + compas::Edge edge = std::make_tuple(s_vec, t_vec); + edgelist.push_back(edge); + } + + } + return edgelist; + +} // =========================================================================== // PyBind11 @@ -52,4 +98,10 @@ void init_straight_skeleton_2(pybind11::module &m) "create_interior_straight_skeleton", &pmp_create_interior_straight_skeleton, pybind11::arg("V").noconvert()); + + submodule.def( + "create_interior_straight_skeleton_with_holes", + &pmp_create_interior_straight_skeleton_with_holes, + pybind11::arg("V").noconvert(), + pybind11::arg("holes").noconvert()); }; diff --git a/src/straight_skeleton_2.h b/src/straight_skeleton_2.h index d84b3c3..baad317 100644 --- a/src/straight_skeleton_2.h +++ b/src/straight_skeleton_2.h @@ -7,4 +7,9 @@ compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V); + +compas::Edges pmp_create_interior_straight_skeleton_with_holes( + Eigen::Ref &V, + std::vector> &holes); + #endif /* COMPAS_STRAIGHT_SKELETON_2_H */ diff --git a/tests/test_straight_skeleton_2.py b/tests/test_straight_skeleton_2.py index 47e4fad..80d419d 100644 --- a/tests/test_straight_skeleton_2.py +++ b/tests/test_straight_skeleton_2.py @@ -1,6 +1,8 @@ -from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton from compas.tolerance import TOL +from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton +from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton_with_holes + def test_straight_polygon(): points = [ @@ -17,6 +19,22 @@ def test_straight_polygon(): assert len(lines) == 8 +def test_straight_skeleton_with_holes(): + points = [ + (-1, -1, 0), + (0, -12, 0), + (1, -1, 0), + (12, 0, 0), + (1, 1, 0), + (0, 12, 0), + (-1, 1, 0), + (-12, 0, 0), + ] + hole = [(-1, 0, 0), (0, 1, 0), (1, 0, 0), (0, -1, 0)] + lines = create_interior_straight_skeleton_with_holes(points, [hole]) + assert len(lines) == 20 + + def test_straight_polygon_2_compare(): points = [ (-1.91, 3.59, 0.0), From 691a3d0e20c8603510141b15b38b376e4e5603f9 Mon Sep 17 00:00:00 2001 From: Romana Rust <117177043+romanavyzn@users.noreply.github.com> Date: Tue, 14 May 2024 09:56:08 +0200 Subject: [PATCH 02/16] Update straight_skeleton_2.py --- src/compas_cgal/straight_skeleton_2.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index e97b09a..3703d09 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -56,6 +56,7 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump points = list(points) if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + V = np.asarray(points, dtype=np.float64) H = [] for hole in holes: points = list(hole) @@ -63,6 +64,4 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump raise ValueError("Please pass a hole with a normal vector of [0, 0, -1].") hole = np.asarray(points, dtype=np.float64) H.append(hole) - - V = np.asarray(points, dtype=np.float64) return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) From 1eb09a4ad214daa1507f831fcd70b96c756865c6 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Tue, 14 May 2024 11:07:01 +0200 Subject: [PATCH 03/16] Update straight_skeleton_2.py --- src/compas_cgal/straight_skeleton_2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index 3703d09..38b9eff 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -57,6 +57,7 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") V = np.asarray(points, dtype=np.float64) + H = [] for hole in holes: points = list(hole) From 4310a02b4292ee1ff87baf03d94ba15f92776c40 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Wed, 3 Jul 2024 21:42:53 +0200 Subject: [PATCH 04/16] adding inner and outer offsets --- docs/examples/straight_skeleton_offset.py | 36 +++++++++++++ src/compas_cgal/straight_skeleton_2.py | 15 ++++++ src/straight_skeleton_2.cpp | 61 +++++++++++++++++++++++ src/straight_skeleton_2.h | 9 +++- tests/test_straight_skeleton_2.py | 20 +++++++- 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 docs/examples/straight_skeleton_offset.py diff --git a/docs/examples/straight_skeleton_offset.py b/docs/examples/straight_skeleton_offset.py new file mode 100644 index 0000000..5d11de0 --- /dev/null +++ b/docs/examples/straight_skeleton_offset.py @@ -0,0 +1,36 @@ +from compas.datastructures import Graph +from compas.geometry import Polygon +from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 +from compas_viewer import Viewer + +points = [ + (-1.91, 3.59, 0.0), + (-5.53, -5.22, 0.0), + (-0.39, -1.98, 0.0), + (2.98, -5.51, 0.0), + (4.83, -2.02, 0.0), + (9.70, -3.63, 0.0), + (12.23, 1.25, 0.0), + (3.42, 0.66, 0.0), + (2.92, 4.03, 0.0), + (-1.91, 3.59, 0.0), +] +polygon = Polygon(points) +offset = 1.5 + +offset_polygons_inner = create_offset_polygons_2(points, offset) +offset_polygons_outer = create_offset_polygons_2(points, -offset) + +# ============================================================================== +# Viz +# ============================================================================== + +viewer = Viewer(width=1600, height=900) +viewer.scene.add(polygon) + +for opolygon in offset_polygons_inner: + viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0)) +for opolygon in offset_polygons_outer: + viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0)) + +viewer.show() diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index 38b9eff..fc7bccb 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -1,5 +1,6 @@ import numpy as np from compas.geometry import normal_polygon +from compas.geometry import Polygon from compas.tolerance import TOL from compas_cgal._cgal import straight_skeleton_2 @@ -66,3 +67,17 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump hole = np.asarray(points, dtype=np.float64) H.append(hole) return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) + + +def create_offset_polygons_2(points, offset) -> PolylinesNumpy: + points = list(points) + if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): + raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + V = np.asarray(points, dtype=np.float64) + offset = float(offset) + if offset < 0: # outside + offset_polygons = straight_skeleton_2.create_offset_polygons_2_outer(V, abs(offset))[1:] # first one is box + else: # inside + offset_polygons = straight_skeleton_2.create_offset_polygons_2_inner(V, offset) + return [Polygon(points.tolist()) for points in offset_polygons] + diff --git a/src/straight_skeleton_2.cpp b/src/straight_skeleton_2.cpp index 02f1697..ae1cf55 100644 --- a/src/straight_skeleton_2.cpp +++ b/src/straight_skeleton_2.cpp @@ -3,6 +3,7 @@ #include #include #include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_2 Point; @@ -12,6 +13,8 @@ typedef CGAL::Straight_skeleton_2 Ss; typedef boost::shared_ptr SsPtr; typedef CGAL::Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle; typedef CGAL::Straight_skeleton_2::Vertex_const_handle Vertex_const_handle; +typedef boost::shared_ptr PolygonPtr; +typedef std::vector PolygonPtrVector; compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V) @@ -86,6 +89,52 @@ compas::Edges pmp_create_interior_straight_skeleton_with_holes( } +std::vector pmp_create_offset_polygons_2_inner(Eigen::Ref &V, double &offset){ + Polygon_2 poly; + for (int i = 0; i < V.rows(); i++){ + poly.push_back(Point(V(i, 0), V(i, 1))); + } + PolygonPtrVector offset_polygons = CGAL::create_interior_skeleton_and_offset_polygons_2(offset, poly); + + std::vector result; + for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ + std::size_t n = (*pi)->size(); + compas::RowMatrixXd points(n, 3); + int j = 0; + for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ + points(j, 0) = (double)(*vi).x(); + points(j, 1) = (double)(*vi).y(); + points(j, 2) = 0; + j++; + } + result.push_back(points); + } + return result; +} + +std::vector pmp_create_offset_polygons_2_outer(Eigen::Ref &V, double &offset){ + Polygon_2 poly; + for (int i = 0; i < V.rows(); i++){ + poly.push_back(Point(V(i, 0), V(i, 1))); + } + PolygonPtrVector offset_polygons = CGAL::create_exterior_skeleton_and_offset_polygons_2(offset, poly); + + std::vector result; + for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ + std::size_t n = (*pi)->size(); + compas::RowMatrixXd points(n, 3); + int j = 0; + for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ + points(j, 0) = (double)(*vi).x(); + points(j, 1) = (double)(*vi).y(); + points(j, 2) = 0; + j++; + } + result.push_back(points); + } + return result; +} + // =========================================================================== // PyBind11 // =========================================================================== @@ -104,4 +153,16 @@ void init_straight_skeleton_2(pybind11::module &m) &pmp_create_interior_straight_skeleton_with_holes, pybind11::arg("V").noconvert(), pybind11::arg("holes").noconvert()); + + submodule.def( + "create_offset_polygons_2_inner", + &pmp_create_offset_polygons_2_inner, + pybind11::arg("V").noconvert(), + pybind11::arg("offset").noconvert()); + + submodule.def( + "create_offset_polygons_2_outer", + &pmp_create_offset_polygons_2_outer, + pybind11::arg("V").noconvert(), + pybind11::arg("offset").noconvert()); }; diff --git a/src/straight_skeleton_2.h b/src/straight_skeleton_2.h index baad317..ae59d88 100644 --- a/src/straight_skeleton_2.h +++ b/src/straight_skeleton_2.h @@ -7,9 +7,16 @@ compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V); - compas::Edges pmp_create_interior_straight_skeleton_with_holes( Eigen::Ref &V, std::vector> &holes); +std::vector pmp_create_offset_polygons_2_inner( + Eigen::Ref &V, + double &offset); + +std::vector pmp_create_offset_polygons_2_outer( + Eigen::Ref &V, + double &offset); + #endif /* COMPAS_STRAIGHT_SKELETON_2_H */ diff --git a/tests/test_straight_skeleton_2.py b/tests/test_straight_skeleton_2.py index 80d419d..c700dc4 100644 --- a/tests/test_straight_skeleton_2.py +++ b/tests/test_straight_skeleton_2.py @@ -2,7 +2,7 @@ from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton_with_holes - +from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 def test_straight_polygon(): points = [ @@ -73,3 +73,21 @@ def test_straight_polygon_2_compare(): # the line direction sometimes changes ... assert TOL.is_allclose(sa, se) or TOL.is_allclose(sa, ee) assert TOL.is_allclose(ea, ee) or TOL.is_allclose(ea, se) + + +def test_offset(): + points = [ + (-1, -1, 0), + (0, -12, 0), + (1, -1, 0), + (12, 0, 0), + (1, 1, 0), + (0, 12, 0), + (-1, 1, 0), + (-12, 0, 0), + ] + offset = 0.5 + polygons = create_offset_polygons_2(points, offset) + assert len(polygons) == 1, len(polygons) + polygons = create_offset_polygons_2(points, -offset) + assert len(polygons) == 1, len(polygons) From 50781334350e9c42183f57a9a70241bb809b6187 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:37:33 +0200 Subject: [PATCH 05/16] remove placeholder --- docs/PLACEHOLDER | 1 - docs/_images/PLACEHOLDER | 1 - 2 files changed, 2 deletions(-) delete mode 100644 docs/PLACEHOLDER delete mode 100644 docs/_images/PLACEHOLDER diff --git a/docs/PLACEHOLDER b/docs/PLACEHOLDER deleted file mode 100644 index f9768c1..0000000 --- a/docs/PLACEHOLDER +++ /dev/null @@ -1 +0,0 @@ -# container for the source files of the documentation diff --git a/docs/_images/PLACEHOLDER b/docs/_images/PLACEHOLDER deleted file mode 100644 index 48f73eb..0000000 --- a/docs/_images/PLACEHOLDER +++ /dev/null @@ -1 +0,0 @@ -# container for images to be included in the docs From 21699780a8d2d5f39ef605ba47ea6cdf91afdc90 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:37:54 +0200 Subject: [PATCH 06/16] adding offset func --- src/straight_skeleton_2.cpp | 73 +++++++++++++++++++++++++++++++++++++ src/straight_skeleton_2.h | 10 +++++ 2 files changed, 83 insertions(+) diff --git a/src/straight_skeleton_2.cpp b/src/straight_skeleton_2.cpp index ae1cf55..dcbde6a 100644 --- a/src/straight_skeleton_2.cpp +++ b/src/straight_skeleton_2.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_2 Point; @@ -135,6 +137,62 @@ std::vector pmp_create_offset_polygons_2_outer(Eigen::Ref pmp_create_weighted_offset_polygons_2_inner(Eigen::Ref &V, double &offset, Eigen::Ref &weights){ + Polygon_2 poly; + for (int i = 0; i < V.rows(); i++){ + poly.push_back(Point(V(i, 0), V(i, 1))); + } + std::vector weights_vec; + for (int i = 0; i < weights.rows(); i++){ + weights_vec.push_back(weights(i, 0)); + } + SsPtr iss = CGAL::create_interior_weighted_straight_skeleton_2(poly, weights_vec); + PolygonPtrVector offset_polygons = CGAL::create_offset_polygons_2(offset, *iss); + + std::vector result; + for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ + std::size_t n = (*pi)->size(); + compas::RowMatrixXd points(n, 3); + int j = 0; + for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ + points(j, 0) = (double)(*vi).x(); + points(j, 1) = (double)(*vi).y(); + points(j, 2) = 0; + j++; + } + result.push_back(points); + } + return result; +} + +std::vector pmp_create_weighted_offset_polygons_2_outer(Eigen::Ref &V, double &offset, Eigen::Ref &weights){ + Polygon_2 poly; + for (int i = 0; i < V.rows(); i++){ + poly.push_back(Point(V(i, 0), V(i, 1))); + } + std::vector weights_vec; + for (int i = 0; i < weights.rows(); i++){ + weights_vec.push_back(weights(i, 0)); + } + SsPtr iss = CGAL::create_exterior_weighted_straight_skeleton_2(offset, weights_vec, poly); + PolygonPtrVector offset_polygons = CGAL::create_offset_polygons_2(offset, *iss); + + std::vector result; + for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ + std::size_t n = (*pi)->size(); + compas::RowMatrixXd points(n, 3); + int j = 0; + for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ + points(j, 0) = (double)(*vi).x(); + points(j, 1) = (double)(*vi).y(); + points(j, 2) = 0; + j++; + } + result.push_back(points); + } + return result; +} + // =========================================================================== // PyBind11 // =========================================================================== @@ -165,4 +223,19 @@ void init_straight_skeleton_2(pybind11::module &m) &pmp_create_offset_polygons_2_outer, pybind11::arg("V").noconvert(), pybind11::arg("offset").noconvert()); + + submodule.def( + "create_weighted_offset_polygons_2_inner", + &pmp_create_weighted_offset_polygons_2_inner, + pybind11::arg("V").noconvert(), + pybind11::arg("offset").noconvert(), + pybind11::arg("weights").noconvert()); + + submodule.def( + "create_weighted_offset_polygons_2_outer", + &pmp_create_weighted_offset_polygons_2_outer, + pybind11::arg("V").noconvert(), + pybind11::arg("offset").noconvert(), + pybind11::arg("weights").noconvert()); + }; diff --git a/src/straight_skeleton_2.h b/src/straight_skeleton_2.h index ae59d88..7f723a3 100644 --- a/src/straight_skeleton_2.h +++ b/src/straight_skeleton_2.h @@ -19,4 +19,14 @@ std::vector pmp_create_offset_polygons_2_outer( Eigen::Ref &V, double &offset); +std::vector pmp_create_weighted_offset_polygons_2_inner( + Eigen::Ref &V, + double &offset, + Eigen::Ref &weights); + +std::vector pmp_create_weighted_offset_polygons_2_outer( + Eigen::Ref &V, + double &offset, + Eigen::Ref &weights); + #endif /* COMPAS_STRAIGHT_SKELETON_2_H */ From 5f32935761208056c3c24ce9d8be15134b69ac3a Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:38:41 +0200 Subject: [PATCH 07/16] updating docs --- .../cgal_straight_skeleton_2_offset.png | Bin 0 -> 45097 bytes ...al_straight_skeleton_2_offset_weighted.png | Bin 0 -> 36406 bytes docs/examples/straight_skeleton_2.rst | 18 +++++++++ ...ffset.py => straight_skeleton_2_offset.py} | 9 +++-- .../straight_skeleton_2_offset_weighted.py | 37 ++++++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 docs/_images/cgal_straight_skeleton_2_offset.png create mode 100644 docs/_images/cgal_straight_skeleton_2_offset_weighted.png rename docs/examples/{straight_skeleton_offset.py => straight_skeleton_2_offset.py} (80%) create mode 100644 docs/examples/straight_skeleton_2_offset_weighted.py diff --git a/docs/_images/cgal_straight_skeleton_2_offset.png b/docs/_images/cgal_straight_skeleton_2_offset.png new file mode 100644 index 0000000000000000000000000000000000000000..0868a50b219066f1ee1d0e7fa3c8714b0f6be0a0 GIT binary patch literal 45097 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 JrE+G${|7pE1pNR2 literal 0 HcmV?d00001 diff --git a/docs/examples/straight_skeleton_2.rst b/docs/examples/straight_skeleton_2.rst index cc1a9bf..9d33bbb 100644 --- a/docs/examples/straight_skeleton_2.rst +++ b/docs/examples/straight_skeleton_2.rst @@ -18,3 +18,21 @@ .. literalinclude:: straight_skeleton_2_holes.py :language: python + + +.. figure:: /_images/cgal_straight_skeleton_2_offset.png + :figclass: figure + :class: figure-img img-fluid + + +.. literalinclude:: straight_skeleton_2_offset.py + :language: python + + +.. figure:: /_images/cgal_straight_skeleton_2_offset_weighted.png + :figclass: figure + :class: figure-img img-fluid + + +.. literalinclude:: straight_skeleton_2_offset_weighted.py + :language: python diff --git a/docs/examples/straight_skeleton_offset.py b/docs/examples/straight_skeleton_2_offset.py similarity index 80% rename from docs/examples/straight_skeleton_offset.py rename to docs/examples/straight_skeleton_2_offset.py index 5d11de0..c2dfd46 100644 --- a/docs/examples/straight_skeleton_offset.py +++ b/docs/examples/straight_skeleton_2_offset.py @@ -1,8 +1,8 @@ -from compas.datastructures import Graph from compas.geometry import Polygon -from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 from compas_viewer import Viewer +from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 + points = [ (-1.91, 3.59, 0.0), (-5.53, -5.22, 0.0), @@ -27,10 +27,11 @@ viewer = Viewer(width=1600, height=900) viewer.scene.add(polygon) +viewer.config.renderer.show_grid = False for opolygon in offset_polygons_inner: - viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0)) + viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0), facecolor=(1.0, 1.0, 1.0, 0.0)) for opolygon in offset_polygons_outer: - viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0)) + viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0), facecolor=(1.0, 1.0, 1.0, 0.0)) viewer.show() diff --git a/docs/examples/straight_skeleton_2_offset_weighted.py b/docs/examples/straight_skeleton_2_offset_weighted.py new file mode 100644 index 0000000..b7ce2b0 --- /dev/null +++ b/docs/examples/straight_skeleton_2_offset_weighted.py @@ -0,0 +1,37 @@ +from compas.geometry import Polygon +from compas_viewer import Viewer + +from compas_cgal.straight_skeleton_2 import create_weighted_offset_polygons_2 + +points = [ + (-1.91, 3.59, 0.0), + (-5.53, -5.22, 0.0), + (-0.39, -1.98, 0.0), + (2.98, -5.51, 0.0), + (4.83, -2.02, 0.0), + (9.70, -3.63, 0.0), + (12.23, 1.25, 0.0), + (3.42, 0.66, 0.0), + (2.92, 4.03, 0.0), + (-1.91, 3.59, 0.0), +] +polygon = Polygon(points) + + +distances = [0.1, 0.3, 0.6, 0.1, 0.7, 0.5, 0.2, 0.4, 0.8, 0.2] +weights = [1.0 / d for d in distances] +offset = 1.0 +offset_polygons_outer = create_weighted_offset_polygons_2(points, -offset, weights) + +# ============================================================================== +# Viz +# ============================================================================== + +viewer = Viewer(width=1600, height=900) +viewer.scene.add(polygon) +viewer.config.renderer.show_grid = False + +for opolygon in offset_polygons_outer: + viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0), facecolor=(1.0, 1.0, 1.0, 0.0)) + +viewer.show() From 198a609532d68fbb28ccd79b8246905aaa6bbede Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:38:58 +0200 Subject: [PATCH 08/16] tests --- src/compas_cgal/straight_skeleton_2.py | 70 +++++++++++++++++++++++--- tests/test_straight_skeleton_2.py | 7 +++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index fc7bccb..510475a 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -1,6 +1,5 @@ import numpy as np -from compas.geometry import normal_polygon -from compas.geometry import Polygon +from compas.geometry import Polygon, normal_polygon from compas.tolerance import TOL from compas_cgal._cgal import straight_skeleton_2 @@ -69,15 +68,74 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) -def create_offset_polygons_2(points, offset) -> PolylinesNumpy: +def create_offset_polygons_2(points, offset): + """Compute the polygon offset. + + Parameters + ---------- + points : list of point coordinates or :class:`compas.geometry.Polygon` + The points of the polygon. + offset : float + The offset distance. If negative, the offset is outside the polygon, otherwise inside. + + Returns + ------- + list of Polygon + The offset polygon(s). + + Raises + ------ + ValueError + If the normal of the polygon is not [0, 0, 1]. + """ points = list(points) if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") V = np.asarray(points, dtype=np.float64) offset = float(offset) - if offset < 0: # outside - offset_polygons = straight_skeleton_2.create_offset_polygons_2_outer(V, abs(offset))[1:] # first one is box - else: # inside + if offset < 0: # outside + offset_polygons = straight_skeleton_2.create_offset_polygons_2_outer(V, abs(offset))[1:] # first one is box + else: # inside offset_polygons = straight_skeleton_2.create_offset_polygons_2_inner(V, offset) return [Polygon(points.tolist()) for points in offset_polygons] + +def create_weighted_offset_polygons_2(points, offset, weights): + """Compute the polygon offset with weights. + + Parameters + ---------- + points : list of point coordinates or :class:`compas.geometry.Polygon` + The points of the polygon. + offset : float + The offset distance. If negative, the offset is outside the polygon, otherwise inside. + weights : list of float + The weights for each edge, starting with the edge between the last and the first point. + + Returns + ------- + list of Polygon + The offset polygon(s). + + Raises + ------ + ValueError + If the normal of the polygon is not [0, 0, 1]. + ValueError + If the number of weights do not match the number of points. + """ + points = list(points) + if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): + raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + V = np.asarray(points, dtype=np.float64) + offset = float(offset) + W = np.asarray(weights, dtype=np.float64) + if W.shape[0] != V.shape[0]: + raise ValueError( + "The number of weights should be equal to the number of points %d != %d." % (W.shape[0], V.shape[0]) + ) + if offset < 0: + offset_polygons = straight_skeleton_2.create_weighted_offset_polygons_2_outer(V, abs(offset), W)[1:] + else: + offset_polygons = straight_skeleton_2.create_weighted_offset_polygons_2_inner(V, offset, W) + return [Polygon(points.tolist()) for points in offset_polygons] diff --git a/tests/test_straight_skeleton_2.py b/tests/test_straight_skeleton_2.py index c700dc4..6286ed3 100644 --- a/tests/test_straight_skeleton_2.py +++ b/tests/test_straight_skeleton_2.py @@ -3,6 +3,8 @@ from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton_with_holes from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 +from compas_cgal.straight_skeleton_2 import create_weighted_offset_polygons_2 + def test_straight_polygon(): points = [ @@ -91,3 +93,8 @@ def test_offset(): assert len(polygons) == 1, len(polygons) polygons = create_offset_polygons_2(points, -offset) assert len(polygons) == 1, len(polygons) + weights = [0.1, 0.5, 0.3, 0.3, 0.9, 1.0, 0.2, 1.0] + polygons = create_weighted_offset_polygons_2(points, offset, weights) + assert len(polygons) == 1, len(polygons) + polygons = create_weighted_offset_polygons_2(points, -offset, weights) + assert len(polygons) == 1, len(polygons) From 7a232fe3619159b0d74e4818b41263b725d0ed52 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:39:52 +0200 Subject: [PATCH 09/16] Revert "adding inner and outer offsets" This reverts commit 4310a02b4292ee1ff87baf03d94ba15f92776c40. --- docs/examples/straight_skeleton_offset.py | 36 ------------- src/compas_cgal/straight_skeleton_2.py | 15 ------ src/straight_skeleton_2.cpp | 61 ----------------------- src/straight_skeleton_2.h | 9 +--- tests/test_straight_skeleton_2.py | 20 +------- 5 files changed, 2 insertions(+), 139 deletions(-) delete mode 100644 docs/examples/straight_skeleton_offset.py diff --git a/docs/examples/straight_skeleton_offset.py b/docs/examples/straight_skeleton_offset.py deleted file mode 100644 index 5d11de0..0000000 --- a/docs/examples/straight_skeleton_offset.py +++ /dev/null @@ -1,36 +0,0 @@ -from compas.datastructures import Graph -from compas.geometry import Polygon -from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 -from compas_viewer import Viewer - -points = [ - (-1.91, 3.59, 0.0), - (-5.53, -5.22, 0.0), - (-0.39, -1.98, 0.0), - (2.98, -5.51, 0.0), - (4.83, -2.02, 0.0), - (9.70, -3.63, 0.0), - (12.23, 1.25, 0.0), - (3.42, 0.66, 0.0), - (2.92, 4.03, 0.0), - (-1.91, 3.59, 0.0), -] -polygon = Polygon(points) -offset = 1.5 - -offset_polygons_inner = create_offset_polygons_2(points, offset) -offset_polygons_outer = create_offset_polygons_2(points, -offset) - -# ============================================================================== -# Viz -# ============================================================================== - -viewer = Viewer(width=1600, height=900) -viewer.scene.add(polygon) - -for opolygon in offset_polygons_inner: - viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0)) -for opolygon in offset_polygons_outer: - viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0)) - -viewer.show() diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index fc7bccb..38b9eff 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -1,6 +1,5 @@ import numpy as np from compas.geometry import normal_polygon -from compas.geometry import Polygon from compas.tolerance import TOL from compas_cgal._cgal import straight_skeleton_2 @@ -67,17 +66,3 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump hole = np.asarray(points, dtype=np.float64) H.append(hole) return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) - - -def create_offset_polygons_2(points, offset) -> PolylinesNumpy: - points = list(points) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): - raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") - V = np.asarray(points, dtype=np.float64) - offset = float(offset) - if offset < 0: # outside - offset_polygons = straight_skeleton_2.create_offset_polygons_2_outer(V, abs(offset))[1:] # first one is box - else: # inside - offset_polygons = straight_skeleton_2.create_offset_polygons_2_inner(V, offset) - return [Polygon(points.tolist()) for points in offset_polygons] - diff --git a/src/straight_skeleton_2.cpp b/src/straight_skeleton_2.cpp index ae1cf55..02f1697 100644 --- a/src/straight_skeleton_2.cpp +++ b/src/straight_skeleton_2.cpp @@ -3,7 +3,6 @@ #include #include #include -#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_2 Point; @@ -13,8 +12,6 @@ typedef CGAL::Straight_skeleton_2 Ss; typedef boost::shared_ptr SsPtr; typedef CGAL::Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle; typedef CGAL::Straight_skeleton_2::Vertex_const_handle Vertex_const_handle; -typedef boost::shared_ptr PolygonPtr; -typedef std::vector PolygonPtrVector; compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V) @@ -89,52 +86,6 @@ compas::Edges pmp_create_interior_straight_skeleton_with_holes( } -std::vector pmp_create_offset_polygons_2_inner(Eigen::Ref &V, double &offset){ - Polygon_2 poly; - for (int i = 0; i < V.rows(); i++){ - poly.push_back(Point(V(i, 0), V(i, 1))); - } - PolygonPtrVector offset_polygons = CGAL::create_interior_skeleton_and_offset_polygons_2(offset, poly); - - std::vector result; - for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ - std::size_t n = (*pi)->size(); - compas::RowMatrixXd points(n, 3); - int j = 0; - for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ - points(j, 0) = (double)(*vi).x(); - points(j, 1) = (double)(*vi).y(); - points(j, 2) = 0; - j++; - } - result.push_back(points); - } - return result; -} - -std::vector pmp_create_offset_polygons_2_outer(Eigen::Ref &V, double &offset){ - Polygon_2 poly; - for (int i = 0; i < V.rows(); i++){ - poly.push_back(Point(V(i, 0), V(i, 1))); - } - PolygonPtrVector offset_polygons = CGAL::create_exterior_skeleton_and_offset_polygons_2(offset, poly); - - std::vector result; - for(auto pi = offset_polygons.begin(); pi != offset_polygons.end(); ++pi){ - std::size_t n = (*pi)->size(); - compas::RowMatrixXd points(n, 3); - int j = 0; - for (auto vi = (*pi)->vertices_begin(); vi != (*pi)->vertices_end(); ++vi){ - points(j, 0) = (double)(*vi).x(); - points(j, 1) = (double)(*vi).y(); - points(j, 2) = 0; - j++; - } - result.push_back(points); - } - return result; -} - // =========================================================================== // PyBind11 // =========================================================================== @@ -153,16 +104,4 @@ void init_straight_skeleton_2(pybind11::module &m) &pmp_create_interior_straight_skeleton_with_holes, pybind11::arg("V").noconvert(), pybind11::arg("holes").noconvert()); - - submodule.def( - "create_offset_polygons_2_inner", - &pmp_create_offset_polygons_2_inner, - pybind11::arg("V").noconvert(), - pybind11::arg("offset").noconvert()); - - submodule.def( - "create_offset_polygons_2_outer", - &pmp_create_offset_polygons_2_outer, - pybind11::arg("V").noconvert(), - pybind11::arg("offset").noconvert()); }; diff --git a/src/straight_skeleton_2.h b/src/straight_skeleton_2.h index ae59d88..baad317 100644 --- a/src/straight_skeleton_2.h +++ b/src/straight_skeleton_2.h @@ -7,16 +7,9 @@ compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V); + compas::Edges pmp_create_interior_straight_skeleton_with_holes( Eigen::Ref &V, std::vector> &holes); -std::vector pmp_create_offset_polygons_2_inner( - Eigen::Ref &V, - double &offset); - -std::vector pmp_create_offset_polygons_2_outer( - Eigen::Ref &V, - double &offset); - #endif /* COMPAS_STRAIGHT_SKELETON_2_H */ diff --git a/tests/test_straight_skeleton_2.py b/tests/test_straight_skeleton_2.py index c700dc4..80d419d 100644 --- a/tests/test_straight_skeleton_2.py +++ b/tests/test_straight_skeleton_2.py @@ -2,7 +2,7 @@ from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton_with_holes -from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 + def test_straight_polygon(): points = [ @@ -73,21 +73,3 @@ def test_straight_polygon_2_compare(): # the line direction sometimes changes ... assert TOL.is_allclose(sa, se) or TOL.is_allclose(sa, ee) assert TOL.is_allclose(ea, ee) or TOL.is_allclose(ea, se) - - -def test_offset(): - points = [ - (-1, -1, 0), - (0, -12, 0), - (1, -1, 0), - (12, 0, 0), - (1, 1, 0), - (0, 12, 0), - (-1, 1, 0), - (-12, 0, 0), - ] - offset = 0.5 - polygons = create_offset_polygons_2(points, offset) - assert len(polygons) == 1, len(polygons) - polygons = create_offset_polygons_2(points, -offset) - assert len(polygons) == 1, len(polygons) From a6516f9916663252aec9cb3788dd90db79a50443 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 11:43:45 +0200 Subject: [PATCH 10/16] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7c8b0..317ca0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton`. * Added `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton_with_holes`. +* Added `compas_cgal.straight_skeleton_2.create_offset_polygons_2_inner`. +* Added `compas_cgal.straight_skeleton_2.create_offset_polygons_2_outer`. +* Added `compas_cgal.straight_skeleton_2.create_weighted_offset_polygons_2_inner`. +* Added `compas_cgal.straight_skeleton_2.create_weighted_offset_polygons_2_outer`. ### Changed From 5fa634be00e10f6f49608722abb7b66102b287a0 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Wed, 3 Jul 2024 21:42:53 +0200 Subject: [PATCH 11/16] adding inner and outer offsets --- docs/examples/straight_skeleton_offset.py | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/examples/straight_skeleton_offset.py diff --git a/docs/examples/straight_skeleton_offset.py b/docs/examples/straight_skeleton_offset.py new file mode 100644 index 0000000..5d11de0 --- /dev/null +++ b/docs/examples/straight_skeleton_offset.py @@ -0,0 +1,36 @@ +from compas.datastructures import Graph +from compas.geometry import Polygon +from compas_cgal.straight_skeleton_2 import create_offset_polygons_2 +from compas_viewer import Viewer + +points = [ + (-1.91, 3.59, 0.0), + (-5.53, -5.22, 0.0), + (-0.39, -1.98, 0.0), + (2.98, -5.51, 0.0), + (4.83, -2.02, 0.0), + (9.70, -3.63, 0.0), + (12.23, 1.25, 0.0), + (3.42, 0.66, 0.0), + (2.92, 4.03, 0.0), + (-1.91, 3.59, 0.0), +] +polygon = Polygon(points) +offset = 1.5 + +offset_polygons_inner = create_offset_polygons_2(points, offset) +offset_polygons_outer = create_offset_polygons_2(points, -offset) + +# ============================================================================== +# Viz +# ============================================================================== + +viewer = Viewer(width=1600, height=900) +viewer.scene.add(polygon) + +for opolygon in offset_polygons_inner: + viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0)) +for opolygon in offset_polygons_outer: + viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0)) + +viewer.show() From 2633d4eed7140084733058d48531abe415dd19de Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 14:56:53 +0200 Subject: [PATCH 12/16] forgot by merging --- src/straight_skeleton_2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/straight_skeleton_2.cpp b/src/straight_skeleton_2.cpp index 9360d30..dcbde6a 100644 --- a/src/straight_skeleton_2.cpp +++ b/src/straight_skeleton_2.cpp @@ -15,6 +15,8 @@ typedef CGAL::Straight_skeleton_2 Ss; typedef boost::shared_ptr SsPtr; typedef CGAL::Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle; typedef CGAL::Straight_skeleton_2::Vertex_const_handle Vertex_const_handle; +typedef boost::shared_ptr PolygonPtr; +typedef std::vector PolygonPtrVector; compas::Edges pmp_create_interior_straight_skeleton( Eigen::Ref &V) From 9ea8c3cb9c3b8c2447da4e6a758f6b8b5b609cfd Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 15:08:38 +0200 Subject: [PATCH 13/16] lint --- src/compas_cgal/straight_skeleton_2.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index 510475a..0ab59cc 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -1,5 +1,6 @@ import numpy as np -from compas.geometry import Polygon, normal_polygon +from compas.geometry import Polygon +from compas.geometry import normal_polygon from compas.tolerance import TOL from compas_cgal._cgal import straight_skeleton_2 @@ -131,9 +132,7 @@ def create_weighted_offset_polygons_2(points, offset, weights): offset = float(offset) W = np.asarray(weights, dtype=np.float64) if W.shape[0] != V.shape[0]: - raise ValueError( - "The number of weights should be equal to the number of points %d != %d." % (W.shape[0], V.shape[0]) - ) + raise ValueError("The number of weights should be equal to the number of points %d != %d." % (W.shape[0], V.shape[0])) if offset < 0: offset_polygons = straight_skeleton_2.create_weighted_offset_polygons_2_outer(V, abs(offset), W)[1:] else: From 1170d4093671bd6dea8ef6c70270bc3528317883 Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Fri, 5 Jul 2024 15:09:33 +0200 Subject: [PATCH 14/16] Update straight_skeleton_2.py --- src/compas_cgal/straight_skeleton_2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index 0ab59cc..2f549e0 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -123,7 +123,7 @@ def create_weighted_offset_polygons_2(points, offset, weights): ValueError If the normal of the polygon is not [0, 0, 1]. ValueError - If the number of weights do not match the number of points. + If the number of weights does not match the number of points. """ points = list(points) if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): From 07689571a912043c1fd7156214f53a54fbb860bb Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Tue, 9 Jul 2024 11:28:37 +0200 Subject: [PATCH 15/16] more elaborate error --- src/compas_cgal/straight_skeleton_2.py | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index 2f549e0..ba8a486 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -27,8 +27,9 @@ def create_interior_straight_skeleton(points) -> PolylinesNumpy: If the normal of the polygon is not [0, 0, 1]. """ points = list(points) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): - raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + normal = normal_polygon(points, True) + if not TOL.is_allclose(normal, [0, 0, 1]): + raise ValueError("The normal of the polygon should be [0, 0, 1]. The normal of the provided polygon is {}".format(normal)) V = np.asarray(points, dtype=np.float64) return straight_skeleton_2.create_interior_straight_skeleton(V) @@ -55,15 +56,17 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump If the normal of a hole is not [0, 0, -1]. """ points = list(points) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): - raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + normal = normal_polygon(points, True) + if not TOL.is_allclose(normal, [0, 0, 1]): + raise ValueError("The normal of the polygon should be [0, 0, 1]. The normal of the provided polygon is {}".format(normal)) V = np.asarray(points, dtype=np.float64) H = [] - for hole in holes: + for i, hole in enumerate(holes): points = list(hole) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, -1]): - raise ValueError("Please pass a hole with a normal vector of [0, 0, -1].") + normal_hole = normal_polygon(points, True) + if not TOL.is_allclose(normal_hole, [0, 0, -1]): + raise ValueError("The normal of the hole should be [0, 0, -1]. The normal of the provided {}-th hole is {}".format(i, normal_hole)) hole = np.asarray(points, dtype=np.float64) H.append(hole) return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) @@ -90,8 +93,9 @@ def create_offset_polygons_2(points, offset): If the normal of the polygon is not [0, 0, 1]. """ points = list(points) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): - raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + normal = normal_polygon(points, True) + if not TOL.is_allclose(normal, [0, 0, 1]): + raise ValueError("The normal of the polygon should be [0, 0, 1]. The normal of the provided polygon is {}".format(normal)) V = np.asarray(points, dtype=np.float64) offset = float(offset) if offset < 0: # outside @@ -126,8 +130,10 @@ def create_weighted_offset_polygons_2(points, offset, weights): If the number of weights does not match the number of points. """ points = list(points) - if not TOL.is_allclose(normal_polygon(points, True), [0, 0, 1]): - raise ValueError("Please pass a polygon with a normal vector of [0, 0, 1].") + normal = normal_polygon(points, True) + if not TOL.is_allclose(normal, [0, 0, 1]): + raise ValueError("The normal of the polygon should be [0, 0, 1]. The normal of the provided polygon is {}".format(normal)) + V = np.asarray(points, dtype=np.float64) offset = float(offset) W = np.asarray(weights, dtype=np.float64) From 56c5ad42e655ba588e27ba04daa82a473bb2a04c Mon Sep 17 00:00:00 2001 From: Romana Rust Date: Tue, 9 Jul 2024 11:33:07 +0200 Subject: [PATCH 16/16] type annotations --- src/compas_cgal/straight_skeleton_2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compas_cgal/straight_skeleton_2.py b/src/compas_cgal/straight_skeleton_2.py index ba8a486..31d9417 100644 --- a/src/compas_cgal/straight_skeleton_2.py +++ b/src/compas_cgal/straight_skeleton_2.py @@ -72,7 +72,7 @@ def create_interior_straight_skeleton_with_holes(points, holes) -> PolylinesNump return straight_skeleton_2.create_interior_straight_skeleton_with_holes(V, H) -def create_offset_polygons_2(points, offset): +def create_offset_polygons_2(points, offset) -> list[Polygon]: """Compute the polygon offset. Parameters @@ -84,7 +84,7 @@ def create_offset_polygons_2(points, offset): Returns ------- - list of Polygon + list[:class:`Polygon`] The offset polygon(s). Raises @@ -105,7 +105,7 @@ def create_offset_polygons_2(points, offset): return [Polygon(points.tolist()) for points in offset_polygons] -def create_weighted_offset_polygons_2(points, offset, weights): +def create_weighted_offset_polygons_2(points, offset, weights) -> list[Polygon]: """Compute the polygon offset with weights. Parameters @@ -119,7 +119,7 @@ def create_weighted_offset_polygons_2(points, offset, weights): Returns ------- - list of Polygon + list[:class:`Polygon`] The offset polygon(s). Raises

N#R0He_Eztj0D@Vp@3T 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 O{5!8_qFbng3;%!4z#i)W literal 0 HcmV?d00001 diff --git a/docs/_images/cgal_straight_skeleton_2_offset_weighted.png b/docs/_images/cgal_straight_skeleton_2_offset_weighted.png new file mode 100644 index 0000000000000000000000000000000000000000..f9ffa8b7d403e2924fcea14b664dcc7d0c38fd97 GIT binary patch literal 36406 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