def read_weight(self, mcluster): mfn_weight_filter = OpenMayaAnim.MFnWeightGeometryFilter(mcluster) dag_paths = self.getDagPathMembers(mcluster) weights = {} for index in range(dag_paths.length()): mit_geometry = OpenMaya.MItGeometry(dag_paths[index]) membership_list = [] weight_list = [] while not mit_geometry.isDone(): component = mit_geometry.currentItem() float_array = OpenMaya.MFloatArray() membership = self.hasMembership(mcluster, dag_paths[index], component) if membership: mfn_weight_filter.getWeights(dag_paths[index], component, float_array) else: float_array = [0, 0, 0] membership_list.append(membership) weight_list.append(float_array[0]) mit_geometry.next() weight = {} weight['weights'] = weight_list weight['memberships'] = membership_list geometry = dag_paths[index].fullPathName().encode() weights.setdefault(geometry, weight) return weights
def transferReverseWeightList(geo, fromDeformer, toDeformer): ''' method for quickly transfering reversed weightList input python string (mesh) input pythin string (fromDeformer) input python string (toDeformer) ''' geoPath = GenAPI.getDagPath(geo) deformerObjectFrom = GenAPI.getMObject(fromDeformer) deformerObjectTo = GenAPI.getMObject(toDeformer) vertItr = om.MItMeshVertex(geoPath) deformerWeightFn = oma.MFnWeightGeometryFilter() while not vertItr.isDone(): componentObject = vertItr.currentItem() weights = om.MFloatArray() deformerWeightFn.setObject(deformerObjectFrom) deformerWeightFn.getWeights(geoPath, componentObject, weights) if weights[0] > 0.000: weights[0] = abs(weights[0] - 1.0) deformerWeightFn.setObject(deformerObjectTo) deformerWeightFn.setWeight(geoPath, componentObject, weights) vertItr.next()
def __init__(self, DeformerNode, geo): #获得一个组件列表 cmp_list = [universal.intoComponents(i) for i in universal.translateToName(geo)] #检查组件列表的数量 if len(cmp_list)<1: raise EOFError('geo没有任何对象') #建立一个组件选择列表 sel_list = om.MSelectionList() [sel_list.add(i) for i in cmp_list] if int(sel_list.length())>1: raise EOFError('%s 不在一个mesh或者其他对象上'%geo) return 1 self.path = om.MDagPath() self.comp = om.MObject() sel_list.getDagPath(0,self.path,self.comp) #获得变形节点 obj = om.MObject() sel_list.add(DeformerNode) sel_list.getDependNode(1,obj) try: self.weightGeo = oma.MFnWeightGeometryFilter(obj) except: raise EOFError('输入的变形节点不是正确的对象(簇,软变形...)')
def copy_joint_weights_to_cluster(skin_mel_node, joint_mel_node): ''' ''' #- initlize api nodes skin_mfn_node = OpenMayaAnim.MFnSkinCluster( pymel.core.PyNode(skin_mel_node).__apiobject__()) joint_dag_path = OpenMaya.MDagPath( pymel.core.PyNode(joint_mel_node).__apiobject__()) #- get joint influcenced points and weight values components = OpenMaya.MSelectionList() weights = OpenMaya.MDoubleArray() skin_mfn_node.getPointsAffectedByInfluence(joint_dag_path, components, weights) #- create cluster component_strings = list() components.getSelectionStrings(component_strings) cluster_mel_node = mc.cluster(component_strings)[0] clus_mfn_node = OpenMayaAnim.MFnWeightGeometryFilter( pymel.core.PyNode(cluster_mel_node).__apiobject__()) #- get geometry's dagpath and component geo_dag_path = OpenMaya.MDagPath() geo_comp_obj = OpenMaya.MObject() components.getDagPath(0, geo_dag_path, geo_comp_obj) #- convert skinweights type to cluster weights type cluster_weights_array = OpenMaya.MFloatArray() for v in weights: cluster_weights_array.append(v) #- set weights clus_mfn_node.setWeight(geo_dag_path, geo_comp_obj, cluster_weights_array)
def setClusterWeights(meshName, weights, clusterName=None): """ asdf """ sel = OpenMaya.MSelectionList() sel.add(meshName) if clusterName is None: sel.add(getClusterFromMesh()) else: sel.add(clusterName) dagPath = OpenMaya.MDagPath() mObj = OpenMaya.MObject() sel.getDagPath(0, dagPath) sel.getDependNode(1, mObj) fn_c = OpenMaya.MFnSingleIndexedComponent() c_obj = fn_c.create(OpenMaya.MFn.kMeshVertComponent) fnMesh = OpenMaya.MFnMesh(dagPath) numVerts = fnMesh.numVertices() indexArray = OpenMaya.MIntArray() for i in range(numVerts): indexArray.append(i) fn_c.addElements(indexArray) cluster = OpenMayaAnim.MFnWeightGeometryFilter() cluster.setObject(mObj) cluster.setWeight(dagPath, c_obj, weights)
def getWeightList(self): ''' returns current weightList of mesh output python float list (weightList) ''' deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) vertItr = om.MItGeometry(self.meshPath) weightList = [] while not vertItr.isDone(): component = vertItr.currentItem() if not self.checkMembership(component): weightList.append(0) else: floatArray = om.MFloatArray() deformerWeightFn.getWeights(self.meshPath, component, floatArray) weightList.append(floatArray[0]) vertItr.next() return weightList
def getDeformerFn(deformer): # Get MFnWeightGeometryFilter deformerObj = getDependNode(deformer) deformerFn = oma.MFnWeightGeometryFilter(deformerObj) # Return result return deformerFn
def mirrorDeformerWeightSingleMesh(self, axis='x', direction='>', table=[-1, 1, 1]): ''' method for mirroring deformer weights for one deformer...only works on single symetrical mesh input python string (axis) input python int list (table) ''' vertItr = om.MItMeshVertex(self.meshPath) deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) util = om.MScriptUtil() progressWin = UILib.ProgressWin() progressWin.itr = vertItr.count() progressWin.setTitle('Mirror Deformer') while not vertItr.isDone(): inComponent = vertItr.currentItem() currentPosition = vertItr.position(om.MSpace.kWorld) if eval('currentPosition.%s%s0.00000' % (axis, direction)): currentIndex = vertItr.index() inComponent = vertItr.currentItem() mirrorVert = MeasuringLib.MeasuringTool.getSymVert( self.meshPath, currentIndex, table) weights = om.MFloatArray() tempItr = om.MItMeshVertex(self.meshPath) intPtr = util.asIntPtr() tempItr.setIndex(mirrorVert[0], intPtr) outComponent = tempItr.currentItem() if self.checkMembership(inComponent): self.addComponentToMembershipList(outComponent) deformerWeightFn.getWeights(self.meshPath, inComponent, weights) deformerWeightFn.setWeight(self.meshPath, outComponent, weights) progressWin.inc = vertItr.index() progressWin.message = '%s.vtx[%i]' % (self.mesh, progressWin.inc) progressWin.progress() vertItr.next() progressWin.end()
def setClusterWeights(self, dag_path, cluster_mobject, weights): if not isinstance(dag_path, OpenMaya.MDagPath): dag_path = self.getDagPath(dag_path) if not isinstance(cluster_mobject, OpenMaya.MObject): cluster_mobject = self.getMObject(cluster_mobject) components = self.getVertexsMObjects(dag_path) mfn_geo_filter = OpenMayaAnim.MFnGeometryFilter(cluster_mobject) deformer_set = mfn_geo_filter.deformerSet() mfn_set = OpenMaya.MFnSet(deformer_set) mfn_set.addMember(dag_path, components) weight_geometry_filter = OpenMayaAnim.MFnWeightGeometryFilter( cluster_mobject) weight_geometry_filter.setWeight(dag_path, components, weights)
def setWeightList(self, weightList): ''' method for setting wieght list to mesh input python float list (weightList) ''' floatArray = om.MFloatArray() util = om.MScriptUtil() util.createFloatArrayFromList(weightList, floatArray) components = GenAPI.getMObjectAllVerts(self.meshPath) deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) deformerWeightFn.setWeight(self.meshPath, components, floatArray)
def mirrorDeformerWeightMultiMesh(self, geoTo, axis='x', table=[-1, 1, 1]): ''' method for mirroring deformer...only works on meshes mirrored across given axis input python string (geoFrom) imput python string (geoTo) input python string (deformer) input python string (axis) input python int list (table) ''' nodePathTo = GenAPI.getDagPath(geoTo) vertItr = om.MItMeshVertex(self.meshPath) deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) util = om.MScriptUtil() progressWin = UILib.ProgressWin() progressWin.itr = vertItr.count() progressWin.setTitle('Mirror Deformer') while not vertItr.isDone(): inComponent = vertItr.currentItem() currentPosition = vertItr.position(om.MSpace.kWorld) inComponent = vertItr.currentItem() mirrorVert = MeasuringLib.MeasuringTool.getSymVertFromClosestPoint( nodePathTo, currentPosition, table) weights = om.MFloatArray() tempItr = om.MItMeshVertex(nodePathTo) intPtr = util.asIntPtr() tempItr.setIndex(mirrorVert[0], intPtr) outComponent = tempItr.currentItem() if self.checkMembership(inComponent): self.addComponentToMembershipList(outComponent) deformerWeightFn.getWeights(self.meshPath, inComponent, weights) deformerWeightFn.setWeight(nodePathTo, outComponent, weights) progressWin.inc = vertItr.index() progressWin.message = '%s.vtx[%i]' % (self.mesh, progressWin.inc) progressWin.progress() vertItr.next() progressWin.end()
def getDeformerFn(deformer): ''' Initialize and return an MFnWeightGeometryFilter function set attached to the specified deformer @param deformer: Name of deformer to create function set for @type deformer: str ''' # Checks if not mc.objExists(deformer): raise UserInputError('Deformer '+deformer+' does not exist!') # Get MFnWeightGeometryFilter deformerObj = glTools.utils.base.getMObject(deformer) deformerFn = OpenMayaAnim.MFnWeightGeometryFilter(deformerObj) # Return result return deformerFn
def reverseWeightList(self): '''method for reversing weighList on current mesh''' deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) weightList = om.MFloatArray() verts = GenAPI.getMObjectAllVerts(self.mesh) deformerWeightFn.getWeights(self.meshPath, verts, weightList) reverseWeightList = [] for i in range(weightList.length()): reverseWeight = abs(weightList[i] - 1.00000) reverseWeightList.append(reverseWeight) return reverseWeightList
def mirrorWeightList(self, axis='x', direction='<', table=[-1, 1, 1]): ''' this method creates a mirrored weightlist and membership list for a single symetrical mesh ''' vertItr = om.MItMeshVertex(self.meshPath) deformerWeightFn = oma.MFnWeightGeometryFilter(self.deformerObject) util = om.MScriptUtil() weightList = [] membershipList = [] progressWindow = UILib.ProgressWin() progressWindow.setTitle('Mirror Wieghts') progressWindow.itr = vertItr.count() while not vertItr.isDone(): currentIndex = vertItr.index() mirrorVert = MeasuringLib.MeasuringTool.getSymVert(self.meshPath, currentIndex, table=table) weights = om.MFloatArray() tempItr = om.MItMeshVertex(self.meshPath) intPtr = util.asIntPtr() tempItr.setIndex(mirrorVert[0], intPtr) outComponent = tempItr.currentItem() deformerWeightFn.getWeights(self.meshPath, outComponent, weights) membershipList.append(self.checkMembership(outComponent)) weightList.append(weights[0]) progressWindow.inc = vertItr.index() progressWindow.message = '%s...%i of %i' % ( self.mesh, vertItr.index(), vertItr.count()) progressWindow.progress() vertItr.next() progressWindow.end() return weightList, membershipList
def getDeformerFn(deformer): ''' Initialize and return an MFnWeightGeometryFilter function set attached to the specified deformer :param deformer str: Name of deformer to create function set for :return: MFnWeightGeometryFilter function set on deformer :rtype: class obj ''' # Checks if not cmds.objExists(deformer): raise Exception('Deformer {0} does not exist!'.format(deformer)) # Get MFnWeightGeometryFilter deformerObj = getMObject(deformer) try: deformerFn = oma.MFnWeightGeometryFilter(deformerObj) except: raise Exception('Could not get a geometry filter for deformer {0}!'.format(deformer)) # Return result return deformerFn
def getDeformerFn(deformer): ''' Initialize and return an MFnWeightGeometryFilter function set attached to the specified deformer @param deformer: Name of deformer to create function set for @type deformer: str ''' # Checks if not mc.objExists(deformer): raise Exception('Deformer '+deformer+' does not exist!') # Get MFnWeightGeometryFilter deformerObj = glTools.utils.base.getMObject(deformer) try: deformerFn = OpenMayaAnim.MFnWeightGeometryFilter(deformerObj) except: # is there a good exception type for this? raise Exception('Could not get a geometry filter for deformer "'+deformer+'"!') # Return result return deformerFn
def setDeformerWeigth(DeformerNode,geo,weights): #获得一个组件列表 cmp_list = [universal.intoComponents(i) for i in universal.translateToName(geo)] #检查组件列表的数量 if len(cmp_list)<1: raise EOFError('geo没有任何对象') #建立一个组件选择列表 sel_list = om.MSelectionList() [sel_list.add(i) for i in cmp_list] if int(sel_list.length())>1: raise EOFError('%s 不在一个mesh或者其他对象上'%geo) return 1 path = om.MDagPath() comp = om.MObject() sel_list.getDagPath(0,path,comp) #获得变形节点 obj = om.MObject() sel_list.add(DeformerNode) sel_list.getDependNode(1,obj) try: weightGeo = oma.MFnWeightGeometryFilter(obj) except: raise EOFError('输入的变形节点不是正确的对象(簇,软变形...)') float_array = om.MFloatArray() append = float_array.append try: [append(i) for i in weights] except: raise EOFError('输入权重列表错误') try: undoIt_float_array = om.MFloatArray() weightGeo.getWeights(path,comp,undoIt_float_array) except: raise EOFError('获得原始权重列表失败') doIt_def = functools.partial(weightGeo.setWeight,path,comp,float_array) undoIt_def = functools.partial(weightGeo.setWeight,path,comp,undoIt_float_array) return cmc.addCommand(doIt_def,undoIt_def)
def createClusterFromSoftSelection(name): '''function for creating a cluster from a soft selection''' clusterData = MeasuringLib.MeasuringTool.createWeightListFromSoftSelection( ) cluster = cmds.cluster(name=name) deformerObject = GenAPI.getMObject(cluster[0]) deformerTool = oma.MFnWeightGeometryFilter(deformerObject) inc = 0 progressWindow = UILib.ProgressWin() progressWindow.setTitle('Cluster From Soft Selection') progressWindow.itr = len(clusterData[1]) for components in clusterData[1]: geoFilter = oma.MFnGeometryFilter(deformerObject) deformerSet = geoFilter.deformerSet() setFn = om.MFnSet(deformerSet) setFn.addMember(components[0], components[1]) floatArray = om.MFloatArray() for i in range(len(clusterData[2][inc])): floatArray.append(clusterData[2][inc][i]) deformerTool.setWeight(components[0], components[1], floatArray) inc += 1 progressWindow.inc = inc progressWindow.message = '%s.vtx[%i]' % (components[0].fullPathName(), inc) progressWindow.progress() progressWindow.end() om.MGlobal.displayInfo('Created cluster from soft selection')
def setDeformerWeigth(DeformerNode,weights,geo=None): #DeformerNode = 'softMod1' #geo = None #weights = [0 for i in pm.selected(fl = True)] if not pm.objExists(DeformerNode): om.MGlobal.displayError('错误输入的变形节点并不存在') return False if not isinstance(DeformerNode,basestring): DeformerNode = DeformerNode.nodeName() if not geo is None: if not pm.objExists(geo): om.MGlobal.displayError('错误输入的对象并不存在') return False if not isinstance(geo,basestring): geo = ['%s'%i for i in pm.ls(geo)] else: geo = [geo] sel = om.MSelectionList() obj = om.MObject() path = om.MDagPath() comp = om.MObject() try: sel.add(DeformerNode) except: om.MGlobal.displayError('无法找到变形节点') return False sel.getDependNode(0,obj) try: weightGeo = oma.MFnWeightGeometryFilter(obj) except: om.MGlobal.displayError('输入的变形节点不是正确的对象(簇,软变形...)') return False float_array = om.MFloatArray() append = float_array.append try: [append(i) for i in weights] except: om.MGlobal.displayError('输入权重列表错误') return False sel = om.MSelectionList() if not geo is None: try: [sel.add(i) for i in geo] except: om.MGlobal.displayError('无法找到变形对象') return False sel.getDagPath(0,path,comp) try: undoIt_float_array = om.MFloatArray() weightGeo.getWeights(path,comp,undoIt_float_array) doIt_def = functools.partial(weightGeo.setWeight,path,comp,float_array) undoIt_def = functools.partial(weightGeo.setWeight,path,comp,undoIt_float_array) cmc.addCommand(doIt_def,undoIt_def) except: om.MGlobal.displayError('设置权重发生错误') return False else: comp_dict = {'mesh':'vtx','nurbsCurve':'cv','nurbsSurface':'cv','lattice':'pt'} for i in range(weightGeo.numOutputConnections()): weightGeo.getPathAtIndex(i,path) itGeo = om.MItGeometry(weightGeo.outputShapeAtIndex(i)) length = itGeo.exactCount() shape = path.fullPathName() shape_type = mc.objectType(shape) comp_type = comp_dict[shape_type] for t in range(length): sel.add('%s.%s[%d]'%(shape,comp_type,itGeo.index()) ) itGeo.next() if sel.length() == 1: sel.getDagPath(0,path,comp) try: undoIt_float_array = om.MFloatArray() weightGeo.getWeights(path,comp,undoIt_float_array) doIt_def = functools.partial(weightGeo.setWeight,path,0,comp,float_array) undoIt_def = functools.partial(weightGeo.setWeight,path,0,comp,undoIt_float_array) cmc.addCommand(doIt_def,undoIt_def) except: om.MGlobal.displayError('设置权重发生错误') return False crr_id = 0 for i in range(sel.length()): sel.getDagPath(i,path,comp) obj_comp_size = om.MFnComponent(comp).elementCount() try: undoIt_float_array = om.MFloatArray() weightGeo.getWeights(path,comp,undoIt_float_array) doIt_float_array = float_array[crr_id:crr_id+obj_comp_size] doIt_def = functools.partial(weightGeo.setWeight,path,i,comp,doIt_float_array) undoIt_def = functools.partial(weightGeo.setWeight,path,i,comp,undoIt_float_array) cmc.addCommand(doIt_def,undoIt_def) #weightGeo.setWeight(path,i,obj,float_array[crr_id:crr_id+obj_comp_size]) except: om.MGlobal.displayError('设置权重发生错误') return False crr_id += obj_comp_size return True
def mirrorWeightListMultiMesh(fromMesh, toMesh, deformer, table=[-1, 1, 1]): ''' this method will create a mirrored weightList from one mesh to another meshes must be symetrical input python string (fromMesh) input python string (toMesh) input python string (deformer) input python list (symetry table) ''' weightList = [] membershipList = [] util = om.MScriptUtil() fromMeshPath = GenAPI.getDagPath(fromMesh) toMeshPath = GenAPI.getDagPath(toMesh) meshToVertItr = om.MItMeshVertex(toMeshPath) deformerObject = GenAPI.getMObject(deformer) deformerWeightFn = oma.MFnWeightGeometryFilter(deformerObject) weights = om.MFloatArray() progressWindow = UILib.ProgressWin() progressWindow.setTitle('Mirror Wieghts') progressWindow.itr = meshToVertItr.count() while not meshToVertItr.isDone(): fromVertPoint = meshToVertItr.position(om.MSpace.kWorld) vertID = MeasuringLib.MeasuringTool.getSymVertFromClosestPoint( fromMeshPath, fromVertPoint, table=table) meshFromVertItr = om.MItMeshVertex(fromMeshPath) intPtr = util.asIntPtr() meshFromVertItr.setIndex(vertID[0], intPtr) fromVert = meshToVertItr.currentItem() try: deformerWeightFn.getWeights(fromMeshPath, fromVert, weights) weightTool = WeightListTool(fromMesh, deformer) membershipList.append(weightTool.checkMembership(fromVert)) weightList.append(weights[0]) except: weightTool = WeightListTool(fromMesh, deformer) membershipList.append(weightTool.checkMembership(fromVert)) weightList.append(0) progressWindow.inc = meshToVertItr.index() progressWindow.message = '%s...%i of %i' % ( fromMesh, meshToVertItr.index(), meshToVertItr.count()) progressWindow.progress() meshToVertItr.next() progressWindow.end() return weightList, membershipList
# get joint influcenced points and weight values components = om.MSelectionList() weights = om.MDoubleArray() skin_mfn.getPointsAffectedByInfluence(joint_dag_path, components, weights) # create cluster components_list = list() components.getSelectionStrings(components_list) cluster_node = cmds.cluster(components_list) cluster_selection_list = om.MSelectionList() om.MGlobal.getSelectionListByName(cluster_node[0], cluster_selection_list) cluster_mobject = om.MObject() cluster_selection_list.getDependNode(0, cluster_mobject) cluster_mfn = oma.MFnWeightGeometryFilter(cluster_mobject) # get geometry's type to cluster weights type geo_dag_path = om.MDagPath() geo_comp_obj = om.MObject() components.getDagPath(0, geo_dag_path, geo_comp_obj) # convert skinweights type to cluster weights type cluster_weights_array = om.MFloatArray() for index in weights: cluster_weights_array.append(index) # set weights cluster_mfn.setWeight(geo_dag_path, geo_comp_obj, cluster_weights_array) # change the cluster position