import time try: import pymel.core as pm except ImportError: pm = None import maya.cmds as cmds # import atcore.atvc.atvc as atvc import os try: import skin_api.Utils as apiUtils import skin_api.Skinning as apiSkinning except ImportError: from . import Utils as apiUtils from . import Skinning as apiSkinning ''' apiVtxAttribs is a "caller"-class in order to organize the simplified returns of the other modules such as EACloth or Skinning I deem it the "garbage" collector for any general combination of the Utils, Skinning, EACloth, Havok modules that we find useful eg a list with skinning, blendshape and paintableAttrs looks like this {"ObjectName": {skinCluster:{clusterWeights, clusterInflNames, clusterMaxInf} {blendShape:{clusterWeights, clusterTargets} {paintableAttr:{clusterWeights} ''' class ApiVtxAttribs(): def __init__(self): if pm: self.activeScenePath = os.path.dirname(pm.sceneName()) else: scene_name = cmds.file(q=True, sn=True) self.activeScenePath = os.path.dirname(scene_name) if scene_name else "" # self.vc = atvc.VersionControl() self.filePath = "" self.sourceWeightDict = {} self.transferWeightDict = {} self.barycentrWeightDict = {} self.skinWeightsFilter = "API Skin weights file (*.skinWeights)" def exportSkinWeights(self, filePath=None, selected=False, saveJointInfo=False): ''' Export skinweights for meshes in maya If no filePath is provided the function prompts a file dialogue window If selected is False, function will operate on all valid objects (meshes) found in the active maya scene. :param filePath: default is None :param selected: default is False :param saveJointInfo: saves joint orient, world transform and parent joint info, default is False :return: ''' msg = "" # get filepath for skinweightsfile if not filePath: filePath = apiUtils.filePathPrompt(dialogMode=0, caption= "Export Skinweights", dirPath=self.activeScenePath, filter = self.skinWeightsFilter) if filePath: if selected: if pm: transNodes = apiUtils.getTransforms(pm.ls(sl=True)) else: transNodes = apiUtils.getTransforms(cmds.ls(sl=True)) else: if pm: transNodes = apiUtils.getTransforms(pm.ls(type="mesh")) else: # cmds.ls 也使用 type 参数 transNodes = apiUtils.getTransforms(cmds.ls(type="mesh")) start = time.time() skinWeightsDict = apiSkinning.buildSkinWeightsDict(transNodes, saveJointInfo=saveJointInfo) apiUtils.pickleDumpWeightsToFile(skinWeightsDict, filePath) end = time.time() msg = "Skinning Exported to %s in: " % filePath + str(end - start) + " seconds" return msg def importSkinWeights(self, filePath=None, selected=False, stripJointNamespaces=False, addNewToHierarchy=False): ''' Import skinweights for meshes in maya. If no filePath is provided the function prompts a file dialogue window If selected is False, function will operate on all valid objects (meshes) found in the active maya scene. Runs a filtering process on the given .skinWeights file, matching objects based on name AND vtx count. :param filePath: default is None, accepts .skinWeights files :param selected: default is False :param stripJointNamespaces: strips joint namespaces on skinWeights file, default is False :param addNewToHierarchy: adds missing joints, world transform and parent only correct when exported with joint info, default is False :return: ''' msg = "" # get filepath for skinweightsfile if not filePath: filePath = apiUtils.filePathPrompt(dialogMode= 1, caption="Import Skinweights", dirPath=self.activeScenePath, filter=self.skinWeightsFilter) if filePath: if os.path.exists(filePath) and filePath.endswith(".skinWeights"): fileWeightDict = apiUtils.getPickleObject(filePath) if fileWeightDict: # then build a filtered local "scene" weight dictionary and a list of valid Objects sceneWeightDict, validNodeList = apiUtils.matchDictionaryToSceneMeshes(weightDictionary=fileWeightDict, selected=selected) if len(validNodeList) > 0: loadBarMaxVal = len(validNodeList) loadBarObj = apiUtils.LoadingBar() msg = "Importing skinning for : " + str(validNodeList) for validNode in validNodeList: loadBarObj.loadingBar("Importing Skinweights...", loadBarMaxVal, "Importing...") apiSkinning.skinClusterBuilder(validNode, sceneWeightDict, stripJointNamespaces=stripJointNamespaces, addNewToHierarchy=addNewToHierarchy) else: # log.error("No valid objects found in scene!") msg = "No valid objects found in scene!" return False else: msg = "Could not find a .skinWeights file with path %s" % filePath # return False return msg