3
$\begingroup$

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.

$\endgroup$
2
  • 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$ Commented 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$
    – CodeManX
    Commented Aug 20, 2014 at 18:56

1 Answer 1

6
$\begingroup$

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()
$\endgroup$
2
  • $\begingroup$ I must say the use of the global variables makes me uncomfortable. I would turn them into explicit function parameters. $\endgroup$
    – Mutant Bob
    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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .