[Bf-extensions-cvs] [a50e8748] master: Rigify: replace Rename To Deform with a new basic.raw_copy rig.

Alexander Gavrilov noreply at git.blender.org
Sun Dec 22 16:52:34 CET 2019


Commit: a50e8748493ac28723ce7dca502daf04de0afb0f
Author: Alexander Gavrilov
Date:   Sun Dec 22 18:27:27 2019 +0300
Branches: master
https://developer.blender.org/rBAa50e8748493ac28723ce7dca502daf04de0afb0f

Rigify: replace Rename To Deform with a new basic.raw_copy rig.

Add a separate rig aimed at transferring bones from the metarig
completely verbatim without the ORG prefix, and remove the hacky
copy_chain/super_copy option for renaming ORG to DEF. Share the
constraint retargeting feature between super_copy and raw_copy.

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

M	rigify/base_generate.py
M	rigify/generate.py
M	rigify/rigs/basic/copy_chain.py
A	rigify/rigs/basic/raw_copy.py
M	rigify/rigs/basic/super_copy.py

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

diff --git a/rigify/base_generate.py b/rigify/base_generate.py
index 651e0612..ea1415c9 100644
--- a/rigify/base_generate.py
+++ b/rigify/base_generate.py
@@ -219,6 +219,9 @@ class BaseGenerator:
         # different rigs don't collide id's
         self.rig_id = random_id(16)
 
+        # Table of renamed ORG bones
+        self.org_rename_table = dict()
+
 
     def disable_auto_parent(self, bone_name):
         """Prevent automatically parenting the bone to root if parentless."""
@@ -231,6 +234,20 @@ class BaseGenerator:
                 self.layer_group_priorities[bone_name][i] = priority
 
 
+    def rename_org_bone(self, old_name, new_name):
+        assert self.stage == 'instantiate'
+        assert old_name == self.org_rename_table.get(old_name, None)
+        assert old_name not in self.bone_owners
+
+        bone = self.obj.data.bones[old_name]
+
+        bone.name = new_name
+        new_name = bone.name
+
+        self.org_rename_table[old_name] = new_name
+        return new_name
+
+
     def __run_object_stage(self, method_name):
         assert(self.context.active_object == self.obj)
         assert(self.obj.mode == 'OBJECT')
@@ -431,9 +448,16 @@ class BaseGenerator:
         assert(self.context.active_object == self.obj)
         assert(self.obj.mode == 'OBJECT')
 
+        self.stage = 'instantiate'
+
+        # Compute the list of bones
+        bone_list = list_bone_names_depth_first_sorted(self.obj)
+
+        self.org_rename_table = {n: n for n in bone_list}
+
         # Construct the rig instances
-        for name in list_bone_names_depth_first_sorted(self.obj):
-            self.__create_rigs(name, halt_on_missing)
+        for name in bone_list:
+            self.__create_rigs(self.org_rename_table[name], halt_on_missing)
 
         # Connect rigs and bones into a tree
         handled = {}
diff --git a/rigify/generate.py b/rigify/generate.py
index 8e3ca0f0..0fe89175 100644
--- a/rigify/generate.py
+++ b/rigify/generate.py
@@ -287,7 +287,9 @@ class Generator(base_generate.BaseGenerator):
                             and prop in obj.pose.bones[bone].keys():
                                 tar.data_path = tar.data_path[7:]
                             else:
-                                tar.data_path = 'pose.bones["%s"]["%s"]' % (make_original_name(bone), prop)
+                                org_name = make_original_name(bone)
+                                org_name = self.org_rename_table.get(org_name, org_name)
+                                tar.data_path = 'pose.bones["%s"]["%s"]' % (org_name, prop)
 
 
     def __assign_widgets(self):
diff --git a/rigify/rigs/basic/copy_chain.py b/rigify/rigs/basic/copy_chain.py
index a3920ced..232671f0 100644
--- a/rigify/rigs/basic/copy_chain.py
+++ b/rigify/rigs/basic/copy_chain.py
@@ -22,7 +22,6 @@ import bpy
 
 from ..chain_rigs import SimpleChainRig
 
-from ...utils.layers import DEF_LAYER
 from ...utils.errors import MetarigError
 from ...utils.rig import connected_children_names
 from ...utils.naming import make_derived_name
@@ -42,12 +41,7 @@ class Rig(SimpleChainRig):
         """ Gather and validate data about the rig.
         """
         self.make_controls = self.params.make_controls
-
-        deform = self.params.make_deforms
-        rename = self.params.rename_to_deform
-
-        self.make_deforms = deform and not rename
-        self.rename_deforms = deform and rename
+        self.make_deforms = self.params.make_deforms
 
     ##############################
     # Control chain
@@ -98,18 +92,6 @@ class Rig(SimpleChainRig):
         if self.make_deforms:
             super().rig_deform_chain()
 
-    ##############################
-    # Rename To Deform
-
-    def finalize(self):
-        if self.rename_deform:
-            new_names = [ self.rename_bone(name, make_derived_name(name, 'def')) for name in self.bones.org ]
-
-            for name in new_names:
-                bone = self.get_bone(name).bone
-                bone.use_deform = True
-                bone.layers = DEF_LAYER
-
     ##############################
     # Parameter UI
 
@@ -121,12 +103,6 @@ class Rig(SimpleChainRig):
         params.make_controls = bpy.props.BoolProperty(name="Controls", default=True, description="Create control bones for the copy")
         params.make_deforms = bpy.props.BoolProperty(name="Deform", default=True, description="Create deform bones for the copy")
 
-        params.rename_to_deform = bpy.props.BoolProperty(
-            name        = "Rename To Deform",
-            default     = False,
-            description = "Rename the original bone itself to use as deform bone (advanced feature)"
-        )
-
     @classmethod
     def parameters_ui(self, layout, params):
         """ Create the ui for the rig parameters.
@@ -136,10 +112,6 @@ class Rig(SimpleChainRig):
         r = layout.row()
         r.prop(params, "make_deforms")
 
-        if params.make_deforms:
-            r = layout.row()
-            r.prop(params, "rename_to_deform")
-
 
 def create_sample(obj):
     """ Create a sample metarig for this rig type.
diff --git a/rigify/rigs/basic/raw_copy.py b/rigify/rigs/basic/raw_copy.py
new file mode 100644
index 00000000..3b45e090
--- /dev/null
+++ b/rigify/rigs/basic/raw_copy.py
@@ -0,0 +1,188 @@
+#====================== BEGIN GPL LICENSE BLOCK ======================
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#======================= END GPL LICENSE BLOCK ========================
+
+# <pep8 compliant>
+
+import bpy
+
+from ...utils.naming import strip_org, strip_prefix
+
+from ...base_rig import BaseRig
+from ...base_generate import SubstitutionRig
+
+from itertools import repeat
+
+
+class Rig(SubstitutionRig):
+    """ A raw copy rig, preserving the metarig bone as is, without the ORG prefix. """
+
+    def substitute(self):
+        # Strip the ORG prefix during the rig instantiation phase
+        new_name = strip_org(self.base_bone)
+        new_name = self.generator.rename_org_bone(self.base_bone, new_name)
+
+        return [ self.instantiate_rig(InstanceRig, new_name) ]
+
+
+class RelinkConstraintsMixin:
+    """ Utilities for constraint relinking. """
+
+    def relink_bone_constraints(self, bone_name):
+        if self.params.relink_constraints:
+            for con in self.get_bone(bone_name).constraints:
+                parts = con.name.split('@')
+
+                if len(parts) > 1:
+                    self.relink_constraint(con, parts[1:])
+
+
+    def relink_bone_parent(self, bone_name):
+        if self.params.relink_constraints:
+            self.generator.disable_auto_parent(bone_name)
+
+            parent_spec = self.params.parent_bone
+            if parent_spec:
+                old_parent = self.get_bone_parent(bone_name)
+                new_parent = self.find_relink_target(parent_spec, old_parent or '') or None
+                self.set_bone_parent(bone_name, new_parent)
+                return new_parent
+
+
+    def relink_constraint(self, con, specs):
+        if con.type == 'ARMATURE':
+            if len(specs) == 1:
+                specs = repeat(specs[0])
+            elif len(specs) != len(con.targets):
+                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 == 'CTRL':
+            spec = strip_prefix(old_target)
+        elif spec in {'DEF', 'MCH'}:
+            spec = spec + '-' + strip_prefix(old_target)
+
+        if spec not in self.obj.pose.bones:
+            self.report_error("Cannot find bone '{}' for relinking", spec)
+
+        return spec
+
+
+    @classmethod
+    def add_relink_constraints_params(self, params):
+        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 '@CTRL', '@DEF' or '@MCH' to simply replace 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 CTRL, DEF or MCH will replace the prefix instead"
+        )
+
+    @classmethod
+    def add_relink_constraints_ui(self, layout, params):
+        r = layout.row()
+        r.prop(params, "relink_constraints")
+
+        if params.relink_constraints:
+            r = layout.row()
+            r.prop(params, "parent_bone")
+
+
+class InstanceRig(BaseRig, RelinkConstraintsMixin):
+    def find_org_bones(self, pose_bone):
+        return pose_bone.name
+
+    def initialize(self):
+        self.relink = self.params.relink_constraints
+
+    def parent_bones(self):
+        self.relink_bone_parent(self.bones.org)
+
+    def rig_bones(self):
+        self.relink_bone_constraints(self.bones.org)
+
+    @classmethod
+    def add_parameters(self, params):
+        self.add_reli

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list