Take the 2-minute tour ×
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It's 100% free, no registration required.

Blender Python question:

I have a list of faces and I need do something with some edges of the current face in a for-loop.

Actually, I need something like this, but with edges. Thanks in advance.

share|improve this question
add comment

2 Answers

Standard API

The active face's index is accessible in the standard API (bpy) like:

me.polygons.active

To get the actual polygon, you do:

me.polygons[me.polygons.active]

Note that the index is 0 (first polygons) even if there's no face at all, and it's independent from vertex and edge selection (a face can be active without its edges or vertices being selected).

There's no direct access for a face's edges, you can create a dictionary from the edge_keys however:

import bpy

ob = bpy.context.object

if ob.type != 'MESH':
    raise TypeError("Active object is not a Mesh")

# Get editmode changes
ob.update_from_editmode()

me = ob.data

if len(me.polygons) < 1:
    raise ValueError("Mesh has no faces")

# Build lookup dictionary for edge keys to edges
edges = me.edges
face_edge_map = {ek: edges[i] for i, ek in enumerate(me.edge_keys)}

# Get active face by index
face = me.polygons[me.polygons.active]

selected = "selected"
not_selected = " ".join(("NOT", selected))

for ek in face.edge_keys:
    edge = face_edge_map[ek]
    print("%12s - %r" % ((selected if edge.select else not_selected), edge))

You can also do without such lookup dictionary, may use less memory and perform better, 'since there's just one face we need to find the edges of:

for ek in face.edge_keys:
    edge = me.edges[me.edge_keys.index(ek)]


Bmesh module

You can access the edges directly using the bmesh module (for edge in face.edges):

import bpy
import bmesh

ob = bpy.context.object

if ob.type != 'MESH':
    raise TypeError("Active object is not a Mesh")

me = ob.data

if me.is_editmode:
    # Gain direct access to the mesh
    bm = bmesh.from_edit_mesh(me)
else:
    # Create a bmesh from mesh
    # (won't affect mesh, unless explicitly written back)
    bm = bmesh.new()
    bm.from_mesh(me)


# Get active face
face = bm.faces.active

selected = "selected"
not_selected = " ".join(("NOT", selected))

for edge in face.edges:
    print("%12s - bm.edges[%i]" % ((selected if edge.select else not_selected), edge.index))


# No need to do anything here if you haven't changed the (b)mesh
# Otherwise, flush changes from wrapped bmesh / write back to mesh
"""
if me.is_editmode:
    bmesh.update_edit_mesh(me)
else:
    bm.to_mesh(me)
    me.update()

bm.free()
del bm
"""
share|improve this answer
add comment
poly = mesh.polygons[mesh.polygons.active]
for i in poly.loop_indices:
    edge = mesh.edges[mesh.loops[i].edge_index]
    # do something with edge

Note:

If the mesh is in edit mode, the selection might be out of synch. (see api docs)

share|improve this answer
    
Cool, should work just as good. Edited my answer to show that a lookup dict is not necessarily needed (can also use me.edge_keys.index(...)). To get the editmode changes, you can call ob.update_from_editmode() in recent Blender versions! –  CoDEmanX Feb 3 at 14:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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