/* NAME: dbTransferAttributes.mel VERSION: 1.0 CATEGORY: Utilities FUNCTION: A script that transfers over incoming and outgoing connections onto a set of new attributes with the ability to automate the process based on selection in the Maya viewport, as well as having the ability for command based functions. USAGE: 1. Copy the dbTransferAttributes.mel into your Maya Scripts directory (Usually found in "My Documents\maya\\scripts\"). 2. Select attributes in the channel box that you wish to break out. 4. In the Maya Script Editor, type in "source dbTransferAttributes; dbMakeControlAndTransfer;" 5. View the source file for more info on command-line functions. AUTHOR: David Bokser E-MAIL: me@davidbokser.com WEBSITE: www.davidbokser.com */ // OTHER FUNCTIONS: // for automatically taking in the selected channels and source object and // creating a text based controller from the selected attributes, use: // run "source dbTransferAttributes; dbMakeControlAndTransfer; // // For command based automation run: // source dbTransferAttributes; dbTransferAttributesCL(string $source, string $target, string $sourceAttr, string $targetAttr, int $overrideTarget) // // To transfer attributes to a specified controller instead of a text based // one use: // source dbTransferAttributes; dbTransferAttributes(string $destObj) // // VERSION HISTORY: // November 22nd, 2007 - initial release // // TODO: // - Create a GUI to specify source objects, attributes, and targets // - Add the functionality to delete the source attributes after transfer // // -------------------------------------------------------------------------- // takes the selected object and attributes and transfers over the connections // to the given destination object global proc dbTransferAttributes(string $destObj) { string $selected[] = `ls -sl -fl`; string $channels[] = `channelBox -q -sma mainChannelBox`; if(`size($selected)` > 1) warning ("Multiple objects selected. Using the first one: " + $selected[0]); string $obj = $selected[0]; for($attr in $channels) { dbTransferAttributesCL($obj, $destObj, $attr, $attr, 1); } } // the meat of the script, this reconnects everything from a source object and // attribute onto a new target object and attribute. It will create the attribute // if it doesn't exist. If the attribute does exist, it takes in the override // flag in case you want to override the incoming connections on that attribute // or error out. global proc int dbTransferAttributesCL(string $source, string $target, string $sourceAttr, string $targetAttr, int $overrideTarget) { if(`objExists ($target + "." + $targetAttr)` && !$overrideTarget) error "Attribute already exists on target. Specify a new attribute"; else if(`objExists ($target + "." + $targetAttr)` && $overrideTarget) { warning "Attribute already exists on target. Overriding incoming connections but keeping outgoing connections"; string $incoming[] = `listConnections -d off -s on -p 1 ($target + "." + $targetAttr)`; for($connection in $incoming) { disconnectAttr $connection ($target + "." + $targetAttr); } } else { string $type = `getAttr -typ ($source + "." + $sourceAttr)`; addAttr -ln $targetAttr -at $type $target; } // get the source attribute properties string $min = `addAttr -q -min ($source + "." + $sourceAttr)`; string $max = `addAttr -q -max ($source + "." + $sourceAttr)`; warning "You're here"; int $locked = `getAttr -l ($source + "." + $sourceAttr)`; int $keyable = `getAttr -k ($source + "." + $sourceAttr)`; float $val = `getAttr ($source + "." + $sourceAttr)`; int $channelBox = `getAttr -cb ($source + "." + $sourceAttr)`; setAttr ($target + "." + $targetAttr) $val; if($min != "") { float $mini = $min; addAttr -e -min $mini ($target + "." + $targetAttr); } if($max != "") { float $maxi = $max; addAttr -e -max $maxi ($target + "." + $targetAttr); } // get the connections from the source string $incoming[] = `listConnections -d off -s on -p 1 ($source + "." + $sourceAttr)`; string $outgoing[] = `listConnections -d on -s off -p 1 ($source + "." + $sourceAttr)`; // break the source connections for($connection in $incoming) { disconnectAttr $connection ($source + "." + $sourceAttr); } for($connection in $outgoing) { disconnectAttr ($source + "." + $sourceAttr) $connection; } // attach the connections to the target for($connection in $incoming) { connectAttr $connection ($target + "." + $targetAttr); } for($connection in $outgoing) { connectAttr ($target + "." + $targetAttr) $connection; } setAttr -l $locked -cb $channelBox -k $keyable ($target + "." + $targetAttr); return 1; } // Automatically takes in the selected attributes in the channel box // and the first object selected and creates a text controller // and transfers over the attributes from that controller. global proc dbMakeControlAndTransfer() { string $text; string $result = `promptDialog -title "Controller Name" -message "Enter Controller Name:" -button "OK" -button "Cancel" -defaultButton "OK" -cancelButton "Cancel" -dismissString "Cancel"`; if ($result == "OK") { $text = `promptDialog -query -text`; string $prefix = ""; if(`objExists ($text + "CTRL")`) { string $result = `promptDialog -title "Prefix" -message "Object already exists! Please enter a prefix:" -button "OK" -button "Cancel" -defaultButton "OK" -cancelButton "Cancel" -dismissString "Cancel"`; if ($result == "OK") { $prefix = `promptDialog -query -text`; } else error "No prefix given. Canceling operation!"; } if(`objExists ($prefix + "_" + $text + "CTRL")`) { confirmDialog -title "Error" -message "That object also exists. Please try again with a new name." -button "Ok." -defaultButton "Ok" -cancelButton "Ok" -dismissString "Ok"; error "That object also exists. Please try again with a new name."; } string $selected[] = `ls -sl -fl`; string $controller = dbCreateTextController($text, $prefix); string $controllerGrp = `group $controller`; string $grpName = `substitute "CTRL" $controller "GRP"`; $controllerGrp = `rename $controllerGrp $grpName`; parentConstraint $selected[0] $controllerGrp; move -r 0 5 0 $controller; setAttr -keyable false -channelBox false ($controller + ".tx"); setAttr -keyable false -channelBox false ($controller + ".ty"); setAttr -keyable false -channelBox false ($controller + ".tz"); setAttr -keyable false -channelBox false ($controller + ".rx"); setAttr -keyable false -channelBox false ($controller + ".ry"); setAttr -keyable false -channelBox false ($controller + ".rz"); setAttr -keyable false -channelBox false ($controller + ".sx"); setAttr -keyable false -channelBox false ($controller + ".sy"); setAttr -keyable false -channelBox false ($controller + ".sz"); select -r $selected[0]; dbTransferAttributes($controller); } } // creates a text controller with a single transform instead of // a multiple transform text object. global proc string dbCreateTextController(string $text, string $prefix) { if($prefix != "") $prefix += "_"; string $textGrp[] = `textCurves -ch 0 -f "Arial Black|h-13|w400|c0" -t $text`; select -hi $textGrp[0]; string $curves[] = `ls -sl -type nurbsCurve`; string $directRelatives[] = `listRelatives -children $textGrp[0]`; select $directRelatives; parent -w; for($curve in $curves) { string $parent[] = `listRelatives -parent $curve`; select $parent; parent -w; makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $parent; parent -add -shape $curve $textGrp[0]; delete $parent; } delete $directRelatives; $textGrp[0] = `rename $textGrp[0] ($prefix + $text + "CTRL")`; string $grp = `group $textGrp[0]`; move -rpr 0 0 0 $grp; parent -w $textGrp[0]; delete $grp; move 0 0 0 ($textGrp[0] + ".scalePivot") ($textGrp[0] + ".rotatePivot") ; makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $textGrp[0]; return $textGrp[0]; }