3
$\begingroup$

In Blender, following this post, I notice that hovering over the Bevel Object dialogue box in the object properties for my curve object, I see the helpful python data for my circleObj object:

Python: Curve.bevel_object
bpy.data.curves[circleObj].bevel_object
  1. What is the first reference to - I cannot see Curve object referenced in the API
  2. When I search the Blender 2.76 API Wiki (or as far back as the site pages went before they redirect to a different blender page), for bpy.data.curves, there returns nothing.

I want to use python to create thin pipework for my vectors, and I'm not turning up any programmatic methods equivalent to the blender SE post referenced above. Anyone done this? I've tried this:

tor0refCirc = vecCircle("tor0refCirc", 6, 1, "NOTHING", 1000.0, 1000.0, 1000.0, 0.0, 0.0, 0.0, 19)
for circleName, circleObj in sorted(cAr.items()):
    circleObj.select = True
    bpy.ops.object.convert(target='CURVE', keep_original=False)
    bpy.data.curves[circleObj].bevel_object = tor0refCirc
    bpy.ops.object.mode_set(mode='EDIT', toggle=True)
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.mesh.remove_doubles()
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

where vecCircle is a function that just calls bpy.ops.mesh.primitive_circle_add to place a circle well out of the way of my scene to act as the diameter reference for my bevel.

$\endgroup$
  • $\begingroup$ vecCircle does that produce a Mesh object or Curve object, bevel_objects must be of type Curve, I see in your code only that you convert the items you are iterating over to a Curve so you can use the bevel feature, but don't see anywhere that the bevel object is converted to a curve too. $\endgroup$ – zeffii Oct 7 '15 at 8:36
  • $\begingroup$ bpy.ops.mesh.select_all(action='SELECT') doesn't work on a curve object either, because ops.mesh . My advice to you is to remove some operations in the loop until you understand how they work on their own. And write your scripts using a .blend with only placeholder shapes to experiment with. $\endgroup$ – zeffii Oct 7 '15 at 8:42
2
$\begingroup$

After your edit I have a few more thoughts. You can't use a Mesh object such as produced by the primitive_circle_add() as a bevel_object, it needs to be a curve. Either make a wrapper function for bpy.ops.curve.primitive_bezier_curve_add, or include a small convert statement inside your vecCircle function (shown below).

In your loop the call to bpy.ops.object.convert doesn't complete and that's where you should start investigation, subsequent lines can be ignored until then.

Preconvert to Curve before a loop


Here's a massively simplified version of what you're doing. This is to get an understanding of how to bevel an object via a script. For simplicity I iterate over Curves here to emphasize where the problem is not!

import bpy

def vecCircle(name, verts, obj_type='MESH'):
    bpy.ops.mesh.primitive_circle_add(vertices=verts)
    obj = bpy.context.active_object
    obj.name = name
    if obj_type == 'CURVE':
        bpy.ops.object.convert(target='CURVE', keep_original=False)
    return obj

tor0refCirc = vecCircle("tor0refCirc", 6, 'CURVE')

beziers = [o for o in bpy.data.objects if o.type == 'CURVE']

for circleObj in beziers:
    circleName = circleObj.name
    circleObj.data.bevel_object = tor0refCirc

turns this:
enter image description here

into this:
enter image description here

Convert to Curve during the loop


But if your original objects are meshes, they do need to be converted either on-mass before the loop, or during the loop.

import bpy

def vecCircle(name, verts, obj_type='MESH'):
    bpy.ops.mesh.primitive_circle_add(vertices=verts)
    obj = bpy.context.active_object
    obj.name = name
    if obj_type == 'CURVE':
        bpy.ops.object.convert(target='CURVE', keep_original=False)
    return obj

tor0refCirc = vecCircle("tor0refCirc", 6, 'CURVE')

# ensure no selected objects
bpy.ops.object.select_all(action='DESELECT')

pre_beziers = [o for o in bpy.data.objects if not (o.name == 'tor0refCirc')]

for circleObj in pre_beziers:
    circleName = circleObj.name
    circleObj.select = True
    bpy.context.scene.objects.active = circleObj   # << -- important
    bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
    bpy.ops.object.convert(target='CURVE', keep_original=False)    
    circleObj.data.bevel_object = tor0refCirc
    circleObj.select = False    

which turns Mesh into Curve before adding bevel_object:

enter image description here

like this ( you might want to increase resolution 6 vertices may be too coarse)

enter image description here

$\endgroup$
2
$\begingroup$

The problem is that you're trying to call the curve object's data from bpy.data using the object reference, instead of the object's name:

bpy.data.curves[circleObj].bevel_object = tor0refCirc

This probably triggers this kind of error:

TypeError: bpy_prop_collection[key]: invalid key, must be a string or an int, not Object

What you should do instead is use the object's name:

bpy.data.curves[ circleObj.name ].bevel_object = tor0refCirc

Or, access the curve data directly from the object itself:

circleObj.data.bevel_object = tor0refCirc

Also and unrelated, it seems that you're using various mesh operators after converting your meshes into curves (select_all, remove_doubles), which probably won't work or might even trigger context errors.

$\endgroup$

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.