1111PI2 = 2.0 * pi
1212
1313
14- def mesh_dual (mesh , cls = None , include_boundary = False , preserve_boundary_vertices = False , preserve_corner_vertices = False ):
14+ def mesh_dual (mesh , cls = None , include_boundary = False ):
1515 """Construct the dual of a mesh.
1616
1717 Parameters
@@ -24,12 +24,6 @@ def mesh_dual(mesh, cls=None, include_boundary=False, preserve_boundary_vertices
2424 include_boundary: str, optional
2525 Whether to include boundary faces for the dual mesh
2626 Default mode is False, don't create faces on boundaries.
27- preserve_boundary_vertices: str, optional
28- Whether to preserve boundary vertices from the original mesh
29- Default mode is False, include the boundary without the original vertices.
30- preserve_corner_vertices: str, optional
31- Whether to preserve corner vertices (only connect to one face) from the original mesh
32- Default mode is False, include the boundary with the original vertices only on corners.
3327
3428 Returns
3529 -------
@@ -46,83 +40,67 @@ def mesh_dual(mesh, cls=None, include_boundary=False, preserve_boundary_vertices
4640 >>> mesh.delete_face(7)
4741 >>> mesh.quads_to_triangles()
4842 >>> mesh = mesh.subdivide('corner')
49- >>> dual = mesh.dual(include_boundary=True, preserve_boundary_vertices=True, preserve_corner_vertices=False )
43+ >>> dual = mesh.dual(include_boundary=True)
5044
5145 """
5246 if not cls :
5347 cls = type (mesh )
5448
5549 dual = cls ()
5650
57- mesh .flip_cycles ()
58-
5951 face_centroid = {face : mesh .face_centroid (face ) for face in mesh .faces ()}
60- outer = list (flatten (mesh .vertices_on_boundaries ()))
52+ outer = set (flatten (mesh .vertices_on_boundaries ()))
53+ inner = list (set (mesh .vertices ()) - outer )
6154 vertex_xyz = {}
6255 face_vertices = {}
63- edge_vertex = {}
6456
65- # safe guarded if face index is arbitrary, random, not starting from 0
66- num_faces = max (max (list (mesh .faces ())) + 1 , mesh .number_of_faces ())
67- for vertex in mesh .vertices ():
57+ for vertex in inner :
6858 faces = mesh .vertex_faces (vertex , ordered = True )
6959 for face in faces :
7060 if face not in vertex_xyz :
7161 vertex_xyz [face ] = face_centroid [face ]
7262 face_vertices [vertex ] = faces
7363
74- if not include_boundary :
75- continue
76-
77- if vertex not in outer or len (faces ) < 1 :
78- continue
79-
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 (preserve_corner_vertices or preserve_boundary_vertices ):
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 preserve_boundary_vertices :
98- vertex_xyz [num_faces ] = mesh .vertex_coordinates (vertex )
99- current_face = num_faces
100- num_faces += 1
101- edge_count += 1
102-
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 ):
105-
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 ])
112-
113- if vertex in outer and len (faces ) == 1 and (preserve_corner_vertices or preserve_boundary_vertices ):
114- boundary_fids .insert (len (faces ) + 1 , current_face )
115-
116- if vertex in outer and len (faces ) != 1 and preserve_boundary_vertices :
117- boundary_fids .insert (len (faces ) + 1 , current_face )
118-
119- face_vertices [vertex ] = boundary_fids
120-
12164 for vertex in vertex_xyz :
12265 x , y , z = vertex_xyz [vertex ]
12366 dual .add_vertex (vertex , x = x , y = y , z = z )
12467
12568 for face in face_vertices :
12669 dual .add_face (face_vertices [face ], fkey = face )
12770
71+ if not include_boundary :
72+ return dual
73+
74+ for boundary in mesh .faces_on_boundaries ():
75+ for face in boundary :
76+ if not dual .has_vertex (face ):
77+ x , y , z = face_centroid [face ]
78+ dual .add_vertex (key = face , x = x , y = y , z = z )
79+
80+ edge_vertex = {}
81+ for boundary in mesh .edges_on_boundaries ():
82+ for u , v in boundary :
83+ x , y , z = mesh .edge_midpoint (u , v )
84+ edge_vertex [u , v ] = edge_vertex [v , u ] = dual .add_vertex (x = x , y = y , z = z )
85+
86+ vertex_vertex = {}
87+ for boundary in mesh .vertices_on_boundaries ():
88+ if boundary [0 ] == boundary [- 1 ]:
89+ boundary = boundary [:- 1 ]
90+ for vertex in boundary :
91+ x , y , z = mesh .vertex_coordinates (vertex )
92+ vertex_vertex [vertex ] = dual .add_vertex (x = x , y = y , z = z )
93+
94+ for boundary in mesh .vertices_on_boundaries ():
95+ if boundary [0 ] == boundary [- 1 ]:
96+ boundary = boundary [:- 1 ]
97+ for vertex in boundary :
98+ vertices = [vertex_vertex [vertex ]]
99+ nbrs = mesh .vertex_neighbors (vertex , ordered = True )[::- 1 ]
100+ vertices .append (edge_vertex [vertex , nbrs [0 ]])
101+ for nbr in nbrs [:- 1 ]:
102+ vertices .append (mesh .halfedge_face (vertex , nbr ))
103+ vertices .append (edge_vertex [vertex , nbrs [- 1 ]])
104+ dual .add_face (vertices [::- 1 ])
105+
128106 return dual
0 commit comments