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$
1
  • $\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
    Commented Oct 9, 2017 at 21:00

1 Answer 1

4
$\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$
2
  • $\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$ Commented Oct 13, 2017 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
    Commented Oct 13, 2017 at 16:51

You must log in to answer this question.

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