I'm trying to perform a bevel operation using the bmesh API. My script either crashes Blender, with the error message EXCEPTION_ACCESS_VIOLATION
, or it doesn't do anything, with the 'new' geometry being {'face':[]}
. To make it crash I pass the edges to the geom argument, pass it the verts causes nothing to happen. Has anyone managed to use bevel successfully before?
import bpy
import bmesh
from math import *
from mathutils import *
AXES = {'X' : Vector((1,0,0)),
'Y' : Vector((0,1,0)),
'Z' : Vector((0,0,1))}
def selectPlane(bm, normal = 'z', location = Vector((0,0,0)), feature = 'verts', tolerance = 0.1) : # bpy.context.active_object.location
normal = normal if isinstance(normal, Vector) else AXES[normal.upper()]
if isinstance(feature, list) :
return {key : planeSelect(bm, normal, feature, location, tolerance) for key in feature}
else :
return {'verts' : [vert for vert in bm.verts if abs(vert.co.__sub__(location).dot(normal)) < tolerance],
'edges' : [],
'faces' : []}[feature]
def selectCylinder(bm, radius = 1, normal = 'z', feature = 'verts', location = Vector((0,0,0)), tolerance = 0.1) :
normal = normal if isinstance(normal, Vector) else AXES[normal.upper()]
projxn = lambda vector : vector - vector.project(normal)
if isinstance(feature, list) :
return {key : selectCylinder(bm, radius, feature, location, tolerance) for key in feature}
else :
return {'verts' : [vert for vert in bm.verts if abs(projxn(vert.co.__sub__(location)).length - radius) < tolerance],
'edges' : [edge for edge in bm.edges if all([abs(projxn(vert.co.__sub__(location)).length - radius) < tolerance for vert in edge.verts])],
'faces' : []}[feature]
me = bpy.data.meshes.new("Temp")
ob = bpy.data.objects.new("Temp", me)
bm = bmesh.new()
diameter = 20
length = 20
matrix = Matrix.Identity(4)
ge = bmesh.ops.create_cone(bm, cap_ends = True,
cap_tris = True,
segments = 12,
diameter1 = diameter,
diameter2 = diameter,
depth = length,
matrix = matrix)
go = selectCylinder(bm, radius = diameter, feature = 'edges')
ug = selectPlane(bm, location = Vector((0, 0, length/2)))
lg = selectPlane(bm, location = Vector((0, 0, -length/2)))
es = [edge for edge in go if all([vert in ug for vert in edge.verts])]
vs = list(set([vert for edge in es for vert in edge.verts]))
print('#'*5)
print(go)
print(es)
ge = bmesh.ops.bevel(bm, geom = vs, # list(set([vert for edge in es for vert in edge.verts])),
offset = 2)
print('>'*5)
print(ge)
bm.to_mesh(me)
bm.free()
me.update()
bpy.context.scene.objects.link(ob)
The selectCylinder
and selectPlane
methods are there to select the appropriate vertices and edges, but for the rest it's just bmesh operations.