Check if object is selected and it is a Mesh (or in Edit Mode)

I have a working addon. Now I am adding error traps.

I have some buttons/functions that generate an error when nothing is selected.

All I need to do is, check and see if any MESH objects are selected ( or in edit mode) or its not selected at all.
If not, I want to either catch the error and display a message box panel or do nothing.

This is what I have… but I can’t seem to get it to work.

class SAVT_OT_Operator(bpy.types.Operator):
    bl_idname = "viewed3d.select_all_mesh"
    bl_label = "Select All Mesh"
    bl_description = "Select All Mesh"
   current_mode = bpy.context.object.mode

   if current_mode == 'EDIT':
       def execute(self, context):
           return {'FINISHED'}

Any help would be appreciated.

You should use the poll method for checking if an operator is allowed to run.

Here’s a link to nearby documentation:

Here’s your example if I understood it right

    def poll(cls, context):
        # Checks to see if there's any active mesh object (selected or in edit mode)
        active_object = context.active_object
        return active_object is not None and active_object.type == 'MESH' and (context.mode == 'EDIT_MESH' or active_object.select_get())

Okay… this is a great start. Thanks

Also, does this work for the entire plugin or each individual command button.
I have 5+ commands per py file. (i have 3 py files of commands)

If this is only used by the py file only, hoe does it know which command I am checking?

Okay… I figured out for myself… I need one for each operator I want to error trap.

Thanks for the help
I am new to python. Been a VB.NET coder for 15 years.
This is easier, I just don’t know Blenders API yet.

Alright… next issue.

Using this code

    def poll(cls, context):
        active_object = context.active_object
        return active_object is not None  
        #and active_object.type == 'MESH' and (context.mode == 'EDIT_MESH')

Starting Blender, button is inactive (disabled)
Add Object, select object… button becomes enabled (active)
I can execute operator.

But, if I click off or deselect all objects
The button stays enabled. It should be disabled.

This is just supposed to evaluate if object is only selected. Being in EDIT_MESH doesn’t matter in this case.

Iam doing this on the Shade Smooth or Flat, and the toggle button (same as tab key)

Okay. come to realize that this is an expected behavior from the toggle/Shade buttons.

Now, I need to figure how to detect if object is selected and a curve, but not in edit mode.

Next Q.

I have two buttons - Curve to Mesh and Mesh to curve.
They both disabled/enable like they should.

However, if I click off and click one of the buttons i get an error.
I guess because the object is not actually selected.

How do I make sure the object is selected to avoid this error?


class CNVC_OT_Operator(bpy.types.Operator):
    bl_idname = "viewed3d.convert_tocurve"
    bl_label = "Convert to Curve"
    bl_description = "Convert to Curve"

    def poll(cls, context):
        active_object = context.active_object
        return active_object is not None and active_object.type == 'CURVE' 
       #and (context.mode == 'EDIT_MESH')

    def execute(self, context):
        return {'FINISHED'}


Great… figured it out.

    def poll(cls, context):
        obj = context.active_object
        objs = context.selected_objects
        if len(objs) == 0: return False
        #if obj.type == 'MESH': return True
        if obj.type == 'CURVE': return True
        return False

Now unto my next issue (if there is one)

Okay, I am down to my last issue.

For my Mesh to Curve button.
I can detect that it is a mesh object fine

But, you cannot convert a cube/sphere etc to a curve.
You have to duplicate and edge, separate it from the object then you can convert it to a curve

So, How I do I detect that the mesh object is a cube/sphere etc and return false on the poll?
Basically, How do I know that the object is a 3d obj or just a line edge (like a circle or plane) - aka single line with no faces)


Exactly, Blender is behaving as it should, context.mode is still Edit and you have not unset the Active Object, you have only deselected it, not the same thing…

Your poll should be something like:

if all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"]):

This checks that the object exists, object is mesh type and object is in Edit mode - this is different from context.mode being “EDIT”.

You could try: faces = bmesh.faces where bmesh is the Bmesh from the object, then count these, if the count is not 0 you have faces in the mesh.


Also look at object.select_get() function, it tells you if an object is selected…

1 Like