def oneToNumberSkin(self, widget=None): rootName = self.skilineEdit.text() suitedName = self.skilineEdit2.text() suitedListName = suitedName.split(',') suitedNode = [pm.PyNode(n) for n in suitedListName] rootSki = self.getSkinCluste(pm.PyNode(rootName)) for node in suitedNode: if rootSki: jointlist = rootSki.getInfluence() if not self.getSkinCluste(node): s = pm.skinCluster(jointlist, node, dr=4.5) pm.copySkinWeights(ss=rootSki, ds=s, noMirror=True, sa='closestPoint', ia='closestJoint') else: s = self.getSkinCluste(node) pm.copySkinWeights(ss=rootSki, ds=s, noMirror=True, sa='closestPoint', ia='closestJoint') widget.reject()
def copy_weights(self, from_this, to_this): try: # skin = current_skin_host.inputs(type='skinCluster')[0] skin = pm.PyNode(pm.mel.findRelatedSkinCluster(from_this.name())) except: # -- If there is no skin cluster we skip this step (this is # -- useful whilst progressively building return # -- Get a list of the influence objects being used # -- by the skin currently influences = skin.influenceObjects() # -- Apply a new skin cluster new_skin = pm.skinCluster( influences, to_this, toSelectedBones=True, maximumInfluences=skin.getMaximumInfluences()) # -- Copy the skin weights between them pm.copySkinWeights( sourceSkin=skin, destinationSkin=new_skin, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation=['name', 'closestJoint', 'label'], )
def run(self, current_skin_host=None, target=None): # -- Get our mesh candidates current_skin_host = pm.selected()[0] target = pm.selected()[1] # -- Look for the mesh log.debug(current_skin_host.inputs()) # skin = current_skin_host.inputs(type='skinCluster')[0] skin = pm.PyNode(pm.mel.findRelatedSkinCluster(current_skin_host)) # -- Get a list of the influence objects being used # -- by the skin currently influences = skin.influenceObjects() # -- Apply a new skin cluster new_skin = pm.skinCluster( influences, target, toSelectedBones=True, maximumInfluences=skin.getMaximumInfluences()) # -- Copy the skin weights between them pm.copySkinWeights( sourceSkin=skin, destinationSkin=new_skin, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation=['name', 'closestJoint', 'label'], )
def batchCovert(): sels = pm.selected() if sels: for sel in sels: if sel.getShape().type() == 'mesh': originNode = sel originShapeNodes = originNode.getShapes() pm.select(cl=True) if originShapeNodes: originShapeNode = originShapeNodes[0] historyNodes = originShapeNode.listHistory() if historyNodes: influenceJoints = [] for node in historyNodes: if node.type() == 'joint': influenceJoints.append(node) tempNode = pm.duplicate(originNode,name=originNode+'_temp')[0] pm.setAttr(tempNode+'.visibility',0) pm.select(influenceJoints,r=True) pm.select(tempNode,add=True) pm.skinCluster(name=tempNode.name()+'_skinCluster',toSelectedBones=True,maximumInfluences=5,dropoffRate=4) pm.copySkinWeights(originNode,tempNode,noMirror=True,surfaceAssociation='closestPoint',influenceAssociation='closestJoint',normalize=True) pm.deltaMushToSkinCluster(source=originShapeNode.name(),target=tempNode.getShape().name()) pm.copySkinWeights(tempNode,originNode,noMirror=True,surfaceAssociation='closestPoint',influenceAssociation='closestJoint') pm.delete(tempNode) else: pm.displayWarning('Please select polygon object!')
def retargetSkin(meshes=None): """ Creates new meshes retargeted to the root skeleton. Args: meshes(list): A list of meshes, defaults to the current selection. """ meshes = meshes or pmc.selected() meshes = getMeshes(meshes) newMeshes = [] for srcMesh in meshes: # Create a duplicate mesh dstParent = pmc.duplicate(srcMesh.getParent()) pmc.parent(dstParent, world=True) # Copy the skinning srcCluster = pmc.ls(srcMesh.listHistory(), type='skinCluster')[0] dstCluster = pmc.skinCluster(dstParent, getBindSkeleton(), mi=4, tsb=True) pmc.copySkinWeights(ss=srcCluster, ds=dstCluster, noMirror=True) newMeshes.append(dstParent) # If more than one mesh selected, combine meshes if len(newMeshes) > 1: newMesh, newCluster = pmc.polyUniteSkinned(newMeshes, ch=False) pmc.delete(newMeshes) pmc.rename(newMesh, 'body') bindRootSkeleton()
def copy_skin(self, *args): """ Copy's the skinning between different meshes only by providing the meshes.\n :args[0] the source mehs, this geo \n :args[1:] the destination mehs where the skin will be copied\n :return a list with all the skin clusters that where created during execution """ source = args[0] destination = args[1:] skin_cluster_node = self.get_skin_cluster(source) skin_cluster_list = [] if skin_cluster_node: list_joints = skin_cluster_node.influenceObjects() if destination: for each_node in destination: new_skin_cluster = pm.skinCluster(list_joints, each_node) skin_cluster_list.append(new_skin_cluster) self.name_convention.rename_name_in_format( new_skin_cluster, name=self.name_convention.get_a_short_name(each_node)) pm.copySkinWeights(source, destination, influenceAssociation=[ 'label', 'name', 'closestJoint', 'oneToOne' ]) return new_skin_cluster
def mirror_eyeCurve_weights(): ''' mirror LT_eye_aimAt_crv_0 to RT_eye_aimAt_crv_0 ''' lf_crv = nt.Transform(u'LT_eye_aimAt_crv_0') rt_crv = nt.Transform(u'RT_eye_aimAt_crv_0') lf_skn = pm.PyNode(mel.findRelatedSkinCluster(lf_crv)) rt_skn = pm.PyNode(mel.findRelatedSkinCluster(rt_crv)) def setEyeJointsLabels(joints): for jnt in joints: ### change the label label = '_'.join(jnt.name().split('_')[1:3]) #label = '_'.join(jnt.name().split('_')[1:4]) jnt.attr('type').set('Other') jnt.otherType.set(label) lf_infs = pm.skinCluster(lf_crv, q=True, inf=True) setEyeJointsLabels(lf_infs) rt_infs = pm.skinCluster(rt_crv, q=True, inf=True) setEyeJointsLabels(rt_infs) lf_crv.sx.setLocked(False) lf_crv.sx.set(-1) pm.copySkinWeights(ss=lf_skn, ds=rt_skn, sa='closestPoint', ia='label', nm=True) lf_crv.sx.set(1)
def mirror_eyeCurve_weights(): """ mirror LT_eye_aimAt_crv_0 to RT_eye_aimAt_crv_0 """ lf_crv = nt.Transform(u"LT_eye_aimAt_crv_0") rt_crv = nt.Transform(u"RT_eye_aimAt_crv_0") lf_skn = pm.PyNode(mel.findRelatedSkinCluster(lf_crv)) rt_skn = pm.PyNode(mel.findRelatedSkinCluster(rt_crv)) def setEyeJointsLabels(joints): for jnt in joints: ### change the label label = "_".join(jnt.name().split("_")[1:3]) # label = '_'.join(jnt.name().split('_')[1:4]) jnt.attr("type").set("Other") jnt.otherType.set(label) lf_infs = pm.skinCluster(lf_crv, q=True, inf=True) setEyeJointsLabels(lf_infs) rt_infs = pm.skinCluster(rt_crv, q=True, inf=True) setEyeJointsLabels(rt_infs) lf_crv.sx.setLocked(False) lf_crv.sx.set(-1) pm.copySkinWeights(ss=lf_skn, ds=rt_skn, sa="closestPoint", ia="label", nm=True) lf_crv.sx.set(1)
def copySkin(skinedMesh, mesh): """ Copy skin cluster from a skined mesh """ # Checks nodetypes if not isinstance(skinedMesh, pm.nodetypes.Transform): skinedMesh = pm.PyNode(skinedMesh) if not isinstance(mesh, pm.nodetypes.Transform): mesh = pm.PyNode(mesh) # get shape skinedMeshShape = skinedMesh.getShape() # loop since a skin cluster are found skinCluster = pm.listHistory(skinedMeshShape, type='skinCluster')[0] # skinCluster = pm.PyNode(skinCluster) skinInf = skinCluster.maxInfluences.get() # joint list jointList = skinCluster.influenceObjects() # create skinCluster copySkinCluster = pm.skinCluster(mesh, jointList, mi=skinInf) print copySkinCluster # copy skin weigths pm.copySkinWeights(ss=skinCluster, ds=copySkinCluster, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation=('closestJoint', 'closestJoint'))
def copyBind(source, destination, sa='closestPoint', ia='closestJoint'): """ Bind and Copy skincluster to destination GEO :param source: mesh str :param destination: mesh str :return: """ # Get Shape and skin from Object skinCluster = findRelatedSkinCluster(source) if skinCluster: skin = skinCluster else: print 'Missing source SkinCluster' # Get joint influence of the skin influnces = skin.getInfluence(q=True) # influences is joint # Bind destination Mesh # pm.select(influnces[0]) # pm.select(destination, add=True) # mel.eval('SmoothBindSkin;') pm.skinCluster(influnces[0], destination, dr=4.0) # copy skin wheights form source pm.select(source) pm.select(destination, add=True) pm.copySkinWeights(noMirror=True, surfaceAssociation=sa, influenceAssociation=ia) pm.select(cl=True)
def skinCopy(sourceMesh=None, targetMesh=None, *args): if not sourceMesh or not targetMesh: if len(pm.selected()) >=2: sourceMesh = pm.selected()[-1] targetMeshes = pm.selected()[:-1] else: pm.displayWarning("Please select target mesh/meshes and source mesh with skinCluster.") return else: targetMeshes = [targetMesh] #we check this here, because if not need to check when we work base on selection. if isinstance(sourceMesh, basestring): sourceMesh = pm.PyNode(sourceMesh) for targetMesh in targetMeshes: if isinstance(targetMesh, basestring): sourceMesh = pm.PyNode(targetMesh) ss = getSkinCluster(sourceMesh) if ss: oDef = pm.skinCluster(sourceMesh, query=True, influence=True) skinCluster = pm.skinCluster(oDef, targetMesh, tsb=True, nw=2, n=targetMesh.name() + "_SkinCluster") pm.copySkinWeights( ss=ss.stripNamespace(), ds=skinCluster.name(), noMirror=True, ia="oneToOne", sm=True, nr=True) else: pm.displayError("Source Mesh :" + sourceMesh.name() + " Don't have skinCluster")
def shadowMesh(triCount=10000): meshArg = pm.ls(sl=True) meshList = pm.duplicate(meshArg, rr=True) shadowGeo = pm.polyUnite(meshList, ch=False, name='ShadowGeo')[0] pm.delete(meshList) #deleting leftover garbage transform nodes pm.parent(shadowGeo, 'CharaA') newSkinClust = pm.skinCluster( shadowGeo, pm.listRelatives('CharaA', ad=True, type='joint')) #skinning begins pm.select(meshArg) pm.select(shadowGeo, add=True) pm.copySkinWeights( noMirror=True, surfaceAssociation='closestPoint', influenceAssociation='closestJoint') #copying skin weights pm.selectMode(o=True) #shadowmesh starts here pm.select(shadowGeo) mel.eval( 'polyCleanupArgList 3 { "0","1","1","0","0","0","0","0","0","1e-005","0","1e-005","0","1e-005","0","1","0" };' ) #clean up before reduction pm.selectMode(o=True) #reduce polycount to fall under budget pm.polyReduce(shadowGeo, ver=1, trm=2, triangleCount=triCount, sharpness=0, keepBorder=1, keepColorBorder=1, keepFaceGroupBorder=1, keepHardEdge=1, keepCreaseEdge=1, keepBorderWeight=0.5, keepMapBorderWeight=0, keepColorBorderWeight=0, keepFaceGroupBorderWeight=0, keepHardEdgeWeight=0.25, keepCreaseEdgeWeight=0, useVirtualSymmetry=0, symmetryTolerance=0.01, sx=0, sy=1, sz=0, sw=0, preserveTopology=1, keepQuadsWeight=1, vertexMapName="", replaceOriginal=1, cachingReduce=1, constructionHistory=1) pm.select(deselect=True) pm.bakePartialHistory(shadowGeo, prePostDeformers=True, preDeformers=True) pm.select(shadowGeo) print('EKKO shadowMesh successful!\nShadow Mesh specs:') print(pm.polyEvaluate(shadowGeo, fmt=True))
def transfer_deformer_weights(self, geo_source, geo_target=None, deformer_source=None, deformer_target=None, surface_association="closestPoint"): """ Copies the weight map of a deformer of an object to the deformer of another object. :param geo_source: Source Shape :param geo_target: Target Shape :param deformer_source: Source Deformer :param deformer_target: Target Deformer :param surface_association: Surface Association. Valid values: closestPoint, rayCast, or closestComponent. """ assert geo_source and deformer_source and deformer_target, \ "select a source and target geometry and then the source and target deformers" previous_selection = pm.selected() if not geo_target: geo_target = geo_source self.progress_bar_init() self.progress_bar_next() deformer_source_weights = deformer_source.weightList[0].weights.get() self.progress_bar_next() tmp_source = pm.duplicate(geo_source)[0] tmp_target = pm.duplicate(geo_target)[0] tmp_source.v.set(True) tmp_target.v.set(True) self.progress_bar_next() pm.select(clear=True) l_jnt = list() l_jnt.append(pm.joint(n="jnt_tmpA_01", p=[0, 0, 0])) l_jnt.append(pm.joint(n="jnt_tmpA_02", p=[0, 1, 0])) skin_source = pm.skinCluster(l_jnt, tmp_source, nw=1) skin_target = pm.skinCluster(l_jnt, tmp_target, nw=1) self.progress_bar_next() skin_source.setNormalizeWeights(0) pm.skinPercent(skin_source, tmp_source, nrm=False, prw=100) skin_source.setNormalizeWeights(True) [pm.setAttr('{}.wl[{}].w[{}]'.format(skin_source, i, 0), value) for i, value in enumerate(deformer_source_weights)] [pm.setAttr('{}.wl[{}].w[{}]'.format(skin_source, i, 1), 1.0 - value) for i, value in enumerate(deformer_source_weights)] self.progress_bar_next() pm.copySkinWeights(ss=skin_source, ds=skin_target, nm=True, sa=surface_association) self.progress_bar_next() deformer_target_weights = [v for v in skin_target.getWeights(tmp_target, 0)] [deformer_target.weightList[0].weights[i].set(val) for i, val in enumerate(deformer_target_weights)] self.progress_bar_next() pm.delete([tmp_source, tmp_target, l_jnt]) pm.select(previous_selection) self.progress_bar_next() self.progress_bar_ends(message="Finished successfully!")
def copy_weights(source_mesh, target_nodes, **copySkinWeights_kwargs): """Copies weights using pm.copySkinWeights with the most commonly used default kwargs. target_nodes can be a single skinned mesh or vertex or it can be a list of vertices. """ default_copySkinWeightsKwargs = {'noMirror': True, 'surfaceAssociation': 'closestPoint', 'influenceAssociation': ('label', 'name', 'closestJoint'), 'normalize': True} default_copySkinWeightsKwargs.update(copySkinWeights_kwargs) pm.copySkinWeights(source_mesh, target_nodes, **default_copySkinWeightsKwargs)
def copy_skin_binding(source_object, destination_object): skin_cluster = get_skinCluster(source_object) if skin_cluster: skin_joints = skin_cluster.influenceObjects() dest_skin = get_skinCluster(destination_object) if dest_skin: pm.delete(dest_skin) new_skin = pm.skinCluster(skin_joints, destination_object, bindMethod=0, toSelectedBones=True) pm.copySkinWeights(sourceSkin=skin_cluster, destinationSkin=new_skin, surfaceAssociation='closestPoint', influenceAssociation=['label', 'name', 'oneToOne'], noMirror=True) print '%s -> %s\n' % (source_object, destination_object)
def copySkinWeightBetweenMesh(selection=pm.ls(sl=True)): """ Copy skin weight to mirrored mesh """ sourceMesh = selection[0] destinationMesh = selection[1] sourceSkinCluster = mel.eval('findRelatedSkinCluster ' + sourceMesh) destinationSkinCluster = mel.eval('findRelatedSkinCluster ' + destinationMesh) pm.copySkinWeights(ss=sourceSkinCluster, ds=destinationSkinCluster, mirrorMode='YZ', surfaceAssociation='closestPoint', influenceAssociation='closestJoint')
def SkinCopy(SEL): for a in SEL[1:]: pm.select(a) pm.select(jntList, add=1) pm.skinCluster(toSelectedBones=1, bindMethod=0, normalizeWeights=1, mi=10, omi=1, dr=10, sm=SknMthd) pm.select(SEL[0]) pm.select(a, add=1) pm.copySkinWeights(noMirror=1, surfaceAssociation='closestPoint')
def copy_weights(self, newTarget): '''@brief Additional function to copy weights from the source geometry to a new one.@details This new geometry will be skinned with the same influence joints. @code test = libWeights.SkinWeights() #Set the target geometry test.target = "pCube1" #copy the weights to the new gometery test.copy_weights("pCube2") @endcode ''' currentInfluences = pm.skinCluster(self.target_deformer, inf=True, q=True) res = libUtilities.skinGeo(newTarget, currentInfluences) # Transfer the weights pm.copySkinWeights(ss=self.target_deformer, ds=res, noMirror=True, surfaceAssociation="rayCast", influenceAssociation="closestJoint")
def copySkinRUI(): sel = pm.ls(sl=1) if sel: source = sel[0] dest = sel[1:] for d in dest: pm.copySkinWeights(source, d, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation='oneToOne') pm.select(sel[1:]) mel.eval('removeUnusedInfluences')
def copyWeights(sourceMesh, destMesh): ''' Select skinned mesh then non-skinned mesh and run: copyWeights(pmc.selected()[0], pmc.selected()[1]) ''' sourceSkin = [ x for x in pmc.listHistory(sourceMesh) if pmc.nodeType(x) == "skinCluster" ][0] influences = pmc.skinCluster(sourceMesh, q=1, influence=1) pmc.select(influences) destSkin = pmc.skinCluster(influences, destMesh) pmc.copySkinWeights(ss=sourceSkin.name(), ds=destSkin.name(), noMirror=True)
def copy_weights(self, newTarget): '''@brief Additional function to copy weights from the source geometry to a new one. @details This new geometry will be skinned with the same influence joints. @code test = libWeights.SkinWeights() #Set the target geometry test.target = "pCube1" #copy the weights to the new gometery test.copy_weights("pCube2") @endcode ''' currentInfluences = pm.skinCluster(self.target_deformer, inf=True, q=True) res = libUtilities.skinGeo(newTarget, currentInfluences) # Transfer the weights pm.copySkinWeights(ss=self.target_deformer, ds=res, noMirror=True, surfaceAssociation="rayCast", influenceAssociation="closestJoint")
def copy_skin_binding_structure(source, destination): match_structure = [] # analysis.Main(source, destination) from pprint import pprint as pp pp(match_structure) done = 'coping from to:\n' for each_object in match_structure.match_dictionary: skin_cluster = get_skinCluster(each_object) if skin_cluster: skin_joints = skin_cluster.influenceObjects() new_skin = pm.skinCluster(skin_joints, match_structure.match_dictionary[each_object], bindMethod=0, toSelectedBones=True) pm.copySkinWeights(sourceSkin=skin_cluster, destinationSkin=new_skin, surfaceAssociation='closestPoint', noMirror=True) done += '%s -> %s\n' % (each_object, match_structure.match_dictionary[each_object]) print done
def mirror_transfer_skin_weights(): """ Helper function to mirror weights from two pieces of geo that are separate. Selection order: This -> That """ user_sel = pm.ls(sl=True) # TODO: More robust way of finding from and to objects. from_object = user_sel[0] to_object = pm.PyNode(from_object.replace('_L', '_R')) # If the to object has no skin cluster, add one best we can. bind_mirror_weights(from_object, to_object) # Duplicate and combine the pieces duplicate_pieces = pm.duplicate([from_object, to_object]) combined_geo, _ = pm.polyUnite(*duplicate_pieces, ch=1, mergeUVSets=1, centerPivot=True, name='TEMP_combined_mirror_geo') # Delete history pm.delete(combined_geo, constructionHistory=True) skin_cluster = copy_skin_influence(from_object, combined_geo) # Mirroring the skin cluster pm.copySkinWeights(ss=skin_cluster, ds=skin_cluster, mirrorMode='YZ', surfaceAssociation='closestPoint', influenceAssociation='closestJoint') # Final copy skin weights to target geo pm.copySkinWeights(combined_geo, to_object, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation='closestJoint') # Cleanup pm.delete(combined_geo) pm.delete(duplicate_pieces) pm.select(user_sel, r=True) print('Copying Complete!')
def SkinCopy(SEL): BaseMod = SEL[0] TargetMod = SEL[1] skinClst = BaseMod.listHistory(type='skinCluster') if skinClst: skinJnt = pm.skinCluster(skinClst[0], query=True, inf=True) skinMhod = pm.getAttr(skinClst[0] + ".skinningMethod") pm.select(TargetMod, skinJnt) pm.skinCluster(sm=skinMhod, tsb=True) pm.copySkinWeights(BaseMod, TargetMod, nm=True, sa="closestPoint", ia="oneToOne") else: pass pm.select(cl=True)
def transfertSkinCluster(): oOldSelection = pm.selected() _oSource = [oOldSelection[0]] _oTarget = oOldSelection[1:] oJoints = [] #Check if there a source mesh if len(_oSource) < 1: pm.displayWarning('You need to have a source mesh') elif len(_oTarget) < 1: pm.displayWarning('You need to have a target mesh') else: #Check if there a skinCluster on the mesh. And add joints of the skinCluster to the lists try: oJoints.extend(pm.skinCluster(_oSource, query=True, influence=True)) except: print "Exception: it doesn't appear to have a skinCluster." #Warnings : check if in the lists oJoints there's objects that are not joints oJointSkin = [] for o in oJoints: if pm.nodeType(o) == 'joint': oJointSkin.append(o) else: pm.warning( "removed the influence of {0} beacuse it's not a joint type object" .format(o)) #Getting skinCluster from the source mesh oSkinClusterSource = GetSkinCluster(_oSource[0]) #Skin the new mesh and copy weight from the source mesh for each in _oTarget: print each pm.select(clear=True) pm.select(oJointSkin) pm.select(each, add=True) oNewSkinCluster = pm.skinCluster(toSelectedBones=True) print 'Transfert DONE' pm.copySkinWeights(sourceSkin=oSkinClusterSource, destinationSkin=oNewSkinCluster, influenceAssociation='oneToOne', noMirror=True) print 'copy weight DONE' pm.select(oOldSelection)
def copy_skin_influence(from_obj, to_obj): """ Copy Joint influence and skin weights form one object ot another. :param PyNode from_obj: Object to copy weights from. :param PyNode to_obj: Object to copy weights to. :return: The created skin cluster :rtype: PyNode """ skinned_joints = pm.skinCluster(from_obj, query=True, influence=True) result_skin = pm.skinCluster(skinned_joints, to_obj) pm.copySkinWeights(from_obj, to_obj, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation='closestJoint') return result_skin
def skinCopy(sourceMesh=None, targetMesh=None, *args): if not sourceMesh or not targetMesh: if len(pm.selected()) >= 2: sourceMesh = pm.selected()[-1] targetMeshes = pm.selected()[:-1] else: pm.displayWarning("Please select target mesh/meshes and source " "mesh with skinCluster.") return else: targetMeshes = [targetMesh] # we check this here, because if not need to check when we work # base on selection. if isinstance(sourceMesh, basestring): sourceMesh = pm.PyNode(sourceMesh) for targetMesh in targetMeshes: if isinstance(targetMesh, basestring): sourceMesh = pm.PyNode(targetMesh) ss = getSkinCluster(sourceMesh) if ss: skinMethod = ss.skinningMethod.get() oDef = pm.skinCluster(sourceMesh, query=True, influence=True) # strip | from longName, or skinCluster command may fail. skinName = targetMesh.name().replace('|','') + "_SkinCluster" skinCluster = pm.skinCluster(oDef, targetMesh, tsb=True, nw=1, n=targetMesh.name() + "_SkinCluster") pm.copySkinWeights(sourceSkin=ss.stripNamespace(), destinationSkin=skinCluster.name(), noMirror=True, influenceAssociation="oneToOne", smooth=True, normalize=True) skinCluster.skinningMethod.set(skinMethod) else: errorMsg = "Source Mesh : {} doesn't have a skinCluster." pm.displayError(errorMsg.format(sourceMesh.name()))
def mirror_skinBinding(scene_objects): for each_object in scene_objects: current_tokens = each_object.split('_') if current_tokens[0] in ['FR', 'MR', 'BR', 'R']: mirror_inverse = True else: mirror_inverse = False skin_cluster = get_skinCluster(each_object) if skin_cluster: skin_joints = get_oposite(skin_cluster.influenceObjects()) oposite_object = get_oposite(each_object) if not get_skinCluster(oposite_object): destination_skin_cluster = pm.skinCluster(skin_joints, oposite_object, bindMethod=0, toSelectedBones=True) pm.copySkinWeights(ss=skin_cluster, ds=destination_skin_cluster, mirrorMode='YZ', influenceAssociation='oneToOne', mirrorInverse=mirror_inverse) destination_skin_cluster.skinningMethod.set(skin_cluster.skinningMethod.get()) else: print 'object %s not processed, already skin cluster attached' % oposite_object
def copySkinWeights_old( objs ): '''weightTransfer('skin_mesh', cmds.ls(sl=True) )''' skinDataObj = objs[0] targetObjs = [pm.PyNode( obj ) for obj in objs[1:]] sourceSkin = pm.mel.findRelatedSkinCluster( skinDataObj ) for i ,mesh in enumerate( targetObjs ): destinationSkin = pm.mel.findRelatedSkinCluster( mesh ) try: pm.copySkinWeights( ss=sourceSkin, ds=destinationSkin, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation=['closestJoint', 'closestBone', 'oneToOne'] ) print 'copySkinWeights (%d/%d): "%s" --> "%s"'%( i+1, len(targetObjs), skinDataObj, mesh ) except : print 'copySkinWeights Fail (%d/%d): "%s" --> "%s"'%( i+1, len(targetObjs), skinDataObj, mesh )
def copy_mirror_skin_binding(source, destination): """ :param source: the source object from where the skinning will be copied :param destination: :return: """ mirror_inverse = True print 'copying from {} to {}'.format(source, destination) skin_cluster = get_skinCluster(source) if skin_cluster: skinJoints = get_oposite(skin_cluster.influenceObjects()) oposite_object = destination if not get_skinCluster(oposite_object): destination_skinCluster = pm.skinCluster(skinJoints, oposite_object, bindMethod=0, toSelectedBones=True) pm.copySkinWeights(ss=skin_cluster, ds=destination_skinCluster, mirrorMode='YZ', influenceAssociation='oneToOne', mirrorInverse=mirror_inverse) destination_skinCluster.skinningMethod.set(skin_cluster.skinningMethod.get()) else: print 'object %s not processed, allready skin cluster attached' % oposite_object else: print'didnt find skinCluster in source object'
def transfer_skincluster(source_object, target_objects, prune_after=False): """Bind the target objects based on source object, then copied the skin data from source to target objects. If target object have skincluster, it will get replaced by new skincluster. :arg source_object: PyNode object transfer source. :type source_object: pm.PyNode :arg target_objects: PyNode objects transfer destination. :type target_objects: list of pm.PyNode :key prune_after: Do prune operation after transfer skincluster or not. :type prune_after: bool :rtype: None """ source_skin_node = get_skincluster_node(source_object) assert source_skin_node, 'Skincluster not found in source object.' skin_info = get_skincluster_info(source_skin_node) joint_list = skin_info['joint_list'] skin_method = skin_info['skin_method'] for tgt_obj in target_objects: old_tgt_skin_node = get_skincluster_node(tgt_obj) if old_tgt_skin_node: old_tgt_skin_node.unbind() try: tgt_skin_node = pm.skinCluster(joint_list, tgt_obj, skinMethod=skin_method) except: tgt_skin_node = pm.skinCluster(joint_list, tgt_obj) pm.copySkinWeights( sourceSkin=source_skin_node, destinationSkin=tgt_skin_node, noMirror=True, surfaceAssociation='closestPoint', influenceAssociation=['name', 'oneToOne', 'closestJoint'], ) remove_unused_influence(tgt_skin_node) if prune_after: prune_skincluster(tgt_skin_node)
def copySkin(cls, skin_from, skin_to): """ !@Brief Copy Skin with point of shape. CopySkin of maya doesn't really works with different shape. :type skin_from: pymel.core.nodetypes.Transform / shape / SkinCluster :param skin_from: Maya node reference for copy skin :type skin_to: pymel.core.nodetypes.Transform / shape / SkinCluster :param skin_to: Maya node to copy skin. :rtype: bool :return: True if copy skin is finish. """ # Get skin Cluster from_node = pmc.listHistory(skin_from, type="skinCluster")[0] to_node = pmc.listHistory(skin_to, type="skinCluster") # If to node is None add Skin cluster from from_node if not to_node: to_node = cls.skinFromOther(from_node, skin_to) else: to_node = to_node[0] # Check two skin in case cls.checkTwoSkin(from_node, to_node) # CopySkin pmc.copySkinWeights( node_utils.getPointName(skin_from), node_utils.getPointName(skin_to), sourceSkin=from_node.name(), destinationSkin=to_node.name(), noMirror=True, surfaceAssociation="closestComponent", influenceAssociation="oneToOne" )
def matchSkinning(): """Select a skin mesh, followed the mesh you wish to match skinning to.""" source, target = pm.ls(sl=1,type='transform') src_cluster = source.listHistory(type='skinCluster')[0] influences = src_cluster.influenceObjects() pm.select(influences, r=1 ) pm.select(target, add=1) pm.skinCluster(toSelectedBones=1, obeyMaxInfluences=src_cluster.getObeyMaxInfluences(), maximumInfluences=src_cluster.getMaximumInfluences(), dropoffRate=2, removeUnusedInfluence=False ) tgt_cluster = target.listHistory(type='skinCluster')[0] pm.copySkinWeights( ss=src_cluster, ds=tgt_cluster, noMirror=True ) pm.select(target, replace=1)
def transfer_deformer_weights(geo_source, geo_target=None, deformer_source=None, deformer_target=None, surface_association="closestPoint", interface=None): """ Copies the weight map of a deformer of an object to the deformer of another object. :param geo_source: Source Shape :param geo_target: Target Shape :param deformer_source: Source Deformer :param deformer_target: Target Deformer :param surface_association: Surface Association. Valid values: closestPoint, rayCast, or closestComponent. :param interface: Copy of class CopyDeformerWeightsUI """ assert geo_source and deformer_source and deformer_target, \ "select a source and target geometry and then the source and target deformers" previous_selection = pm.selected() if not geo_target: geo_target = geo_source if interface: interface.progress_bar_init() interface.progress_bar_next() source_weight_list = get_weight_list(deformer_source, geo_source) if not source_weight_list: pm.warning( "The deformer {} does not have the weight list for {}".format( deformer_source, geo_source)) if interface: interface.progress_bar_ends(message="Finished with errors!") return target_weight_list = get_weight_list(deformer_target, geo_target) if not target_weight_list: pm.warning( "The deformer {} does not have the weight list for {}".format( deformer_target, geo_target)) if interface: interface.progress_bar_ends(message="Finished with errors!") return initialize_weight_list(target_weight_list, geo_target) if interface: interface.progress_bar_next() tmp_source = pm.duplicate(geo_source)[0] tmp_target = pm.duplicate(geo_target)[0] pm.rename(tmp_source, tmp_source.nodeName() + "_cdw_DUP") pm.rename(tmp_target, tmp_target.nodeName() + "_cdw_DUP") tmp_source.v.set(True) tmp_target.v.set(True) if interface: interface.progress_bar_next() pm.select(clear=True) l_jnt = list() l_jnt.append(pm.joint(n="jnt_tmpA_01", p=[0, 0, 0])) l_jnt.append(pm.joint(n="jnt_tmpA_02", p=[0, 1, 0])) skin_source = pm.skinCluster(l_jnt, tmp_source, nw=1) skin_target = pm.skinCluster(l_jnt, tmp_target, nw=1) if interface: interface.progress_bar_next() skin_source.setNormalizeWeights(0) pm.skinPercent(skin_source, tmp_source, nrm=False, prw=100) skin_source.setNormalizeWeights(True) n_points = len(geo_source.getShape().getPoints()) if deformer_source.type() == "blendShape": [ skin_source.wl[i].w[0].set(source_weight_list.baseWeights[i].get()) for i in range(n_points) ] [ skin_source.wl[i].w[1].set(1.0 - source_weight_list.baseWeights[i].get()) for i in range(n_points) ] else: [ skin_source.wl[i].w[0].set(source_weight_list.weights[i].get()) for i in range(n_points) ] [ skin_source.wl[i].w[1].set(1.0 - source_weight_list.weights[i].get()) for i in range(n_points) ] if interface: interface.progress_bar_next() pm.copySkinWeights(ss=skin_source, ds=skin_target, nm=True, sa=surface_association) if interface: interface.progress_bar_next() tmp_shape = skin_target.getGeometry()[0] deformer_target_weights = [v for v in skin_target.getWeights(tmp_shape, 0)] [ target_weight_list.weights[i].set(val) for i, val in enumerate(deformer_target_weights) ] if interface: interface.progress_bar_next() pm.delete([tmp_source, tmp_target, l_jnt]) pm.select(previous_selection) if interface: interface.progress_bar_next() interface.progress_bar_ends(message="Finished successfully!")
def run(): # validate that we selected 1 skinned mesh and 1 non-skinned mesh sel = pm.ls(sl=True) if len(sel)!=2: raise Exception("copyWeightsToFurCards: select skin mesh, shift select fur cards. Aborted.") # src_mesh_trans = sel[0] src_mesh_shape = pm.listRelatives(src_mesh_trans, s=True)[0] if type(src_mesh_shape) != pm.nodetypes.Mesh: raise Exception("copyWeightsToFurCards: source object must be a skinned mesh.") # fur_trans = sel[1] fur_shape = pm.listRelatives(fur_trans, s=True)[0] if type(fur_shape) != pm.nodetypes.Mesh: raise Exception("copyWeightsToFurCards: target object must be a mesh.") # src_skincluster = getRelatedSkinCluster(src_mesh_trans) if type(src_skincluster) != pm.nodetypes.SkinCluster: raise Exception("copyWeightsToFurCards: source mesh must have a skinCluster deformer.") # fur_skincluster = getRelatedSkinCluster(fur_trans) if fur_skincluster != None: raise Exception("copyWeightsToFurCards: target mesh must not be skinned.") # bind the fur cards to the same influences as the source mesh src_influences = src_skincluster.getInfluence() pm.select(src_influences, r=True) pm.select(fur_trans, add=True) fur_skincluster = pm.skinCluster(tsb=True) # copy skin weights from source to fur cards pm.copySkinWeights( ss=str(src_skincluster), ds=str(fur_skincluster), noMirror=True, surfaceAssociation = "closestPoint", influenceAssociation = "oneToOne") # split mesh into list of vertex lists (1 per shell) vertex_shells = [] num_faces = pm.polyEvaluate(fur_trans,f=True) faces_checked = set(range(num_faces)) # gMainProgressBar = mel.eval('$tmp = $gMainProgressBar'); pm.progressBar( gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Gathering vertex shells...', maxValue=num_faces ) # while len(faces_checked)>0: #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=num_faces-len(faces_checked)) face = faces_checked.pop() shell_faces = pm.polySelect( fur_trans, extendToShell=face ) faces_checked = faces_checked.difference(shell_faces) face_vert_info = pm.polyInfo(faceToVertex=True) verts_in_shell = [] #pm.polyInfo returns horrible unicode format that must be parsed for face_verts_str in face_vert_info: verts_str = face_verts_str.split(":")[1] vert_strings = verts_str.split(" ") for v in vert_strings: try: v_id = int(v) verts_in_shell.append(v_id) except: pass vertex_shells.append(verts_in_shell) # now search for closest vertex in each shell... sel_list = OpenMaya.MSelectionList() sel_list.add(str(fur_shape)) nodeDagPath = sel_list.getDagPath(0) mfnMesh = OpenMaya.MFnMesh(nodeDagPath) space = OpenMaya.MSpace.kWorld pm.progressBar(gMainProgressBar, edit=True, step=0, status="Getting vertex positions...") verts = OpenMaya.MPointArray() verts = mfnMesh.getPoints(OpenMaya.MSpace.kWorld) pm.progressBar(gMainProgressBar, edit=True, status="Finding closest vertex per card...") pm.progressBar(gMainProgressBar, edit=True, step=0, maxValue=len(vertex_shells)) closest_vert_per_shell = [] for i,shell in enumerate(vertex_shells): #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=i) closest_dist = None closest_vert = None for vert_id in shell: point = verts[vert_id] closestPoint, faceIdx = mfnMesh.getClosestPoint(point, space) dist = closestPoint.distanceTo(point) if closest_dist==None: closest_dist = dist closest_vert = vert_id elif dist < closest_dist: closest_dist = dist closest_vert = vert_id closest_vert_per_shell.append(closest_vert) pm.progressBar(gMainProgressBar, edit=True, status="Apply weights for each card...") pm.progressBar(gMainProgressBar, edit=True, step=0, maxValue=len(vertex_shells)) # vtx_base = str(fur_trans)+".vtx[" for i,shell in enumerate(vertex_shells): #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=i) #get weight value of closest vertex c = closest_vert_per_shell[i] vtx = vtx_base+str(c)+"]" values = pm.skinPercent(fur_skincluster,vtx,q=1,v=1,ib=0.0001) transforms = pm.skinPercent(fur_skincluster,vtx,q=1,t=None,ib=0.0001) influences = [] for i in range(len(transforms)): influences.append((transforms[i],values[i])) #paste weight values on all other vertices in shell for v in shell: vtx = vtx_base+str(v)+"]" pm.skinPercent(fur_skincluster,vtx,tv=influences) pm.progressBar(gMainProgressBar, edit=True, endProgress=True)
def option_box_apply(self): pm.setParent(self.option_box) input_deformer = self.input_deformer_list.get_selected_deformer() input_shape, _ = self.input_shape_list.get_selected_shape() output_deformer = self.output_deformer_list.get_selected_deformer() output_shape, _ = self.output_shape_list.get_selected_shape() # Find the selected surface association mode, and map it to a copySkinWeights argument. surface_association = self.get_selected_surface_association_idx() surface_association_modes = { 1: 'closestPoint', 2: 'rayCast', 3: 'closestComponent', 4: 'uvSpace', } surface_association = surface_association_modes[surface_association] # Duplicate the input and output shapes. input_shape_copy = pm.duplicate(input_shape)[0].getShape() output_shape_copy = pm.duplicate(output_shape)[0].getShape() # Create a temporary joint, and skin both shapes to it. Disable weight normalization, # or weights will get forced to 1 since we only have one joint. temporary_joint = pm.createNode('joint') input_shape_skin = pm.skinCluster([input_shape_copy, temporary_joint], removeUnusedInfluence=False, normalizeWeights=False) output_shape_skin = pm.skinCluster([output_shape_copy, temporary_joint], removeUnusedInfluence=False, normalizeWeights=False) # Disable the skinClusters. We're using them to transfer data, and we don't want them # to influence the temporary meshes. input_shape_skin.attr('envelope').set(0) output_shape_skin.attr('envelope').set(0) try: # Figure out which attributes to copy where. attrs_to_map = self.get_selected_attrs() # Do the copy. for src_attr, dst_attr in attrs_to_map: if not maya_helpers.copy_weights_to_skincluster(src_attr, input_shape_skin, input_shape_copy): log.warning('Input has no deformer weights: %s', src_attr) continue copy_options = { 'sourceSkin': input_shape_skin, 'destinationSkin': output_shape_skin, 'noMirror': True, # Always use one-to-one joint association, since we're always copying the # two temporary joints. 'influenceAssociation': 'oneToOne', } # If we're in UV space mode, find a UV set to copy. Otherwise, set the association # mode. if surface_association == 'uvSpace': # Use the current UV set for each mesh. def get_current_uv_set(shape): uv_sets = pm.polyUVSet(shape, q=True, currentUVSet=True) if uv_sets: return uv_sets[0] else: return 'map1' input_shape_uv_set = get_current_uv_set(input_shape) output_shape_uv_set = get_current_uv_set(output_shape) copy_options['uvSpace'] = (input_shape_uv_set, output_shape_uv_set) else: copy_options['surfaceAssociation'] = surface_association pm.copySkinWeights(**copy_options) # Read the copied weights out of the skinCluster and copy them to the output attribute. copied_weights = list(output_shape_skin.getWeights(output_shape_copy, 0)) dst_weight_path = str(dst_attr) for index, value in enumerate(copied_weights): cmds.setAttr('%s[%i]' % (dst_weight_path, index), value) finally: # Clean up our temporary nodes. pm.delete(input_shape_copy.getTransform()) pm.delete(output_shape_copy.getTransform()) pm.delete(temporary_joint) log.info( 'Copied %i %s' % (len(attrs_to_map), 'map' if len(attrs_to_map) == 1 else 'maps'))