edits to the bone copy metarig type from Cessen, pointcache warning fix
[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 # <pep8 compliant>
20
21 import bpy
22 from rigify import RigifyError
23
24 # not used, defined for completeness
25 METARIG_NAMES = tuple()
26
27
28 def metarig_template():
29     # generated by rigify.write_meta_rig
30     bpy.ops.object.mode_set(mode='EDIT')
31     obj = bpy.context.active_object
32     arm = obj.data
33     bone = arm.edit_bones.new('bonesker')
34     bone.head[:] = 0.0000, 0.0000, 0.0000
35     bone.tail[:] = -0.0000, 0.7382, 0.1895
36     bone.roll = -0.0000
37     bone.connected = False
38     bone = arm.edit_bones.new('delta')
39     bone.head[:] = -0.0497, 0.8414, 0.3530
40     bone.tail[:] = -0.2511, 1.1588, 0.9653
41     bone.roll = 2.6044
42     bone.connected = False
43     bone.parent = arm.edit_bones['bonesker']
44     bone = arm.edit_bones.new('boney')
45     bone.head[:] = 0.7940, 2.5592, 0.4134
46     bone.tail[:] = 0.7940, 3.3975, 0.4890
47     bone.roll = 3.1416
48     bone.connected = False
49     bone.parent = arm.edit_bones['delta']
50
51     bpy.ops.object.mode_set(mode='OBJECT')
52     pbone = obj.pose.bones['delta']
53     pbone['type'] = 'delta'
54
55
56 def metarig_definition(obj, orig_bone_name):
57     '''
58     The bone given is the head, its parent is the body,
59     # its only child the first of a chain with matching basenames.
60     eg.
61         body -> head -> neck_01 -> neck_02 -> neck_03.... etc
62     '''
63     arm = obj.data
64     delta = arm.bones[orig_bone_name]
65     children = delta.children
66
67     if len(children) != 1:
68         raise RigifyError("only 1 child supported for delta on bone '%s'" % delta.name)
69
70     if delta.connected:
71         raise RigifyError("bone cannot be connected to its parent '%s'" % delta.name)
72
73     bone_definition = [delta.name, children[0].name]
74
75     return bone_definition
76
77
78 def main(obj, bone_definition, base_names, options):
79     '''
80     Use this bone to define a delta thats applied to its child in pose mode.
81     '''
82     mode_orig = obj.mode
83     bpy.ops.object.mode_set(mode='OBJECT')
84
85     delta_name, child_name = bone_definition
86
87     delta_pbone = obj.pose.bones[delta_name]
88
89     arm = obj.data
90     child_pbone = obj.pose.bones[child_name]
91
92     delta_phead = delta_pbone.head.copy()
93     delta_ptail = delta_pbone.tail.copy()
94     delta_pmatrix = delta_pbone.matrix.copy()
95
96     child_phead = child_pbone.head.copy()
97     child_ptail = child_pbone.tail.copy()
98     child_pmatrix = child_pbone.matrix.copy()
99
100
101     children = delta_pbone.children
102
103     bpy.ops.object.mode_set(mode='EDIT')
104
105     delta_ebone = arm.edit_bones[delta_name]
106     child_ebone = arm.edit_bones[child_name]
107
108     delta_head = delta_ebone.head.copy()
109     delta_tail = delta_ebone.tail.copy()
110
111     child_head = child_ebone.head.copy()
112     child_tail = child_ebone.tail.copy()
113
114     #arm.edit_bones.remove(delta_ebone)
115     #del delta_ebone # cant use this
116     del child_pbone
117
118     bpy.ops.object.mode_set(mode='OBJECT')
119
120
121     # Move the child bone to the deltas location
122     obj.animation_data_create()
123     delta_pbone = obj.pose.bones[delta_name]
124     # child_pbone = obj.pose.bones[child_name]
125
126     # ------------------- drivers
127
128     delta_pbone.rotation_mode = 'XYZ'
129
130     rot = delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
131     rot = rot.invert().toEuler()
132
133     fcurve_drivers = delta_pbone.driver_add("rotation_euler", -1)
134     for i, fcurve_driver in enumerate(fcurve_drivers):
135         driver = fcurve_driver.driver
136         driver.type = 'AVERAGE'
137         #mod = fcurve_driver.modifiers.new('GENERATOR')
138         mod = fcurve_driver.modifiers[0]
139         mod.poly_order = 1
140         mod.coefficients[0] = rot[i]
141         mod.coefficients[1] = 0.0
142
143     # tricky, find the transform to drive the bone to this location.
144     delta_head_offset = child_pmatrix.rotationPart() * (delta_phead - child_phead)
145
146     fcurve_drivers = delta_pbone.driver_add("location", -1)
147     for i, fcurve_driver in enumerate(fcurve_drivers):
148         driver = fcurve_driver.driver
149         driver.type = 'AVERAGE'
150         #mod = fcurve_driver.modifiers.new('GENERATOR')
151         mod = fcurve_driver.modifiers[0]
152         mod.poly_order = 1
153         mod.coefficients[0] = delta_head_offset[i]
154         mod.coefficients[1] = 0.0
155
156
157     bpy.ops.object.mode_set(mode='EDIT')
158
159     bpy.ops.object.mode_set(mode=mode_orig)
160
161     # no blendeing
162     return None