diff options
author | Demeter Dzadik <demeterdzadik@gmail.com> | 2020-11-05 15:42:40 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2020-11-05 16:13:40 +0300 |
commit | d32998246bdb0dba15946ee387ca672b4e17911a (patch) | |
tree | 89fea59a0ff182c28b207a6b5e0fac7822800f40 | |
parent | 0d55b1f93c70b55bf007d7e80299a1c36634883d (diff) |
Rigify: allow passing Armature "targets" as a kwarg for make_constraint.
It seems like the make_constraint() function was designed to allow fully
defining a constraint with a single call, but currently when creating
Armature constraints, its targets have to be created separately after
the make_constraint() call.
This patch addresses this, allowing you to pass a "targets" dictionary.
Armature constraint targets only have three properties, which are "target",
"subtarget" and "weight". For convenience, since 99.99% of the times the
"target" will be the rig, that doesn't have to be specified, but it can be.
Differential Revision: https://developer.blender.org/D9092
-rw-r--r-- | rigify/utils/mechanism.py | 25 | ||||
-rw-r--r-- | rigify/utils/switch_parent.py | 13 |
2 files changed, 27 insertions, 11 deletions
diff --git a/rigify/utils/mechanism.py b/rigify/utils/mechanism.py index 232fb7af..e3f9f1c2 100644 --- a/rigify/utils/mechanism.py +++ b/rigify/utils/mechanism.py @@ -39,9 +39,9 @@ def _set_default_attr(obj, options, attr, value): options.setdefault(attr, value) def make_constraint( - owner, type, target=None, subtarget=None, *, insert_index=None, + owner, con_type, target=None, subtarget=None, *, insert_index=None, space=None, track_axis=None, use_xyz=None, use_limit_xyz=None, invert_xyz=None, - **options): + targets=None, **options): """ Creates and initializes constraint of the specified type for the owner bone. @@ -55,11 +55,30 @@ def make_constraint( use_limit_xyz : list of 3 items is assigned to use_limit_x/y/z options invert_xyz : list of 3 items is assigned to invert_x, invert_y and invert_z options min/max_x/y/z : a corresponding use_(min/max/limit)_(x/y/z) option is set to True + targets : list of strings, tuples or dicts describing Armature constraint targets Other keyword arguments are directly assigned to the constraint options. Returns the newly created constraint. """ - con = owner.constraints.new(type) + con = owner.constraints.new(con_type) + + # For Armature constraints, allow passing a "targets" list as a keyword argument. + if targets is not None: + assert con.type == 'ARMATURE' + for target_info in targets: + con_target = con.targets.new() + con_target.target = owner.id_data + # List element can be a string, a tuple or a dictionary. + if isinstance(target_info, str): + con_target.subtarget = target_info + elif isinstance(target_info, tuple): + if len(target_info) == 2: + con_target.subtarget, con_target.weight = target_info + else: + con_target.target, con_target.subtarget, con_target.weight = target_info + else: + for key, val in target_info.items(): + setattr(con_target, key, val) if insert_index is not None: owner.constraints.move(len(owner.constraints)-1, insert_index) diff --git a/rigify/utils/switch_parent.py b/rigify/utils/switch_parent.py index 61721266..1a0e81fe 100644 --- a/rigify/utils/switch_parent.py +++ b/rigify/utils/switch_parent.py @@ -385,19 +385,16 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin): # Implement via an Armature constraint mch = child['mch_bone'] - con = self.make_constraint(mch, 'ARMATURE', name='SWITCH_PARENT') + con = self.make_constraint( + mch, 'ARMATURE', name='SWITCH_PARENT', + targets=[ (parent, 0.0) for parent, _ in child['parent_bones'] ] + ) prop_var = [(child['prop_bone'], child['prop_id'])] for i, (parent, parent_name) in enumerate(child['parent_bones']): - tgt = con.targets.new() - - tgt.target = self.obj - tgt.subtarget = parent - tgt.weight = 0.0 - expr = 'var == %d' % (i+1) - self.make_driver(tgt, 'weight', expression=expr, variables=prop_var) + self.make_driver(con.targets[i], 'weight', expression=expr, variables=prop_var) # Add copy constraints copy = child['copy'] |