MetaFusion/Reference/SuperRiggingEditor/scripts/SGCloneBlandShape.mel

449 lines
16 KiB
Plaintext
Raw Permalink Normal View History

2025-02-03 22:58:41 +08:00
//******************************************************************************
//
// <20><>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>: <20><>Ϫʱ<CFAA><CAB1><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD>޹<EFBFBD>˾
// <20><>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>: q.100@qq.com
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: 2023/08/08
//
//******************************************************************************
global proc SGCloneBlandShape() {
if (`window -ex wrapChangeBS`){
deleteUI wrapChangeBS;
}
window
-w 300
-h 300
-t "BlendShapeBake"
-menuBar on
wrapChangeBS;
columnLayout -adj 1 -columnAttach "both" 5 -rowSpacing 2 -columnWidth 150 ;
separator -height 10 -style "in";
checkBox -label "Use Wrap Method" -v 1 -cc sparklyWrapConvertBlendCheckRetrun wrapMethod;
if (`exists deltaMush`) {
checkBox -label "DeltaMushTarget" -v 0 -cc sparklyWrapConvertBlendCheckRetrun deltaMushTarget;
intSliderGrp -f on -min 0 -max 100 -w 50 -v 10 deltaIntensity;
separator -height 10 -style "in";
}
else {
text -fn "boldLabelFont" -l "<22>Ͱ汾DeltaMush<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
separator -height 10 -style "in";
}
button -l "Cloning" -c "SGWrapConvertBlend";
button -l "Copy" -c "SGCopyBlend";
button -l "Mirror" -c "SGMirrorBlend";
separator -height 10 -style "in";
window -e
-w 260
-h 85
wrapChangeBS;
showWindow;
}
global proc sparklyWrapConvertBlendCheckRetrun() {
}
global proc string[] sparkey_getBlendShape(string $geo)
{
string $skins[] ;
clear $skins ;
if ($geo == "" || objExists($geo) != true)
return $skins ;
string $hist[] = `listHistory -pdo 1 -il 2 $geo` ;
string $h ;
for ($h in $hist)
{
if (nodeType($h) == "blendShape")
{
$skins[size($skins)] = $h ;
}
}
return $skins ;
}
global proc string[] sparkey_getWrap(string $geo)
{
string $skins[] ;
clear $skins ;
if ($geo == "" || objExists($geo) != true)
return $skins ;
string $hist[] = `listHistory -pdo 1 -il 2 $geo` ;
string $h ;
for ($h in $hist)
{
if (nodeType($h) == "wrap")
{
$skins[size($skins)] = $h ;
}
}
return $skins ;
}
global proc SGWrapConvertBlend() {
string $sel[] = `ls -sl`;
if (size($sel) == 2) {
string $bs[] = `sparkey_getBlendShape($sel[1])`;
if (size($bs) != 0) {
/*-------------------------------------*/
string $bsNode[] = `listAttr -m ($bs[0] + ".w")`;
int $bsNum = size($bsNode);
if ($bsNum != 0) {
if (`checkBox -q -v wrapMethod`) {
select -r $sel[0] $sel[1];
CreateWrap;
}
string $rbMesh[];
clear $rbMesh;
/*--------------- copy target ----------------------*/
if (`objExists "WrapConvertTemp"`) {
delete "WrapConvertTemp";
}
else {
group -em -n "WrapConvertTemp";
}
for ($num = 0; $num < $bsNum; $num++) {
int $bsWeight = `getAttr ($bs[0] + "." + $bsNode[$num])`;
int $conInfo=`connectionInfo -il ($bs[0] + "." + $bsNode[$num])`;
if (($bsWeight != 1)&&($conInfo==0)) {
setAttr ($bs[0] + "." + $bsNode[$num]) 1 ;
string $copyMesh[] = `duplicate $sel[0]`;
parent $copyMesh[0] "WrapConvertTemp";
rename $copyMesh[0] $bsNode[$num];
$rbMesh[size($rbMesh)] = (":WrapConvertTemp|:" + $bsNode[$num]);
setAttr ($bs[0] + "." + $bsNode[$num]) 0 ;
}
}
/*--------------- category ----------------------*/
if (`checkBox -q -v wrapMethod`) {
string $wrapName[] = `sparkey_getWrap ($sel[0])`;
string $del[] = `ls ($sel[1] + "Bas*")`;
delete $wrapName $del;
}
blendShape -frontOfChain $rbMesh $sel[0];
delete "WrapConvertTemp";
print "blendshape<70><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>";
/*----------------delta mush ---------------------*/
if (`checkBox -q -v deltaMushTarget`) {
int $deltaValue = `intSliderGrp -q -v deltaIntensity`;
string $dlNames[] = `deltaMush -smoothingIterations $deltaValue -smoothingStep 1.0 -pinBorderVertices 1 -envelope 1 $sel[0]`;
string $bs[] = `sparkey_getBlendShape($sel[0])`;
string $bsNode[] = `listAttr -m ($bs[0] + ".w")`;
int $bsNum = size($bsNode);
string $rbMesh[];
clear $rbMesh;
if (`objExists "WrapConvertTemp"`) {
delete "WrapConvertTemp";
}
else {
group -em -n "WrapConvertTemp";
}
for ($num = 0; $num < $bsNum; $num++) {
int $bsWeight = `getAttr ($bs[0] + "." + $bsNode[$num])`;
if ($bsWeight != 1) {
setAttr ($bs[0] + "." + $bsNode[$num]) 0 ;
currentTime -10;
setAttr ($bs[0] + "." + $bsNode[$num]) 1 ;
currentTime 0;
string $copyMesh[] = `duplicate $sel[0]`;
parent $copyMesh[0] "WrapConvertTemp";
rename $copyMesh[0] $bsNode[$num];
$rbMesh[size($rbMesh)] = (":WrapConvertTemp|:" + $bsNode[$num]);
setAttr ($bs[0] + "." + $bsNode[$num]) 0 ;
currentTime -10;
currentTime 0;
}
}
delete $dlNames $bs;
blendShape -frontOfChain $rbMesh $sel[0];
delete "WrapConvertTemp";
print "DeltaMush<73><68><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD>ϣ<EFBFBD>";
}
}
else {
warning "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>blendshape<70>б<EFBFBD>Ϊ<EFBFBD><CEAA>";
}
}
else {
warning "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5B2BB><EFBFBD><EFBFBD>blendshape<70><65><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5>blendshape";
}
}
else {
warning "<22><>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
}
}
global proc SGCopyBlend() {
string $SelBsNameList[] = getShapeEditorTreeviewSelection(14);
string $tmpA[] = stringToStringArray($SelBsNameList[0], ".");
string $tmpB[] = stringToStringArray($SelBsNameList[1], ".");
int $targetA = $tmpA[1];
int $targetB = $tmpB[1];
//refresh;//Maya2016 bug workaround
string $MeshA[] = `sculptTarget -e -regenerate true -target $targetA $tmpA[0]`;
string $MeshShapeA[] = `listRelatives -s $MeshA[0]`;
disconnectAttr ($MeshShapeA[0]+".worldMesh[0]") ($tmpA[0]+".inputTarget[0].inputTargetGroup["+$targetA+"].inputTargetItem[6000].inputGeomTarget");
connectAttr -f ($MeshShapeA[0]+".worldMesh[0]") ($tmpA[0]+".inputTarget[0].inputTargetGroup["+$targetB+"].inputTargetItem[6000].inputGeomTarget");
delete $MeshA;
//refresh;//Maya2016 bug workaround
//blendShape -e -ft 0 $targetB -ss 1 -sa "x" $tmpB[0];
}
global proc SGMirrorBlend() {
int $originalSymmetry = `symmetricModelling -q -s`;
string $symmetrySpace, $symmetryAxis;
if ($originalSymmetry)
{
$symmetrySpace = `symmetricModelling -q -about`;
if ($symmetrySpace == "topo")
$symmetryAxis = blendShapeGetTopoSymmetryEdge();
else
$symmetryAxis = `symmetricModelling -q -axis`;
}
string $SelBsNameList[] = getShapeEditorTreeviewSelection(14);
string $tmpA[] = stringToStringArray($SelBsNameList[0], ".");
string $tmpB[] = stringToStringArray($SelBsNameList[1], ".");
int $targetA = $tmpA[1];
int $targetB = $tmpB[1];
//refresh;//Maya2016 bug workaround
string $MeshA[] = `sculptTarget -e -regenerate true -target $targetA $tmpA[0]`;
string $MeshShapeA[] = `listRelatives -s $MeshA[0]`;
disconnectAttr ($MeshShapeA[0]+".worldMesh[0]") ($tmpA[0]+".inputTarget[0].inputTargetGroup["+$targetA+"].inputTargetItem[6000].inputGeomTarget");
connectAttr -f ($MeshShapeA[0]+".worldMesh[0]") ($tmpA[0]+".inputTarget[0].inputTargetGroup["+$targetB+"].inputTargetItem[6000].inputGeomTarget");
delete $MeshA;
//refresh;//Maya2016 bug workaround
blendShape -e -ft 0 $targetB -ss 1 -sa "x" $tmpB[0];
reflectionSetMode none;
string $cmd;
if (!$originalSymmetry || size($symmetryAxis) == 0)
$cmd += "eval -ue 0 \"symmetricModelling -s 0\";";
else if ($symmetrySpace == "topo")
$cmd += "eval -ue 0 \"symmetricModelling -e -about " + $symmetrySpace + " -s 1 " + $symmetryAxis + "\";";
else
$cmd += "eval -ue 0 \"symmetricModelling -e -about " + $symmetrySpace + " -axis " + $symmetryAxis + " -s 1\";";
eval($cmd);
}
// ===========================================================================
// Copyright 2016 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
// ===========================================================================
global proc string[] getShapeEditorTreeviewSelection(int $scope)
//
// Description:
// Get selections from shape editor tree view
//
// Input Arguments:
// int $scope - Scope of tree view selection:
//
// Simple Scopes:
// 0: Selected blend shape deformer group indices. e.g. {"-1", "-2", "-3"}
// 1: Selected blend shape deformers. e.g. {"blendShape1", "blendShape2", "blendShape3", "blendShape4"}
// 2: Blend shape deformers in selected groups. e.g. {"blendShape1", "blendShape2"}
// 3: Selected target group indices with blend shape name prefix. e.g. {"blendShape1.-1", "blendShape1.-2", "blendShape2.-1", "blendShape2.-2"}
// 4: Selected target indices with blend shape name prefix. e.g. {"blendShape1.0", "blendShape1.1", "blendShape1.2"}
// 5: Targets in selected groups with blend shape name prefix. e.g. {"blendShape2.0", "blendShape2.1"}
// 6: Inbetween targets. e.g. {"blendShape2.0.5500", "blendShape2.1.5800"}
// 7: Purely selected blend shape deformer (groups). e.g. {"-1", "2", "blendshape1", "blendshap2", "-3"}
// 8: Purely selected target (groups). e.g. {"blendshape1.1", "blendshape1.-1", "blendshape2.2", "blendshape2.-2"}
// 9: Purely selected target (groups) within one BSD. e.g. {"blendshape1.1", "blendshape1.-1"}
//
// Only one type of item is selected:
// 10: Purely selected blend shape deformer group indices:, return {} for mixed selection
// 11: Purely selected blend shape deformers:, return {} for mixed selection
// 12: Blend shape deformers in purely selected of groups:, return {} for mixed selection
// 13: Purely selected target group indices:, return {} for mixed selection
// 14: Purely selected targets:, return {} for mixed selection
// 15: Target in purely selected of groups, return {} for mixed selection
// 16: Purely selected in-between targets. return {} for mixed selection
//
// Last Selected Item
// 20: Last selection
//
// Only one type and its group type of item are selected:
// 21: Purely selected blend shape deformers and the ones in group without duplicates, return {} for mixed selection.
// 24: Purely selected target and the ones in group without duplicates, return {} for mixed selection.
//
// Flags:
// 30: If selection contains reference item. return {"1"} if true; {"0"} if false;
// 31: First selection item
//
// Return Value:
// String array of given scope
//
{
$TypeRoof = 6; //NOTE: Update roof when new tree item type added
int $TypeArray[];
for ($i = 0; $i < $TypeRoof; ++ $i)
$TypeArray[$i] = $i; // initialize type arrary
if(!`optionVar -exists blendShapeEditorTreeViewSelection`)
return{};
string $ov[] = `optionVar -q blendShapeEditorTreeViewSelection`;
if($scope > -1 && $scope < $TypeRoof + 3) //Scope 0 ~ 8
return stringToStringArray($ov[$scope], "/");
if($scope == 9) //Scope 9
return filterSingleBSD(stringToStringArray($ov[8], "/"));
else if($scope > 9 && $scope < $TypeRoof + 11) //Scope 10 ~ 16
{
$selection = stringToStringArray($ov[$scope-10], "/");
if(size($selection) == 0)
return {};
int $newTypeArray[] = intArrayRemove({$scope-10, 2, 5}, $TypeArray); // Skip checking scope related types
if($scope == 12 || $scope == 15)
$newTypeArray = intArrayRemove({$scope-12}, $newTypeArray); // Skip checking bsd/target group types
for ($i in $newTypeArray)
if(size(stringToStringArray($ov[$i], "/")) != 0)
return {}; // If mixed selection
return $selection;
}
else if($scope == 20) //Scope 20
return stringToStringArray($ov[9], "/");
else if ($scope == 21 || $scope == 24) //Scope 21, 24
{
$selectionOutG = stringToStringArray($ov[$scope-20], "/");
$selectionInG = stringToStringArray($ov[$scope-19], "/");
$selection = stringArrayRemoveDuplicates(stringArrayCatenate($selectionOutG, $selectionInG));
if(size($selection) == 0)
return {};
int $newTypeArray[] = intArrayRemove({$scope-20, $scope-19, $scope-21}, $TypeArray); // Skip checking scope related types
for ($i in $newTypeArray)
if(size(stringToStringArray($ov[$i], "/")) != 0)
return {}; // If mixed selection
return $selection;
}
else if ($scope == 30) //Scope 30
return stringToStringArray($ov[10], "/");
else if ($scope == 31)
return stringToStringArray($ov[11], "/");
else // Invalid scope
return {};
}
global proc string[] filterSingleBSD(string $items[])
//
// Description:
// Return selected target(group) from single blend shape deformer. return empty for more multi-BSD
//
{
string $result[];
string $oneBsd = "";
for($item in $items)
{
string $subStrings[] = stringToStringArray($item, ".");
if($oneBsd == "")
$oneBsd = $subStrings[0];
if($oneBsd != $subStrings[0])
{
return {};
}
$result = stringArrayCatenate($result, {$item});
}
return $result;
}
global proc int isShapeEditorRefItemSelected()
//
// Description:
// Return 1 if reference item selected in shape editor tree view
//
{
$ResultL = getShapeEditorTreeviewSelection(30);
if(size($ResultL) == 1)
{
if($ResultL[0] == "1")
return 1;
else
return 0;
}
return 0;
}
global proc int blendShapeEditorSelectedAncestor(string $bsdName, int $tgtIndex, string $selectedTargets[])
//
// Description:
// Get the selected ancestor if there is, otherwise return 0.
// In the blendShape target/directory hierarchy, there is always a highest directory
// with index=0 and cannot be selected, if going up to this highest directory, stop and return 0.
// Since this directory 0 cannot be selected, so return 0 means fail to find.
//
// This function dest not care whether the $tgtIndex is selected or not.
//
// Input:
// $tgtIndex >= 0, target,
// < 0, target directory.
//
// Return:
// 0 if ancestors are not selected.
// if there is a highest ancestor is selected, which must be a directory,
// since target's parent and directory's parent are directory.
//
{
int $highestParentDirectory = 0;
int $parentDir = -1;
if ($tgtIndex >= 0)
{
// this is a target,
// go to parent directory.
$tempAttr = $bsdName + ".parentDirectory[" + $tgtIndex + "]";
$parentDir = `getAttr $tempAttr`;
if ($parentDir <= -1)
return 0; // default value
if ($parentDir == 0)
return 0; // target item directly under blendShape node
}
else
{
// this is a target directory.
// go to parent directory
$tempAttr = $bsdName + ".targetDirectory[" + -$tgtIndex + "].parentIndex";
$parentDir = `getAttr $tempAttr`;
}
while ($parentDir > 0)
{
// check if this directory is selected or not
string $dirNameEncoded = $bsdName + "." + -$parentDir;
if ( stringArrayFind($dirNameEncoded, 0, $selectedTargets) != -1 )
$highestParentDirectory = $parentDir;
// go to parent directory, parent of a directory is always a directory.
$tempAttr = $bsdName + ".targetDirectory[" + $parentDir + "].parentIndex";
$parentDir = `getAttr $tempAttr`;
}
return $highestParentDirectory;
}