44
55from math import pi
66from compas .utilities import flatten
7- from compas .utilities import geometric_key
87
98__all__ = ['mesh_dual' ]
109
@@ -24,24 +23,41 @@ def mesh_dual(mesh, cls=None, boundary=0):
2423 Defaults to the type of the provided mesh object.
2524 boundary: float, optional
2625 boundary mode for the dual mesh
27- Default mode is 0, not create faces on boundaries
26+ Default mode is 0, not create faces on boundaries.
27+ 1, create faces on mesh edges, not include original mesh boundary vertices.
28+ 2. create faces on mesh edges and include original mesh boundary vertices on the corner.
29+ 3. create faces on mesh edges and include all original mesh boundary vertices.
2830
2931 Returns
3032 -------
3133 :class:`~compas.datastructures.Mesh`
3234 The dual mesh object.
3335
36+ Examples
37+ --------
38+ >>> from compas.datastructures import Mesh
39+ >>> mesh = Mesh.from_obj(compas.get('faces.obj'))
40+ >>> mesh.delete_face(11)
41+ >>> mesh.delete_face(6)
42+ >>> mesh.delete_face(7)
43+ >>> mesh.quads_to_triangles()
44+ >>> mesh = mesh.subdivide('corner')
45+ >>> dual = mesh.dual(boundary=3)
46+
3447 """
3548 if not cls :
3649 cls = type (mesh )
3750
3851 dual = cls ()
3952
53+ mesh .unify_cycles ()
54+ mesh .flip_cycles ()
55+
4056 face_centroid = {face : mesh .face_centroid (face ) for face in mesh .faces ()}
4157 outer = list (flatten (mesh .vertices_on_boundaries ()))
4258 vertex_xyz = {}
4359 face_vertices = {}
44- boundary_xyz = {}
60+ edge_vertex = {}
4561
4662 # safe guarded if face index is arbitrary, random, not starting from 0
4763 num_faces = max (max (list (mesh .faces ())) + 1 , mesh .number_of_faces ())
@@ -54,28 +70,53 @@ def mesh_dual(mesh, cls=None, boundary=0):
5470
5571 if not boundary :
5672 continue
57- if vertex not in outer or len (faces ) <= 1 :
73+
74+ if boundary > 3 :
75+ raise ValueError ("edge mode from 0 to 3!" )
76+
77+ if vertex not in outer or len (faces ) < 1 :
5878 continue
5979
60- nbr_vertices = reversed (mesh .vertex_neighbors (vertex , ordered = True ))
61- boundary_vertices = faces
80+ boundary_fids = faces [:]
81+ current_face = vertex
82+ corner_count = 0
83+ edge_count = 0
84+
85+ for nbr_vertex in reversed (mesh .vertex_neighbors (vertex , ordered = True )):
86+
87+ if not mesh .is_edge_on_boundary (vertex , nbr_vertex ):
88+ continue
89+ pt = mesh .edge_midpoint (vertex , nbr_vertex )
90+
91+ if num_faces not in vertex_xyz and len (faces ) == 1 and corner_count == 0 and (boundary == 2 or boundary == 3 ):
92+ vertex_xyz [num_faces ] = mesh .vertex_coordinates (vertex )
93+ current_face = num_faces
94+ num_faces += 1
95+ corner_count += 1
96+
97+ if num_faces not in vertex_xyz and len (faces ) != 1 and edge_count == 0 and boundary == 3 :
98+ vertex_xyz [num_faces ] = mesh .vertex_coordinates (vertex )
99+ current_face = num_faces
100+ num_faces += 1
101+ edge_count += 1
62102
63- for nbr_vertex in nbr_vertices :
103+ if num_faces not in vertex_xyz and ((vertex , nbr_vertex ) not in edge_vertex and
104+ (nbr_vertex , vertex ) not in edge_vertex ):
64105
65- if mesh .is_edge_on_boundary (vertex , nbr_vertex ):
66- pt = mesh .edge_midpoint (vertex , nbr_vertex )
106+ vertex_xyz [num_faces ] = pt
107+ edge_vertex [vertex , nbr_vertex ] = edge_vertex [nbr_vertex , vertex ] = num_faces
108+ boundary_fids .append (num_faces )
109+ num_faces += 1
110+ else :
111+ boundary_fids .append (edge_vertex [vertex , nbr_vertex ])
67112
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
113+ if vertex in outer and len (faces ) == 1 and (boundary == 2 or boundary == 3 ):
114+ boundary_fids .insert (len (faces ) + 1 , current_face )
72115
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 )
116+ if vertex in outer and len (faces ) != 1 and boundary == 3 :
117+ boundary_fids .insert (len (faces ) + 1 , current_face )
77118
78- face_vertices [vertex ] = boundary_vertices
119+ face_vertices [vertex ] = boundary_fids
79120
80121 for vertex in vertex_xyz :
81122 x , y , z = vertex_xyz [vertex ]
0 commit comments