Skip to content

Instantly share code, notes, and snippets.

@leestuartx
Created November 7, 2019 21:55
Show Gist options
  • Save leestuartx/c4b654dcce9bbea62167d9ad3a580497 to your computer and use it in GitHub Desktop.
Save leestuartx/c4b654dcce9bbea62167d9ad3a580497 to your computer and use it in GitHub Desktop.
/*
*
Steps:
Make sure there is a "_BS" on all the blendshapes
then set the fps to 30
then we are going to set the initial keyframe to 0
set max keyframe to 70
run "SetAllKeyframesToZero()" on the blendshape node
run "KeyAllBlendshapesFromFile("A:/latestPoseList_v2.txt"); on the blendshape node
set the material
optimize scene
save
export all
import into ue4
create pose asset
create secondary pose asset
*/
//Extract all the blendshapes for a model //ExtractAllFaceShapes("body_mesh", "jennifer_body");
global proc ExtractAllFaceShapes(string $baseMeshName, string $charName)
{
select - r $baseMeshName;
string $allShapes[] = `listAttr - m($charName + ".w")`;
for ($curShape in $allShapes)
{
//print("shape:" + $curShape + "\r\n");
ExtractShape($baseMeshName, $charName, $curShape);
}
}
global proc ExtractShape(string $baseMeshName, string $charName, string $blendshapeName)
{
if ($blendshapeName != "worldMesh[0]")
{
string $mName = ($charName + "." + $blendshapeName);
evalDeferred("TurnOnAttr (\"" + $mName + "\")");
evalDeferred("DupModel (\"" + $baseMeshName + "\",\"" + ($blendshapeName + "_BS") + "\")");
evalDeferred("TurnOffAttr (\"" + $mName + "\")");
}
}
global proc TurnOnAttr(string $attrName)
{
setAttr $attrName 1;
}
global proc DupModel(string $oldMeshName, string $newMeshName)
{
select - r $oldMeshName;
duplicate - rr;
string $newBlendshapeMdl = `rename $newMeshName`;
}
global proc TurnOffAttr(string $attrName)
{
setAttr $attrName 0;
}
global proc SetAllKeyframesToZero(string $blendShapeName)
{
if(`objExists($blendShapeName)`)
{
int $curKeyframe = 0;
string $allBlendShapes[]=`listAttr -m($blendShapeName + ".w")`;
int $maxKeys = 70;//size($allBlendShapes);
for ($curKeyframe = 0; $curKeyframe < $maxKeys; $curKeyframe++)
{
int $i = 0;
setKeyframe -t $curKeyframe ($blendShapeName + ".envelope");
for ($curShape in $allBlendShapes)
{
setAttr ($blendShapeName + "." + $curShape) 0;
setKeyframe -t $curKeyframe ($blendShapeName + "." + $curShape);
$i +=1;
}
}
}
}
//Function is used to load a text file with a list of all the blendshape names and then sets a key on every blendshape in the order they are set in the text file
global proc KeyAllBlendshapesFromFile(string $blendShapeName, string $filePath)
{
// All the blendshapes listed in the file
string $allBlendshapes[] = jgTextFileToStringArray(0, $filePath);
// All the blendshapes that exist for this blend node
string $existingBlendShapes[]=`listAttr -m($blendShapeName + ".w")`;
int $i = 0;
//For all the shapes in the text file
for($curShape in $allBlendshapes)
{
string $ourBlendshape = `substitute "_P" $curShape ""`;
string $searchName = ("*" + $ourBlendshape + "*");
//For all the shapes that exist in the blend node
for ($curExistingShape in $existingBlendShapes)
{
if (`gmatch $curExistingShape $searchName`) // if the object name contains the name from the file
{
//print ("The shape exists: " + $curShape + "\r\n");
print ($curShape + "\r\n");
setNewKey($i, $blendShapeName, $curExistingShape);
}
}
$i += 1;
}
}
// Reads A Text File And Returns A String Array Of Each Line
global proc string[] jgTextFileToStringArray(int $skipFirstLine, string $filePath) {
// Open File
$fileId = `fopen $filePath "r"` ;
// Define String Array
string $dataArray[] ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data On That Line)
while (size($nextLine) > 0)
{
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Add To Array
$dataArray[size($dataArray)] = $cleanLine ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
// Remove First Line
if($skipFirstLine) stringArrayRemoveAtIndex(0,$dataArray) ;
// Return Array
return $dataArray ;
}
global proc setNewKey(int $curKey, string $bsGroup, string $curShape)
{
//SetKeyframes on current blendshape
setAttr ($bsGroup + "." + $curShape) 1;
setKeyframe -t $curKey ($bsGroup + "." + $curShape);
setAttr ($bsGroup + "." + $curShape) 0;
setKeyframe -t ($curKey+ 1) ($bsGroup + "." + $curShape);
}
global proc RetargetFacewareFace()
{
//Select faceware mesh, then select retarget mesh
string $selectedObj[] = `ls -sl`;
if (size($selectedObj) > 1)
{
print ("Starting retarget");
string $facewareFace = $selectedObj[0];
string $retargetFace = $selectedObj[1];
//Select retarget mesh and duplicate it and offset it's position
select -r $retargetFace;
FreezeTransformations;
ResetTransformations;
CenterPivot;
duplicate -rr;
string $retargetFaceCopy = `rename "retarget_face_copy"`;
move -r -10 0 0 ;
//Then select the faceware face geometry and then shift select the retarget face and transfer vertex position based on uv
select -r $facewareFace;
select -tgl $retargetFace;
transferAttributes -transferPositions 1 -transferNormals 0 -transferUVs 2 -transferColors 2 -sampleSpace 3 -sourceUvSpace "map1" -targetUvSpace "map1" -searchMethod 3-flipUVs 0 -colorBorders 1 ;
//Duplicate this mesh and offset it
select -r $retargetFace;
move -r -5 0 0 ;
duplicate -rr;
move -r -5 0 0 ;
string $retargetFaceCopy2 = `rename "retarget_face_second_copy"`;
//Then in this order,
//1.baseRetargetMesh 2.retarget1Copy 3.retarget2Copy
select -r $retargetFace ;
select -tgl $retargetFaceCopy ;
select -tgl $retargetFaceCopy2 ;
//deform, blendshape
string $newBlendshape2[] = `blendShape -tc 0`;
setAttr ($newBlendshape2[0] + "." + $retargetFaceCopy) 1;
setAttr ($newBlendshape2[0] + "." + $retargetFace) 1;
}
else{
print("Error: Select faceware mesh, then select retarget mesh");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment