def face_adjacency(mesh): """Build a face adjacency dict. Parameters ---------- mesh : Mesh A mesh object. Returns ------- dict A dictionary mapping face identifiers (keys) to lists of neighbouring faces. Notes ----- This algorithm is used primarily to unify the cycle directions of a given mesh. Therefore, the premise is that the topological information of the mesh is corrupt and cannot be used to construct the adjacency structure. The algorithm is thus purely geometrical, but uses a spatial indexing tree to speed up the search. """ fkey_index = {fkey: index for index, fkey in enumerate(mesh.faces())} index_fkey = {index: fkey for index, fkey in enumerate(mesh.faces())} points = [mesh.face_centroid(fkey) for fkey in mesh.faces()] try: from scipy.spatial import cKDTree tree = cKDTree(points) _, closest = tree.query(points, k=10, n_jobs=-1) except Exception: try: import Rhino except Exception: from compas.geometry import KDTree tree = KDTree(points) closest = [tree.nearest_neighbours(point, 10) for point in points] closest = [[index for xyz, index, d in nnbrs] for nnbrs in closest] else: from Rhino.Geometry import RTree from Rhino.Geometry import Sphere from Rhino.Geometry import Point3d tree = RTree() for i, point in enumerate(points): tree.Insert(Point3d(*point), i) def callback(sender, e): data = e.Tag data.append(e.Id) closest = [] for i, point in enumerate(points): sphere = Sphere(Point3d(*point), 2.0) data = [] tree.Search(sphere, callback, data) closest.append(data) adjacency = {} for fkey in mesh.faces(): nbrs = [] index = fkey_index[fkey] found = set() nnbrs = closest[index] for u, v in mesh.face_halfedges(fkey): for index in nnbrs: nbr = index_fkey[index] if nbr == fkey: continue if nbr in found: continue for a, b in mesh.face_halfedges(nbr): if v == a and u == b: nbrs.append(nbr) found.add(nbr) break for a, b in mesh.face_halfedges(nbr): if u == a and v == b: nbrs.append(nbr) found.add(nbr) break adjacency[fkey] = nbrs return adjacency
def _mesh_face_adjacency(mesh, nmax=10, radius=2.0): fkey_index = {fkey: index for index, fkey in enumerate(mesh.faces())} index_fkey = {index: fkey for index, fkey in enumerate(mesh.faces())} points = [mesh.face_centroid(fkey) for fkey in mesh.faces()] k = min(mesh.number_of_faces(), nmax) try: from scipy.spatial import cKDTree tree = cKDTree(points) _, closest = tree.query(points, k=k, n_jobs=-1) except Exception: try: import Rhino except Exception: from compas.geometry import KDTree tree = KDTree(points) closest = [tree.nearest_neighbors(point, k) for point in points] closest = [[index for xyz, index, d in nnbrs] for nnbrs in closest] else: from Rhino.Geometry import RTree from Rhino.Geometry import Sphere from Rhino.Geometry import Point3d tree = RTree() for i, point in enumerate(points): tree.Insert(Point3d(* point), i) def callback(sender, e): data = e.Tag data.append(e.Id) closest = [] for i, point in enumerate(points): sphere = Sphere(Point3d(* point), radius) data = [] tree.Search(sphere, callback, data) closest.append(data) adjacency = {} for fkey in mesh.faces(): nbrs = [] index = fkey_index[fkey] found = set() nnbrs = set(closest[index]) for u, v in mesh.face_halfedges(fkey): for index in nnbrs: nbr = index_fkey[index] if nbr == fkey: continue if nbr in found: continue for a, b in mesh.face_halfedges(nbr): if v == a and u == b: nbrs.append(nbr) found.add(nbr) break for a, b in mesh.face_halfedges(nbr): if u == a and v == b: nbrs.append(nbr) found.add(nbr) break adjacency[fkey] = nbrs return adjacency
def face_adjacency(xyz, faces): """""" points = [ centroid_points([xyz[index] for index in face]) for face in faces ] try: from scipy.spatial import cKDTree tree = cKDTree(points) _, closest = tree.query(points, k=10, n_jobs=-1) except Exception: try: import Rhino except Exception: from compas.geometry import KDTree tree = KDTree(points) closest = [tree.nearest_neighbors(point, 10) for point in points] closest = [[index for _, index, _ in nnbrs] for nnbrs in closest] else: from Rhino.Geometry import RTree from Rhino.Geometry import Sphere from Rhino.Geometry import Point3d tree = RTree() for i, point in enumerate(points): tree.Insert(Point3d(*point), i) def callback(sender, e): data = e.Tag data.append(e.Id) closest = [] for i, point in enumerate(points): sphere = Sphere(Point3d(*point), 2.0) data = [] tree.Search(sphere, callback, data) closest.append(data) adjacency = {} for face, vertices in enumerate(faces): nbrs = [] found = set() nnbrs = set(closest[face]) for u, v in pairwise(vertices + vertices[0:1]): for nbr in nnbrs: if nbr == face: continue if nbr in found: continue for a, b in pairwise(faces[nbr] + faces[nbr][0:1]): if v == a and u == b: nbrs.append(nbr) found.add(nbr) break for a, b in pairwise(faces[nbr] + faces[nbr][0:1]): if u == a and v == b: nbrs.append(nbr) found.add(nbr) break adjacency[face] = nbrs return adjacency