Skip to content

Commit ec9af85

Browse files
committed
add face triangulation option and increase default u and v to 16
1 parent d485eb3 commit ec9af85

File tree

7 files changed

+146
-44
lines changed

7 files changed

+146
-44
lines changed

src/compas/geometry/shapes/box.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from compas.geometry import Frame
99
from compas.geometry import Vector
1010

11-
from compas.geometry.shapes._shape import Shape
11+
from ._shape import Shape
1212

1313

1414
class Box(Shape):
@@ -519,6 +519,29 @@ def from_diagonal(cls, diagonal):
519519
# methods
520520
# ==========================================================================
521521

522+
def to_vertices_and_faces(self, triangulated=False):
523+
"""Returns a list of vertices and faces.
524+
525+
Parameters
526+
----------
527+
triangulated: bool, optional
528+
Flag indicating that the faces have to be triangulated.
529+
530+
Returns
531+
-------
532+
(vertices, faces)
533+
A list of vertex locations and a list of faces,
534+
with each face defined as a list of indices into the list of vertices.
535+
"""
536+
if triangulated:
537+
faces = []
538+
for a, b, c, d in self.faces:
539+
faces.append([a, b, c])
540+
faces.append([a, c, d])
541+
else:
542+
faces = self.faces
543+
return self.vertices, faces
544+
522545
def contains(self, point):
523546
"""Verify if the box contains a given point.
524547
@@ -538,17 +561,6 @@ def contains(self, point):
538561
return True
539562
return False
540563

541-
def to_vertices_and_faces(self):
542-
"""Returns a list of vertices and faces.
543-
544-
Returns
545-
-------
546-
(vertices, faces)
547-
A list of vertex locations and a list of faces,
548-
with each face defined as a list of indices into the list of vertices.
549-
"""
550-
return self.vertices, self.faces
551-
552564
def transform(self, transformation):
553565
"""Transform the box.
554566

src/compas/geometry/shapes/capsule.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from compas.geometry import Plane
1313
from compas.geometry import Line
1414

15-
from compas.geometry.shapes import Shape
15+
from ._shape import Shape
1616

1717

1818
class Capsule(Shape):
@@ -186,17 +186,17 @@ def from_data(cls, data):
186186
# methods
187187
# ==========================================================================
188188

189-
def to_vertices_and_faces(self, u=10, v=10):
189+
def to_vertices_and_faces(self, u=16, v=16, triangulated=False):
190190
"""Returns a list of vertices and faces.
191191
192192
Parameters
193193
----------
194194
u : int, optional
195195
Number of faces in the 'u' direction.
196-
Default is ``10``.
197196
v : int, optional
198197
Number of faces in the 'v' direction.
199-
Default is ``10``.
198+
triangulated: bool, optional
199+
Flag indicating that the faces have to be triangulated.
200200
201201
Returns
202202
-------
@@ -263,6 +263,16 @@ def to_vertices_and_faces(self, u=10, v=10):
263263
nn = len(vertices) - 3 - (j + 1) % u
264264
faces.append([np, nn, nc])
265265

266+
if triangulated:
267+
triangles = []
268+
for face in faces:
269+
if len(face) == 4:
270+
triangles.append(face[0:3])
271+
triangles.append([face[0], face[2], face[3]])
272+
else:
273+
triangles.append(face)
274+
faces = triangles
275+
266276
return vertices, faces
267277

268278
def transform(self, transformation):

src/compas/geometry/shapes/cone.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from compas.geometry import Frame
1616
from compas.geometry import Plane
1717

18-
from compas.geometry.shapes._shape import Shape
18+
from ._shape import Shape
1919

2020

2121
class Cone(Shape):
@@ -223,14 +223,15 @@ def from_data(cls, data):
223223
# methods
224224
# ==========================================================================
225225

226-
def to_vertices_and_faces(self, u=10):
226+
def to_vertices_and_faces(self, u=16, triangulated=False):
227227
"""Returns a list of vertices and faces.
228228
229229
Parameters
230230
----------
231231
u : int, optional
232232
Number of faces in the "u" direction.
233-
Default is ``10``.
233+
triangulated: bool, optional
234+
Flag indicating that the faces have to be triangulated.
234235
235236
Returns
236237
-------
@@ -263,6 +264,16 @@ def to_vertices_and_faces(self, u=10):
263264
faces.append([last - 1, 1, last])
264265
faces.append([1, last - 1, first])
265266

267+
if triangulated:
268+
triangles = []
269+
for face in faces:
270+
if len(face) == 4:
271+
triangles.append(face[0:3])
272+
triangles.append([face[0], face[2], face[3]])
273+
else:
274+
triangles.append(face)
275+
faces = triangles
276+
266277
return vertices, faces
267278

268279
def transform(self, transformation):

src/compas/geometry/shapes/cylinder.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from compas.geometry import Frame
1313
from compas.geometry import Plane
1414

15-
from compas.geometry.shapes import Shape
15+
from ._shape import Shape
1616

1717

1818
class Cylinder(Shape):
@@ -219,14 +219,15 @@ def from_data(cls, data):
219219
# methods
220220
# ==========================================================================
221221

222-
def to_vertices_and_faces(self, u=10):
222+
def to_vertices_and_faces(self, u=16, triangulated=False):
223223
"""Returns a list of vertices and faces.
224224
225225
Parameters
226226
----------
227227
u : int, optional
228228
Number of faces in the "u" direction.
229-
Default is ``10``.
229+
triangulated: bool, optional
230+
Flag indicating that the faces have to be triangulated.
230231
231232
Returns
232233
-------
@@ -265,6 +266,16 @@ def to_vertices_and_faces(self, u=10):
265266
faces.append(top)
266267
faces.append(bottom[::-1])
267268

269+
if triangulated:
270+
triangles = []
271+
for face in faces:
272+
if len(face) == 4:
273+
triangles.append(face[0:3])
274+
triangles.append([face[0], face[2], face[3]])
275+
else:
276+
triangles.append(face)
277+
faces = triangles
278+
268279
return vertices, faces
269280

270281
def transform(self, transformation):

src/compas/geometry/shapes/polyhedron.py

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
from math import sqrt
66
from compas.geometry import transform_points
7+
from compas.geometry import centroid_polygon
78
from compas.utilities import pairwise
89

9-
from compas.geometry.shapes._shape import Shape
10+
from ._shape import Shape
1011

1112

1213
class Polyhedron(Shape):
@@ -95,7 +96,7 @@ def data(self, data):
9596
# ==========================================================================
9697

9798
def __repr__(self):
98-
return 'Polyhedron({0!r}, {1!r})'.format(self.vertices, self.faces)
99+
return '<Polyhedron with {} vertices and {} faces>'.format(len(self.vertices), len(self.faces))
99100

100101
def __len__(self):
101102
return 2
@@ -164,16 +165,19 @@ def from_platonicsolid(cls, f):
164165
165166
"""
166167
if f == 4:
167-
return cls(* tetrahedron())
168-
if f == 6:
169-
return cls(* hexahedron())
170-
if f == 8:
171-
return cls(* octahedron())
172-
if f == 12:
173-
return cls(* dodecahedron())
174-
if f == 20:
175-
return cls(* icosahedron())
176-
raise ValueError("The number of sides of a platonic solid must be one of: 4, 6, 8, 12, 20.")
168+
vertices, faces = tetrahedron()
169+
elif f == 6:
170+
vertices, faces = hexahedron()
171+
elif f == 8:
172+
vertices, faces = octahedron()
173+
elif f == 12:
174+
vertices, faces = dodecahedron()
175+
elif f == 20:
176+
vertices, faces = icosahedron()
177+
else:
178+
raise ValueError("The number of sides of a platonic solid must be one of: 4, 6, 8, 12, 20.")
179+
solid = cls(vertices, faces)
180+
return solid
177181

178182
@classmethod
179183
def from_halfspaces(cls, halfspaces, interior_point):
@@ -263,16 +267,49 @@ def from_planes(cls, planes):
263267
# methods
264268
# ==========================================================================
265269

266-
def to_vertices_and_faces(self):
270+
def to_vertices_and_faces(self, triangulated=False):
267271
"""Returns a list of vertices and faces.
268272
273+
Parameters
274+
----------
275+
triangulated: bool, optional
276+
Flag indicating that the faces have to be triangulated.
277+
269278
Returns
270279
-------
271280
(vertices, faces)
272281
A list of vertex locations and a list of faces,
273282
with each face defined as a list of indices into the list of vertices.
274283
"""
275-
return self.vertices, self.faces
284+
if triangulated:
285+
vertices = self.vertices[:]
286+
faces = []
287+
for face in self.faces:
288+
if len(face) > 3:
289+
centroid = centroid_polygon([vertices[index] for index in face])
290+
index = len(vertices)
291+
vertices.append(centroid)
292+
for a, b in pairwise(face):
293+
faces.append([a, b, index])
294+
else:
295+
faces.append(face)
296+
else:
297+
vertices = self.vertices
298+
faces = self.faces
299+
return vertices, faces
300+
301+
def is_closed(self):
302+
"""Verify that the polyhedron forms a closed surface.
303+
304+
Returns
305+
-------
306+
bool
307+
True if the polyhedron is closed.
308+
False otherwise.
309+
"""
310+
from compas.datastructures import Mesh
311+
mesh = Mesh.from_vertices_and_faces(self.vertices, self.faces)
312+
return mesh.is_closed()
276313

277314
def transform(self, transformation):
278315
"""Transform the polyhedron.

src/compas/geometry/shapes/sphere.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from compas.geometry import Point
1010

11-
from compas.geometry.shapes import Shape
11+
from ._shape import Shape
1212

1313

1414
class Sphere(Shape):
@@ -184,17 +184,17 @@ def from_data(cls, data):
184184
# methods
185185
# ==========================================================================
186186

187-
def to_vertices_and_faces(self, u=10, v=10):
187+
def to_vertices_and_faces(self, u=16, v=16, triangulated=False):
188188
"""Returns a list of vertices and faces
189189
190190
Parameters
191191
----------
192192
u : int, optional
193193
Number of faces in the "u" direction.
194-
Default is ``10``.
195194
v : int, optional
196195
Number of faces in the "v" direction.
197-
Default is ``10``.
196+
triangulated: bool, optional
197+
Flag indicating that the faces have to be triangulated.
198198
199199
Returns
200200
-------
@@ -245,6 +245,16 @@ def to_vertices_and_faces(self, u=10, v=10):
245245
nn = len(vertices) - 3 - (j + 1) % u
246246
faces.append([np, nn, nc])
247247

248+
if triangulated:
249+
triangles = []
250+
for face in faces:
251+
if len(face) == 4:
252+
triangles.append(face[0:3])
253+
triangles.append([face[0], face[2], face[3]])
254+
else:
255+
triangles.append(face)
256+
faces = triangles
257+
248258
return vertices, faces
249259

250260
def transform(self, transformation):

src/compas/geometry/shapes/torus.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from compas.geometry import Frame
1212
from compas.geometry import Plane
1313

14-
from compas.geometry.shapes import Shape
14+
from ._shape import Shape
1515

1616

1717
class Torus(Shape):
@@ -208,17 +208,17 @@ def from_data(cls, data):
208208
# methods
209209
# ==========================================================================
210210

211-
def to_vertices_and_faces(self, u=10, v=10):
211+
def to_vertices_and_faces(self, u=16, v=16, triangulated=False):
212212
"""Returns a list of vertices and faces
213213
214214
Parameters
215215
----------
216216
u : int, optional
217217
Number of faces in the "u" direction.
218-
Default is ``10``.
219218
v : int, optional
220219
Number of faces in the "v" direction.
221-
Default is ``10``.
220+
triangulated: bool, optional
221+
Flag indicating that the faces have to be triangulated.
222222
223223
Returns
224224
-------
@@ -256,6 +256,17 @@ def to_vertices_and_faces(self, u=10, v=10):
256256
c = ii * v + jj
257257
d = i * v + jj
258258
faces.append([a, b, c, d])
259+
260+
if triangulated:
261+
triangles = []
262+
for face in faces:
263+
if len(face) == 4:
264+
triangles.append(face[0:3])
265+
triangles.append([face[0], face[2], face[3]])
266+
else:
267+
triangles.append(face)
268+
faces = triangles
269+
259270
return vertices, faces
260271

261272
def transform(self, transformation):

0 commit comments

Comments
 (0)