//dwPoser.mel //David Walden // www.davidwalden.com // dwalden74@hotmail.com //July 19-21, 2003. // //Updated: Sept. 17, 2003 // //Info: //Creates a poser UI that lets user save and apply pose information for Maya character sets in a fast and efficient way. //Poses are saved with a "*.pose" extension in the current project´s "/poses" folder. If no such folder is found upon running, //the script will prompt the user to create one in the current project directory. This "/poses" directory is necessary for //the script to read and write pose files correctly, and therefore the script will not work if the user does not create this folder. // //It is important that the user realize he/she should be working in the current project (File->Project->Set) while using this script, //while all information about where the pose files are saved is given through this current project directory (`workspace -q -rd` command). //Poses are saved and applied according to which "Character" is selected in the poserUI window (NOT which character set is active in the //main Maya UI). This option menu shows a list of all character sets in the scene. Note: This script works with MAYA CHARACTER SETS only; //therefore you must have one or more character sets existing in your scene (Character->Create Character Set menu item). // //If "List by character" is selected, the UI list shows only the poses that correspond to the selected "Character" in the poserUI. //If "List by character" is deselected, the poser UI will show all pose files in the current "/pose" folder. This is useful when the user wants to apply a //pose that was saved from one character to a different character. When applying poses, dwPoser looks for attributes from the pose file that match //attribute names on the destination character. If a name is matched, then the attribute is set. Otherwise it keeps looking until it finds a match. // //The "Apply to Character" checkbox, if selected, will apply the pose to the entire character set. If deselected, the pose will be applied only //to the selected objects in the main Maya UI. // //The "Import Pose" menu item will copy a pose file from an external directory into the current directory and add it to the UI list. Of course, the //user can also just copy these files under the OS if this is easier. // //Everything else should be pretty self-explanatory. E-mail me with any comments or problems you may have: dwalden74@hotmail.com //Procedure adds namespace to an item according to an input character name that has a namespace. global proc string dwGetNamespace(string $characterName) { string $nameBuffer[]; int $sizeBuffer = `tokenize $characterName ":" $nameBuffer`; string $namespace = ""; int $i; for ($i = 0; $i < $sizeBuffer; $i++) { if (($i + 1) == $sizeBuffer) break; else $namespace += ($nameBuffer[$i] + ":"); } return $namespace; }//End of procedure. //Converts an attribute´s long name (for example, "translateX") to the short-name form ("tx"). //We need this to match selected channelbox channels (short names) with attribute names in the text files. global proc string dwConvertToShortName(string $inputName) { string $outputName; switch ($inputName) { case "translateX": $outputName = "tx"; break; case "translateY": $outputName = "ty"; break; case "translateZ": $outputName = "tz"; break; case "rotateX": $outputName = "rx"; break; case "rotateY": $outputName = "ry"; break; case "rotateZ": $outputName = "rz"; break; case "scaleX": $outputName = "sx"; break; case "scaleY": $outputName = "sy"; break; case "scaleZ": $outputName = "sz"; break; case "visibility": $outputName = "v"; break; default: $outputName = $inputName; break; } return $outputName; } //PROCEDURE RETURNS A STRING ARRAY OF ALL CHARACTERMEMBERS IN THE CURRENT CHARACTER, //INCLUDING ALL MEMBERS OF ALL SUBCHARACTERS. global proc string[] dwGetAllCharacterMembers(string $character) { string $subCharacters[] = `listConnections -s 1 -d 0 -type character $character`; string $newSubCharacters[]; string $allCharacters[]; string $originalCharacter[1] = {$character}; //If $character has subcharacters, gather all connected subcharacters into one string array. if (`size($subCharacters)` != 0) { for ($s in $subCharacters) { $newSubCharacters = `listConnections -s 1 -d 0 -type character $s`; $subCharacters = `stringArrayCatenate $subCharacters $newSubCharacters`; } $allCharacters = `stringArrayCatenate $originalCharacter $subCharacters`; } else $allCharacters[0] = $character; //return $allCharacters; //Get all attributes (non-character types) in all characters. string $attrTemp[]; string $attributes[]; int $ii = 0; for ($c in $allCharacters) { $attrTemp = `character -q $c`; for ($a in $attrTemp) { if (`objectType $a` != "character") { $attributes[$ii] = $a; //print ($attributes[$ii] + "\n"); $ii++; } } } return $attributes; } //Procedure applies a pose to a character. Pose information (attributes and their values) are saved without namespaces. //Therefore the correct namespace must be added to the character name and the attributes´ names before they will work. //Poses can be applies to the entire character, to selected objects, or to selected objects´ selected channels. global proc dwApplyPose(string $poseName[], string $character, int $applyToCharacterFlag, int $applyToChannelsFlag) { if (size($poseName) != 1) error "Select one pose to apply."; //Get path of file. Files reside in current project´s "/poses" subdirectory. string $currentProject = `workspace -q -rd`; //Assign full pose file name: consists of ($character + "." + $fileName + ".pose"). string $completeFileName = ($currentProject + "poses/" + $poseName[0] + ".pose"); //Open file session for reading. int $fileId = `fopen $completeFileName "r"`; string $nextLine = `fgetline $fileId`; //IMPORTANT: Remove "\n" from string. Each item is saved to list with escaped character "\n". //This must be removed when the file lines are read into the list. string $lineBuffer[]; tokenize $nextLine "\n" $lineBuffer; //Tokenize again. We need to isolate the different parts of the string (character, attribute, value). string $values[]; tokenize $lineBuffer[0] $values; string $attribute = $values[0]; float $attributeValue = $values[1]; //Get namespace of character and attributes. string $namespace = `dwGetNamespace($character)`; //Assign variable to attribute WITH namespaces. string $attributeNameWithNamespace = ($namespace + $attribute); string $selection[]; string $characterSet[]; string $characterBuffer[]; string $characterAttrShortName; string $selectedChannels[] = `channelBox -q -sma mainChannelBox`; string $attrLongName[]; while (size($nextLine) > 0) { //If $applyToCharacterFlag is true, apply pose to all character members. We will ignore the $applyToChannelsFlag in this case, //as the user will want to apply to selected channels only when he/she is applying the pose to selected objects, and not to the entire character. if ($applyToCharacterFlag) { //Set attributes if character set member names are the same as the names in the pose file. //This allows us to set attributes where a name was matched correctly; we don´t care of some names don´t match. //If $character has no subcharacters, query the character. Otherwise, get all subcharacters´ members. if (size(`listConnections -s 1 -d 0 -type character $character`)) $characterSet = `dwGetAllCharacterMembers($character)`; else if (! size(`listConnections -s 1 -d 0 -type character $character`)) $characterSet = `character -q $character`; for ($c in $characterSet) { tokenize $c "." $characterBuffer; $characterAttrShortName = `dwConvertToShortName($characterBuffer[1])`; if (($characterBuffer[0] + "." + $characterAttrShortName) == $attributeNameWithNamespace) setAttr $attributeNameWithNamespace $attributeValue; } } //If $applyToCharacterFlag is false, apply pose only to selected objects. else if (!$applyToCharacterFlag) { $selection = `ls -sl`; if (size($selection) == 0) error "No objects selected. Select some objects and try again."; string $attributeBuffer[]; tokenize $attributeNameWithNamespace "." $attributeBuffer; //Find matchable names in selection and set attributes. for ($s in $selection) { //If $applyToChannelsFlag is false, then apply to all attributes that are matched. if (! $applyToChannelsFlag) { if ($s == $attributeBuffer[0]) { setAttr $attributeNameWithNamespace $attributeValue; } } //Otherwise, if $applyToChannelsFlag is true, then apply ONLY TO SELECTED CHANNELS that are matched. if ($applyToChannelsFlag) { //First, check if object names match. if ($s == $attributeBuffer[0]) { //Now check if attribute names match. If so, set the attribute. for ($channel in $selectedChannels) { if ($channel == $attributeBuffer[1]) setAttr $attributeNameWithNamespace $attributeValue; } } } } } $nextLine = `fgetline $fileId`; if ($nextLine == "") break; clear $lineBuffer; clear $values; tokenize $nextLine "\n" $lineBuffer; tokenize $lineBuffer[0] $values; $attribute = $values[0]; $attributeValue = $values[1]; //Get namespace of character and attributes. $namespace = `dwGetNamespace($character)`; //Assign variable to attribute with namespaces. $attributeNameWithNamespace = ($namespace + $attribute); } fclose $fileId; } //Procedure removes any namespaces on a given node and returns the name without the namespace. global proc string dwRemoveNamespace(string $namespaceName) { string $nameBuffer[]; tokenize $namespaceName ":" $nameBuffer; string $nameWithoutNamespace; if (size($nameBuffer) > 1) $nameWithoutNamespace = $nameBuffer[size($nameBuffer) - 1]; else $nameWithoutNamespace = $namespaceName; //Return name without namespace. return $nameWithoutNamespace; }//End of procedure. //Procedure writes the ".pose" file for a given character set. //Namespaces are ignored, and must be added at the time the pose is applied. global proc dwWritePoseFile(string $fileName, string $character) { //Open file session. $fileId = `fopen $fileName "w"`; string $attributes[]; if (size(`listConnections -s 1 -d 0 -type character $character`)) $attributes = `dwGetAllCharacterMembers($character)`; else if (! size(`listConnections -s 1 -d 0 -type character $character`)) $attributes = `character -q $character`; string $attributeNoNamespace; string $attributeBuffer[]; string $shortName; float $values[]; int $i; for ($i = 0; $i < size($attributes); $i++) { $values[$i] = `getAttr $attributes[$i]`; //print ($values[$i] + "\n"); //print ($attributes[$i] + "\n"); //Get character member names without namespace; $attributeNoNamespace = `dwRemoveNamespace($attributes[$i])`; //print ($attributeNoNamespace + "\n"); //Tokenize member name by "." This separates the object name and the attribute name. tokenize $attributeNoNamespace "." $attributeBuffer; //Assign $shortName to attribute name. We need to get the attributes´ names in their short forms. //This helps us later when we need to match selected channels (`channelBox -q -sma`) with attributes in the pose file. //Querying selected channelbox channels returns names ONLY in their short form. $shortName = `dwConvertToShortName($attributeBuffer[1])`; fprint $fileId ($attributeBuffer[0] + "." + $shortName + " " + $values[$i]); //Don´t add "\n" if it´s the last item. if ($i < (size($attributes) - 1)) fprint $fileId "\n"; else break; } //Close file session. fclose $fileId; }//End of procedure. //Procedure saves a pose with a given name. If pose sile exists already, user is prompted to overwrite it. Makes call to dwWritePoseFile. global proc dwSavePose(string $character) { string $dialogResult = `promptDialog -t "Pose Name" -message "Enter Name:" -button "OK" -button "Cancel" -defaultButton "OK" -cancelButton "Cancel" -dismissString "Cancel"`; if ($dialogResult == "OK") { //Get complete path of file to write. string $fileName = `promptDialog -q`; string $currentProject = `workspace -q -rd`; //Remove namespace if one exists. string $characterNoNamespace = `dwRemoveNamespace($character)`; //Assign full pose file name: consists of ($character + "." + $fileName + ".pose"). string $completeFilePath = ($currentProject + "poses/" + $characterNoNamespace + "." + $fileName + ".pose"); //If file already exists, prompt to overwrite. if (`filetest -r $completeFilePath`) { string $overwriteDialog = `confirmDialog -title "Overwrite pose:" -message "Pose already exists. Are you sure you want to overwrite file?" -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; //If user chose to overwrite file, create file. if ($overwriteDialog == "Yes") dwWritePoseFile($completeFilePath, $character); else print "Save new pose cancelled.\n"; } //Else if file doesn´t exist, start file session. else if (! `filetest -r $completeFilePath`) dwWritePoseFile($completeFilePath, $character); } else print ("Save new pose cancelled.\n"); }//End of procedure. //Procedure renames pose and returns its new name. Works in current project´s "/poses" folder only. global proc string dwRenamePose (string $poseName[]) { if (size($poseName) != 1) error "Select one pose to rename."; string $dialogResult = `promptDialog -t "Rename Pose" -message "Enter New Name:" -button "OK" -button "Cancel" -defaultButton "OK" -cancelButton "Cancel" -dismissString "Cancel"`; if ($dialogResult == "OK") { //Get new name from promptDialog. string $newName = `promptDialog -q`; //Get current project dir. string $currentProject = `workspace -q -rd`; //Tokenize given $poseName (separacter "character" part of name. string $nameBuffer[]; tokenize $poseName[0] "." $nameBuffer; //Assign variables to full path of old name and new name. string $fullNewName = ($currentProject + "poses/" + $nameBuffer[0] + "." + $newName + ".pose"); string $fullOldName = ($currentProject + "poses/" + $poseName[0] + ".pose"); //Rename and print results. sysFile -rename $fullNewName $fullOldName; print ($fullOldName + " renamed to " + $fullNewName + "\n"); //Return new name. return ($nameBuffer[0] + "." + $newName + ".pose\n"); } else { print ("Rename pose cancelled.\n"); return $poseName[0]; } }//End of procedure. //Procedure deletes a given pose file. global proc dwDeletePose(string $poses[]) { if (size($poses) == 0) error "No poses selected for deletion."; for ($p in $poses) { string $currentWorkspace = `workspace -q -rd`; string $poserFolder = "poses"; string $poseCompletePath = ($currentWorkspace + $poserFolder + "/" + $p + ".pose"); string $deleteDialog; //Make sure file exists before prompting to delete it. if (`filetest -r $poseCompletePath`) { $deleteDialog = `confirmDialog -title "Delete pose:" -message ("Are you sure you want to delete \n" + $poseCompletePath + "?") -button "Yes" -button "Cancel" -defaultButton "Yes" -cancelButton "Cancel" -dismissString "Cancel"`; if ($deleteDialog == "Yes") { int $deleted = `sysFile -del $poseCompletePath`; //Check if file was removed. Sometimes the file is in use and cannot be deleted. //If it was deleted, remove it from the TSL. if ($deleted) { print ($poseCompletePath + " deleted.\n"); textScrollList -e -ri $p poserTSL; } else print ($poseCompletePath + " cannot be deleted at this time. File may be in use.\n"); } else print ("Delete pose cancelled.\n"); } //If file doesn´t exist, issue warning. else warning "No file found. Check \"/pose\" directory of current project."; } }//End of procedure. //Procedure called whenever UI needs to be updated. global proc dwUpdatePoserUI(string $characterName, int $listByCharacterCheckbox) { string $currentWorkspace = `workspace -q -rd`; string $poserFolder = "poses"; string $poserFolderCompletePath = $currentWorkspace + $poserFolder; string $fileList[] = `getFileList -folder ($poserFolderCompletePath + "/") -filespec "*.pose"`; //Remove all items from TSL first. textScrollList -e -ra poserTSL; string $poseBuffer[]; //If $listByCharacterCheckbox is false, add every file item to TSL. if (!$listByCharacterCheckbox) { for ($f in $fileList) { tokenize $f "." $poseBuffer; textScrollList -e -a ($poseBuffer[0] + "." + $poseBuffer[1]) poserTSL; } } //Otherwise, add only pose files that correspond to current character (given in UI characterOptionMenu). else { for ($f in $fileList) { //Remove namespace from $characterName. string $characterNoNamespace = `dwRemoveNamespace($characterName)`; tokenize $f "." $poseBuffer; if ($poseBuffer[0] == $characterNoNamespace) textScrollList -e -a ($poseBuffer[0] + "." + $poseBuffer[1]) poserTSL; } } }//End of procedure. //Procedure copies a pose file to the current project´s "/pose" subfolder and adds it to the UI list. global proc dwImportPose() { //Check if "/poses" subfolder exists in current project. string $currentWorkspace = `workspace -q -rd`; string $poserFolder = "poses"; string $poserFolderCompletePath = $currentWorkspace + $poserFolder; int $poseFolderExists = `filetest -d $poserFolderCompletePath`; string $createDialog; //If no Poses folder exists, prompt to create one with `confirmDialog`. if (!$poseFolderExists) { $createDialog = `confirmDialog -title "Create new pose folder:" -message ("No \"poses\" folder was found in the current project directory. Create one?") -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; if ($createDialog == "Yes") { workspace -dir $currentWorkspace; workspace -cr "poses"; } else print "Import pose cancelled.\n"; } //Re-evaluate $poseFolderExists variable to see if the folder was created. $poseFolderExists = `filetest -d $poserFolderCompletePath`; //If the "/poses" folder exists, OR if the user chose to create a "/poses" folder, go ahead and proceed to select file for import and copy it. if ($poseFolderExists) { string $poseFile = `fileDialog -dm "*.pose"`; //If user didn´t cancel the fileDialog operation, continue. if (size($poseFile) != 0) { //Check if file name exists in current poses folder, and if so prompt to overwrite. string $poseFileBuffer[]; int $poseTokens = `tokenize $poseFile "/" $poseFileBuffer`; string $overwriteDialog; string $newPoseCurrentProject = ($poserFolderCompletePath + "/" + $poseFileBuffer[$poseTokens - 1]); //If file name already exists, prompt to overwrite or rename. if (`filetest -r $newPoseCurrentProject`) { $overwriteDialog = `confirmDialog -title "Overwrite pose file:" -message ("File " + $newPoseCurrentProject + "\nexists in current project´s \"/pose\" directory. What do you want to do?") -button "Overwrite Pose" -button "Rename Pose" -button "Cancel" -defaultButton "Yes" -cancelButton "Cancel" -dismissString "Cancel"`; if ($overwriteDialog == "Overwrite Pose") { system ("copy " + "\"" + $poseFile + "\"" + " " + "\"" + $poserFolderCompletePath + "\""); print ($poseFile + " copied to " + $poserFolderCompletePath + "\n"); } else if ($overwriteDialog == "Rename Pose") { //Tokenize filename (just filename, no path) to separate the parts. Then add "_temp" extension to second part. string $poseNameBuffer[]; tokenize $poseFileBuffer[$poseTokens - 1] "." $poseNameBuffer; string $poseTempName = ($poseNameBuffer[1] + "_temp"); //Copy into folder with new "_temp" name. system ("copy " + "\"" + $poseFile + "\"" + " " + "\"" + $poserFolderCompletePath + "/" + $poseNameBuffer[0] + "." + $poseTempName + ".pose" + "\""); //Now assign variable to this new filename. We need to give dwRenamePose procedure a 1-element string array. string $newPoseNameTemp[1] = {$poseNameBuffer[0] + "." + $poseTempName}; string $newName = `dwRenamePose($newPoseNameTemp)`; //If $newName is different from previous name, then update UI and print results. if (($newName + ".pose") != ($poseNameBuffer[0] + "." + $poseTempName + ".pose")) { dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`); print ($poseFile + " copied to " + $poserFolderCompletePath + " and renamed to " + $newName + ".\n"); } //Otherwise if "Cancel" button is selected during rename, cancel operation and delete copied temp file. else { sysFile -del ($poserFolderCompletePath + "/" + $poseNameBuffer[0] + "." + $poseTempName + ".pose"); print ("Import pose cancelled.\n"); } } //If the "Cancel" dialog button is chosen, cancel operation. else print "Import pose cancelled."; } //If file name doesn´t exist, copy it normally. else { system ("copy " + "\"" + $poseFile + "\"" + " " + "\"" + $poserFolderCompletePath + "\""); print ("File " + $poseFile + " copied to " + $poserFolderCompletePath + "\n"); } } //Otherwise if user cancelled fileDialog operation (before selecting a file for import), cancel operation. else print ("Import pose cancelled.\n"); } dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`); }//End of procedure. //Procedure creates help window. global proc dwPoserHelp() { if (`window -ex dwPoserHelpUI`) deleteUI dwPoserHelpUI; window -t "Poser Help" dwPoserHelpUI; string $form = `formLayout`; string $scroll = `scrollLayout -cr true -mcw 445`; columnLayout -cat "left" 5; string $text = `text -l "" -al "left"`; setParent..; setParent..; string $closeButton = `button -l "Close Window" -c "deleteUI dwPoserHelpUI"`; string $helpText = "dwPoser.mel\n" + "David Walden: dwalden74@hotmail.com\n" + "July 19-21, 2003.\n" + "\n" + "\n" + "Info:\n" + "Creates a poser UI that lets user save and apply pose information for Maya character sets \n" + "in a fast and efficient way. Poses are saved with a \"*.pose\" extension in the current project´s \n" + "\"/poses\" folder. If no such folder is found upon running, the script will prompt the user \n" + "to create one in the current project directory. This \"/poses\" directory is necessary for\n" + "the script to read and write pose files correctly, and therefore the script will not work\n" + "if the user does not create this folder.\n" + "\n" + "It is important that the user realize he/she should be working in the current Maya project\n" + "(File->Project->Set) while using this script, while all information about where the pose files\n" + "are saved is given through this current project directory (`workspace -q -rd` command).\n" + "\n" + "Poses are saved and applied according to which \"Character\" is selected in the poserUI\n" + "window (NOT which character set is active in the main Maya UI). This option menu shows a \n" + "list of all character sets in the scene. Note: This script works with MAYA CHARACTER SETS \n" + "only; therefore you must have one or more character sets existing in your scene \n" + "(Character->Create Character Set menu item).\n" + "\n" + "If \"List by character\" is selected, the UI list shows only the poses that correspond to the\n" + "selected \"Character\" in the poserUI. If \"List by character\" is deselected, the poser UI \n" + "will show all pose files in the current \"/pose\" folder. This is useful when the user wants to\n" + "take a pose that was saved from one character and apply it to a different character. When \n" + "applying poses, dwPoser looks for attributes from the pose file that match attribute names \n" + "on the destination character. If a name is matched, then the attribute is set. Otherwise \n" + "it keeps looking until it finds a match.\n" + "\n" + "The \"Apply to Character\" checkbox, if selected, will apply the pose to the entire character \n" + "set. If deselected, the pose will be applied only to the selected objects in the main Maya UI. \n" + "\n" + "The \"Import Pose\" menu item will copy a pose file from an external directory into the\n" + "current directory and add it to the UI list. Of course, the user can also simply copy these\n" + "files under the OS if this is easier.\n" + "\n" + "Everything else should be pretty self-explanatory. E-mail me with any comments or problems:\n" + "dwalden74@hotmail.com\n" + "\n" + "\n" + "dwPoser.mel was tested only on Windows XP operating system."; text -e -l $helpText $text; formLayout -e -af $scroll left 5 -af $scroll top 5 -af $scroll right 5 -ac $scroll bottom 5 $closeButton -af $closeButton left 5 -af $closeButton right 5 -af $closeButton bottom 5 $form; showWindow dwPoserHelpUI; } global proc dwPoser() { if (`window -ex dwPoserUI`) deleteUI dwPoserUI; window -t "dwPoser" -menuBar true dwPoserUI; menu -l "File" -to true; menuItem -l "Rename Pose..." -c "dwRenamePose(`textScrollList -q -si poserTSL`);\ dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);"; menuItem -l "Import Pose..." -c "dwImportPose"; menuItem -d true; menuItem -l "Delete Pose" -c "dwDeletePose(`textScrollList -q -si poserTSL`);\ dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);"; menuItem -d true; menuItem -l "Update Poser Window" -c "dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);"; menu -l "Help"; menuItem -l "Poser Help" -c "dwPoserHelp;"; string $form = `formLayout`; //Current character text: Text at top of list which shows the current project. string $currentCharacterTXT = `text -l "Character:" -w 65 -align left -font boldLabelFont`; //characterOptionMenu: shows different characters in scene. string $characterOptionMenu = `optionMenu -l "" characterOptionMenu`; //Query the characters in the scene, then build a menuItem for each one. string $numberCharacters[] = `ls -type "character"`; if (size($numberCharacters) != 0) { int $c; for ($c = 0; $c < size($numberCharacters); $c++) menuItem -l $numberCharacters[$c] ($numberCharacters[$c] + "_menuItem"); setParent..; //Now select the menuItem corresponding to the current character. string $currentCharacters[] = `currentCharacters`; if (size($currentCharacters) != 0) { string $menuItems[] = `optionMenu -q -ils $characterOptionMenu`; $c = 0; for ($m in $menuItems) { if ($m == ($currentCharacters[0] + "_menuItem")) optionMenu -e -sl ($c + 1) $characterOptionMenu; $c++; } } else optionMenu -e -sl 1 $characterOptionMenu; } //After creating $characterOptionMenu and selecting current character, edit the "-changeCommand" flag //of the optionMenu so when user wants to edit project list for other Maya versions, the TSL is updated. optionMenu -e -cc "dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" characterOptionMenu; string $sortListCheckbox = `checkBox -l "List by character" -onc "dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" -ofc "dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" -v 1 listByCharacterCheckbox`; //textScrollList: reads user´s projects file. string $poserTSL = `textScrollList -allowMultiSelection false -dcc "dwApplyPose(`textScrollList -q -si poserTSL`, `optionMenu -q -v characterOptionMenu`, `checkBox -q -v applyToCharacterCheckbox`, 0);" poserTSL`; //popupMenu: With RMB user can choose some of the button commands. popupMenu -b 3 -p poserTSL dwPoserPOPUP; menuItem -l "Apply Pose" -c "dwApplyPose(`textScrollList -q -si poserTSL`, `optionMenu -q -v characterOptionMenu`, `checkBox -q -v applyToCharacterCheckbox`, 0);" dwPoserPOPUP_MenuItem1; menuItem -l "Apply Pose to Selected Channels" -c "dwApplyPose(`textScrollList -q -si poserTSL`, `optionMenu -q -v characterOptionMenu`, `checkBox -q -v applyToCharacterCheckbox`, 1);" -en 0 dwPoserPOPUP_MenuItem2; menuItem -d true dwPoserPOPUP_MenuItem3; menuItem -l "Rename Pose..." -c "dwRenamePose(`textScrollList -q -si poserTSL`);\ dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" dwPoserPOPUP_MenuItem4; menuItem -d true dwPoserPOPUP_MenuItem5; menuItem -l "Delete Pose" -c "dwDeletePose(`textScrollList -q -si poserTSL`);\ dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" dwPoserPOPUP_MenuItem6; menuItem -d true dwPoserPOPUP_MenuItem7; menuItem -l "Update Poser Window" -c "dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);" dwPoserPOPUP_MenuItem8; setParent..; setParent..; //Check if "/poses" subfolder exists in current project. string $currentWorkspace = `workspace -q -rd`; string $poserFolder = "poses"; string $poserFolderCompletePath = $currentWorkspace + $poserFolder; int $poseFolderExists = `filetest -d $poserFolderCompletePath`; //If no Poses folder exists, prompt to create one with `confirmDialog`. if (!$poseFolderExists) { string $createDialog = `confirmDialog -title "Create new \"poses\" folder:" -message ("No \"/poses\" folder was found in the current project directory. The current project \n" + "requires this folder to be created so that dwPoser can work. Create this folder?") -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; //If user chose to create poses folder, create it. if ($createDialog == "Yes") { workspace -dir $currentWorkspace; workspace -cr "poses"; } } //If poses folder exists, update poser UI. if (($poseFolderExists) && (size($numberCharacters) != 0)) dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`); //Add controls to layout. //string $useNamespacesCheck = `checkBox -l "Use Namespaces" -onc "" -ofc "" -v 1`; string $applyToCharacterCheck = `checkBox -l "Apply to Character" -v 1 -onc "menuItem -e -en 0 dwPoserPOPUP_MenuItem2; menuItem -e -en 0 dwApplyPOPUP_MenuItem1;" -ofc "menuItem -e -en 1 dwPoserPOPUP_MenuItem2; menuItem -e -en 1 dwApplyPOPUP_MenuItem1;" applyToCharacterCheckbox`; //"Save New Pose" button. string $savePoseButton = `button -l "Save New Pose..." -c "dwSavePose(`optionMenu -q -v characterOptionMenu`);\ dwUpdatePoserUI(`optionMenu -q -v characterOptionMenu`, `checkBox -q -v listByCharacterCheckbox`);"`; //"Apply Pose" button. string $applyPoseButton = `button -l "Apply Pose" -c "dwApplyPose(`textScrollList -q -si poserTSL`, `optionMenu -q -v characterOptionMenu`, `checkBox -q -v applyToCharacterCheckbox`, 1);"`; popupMenu -b 3 -p $applyPoseButton dwApplyButtonPOPUP; menuItem -l "Apply Pose to Selected Channels" -c "dwApplyPose(`textScrollList -q -si poserTSL`, `optionMenu -q -v characterOptionMenu`, `checkBox -q -v applyToCharacterCheckbox`, 1);" -en 0 dwApplyPOPUP_MenuItem1; setParent..; setParent..; setParent..; //Edit formLayout. formLayout -e -af $currentCharacterTXT left 5 -af $currentCharacterTXT top 5 -ac $characterOptionMenu left 5 $currentCharacterTXT -af $characterOptionMenu right 5 -af $characterOptionMenu top 5 -af $sortListCheckbox left 5 -af $sortListCheckbox right 5 -ac $sortListCheckbox top 12 $currentCharacterTXT -af $poserTSL left 5 -ac $poserTSL top 5 $sortListCheckbox -af $poserTSL right 5 -ac $poserTSL bottom 5 $applyToCharacterCheck -af $applyToCharacterCheck left 5 -af $applyToCharacterCheck right 5 -ac $applyToCharacterCheck bottom 5 $applyPoseButton -af $applyPoseButton left 5 -ap $applyPoseButton right 5 50 -af $applyPoseButton bottom 5 -ac $savePoseButton left 5 $applyPoseButton -af $savePoseButton right 5 -af $savePoseButton bottom 5 $form; showWindow dwPoserUI; }//End of procedure.