mesh.blend (497 KB)
from mathutils.kdtree import KDTree
from itertools import cycle
def get_vertex(mesh, index, mapping, mat_id=0):
try:
return mapping[index]
except KeyError:
mapping[index] = mesh.getVertex(mat_id, index)
return mapping[index]
def get_polygons(mesh):
num_polygons = mesh.numPolygons
for i in range(num_polygons):
yield mesh.getPolygon(i)
def get_split_to_grouped_vertices(mesh_vertices):
# Build KDTree
kdtree = KDTree(len(mesh_vertices))
for i, vertex in enumerate(mesh_vertices):
kdtree.insert(vertex.XYZ, i)
kdtree.balance()
tolerance = 1e-5
visited_vertices = set()
split_to_group = {}
# Find near vertices (split vertices) and non split vertices
for vertex in mesh_vertices:
if vertex in visited_vertices:
continue
result = kdtree.find_range(vertex.XYZ, tolerance)
group_vertices = tuple([mesh_vertices[i] for (p, i, d) in result])
visited_vertices.update(group_vertices)
for vertex in group_vertices:
split_to_group[vertex] = group_vertices
return split_to_group
def build(cont):
own = cont.owner
mesh = own.meshes[0]
vertex_to_poly = {}
id_to_vertex = {}
polygon_vertices = {}
for polygon in get_polygons(mesh):
polygon_vertices[polygon] = vertices = []
for i in range(polygon.getNumVertex()):
vertex_index = polygon.getVertexIndex(i)
vertex = get_vertex(mesh, vertex_index, id_to_vertex)
# Two-way mappings
vertex_to_poly[vertex] = polygon
vertices.append(vertex)
mesh_vertices = list(vertex_to_poly)
split_to_group = get_split_to_grouped_vertices(mesh_vertices)
# dict(split_to_group=split_to_group, vertex_to_poly=vertex_to_poly, poly_to_vertices=polygon_vertices)
This will find several pieces of useful information, such as the mapping from vertex to face (which can tell you the edges inside that face - find the index of the vertex in the vertex list of the polygons that it belongs to, and the two vertices either side of it (for each found polygon) are connected by edges.
To account for vertex “splitting”, you have to perform this step for each of the split vertices:
See blend