# 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()