[Bf-committers] ops functions, parameters, and returns

Charles Wardlaw cwardlaw at marchentertainment.com
Sun Mar 21 18:34:36 CET 2010

Hi again Campbell,

> Operators are tools and not api functions, the idea is that operators
> manipulate the context so python can be used to create macro's
> What an operator would return isnt always clear, for instance if you
> link in objects, would it contain a list of every object, scene and
> text blocked linked??

Perhaps.  Or if you link in a scene, then the scene would be returned by itself and would be traversable like bpy.data.scenes.

I don't know that linking is a good example-- linking in / appending objects of different types should, I think, have different returns.  Linking in a group for character rig linking, for instance, should return a list like the following:

[ 'FINISHED', group, armature1, armature2, ... armatureN, mesh1, mesh2, ... meshN ]

That way scripts could go in and add proxies automatically to all armature objects that have been linked in.

I think that returns should be opened up to discussion, to see how people would expect things to work.  Linking aside, I would like to see any add() function return a handle for the added data. So that something like:

ob = bpy.object.addObject(name="Foo")
ob.data = bpy.armature.addArmature(name="Bar")

would work.  I'd get rid of all the 'FINISHED' returns since it's just as easy to check for a NoneType return, or an empty tuple.

> however in some cases its really obvious that you would want to run an
> operator and get a return value, in these cases we should probably
> make RNA function calls for these operators (internally they can use
> the same C functions).
> There are also quite a few cases where the operators should be removed
> and only have API calls only. Things like "Move Modifier Up" IMHO are
> not useful as operators.
> But then we need to see how rna function calls can be done from the UI :S.

Heh that's a question beyond me. :)  Although maybe it'd be nice to provide a function that registers a new operator based on a function and some arguments -- something similar to how the partial() stuff works in Python.

The main thing is to make the API easy and intuitive for real coders, but also simple enough to understand for more casual users so that they can copy and paste from the script log to make their macros.

At the moment I can copy and paste from the script log, but nothing in the commands there show how to rename objects or how to get at data.  Something as simple as modifying this call:

bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(-0.586031, -0.0568311, 7.21605), rotation=(0, 0, 0), layer=(False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False))

to something more readable, stripping out default value passings:

bpy.ops.mesh.primitive_cube_add(name="MyMesh", view_align=False, enter_editmode=False, location=(-0.586031, -0.0568311, 7.21605))

would make life easier on casual scripters.  Now they know exactly how to change the name just by looking at the code, and they don't get overwhelmed looking at a really long list of things that are irrelevant. Incidentally if a location is passed, operators should bypass the 3D cursor. Or perhaps the functions should have a standard way of specifying at-cursor placements:

bpy.ops.mesh.primitive_cube_add(location=(-0.586031, -0.0568311, 7.21605)) # ignore the cursor
bpy.ops.mesh.primitive_cube_add(placement ='CURSOR') # place at cursor, ignore location kwarg

In this case the default could be placement='WORLD'.  Then when commands show in the script log, users would see that the location type is being modified since the UI always places things at the cursor:

bpy.ops.mesh.primitive_cube_add(name="MyMesh", view_align=False, enter_editmode=False, placement='CURSOR')

Sure, you want users to read the manual and learn how to search for the functions they want, but there are users out there who will surprise you with what they can do with simple copy and pastes.

> We could try to make operators behave more like API functions but this
> is not a small task and not what operators were originally designed to
> do. so I think its out of the scope of 2.5 tool refactor.

And maybe that's not the way to go.  I mean, it's easy enough to have functions with different kinds of returns, but I understand that it would go against the original design.

At the same time, there could be easier methods for common tasks.  What those functions need to be are anyone's guess at the moment; I'll keep notes as I go, as should all python coders working with the Alphas.

> Different developers wrote operators, mostly to get blender working
> again and not having read how all other operators work. When you try
> use operators from python you end up finding many problems like this.

Ahh okay, no worries.  Moving forwards it would be nice to make names agree with each other, too.  Things like bpy.ops.mesh.primitive_circle_add bpy.ops.armature.bone_primitive_add should match.  (Although I think that the names should be shortened to addCircle and addBone respectively.)  On a personal note with regards to naming, it'd be *awesome* if the underscores were thrown out for camelCase.

> for data creation and removal though we accept that operators are not
> ideal and there are existing functions for this
> # Example
> arm = bpy.data.armatures.new("MyArmature")
> obj = bpy.data.objects.new("MyObject", arm)
> scene = bpy.context.scene
> scene.objects.link(obj)

Ahh cool, thanks for that.

One last question: is there any particular reason why at this point objects require edit mode on the script side?  I know there's an update that's triggered on change from edit to object modes, but to me it seems like extra steps (not unlike how you have to leave edit mode to apply a modifier -- if it's smart enough to tell you that, it should be smart enough to toggle edit mode for you ^_^).

~ C

PS: Thanks for fixing the help() function.

More information about the Bf-committers mailing list