Skip to content

Commit dbdd07b

Browse files
committed
Add triangulated flag to Mesh.to_vertices_and_faces and also Shape's abstract method
1 parent 02c5a76 commit dbdd07b

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added optional `triangulated` flag to `Mesh.to_vertices_and_faces`.
13+
1214
### Changed
1315

1416
### Removed

src/compas/datastructures/mesh/mesh.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,14 @@ def from_vertices_and_faces(cls, vertices, faces):
473473

474474
return mesh
475475

476-
def to_vertices_and_faces(self):
476+
def to_vertices_and_faces(self, triangulated=False):
477477
"""Return the vertices and faces of a mesh.
478478
479+
Parameters
480+
----------
481+
triangulated: bool, optional
482+
If True, triangulate the faces.
483+
479484
Returns
480485
-------
481486
list[list[float]]
@@ -486,7 +491,36 @@ def to_vertices_and_faces(self):
486491
"""
487492
key_index = self.key_index()
488493
vertices = [self.vertex_coordinates(key) for key in self.vertices()]
489-
faces = [[key_index[key] for key in self.face_vertices(fkey)] for fkey in self.faces()]
494+
495+
if not triangulated:
496+
faces = [[key_index[key] for key in self.face_vertices(fkey)] for fkey in self.faces()]
497+
return vertices, faces
498+
499+
faces = []
500+
501+
for fkey in self.faces():
502+
face_vertices = self.face_vertices(fkey)
503+
504+
if len(face_vertices) == 3:
505+
a, b, c = face_vertices
506+
faces.append([key_index[a], key_index[b], key_index[c]])
507+
elif len(face_vertices) == 4:
508+
a, b, c, d = face_vertices
509+
faces.append([key_index[a], key_index[b], key_index[c]])
510+
faces.append([key_index[a], key_index[c], key_index[d]])
511+
else:
512+
centroid = centroid_polygon([self.vertex_coordinates(key) for key in face_vertices])
513+
vertices.append(centroid)
514+
vcount = len(vertices)
515+
516+
for i in range(len(face_vertices) - 1):
517+
a, b, c = face_vertices[i], face_vertices[i + 1], vcount - 1
518+
faces.append([key_index[a], key_index[b], c])
519+
520+
# last face between first, last and centroid
521+
a, b, c = face_vertices[0], face_vertices[-1], vcount - 1
522+
faces.append([key_index[b], key_index[a], c])
523+
490524
return vertices, faces
491525

492526
@classmethod

src/compas/geometry/shapes/_shape.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Shape(Geometry):
1010
"""Base class for geometric shapes."""
1111

1212
@abc.abstractmethod
13-
def to_vertices_and_faces(self):
13+
def to_vertices_and_faces(self, triangulated=False):
1414
pass
1515

1616
def __add__(self, other):

tests/compas/datastructures/test_mesh.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pickle import TRUE
12
import tempfile
23

34
import pytest
@@ -7,6 +8,7 @@
78
from compas.datastructures import meshes_join_and_weld
89
from compas.geometry import Box
910
from compas.geometry import Polygon
11+
from compas.geometry import Polyhedron
1012
from compas.geometry import Translation
1113
from compas.geometry import allclose
1214

@@ -183,6 +185,25 @@ def test_to_vertices_and_faces():
183185
assert len(faces) == 25
184186

185187

188+
def test_to_vertices_and_faces_triangulated():
189+
# tri
190+
mesh = Mesh.from_shape(Polyhedron.from_platonicsolid(4))
191+
vertices, faces = mesh.to_vertices_and_faces(triangulated=True)
192+
assert len(vertices) == 4
193+
assert len(faces) == 4
194+
195+
# quad
196+
mesh = Mesh.from_shape(Polyhedron.from_platonicsolid(6))
197+
vertices, faces = mesh.to_vertices_and_faces(triangulated=True)
198+
assert len(vertices) == 8
199+
assert len(faces) == 12
200+
201+
# ngon
202+
mesh = Mesh.from_shape(Polyhedron.from_platonicsolid(12))
203+
vertices, faces = mesh.to_vertices_and_faces(triangulated=True)
204+
assert len(vertices) == 32
205+
assert len(faces) == 60
206+
186207
# --------------------------------------------------------------------------
187208
# helpers
188209
# --------------------------------------------------------------------------

0 commit comments

Comments
 (0)