- 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
This commit is contained in:
Campbell Barton 2009-12-03 14:20:35 +00:00
parent 3b1c6d6065
commit 685d418f3a
3 changed files with 150 additions and 11 deletions

@ -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']

@ -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] == "_":
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

@ -133,8 +133,7 @@ class DATA_PT_geometry_curve(DataButtonsPanel):
if obj and obj.type == 'SURFACE':
return False
curve = context.curve
return (curve and curve.active_spline)
return context.curve
def draw(self, context):
layout = self.layout