diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2020-11-25 14:07:44 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2020-11-25 14:42:56 +0300 |
commit | 292b5975d6d4d470f51ff683d5b5a5d979e887a4 (patch) | |
tree | 98623b8bc46f0d6c07a0ad3ced951bf45393ed3d | |
parent | 1a9a9d008dea3fab2bdfd04a57bcdd364ae5d0b8 (diff) |
Rigify: support including Inherit Scale and constraints in metarig.
Also fix metarig Inherit Scale support in limbs.super_finger.
-rw-r--r-- | rigify/rigs/basic/raw_copy.py | 2 | ||||
-rw-r--r-- | rigify/rigs/limbs/super_finger.py | 4 | ||||
-rw-r--r-- | rigify/utils/bones.py | 8 | ||||
-rw-r--r-- | rigify/utils/rig.py | 51 |
4 files changed, 60 insertions, 5 deletions
diff --git a/rigify/rigs/basic/raw_copy.py b/rigify/rigs/basic/raw_copy.py index 5e7c0978..7d6d693e 100644 --- a/rigify/rigs/basic/raw_copy.py +++ b/rigify/rigs/basic/raw_copy.py @@ -119,6 +119,8 @@ class RelinkConstraintsMixin: r = layout.row() r.prop(params, "parent_bone") + layout.label(text="Constraint names have special meanings.", icon='ERROR') + class InstanceRig(BaseRig, RelinkConstraintsMixin): def find_org_bones(self, pose_bone): diff --git a/rigify/rigs/limbs/super_finger.py b/rigify/rigs/limbs/super_finger.py index 02f9bff8..5dd7e681 100644 --- a/rigify/rigs/limbs/super_finger.py +++ b/rigify/rigs/limbs/super_finger.py @@ -100,7 +100,7 @@ class Rig(SimpleChainRig): self.bones.ctrl.fk += [self.make_tip_control_bone(orgs[-1], orgs[0])] def make_control_bone(self, i, org): - return self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=False) + return self.copy_bone(org, make_derived_name(org, 'ctrl'), inherit_scale=True) def make_tip_control_bone(self, org, name_org): name = self.copy_bone(org, make_derived_name(name_org, 'ctrl'), parent=False) @@ -219,7 +219,7 @@ class Rig(SimpleChainRig): self.bones.mch.bend = map_list(self.make_mch_bend_bone, self.bones.org) def make_mch_bend_bone(self, org): - return self.copy_bone(org, make_derived_name(org, 'mch', '_drv'), parent=False, scale=0.3) + return self.copy_bone(org, make_derived_name(org, 'mch', '_drv'), inherit_scale=True, scale=0.3) @stage.parent_bones def parent_mch_bend_chain(self): diff --git a/rigify/utils/bones.py b/rigify/utils/bones.py index f0e5e388..92b91ade 100644 --- a/rigify/utils/bones.py +++ b/rigify/utils/bones.py @@ -121,7 +121,7 @@ def new_bone(obj, bone_name): raise MetarigError("Can't add new bone '%s' outside of edit mode" % bone_name) -def copy_bone(obj, bone_name, assign_name='', *, parent=False, bbone=False, length=None, scale=None): +def copy_bone(obj, bone_name, assign_name='', *, parent=False, inherit_scale=False, bbone=False, length=None, scale=None): """ Makes a copy of the given bone in the given armature object. Returns the resulting bone's name. """ @@ -151,6 +151,8 @@ def copy_bone(obj, bone_name, assign_name='', *, parent=False, bbone=False, leng edit_bone_2.use_inherit_rotation = edit_bone_1.use_inherit_rotation edit_bone_2.use_local_location = edit_bone_1.use_local_location + + if parent or inherit_scale: edit_bone_2.inherit_scale = edit_bone_1.inherit_scale if bbone: @@ -385,9 +387,9 @@ class BoneUtilityMixin(object): self.register_new_bone(name) return name - def copy_bone(self, bone_name, new_name='', *, parent=False, bbone=False, length=None, scale=None): + def copy_bone(self, bone_name, new_name='', *, parent=False, inherit_scale=False, bbone=False, length=None, scale=None): """Copy the bone with the given name, returning the new name.""" - name = copy_bone(self.obj, bone_name, new_name, parent=parent, bbone=bbone, length=length, scale=scale) + name = copy_bone(self.obj, bone_name, new_name, parent=parent, inherit_scale=inherit_scale, bbone=bbone, length=length, scale=scale) self.register_new_bone(name, bone_name) return name diff --git a/rigify/utils/rig.py b/rigify/utils/rig.py index e1957a21..bcb3ff74 100644 --- a/rigify/utils/rig.py +++ b/rigify/utils/rig.py @@ -23,6 +23,8 @@ import importlib import importlib.util import os +from bpy.types import bpy_struct, bpy_prop_array, Constraint + RIG_DIR = "rigs" # Name of the directory where rig types are kept METARIG_DIR = "metarigs" # Name of the directory where metarigs are kept TEMPLATE_DIR = "ui_templates" # Name of the directory where ui templates are kept @@ -147,6 +149,30 @@ def list_bone_names_depth_first_sorted(obj): return result_list +def _get_property_value(obj, name): + value = getattr(obj, name, None) + if isinstance(value, bpy_prop_array): + value = tuple(value) + return value + +def _generate_properties(lines, prefix, obj, base_class, *, defaults={}, objects={}): + block_props = set(prop.identifier for prop in base_class.bl_rna.properties) - set(defaults.keys()) + + for prop in type(obj).bl_rna.properties: + if prop.identifier not in block_props and not prop.is_readonly: + cur_value = _get_property_value(obj, prop.identifier) + + if prop.identifier in defaults: + if cur_value == defaults[prop.identifier]: + continue + + if isinstance(cur_value, bpy_struct): + if cur_value in objects: + lines.append('%s.%s = %s' % (prefix, prop.identifier, objects[cur_value])) + else: + lines.append('%s.%s = %r' % (prefix, prop.identifier, cur_value)) + + def write_metarig(obj, layers=False, func_name="create", groups=False): """ Write a metarig as a python script, this rig is to have all info needed for @@ -211,6 +237,8 @@ def write_metarig(obj, layers=False, func_name="create", groups=False): code.append(" bone.tail = %.4f, %.4f, %.4f" % bone.tail.to_tuple(4)) code.append(" bone.roll = %.4f" % bone.roll) code.append(" bone.use_connect = %s" % str(bone.use_connect)) + if bone.inherit_scale != 'FULL': + code.append(" bone.inherit_scale = %r" % str(bone.inherit_scale)) if bone.parent: code.append(" bone.parent = arm.edit_bones[bones[%r]]" % bone.parent.name) code.append(" bones[%r] = bone.name" % bone.name) @@ -243,6 +271,29 @@ def write_metarig(obj, layers=False, func_name="create", groups=False): code.append(" pbone.rigify_parameters.%s = %s" % (param_name, str(param))) code.append(" except AttributeError:") code.append(" pass") + # Constraints + for con in pbone.constraints: + code.append(" con = pbone.constraints.new(%r)" % (con.type)) + code.append(" con.name = %r" % (con.name)) + # Add target first because of target_space handling + if con.type == 'ARMATURE': + for tgt in con.targets: + code.append(" tgt = con.targets.new()") + code.append(" tgt.target = obj") + code.append(" tgt.subtarget = %r" % (tgt.subtarget)) + code.append(" tgt.weight = %.3f" % (tgt.weight)) + elif getattr(con, 'target', None) == obj: + code.append(" con.target = obj") + # Generic properties + _generate_properties( + code, " con", con, Constraint, + defaults={ + 'owner_space': 'WORLD', 'target_space': 'WORLD', + 'mute': False, 'influence': 1.0, + 'target': obj, + }, + objects={obj: 'obj'}, + ) code.append("\n bpy.ops.object.mode_set(mode='EDIT')") code.append(" for bone in arm.edit_bones:") |