def import_skin_weights_selected(): """Imports skin weights on selected meshes from Maya Project's "data" directory using Maya's deformerWeights command. Skin weights should be exported using the meshes name, for instance, the skin weight file for the mesh "cn_head_mesh" should be exported as "cn_head_mesh.xml' If a skin weight file is not found, the process is skipped without error """ PROJ_PATH = cmds.workspace(query=True, rd=True) DATA_PATH = PROJ_PATH + 'data/' selection = cmds.ls(selection=True) if selection: for mesh in selection: # Check if there's a skin cluster on mesh sc = mel.eval('findRelatedSkinCluster("{}")'.format(mesh)) if sc: # Check if the skin weight xml file exist if os.path.exists(DATA_PATH + "{}.xml".format(mesh)): cmds.deformerWeights("{}.xml".format(mesh), im=True, method='index', deformer=sc, path=DATA_PATH) cmds.skinCluster(sc, edit=True, forceNormalizeWeights=True) LOG.info('Imported skin weight file {}'.format( (DATA_PATH + "{}.xml".format(mesh)))) else: LOG.warning( 'No skin weight XML file found for {}'.format(mesh)) else: LOG.warning('No skin cluster found on {}'.format(mesh))
def saveSkin(geo, assetName=None, prompt=False): """ Save skin values for the specified geometry to a file. [Args]: geo (string) - The name of the geometry to save the skin of assetName (string) - The name of the rig the geometry is part of prompt (bool) - Toggles prompting the user to select the assetName """ assetName = fileFn.assetNameSetup(assetName, prompt) path = fileFn.getAssetDir() fileName = fileFn.getLatestVersion(assetName, path, 'rig/WIP/skin', new=True, name=geo) skinCls = getSkinInfo(geo) if skinCls: for each in skinCls: if each: truncateWeights(each, geo) cmds.deformerWeights(fileName, path='', deformer=each, ex=1, wp=5, wt=0.00001) return True else: return False
def copy_cluster_weights(shape, weight_file, method="bilinear"): """ Copy cluster weights to the given shape from the given weight files :param shape: the shape node name containing the cluster deformers :type shape: str :param weight_file: containing the deformers and weight filter names :type weight_file: dict :param method: method type that should be used when updating the weights :type method: str """ # gets the temporary folder path temp_path = get_temp_folder() short_name = get_prefix_less_name(shape) for node in weight_file: if not weight_file[node]: continue cmds.deformerWeights(weight_file[node], im=True, shape=short_name, deformer=node, path=temp_path, method=method, vertexConnections=True)
def export_skin_weights_selected(): """Exports skin weights on selected meshes to Maya Project's "data" directory using Maya's deformerWeights command. Skin weights are exported using the meshes name, for instance, the skin weight file for the mesh "cn_head_mesh" would be exported as "cn_head_mesh.xml' If a skin cluster is not found on a mesh, the process is skipped without error """ PROJ_PATH = cmds.workspace(query=True, rd=True) DATA_PATH = PROJ_PATH + 'data/' selection = cmds.ls(selection=True) if selection: for mesh in selection: # Check if there's a skin cluster on mesh sc = mel.eval('findRelatedSkinCluster("{}")'.format(mesh)) if sc: # Check if the skin weight xml file exist if os.path.exists(DATA_PATH): cmds.deformerWeights("{}.xml".format(mesh), export=True, method='index', deformer=sc, path=DATA_PATH) LOG.info('Exported skin weight data to {}'.format( (DATA_PATH + "{}.xml".format(mesh)))) else: LOG.warning( 'No data directory found under {} to save skin weight file to' .format(PROJ_PATH)) else: LOG.warning('No skin cluster found on {}'.format(mesh))
def export_skin_weight(self): """@todo: insert doc for export_skin_weight""" sel = cmds.ls(sl=True) for s in sel: skin = mel.eval('findRelatedSkinCluster %s;' % s) name = '%s_weights.0001.xml' % s cmds.deformerWeights(name, export=True, deformer=skin, path='C:/PROJECTS/GOT_Dragon/data/')
def skin_dragon(self): """@todo: insert doc for skin_dragon""" cmds.setAttr('L_foot_CTL.tx', 3.061) cmds.setAttr('R_foot_CTL.tx', -3.061) data = 'C:/PROJECTS/GOT_Dragon/data/' done = list() for weight in os.listdir(data): cmds.select(clear=True) if weight in done: continue name = weight.split('_weights')[0] if not cmds.objExists('Drache:%s' % name): continue weight = self.get_latest_version(weight, data) self.select_result_jnts(name) cmds.select('Drache:%s' % name, add=True) skin = cmds.skinCluster(tsb=True, sm=True)[0] cmds.deformerWeights(weight, im=True, method='index', deformer=skin, path=data) cmds.skinCluster(skin, e=True, forceNormalizeWeights=True) cmds.select('Drache:%s' % name) done.append(weight) #mel.eval('removeUnusedInfluences;') # end for weight in os.listdir(data) cmds.setAttr('L_foot_CTL.tx', 0) cmds.setAttr('R_foot_CTL.tx', 0)
def action_LoadWeights(loadPath='', pruneValue=.05): selectionList = mc.ls(sl=True, objectsOnly=True) loaded = False if not loadPath: loadPath = dirPath() for obj in selectionList: if mc.objectType(obj, isType="transform"): mc.select(obj) xmlName = str(obj) + ".xml" mesh = mc.ls(sl=True, objectsOnly=True) try: meshSkinCluster = str( mc.ls(mc.listHistory(mesh), type='skinCluster')[0]) mc.deformerWeights(xmlName, im=True, method="index", path=loadPath, deformer=meshSkinCluster) if pruneValue > 0: mc.skinPercent(meshSkinCluster, pruneWeights=0.01) mc.skinCluster(meshSkinCluster, edit=True, forceNormalizeWeights=True) print "Loaded Skinweights: " + loadPath + xmlName loaded = True except: e = sys.exc_info()[1] print "Skipping mesh: {obj}: ".format(obj=obj) + str(e) loaded = False return loaded
def saveSkinWeights(mesh, path, force=False): '''wrapper for deformerWeights command, however will attempt to find skinCluster if none specified. mesh: input mesh or skinCluster node path: output path for xml file force: if False then file will no be overwritten remap: regular expression, passed through to command (see deformerWeights cmd docs) ''' #check paths fileDir, fileName = os.path.split(path) if not os.path.exists(fileDir) and not os.path.isdir(fileDir): raise RuntimeError('Directory %s not found to save skin weights' % fileDir) if os.path.exists(path) and not force: raise RuntimeError( 'Skin weights file %s already exists, use force=True to overwrite' % path) if not cmds.objExists(mesh): raise RuntimeError( 'mesh or skincluster %s not found, cannot save weights' % mesh) #check/find skinCluster node skinCluster = None if cmds.nodeType(mesh) == 'skinCluster': skinCluster = mesh else: skinCluster = mel.eval('findRelatedSkinCluster("%s");' % mesh) if not skinCluster: raise RuntimeError('skinCluster not found on mesh %s' % mesh) cmds.deformerWeights(fileName, path=fileDir, deformer=skinCluster, export=True)
def importDeformerWeights(nodes=None, directory="/tmp/", method="index"): if not os.path.isdir(directory): raise Exception("Directory not found: " + directory) if method not in ["index", "nearest", "barycentric", "bilinear", "over"]: raise Exception( 'Keyword argument "method" can be "index", "nearest", "barycentric", "bilinear", or "over".' ) if type(nodes) == str or type(nodes) == unicode: l = [nodes] elif type(nodes) == list: l = nodes elif nodes == None: l = mc.ls(sl=True, o=True) or [] if len(l) == 0: raise Exception( "Nothing is selected. Select objects with applied deformers.") nodes = [] for f in os.listdir(directory): if not f.endswith(".xml"): continue n = f.split(".")[0] if n not in l: continue mc.deformerWeights(f, p=directory, im=True, deformer="*", sh=n, m=method)
def skin_geo(): """Skins geometry to influence objects""" PROJ_PATH = cmds.workspace(query=True, rd=True) DATA_PATH = PROJ_PATH + 'data/' cmds.skinCluster([u'lf_legFrontUpperPiston_jnt'], 'lf_frontThighPiston_mesh', n='lf_frontThighPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legFrontUpper_jnt'], 'lf_frontThigh_mesh', n='lf_frontThigh_mesh_sc', tsb=True) cmds.skinCluster([u'cn_body_jnt', u'lf_shoulderFront_jnt'], 'lf_frontShoulderHinge_mesh', n='lf_frontShoulderHinge_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legRearShin_jnt'], 'rt_rearFoot_mesh', n='rt_rearFoot_mesh_sc', tsb=True) cmds.skinCluster([u'cn_body_jnt', u'rt_shoulderFront_jnt'], 'rt_frontShoulderHinge_mesh', n='rt_frontShoulderHinge_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legFrontLower_jnt'], 'rt_frontShin_mesh', n='rt_frontShin_mesh_sc', tsb=True) cmds.skinCluster([u'cn_neck_jnt'], 'cn_neck_mesh', n='cn_neck_mesh_sc', tsb=True) cmds.skinCluster([u'cn_body_jnt'], 'cn_mainBody_mesh', n='cn_mainBody_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legFrontUpper_jnt'], 'rt_frontThigh_mesh', n='rt_frontThigh_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legFrontUpperPiston_jnt'], 'rt_frontThighPiston_mesh', n='rt_frontThighPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legFrontLowerPiston_jnt', u'lf_legFrontUpperPiston_jnt'], 'lf_frontShinPiston_mesh', n='lf_frontShinPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legFrontShin_jnt'], 'lf_frontFoot_mesh', n='lf_frontFoot_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legRearUpperPiston_jnt'], 'lf_rearThighPiston_mesh', n='lf_rearThighPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legRearLower_jnt'], 'lf_rearShin_mesh', n='lf_rearShin_mesh_sc', tsb=True) cmds.skinCluster([u'cn_body_jnt', u'lf_shoulderRear_jnt'], 'lf_rearShoulderHinge_mesh', n='lf_rearShoulderHinge_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legRearUpper_jnt'], 'lf_rearThigh_mesh', n='lf_rearThigh_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legFrontShin_jnt'], 'rt_frontFoot_mesh', n='rt_frontFoot_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legFrontLowerPiston_jnt', u'rt_legFrontUpperPiston_jnt'], 'rt_frontShinPiston_mesh', n='rt_frontShinPiston_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legRearUpper_jnt'], 'rt_rearThigh_mesh', n='rt_rearThigh_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legRearUpperPiston_jnt'], 'rt_rearThighPiston_mesh', n='rt_rearThighPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legFrontLower_jnt'], 'lf_frontShin_mesh', n='lf_frontShin_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legRearLowerPiston_jnt', u'lf_legRearUpperPiston_jnt'], 'lf_rearShinPiston_mesh', n='lf_rearShinPiston_mesh_sc', tsb=True) cmds.skinCluster([u'lf_legRearShin_jnt'], 'lf_rearFoot_mesh', n='lf_rearFoot_mesh_sc', tsb=True) cmds.skinCluster([u'cn_body_jnt', u'rt_shoulderRear_jnt'], 'rt_rearShoulderHinge_mesh', n='rt_rearShoulderHinge_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legRearLowerPiston_jnt', u'rt_legRearUpperPiston_jnt'], 'rt_shinPiston_mesh', n='rt_shinPiston_mesh_sc', tsb=True) cmds.skinCluster([u'rt_legRearLower_jnt'], 'rt_rearShin_mesh', n='rt_rearShin_mesh_sc', tsb=True) # Example of skinning head mesh and importing skin weights cmds.skinCluster([u'cn_head_jnt', u'lf_antennaRear_jnt', u'lf_antenna_jnt'], 'cn_head_mesh', n='cn_head_mesh_sc', tsb=True) cmds.deformerWeights("cn_head_mesh.xml", im=True, method='index', deformer='cn_head_mesh_sc', path=DATA_PATH) cmds.skinCluster('cn_head_mesh_sc', edit=True, forceNormalizeWeights=True) # OR just do a mass import of skin weight files onto the meshes in your scene skin_meshes = cmds.listRelatives('geo', children=True) if skin_meshes: cmds.select(skin_meshes) skin.import_skin_weights_selected() LOG.info('Successfully skinned geometry')
def transferSingleFunction(self, getChildrenController, getChildrenTarget, skinPath): print "here is "+getChildrenController[0], getChildrenTarget[0] queryJoint=cmds.optionMenu(jointSelect, q=1, v=1) queryJoint=queryJoint+":" try: newname, skinID=getClass.getSkinWeightsforXML(getChildrenController[0]) cmds.deformerWeights (newname+".xml", p=skinPath, ex=True, deformer=skinID) print "deformer weights have been exported from "+getChildrenController[0] except: print "shape missing" pass try: GetPath=skinPath+newname+".xml" except: print getChildrenController[0]+" does not have a skinCluster to reference from" getCtrlgetChildrenTargetName=getChildrenController[0].split(":") getTgtgetChildrenTargetName=getChildrenTarget[0].split(":") getOldMeshNameSpace=':'.join(getCtrlgetChildrenTargetName[:-1])+":" try: getSkinCluster=cmds.skinCluster(getChildrenController[0], q=1, dt=1) skinID, getInf=getClass.skinClust(getSkinCluster, getChildrenController[0]) getJointNameSpace=getInf[0].split(":") getOldJointNameSpace=':'.join(getJointNameSpace[:-1])+":" dataFromTextFile=open(GetPath).read() dataFromTextFile=dataFromTextFile.replace(getOldJointNameSpace, queryJoint) if "face" in getOldJointNameSpace: dataFromTextFile=dataFromTextFile.replace(getOldJointNameSpace, "") replacedDataTextFile=open(GetPath, 'w') replacedDataTextFile.write(dataFromTextFile) replacedDataTextFile.close() print "xml has been updated with new joint names" pass except: print "shape is missing - passed" pass getJointBucket=[] for jointItem in getInf: getJointName=jointItem.split(":") getJoint=getJointName[-1:][0] getNewJoint=queryJoint+getJoint getJointBucket.append(getNewJoint) cmds.select(getChildrenTarget[0]) try: cmds.skinCluster(getChildrenTarget[0],getJointBucket[0], tsb=1, nw=1) print getChildrenTarget[0]+" has been successfully bound to "+getJointBucket[0] if len(getJointBucket)>1: for eachjoint in getJointBucket[1:]: try: cmds.skinCluster(getChildrenTarget[0], e=1, ai=eachjoint, tsb=1, nw=1) print eachjoint+" has been successfully added to "+getChildrenTarget[0] except: pass except: print getChildrenTarget[0]+" is already bound" newgetChildrenTargetName, newskinID=getClass.getSkinWeightsforXML(getChildrenTarget[0]) cmds.deformerWeights (newname+".xml", p=skinPath, im=True, deformer=newskinID) print "deformer weights have been applied to "+newgetChildrenTargetName
def load_deformer_weights(file_name="", deformer_name=""): """ loads the deformer weights :param file_name: <str> :param deformer_name: <str> :return: <bool> True for success. """ cmds.deformerWeights(file_name, path=dir, deformer=deformer_name, im=1) return True
def weightCopy(self): saveData = {} # 保存ディレクトリが無かったら作成 if not os.path.exists(self.filePath): os.makedirs(os.path.dirname(self.filePath + '\\')) # 末尾\\が必要なので注意 else: # ある場合は中身を削除 files = os.listdir(self.filePath) if files is not None: for file in files: os.remove(self.filePath + '\\' + file) skinFlag = False for skinMesh in self.skinMeshes: try: cmds.bakePartialHistory(skinMesh, ppt=True) except: pass # ノードの中からスキンクラスタを取得してくる#inMesh直上がSkinClusterとは限らないので修正 srcSkinCluster = cmds.ls(cmds.listHistory(skinMesh), type='skinCluster') if not srcSkinCluster: continue # スキンクラスタがなかったら次に移行 tempSkinNode = skinMesh #親を取得するためスキンクラスタのあるノードを保存しておく # スキンクラスタのパラメータ色々を取得しておく srcSkinCluster = srcSkinCluster[0] skinningMethod = cmds.getAttr(srcSkinCluster + ' .skm') dropoffRate = cmds.getAttr(srcSkinCluster + ' .dr') maintainMaxInfluences = cmds.getAttr(srcSkinCluster + ' .mmi') maxInfluences = cmds.getAttr(srcSkinCluster + ' .mi') bindMethod = cmds.getAttr(srcSkinCluster + ' .bm') normalizeWeights = cmds.getAttr(srcSkinCluster + ' .nw') influences = cmds.skinCluster(srcSkinCluster, q=True, inf=True) saveData[skinMesh + ';skinningMethod'] = skinningMethod saveData[skinMesh + ';dropoffRate'] = dropoffRate saveData[skinMesh + ';maintainMaxInfluences'] = maintainMaxInfluences saveData[skinMesh + ';maxInfluences'] = maxInfluences saveData[skinMesh + ';bindMethod'] = bindMethod saveData[skinMesh + ';normalizeWeights'] = normalizeWeights saveData[skinMesh + ';influences'] = influences skinFlag = True if self.engine == 'maya': # 読みに行くセーブファイル名を指定、autoならメッシュ名 if self.weightFile == 'auto': weightFile = skinMesh else: weightFile = self.weightFile # Pipeはファイル名に出来ないので変換しておく meshName = str(weightFile).replace('|', '__pipe__') # コロンはファイル名に出来ないので変換しておく meshName = str(meshName).replace(':', '__colon__') cmds.deformerWeights(meshName + '.xml', export=True, deformer=srcSkinCluster, path=self.filePath + '\\') with open(self.fileName, 'w') as f: # ファイル開く'r'読み込みモード'w'書き込みモード json.dump(saveData, f)
def applyWeightInfo(self): for shape in self.shapes: #make a skincluster using the joints if cmds.objExists(shape): ss = self.shapes[shape] skinList = ss.joints skinList.append(shape) cmds.select(skinList, r=True) cluster = cmds.skinCluster(name=ss.skin, tsb=1) cmds.deformerWeights(fname , path = fpath, deformer=ss.skin, im=1)
def import_blendshape(filePath): """ Imports blendshape deformer from file onto specified mesh Args: filePath: Full file path to mesh: Name of the mesh to import blendshape onto Returns: True/False Example: import_blendshape('deform/blendshapes/Ch_Pufferfish_LOD0_SM__Ch_Pufferfish_LOD0_SM_bs.json') """ resolved_path = resolve_file_path(filePath) import_dir = os.path.dirname(resolved_path) import_filename = os.path.basename(resolved_path) if not os.path.isfile(resolved_path): LOG.error('File does not exist: {}'.format(resolved_path)) return False with open(resolved_path) as infile: try: data = json.load(infile) LOG.info('Loaded blendShape data from {0}.'.format(filePath)) except: LOG.error('Unable to load blendShape data from {0}.'.format(filePath)) return False # Check mesh exists mesh = data['mesh'][0] if not cmds.objExists(mesh): LOG.error('Mesh {} does not exist in scene'.format(mesh)) return # If blendshape exists, delete if cmds.objExists(data['blendshape_node']): cmds.delete(data['blendshape_node']) try: cmds.blendShape(mesh, foc=True, name=data['blendshape_node']) mm.eval('blendShape -edit -import "%s/%s" "%s";' % (import_dir, data['blendshape_file'], data['blendshape_node'])) cmds.deformerWeights(data['blendshape_weights'], im=True, deformer=data['blendshape_node'], method="index", path=import_dir) # Set each target attr to zero, coming in set to 1 otherwise. tgts = cmds.listAttr(data['blendshape_node'], m=True, st="weight") if tgts: for tgt in tgts: cmds.setAttr("%s.%s" % (data['blendshape_node'], tgt), 0) return True except: LOG.error('Unable to create blendshape {} from file {}'.format(data['blendshape_node'], import_filename)) return False
def importBlendshape(geometry, filename=''): """ Imports blendshape deformer (used for scripted rig builds) Args: geometry: Name of object to import blendshape to filename: Name of .shp blendshape data file Returns: File path of imported blendshape file. Example: importBlendshape('ray_cn_body', filename='deform/blendshapes/ray_cn_body__ray_cn_body_bs.shp') """ projDir = cmds.workspace(query=True, rd=True) blendshapesDir = '%s/%s' % (projDir, filename) if not '.shp' in blendshapesDir: blendshapesDir = '%s.shp' % blendshapesDir if not os.path.exists(blendshapesDir): LOG.error('Blendshape file does not exist...' % filename) return else: # Do blendshapes import shpDir = os.path.dirname(os.path.abspath(blendshapesDir)) + "\\" shpDir = shpDir.replace("\\", "/") shpFullFilename = blendshapesDir.split('/')[-1] shpFilename = shpFullFilename.split('.')[0] bsName = shpFilename.split('__')[1] try: # Create blendshape deformer first cmds.blendShape(geometry, foc=True, name=bsName) mel.eval('blendShape -edit -import "%s" "%s";' % (blendshapesDir, bsName)) if os.path.isfile(blendshapesDir): cmds.deformerWeights("%s.xml" % shpFilename, im=True, deformer=bsName, method="index", path=shpDir) # Set each target attr to zero, coming in set to 1 otherwise. tgts = cmds.listAttr(bsName, m=True, st="weight") if tgts: for tgt in tgts: cmds.setAttr("%s.%s" % (bsName, tgt), 0) LOG.info('Imported %s' % blendshapesDir) return blendshapesDir except: LOG.error('Could not import blendshape file %s...' % blendshapesDir) return
def export_blendshape(export_file_path, blendshape_node): """Exports blendshape deformer to file Args: export_file_path: Full file path for exported blendshape data blendshape_node: Blendshape node to export Returns: Blendshape import command Example: bs_file_path = 'deform/blendshapes/Ch_Pufferfish_LOD0_SM__Ch_Pufferfish_LOD0_SM_bs.json' export_blendshape(bs_file_path, 'Ch_Pufferfish_LOD0_SM_bs') """ resolved_path = resolve_file_path(export_file_path) export_dir = os.path.dirname(resolved_path) export_filename = os.path.basename(resolved_path) #export_filename_no_ext = export_filename.split('.')[0] # Check blendshape if not cmds.objExists(blendshape_node): LOG.error('Blendshape node {0} does not exist.'.format(blendshape_node)) return False # Check directory path, create directory if it doesn't exist if not os.path.isdir(export_dir): try: LOG.info('{} does not exist, creating...'.format(export_dir)) os.mkdir(export_dir) except: LOG.error('Could not create directory {} for export...'.format(export_dir)) return # Do blendshape export try: # filename = '{}__{}'.format(export_filename_no_ext, blendshape_node) cmds.blendShape(blendshape_node, edit=True, export='{}/{}.bshp'.format(export_dir, blendshape_node)) cmds.deformerWeights("{}.xml".format(blendshape_node), ex=True, deformer=blendshape_node, method="index", path=export_dir) bs_data = {} bs_data['blendshape_file'] = '{}.bshp'.format(blendshape_node) bs_data['blendshape_weights'] = '{}.xml'.format(blendshape_node) bs_data['blendshape_node'] = blendshape_node bs_data['mesh'] = get_geo_from_blendshape(blendshape_node) with open(resolved_path, 'w') as outfile: json.dump(bs_data, outfile, sort_keys=True, indent=4) LOG.info('Exported blendshape node {} to {}'.format(blendshape_node, export_file_path)) return "Blendshape export data..." except: LOG.error('Blendshape does not exist to export {}...'.format(blendshape_node)) return
def save_deformer_skin_weights(skin_name="", directory_path_name=""): """ saves the deformer skin weights. :param skin_name: <str> :param directory_path_name: <str> The directory path to save the skin weights to. :return: <bool> True for success. """ cmds.deformerWeights(skin_name + '.skinWeights', path=directory_path_name, ex=1, deformer=skin_name) return True
def importWeights(geometry, deformer, filepath): ''' This will import weights for the given deformer into the given directory. .. example:: importWeights("body_geo", "cluster1", "shows/template/collections/rigrepo/templates/biped/rig/build/base/cluster_wts/body_geo__cluster1.xml) .. note:: This is setup to import only one file at a time. We should write something that imports multiple files in a directory :param geometry: The geometry(s) you wish to import the weights for. :type geometry: str :param deformer: This is the deforemr(s) you wish to import weights onto :type deformer: str :param filepath: The filepath you want to use for the weights. :type filepath: str ''' if not os.path.isfile(filepath): raise RuntimeError("{} is not an existing filepath.".format(filepath)) # split up the path so we can pass the file name and directory in seperately filename = os.path.basename(filepath) directory = os.path.dirname(filepath) # adding the geometry to a selection list so I can extend to the shape # reliably with out any issues. selList = om.MSelectionList() selList.add(geometry) dagPath = selList.getDagPath(0) dagPath.extendToShape() # once we have the correct shape. Now we will check it against the other shapes # that the given deformer is influencing. shapes = mc.deformer(deformer, q=True, g=True) geoShape = dagPath.partialPathName() # get the difference between the deformer and the deformers influenced by if geoShape in shapes: skipGeo = ";".join(list(set(shapes).difference(set([geoShape])))) #import the weights for the given deformer and filepath try: mc.deformerWeights(filename, im=True, deformer=deformer, skip=skipGeo, path=directory) except: mc.warning("couldn't apply {} to {}".format(filename, deformer))
def loadSkin(geo, assetName=None, prompt=False): """ Load skin values for the specified geometry from a file. [Args]: geo (string) - The name of the geometry to apply the skin to assetName (string) - The name of the rig the geometry is part of prompt (bool) - Toggles prompting the user to select the assetName [Returns]: True """ cmds.progressWindow(e=1, s='Skinning Rig') if cmds.progressWindow(q=1, isCancelled=True): return False assetName = fileFn.assetNameSetup(assetName, prompt) path = fileFn.getAssetDir() fileName = fileFn.getLatestVersion(assetName, path, 'rig/WIP/skin', name=geo) if not fileName: return False fileFn.printToMaya('Currently Skinning: {}'.format(geo)) skinCls = getSkinInfo(geo) if not skinCls: skinInfo = {'joints': []} xmlRoot = xml.etree.cElementTree.parse(fileName).getroot() # skinInfo['joints'] = [each.get('source') for each in xmlRoot.findall('weights')] # skinInfo['joints'] = [each.get('source') for each in xmlRoot.findall('weights') if int(each.get('size')) > 1] for each in xmlRoot.findall('weights'): if int(each.get('size')) > 1: skinInfo['joints'].append(each.get('source')) skinInfo['unknownJnts'] = [] for each in skinInfo['joints']: if not cmds.objExists(each): skinInfo['unknownJnts'].append(each) # skinInfo['joints'].remove(each) skinInfo['joints'] = list( set(skinInfo['joints']) - set(skinInfo['unknownJnts'])) skinCls = cmds.skinCluster(geo, skinInfo['joints'], tsb=1)[0] # try: # skinCls = cmds.skinCluster(geo, skinInfo['joints'], tsb=1)[0] # except ValueError: # print 'Errored whilst skinning {}, Skipping.'.format(geo) # return False cmds.select(cl=1) cmds.deformerWeights(fileName, path='', deformer=skinCls, im=1, wp=5, wt=0.00001) cmds.skinCluster(skinCls, e=1, fnw=1) return True
def export_xml_weights(file_name, skins): """Save out skin weights to an XML file. Args: file_name: Name for output file skins: Skin clusters to gather skin weights from Returns: str: File path to output weights file """ weights_dir = get_weights_directory() if not os.path.exists(weights_dir): os.makedirs(weights_dir) output_file_name = '{}.xml'.format(file_name) skin_names = [oma2.MFnSkinCluster(v).name() for k, v in skins.items()] output_path = cmds.deformerWeights(output_file_name, p=weights_dir, ex=True, vc=True, deformer=skin_names) return output_path
def import_xml_weights(file_path, skin, method=0, **kwargs): """Import xml file skin weights. Args: file_path: Full file path to the XML weight file skin: Skin cluster node to apply the weights to method: Import method for cmds.deformerWeights [0='index', 1='nearest', 2='barycentric', 3='bilinear', 4='over'] **kwargs: Keyword arguments for cmds.deformerWeights command Returns: None """ cmds.deformerWeights(file_path, im=True, method=XML_IMPORT_METHOD[method], deformer=skin, **kwargs)
def applyWeightInfo(self): for shape in self.shapes: #make a skincluster using the joints if cmds.objExists(shape): sc = mel.eval('findRelatedSkinCluster ' + shape) if cmds.objExists(sc): cmds.delete(sc) ss = self.shapes[shape] skinList = ss.joints skinList.append(shape) cmds.select(cl=1) cmds.select(skinList) cluster = cmds.skinCluster(name=ss.skin, tsb=1) fname = self.path.split('\\')[-1] dir = self.path.replace(fname,'') cmds.deformerWeights(fname , path = dir, deformer=ss.skin, im=1)
def import_weights(self, filename=None, filepath=None): """ Import the weights of the given shape """ joints = cmds.ls(type='joint') if not self.skincluster: self.skincluster = cmds.skinCluster(joints, self.shape, toSelectedBones=True)[0] bla = cmds.deformerWeights(filename, im=True, method="index", deformer=self.skincluster, path=filepath) print bla
def exportDeformerWeights(nodes=None, directory="/tmp/"): if type(nodes) == str or type(nodes) == unicode: l = [nodes] elif type(nodes) == list: l = nodes elif nodes == None: l = mc.ls(sl=True, o=True) or [] if len(l) == 0: raise Exception( "Nothing is selected. Select objects with applied deformers.") nodes = [] for n in l: t = mc.nodeType(n) if t == "mesh" or t == "nurbsCurve" or t == "nurbsSurface": nodes.append(mc.listRelatives(n, pa=True, p=True)[0]) else: for t in ["mesh", "nurbsCurve", "nurbsSurface"]: l2 = mc.listRelatives(n, pa=True, s=True, ni=True, typ=t) or [] if len(l2) > 0: nodes.append(n) break if not os.path.isdir(directory): try: os.makedirs(directory) except: raise Exception("Cannot create directory: " + directory) for n in nodes: deformers = [] for n2 in mc.listHistory(n): l2 = mc.nodeType(n2, i=True) if "geometryFilter" in l2 and "tweak" not in l2: deformers.append(n2) if len(deformers) == 0: continue try: mc.deformerWeights(n + ".xml", p=directory, df=deformers, ex=True, vc=True, ws=True, at="*") except: pass
def saveWeightInfo(self, fpath, meshes, all=True): t1 = time.time() #get skin clusters meshDict = {} for mesh in meshes: sc = mel.eval('findRelatedSkinCluster '+mesh) #not using shape atm, mesh instead msh = cmds.listRelatives(mesh, shapes=1) if sc != '': meshDict[sc] = mesh else: cmds.warning('>>>saveWeightInfo: ' + mesh + ' is not connected to a skinCluster!') for skin in meshDict: cmds.deformerWeights(meshDict[skin] + '.skinWeights', path=fpath, ex=True, deformer=skin) elapsed = time.time()-t1 print 'Exported skinWeights for', len(meshes), 'meshes in', elapsed, 'seconds.'
def create_clusters_backup(shape, nodes): """ Generates weight files for the given cluster nodes in the given shape :param shape: the shape node name containing the cluster deformers nodes :type shape: str :param nodes: the cluster nodes :type nodes: list :return: cluster weight files names :rtype: dict """ logger.info("Creating cluster weights backup for {}".format(nodes)) # gets the temp folder path temp_path = get_temp_folder() # prefix less shape name shape = get_prefix_less_name(shape) # dict for weights files weight_files = {} for node in nodes: # If there is not weights creating the deformer maps is useless try: cmds.getAttr("{}.weightList[0].weights".format(node)) except RuntimeError: weight_files[node] = None continue # Creates the weight map if weights are found on shape points cmds.deformerWeights('{}_{}.xml'.format(shape, node), export=True, vertexConnections=True, weightPrecision=5, shape=shape, deformer=node, path=temp_path) weight_files[node] = '{}_{}.xml'.format(shape, node) return weight_files
def export_deformer(self): window = 'export_deformer_weights' window_title = 'What to do now!' if py.window(window, exists=True): py.deleteUI(window, window=True) window_obj = py.window(window, title=window_title, widthHeight=(300, 100), sizeable=False) py.columnLayout('prompt_column', p=window) py.text(' This tool cannot do everything for you! Sadly, you still must do the following for me before\ \n we can import the deformer weights back on to the mesh!') py.text('\tSeparate the eyes, lower and upper jaws from the mesh.') py.text('\tMove the lower jaw parts and the upper jaw parts into groups') py.text('\tDelete your history on the resulting meshes!') py.text('\tImport the deformer weights.') window_obj.show() try: self.mesh = mc.ls(sl=True)[0] mc.deformerWeights(mi.GelUtil.file_path + ".xml", ex=True, shape="%sShape" % self.mesh) except: raise
def getXtm(nameFile, *pArgs): geo = cmds.ls(sl=True)[0] geo = cmds.listRelatives(geo) for i in geo: if 'Orig' in i: pass elif 'Shape' in i: shape = i else: pass cmds.objectType('skinCluster1') connections = cmds.listConnections(shape) for c in connections: if cmds.objectType(c) == 'skinCluster': skin = c else: pass cmds.deformerWeights('{}.xtm'.format(nameFile), export=True, deformer=skin)
def BindSkin(): #hide all ik handles cmds.setAttr("ik_R_leg.visibility", 0) cmds.setAttr("ik_L_leg.visibility", 0) cmds.setAttr("ik_L_upper_wing.visibility", 0) cmds.setAttr("ik_L_lower_wing.visibility", 0) cmds.setAttr("ik_R_upper_wing.visibility", 0) cmds.setAttr("ik_R_lower_wing.visibility", 0) cmds.setAttr('Joints.visibility', 0) #hide joints so animators do not accidently move them cmds.delete('loc*') #delete locators #bind the bird mesh to the rig using a geodexic voxel bind cmds.select('bird') sel = cmds.ls(selection = True) for i in range(0, len(sel)): cmds.skinCluster(sel[i], 'jnt_root', bm=3, sm=1, dr=0.1, name='Mesh'+str(i)) cmds.geomBind('Mesh'+str(i), bm=3, gvp=[256,1], mi=2) #import skin weights cmds.deformerWeights('skinWeights.xml',im=True, sh='bird') print 'Skin Bound'
def loadSkinWeights(mesh, path): '''wrapper for deformerWeights command, however will parse xml and find joints, and create skinCluster if none is specified mesh: mesh or skinCluster node to load onto (if mesh, skinCluster will be created) path: path to xml file ''' #check paths fileDir, fileName = os.path.split(path) if not os.path.exists(path) and not os.path.isfile(path): raise RuntimeError('Skin weights file %s not found' % path) if not cmds.objExists(mesh): raise RuntimeError('Node not found to load skinWeights: %s' % mesh) #check node name/type skinCluster = None if cmds.nodeType(mesh) == 'skinCluster': skinCluster = mesh else: #try to find: skinCluster = mel.eval('findRelatedSkinCluster("%s");' % mesh) if not skinCluster: #create skinCluster joints = getJointsFromSkinFile(path) if not joints: raise RuntimeError( 'Could not find joints in skinweights xml:%s' % path) joints.append(mesh) skinCluster = cmds.skinCluster(*joints, tsb=True, nw=0)[0] #zero everything, was seeing weird values perhaps from initial default weights. cmds.skinPercent(skinCluster, mesh, pruneWeights=100, normalize=False) #load new weights cmds.deformerWeights(fileName, path=fileDir, deformer=skinCluster, im=True, method='index')
def action_SaveWeights(savePath=''): savePath = '' selectionList = mc.ls(sl=True, objectsOnly=True) if not savePath: savePath = dirPath() for obj in selectionList: if mc.objectType(obj, isType="transform"): mc.select(obj) xmlName = str(obj) + ".xml" try: mesh = mc.ls(sl=True, objectsOnly=True) meshSkinCluster = str( mc.ls(mc.listHistory(mesh), type='skinCluster')[0]) mc.deformerWeights(xmlName, ex=True, path=savePath, deformer=meshSkinCluster) except: e = sys.exc_info()[1] print "Skipping mesh: {obj}: ".format(obj=obj) + str(e) print "----------------------------------------" print savePath.replace("/", "\\") return savePath
def saveSkin(self, *args): selection = self.getSelectedMesh() if selection == None: return(mc.headsUpMessage("Select Geometry")) sknCluster = self.getSelectionSkinClusters(selection) if sknCluster == None: return(mc.headsUpMessage('skinCluster Not Found')) # Add a file browser basicFilter = "*.xml" fdir = mc.fileDialog2(fileFilter=basicFilter, dialogStyle=3) fileName = fdir[0].rpartition('/')[2] filePath = fdir[0].rpartition('/')[0] mc.deformerWeights (fileName, ex=True, deformer=sknCluster[0], p=filePath) mc.headsUpMessage("Skin Exported")
def ImportSkinning(skinData, pDeleteFilesAfterImport=False): with DebugTimer('Import skinning'): xmlFilePaths = [] for sd in skinData: #print sd cmds.skinCluster(sd[3], sd[0], name=sd[2], tsb=True) fileName = sd[0] + '_WEIGHTS.xml' filePath = cmds.deformerWeights(fileName, im=True, deformer=sd[2], method='index') if filePath: xmlFilePaths.append(filePath) if pDeleteFilesAfterImport: for filePath in xmlFilePaths: try: os.remove(filePath) except BaseException: print("Error while deleting file ", filePath)
def loadSkin(self, selection, *args): print "In Load Skin" #Open Browser basicFilter = "*.xml" fdir = mc.fileDialog2(fileFilter=basicFilter, cap='Import weights:', okCaption='Import', dialogStyle=2) fileName = fdir[0].rpartition('/')[2] filePath = fdir[0].rpartition('/')[0] selection = self.getSelectedMesh() """instance object inherited from getSelectionSKinClusters method(arg called from function) Must be passed inside functions scope to be difned within that function.""" sknCluster = self.getSelectionSkinClusters(selection) if sknCluster == None: return(mc.headsUpMessage('skinCluster Not Found')) #import weights print sknCluster importSkin = mc.deformerWeights (fileName, im=True, deformer=sknCluster[0], m="index", p=filePath) mc.headsUpMessage(fileName + ' Imported Successfully')
def load(self, dirName='locatorData', assetName=None, dataType='locator'): #--- this method loads the data attr = attribute.Attribute() if dataType == 'attribute': result = self.read_data(dirName = dirName, folder = 'data', fileName = assetName) for i in result: if cmds.objExists(i.split(',')[0]): attr.setAttr(node = i.split(',')[0].split('.')[0], attribute = i.split(',')[0].split('.')[1], value = i.split(', ')[1]) elif dataType == 'locator': if assetName: result = self.read_data(dirName = dirName, folder = 'data', fileName = assetName) if result: for obj in result: ctl = obj[0] attr = obj[1] value = obj[2] #--- set locatorData if cmds.objExists(ctl + '.' + str(attr)): cmds.setAttr(ctl + '.' + str(attr), lock=False) cmds.setAttr(ctl + '.' + str(attr), value, lock=True, keyable=False, channelBox=False) else: raise Exception('There is no locator data!') else: raise Exception('There is no locator data of ' + assetName + '!') print 'LocatorData loaded!' elif dataType == 'weights': #--- get the data path data_path = os.path.join(self.root, 'data', dirName, assetName) if os.path.exists(data_path): #--- get the skinClusters, meshes and shapes w = skinweight.Weights() skins = w.get_skin_weights() skin_weights = list() for mesh in skins[0]: #--- skin the meshes skin = cmds.skinCluster(mesh,skins[3], toSelectedBones=True) skin_weights.append(skin[0]) #--- list all xml files in this folder files = os.listdir(data_path) for file in files: mesh_name = file.split('.')[0] for mesh, shape, skin in zip(skins[0], skins[1], skin_weights): if mesh_name == mesh: try: #--- import the new weights cmds.deformerWeights(file, im=True, method='index', deformer=skin, path=data_path, shape=shape) cmds.skinCluster(skin, edit=True, forceNormalizeWeights=True) except: pass print 'WeightData loaded!'
def save(self, dirName = None, assetName = None, dataType = None): #--- this method saves the data attr = attribute.Attribute() sel = cmds.ls('*_GCTL', type = 'transform') data = list() shape = list() locator = list() if dataType == 'guides': #--- save the guides for i in sel: list_attr = cmds.listAttr(i, keyable = True, visible = True) value_list = [] for attrs in list_attr: value = attr.getAttr(node = i, attribute = attrs) result = (str(i) + '.' + str(attrs), str(value)) value_list.append(result) data.append(value_list) self.write_data(dirName = dirName, folder = 'data', fileName = assetName, obj = data) print 'GuideData saved!' elif dataType == 'weights': #--- get the skinClusters, meshes and shapes w = skinweight.Weights() skins = w.get_skin_weights() folder = os.path.join('data', dirName) #--- create a new character folder if it does not exist self.new_data_folder(folder=folder, dirName=assetName) for mesh, shape, skin in zip(skins[0], skins[1], skins[2]): data_path = os.path.join(self.root, 'data', dirName, assetName) file_name = mesh + '.xml' cmds.deformerWeights(file_name, path=data_path, shape=shape, export=True, deformer=skin) print 'WeightData saved' elif dataType == 'locators': #--- save all the information provided by the custom locators sel = cmds.ls('*_*CTLShape') for i in sel: obj_type = cmds.nodeType(i) if obj_type == 'eLocator': attrs = cmds.listAttr(i, locked=True, unlocked=True) for attr in attrs: if not 'localScale' in attr: if (attr == 'size' or attr == 'shape' or attr == 'orientation' or attr =='width' or attr == 'localPositionX' or attr == 'localPositionY' or attr == 'localPositionZ'): value = cmds.getAttr(i + '.' + attr) result = [i, attr, value] locator.append(result) else: raise Exception('There is no eLocator shape of this node!') self.write_data(dirName = dirName, folder = 'data', fileName = assetName, obj = locator) print 'LocatorData saved!' elif dataType == 'shapes': #--- save all curve shape information for i in sel: shape_type = cmds.listRelatives(i, allDescendents = True, shapes = True) obj_type = cmds.objectType(shape_type) if obj_type == 'nurbsCurve' or obj_type == 'nurbsSurface': curve = cmds.ls(i + '.cv[*]', flatten = True) for cv in curve: pos = cmds.xform(cv, query = True, translation = True, worldSpace = True) result = [i, pos] shape.append(result) elif obj_type == 'mesh': vertices = cmds.ls(i + '.vtx[*]', flatten = True) for vtx in vertices: pos = cmds.xform(vtx, query = True, translation = True, worldSpace = True) result = [i, pos] shape.append(result) else: raise Exception('There is no component mode of this node!') self.write_data(dirName = dirName, folder = 'data', fileName = assetName, obj = shape) print 'ShapeData saved!'
def export_weights(self, filename=None, filepath=None): """ Export the weights of the given shape """ if not self.skincluster: return cmds.deformerWeights(filename, export=True, deformer=self.skincluster, path=filepath)
def import_deformer(self): if os.path.exists(mi.GelUtil.file_path + ".xml"): mc.deformerWeights(mi.GelUtil.file_path + ".xml", im=True, shape="%sShape" % self.mesh) else: mc.warning('No xml file exists for character.')