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
(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.
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
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.
etc
so in
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?
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
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.
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 is commented it gives me this error
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 achieveThanks in advance !!
John.
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.
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()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
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 ?
import os userhome = os.path.expanduser('~')That should return DriveLetter:\Users\Username
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.
#new mel.eval('FBXExport -f "MyVehicle";') #old mel.eval('FBXExport -f "C:/temp/MyVehicle.fbx";')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.
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
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 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()I edited your add button command to:
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.
Best.
Joe