How to check that the selected object is a mesh?

Newbie here. I would like to test the active selected object to see if it is a mesh before moving on. How to do this an not throw an error if it is not? TIA.

This is a bit of code I use a lot…

objs = bpy.data.objects

i = 0
j = len(objs)

for obj in objs:
if (obj.type != “MESH”):
continue

#mesh = obj.data
#vcount = len(mesh.vertices)
#ecount = len(mesh.edges)
#pcount = len(mesh.polygons)

I seem to get an error when I run it.

Here’s the code:

def execute(self, context):       

        objs = bpy.data.objects

        i = 0
        j = len(objs)

        for obj in objs:
            if (obj.type == 'MESH'):
                obj = context.active_object
                bpy.ops.uv.smart_project(angle_limit=30, island_margin=0.06)

        return {'FINISHED'}

It throws an error when nothing is selected.

I think this may be what I’m asking for, but I’m still throwing an error each time I press a button that executes…

@classmethod
    def poll(cls, context):
        selected = context.selected_objects
        object = context.active_object
        if object is None: return False
        if object.mode == "OBJECT" and all(obj.type == "MESH" for obj in selected):
            return True 

In blender an object can be active and not selected at the same time

Most likely this is best:

@classmethod
    def poll(cls, context):
        our_case = False
        selected = context.selected_objects
        object = context.active_object
        if object.mode == "OBJECT" and all("MESH" in obj.type for obj in selected) and "MESH" in object.type:
            our_case = True
        return our_case

With nothing selected, this still prints the last active object: Why?

@classmethod
    def poll(cls, context):
        our_case = False
        selected = context.selected_objects
        object = context.active_object
        if object.mode == "OBJECT" and all("MESH" in obj.type for obj in selected) and "MESH" in object.type:
            our_case = True
        return our_case

    def execute(self, context):                   # execute() is called when running the operator.
      
        obj = context.active_object
        print(obj.name)

        return {'FINISHED'}

It turns out that there is always an active object in the scene. Even if nothing is selected.
You can simply ignore the active object or work only with selected ones.

So, I’m trying to unwrap the active selected object. If there is no object selected, then the

bpy.ops.uv.smart_project(angle_limit=30, island_margin=0.06)

fails with an error.

This should be simple. I just want to make sure the object is a mesh before I call

bpy.ops.uv.smart_project(angle_limit=30, island_margin=0.06)

What am I missing?

Check that the object was both selected and active.
Or, you can directly select the active object in the script before calling: bpy.ops.uv.smart_project(angle_limit=30, island_margin=0.06)

And that is the topic of this post

@classmethod
    def poll(cls, context):
        our_case = False
        selected = context.selected_objects
        active_object = context.active_object
        if active_object.mode == "OBJECT" and active_object in selected and all("MESH" in obj.type for obj in selected):
            our_case = True
        return our_case

    def execute(self, context):                   # execute() is called when running the operator.
      
        obj = context.active_object
        print(obj.name)

        return {'FINISHED'}

so if the object is active but not selected, the script will not work

That is, this script is the answer to the topic. Checking whether the active object is selected, whether all the selected objects are MESH and we are in object mode.

Thanks for your help.

When I added the print function to your script, then ran it (as part of a button), then deselected everything in the scene (menu Select>None), it still returned TRUE.

 @classmethod
    def poll(cls, context):
        our_case = False
        selected = context.selected_objects
        object = context.active_object
        if object.mode == "OBJECT" and all("MESH" in obj.type for obj in selected) and "MESH" in object.type:
            our_case = True
        print(our_case)
        return our_case

I wanted to show this script that if no object is selected then the active object remains in the scene and it can be “MESH” or not.

Try the last script. It falls under your task.

I got it to work using the len(context.selected.objects) :slight_smile:

@classmethod
    def poll(cls, context):
        obj = context.active_object
        objs = context.selected_objects
        #print("num selected: " + str(len(objs)))
        #print("active: " + obj.name)
        if len(objs) == 0: return False
        if obj.type == 'MESH': return True
        return False
1 Like

Yeah, the lack of an active object is the issue, it will read through the objects, but it isn’t classed as active when processing. You’d need to make the ‘obj’ the active object first if the action only works on an active object.