Blog

Script: Duplicate hierarchy and parent constrain existing hierarchy to duplicate hierarchy, Maya, Python

Posted by:

This script will duplicate the selected hierarchy and parent constrain each child of the first hierarchy to its twin in the new hierarchy.  This script opens a window that allows you to select the root object to duplicate then duplicates, renames the new hierarchy, establishes the parent constraint and sets up a control for all of the parent constraints to be controlled from a single attribute on the original root object.

  1. #jfm_dupeRigParentConstrain
  2. #Created by: Seth Meshko, 3danimationartist.com
  3. #12/17/17
  4.  
  5. '''
  6. This script opens a gui window that will allow you to select a skeleton then with a button push automatically
  7. duplicates your skinned rig, renames each joint, removes all shapes, transforms and effectors and
  8. creates the parent constraints for each joint and establishes a common control to turn the parent
  9. constraint network on and off with a single attribute on the skin rig root.
  10. NOTE!: This script will fail if there are any objects in your scene that are named the same as any object
  11. in your new rig. Although this is fairly unlikely it bears mentioning.
  12. ANOTHER NOTE!: If you are using this after having already run jfm_HandSetup.py then you don't want this script
  13. you want jfm_dupeRigPrntConstWithHandSetup
  14. '''
  15.  
  16. import maya.cmds as cmds
  17. import functools
  18.  
  19. windowID = 'jfm_dupeRigParentConstrain'
  20.  
  21. global globalRigToDupe
  22. global globalTargetRig
  23.  
  24. def loadSelected(loadSelected):
  25. rigToDupe = cmds.ls(selection = True)
  26. newSelection = cmds.textField('selectedObjectField', edit = True, text = rigToDupe[0].encode('utf8'))
  27. print('loadSelected, the globalRigToDupe is: ' + str(rigToDupe))
  28. global globalRigToDupe
  29. globalRigToDupe = rigToDupe
  30.  
  31. def renameObject(text, dic):
  32. for i, j in dic.iteritems():
  33. text = text.replace(i, j)
  34. return text
  35.  
  36. def deleteFilteredObjects(rootJoint, typeOfObject):
  37. listToPrune = cmds.listRelatives(rootJoint, allDescendents = True)
  38. for eachObject in listToPrune:
  39. objectType = cmds.objectType(eachObject)
  40. if(objectType == typeOfObject):
  41. cmds.delete(eachObject)
  42.  
  43. def dupeRig(dupeRig, pNameSearchField, pNameReplaceField):
  44.  
  45. objectType = cmds.objectType(globalRigToDupe)
  46.  
  47. #The order in which these are assigned matters more than the first arguement
  48. searchForField = cmds.textField(nameSearchField, query=True, text=True)
  49. replaceWithField = cmds.textField(nameReplaceField, query=True, text=True)
  50.  
  51. print('dupeRig(), the searchForField is: ' + searchForField)
  52. print('dupeRig(), the replaceWithField is: ' + replaceWithField)
  53.  
  54. if (objectType != 'joint'):
  55. print('You must load a joint to duplicate')
  56. elif (objectType == 'joint'):
  57.  
  58. originalRootName = globalRigToDupe[0] #Storing the original name of root
  59. print('dupeRig(), the originalRootName is : ' + str(originalRootName))
  60. newObject = cmds.duplicate(globalRigToDupe[0], n='temp', rc=True) #the objects have to be renamed because there is nothing you can do with them until they have a different name from their originals
  61. cmds.parent(newObject[0], world = True)
  62. print('dupeRig(), the newObject is : ' + str(newObject))
  63. reps = {searchForField: replaceWithField, 'SknNoWeight':'Rig', '1': ''}
  64. nameForRootObject = renameObject(originalRootName, reps) #replacing the prefix
  65. print('dupeRig(), the newObject[0] is : ' + str(newObject[0]))
  66. duplicatedJoint = cmds.rename(newObject[0], nameForRootObject) #Changing the name back to something that makes sense
  67. print('dupeRig(), the duplicatedJoint is : ' + str(duplicatedJoint))
  68. global globalTargetRig
  69. globalTargetRig = duplicatedJoint
  70. newSelection = cmds.listRelatives(duplicatedJoint, allDescendents=True)#creating a new list from the childern of the duplicated object, note we had to use the new name for the root object
  71. print('dupeRig(), the newSelection is: ' + str(newSelection))
  72.  
  73. #renaming the childen
  74. i=0
  75. originalNameList = cmds.listRelatives(globalRigToDupe[0], allDescendents = True)
  76. print('dupeRig(), the originalNameList is: ' + str(originalNameList))
  77. reps = {searchForField: replaceWithField, 'SknNoWeight': 'Rig', 'SknGeo' : 'Rig', 'Hair':'Rig_Hair'}
  78. for eachObject in newSelection:
  79. objectName = originalNameList[i]
  80. # bind the returned text of the method
  81. # to a variable and print it
  82. newNameA = renameObject(objectName, reps)
  83. #print newNameAs
  84. print('dupeRig(), the object to rename is: ' + str(eachObject))
  85. newName = cmds.rename(eachObject, newNameA)
  86. i= i+1
  87.  
  88. #parent constraining original rig to duplicated rig
  89. parentConstrainedRigList = cmds.listRelatives(globalRigToDupe[0], allDescendents = True, type = 'joint')
  90. print('dupRig(), globalTargetRig is: ' + str(globalTargetRig)) #at this point globalTargetRig is the root of the target rig
  91. targetRigList = cmds.listRelatives(globalTargetRig, allDescendents = True, type = 'joint')
  92. parentConstrainedRigList.insert(0, globalRigToDupe[0])
  93. targetRigList.insert(0, globalTargetRig)
  94. print('dupeRig(), the parentConstrainedRigList[0] is: ' + str(parentConstrainedRigList[0]))
  95. print('dupeRig(), the targetRigList[0] is: ' + str(targetRigList[0]))
  96. #if cmds.attributeQuery(parentConstrainedRigList[0], node = 'RigFollow'):
  97. if (cmds.objExists(parentConstrainedRigList[0] + '.RigFollow')):
  98. print('dupeRig(), attribute RigFollow found')
  99. #cmds.select(parentConstrainedRigList[0])
  100. cmds.deleteAttr(parentConstrainedRigList[0], attribute = 'RigFollow')
  101. cmds.addAttr(parentConstrainedRigList[0], attributeType = 'float', longName = 'RigFollow', hasMinValue = True, minValue = 0, maxValue = 1, defaultValue = 1, keyable = True)
  102.  
  103. i=0
  104. for eachJoint in parentConstrainedRigList:
  105. print('dupeRig(), the parentConstrainedRigList[i] is: ' + str(parentConstrainedRigList[i]))
  106. print('dupeRig(), the targetRigList[i] is: ' + str(targetRigList[i]))
  107. newParentConstraint = cmds.parentConstraint(targetRigList[i], parentConstrainedRigList[i])
  108. reps = {'|':''}
  109. targetRigString = renameObject(targetRigList[i], reps)
  110. cmds.connectAttr(str(parentConstrainedRigList[0]) + '.RigFollow', newParentConstraint[0].encode('utf8') + '.' + targetRigString + 'W0', force = True)
  111. i=i+1
  112.  
  113.  
  114. #This is all cleanup for the rig skeleton. It's just deleting all of the unused artifacts from the skin joint skeleton
  115. shapeSelection = cmds.listRelatives(globalTargetRig, allDescendents = True, type = 'shape' ) #creating a list to select any unwanted shapes in the hierarchy
  116. #The reason why this is done as a loop is because if the throws an error you will know which shape to deal with
  117. for eachObject in shapeSelection:
  118. shapeTransform = cmds.listRelatives(eachObject, type = 'transform', parent = True ); #selecting the transforms of the shape nodes
  119. cmds.delete(shapeTransform)
  120.  
  121. typeToPrune = 'transform'
  122. deleteFilteredObjects(globalTargetRig, typeToPrune)
  123. typeToPrune = 'ikEffector'
  124. deleteFilteredObjects(globalTargetRig, typeToPrune)
  125.  
  126. #Start GUI
  127.  
  128. if cmds.window(windowID, exists=True):
  129. cmds.deleteUI(windowID)
  130.  
  131. cmds.window(windowID, title='Dupe Rig, Parent Constrain Hierarchy', sizeable=False, resizeToFitChildren=True)
  132.  
  133. #Start of 1st frame
  134. cmds.frameLayout(label='Duplicate and Rename', collapsable=True)
  135.  
  136. cmds.text(label = 'Select the joint root to duplicate and enter search and replace names')
  137. #Start of 1st frame content
  138. cmds.rowColumnLayout(numberOfColumns=5, columnWidth=[(1,150), (2,150), (3,10), (4,100), (5,150)], columnOffset=[(1,'right', 3)])
  139.  
  140. #New Row
  141. cmds.text(label='Joint root to duplicate:')
  142.  
  143. jointNameField = cmds.textField('selectedObjectField')
  144.  
  145. cmds.separator(h=10, style='none')
  146.  
  147. cmds.separator(h=10, style='none')
  148.  
  149. cmds.button(label='Select', command=(loadSelected)) #functools.partial
  150.  
  151.  
  152. #New Row
  153.  
  154. cmds.text(label='Name Search:')
  155.  
  156. nameSearchField = cmds.textField(text='SKIN')
  157.  
  158. cmds.separator(h=10, style='none')
  159.  
  160. cmds.text(label='Name Replace:')
  161.  
  162. nameReplaceField = cmds.textField(text='RIG')
  163.  
  164. #New Row
  165.  
  166. cmds.separator (h=10, style='none')
  167. cmds.separator (h=10, style='none')
  168. cmds.separator (h=10, style='none')
  169. cmds.separator (h=10, style='none')
  170. cmds.separator (h=10, style='none')
  171.  
  172. #New Row
  173.  
  174. cmds.separator (h=10, style='none')
  175. cmds.separator (h=10, style='none')
  176. cmds.separator (h=10, style='none')
  177. cmds.separator (h=10, style='none')
  178. cmds.button(label='Duplicate', command=functools.partial(dupeRig, nameSearchField, nameReplaceField)) #
  179.  
  180. cmds.setParent('..')
  181. #End of 1st frame
  182.  
  183. cmds.showWindow()

 

0
  Related Posts
  • No related posts found.

You must be logged in to post a comment.