1
$\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$
  • 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$ – someonewithpc Aug 20 '14 at 17:09
  • 1
    $\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 Aug 20 '14 at 18:56
5
$\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$
  • $\begingroup$ I must say the use of the global variables makes me uncomfortable. I would turn them into explicit function parameters. $\endgroup$ – Mutant Bob Aug 23 '14 at 16:36
  • $\begingroup$ Fair enough, updated to remove globals and avoid your discomfort. :) $\endgroup$ – Mike N. Aug 23 '14 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.