Tasks/3dsMaxBipedTemplate.py

Tasks/3dsMaxBipedTemplate.py
1 # Copyright 2009 Autodesk, Inc. All rights reserved.
2 # Use of this software is subject to the terms of the Autodesk license agreement
3 # provided at the time of installation or download, or which otherwise accompanies
4 # this software in either electronic or hard copy form.
5 #
6 # Script description:
7 # This script is executed when a template with the script name ((in Asset\Character)) is dragged on a character.
8 # It will Characterize a 3DS Max Biped so it fits the MoBu naming.
9 #
10 # Topic: FBFindModelByLabelName,FBCharacter.SetCharacterizeOn,FBProgress
11 #
12 
13 from pyfbsdk import *
14 
15 # These three variables controls how characterization is done
16 
17 # This is the Root Name. For a Biped this will be the Biped Name. For Custom Skeleton user must set
18 # it according to their naming convention
19 bipedrootname = "<CharacterName>"
20 
21 # For biped, all bones have the following naming scheme <BipedName> <BipedBone>. Set this variable to
22 # False if you have Custom Skeleton.
23 bipedPrefixNamingScheme = True
24 
25 # This is the biped map mapping all bipeds Name to Mobu Names.
26 # If you have a custom skeleton, you need to recreate this map according to your naming convention.
27 bipedMap = {'Reference' : 'Fbx_Root',
28  'Hips':'',
29  'LeftUpLeg' : 'L Thigh',
30  'LeftLeg' : 'L Calf',
31  'LeftFoot' : 'L Foot',
32  'RightUpLeg' : 'R Thigh',
33  'RightLeg' : 'R Calf',
34  'RightFoot' : 'R Foot',
35  'Spine' : 'Spine',
36  'LeftArm' : 'L UpperArm',
37  'LeftForeArm' : 'L Forearm',
38  'LeftHand' : 'L Hand',
39  'RightArm' : 'R UpperArm',
40  'RightForeArm' : 'R Forearm',
41  'RightHand' : 'R Hand',
42  'Head' : 'Head',
43  'LeftShoulder' : 'L Clavicle',
44  'RightShoulder' : 'R Clavicle',
45  'Neck' : 'Neck',
46  'Spine1' : 'Spine1',
47  'Spine2' : 'Spine2',
48  'Spine3' : 'Spine3',
49  'Spine4' : 'Spine4',
50  'Spine5' : 'Spine5',
51  'Spine6' : 'Spine6',
52  'Spine7' : 'Spine7',
53  'Spine8' : 'Spine8',
54  'Spine9' : 'Spine9',
55  'Neck1' : 'Neck1',
56  'Neck2' : 'Neck2',
57  'Neck3' : 'Neck3',
58  'Neck4' : 'Neck4',
59  'Neck5' : 'Neck5',
60  'Neck6' : 'Neck6',
61  'Neck7' : 'Neck7',
62  'Neck8' : 'Neck8',
63  'Neck9' : 'Neck9',
64  'LeftHandThumb1' : 'L Finger0',
65  'LeftHandThumb2' : 'L Finger01',
66  'LeftHandThumb3' : 'L Finger02',
67  'LeftHandIndex1' : 'L Finger1',
68  'LeftHandIndex2' : 'L Finger11',
69  'LeftHandIndex3' : 'L Finger12',
70  'LeftHandMiddle1' : 'L Finger2',
71  'LeftHandMiddle2' : 'L Finger21',
72  'LeftHandMiddle3' : 'L Finger22',
73  'LeftHandRing1' : 'L Finger3',
74  'LeftHandRing2' : 'L Finger31',
75  'LeftHandRing3' : 'L Finger32',
76  'LeftHandPinky1' : 'L Finger4',
77  'LeftHandPinky2' : 'L Finger41',
78  'LeftHandPinky3' : 'L Finger42',
79  'RightHandThumb1' : 'R Finger0',
80  'RightHandThumb2' : 'R Finger01',
81  'RightHandThumb3' : 'R Finger02',
82  'RightHandIndex1' : 'R Finger1',
83  'RightHandIndex2' : 'R Finger11',
84  'RightHandIndex3' : 'R Finger12',
85  'RightHandMiddle1' : 'R Finger2',
86  'RightHandMiddle2' : 'R Finger21',
87  'RightHandMiddle3' : 'R Finger22',
88  'RightHandRing1' : 'R Finger3',
89  'RightHandRing2' : 'R Finger31',
90  'RightHandRing3' : 'R Finger32',
91  'RightHandPinky1' : 'R Finger4',
92  'RightHandPinky2' : 'R Finger41',
93  'RightHandPinky3' : 'R Finger42',
94  'LeftFootThumb1' : 'L Toe4',
95  'LeftFootThumb2' : 'L Toe41',
96  'LeftFootThumb3' : 'L Toe42',
97  'LeftFootIndex1' : 'L Toe3',
98  'LeftFootIndex2' : 'L Toe31',
99  'LeftFootIndex3' : 'L Toe32',
100  'LeftFootMiddle1' : 'L Toe2',
101  'LeftFootMiddle2' : 'L Toe21',
102  'LeftFootMiddle3' : 'L Toe22',
103  'LeftFootRing1' : 'L Toe1',
104  'LeftFootRing2' : 'L Toe11',
105  'LeftFootRing3' : 'L Toe12',
106  'LeftFootPinky1' : 'L Toe0',
107  'LeftFootPinky2' : 'L Toe01',
108  'LeftFootPinky3' : 'L Toe02',
109  'RightFootThumb1' : 'R Toe4',
110  'RightFootThumb2' : 'R Toe41',
111  'RightFootThumb3' : 'R Toe42',
112  'RightFootIndex1' : 'R Toe3',
113  'RightFootIndex2' : 'R Toe31',
114  'RightFootIndex3' : 'R Toe32',
115  'RightFootMiddle1' : 'R Toe2',
116  'RightFootMiddle2' : 'R Toe21',
117  'RightFootMiddle3' : 'R Toe22',
118  'RightFootRing1' : 'R Toe1',
119  'RightFootRing2' : 'R Toe11',
120  'RightFootRing3' : 'R Toe12',
121  'RightFootPinky1' : 'R Toe0',
122  'RightFootPinky2' : 'R Toe01',
123  'RightFootPinky3' : 'R Toe02',
124  'LeftUpLegRoll' : 'LThighTwist',
125  'LeftLegRoll' : 'LCalfTwist',
126  'RightUpLegRoll' : 'RThighTwist',
127  'RightLegRoll' : 'RCalfTwist',
128  'LeftArmRoll' : 'LUpArmTwist',
129  'LeftForeArmRoll' : 'L ForeTwist',
130  'RightArmRoll' : 'RUpArmTwist',
131  'RightForeArmRoll' : 'R ForeTwist' }
132 
133 def addJointToCharacter ( characterObject, slot, jointName ):
134  myJoint = FBFindModelByLabelName(jointName)
135  if myJoint:
136  proplist = characterObject.PropertyList.Find(slot + "Link")
137  proplist.append (myJoint)
138 
139 def Characterize(rootname, useBipedPrefixNamingScheme, boneMap):
140  # Create an empty FBModelList object.
141  models = FBModelList()
142 
143  # Obtain the list of selected models.
144  FBGetSelectedModels(models)
145 
146  system = FBSystem()
147  app = FBApplication()
148 
149  # check if there is a selection
150  if len( models ) == 0:
151  FBMessageBox( "Message", "Please select a Biped joint.", "OK", None, None )
152  elif len( models ) > 1:
153  # Only one biped joint must be selected else we can have problems if joints belongs to different bipeds.
154  FBMessageBox( "Message", "Only one Biped joint must be selected.", "OK", None, None )
155  else:
156  # Extract the name of the model including its namespace
157  longname = models[0].LongName
158  namespaceindex = longname.rfind(":")
159  if namespaceindex != -1:
160  namespace = longname[0:namespaceindex+1]
161  name = longname[namespaceindex + 1:]
162  else:
163  namespace = ""
164  name = longname
165 
166  # If in Biped mode, extract the character prefix name
167  bipednameprefix = ""
168  if useBipedPrefixNamingScheme:
169  splitname = name.split()
170  bipednameprefix = splitname[0] + " "
171  # Override the rootname so it is the character orefix name
172  rootname = splitname[0]
173 
174  myBiped = FBCharacter("mycharacter")
175  myBiped.LongName = namespace + rootname
176  app.CurrentCharacter = myBiped
177 
178  # Create a FBProgress object and set default values for the caption and text.
179  fbp = FBProgress()
180  fbp.Caption = ""
181  fbp.Text = " ----------------------------------- Creating Biped character"
182  progress = 0.0
183  progresssteps = len(boneMap)
184 
185  # assign Biped to Character Mapping.
186  for pslot, pjointName in boneMap.iteritems():
187  if not pjointName:
188  addJointToCharacter (myBiped, pslot, namespace + rootname)
189  else:
190  addJointToCharacter (myBiped, pslot, namespace + bipednameprefix + pjointName)
191  progress += 1
192  val = progress / len(boneMap) * 100
193  fbp.Percent = int(val)
194 
195  switchOn = myBiped.SetCharacterizeOn( True )
196  print "Character mapping created for " + (myBiped.LongName)
197 
198  # We must call FBDelete when the FBProgress object is no longer needed.
199  fbp.FBDelete()
200 
201 
202 # Call the Characterize Character Function with all bipeds defined variables.
203 Characterize(bipedrootname, bipedPrefixNamingScheme, bipedMap)
204 
205