Toggle Subdivision Surface Modifier for all Objects

Hi,

Is anyone aware of a script that toggles the Visibility of the Subdivision Surface Modifiers for all Objects in the Scene?

In the Display Tools Addon is a script to toggle the Visibility for the active object but not for all at the same time unfortunately.
The Display Tools Script looks like this:

#Display Modifiers Viewport ondef modifiers_viewport_on(context):
    selection = bpy.context.selected_objects 
    
    if not(selection):    
        for obj in bpy.data.objects:        
            for mod in obj.modifiers:
                mod.show_viewport = True
    else:
        for obj in selection:        
            for mod in obj.modifiers:
                mod.show_viewport = True
        
class DisplayModifiersViewportOn(bpy.types.Operator):
    '''Display modifiers in viewport'''
    bl_idname = "view3d.display_modifiers_viewport_on"
    bl_label = "On"


    @classmethod
    def poll(cls, context):
        return True


    def execute(self, context):
        modifiers_viewport_on(context)
        return {'FINISHED'}
    
#Display Modifiers Viewport off
def modifiers_viewport_off(context):
    selection = bpy.context.selected_objects 
    
    if not(selection):    
        for obj in bpy.data.objects:        
            for mod in obj.modifiers:
                mod.show_viewport = False
    else:
        for obj in selection:        
            for mod in obj.modifiers:
                mod.show_viewport = False


class DisplayModifiersViewportOff(bpy.types.Operator):
    '''Hide modifiers in viewport'''
    bl_idname = "view3d.display_modifiers_viewport_off"
    bl_label = "Off"


    @classmethod
    def poll(cls, context):
        return True


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

Cheers Christian

Just found a toggle that works for selected objects but only in object mode.
It would be nice to have this script work in edit mode as well and make it work for all objects in the scene.

def ss_optimal():    sel = bpy.context.selected_objects
    act_obj = bpy.context.active_object
    if act_obj.type == 'MESH' or act_obj.type == 'CURVE' or act_obj.type == 'FONT' or act_obj.type == 'META' or act_obj.type == 'SURFACE':            
        for mod in act_obj.modifiers:
            if mod.type == 'SUBSURF':                    
                optimal = not(mod.show_only_control_edges)
                break
        else: optimal = False
        for obj in sel:
            if obj.type == 'MESH' or obj.type == 'CURVE' or obj.type == 'FONT' or obj.type == 'META' or obj.type == 'SURFACE':            
                for mod in obj.modifiers:
                    if mod.type == 'SUBSURF':
                        mod.show_only_control_edges = optimal


class OBJECT_OT_ss_optimal(bpy.types.Operator):
 
    bl_idname = "object.ss_optimal"
    bl_label = "Toggle Optimal Display"
    bl_options = {'REGISTER'} 
        
    
    def execute(self, context):                      
        ss_optimal() 
        return {'FINISHED'}

Do you want to use this within a game, or just while you are modeling or animating? If it is not within a game environment, just go into the scene tab, scroll down to the bottom, check simplify and turn the subdivisions to 0.

@ randy:
thanks for the script ^^ it works really great but i’d rather be able to toggle the modifier instead of setting it to a certain subd level.
because then the objects could have different subd levels and i could still toggle the modifier

@harley
i’d like to use it for modeling because sometimes its easier to see certain things without subd’s

i tried something like this now but it doesn’t work of course :wink:

bl_info = {    "name": "GlobalSubDToggle",
    "location": "File/UserPrefs/Input Add new key in 3D View 'object.GlobalSubDToggle'",  
    "description": "GlobalSubDToggle",  
    "category": "Mesh",
}
 
import bpy
 
class zzz(bpy.types.Operator):
    """GlobalSubDToggle"""                          # blender will use this as a tooltip for menu items and buttons.
    bl_idname = "object.GlobalSubDToggle"           # unique identifier for buttons and menu items to reference.
    bl_label = "GlobalSubDToggle"                   # display name in the interface.
    bl_options = {'REGISTER', 'UNDO'} 
 
    def execute(self, context):             # execute() is called by blender when running the operator.
 
        # The original script
            if obj.type == 'MESH' or obj.type == 'CURVE' or obj.type == 'FONT' or obj.type == 'META' or obj.type == 'SURFACE':            
                for mod in obj.modifiers:
                    if mod.type == 'SUBSURF':                    
                        optimal = not(mod.show_only_control_edges)
                        break
                else: optimal = False
                for obj in sel:
                    if obj.type == 'MESH' or obj.type == 'CURVE' or obj.type == 'FONT' or obj.type == 'META' or obj.type == 'SURFACE':            
                        for mod in obj.modifiers:
                            if mod.type == 'SUBSURF':
                                mod.show_only_control_edges = optimal


            return {'FINISHED'}                 # this lets blender know the operator finished successfully.
 
def register():
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)
    
# This allows you to run the script directly from blenders text editor
# to test the addon without having to install it.
if __name__ == "__main__":
    register()

okay, i found another script that almost works perfectly except that i have to select all objects in the scene first

bl_info = {    "name": "Subsurf Viewport Toggle",
    "description": "Adds toggle button in property region for subsurf viewport visibility",
    "author": "Aditia A. Pratama, Greg Zaal",
    "version": (0, 2),
    "blender": (2, 66, 1),
    "location": "3D View > Property Region (N-key)",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"}


import bpy


class SubsurfToggle(bpy.types.Operator):
    'Toggle subsurf visibility'
    bl_idname='subsurf.toggle'
    bl_label='Subsurf Toggle'
       
        
    
    def execute(self,context):
        state = bpy.context.active_object.modifiers['Subsurf'].show_viewport
        for e in bpy.context.selected_objects:
            try:
                if state==False:
                    e.modifiers['Subsurf'].show_viewport = True
                else:
                    e.modifiers['Subsurf'].show_viewport = False
            except KeyError:
                print ("No subsurf on "+e.name+" or it is not named Subsurf")
        return {'FINISHED'}
            
class Visibility(bpy.types.Panel):
    bl_label = "Subsurf Viewport"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
       
    def draw (self, context):
        layout=self.layout
                                                   
        col=layout.column()
        col.operator("subsurf.toggle",  text="On/Off", icon="MOD_SUBSURF")
        
        col.separator()            
        
        view = context.scene.render
          
        col.prop(view, "use_simplify", text="Simplify")
        sub = col.column()
        sub.active = view.use_simplify
        sub.prop(view, "simplify_subdivision", text="Subdivision")


def register():
   bpy.utils.register_module(__name__)
   
def unregister():
    bpy.utils.unregister_module(__name__)
 
if __name__ == "__main__":
    register()



yes, seems like he is looking for almost the same thing.
what i’d really like to have is that this button toggles the visibility of the subd modifier for all subtools in the scene though.
thanks for looking into it randy :slight_smile:

Sorry I’ve been away…

Try this:
http://www.pasteall.org/52505/python

It will work as-is and should do what I think you want. I still need to add in a few bits of text (tooltips, etc) and take a look at some of the code (maybe better way to do parts of it), but it works well for now.

Over the next few days I’ll look into what I mentioned above, in the mean time, test it and tell me if you need anything else from the script. Then when it’s done, I release the new version properly…

Randy

Depending on what you’re using it for…

Why not try Object Properties > Simplify?

You can set the number of subdivisions for all objects in a scene. Works for simplifying and complexifying (sic) as well.

hi randy.

if i click the eye button nothing happens.
or is it supposed to work differently?

cheers christian

I thought the same thing Ron. Setting the subdivision surface to 0 has the same visual effect as turning off the “eye” icon.


import bpy


scene = bpy.data.scenes[0]


for ob in scene.objects:
    if len(ob.modifiers) > 0:
        for m in ob.modifiers:
            if m.type == 'SUBSURF':
                # NOTE: change show flag to which ever you want. (see doc URL)
                if m.show_viewport:
                    m.show_viewport = False
                else:
                    m.show_viewport = True

http://www.blender.org/documentation/blender_python_api_2_70_release/bpy.types.Modifier.html?highlight=modifier

i’ve got no clue where to find that mysterious simplyfy button but the script works perfectly :slight_smile:
thanks for the help guys (ron as well ;))

Did you then click on the ‘Apply Subsurf Settings’ button?

Perhaps I need to change the UI of the script to make it more appearent that you need to click that button as well…

My script does what Atom’s script does, and more, but his lacks a UI…

Randy

yes i did but then the settings got applied (view 1 / render 2)
but the short scipt by atom does exactly what i need.
still many thanks of course!!

Sorry; should have told you. Go to the Scene properties tab and you’ll find it. Default position is second from the bottom.

ah, there it is :slight_smile:
thanks again everyone for the help!

Oooppss I forgot about that detail. I guess it’s senseless at this point, as you have what you need now, but I’ve fixed my script to not change the levels if desired. Here’s a screenshot:


The code is here: http://www.pasteall.org/52605/python

still needs a couple of tool tips and stuff, but it works.

Randy

Does anyone know how to change this script to toggle ALL subsurf modifiers for the active object?
currently it only works for one modifier :confused:

bl_info = {    "name": "Subsurf Viewport Toggle",
    "description": "Adds toggle button in property region for subsurf viewport visibility",
    "author": "Aditia A. Pratama, Greg Zaal",
    "version": (0, 2),
    "blender": (2, 66, 1),
    "location": "3D View > Property Region (N-key)",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"}


import bpy


class SubsurfToggle(bpy.types.Operator):
    'Toggle subsurf visibility'
    bl_idname='subsurf.toggle'
    bl_label='Subsurf Toggle'
       
        
    
    def execute(self,context):
        state = bpy.context.active_object.modifiers['Subsurf'].show_viewport
        for e in bpy.context.selected_objects:
            try:
                if state==False:
                    e.modifiers['Subsurf'].show_viewport = True
                else:
                    e.modifiers['Subsurf'].show_viewport = False
            except KeyError:
                print ("No subsurf on "+e.name+" or it is not named Subsurf")
        return {'FINISHED'}
            
class Visibility(bpy.types.Panel):
    bl_label = "Subsurf Viewport"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
       
    def draw (self, context):
        layout=self.layout
                                                   
        col=layout.column()
        col.operator("subsurf.toggle",  text="On/Off", icon="MOD_SUBSURF")
        
        col.separator()            
        
        view = context.scene.render
          
        col.prop(view, "use_simplify", text="Simplify")
        sub = col.column()
        sub.active = view.use_simplify
        sub.prop(view, "simplify_subdivision", text="Subdivision")


def register():
   bpy.utils.register_module(__name__)
   
def unregister():
    bpy.utils.unregister_module(__name__)
 
if __name__ == "__main__":
    register()



anyone? :slight_smile: