Skip to content

Commit 4d1eca6

Browse files
authored
Merge pull request #35 from compas-dev/feature/offset_with_holes
Added function `create_offset_polygons_with_holes_2`
2 parents 6522ee2 + 33787d5 commit 4d1eca6

11 files changed

+254
-137
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
* Added recipe hasher.
1313
* Added `scip` to dev install instructions in README.md
14+
* Added `compas_cgal.straight_skeleton_2.offset_polygon_with_holes`.
1415

1516
### Changed
17+
* Changed name of `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton` to `interior_straight_skeleton`
18+
* Changed name of `compas_cgal.straight_skeleton_2.create_interior_straight_skeleton_with_holes` to `interior_straight_skeleton_with_holes`
19+
* Changed name of `compas_cgal.straight_skeleton_2.create_offset_polygons_2` to `offset_polygon`
20+
* Changed name of `compas_cgal.straight_skeleton_2.create_weighted_offset_polygons_2` to `weighted_offset_polygon`
1621

1722
### Removed
1823

docs/api/compas_cgal.straight_skeleton_2.rst

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@ compas_cgal.straight_skeleton_2
88
:toctree: generated/
99
:nosignatures:
1010

11-
create_interior_straight_skeleton
12-
create_interior_straight_skeleton_with_holes
11+
interior_straight_skeleton
12+
interior_straight_skeleton_with_holes
13+
offset_polygon
14+
weighted_offset_polygon
15+
offset_polygon_with_holes

docs/examples/polygonal_poinset_reconstruction.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ Polygonal PointSet Reconstruction
77
:class: figure-img img-fluid
88

99

10-
.. literalinclude:: polygonal_poinset_reconstruction_ransac.py
10+
.. literalinclude:: polygonal_poinset_reconstruction.py
1111
:language: python

docs/examples/straight_skeleton_2.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton
1+
from compas_cgal.straight_skeleton_2 import interior_straight_skeleton
22
from compas_viewer import Viewer
33

44
points = [
@@ -15,7 +15,7 @@
1515
]
1616

1717

18-
graph = create_interior_straight_skeleton(points)
18+
graph = interior_straight_skeleton(points)
1919

2020
# ==============================================================================
2121
# Viz

docs/examples/straight_skeleton_2_holes.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from compas.geometry import Polygon
2-
from compas_cgal.straight_skeleton_2 import create_interior_straight_skeleton_with_holes
32
from compas_viewer import Viewer
43

4+
from compas_cgal.straight_skeleton_2 import interior_straight_skeleton_with_holes
5+
56
points = [
67
(-1.91, 3.59, 0.0),
78
(-5.53, -5.22, 0.0),
@@ -24,7 +25,7 @@
2425

2526
polygon = Polygon(points)
2627
holes = [Polygon(hole) for hole in holes]
27-
graph = create_interior_straight_skeleton_with_holes(polygon, holes)
28+
graph = interior_straight_skeleton_with_holes(polygon, holes)
2829

2930
# ==============================================================================
3031
# Viz

docs/examples/straight_skeleton_2_offset.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from compas.geometry import Polygon
2-
from compas_cgal.straight_skeleton_2 import create_offset_polygons_2
32
from compas_viewer import Viewer
43

4+
from compas_cgal.straight_skeleton_2 import offset_polygon
5+
56
points = [
67
(-1.91, 3.59, 0.0),
78
(-5.53, -5.22, 0.0),
@@ -17,8 +18,8 @@
1718
polygon = Polygon(points)
1819
offset = 1.5
1920

20-
offset_polygons_inner = create_offset_polygons_2(points, offset)
21-
offset_polygons_outer = create_offset_polygons_2(points, -offset)
21+
offset_polygon_inner = offset_polygon(points, offset)
22+
offset_polygon_outer = offset_polygon(points, -offset)
2223

2324
# ==============================================================================
2425
# Viz
@@ -28,9 +29,9 @@
2829
viewer.scene.add(polygon)
2930
viewer.config.renderer.show_grid = False
3031

31-
for opolygon in offset_polygons_inner:
32+
for opolygon in offset_polygon_inner:
3233
viewer.scene.add(opolygon, linecolor=(1.0, 0.0, 0.0), facecolor=(1.0, 1.0, 1.0, 0.0))
33-
for opolygon in offset_polygons_outer:
34+
for opolygon in offset_polygon_outer:
3435
viewer.scene.add(opolygon, linecolor=(0.0, 0.0, 1.0), facecolor=(1.0, 1.0, 1.0, 0.0))
3536

3637
viewer.show()

docs/examples/straight_skeleton_2_offset_weighted.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from compas.geometry import Polygon
2-
from compas_cgal.straight_skeleton_2 import create_weighted_offset_polygons_2
32
from compas_viewer import Viewer
43

4+
from compas_cgal.straight_skeleton_2 import weighted_offset_polygons
5+
56
points = [
67
(-1.91, 3.59, 0.0),
78
(-5.53, -5.22, 0.0),
@@ -20,7 +21,7 @@
2021
distances = [0.1, 0.3, 0.6, 0.1, 0.7, 0.5, 0.2, 0.4, 0.8, 0.2]
2122
weights = [1.0 / d for d in distances]
2223
offset = 1.0
23-
offset_polygons_outer = create_weighted_offset_polygons_2(points, -offset, weights)
24+
offset_polygons_outer = weighted_offset_polygons(points, -offset, weights)
2425

2526
# ==============================================================================
2627
# Viz

src/compas_cgal/straight_skeleton_2.py

+69-16
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ def graph_from_skeleton_data(points: VerticesNumpy, indices: IntNx1, edges: IntN
4848
return graph
4949

5050

51-
def create_interior_straight_skeleton(points, as_graph=True) -> Union[Graph, Tuple[VerticesNumpy, IntNx1, IntNx2, IntNx1]]:
52-
"""Compute the skeleton of a polygon.
51+
def interior_straight_skeleton(points, as_graph=True) -> Union[Graph, Tuple[VerticesNumpy, IntNx1, IntNx2, IntNx1]]:
52+
"""Compute the skeleton of a 2D polygon.
5353
5454
Parameters
5555
----------
@@ -66,7 +66,7 @@ def create_interior_straight_skeleton(points, as_graph=True) -> Union[Graph, Tup
6666
Raises
6767
------
6868
ValueError
69-
If the normal of the polygon is not [0, 0, 1].
69+
If the normal of the polygon is not directed vertically upwards like [0, 0, 1].
7070
"""
7171
points = list(points)
7272
normal = normal_polygon(points, True)
@@ -79,13 +79,13 @@ def create_interior_straight_skeleton(points, as_graph=True) -> Union[Graph, Tup
7979
return points, indices, edges, edge_types
8080

8181

82-
def create_interior_straight_skeleton_with_holes(points, holes, as_graph=True) -> Union[Graph, Tuple[VerticesNumpy, IntNx1, IntNx2, IntNx1]]:
83-
"""Compute the skeleton of a polygon with holes.
82+
def interior_straight_skeleton_with_holes(points, holes, as_graph=True) -> Union[Graph, Tuple[VerticesNumpy, IntNx1, IntNx2, IntNx1]]:
83+
"""Compute the skeleton of a 2D polygon with holes.
8484
8585
Parameters
8686
----------
8787
points : list of point coordinates or :class:`compas.geometry.Polygon`
88-
The points of the polygon.
88+
The points of the 2D polygon.
8989
holes : list of list of point coordinates or list of :class:`compas.geometry.Polygon`
9090
The holes of the polygon.
9191
as_graph : bool, optional
@@ -99,8 +99,8 @@ def create_interior_straight_skeleton_with_holes(points, holes, as_graph=True) -
9999
Raises
100100
------
101101
ValueError
102-
If the normal of the polygon is not [0, 0, 1].
103-
If the normal of a hole is not [0, 0, -1].
102+
If the normal of the polygon is not directed vertically upwards like [0, 0, 1].
103+
If the normal of a hole is not directed vertically downwards like [0, 0, -1].
104104
"""
105105
points = list(points)
106106
normal = normal_polygon(points, True)
@@ -122,13 +122,13 @@ def create_interior_straight_skeleton_with_holes(points, holes, as_graph=True) -
122122
return points, indices, edges, edge_types
123123

124124

125-
def create_offset_polygons_2(points, offset) -> list[Polygon]:
126-
"""Compute the polygon offset.
125+
def offset_polygon(points, offset) -> list[Polygon]:
126+
"""Compute the offset from a 2D polygon.
127127
128128
Parameters
129129
----------
130130
points : list of point coordinates or :class:`compas.geometry.Polygon`
131-
The points of the polygon.
131+
The points of the 2D polygon.
132132
offset : float
133133
The offset distance. If negative, the offset is outside the polygon, otherwise inside.
134134
@@ -140,7 +140,7 @@ def create_offset_polygons_2(points, offset) -> list[Polygon]:
140140
Raises
141141
------
142142
ValueError
143-
If the normal of the polygon is not [0, 0, 1].
143+
If the normal of the polygon is not directed vertically upwards like [0, 0, 1].
144144
"""
145145
points = list(points)
146146
normal = normal_polygon(points, True)
@@ -155,13 +155,66 @@ def create_offset_polygons_2(points, offset) -> list[Polygon]:
155155
return [Polygon(points.tolist()) for points in offset_polygons]
156156

157157

158-
def create_weighted_offset_polygons_2(points, offset, weights) -> list[Polygon]:
159-
"""Compute the polygon offset with weights.
158+
def offset_polygon_with_holes(points, holes, offset) -> list[Tuple[Polygon, list[Polygon]]]:
159+
"""Compute the offset from a 2D polygon with holes.
160160
161161
Parameters
162162
----------
163163
points : list of point coordinates or :class:`compas.geometry.Polygon`
164-
The points of the polygon.
164+
The points of the 2D polygon.
165+
holes : list of list of point coordinates or list of :class:`compas.geometry.Polygon`
166+
The holes of the polygon.
167+
offset : float
168+
The offset distance. If negative, the offset is outside the polygon, otherwise inside.
169+
170+
Returns
171+
-------
172+
list of tuple of (:class:`Polygon`, list[:class:`Polygon`])
173+
The polygons with holes.
174+
175+
Raises
176+
------
177+
ValueError
178+
If the normal of the polygon is not directed vertically upwards like [0, 0, 1].
179+
If the normal of a hole is not directed vertically downwards like [0, 0, -1].
180+
"""
181+
points = list(points)
182+
normal = normal_polygon(points, True)
183+
if not TOL.is_allclose(normal, [0, 0, 1]):
184+
raise ValueError("The normal of the polygon should be [0, 0, 1]. The normal of the provided polygon is {}".format(normal))
185+
V = np.asarray(points, dtype=np.float64)
186+
187+
H = []
188+
for i, hole in enumerate(holes):
189+
points = hole
190+
normal_hole = normal_polygon(points, True)
191+
if not TOL.is_allclose(normal_hole, [0, 0, -1]):
192+
raise ValueError("The normal of the hole should be [0, 0, -1]. The normal of the provided {}-th hole is {}".format(i, normal_hole))
193+
hole = np.asarray(points, dtype=np.float64)
194+
H.append(hole)
195+
196+
if offset < 0: # outside
197+
offset_polygons = straight_skeleton_2.create_offset_polygons_2_outer_with_holes(V, H, abs(offset))
198+
else: # inside
199+
offset_polygons = straight_skeleton_2.create_offset_polygons_2_inner_with_holes(V, H, offset)
200+
201+
result = []
202+
for points, holes_np in offset_polygons:
203+
polygon = Polygon(points.tolist())
204+
holes = []
205+
for hole in holes_np:
206+
holes.append(Polygon(hole.tolist()))
207+
result.append((polygon, holes))
208+
return result
209+
210+
211+
def weighted_offset_polygon(points, offset, weights) -> list[Polygon]:
212+
"""Compute the offset from a 2D polygon with weights.
213+
214+
Parameters
215+
----------
216+
points : list of point coordinates or :class:`compas.geometry.Polygon`
217+
The points of the 2D polygon.
165218
offset : float
166219
The offset distance. If negative, the offset is outside the polygon, otherwise inside.
167220
weights : list of float
@@ -175,7 +228,7 @@ def create_weighted_offset_polygons_2(points, offset, weights) -> list[Polygon]:
175228
Raises
176229
------
177230
ValueError
178-
If the normal of the polygon is not [0, 0, 1].
231+
If the normal of the polygon is not directed vertically upwards like [0, 0, 1].
179232
ValueError
180233
If the number of weights does not match the number of points.
181234
"""

0 commit comments

Comments
 (0)