2
$\begingroup$

I'm just messing around with bmesh and was trying to create a script that would extrude the edges I mark as sharp. Here's my code:

import bpy
import bmesh
from mathutils import Vector

ob = bpy.context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)
selected_verts = [v for v in bm.faces if v.select]
verts_to_extrude = []

for e in bm.edges:
    if not e.smooth:
        verts_to_extrude.append(e)

bmesh.ops.extrude_edge_only(bm, edges=verts_to_extrude)

bmesh.update_edit_mesh(bpy.context.object.data)     

Here is what it does:

Before:

enter image description here

After:

enter image description here

Note: the code does not move the selected vertices, I just moved them out of the way so you could see what its doing.

It is doing what I want in that it is extruding the vertices marked sharp, but it leaves the original vertices I had selected, selected. Is there any way to make it so that it selects the extruded vertices and deselects the vertices I had selected before the operation?

$\endgroup$
  • $\begingroup$ Trybpy.ops.mesh.extrude_edges_indiv() instead of bmesh.ops.extrude_edge_only(bm, edges=verts_to_extrude). Therefore you must select the edges beforehand rather than store them in a list. Not sure if that solves your problem so I didn't write an answer. $\endgroup$ – Dimali Oct 9 '17 at 21:00
2
$\begingroup$

Bmesh ops have return values.


Unlike bpy.ops which only return a status of operation, bmesh.ops in many cases return a result. bmesh.ops.extrude_edge_only(...) is one.

It returns a dictionary with a list of elements. {'geom': [<BMVert(0x7fc7a6b0ef50), index=528>,....]}

There is an example on bmesh ops api that uses extrude extensively.

import bpy
import bmesh
from mathutils import Vector

ob = bpy.context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)
selected_verts = [v for v in bm.verts if v.select]
# deselect all verts
for v in bm.verts:  
    v.select = False

edges_to_extrude = [e for e in bm.edges if not e.smooth]

ret = bmesh.ops.extrude_edge_only(bm, edges=edges_to_extrude)
geom_extrude = ret["geom"]
print(ret) # the geometry returned from op.
del ret

verts_extrude = [ele for ele in geom_extrude
                   if isinstance(ele, bmesh.types.BMVert)]
# select them
for v in verts_extrude:
    v.select = True
bmesh.update_edit_mesh(me)  
$\endgroup$
  • $\begingroup$ Thanks for the answer it worked perfectly! Related question though, what if I wanted to select the edges between the extruded vertices and the old vertices as well? I've gotten farther in this project, and noticed that after doing an extrude on a vertice and a rip on another set of edges, that despite selecting the old and new vertices with connecting edges bmesh doesn't automatically select the edge too. $\endgroup$ – NotaProphet Oct 13 '17 at 16:07
  • 1
    $\begingroup$ Set the select mode set to include edges. And flush the selection. bm.select_flush() or bm.select_flush_mode() $\endgroup$ – batFINGER Oct 13 '17 at 16:51

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.