//////////////////////////////////////////////////////
//kfSwordSwipe
//////////////////////////
//Written by Kiel Figgins
//www.3dfiggins.com
//////////////////////////
//Use to create a lofted surface over time between two points
//////////////////////////
//Version History
//////////////////////////
//2.01 (09-21-2021) - Simplying for public release focused only on Swipes not tron trails
// -Changed UI order, R click on S/E frame to current frame, create mesh by default
// -Create Shader option, changed top group name, default trail to 3, clean top group
// -Lock mesh transforms, show mid frame of swipe, Help button added
//1.06 (05-29-2012) - Added single cv per frame non animated path obj
//1.05 (05-24-2012) - Changed naming of taper groups, fixed taper equation, added scale min/max, added tail length check, added tail length min, added sub min
//1.04 (05-23-2012) - Stripped out workflow
//1.03 (05-10-2012) - Cleaning up, trying to get to actually work
//1.02 (01-27-2012) - Added substep, clean up procs a bit
//1.01 (01-23-2012) - Added output mesh option, multiple object option, end frame half way
//1.00 (01-21-2012) - Orginal version
//////////////////////////
//Coming Soon
/*
//Coming Up
//Wishlist
-progress bar
-determine if you need to get the vert/pivot location of a target
-fade on/off
-curves actually shrink as gets closer to end of frame range
*/
global proc kfSwordSwipe()
{
if (`window -q -ex kfSwordSwipeWin`)
{
showWindow kfSwordSwipeWin ;
return ;
}
window -w 250 -h 600 -t "剑轨工具-by Kiel Figgins(喵喵动画屋修改)" kfSwordSwipeWin ;
formLayout mainSaveForm ;
//UI pieces
text -l "1. 创建 2 个或以上定位器并约束到刀刃" txST_Locs;
text -l "2. 从尖到柄选择定位器" txST_LocSel;
text -l "3. 设置定位器" txSTDefNum;
textField -w 90 -ed false -tx "" tfSTDefNum;
button -l " < " -w 20 -ann "根据选择填充" -c ("kfSTDefNumFill();") btnSTDefNumFill;
text -l "4. 起始 / 结束帧(右键设置)" txSTStartEnd;
intField -w 40 -v 10 intSTStart;
popupMenu();
menuItem -l "设为当前帧" -c ("kfSS_SetFrame(1);");
intField -w 40 -v 20 intSTEnd;
popupMenu();
menuItem -l "设为当前帧" -c ("kfSS_SetFrame(2);");
text -l "5. 轨迹帧长度" txSTLength;
intField -min 1 -w 40 -v 3 intSTLength;
text -l "6. 轨迹缩放衰减%:" txSTScale;
floatField -min 0 -max 100 -pre 1 -w 40 -v 0 floatSTScale;
text -l "7. 帧内子步数:" txSTStep;
intField -min 0 -w 40 -v 20 intSTStep;
text -l "8. 请开启NURBS曲面与Viewport 2.0" txST_View;
text -l "9. 命名:" txSTNaming;
textField -w 140 -tx "Swipe_A" tfSTNaming;
button -l "帮助" -bgc .2 .55 .75 -w 40 -ann "" -c ("kfSS_Instruct();") btnST_Help;
separator -style "in" -h 3 sepSTA;
button -l "创建剑轨" -w 150 -ann "" -c ("kfSTTailLen(); kfSTCreate();") btnSTCreate;
checkBox -l "创建材质" -v 1 chBxSTShader;
// 10. 噪声颜色增益(colorGain)
text -l "10. 噪声颜色增益:" txNoiseGainLbl;
colorSliderGrp -l "" -rgb 1 1 1 -cw 1 1 -cw 2 220 -cw 3 1 -adj 2 -h 18 -cc "kfSS_OnColorGainChange()" csNoiseGain;
// 11. 噪声颜色偏移(colorOffset)
text -l "11. 噪声颜色偏移:" txNoiseOffsetLbl;
colorSliderGrp -l "" -rgb 0 0 0 -cw 1 1 -cw 2 220 -cw 3 1 -adj 2 -h 18 -cc "kfSS_OnColorOffsetChange()" csNoiseOffset;
// 12. 环境光颜色(ambientColor)
text -l "12. 环境光颜色:" txAmbientLbl;
colorSliderGrp -l "" -rgb 0 0 0 -cw 1 1 -cw 2 220 -cw 3 1 -adj 2 -h 18 -cc "kfSS_OnAmbientColorChange()" csAmbient;
// 获取与重置
button -l "从选择获取颜色" -w 120 -c ("kfSS_FetchNoiseFromSelection();") btnFetchNoise;
button -l "重置颜色" -w 120 -c ("kfSS_ResetColors();") btnResetColors;
//UI FormLayout
formLayout -e
-af txST_Locs "top" 8
-an txST_Locs "bottom"
-af txST_Locs "left" 5
-an txST_Locs "right"
-ac txST_LocSel "top" 8 txST_Locs
-an txST_LocSel "bottom"
-af txST_LocSel "left" 5
-an txST_LocSel "right"
-ac txSTDefNum "top" 8 txST_LocSel
-an txSTDefNum "bottom"
-af txSTDefNum "left" 5
-an txSTDefNum "right"
-ac tfSTDefNum "top" 8 txST_LocSel
-an tfSTDefNum "bottom"
-ac tfSTDefNum "left" 5 txSTDefNum
-an tfSTDefNum "right"
-ac btnSTDefNumFill "top" 8 txST_LocSel
-an btnSTDefNumFill "bottom"
-ac btnSTDefNumFill "left" 5 tfSTDefNum
-an btnSTDefNumFill "right"
-ac txSTStartEnd "top" 8 btnSTDefNumFill
-an txSTStartEnd "bottom"
-af txSTStartEnd "left" 5
-an txSTStartEnd "right"
-ac intSTStart "top" 8 btnSTDefNumFill
-an intSTStart "bottom"
-ac intSTStart "left" 5 txSTStartEnd
-an intSTStart "right"
-ac intSTEnd "top" 8 btnSTDefNumFill
-an intSTEnd "bottom"
-ac intSTEnd "left" 5 intSTStart
-an intSTEnd "right"
-ac txSTLength "top" 8 intSTEnd
-an txSTLength "bottom"
-af txSTLength "left" 5
-an txSTLength "right"
-ac intSTLength "top" 8 intSTEnd
-an intSTLength "bottom"
-ac intSTLength "left" 5 txSTLength
-an intSTLength "right"
-ac txSTScale "top" 8 intSTLength
-an txSTScale "bottom"
-af txSTScale "left" 5
-an txSTScale "right"
-ac floatSTScale "top" 8 intSTLength
-an floatSTScale "bottom"
-ac floatSTScale "left" 5 txSTScale
-an floatSTScale "right"
-ac txSTStep "top" 8 floatSTScale
-an txSTStep "bottom"
-af txSTStep "left" 5
-an txSTStep "right"
-ac intSTStep "top" 8 floatSTScale
-an intSTStep "bottom"
-ac intSTStep "left" 5 txSTStep
-an intSTStep "right"
-ac txST_View "top" 8 intSTStep
-an txST_View "bottom"
-af txST_View "left" 5
-an txST_View "right"
-ac txSTNaming "top" 8 txST_View
-an txSTNaming "bottom"
-af txSTNaming "left" 5
-an txSTNaming "right"
-ac tfSTNaming "top" 8 txST_View
-an tfSTNaming "bottom"
-ac tfSTNaming "left" 5 txSTNaming
-an tfSTNaming "right"
-ac btnST_Help "top" 8 txST_View
-an btnST_Help "bottom"
-an btnST_Help "left"
-af btnST_Help "right" 5
-ac sepSTA "top" 8 btnST_Help
-an sepSTA "bottom"
-af sepSTA "left" 0
-af sepSTA "right" 0
-ac btnSTCreate "top" 8 sepSTA
-an btnSTCreate "bottom"
-af btnSTCreate "left" 5
-an btnSTCreate "right"
-ac chBxSTShader "top" 8 sepSTA
-an chBxSTShader "bottom"
-an chBxSTShader "left"
-af chBxSTShader "right" 5
-ac txNoiseGainLbl "top" 8 chBxSTShader
-an txNoiseGainLbl "bottom"
-af txNoiseGainLbl "left" 5
-an txNoiseGainLbl "right"
-ac csNoiseGain "top" -2 txNoiseGainLbl
-an csNoiseGain "bottom"
-ac csNoiseGain "left" 5 txNoiseGainLbl
-af csNoiseGain "right" 5
-ac txNoiseOffsetLbl "top" 8 csNoiseGain
-an txNoiseOffsetLbl "bottom"
-af txNoiseOffsetLbl "left" 5
-an txNoiseOffsetLbl "right"
-ac csNoiseOffset "top" -2 txNoiseOffsetLbl
-an csNoiseOffset "bottom"
-ac csNoiseOffset "left" 5 txNoiseOffsetLbl
-af csNoiseOffset "right" 5
-ac txAmbientLbl "top" 8 csNoiseOffset
-an txAmbientLbl "bottom"
-af txAmbientLbl "left" 5
-an txAmbientLbl "right"
-ac csAmbient "top" -2 txAmbientLbl
-an csAmbient "bottom"
-ac csAmbient "left" 5 txAmbientLbl
-af csAmbient "right" 5
-ac btnFetchNoise "top" 8 csAmbient
-an btnFetchNoise "bottom"
-af btnFetchNoise "left" 5
-an btnFetchNoise "right"
-ac btnResetColors "top" 8 csAmbient
-an btnResetColors "bottom"
-ac btnResetColors "left" 5 btnFetchNoise
-an btnResetColors "right"
mainSaveForm ;
showWindow kfSwordSwipeWin ;
//Resize the main window
window -e -widthHeight 360 480 kfSwordSwipeWin;
}//end of proc kfSwordSwipe
////////////////////
//UI Specific Procs
//////////////////////////////////////////////////////////////////
global proc kfSS_SetFrame(int $which)
{
int $cF = `currentTime -q`;
if($which == 1){intField -e -v $cF intSTStart;}
if($which == 2){intField -e -v $cF intSTEnd;}
}//end of proc
//////////////////////////////////////////////////////////////////
global proc kfSTTailLen()
{
int $startFrame = `intField -q -v intSTStart`;
int $endFrame = `intField -q -v intSTEnd`;
int $tailLength = `intField -q -v intSTLength`;
int $frameLength = ($endFrame - $startFrame);
if($tailLength > $frameLength){intField -e -v $frameLength intSTLength;}
}
//////////////////////////////////////////////////////////////////
global string $kfSTDefNum[];
global proc kfSTDefNumFill()
{
global string $kfSTDefNum[];
string $userSel[] =`ls -sl`;
int $theSize = size($userSel);
if($theSize == 0)
{
$kfSTDefNum = `ls -sl`;
textField -e -tx "" tfSTDefNum;
//checkBox -e -en false -v 0 chBxSTMesh;
print "\nFAIL: Please Select at Least (1) Object";
}
if($theSize == 1)
{
$kfSTDefNum = `ls -sl`;
//checkBox -e -en false -v 0 chBxSTMesh;
textField -e -tx $userSel[0] tfSTDefNum;
}
if($theSize > 1)
{
$kfSTDefNum = `ls -sl`;
//checkBox -e -en true -v 1 chBxSTMesh;
textField -e -tx ($theSize + " Objects") tfSTDefNum;
}
}//end of global proc
//////////////////////////////////////////////////////////////////
global proc kfSTDefNumSel()
{
global string $kfSTDefNum[];
select $kfSTDefNum;
}//end of global proc
//////////////////////////////////////////////////////////////////
global proc kfSTCreate()
{
global string $kfSTDefNum[];
select $kfSTDefNum;
string $targets[] = `ls -sl`;
string $namer = `textField -q -tx tfSTNaming`;
int $startFrame = `intField -q -v intSTStart`;
int $endFrame = `intField -q -v intSTEnd`;
int $tailLength = `intField -q -v intSTLength`;
int $subStep = `intField -q -v intSTStep`;
float $falloffPercent = `floatField -q -v floatSTScale`;
//0 no, 1 yes
//int $outputMesh = `checkBox -q -v chBxSTMesh`;
int $outputMesh = 1;
int $createShader = `checkBox -q -v chBxSTShader`;
// 解锁材质组,确保在锁定场景中也能正常创建材质
if(`objExists initialShadingGroup`){
lockNode -l 0 -lu 0 initialShadingGroup;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Work - Single Stroke
//Delete if already exists
if(`objExists ($namer + "_Swipe_Elements")`){delete ($namer + "_Swipe_Elements");}
if($createShader == 1 && `objExists ("mat_" + $namer)` == 1){delete ("mat_" + $namer);}
//////////////////////////
//Create Curves and Groups
group -empty -n ($namer + "_Swipe_Elements");
group -empty -n ($namer + "_Loft_Curves");
group -empty -n ($namer + "_Loft_Mesh");
group -empty -n ($namer + "_Loft_Nulls");
parent ($namer + "_Loft_Curves") ($namer + "_Loft_Mesh") ($namer + "_Loft_Nulls") ($namer + "_Swipe_Elements");
setAttr ($namer + "_Loft_Curves.v") 0;
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.tx");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.ty");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.tz");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.rx");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.ry");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.rz");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.sx");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.sy");
setAttr -lock true -keyable false -channelBox false ($namer + "_Swipe_Elements.sz");
//for each target, create Nulls
int $counter;
int $sizer = `size($targets)`;
for ($counter = 0; $counter < $sizer; $counter++)
{
//////////////////////////
//Go through timeline and create placment nulls
currentTime $startFrame;
group -empty -n ("rig_" + $namer + "_" + $counter + "_Nulls");
string $nullGrp[] = `ls -sl`;
parent $nullGrp ($namer + "_Loft_Nulls");
//////////////////
//Go Through Frames
int $counterF;
int $sizerF = ($endFrame - $startFrame);
for ($counterF = 0; $counterF <= $sizerF; $counterF++)
{
//if $counterF = 0, its first frame, make all nulls at default position
if($counterF == 0)
{
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
float $pos[] = `xform -q -ws -rp $targets[$counter]`;
group -empty -n ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
move -ws $pos[0] $pos[1] $pos[2] ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
parent ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN) $nullGrp;
}//end of create nulls
}//end of if counterF = 0
if($counterF <= $tailLength && $counterF != 0)
{
float $counterFFloat = $counterF;
float $frameStep = ($counterFFloat / $subStep);
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
currentTime ($startFrame + ($frameStep * $counterN));
float $pos[] = `xform -q -ws -rp $targets[$counter]`;
group -empty -n ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
move -ws $pos[0] $pos[1] $pos[2] ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
parent ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN) $nullGrp;
}
}//end of if counterF != 0
if($counterF > $tailLength && $counterF != 0)
{
float $counterFFloat = $counterF;
float $frameStep = (($counterFFloat - ($counterFFloat - $tailLength)) / $subStep);
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
currentTime ($startFrame + ($counterF - $tailLength) + ($frameStep * $counterN));
float $pos[] = `xform -q -ws -rp $targets[$counter]`;
group -empty -n ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
move -ws $pos[0] $pos[1] $pos[2] ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN);
parent ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN) $nullGrp;
}
}//end of if counterF != 0
}//end of loop through frames
}//end of loop through all targets for creating nulls
//scale Nulls for taper
int $counterF;
int $sizerF = ($endFrame - $startFrame);
for ($counterF = 0; $counterF <= $sizerF; $counterF++)
{
//int $subStep = `intField -q -v intSTStep`;
//float $falloffPercent = `floatField -q -v floatSTScale`;
//if $counterF = 0, its first frame, make all nulls at default position
if($counterF == 0)
{
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
select ("rig_" + $namer + "_*_FinderNull_" + $counterF + "_" + $counterN);
group -n ("rig_" + $namer + "_" + $counterF + "_" + $counterN + "_Taper");
string $taperGrp[] = `ls -sl`;
select $taperGrp;
CenterPivot;
float $subStepF = $subStep;
float $counterNFloat = $counterN;
setAttr ($taperGrp[0] + ".sx") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sy") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sz") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
}//end of create nulls
}//end of if counterF = 0
if($counterF <= $tailLength && $counterF != 0)
{
float $counterFFloat = $counterF;
float $frameStep = ($counterFFloat / $subStep);
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
select ("rig_" + $namer + "_*_FinderNull_" + $counterF + "_" + $counterN);
group -n ("rig_" + $namer + "_" + $counterF + "_" + $counterN + "_Taper");
string $taperGrp[] = `ls -sl`;
select $taperGrp;
CenterPivot;
float $subStepF = $subStep;
float $counterNFloat = $counterN;
setAttr ($taperGrp[0] + ".sx") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sy") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sz") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
}
}//end of if counterF != 0
if($counterF > $tailLength && $counterF != 0)
{
float $counterFFloat = $counterF;
float $frameStep = (($counterFFloat - ($counterFFloat - $tailLength)) / $subStep);
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
select ("rig_" + $namer + "_*_FinderNull_" + $counterF + "_" + $counterN);
group -n ("rig_" + $namer + "_" + $counterF + "_" + $counterN + "_Taper");
string $taperGrp[] = `ls -sl`;
select $taperGrp;
CenterPivot;
float $subStepF = $subStep;
float $counterNFloat = $counterN;
setAttr ($taperGrp[0] + ".sx") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sy") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
setAttr ($taperGrp[0] + ".sz") (1 - ($falloffPercent * .01) + ((($falloffPercent / $subStepF) * $counterNFloat) * .01));
}
}//end of if counterF != 0
}//end of scaling nulls for taper
//create/align curves
int $counter;
int $sizer = `size($targets)`;
for ($counter = 0; $counter < $sizer; $counter++)
{
curve -d 3 -p 0 0 0 -p 0 0 1 -p 0 0 2 -p 0 0 3 -p 0 0 4 -k 0 -k 0 -k 0 -k 1 -k 2 -k 2 -k 2 ;
rename ("rig_" + $namer + "_curve_" + $counter);
rebuildCurve -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s ($subStep - 2) -d 3 -tol 0.01 ("rig_" + $namer + "_curve_" + $counter);
parent ("rig_" + $namer + "_curve_" + $counter) ($namer + "_Loft_Curves");
select ("rig_" + $namer + "_curve_" + $counter);
string $curve[] = `ls -sl`;
/////////////////////////////
//Go through and align curve to placement nulls
select ("rig_" + $namer + "_curve_" + $counter);
string $curve[] = `ls -sl`;
int $counterF;
int $sizerF = ($endFrame - $startFrame);
for ($counterF = 0; $counterF <= $sizerF; $counterF++)
{
currentTime ($startFrame + $counterF);
int $counterN;
int $sizerN = $subStep;
for ($counterN = 0; $counterN <= $sizerN; $counterN++)
{
float $pos[] = `xform -q -ws -rp ("rig_" + $namer + "_" + $counter + "_FinderNull_" + $counterF + "_" + $counterN)`;
move -ws $pos[0] $pos[1] $pos[2] ($curve[0] + ".cv[" + $counterN + "]");
setKeyframe -breakdown 0 -hierarchy none -controlPoints 0 -shape 0 {($curve[0] + ".cv[" + $counterN + "]")};
}
}//end of loop through time alignint curve to nulls
}//end of create/align curves
if($createShader == 1)
{
//Base Material
shadingNode -asShader lambert -n ("mat_" + $namer);
string $sColor[] = `ls -sl`;
sets -renderable true -noSurfaceShader true -empty -name ($sColor[0] + "SG");
connectAttr -f ($sColor[0] + ".outColor") ($sColor[0] + "SG.surfaceShader");
setAttr ($sColor[0] + ".diffuse") 1;
setAttr ($sColor[0] + ".translucence") 1;
setAttr ($sColor[0] + ".ambientColor") -type double3 0 0 1 ;
//Noise
string $noise = `shadingNode -asTexture noise -n ($namer + "_Noise")`;
string $noiseP = `shadingNode -asUtility place2dTexture -n ($namer + "_Noise_Place2dText")`;
connectAttr ($noiseP + ".outUV") ($noise + ".uv");
connectAttr ($noiseP + ".outUvFilterSize") ($noise + ".uvFilterSize");
connectAttr -force ($noise + ".outColor") ($sColor[0] + ".color");
setAttr ($noise + ".time") 0.45;
setAttr ($noise + ".frequency") 6;
setAttr ($noiseP + ".repeatU") 0.1;
//Transp Ramp
string $ramp = `shadingNode -asTexture ramp -n ($namer + "_Ramp")`;
string $rampP = `shadingNode -asUtility place2dTexture -n ($namer + "_Ramp_Place2dText")`;
connectAttr ($rampP + ".outUV") ($ramp + ".uv");
connectAttr ($rampP + ".outUvFilterSize") ($ramp + ".uvFilterSize");
connectAttr -force ($ramp + ".outColor") ($sColor[0] + ".transparency");
removeMultiInstance -break true ($ramp + ".colorEntryList[1]");
setAttr ($ramp + ".type") 1;
setAttr ($ramp + ".interpolation") 2;
setAttr ($ramp + ".colorEntryList[0].color") -type double3 .5 .5 .5 ;
setAttr ($ramp + ".colorEntryList[2].color") -type double3 1 1 1;
setAttr ($ramp + ".colorEntryList[0].position") 1;
setAttr ($ramp + ".colorEntryList[2].position") 0.3;
//Assign to Loft
//sets -e -forceElement ($sColor[0] + "SG");
}
select ("rig_" + $namer + "_curve_*");
string $loftCurves[] = `ls -tr -sl`;
if($outputMesh)
{
loft -n ("mesh_" + $namer + "_LoftSurface") -ch 1 -u 1 -c 0 -ar 0 -d 3 -ss 1 -rn 0 -po 0 -rsn true $loftCurves;
string $loftMesh[] = `ls -sl`;
parent $loftMesh ($namer + "_Loft_Mesh");
select $loftMesh;
if($createShader == 1){sets -e -forceElement ("mat_" + $namer + "SG");}
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".tx");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".ty");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".tz");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".rx");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".ry");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".rz");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".sx");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".sy");
setAttr -lock true -keyable false -channelBox false ($loftMesh[0] + ".sz");
}
else
{
setAttr ($namer + "_Loft_Curves.v") 1;
}
//Key Vis on Mesh output
setKeyframe -v 0 -t ($startFrame - 1) ($namer + "_Loft_Mesh.v");
setKeyframe -v 1 -t $startFrame ($namer + "_Loft_Mesh.v");
setKeyframe -v 1 -t $endFrame ($namer + "_Loft_Mesh.v");
setKeyframe -v 0 -t ($endFrame + 1) ($namer + "_Loft_Mesh.v");
int $midF = ((($endFrame - $startFrame) * .5) + $startFrame);
currentTime $midF;
print "\n成功:已创建剑轨";
}//end of global proc kfMUListCommand
//////////////////////////////////////////////////////////////////
global proc kfSTCreateObjPath()
{
global string $kfSTDefNum[];
select $kfSTDefNum;
string $targets[] = `ls -sl`;
string $namer = `textField -q -tx tfSTNaming`;
int $startFrame = `intField -q -v intSTStart`;
int $endFrame = `intField -q -v intSTEnd`;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Work - Single Stroke
//for each target, create Nulls
int $counter;
int $sizer = `size($targets)`;
for ($counter = 0; $counter < $sizer; $counter++)
{
curve -d 3 -p 0 0 0 -p 0 0 1 -p 0 0 2 -p 0 0 3 -p 0 0 4 -k 0 -k 0 -k 0 -k 1 -k 2 -k 2 -k 2 ;
rename ("rig_" + $namer + "_curve_" + $counter);
rebuildCurve -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s ($endFrame - $startFrame - 2) -d 3 -tol 0.01 ("rig_" + $namer + "_curve_" + $counter);
//////////////////
//Go Through Frames
int $counterF;
int $sizerF = ($endFrame - $startFrame);
for ($counterF = 0; $counterF <= $sizerF; $counterF++)
{
//Go through timeline and create placment nulls
currentTime ($startFrame + $counterF);
float $pos[] = `xform -q -ws -rp $targets[$counter]`;
move -ws $pos[0] $pos[1] $pos[2] ("rig_" + $namer + "_curve_" + $counter + ".cv[" + $counterF + "]");
}//end of loop through frames
}//end of loop through all targets for creating nulls
}
///////////////////////////////////////////////////////////////
//Instructions
global proc kfSS_Instruct()
{
if (`window -q -ex kfSS_InstructWin`)
{
showWindow kfSS_InstructWin ;
return ;
}
window -w 850 -h 500 -t "剑轨工具 - 使用说明" kfSS_InstructWin ;
formLayout mainSaveForm ;
//UI pieces
scrollField -w 100 -h 100 -wordWrap true -tx
(
"剑轨工具 - 作者: Kiel Figgins - 邮箱: KielFiggins22@gmail.com - 网站: 3dFiggins.com"
+ "\n\n" +
"完整教程(含示例与图片),请访问 3dFiggins.com/Store/Support/SwordSwipe"
+ "\n\n" +
"网站包含火焰轨迹、Tron 轨迹、故障排查等更多内容!"
)
-ed 0 scrollSS_Instruct;
//UI FormLayout
formLayout -e
-af scrollSS_Instruct "top" 5
-af scrollSS_Instruct "bottom" 5
-af scrollSS_Instruct "left" 5
-af scrollSS_Instruct "right" 5
mainSaveForm ;
showWindow kfSS_InstructWin ;
//Resize the main window
window -e -widthHeight 650 150 kfSS_InstructWin;
}//end of proc
// ====== 实时颜色变化回调函数 ======
global proc kfSS_OnColorGainChange()
{
global string $g_kfNoiseNode;
// 如果还没有获取到噪声节点,尝试自动获取
if($g_kfNoiseNode == ""){
// 尝试从当前选择中自动获取噪声节点
string $sel[] = `ls -sl`;
if(size($sel) > 0){
kfSS_FetchNoiseFromSelection();
}
}
// 如果仍然没有噪声节点,直接返回
if($g_kfNoiseNode == ""){
return;
}
// 实时更新噪声节点的colorGain
float $g[] = `colorSliderGrp -q -rgbValue csNoiseGain`;
if(`objExists $g_kfNoiseNode` && `attributeQuery -ex -n $g_kfNoiseNode "colorGain"`){
setAttr ($g_kfNoiseNode+".colorGain") -type double3 $g[0] $g[1] $g[2];
}
}
global proc kfSS_OnColorOffsetChange()
{
global string $g_kfNoiseNode;
// 如果还没有获取到噪声节点,尝试自动获取
if($g_kfNoiseNode == ""){
// 尝试从当前选择中自动获取噪声节点
string $sel[] = `ls -sl`;
if(size($sel) > 0){
kfSS_FetchNoiseFromSelection();
}
}
// 如果仍然没有噪声节点,直接返回
if($g_kfNoiseNode == ""){
return;
}
// 实时更新噪声节点的colorOffset
float $o[] = `colorSliderGrp -q -rgbValue csNoiseOffset`;
if(`objExists $g_kfNoiseNode` && `attributeQuery -ex -n $g_kfNoiseNode "colorOffset"`){
setAttr ($g_kfNoiseNode+".colorOffset") -type double3 $o[0] $o[1] $o[2];
}
}
global proc kfSS_OnAmbientColorChange()
{
global string $g_kfNoiseNode;
// 如果还没有获取到噪声节点,尝试自动获取
if($g_kfNoiseNode == ""){
// 尝试从当前选择中自动获取噪声节点
string $sel[] = `ls -sl`;
if(size($sel) > 0){
kfSS_FetchNoiseFromSelection();
}
}
// 如果仍然没有噪声节点,直接返回
if($g_kfNoiseNode == ""){
return;
}
// 实时更新材质的环境光颜色
string $shader = "";
string $hist[] = `listHistory -f 1 $g_kfNoiseNode`;
for($n in $hist){
if(`nodeType $n` == "lambert" || `nodeType $n` == "blinn" || `nodeType $n` == "phong" || `nodeType $n` == "surfaceShader" || `nodeType $n` == "aiStandardSurface"){
$shader = $n;
break;
}
}
if($shader != ""){
float $ambient[] = `colorSliderGrp -q -rgbValue csAmbient`;
if(`attributeQuery -ex -n $shader "ambientColor"`){
setAttr ($shader+".ambientColor") -type double3 $ambient[0] $ambient[1] $ambient[2];
}
}
}
// Auto-run the UI when this script is sourced
evalDeferred "kfSwordSwipe();";
// ====== 辅助:从选择获取噪声节点并读写颜色 ======
global string $g_kfNoiseNode;
global proc kfSS_FetchNoiseFromSelection()
{
global string $g_kfNoiseNode;
$g_kfNoiseNode = "";
string $sel[] = `ls -sl`;
if(size($sel) == 0){ warning "请选择一个已创建的拖尾网格或其材质节点"; return; }
string $node = $sel[0];
string $type = `nodeType $node`;
// 如果直接选中了 noise
if($type == "noise"){
$g_kfNoiseNode = $node;
}
else
{
string $shader = "";
// 如果选中的是着色器(lambert/blinn/aiStandardSurface等)
if($type == "lambert" || $type == "blinn" || $type == "phong" || $type == "surfaceShader" || $type == "aiStandardSurface"){
$shader = $node;
}
// 如果选中的是着色分配组(shadingEngine)
else if($type == "shadingEngine"){
string $ss[] = `listConnections -s true -d false ($node+".surfaceShader")`;
if(size($ss) > 0){ $shader = $ss[0]; }
}
else
{
// 认为是几何体/transform,从其 shape 找到 SG -> Shader
string $shape[] = `listRelatives -s -pa $node`;
if(size($shape) == 0){ $shape = stringArrayCatenate($shape, {$node}); }
// 取第一个 shape
if(size($shape) > 0){
string $sgs[] = `listConnections -type shadingEngine $shape[0]`;
if(size($sgs) > 0){
string $ss[] = `listConnections -s true -d false ($sgs[0]+".surfaceShader")`;
if(size($ss) > 0){ $shader = $ss[0]; }
}
}
}
// 从 Shader 向上游寻找 noise
if($shader != ""){
// 先从 color 插口向上找 noise
string $n1[] = `listConnections -s true -d false -type noise ($shader+".color")`;
if(size($n1) > 0){ $g_kfNoiseNode = $n1[0]; }
else{
// 退化为整网搜索:从 shader 的历史中过滤出 noise
string $hist[] = `listHistory -f 1 $shader`;
for($n in $hist){ if(`nodeType $n` == "noise"){ $g_kfNoiseNode = $n; break; } }
}
}
}
if($g_kfNoiseNode == ""){ warning "未找到连接的 noise 节点"; return; }
// 读取 colorGain / colorOffset 并更新UI
if(`attributeQuery -ex -n $g_kfNoiseNode "colorGain"`){
float $gain[] = `getAttr ($g_kfNoiseNode+".colorGain")`;
// 临时禁用回调,避免在设置颜色时触发实时更新
colorSliderGrp -e -rgb $gain[0] $gain[1] $gain[2] -cc "" csNoiseGain;
colorSliderGrp -e -cc "kfSS_OnColorGainChange()" csNoiseGain;
}
if(`attributeQuery -ex -n $g_kfNoiseNode "colorOffset"`){
float $off[] = `getAttr ($g_kfNoiseNode+".colorOffset")`;
// 临时禁用回调,避免在设置颜色时触发实时更新
colorSliderGrp -e -rgb $off[0] $off[1] $off[2] -cc "" csNoiseOffset;
colorSliderGrp -e -cc "kfSS_OnColorOffsetChange()" csNoiseOffset;
}
// 从噪声节点向上追溯找到材质,获取环境光颜色
string $shader = "";
string $hist[] = `listHistory -f 1 $g_kfNoiseNode`;
for($n in $hist){
if(`nodeType $n` == "lambert" || `nodeType $n` == "blinn" || `nodeType $n` == "phong" || `nodeType $n` == "surfaceShader" || `nodeType $n` == "aiStandardSurface"){
$shader = $n;
break;
}
}
if($shader != ""){
if(`attributeQuery -ex -n $shader "ambientColor"`){
float $ambient[] = `getAttr ($shader+".ambientColor")`;
// 临时禁用回调,避免在设置颜色时触发实时更新
colorSliderGrp -e -rgb $ambient[0] $ambient[1] $ambient[2] -cc "" csAmbient;
colorSliderGrp -e -cc "kfSS_OnAmbientColorChange()" csAmbient;
}
}
print ("\n已获取噪声节点: "+$g_kfNoiseNode);
print ("实时颜色更新已启用!现在可以直接拖动颜色滑块查看效果。");
}
// ====== 重置颜色函数 ======
global proc kfSS_ResetColors()
{
global string $g_kfNoiseNode;
// 如果还没有获取到噪声节点,尝试自动获取
if($g_kfNoiseNode == ""){
string $sel[] = `ls -sl`;
if(size($sel) > 0){
kfSS_FetchNoiseFromSelection();
}
}
// 如果仍然没有噪声节点,提示用户
if($g_kfNoiseNode == ""){
warning "请先选择已创建的剑轨网格或材质节点,然后点击'从选择获取颜色'";
return;
}
// 重置噪声节点的颜色到默认值
if(`objExists $g_kfNoiseNode`){
// 重置colorGain到默认值 (1,1,1)
if(`attributeQuery -ex -n $g_kfNoiseNode "colorGain"`){
setAttr ($g_kfNoiseNode+".colorGain") -type double3 1 1 1;
colorSliderGrp -e -rgb 1 1 1 csNoiseGain;
}
// 重置colorOffset到默认值 (0,0,0)
if(`attributeQuery -ex -n $g_kfNoiseNode "colorOffset"`){
setAttr ($g_kfNoiseNode+".colorOffset") -type double3 0 0 0;
colorSliderGrp -e -rgb 0 0 0 csNoiseOffset;
}
}
// 重置环境光颜色到创建时的默认值 (0,0,1) 蓝色
string $shader = "";
string $hist[] = `listHistory -f 1 $g_kfNoiseNode`;
for($n in $hist){
if(`nodeType $n` == "lambert" || `nodeType $n` == "blinn" || `nodeType $n` == "phong" || `nodeType $n` == "surfaceShader" || `nodeType $n` == "aiStandardSurface"){
$shader = $n;
break;
}
}
if($shader != ""){
if(`attributeQuery -ex -n $shader "ambientColor"`){
setAttr ($shader+".ambientColor") -type double3 0 0 1;
colorSliderGrp -e -rgb 0 0 1 csAmbient;
}
}
print ("\n颜色已重置为创建时的默认值:");
print ("- 噪声颜色增益: (1, 1, 1)");
print ("- 噪声颜色偏移: (0, 0, 0)");
print ("- 环境光颜色: (0, 0, 1) 蓝色");
}
global proc kfSS_ApplyNoiseColors()
{
global string $g_kfNoiseNode;
if($g_kfNoiseNode == ""){ kfSS_FetchNoiseFromSelection(); if($g_kfNoiseNode == ""){ return; } }
float $g[] = `colorSliderGrp -q -rgbValue csNoiseGain`;
float $o[] = `colorSliderGrp -q -rgbValue csNoiseOffset`;
if(`objExists $g_kfNoiseNode`){
if(`attributeQuery -ex -n $g_kfNoiseNode "colorGain"`){ setAttr ($g_kfNoiseNode+".colorGain") -type double3 $g[0] $g[1] $g[2]; }
if(`attributeQuery -ex -n $g_kfNoiseNode "colorOffset"`){ setAttr ($g_kfNoiseNode+".colorOffset") -type double3 $o[0] $o[1] $o[2]; }
print ("\n已应用颜色到噪声节点: "+$g_kfNoiseNode);
}else{
warning "噪声节点不存在,无法设置";
}
}
global proc kfSS_ApplyAmbientColor()
{
global string $g_kfNoiseNode;
if($g_kfNoiseNode == ""){ kfSS_FetchNoiseFromSelection(); if($g_kfNoiseNode == ""){ return; } }
// 从噪声节点向上追溯找到材质
string $shader = "";
string $hist[] = `listHistory -f 1 $g_kfNoiseNode`;
for($n in $hist){
if(`nodeType $n` == "lambert" || `nodeType $n` == "blinn" || `nodeType $n` == "phong" || `nodeType $n` == "surfaceShader" || `nodeType $n` == "aiStandardSurface"){
$shader = $n;
break;
}
}
if($shader == ""){ warning "未找到连接的材质节点"; return; }
float $ambient[] = `colorSliderGrp -q -rgbValue csAmbient`;
if(`attributeQuery -ex -n $shader "ambientColor"`){
setAttr ($shader+".ambientColor") -type double3 $ambient[0] $ambient[1] $ambient[2];
print ("\n已应用环境光颜色到材质: "+$shader);
}else{
warning "材质节点没有ambientColor属性";
}
}
Maya控制器颜色设置脚本
string $lanzi[] = `ls -sl`;
int $shuliang = size($lanzi);
print($shuliang+"\n");
for($i=0;$i<$shuliang;$i++)
{
//启用绘制覆盖
setAttr ($lanzi[$i]+".overrideEnabled") 1;
//8_黄色 13为红色 6为蓝色 9为紫色
setAttr ($lanzi[$i]+".overrideColor") 13;
}
arShake 相机震动脚本工具
arShake 相机震动 / 摇晃脚本,来自 Highend3d / Creative Crash。
这个脚本用于在时间范围内为物体创建震动、振动或摇晃的动画。
将 arShake.py
放入 Documents/Maya/Scripts
文件夹。 将 shelfScript.txt
文件的内容作为 Python 脚本添加到 Maya 的工具架上。
- 设置 –
每帧:1 表示每帧震动,2 表示每隔一帧震动,3 表示每隔三帧震动,依此类推。
平移量:震动时将添加或减去的平移值。
旋转量:震动时将添加或减去的旋转值。
平移和旋转轴可以选择启用或禁用。
使用曲线:震动的量会根据提供的曲线进行渐入和渐出。
所有震动值将被烘焙到一个动画层上。
演示视频:点击这里
Maya绑定教学:一键导入胸部骨架预设
这段视频内容主要介绍了如何在Maya中为模型的胸部添加绑定。以下是主要步骤总结:
- 介绍:
- 主持人向大家问好,并说明今天要讲解的内容是胸部的绑定。
- 提到之前的视频比较复杂,因此将提供更简单的方法。
- 导入绑定文件:
- 主持人导出了一个独立的胸部绑定文件,观众可以下载并使用。
- 操作步骤:
- 打开新的绑定文件,导入胸部模型。
- 调整模型大小并匹配位置,确保其与其他关节对齐。
- 选择胸部和关节,执行父对象约束。
- 为确保后期缩放时模型能够跟随,需要添加缩放约束。
- 添加权重影响:
- 选择首尾骨骼,展开并选择身体进行蒙皮设置。
- 取消“使用几何体”选项,勾选权重锁定,默认值为0,然后添加影响。
- 刷权重:
- 讲解了如何刷权重,确保胸部绑定效果正确。
Maya清除场景中的未知节点(Maya clears unknown nodes in the scene)
当我们需要把Maya场景保存为ma格式的时候,如果maya自带的优化场景无效,可以尝试以下mel代码来清除。(When we need to save the Maya scene in ma format, if the optimized scene that comes with Maya is invalid, you can try the following mel code to clear it.)
{
string $unknownNodes[] = `lsType unknown`;
for($node in $unknownNodes){
if($node=="<done>")
break;
if(`objExists $node`)
{
int $lockState[] = `lockNode -q -l $node`;
if($lockState[0]==1)
lockNode -l off $node;
delete $node;
}
}
}
论坛作者链接:https://autodeskfeedback.az1.qualtrics.com/jfe/form/SV_1yNWNw40yATej3g
Maya Mery_v3.5走路和跑步动画源文件下载
Maya脚本:重命名脚本
import maya.cmds as cmds
# 定义窗口名称
window = "renameWindow"
# 如果窗口已经存在则删除
if cmds.window(window, exists=True):
cmds.deleteUI(window)
# 创建窗口
cmds.window(window, title="重命名(Rename)-by 喵喵动画屋-miaodonghua.com")
# 创建主布局
cmds.columnLayout(adjustableColumn=True)
# 创建输入框用于输入通用名称
cmds.text(label="通用名称(Common Name):")
textField = cmds.textField()
# 创建单选框用于选择左侧或右侧
cmds.text(label="命名规则(Naming rules):")
sideRadio = cmds.radioButtonGrp(label="", numberOfRadioButtons=3, labelArray3=["左 (L)", "右 (R)", "无(none)"])
# 创建按钮用于执行重命名操作
def renameObjects(*args):
# 获取输入的通用名称
prefix = cmds.textField(textField, query=True, text=True)
# 获取选择的侧
side = cmds.radioButtonGrp(sideRadio, query=True, select=True)
# 检查选择的侧
sideString = ""
if side == 1:
sideString = "L"
elif side == 2:
sideString = "R"
# 获取当前选择的对象
selectedObjects = cmds.ls(selection=True)
# 循环重命名对象
count = 1
for obj in selectedObjects:
newName = prefix
if sideString:
newName += "_" + sideString
# 添加序号
newName += str(count)
cmds.rename(obj, newName)
count += 1
cmds.button(label="执行重命名(Apply naming)", command=renameObjects)
# 显示窗口
cmds.showWindow(window)
Maya脚本:随机分布
string $lanzi[] = `ls -sl`;
//print($lanzi[0]+"\n");
//print($lanzi[1]+"\n");
//print($lanzi[2]+"\n");
int $shuliang = size($lanzi);
for($i=0;$i<$shuliang;$i++)
{
float $px = rand(-10,10);
float $py = rand(-10,10);
float $pz = rand(-10,10);
setAttr($lanzi[$i]+".translateX") $px;
setAttr($lanzi[$i]+".translateY") $py;
setAttr($lanzi[$i]+".translateZ") $pz;
}
Maya2022/2024飘带插件spring magic安装教程,解决报错。
Maya 2022以下的版本
可以直接放到对应的版本的script文件夹下(防止和Python3版本冲突),然后执行
execfile(r'C:\Users\Administrator\Documents\maya\2018\scripts\springmagic\springMagic.py')
Maya 2022以上的版本
找到对应的bin文件夹,路径中输入cmd回车,进入CMD模式

继续执行以下两行代码
mayapy -m pip list
mayapy -m pip install pymel~=1.3.0a
Maya绑定教学:nHair头发动力学
这视频主要介绍了在玛雅中如何使用头发动力学进行绑定,相比传统的绑定方式,动力学可以在保证效果的同时节省时间。以下是视频内容的总结:
- 隐藏控制器: 在开始之前,将不需要的控制器隐藏,以防止干扰后续工作。
- 创建骨骼: 确保头发骨骼完整,足够多的关节是为了保证最终效果。
- 骨骼绑定: 将头发绑定到头部以上的骨骼,确保头部和马尾部分都被正确绑定。
- 处理马尾部分: 使用合并转移的方式,将头部和马尾部分分离开,以便更好地处理。
- 创建曲线: 使用IK样条控制,在头发骨骼上创建曲线,主要在头发拐弯往下的部分。
- 曲线动力学: 对曲线应用动力学属性,取消勾选将曲线附加到选定曲面。
- 输出曲线驱动骨骼: 使用IK样条控制器,让毛发系统下的输出曲线驱动头发骨骼的运动。
- 优化动力学效果: 调整抗弯曲、抗扭曲、阻尼值等参数,以获得更自然的头发动力学效果。
- 处理碰撞: 设置身体为被动碰撞体,调整碰撞厚度,以避免头发穿过身体表面。
- 动力学开关: 在头部或其他控制器上添加动力学开关,使用表达式与模拟方法建立开关关系,方便控制动力学的开启和关闭。
- 解算设置: 可以在解算器中设置起始帧位置,以满足特定解算需求。
总体而言,视频提供了一个详细的玛雅动力学头发绑定教程,涵盖了从基本设置到优化效果的多个步骤。