diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-12-03 17:20:35 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-12-03 17:20:35 +0300 |
commit | 685d418f3a185a3e52fb84ba121c621e1017b623 (patch) | |
tree | 44facaafb50e87da76d5647196c400c05fcec98b /release/scripts/modules | |
parent | 3b1c6d6065ea784e6986bff58a842afd0915dc7a (diff) |
- curve geometry curve panel wasnt displaying with no active spline
- graph export didnt work for constraints with no subtarget
- utility functions for duplicating a set of bones and blending between 2 sets
Diffstat (limited to 'release/scripts/modules')
-rw-r--r-- | release/scripts/modules/graphviz_export.py | 2 | ||||
-rw-r--r-- | release/scripts/modules/rigify/__init__.py | 156 |
2 files changed, 149 insertions, 9 deletions
diff --git a/release/scripts/modules/graphviz_export.py b/release/scripts/modules/graphviz_export.py index 84614c9dc70..5d0ff4fe824 100644 --- a/release/scripts/modules/graphviz_export.py +++ b/release/scripts/modules/graphviz_export.py @@ -119,7 +119,7 @@ def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True): pbone = obj.pose.bones[bone] # must be ordered for constraint in pbone.constraints: - subtarget = constraint.subtarget + subtarget = getattr(constraint, "subtarget", "") if subtarget: # TODO, not internal links opts = ['dir=forward', "weight=1", "arrowhead=normal", "arrowtail=none", "constraint=false", 'color="red"', 'labelfontsize=4'] diff --git a/release/scripts/modules/rigify/__init__.py b/release/scripts/modules/rigify/__init__.py index 78ace98ff89..c61886fde1f 100644 --- a/release/scripts/modules/rigify/__init__.py +++ b/release/scripts/modules/rigify/__init__.py @@ -47,15 +47,123 @@ def _bone_class_instance_update(self): pbones = self.obj.pose.bones ebones = arm.edit_bones - for member in self.__slots__: - if not member[-2] == "_": - name = getattr(self, member, None) - if name is not None: - setattr(self, member + "_b", bbones.get(name, None)) - setattr(self, member + "_p", pbones.get(name, None)) - setattr(self, member + "_e", ebones.get(name, None)) + for member in self.attr_names: + name = getattr(self, member, None) + if name is not None: + setattr(self, member + "_b", bbones.get(name, None)) + setattr(self, member + "_p", pbones.get(name, None)) + setattr(self, member + "_e", ebones.get(name, None)) + + +def _bone_class_instance_copy(self, from_prefix="", to_prefix=""): + orig_name_ls = [] + new_name_ls = [] + new_slot_ls = [] + + for attr in self.attr_names: + bone_name_orig = getattr(self, attr) + ebone = getattr(self, attr + "_e") + # orig_names[attr] = bone_name_orig + + # insert prefix + bone_name = "ORG-" + bone_name_orig + ebone.name = bone_name + bone_name = ebone.name # cant be sure we get what we ask for + setattr(self, attr, bone_name) + + new_slot_ls.append(attr) + orig_name_ls.append(bone_name) + new_name_ls.append(bone_name_orig) + + new_bones = copy_bone_simple_list(self.obj.data, orig_name_ls, new_name_ls, True) + new_bc = bone_class_instance(self.obj, new_slot_ls) + + for i, attr in enumerate(new_slot_ls): + ebone = new_bones[i] + setattr(new_bc, attr + "_e", ebone) + setattr(new_bc, attr, ebone.name) + + return new_bc + + +def _bone_class_instance_blend(self, from_bc, to_bc, blend_target=None, use_loc=True, use_rot=True): + ''' + Use for blending bone chains. + + blend_target = (bone_name, bone_property) + default to the last bone, blend prop + + XXX - toggles editmode, need to re-validate all editbones :( + ''' + if self.attr_names != to_bc.attr_names: + raise Exception("can only blend between matching chains") + + obj = self.obj + + if obj.mode == 'EDIT': + raise Exception("blending cant be called in editmode") + + # setup the blend property + if blend_target: + prop_bone_name, prop_name = blend_target + else: + prop_bone_name, prop_name = self.attr_names[-1], "blend" + + prop_pbone = obj.pose.bones[prop_bone_name] + if prop_pbone.get(prop_bone_name, None) is None: + prop = rna_idprop_ui_prop_get(prop_pbone, prop_name, create=True) + prop_pbone[prop_name] = 0.5 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + + driver_path = prop_pbone.path_to_id() + ('["%s"]' % prop_name) + + def blend_target(driver): + tar = driver.targets.new() + tar.name = prop_bone_name + tar.id_type = 'OBJECT' + tar.id = obj + tar.rna_path = driver_path + + for attr in self.attr_names: + new_pbone = getattr(self, attr + "_p") + from_bone_name = getattr(from_bc, attr) + to_bone_name = getattr(to_bc, attr) + if use_loc: + con = new_pbone.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = from_bone_name + + con = new_pbone.constraints.new('COPY_LOCATION') + con.target = obj + con.subtarget = to_bone_name + + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + driver.type = 'AVERAGE' + fcurve.modifiers.remove(0) # grr dont need a modifier + + blend_target(driver) + + if use_rot: + con = new_pbone.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = from_bone_name + + con = new_pbone.constraints.new('COPY_ROTATION') + con.target = obj + con.subtarget = to_bone_name + + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + driver.type = 'AVERAGE' + fcurve.modifiers.remove(0) # grr dont need a modifier + + blend_target(driver) + def bone_class_instance(obj, slots, name="BoneContainer"): + attr_names = tuple(slots) # dont modify the original slots = slots[:] # dont modify the original for i in range(len(slots)): member = slots[i] @@ -63,7 +171,14 @@ def bone_class_instance(obj, slots, name="BoneContainer"): slots.append(member + "_p") # pose bone slots.append(member + "_e") # edit bone - class_dict = {"obj":obj, "update":_bone_class_instance_update} + class_dict = { \ + "obj":obj, \ + "attr_names":attr_names, \ + "update":_bone_class_instance_update, \ + "copy":_bone_class_instance_copy, \ + "blend":_bone_class_instance_blend, \ + } + instance = auto_class_instance(slots, name, class_dict) return instance @@ -94,6 +209,31 @@ def copy_bone_simple(arm, from_bone, name, parent=False): return ebone_new +def copy_bone_simple_list(arm, from_bones, to_bones, parent=False): + dup_bones = {} + + if len(from_bones) != len(to_bones): + raise Exception("bone list sizes must match") + + copy_bones = [copy_bone_simple(arm, bone_name, to_bones[i], True) for i, bone_name in enumerate(from_bones)] + + # now we need to re-parent + for ebone in copy_bones: + parent = ebone.parent + if parent: + try: + i = from_bones.index(parent.name) + except: + i = -1 + + if i == -1: + ebone.parent = None + else: + ebone.parent = copy_bones[i] + + return copy_bones + + def add_stretch_to(obj, from_name, to_name, name): ''' Adds a bone that stretches from one to another |