def _makeSharedShape(obj, name, shapeType): ''' shapeType should be either 'sharedShape' or 'kinematicSwitch' Returns a string of the shape, ex 'Foot_L|sharedShape' (to bypass pymel warnings) ''' shape = cmds.createNode( 'nurbsCurve', p=obj.longName() ) # 2017 added a bunch of keyable attrs so get rid of them if possible. for attr in cmds.listAttr(shape, k=True): try: cmds.setAttr(shape + '.' + attr, k=False, l=True) except Exception as e: # noqa #print( e ) pass # Make it a valid curve so it doesn't get deleted during optimize scene # but lock and hide it. mel.eval('''setAttr "%s.cc" -type "nurbsCurve" 1 1 0 no 3 2 0 1 2 0 0 0 0 0 0 ;''' % shape ) setAttr(shape + '.visibility', False, l=True) # noqa addAttr(shape, ln=core.shape.sharedShapeTag, at='message') cmds.addAttr( shape, ln=shapeType, at='message' ) cmds.rename( shape, name ) return obj.longName() + '|' + name
def fbxExport(objs, start, end, filepath): ''' Convenience function to export fbx animations. :param node/list objs: An object, or list, to export. Most likely Rig:b_root. :param int start: The beginning of the range to export. :param int end: The end of the range to export. :param string filepath: The full name to export. ''' assert os.path.exists( FBX_ANIM_PRESETS_FILE ), 'FBX presets file "%s" does not exist' % FBX_ANIM_PRESETS_FILE # Ensure directories exist filepath = filepath.replace('\\', '/') if not os.path.exists(os.path.dirname(filepath)): os.makedirs(os.path.dirname(filepath)) select(objs) mel.FBXPushSettings() mel.FBXResetExport() # Preset path MUST use forward slashes. mel.eval('FBXLoadExportPresetFile -f "{0}"'.format( FBX_ANIM_PRESETS_FILE.replace('\\', '/'))) mel.eval('FBXExportBakeComplexStart -v {0}'.format(start)) mel.eval('FBXExportBakeComplexEnd -v {0}'.format(end)) try: preFbxExport(objs, start, end, filepath) mel.eval('FBXExport -f "%s" -s' % filepath) postFbxExport(objs, start, end, filepath) finally: mel.FBXPopSettings()
def fossilPickWalk(d='down'): allControls = set(ls('*.fossilCtrlType', o=True, r=True)) selected = set(ls(sl=True)) if selected.issubset(allControls): #maya.cmds.attributeQuery( 'fossil9CtrlType', n='Shoulder_L_ctrl', ex=1 ) pickerPlugs = [getPickerPlug(ctrl) for ctrl in selected] if all(pickerPlugs): # All the selection are controls so we can process their special connections select([ getNextNode(pickerPlug, d, ctrl) for pickerPlug, ctrl in zip(pickerPlugs, selected) ]) return # Fallback of normal pickwalking if d == 'down': mel.eval('pickWalkDown') elif d == 'up': mel.eval('pickWalkUp') elif d == 'left': mel.eval('pickWalkLeft') elif d == 'right': mel.eval('pickWalkRight')
def show( self, *args ): self.delete() self.win = pm.window( self.__name__, toolbox=True, resizeToFitChildren=True ) self.win.setTitle( self.title ) self._buildControls() self._updateControls() self.win.show() jobCmd = r'python(\"%s.%s._updateControls()\");' % ( __name__, self.__name__ ) job1 = "scriptJob -parent \"%s\" -event \"SelectionChanged\" \"%s\";" % ( self.__name__, jobCmd ) job2 = "scriptJob -parent \"%s\" -event \"timeChanged\" \"%s\";" % ( self.__name__, jobCmd ) mel.eval( job1 ) mel.eval( job2 )
def setNurbsShapeCache(shape, data): ''' Applies the data from `getNurbsShapeCache` to the given shape node. ''' text = [ '{0[degU]} {0[degV]} {0[formU]} {0[formV]} {0[rational]}'.format(data) ] text.append( str(len(data['knotsU'])) + ' ' + ' '.join(str(k) for k in data['knotsU'])) text.append( str(len(data['knotsV'])) + ' ' + ' '.join(str(k) for k in data['knotsV'])) text.append(str(data['cvU'] * data['cvV'])) text += ['{0.x} {0.y} {0.z}'.format(cv) for cv in data['cvs']] mel.eval('setAttr {}.cc -type "nurbsSurface" \n{}'.format( shape, '\n'.join(text)))
def copySkinning(): ''' Wrapper for maya's copy that binds to the same joints if needed. Why this isn't the default behavior, I have no idea. ''' src = selected()[0] targets = selected()[1:] joints = skinCluster(src, q=True, inf=True) skin = findRelatedSkinCluster(src) for dest in targets: if not findRelatedSkinCluster(dest): skinCluster(dest, joints, tsb=True, mi=skin.maxInfluences.get()) select(src, dest) mel.eval('CopySkinWeights()')
def screenshotControlShapes(): ''' Takes screen shots of all the available controls shapes as `./ui/shapes/<shape_name>_large.png`. ''' global SHAPES cam = PyNode('persp') cam.rx.set(-30) cam.ry.set(45) shapes = listShapes() args = ['temp_shape', 1, 'blue 0.5'] for shape in shapes: destfile = os.path.dirname( ui.__file__) + '/shapes/' + shape + '_large.png' regfile = os.path.dirname(ui.__file__) + '/shapes/' + shape + '.png' if os.path.exists(destfile) or os.path.exists(regfile): continue print('Grabbing', shape) obj = SHAPES[shape](*args) select(obj) viewFit(f=.95) # .95 is default #need to frame 'deal' and zoom by some amount, or just crop in post? # -viewer 0 to skip fcheck result = mel.eval( 'playblast -startTime 1 -endTime 1 -format image -sequenceTime 0 -clearCache 1 -viewer 0 -showOrnaments 0 -fp 0 -percent 100 -compression "png" -quality 70 -widthHeight 512 512;' ) time.sleep(2.5) #Need to wait for render filename = result.replace('####', '1') os.rename(filename, destfile) delete(obj) print('Done')
return core.DilloTools.getInstance() def getTools(): """Return the current tool data""" return getInstance().getTools() def getDilloImage(image): """Return the full path to a dillo tools image""" fullImage = os.path.normpath(os.path.join(IMAGES_DIR, image)) return fullImage def getVersion(): return __version__ def createWindow(): getInstance().createWindow() def createShelf(): getInstance().createShelf() def deleteShelf(): getInstance().deleteShelf() #extension of userSetup, dilloTools must be imported during maya startup userPaths.addScript(SCRIPTS_DIR) userPaths.addPlugin(PLUGIN_DIR) mel.eval("source boRightClickManager")
def cardIk(card): #ctrl = mel.eval( 'curve -d 1 -p -0.5 1 -0.866026 -p -0.5 1 0.866025 -p 1 1 0 -p -0.5 1 -0.866026 -p 0 0 0 -p -0.5 -1 -0.866026 -p -0.5 -1 0.866025 -p 0 0 0 -p -0.5 1 0.866025 -p 1 1 0 -p 0 0 0 -p 1 -1 0 -p -0.5 -1 -0.866026 -p -0.5 -1 0.866025 -p 1 -1 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 ;' ) ctrl = PyNode( mel.eval( 'curve -d 1 -p 0 4 0 -p -2.828427 2.828427 -2.47269e-007 -p -4 0 -3.49691e-007 -p -2.828427 -2.828427 -2.47269e-007 -p 0 -4 0 -p 2.828427 -2.828427 0 -p 4 0 0 -p 2.828427 2.828427 0 -p 0 4 0 -p -1.23634e-007 2.828427 2.828427 -p -1.74846e-007 0 4 -p -1.23634e-007 -2.828427 2.828427 -p 0 -4 0 -p 3.70903e-007 -2.828427 -2.828427 -p 5.24537e-007 0 -4 -p 3.70903e-007 2.828427 -2.828427 -p 0 4 0 -p 0 0 0 -p 0 -4 0 -p 0 0 0 -p -4 0 0 -p 4 0 0 -p 0 0 -4 -p 0 0 4 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 ;' )) ctrl.rename(card.name() + "_target") upCtrl = duplicate(ctrl)[0] upCtrl.rename(card.name() + "_up") aim = spaceLocator() aim.setParent(ctrl) aim.t.set(0, 0, 0) hide(aim) up = spaceLocator() up.setParent(upCtrl) hide(up) base = spaceLocator() base.rename('cardIkBase') hide(base) pointConstraint(card, base) util.moveTo(ctrl, card.joints[-1]) util.moveTo(upCtrl, card.vtx[1]) aimConstraint(aim, card, wut='object', wuo=up, aim=[0, -1, 0], u=[0, 0, -1]) dist = distanceDimension(base, aim) dist.getParent().setParent(ctrl) hide(dist) core.math.divide(dist.distance, dist.distance.get() / card.sy.get()) >> card.sy follower = spaceLocator() follower.rename('cardIkFollower') follower.setParent(card) follower.t.set(0, 0, 0) hide(follower) pointConstraint(up, follower, skip=['x', 'z']) sideDist = distanceDimension(follower, up) sideDist.getParent().setParent(ctrl) hide(sideDist) core.math.divide(sideDist.distance, sideDist.distance.get() / card.sz.get()) >> card.sz # Orient controls with the card so moving in local space initially preserves orientation. upCtrl.setRotation(card.getRotation(space='world'), space='world') ctrl.setRotation(card.getRotation(space='world'), space='world') distBetweenCtrls = (ctrl.getTranslation(space='world') - upCtrl.getTranslation(space='world')).length() if distBetweenCtrls < 8.0: upCtrl.s.set([distBetweenCtrls / 8.0] * 3) ctrl.s.set([distBetweenCtrls / 8.0] * 3) select(ctrl)
"""Return the current tool data""" return getInstance().getTools() def getDilloImage(image): """Return the full path to a dillo tools image""" fullImage = os.path.normpath(os.path.join(IMAGES_DIR, image)) return fullImage def getVersion(): return __version__ def createWindow(): getInstance().createWindow() def createShelf(): getInstance().createShelf() def deleteShelf(): getInstance().deleteShelf() #extension of userSetup, dilloTools must be imported during maya startup userPaths.addScript(SCRIPTS_DIR) userPaths.addPlugin(PLUGIN_DIR) mel.eval("source boRightClickManager")
pm.select( sel_list ) pm.workspace.open( current_ws ) pm.waitCursor( state=False ) __cmd = """ global proc kx_renderCleanup( string $image, int $fs, int $fe, int $fi, int $rate, string $path, string $filename ) { python("kinetifex.screenshot._renderCleanup( '"+$path+"','"+$filename+"' )"); } """ mel.eval( __cmd ) def _renderCleanup( path, filename ): pm.window( 'glRenderWindow', e=1, vis=0 ) f1 = filename.replace('@', str(int(pm.currentTime())) ) f2 = filename.replace('@.', '' ) p1 = Path(path) / f1 p2 = Path(path) / f2 if not p2.exists(): p1.rename( p2 )
def tempWidget(): ctrl = PyNode( mel.eval( 'curve -d 1 -p 0 4 0 -p -2.828427 2.828427 -2.47269e-007 -p -4 0 -3.49691e-007 -p -2.828427 -2.828427 -2.47269e-007 -p 0 -4 0 -p 2.828427 -2.828427 0 -p 4 0 0 -p 2.828427 2.828427 0 -p 0 4 0 -p -1.23634e-007 2.828427 2.828427 -p -1.74846e-007 0 4 -p -1.23634e-007 -2.828427 2.828427 -p 0 -4 0 -p 3.70903e-007 -2.828427 -2.828427 -p 5.24537e-007 0 -4 -p 3.70903e-007 2.828427 -2.828427 -p 0 4 0 -p 0 0 0 -p 0 -4 0 -p 0 0 0 -p -4 0 0 -p 4 0 0 -p 0 0 -4 -p 0 0 4 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 ;' )) return ctrl
def export(filepath, objs, start, end): ''' :param node/list objs: An object, or list, to export. Most likely Rig:b_root. :param int start: The beginning of the range to export. :param int end: The end of the range to export. :param string filepath: The full name to export. ''' filepath = filepath.replace('\\', '/') if not os.path.exists(os.path.dirname(filepath)): os.makedirs(os.path.dirname(filepath)) select(objs) mel.FBXPushSettings() mel.FBXResetExport() if version() >= 2016: fbxPreset = os.path.expandvars( '%RxArtToolRoot%/Maya/FBXPresets/Motiga_Anim.fbxexportpreset' ).replace('\\', '/') mel.FBXPushSettings() mel.FBXResetExport() mel.eval('FBXLoadExportPresetFile -f "{0}"'.format(fbxPreset)) mel.eval('FBXExportBakeComplexStart -v {0}'.format(start)) mel.eval('FBXExportBakeComplexEnd -v {0}'.format(end)) else: mel.eval('FBXExportConvertUnitString cm') mel.eval('FBXExportAnimationOnly -v 0') mel.eval('FBXExportBakeComplexAnimation -v 1') mel.eval('FBXExportBakeComplexStep -v 1') mel.eval('FBXExportBakeResampleAnimation -v 1') mel.eval('FBXExportBakeComplexStart -v {0}'.format(start)) mel.eval('FBXExportBakeComplexEnd -v {0}'.format(end)) mel.eval('FBXExportUpAxis z') # Turning off input connections prevents the controllers from coming in. mel.FBXExportInputConnections(v=0) try: mel.eval('FBXExport -f "%s" -s' % filepath) finally: mel.FBXPopSettings()