weight_transfer.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import pymel.core as pm
  2. import json
  3. import maya.cmds as cmds
  4. import math
  5. selection = pm.selected()[0]
  6. class PointCloud(object):
  7. def __init__(self):
  8. self.points = {}
  9. self.joints = {}
  10. def info(self):
  11. for point, value in self.points.iteritems():
  12. print point, value
  13. def save(self, filename):
  14. with open(filename, 'w') as f:
  15. json.dump(self.points, f, indent=4)
  16. with open(filename+'j', 'w') as f:
  17. json.dump(self.joints, f, indent=4)
  18. def load(self, filename):
  19. with open(filename) as pcfile:
  20. self.points = json.load(pcfile)
  21. with open(filename+'j') as pcfile:
  22. self.joints = json.load(pcfile)
  23. def find_joint_members(self, joint):
  24. joint = str(joint)
  25. bound_verts = []
  26. for index, attributes in self.points.iteritems():
  27. #print attributes['joints'][joint]
  28. if joint in attributes['joints']:
  29. #print joint, attributes['joints'][joint]
  30. pos = attributes['position']
  31. bound_verts.append(self.find_nearest_points(pos, selection)[0])
  32. return bound_verts
  33. def find_nearest_points(self, pos, mesh_node, max_results=3):
  34. distlist = []
  35. closest_points = []
  36. for pt in mesh_node.verts:
  37. target = pt.getPosition()
  38. xd = pos[0] - target[0]
  39. yd = pos[1] - target[1]
  40. zd = pos[2] - target[2]
  41. dist = math.sqrt((xd*xd) + (yd*yd) + (zd*zd))
  42. distlist.append([dist, pt])
  43. distlist = sorted(distlist)[0:max_results]
  44. for vertex in distlist:
  45. closest_points.append(vertex[1])
  46. return closest_points
  47. def add_influence(self, point, joint, weight):
  48. #index = self.points.index(point)
  49. #self.points[index] =
  50. pass
  51. #self.points[point] = {}
  52. def add_joint(self, joint, data):
  53. self.joints[str(joint)] = data
  54. def add_point(self, point, joint, weight):
  55. index = point.index()
  56. if index in self.points:
  57. self.points[index]['joints'][joint.name()] = weight
  58. else:
  59. self.points[index] = {'joints': {joint.name(): weight}, 'position': list(point.getPosition('world'))}
  60. #print self.points[point]
  61. def find_skincluster(mesh):
  62. skincluster = None
  63. for meshnode in pm.listHistory(mesh):
  64. if type(meshnode) == pm.nodetypes.SkinCluster:
  65. skincluster = meshnode
  66. return skincluster
  67. def get_skinning_info(mesh_node):
  68. sk = find_skincluster(selection)
  69. pc = PointCloud()
  70. for joint in find_skincluster(selection).getInfluence():
  71. affected_points = sk.getPointsAffectedByInfluence(joint)
  72. index_weight_dict = {}
  73. vert_set_list = list(affected_points[0])
  74. weight_list = list(affected_points[1]) # holds all weights in mesh order
  75. vert_list = [] # holds all vertices in mesh order
  76. for vert in vert_set_list:
  77. vert_list = list(vert)
  78. i = 0
  79. for weight in weight_list:
  80. pc.add_point(vert_list[i], joint, weight)
  81. index_weight_dict[vert_list[i].index()] = {'weight': weight, 'position': list(vert_list[i].getPosition('world'))}
  82. i += 1
  83. # add joints
  84. print index_weight_dict
  85. pc.add_joint(joint, index_weight_dict)
  86. pc.save('/Users/jwoelper/skin')
  87. def set_skinning_info(mesh_node):
  88. pc = PointCloud()
  89. pc.load('/Users/jwoelper/skin')
  90. #pc.info()
  91. sk = find_skincluster(selection)
  92. #pm.select(pc.find_nearest_points([0,0,0], mesh_node))
  93. """
  94. for vert in selection.verts:
  95. pass
  96. #sk.skinPercent()
  97. #sk_name = sk.name()
  98. #cmds.skinPercent(sk_name, vert, transformValue=[('joint1', 0.2), ('joint1', 0.8)])
  99. """
  100. for joint in find_skincluster(selection).getInfluence():
  101. influenced_verts = {}
  102. if str(joint) in pc.joints:
  103. for vertex, data in pc.joints[str(joint)].iteritems():
  104. pos = data['position']
  105. weight = data['weight']
  106. influenced_verts[pc.find_nearest_points(pos, selection)[0]] = weight
  107. print influenced_verts
  108. for vertex, weight in influenced_verts.iteritems():
  109. pm.skinPercent(sk, vertex, transformValue=[(joint, weight)])
  110. #pc.find_joint_members(joint)
  111. """
  112. affected_points = sk.getPointsAffectedByInfluence(joint)
  113. vert_set_list = list(affected_points[0])
  114. weight_list = list(affected_points[1])
  115. vert_list = []
  116. for vert in vert_set_list:
  117. vert_list = list(vert)
  118. """
  119. #get_skinning_info(selection)
  120. set_skinning_info(selection)
  121. """
  122. if len(selection) == 1:
  123. for vert in selection[0].verts:
  124. print vert.getPosition()
  125. """