Help with returning whether or not something has a modifier or is of a mesh type?

The function of the script is to allow all selected objects (that contain a mesh) to be given a subsurf modifier when the script is executed, if the script is executed again (aka the hotkey I will give it later on is pressed) it will ask if the object already has a subsurf modifier and then increase it’s view and render levels of subdivision instead of adding another subsurf modifier to it. Further, the script will increase the multires modifier subdivisions when executed if an object already has a multires modifier on it.

HERE’S WHAT’S WORKING:
So the script works fine if I take the multires modifier bit out of the equation. I can select one or multiple objects, execute the script to give them all subsurf and smooth shading and then keep wailing on the hotkey to increase the levels of subdivision. It works as is expected with the multires modifier also but only on very low poly count objects such as a cube. The script will cause Blender to crash if using it on say a UV sphere or a Monkey head. The script is pretty ugly, as I’m new to Python I’ve been frankensteining this code together. I imagine the crashing is caused due to the fact I’m adding a subsurf modifier to an object with a multires modifier and then deleting it every damn time the key is pressed but the ways I thought I could get it to work using if else cases etc… haven’t worked.

HERE’S WHAT I ACTUALLY NEED:
• First, I need to know how to make an exception which will ask whether or not the objects selected contain a mesh before proceeding with any of the script’s functions. (So the script doesn’t try to give a modifier to an empty, light, or armature or something and cause an error if the user accidently taps the hotkey while one of those are selected.)

• Second, a better way of getting the code to ask if each selected object has a multires modifier on it so it knows not to add a subsurf modifier to objects that already have a multires modifier. Like I said, the code’s pretty ugly and may need some major reworking. I’m trying to learn as much as I can. Any help would be great. Thanks.

import bpy

scene = bpy.context.scene
selected = bpy.context.selected_objects
object = bpy.ops.object


for obj in selected:
    scene.objects.active = obj
    
    try:
        bpy.context.object.modifiers["Subsurf"].levels += 1
        bpy.context.object.modifiers["Subsurf"].render_levels += 1
    except:
        bpy.ops.object.modifier_add(type='SUBSURF')
        bpy.context.object.modifiers["Subsurf"].levels = 1
        bpy.context.object.modifiers["Subsurf"].render_levels = 1
        bpy.ops.object.shade_smooth()
        bpy.ops.object.multires_subdivide(modifier="Multires")


for mod in obj.modifiers:
    if mod.type == "MULTIRES" and "SUBSURF":
        bpy.ops.object.modifier_remove(modifier="Subsurf")

For testing if an Object has a Mesh attached you can do this:


if isinstance(obj.data, bpy.types.Mesh):
  # Do stuff if this is a mesh

Or if you just want to skip non-Mesh objects


# Assumes you are inside a loop that is iterating all
# the selected Objects
if not isinstance(obj.data, bpy.types.Mesh):
  continue

Likewise, you can check for the presence of a multires modifier and then stop processing it.


multires = len([mod for mod in obj.modifiers if mod.type == 'MULTIRES'])
if multires:
  continue

You can remove this line:

 object = bpy.ops.object

In your for-loop, you can test the object (obj) like:

 if (obj.type == 'MESH' and
        'MULTIRES' not in (mod.type for mod in obj.modifiers)):
    # ...

@kastoria: isinstance() is discouraged for object type checking. To check for presence of a multires modifier, there’s no need to create a list and count how many there are. My generator expression stops checking after the first multires modifier, we don’t need to know how many there are.

Kastoria your multires solution was simple to implement and worked straight away, likewise CoDEmanX your mesh checking solution seemed to do the trick. Not sure if it was just my incompetence that I needed pieces from both solutions to get this to work properly, but I could care less because now it does what I want. My code now meets all requirements and does not crash or slow down Blender. It’s nice to be sculpting a face, realize I’m running out of geometry on a nose and just tap a button for more lol. Thanks very much! Here’s the final code:

import bpy
scene = bpy.context.scene
selected = bpy.context.selected_objects

for obj in selected:
scene.objects.active = obj

if (obj.type == 'MESH' and 'MULTIRES' not in (mod.type for mod in obj.modifiers)):

    try:
        bpy.context.object.modifiers["Subsurf"].levels += 1
        bpy.context.object.modifiers["Subsurf"].render_levels += 1
    except:
        bpy.ops.object.modifier_add(type='SUBSURF')
        bpy.context.object.modifiers["Subsurf"].levels = 1
        bpy.context.object.modifiers["Subsurf"].render_levels = 1
        bpy.ops.object.shade_smooth()
        
multires = len([mod for mod in obj.modifiers if mod.type == 'MULTIRES']) 
if multires:
    bpy.ops.object.shade_smooth()
    bpy.ops.object.multires_subdivide(modifier="Multires")