I am a newbie here. I tried to write python script by copying and pasting commands from the top scripting window in Blender. I met a problem when trying to extrude an object programmatically. Here is my sample code:

      radius=2.5, # The initial radius is the radius of starting point

bpy.context.object.modifiers["Subsurf"].levels = 4

                             TRANSFORM_OT_translate={"value":(0, 0, 0),
                             "constraint_axis":(False, False, False), 
                             "snap_point":(0, 0, 0), 
                             "snap_normal":(0, 0, 0), 

I first merged the mesh of a cube into a single point in edit mode and added a skin modifier to the point, then tried to extrude this point to create an object similar to this:

enter image description here

However, I realized that there is no such keyword to select the vertex that I want to extrude out the bar from. So I was wondering if anyone knows how to select or activate a specific point (by vertex coordinate?) for extrusion?


1 Answer 1


A bmesh approach.

In as much as the operator calls are written in INFO area, and can be used to make scripts I always recommend using API class methods when possible.

Here I've created a new object at (1, 2, 3) using a bmesh and the bmesh extrude individual vert bmesh.ops.extrude_vert_indiv(...) which returns the newly created vert at the other end. For example sake I've added 3 random length branches in random directions.

Because of the random in all directions will get some rubbish result. For practical use some kind of tree data structure.

Added the modifiers using API method Object.modifiers.new(name, type)

enter image description here a test run

import bpy
import bmesh
from mathutils import Vector
from random import randint, uniform
context = bpy.context
scene = context.scene
me = bpy.data.meshes.new("Thing")
ob = bpy.data.objects.new("Thing", me)

bm = bmesh.new()
root = bm.verts.new()
for i in range(3): # tree branches
    v = root
    for l in range(randint(1, 4)):
        ret = bmesh.ops.extrude_vert_indiv(bm, verts=[v])
        for v in ret['verts']:
            v.co += Vector([uniform(-1, 1) for axis in "xyz"])

ob.location = (1, 2, 3)
skin = ob.modifiers.new(name="Skin", type='SKIN')
sub = ob.modifiers.new(name="Sub", type='SUBSURF')
sub.levels = 2

Used the extrude operator to match the question. Could simply add a vertex at next location and use that to create edge.

newvert = bm.verts.new((2, 2, 2))
newedge = bm.edges.new([root, newvert])
  • $\begingroup$ Hi, thanks for the answer. The ops commands have been giving me warnings like ConvertViewVec: called in invalid context blender. I think I have to switch to bmesh. However, how do I select a vertex by location to extrude and then resize? $\endgroup$
    – HSChan
    Sep 3, 2018 at 2:10
  • $\begingroup$ If you have some local location p select vert(s) such that v.select = (v.co - p).length < TOL where TOL is some small tolerance distance from your point. $\endgroup$
    – batFINGER
    Sep 5, 2018 at 8:57

You must log in to answer this question.

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