The short of it:
- Import your new beard/gotee whatever
- Position it where you want it in relation to a ZEROED out Morphy face
- Select your custom mesh, then his face mesh
- Source and run script
- Go grab some candy. Preferably dark chocolate.
- Come back and animate.
For those of you interested, here's how I go about tackling things like that. First I figure out what I want the script to do. Here's my original "plan" notes:
- Process to be scripted
- Select $customGeo followed by deformingMesh
- Create wrapDeformer
- Get blendshape channels into array
- For loop
- for each blendshape channel on the deforming mesh (limit by facial region?)
- Get input connector value and put in $driverArray
- Break the connection on the blendshapeChannel
- turn channel value to 1
- duplicate $customGeo to freeze it
- Add new geo name to $bakedCustomGeo string array
- position new geo
- reconnect the connecter value with data from $driverArray
- Put all new blendshape geo in new group
- Name group
- Connect all new geo back into original geo as blendshape node ($customGeoBaseName_bsNode)
Of course that's not going to be everything as lots of stuff rears it's head and must be put down like a many headed beast trying to devour your time. Next thing I do is look through scripts I have or can find online that might have similar functions I can hack (see my previous hacking other people's scripts post). I had used a great script written Asi Sudai called extractBlendshapes. It will take a mesh with a blendshape that you want to get the blendshapes from if, say for example, you deleted the original target meshes. It even puts them in a handy visual columns/rows format in worldspace. I made judicous use of large chunks of his code for the duplication and extraction function. I just modified it to duplicate the wrap deformed customGeo instead of the main mesh then did all the rest of the stuff I needed to do to get things working.
Also, thanks to my buddy David Bokser who helped me out with a syntax issue I was getting stuck on last night.
Also, thanks to my buddy David Bokser who helped me out with a syntax issue I was getting stuck on last night.
Here's the script (sorry, I don't have the best coding practices as I'm still a novice at it):
/*
TITLE: jbMorpheusFacialCustomGeoBaker
VERSION: 1.0
AUTHOR:Josh Burton
www.joshburton.com
DATE: August 26, 2010
DESCRIPTION:
Script for baking out custom facial geo for the Morpheus Rig.
DISCLAIMER:
If your computer explodes, I didn't do it.
HOW TO USE:
1. First select the custom geo to bake
2. Then select the head (to wrap it to)
3. Run script
HISTORY:
08.26.10 - BIRTH!
Acknowledgements -
1. Blendshape extraction, size, existance checking from extractBlendShapes - Asi Sudai
asi@asimation.com www.reel.asimation.com
2. David Bokser for helping me fix some of my syntax issues
*/
//sub Procs
// Debuging printing proc - Acknowledgement 1
proc extractBlendShape.debug(string $msg)
{
if (1==1)
print ("\n***Debug: " + $msg +"\n");
}// End
// Get object bounding size - Acknowledgement 1
proc extractBlendShape.getBounding(string $node)
{
float $bounding[]=`xform -q -bb $node`;
float $xSize=(`abs $bounding[0]` +`abs $bounding[3]`);
print $xSize;
}// End
// check the object have blendShapes - Acknowledgement 1
proc string extractBlendShape.getBlendShape(string $node)
{
string $shapes[] = `listRelatives -s $node`;
for ($shape in $shapes){
string $tempArray[]=`listConnections -s 1 -d 0 -type "blendShape" ($shape + ".inMesh")`;
if ($tempArray[0] != "") return $tempArray[0];
}
return "none";
}// End
//Main Proc
global proc jbMorpheusFacialCustomGeoBaker() {
//Declaring our intial variables
string $blendShapeNamesBaked[];
string $blendshapeConnections[];
string $currentConnections[];
string $selected[] = `ls -sl`;
//Josh, do an error check to make sure the selection order is correct
$customGeo = $selected[0];
$deformerGeo = $selected[1];
//create and store name of Wrap deformer
string $wrapDeformer[] = `deformer -type wrap $customGeo`;
select -r $customGeo;
select -tgl $deformerGeo;
AddWrapInfluence;
select -cl;
//reorders deformation order for proper baking of skinned mesh
reorderDeformers "tweak1" "face_skinCluster" $deformerGeo;
// Check if object have blendShape node. - Acknowledgement 1
string $blendShapeNode = `extractBlendShape.getBlendShape $deformerGeo`;
if ($blendShapeNode == "none") { print ("\n"+ $deformerGeo + " don't have blendShape"); return; }
// Get all BlendShapes shapes - Acknowledgement 1
extractBlendShape.debug $blendShapeNode;
string $blendShapeNamesShort[] = `listAttr -m ($blendShapeNode + ".weight")`;
int $n = 0;
//Creates a new name for the geo to be baked
for ($name in $blendShapeNamesShort) {
$blendShapeNamesBaked[$n] = $customGeo + "_" + $blendShapeNamesShort[$n];
$n++;
}
// Start extracting
// Get object size, to better spread the blendShapes - Acknowledgement 1
float $bounding[]=`xform -q -bb $customGeo`;
float $boundingSizeX=(`abs $bounding[0]` +`abs $bounding[3]`);
float $boundingSizeY=(`abs $bounding[1]` +`abs $bounding[4]`);
extractBlendShape.debug ("Bounding size = " + $boundingSizeX);
// Start extracting each shape - Acknowledgement 1, changed to export the custom geo instead of the deforming Geo
int $t=1;
string $bakedCustomGeo[];
for ($i=0; $i<`size($blendShapeNamesShort)`; $i++) { int $row = `floor($i/5)`; if ($t>5) $t=1;
extractBlendShape.debug ("doing blendShape - " + $blendShapeNamesShort[$i]);
//queries the connection that goes into the blendshape node and stores it
string $currentBlendShapeChannel = $blendShapeNode + "." + $blendShapeNamesShort[$i];
$currentConnections = `listConnections -d off -p on -s on $currentBlendShapeChannel`;
$blendshapeConnections[$i] = $currentConnections[0];
//breaks connection on blendshape node
disconnectAttr $blendshapeConnections[$i] ($blendShapeNode + "." + $blendShapeNamesShort[$i] ) ;
//back to Asi's code
setAttr ($blendShapeNode + "." + $blendShapeNamesShort[$i] ) 1;
string $bakedCustomGeo[]=`duplicate -name $blendShapeNamesBaked[$i] $customGeo`;
xform -r -t (($boundingSizeX*($t+1.2))*1.1) (($boundingSizeY*$row)*-1) 0 $bakedCustomGeo[0];
setAttr ($blendShapeNode + "." + $blendShapeNamesShort[$i] ) 0;
// Restores connection
connectAttr $blendshapeConnections[$i] $currentBlendShapeChannel;
$t++;
}
//Restores deformation order of the Deformer Geo
reorderDeformers "face_skinCluster" "tweak1" $deformerGeo;
reorderDeformers "face_skinCluster" "face_bsNode" $deformerGeo;
//Delete wrap and connect baked custom geo as blendshapes to original custom geo
delete $wrapDeformer[0];
$customGeoBlendShapeNode = $customGeo+"_bsNode";
blendShape -n $customGeoBlendShapeNode $blendShapeNamesBaked $customGeo ;
//groups our new baked geo for easy cleanup later on
$bakedCustomGeoGroupName = $customGeo+"_bsGeo_grp";
group -n $bakedCustomGeoGroupName $blendShapeNamesBaked;
setAttr ($bakedCustomGeoGroupName +".v") 0;
parent $bakedCustomGeoGroupName customFacialGeo_bsGeo_grp;
//Connects our custom geo blendshape channels to the original deforming mesh channels
int $b=0;
for ($bshape in $blendShapeNamesBaked) {
connectAttr ($blendShapeNode + "." + $blendShapeNamesShort[$b]) ($customGeoBlendShapeNode +"."+ $blendShapeNamesBaked[$b]);
$b++;
}
//Skin the custom geo
$customGeoSkinName = $customGeo+"_skinCluster";
skinCluster -n $customGeoSkinName -tsb qssFaceSkinJoints $customGeo;
//copy the skin weights from the deformer geo to the custom geo
copySkinWeights -ds $customGeoSkinName -ss "face_skinCluster" -noMirror -surfaceAssociation closestPoint -influenceAssociation name;
//renames our original custom geo properly
$customGeoProperName = $customGeo+"_customGeo";
rename $customGeo $customGeoProperName;
//Report complete
print ($customGeoProperName + " exported properly. I'd move the joysticks around to make sure.") ;
}
What else?
- Been doing some polishing on some of the blendshapes for the rig and deformation
- Pushed Nose widener more at a beta tester's request
- Bug fix - eyebrow mover rotation is now properly mirrored
- Moved out the jaw_anim control so it wouldn't get stuck behind beards
- Moved the hair over to using skinning rather than wrap deformers
Now, pardon me but I have some pig tails that were sent in to look at. Keep em comin!
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.