Simple and maybe stupid question:
I was reading this lot of time, that
"you should avoid using
bpy.ops
, or "instead ofbpy.ops
, use this and that"...
So why is that? Is that buggy, or what?
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It only takes a minute to sign up.
Sign up to join this communityLots of bpy.ops
operators depend on the context (selected objects, active shape key index, etc.), therefore I think some are more suitable to be used interactively than in a script.
I'd use bpy.ops
judiciously rather than avoiding it wholesale. For example, I find creating constraint through a posebone's constraints.new
easier to read, and independent from context, compared to changing context then calling pose.constraint_add_with_targets
. But bpy.ops
can be indispensable for some tasks like vertex group manipulation and file operation even though it means temporarily messing with context.
For me, it really depends on what you're trying to do. Before resorting to bpy.ops.*
, see if the task can be accomplished in any other way. Using bpy.ops
operators may not always be best, but careful application can still result in readable code and smooth user interaction.
I'll just quote ideasman42:
When possible I would avoid using bpy.ops, These wrap tools in a way that relies on the context and dont have a good way to pass args and return results to scripts. If there is an alternative (as with bmesh), it's better integrated into python, and you don't have to worry about active object, modes, visible layers etc.
Avoiding bpy.ops
may boost performance of your scripts when manipulating lots of objects. See: Python performance with Blender operators
Apart from what's been said already, operators also create undo steps. This means that every time you execute an operator, the entire blend file is saved in memory. This is one of the reasons calling an operator is much slower than the corresponding alternative function calls.
This is also why it's a good idea to, when writing an operator, place the major part of the code into regular Python functions, and call those from the operator code. This allows others to import your module and call those functions as well, from their own code.
bpy.context.user_preferences.edit.undo_steps
to 0 and bpy.context.user_preferences.edit.use_global_undo
to False
?
$\endgroup$
bpy.ops.mesh.primitive_cube_add()
? Should I manually put vertices in the scene and then make polygons? My point is it looks like there is no official guideline on how people can avoid using bpy.ops
$\endgroup$
Scene.update()
once at the very end. $\endgroup$