Hacker News new | ask | show | jobs
by ahaferburg 1844 days ago
> That is pretty much how it works in Blender. All the buttons and properties in the UI are accessible through the Python API.

Yes, it seems that way, and I was hopeful at first. But then I tried to use it.

In Maya, you can just copy paste a command from the command window, and it will work.

When you do that in Blender, it will probably give you an unspecific error message like "not possible in the current context". Because you need to manually switch Blender e. g. from Object mode to Edit mode (Faces), and your command only works in that context. So you develop a script that works initially, but later you find that it only works if Blender is in a certain state. That state is nowhere documented, you have to guess what it wants.

While Maya uses arguments to commands, Blender uses the equivalent of global variables.

1 comments

That is specific to operators (Blender's implementation of buttons) since they are closely tied to their use in the UI. They may expect a specific context which is checked by the operator's `poll()` function. The namespace the operator is in should hint at what that context is, e.g. `bpy.ops.mesh` works with mesh data which is accessed in edit mode. Other operator namespaces directly reference area types, those need to be executed within that area. For instance operators `bpy.ops.view3d` will most likely require to be executed in an area of type `VIEW3D`. That is a requirement because the data that the operator needs is otherwise not accessible. I understand that the approach you are used to in Maya is more convenient.

When you have issues with calling an operator due to a wrong context, there are different ways to approach the problem:

1. Figure out what the necessary context is and switch modes, areas, etc. to match the requirements.

2. Figure out what the necessary context is and override the context.

3. Avoid using operators.

Approach 1.) could be accomplished by checking where the operator is originally used in Blender. For instance the `bpy.ops.mesh.remove_doubles()` is available in edit mode in the Mesh > Clean up menu. Thus edit mode is required to run the operator. This will work for many operators because they don't have very complicated requirements.

Approach 2.) is for when you must use an operator, it requires a complicated context and you know about Blender's internals. You can look at the operator's (poll) implementation and construct a specific context that is passed into the operator [0]. This should only be used if there is no better alternative.

Approach 3.) is preferable when you are working with mesh data. Instead of using regular operators you can use bmesh instead [1]. It doesn't require switching to edit mode or passing a context. It's usually the more efficient approach as well.

[0] https://docs.blender.org/api/current/bpy.ops.html#overriding...

[1] https://docs.blender.org/api/current/bmesh.html

The comment above is more of an explanation of how this currently works in Blender and how one can approach the aforementioned challenge.

I do agree that the Python API is often just a thin wrapper around the C/C++ code [0] and that the documentation of the required context for operators is a bit lacking for people who are not familiar with Blender's implementation. This is also acknowledged in the API docs [1]. However, I do think the API is quite usable and not particularly complicated to understand.

[0] https://docs.blender.org/api/current/info_gotcha.html

[1] https://docs.blender.org/api/current/info_gotcha.html#why-do...