# MayaCurveCache.py
# Implements a specialized version of the cache
# that can generate Maya curves based on the
# data it has been given
#--> = my added notes
import BasicCache as BC
import maya.cmds as mc
import ProjectUtilities as PU
import random
#============================================
# Note this super class is derived from BasicCache.
class MayaParticleCache(BC.BasicCache):
# This queries the particle system and used the base
# class method "add()" to accumulate xyz data
#--> tnode is an argument passed over by the MEL script at call
def updateCache(self, tnode):
pnum = mc.particle(tnode, q = True, count = True)
for n in range(pnum):
pname = tnode + ".pt[%s]" % n
pos = mc.getParticleAttr(pname,at = 'position')
# getParticleAttr returns a list of 6 values of which
# only the first three are a particles xyz position!
#--> the trim function cuts this down to the first three
#--> i.e. the first position (0) up to but not including
#--> the fourth (3)
self.add(pos[0:3])
# Construct the string that will become the Mel command to
# create a curve
def writeCurve(self):
melcmd = 'curve -d 3 '
#--> counter for line-breaks for readability
count = 1
for xyz in self.data:
#--> remember, the point coords are stored in a LIST of TUPLES
#--> therefore xyz denotes the LIST index and the bracketed
#--> numbers indicate the TUPLE index of that LIST index
melcmd = melcmd + '-p %1.3f %1.3f %1.3f ' % (xyz[0],xyz[1],xyz[2])
count += 1
if count > 5:
#--> adds a return and tab carriage for human-readability
melcmd += '\n\t'
count = 1
melcmd = melcmd + ';'
#--> stores the string in dataStr in case we want
#--> to concatenate with others
self.dataStr = self.dataStr + melcmd
return melcmd
#--> randomized version of the single curve code
#--> uses the position of the particles but adds
#--> a random value to each before generating the curve
def writeRandomCurve(self):
melcmd = 'curve -d 3 '
#--> counter for line-breaks for readability
count = 1
for xyz in self.data:
randX = random.uniform (.1, .3)
newX = xyz[0] + randX
randY = random.uniform (.1, .3)
newY = xyz[1] + randY
randZ = random.uniform (.1, .3)
newZ = xyz[2] + randZ
#--> remember, the point coords are stored in a LIST of TUPLES
#--> therefore xyz denotes the LIST index and the bracketed
#--> numbers indicate the TUPLE index of that LIST index
melcmd = melcmd + '-p %1.3f %1.3f %1.3f ' % (newX,newY,newZ)
count += 1
if count > 5:
#--> adds a return and tab carriage for human-readability
melcmd += '\n\t'
count = 1
melcmd = melcmd + ';'
#--> stores the string in dataStr in case we want
#--> to concatenate with others
self.dataStr = self.dataStr + melcmd
return melcmd
#--> Construct the multiple strings that will become
#--> the Mel command to create multiple spikes
def writeManyCurves(self):
starter = 'curve -d 1 -p 0 0 0 '
melcmd = starter
for xyz in self.data:
melcmd = melcmd + '-p %1.3f %1.3f %1.3f' % (xyz[0],xyz[1],xyz[2]) + ';\n'
if xyz <= (self.data):
melcmd = melcmd + starter
else:
melcmd = melcmd + ';'
self.dataStr = self.dataStr + melcmd
return melcmd
#--> randomized version of the spikes
def writeManyRandomCurves(self):
starter = 'curve -d 1 -p 0 0 0 '
melcmd = starter
for xyz in self.data:
randX = random.uniform (.1, .3)
newX = xyz[0] + randX
randY = random.uniform (.1, .3)
newY = xyz[1] + randY
randZ = random.uniform (.1, .3)
newZ = xyz[2] + randZ
melcmd = melcmd + '-p %1.3f %1.3f %1.3f' % (newX,newY,newZ) + ';\n'
if xyz <= (self.data):
melcmd = melcmd + starter
else:
melcmd = melcmd + ';'
self.dataStr = self.dataStr + melcmd
return melcmd
#============================================
#--> instance the above superclass
pCache = MayaParticleCache()
projUtils = PU.ProjectUtilities()
def particlesToMayaCurves(tnode, startAt, endFrame, curveType):
# If we prefer to base the duration of the simulation on the users
# render globals the next line can be activated
#endFrame = mc.getAttr("defaultRenderGlobals.endFrame");
#--> sets the script up to work on the correct file
pCache.setDataPath(projUtils.getDataDir() + "/" + projUtils.getSceneName() + ".mel");
for currFrame in range(endFrame):
#--> we increment first instead of after because "currFrame"
#--> starts at zero and there is no frame zero
currFrame += 1;
mc.currentTime(currFrame);
print("frame %s" % currFrame)
if currFrame == 1:
pCache.reset()
if currFrame >= startAt and currFrame <= endFrame:
pCache.updateCache(tnode)
if currFrame == endFrame:
if curveType == 1:
#--> single curve
return pCache.writeCurve()
elif curveType == 2:
#--> spikes
return pCache.writeManyCurves()
elif curveType == 3:
#--> single curve randomized
return pCache.writeRandomCurve()
elif curveType == 4:
#--> spikes randomized
return pCache.writeManyRandomCurves()
else:
print "FAIL: Did not recognize curve type"
def writeToFile():
return pCache.writeToFile()