/* Official Klockworks.net Release! This script is like many of the other particle path curve generators, except this script can handle particle death. This script not only handles particle death but adds custom attributes to each curve detailing the birth and death frame. DISCLAIMER: This script does have an upper limit to the amount of particles it can handle alive at one time, I do not know the exact number but it is dictated by your RAM. Should you hit this upper limit MAYA WILL FREEZE, no auto-save, no crash, just a full freeze. Note: You may notice it actually continueing to go, even if just very slowly. This is due to the amount of particles it has to go through for that frame, lots of particles alive at one time, lots of steps needed to complete the loop. With the addition of the progress bar to v1.2 and up you can push esc at any time during the script execution to cancel the process. This will stop after the current frame is done and create what it has so far into curves. USE: To use this script rehash your script table, source it, and run the particlePath() script, the GUI will appear. EX: rehash; source sgkParticlePathCurves.mel; particlePath; VERSIONS: 1.2: Added a progress bar. 1.1: Added sample step. 1.0: Initial release. If you have any questions, comments, or bugs relating to this script please post a comment http://klockworks.net/blog/?p=52 If you have any general questions or requests of any kind don't hesitate to send me an email at klock.sam@gmail.com To-Do: Figure out a way to handle multiple particle shapes without going through the timeline multiple times. ENJOY! */ global proc particlePath(){ string $window = "sgkParticlePathCurves";//Global name for window if (`window -exists $window`)//Is my window there? deleteUI $window; window -title "Klockworks Particle Paths" -widthHeight 287 176 -maximizeButton false $window; scrollLayout; columnLayout -columnAlign "left"; columnLayout; floatFieldGrp -numberOfFields 1 -precision 0 -label "Start Frame" -value1 1 startFrame; floatFieldGrp -numberOfFields 1 -precision 0 -label "End Frame" -value1 240 endFrame; floatFieldGrp -numberOfFields 1 -precision 0 -label "Sample Step" -value1 1 sampleStep; floatFieldGrp -numberOfFields 1 -precision 0 -label "Curve Degree" -value1 3 curveDegree; floatFieldGrp -numberOfFields 1 -precision 0 -label "Mimimum Degree" -value1 3 minCurveDegree; button -label "Go!" -align "center" -command "sgkPartsToCurves"; showWindow $window; } global proc sgkPartsToCurves() { int $startFrame = `floatFieldGrp -q -value1 startFrame`; int $endFrame = `floatFieldGrp -q -value1 endFrame`; int $sample = `floatFieldGrp -q -value1 sampleStep`; int $curveDegree = `floatFieldGrp -q -value1 curveDegree`; int $minDegree = `floatFieldGrp -q -value1 minCurveDegree`; if ($minDegree<$curveDegree){ error "MINIMUM DEGREE MUST BE GREATER TO THE CURVE DEGREE."; }else{ sgkParticlePathCurves($startFrame, $endFrame, $sample, $curveDegree, $minDegree);} } global proc sgkParticlePathCurves(int $startFrame, int $endFrame, int $sample, int $curveDegree, int $minDegree) { int $i, $tmp, $frame; int $birth[], $death[], $cvs[]; float $temp[], $pos[]; string $particle, $particles[], $createCurvesCommands[]; global string $gMainProgressBar; int $progressTestSteps = $endFrame - $startFrame; progressBar -edit -beginProgress -isInterruptable true -status "Recording Particle Position..." -maxValue $progressTestSteps $gMainProgressBar; $particles = `ls -sl -dag -exactType particle`; if (!size($particles)){ warning "FINDING THE FIRST PARTICLE SHAPE NODES IN SCENE. MAY HAVE UNINTENDED RESULTS"; $particles = `ls -dag -exactType particle`; } evalDeferred("progressBar -edit -endProgress $gMainProgressBar ;"); for ($frame = $startFrame; $frame <= $endFrame; $frame++){ currentTime $frame; $count = `getAttr ($particles[0]+".count")`; for ($i = 0; $i < $count; $i++){ $temp = `getParticleAttr -attribute id ($particles[0]+".pt["+$i+"]")`; $tmp = $temp[0]; if (!$birth[$tmp]){ $birth[$tmp] = $frame; $createCurvesCommands[$tmp] = ("curve -d " + $curveDegree); $cvs[$tmp] = 0; } $death[$tmp] = $frame; if (!($frame%$sample)){ $pos = `particle -attribute position -id $tmp -query $particles[0]`; $createCurvesCommands[$tmp] = $createCurvesCommands[$tmp] + ("-p " + $pos[0] + " " + $pos[1] + " " + $pos[2] + " "); $cvs[$tmp] += 1; } if(`progressBar -query -isCancelled $gMainProgressBar`)//This is where the esc button is checked, so not all the particles will be checked up to the same frame should you hit the esc button. { print ("// User cancelled the operation with the Escape key.\n"); break; } } progressBar -edit -step 1 $gMainProgressBar; } string $group = `group -em -n sgkParticleCurves`; 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; progressBar -edit -endProgress $gMainProgressBar; }