2
2
import nibabel as nib
3
3
import numpy as np
4
4
from copy import deepcopy
5
+ import networkx as nx
5
6
6
7
7
8
def write_surface_to_gifti (points , faces , out_surf_gii ):
@@ -21,6 +22,48 @@ def write_surface_to_gifti(points, faces, out_surf_gii):
21
22
gifti .to_filename (out_surf_gii )
22
23
23
24
25
+ def largest_connected_component (vertices : np .ndarray , faces : np .ndarray ):
26
+ """
27
+ Returns the vertices, faces, and original indices of the largest connected component of a 3D surface mesh.
28
+
29
+ Parameters:
30
+ vertices (np.ndarray): Array of vertex coordinates (N x 3).
31
+ faces (np.ndarray): Array of face indices (M x 3).
32
+
33
+ Returns:
34
+ tuple: (new_vertices, new_faces, largest_component), where new_vertices are the vertex coordinates of the largest component,
35
+ new_faces are the face indices adjusted to the new vertex order, and largest_component contains the indices of the original vertices.
36
+ """
37
+ # Build adjacency graph from face connectivity
38
+ G = nx .Graph ()
39
+ for face in faces :
40
+ G .add_edges_from (
41
+ [(face [i ], face [j ]) for i in range (3 ) for j in range (i + 1 , 3 )]
42
+ )
43
+
44
+ # Find connected components
45
+ components = list (nx .connected_components (G ))
46
+
47
+ # Select the largest connected component
48
+ largest_component = max (components , key = len )
49
+ largest_component = np .array (list (largest_component ))
50
+
51
+ # Create a mapping from old vertex indices to new ones
52
+ index_map = {old_idx : new_idx for new_idx , old_idx in enumerate (largest_component )}
53
+
54
+ # Filter the vertices and faces
55
+ new_vertices = vertices [largest_component ]
56
+ new_faces = np .array (
57
+ [
58
+ [index_map [v ] for v in face ]
59
+ for face in faces
60
+ if all (v in index_map for v in face )
61
+ ]
62
+ )
63
+
64
+ return new_vertices , new_faces , largest_component
65
+
66
+
24
67
def remove_nan_vertices (vertices , faces ):
25
68
"""
26
69
Removes vertices containing NaNs and updates faces accordingly.
@@ -186,5 +229,9 @@ def compute_geodesic_distances(vertices, faces, source_indices):
186
229
points , faces = remove_nan_vertices (points , faces )
187
230
188
231
232
+ # apply largest connected component
233
+ points , faces , i_concomp = largest_connected_component (vertices_orig , faces )
234
+
235
+
189
236
# write to gifti
190
237
write_surface_to_gifti (points , faces , snakemake .output .surf_gii )
0 commit comments