8
$\begingroup$

I am using bpy.ops.object.convert(target='MESH', keep_original= False) in a python function in blender to convert metaballs to a mesh. The script works fine when run from the text editor. However, the goal is to add the function to the render events via bpy.app.handlers.render_pre.append() and bpy.app.handlers.render_post.append()

When the function using bpy.ops.object.convert is used in the handler, a polling error occurs. The typical recommendation is to either use overrides or low-level functions to eliminate the polling/context error. I would like to use low-level functions.

A code snippet in the Blender 2.75a low-level API for bpy.ops.object.convert(target='MESH', keep_original= False), where the selected object is a meatball, would be appreciated.

$\endgroup$

3 Answers 3

10
$\begingroup$

The to_mesh method

import bpy

context = bpy.context
scene = context.scene

mball = bpy.data.objects.get("Mball")

if mball:
    me = mball.to_mesh(scene, False, 'PREVIEW')

    # add an object
    o = bpy.data.objects.new("MBallMesh", me)
    scene.objects.link(o)
    o.matrix_world = mball.matrix_world

    # not keep original
    scene.objects.unlink(mball)
$\endgroup$
2
3
$\begingroup$

I had the similar problem. And to_mesh did not help me, it still didn't work. I imported some curves and then tried to convert them to mesh and exception related to incorrect context occurred. After short investigation I discover that correct context for convert function means existence not-None active_object and not-None selected_object in bpy.context. So the following code should work for conversion from/to mesh:

obj = D.objects[0] # the sample
bpy.context.scene.objects.active = obj
obj.select = True
bpy.ops.object.convert.poll() # should return True now
$\endgroup$
2
  • $\begingroup$ sorry , yourbpy.context.scene.objects.active = obj will occur bpy_prop_collection: attribute "active" not found ,maybe it is the version issue $\endgroup$
    – Super-ilad
    Mar 19, 2020 at 1:25
  • 2
    $\begingroup$ Yes it is a version issue. See date of answer. blender.stackexchange.com/questions/126577/… ob.select_set(True) replaces ob.select $\endgroup$
    – batFINGER
    Mar 19, 2020 at 2:41
1
$\begingroup$

I wanted to add that if you create the metaballs programmatically as in

metaball = bpy.data.metaballs.new('MetaBall')
obj = bpy.data.objects.new('MetaBallObject', metaball)
bpy.context.scene.objects.link(obj)

element = metaball.elements.new()
element.co = (0, 0, 0)
element.radius = 1.0

you need to add bpy.context.scene.update() after you created the metaballs. Then you can

mesh = obj.to_mesh(bpy.context.scene, False, 'PREVIEW')
new_obj = bpy.data.objects.new('MetaBallMeshObject', mesh)
bpy.context.scene.objects.link(new_obj)

otherwise you won't have any geometry.

$\endgroup$
1
  • 1
    $\begingroup$ This creates an empty object. Do you know an updated version for 2.80 or 2.79b? $\endgroup$
    – yarun can
    Mar 13, 2019 at 18:38

You must log in to answer this question.

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