Sunday 8 July 2012

Annoying quick selection sets..

If you find yourself selecting stuff, setting a key, then selecting other stuff, this is for you!

Its took me about a week but I really needed a tool to help with setting keys on lots of items but also respect what I have selected, I think I cracked it.

A quick rundown on the script..

Its a python script for Maya 2011, not sure how well it will work in previous versions.
Here is the bit to copy paste into a python shelf button.

#Ive also just updated the below to work much better across files. It now no longer creates a unkown node that can cause problems with saving .MA files. Also it should work much better when nested into referenced files. Happy days.


#QSelectSet 101!
# Tool for creating/remmbering selection sets, can be used in multiple maya files by copying the "QuickSelectSet_Kevs" (will be hidden away isnt a dag node) node across to other maya files..! 
#updates: new node type used that will be less hassle, works much better in refranced files, selection sets can  be used from a file already reffed..
#bug fixes.
import maya.cmds as cmds

def Items_Selected(): #returns the selected as an array/list
    selcted= []
    selcted = cmds.ls( selection=True)
    if len(selcted) < 1:
        print "No items selected.."
    else:
        return selcted    

def QSSNodeNameFinder()    : #finds if the node is reffed into the scene or not
    SearchForQSSNode = cmds.ls( 'QuickSelectSet_Kevs' )
    if len(SearchForQSSNode) < 1:
        testForRef = cmds.ls( ("*:"+'QuickSelectSet_Kevs' ))
        if testForRef > 0:
            return testForRef
        else:
            pass
    else:
        return SearchForQSSNode
        
def QSelectSetsMenu_Search(): #Finds if the scene holds a info node (qss) already!
    SearchForQSSNode = QSSNodeNameFinder()
    if len(SearchForQSSNode) > 0:
        print "found previous QSSNode"
        return True
    else:
        print "Not Found QSS Node"
        return False

def QSSName_Legal(NameTest): #is the name used already? Y/N
    QSSNode = QSSNodeNameFinder()
    QSS_List = cmds.listAttr( QSSNode, ud=True)      # grabs a list of all user added atrs to item
    if NameTest in QSS_List:
        return "nonelegalname"
    else:
        return "legalname"

def QSelectSetsMenu_CreateSetWin(): #window for naming the set
    T1LC=[200,200]
    # QSelectSet = "WindowQSelectSet"
    # T1LC = cmds.windowPref( QSelectSet, query=True, tlc=True)    
    if cmds.window('CreateSetWin', exists=True):
        cmds.deleteUI('CreateSetWin', window=True)
        cmds.windowPref( 'CreateSetWin', remove=True )
    cmds.window( 'CreateSetWin' , widthHeight=(160, 50) , toolbox=True)
    
    cmds.columnLayout('main')
    cmds.textField( 'SetNameFld', tx = "Name the Set here!" , width = 160)
    cmds.setParent('main') 
    
    cmds.rowColumnLayout( numberOfColumns=2)
    cmds.button(width = 80 , label = "Done", bgc = (0.6, 0.45, 0.12), command = 'QSelectSetsMenu_CreateSet()')
    cmds.button(width = 80 ,label = "Cancel", bgc = (0.5, 0.2, 0.2), command = "cmds.deleteUI('CreateSetWin', window=True)")
    cmds.setParent('main') 
    cmds.showWindow('CreateSetWin')
    
def QSelectSetsMenu_CreateSet(): #creates a set
    
    QSSNode = QSSNodeNameFinder()
    SearchResult = QSelectSetsMenu_Search()
    SearchSetName = cmds.textField( 'SetNameFld' ,q= True , tx=True)
    if SearchResult is True:
        # we dont need to make from scratch
        #now to name test
        TestingName = QSSName_Legal(SearchSetName)
        if TestingName is "nonelegalname":
            cmds.textField( 'SetNameFld' ,e= True , tx="This name is already used.!") #lets the user know!
        else:
            cmds.addAttr(  QSSNode , shortName=SearchSetName, dt = "string"  ) #add it to node
            QSelectSetsMenu_AddToSet(SearchSetName)
    else:
        cmds.createNode( 'multiplyDivide', n='QuickSelectSet_Kevs' , ss=True) # we need to make from scratch
        #one time check/procedre over
        cmds.addAttr(  'QuickSelectSet_Kevs' , shortName=SearchSetName, dt = "string"  ) #add it to node
        #now we set the selected items to this new set!
        QSelectSetsMenu_AddToSet(SearchSetName)
    
def QSelectSetsMenu_AddToSet(SetName): #menu type = 0

    #grab selected..
    seled = Items_Selected()
    #read if there was anything there previous..
    QSSNode = QSSNodeNameFinder()
    exhist_Test = cmds.attributeQuery( (SetName), node=QSSNode[0] , ex=True )
    if exhist_Test is True: #does it exhist?
        oldstring= cmds.getAttr(QSSNode[0] + "." + SetName) #grab the old string..
        if oldstring > 1: #does it even have anything?
            old_list = ConvertList_From_String(oldstring)
            new_list = old_list + seled
            FlatSelected = ConvertList_To_String(new_list) #recombobulate
        else:
            FlatSelected = ConvertList_To_String(seled)
    else:
        FlatSelected = ConvertList_To_String(seled)
    cmds.setAttr((QSSNode[0] + "." + SetName),  FlatSelected , type = "string" )    
    UpdateSetMenu() #now update all menus with new changes!
    
def ConvertList_To_String(NamesList): #feed it a list, it will feed back a string
    new_list = sorted(set(NamesList))#removes duplicates!
    tmp='@'.join(new_list) 
    return tmp
    
def ConvertList_From_String(NamesFlat): #feed it a string it will feed back a list
    tmp = NamesFlat.split('@')
    new_tmp =sorted(set(tmp)) #removes duplicates!
    return new_tmp

def QSelectSetsMenu_RemoveFrmSet(SetName): #menu type = 1 removes selected ffrom a setname given
    #grab selected..
    seled = Items_Selected()
    #read if there was anything there previous..
    QSSNode = QSSNodeNameFinder()
    exhist_Test = cmds.attributeQuery( (SetName), node=QSSNode[0] , ex=True )
    if exhist_Test is True: #does it exhist?
        oldstring= cmds.getAttr(QSSNode[0] + "." + SetName) #grab the old string..
        if str(oldstring) > 2: #does it even have anything?
            old_list = ConvertList_From_String(oldstring)
            #we have the old list as an array of items, we need to removed the currently selected..
            new_list = (set(old_list)-set(seled)) #old list  minus the currently selected!
            if len(new_list) < 1:
                cmds.deleteAttr( QSSNode[0] + "."  + SetName ) #delete the set
            else:
                FlatSelected = ConvertList_To_String(new_list) #recombobulate
                cmds.setAttr((QSSNode[0] + "."  + SetName),  FlatSelected , type = "string" )    
        else:
            print "items not in this quick select set."
            cmds.deleteAttr( QSSNode[0] + "."  + SetName )
    else:
        print "Set doesnt exhist"
    UpdateSetMenu() #now update all menus with new changes!

def QSelectSetsMenu_RenameSetWin(SetName): #menu type = 2
    #spawn a window with a txt field
    T1LC=[200,200]
    # QSelectSet = "WindowQSelectSet"
    # T1LC = cmds.windowPref( QSelectSet, query=True, tlc=True)
    
    if cmds.window('RenameSetWin', exists=True):
        cmds.deleteUI('RenameSetWin', window=True)
        cmds.windowPref( 'RenameSetWin', remove=True )
    cmds.window( 'RenameSetWin' , widthHeight=(160, 50) , toolbox=True)
    
    cmds.columnLayout('main')
    cmds.textField( 'RenameNameFld', tx = "Name the Set here!" , width = 160)
    cmds.setParent('main') 
    
    cmds.rowColumnLayout( numberOfColumns=2)
    cmds.button(width = 80 , label = "Done", bgc = (0.6, 0.45, 0.12), command = 'QSelectSetsMenu_RenameSet("' + SetName + '")')
    cmds.button(width = 80 ,label = "Cancel", bgc = (0.5, 0.2, 0.2), command = "cmds.deleteUI('RenameSetWin', window=True)")
    cmds.setParent('main') 
    cmds.showWindow('RenameSetWin')
    
def QSelectSetsMenu_RenameSet(SetName):
    RenameSetName = cmds.textField( 'RenameNameFld' ,q= True , tx=True)
    QSSNode = QSSNodeNameFinder()
    cmds.renameAttr( QSSNode[0] + "." + SetName, RenameSetName)
    print ("Renaming Set.." + SetName + " . too " + RenameSetName + ".")
    cmds.deleteUI('RenameSetWin', window=True)
    UpdateSetMenu()
    
def QSelectSetsMenu_DeleteSet(SetName): #menu type = 3 removes a set entirely, just deletes the atr
    QSSNode = QSSNodeNameFinder()
    cmds.deleteAttr( QSSNode[0] + "." + SetName )
    UpdateSetMenu() #now update all menus with new changes!
    
def UpdateSetMenu(): #updates all the menus..
    QSSNode = QSSNodeNameFinder()
    QSS_List = cmds.listAttr( QSSNode[0] , ud=True) 
    if QSS_List < 1:
        cmds.delete( QSSNode[0])
    else:
        pass
    # QSelectSet = "WindowQSelectSet"
    # if cmds.window(QSelectSet, exists=True):
        # cmds.deleteUI(QSelectSet, window=True)
        # cmds.windowPref( QSelectSet, remove=True )
    QSelectSetWin()
    QSS_ButtonUpdater()
    
def QSelectSetsMenu_Create(MenuType):   #define create menu function for the builders available:
    SearchResult = QSelectSetsMenu_Search()
    QSSNode = QSSNodeNameFinder()
    if SearchResult is True:
        #node found, grab the sets!
        QSS_List = cmds.listAttr( QSSNode[0] , ud=True)      # grabs a list of all user added atrs to item
    else:
        QSS_List = ["No Sets Found"]
        #node not found

    for i in QSS_List:                    #run a for loop to ...
        commandChoices = ["QSelectSetsMenu_AddToSet","QSelectSetsMenu_RemoveFrmSet","QSelectSetsMenu_RenameSetWin" ,"QSelectSetsMenu_DeleteSet"]
        Ccommand =  commandChoices[MenuType]  + "('" + i + "')"
        # print Ccommand
        cmds.menuItem( label=(i) , command = Ccommand ,ec=True)    #create as much menuItems as number of objects selected, label them with object name

def QSS_ButtonUpdater(): #updates the buttons in the main window from the list available
    SearchResult = QSelectSetsMenu_Search()
    QSSNode = QSSNodeNameFinder()
    if SearchResult is True: #if we have a qss node present..
        QSS_List = cmds.listAttr( QSSNode[0] , ud=True)      # grabs a list of all user added atrs to item
        ButtonsStillAround = cmds.layout( 'ButtonsGoHere', query=True, childArray=True )
        if ButtonsStillAround > 1:
            for x in ButtonsStillAround:
                cmds.deleteUI( x , control=True )
        else:
            pass
        count = 0
        for i in QSS_List:                    #run a for loop to ...
            
            ColourChanger1 = (0.5+ count)
            ColourChanger2 =  (0.12 + count)
            cmds.button( (i + "_k") , label = (i + "  Key"), bgc = (ColourChanger1, 0.2, 0.2), command = 'QSS_Select_Set_Key' + "('" + i + "')")
            cmds.button( (i + "_s") , label = "Select", bgc = (0.6, 0.75, ColourChanger2), command = 'QSS_Select_Set' + "('" + i + "')")
            if count < 0.13:
                count =(count + 0.07)
            else:
                count = 0

        WindowHeight = (40 +(len(QSS_List * 23)))
        QSelectSet = "WindowQSelectSet"
        cmds.window( QSelectSet , widthHeight=(160, WindowHeight) , toolbox=True , menuBar=True, e=True)
    
    else:
        pass
        
def QSS_Select_Set(SetName):    
    QSSNode = QSSNodeNameFinder()
    SelectGoal_String= cmds.getAttr(QSSNode[0] + '.' + SetName) #grab the old string..
    if SelectGoal_String > 0: #does it even have anything?
        SelectGoal_List = ConvertList_From_String(SelectGoal_String)
        cmds.select( clear=True )
        for x in SelectGoal_List:
            #check if we get a hit
            tester = cmds.ls( x )
            if len(tester) < 1:
                # print "Must be a ref.."
                testerRef = cmds.ls( ("*:" + x) )
                if len(testerRef) > 0:
                    # print "ref found.."
                    cmds.select( ("*:" + x) , add=True)
                else:
                    print x
                    print " No longer exhists?"
            else:
                cmds.select (x , add=True)    
    else:
        "There doesnt appear to be anything"
        
def QSS_Select_Set_Key(SetName):
    QSSNode = QSSNodeNameFinder()
    SelectGoal_String= cmds.getAttr(QSSNode[0] + '.' + SetName) #grab the old string..
    if SelectGoal_String > 0: #does it even have anything?
        SelectGoal_List = ConvertList_From_String(SelectGoal_String)
        
        for x in SelectGoal_List:
            #check if we get a hit
            tester = cmds.ls( x )
            if len(tester) < 1:
                # print "Must be a ref.."
                testerRef = cmds.ls( ("*:" + x) )
                if len(testerRef) > 0:
                    # print "ref found.."
                    cmds.setKeyframe(("*:" + x))
                    cmds.setKeyframe(("*:" + x))
                else:
                    print x
                    print " No longer exhists?"
            else:
                cmds.setKeyframe( x)
                cmds.setKeyframe( x)
        
def QSelectSetWin(): #windows
    QSelectSet = "WindowQSelectSet"

    if cmds.window(QSelectSet, exists=True):
        cmds.deleteUI(QSelectSet, window=True)
        cmds.windowPref( QSelectSet, remove=True )
    cmds.window( QSelectSet , widthHeight=(160, 30) , toolbox=True , menuBar=True)

    cmds.rowColumnLayout( 'main', numberOfColumns=1)
    cmds.menu( label='Create' )
    cmds.radioMenuItemCollection()
    cmds.menuItem( label='New Set',command = 'QSelectSetsMenu_CreateSetWin()')

    cmds.menu( label='Add_to_Set' )
    cmds.radioMenuItemCollection()
    QSelectSetsMenu_Create(0)
    
    cmds.menu( label='Remove_frm_Set' )
    cmds.radioMenuItemCollection()
    QSelectSetsMenu_Create(1)

    cmds.menu( label='Rename_Set' )
    cmds.radioMenuItemCollection()
    QSelectSetsMenu_Create(2)

    cmds.menu( label='Delete_Set' )
    cmds.radioMenuItemCollection()
    QSelectSetsMenu_Create(3)
    cmds.setParent('main') 
    
    cmds.rowColumnLayout( 'ButtonsGoHere' , numberOfColumns=2 , columnWidth=[(1, 110), (2, 50)])
    cmds.setParent('ButtonsGoHere') 

    cmds.showWindow( QSelectSet )
    
QSelectSetWin()
QSS_ButtonUpdater()

No comments:

Post a Comment