def apply(self, objects, **kwargs): presetDict = self.unpickle() srcObjs = presetDict[kEXPORT_DICT_OBJECTS] clip = presetDict[kEXPORT_DICT_THE_CLIP] #do a version check - if older version clip is being used - perhaps we can write conversion functionality? try: ver = presetDict[kEXPORT_DICT_TOOL_VER] if ver != VER: api.melWarning("the anim clip version don't match!") except KeyError: api.melWarning( "this is an old VER 1 pose clip - I don't know how to load them anymore..." ) return #generate the name mapping slamApply = kwargs.get('slam', False) if slamApply: objects = cmd.ls(typ='transform') tgts = names.matchNames(srcObjs, objects, threshold=kDEFAULT_MAPPING_THRESHOLD) mapping = Mapping(srcObjs, tgts) else: tgts = names.matchNames(srcObjs, objects, threshold=kDEFAULT_MAPPING_THRESHOLD) mapping = Mapping(srcObjs, tgts) #run the clip's apply method clip.apply(mapping, **kwargs)
def apply( self, objects, attributes=None, **kwargs ): presetDict = self.unpickle() srcObjs = presetDict[ kEXPORT_DICT_OBJECTS ] clip = presetDict[ kEXPORT_DICT_THE_CLIP ] #do a version check - if older version clip is being used - perhaps we can write conversion functionality? try: ver = presetDict[ kEXPORT_DICT_TOOL_VER ] if ver != VER: api.melWarning("the anim clip version don't match!") except KeyError: api.melWarning("this is an old VER 1 pose clip - I don't know how to load them anymore...") return #generate the name mapping slamApply = kwargs.get( 'slam', False ) if slamApply: objects = cmd.ls( typ='transform' ) tgts = names.matchNames( srcObjs, objects, threshold=kDEFAULT_MAPPING_THRESHOLD ) mapping = Mapping( srcObjs, tgts ) else: tgts = names.matchNames( srcObjs, objects, threshold=kDEFAULT_MAPPING_THRESHOLD ) mapping = Mapping( srcObjs, tgts ) #run the clip's apply method clip.apply( mapping, attributes, **kwargs )
def merge( directionAstart, directionAend, directionBstart, newStart ): '''merges two different locomotes together - for example N and E to give a NE locomote''' #determine which ctrl set to use length = directionAend-directionAstart ctrlSet = names.matchNames(['body_ctrls'],cmd.ls(type='objectSet')) if not ctrlSet: raise Exception('control set not found') ctrlSet = ctrlSet[0] ctrls = cmd.sets(ctrlSet,q=True) #deal with the assets for the new animation vx = exportManagerCore.ExportManager() assetA = vx.exists(start=directionAstart,end=directionAend)[0] assetB = vx.exists(start=directionBstart,end=directionBstart+length)[0] exportSet = assetA.obj assetC = vx.exists(start=newStart,end=newStart+length) if not assetC: assetC = vx.createAsset(exportSet) assetC.setAttr('start', newStart) assetC.setAttr('end', newStart+length) assetC.setAttr('name', assetA.name + assetB.name) assetC.setAttr('type', exportManagerCore.ExportComponent.kANIM) #now start building the animations animationA = Animation(ctrls,directionAstart,directionAend) animationB = Animation(ctrls,directionBstart,directionBstart+length) animationB.offset(-directionBstart+directionAstart) animationC = animationA+animationB animationC.offset(newStart) #grab the list of ctrls we need to actually transform toFind = ['upperBodyControl','legControl_L','legControl_R'] xformCtrls = [name for name in names.matchNames(toFind,ctrls,parity=True,threshold=0.8) if name != ''] for ctrl in xformCtrls: motionA = motionList(ctrl,directionAstart,directionAend) motionB = motionList(ctrl,directionBstart,directionBstart+length) #make the time zero based times = [int(time)-newStart for time in animationC[ctrl].get_times(channels=['translateX','translateZ'])] times.sort() print times,len(motionA),len(motionB) for time in times: print motionA[time],motionB[time] newPos = vectors.Vector(motionA[time]) + vectors.Vector(motionB[time]) newPos *= 0.70710678118654757 #= math.cos(45degrees) tx = animationC[ctrl].translateX[time] tz = animationC[ctrl].translateZ[time] if tx: tx.keys[0] = newPos.x if tz: tz.keys[0] = newPos.z animationC.applyToObjs() #end
def on_selectSrc(self, *a): src = self.getSelectedSrc() if src: #if the object doesnt' exist in teh scene - try to find it if not cmd.objExists(src): src = names.matchNames([src], cmd.ls(typ='transform'))[0] if cmd.objExists(src): cmd.select(src)
def on_selectSrc( self, *a ): src = self.getSelectedSrc() if src: #if the object doesnt' exist in teh scene - try to find it if not cmd.objExists( src ): src = names.matchNames( [ src ], cmd.ls( typ='transform' ) )[ 0 ] if cmd.objExists( src ): cmd.select( src )
def mapSrcItem(self, src): self._srcToTgtDict[src] = names.matchNames( [src], self.tgts, self.STRIP_NAMESPACES, self.PARITY_MATCH, self.UNIQUE_MATCHING, self.MATCH_OPPOSITE_PARITY, self.THRESHOLD, )
def on_selectTgt( self, *a ): tgts = self.getSelectedTgts() if tgts: toSearch = cmd.ls( typ='transform' ) existingTgts = [] for t in tgts: if not cmd.objExists( t ): t = names.matchNames( [ t ], toSearch )[ 0 ] if cmd.objExists( t ): existingTgts.append( t ) if existingTgts: cmd.select( existingTgts )
def resolveMapping(mapping, **kw): ''' resolves the mapping to actual maya nodes - returns a mapping object with non existing nodes stripped. any additional kw args are passed to the matchNames function ''' assert isinstance(mapping, names.Mapping) toSearch = cmd.ls(typ='transform') existingSrcs = [] existingTgts = [] for src, tgt in mapping.iteritems(): if not cmd.objExists(src): src = names.matchNames([src], toSearch, **kw)[0] if not cmd.objExists(tgt): tgt = names.matchNames([tgt], toSearch, **kw)[0] if cmd.objExists(src) and cmd.objExists(tgt): existingSrcs.append(src) existingTgts.append(tgt) return names.Mapping(existingSrcs, existingTgts)
def resolveMapping( mapping, **kw ): ''' resolves the mapping to actual maya nodes - returns a mapping object with non existing nodes stripped. any additional kw args are passed to the matchNames function ''' assert isinstance( mapping, names.Mapping ) toSearch = cmd.ls( typ='transform' ) existingSrcs = [] existingTgts = [] for src, tgt in mapping.iteritems(): if not cmd.objExists( src ): src = names.matchNames( [ src ], toSearch, **kw )[ 0 ] if not cmd.objExists( tgt ): tgt = names.matchNames( [ tgt ], toSearch, **kw )[ 0 ] if cmd.objExists( src ) and cmd.objExists( tgt ): existingSrcs.append( src ) existingTgts.append( tgt ) return names.Mapping( existingSrcs, existingTgts )
def on_selectTgt(self, *a): tgts = self.getSelectedTgts() if tgts: toSearch = cmd.ls(typ='transform') existingTgts = [] for t in tgts: if not cmd.objExists(t): t = names.matchNames([t], toSearch)[0] if cmd.objExists(t): existingTgts.append(t) if existingTgts: cmd.select(existingTgts)
def loadPostTraceSchemeFilepath( presetFile ): ''' re-applies a stored post trace command scheme back to the controls found in the current scene ''' #first we need to purge all existing post trace commands clearPostTraceScheme() presetFile = Path( presetFile ) if not presetFile.isfile(): raise IOError, "no such preset" xportDict, postTraceDict = presetFile.unpickle() allTransforms = cmd.ls( typ='transform' ) for n, postTraceCmd in postTraceDict.iteritems(): n = n.split( '.' )[ 0 ] #strip off the attribute nInScene = names.matchNames( [ n ], allTransforms )[ 0 ] if cmd.objExists( nInScene ): api.mel.zooSetPostTraceCmd( nInScene, postTraceCmd )
def loadPostTraceSchemeFilepath(presetFile): ''' re-applies a stored post trace command scheme back to the controls found in the current scene ''' #first we need to purge all existing post trace commands clearPostTraceScheme() presetFile = Path(presetFile) if not presetFile.isfile(): raise IOError, "no such preset" xportDict, postTraceDict = presetFile.unpickle() allTransforms = cmd.ls(typ='transform') for n, postTraceCmd in postTraceDict.iteritems(): n = n.split('.')[0] #strip off the attribute nInScene = names.matchNames([n], allTransforms)[0] if cmd.objExists(nInScene): api.mel.zooSetPostTraceCmd(nInScene, postTraceCmd)
def commonApply(rig, rigNS, filename, nodes, mapping, postTraceSchemeFilepath=None, sortBySrcs=True): #apply the post trace scheme if applicable if postTraceSchemeFilepath is not None: loadPostTraceSchemeFilepath(postTraceSchemeFilepath) possibleSrcs = cmd.ls('%s*' % IMPORT_DATA_NS, typ='transform') possibleTgts = cmd.ls('%s*' % rigNS, typ='transform') #build the ctrl-bone mapping - and ensure proper namespaces are present... the mapping contains no namespaces srcs, tgts = [], [] idx = 0 if sortBySrcs else 1 toSort = [] for src, tgt in mapping.iteritems(): src = names.matchNames([src], possibleSrcs)[0] tgt = names.matchNames([tgt], possibleTgts)[0] srcOrTgt = src, tgt if cmd.objExists(srcOrTgt[idx]): numParents = len(list(api.iterParents(srcOrTgt[idx]))) toSort.append((numParents, src, tgt)) toSort.sort() for idx, src, tgt in toSort: srcs.append(src) tgts.append(tgt) print "rig namespace is:", rigNS print 'srcs are', srcs print 'tgts are', tgts #sort the items by hierarchy based on the src items - xferAnim does have the option of doing this, but it sorts using the tgt list, and its done in mel, so... I don't trust it srcsParentCount = [(len([p for p in api.iterParents(s)]), s, t) for s, t in zip(srcs, tgts) if cmd.objExists(s)] srcsParentCount.sort() srcs = [s[1] for s in srcsParentCount] tgts = [s[2] for s in srcsParentCount] #now turn any ik off - we'll restore it afterwards, but if ik is on, then fk controls don't get traced properly... coz maya is ghey! initIkBlendValues = {} for t in tgts: attrPath = "%s.ikBlend" % t if cmd.objExists(attrPath): initIkBlendValues[attrPath] = cmd.getAttr(attrPath) cmd.setAttr(attrPath, 0) #perform the trace api.melecho.zooXferTrace(srcs, tgts, True, True, False, True, False, -1000, 1000) #restore ik settings for attrPath, value in initIkBlendValues.iteritems(): cmd.setAttr(attrPath, value) #rename the file mayaFilepath = apps.getAssetRoot( rig, apps.MAYA) / 'maya/animation' / filename.name() mayaFilepath.up().create() cmd.file(rename=mayaFilepath) mayaFilepath = Path(cmd.file(q=True, sn=True)) #try to determine the info node to export exportNode = None for n in cmd.ls(typ='vstInfo'): if n.startswith(rigNS): exportNode = n break #setup the export manager data if we can... if exportNode is not None: xm = exportManagerCore.ExportManager() comp = xm.createExportComponent([exportNode]) comp.setAttr('name', mayaFilepath.name()) comp.setAttr('type', exportManagerCore.ExportComponent.kANIM) #save changes... cmd.file(save=True, f=True) return mayaFilepath
def mapSrcItem( self, src ): self._srcToTgtDict[ src ] = names.matchNames( [ src ], self.tgts, self.STRIP_NAMESPACES, self.PARITY_MATCH, self.UNIQUE_MATCHING, self.MATCH_OPPOSITE_PARITY, self.THRESHOLD )
def generate( baseStart, baseEnd,\ rotations = PRIMARY_ROTATIONS,\ strideLengthMultipliers = PRIMARY_SPEEDS,\ starts = PRIMARY_START_FRAMES,\ directions = PRIMARY_NAMES ): #determine which ctrl set to use ctrlSet = names.matchNames(['body_ctrls'], cmd.ls(type='objectSet'), threshold=1) if not ctrlSet: raise Exception('control set not found') ctrlSet = ctrlSet[0] ctrls = cmd.sets(ctrlSet, q=True) length = baseEnd - baseStart num = len(rotations) #does the base locomote have an asset? vx = exportManagerCore.ExportManager() baseAsset = vx.exists(start=baseStart, end=baseEnd) infoNode = '' exportSet = '' if len(baseAsset): baseAsset = baseAsset[0] exportSet = baseAsset.obj else: #if it doesn't exist, try and create one infoNodes = cmd.ls(type='vstInfo') candidates = [] for node in infoNodes: if not cmd.referenceQuery(node, inr=True): continue if not cmd.listRelatives(node): continue candidates.append(node) infoNode = candidates[0] exportSet = exportManagerCore.ExportManager.CreateExportSet([infoNode]) #now build the actual asset asset = vx.createAsset(exportSet) asset.setAttr('start', baseStart) asset.setAttr('end', baseEnd) asset.setAttr('name', 'N') asset.setAttr('type', exportManagerCore.ExportComponent.kANIM) #grab the list of ctrls we need to actually transform toFind = ['upperBodyControl', 'legControl_L', 'legControl_R'] #, 'armControl_L', 'armControl_R' ] xformCtrls = [ name for name in names.matchNames(toFind, ctrls, parity=True, threshold=0.8) if name != '' ] animation = Animation(ctrls, baseStart, baseEnd) animation.getWorld(xformCtrls, ['translateX', 'translateZ']) #save the animation out - useful for doing deltas later on #write(animation,g_defaultKeyUtilsPickle) #build the rotation axis axis = vectors.Vector([0, 1, 0]) for n in xrange(num): offset = starts[n] - baseStart tmpAnim = animation.copy() tmpAnim.offset(offset) #convert angles to radians, and do other static calcs angle = rotations[n] angle = math.radians(angle) quat = vectors.Quaternion.AxisAngle(axis, angle) for ctrl in xformCtrls: clip = tmpAnim[ctrl] #do the actual rotation around Y mats = clip.world translateX = clip.translateX.keys = [] translateZ = clip.translateZ.keys = [] for mat in mats: pos = mat.get_position() pos = pos.rotate(quat) mat[3][:3] = pos translateX.append(Key(time=mat.time, value=pos.x)) translateZ.append(Key(time=mat.time, value=pos.z)) #now do stride length multiplication strideMult = strideLengthMultipliers[n] if strideMult is not None: def makeShorter(key): key.value *= strideMult return key clip.translateX.transform(makeShorter) clip.translateZ.transform(makeShorter) tmpAnim.applyToObjs(clearFirst=True) #finally create an asset for the new anim existing = vx.exists(start=starts[n], end=starts[n] + length, name=directions[n]) if not len(existing): asset = vx.createAsset(exportSet) asset.setAttr('start', starts[n]) asset.setAttr('end', starts[n] + length) asset.setAttr('name', directions[n]) asset.setAttr('type', exportManagerCore.ExportComponent.kANIM)
def commonApply( rig, rigNS, filename, nodes, mapping, postTraceSchemeFilepath=None, sortBySrcs=True ): #apply the post trace scheme if applicable if postTraceSchemeFilepath is not None: loadPostTraceSchemeFilepath( postTraceSchemeFilepath ) possibleSrcs = cmd.ls( '%s*' % IMPORT_DATA_NS, typ='transform' ) possibleTgts = cmd.ls( '%s*' % rigNS, typ='transform' ) #build the ctrl-bone mapping - and ensure proper namespaces are present... the mapping contains no namespaces srcs, tgts = [], [] idx = 0 if sortBySrcs else 1 toSort = [] for src, tgt in mapping.iteritems(): src = names.matchNames( [ src ], possibleSrcs )[ 0 ] tgt = names.matchNames( [ tgt ], possibleTgts )[ 0 ] srcOrTgt = src, tgt if cmd.objExists( srcOrTgt[ idx ] ): numParents = len( list( api.iterParents( srcOrTgt[ idx ] ) ) ) toSort.append( (numParents, src, tgt) ) toSort.sort() for idx, src, tgt in toSort: srcs.append( src ) tgts.append( tgt ) print "rig namespace is:", rigNS print 'srcs are', srcs print 'tgts are', tgts #sort the items by hierarchy based on the src items - xferAnim does have the option of doing this, but it sorts using the tgt list, and its done in mel, so... I don't trust it srcsParentCount = [ (len( [p for p in api.iterParents( s )] ), s, t) for s, t in zip( srcs, tgts ) if cmd.objExists( s ) ] srcsParentCount.sort() srcs = [ s[ 1 ] for s in srcsParentCount ] tgts = [ s[ 2 ] for s in srcsParentCount ] #now turn any ik off - we'll restore it afterwards, but if ik is on, then fk controls don't get traced properly... coz maya is ghey! initIkBlendValues = {} for t in tgts: attrPath = "%s.ikBlend" % t if cmd.objExists( attrPath ): initIkBlendValues[ attrPath ] = cmd.getAttr( attrPath ) cmd.setAttr( attrPath, 0 ) #perform the trace api.melecho.zooXferTrace( srcs, tgts, True, True, False, True, False, -1000, 1000 ) #restore ik settings for attrPath, value in initIkBlendValues.iteritems(): cmd.setAttr( attrPath, value ) #rename the file mayaFilepath = apps.getAssetRoot( rig, apps.MAYA ) / 'maya/animation' / filename.name() mayaFilepath.up().create() cmd.file( rename=mayaFilepath ) mayaFilepath = Path( cmd.file( q=True, sn=True ) ) #try to determine the info node to export exportNode = None for n in cmd.ls( typ='vstInfo' ): if n.startswith( rigNS ): exportNode = n break #setup the export manager data if we can... if exportNode is not None: xm = exportManagerCore.ExportManager() comp = xm.createExportComponent( [ exportNode ] ) comp.setAttr( 'name', mayaFilepath.name() ) comp.setAttr( 'type', exportManagerCore.ExportComponent.kANIM ) #save changes... cmd.file( save=True, f=True ) return mayaFilepath
def generate( baseStart, baseEnd,\ rotations = PRIMARY_ROTATIONS,\ strideLengthMultipliers = PRIMARY_SPEEDS,\ starts = PRIMARY_START_FRAMES,\ directions = PRIMARY_NAMES ): #determine which ctrl set to use ctrlSet = names.matchNames(['body_ctrls'],cmd.ls(type='objectSet'),threshold=1) if not ctrlSet: raise Exception('control set not found') ctrlSet = ctrlSet[0] ctrls = cmd.sets(ctrlSet,q=True) length = baseEnd-baseStart num = len(rotations) #does the base locomote have an asset? vx = exportManagerCore.ExportManager() baseAsset = vx.exists(start=baseStart,end=baseEnd) infoNode = '' exportSet = '' if len(baseAsset): baseAsset = baseAsset[0] exportSet = baseAsset.obj else: #if it doesn't exist, try and create one infoNodes = cmd.ls(type='vstInfo') candidates = [] for node in infoNodes: if not cmd.referenceQuery(node,inr=True): continue if not cmd.listRelatives(node): continue candidates.append(node) infoNode = candidates[0] exportSet = exportManagerCore.ExportManager.CreateExportSet( [infoNode] ) #now build the actual asset asset = vx.createAsset(exportSet) asset.setAttr('start', baseStart) asset.setAttr('end', baseEnd) asset.setAttr('name', 'N') asset.setAttr('type', exportManagerCore.ExportComponent.kANIM) #grab the list of ctrls we need to actually transform toFind = [ 'upperBodyControl', 'legControl_L', 'legControl_R' ]#, 'armControl_L', 'armControl_R' ] xformCtrls = [ name for name in names.matchNames( toFind, ctrls, parity=True, threshold=0.8 ) if name != '' ] animation = Animation( ctrls, baseStart, baseEnd ) animation.getWorld(xformCtrls,['translateX','translateZ']) #save the animation out - useful for doing deltas later on #write(animation,g_defaultKeyUtilsPickle) #build the rotation axis axis = vectors.Vector([0, 1, 0]) for n in xrange(num): offset = starts[n]-baseStart tmpAnim = animation.copy() tmpAnim.offset( offset ) #convert angles to radians, and do other static calcs angle = rotations[n] angle = math.radians(angle) quat = vectors.Quaternion.AxisAngle( axis, angle ) for ctrl in xformCtrls: clip = tmpAnim[ctrl] #do the actual rotation around Y mats = clip.world translateX = clip.translateX.keys = [] translateZ = clip.translateZ.keys = [] for mat in mats: pos = mat.get_position() pos = pos.rotate(quat) mat[3][:3] = pos translateX.append( Key( time=mat.time, value=pos.x ) ) translateZ.append( Key( time=mat.time, value=pos.z ) ) #now do stride length multiplication strideMult = strideLengthMultipliers[n] if strideMult is not None: def makeShorter( key ): key.value *= strideMult return key clip.translateX.transform(makeShorter) clip.translateZ.transform(makeShorter) tmpAnim.applyToObjs(clearFirst=True) #finally create an asset for the new anim existing = vx.exists( start=starts[n], end=starts[n]+length, name=directions[n] ) if not len(existing): asset = vx.createAsset( exportSet ) asset.setAttr('start', starts[n]) asset.setAttr('end', starts[n]+length) asset.setAttr('name', directions[n]) asset.setAttr('type', exportManagerCore.ExportComponent.kANIM)