For a single vertex, how can I create a list of all the vertices connected directly or indirectly to it? Similar to Select Linked but without actually selecting anything.
-
1$\begingroup$ If there's no better way, you could Select linked, get a list of selected vertices and deselect all. Check blender.stackexchange.com/questions/5781/… $\endgroup$– someonewithpcCommented Aug 20, 2014 at 17:09
-
2$\begingroup$ You can get the edges the vertex is part of, then get their vertices (but exclude the verts you already visited). But Select linked is still better, because it uses native code and superior bmesh walkers. $\endgroup$– CodeManXCommented Aug 20, 2014 at 18:56
1 Answer
Assuming the following definitions are a correct interpretation of what you are asking...
directly: connected by a single edge
indirectly: connected through a continuous path of N edges
...then the following code will find all directly or indirectly connected vertices of a given vertex. findConnectedVerts() takes the vertex of interest plus a maximum depth as arguments. It will then recursively find the connected vertices. I've tested this on a cube to verify that depth 1 yields the directly connected vertices, depth 2 yields all but a single vertex (which is 3 away) and depth 3 yields all the vertices in the cube (well, not the vertex passed in).
Note: I wasn't considering performance only functionality
import bpy
def getEdgesForVertex(v_index, mesh, marked_edges):
all_edges = [e for e in mesh.edges if v_index in e.vertices]
unmarked_edges = [e for e in all_edges if e.index not in marked_edges]
return unmarked_edges
def findConnectedVerts(v_index, mesh, connected_verts, marked_edges, maxdepth=1, level=0):
if level >= maxdepth:
return
edges = getEdgesForVertex(v_index, mesh, marked_edges)
for e in edges:
othr_v_index = [idx for idx in mesh.edges[e.index].vertices if idx != v_index][0]
connected_verts[othr_v_index] = True
marked_edges.append(e.index)
findConnectedVerts(othr_v_index, mesh, connected_verts, marked_edges, maxdepth=maxdepth, level=level+1)
def main():
mesh = bpy.context.object.data
connected_verts = {}
marked_edges = []
findConnectedVerts(0, mesh, connected_verts, marked_edges, maxdepth=1)
print(",".join([str(v) for v in connected_verts.keys()]))
connected_verts = {}
marked_edges = []
findConnectedVerts(0, mesh, connected_verts, marked_edges, maxdepth=2)
print(",".join([str(v) for v in connected_verts.keys()]))
connected_verts = {}
marked_edges = []
findConnectedVerts(0, mesh, connected_verts, marked_edges, maxdepth=3)
print(",".join([str(v) for v in connected_verts.keys()]))
main()
-
$\begingroup$ I must say the use of the global variables makes me uncomfortable. I would turn them into explicit function parameters. $\endgroup$ Commented Aug 23, 2014 at 16:36
-
$\begingroup$ Fair enough, updated to remove globals and avoid your discomfort. :) $\endgroup$– Mike N.Commented Aug 23, 2014 at 19:26