6
$\begingroup$

I've just started trying to write a script to speed up my workflow in Blender, but I'm having trouble interpreting the Python commands that show up when you hover the cursor over a button.

For example, I want to toggle the "Limit Selection to Visible" button in Edit Mode, but keep getting errors. If I click the button, the log/output window shows:

bpy.context.space_data.use_occlude_geometry = True

But if I type this into the console, it gives me an error (see screenshot).

enter image description here

Looking at the Blender API provides some information, but not enough for someone with my limited amount of scripting experience.

Just taking the python line from the log window and pasting that into the console works for some things, but not others. Any ideas why?

Many thanks in advance.

$\endgroup$
6
$\begingroup$

Operators and properties are often context sensitive. It means they need to be executed from specific context (screen area). Your example needs to be run from View_3D context, so it cannot run from the Python Console.

Luckily, there is a way to access different screen areas and get their types and properties. In your case use_occlude_geometry is a property of SpaceView3D, thus only accessible from that space:

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        if context.active_object.mode == 'EDIT':
            area.spaces[0].use_occlude_geometry = True

You can paste and run the above example in Python Console as a multi-line command or run it from the Text Editor as usual.


However, best practice for Addons is writing your own Operator to match the context:

import bpy

class OccludeGeometryToggle(bpy.types.Operator):
    """Toggle Occlude Geometry Option in 3D View"""
    bl_idname = "view3d.toggle_occlude_geometry"
    bl_label = "Occlude Geometry Toggle"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return context.active_object.mode == 'EDIT'

    def execute(self, context):
        context.space_data.use_occlude_geometry = \
            not context.space_data.use_occlude_geometry
        return {'FINISHED'}

def register():
    bpy.utils.register_class(OccludeGeometryToggle)

def unregister():
    bpy.utils.unregister_class(OccludeGeometryToggle)

if __name__ == "__main__":
    register()

Once the operator is registered, press Space in Edit Mode (since the poll() method checks whether the active object is in the correct mode) and type "Occlude Geometry Tog...".

$\endgroup$
  • 1
    $\begingroup$ Very helpful Miki, thank you. I had no idea about the context-specific bit. Makes a lot more sense now. $\endgroup$ – TSemp Jan 3 '18 at 2:44
  • $\begingroup$ It is also possible to override the context used by any existing operator. $\endgroup$ – sambler Jan 5 '18 at 22:48
-1
$\begingroup$

A good introduction into Python scripting for Blender is given in the ebook "The Blender Python API, precision 3D modelling and add-on development" by Chris Conlan, Apress, ISBN-13 978-1-4842-2802-9

$\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.