[Bf-extensions-cvs] [feb02092] master: Rigify: add super_copy options to replace parent and constraint targets.

Alexander Gavrilov noreply at git.blender.org
Mon Nov 4 12:23:10 CET 2019


Commit: feb02092bca9560e84748b7157e08ce7db2f5477
Author: Alexander Gavrilov
Date:   Mon Nov 4 14:20:33 2019 +0300
Branches: master
https://developer.blender.org/rBAfeb02092bca9560e84748b7157e08ce7db2f5477

Rigify: add super_copy options to replace parent and constraint targets.

Allow replacing the parent bone and constraint targets after all
bones have been generated. When enabled, constraints with a '@bone'
notation in their name will have their target bone replaced with
the one from the name. Using just 'MCH' or 'DEF' will replace the
prefix of the existing target. The parent bone can be replaced via
a string input field in rig options.

Tested by wrapping the simple muscle system of MB-Lab.

===================================================================

M	rigify/rigs/basic/super_copy.py

===================================================================

diff --git a/rigify/rigs/basic/super_copy.py b/rigify/rigs/basic/super_copy.py
index 5fc589c4..f55dce68 100644
--- a/rigify/rigs/basic/super_copy.py
+++ b/rigify/rigs/basic/super_copy.py
@@ -26,6 +26,8 @@ from ...utils.layers import DEF_LAYER
 from ...utils.naming import strip_org, make_deformer_name
 from ...utils.widgets_basic import create_bone_widget, create_circle_widget
 
+from itertools import repeat
+
 
 class Rig(BaseRig):
     """ A "copy" rig.  All it does is duplicate the original bone and
@@ -51,6 +53,8 @@ class Rig(BaseRig):
         self.make_deform  = deform and not rename
         self.rename_deform = deform and rename
 
+        self.relink = self.params.relink_constraints
+
 
     def generate_bones(self):
         bones = self.bones
@@ -70,6 +74,18 @@ class Rig(BaseRig):
         if self.make_deform:
             self.set_bone_parent(bones.deform, bones.org, use_connect=False)
 
+        if self.relink:
+            self.generator.disable_auto_parent(bones.org)
+
+            parent_spec = self.params.parent_bone
+            if parent_spec:
+                old_parent = self.get_bone_parent(bones.org)
+                new_parent = self.find_relink_target(parent_spec, old_parent or '') or None
+                self.set_bone_parent(bones.org, new_parent)
+
+                if self.make_control:
+                    self.set_bone_parent(bones.ctrl, new_parent)
+
 
     def configure_bones(self):
         bones = self.bones
@@ -81,9 +97,53 @@ class Rig(BaseRig):
     def rig_bones(self):
         bones = self.bones
 
+        if self.relink:
+            for con in self.get_bone(bones.org).constraints:
+                parts = con.name.split('@')
+
+                if len(parts) > 1:
+                    self.relink_constraint(con, parts[1:])
+
         if self.make_control:
             # Constrain the original bone.
-            self.make_constraint(bones.org, 'COPY_TRANSFORMS', bones.ctrl)
+            self.make_constraint(bones.org, 'COPY_TRANSFORMS', bones.ctrl, insert_index=0)
+
+    def relink_constraint(self, con, specs):
+        if con.type == 'ARMATURE':
+            if len(specs) == 1:
+                specs = repeat(specs[0])
+            elif len(specs) != len(con.specs):
+                self.report_error("Constraint {} actually has {} targets", con.name, len(con.targets))
+
+            for tgt, spec in zip(con.targets, specs):
+                tgt.subtarget = self.find_relink_target(spec, tgt.subtarget)
+
+        else:
+            if len(specs) > 1:
+                self.report_error("Only the Armature constraint can have multiple '@' targets: {}", con.name)
+
+            con.subtarget = self.find_relink_target(specs[0], con.subtarget)
+
+    def find_relink_target(self, spec, old_target):
+        if spec == '':
+            return old_target
+        elif spec in {'DEF', 'MCH'}:
+            spec = spec + '-' + strip_org(old_target)
+
+        if spec not in self.obj.pose.bones:
+            # Hack: allow referring to copy rigs using Rename To Deform as DEF
+            if old_target.startswith('ORG-') and spec == make_deformer_name(strip_org(old_target)):
+                from . import copy_chain
+
+                owner = self.generator.bone_owners.get(old_target)
+
+                if ((isinstance(owner, Rig) and owner.rename_deform) or
+                    (isinstance(owner, copy_chain.Rig) and owner.rename_deforms)):
+                    return old_target
+
+            self.report_error("Cannot find bone '{}' for relinking", spec)
+
+        return spec
 
 
     def generate_widgets(self):
@@ -135,6 +195,18 @@ class Rig(BaseRig):
             description = "Rename the original bone itself to use as deform bone (advanced feature)"
         )
 
+        params.relink_constraints = bpy.props.BoolProperty(
+            name        = "Relink Constraints",
+            default     = False,
+            description = "For constraints with names formed like 'base at bonename', use the part after '@' as the new subtarget after all bones are created. Use '@DEF' or '@MCH' to simply prepend the prefix"
+        )
+
+        params.parent_bone = bpy.props.StringProperty(
+            name        = "Parent",
+            default     = "",
+            description = "Replace the parent with a different bone after all bones are created. Using simply DEF or MCH will prepend the prefix instead"
+        )
+
 
     @classmethod
     def parameters_ui(self, layout, params):
@@ -152,6 +224,13 @@ class Rig(BaseRig):
             r = layout.row()
             r.prop(params, "rename_to_deform")
 
+        r = layout.row()
+        r.prop(params, "relink_constraints")
+
+        if params.relink_constraints:
+            r = layout.row()
+            r.prop(params, "parent_bone")
+
 
 def create_sample(obj):
     """ Create a sample metarig for this rig type.



More information about the Bf-extensions-cvs mailing list