import pymel.core as pm import json import maya.cmds as cmds import math selection = pm.selected()[0] class PointCloud(object): def __init__(self): self.points = {} self.joints = {} def info(self): for point, value in self.points.iteritems(): print point, value def save(self, filename): with open(filename, 'w') as f: json.dump(self.points, f, indent=4) with open(filename+'j', 'w') as f: json.dump(self.joints, f, indent=4) def load(self, filename): with open(filename) as pcfile: self.points = json.load(pcfile) with open(filename+'j') as pcfile: self.joints = json.load(pcfile) def find_joint_members(self, joint): joint = str(joint) bound_verts = [] for index, attributes in self.points.iteritems(): #print attributes['joints'][joint] if joint in attributes['joints']: #print joint, attributes['joints'][joint] pos = attributes['position'] bound_verts.append(self.find_nearest_points(pos, selection)[0]) return bound_verts def find_nearest_points(self, pos, mesh_node, max_results=3): distlist = [] closest_points = [] for pt in mesh_node.verts: target = pt.getPosition() xd = pos[0] - target[0] yd = pos[1] - target[1] zd = pos[2] - target[2] dist = math.sqrt((xd*xd) + (yd*yd) + (zd*zd)) distlist.append([dist, pt]) distlist = sorted(distlist)[0:max_results] for vertex in distlist: closest_points.append(vertex[1]) return closest_points def add_influence(self, point, joint, weight): #index = self.points.index(point) #self.points[index] = pass #self.points[point] = {} def add_joint(self, joint, data): self.joints[str(joint)] = data def add_point(self, point, joint, weight): index = point.index() if index in self.points: self.points[index]['joints'][joint.name()] = weight else: self.points[index] = {'joints': {joint.name(): weight}, 'position': list(point.getPosition('world'))} #print self.points[point] def find_skincluster(mesh): skincluster = None for meshnode in pm.listHistory(mesh): if type(meshnode) == pm.nodetypes.SkinCluster: skincluster = meshnode return skincluster def get_skinning_info(mesh_node): sk = find_skincluster(selection) pc = PointCloud() for joint in find_skincluster(selection).getInfluence(): affected_points = sk.getPointsAffectedByInfluence(joint) index_weight_dict = {} vert_set_list = list(affected_points[0]) weight_list = list(affected_points[1]) # holds all weights in mesh order vert_list = [] # holds all vertices in mesh order for vert in vert_set_list: vert_list = list(vert) i = 0 for weight in weight_list: pc.add_point(vert_list[i], joint, weight) index_weight_dict[vert_list[i].index()] = {'weight': weight, 'position': list(vert_list[i].getPosition('world'))} i += 1 # add joints print index_weight_dict pc.add_joint(joint, index_weight_dict) pc.save('/Users/jwoelper/skin') def set_skinning_info(mesh_node): pc = PointCloud() pc.load('/Users/jwoelper/skin') #pc.info() sk = find_skincluster(selection) #pm.select(pc.find_nearest_points([0,0,0], mesh_node)) """ for vert in selection.verts: pass #sk.skinPercent() #sk_name = sk.name() #cmds.skinPercent(sk_name, vert, transformValue=[('joint1', 0.2), ('joint1', 0.8)]) """ for joint in find_skincluster(selection).getInfluence(): influenced_verts = {} if str(joint) in pc.joints: for vertex, data in pc.joints[str(joint)].iteritems(): pos = data['position'] weight = data['weight'] influenced_verts[pc.find_nearest_points(pos, selection)[0]] = weight print influenced_verts for vertex, weight in influenced_verts.iteritems(): pm.skinPercent(sk, vertex, transformValue=[(joint, weight)]) #pc.find_joint_members(joint) """ affected_points = sk.getPointsAffectedByInfluence(joint) vert_set_list = list(affected_points[0]) weight_list = list(affected_points[1]) vert_list = [] for vert in vert_set_list: vert_list = list(vert) """ #get_skinning_info(selection) set_skinning_info(selection) """ if len(selection) == 1: for vert in selection[0].verts: print vert.getPosition() """