Home Technical Talk

Python for maya - Renaming and Skinning Multiple joints

ok so im creating this auto rigger, ive currently got it so it can create several joints each at its own object,I want to try and get it so it names the joints after the object it is created on and add _Joint to the end of its name.

Also as the title says, I want to add skinning, I cant get my head around it.

thanks for any help !

Replies

  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    For the naming, you already get the name from the for loop so you can just do something like
    cmds.joint(p=piv[0:3], name="%s_joint" % (geo))
    

    (The % is a quick way to concatenate strings in python). Not sure about the skinning.

    Should have just bumped this one up than make a new thread haha.
  • Johnm3D
    Options
    Offline / Send Message
    Thanks again :P yea i wasn't sure, I thought I should maybe make a new thread in-case someone else searches for something similar in a thread title.
  • Johnm3D
    Options
    Offline / Send Message
    *bump* lol, OK so I have got what I need set up, I know how to parent the stuff. but when I put in the parent script underneath what I have already put, it states that it cant find the bones (because it hasn't made them yet) is there a way for me to delay its check for the joint within the same python script ? or will I have to set up a separate script to perform the parenting. If so, I have been attempting to create a GUI using buttons but cant figure out how to call a script when the button is pressed.

    Thanks for any help !

    John.

    ps - these two websites are what I am going from to learn what to put into my script but some parts, im finding harder to figure out.

    http://download.autodesk.com/global/docs/maya2012/en_us/CommandsPython/index.html

    http://docs.python.org/2.6/index.html
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Mind posting the code? The parent stuff should probably go after the generation of the bones. Ideally you want to split the function of the scripts into well functions. The button would startoff a main procedure (something like autorigStart) which in turn calls helper functions like generating bones, parenting etc. Probably be able to help more once you post up your stuff.
  • Johnm3D
    Options
    Offline / Send Message
    ok sure, here is my menu code so far
    import maya.cmds as cmds
    
    window = cmds.window( title="Long Name", iconName='Short Name', widthHeight=(200, 100));
    cmds.frameLayout(lv=0, borderStyle='etchedIn');
    cmds.columnLayout( adjustableColumn=True );
    cmds.button( label='Help Me');
    cmds.button( label='Close', command=('cmds.deleteUI(\"' + window + '\", window=True)') );
    cmds.setParent( '..' );
    cmds.showWindow( window );
    

    and this is the rest
    import maya.cmds as cmds
    
    
    
    for geo in cmds.ls('RL_Wheel', 'RR_Wheel', 'FL_Wheel', 'FR_Wheel', 'Bonet', 'Chassis'):
    
        piv = cmds.xform(geo, q=True, piv=True, ws=True);
        cmds.select(clear=True);
        cmds.joint(p=piv[0:3], name="%s_joint" % (geo));
    


    after this part i was looking at firstly parenting the joints to the chassis joint, then he joints to their relevant parts of the vehicle.
    cmds.parentConstraint( 'Chassis_joint', 'RL_Wheel_joint' )
    
    etc
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    What you're looking for is cmds.parents not parentConstraint ;)

    so in
    cmds.parent( 'pSphere2_joint', 'pSphere1_joint' )
    

    pSphere2 will the child and pSphere1 joint will be the parent. Also should edit your window code to this:
    if cmds.window('MyWindow', exists=True):
        cmds.deleteUI('MyWindow')
    window = cmds.window("MyWindow",title="Long Name", iconName='Short Name', widthHeight=(200, 100));
    

    That way you dont have multiple windows showing up.

    Out of curiosity is this for a school project?
  • Johnm3D
    Options
    Offline / Send Message
    Last question, fingers crossed.

    when I first execute the script above that creates the joints at the pivots (this will be button 1 on my UI)

    then I execute this script the bind the joints (button 2)

    i get this error after executing the bind joints
    # Error: RuntimeError: Not enough objects or values. #
    

    this is the script I came upwith, I remembered that I used smooth bind when I created the original rig, after the rig is bound, I then parent bones to the chassis_bone
    import maya.cmds as cmds
    
    for geo in cmds.ls('RL_Wheel', 'RR_Wheel', 'FL_Wheel', 'FR_Wheel', 'RL_Door', 'RR_Door', 'FL_Door', 'FR_Door', 'RL_Suspension', 'RR_Suspension', 'FL_Suspension', 'FR_Suspension', 'Boot', 'Bonet', 'Chassis'):
        
        rootBone = "Chassis_joint"
        cmds.skinCluster("%s_joint" % (geo), "%s" % (geo),
            toSelectedBones=True,
            ignoreHierarchy=True,
            normalizeWeights=2,
            dropoffRate=0.1,
            removeUnusedInfluence=True,
            
        );
        cmds.parent("%s_joint" % (geo),rootBone);
    

    for the UI do I put these two scripts in with the UI script then have the buttons execute them or do the scripts all have to be separate? if that makes sense.

    Sorry if im asking alot of questions, I am currently reading the two websites I mentioned earlier as well as this book - Maya Python for Games and Film.

    that book is helping me alot (for those who are learning python for Maya and reading this thread) hence why I have been able to come up with the bind skin script myself. I cant seem to figure out the error though. also any help with the menu is greatly appreciated, the menu seems more confusing then it should me.

    thanks again,
    john.
  • Johnm3D
    Options
    Offline / Send Message
    ok so I figured out the error, it was because I was trying to connect Chassis_joint to itself.

    I changed that by having a button in my menu change Chassis_joint to Root_Bone.

    I have created a few buttons that function properly but there are two buttons which I can't get to work and thats because they are using a string I think its called ? here is the button -
    cmds.button( label='Parent Bones', command=("cmds.parent('%s_joint' % (geo), 'Root_Bone' )") );
    

    now I know for a fact that this bit of code works outside of the button, but I believe because the
    % (geo)
    
    is commented it gives me this error
    # Error: Invalid Code Fragment: Found no executable Python code. #
    

    now when I just put a single bone in the command button instead of the string like so
    cmds.button( label='Parent Bones', command=("cmds.parent('RL_Wheel_joint', 'Root_Bone' )") );
    
    it works perfectly for that single joint and creates the bone.

    Basically, what i'm asking is, is there a way to get this working, I was thinking of perhaps naming it outside of the button to call it, if that makes sense eg
    Bones = '%s_joint' % (geo);
    cmds.button( label='Parent Bones', command=("cmds.parent('Bones', 'Root_Bone' )") );
    
    but I know that doesn't work, I can't figure out how to set that up properly, if someone understands what i'm actually trying to achieve :)

    Thanks in advance !!
    John.
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Hey John, sorry didnt see the bump. So reason why it doesnt work is because geo is a temp variable that is referenced in the for loop (You can call it later in the script too but it would be the last object in the selection list or objects passed in. What you want to do is seperate functionality into functions. This way you can call a command to the button using the command flag. Also note that maya likes to send arguments (none that we are using but maya uses) so we need to add *args to the arguments list for the function. Formatted your code as an example. There were parts missing from before so I just added them.
    import maya.cmds as cmds
    
    def createUI():
        if cmds.window('MyWindow', exists=True):
            cmds.deleteUI('MyWindow')
        window = cmds.window("MyWindow",title="Long Name", iconName='Short Name', widthHeight=(200, 100));
        cmds.frameLayout(lv=0, borderStyle='etchedIn');
        cmds.columnLayout( adjustableColumn=True );
        cmds.button( label='Help Me', command=createBones);
        cmds.button( label='Close', command=('cmds.deleteUI(\"' + window + '\", window=True)') );
        cmds.setParent( '..' );
        cmds.showWindow( window );
    
    def createBones(*args):
        for geo in cmds.ls(cmds.ls(sl=True)):
        
            rootBone = "Chassis_joint"
            piv = cmds.xform(geo, q=True, piv=True, ws=True);
            cmds.select(clear=True);
            cmds.joint(p=piv[0:3], name="%s_joint" % (geo));
            cmds.skinCluster("%s_joint" % (geo), "%s" % (geo),
                toSelectedBones=True,
                ignoreHierarchy=True,
                normalizeWeights=2,
                dropoffRate=0.1,
                removeUnusedInfluence=True,
            
            );
            cmds.parent("%s_joint" % (geo),rootBone);
            
    createUI()
    

    Also another thing to watch out is that you do checks on say what you are selecting or if the rootbone exists etc.
  • Johnm3D
    Options
    Offline / Send Message
    thank you ! that was exactly what I needed to finish all of my buttons ! the menu is actually completed :) if I could give you kudos on this forum I would ! one last small question, purely for aesthetics, can you change the state of another button once the one before it has been pushed, eg
    button1 - enable=True
    button2 - enable=False
    
    when button 1 is pressed it changes button2's enable state to True
    

    is this possible ? would help to stop people pressing the buttons in the wrong order and stuff :)
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Johnm3D wrote: »
    thank you ! that was exactly what I needed to finish all of my buttons ! the menu is actually completed :) if I could give you kudos on this forum I would ! one last small question, purely for aesthetics, can you change the state of another button once the one before it has been pushed, eg
    button1 - enable=True
    button2 - enable=False
    
    when button 1 is pressed it changes button2's enable state to True
    

    is this possible ? would help to stop people pressing the buttons in the wrong order and stuff :)

    Yeah. You can use another built in module called partial from functools and send arguments to the function. You would have to do something like:
    import maya.cmds as cmds
    from functools import partial
    
    def createUI():
        if cmds.window('MyWindow', exists=True):
            cmds.deleteUI('MyWindow')
        window = cmds.window("MyWindow",title="Long Name", iconName='Short Name', widthHeight=(200, 100));
        cmds.frameLayout(lv=0, borderStyle='etchedIn');
        cmds.columnLayout( adjustableColumn=True );
        #Declare all your buttons making sure to give assign them to variables   
        createBonesBtn = cmds.button( label='Click Me');
        secondBtn = cmds.button(label='I\'m disabled', en=False)
        cmds.button( label='Close', command=('cmds.deleteUI(\"' + window + '\", window=True)') );
        #Edit button commands here.    
        cmds.button(createBonesBtn, edit=True, c=partial(createBones,createBonesBtn,secondBtn))  
        cmds.button(secondBtn, edit=True, c=partial(secondButtonFunc,secondBtn,createBonesBtn))      
        cmds.setParent( '..' );
        cmds.showWindow( window );
    
    def createBones(originalBtn,setActiveBtn,*args):
           
        for geo in cmds.ls(cmds.ls(sl=True)):
        
            rootBone = "Chassis_joint"
            piv = cmds.xform(geo, q=True, piv=True, ws=True);
            cmds.select(clear=True);
            cmds.joint(p=piv[0:3], name="%s_joint" % (geo));
            cmds.skinCluster("%s_joint" % (geo), "%s" % (geo),
                toSelectedBones=True,
                ignoreHierarchy=True,
                normalizeWeights=2,
                dropoffRate=0.1,
                removeUnusedInfluence=True,
            
            );
            cmds.parent("%s_joint" % (geo),rootBone);   
        #Doing our toggle here
        cmds.button(originalBtn, edit=True, en=False, label='I\'m disabled')
        cmds.button(setActiveBtn, edit=True, en=True, label='Its alive')  
    
    def secondButtonFunc(originalBtn,setActiveBtn,*args): 
        #Doing our second button toggle here  
        cmds.button(originalBtn, edit=True, en=False, label='I\'m disabled')
        cmds.button(setActiveBtn, edit=True, en=True, label='I\'m back') 
    
    createUI()
    
  • Johnm3D
    Options
    Offline / Send Message
    Hey, ive been having feedback from the script, and have found that the export function doesn't work because it can't create the temp folder in the C drive on some peoples computers.

    This is what I was using.
    import maya.cmds as cmds
    import maya.mel as mel
    from functools import partial
    
    def exportVehicle(originalBtn, setActiveBtn, *args):
    
            cmds.headsUpMessage( 'Exporting your Vehicle...!', time=5.0 )
            mel.eval('FBXExport -f "C:/Temp/MyVehicle.fbx";')
            cmds.button(originalBtn, edit=True, en=False, bgc=[0,1,0])
            cmds.button(setActiveBtn, edit=True, en=True, bgc=[0,0,0])            
            cmds.headsUpMessage( 'Vehicle has been Exported to "C:/Temp/MyVehicle.fbx", You may now Close...!', time=5.0 )
    

    What I have been trying to find out is if maybe I could create some sort of string in the address maybe? i'm not sure if thats the right way to go about it. What I need to do is maybe send the exported file to the users "my documents" or maybe just the desktop. but I can't seem to achieve this because of the users computer obviously has different user name which changes the address.

    Just wondered if you could point me in the right direction ( thats if im making any sense :P )

    Thanks
  • Johnm3D
    Options
    Offline / Send Message
    Just bumping, just incase the edit doesn't bump it for me.

    I also wondered if I could put a text field so the user could type / copy and paste their desired save location and then it reads that texts and inputs that string into the -f flag string? if the previous method isn't doable perhaps this method is ?
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    You could use the fileBrowserDialog2 command linked to a button to get a directory picker. Then just add a textfield and edit that. To get the user profile use the os module
    import os
    
    userhome = os.path.expanduser('~')
    

    That should return DriveLetter:\Users\Username
  • Johnm3D
    Options
    Offline / Send Message
    Ok so I get most of what you said, this is what I have done so you know where I am -
    def exportVehicle(originalBtn, setActiveBtn, *args):
    
            cmds.headsUpMessage( 'Exporting your Vehicle...!', time=5.0 )
            cmds.fileDialog2(fileMode=2, caption="Export Vehicle")
            #mel.eval('FBXExport -f "C:/temp/MyVehicle.fbx";')
            cmds.button(originalBtn, edit=True, en=False, bgc=[0,1,0])
            cmds.button(setActiveBtn, edit=True, en=True, bgc=[0,0,0])            
            cmds.headsUpMessage( 'Vehicle has been Exported, You may now Close...!', time=5.0 )
    

    the commented out mel.eval was what I was running before.
    I just don't understand what you mean by the textfield and the os module. cant find what I need in the maya python commands page so im guessing its from a different library or something like the functools ?

    Thanks.
  • Johnm3D
    Options
    Offline / Send Message
    Sorry I was tired last night and couldnt figure it out, woke up this morning and tried somthing durastic. took away the folder names and waited to see where it saves, and it goes to desktop. Just waiting for people to confirm this works on their computers.

    #new
    mel.eval('FBXExport -f "MyVehicle";')
    
    #old
    mel.eval('FBXExport -f "C:/temp/MyVehicle.fbx";')
    
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Heres some sample code for you and how to use the path returned from filedialog.
    import maya.cmds as cmds
    import maya.mel as mel
    import os
    
    def createUI():
        if cmds.window('MyWindow', exists=True):
            cmds.deleteUI('MyWindow')
        window = cmds.window("MyWindow",title="Long Name", iconName='Short Name', widthHeight=(200, 100));
        cmds.frameLayout(lv=0, borderStyle='etchedIn');
        createBonesBtn = cmds.button( label='Export', command=exportVehicle);
        cmds.setParent( '..' );
        cmds.showWindow( window );
        
    def exportVehicle(*args):
        cmds.headsUpMessage( 'Exporting your Vehicle...!', time=5.0 )
        path = cmds.fileDialog2(fileMode=0, caption="Export Vehicle", fileFilter="*.fbx")
        mel.eval('FBXExport -f "%s" -s'%(path[0]))
        cmds.headsUpMessage( 'Vehicle has been Exported to %s, You may now Close...!' % (path[0]), time=5.0 )
    createUI()
    

    The os Module is like functools where its a built in module for python. Using the command userhome = os.path.expanduser('~') would give us their user folder so for Windows it would be like C :\Users\Username and then you can appent whatever folder you want so if you wanted Desktop you could do userhome + "\Desktop" and there you go. Will export out to desktop. I would highly suggest doing either option as this makes your export process foolproof.
  • Johnm3D
    Options
    Offline / Send Message
    Hey, hopefully you will see this, I finished my Uni course and wanted to carry this on as its good for my portfolio as well as me finding it highly enjoyable. Im trying to do the whole UI now. Basically what I want is this (very basic diagram :P ) - This img


    Basically, I want a box for the root_bone to be inserted into by the user having the object selected and then hitting a button next to the non editable text box where the name of the object will appear. then a similar thing will occur for the child bones except I wanted there to be a + button to add more boxes for children, as well as another button to add a child bone to the children for stuff like turrets, the names that will be added to this text box, I want to be added to the selected list (cmds.ls ('blah') ) which will then be rigged.

    Ive figured out how to add more textboxes but not sure how to make these boxes none editable, also they get added onto the end of my script, but I want them to be added to a specific place, before the rigging buttons.

    hopefully this makes sense, this is the add text box script that ive figured out -
        cmds.textField( editable=False );
    
        cmds.button( label='Add Object', command=('cmds.textField(parent=\"' + parentLayout + '\"); ') );
        cmds.setParent( '..' );
    

    ive been looking on the autodesk and python documentation but cant seem to find how to add a selected objects name into the box by a click of a button.

    im guessing im going to need some kind of string to get the object names from the box's to the selected list, this is the part that confuses me the most, strings are my weak point atm
  • Johnm3D
    Options
    Offline / Send Message
    hmmm, bump? :P Just really want to get the most of this and make it a great tool for the community to use :) any help is great, its come along way since last post.
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Hey sorry Johnm didnt see this before but you mind posting the code you already have? Just having a bit of trouble understanding the function of the ui.
  • Johnm3D
    Options
    Offline / Send Message
    This is what I have so far.
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    If you use this Script, Please reference my website - JohnM3D.com - 
    
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    
    
    
    
    
    import maya.cmds as cmds
    import maya.mel as mel
    from functools import partial
    import os
     
     
    #Creates the UI Menu 
     
     
    def createUI():
        if cmds.window( 'MyWindow', exists=True ):
            cmds.deleteUI( 'MyWindow' );
        window = cmds.window( "MyWindow",title="Vehicle Auto-Rigger by JohnM3D.com", iconName='Auto-Rigger', topLeftCorner=[1,1], resizeToFitChildren=True, titleBarMenu=False, sizeable=False );
        parentLayout = cmds.frameLayout( labelVisible=0, borderStyle='etchedIn' );
        cmds.columnLayout( adjustableColumn=True );
        #cmds.text( 'Move the pivot points on the parts that will be rigged, Then press the "finished pivots" button below, Then click the buttons as they light up.', wordWrap=True );
        cmds.separator( height=10, style='in' );
        cmds.text( 'Naming convention type' );
        cmds.separator( height=10, style='none' );
        cmds.radioCollection();
        cmds.rowColumnLayout( numberOfColumns=2, width=285 );
    
        cmds.textField( editable=False );
    
        cmds.button( label='Add Object', command=('cmds.textField(parent=\"' + parentLayout + '\"); ') );
        cmds.setParent( '..' );
    
    
        cmds.columnLayout( adjustableColumn=True );
        cmds.separator( height=10, style='out' );
    
    
        
    #Edit the window preferences    
    
        cmds.windowPref( 'MyWindow', topLeftCorner=[1,1] ); 
    
      
    #Defining the Buttons 
     
        
        finishedPivotsBtn = cmds.button( label='Objects Named and Pivots Placed', bgc=[0,0,0] );
        
        cmds.rowColumnLayout( numberOfColumns=2 )
        
        placeBonesBtn = cmds.button( label='Place Bones at Pivots', enable=False, bgc=[1,0,0] );
        undoPlaceBonesBtn = cmds.button( label='<-- Undo This', visible=False, bgc=[0,0,0] );
        
        skinBonesBtn = cmds.button( label='Skin Bones', enable=False, bgc=[1,0,0] );
        undoSkinBonesBtn = cmds.button( label='<-- Undo This', visible=False, bgc=[0,0,0] );
        
        renameRootBtn = cmds.button( label='Rename Chassis_joint to Main_Root', enable=False, bgc=[1,0,0] );
        undoRenameRootBtn = cmds.button( label='<-- Undo This', visible=False, bgc=[0,0,0] );
        
        parentBonesBtn = cmds.button( label='Parent Bones', enable=False, bgc=[1,0,0] );
        undoParentBonesBtn = cmds.button( label='<-- Undo This', visible=False, bgc=[0,0,0] );
        
        cmds.columnLayout( adjustableColumn=True, height=80 );
        
        exportVehicleBtn = cmds.button( label='Export Now!', enable=False, bgc=[1,0,0] );
        mel.eval( 'string $gMainProgressBar = `progressBar -maxValue 10 -width 200` ' );
        
        closeWindowBtn = cmds.button( label='Close', command=( 'cmds.deleteUI(\"' + window + '\", window=True)' ) );
        
    
    #The arguements for the Buttons
    
        """Finish Pivots button"""    
        cmds.button( finishedPivotsBtn, edit=True, command=partial( finishPivots, finishedPivotsBtn, placeBonesBtn ) );
    
        """Place Bones and Undo button"""    
        cmds.button( placeBonesBtn, edit=True, command=partial( createBones, placeBonesBtn, skinBonesBtn, undoPlaceBonesBtn, undoPlaceBonesBtn ) );
        cmds.button( undoPlaceBonesBtn, edit=True, command=partial( undoCreateBones, undoPlaceBonesBtn, finishedPivotsBtn, placeBonesBtn, skinBonesBtn, undoPlaceBonesBtn, finishedPivotsBtn ) ); 
    
        """Skin Bones and Undo button"""    
        cmds.button( skinBonesBtn, edit=True, command=partial( skinBones, skinBonesBtn, renameRootBtn, undoPlaceBonesBtn, undoSkinBonesBtn ) );
        cmds.button( undoSkinBonesBtn, edit=True, command=partial( undoSkinBones, undoSkinBonesBtn, placeBonesBtn, skinBonesBtn, renameRootBtn, undoSkinBonesBtn, undoPlaceBonesBtn ) );
    
        """Rename Root and Undo button"""    
        cmds.button( renameRootBtn, edit=True, command=partial( renameRootBone, renameRootBtn, parentBonesBtn, undoSkinBonesBtn, undoRenameRootBtn ) );
        cmds.button( undoRenameRootBtn, edit=True, command=partial( undoRenameRootBone, undoRenameRootBtn, skinBonesBtn, renameRootBtn, parentBonesBtn, undoRenameRootBtn, undoSkinBonesBtn ) );
    
        """Parent Bones and Undo button"""    
        cmds.button( parentBonesBtn, edit=True, command=partial( parentBones, parentBonesBtn, exportVehicleBtn, undoRenameRootBtn, undoParentBonesBtn ) );    
        cmds.button( undoParentBonesBtn, edit=True, command=partial( undoParentBones, undoParentBonesBtn, renameRootBtn, parentBonesBtn, exportVehicleBtn, undoParentBonesBtn, undoRenameRootBtn ) );
    
        """Export button"""    
        cmds.button( exportVehicleBtn, edit=True, command=partial( exportVehicle, exportVehicleBtn, closeWindowBtn ) ); 
        cmds.setParent( '..' );
        cmds.showWindow( window );    
        
       
    #Finished placing pivots, deletes History    
        
    def finishPivots( originalBtn, setActiveBtn, *args ):
            
            cmds.headsUpMessage( 'Deleted your Non-Deformer History...!', time=5.0 );
            cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
            cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );
    
    #Creates the Bones at the pivot points of the listed objects
        
    def createBones( originalBtn, setActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        for geo in cmds.ls( 'RL_Wheel', 'RR_Wheel', 'FL_Wheel', 'FR_Wheel', 'RL_Door', 'RR_Door', 'FL_Door', 'FR_Door', 'RL_Suspension', 'RR_Suspension', 'FL_Suspension', 'FR_Suspension', 'Boot', 'Bonnet', 'Chassis' ):
           
            cmds.headsUpMessage( 'Created your Bones...!', time=5.0 );
            piv = cmds.xform( geo, q=True, piv=True, ws=True );
            cmds.select( clear=True );
            cmds.joint( p=piv[0:3], name="%s_joint" % ( geo ) );
            cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
            cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );
            cmds.button( originalUndoBtn, edit=True, visible=False );
            cmds.button( setActiveUndoBtn, edit=True, visible=True );
    
    #Undo function for createBones
    
    def undoCreateBones( originalBtn, setActiveBtn, undoneBtn, oldActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        cmds.undo();
        cmds.button( undoneBtn, edit=True, en=False, bgc=[1,0,0] );
        cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] ); 
        cmds.button( oldActiveBtn, edit=True, en=False, bgc=[1,0,0] ); 
        cmds.button( originalUndoBtn, edit=True, visible=False );
        cmds.button( setActiveUndoBtn, edit=True, visible=True );
        
    #Skins the listed objects to their bones via a string naming system   
            
    def skinBones( originalBtn, setActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        for geo in cmds.ls( 'RL_Wheel', 'RR_Wheel', 'FL_Wheel', 'FR_Wheel', 'RL_Door', 'RR_Door', 'FL_Door', 'FR_Door', 'RL_Suspension', 'RR_Suspension', 'FL_Suspension', 'FR_Suspension', 'Boot', 'Bonnet', 'Chassis' ):
    
            cmds.headsUpMessage( 'Skinned the Bones to your Objects...!', time=5.0 );
            cmds.skinCluster( "%s_joint" % ( geo ), "%s" % ( geo ),
                toSelectedBones=True,
                ignoreHierarchy=True,
                normalizeWeights=2,
                dropoffRate=0.1,
                removeUnusedInfluence=True,           
            );
            cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
            cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );
            cmds.button( originalUndoBtn, edit=True, visible=False );
            cmds.button( setActiveUndoBtn, edit=True, visible=True );
          
    #Undo function for skinBones
    
    def undoSkinBones( originalBtn, setActiveBtn, undoneBtn, oldActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        cmds.undo();
        cmds.button( undoneBtn, edit=True, en=False, bgc=[1,0,0] );
        cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] ); 
        cmds.button( oldActiveBtn, edit=True, en=False, bgc=[1,0,0] ); 
        cmds.button( originalUndoBtn, edit=True, visible=False );
        cmds.button( setActiveUndoBtn, edit=True, visible=True );
    
    #Renames the root bone from Chassis_joint to Main_Root, a naming convention for UDK      
            
    def renameRootBone( originalBtn, setActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
         
            cmds.headsUpMessage( 'Renamed Chassis_joint to Main_Root...!', time=5.0 );
            cmds.rename( 'Chassis_joint', 'Main_Root' );
            cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
            cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );
            cmds.button( originalUndoBtn, edit=True, visible=False );
            cmds.button( setActiveUndoBtn, edit=True, visible=True );
                
    #Undo function for renameRootBone
    
    def undoRenameRootBone( originalBtn, setActiveBtn, undoneBtn, oldActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        cmds.undo();
        cmds.button( undoneBtn, edit=True, en=False, bgc=[1,0,0] );
        cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] ); 
        cmds.button( oldActiveBtn, edit=True, en=False, bgc=[1,0,0] ); 
        cmds.button( originalUndoBtn, edit=True, visible=False );
        cmds.button( setActiveUndoBtn, edit=True, visible=True );
    
    #Parents the Bones in the list to the Main_Root bone            
                
    def parentBones( originalBtn, setActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        for geo in cmds.ls( 'RL_Wheel', 'RR_Wheel', 'FL_Wheel', 'FR_Wheel', 'RL_Door', 'RR_Door', 'FL_Door', 'FR_Door', 'RL_Suspension', 'RR_Suspension', 'FL_Suspension', 'FR_Suspension', 'Boot', 'Bonnet' ):
    
            cmds.headsUpMessage( 'Parented your Bones...!', time=5.0 );
            cmds.parent( "%s_joint" % ( geo ), "Main_Root" ); 
            cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
            cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );
            cmds.button( originalUndoBtn, edit=True, visible=False );
            cmds.button( setActiveUndoBtn, edit=True, visible=True );
         
    #Undo function for parentBones
    
    def undoParentBones( originalBtn, setActiveBtn, undoneBtn, oldActiveBtn, originalUndoBtn, setActiveUndoBtn, *args ):
        cmds.undo();
        cmds.button( undoneBtn, edit=True, en=False, bgc=[1,0,0] );
        cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] ); 
        cmds.button( oldActiveBtn, edit=True, en=False, bgc=[1,0,0] ); 
        cmds.button( originalUndoBtn, edit=True, visible=False );
        cmds.button( setActiveUndoBtn, edit=True, visible=True );
    
    #Export function     
            
    def exportVehicle( originalBtn, setActiveBtn, setActiveUndoBtn, *args ):
        cmds.headsUpMessage( 'Exporting your Vehicle...!', time=5.0 );
        path = cmds.fileDialog2( fileMode=0, caption="Export Vehicle - Select your Export location and Name your file", fileFilter="*.fbx" );
        mel.eval( 'FBXExport -f "%s" -s'%( path[0] ) );
        cmds.headsUpMessage( 'Vehicle has been Exported to %s, You may now Close...!' % ( path[0] ), time=5.0 );
        cmds.button( originalBtn, edit=True, en=False, bgc=[0,1,0] );
        cmds.button( setActiveBtn, edit=True, en=True, bgc=[0,0,0] );    
    
     
    createUI()
    
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Hey Johnm sorry for the late reply heres some code to get you started. I think you should start moving stuff into functions as its better than formatting everything into a string.

    I edited your add button command to:
    cmds.button( label='Add Object', command=partial(addObject,parentLayout ) );
    

    and the function is
    def addObject (parentLayout,*args):
        selection = cmds.ls(sl=True)
        if len(selection)>0:    
            cmds.textField(parent=parentLayout,editable=False,text=selection[0])
    

    I dont think this is the right approach to this and maybe something like a treeView ()http://download.autodesk.com/us/maya/2010help/CommandsPython/treeView.html) might help though I dont have much experience using it. When I get some time I'll try and something quick for you.
  • Johnm3D
    Options
    Offline / Send Message
    This has helped a lot thanks again :)
  • rabbijoe
    Options
    Offline / Send Message
    Hey guys im really glad i found this post, Can you guys recommend me a place i know a little bit of python already, i would like to eventually move on to automating my rigging with autorigs, UI's and such, where is a good place to start learning how to make rigging and OOP tools in maya?

    Best.
    Joe
  • Johnm3D
    Options
    Offline / Send Message
    Hey, sorry I didn't see your post. I used a mixture of Python and Maya Documentation along side asking for help on this forum. If you have money id recommend tutorials as well, I haven't been able to as of yet.
  • passerby
    Options
    Offline / Send Message
    passerby polycounter lvl 12
    @rabbijoe, ya maya docs, but if your wanting to use it for rigging and wanting to learn OOP concepts you should move to pymel, and stop using maya.cmds, it is mostly all oop.
Sign In or Register to comment.