33from __future__ import division
44
55from math import pi
6-
6+ from compas .utilities import flatten
7+ from compas .utilities import geometric_key
78
89__all__ = ['mesh_dual' ]
910
1011
1112PI2 = 2.0 * pi
1213
1314
14- def mesh_dual (mesh , cls = None ):
15+ def mesh_dual (mesh , cls = None , boundary = 0 ):
1516 """Construct the dual of a mesh.
1617
1718 Parameters
@@ -21,6 +22,9 @@ def mesh_dual(mesh, cls=None):
2122 cls : Type[:class:`~compas.datastructures.Mesh`], optional
2223 The type of the dual mesh.
2324 Defaults to the type of the provided mesh object.
25+ boundary: float, optional
26+ boundary mode for the dual mesh
27+ Default mode is 0, not create faces on boundaries
2428
2529 Returns
2630 -------
@@ -34,17 +38,45 @@ def mesh_dual(mesh, cls=None):
3438 dual = cls ()
3539
3640 face_centroid = {face : mesh .face_centroid (face ) for face in mesh .faces ()}
37- inner = list (set (mesh .vertices ()) - set ( mesh . vertices_on_boundary ()))
41+ outer = list (flatten (mesh .vertices_on_boundaries ()))
3842 vertex_xyz = {}
3943 face_vertices = {}
44+ boundary_xyz = {}
4045
41- for vertex in inner :
46+ # safe guarded if face index is arbitrary, random, not starting from 0
47+ num_faces = max (max (list (mesh .faces ())) + 1 , mesh .number_of_faces ())
48+ for vertex in mesh .vertices ():
4249 faces = mesh .vertex_faces (vertex , ordered = True )
4350 for face in faces :
4451 if face not in vertex_xyz :
4552 vertex_xyz [face ] = face_centroid [face ]
4653 face_vertices [vertex ] = faces
4754
55+ if not boundary :
56+ continue
57+ if vertex not in outer or len (faces ) <= 1 :
58+ continue
59+
60+ nbr_vertices = reversed (mesh .vertex_neighbors (vertex , ordered = True ))
61+ boundary_vertices = faces
62+
63+ for nbr_vertex in nbr_vertices :
64+
65+ if mesh .is_edge_on_boundary (vertex , nbr_vertex ):
66+ pt = mesh .edge_midpoint (vertex , nbr_vertex )
67+
68+ if geometric_key (pt ) not in boundary_xyz and num_faces not in vertex_xyz :
69+ vertex_xyz [num_faces ] = pt
70+ boundary_xyz [geometric_key (pt )] = num_faces
71+ num_faces += 1
72+
73+ if geometric_key (pt ) in boundary_xyz :
74+ boundary_vertices .append (boundary_xyz [geometric_key (pt )])
75+ else :
76+ boundary_vertices .append (num_faces )
77+
78+ face_vertices [vertex ] = boundary_vertices
79+
4880 for vertex in vertex_xyz :
4981 x , y , z = vertex_xyz [vertex ]
5082 dual .add_vertex (vertex , x = x , y = y , z = z )
0 commit comments