//------------------------------------------------------------------- // Script finds all UV Sets applied to polygon objects and conveniently lists them in // a scroll-layout. The UI then provides various options, for example: // - select all, none, all with common name // - delete selected, delete all // - create new, empty UV set with custom name // - copy default UV set to selected UV sets. // // Error handling includes detecting invalid UV Set names (i.e. spaces in names, // numeric-only characters) // // // N.B. Some interference with existing Maya UI Layouts // // Usage: skWindowCreateUVSetEditorUI(); // opens the UV Sets Made Easy editor UI // // // v0.1 - basic functionality and basic error handling // by Steven Kent, 2008 :: www.steven-kent.com // --------------- Procedure for collecting objects in an array global proc skGetObjects() { global int $gSkUserSelect = 1; global string $gSkReadObjects[]; string $selectedObjects[]; int $invalidStringType; switch ($gSkUserSelect) { case 1: $selectedObjects = `ls -selection -dag -type geometryShape`; break; case 2: $selectedObjects = `ls -dag -type geometryShape `; break; } clear $gSkReadObjects; $gSkReadObjects = $selectedObjects; } // --------------- Procedure for the main UI global proc skWindowCreateUVSetEditorUI() { global int $gSkUserSelect; global string $gSkReadObjects[]; global int $gSkFlag = 0; clear $gSkReadObjects; selectMode -object; // Create window with default name: sk_DefaultWindowName // and delete the UI if it already exists. if ( `window -exists skUvSetEditorWindow` ) deleteUI -window skUvSetEditorWindow; // Create the window window -menuBar true -title "UV Sets Made Easy" -rtf false -sizeable false -maximizeButton false -widthHeight 400 500 skUvSetEditorWindow; scriptJob -parent "skUvSetEditorWindow" -event "SelectionChanged" "skRefreshUI(1)"; scriptJob -parent "skUvSetEditorWindow" -event "SceneOpened" "skDeleteUI()"; // Call procedure for the menu layout skWindowCreateFormLayout(); // show the window showWindow; skRefreshUI(1); } // --------------- procedure fixes uv set names, using the fixSpacesInNames procedure global proc string skFixUvSetNames (string $inputName, string $useObject) { string $confirm; int $i = 0; int $flag = 0; string $confirmTitle = ("Bad names found?"); $confirm = `confirmDialog -title $confirmTitle -message ("\"" + $inputName + "\" has invalid characters and will be changed.\nAre you sure? ") -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; if ($confirm == "Yes") { //... continue } else { $gSkUserSelect = 1; select -cl; string $confirmDialogText; $confirmDialogText = ("This tool will now close. \nPlease try again later."); confirmDialog -title "Bad UV Set name found" -message $confirmDialogText -button "OK, thanks" -defaultButton "OK, thanks" -cancelButton "OK, thanks" -dismissString "OK, thanks"; } polyUVSet -currentUVSet -uvSet $inputName $useObject; $outputName = skFixSpacesInNames($inputName); do { if (catch (`polyUVSet -rename -newUVSet $outputName`)) { string $noSuffix = `match ".*[^0-9]" $outputName`; int $suffix = `match "[0-9]+$" $outputName`; $suffix++; $outputName = $noSuffix + $suffix; } else { $flag = 1; } } while ($flag == 0); print ("Renamed \"" + $inputName + "\" to \"" + $outputName + "\".\n"); skRefreshUI(0); return $outputName; } // --------------- procedure detects spaces in names and creates one string out of the words global proc string skFixSpacesInNames(string $inputName) { int $catchSpaces = 0; string $buffer[]; string $collected; string $outputName; int $invalidStringType; $invalidStringType = 0; // check why the string is invalid if (isValidString($inputName, "([a-zA-Z]+)([a-zA-Z0-9_])*")) { //... continue } else if (isValidString($inputName, "([a-zA-Z]+)([a-zA-Z0-9_ ])*")) { print ($inputName + " contains spaces and will be changed.\n"); $invalidStringType = 1; } else if (isValidString($inputName, "([0-9])*")) { print ($inputName + " contains only numbers and will be changed.\n"); $invalidStringType = 2; } else if (isValidString($inputName, "([0-9_ ])*")) { print ($inputName + " contains numbers and spaces and will be changed.\n"); $invalidStringType = 3; } else { print ($inputName + " is somehow not valid and will be changed.\n"); $invalidStringType = 1; } // execute the correct fix if ($invalidStringType == 1) { string $inputNameTemp = $inputName; $catchSpaces = `tokenize $inputNameTemp $buffer`; if ($catchSpaces >= 1) { string $collected = ""; for ($item in $buffer) $collected = $collected + $item; print ("\nRenamed \"" + $inputName + "\" to \"" + $collected + "\".\n"); $outputName = $collected; } } else if ($invalidStringType == 2) { int $uniqueName = `rand 10000`; $outputName = ("autoRenamed_" + $inputName + "_" + $uniqueName); } else if ($invalidStringType == 3) { string $inputNameTemp = $inputName; $catchSpaces = `tokenize $inputNameTemp $buffer`; if ($catchSpaces >= 1) { string $collected = ""; for ($item in $buffer) $collected = $collected + $item; print ("\nRenamed \"" + $inputName + "\" to \"" + $collected + "\"."); $outputName = ("autoRenamed" + $collected); } } return $outputName; } // --------------- Procedure for creating the main layout global proc skWindowCreateFormLayout() { global int $gSkUserSelect; global string $gSkReadObjects[]; // Commands for MenuItems string $deleteAllCmd; string $deleteSelectedCmd; string $selectAllListedCmd[]; string $createEmptyCmd; string $copyUVSetsCmd; string $selectAllUVSetsCmd; string $selectNoneUVSetsCmd; string $descriptionCmd; string $aboutCmd; $deleteAllCmd = ("skDeleteUVSets(\"deleteAll\")"); $deleteSelectedCmd = ("skDeleteUVSets(\"deleteSelected\")"); int $i = 0; for ($z in skGetCombinedSets()) { $selectAllListedCmd[$i] = ("skSelectUVSets(\"" + $z + "\")"); $i++; } $createEmptyCmd = ("skCreateEmptySets()"); $copyUVSetsCmd = ("skCopyUVSets()"); $selectAllUVSetsCmd = ("skSelectUVSets(\"selectAll\")"); $selectNoneUVSetsCmd = ("skSelectUVSets(\"selectNone\")"); $descriptionCmd = ("skPopupToolDescription()"); $aboutCmd = ("skPopupAbout()"); $WebsiteCmd = ("showHelp -a \"http://www.steven-kent.com/\""); //set up the menu menu -label "Options" -allowOptionBoxes false skMainMenu; menuItem -subMenu true -label "Delete"; menuItem -label "All UV Sets" -command $deleteAllCmd; menuItem -divider true; menuItem -label "Selected UV Sets" -command $deleteSelectedCmd; setParent -menu ..; menuItem -divider true; menuItem -label "Create Empty UV Sets" -command $createEmptyCmd; menuItem -divider true; menuItem -subMenu true -label "Copy UVs from default set"; menuItem -label "to selected UV Sets" -command $copyUVSetsCmd; setParent -menu ..; setParent -menu ..; menu -label "Select UVSets" -allowOptionBoxes false skSelectionMenu; menuItem -label "Select All" -command $selectAllUVSetsCmd; menuItem -label "Select None" -command $selectNoneUVSetsCmd; menuItem -divider true; int $i = 0; for ($z in skGetCombinedSets()) { menuItem -label ("All UV Sets named " + $z) -command $selectAllListedCmd[$i]; $i++; } setParent -menu ..; menu -label "Help" -allowOptionBoxes false helpMenu; menuItem -label "Tool Description" -command $descriptionCmd; menuItem -divider true; menuItem -label "Visit Website... " -command $WebsiteCmd; menuItem -divider true; menuItem -label "About" -command $aboutCmd; setParent -menu ..; // Create main layout formLayout mainLayout; columnLayout userSelectLayout1; // Create radio buttons for objects listed string $radioButton1Cmd; string $radioButton2Cmd; $radioButton1Cmd = ("$gSkUserSelect = 1;skRefreshUI(1)") ; $radioButton2Cmd = ("$gSkUserSelect = 2;skRefreshUI(1)"); radioButtonGrp -numberOfRadioButtons 2 -label "List Objects in Scene" -select $gSkUserSelect -labelArray2 "Selection" "All" -onCommand1 $radioButton1Cmd -onCommand2 $radioButton2Cmd; setParent..; scrollLayout -childResizable true mainScroll; columnLayout subScrollLayout1; // Call procedure for the scroll layout rowColumnLayout -numberOfColumns 1 -columnWidth 1 375 subScrollLayout2; // create a collapsable frame layout for each object if (size($gSkReadObjects) != 0) { for( $useObject in $gSkReadObjects ) { $getUvSets = `polyUVSet -q -allUVSets $useObject`; frameLayout -collapsable true -label $useObject $useObject; // define the layout of controls added columnLayout subLayout3; for ($UVSetName in $getUvSets) { string $defaultUvSetName = `getAttr ($useObject + ".uvSet[0].uvSetName")`; if ($UVSetName == $defaultUvSetName) checkBox -label $UVSetName -align "left" -enable false $UVSetName; else checkBox -label $UVSetName -align "left" -value false $UVSetName; } setParent ..; setParent ..; } } setParent ..; // Edit the main layout formLayout -edit -af userSelectLayout1 "top" 10 -af userSelectLayout1 "left" 10 -af userSelectLayout1 "right" 10 -an userSelectLayout1 "bottom" -ac mainScroll "top" 10 userSelectLayout1 -af mainScroll "left" 10 -af mainScroll "right" 10 -af mainScroll "bottom" 10 mainLayout; } // --------------- Procedure for refreshing the UV Editor UI global proc skRefreshUI(int $overrideConfirm) { selectMode -object; // declare global variables global string $gSkReadObjects[]; global int $gSkUserSelect; global int $gSkFlag; // reassign relevant objects to array skGetObjects(); string $confirm; string $confirmTitle = (size($gSkReadObjects) + " objects found."); if (size($gSkReadObjects) > 100 && $overrideConfirm != 0) { $confirm = `confirmDialog -title $confirmTitle -message "Refreshing may take a few seconds. Are you sure?" -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; } if ($confirm == "No") { $gSkReadObjects = {}; $gSkUserSelect = 1; select -cl; } // Check if the main UI exists if ( `window -exists skUvSetEditorWindow` ) { deleteUI skUvSetEditorWindow|mainLayout; deleteUI skUvSetEditorWindow|skMainMenu; deleteUI skUvSetEditorWindow|skSelectionMenu; deleteUI skUvSetEditorWindow|helpMenu; skWindowCreateFormLayout(); } else error "\"UV Sets Made Easy\" UI does not exist"; } global proc skDeleteUI() { if ( `window -exists skUvSetEditorWindow` ) deleteUI -window skUvSetEditorWindow; if ( `window -exists skDescriptionPopupWindow` ) deleteUI -window skDescriptionPopupWindow; if ( `window -exists skAboutPopupWindow` ) deleteUI -window skAboutPopupWindow; } // --------------- Procedure to collect all UV Sets on all relevant objects global proc string[] skGetCombinedSets() { // declare global variables global string $gSkReadObjects[]; string $combinedUvSets[] = {}; string $flag; for( $useObject in $gSkReadObjects ) { $getUvSets = `polyUVSet -q -allUVSets $useObject`; string $defaultUvSetName = `getAttr ($useObject + ".uvSet[0].uvSetName")`; for ($a in $getUvSets) { if ($a != $defaultUvSetName) { $flag = "false"; for ($i in $combinedUvSets) { if ($a == $i) $flag = "true"; } if ($flag == "false") $combinedUvSets[size($combinedUvSets)] = $a; } } } $combinedUvSets = `sort $combinedUvSets`; return $combinedUvSets; } // --------------- Procedure to delete uv sets, either by selection, or all. global proc skDeleteUVSets(string $deleteWhat) { // declare global variables global string $gSkReadObjects[]; string $getUvSets[]; string $findCheckBox; int $checkValue; if (size($gSkReadObjects) != 0) { for( $useObject in $gSkReadObjects ) { $getUvSets = `polyUVSet -q -allUVSets $useObject`; string $defaultUvSetName = `getAttr ($useObject + ".uvSet[0].uvSetName")`; for ( $uvSetName in $getUvSets ) { $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); if ( catch( `checkBox -query -value $findCheckBox` )) { warning ("Couldn't work with " + $uvSetName + " on " + $useObject + ".\n"); $uvSetName = skFixUvSetNames($uvSetName, $useObject); $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); } else $checkValue = `checkBox -query -value $findCheckBox`; // Override checkboxes if delete all is chosen. if ($deleteWhat == "deleteAll" && $uvSetName != $defaultUvSetName) { $checkValue = 1; } else if ($deleteWhat == $defaultUvSetName) print ("I'd like to delete " + $uvSetName + "... but I won't, because it's the default set. \n"); if ( $checkValue == 1) { print ("Deleting UV Set \"" + $uvSetName + "\" from object " + $useObject + "\n"); polyUVSet -currentUVSet -uvSet $uvSetName $useObject; polyUVSet -delete -uvSet $uvSetName $useObject; } } } } skRefreshUI(0); } // --------------- Procedure to select checkboxes, either selected, all or none. global proc skSelectUVSets(string $selectWhat) { //declare global variables global string $gSkReadObjects[]; string $findCheckBox; string $findValue; if (size($gSkReadObjects) != 0) { for( $useObject in $gSkReadObjects ) { $getUvSets = `polyUVSet -q -allUVSets $useObject`; string $defaultUvSetName = `getAttr ($useObject + ".uvSet[0].uvSetName")`; for ( $uvSetName in $getUvSets ) { $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); if ( catch( `checkBox -query -value $findCheckBox` )) { warning ("Couldn't work with " + $uvSetName + " on " + $useObject + ".\n"); $uvSetName = skFixUvSetNames($uvSetName, $useObject); $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); } $checkValue = `checkBox -query -value $findCheckBox`; checkBox -edit -value off $findCheckBox; // Override checkboxes if select all is chosen. if ($selectWhat == "selectAll" && $uvSetName != $defaultUvSetName) checkBox -edit -value on $findCheckBox; else if ($selectWhat == "selectNone") checkBox -edit -value off $findCheckBox; else if ($selectWhat == $uvSetName && $selectWhat != $defaultUvSetName) checkBox -edit -value on $findCheckBox; } } } } // --------------- Procedure to create empty UV Sets for all listed objects global proc skCreateEmptySets() { //declare global variables global string $gSkReadObjects[]; // get name for new UV Sets string $text; if (size($gSkReadObjects) != 0) { // --- create a prompt dialog to request the users name string $result = `promptDialog -title "Name for new UV Sets" -message "Enter UV Set Name:" -button "OK" -button "Cancel" -defaultButton "OK" -cancelButton "Cancel" -dismissString "Cancel"`; if ($result == "OK") { $text = `promptDialog -query -text`; //create empty UV Sets for read objects for ( $useObject in $gSkReadObjects ) polyUVSet -create -uvSet $text $useObject; } skRefreshUI(0); } } // --------------- Procedure to copy UV Sets from default set to selected sets. global proc skCopyUVSets() { //declare global variables global string $gSkReadObjects[]; global int $gSkUserSelect; string $findCheckBox; string $findValue; // copy UVs of map1 to selected UV Sets if (size($gSkReadObjects) != 0) { for( $useObject in $gSkReadObjects ) { $getUvSets = `polyUVSet -q -allUVSets $useObject`; string $defaultUvSetName = `getAttr ($useObject + ".uvSet[0].uvSetName")`; for ( $uvSetName in $getUvSets ) { $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); if ( catch( `checkBox -query -value $findCheckBox` )) { warning ("Couldn't work with " + $uvSetName + " on " + $useObject + ".\n"); $uvSetName = skFixUvSetNames($uvSetName, $useObject); $findCheckBox = ("skUvSetEditorWindow|mainLayout|mainScroll|subScrollLayout1|subScrollLayout2|" + $useObject + "|subLayout3|" + $uvSetName); } $findValue = `checkBox -query -value $findCheckBox`; if ($findValue == 1) { if ($uvSetName != $defaultUvSetName) { print ("Copied UVs of \"" + $defaultUvSetName + "\" to \"" + $uvSetName + "\" on object \"" + $useObject + "\".\n"); polyUVSet -currentUVSet -uvSet $uvSetName $useObject; polyCopyUV -ch off -uvSetNameInput $defaultUvSetName -uvSetName $uvSetName $useObject; select -r $useObject; } } } } } select -cl; if ($gSkUserSelect == 1) { for ($useObject in $gSkReadObjects) select -tgl $useObject; } skRefreshUI(0); } // --------------- Procedure to create "About" popup window global proc skPopupAbout() { // Create a window with the default name: skInstructionsPopup if ( `window -exists skAboutPopupWindow` ) deleteUI -window skAboutPopupWindow; if ( `window -exists skUvSetEditorWindow` ) deleteUI -window skUvSetEditorWindow; // Create the window. window -menuBar true -title "About UV Sets Made Easy" -rtf false -sizeable false -maximizeButton false -widthHeight 400 200 skAboutPopupWindow; string $closeAboutWindow; $closeAboutWindow = "deleteUI -window skAboutPopupWindow;skWindowCreateUVSetEditorUI();"; formLayout aboutLayout; string $column = `columnLayout -adjustableColumn true`; text -label "About UV Sets Made Easy v0.1\n\n" -align "center" -font "boldLabelFont"; text -label "Created by Steven Kent, 2008\n\n\n\n" -align "center"; text -label "www.steven-kent.com\n" -align "left"; setParent..; string $column2 = `columnLayout`; string $b1 = `button -label " OK, take me back to the tool! " -command $closeAboutWindow`; setParent..; formLayout -edit -af $column "top" 10 -af $column "left" 15 -af $column "right" 15 -an $column "bottom" -an $column2 "top" -an $column2 "left" -af $column2 "right" 15 -af $column2 "bottom" 15 aboutLayout; showWindow; } // --------------- Procedure to create "Description" popup window global proc skPopupToolDescription() { // Create a window with the default name: skDescriptionPopup if ( `window -exists skDescriptionPopupWindow` ) deleteUI -window skDescriptionPopupWindow; if ( `window -exists skUvSetEditorWindow` ) deleteUI -window skUvSetEditorWindow; // Create the window. window -menuBar true -title "Tool Description UV Sets Made Easy" -rtf false -sizeable false -maximizeButton false -widthHeight 400 200 skDescriptionPopupWindow; string $closeDescriptionWindow; $closeDescriptionWindow = "deleteUI -window skDescriptionPopupWindow;skWindowCreateUVSetEditorUI()"; formLayout descriptionLayout; string $column = `columnLayout -adjustableColumn true`; text -label "UV Sets Made Easy v0.1" -align "center" -font "boldLabelFont"; text -label "Script finds all UV Sets applied to polygon objects and conveniently \nlists them in a scroll-layout.\nThe UI then provides various options, for example:" -align "left"; text -label "- select all, none, all with common name\n- delete selected, delete all\n- create new, empty UV set with custom name\n- copy default UV set to selected UV sets. \n" -align "left"; setParent..; string $column2 = `columnLayout`; string $b1 = `button -label " OK, take me back to the tool! " -command $closeDescriptionWindow`; setParent..; formLayout -edit -af $column "top" 10 -af $column "left" 15 -af $column "right" 15 -an $column "bottom" -an $column2 "top" -an $column2 "left" -af $column2 "right" 15 -af $column2 "bottom" 15 descriptionLayout; showWindow; }