# M : Rhino.Geometry.Mesh
def face_vertex_indices(mesh, fi):
"""Return a list of vertex indices for face fi (tri or quad)."""
return [f.A, f.B, f.C, f.D]
"""Given face vertex indices in order, return undirected edges as sorted tuples."""
def build_face_neighbors(mesh):
Build face adjacency by shared edges.
Returns: list of sorted unique neighbor face indices for each face.
if mesh is None or mesh.Faces.Count == 0:
face_count = mesh.Faces.Count
# Map: edge (v0,v1) -> list of face indices that use it
for fi in range(face_count):
verts = face_vertex_indices(mesh, fi)
for e in face_edges(verts):
if e not in edge_to_faces:
edge_to_faces[e].append(fi)
# Now build neighbors per face
nbr_sets = [set() for _ in range(face_count)]
for e, faces in edge_to_faces.items():
# All faces sharing this edge are neighbors of each other
for i in range(len(faces)):
for j in range(len(faces)):
nbr_sets[fi].add(faces[j])
neighbors = [sorted(list(s)) for s in nbr_sets]
raise Exception("Input mesh M is None.")
neighbors = build_face_neighbors(M)
if not filepath or not isinstance(filepath, str):
raise Exception("Provide a valid filepath string.")
folder = os.path.dirname(filepath)
if folder and not os.path.exists(folder):
"faceCount": M.Faces.Count,
# Write JSON (compact + Unity-friendly)
with open(filepath, "w") as f:
msg = "Saved adjacency for {} faces to:\n{}".format(M.Faces.Count, filepath)
msg = "Error: {}".format(str(e))