| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  | # ##### BEGIN GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | #  modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | #  as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | #  of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | #  GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | #  along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  | #  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # ##### END GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # <pep8 compliant> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import bpy | 
					
						
							|  |  |  | from rigify import RigifyError | 
					
						
							|  |  |  | from rigify_utils import bone_class_instance, copy_bone_simple | 
					
						
							|  |  |  | from rna_prop_ui import rna_idprop_ui_prop_get | 
					
						
							| 
									
										
										
										
											2010-04-11 14:22:27 +00:00
										 |  |  | from mathutils import Vector, RotationMatrix | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  | from math import radians, pi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # not used, defined for completeness | 
					
						
							|  |  |  | METARIG_NAMES = ("pelvis", "ribcage") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def metarig_template(): | 
					
						
							|  |  |  |     # TODO | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  |     # generated by rigify.write_meta_rig | 
					
						
							|  |  |  |     #bpy.ops.object.mode_set(mode='EDIT') | 
					
						
							|  |  |  |     #obj = bpy.context.active_object | 
					
						
							|  |  |  |     #arm = obj.data | 
					
						
							|  |  |  |     #bone = arm.edit_bones.new('tail.01') | 
					
						
							|  |  |  |     #bone.head[:] = 0.0000, -0.0306, 0.1039 | 
					
						
							|  |  |  |     #bone.tail[:] = 0.0000, -0.0306, -0.0159 | 
					
						
							|  |  |  |     #bone.roll = 0.0000 | 
					
						
							|  |  |  |     #bone.connected = False | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     #bpy.ops.object.mode_set(mode='OBJECT') | 
					
						
							|  |  |  |     #pbone = obj.pose.bones['tail.01'] | 
					
						
							|  |  |  |     #pbone['type'] = 'tail_spline_ik' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def metarig_definition(obj, orig_bone_name): | 
					
						
							|  |  |  |     """ Collects and returns the relevent bones for the rig.
 | 
					
						
							|  |  |  |         The bone given is the first in the chain of tail bones. | 
					
						
							|  |  |  |         It includes bones in the chain up until it hits a bone that doesn't | 
					
						
							|  |  |  |         have the same name base. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tail.01 -> tail.02 -> tail.03 -> ... -> tail.n | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     arm = obj.data | 
					
						
							|  |  |  |     tail_base = arm.bones[orig_bone_name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if tail_base.parent == None: | 
					
						
							|  |  |  |         raise RigifyError("'tail_control' rig type on bone '%s' requires a parent." % orig_bone_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bone_definitions = [tail_base.name] | 
					
						
							|  |  |  |     bone_definitions.extend([child.name for child in tail_base.children_recursive_basename]) | 
					
						
							|  |  |  |     return bone_definitions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(obj, bone_definitions, base_names, options): | 
					
						
							|  |  |  |     bpy.ops.object.mode_set(mode='EDIT') | 
					
						
							|  |  |  |     arm = obj.data | 
					
						
							|  |  |  |     bb = obj.data.bones | 
					
						
							|  |  |  |     eb = obj.data.edit_bones | 
					
						
							|  |  |  |     pb = obj.pose.bones | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Create bones for hinge/free | 
					
						
							|  |  |  |     # hinge 1 sticks with the parent | 
					
						
							|  |  |  |     # hinge 2 is the parent of the tail controls | 
					
						
							|  |  |  |     hinge1 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge1" % base_names[bone_definitions[0]], parent=True).name | 
					
						
							|  |  |  |     hinge2 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge2" % base_names[bone_definitions[0]], parent=False).name | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Create tail control bones | 
					
						
							|  |  |  |     bones = [] | 
					
						
							|  |  |  |     i = 0 | 
					
						
							|  |  |  |     for bone_def in bone_definitions: | 
					
						
							|  |  |  |         bone = copy_bone_simple(arm, bone_def, base_names[bone_def], parent=True).name | 
					
						
							|  |  |  |         if i == 1:  # Don't change parent of first tail bone | 
					
						
							|  |  |  |             eb[bone].connected = False | 
					
						
							|  |  |  |             eb[bone].parent = eb[hinge2] | 
					
						
							|  |  |  |             eb[bone].local_location = False | 
					
						
							|  |  |  |         i = 1 | 
					
						
							|  |  |  |         bones += [bone] | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     bpy.ops.object.mode_set(mode='OBJECT') | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Rotation mode and axis locks | 
					
						
							|  |  |  |     for bone, org_bone in zip(bones, bone_definitions): | 
					
						
							|  |  |  |         pb[bone].rotation_mode = pb[org_bone].rotation_mode | 
					
						
							|  |  |  |         pb[bone].lock_location = tuple(pb[org_bone].lock_location) | 
					
						
							|  |  |  |         pb[bone].lock_rotations_4d = pb[org_bone].lock_rotations_4d | 
					
						
							|  |  |  |         pb[bone].lock_rotation = tuple(pb[org_bone].lock_rotation) | 
					
						
							|  |  |  |         pb[bone].lock_rotation_w = pb[org_bone].lock_rotation_w | 
					
						
							|  |  |  |         pb[bone].lock_scale = tuple(pb[org_bone].lock_scale) | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Add custom properties | 
					
						
							|  |  |  |     pb[bones[0]]["hinge"] = 0.0 | 
					
						
							|  |  |  |     prop = rna_idprop_ui_prop_get(pb[bones[0]], "hinge", create=True) | 
					
						
							|  |  |  |     prop["min"] = 0.0 | 
					
						
							|  |  |  |     prop["max"] = 1.0 | 
					
						
							|  |  |  |     prop["soft_min"] = 0.0 | 
					
						
							|  |  |  |     prop["soft_max"] = 1.0 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     pb[bones[0]]["free"] = 0.0 | 
					
						
							|  |  |  |     prop = rna_idprop_ui_prop_get(pb[bones[0]], "free", create=True) | 
					
						
							|  |  |  |     prop["min"] = 0.0 | 
					
						
							|  |  |  |     prop["max"] = 1.0 | 
					
						
							|  |  |  |     prop["soft_min"] = 0.0 | 
					
						
							|  |  |  |     prop["soft_max"] = 1.0 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Add constraints | 
					
						
							|  |  |  |     for bone, org_bone in zip(bones, bone_definitions): | 
					
						
							|  |  |  |         con = pb[org_bone].constraints.new('COPY_TRANSFORMS') | 
					
						
							|  |  |  |         con.target = obj | 
					
						
							|  |  |  |         con.subtarget = bone | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     con_f = pb[hinge2].constraints.new('COPY_LOCATION') | 
					
						
							|  |  |  |     con_f.target = obj | 
					
						
							|  |  |  |     con_f.subtarget = hinge1 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     con_h = pb[hinge2].constraints.new('COPY_TRANSFORMS') | 
					
						
							|  |  |  |     con_h.target = obj | 
					
						
							|  |  |  |     con_h.subtarget = hinge1 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     # Add drivers | 
					
						
							| 
									
										
										
										
											2010-04-06 07:49:10 +00:00
										 |  |  |     bone_path = pb[bones[0]].path_from_id() | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-03 19:12:11 +00:00
										 |  |  |     driver_fcurve = con_f.driver_add("influence") | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     driver = driver_fcurve.driver | 
					
						
							|  |  |  |     driver.type = 'AVERAGE' | 
					
						
							|  |  |  |     var = driver.variables.new() | 
					
						
							|  |  |  |     var.name = "free" | 
					
						
							|  |  |  |     var.targets[0].id_type = 'OBJECT' | 
					
						
							|  |  |  |     var.targets[0].id = obj | 
					
						
							|  |  |  |     var.targets[0].data_path = bone_path + '["free"]' | 
					
						
							|  |  |  |     mod = driver_fcurve.modifiers[0] | 
					
						
							|  |  |  |     mod.poly_order = 1 | 
					
						
							|  |  |  |     mod.coefficients[0] = 1.0 | 
					
						
							|  |  |  |     mod.coefficients[1] = -1.0 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-03 19:12:11 +00:00
										 |  |  |     driver_fcurve = con_h.driver_add("influence") | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     driver = driver_fcurve.driver | 
					
						
							|  |  |  |     driver.type = 'AVERAGE' | 
					
						
							|  |  |  |     var = driver.variables.new() | 
					
						
							|  |  |  |     var.name = "hinge" | 
					
						
							|  |  |  |     var.targets[0].id_type = 'OBJECT' | 
					
						
							|  |  |  |     var.targets[0].id = obj | 
					
						
							|  |  |  |     var.targets[0].data_path = bone_path + '["hinge"]' | 
					
						
							|  |  |  |     mod = driver_fcurve.modifiers[0] | 
					
						
							|  |  |  |     mod.poly_order = 1 | 
					
						
							|  |  |  |     mod.coefficients[0] = 1.0 | 
					
						
							|  |  |  |     mod.coefficients[1] = -1.0 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 16:46:24 +00:00
										 |  |  |     return None |