Page MenuHome

Armature custom display tool.
Closed, ArchivedPublic

Description

bl_info = {
    "name": "Armature Custom Display",
    "author": "Ameen Vengara",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D >  Use shortcut keys E and ALT E ",
    "description": "Hide all armatures except the character's you are working on",
    "warning": "",
    "wiki_url": "",
    "category": "Tools"}


import bpy


class ArmatureDisplay(bpy.types.Operator):
       bl_idname = "object.armature_display_tool"  
       bl_label = "Hide unselected armature objects"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #If nothing is selected in the viewport
           if bpy.context.selected_objects == []:
               for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE':
                      #hide all armatures
                       ob.select = True
                       ob.hide = True
           else:
               
                       
              #hiding all armatures except the selected one/ character's
              for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE': 
                       
                       #Prevent the selected armature from hiding 
                       if ob == bpy.context.active_object:
                           ob.select = True
                           ob.hide = False
                       else:
                           #hiding all armatures
                           ob.select = True
                           ob.hide = True
                   else:
                       if ob.type == 'ARMATURE':
                           ob.hide = False
            # unhide selected object parent
           if bpy.context.active_object.parent:
               if bpy.context.active_object.parent.type == 'ARMATURE':
                   bpy.context.active_object.parent.hide = False  
                   bpy.context.active_object.parent.select = True
                   return {'FINISHED'}
           else:
               return {'FINISHED'}
           
class UnhideAllArmatures(bpy.types.Operator):
       bl_idname = "object.unhide_all_armatures"  
       bl_label = "unhide all armatures from the scene"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #Unhiding all armatures from scene
           for ob in bpy.context.scene.objects:
               if ob.type == 'ARMATURE':
                   ob.hide = False 
           return {'FINISHED'}        
               
 
def register():
    bpy.utils.register_class(ArmatureDisplay)
    bpy.utils.register_class(UnhideAllArmatures)
    
def unregister():
    bpy.utils.unregister_class(ArmatureDisplay)
    bpy.utils.unregister_class(UnhideAllArmatures)
        
if __name__ == "__main__":
    register()

    #bpy.ops.object.armature_display_tool()
    bpy.ops.object.unhide_all_armatures()

This script makes the animation workflow a lot easier. I made this recently. It works pretty well for me. I think this type of a tool is essential in Blender by default. Please go through my demo video. It is very short in length.

https://youtu.be/rtpdNtdB-lY

Details

Type
Patch

Event Timeline

ameen vengara (ameen_vga) updated the task description. (Show Details)
ameen vengara (ameen_vga) raised the priority of this task from to Needs Triage by Developer.
ameen vengara (ameen_vga) set Type to Patch.
Campbell Barton (campbellbarton) triaged this task as Needs Information from User priority.May 15 2015, 12:40 PM

Hi, this seems generally useful. but have a request:

Instead of just hiding unselected armatures, this could hide armatures not connected to selected objects.

So if you have 3 characters selected, (for example), it would ensure their rigs are visible. (by checking the modifiers).

I think for inclusion in Blender it would be good to add support in the patch for this.


This could be extended to other control objects (Empty constraints, curve deformers, lattices etc... ) so you could hide any control objects for unselected data.

bl_info = {
    "name": "Armature Custom Display",
    "author": "Ameen Vengara",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D >  Hide unselected armatures > Assign a shortCut 'E' ",
    "description": "Hide all armatures except the character's you are working on",
    "warning": "",
    "wiki_url": "",
    "category": "Tools"}


import bpy


class ArmatureDisplay(bpy.types.Operator):
       bl_idname = "object.armature_display_tool"  
       bl_label = "Hide unselected armature objects"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #If nothing is selected in the viewport
           if bpy.context.selected_objects == []:
               for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE':
                      #hide all armatures
                       ob.select = True
                       ob.hide = True
           else:
               
                       
              #hiding all armatures except the selected character/'s
              for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE': 
                       
                       #Prevent the selected 'armature' from hiding 
                       if ob == bpy.context.active_object:
                           ob.select = True
                           ob.hide = False
                       else:
                           #hiding all armatures
                           ob.select = True
                           ob.hide = True
                   else:
                       if ob.type == 'ARMATURE':
                           ob.hide = False
            # unhide selected object parent
           for ob in bpy.context.selected_objects:
               if ob.parent:
                   if ob.parent.type == 'ARMATURE':
                       ob.parent.select
                       ob.parent.hide = False
                
                       
           return {'FINISHED'}       
               
                   
                   
           
class UnhideAllArmatures(bpy.types.Operator):
       bl_idname = "object.unhide_all_armatures"  
       bl_label = "unhide all armatures from the scene"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #Unhiding all armatures from scene
           for ob in bpy.context.scene.objects:
               if ob.type == 'ARMATURE':
                   ob.hide = False 
           return {'FINISHED'}        
               
 
def register():
    bpy.utils.register_class(ArmatureDisplay)
    bpy.utils.register_class(UnhideAllArmatures)
    
def unregister():
    bpy.utils.unregister_class(ArmatureDisplay)
    bpy.utils.unregister_class(UnhideAllArmatures)
        
if __name__ == "__main__":
    register()

    #bpy.ops.object.armature_display_tool()
    bpy.ops.object.unhide_all_armatures()

I had already modified the code from active object to selected objects. Now if you have more than one character selected it will display their rigs

what the operator does is it checks the parent. If it is Armature type, it hide/show the parent. looking in modifieres panel for armature modifier is also a great idea. which one you prefer?

I have corrected the above code a little bit.

bl_info = {
    "name": "Armature Custom Display",
    "author": "Ameen Vengara",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D >  Hide unselected armatures > Assign a shortCut 'E' ",
    "description": "Hide all armatures except the character's you are working on",
    "warning": "",
    "wiki_url": "",
    "category": "Tools"}


import bpy


class ArmatureDisplay(bpy.types.Operator):
       bl_idname = "object.armature_display_tool"  
       bl_label = "Hide unselected armature objects"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #If nothing is selected in the viewport
           if bpy.context.selected_objects == []:
               for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE':
                      #hide all armatures
                       ob.select = True
                       ob.hide = True
           else:
               
                       
              #hiding all armatures except the selected one/ character's
              for ob in bpy.context.scene.objects:
                   if ob.type == 'ARMATURE': 
                       
                       #Prevent the selected 'armature' from hiding 
                       if ob == bpy.context.active_object:
                           ob.select = True
                           ob.hide = False
                       else:
                           #hiding all armatures
                           ob.select = True
                           ob.hide = True
                   else:
                       if ob.type == 'ARMATURE':
                           ob.hide = False
            # unhide selected object parent
           for ob in bpy.context.selected_objects:
               if ob.parent:
                   if ob.parent.type == 'ARMATURE':
                       ob.parent.select
                       ob.parent.hide = False
                
                       
           return {'FINISHED'}       
               
                   
                   
           
class UnhideAllArmatures(bpy.types.Operator):
       bl_idname = "object.unhide_all_armatures"  
       bl_label = "unhide all armatures from the scene"  
       
       
       def execute(self, context):
           scene = bpy.context.scene
           #Unhiding all armatures from scene
           for ob in bpy.context.scene.objects:
               if ob.type == 'ARMATURE':
                   ob.hide = False 
           return {'FINISHED'}        
               
 
def register():
    bpy.utils.register_class(ArmatureDisplay)
    bpy.utils.register_class(UnhideAllArmatures)
    
def unregister():
    bpy.utils.unregister_class(ArmatureDisplay)
    bpy.utils.unregister_class(UnhideAllArmatures)
        
if __name__ == "__main__":
    register()

I have modified the code further. Now it will hide/display Armature, Lattice, hook, curve deformers also.

Rewrited the entire code.
It works fine for me.

bl_info = {
    "name": "Deform Display Controller",
    "author": "Ameen Vengara",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D >  Use shortCut 'E' and ' ALT E' ",
    "description": "Hide all deform controls except the character's you are working on",
    "warning": "",
    "wiki_url": "",
    "category": "Tools"}


import bpy


class DisplayDeformController(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.deform_display_operator"
    bl_label = "Display Controller of deform objects"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        
        #Creating a new array to save the selected objects
        saveselection = []
        #Types of modifiers 
        objtypes = ['LATTICE', 'ARMATURE', 'CURVE', 'HOOK']
        #If nothing is selected, hide every deform controls
        if bpy.context.selected_objects == []:
            for obj in bpy.data.objects:
                for objmodifier in obj.modifiers:
                    for obtype in objtypes:
                        if objmodifier.type == obtype:
                            if objmodifier.object:
                                objmodifier.object.hide = True
        
        #If anything is selected 
        elif bpy.context.selected_objects != []:
            #Saving the selected objects to the array
            for obj in bpy.context.selected_objects:
                saveselection.insert(0, obj)
                
            #hiding every deform controls    
            for obj in bpy.data.objects:
                for objmodifier in obj.modifiers:
                    for obtype in objtypes:
                        if objmodifier.type == obtype:
                            if objmodifier.object:
                                objmodifier.object.hide = True
                    
            #displaying the saved selection and it's controls           
            for obj in saveselection:
                for objmodifier in obj.modifiers:
                    for obtype in objtypes:
                        if objmodifier.type == obtype:
                            if objmodifier.object:
                                objmodifier.object.hide = False
                obj.hide = False    
        return {'FINISHED'}

class UnhideDeformControles(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.unhide_deform_controls"
    bl_label = "unhide all deform Controls"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        
        objtypes = ['LATTICE', 'ARMATURE', 'CURVE', 'HOOK']
        
        for obj in bpy.data.objects:
            for objmodifier in obj.modifiers:
                for obtype in objtypes:
                    if objmodifier.type == obtype:
                        if objmodifier.object:
                            objmodifier.object.hide = False
          
        return {'FINISHED'}
    
    
def register():
    bpy.utils.register_class(DisplayDeformController)
    bpy.utils.register_class(UnhideDeformControles)


def unregister():
    bpy.utils.unregister_class(DisplayDeformController)
    bpy.utils.unregister_class(UnhideDeformControles)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.deform_display_operator()

Waiting for a reply.
Also, what is 'add support in the patch for this'? Didn't get that one. : (

@ameen vengara (ameen_vga), Thanks for looking into the updates,
But this would better suit a differential, uploading a whole new script for every edit isn't great.

Some feedback...

  • Logic to check if an object is associated with another should be shared and written as a function.
  • Looping over all objects bpy.data.objects is not good, since this can manipulate objects in other scenes, this should use the current scenes objects.
  • saveselection.insert(0, obj) is slow, (has to move all elements in the array every time. why not append?), or why not simply do saveselection = context.selected_objects?

@Campbell Barton (campbellbarton)
I am just a beginner in programming.
So there will be problems.

  • Created a function to check if an object is associated with another.
  • changed to scene objects. Removed data.objects.
  • There was no need of array insertion.

It works fine.
Hope further feedbacks. Of course, there will be problems

bl_info = {
    "name": "Deform Display Controller",
    "author": "Ameen Vengara",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D >  Use shortCut 'E' and ' ALT E' ",
    "description": "Hide all deform controls except the character's you are working on",
    "warning": "",
    "wiki_url": "",
    "category": "Tools"}


import bpy

#Types of modifiers 
modifTypes = ['LATTICE', 'ARMATURE', 'CURVE', 'HOOK']

class HideDeformObjects(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.hide_deform_objects"
    bl_label = "Hiding all deform control objects"
    
        
    def execute(self, context):
        
        # Search every objects in the scene and looking for modifiers
        for obj in bpy.context.scene.objects:
            for objmodifier in obj.modifiers:
                
                # checking with modifTypes array, whether the modifier type is Lattice, armature, curve or hook
                for obtype in modifTypes:
                    if objmodifier.type == obtype:
                        
                        # making sure deform control object is selected in the modifier panel. 
                        if objmodifier.object:
                            
                            # hiding deform object
                            objmodifier.object.hide = True
        return {'FINISHED'}
                               
class UnhideDeformObjects(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.unhide_deform_objects"
    bl_label = "unhide all deform Control objects"

    
    def execute(self, context):
        # Search every objects in the scene and looking for modifiers
        for obj in bpy.context.scene.objects:
            for objmodifier in obj.modifiers:
                
                # checking with modifTypes array, whether the modifier type is Lattice, armature, curve or hook
                for obtype in modifTypes:
                    if objmodifier.type == obtype:
                        
                        # making sure modifier control object is selected in the modifier panel. 
                        if objmodifier.object:
                            
                            # unhiding deform object
                            objmodifier.object.hide = False    
                      
        return {'FINISHED'}
    
        
class DeformDisplayOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.deform_display_operator"
    bl_label = "Display Controller of deform objects"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        
        # An array to save the selected objects
        selectedObjects = []
        
        
        # If nothing is selected, hide every deform controls
        if bpy.context.selected_objects == []:
            bpy.ops.object.hide_deform_objects()
            
        
        # If anything is selected 
        elif bpy.context.selected_objects != []:
            
            #Saving the selected objects to the array
            selectedObjects = bpy.context.selected_objects
                
            # hiding every deform controls
            bpy.ops.object.hide_deform_objects()
            
            # displaying the selectedObject's deform control objects if available
            for obj in selectedObjects:
                for objmodifier in obj.modifiers:
                    for obtype in modifTypes:
                        if objmodifier.type == obtype:
                            if objmodifier.object:
                                objmodifier.object.hide = False
                
                # Preventing the selected object from hiding       
                obj.hide = False    
        return {'FINISHED'}


    
    
def register():
    bpy.utils.register_class(DeformDisplayOperator)
    bpy.utils.register_class(UnhideDeformObjects)
    bpy.utils.register_class(HideDeformObjects)
 


def unregister():
    bpy.utils.unregister_class(DeformDisplayOperator)
    bpy.utils.unregister_class(UnhideDeformObjects)
    bpy.utils.unregister_class(HideDeformObjects)



if __name__ == "__main__":
    register()

    # test call
    #bpy.ops.object.deform_display_operator()
    #bpy.ops.object.unhide_deform_objects()

Is there anything I have to do now?

Aaron Carlisle (Blendify) raised the priority of this task from Needs Information from User to Normal.Jun 5 2015, 4:53 PM

Hi, thanks for the update.

Added @Hjalti Hjálmarsson (hjalti), Would be interested in review from experienced user, maybe @Beorn Leonard (freen) too? (possibly some improvements can be made too).

Looks like theres some slightly odd use of the API still, but need to go over in a bit more before including (its a bit tedious to go over a lot of detail in review. may be easier just to make edits before committing.)

It's actually much better to submit code as a python file instead of inlining it into the comment.

As for the code, there're some quite inefficient thing going around bpy.context.selected_objects. It could be just:

if bpy.context.selected_objects:
  foo()
else:
  bar()

@Campbell Barton (campbellbarton) can correct my code if it's still not totally efficient.

re: bpy.context.selected_objects

Just do...

selected = bpy.context.selected_objects
...
# Then afterwards access 'selected' (unless the selection changes and you need to access a changes state).

I have added some more functionality to the script. So that it will do the same thing in pose mode also.ie hiding /unhiding unselected bones. It really helped my animation workflow.

@Campbell Barton (campbellbarton)

I just added one more function in the above script. After assigning shortcut key 'E' in pose mode it will hide the unselected posebones when you press 'E'. When you have nothing selected it will display the hidden posebones again. So you can concentrate on the selected area. It will be useful for lip synching, secondary actions etc...

Shortcut keys...

In 3D view > Object mode >
object.deform_display_operator ---- E
object.unhide_deform_objects ------ Alt E

In 3D view > Pose>
object.pose_bone_display_operator ----- E

@Campbell Barton (campbellbarton)
When we import characters as linked groups the script will not work for them( The first two functions ). When I click on the imported mesh it is of type 'EMPTY'. no parent, no modifiers. How can I access the armature of a linked character?

no resolution here 18 months. closing as archived.