Johann Woelper 9 years ago
parent
commit
a4ead652a2
2 changed files with 1282 additions and 224 deletions
  1. 1153 200
      sw/test.ma
  2. 129 24
      sw/weight_transfer.py

File diff suppressed because it is too large
+ 1153 - 200
sw/test.ma


+ 129 - 24
sw/weight_transfer.py

@@ -1,10 +1,59 @@
 import pymel.core as pm
-selection = pm.selected()
+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)
@@ -13,8 +62,19 @@ class PointCloud(object):
         pass
         #self.points[point] = {}
 
-    def add_point(self, point):
-        self.points[point] = {'joints': [], 'position': (0,0,0)}
+    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
@@ -24,33 +84,78 @@ def find_skincluster(mesh):
     return skincluster
 
 
-sk = find_skincluster(selection)
 
-pc = PointCloud()
-for joint in find_skincluster(selection).getInfluence():
-    affected_points = sk.getPointsAffectedByInfluence(joint)
-    #print joint
-    #print 'sel', affected_points[0]
-    #print 'pt', affected_points[1]
+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
 
-    vert_set_list = list(affected_points[0])
-    weight_list = list(affected_points[1])
-    vert_list = []
+        for vertex, weight in influenced_verts.iteritems():
+            pm.skinPercent(sk, vertex, transformValue=[(joint, weight)])
 
-    for vert in vert_set_list:
-        vert_list = list(vert)
+        #pc.find_joint_members(joint)
+        """
+        affected_points = sk.getPointsAffectedByInfluence(joint)
 
-    #print len(vert_list), vert_list
-    #print len(weight_list), weight_list
+        vert_set_list = list(affected_points[0])
+        weight_list = list(affected_points[1])
+        vert_list = []
 
-    for vert in vert_list:
-        pc.add_point(vert)
+        for vert in vert_set_list:
+            vert_list = list(vert)
+        """
 
-    i = 0
-    for weight in weight_list:
-        #print vert_list[i], weight, joint
-        pc.add_influence(vert_list[i], joint, weight)
-        i += 1
+#get_skinning_info(selection)
+set_skinning_info(selection)
 
 """
 if len(selection) == 1: