// ------------------------------------------------------------------------------ // -- // -- LOAD a file with skinclusters datas // -- // ------------------------------------------------------------------------------ // (c) Copyright by David Lanier 2003 // http://www.dl3d.com // contact@dl3d.com //---------------------------------- DEBUG STUFF ----------------------- proc DavMsgBox(string $s) { confirmDialog -title "Error" -message $s -b "OK"; } proc DebugPrintArray(string $msg[]) { global int $SkinDebug; if ($SkinDebug) { print($msg); print("\n"); } } proc DebugPrint(string $msg) { global int $SkinDebug; if ($SkinDebug) { print($msg + "\n"); } } //--------------------- NODE PARSING ---------------------------------- proc string GetSelNodeFromSelection() { string $currentSelection[] = `ls -sl`; DebugPrint("Current Selection :"); DebugPrintArray($currentSelection); int $SizeOfCurSel = size($currentSelection); if ($SizeOfCurSel != 1) { DavMsgBox("Select 1 skinned object"); return ""; } return $currentSelection[0]; } proc string[] GetJointsFromSkinCluster(string $ClusterName) { string $NULLStringArr[]; string $Joints[]; string $RealJoints[]; //We have twice the list of joints with the following command $Joints = `listConnections -type joint $ClusterName`; //So copy half the array int $size = size($Joints); if ($size <= 0) return $NULLStringArr; DebugPrint("Size of joints array is "+$size); int $halfSize = 0.5 * $size; DebugPrint("Half Size of joints array is "+$halfSize); int $Count = 0; string $Temp = ""; for ($Temp in $Joints) { $RealJoints[$Count++] = $Temp; //Copy the array if ($Count == $halfSize) break; //Finished } return $RealJoints; } proc WriteInfosInSkinCluster(string $TabJoints[], string $TabWeights[], int $TabVtx[]) { global int $SkinDebug; //Extern // Get the currenly selected objects and components string $currentSelection[] = `ls -sl`; DebugPrint("Cur Sel :"); DebugPrintArray($currentSelection); string $SelNode = GetSelNodeFromSelection(); if ($SelNode == "") { DavMsgBox("Select 1 skinned object (not any vertices, only the object)"); return; } //We should only have a skinned object selected //Get the skin cluster linked to our selected node string $ClusterName = findRelatedSkinCluster($SelNode); if ($ClusterName == "") { DavMsgBox("The object "+$SelNode +" is not skinned ! Please choose a skinned object"); return; } DebugPrint("ClusterName :"+$ClusterName); //To memorize the indexes in the skincluster of the joints name from the file //Say there is the joint1 in the file, we'd like to know which is its index in the //skincluster of the selected object in Maya to be able to set the good attribute int $TabIndexOfJointsFromFileInSkinCluster[]; string $JointsFromSkinClusters[] = GetJointsFromSkinCluster($ClusterName); if ($SkinDebug) { DebugPrint ("TabJoints"); DebugPrintArray ($TabJoints); DebugPrint ("JointsFromSkinClusters"); DebugPrintArray ($JointsFromSkinClusters); } int $SizeJointsFromSkinClusters = size($JointsFromSkinClusters); int $SizeTabJoints = size($TabJoints); DebugPrint("Size of tabjoints = "+$SizeTabJoints); DebugPrint("Size of joints from skinclusters = "+$SizeJointsFromSkinClusters); //Check if names of TabJoints are in $JointsFromSkinClusters int $i = 0; int $j = 0; for ($j=0;$j<$SizeTabJoints;$j++) //Get joints from file { int $Found = false; string $JointNameRomTabJoints = $TabJoints[$j]; for ($i=0;$i<$SizeJointsFromSkinClusters;$i++) //Get joints from skin cluster of sel obj { if ($JointNameRomTabJoints == $JointsFromSkinClusters[$i] ) { $TabIndexOfJointsFromFileInSkinCluster[$j] = $i; $Found = true; break; } } if ($Found == false) { //This joint is not in the current skinCluster $TabIndexOfJointsFromFileInSkinCluster[$j] = -1; DebugPrint("The joint named :"+ $TabJoints[$j] + " is in the file but it is not in the current skincluster of the selected object"); } } //So now you can set the weights int $NumJoints = size($TabJoints); int $NumVtx = size($TabVtx); DebugPrint("NumJoints : "+$NumJoints); DebugPrint("NumVtx : "+$NumVtx); int $vtxIndex = 0; for ($vtxIndex=0;$vtxIndex<$NumVtx;$vtxIndex++) { for ($JointIndex=0;$JointIndex<$NumJoints;$JointIndex++) { int $indexInTabIndexOfJointsFromFileInSkinCluster = $TabIndexOfJointsFromFileInSkinCluster[$JointIndex]; if ($indexInTabIndexOfJointsFromFileInSkinCluster == -1) continue; //This joint is not in the current skinCluster, so continue DebugPrint("Joint Index = " + $JointIndex); DebugPrint("Index in tab index of joints from file in skinCluster = "+$indexInTabIndexOfJointsFromFileInSkinCluster); int $indexInTabWeight = ($vtxIndex*$NumJoints)+$JointIndex; DebugPrint("Index in tabweight = "+$indexInTabWeight); float $Weight = $TabWeights[$indexInTabWeight]; string $Temp = $ClusterName + ".weightList[" + $vtxIndex + "].weights[" + $indexInTabIndexOfJointsFromFileInSkinCluster + "] " + $Weight; eval("setAttr "+$Temp); //Set the attribute } } DavMsgBox("OK, everything seems fine for me."); } proc LoadWeightsFromFile() { string $SelNode = GetSelNodeFromSelection(); if ($SelNode == "") { DavMsgBox("Select 1 skinned object (not any vertices, only the object)"); return; } //Here is a complete example of the kind of file we should have to read. //While tags ( = strings between ****) can change // *************Skinning-Weights-File-DLanier************* // *************Joints************* // joint1 joint2 joint3 joint4 // *************Weights************* // vtx0 // 0.009708336554 0.473375231 0.473375231 0.04354116693 // vtx1 // 0.003694577608 0.0544359386 0.4709347486 0.4709347486 // vtx2 // 0.473387599 0.473387599 0.04237246141 0.010852376 // vtx3 // 0.4683769345 0.4721248746 0.04765871912 0.01183938608 // vtx4 // 0.5454077721 0.3821890056 0.0526313521 0.01977190748 // vtx5 // 0.5196709037 0.3956035078 0.06144377589 0.02328189276 global string $KTag = "*************Skinning-Weights-File-DLanier*************"; global string $WeightTag = "*************Weights*************"; global string $JointTag = "*************Joints*************"; global int $SkinDebug; //Extern //We're going to read the datas from the file and set them in these 3 arrays string $TabJoints []; //To memorize Joints names string $TabWeights []; //To memorize weights int $TabVtx []; //To memorize vertices numbers int $NumWeights =0; //To scan the tabweights int $NumJoints =0; //To scan the tabjoints int $NumVtx =0; //To scan the vertex array //Choose the file to load string $FileName = `fileDialog -dm "*.*"`; DebugPrint ("File to load :"+$FileName); //Open this file to read it int $OpenFileID = `fopen $FileName "r"`; //Get all contents and save it in an array before using it string $nextWord = `fgetword $OpenFileID`; //Compare it to the K Tag if ($nextWord != $KTag) { DavMsgBox("This is not a valid skinning file"); //Close file fclose $OpenFileID; return; } //This one should be the joint tag $nextWord = `fgetword $OpenFileID`; if ($nextWord != $JointTag) { error("We should have the joint tag now"); //Close file fclose $OpenFileID; return; } //Now read joints names while ( (! `feof($OpenFileID)`) ) { //Get the joints names in an array $nextWord = `fgetword $OpenFileID`; if ($nextWord == $WeightTag) break; DebugPrint("Joint name :"+$nextWord); //Memorize this joint in our array $TabJoints[$NumJoints++] = $nextWord; } //We now have in $NumJoints the number of joints used for this skinning DebugPrint("NumJoints = "+ $NumJoints); //We should now be onthe weight tag if ($nextWord != $WeightTag) { //A problem occured, so quit error("We should have the weight tag now"); //Close file fclose $OpenFileID; return; } //To get the vtx indexes string $buf[]; //Now there should have only the vtx index and their weights in the file while ( 1 ) { DebugPrint("Beginning of while loop"); //Erase array clear ($buf); //Now read vtx and weights values $nextWord = `fgetword $OpenFileID`; if (`feof($OpenFileID)`) { //Ok, we have finished break; } DebugPrint("This string should be vtx :"+$nextWord); //The $nextword string should now contain a vtx index (like vtx133 for example), let's get the indexes tokenize($nextWord,"vtx",$buf); if ( size($buf) != 1) { //A problem occured, so quit error("We should have the weight tag now"); //Close file fclose $OpenFileID; return; } //Memorize this vtx index in our array $TabVtx[$NumVtx++] = $buf[0]; //Now get the weights values from this vtx index int $i=0; DebugPrint("Entering for loop with numjoints"); for ($i = 0;$i<$NumJoints;$i++) { $nextWord = `fgetword $OpenFileID`; DebugPrint("This should be a weight :"+$nextWord); if (`feof($OpenFileID)`) { //A problem occured, so quit error("We shouldn't have reach the eof"); //Close file fclose $OpenFileID; return; } //memorize weight $TabWeights[$NumWeights++] = $nextWord; } } //Close file fclose $OpenFileID; //Check if everyhing is ok if ($NumWeights != ($NumJoints * $NumVtx) ) { error("An error occured, $NumWeights != ($NumJoints * $NumVtx)"); return; } //Debugging arrays if ($SkinDebug) { DebugPrint("Num Joints = "+$NumJoints); DebugPrint("Num Weights = "+$NumWeights); DebugPrint("Num Vtx = "+$NumVtx); int $i =0; string $Temp; DebugPrint("Printing TabJoints"); for ($Temp in $TabJoints) { DebugPrint($Temp); } DebugPrint("Printing TabWeights"); for ($Temp in $TabWeights) { DebugPrint($Temp); } DebugPrint("Printing TabVtx"); for ($i in $TabVtx) { DebugPrint($i); } } //Now write everything in the skincluster WriteInfosInSkinCluster($TabJoints, $TabWeights, $TabVtx); } //------------------------ FILE STUFF ---------------------------------------- global proc l(int $ParamDebug) { //Set the debug or not global int $SkinDebug; $SkinDebug = $ParamDebug; LoadWeightsFromFile(); } //-------------------------- MEL CODE EXECUTED ------------------------------ l(0); //Don't show debug info