Suppose I want to select the entire mesh boundary. Alt + RMB on a boundary edge would select one edge loop (left image), while Alt + double RMB yields the desired result (right image).

edge loop select

How would I achieve this result by scripting? Assume the user first selects one boundary edge manually. I reckon it is buried somewhere in this function:

bpy.ops.mesh.loop_select(extend=False, deselect=False, toggle=False, ring=False)

But I can't quite understand how to use this function. Examples on how to do this would be very much welcome.


1 Answer 1


Bmesh script.

With a single boundary edge selected in edit mode, the LHS of question images can be achieved calling bpy.ops.mesh.loop_multi_select() directly from the python console.

>>> bpy.ops.mesh.loop_multi_select(
Select a loop of connected edges by connection type
>>> bpy.ops.mesh.loop_multi_select()

enter image description here

The mesh.loop_select operator is a different kettle of fish and requires context override if called from outside the 3D view.

This is a matter of giving the context override dictionary a 3d view "area", "space_data" and "region"

However even then, with all combos of options it still did not perform as did the alt double click on my test mesh.

Use bmesh.

IMO edit mode mesh operators can become mind-numbingly annoying to code when they cannot be "made to perform" as desired

Touched on some other reasons to avoid operators Element indices messed up after switching from Edit to Object Mode

Can instead create our own methods

The boundary select function below takes an edge, tags it, looks at all untagged boundary edges linked to its two end verts, tags them and so on until it can go no further, then returns the edges.

Test script, run in edit mode with a single boundary edge selected.

import bpy
import bmesh
from collections import defaultdict

context = bpy.context

ob = context.edit_object
me = ob.data

bm = bmesh.from_edit_mesh(me)

edge = bm.select_history.active

assert isinstance(edge, bmesh.types.BMEdge), "Select an Edge"

def boundary_select(edge):
    tag = defaultdict(bool)
    tag[edge] = True
    grow = True
    edges = [edge]
    while grow:
        more = [
        el for es in edges 
        for v in es.verts 
        for el in v.link_edges if not tag[el] and el.is_boundary
        for e in more:
            tag[e] = True
        grow = bool(more)
    return edges
for e in boundary_select(edge):

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

Persistence of element tag and select using bound bmesh

How to detect disconnected parts within a selection?

  • $\begingroup$ Alright this has answered my question. Hoped it would be easier to use the bpy operator instead of recreating the method. Does context override have disadvantages? When would you use override instead of creating your own method? $\endgroup$
    – Niels
    Mar 1, 2021 at 9:01
  • $\begingroup$ Chances are can use the operator, couldn't crack it, but am slowly learning not to bother if can do it with bmesh. (in less time). Re overriding context, would make a good question (may be one IIRC) I am of the view that if you make a method like above, it takes context out of equation. All that matters is a valid bmesh. (btw have another similar answer re this somewhere that orders edges --> slice n feed into bmesh grid fill for instance) Possibly most important is what you wish to achieve via scripting. Covered some of this in prior answers to your questions. Started coding blender $\endgroup$
    – batFINGER
    Mar 1, 2021 at 9:39
  • $\begingroup$ in 2.49, then 2.5 brought in bpy with no bmesh. Used to write all mesh manipulation either via ops or manipulating mesh data. Had no idea how to use bmesh for a long while, after it arrived, and was all the rage. (similarly with cycles and material nodes lol) . When it twigs, its nigh on impossible to look back . .. tho, to reiterate, depends on your use case. $\endgroup$
    – batFINGER
    Mar 1, 2021 at 9:51

You must log in to answer this question.

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