/*{ // Example 10 // This global variable is defined by Maya global string $gMainProgressBar; // This value is used more than once in the script, so it is isolated to a variable. int $progressTestSteps = 50000; // The -maxValue flag sets up the command to use the -step flag below in the for loop. progressBar -edit -beginProgress -isInterruptable true -status "Example Calculation ..." -maxValue $progressTestSteps $gMainProgressBar; // evalDeferred will evaluate its argument at the next idle time. // In this case, after the script is finished executing. evalDeferred("progressBar -edit -endProgress $gMainProgressBar ;"); int $i; for($i = 0; $i < $progressTestSteps; $i++) { if(`progressBar -query -isCancelled $gMainProgressBar`) { print ("// User cancelled the operation with the Escape key.\n"); break; } progressBar -edit -step 1 $gMainProgressBar; } progressBar -edit -endProgress $gMainProgressBar; }*/ //This proc is included in the submission because I did spend a long time coding this and getting it to work. As of right now it does not mesh with my workflow, I need to go back and include my method of accuratly finding distance that gets used later //This does work as of right now. global proc sgkCurveMoveWithPlugin() { global string $gMainProgressBar; string $curves[] = `ls -selection -dagObjects -exactType nurbsCurve`; string $curve; string $controll[]; if (size(`ls -selection -dagObjects -exactType mesh`)) $controll = `ls -selection -dagObjects -exactType mesh`; int $i; string $cpoc[], $surfaces[]; for ($curve in $curves)//set up the curves for the proc { $cpoc[size($cpoc)]=`closestPointOnCurve $curve`; string $captured[] = `listConnections -source 0 $curve`; string $test[] = `ls -dagObjects -exactType nurbsSurface`; if (!size($test)) $surfaces[size($surfaces)] = `listConnections -source 0 ($captured[0])`;//these are going to be used for the ultimate version after extrude to get exact distances } string $npom = `nearestPointOnMesh $controll[0]`; float $vineRadius = .25; //stand in until i get it working with the new distance check method int $cvCount = 3 + `floatFieldGrp -q -value1 cvRebuildAmount`; int $progressTestSteps = (sgkAddThat(size($curves))*$cvCount); progressBar -edit -beginProgress -isInterruptable true -status "Moving the Curves" -maxValue $progressTestSteps $gMainProgressBar; evalDeferred("progressBar -edit -endProgress $gMainProgressBar ;"); select -replace $curves; int $j, $k, $l; float $d1, $d2, $bigRadius, $paramMax[], $paramStep[], $vineRadius1, $vineRadius2; vector $normalToPoly, $curveInPosition; int $init; for ($i = 0; $i < size($curves); $i++){//curve to check against if(`progressBar -query -isCancelled $gMainProgressBar`) { print ("// User cancelled the operation with the Escape key.\n"); break; for ($j = 0; $j < $cvCount; $j++){//its cvs for ($k = $i+1; $k < size($curves); $k++){//evaluating curve for ($l = 0; $l < $cvCount; $l++){//its cvs $curveInPosition = `xform -query -translation ($curves[$k]+".cv["+ $l +"]")`;//old method following this formula d2 = d1 - (vineRadius1 + vineRadius2). If d2 is negative or 0 they are touching/penetrating setAttr ($cpoc[$i]+".inPosition") -type "double3" ($curveInPosition.x) ($curveInPosition.y) ($curveInPosition.z); $d1 = `getAttr ($cpoc[$i]+".distance")`; $paramMax[0] = `getAttr ($curves[$i]+".minMaxValue.maxValue")`; $paramMax[1] = `getAttr ($curves[$k]+".minMaxValue.maxValue")`; $paramStep[0] = `getAttr ($cpoc[$i]+".paramU")`; $paramStep[1] = `getAttr ($cpoc[$k]+".paramU")`; $vineRadius1 = $vineRadius * (1 - linstep(1e-007, $paramMax[0], $paramStep[0]));//old method for finding out where they are on the curve $vineRadius2 = $vineRadius * (1 - linstep(1e-007, $paramMax[1], $paramStep[1])); $d2 = $d1 - ($vineRadius1 + $vineRadius2); if ($d2 < 0){//only evalled if they penetrate. this will keep from my script moving things when they shouldnt be and lowering execution time setAttr ($npom+".inPosition") -type "double3" ($curveInPosition.x) ($curveInPosition.y) ($curveInPosition.z); $normalToPoly = `getAttr ($npom+".n")`; $d2 = $d2 * -1;//since d2 is the distance they penetrate we can use it to move the vines out the right amount $normalToPoly = $normalToPoly * $d2;//normal is a unit vector. multiply d2 with the normal and you have the exact amount to move in the correct direction move -relative ($normalToPoly.x) ($normalToPoly.y) ($normalToPoly.z) ($curves[$k]+".cv["+ $l +"]"); refresh -currentView;//view only refreshed if it moves. this line can be commented out to lower execution time dramatically. } progressBar -edit -step 1 $gMainProgressBar; } } } } delete $npom;//scene cleanup delete $cpoc; progressBar -edit -endProgress $gMainProgressBar; } } //used for progress bar in the above script. Its like factorial for addition! global proc int sgkAddThat(int $num) { int $value = $num; do{ $value = $value + ($num - 1); $num = $num - 1; }while($num > 1); return $value; } //A real factorial. Was honestly developed so I could make sure I did the math right. And because I couldn't find a factorial proc in the documentation. global proc int sgkFactorial(int $num) { int $value = $num; do{ $value = $value * ($num - 1); $num = $num - 1; }while($num > 1); return $value; } //Initial adjustment. This script is kind of buggy at the moment. It moves everything even though it shouldn't be. Though it does move it the proper amount! As well as the last point in the curve gets put up way off of the surface. Well it does have its moments of working perfectly. //Also it seems to mess with curve normals. Which makes extrusion ugly. Makes things look funny if the curve moves in space in a turbulant pattern. Lots of squiggles. global proc sgkCurveOffsetToMesh() { global string $gMainProgressBar; string $curves[] = `ls -selection -dagObjects -exactType nurbsCurve`; string $curve; string $controll[], $curveShape[], $captured[], $cpoc[], $surfaces[]; if (size(`ls -selection -dagObjects -exactType mesh`)) $controll = `ls -selection -dagObjects -exactType mesh`; string $npom = `nearestPointOnMesh $controll[0]`; int $progressTestSteps = size($curves); progressBar -edit -beginProgress -isInterruptable true -status "Offseting from the surface" -maxValue $progressTestSteps $gMainProgressBar; evalDeferred("progressBar -edit -endProgress $gMainProgressBar ;"); int $i = 0; int $curveDegree, $curveSpans, $totalCvs[], $touch[]; float $vineRadius, $d1, $d2[], $falloff, $temp2[]; vector $normalToPoly, $curveInPosition[], $surfPos, $temp, $temp3; for ($curve in $curves){//found a new way of consolodating the loops together. This uses the best way I have figured out to calculate the distance. if(`progressBar -query -isCancelled $gMainProgressBar`) { print ("// User cancelled the operation with the Escape key.\n"); break; } $curveDegree = `getAttr ($curve+".degree")`; $curveSpans = `getAttr ($curve+".spans")`; $totalCvs[size($totalCvs)] = $curveDegree + $curveSpans; $cpoc[size($cpoc)] = `closestPointOnCurve $curve`;//I really don't like having it be this general of an array definition, but it works which is what is important. $curveShape = `ls -dag -exactType nurbsCurve $curve`; $captured = `listConnections -type subCurve -source 0 $curveShape[0]`; if (!size(`ls -leaf -dagObjects -exactType nurbsSurface $captured[0]`)) $captured = `listConnections -source 0 $captured[0]`;//recursive for finding what i want. if (!size(`ls -leaf -dagObjects -exactType nurbsSurface $captured[0]`)) $captured = `listConnections -source 0 $captured[0]`; $captured = `ls -leaf -dagObjects -exactType nurbsSurface $captured[0]`; $surfaces[size($surfaces)] = $captured[0]; for ($i = 0; $i < $totalCvs[size($totalCvs) - 1]; $i++){//calculates and stores all the distances from vine to the surface $curveInPosition[$i] = `xform -query -ws -translation ($curveShape[0]+".cv["+ $i +"]")`; $temp = $curveInPosition[$i];//point on curve setAttr ($npom+".inPosition") -type "double3" ($temp.x) ($temp.y) ($temp.z); $temp2 = `getAttr ($npom+".position")`;//I know I shouldnt use this general of defs but it happened that way. This is the nearest point on the mesh to the given point on the curve. $temp3 = <<$temp2[0], $temp2[1], $temp2[2]>>;//point on mesh. takes that var and puts it into a vector. $d1 = mag( ( ($temp) - ($temp3) ) );//Yay distance. $surfPos = `xform -query -translation ($surfaces[size($surfaces) - 1] + ".cv[2][" + $i + "]")`;//random u but specific v. $vineRadius = mag( ($surfPos - $temp) ); $d2[$i] = $d1 - $vineRadius;//modified formula since I am only looking at the relationship of a curve to a mesh if ($d2[$i] <= 0){//if touching $touch[$i] = 1;//boolean for figuring out if they are touching } } for ($i = 0; $i < $totalCvs[size($totalCvs) - 1]; $i++){//the part that actually moves the points if ($touch[$i]){//boolean test. based off the idea of your method of particles to curves. $temp = $curveInPosition[$i]; setAttr ($npom+".inPosition") -type "double3" ($temp.x) ($temp.y) ($temp.z);//wish i could do this with a vector array. Never parsed right. $normalToPoly = `getAttr ($npom+".n")`; $d2[$i] = $d2[$i] * -1; $normalToPoly = $normalToPoly * $d2[$i]; move -relative ($normalToPoly.x) ($normalToPoly.y) ($normalToPoly.z) ($curve+".cv["+ $i +"]"); refresh -currentView;//view only refreshed if it moves. this line can be commented out to lower execution time dramatically. } } progressBar -edit -step 1 $gMainProgressBar; } delete $npom; progressBar -edit -endProgress $gMainProgressBar; } //Creates Extrusions with SubCurve setup. While using the gradient control is nice for a final STILL image should you try to animate the subcurve with anything but the built in scale it starts acting funny because of cv name missmatches. //Just had an idea, can you use subcurves with lofts? because with lofts you wouldn't get the cv name missmatches. and you could edit the scale of the profile curves easier. global proc sgkCurveExtruding() { int $noiseToggle = `checkBox -q -value noiseExtrudeCurve`; int $cvRebuild = `floatFieldGrp -q -value1 cvRebuildAmount`; int $specialToggle = `checkBox -q -value specialExtrusion`; float $circRadius = `floatFieldGrp -q -value1 cvRadius`; global string $gMainProgressBar; sgkVinesToolset;//This was an attempt to fix a bug with the gradient control starting to incorrectly store a temp string with the positions. See the gradient control documentation for info about the string. int $autoFind = `menuItem -q -checkBox autoFind`; string $curves[] = `ls -sl -dag -exactType nurbsCurve`; if ($autoFind){ if (!size($curves)){ warning "FINDING ALL NURBS CURVE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $curves = `ls -dag -exactType nurbsCurve`; } } int $progressTestSteps; if ($specialToggle){$progressTestSteps = size($curves) * ($cvRebuild+3);} else {$progressTestSteps = size($curves);} progressBar -edit -beginProgress -isInterruptable true -status "Extruding Curves..." -maxValue $progressTestSteps $gMainProgressBar; vector $centerPos; string $curve, $circles[], $capturedCircle[], $cpoc[]; evalDeferred("progressBar -edit -endProgress $gMainProgressBar ;"); int $i, $spans; float $maxParam, $minParam, $ratio, $scale, $ran; string $extrude[], $offset[], $tempCPOC; vector $xform, $piv; int $totalCvs = $cvRebuild + 3; string $groupCirc = `group -em -n initialCircles`; string $groupExtrude = `group -em -n sgkExtrudedVines`; for ($curve in $curves){ if(`progressBar -query -isCancelled $gMainProgressBar`) { print ("// User cancelled the operation with the Escape key.\n"); break; } $curve = `rename $curve "particlePath"`; rebuildCurve -replaceOriginal 1 -rebuildType 0 -spans $cvRebuild -degree 3 $curve; $cpoc[size($cpoc)]=`closestPointOnCurve $curve`; $centerPos = `xform -query -translation ($curve+".cv[0]")`;//make those profile curves! $capturedCircle = `circle -center 0 0 0 -radius .25`; move -a ($centerPos.x) ($centerPos.y) ($centerPos.z); $circles[size($circles)] = $capturedCircle[0]; parent -relative $capturedCircle[0] $groupCirc; select -replace $circles[(size($circles)-1)]; select -add $curve; if ($specialToggle){//Use gradient control $extrude = `extrude -rn true -useComponentPivot 1 -fixedPath 1 -useProfileNormal 1 -rotation 0 -scale 1 -reverseSurfaceIfPathReversed 1 $circles[(size($circles)-1)] $curve`; parent -relative $extrude[0] $groupExtrude; $offset = `offsetCurve -ch on -rn false -cb 2 -st true -cl true -cr 0 -d 0 -tol 0.01 -sd 5 -ugn false ($extrude[0]+".u[1]")`;//easiest way i found to find the param locations along the isoparms of the extruded surface $maxParam = `getAttr ($offset[0]+".minMaxValue.maxValue")`; $tempCPOC =`closestPointOnCurve $offset[0]`; $spans = `getAttr ($extrude[0]+".spansU")` - 1; for ($i = 0; $i < $totalCvs; $i++){ $piv = `xform -q -ws -translation ($curve+".cv["+$i+"]")`;//so the scale doesnt act funny see the pivot flag for more info $xform = `xform -q -ws -translation ($offset[0] + ".cv[" + $i + "]")`; setAttr ($tempCPOC +".inPosition") -type "double3" ($xform.x) ($xform.y) ($xform.z); $minParam = `getAttr ($tempCPOC+".paramU")`;//technically the current param location $ratio = linstep(0, $maxParam, $minParam); $scale = `gradientControlNoAttr -valueAtPoint $ratio -q extrudeCurve`; $ran = rand(-.1,.1)*$ratio; if ($noiseToggle) $scale = $scale + $ran; $scale = clamp(0.000001, 1, ($scale));//this is to ensure it never penetrates itself and if noise is on that you dont get a negative scale scale -relative -pivot ($piv.x) ($piv.y) ($piv.z) $scale $scale $scale ($extrude[0]+".cv[0:"+$spans+"]["+$i+"]");//technically i could hard code in the spans, but i already have it saved, might as well be sure maya doesnt change things without me knowing progressBar -edit -step 1 $gMainProgressBar; } delete $offset $tempCPOC;//cleanup }else{//use the built in scale for animation. $extrude = `extrude -rn true -po 0 -et 2 -ucp 1 -fpt 1 -upn 1-scale 1e-06 -rsp 1 $circles[(size($circles)-1)] $curve`; parent -relative $extrude[0] $groupExtrude; progressBar -edit -step 1 $gMainProgressBar; } refresh -currentView; } delete $cpoc; progressBar -edit -endProgress $gMainProgressBar; floatFieldGrp -e -value1 $cvRebuild cvRebuildAmount;//resets the values after it has run in case you do it twice. floatFieldGrp -e -value1 $circRadius cvRadius;//the fix to ensure that I can read the correct vals(due to random problems with gradient control) resets the values to the defaults for these two. This puts them back. } //I can't figure out a way to get this to work. Ideally I should be able to use the nearestPointOnMesh to find out when it penetrates the finish line box and then I should be able to forcibly kill THAT particle. //At the moment the expression executes, parses correctly, but ends up killing all of the particles off(meaning that global proc sgkFinishLine() { int $autoFind = `menuItem -q -checkBox autoFind`; string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } string $goal[] = `polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1`; $goal[0] = `rename $goal[0] "goal"`; polyBevel -offset 0.175 -offsetAsFraction 1 -autoFit 1 -segments 5 -worldSpace 1 -uvAssignment 0 -fillNgons 1 -mergeVertices 1 -mergeVertexTolerance 0.0001 -smoothingAngle 30 -miteringAngle 180 -angleTolerance 180 -ch 1 $goal[0]; string $npom = `nearestPointOnMesh $goal[0]`; //controls... everyone loves controls. addAttr -ln "Width" -at double -min 1e-005 -max 15 -dv 1 ("|"+$goal[0]); setAttr -e-keyable true ("|"+$goal[0]+".Width"); addAttr -ln "Depth" -at double -min 1e-005 -max 15 -dv 1 ("|"+$goal[0]); setAttr -e-keyable true ("|"+$goal[0]+".Depth"); addAttr -ln "Height" -at double -min 1e-005 -max 15 -dv 1 ("|"+$goal[0]); setAttr -e-keyable true ("|"+$goal[0]+".Height"); expression -s ($goal[1]+".width = "+$goal[0]+".Width;") -o $goal[1] -ae 1 -uc all ; expression -s ($goal[1]+".height = "+$goal[0]+".Height;") -o $goal[1] -ae 1 -uc all ; expression -s ($goal[1]+".depth = "+$goal[0]+".Depth;") -o $goal[1] -ae 1 -uc all ; string $test = `dynExpression -q -s -rad $particles[0]`; if (!size($test)) dynExpression -rad -s ($particles[0]+".lifespanPP = 10 + rand(3);\r\nvector $pos = particleShape1.position;\r\nint $val;\r\nsetAttr "+$npom+".inPosition -type \"double3\" ($pos.x) ($pos.y) ($pos.z);\r\n\r\nvector $pos2 = << "+$npom+".positionX, "+$npom+".positionY, "+$npom+".positionZ>>;\r\nvector $norm = << "+$npom+".normalX, "+$npom+".normalY, "+$npom+".normalZ>>;\r\n\r\nvector $new = $pos - $pos2;\r\n\r\nfloat $angle = `angle $norm $new`;\r\n\r\nif ($angle > 1.570796){$val = particleId;\r\n"+$particles[0]+".lifespanPP = 0;\r\n}") $particles[0]; else dynExpression -e -rad -s ($test+"\r\n\r\nsetAttr "+$npom+".inPosition -type \"double3\" ($pos.x) ($pos.y) ($pos.z);\r\n\r\nvector $pos2 = << "+$npom+".positionX, "+$npom+".positionY, "+$npom+".positionZ>>;\r\nvector $norm = << "+$npom+".normalX, "+$npom+".normalY, "+$npom+".normalZ>>;\r\n\r\nvector $new = $pos - $pos2;\r\n\r\nfloat $angle = `angle $norm $new`;\r\n\r\nif ($angle > 1.570796){\r\n"+$particles[0]+".lifespanPP = 0;\r\n}") $particles[0]; //this adds the test that the above expression does for another goal object. IE Expandable. } global proc sgkGravFieldMaker()//awesome grav field control I really ran out of time to make the others. That and grav was really the only one that made sense to visualize for this script. { int $autoFind = `menuItem -q -checkBox autoFind`; string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } string $gravField[] = `gravity -pos 0 0 0 -m 9.8 -att 0 -dx 0 -dy -1 -dz 0 -mxd -1 -vsh none -vex 0 -vof 0 0 0 -vsw 360 -tsr 0.5 `; setAttr ($gravField[0]+".useMaxDistance") 1; connectDynamic -fields $gravField $particles; string $sphere[] = `polySphere -radius .5 -sx 20 -sy 20 -ch 0 `; string $curve = `curve -d 1 -p 0 0 0 -p 0 0 .2 -p 0 -1 .2 -p 0 -1 0 `; string $arrow1 = `curve -d 1 -p 0 1 -1 -p 0 0 -1 -p 0 0 0 -p 0 -1 -1.5 -p 0 0 -3 -p 0 0 -2 -p 0 1 -2 `; closeCurve -ch 0 -ps 1 -rpo 1 -bb 0.5 -bki 0 -p 0.1 $arrow1; scale -r .5 .5 .25 $arrow1; move -a 0 0 .375 $arrow1; string $captured[] = `duplicate $arrow1`; string $arrow2 = $captured[0]; xform -ws -piv 0 -1 0.2 $curve; move -rpr .5 -.5 .5 $curve; move -r .5 0 0 $arrow1; move -r -.5 0 0 $arrow2; string $group = `group -name "GravityField1" $sphere[0] $curve $gravField[0] $arrow1 $arrow2`; addAttr -ln "Magnitude" -at double -min 1e-006 -max 100 -dv 9.8 ("|"+$group); setAttr -e-keyable true ("|"+$group+".Magnitude"); addAttr -ln "MaxDistance" -at double -min 0.0001 -max 35 -dv 1 ("|"+$group); setAttr -e-keyable true ("|"+$group+".MaxDistance"); expression -s ($group+".scaleX = "+$group+".MaxDistance;\r\n"+$group+".scaleY = "+$group+".MaxDistance;\r\n"+$group+".scaleZ = "+$group+".MaxDistance;") -o $group -ae 1 -uc all ;//make the maxdist visulizing expression expression -s ($curve+".scaleY = linstep(0, 100, "+$group+".Magnitude);") -o $curve -ae 1 -uc all ;//mag bar expression -s ($gravField[0]+".maxDistance = .5 * "+$group+".MaxDistance;") -o $gravField[0] -ae 1 -uc all ;//turns out maxdistance in the control is twice the units you specify. Can you say bug? expression -s ($gravField[0]+".magnitude = "+$group+".Magnitude;") -o $gravField[0] -ae 1 -uc all ; expression -s ("vector $p1 = `xform -q -ws -translation "+$arrow1+".cv[0]`;\r\nvector $p2 = `xform -q -ws -translation "+$arrow1+".cv[1]`;\r\n\r\nvector $dir = $p2 - $p1;\r\n$dir = unit($dir);\r\n\r\n\r\n"+$gravField[0]+".directionX = $dir.x;\r\n"+$gravField[0]+".directionY = $dir.y;\r\n"+$gravField[0]+".directionZ = $dir.z;") -o $gravField[0] -ae 1 -uc all ;//my awesome vector direction expression. Auto updates the direction vector for the field with the correct rotation! } global proc sgkTurbFieldMaker() { int $autoFind = `menuItem -q -checkBox autoFind`; string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } string $turbField[] = `turbulence -pos 0 0 0 -m 5 -att 1 -f 1 -phaseX 0 -phaseY 0 -phaseZ 0 -noiseLevel 0 -noiseRatio 0.707 -mxd -1`; setAttr ($turbField[0]+".useMaxDistance") 1; connectDynamic -fields $turbField $particles; } global proc sgkVortexFieldMaker() { int $autoFind = `menuItem -q -checkBox autoFind`; string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } string $vortField[] = `vortex`; connectDynamic -fields $vortField $particles; } global proc sgkGoalMaker() { int $autoFind = `menuItem -q -checkBox autoFind`; string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } string $locator[] = `spaceLocator -p 0 0 0`; goal -w 0.5 -utr 1 -goal $locator $particles; addAttr -ln "Weight" -at double -min 0 -max 1 -dv .5 ("|"+$locator[0]); setAttr -e-keyable true ("|"+$locator[0]+".Weight"); string $connection[] = `listConnections -s 0 -p 1 ($locator[0]+".worldMatrix")`; string $match = `match "\\[[0-9]+\\]" $connection[0]`; connectAttr -f ($locator[0]+".Weight") ($particles[0]+".goalWeight"+$match); } global proc int floatEq( float $vLhs, float $vRhs )//this is included in the maya documentation but is not actually rolled out. Which is sad because it is useful! used in sgkCurveControl { return abs( $vLhs - $vRhs ) < 0.001; } global proc sgkCurveAnimate()//set the keys from the birth and death fields for the surfaces. { int $autoFind = `menuItem -q -checkBox autoFind`; string $curves[] = `ls -sl`; if ($autoFind){ if (!size($curves)){ warning "FINDING ALL NURBS CURVE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $curves = `ls -dag -exactType nurbsCurve`; } } string $curve, $curveShape[], $captured[], $sub[]; int $birth[], $death[], $i; for ($curve in $curves) { $curveShape = `ls -dag -exactType nurbsCurve $curve`; $captured = `listConnections -type subCurve -source 0 $curveShape[0]`; if (!size(`ls -leaf -dagObjects -exactType subCurve $captured[0]`)) $captured = `listConnections -source 0 subCurve $captured[0]`;//these are going to be used for the ultimate version after extrude to get exact distances if (!size(`ls -leaf -dagObjects -exactType subCurve $captured[0]`)) $captured = `listConnections -source 0 subCurve $captured[0]`; $captured = `ls -leaf -dagObjects -exactType subCurve $captured[0]`; $sub[size($sub)] = $captured[0]; $birth[size($birth)] = `getAttr ($curve+".Birth")`; $death[size($death)] = `getAttr ($curve+".Death")`; } for ($i = 0; $i < size($birth); $i++){//I couldn't get most of the flags to work for setKeyframe. It would have been nice to just use the flags without having to set frames and setAttr. currentTime -update false $birth[$i]; setAttr ($sub[$i]+".maxValue") .00001; setKeyframe ($sub[$i]+".maxValue"); print $sub[$i]; currentTime -update false $death[$i]; setAttr ($sub[$i]+".maxValue") 1; setKeyframe ($sub[$i]+".maxValue"); } } //Yes it is overengineered, but it works. I haven't found any bugs with this lately. I will probably update this over the break with your method, because it is a useful way to visualize particle movement without rendering. //This does have an upper limit I have found, at around 1000+ particles and 200 frames it chugs and ultimately maya freezes. Which is fun. global proc sgkParticlesToCurves(int $startFrame, int $endFrame, int $curveDegree, int $minDegree) { int $i, $j, $k, $currentParticle, $lastParticle, $count, $tmp, $frame, $oldPt; int $index[], $pt[], $birth[], $death[], $id[], $cvs[]; float $temp[], $pos[]; string $particle, $particles[], $createCurvesCommands[]; //This loop is for base values for each of the arrays, because of if statements within the next loop. for ($i = 0; $i < 800; $i++){ $index[$i] = 0; $pt[$i] = -1; $birth[$i] = -1; $death[$i] = -1; $id[$i] = -1; $createCurvesCommands[$i] = ("curve -d "+$curveDegree); $cvs[$i] = 0; } int $autoFind = `menuItem -q -checkBox autoFind`; $particles = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } for ($frame = $startFrame; $frame <= $endFrame; $frame++){ currentTime $frame; //for ($particle in $particles){//This will eventually allow for multiple particle shapes. $count = `getAttr ($particles[0]+".count")`; for ($j = 0; $j < $count; $j++){ $temp = `getParticleAttr -attribute id ($particles[0]+".pt["+$j+"]")`; $tmp = $temp[0]; //weird Cannot convert data of type float[] to type int[] error. Fix for that. This also fixes array index must be type int errors. $k = 0;//This is a very important counting variable. It is almost the entire reason this script works. do{//This loop finds out where the id is in the full array, this check ensures that the $birth $death and $curve are all accurate and looking at the same particle. Overengineered, but it wont ever be wrong. if($id[$k] == $tmp){ break; } $k++; }while($id[$k] != -1); if ($temp[0] != $pt[$j]){ //if queried id does not equal old value $index[$tmp] = $k; $id[$k] = $temp[0]; $currentParticle = $k; if ($pt[$j] != -1){ $lastParticle = $index[$pt[$j]];//The only place index gets used. Because it is much simpler to just look at an array than doing ANOTHER loop. This is silly looking back at it. Especially with the min degree value. if ($i > $startFrame){ $death[$lastParticle] = $frame; } } if ($i > $startFrame && $birth[$currentParticle] < 0){ $birth[$currentParticle] = $frame; } $pt[$j] = $temp[0]; } $currentParticle = $k; if ($frame == $endFrame) $death[$currentParticle] = $frame; $pos = `particle -attribute position -id $tmp -query $particles[0]`; $createCurvesCommands[$currentParticle] = $createCurvesCommands[$currentParticle] + ("-p " + $pos[0] + " " + $pos[1] + " " + $pos[2] + " "); $cvs[$currentParticle] += 1; } //} } // generate a group for the curves string $group = `group -em -n sgkParticleCurves`; //Making some curves for ($i = 0; $i < size($createCurvesCommands); $i++){ $createCurvesCommands[$i] = $createCurvesCommands[$i] + ";"; if ($cvs[$i] > $minDegree){ string $curve = `eval($createCurvesCommands[$i])`; parent -relative $curve $group; addAttr -ln "Birth" -at long ("|"+$group+"|"+$curve); addAttr -ln "Death" -at long ("|"+$group+"|"+$curve); setAttr ($curve+".Birth") $birth[$i]; setAttr ($curve+".Death") $death[$i]; } } select -r $group; } global proc sgkMakeCollide()//Collides the particles with the objects, NOT DEPENDANT ON ORDER. { int $autoFind = `menuItem -q -checkBox autoFind`; string $objects[] = `ls -sl -dag -et mesh`; if ($autoFind){ if (!size($objects)){ warning "FINDING ALL MESH SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $objects = `ls -dag -exactType mesh`; } } string $particles[] = `ls -sl -dag -exactType particle`; if ($autoFind){ if (!size($particles)){ warning "FINDING ALL PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } } if (size($objects) != 0){ collision -resilience 0 -friction .1 $objects; connectDynamic -collisions $objects $particles; } else{ warning "//NO OBJECTS SELECTED. NO COLLISION DONE. PLEASE SELECT OBJECTS OR TURN AUTO-FIND ON.//"; } } global proc sgkMakeEmitter()//Make that emitter and set it up right! { int $collideToggle = `checkBox -q -value autoCollide`; int $maxCount = `intSliderGrp -q -value maxCount`; int $lifespanToggle = `checkBox -q -value lifespan`; int $autoFind = `menuItem -q -checkBox autoFind`; float $lifespanValue = `floatSliderGrp -q -value lifespanValue`; float $lifespanValueRandom = `floatSliderGrp -q -value lifespanValueRandom`; float $lifespanValueSeed = `floatSliderGrp -q -value lifespanValueSeed`; string $objects[] = `ls -sl -dag -et mesh`; if ($autoFind){ if (!size($objects)){ warning "FINDING ALL MESH SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $objects = `ls -dag -exactType mesh`; } } string $emitter[] = `emitter -pos 0 0 0 -type omni -rate 100 -cye none -spd 1 -nsp 1 -tsp 0 -mxd 0 -mnd 0 -dx 1 -dy 0 -dz 0 -sp 0 `; string $particle[] = `particle`; connectDynamic -em $emitter $particle; setAttr ($particle[0]+".goalSmoothness") 8; setAttr ($particle[0]+".maxCount") $maxCount; if (size($objects) != 0){ switch ($collideToggle){ case 1: collision -resilience 0 -friction .1 $objects; connectDynamic -collisions $objects $particle; break; case 0: break; } }else{warning "//NO OBJECTS SELECTED. NO COLLISION DONE. PLEASE SELECT OBJECTS OR TURN AUTO-FIND ON.//";} switch ($lifespanToggle) { case 1: setAttr ($particle[0]+".lifespanMode") 2; setAttr ($particle[0]+".lifespan") $lifespanValue; setAttr ($particle[0]+".lifespanRandom") $lifespanValueRandom; setAttr ($particle[0]+".generalSeed") $lifespanValueSeed; break; case 0: break; } }