2
$\begingroup$

Using bmesh.ops.extrude_edge_only(bm, edges=[], use_normal_flip=False, use_select_history=False) (https://docs.blender.org/api/current/bmesh.ops.html#bmesh.ops.extrude_edge_only), how do I specify how far and in what direction to extrude?

$\endgroup$

1 Answer 1

2
$\begingroup$

The operator returns the geometry created by the extrusion, as a dictionary with a single key named geom. The extrusion is done in place, rather counter-intuitively. It contains all the new faces, edges and verts so you can pick and choose which ones you want, here you want the vertices. You can then simply transform it as you want using the vertices coordinates.

You can use a wrapper if you want to simplify calling this operator and transform the verts in the same function.

import bpy
import bmesh
from mathutils import Vector


def extrude_verts(mesh, direction):
    if bpy.context.mode == "EDIT_MESH":  # You access the bmesh differently in edit mode
        bm = bmesh.from_edit_mesh(mesh)
    else:
        bm = bmesh.new()
        bm.from_mesh(mesh)
    for geom in bmesh.ops.extrude_edge_only(bm, edges=bm.edges)["geom"]:
        if isinstance(geom, bmesh.types.BMVert):
            geom.co += direction  # Here you transform the vertices
    bmesh.ops.recalc_face_normals(bm, faces=bm.faces)  # Force calculating normals for the new faces

    if bpy.context.mode == "EDIT_MESH":  # You update the mesh differently in edit mode
        bmesh.update_edit_mesh(mesh)
    else:
        bm.to_mesh(mesh)
    bm.free()  # Not mandatory, bm is supposed to be garbage collected at the end of script

    [a.tag_redraw() for a in bpy.context.screen.areas]  # Not mandatory, but it updates the 3D viewport


if __name__ == "__main__":
    extrude_verts(bpy.context.active_object.data, Vector((0, 0, 2)))
$\endgroup$

You must log in to answer this question.

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