def vtxToSkinWeights(mesh, vertSphere, jnt, srcJnt, fallOffRate = 5): ''' will apply the provided value to the vtx on the supplied joint. ''' skCluster = returnSkinCluster(mesh) dist, wPosition = vSphereinfo(mesh, vertSphere) wtIncrement = 1. /float(fallOffRate) distIncrement = dist /float(fallOffRate) wtValue = 1 minDist = 0 maxDist = distIncrement for fo in range(int(fallOffRate)): vtxList = vtxFromPnt(mesh, minDist = minDist, maxDist = maxDist, pntCenter = wPosition, selectVtx = True) pm.select(cl = True) lkVerts = checkAddReturnAttr(mesh, vtxValue = [], attrName = 'lockedVtx', action = 'return') for vt in lkVerts: try: vtxList.remove(vt) except ValueError: pass pm.select(vtxList) pm.skinPercent(skCluster, tv = [jnt, wtValue]) #pm.skinCluster(skCluster, e = True, sw = .5) minDist = minDist + distIncrement maxDist = maxDist + distIncrement wtValue = wtValue - wtIncrement pm.select(cl = True)
def resetSkinInfluences(self): """ !@Brief Reset skin influences weights. """ self.setInfluences(self.INFLUENCES.values(), lock_value=False) points_shape = len(pmc.ls("%s.cp[*]" % self.SHAPE.name(), flatten=True)) progress_bar = ProgressBar(len(self.INFLUENCES.values()), "Reset Influences") influences = [] for idf, (key, value) in enumerate(self.INFLUENCES.items()): influences.append((value, 0.0)) progress_bar.update(idf) progress_bar.kill() component_type = 'vtx' if isinstance(self.SHAPE, (pmc.nodetypes.NurbsSurface, pmc.nodetypes.NurbsCurve)): component_type = 'cv' pmc.skinPercent( self.SKIN_NODE.name(), ('%s.%s[0:%s]' % (self.SHAPE, component_type, points_shape)), transformValue=influences )
def prune_influence(_vertex): mesh_transform = pm.PyNode(_vertex.split('.')[0]).getTransform() skin_cluster = pm.mel.eval('findRelatedSkinCluster {}'.format(str(mesh_transform))) influences_joints = pm.skinPercent(skin, _vertex, query = True, transform = None) value = pm.skinPercent(skin, _vertex, query = True, value = True) pm.skinPercent(skin_cluster, _vertex, pruneWeights = prune_value)
def shell_skin(self, geometry): shells_list = polygon_tools.shells(geometry) weights_dictionary = self.get_weights_dictionary() for each_shell in shells_list: average_influence_list = [] average_weight_list = [] for each_vertex in list(each_shell): vertex_influence_list = weights_dictionary['weights'][ each_vertex][0] weight_list = weights_dictionary['weights'][each_vertex][1] for index, each_influence in enumerate(vertex_influence_list): if each_influence not in average_influence_list: average_influence_list.append(each_influence) average_weight_list.append(0.0) average_weight_list[average_influence_list.index( each_influence)] += weight_list[index] average_weight_list = [ each / float(len(average_influence_list)) for each in average_weight_list ] for each_vertex in each_shell: weights_dictionary['weights'][each_vertex] = [ average_influence_list, average_weight_list ] self.apply_weights_dictionary(weights_dictionary) pm.skinPercent(self.node, normalize=True)
def set_joint_weight(self, value): selected_index = self.get_selected_index() joint_name = self.get_selected_item_in_list() temp3 = pm.ls(sl=1, type="joint") pm.select(temp3, d=1) sel_list = pm.ls(sl=1) pm.select(temp3, add=1) skin_cluster = self.get_skin_cluster(sel_list[0]) if not skin_cluster: # try to get it from the interface skin_cluster = self.get_skin_cluster_from_interface() if value: temp3 = pm.ls(sl=1, type="joint") joint_name = temp3[0] print("skin_cluster: %s" % skin_cluster) print("sel_list : %s" % sel_list) print("join_name : %s" % joint_name) print("value : %s" % value) pm.skinPercent(skin_cluster, sel_list, tv=[(joint_name, value)]) self.update_list() if value == 0: number_of_items = self.get_number_of_items() selected_index = selected_index if selected_index < number_of_items else number_of_items pm.textScrollList( self.influence_list_text_scroll_list, e=1, sii=selected_index )
def build_weights_association(self): """ Associates weights and influences in the skin cluster per vertex. Handy for saving out skin weights or transferring them to a different mesh with the same topology. :return weights_association: """ self.vertex_weights = dict() threshold = 0.001 for vtx in self.mesh.vtx: influence_name = pm.skinPercent(self.skin_cluster, vtx, transform=None, q=True, ib=threshold) influence_value = pm.skinPercent(self.skin_cluster, vtx, q=True, v=True, ib=threshold) # Encode unicode to str, so that we can export these values in the future vtx = str(vtx.name()) influence_name = to_str(influence_name) self.vertex_weights[vtx] = zip(influence_name, influence_value)
def get_vertex_info(sel): baseVerts = [] shape = pm.listRelatives(sel[0], p=True) baseObj = pm.listRelatives(shape, p=True) skC = str(sel[0].listHistory(type='skinCluster')[0]) baseCount = pm.polyEvaluate(baseObj, v=True) vtxInf = pm.skinPercent(skC, v, query=True, ib=0.0000001, t=None) vtxVal = pm.skinPercent(skC, v, query=True, ib=0.0000001, v=True) for vtx in sel: print vtx for v in vtx: print skC vtxNum = v.replace(str(shape) + '.vtx', '') print vtxNum '''Query vertex influence name''' '''Query vertex influence value''' all = (vtxNum, vtxInf, vtxVal) baseVerts.append(all) return baseVerts, baseObj, baseCount
def setWeightsAtIndex(self, index, weights, autoAddInfluence=True): ''' Returns the weight dict for the given index of the object (verts/cvs do not matter) Args: index (int): index of shape node component you want queried weights (list[list]): weights stored as: [[influence (string), weight (float)], w2...w(n)] autoAddInfluence (Boolean): detects whether influence wasn't added and auto-adds if not Returns: (dict): dictionary of {influence:weights} ''' # TODO: allow this to input dict weights since that's way easier to manipulate. # Error checking if 0 > index or index > len(self.weights) -1: pm.error('Index does not exist on skinCluster for given shape') weightTotal=0 for weight in weights: if not type(weight) == list: pm.error('Unsupported format for input weights, please read help') weightTotal+=weight[1] if weightTotal > 1: pass #this used to error check, but maya normalizes anyways. pm.warning('Your input weight values you surpassed 1, normalization will occur. Results may vary') component=None if self.shape.type() == 'nurbsCurve': component = self.shape.cv[index] if self.shape.type() == 'mesh': component = self.shape.vtx[index] if autoAddInfluence: for weight in weights: sourceInfluence = weight[0] if sourceInfluence not in self.influences: self.addInfluence(sourceInfluence) pm.skinPercent(self.skinCluster, component, transformValue=(weights)) self._update() return True
def __areaSkin(self,*args): geo = pm.ls(sl = 1)[0] skinCluster = mel.eval('findRelatedSkinCluster ' + geo) vertex = pm.polyEvaluate(geo,v = 1) joints = pm.skinCluster(skinCluster,q = 1,inf = 1) skinList = {} for num in range(0,vertex): vertex = geo + '.vtx[' + str(num) + ']' vertPos = pm.xform(vertex,q = 1,t = 1,ws = 1) tempDict = {} for joint in joints: jntPos = pm.xform(joint,q = 1,t = 1,ws = 1) dist = math.sqrt(pow(vertPos[0] - jntPos[0],2) + pow(vertPos[1] - jntPos[1],2) + pow(vertPos[2] - jntPos[2],2)) tempDict.setdefault(joint,dist) minDistVal = min(distVal for distVal in tempDict.values()) for joint in tempDict.keys(): if minDistVal == tempDict[joint]: if joint not in skinList: skinList[joint] = [] skinList[joint].append(vertex) for item in skinList.items(): joint = item[0] vertex = item[1] for vert in vertex: pm.skinPercent(skinCluster,vert,transformValue = (joint,1))
def remove_vertex_weight(baseVerts, target): targetSkc = funcs.get_skin_cluster(target) '''TURN OFF normalize skin weights''' targetSkc.normalizeWeights.set(0) print target for i in range(len(baseVerts)): targetVtx = str(target) + 'Shape.vtx' + str(baseVerts[i][0]) targetInf = pm.skinPercent(targetSkc, targetVtx, query=True, ib=0.0000001, t=None) '''Iterate through target vertex influences and sets them to zero.''' if targetInf is not None: for inf in range(len(targetInf)): pm.skinPercent(targetSkc, targetVtx, transformValue=[targetInf[inf], 0]) for inf in range(len(baseVerts[i][1])): pm.skinPercent( targetSkc, targetVtx, transformValue=[baseVerts[i][1][inf], baseVerts[i][2][inf]]) '''TURN ON normalize skin weights''' targetSkc.normalizeWeights.set(1)
def getVertexWeight(): ''' Category: Skinning Copy a vertex weight to another Select 2 vertices, will copy the weights from 1st selected to second ''' vtx = pm.ls(fl=1, os=1) print vtx if len(vtx) == 2: if vtx[0].__class__.__name__ == 'MeshVertex' and vtx[ 1].__class__.__name__ == 'MeshVertex': shape = vtx[0].node() skinCls = getSkinCluster(shape) influences = pm.skinPercent(skinCls, vtx[0].name(), query=True, transform=None) weights = pm.skinPercent(skinCls, vtx[0].name(), query=True, v=True) normWeights = [float(i) / sum(weights) for i in weights] tvList = [] for i in range(len(influences)): tvList.append((influences[i], normWeights[i])) pm.skinPercent(skinCls, vtx[1], transformValue=tvList)
def rig_curveBetweenTwoPoints(start,end, name='curveBetween' , degree=1, colour='white', parent='allModel_GRP'): startPos = pm.xform( start, translation=True, query=True, ws=True) endPos = pm.xform( end, translation=True, query=True, ws=True) pm.select(cl=True) startJnt = pm.joint(name=name+'Start_JNT') pm.pointConstraint( start, startJnt ) pm.select(cl=True) endJnt = pm.joint(name=name+'End_JNT') pm.pointConstraint( end, endJnt ) curve = pm.curve( n=name+'_CRV', d=degree, p=(startPos, endPos), k=(0,1) ) sc = pm.skinCluster( (startJnt, endJnt),curve , tsb=True, dr=1) pm.skinPercent( sc, curve.cv[0],tv=(startJnt, 1) ) pm.skinPercent( sc, curve.cv[1],tv=(endJnt, 1) ) col = name_to_rgb(colour) curve.overrideColorRGB.set(col[0], col[1], col[2]) topGrp = 'puppetLinearCurves_GRP' if not pm.objExists(topGrp): topGrp = rig_transform(0, name='puppetLinearCurves', type='group', parent=parent).object pm.parent(curve,startJnt,endJnt, topGrp) pm.setAttr(curve+".inheritsTransform", 0) pm.setAttr(curve+".template", 1) pm.hide( startJnt, endJnt ) return curve
def find_single_vertexInfluences(vtx, _formating = formating): """ Returns a dictionnary of the influences of a vertex """ _influenceDic = {} mesh_transform = pm.PyNode(vtx.split('.')[0]).getTransform() skin_cluster = pm.mel.eval('findRelatedSkinCluster {}'.format(str(mesh_transform))) influences_joints = pm.skinPercent(skin, vtx, query = True, transform = None) value = pm.skinPercent(skin, vtx, query = True, value = True) value_format = ['{:.8f}'.format(val) for val in value] if _formating == False: for influence, val in zip (influences_joints, value): _influenceDic[str(influence)] = val influenceDic = OrderedDict(sorted(_influenceDic.items(), key=lambda x: x[1], reverse=False)) elif _formating == True: for influence, val in zip (influences_joints, value_format): _influenceDic[str(influence)] = val influenceDic = OrderedDict(sorted(_influenceDic.items(), key=lambda x: x[1], reverse=False)) print '\n' print (vtx) for item in influenceDic.items(): print (' --- {}'.format(item)) print ('Number of influences : {}'.format(len(influenceDic)))
def test_copy_weights_vert_order_same_skeleton(self): source_cube, source_joints, source_skincluster = self.create_skinned_cube( ) target_cube = self.create_cube() target_skincluster = skinutils.bind_mesh_to_joints( target_cube, source_joints) transform_values = dict( itertools.zip_longest(source_joints[:4], [0.25], fillvalue=0.25)) transform_values[source_joints[-1]] = 0.0 pm.skinPercent(source_skincluster, source_cube.vtx[0], transformValue=transform_values.items()) source_weightedinfs = skinutils.get_weighted_influences( target_cube.vtx[0], target_skincluster) transform_values = dict( itertools.zip_longest(source_joints[1:], [0.25], fillvalue=0.25)) transform_values[source_joints[0]] = 0.0 pm.skinPercent(target_skincluster, target_cube.vtx[0], transformValue=transform_values.items()) target_weightedinfs = skinutils.get_weighted_influences( target_cube.vtx[0], target_skincluster) self.assertNotEqual(source_weightedinfs, target_weightedinfs) skinutils.copy_weights_vert_order_inf_order(source_cube, target_cube, source_skincluster, target_skincluster) expected = skinutils.get_weighted_influences(source_cube.vtx[0], source_skincluster) result = skinutils.get_weighted_influences(target_cube.vtx[0], target_skincluster) self.assertDictEqual(expected, result)
def influence_to_verts( selection, remove=True ): '''Takes the weights on the source object and matches them to all the transforms Args: selection [pm.PyNode]: selection, in pynodes Returns (None) Usage: influence_to_verts( pm.ls(sl=True), remove=False ) ''' selection = pm.ls( selection, fl=True ) verts = [ vertex for vertex in selection if type( vertex ) == pm.general.MeshVertex ] joints = [ joint for joint in selection if type( joint ) == pm.nt.Joint ] transform = verts[0].node().getParent() skinCluster = lib_skin.SkinCluster(transform=transform) #for vert in verts: for joint in joints: if joint in skinCluster.influences: value = 1.0 if remove: value = 0.0 pm.skinPercent( skinCluster.node, verts, nrm=True, transformValue=[(joint, 1.0)]) function = 'and replaced existing weights with influence' if remove: function = 'and removed existing related influence\'s weights' print '\nInfluences:\n%s\n\n%s.' % (function, '\t\n'.join([joint.name() for joint in joints])) return
def test_simple(self): source_cube = self.create_cube() target_cube = self.create_cube() source_joints = [self.create_joint() for _ in range(5)] [pm.move(j, (0.1, 0.1, 0.1)) for j in source_joints] source_skincl = skinutils.bind_mesh_to_joints(source_cube, source_joints) expected = [ pm.skinPercent(source_skincl, v, value=True, q=True) for v in source_cube.vtx ] pm.select(clear=True) target_joints = [self.create_joint() for _ in range(5)] [pm.move(j, (0.1, 0.1, 0.1)) for j in target_joints] target_skincl = skinutils.bind_mesh_to_joints(target_cube, target_joints) pm.skinPercent(target_skincl, target_cube.vtx, transformValue=(target_joints[-1], 1.0)) skinutils.copy_weights(source_cube, target_cube) result = [ pm.skinPercent(source_skincl, v, value=True, q=True) for v in source_cube.vtx ] for e, r in zip(expected, result): [ self.assertAlmostEqual(expected_weight, result_weight) for expected_weight, result_weight in zip(e, r) ]
def setWeightsAtIndex(self, index, weights, autoAddInfluence=True): """Returns the weight dict for the given index of the object (verts/cvs do not matter) Args: index (int): index of shape node component you want queried weights (list[list]): weights stored as: [[influence (string), weight (float)], w2...w(n)] Returns: (dict): dictionary of {influence:weights} """ # error checking if 0 > index or index > len(self.weights) - 1: pm.error("Index does not exist on skinCluster for given shape") weightTotal = 0 for weight in weights: if not type(weight) == list: pm.error("Unsupported format for input weights, please read help") weightTotal += weight[1] if weightTotal > 1: pass # this used to error check, but maya normalizes anyways. # pm.error('All your weights must be normalized to 1') pm.warning("Your input weight values you surpassed 1, normalization will occur. Results may vary") # meat component = None if self.shape.type() == "nurbsCurve": component = self.shape.cv[index] if self.shape.type() == "mesh": component = self.shape.vtx[index] if autoAddInfluence: for weight in weights: sourceInfluence = weight[0] if sourceInfluence not in self.influences: self.addInfluence(sourceInfluence) pm.skinPercent(self.skinCluster, component, transformValue=(weights)) self._update() return True
def make_joints_for_cards(cards=None, head_jnt=None, numCVs=5, w=2): """ Create a joint chain at the averaged position of each ring for the given hair cards. This joint chain can then be driven by FK controls which can themselves blend into riding along an nHair via motionPath. FOR NOW, JUST DO JOINTS << MAKE JOINTS DYNAMIC THOUGH. TO TEST HOW IT LOOKS. Maybe rotate since that goes better with FK controls which are probably better for hair. """ if not cards: cards = pmc.selected() if not head_jnt: head_jnt = cards.pop() # max influences = 1, to only head_jnt (not children) merged_cards = pmc.polyUnite(cards, muv=True)[0] sc = pmc.skinCluster(head_jnt, merged_cards, mi=1, tsb=True) j = head_jnt pmc.select(cl=True) for n in range(numCVs): # starting point is length step by width steps, step is total verts per card if n: pmc.skinCluster(sc, e=True, addInfluence=j, wt=0) verts = [ v for i in range(w) for v in merged_cards.vtx[n * w + i::numCVs * w] ] pmc.skinPercent(sc, verts, transformValue=(j, 1.0)) avg_pos = sum(v.getPosition() for v in verts) / len(verts) j = pmc.joint(p=avg_pos, n="hairCurve{:02d}_bind".format(n + 1)) j.radius.set(.05) # merging objects & skinclusters is be one easy step return merged_cards
def bindSpliceBetweenJoints(startJnt, endJnt, crv, startIndex, endIndex, targetCrv, skn, heightVec, intVec): ''' startJnt = upperBnds[0] endJnt = upperBnds[1] startIndex = upperBndTable[startJnt] endIndex = upperBndTable[endJnt] crv = drvCrv targetCrv = pm.PyNode('target_crv') ''' startHeight = lcrv.calcHeightFromCurve(startJnt, targetCrv, heightVec=heightVec, intVec=intVec) endHeight = lcrv.calcHeightFromCurve(endJnt, targetCrv, heightVec=heightVec, intVec=intVec) # figure out which splice to work on sectionBetween = crv.cv[min(startIndex, endIndex)+1:max(startIndex, endIndex)-1] sectionOutside = [cv for cv in crv.cv if cv not in sectionBetween and cv.index() not in (startIndex, endIndex)] # use the shorter section section = min((sectionBetween, sectionOutside), key=lambda sec: len(sec)) for eachCV in section: pos = eachCV.getPosition(space='world') height = lcrv.calcHeightFromCurve(pos, targetCrv) startSeg = height - startHeight endSeg = endHeight - height weight = startSeg / (startSeg + endSeg) pm.skinPercent(skn, eachCV, tv=((startJnt, 1-weight),(endJnt, weight)))
def test_normalizes_weights(self): source_cube = self.create_cube() target_cube = self.create_cube() test_joints = [self.create_joint() for _ in range(5)] skinutils.bind_mesh_to_joints(source_cube, test_joints) target_skincl = skinutils.bind_mesh_to_joints(target_cube, test_joints) target_skincl.setNormalizeWeights(False) pm.skinPercent(target_skincl, target_cube.vtx, transformValue=(test_joints[-1], 2.0)) weights = [ sum(pm.skinPercent(target_skincl, v, value=True, q=True)) for v in target_cube.vtx ] [self.assertLess(1.0, w) for w in weights] self.scene_nodes.append(skinutils.apply_delta_mush(source_cube)) target_skincl = skinutils.bake_deformer_to_skin(source_cube, target_cube, cleanup=True) # target_skincl.forceNormalizeWeights() weights = [ sum(pm.skinPercent(target_skincl, v, value=True, q=True)) for v in target_cube.vtx ] [self.assertGreaterEqual(1.0, w) for w in weights]
def test_two_skeletons(self): source_cube = self.create_cube() target_cube = self.create_cube() source_joints = [self.create_joint() for _ in range(5)] pm.select(clear=True) target_joints = [self.create_joint() for _ in range(5)] skinutils.bind_mesh_to_joints(source_cube, source_joints) target_skincl = skinutils.bind_mesh_to_joints(target_cube, target_joints) self.scene_nodes.append(skinutils.apply_delta_mush(source_cube)) pm.skinPercent(target_skincl, target_cube.vtx, transformValue=(target_joints[-1], 1.0)) previous_val = pm.skinPercent(target_skincl, target_cube.vtx[0], query=True, transform=target_joints[-1]) # pm.skinPercent(skincluster, vertex, transformValue=pruned_infs_to_weights.items()) target_skincl = skinutils.bake_deformer_to_skin( source_cube, target_cube, source_joints, target_joints) result = pm.skinPercent(target_skincl, target_cube.vtx[0], query=True, transform=target_joints[-1]) self.assertNotEqual(previous_val, result)
def prune_skin_weights(obj): skin_cluster = find_skin_cluster(obj) joint_list = pm.skinCluster(skin_cluster, q=True, inf=True) main_progress_bar = pm.mel.eval('$tmp = $gMainProgressBar') pm.progressBar(main_progress_bar, edit=True, beginProgress=True, isInterruptable=True, status='Pruning Skin Weights...', maxValue=obj.vtx.count()) for index in xrange(0, obj.vtx.count()): pm.progressBar(main_progress_bar, edit=True, step=1) vertex_index_string = obj.name() + ".vtx[{0}]".format(index) skin_values = pm.skinPercent(skin_cluster, vertex_index_string, q=True, value=True) for i in xrange(0, len(skin_values)): if skin_values[i] < 0.0001: pm.skinPercent(skin_cluster, vertex_index_string, normalize=False, transformValue=(joint_list[i], 0)) pm.progressBar(main_progress_bar, edit=True, endProgress=True)
def takeComponentWeight(self): components = pm.selected(fl=True) if len(components) != 1: pm.displayWarning('can only select one component') return component = components[0] if component.node().type() not in self.OBJ_TYPE: pm.displayWarning('wrong select, component needed') return node = component.node().getParent() skinClusterNodes = self.getSkinCluster(node=node) if skinClusterNodes: self.componentInfluenceList = pm.skinPercent( skinClusterNodes[0], component, ignoreBelow=self.IGNORE_VALUE, query=True, t=None) self.componentSkinWeightList = pm.skinPercent( skinClusterNodes[0], component, ignoreBelow=self.IGNORE_VALUE, query=True, v=True) else: pm.displayWarning('no skin')
def test_export_referenced_mesh(self): ref_cube, ref_joints, ref_skincluster = self.create_skinned_cube() ref_cube_name = ref_cube.nodeName() pm.skinPercent(ref_skincluster, ref_cube.vtx, transformValue=(ref_joints[2], 1.0)) with tempfile.TemporaryDirectory() as tempdir_name: # skin a cube and export it to a separate file ref_filename = os.path.join(tempdir_name, 'ref_test.ma') stuff = [ref_cube] + ref_joints pm.select(stuff, r=True) pm.exportSelected(ref_filename, type='mayaAscii', constructionHistory=True, force=True) # clean scene then reference in the file just exported self._clean_scene() file_reference = pm.createReference(ref_filename) ref_nodes = file_reference.nodes() ref_cube = [ r for r in ref_nodes if r.nodeName().endswith(ref_cube_name) ][0] # export the skin weights dest_filename = os.path.join(tempdir_name, 'test_weights.ma') skinio.export_skinned_mesh(ref_cube, dest_filename) # open the exported skin file pm.openFile(dest_filename, force=True) result_cube = skinutils.get_skinned_meshes_from_scene()[0] result_skincl = skinutils.get_skincluster(result_cube) result_joints = result_skincl.influenceObjects() result = skinutils.get_weighted_influences(result_cube.vtx[0]) expected = {result_joints[2]: 1.0} self.assertEqual(expected, result)
def apply_voxel_weighting(obj, voxel_data, max_iterations, min_distance): start_time = time.clock() main_progress_bar = pm.mel.eval('$tmp = $gMainProgressBar') pm.progressBar(main_progress_bar, edit=True, beginProgress=True, isInterruptable=True, status='Applying Skin Weights...', maxValue=obj.vtx.count()) voxel_size = voxel_data['voxel_size'] joint_list = [ pm.nt.Joint(obj.namespace() + x) for x in voxel_data['joint_list'] ] skin_cluster = find_skin_cluster(obj) if find_skin_cluster( obj) else pm.skinCluster([obj] + joint_list, toSelectedBones=True) for index in xrange(0, obj.vtx.count()): if pm.progressBar(main_progress_bar, query=True, isCancelled=True): break pm.progressBar(main_progress_bar, edit=True, step=1) vertex_index_string = obj.name() + ".vtx[{0}]".format(index) vert_ws_vector = v1_math.vector.Vector( pm.xform(vertex_index_string, q=True, ws=True, t=True)) voxel_vector, voxel_pos = v1_shared.skin_weight_utils.get_voxel_vector( vert_ws_vector, voxel_size) normal_vector = v1_math.vector.Vector( pm.polyNormalPerVertex(vertex_index_string, q=True, xyz=True, relative=True)[:3]) voxel_list = [voxel_vector] voxel_list = v1_shared.skin_weight_utils.get_initial_search_voxels( voxel_list, voxel_vector, voxel_pos, voxel_size, normal_vector) weight_entry = v1_shared.skin_weight_utils.find_matching_point_from_voxels( vert_ws_vector, voxel_list, voxel_data, max_iterations, min_distance) if weight_entry: weighted_joint_list = [ pm.nt.Joint(obj.namespace() + x) for x in weight_entry[2] ] pm.skinPercent(skin_cluster, vertex_index_string, normalize=False, transformValue=zip(weighted_joint_list, weight_entry[1])) pm.select(obj) pm.mel.removeUnusedInfluences() pm.progressBar(main_progress_bar, edit=True, endProgress=True) print time.clock() - start_time
def _create_tmp_skindata(self): test_cube, test_joints, test_skincluster = self.create_skinned_cube() pm.skinPercent(test_skincluster, test_cube.vtx, transformValue=(test_joints[2], 1.0)) self.skin_path = os.path.join(self.tmp_dir, 'test_skinning.ma') skinio.export_skinned_mesh(test_cube, self.skin_path) pm.delete(self.scene_nodes)
def set_joint_weight(self, joint, vertices, value): """sets joint weights to the given value :param joint: :param vertices: :param value: :return: """ pm.skinPercent(self.skin_cluster, vertices, tv=[(joint, value)])
def move_weights(skin_cluster, vertex, origin_inf, destination_inf): """Sets origin_inf weight to 0.0 and adds its original weight to destination_inf.""" infs_to_weights = get_weighted_influences(vertex, skin_cluster) initial_origin_weight = infs_to_weights.get(origin_inf, 0.0) initial_destination_weight = infs_to_weights.get(destination_inf, 0.0) destination_weight = initial_origin_weight + initial_destination_weight infs_to_weights[origin_inf] = 0.0 infs_to_weights[destination_inf] = destination_weight pm.skinPercent(skin_cluster, vertex, transformValue=infs_to_weights.items())
def create_skin(PDX_skin, mesh, skeleton, max_infs=None): if max_infs is None: max_infs = PDX_MAXSKININFS # create dictionary of skinning info per vertex skin_dict = dict() num_infs = PDX_skin.bones[0] for vtx in xrange(0, len(PDX_skin.ix) / max_infs): skin_dict[vtx] = dict(joints=[], weights=[]) # gather joint index and weighting that each vertex is skinned to for vtx, j in enumerate(xrange(0, len(PDX_skin.ix), max_infs)): skin_dict[vtx]['joints'] = PDX_skin.ix[j : j + num_infs] skin_dict[vtx]['weights'] = PDX_skin.w[j : j + num_infs] # select mesh and joints pmc.select(skeleton, mesh) # create skin cluster and then prune all default skin weights skin_cluster = pmc.skinCluster( bindMethod=0, skinMethod=0, normalizeWeights=0, maximumInfluences=num_infs, obeyMaxInfluences=True ) pmc.skinPercent(skin_cluster, mesh, normalize=False, pruneWeights=100) # API skin cluster function set skin_obj = get_MObject(skin_cluster.name()) mFn_SkinCluster = OpenMayaAnim.MFnSkinCluster(skin_obj) mesh_dag = get_MDagPath(mesh.name()) indices = OpenMaya.MIntArray() for vtx in xrange(len(skin_dict.keys())): indices.append(vtx) mFn_SingleIdxCo = OpenMaya.MFnSingleIndexedComponent() vertex_IdxCo = mFn_SingleIdxCo.create(OpenMaya.MFn.kMeshVertComponent) mFn_SingleIdxCo.addElements(indices) # must only add indices after running create() infs = OpenMaya.MIntArray() for j in xrange(len(skeleton)): infs.append(j) weights = OpenMaya.MDoubleArray() for vtx in xrange(len(skin_dict.keys())): jts = skin_dict[vtx]['joints'] wts = skin_dict[vtx]['weights'] for j in xrange(len(skeleton)): if j in jts: weights.append(wts[jts.index(j)]) else: weights.append(0.0) # set skin weights mFn_SkinCluster.setWeights(mesh_dag, vertex_IdxCo, infs, weights) # turn on skin weights normalization again pmc.setAttr('{}.normalizeWeights'.format(skin_cluster), 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 prune_skincluster(skin_node, prune_value=0.01): """Prune small weight influences on skincluster. :arg skin_node: PyNode skincluster need to prune. :type skin_node: pm.nt.SkinCluster :key prune_value: Determine small weight value to prune. :type prune_value: float :rtype: None """ pm.skinPercent(skin_node, pruneWeights=prune_value)
def setSkinWeights(skin, weights, prune=True): """ Set the exact weights for a skin. Args: skin (PyNode): A skin cluster node weights (list): A list of vertex weights, as given by `getSkinWeights` prune (bool): If true, remove influences that have no weights """ # make sure the weight data is equal in length to the indices, # or the current weight list of the skin cluster influences = getSkinInfluences(skin) infIdMap = dict([(v, k) for k, v in influences.items()]) infIdByNameMap = dict([(v.nodeName(), k) for k, v in influences.items()]) # keep track of missing influences missingInfluences = set() for vertIndex, vertWeights in weights: weightsPlug = skin.weightList[vertIndex].weights.__apiobject__() # keep track of original logical indices, set values to 0 on unused currentInfIds = api.MIntArray() weightsPlug.getExistingArrayAttributeIndices(currentInfIds) usedInfIds = [] for inf, weight in vertWeights: infId = infIdMap.get(inf, None) if infId is None: # try retrieving by name infId = infIdByNameMap.get(inf, None) if infId is None: missingInfluences.add(inf) continue weightsPlug.elementByLogicalIndex(infId).setFloat(weight) usedInfIds.append(infId) # assign 0 to unused existing plugs for i in range(currentInfIds.length()): infId = currentInfIds[i] if infId not in usedInfIds: weightsPlug.elementByLogicalIndex(infId).setFloat(0) if prune: pm.skinPercent(skin, skin.getGeometry(), nrm=False, prw=0) for inf in missingInfluences: meshes = skin.getGeometry() mesh = meshes[0] if meshes else None LOG.warning("Mesh {0} is missing influence: {1} ".format(mesh, inf)) return missingInfluences
def assignWeight(geo, wdata, skinc=None, jnt=None, pos=None): comp = "vtx" if geo.type() == "nurbsCurve": comp = "cv" mesh = None if pm.PyNode(geo).type() != "transform": mesh = geo geo = geo.getParent() #TODO: find center of wlist if not pos: pos = [0, 0, 0] if not jnt: print " Z" pm.select(cl=1) jnt = pm.joint(p=pos) jnt_grp = pm.group(jnt, em=1, n=str(jnt) + "_grp") jnt_grp.setTranslation(pos) jnt.setParent(jnt_grp) if not skinc: print " Y" skinc = getSkinc(geo) if not skinc: print " X" # insert base jnt pm.select(cl=1) basejnt = pm.joint(n=(str(geo) + "_baseJnt")) # check cons TODO: reconnect all constraint types ls_constrs = pm.parentConstraint(geo, q=1, n=1) if ls_constrs: transfer_constraint(geo, basejnt) skinc = pm.skinCluster(geo, basejnt) print " New skincluster: {0}".format(skinc) print "_:", geo, skinc # add infl pm.skinCluster(skinc, e=1, ai=jnt, lw=1, wt=0) print "_:", jnt ######### """ for v, w in vtxs_data1.items(): print "__:", v, w pm.skinPercent(snc, v, tv=[str(jnt), w]) """ for i, w in wdata.items(): #print "__:", i, w print i, w pm.skinPercent(skinc, geo.__getattr__(comp)[i], tv=[str(jnt), w]) return jnt
def loadWeights(weightsPath): files = [ f for f in os.listdir(weightsPath) if os.path.isfile(os.path.join(weightsPath, f)) and 'faceWeights.json' in f ] for f in files: mesh = None try: mesh = pmc.PyNode(f.split('_faceWeights.json')[0]) except: continue skin = getSkin(mesh) if not skin: print 'no skin cluster found on %s' % node.name() continue #pmc.setAttr('%s.maxInfluences' % skin, 4) pmc.setAttr('%s.maintainMaxInfluences' % skin, 0) pmc.setAttr('%s.weightDistribution' % skin, 1) # Get list of joints from weights file weights = None with open(os.path.join(weightsPath, f), 'r') as jsonFile: weights = json.load(jsonFile) # Make sure joints from weights file are added to skinCluster joints = None try: joints = [ pmc.PyNode(j) for j in weights['joints'] if not j == 'null_jnt' ] print joints except: raise RuntimeError( 'Some joints specified in the weights file not found in scene: %s' % weights['joints']) try: pmc.skinCluster(skin, ai=joints, lw=1, wt=0, e=1) except: print 'joints are already in %s: %s' % (skin, joints) # Apply weights for v in weights.keys(): if v == 'joints': continue keys = [key for key in weights[v].keys() if key != 'null_jnt'] values = [weights[v][key] for key in keys] pmc.skinPercent(skin, '%s.vtx[%s]' % (mesh, v), transformValue=list(zip(keys, values)))
def pasteVertexWeights( vert=None ): """Paste previously copied skin weights data to a single vertex.""" global copy_skin_cluster global copy_skin_weights if vert is None: vert = pm.ls(sl=1,type='float3')[0] assert isinstance(vert,pm.MeshVertex), "Requires vertex. (MeshVertex)" pm.skinPercent( copy_skin_cluster.name(), transformValue=copy_skin_weights )
def copyWeights(src_vtx, dest_vtx, dist=1): shape_mesh = pm.ls(src_vtx[0].name().split('.')[0])[0] skin_cluster = pm.listConnections(shape_mesh.name(), type = 'skinCluster')[0] pairs = createPairs(src_vtx, dest_vtx, dist) for v in src_vtx: src_val = pm.skinPercent(skin_cluster, v, q=1, v=1) src_inf = pm.skinPercent(skin_cluster, v, q=1, t=None) transform_value = zip(src_inf, src_val) pm.skinPercent(skin_cluster, pairs[v], tv=transform_value, )
def apply_index_weighting(obj, weight_data): start_time = time.clock() main_progress_bar = pm.mel.eval('$tmp = $gMainProgressBar') pm.progressBar(main_progress_bar, edit=True, beginProgress=True, isInterruptable=True, status='Applying Skin Weights...', maxValue=obj.vtx.count()) joint_lists = weight_data['joint_lists'].values() weight_cloud = weight_data['weight_cloud'] transform = obj.getParent() if type(obj) == pm.nt.Mesh else obj combined_joint_list = [] for joint_list in joint_lists: combined_joint_list = combined_joint_list + joint_list combined_joint_list = list(set(combined_joint_list)) combined_joint_list = [ pm.nt.Joint(obj.namespace() + x) for x in combined_joint_list ] skin_cluster = find_skin_cluster(obj) if find_skin_cluster( obj) else pm.skinCluster([obj] + combined_joint_list, toSelectedBones=True) for weight_entry in weight_cloud.itervalues(): if pm.progressBar(main_progress_bar, query=True, isCancelled=True): break entry_obj = pm.PyNode(obj.namespace() + weight_entry[1]) if transform == entry_obj: pm.progressBar(main_progress_bar, edit=True, step=1) weight_values = weight_entry[0] weighted_joint_list = [ pm.nt.Joint(obj.namespace() + x) for x in weight_data['joint_lists'][weight_entry[1]] ] index = weight_entry[2] pm.skinPercent(skin_cluster, obj.vtx[index], normalize=False, transformValue=zip(weighted_joint_list, weight_values)) pm.select(obj) pm.mel.removeUnusedInfluences() pm.progressBar(main_progress_bar, edit=True, endProgress=True) print time.clock() - start_time
def setIkWeights(self): # Set to post Normalisation self.ikSkin.normalizeWeights.set(2) for i in range(len(self.ikSkinWeightMap)): jointWeights = zip(self.ikSkinJoints, self.ikSkinWeightMap[i]) pm.skinPercent(self.ikSkin, self.ikDriveCurve.cv[i], transformValue=jointWeights, normalize=False) # Pruneweights # Set weight to post interactive weight pm.skinPercent(self.ikSkin, self.ikDriveCurve, pruneWeights=.075) # Normalise the weights self.ikSkin.forceNormalizeWeights() # Pruneweights self.ikSkin.normalizeWeights.set(1)
def mirror_crv_weights(map_tbl): src_cv, dest_cv = map_tbl.items()[0] pm.select(map_tbl.items()[0]) src_skn = pm.PyNode(mel.findRelatedSkinCluster(src_cv.node())) dest_skn = pm.PyNode(mel.findRelatedSkinCluster(dest_cv.node())) for src_cv, dest_cv in map_tbl.items(): infs = pm.skinCluster(src_skn, q=True, inf=True) dest_infs = [pm.PyNode(inf.name().replace("LT_", "RT_")) for inf in infs] weights = pm.skinPercent(src_skn, src_cv, q=True, v=True) weights_list = zip(dest_infs, weights) pm.skinPercent(dest_skn, dest_cv, tv=weights_list)
def build(): allCtrl = blocks.Ctrl(name='all_ctrl', shape=Ctrl.CIRCLE, radius=20, normal=[0,1,0], color=Ctrl.YELLOW, group=False).ctrl rootLoc = pm.PyNode('root_loc') rootJoint = utils.placeXform(name="m_root_%s" % defines.BIND, mtype='joint', matrix=rootLoc.getMatrix(worldSpace=True), worldSpace=True, parent=allCtrl) rootCtrl = InlineOffset( rootJoint, name='m_root_%s' % defines.CTRL, controlShape=Ctrl.CIRCLE, controlRadius=15, controlColor=Ctrl.YELLOW) # # Inner Tentacles # innerTentacles(allCtrl, rootCtrl) # # LOWER BELL # bell(allCtrl, rootCtrl) # # Outer Tentacles # outerTentacles(allCtrl) # # SKIN # skin.bind(skinDict) pm.PyNode(u'upperBellLatticeBase').setParent(rootCtrl.controls[0]) upperBellDefVerts = [MeshVertex(u'headDomeShapeDeformed.vtx[0:421]'), MeshVertex(u'headDomeShapeDeformed.vtx[426:431]'), MeshVertex(u'headDomeShapeDeformed.vtx[433:434]'), MeshVertex(u'headDomeShapeDeformed.vtx[436:437]'), MeshVertex(u'headDomeShapeDeformed.vtx[439:442]'), MeshVertex(u'headDomeShapeDeformed.vtx[444:445]'), MeshVertex(u'headDomeShapeDeformed.vtx[458:461]'), MeshVertex(u'headDomeShapeDeformed.vtx[474:477]'), MeshVertex(u'headDomeShapeDeformed.vtx[480:481]'), MeshVertex(u'headDomeShapeDeformed.vtx[483:486]'), MeshVertex(u'headDomeShapeDeformed.vtx[488:489]'), MeshVertex(u'headDomeShapeDeformed.vtx[491:492]'), MeshVertex(u'headDomeShapeDeformed.vtx[494:496]'), MeshVertex(u'headDomeShapeDeformed.vtx[498]'), MeshVertex(u'headDomeShapeDeformed.vtx[511:514]'), MeshVertex(u'headDomeShapeDeformed.vtx[524:526]'), MeshVertex(u'headDomeShapeDeformed.vtx[528:530]'), MeshVertex(u'headDomeShapeDeformed.vtx[532:535]'), MeshVertex(u'headDomeShapeDeformed.vtx[537:543]'), MeshVertex(u'headDomeShapeDeformed.vtx[545:547]'), MeshVertex(u'headDomeShapeDeformed.vtx[549:553]'), MeshVertex(u'headDomeShapeDeformed.vtx[555:559]'), MeshVertex(u'headDomeShapeDeformed.vtx[561:563]'), MeshVertex(u'headDomeShapeDeformed.vtx[585:595]'), MeshVertex(u'headDomeShapeDeformed.vtx[620:633]'), MeshVertex(u'headDomeShapeDeformed.vtx[636:638]'), MeshVertex(u'headDomeShapeDeformed.vtx[640:644]'), MeshVertex(u'headDomeShapeDeformed.vtx[646:650]'), MeshVertex(u'headDomeShapeDeformed.vtx[652:654]'), MeshVertex(u'headDomeShapeDeformed.vtx[656:660]'), MeshVertex(u'headDomeShapeDeformed.vtx[662:666]'), MeshVertex(u'headDomeShapeDeformed.vtx[668:669]'), MeshVertex(u'headDomeShapeDeformed.vtx[694:705]'), MeshVertex(u'headDomeShapeDeformed.vtx[727:750]'), MeshVertex(u'headDomeShapeDeformed.vtx[760:765]'), MeshVertex(u'headDomeShapeDeformed.vtx[778:801]'), MeshVertex(u'headDomeShapeDeformed.vtx[814:821]'), MeshVertex(u'headDomeShapeDeformed.vtx[834:873]'), MeshVertex(u'headDomeShapeDeformed.vtx[922:953]'), MeshVertex(u'headDomeShapeDeformed.vtx[1002:1105]'), MeshVertex(u'headDomeShapeDeformed.vtx[1154:1177]'), MeshVertex(u'headDomeShapeDeformed.vtx[1214:1296]'), MeshVertex(u'headDomeShapeDeformed.vtx[1339:1362]'), MeshVertex(u'headDomeShapeDeformed.vtx[1411:1414]'), MeshVertex(u'headDomeShapeDeformed.vtx[1417:1427]'), MeshVertex(u'headDomeShapeDeformed.vtx[1430:1441]'), MeshVertex(u'headDomeShapeDeformed.vtx[1444:1449]'), MeshVertex(u'headDomeShapeDeformed.vtx[1452:1463]'), MeshVertex(u'headDomeShapeDeformed.vtx[1466:1477]'), MeshVertex(u'headDomeShapeDeformed.vtx[1480:1485]'), MeshVertex(u'headDomeShapeDeformed.vtx[1490:1517]'), MeshVertex(u'headDomeShapeDeformed.vtx[1566:1587]'), MeshVertex(u'headDomeShapeDeformed.vtx[1630:1635]'), MeshVertex(u'headDomeShapeDeformed.vtx[1638:1649]'), MeshVertex(u'headDomeShapeDeformed.vtx[1652:1663]'), MeshVertex(u'headDomeShapeDeformed.vtx[1666:1671]'), MeshVertex(u'headDomeShapeDeformed.vtx[1674:1691]'), MeshVertex(u'headDomeShapeDeformed.vtx[1694:1701]'), MeshVertex(u'headDomeShapeDeformed.vtx[1704:1709]'), MeshVertex(u'headDomeShapeDeformed.vtx[1712:2583]'), MeshVertex(u'headDomeShapeDeformed.vtx[2632:2663]'), MeshVertex(u'headDomeShapeDeformed.vtx[2712:2823]'), MeshVertex(u'headDomeShapeDeformed.vtx[2872:2895]'), MeshVertex(u'headDomeShapeDeformed.vtx[2932:3361]')] pm.skinPercent('skinCluster84', upperBellDefVerts, transformValue = [(rootJoint,1.0)]) pm.reorderDeformers(u'upperBellLattice',u'skinCluster84', u'model:headDome') pm.reorderDeformers(u'upperBellLattice',u'skinCluster48', u'model:innerDome') # save skin dict utils.writeFile('rigPirateCaptain_skin.json',skinDict)
def remove_influence_from_verts(selection): """Takes the weights on the source object and matches them to all the transforms Args: selection [pm.PyNode]: selection, in pynodes Returns (None) Usage: remove_influence_from_verts( pm.ls(sl=True) ) """ selection = pm.ls(selection, fl=True) verts = [vertex for vertex in selection if type(vertex) == pm.general.MeshVertex] joints = [joint for joint in selection if type(joint) == pm.nt.Joint] transform = verts[0].node().getParent() skinCluster = lib_skin.SkinCluster(transform=transform) # for vert in verts: for joint in joints: if joint in skinCluster.influences: pm.skinPercent(skinCluster.node, verts, nrm=True, transformValue=[(joint, 0.0)]) print "\nInfluences:\n%s\n\nremoved from selected verts." % ("\t\n".join([joint.name() for joint in joints])) return
def copy_skinCluster_weight (src_mesh, dst_mesh): src_skin = get_skinCluster(src_mesh) dst_skin = get_skinCluster(dst_mesh) src_skinCls_matrix_dict = get_skinCluster_matrix(src_mesh) dst_skinCls_matrix_dict = get_skinCluster_matrix(dst_mesh) pm.skinCluster(dst_skin, e=True, normalizeWeights=False) for vertexID in xrange(dst_mesh.numVertices()): pm.skinPercent( dst_skin, "%s.vtx[%s]"%(dst_mesh, vertexID), pruneWeights=100) for src_joint, src_jointIndex in src_skinCls_matrix_dict.iteritems(): weight = pm.getAttr("%s.wl[%d].w[%d]" %(src_skin, vertexID, src_jointIndex)) if weight != 0.0: dst_jointIndex = dst_skinCls_matrix_dict[src_joint] pm.setAttr("%s.wl[%d].w[%d]" %(dst_skin, vertexID, dst_jointIndex), weight) pm.skinCluster(dst_skin, e=True, normalizeWeights=True)
def swap_influence_1(skinCl, vert, inflA, inflB): """For a given vertex, swaps the weight between two influences.""" valA = pmc.skinPercent(skinCl, vert, q=True, t=inflA) valB = pmc.skinPercent(skinCl, vert, q=True, t=inflB) with denormalized_skin(skinCl): pmc.skinPercent(skinCl, vert, tv=[inflA, valB]) pmc.skinPercent(skinCl, vert, tv=[inflB, valA])
def skinSrf(self): skinCls = pm.skinCluster( self.srf,self.jntList, tsb=1, ih=1, skinMethod = 0, maximumInfluences = 1, dropoffRate = 10.0 )[0] for i in range(self.numJnt): if i == 0: pm.skinPercent(skinCls.name(),self.srf.name() + '.cv[0:1][0:3]',tv=[(self.jntList[i],1)]) elif i > 0 and i < self.numJnt-1: pm.skinPercent(skinCls.name(),self.srf.name() + '.cv[' + str(i+1) + '][0:3]',tv=[(self.jntList[i],1)]) elif i == self.numJnt-1: pm.skinPercent(skinCls.name(),self.srf.name() + '.cv[' + str(i+1) + ':' + str(i+2) + '][0:3]',tv=[(self.jntList[i],1)])
def combine_meshes(self): x = 0 verts = [] self.joints = [] bound_objects = [] for bound_geo in self.bound_geo_instances: geo = bound_geo.get_bound_geo() joint = bound_geo.get_joint() vert = bound_geo.get_verts() bound_objects.append(geo) self.joints.append(joint) verts.append(vert) self.combined_object = pm.polyUnite(bound_objects, name= '%s_mesh' % (self.name), ch= False)[0] self.bind_geo() #pm.skinPercent( 'skinCluster1', vert, transformValue=['joint1', 1]) print verts, self.joints while x < len(verts): #self.number = None if x > 0: pm.skinPercent( '%s' % (self.skin_cluster), '%s.vtx[%s:%s]' % (self.combined_object, self.number, self.number+verts[x]), transformValue=['%s' % (self.joints[x]), 1]) self.number += verts[x] print verts[x], self.number if x == 0: pm.skinPercent( '%s' % (self.skin_cluster), '%s.vtx[0:%s]' % (self.combined_object, verts[x]), transformValue=['%s' % (self.joints[x]), 1]) self.number = verts[x] print self.number, 'first' x += 1 return self.combined_object
def rig_getSkinClusterInfluencedMostFace(mesh, skinCluster, influence, *args): '''Takes in a list of meshes to cut pieces that are influenced by influence object (joint) Args: mesh (list(pm.nt.Transform)): mesh to get faces from skinCluster (pm.nt.SkinCluster): skinCluster to query influence (pm.nt.Joint): figures out the faces influenced based on this one joint Returns: list (pm.nt.Transform): list of faces that are most influenced by an influence/joint Usage: rig_getSkinClusterInfluencedMostFace('pm.ls(sl=True)[0]', pm.PyNode('skinCluster1'), pm.PyNode('joint1') ) ''' selectFaces=[] influences = skinCluster.getWeightedInfluence() if influence in influences: infVerts = skinCluster.getPointsAffectedByInfluence(influence)[0] if not infVerts: pm.warning("Skipping %s %s no weight on object %s" % (skinCluster, influence, mesh.name())) else: faces = pm.ls(pm.polyListComponentConversion(infVerts, fv=True, tf=True), fl=True) for face in faces: infList = pm.skinPercent(skinCluster, face, t=None, q=True) infWeights = [] #TODO figure out the inf list setup for inf in infList: infWeights.append( pm.skinPercent(skinCluster, face, t=inf, q=True) ) maxWeight = 0.0 maxInf = '' for i, inf in enumerate(infList): if infWeights[i] > maxWeight: maxWeight = infWeights[i] maxInf = inf if maxInf == influence: selectFaces.append(face) else: pm.warning('%s is not an influence on %s' % (influence, skinCluster)) return pm.ls(selectFaces, fl=True)
def swap_influence_fast(skinCl, vert, inflA, inflB): """For a given vertex, swaps the weight between two influences. `skinCl` should be denormalized before calling this function. See `denormalized_skin`. """ valA = pmc.skinPercent(skinCl, vert, q=True, t=inflA) valB = pmc.skinPercent(skinCl, vert, q=True, t=inflB) pmc.skinPercent(skinCl, vert, tv=[inflA, valB]) pmc.skinPercent(skinCl, vert, tv=[inflB, valA])
def mesh_vert_pos_dict(mesh): """ Creates a dictionary of positions mapped to vertices from the mesh Args: mesh (str): transform's shape node mesh we're looking to scrape Returns (dict): dict of {(x,y,z): [vert index, most largest influence]} Usage: mesh_vert_pos_dict(cmds.listRelatives(cmds.ls(sl=True)[0], c=True, s=True)[0]) """ vert_dict = dict() skinCluster = cmds.listConnections(mesh, type='skinCluster')[0] for vertex in cmds.ls(mesh+'.vtx[:]', fl=True): vertex_pos = cmds.xform(vertex, q=True, ws=True, t=True) influences = cmds.skinPercent(skinCluster, vertex, q=True, t=None) influence_val, influence = max([[pm.skinPercent(skinCluster, vertex, v=True, t=inf, q=True), inf] for inf in influences]) vert_dict[','.join([str(pos) for pos in vertex_pos])] = [vertex, influence] return vert_dict
def load(self, *reList): if len(reList) != 0: self.jointList = [] for s in reList[0]: self.jointList.append(s) if self.shape.type() == 'mesh': for a in range(len(self.weightDic)): for t in range(len(self.weightDic['0'])): self.weightDic[x][t][0] = self.jointList[t] pm.skinPercent(self.skin, self.shape.vtx[a], tv = self.weightDic[x]) elif self.shape.type() == 'nurbsCurve': for a in range(len(self.weightDic)): for t in range(len(self.weightDic['0'])-1): self.weightDic[x][t][0] = self.jointList[t] pm.skinPercent(self.skin, self.shape.cv[a], tv = self.weightDic[x]) elif self.shape.type() == 'lattice': reData = [] for a in self.weightDic: reData.append(ast.literal_eval(a)) for y, x in enumerate(self.weightDic): for t in range(len(self.weightDic[x])): self.weightDic[x][t][0] = self.jointList[t] pm.skinPercent(self.skin, self.shape.pt[reData[y][0]][reData[y][1]][reData[y][2]], tv = self.weightDic[x])
def RigBendyLimb( **kwargs ): jnts = kwargs.setdefault( 'jnts' ) volume = kwargs.setdefault( 'volume' , False ) limbName = kwargs.setdefault( 'limbName', 'arm' ) side = kwargs.setdefault( 'side', 'L' ) numOfSegs = kwargs.setdefault( 'numOfSegs', 5 ) FKIKMode = kwargs.setdefault( 'FKIKMode', 'FKIK' ) bendyCtrl = kwargs.setdefault( 'bendyCtrl' ) isMirroredJoint = kwargs.setdefault( 'isMirroredJoint' , False ) if not ( jnts and bendyCtrl ): objects = pm.ls(sl=True) if not len( objects ) == 4 : pm.error('ehm_tools...rigBendyLimb: select 3 joint and a control curve') uparmJnt = objects[0] elbowJnt = objects[1] handJnt = objects[2] bendyCtrl = objects[3] else: uparmJnt = jnts[0] elbowJnt = jnts[1] handJnt = jnts[2] # if limb is not straight, make it so. necessary for for skinning bendy curves. if not FKIKMode == "IK" : tempElbowOri = elbowJnt.jointOrient.get() elbowJnt.jointOrient.set( 0,0,0 ) else : # find position for putting the ik so that arm gets straight tempHandIKLoc = pm.spaceLocator () pm.parent ( tempHandIKLoc , uparmJnt ) tempHandIKLoc.rotate.set(0,0,0) armLen = elbowJnt.translate.translateX.get() + handJnt.translate.translateX.get() tempHandIKLoc.translate.set( armLen ,0,0) tempHandIKPos = pm.xform ( tempHandIKLoc , q=True , ws=True , translation = True ) pm.parent (IKarmDistLocs[1], w=True) # straighten the arm for skinning IKarmDistLocs[1].translate.set( tempHandIKPos ) # create bendy joint uparmSegStuff = Segmentor( jnt = uparmJnt ,numOfSegs= numOfSegs ,volume= volume ,thicknessPlace= 'end' ,isMirroredJoint= isMirroredJoint ) elbowSegStuff = Segmentor( jnt = elbowJnt ,numOfSegs= numOfSegs ,volume= volume ,thicknessPlace= 'start' ,isMirroredJoint= isMirroredJoint ) # avoid shear on elbow seg joints pm.scaleConstraint( uparmJnt, elbowSegStuff[1][2].getParent() ) # create the uparm orientaion loc, point and aim constraint it so that it aims to hand joint uparmOriLoc = pm.spaceLocator () pm.pointConstraint( uparmJnt, uparmOriLoc ) pm.aimConstraint( handJnt, uparmOriLoc ) # create the elbow orientation loc, connect it to uparm ori loc and elbow joint elbowOriLoc = pm.spaceLocator () pm.pointConstraint( elbowJnt, elbowOriLoc ) pm.orientConstraint( uparmOriLoc, elbowOriLoc ) # move second and forth CVs of the bendy curves very close to where joints are. uparm_seg_crv = uparmSegStuff[1][2] elbow_seg_crv = elbowSegStuff[1][2] closeToUparm = FindPosBetween( percent=1, base=uparmJnt, tip=elbowJnt ) closeToElbow = FindPosBetween( percent=99, base=uparmJnt, tip=elbowJnt ) closeToElbowAfter = FindPosBetween( percent=1, base=elbowJnt, tip=handJnt ) closeToHand = FindPosBetween( percent=99, base=elbowJnt, tip=handJnt ) pm.xform( uparm_seg_crv.cv[1], ws=True, t=closeToUparm ) pm.xform( uparm_seg_crv.cv[3], ws=True, t=closeToElbow ) pm.xform( elbow_seg_crv.cv[1], ws=True, t=closeToElbowAfter ) pm.xform( elbow_seg_crv.cv[3], ws=True, t=closeToHand ) # create joints, sking to bendy curves and parent the middle one under elbow ori loc. bendyJnts_dict = { 'one':uparmJnt , 'two':elbowJnt , 'three':handJnt } for i in bendyJnts_dict.keys() : pm.select( clear=True ) tmp = pm.joint( name='%s_%s_bendy_%s_jnt' %( side, limbName, i ) ) tmp.setParent( bendyJnts_dict[i] ) tmp.translate.set(0,0,0) bendyJnts_dict[i] = tmp bendyJnts_dict['two'].setParent( elbowOriLoc ) # skin the seg_crvs and set the weights uparm_seg_crv_skinCluster = ( pm.skinCluster( uparm_seg_crv , bendyJnts_dict['one'] , bendyJnts_dict['two'] , toSelectedBones = True ) ) elbow_seg_crv_skinCluster = ( pm.skinCluster( elbow_seg_crv , bendyJnts_dict['two'] , bendyJnts_dict['three'] , toSelectedBones = True ) ) pm.skinPercent ( uparm_seg_crv_skinCluster , (uparm_seg_crv + ".cv[2:4]") , transformValue = ( bendyJnts_dict['two'], 1) ) pm.skinPercent ( elbow_seg_crv_skinCluster , (elbow_seg_crv + ".cv[0:2]") , transformValue = ( bendyJnts_dict['two'], 1) ) pm.skinPercent ( uparm_seg_crv_skinCluster , (uparm_seg_crv + ".cv[0:1]") , transformValue = ( bendyJnts_dict['two'], 0) ) pm.skinPercent ( elbow_seg_crv_skinCluster , (elbow_seg_crv + ".cv[3:4]") , transformValue = ( bendyJnts_dict['two'], 0) ) # setting the twist parameters for the segmenty joints # add bendy attribute to finger ctrl and connect it if not pm.attributeQuery( 'bendy', n=bendyCtrl, exists=True ): try: pm.addAttr( bendyCtrl, ln="bendy", at = 'double', min = 0, dv = 0 ) pm.setAttr( bendyCtrl.bendy, e=True, keyable=True ) except: pm.error( 'ehm_tools...rigBendyLimb: could not add bendy attr to %s'%bendyCtrl ) # slow down the bendy attribute by 10 times bendySlower_mdn = pm.createNode( 'multiplyDivide', name='%s_%s_bendySlower_mdn'%(side,limbName) ) bendyCtrl.bendy >> bendySlower_mdn.input1X bendySlower_mdn.input2X.set(0.1) bendySlower_mdn.outputX >> elbowOriLoc.scaleX # set the limb back to it's old position. if not FKIKMode == "IK" : elbowJnt.jointOrient.set( tempElbowOri ) else: pm.parent ( IKarmDistLocs[1] , handIKCtrl ) IKarmDistLocs[1].translate.set( 0,0,0 ) segStuffGrp = pm.group( uparmSegStuff[2], elbowSegStuff[2], name='%s_%s_bendyStuff_grp'%(side,limbName) ) pm.xform( os=True, piv=(0,0,0) ) # return return( uparmSegStuff, elbowSegStuff, segStuffGrp )
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 getweight(ind): return pmc.skinPercent(cl, plane.vtx[0], q=True, t=joints[ind])
def setEyelidLoopWeights(prefix, upperBnds=None, lowerBnds=None): # define data drvCrv = pm.PyNode(prefix+'_eye_aimAt_crv_0') if not upperBnds: upperBnds = [nt.Joint(prefix+'_inner_eyelid_bnd'), nt.Joint(prefix+'_innerUpper_eyelid_bnd'), nt.Joint(prefix+'_upper_eyelid_bnd'), nt.Joint(prefix+'_outerUpper_eyelid_bnd'), nt.Joint(prefix+'_outer_eyelid_bnd')] if not lowerBnds: lowerBnds = [nt.Joint(prefix+'_inner_eyelid_bnd'), nt.Joint(prefix+'_innerLower_eyelid_bnd'), nt.Joint(prefix+'_lower_eyelid_bnd'), nt.Joint(prefix+'_outerLower_eyelid_bnd'), nt.Joint(prefix+'_outer_eyelid_bnd')] cornerBnds = upperBnds[0], upperBnds[2], upperBnds[4], lowerBnds[2] ''' cornerPLocs = [pm.PyNode(bnd.replace('_bnd','_pLoc')) for bnd in cornerBnds] cornerCvIds = [pLoc.cv_id.get() for pLoc in cornerPLocs] print cornerCvIds ''' cornerCvIds = [lcrv.getClosestCVtoXfo(eachBnd, drvCrv).index() for eachBnd in cornerBnds] print cornerCvIds targetCrvs = getUpperLowerEyeCurves(drvCrv, cornerCvIds) setEyelidControlsWeights(prefix, upperBnds, lowerBnds, targetCrvs) # map bnds to CV index upperBndTable = {} for eachBnd in upperBnds: # get CV index closest to eachBnd cv = lcrv.getClosestCVtoXfo(eachBnd, drvCrv) upperBndTable[eachBnd] = cv.index() lowerBndTable = {} for eachBnd in lowerBnds: # get CV index closest to eachBnd cv = lcrv.getClosestCVtoXfo(eachBnd, drvCrv) lowerBndTable[eachBnd] = cv.index() # initial bind skn = pm.skinCluster(upperBnds+lowerBnds, drvCrv) # make sure each bnd has 100% weight to its closest cv for eachBnd in upperBnds: bindCV = upperBndTable[eachBnd] pm.skinPercent(skn, drvCrv.cv[bindCV], tv=(eachBnd, 1.0)) for eachBnd in lowerBnds: bindCV = lowerBndTable[eachBnd] pm.skinPercent(skn, drvCrv.cv[bindCV], tv=(eachBnd, 1.0)) # bind splices between each bind jnt # get vector from upper control heightVec = pm.dt.Vector(0,-1,0) * upperBnds[2].getMatrix(ws=True) intVec = pm.dt.Vector(0,0,-1) * upperBnds[2].getMatrix(ws=True) bindSpliceBetweenJoints(upperBnds[0], upperBnds[1], drvCrv, upperBndTable[upperBnds[0]], upperBndTable[upperBnds[1]], targetCrvs['lower'], skn, heightVec, intVec) bindSpliceBetweenJoints(upperBnds[1], upperBnds[2], drvCrv, upperBndTable[upperBnds[1]], upperBndTable[upperBnds[2]], targetCrvs['lower'], skn, heightVec, intVec) bindSpliceBetweenJoints(upperBnds[2], upperBnds[3], drvCrv, upperBndTable[upperBnds[2]], upperBndTable[upperBnds[3]], targetCrvs['lower'], skn, heightVec, intVec) bindSpliceBetweenJoints(upperBnds[3], upperBnds[4], drvCrv, upperBndTable[upperBnds[3]], upperBndTable[upperBnds[4]], targetCrvs['lower'], skn, heightVec, intVec) # get vector from lower control heightVec = pm.dt.Vector(0,-1,0) * lowerBnds[2].getMatrix(ws=True) intVec = pm.dt.Vector(0,0,-1) * lowerBnds[2].getMatrix(ws=True) bindSpliceBetweenJoints(lowerBnds[0], lowerBnds[1], drvCrv, lowerBndTable[lowerBnds[0]], lowerBndTable[lowerBnds[1]], targetCrvs['upper'], skn, heightVec, intVec) bindSpliceBetweenJoints(lowerBnds[1], lowerBnds[2], drvCrv, lowerBndTable[lowerBnds[1]], lowerBndTable[lowerBnds[2]], targetCrvs['upper'], skn, heightVec, intVec) bindSpliceBetweenJoints(lowerBnds[2], lowerBnds[3], drvCrv, lowerBndTable[lowerBnds[2]], lowerBndTable[lowerBnds[3]], targetCrvs['upper'], skn, heightVec, intVec) bindSpliceBetweenJoints(lowerBnds[3], lowerBnds[4], drvCrv, lowerBndTable[lowerBnds[3]], lowerBndTable[lowerBnds[4]], targetCrvs['upper'], skn, heightVec, intVec) pm.delete(targetCrvs.values())
def setWeight( *args, **kwargs ): ''' setWeight( componenets, influence, weightValue ) setWeight( mesh.vtx[0], mesh.vtx[1]..., 'joint1', 1.0 ) :version: 2014-10-28 : args만으로 처리 할 수 있도록 조정 :Sample Code: # ex1) 웨이트는 1.0 setWeight( mesh.vtx[0], mesh.vtx[1], mesh.vtx[2], 'joint1', 1.0 ) # ex2) 웨이트는 기본값으로 처리 setWeight( mesh.vtx[0], mesh.vtx[1], mesh.vtx[2], 'joint1') # ex3) 웨이트는 0.5 pm.select(mesh.vtx[0], mesh.vtx[1], mesh.vtx[2], 'joint1') setWeight(0.5) # ex4) 웨이트는 기본값으로 처리 pm.select(mesh.vtx[0], mesh.vtx[1], mesh.vtx[2], 'joint1') setWeight() ''' # # 웨이트부터 처리함, 인자 마지막값으로 정수나 실수가들어오면 웨이트 값으로 처리 # 그렇지 않으면 기본값 1로 처리함. weight = 1 if args: if isinstance(args[-1],int) or isinstance(args[-1],float): args = list(args) weight = float( args.pop(-1) ) # # 입력된 오브젝트가 있는지 확인 : 없음 종료 if args: pm.select( args ) sel = cmds.ls(sl=True, fl=True) if len(sel)<2: return # # 요소 분리 influences = cmds.ls(sel, type=['joint','transform'] ) if not influences: print u'influence 오브젝트 하나는 선택해주세요.' return for inf in influences: sel.remove(inf) components = sel # 해당 인플루언스가 스킨클러스터에 포함 안된경우 경우 추가 할건지? addInfluence = kwargs.get('addInfluence', False) print ' components :',components print ' influence :',influences print ' weight :',weight print 'addInfluence :',addInfluence for comp in components: # 상이한 지오메트리 콤포넌트를 선택한 경우 스킨클러스터가 각기 다름. # 콤포넌트의 지오메트리를 확인하고, 콤포넌트별 해당 스킨클러스터를 파악함. geo = comp.split('.')[0] skinCluster = pm.mel.findRelatedSkinCluster( geo ) if addInfluence: if influences not in pm.skinCluster( skinCluster, query=True, inf=True): # 콤포넌트마다 체크해야 해서 무거움. # # 인플루언스 추가 pm.skinCluster( skinCluster, e=True, lw=True, wt=0.0, addInfluence=influence ) print u'("%s") %s : "%s" 인플루언스 오브젝트 추가' %(skinCluster, geo, influence) #------------------------------ # # 웨이트값 변경 # #------------------------------ w = float(weight) / len(influences) tv = [] for influence in influences: tv.append((influence,w)) print '("%s") %s : %s '%(skinCluster, comp, tv) # pm.skinPercent( skinCluster, comp, tv=[(influence, w)] ) pm.skinPercent( skinCluster, comp, tv=tv )
def CopySkinPolyToNurbs( source=None , dest=None, searchTolerance=0.005 ): if source==None or dest==None : source, dest = pm.ls(sl=True) # find shapes and skin nodes sourceShape = source.getShape() sourceSkin = FindDeformers( sourceShape , 'skinCluster' ) if not sourceSkin: pm.error("source object doesn't have a skin deformer") sourceSkin = sourceSkin[0] destShape = dest.getShape() destSkin = FindDeformers( destShape , 'skinCluster' ) if not destSkin: pm.error("target object doesn't have a skin deformer") destSkin = destSkin[0] # find joints affection the skin sourceJnts = pm.skinCluster(sourceSkin, q=True, influence=True) destJnts = pm.skinCluster(destSkin, q=True, influence=True) if sourceJnts != destJnts: pm.error("SkinClusters must have the same joint.") Us = destShape.numCVsInU() Vs = destShape.numCVsInV() numVtxs= pm.polyEvaluate( sourceShape, v=True ) # unlock all joint for jnt in destJnts: jnt.liw.set(0) #=============================== pm.select(cl=True) for U in range(Us): for V in range(Vs): pm.select( destShape.cv[U][V], add=True ) pos = destShape.getCV( U, V, space='world' ) # find vertex by position pm.select( source.vtx[0:numVtxs-1]) pm.polySelectConstraint( mode=2, type=1, dist=1, distbound=(0,searchTolerance), distpoint=pos ) vtx = pm.ls(sl=True)[0] pm.polySelectConstraint( dist=0 ) # find wieghts from found vertex wtList = [] rawWts = pm.skinPercent( sourceSkin, vtx, q=True, value=True ) # find joints affection the vertex jntList = [] for i in range(len(rawWts)): if rawWts[i] > 0.0: jntList.append(sourceJnts[i]) wtList.append(rawWts[i]) # set weights to nurbs point opt = [] for j in range(len(jntList)): tmp= [] tmp.append( str(jntList[j]) ) tmp.append( wtList[j] ) opt.append( tmp ) pm.skinPercent( str(destSkin), destShape.cv[U][V] , transformValue=( opt ) )
def bendyLimb( self , *args ): print 'ehm_leg........................bendyLimb' #============================================================================ # duplicate main leg joints and rename bendy joints self.segMainJnts = pm.duplicate (self.upLegJnt ) # delete not joint nodes under the hierarchy if any extraShapes = pm.listRelatives (self.segMainJnts[0], ad=True ) for extraShape in extraShapes : if not pm.objectType(extraShape) == "joint": pm.delete(extraShape) self.segMainJnt = pm.ls (self.segMainJnts[0] )[0] self.segMainJnts = pm.listRelatives (self.segMainJnts[0], ad=True ) self.segMainJnts.append(self.segMainJnt) self.segMainJnts.reverse() #============================================================================ # create locators for positioning and orienting "curvy_midCtrl" # upLeg_rev_loc upLeg_rev_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( upLeg_rev_loc , self.upLegJnt ) pm.rename ( upLeg_rev_loc , self.side + "_upLeg_rev_loc" ) upLeg_rev_loc.translate.translateX.set ( self.dist + self.dist/20 ) upLeg_rev_loc.translate.translateY.set ( 0 ) upLeg_rev_loc.translate.translateZ.set ( (self.dist/200) ) upLeg_rev_loc.rotate.set (0,0,0) #============================================================================ # find the position of self.kneeJnt to create empty group for this loc # we can compensate the length of leg parts by scaling this group upLeg_rev_loc_grp = pm.group ( n = upLeg_rev_loc.name() + "_grp" ) pm.xform ( upLeg_rev_loc_grp , ws=True , piv = self.kneePos) # we need to make this locator scalable. if not, we won't be able to scale upLeg or knee seperately upLeg_rev_loc_mdn = pm.createNode ("multiplyDivide" , n = upLeg_rev_loc.name() + "_mdn" ) upLeg_rev_loc_mdn.operation.set ( 2 ) upLeg_rev_loc_mdn.input1X.set ( 1 ) self.upLegJnt.scaleX >> upLeg_rev_loc_mdn.input2X upLeg_rev_loc_mdn.outputX >> upLeg_rev_loc_grp.scaleX #============================================================================ # knee_rev_loc knee_rev_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( knee_rev_loc , self.kneeJnt ) pm.rename ( knee_rev_loc , self.side + "_knee_rev_loc" ) knee_rev_loc.translate.translateX.set (self.dist/-20) knee_rev_loc.translate.translateY.set ( 0 ) knee_rev_loc.translate.translateZ.set (self.dist/200) knee_rev_loc.rotate.set (0,0,0) pm.select(knee_rev_loc) knee_rev_loc_grp = pm.group ( n = knee_rev_loc.name() + "_grp" ) pm.xform ( knee_rev_loc_grp , ws=True , piv = self.kneePos ) # we need to make this locator scalable. if not, we won't be able to scale upLeg or knee seperately knee_rev_loc_mdn = pm.createNode ("multiplyDivide" , n = knee_rev_loc.name() + "_mdn") knee_rev_loc_mdn.operation.set ( 2 ) knee_rev_loc_mdn.input1X.set ( 1 ) self.kneeJnt.scaleX >> knee_rev_loc_mdn.input2X knee_rev_loc_mdn.outputX >> knee_rev_loc_grp.scaleX # L_knee_aim_loc #================ knee_aim_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( knee_aim_loc , self.kneeJnt ) pm.rename ( knee_aim_loc , self.side + "_knee_aim_loc" ) pm.pointConstraint( upLeg_rev_loc , knee_rev_loc , knee_aim_loc ) # creating the curvy_midCtrl_Parent for mid_joint position ( main purpose of this part ) self.midCtrlParent = pm.group ( em = True ) pm.pointConstraint( self.kneeJnt , self.midCtrlParent ) pm.aimConstraint ( knee_aim_loc, self.midCtrlParent , aimVector = (0,0,-1) , upVector = (-1,0,0) , worldUpType = "object" , worldUpObject = self.upLegJnt ) pm.rename ( self.midCtrlParent , self.side + "_curvy_midCtrl_Parent") #============================================================================ # finding the position for segMainJnts and creating them self.midJntPosition = 0.0 midJnt = self.segMainJnts[0] # create upLeg seg joints for i in ( range (self.legNumOfJnts-1) ) : midJntPosition = (self.kneeJnt.translate.translateX.get() / self.legNumOfJnts ) midJnt = pm.insertJoint ( midJnt ) pm.joint ( midJnt , e = True , relative = True , component = True , position = ( midJntPosition , 0 , 0 ) ) #============= # create knee seg joints # create an extra joint on knee in segmenty so that we could create two ikSplines for the whole leg midJnt = self.segMainJnts[1] midJntParent = midJnt.duplicate() pm.delete ( pm.listRelatives ( midJntParent , allDescendents = True) ) pm.parent ( midJnt , midJntParent) for i in ( range (self.legNumOfJnts-1) ) : midJntPosition = (self.ankleJnt.translate.translateX.get() / self.legNumOfJnts ) midJnt = pm.insertJoint ( midJnt ) pm.joint ( midJnt , e = True , relative = True , component = True , position = ( midJntPosition , 0 , 0 ) ) segJnts = pm.listRelatives ( self.segMainJnts[0] , allDescendents = True) segJnts.append ( self.segMainJnts[0] ) segJnts.reverse() pm.select (segJnts) segJnts = Renamer ( objs=segJnts, name=self.side+"_leg_seg_###_jnt" , hierarchyMode=False).newJnts # select skin joint tempSkinJnts = pm.ls ( segJnts [ 0 : self.legNumOfJnts ] , segJnts [ self.legNumOfJnts+1 : self.legNumOfJnts*2+1 ] ) # add skin jnt to skinJnts list for jnt in tempSkinJnts : self.skinJnts.append ( jnt ) # rename them pm.select ( tempSkinJnts ) SearchReplaceNames ( "_jnt", "_skinJnt", tempSkinJnts ) #============================================================================ # creating ik splines for segmenty joints pm.select ( segJnts[0] ) pm.select ( segJnts[self.legNumOfJnts] , add = True ) self.upLeg_seg_ik_stuff = pm.ikHandle ( sol = "ikSplineSolver" , parentCurve = False , ns = 2 ) self.upLeg_seg_ikh = pm.rename ( self.upLeg_seg_ik_stuff[0] , self.side + "_upLeg_seg_ikh" ) upLeg_seg_eff = pm.rename ( self.upLeg_seg_ik_stuff[1] , self.side + "_upLeg_seg_eff" ) upLeg_seg_crv = pm.rename ( self.upLeg_seg_ik_stuff[2] , self.side + "_upLeg_seg_crv" ) pm.select ( segJnts[self.legNumOfJnts+1] ) pm.select ( segJnts[self.legNumOfJnts*2+1] , add = True ) self.knee_seg_ik_stuff = pm.ikHandle ( sol = "ikSplineSolver" , parentCurve = False , ns = 2 ) knee_seg_ikh = pm.rename ( self.knee_seg_ik_stuff[0] , self.side + "_knee_seg_ikh" ) knee_seg_eff = pm.rename ( self.knee_seg_ik_stuff[1] , self.side + "_knee_seg_eff" ) knee_seg_crv = pm.rename ( self.knee_seg_ik_stuff[2] , self.side + "_knee_seg_crv" ) #============================================================================ # creating curvy_midCtrl_jnt curvy_midCtrl_jnt = pm.joint ( p = ( self.kneePos[0] , self.kneePos[1] ,self.kneePos[2] ) , name = ( self.side + "_curvy_midCtrl_jnt" ) ) # creating ctrl curve for curvy_midCtrl_jnt self.midCtrl = Circle8Crv ( self.legSize*1.2 , self.side+"_leg_toon_ctrl") pm.parent (self.midCtrl , self.midCtrlParent ) self.midCtrl.rotate.set (0,0,0) self.midCtrl.translate.set (0,0,0) pm.parent (curvy_midCtrl_jnt , self.midCtrl ) curvy_midCtrl_jnt.jointOrient.set (0,0,0) LockHideAttr ( objs=curvy_midCtrl_jnt , attrs="vv") LockHideAttr ( objs=self.midCtrl , attrs="sy") LockHideAttr ( objs=self.midCtrl , attrs="sz") LockHideAttr ( objs=self.midCtrl , attrs="v") #============================================================================ # skinning the seg_crvs #========== # before skinning we should make sure that leg is completely staright. # we temporarly parent segmenty ikCurve to joint pm.parent ( knee_seg_crv , self.kneeJnt ) if self.FKIKMode != "IK" : # tempKneeOri = pm.getAttr ( self.kneeJnt.jointOrient ) tempKneeOri = self.kneeJnt.jointOrient.get() self.kneeJnt.jointOrient.set(0,0,0) else : # find position for putting the ik so that leg gets straight tempAnkleIKLoc = pm.spaceLocator ( p = (0,0,0) ) pm.parent (tempAnkleIKLoc , self.upLegJnt ) tempAnkleIKLoc.rotate.set(0,0,0) legLen = ( self.kneeJnt.translate.translateX.get() + self.ankleJnt.translate.translateX.get() ) tempAnkleIKLoc.translate.set( legLen ,0,0) tempAnkleIKPos = pm.xform ( tempAnkleIKLoc , q=True , ws=True , translation = True ) pm.parent (self.IKlegDistLocs[1], w=True) # straighten the leg for skinning self.IKlegDistLocs[1].translate.set( tempAnkleIKPos ) #========== upLeg_seg_crv_skinCluster = ( pm.skinCluster( upLeg_seg_crv , self.upLegJnt , curvy_midCtrl_jnt , toSelectedBones = True ) ) knee_seg_crv_skinCluster = ( pm.skinCluster( knee_seg_crv , curvy_midCtrl_jnt , self.kneeJnt , toSelectedBones = True ) ) #========== pm.setAttr ( upLeg_seg_crv.tx , lock=False ) pm.setAttr ( upLeg_seg_crv.ty , lock=False ) pm.setAttr ( upLeg_seg_crv.tz , lock=False ) pm.setAttr ( upLeg_seg_crv.rx , lock=False ) pm.setAttr ( upLeg_seg_crv.ry , lock=False ) pm.setAttr ( upLeg_seg_crv.rz , lock=False ) pm.setAttr ( knee_seg_crv.tx , lock=False ) pm.setAttr ( knee_seg_crv.ty , lock=False ) pm.setAttr ( knee_seg_crv.tz , lock=False ) pm.setAttr ( knee_seg_crv.rx , lock=False ) pm.setAttr ( knee_seg_crv.ry , lock=False ) pm.setAttr ( knee_seg_crv.rz , lock=False ) pm.parent ( knee_seg_crv , w =True ) pm.setAttr ( upLeg_seg_crv.tx , lock=True ) pm.setAttr ( upLeg_seg_crv.ty , lock=True ) pm.setAttr ( upLeg_seg_crv.tz , lock=True ) pm.setAttr ( upLeg_seg_crv.rx , lock=True ) pm.setAttr ( upLeg_seg_crv.ry , lock=True ) pm.setAttr ( upLeg_seg_crv.rz , lock=True ) pm.setAttr ( knee_seg_crv.tx , lock=True ) pm.setAttr ( knee_seg_crv.ty , lock=True ) pm.setAttr ( knee_seg_crv.tz , lock=True ) pm.setAttr ( knee_seg_crv.rx , lock=True ) pm.setAttr ( knee_seg_crv.ry , lock=True ) pm.setAttr ( knee_seg_crv.rz , lock=True ) if self.FKIKMode != "IK" : self.kneeJnt.jointOrient.set ( tempKneeOri ) else: # now that we have skinned segmenty curves, we can put the leg to it's default pose pm.parent ( self.IKlegDistLocs[1] , self.ankleIKCtrl ) self.IKlegDistLocs[1].translate.set( 0,0,0 ) # setting the weights pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[3:4]") , transformValue = ( curvy_midCtrl_jnt, 1) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[0:1]") , transformValue = ( curvy_midCtrl_jnt, 1) ) pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[2]") , transformValue = ( curvy_midCtrl_jnt, 0.5) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[2]") , transformValue = ( curvy_midCtrl_jnt, 0.5) ) pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[1]") , transformValue = ( curvy_midCtrl_jnt, 0.1) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[3]") , transformValue = ( curvy_midCtrl_jnt, 0.1) ) #============================================================================ # making the joints stratchable MakeSplineStretchy ( ikCrv=upLeg_seg_crv , stretchSwitch=True , volume=False , thicknessPlace="end") upLeg_seg_crv.inheritsTransform.set ( 0 ) MakeSplineStretchy ( ikCrv=knee_seg_crv , stretchSwitch=True , volume=False ,thicknessPlace="start") knee_seg_crv.inheritsTransform.set ( 0 ) #============================================================================ # setting the twist parameters for the segmenty joints self.upLeg_seg_ikh.dTwistControlEnable.set ( 1 ) self.upLeg_seg_ikh.dWorldUpType.set ( 4 ) self.upLeg_seg_ikh.dWorldUpVectorX.set ( 1 ) self.upLeg_seg_ikh.dWorldUpVectorY.set ( 0 ) pm.connectAttr ( self.kneeJnt + ".worldMatrix[0]" , self.upLeg_seg_ikh + ".dWorldUpMatrixEnd" , f = True ) knee_seg_ikh.dTwistControlEnable.set ( 1 ) knee_seg_ikh.dWorldUpType.set ( 4 ) pm.connectAttr ( self.kneeJnt + ".worldMatrix[0]" , knee_seg_ikh + ".dWorldUpMatrix" , f = True ) pm.connectAttr ( self.ankleJnt + ".worldMatrix[0]" , knee_seg_ikh + ".dWorldUpMatrixEnd" , f = True )
def SkinToClust ( joints=None, sourceGeometry=None, finalGeometry=None ): #============================================================================ # user inputs if sourceGeometry==None or finalGeometry==None or joints==None: geoAndJnts = pm.ls(sl=True) sourceGeometry = geoAndJnts[ len (geoAndJnts) -2 ] finalGeometry = geoAndJnts[ len (geoAndJnts) -1 ] joints = geoAndJnts[:len (geoAndJnts) -2 ] #============================================================================ # find the skinCluster node on given objects skinClust = pm.ls ( pm.listHistory (sourceGeometry ) , type = "skinCluster" )[0] if skinClust == []: pm.error( "Source Object is not skinned." ) #============================================================================ # create a list per selected influence containing # all the vertices and their weights # find shape of sourceShape sourceShape = sourceGeometry.getShape() # find shape of finalShape finalShape = finalGeometry.getShape() # find the number of vertices of sourceGeometry numOfVtxs = pm.polyEvaluate(finalGeometry) ["vertex"] jnt = joints[0] for jnt in joints: # start progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" find " + str(jnt) + " weights:"), isInterruptable=True ) # create a dictionary containing all the values #================== tempDic = {} zeroVtxs = [] # create counter for amount for status present if numOfVtxs != 0: counter = 100.0 / numOfVtxs vtx = 1 for vtx in range(numOfVtxs): # get values from skinCluster tempVal = pm.skinPercent ( skinClust , sourceShape.vtx[vtx] ,q =True , value=True , transform = jnt ) # if the value is not 0 then add it to dictionary if not ( tempVal == 0 ): tempDic [vtx] = tempVal # else create a list containing 0 valued vertices else: zeroVtxs.append ( finalGeometry.vtx[vtx] ) # change progress window # pm.progressWindow ( edit=True, progress= int (amount), status=(" find " + str(jnt) + " weights:") ) # change amount for status present amount += counter # end progress window pm.progressWindow(endProgress=1) # create a cluster in the position of the joint #================== currentClustAndHandle = pm.cluster( finalShape , rel=True , n = (str(jnt)+"clust") ) currentClust = pm.ls( currentClustAndHandle[0] )[0] currentClustHandle = pm.ls( currentClustAndHandle[1] )[0] # change membership of cluster #================== # start progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" change " + str(jnt) + " membership:"), isInterruptable=True ) # create counter for amount for status present if len(zeroVtxs) != 0: counter = 100.0 / len(zeroVtxs) pm.sets ( currentClust+"Set" , rm = zeroVtxs ) # end progress window pm.progressWindow(endProgress=1) # positioning the clusters #================== # get position from current joint clustPos = pm.xform (jnt , q =True , ws=True , t=True ) # set cluster origin values currentClustHandle.origin.set( clustPos ) # center pivot of cluster pm.xform( currentClustHandle , centerPivots=True) # start progress window #==================== # create a new progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" apply " + str(jnt) + " weights:") , isInterruptable=True ) # create counter for amount for status present if len(tempDic) != 0: counter = 100.0 / len(tempDic) # get the values from dictionary we've created and use them as cluster weights #================== for vtx in tempDic: # applying values pm.percent ( currentClust , finalShape.vtx[vtx] , v = tempDic [vtx] ) # change progress window #pm.progressWindow ( edit=True, progress= int (amount), status=(" apply " + str(jnt) + " weights:") ) # change amount for status present amount += counter # end progress window pm.progressWindow(endProgress=1)
def normalize(skinNode, geoms, methode=0, keepBonesLocked=False): """normalize""" # get atom if possible geoms = various.getAtoms(geoms) # get influence list joints = skinNode.influenceObjects() # get which bones is not locked a = [] for i in range(len(joints)): if (keepBonesLocked==False) or (joints[i].liw.get()==False): a.append(i) # loop on goemetry for geom in geoms: # loop again to get a single object no [x:x] for geo in geom: # the length will be the total of each influence length = 0 lengthLock = 0 data = [] # loop for each bones for i in range(len(joints)): wts = skinNode.getWeights(geo, i) for wt in wts: if keepBonesLocked: if joints[i].liw.get(): lengthLock += wt else: length += wt else: length += wt data.append(wt) print length print lengthLock # if lenght is not equal 1.0 we aren't normalize if (length+lengthLock) != 1.0: skinPerc = [] # check if not everything is locked if len(a) == len(data): keepBonesLocked = False # more complexe methode when some bones has to be kept as they are if keepBonesLocked: # we check if the length of the locked bones is less than 1.0 if lengthLock < 1.0: # check if length is not equal at zero if length: # multiply each influence by the invert length length = (1-lengthLock) / length if methode == 0: for i in range(0, len(a)): skinPerc.append( (joints[a[i]], data[a[i]]*length) ) else: for i in range(0, len(a)): data[i] = data[a[i]]*length else: add = (1-lengthLock) / len(a) if methode == 0: for i in range(0, len(a)): skinPerc.append( (joints[a[i]], data[a[i]]+add) ) else: for i in range(0, len(a)): data[i] = data[a[i]]+add # otherwise we just keep other weight at 0 else : if methode == 0: for i in range(0, len(a)): skinPerc.append( (joints[i], 0) ) else: for i in range(0, len(a)): data[i] = 0 # simple one else : if methode == 0: for i in range(0, len(a)): skinPerc.append( (joints[i], data[i]/length) ) else: for i in range(0, len(a)): data[i] = data[i]/length # keeping and changing the normalization weights previousNormalize = skinNode.normalizeWeights.get() skinNode.normalizeWeights.set(0) # set with the right data if methode == 0: pmc.skinPercent( skinNode, geo, transformValue=skinPerc) else: skinNode.setWeights(geo, a, data, normalize=False) # changing the normalization weights from previous data skinNode.normalizeWeights.set(previousNormalize)
def __ikJj(self): self.ikJj = [] #create IKRibbonSpine #ribbon spine info: curveInfo = [0,(self.segment - 1) / 4,(self.segment - 1) / 2, ((self.segment - 1) / 2 + (self.segment - 1)) / 2, (self.segment - 1)] ribbonCurve = [] self.folList = [] #create curve for jjInfo in curveInfo: ribonJjPos = self.spineFkBlendChain.chain[jjInfo].getTranslation(space = 'world') ribbonCurve.append(ribonJjPos) #set ribbon offset offset = float(self.length * 0.05) #set ribbon cur ribbonCurveL = pm.curve(d = 3,p = [ribbonCurve[0],ribbonCurve[1],ribbonCurve[2],ribbonCurve[3],ribbonCurve[4]], k = [0,0,0,1,2,2,2],n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbonL','gud')) pm.move(offset,0,0,ribbonCurveL) ribbonCurveR = pm.curve(d = 3,p = [ribbonCurve[0],ribbonCurve[1],ribbonCurve[2],ribbonCurve[3],ribbonCurve[4]], k = [0,0,0,1,2,2,2],n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbonR','gud')) pm.move(-offset,0,0,ribbonCurveR) ribbonCurveR.setParent(self.guideGrp) ribbonCurveL.setParent(self.guideGrp) #create ribbon surf ribbonGeo = pm.loft(ribbonCurveR,ribbonCurveL,ch = 0,u = 1,c = 0,ar = 1,d = 3,ss = 1, rn = 0,po = 0,rsn = 1, n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbon','surf')) ribbonClusList = [] self.ribbonJc = [] self.spineCc = [] #get loc pos for num,loc in enumerate(self.fkGuides): startLoc = self.fkGuides[0] midLoc = self.fkGuides[(len(self.fkGuides) - 1) / 2] endLoc = self.fkGuides[-1] startLocPos = pm.xform(startLoc,ws = 1,t = 1,q = 1)[1] midLocPos = pm.xform(midLoc,ws = 1,t = 1,q = 1)[1] endLocPos = pm.xform(endLoc,ws = 1,t = 1,q = 1)[1] #get Jc pos for num in [0,2,4]: pos = pm.select(ribbonGeo[0] + '.cv[' + str(num) + '][0:3]',r = 1) clus = pm.cluster() pm.rename(clus[1],nameUtils.getUniqueName(self.side,self.baseName + '_ribbon','cls')) ribbonClusList.append(clus) pm.select(cl = 1) #set cvpos for vert in [1,3]: for row in range(0,4): cvNum = pm.select(ribbonGeo[0] + '.cv[' + str(vert) + '][' + str(row) + ']',r = 1) oriPos = pm.xform(cvNum,ws = 1,t = 1,q = 1) if vert == 1: pm.xform(cvNum,ws = 1,t = (oriPos[0],(startLocPos + midLocPos) / 2,oriPos[2])) elif vert == 3: pm.xform(cvNum,ws = 1,t = (oriPos[0],(endLocPos + midLocPos) / 2,oriPos[2])) #set Jc and Jc ctrl for num,x in enumerate(ribbonClusList): jc = pm.joint(p = x[1].getRotatePivot(), n = nameUtils.getUniqueName(self.side,self.baseName + self.nameList[num],'jc'), radius = self.length / 3) self.ribbonJc.append(jc) pm.select(cl = 1) pm.delete(ribbonClusList[num]) pm.select(cl = 1) cc = control.Control(self.side,self.baseName + self.nameList[num],size = self.ikSize,aimAxis = self.ctrlAxis) cc.circleCtrl() pm.makeIdentity(cc.control,apply = True,t=0,r=1,s=0,n=0,pn=1) # self.bodyCtrl.control.ik_vis.connect(cc.controlGrp.v) self.bodyCtrl.control.ik_vis.connect(cc.control.getShape().v) self.spineCc.append(cc.control) control.lockAndHideAttr(cc.control,['sx','sy','sz','v']) pm.xform(cc.controlGrp,ws = 1,matrix = jc.worldMatrix.get()) #skin Jc for num,jc in enumerate(self.ribbonJc): jc.setParent(self.spineCc[num]) ribbonSkin = pm.skinCluster(self.ribbonJc[0],self.ribbonJc[1],self.ribbonJc[2],ribbonGeo[0], tsb = 1,ih = 1,mi = 3,dr = 4,rui = 1,n = nameUtils.getSkinName()) #skin pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[0][0:3]', transformValue=[(self.ribbonJc[0],1)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[1][0:3]', transformValue=[(self.ribbonJc[1],0.5),(self.ribbonJc[0],0.5)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[2][0:3]', transformValue=[(self.ribbonJc[1],1)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[3][0:3]', transformValue=[(self.ribbonJc[1],0.5),(self.ribbonJc[2],0.5)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[4][0:3]', transformValue=[(self.ribbonJc[2],1)]) #set fol #create / rename fol self.folGrp = pm.group(em = 1,n = nameUtils.getUniqueName(self.side,self.baseName + 'Fol','grp')) for fol in range(0,self.segment): #createNodeName follicleTransName = nameUtils.getUniqueName(self.side,self.baseName,'fol') follicleShapeName = nameUtils.getUniqueName(self.side,self.baseName,'folShape') #createNode follicleShape = pm.createNode('follicle',n = follicleShapeName) follicleTrans = pm.listRelatives(follicleShape, parent=True)[0] follicleTrans = pm.rename(follicleTrans, follicleTransName) # connect the surface to the follicle if ribbonGeo[0].getShape().nodeType() == 'nurbsSurface': pm.connectAttr((ribbonGeo[0] + '.local'), (follicleShape + '.inputSurface')) #Connect the worldMatrix of the surface into the follicleShape pm.connectAttr((ribbonGeo[0].getShape() + '.worldMatrix[0]'), (follicleShape + '.inputWorldMatrix')) #Connect the follicleShape to it's transform pm.connectAttr((follicleShape + '.outRotate'), (follicleTrans + '.rotate')) pm.connectAttr((follicleShape + '.outTranslate'), (follicleTrans + '.translate')) #Set the uValue and vValue for the current follicle pm.setAttr((follicleShape + '.parameterV'), 0.5) pm.setAttr((follicleShape + '.parameterU'), float(1.0 / float(self.segment - 1)) * fol) #Lock the translate/rotate of the follicle pm.setAttr((follicleTrans + '.translate'), lock=True) pm.setAttr((follicleTrans + '.rotate'), lock=True) pm.setAttr((follicleShape + '.degree'),1) #parent self.folList.append(follicleTrans) follicleTrans.setParent(self.folGrp) #rebuild fol pos self.spineIkBlendJoint = [] self.stretchCube = [] for num,fol in enumerate(self.folList): jj = pm.joint(p = (0,0,0),n = nameUtils.getUniqueName(self.side,self.baseName,'jj'), radius = self.length / 5) self.spineIkBlendJoint.append(jj) jj.setParent(fol) tempCube = pm.polyCube(ch = 1,o = 1,w = float(self.length / 5),h = float(self.length / 10), d = float(self.length / 5),cuv = 4,n = nameUtils.getUniqueName(self.side,self.baseName,'cube')) tempCube[0].setParent(jj) tempCube[0].v.set(0) self.stretchCube.append(tempCube[0]) jj.translateX.set(0) jj.translateY.set(0) jj.translateZ.set(0) self.ikJj.append(jj) #create spine grp self.spineIkGrp = pm.group(self.spineCc[0].getParent(),self.spineCc[1].getParent(),self.spineCc[2].getParent(),self.folGrp,ribbonGeo[0], n = nameUtils.getUniqueName(self.side,self.baseName + 'Ik','grp')) ribbonGeo[0].inheritsTransform.set(0) self.folGrp.inheritsTransform.set(0) #clean self.spineIkGrp.setParent(self.bodyCtrl.control) #temp self.spineIkGrp.v.set(1) '''put chest ctrl under chest cc''' '''put leg under hip cc'''
def loadSkinning(path): with open(path, 'rb') as handle: fileData = pickle.load(handle) for msh, dataDict in fileData.iteritems(): mshAndJnts = dataDict.keys() mshAndJnts.append(msh) skinCls = findSkinCluster(msh) if skinCls: for eachJnt in mshAndJnts: pm.skinCluster(skinCls, edit=True, ai=eachJnt, lw=True) else: skinCls = pm.skinCluster(mshAndJnts, tsb=True, tst=False) skinCls.setNormalizeWeights(0) pm.skinPercent(skinCls, msh, nrm=False, prw=100) jointDict = {} for storedJoint in dataDict: try: jnt = pm.PyNode(storedJoint) except pm.MayaNodeError: logger.debug('nao achou jnt: %s' % jnt) jointDict[storedJoint] = skinCls.indexForInfluenceObject(jnt) for infl in dataDict: for vtx in dataDict[infl]: pm.setAttr( skinCls.name() + '.weightList[' + str(vtx[0]) + '].weights[' + str(jointDict[infl]) + ']', vtx[1]) skinCls.setNormalizeWeights(1) logger.debug('skin loading ok!')