@@ -52,3 +52,63 @@ def mesh_remesh(
5252 V = np .asarray (V , dtype = np .float64 , order = "C" )
5353 F = np .asarray (F , dtype = np .int32 , order = "C" )
5454 return _meshing .remesh (V , F , target_edge_length , number_of_iterations )
55+
56+
57+ def mesh_remesh_dual (
58+ mesh : VerticesFaces ,
59+ target_edge_length : float ,
60+ number_of_iterations : int = 10 ,
61+ angle_radians : float = 0.0 ,
62+ circumcenter : bool = True ,
63+ ) -> tuple [np .ndarray , list [list [int ]]]:
64+ """Create a dual mesh from a triangular mesh with variable-length faces.
65+
66+ Parameters
67+ ----------
68+ mesh : :attr:`compas_cgal.types.VerticesFaces`
69+ The mesh to create a dual from.
70+ target_edge_length : float
71+ The target edge length for primal mesh remeshing before dual creation.
72+ number_of_iterations : int, optional
73+ Number of remeshing iterations for the primal mesh.
74+ angle_radians : double, optional
75+ Angle limit in radians for boundary vertices to remove.
76+ circumcenter : bool, optional
77+ Whether to use the circumcenter of the triangle instead of the centroid.
78+
79+ Returns
80+ -------
81+ tuple
82+ A tuple containing:
83+ - Dual mesh vertices as an Nx3 numpy array.
84+ - Variable-length faces as a list of lists of vertex indices.
85+
86+ Notes
87+ -----
88+ This dual mesh implementation includes proper boundary handling by:
89+ 1. Creating vertices at face centroids of the primal mesh
90+ 2. Creating additional vertices at boundary edge midpoints
91+ 3. Creating proper connections for boundary edges
92+
93+ Examples
94+ --------
95+ >>> from compas.datastructures import Mesh
96+ >>> from compas_cgal.meshing import mesh_remesh_dual
97+
98+ >>> # Create a simple quad mesh
99+ >>> mesh = Mesh.from_vertices_and_faces([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], [[0, 1, 2, 3]])
100+ >>> vertices, faces = mesh.to_vertices_and_faces()
101+
102+ >>> # Create its dual mesh with variable-length faces
103+ >>> V, F = mesh_remesh_dual((vertices, faces), 0.1)
104+ >>> dual_mesh = Mesh.from_vertices_and_faces(V, [])
105+ >>> # Add the variable-length faces to the mesh
106+ >>> for face in F:
107+ ... dual_mesh.add_face(face)
108+
109+ """
110+ V , F = mesh
111+ V = np .asarray (V , dtype = np .float64 , order = "C" )
112+ F = np .asarray (F , dtype = np .int32 , order = "C" )
113+ vertices , var_faces = _meshing .remesh_dual (V , F , target_edge_length , number_of_iterations , angle_radians , circumcenter )
114+ return vertices , var_faces
0 commit comments