split up metarig hierarchy evaluation and modifying the metarig into 2 steps,
[blender.git] / release / scripts / modules / rigify / delta.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 import bpy
20 from rigify import get_bone_data
21
22 # not used, defined for completeness
23 METARIG_NAMES = tuple()
24
25 def metarig_definition(obj, orig_bone_name):
26     '''
27     The bone given is the head, its parent is the body,
28     # its only child the first of a chain with matching basenames.
29     eg.
30         body -> head -> neck_01 -> neck_02 -> neck_03.... etc
31     '''
32     arm = obj.data
33     delta = arm.bones[orig_bone_name]
34     children = delta.children
35     
36     if len(children) != 1:
37         print("only 1 child supported for delta")
38     
39     bone_definition = [delta.name, children[0].name]
40     
41     return bone_definition
42
43 def main(obj, bone_definition, base_names):
44     '''
45     Use this bone to define a delta thats applied to its child in pose mode.
46     '''
47     
48     mode_orig = obj.mode
49     bpy.ops.object.mode_set(mode='OBJECT')
50     
51     delta_name, child_name = bone_definition
52     
53     delta_pbone = obj.pose.bones[delta_name]
54
55     arm, child_pbone, child_bone = get_bone_data(obj, child_name)
56     
57     delta_phead = delta_pbone.head.copy()
58     delta_ptail = delta_pbone.tail.copy()
59     delta_pmatrix = delta_pbone.matrix.copy()
60     
61     child_phead = child_pbone.head.copy()
62     child_ptail = child_pbone.tail.copy()
63     child_pmatrix = child_pbone.matrix.copy()
64     
65     
66     children = delta_pbone.children
67
68     bpy.ops.object.mode_set(mode='EDIT')
69     
70     delta_ebone = arm.edit_bones[delta_name]
71     child_ebone = arm.edit_bones[child_name]
72     
73     delta_head = delta_ebone.head.copy()
74     delta_tail = delta_ebone.tail.copy()    
75     
76     # arm, parent_pbone, parent_bone = get_bone_data(obj, delta_name)
77     child_head = child_ebone.head.copy()
78     child_tail = child_ebone.tail.copy()
79     
80     arm.edit_bones.remove(delta_ebone)
81     del delta_ebone # cant use this
82     
83     bpy.ops.object.mode_set(mode='OBJECT')
84     
85     
86     # Move the child bone to the deltas location
87     obj.animation_data_create()
88     child_pbone = obj.pose.bones[child_name]
89     
90     # ------------------- drivers
91     
92     child_pbone.rotation_mode = 'XYZ'
93     
94     rot =  delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
95     rot = rot.invert().toEuler()
96     
97     fcurve_drivers = child_pbone.driver_add("rotation_euler", -1)
98     for i, fcurve_driver in enumerate(fcurve_drivers):
99         driver = fcurve_driver.driver
100         driver.type = 'AVERAGE'
101         #mod = fcurve_driver.modifiers.new('GENERATOR')
102         mod = fcurve_driver.modifiers[0]
103         mod.poly_order = 1
104         mod.coefficients[0] = rot[i]
105         mod.coefficients[1] = 0.0
106     
107     # tricky, find the transform to drive the bone to this location.
108     delta_head_offset =  child_pmatrix.rotationPart() * (delta_phead - child_phead)
109     
110     fcurve_drivers = child_pbone.driver_add("location", -1)
111     for i, fcurve_driver in enumerate(fcurve_drivers):
112         driver = fcurve_driver.driver
113         driver.type = 'AVERAGE'
114         #mod = fcurve_driver.modifiers.new('GENERATOR')
115         mod = fcurve_driver.modifiers[0]
116         mod.poly_order = 1
117         mod.coefficients[0] = delta_head_offset[i]
118         mod.coefficients[1] = 0.0
119     
120     
121     # arm, parent_pbone, parent_bone = get_bone_data(obj, delta_name)
122     bpy.ops.object.mode_set(mode='EDIT')
123     
124     bpy.ops.object.mode_set(mode=mode_orig)
125
126     # no blendeing
127     return None
128