Skip to content

Commit 240ca57

Browse files
authored
Merge pull request #924 from compas-dev/mesh-strip-split
Mesh split strip
2 parents 58ac4d3 + 5ef3946 commit 240ca57

File tree

5 files changed

+81
-0
lines changed

5 files changed

+81
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
* Added halfedge loops in `compas.datastructures.Halfedge.halfedge_loop`.
1313
* Added halfedge strips in `compas.datastructures.Halfedge.halfedge_strip`.
14+
* Added `compas.datastructures.mesh_split_strip` and `compas.datastructures.Mesh.split_strip`.
1415
* Added boundingbox to `compas_rhino.conduits.BaseConduit`
1516

1617
### Changed

src/compas/datastructures/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
mesh_smooth_centroid
109109
mesh_split_edge
110110
mesh_split_face
111+
mesh_split_strip
111112
mesh_subdivide_catmullclark
112113
mesh_subdivide_corner
113114
mesh_subdivide_doosabin
@@ -246,6 +247,7 @@
246247
mesh_smooth_centroid,
247248
mesh_split_edge,
248249
mesh_split_face,
250+
mesh_split_strip,
249251
mesh_subdivide_catmullclark,
250252
mesh_subdivide_corner,
251253
mesh_subdivide_doosabin,
@@ -385,6 +387,7 @@
385387
'mesh_smooth_centroid',
386388
'mesh_split_edge',
387389
'mesh_split_face',
390+
'mesh_split_strip',
388391
'mesh_subdivide_catmullclark',
389392
'mesh_subdivide_corner',
390393
'mesh_subdivide_doosabin',

src/compas/datastructures/mesh/mesh.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from .operations import mesh_collapse_edge
4646
from .operations import mesh_split_edge
4747
from .operations import mesh_split_face
48+
from .operations import mesh_split_strip
4849
from .operations import mesh_merge_faces
4950

5051
from .bbox import mesh_bounding_box
@@ -122,6 +123,7 @@ class Mesh(HalfEdge):
122123
smooth_area = mesh_smooth_area
123124
split_edge = mesh_split_edge
124125
split_face = mesh_split_face
126+
split_strip = mesh_split_strip
125127
subdivide = mesh_subdivide
126128
transform = mesh_transform
127129
transformed = mesh_transformed

src/compas/datastructures/mesh/operations/split.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from __future__ import absolute_import
33
from __future__ import division
44

5+
from compas.utilities import pairwise
6+
57

68
__all__ = [
79
'mesh_split_edge',
810
'mesh_split_face',
11+
'mesh_split_strip',
912
'trimesh_split_edge',
1013
]
1114

@@ -222,3 +225,39 @@ def mesh_split_face(mesh, fkey, u, v):
222225
del mesh.face[fkey]
223226

224227
return f, g
228+
229+
230+
def mesh_split_strip(mesh, edge):
231+
"""Split the srip of faces corresponding to a given edge.
232+
233+
Parameters
234+
----------
235+
mesh : :class:`compas.datastructures.Mesh`
236+
The input mesh.
237+
edge : tuple of int
238+
The edge identifying the strip.
239+
240+
Returns
241+
-------
242+
list of int
243+
The split vertices in the same order as the edges of the strip.
244+
"""
245+
strip = mesh.edge_strip(edge)
246+
is_closed = strip[0] == strip[-1]
247+
248+
ngons = []
249+
splits = []
250+
for u, v in strip[:-1]:
251+
ngons.append(mesh.halfedge_face(u, v))
252+
splits.append(mesh.split_edge(u, v, t=0.5, allow_boundary=True))
253+
254+
if is_closed:
255+
splits.append(splits[0])
256+
else:
257+
u, v = strip[-1]
258+
splits.append(mesh.split_edge(u, v, t=0.5, allow_boundary=True))
259+
260+
for (u, v), ngon in zip(pairwise(splits), ngons):
261+
mesh.split_face(ngon, u, v)
262+
263+
return splits

tests/compas/datastructures/test_halfedge.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import compas
55

66
from compas.geometry import Sphere
7+
from compas.geometry import Box
78

89
from compas.datastructures import HalfEdge
910
from compas.datastructures import Mesh
@@ -47,6 +48,13 @@ def sphere():
4748
return mesh
4849

4950

51+
@pytest.fixture
52+
def box():
53+
box = Box.from_corner_corner_height([0, 0, 0], [1, 1, 0], 1.0)
54+
mesh = Mesh.from_shape(box)
55+
return mesh
56+
57+
5058
@pytest.fixture
5159
def grid():
5260
mesh = Mesh.from_meshgrid(dx=10, nx=10)
@@ -358,3 +366,31 @@ def test_loops_and_strips_open_boundary(grid):
358366
assert edge == strip[-1]
359367
else:
360368
assert edge == strip[0]
369+
370+
371+
def test_split_strip_closed(box):
372+
edge = box.edge_sample()[0]
373+
374+
box.split_strip(edge)
375+
376+
assert box.is_valid()
377+
assert box.number_of_faces() == 10
378+
379+
380+
def test_split_strip_open(grid):
381+
edge = grid.edge_sample()[0]
382+
383+
grid.split_strip(edge)
384+
385+
assert grid.is_valid()
386+
assert grid.number_of_faces() == 110
387+
388+
389+
def test_split_strip_open_corner(grid):
390+
corner = list(grid.vertices_where({'vertex_degree': 2}))[0]
391+
392+
for edge in grid.vertex_edges(corner):
393+
grid.split_strip(edge)
394+
395+
assert grid.is_valid()
396+
assert grid.number_of_faces() == 121

0 commit comments

Comments
 (0)