Advertisement
OCEAlpha

mocaptool_ops

Jan 21st, 2018
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.50 KB | None | 0 0
  1. import bpy
  2.  
  3. class MocapNormalizeNames(bpy.types.Operator):
  4.     bl_idname = "wm.normalize_names"
  5.     bl_label = "Normalize Names"
  6.     bl_description = "Remove 'Left' and 'Right' from names and replace \nwith conventional names using '.L' and '.R'"
  7.  
  8.     def execute(self, context):
  9.         for bone in bpy.data.objects[context.scene.mocap.source].pose.bones:
  10.             if 'Left' in bone.name:                
  11.                 bone.name = bone.name.replace('Left', '')
  12.                 if '.L' not in bone.name:
  13.                      bone.name += '.L'
  14.             elif 'Right' in bone.name:                
  15.                 bone.name = bone.name.replace('Right', '')
  16.                 if '.R' not in bone.name:
  17.                      bone.name += '.R'
  18.         return {'FINISHED'}
  19.    
  20. class MocapAutomapNames(bpy.types.Operator):
  21.     bl_idname = "wm.automap_names"
  22.     bl_label = "Automap Names"
  23.     bl_description = "Fill properties with matching names if avatible"
  24.    
  25.     def execute(self, context):
  26.         for sbone in bpy.data.objects[context.scene.mocap.source].pose.bones:
  27.             for tbone in bpy.data.objects[context.scene.mocap.target].pose.bones:
  28.                 if tbone.bone_source == '' and tbone.name == sbone.name:
  29.                     tbone.bone_source = sbone.name
  30.         return {'FINISHED'}
  31.    
  32. class MocapToggleIK(bpy.types.Operator):
  33.     bl_idname = "wm.toggle_ikconstraints"
  34.     bl_label = "Toggle IK"
  35.     bl_description = "Toggle IK constraints on selected armature's bones"
  36.    
  37.     def execute(self, context):
  38.         target_arm = bpy.data.objects[context.scene.mocap.target].pose
  39.         if bpy.context.object.type == 'ARMATURE':
  40.             target_arm = bpy.context.object.pose
  41.         bool = False
  42.         for tbone in target_arm.bones:
  43.             if "IK" in tbone.constraints.keys():
  44.                 bool = not tbone.constraints['IK'].mute
  45.                 break
  46.         for tbone in target_arm.bones:
  47.             if "IK" in tbone.constraints.keys():
  48.                 tbone.constraints['IK'].mute = bool
  49.         return {'FINISHED'}
  50.  
  51. class convert():
  52.  
  53.     def get_or_create_fcurve(self, t_action, t_data_path, array_index=-1, group=None):
  54.         for fc in t_action.fcurves:
  55.             if fc.data_path == t_data_path and (array_index<0 or fc.array_index == array_index):
  56.                 return fc
  57.  
  58.         fc = t_action.fcurves.new(t_data_path, array_index)
  59.         fc.group = group
  60.         return fc
  61.  
  62.     def add_keyframe_quat(self, t_action, quat, frame, t_data_path):
  63.         for i in range(len(quat)):
  64.             fc = self.get_or_create_fcurve(t_action, t_data_path, i)
  65.             pos = len(fc.keyframe_points)
  66.             fc.keyframe_points.add(1)
  67.             fc.keyframe_points[pos].co = [frame, quat[i]]
  68.             fc.update()
  69.  
  70.     def add_keyframe_euler(self, t_action, euler, frame, t_data_path):
  71.         for i in range(len(euler)):
  72.             fc = self.get_or_create_fcurve(t_action, t_data_path, i)
  73.             pos = len(fc.keyframe_points)
  74.             fc.keyframe_points.add(1)
  75.             fc.keyframe_points[pos].co = [frame, euler[i]]
  76.             fc.update()
  77.  
  78.     #Gets the X value from kp.co and forms an array of keyframe locations
  79.     def frames_matching(self, action, data_path):
  80.         frames = set()
  81.         for fc in action.fcurves:
  82.             if fc.data_path == data_path:
  83.                 fri = [kp.co[0] for kp in fc.keyframe_points]
  84.                 frames.update(fri)
  85.         return frames
  86.        
  87.     # Converts only one group/bone in one action - Euler to Quat
  88.     def group_eq(self, s_action, s_bone, s_data_path, t_action, t_bone, t_data_path, order):
  89.        
  90.         frames = self.frames_matching(s_action, s_data_path)
  91.        
  92.         for fr in frames:
  93.             euler = s_bone.rotation_euler.copy()
  94.             for fc in s_action.fcurves:
  95.                 if fc.data_path == s_data_path:
  96.                     euler[fc.array_index] = fc.evaluate(fr)
  97.             quat = euler.to_quaternion()
  98.  
  99.             self.add_keyframe_quat(t_action, quat, fr, t_data_path)
  100.             t_bone.rotation_mode = order
  101.            
  102.     # Converts only one group/bone in one action - Quat to euler
  103.     def group_qe(self, s_action, s_bone, s_data_path, t_action, t_bone, t_data_path, order):
  104.        
  105.         frames = self.frames_matching(s_action, data_path)
  106.        
  107.         for fr in frames:
  108.             quat = s_bone.rotation_quaternion.copy()
  109.             for fc in s_action.fcurves:
  110.                 if fc.data_path == data_path:
  111.                     quat[fc.array_index] = fc.evaluate(fr)
  112.             euler = quat.to_euler(order)
  113.  
  114.             self.add_keyframe_euler(t_action, euler, fr, t_data_path)
  115.             bone.rotation_mode = order
  116.  
  117.     ##### BONE TO BONE #####
  118.     def bon_to_bon(self, s_action, s_bone, t_action, t_bone, order):
  119.         do = False
  120.         s_data_path = ''
  121.         t_data_path = ''
  122.        
  123.         # Check weather there needs to be a conversion  
  124.         for fcurve in s_action.fcurves:
  125.             if s_bone.name in fcurve.data_path:
  126.                
  127.                 # If To-Euler conversion
  128.                 if order != 'QUATERNION':
  129.                     if fcurve.data_path.endswith('rotation_quaternion'):
  130.                         do = True
  131.                         s_data_path = fcurve.data_path #[:-len('rotation_quaternion')]
  132.                         t_data_path = 'pose.bones["' + t_bone.name + '"].rotation_quaternion'
  133.                         break
  134.                
  135.                 # If To-Quat conversion
  136.                 else:
  137.                     if fcurve.data_path.endswith('rotation_euler'):
  138.                         do = True
  139.                         s_data_path = fcurve.data_path #[:-len('rotation_euler')]
  140.                         t_data_path = 'pose.bones["' + t_bone.name + '"].rotation_euler'
  141.                         break
  142.        
  143.         # If To-Euler conversion
  144.         if do and order != 'QUATERNION':
  145.             self.group_qe(s_action, s_bone, s_data_path, t_action, t_bone, t_data_path, order)          
  146.  
  147.         # If To-Quat conversion
  148.         elif do:
  149.             self.group_eq(s_action, s_bone, s_data_path, t_action, t_bone, t_data_path, order)
  150.  
  151.         # Changes rotation mode to new one
  152.         t_bone.rotation_mode = order
  153.        
  154.     ##### BONE TO BONE #####
  155.     def bon_every_bon(self, s_action, s_obj, t_action, t_obj, order):
  156.         print('#\n# New Run \n#')
  157.        
  158.         s_bones = set()
  159.         for t_bone in t_obj.pose.bones:
  160.             if t_bone.bone_source is None or t_bone.bone_source != '':
  161.                 s_bones.add(t_bone.bone_source)
  162.                 s_obj.pose.bones[t_bone.bone_source].bone_source = t_bone.name
  163.                 print(t_bone.bone_source + ' -> ' + t_bone.name)
  164.        
  165.         # Collects pose_bones that are in the action
  166.         pose_bones = set()
  167.         # Checks all fcurves
  168.         for fcurve in s_action.fcurves:
  169.             # Look for the ones that has rotation_euler
  170.             if order == 'QUATERNION':
  171.                 if fcurve.data_path.endswith('rotation_euler'):
  172.                     # If the bone from action really exists
  173.                     bone_name = fcurve.data_path[12:-17]
  174.                     if bone_name in s_bones:
  175.                         if s_obj.pose.bones[bone_name] not in pose_bones:
  176.                             pose_bones.add(s_obj.pose.bones[bone_name])
  177.                             print('added ' + bone_name)
  178.                     else:
  179.                         print(bone_name, 'is not selected')
  180.  
  181.             # Look for the ones that has rotation_quaternion
  182.             else:
  183.                 if fcurve.data_path.endswith('rotation_quaternion'):
  184.                     # If the bone from action really exists
  185.                     bone_name = fcurve.data_path[12:-22]
  186.                     if bone_name in s_bones:
  187.                         if s_obj.pose.bones[bone_name] not in pose_bones:
  188.                             pose_bones.add(s_obj.pose.bones[bone_name])
  189.                             print('added ' + s_obj.pose.bones[bone_name])
  190.                     else:
  191.                         print(bone_name, 'is not selected')
  192.                        
  193.         # Convert current action and pose_bones that are in each action                
  194.         for s_bone in pose_bones:
  195.             if s_bone.bone_source is None or s_bone.bone_source == '':
  196.                 print('bone source cannot be ' + s_bone.bone_source)
  197.                 continue
  198.             t_bone = t_obj.pose.bones[s_bone.bone_source]
  199.             self.bon_to_bon(s_action, s_bone, t_action, t_bone, order)
  200.  
  201. convert = convert()
  202.  
  203. class COPY_current_action_bones_bones(bpy.types.Operator):
  204.     bl_idname = "wm.copy_mapped_animation"
  205.     bl_label = "Copy Animation"
  206.     bl_description = ""
  207.    
  208.     # on mouse up:
  209.     def invoke(self, context, event):
  210.         self.execute(context)
  211.         return {'FINISHED'}
  212.    
  213.     def execute(op, context):
  214.         s_action = bpy.data.objects[context.scene.mocap.source].animation_data.action
  215.         s_obj = bpy.data.objects[context.scene.mocap.source]
  216.        
  217.         t_action = bpy.data.objects[context.scene.mocap.target].animation_data.action
  218.         t_obj = bpy.data.objects[context.scene.mocap.target]
  219.         order = bpy.context.scene.mocap.rotation_mode
  220.        
  221.         convert.bon_every_bon(s_action, s_obj, t_action, t_obj, order)
  222.         return {'FINISHED'}
  223.    
  224. def register():
  225.     bpy.utils.register_module(__name__)
  226.  
  227. def unregister():  
  228.     bpy.utils.unregister_module(__name__)
  229.    
  230. if __name__ == '__main__':
  231.     register()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement