[Bf-extensions-cvs] [67f1fbca] master: Rigify: support switchable parents in the basic.pivot rig.

Alexander Gavrilov noreply at git.blender.org
Sat Nov 2 14:13:06 CET 2019


Commit: 67f1fbca1482d9d9362a4001332e785c3fd5d230
Author: Alexander Gavrilov
Date:   Sat Nov 2 16:08:26 2019 +0300
Branches: master
https://developer.blender.org/rBA67f1fbca1482d9d9362a4001332e785c3fd5d230

Rigify: support switchable parents in the basic.pivot rig.

Implement options to generate a parent switch mechanism for the
main pivot control, and to register the pivot as a parent for other
rigs to use (including support for one level parent injection).

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

M	rigify/rigs/basic/pivot.py
M	rigify/rigs/limbs/super_palm.py
M	rigify/rigs/spines/super_head.py
M	rigify/utils/switch_parent.py

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

diff --git a/rigify/rigs/basic/pivot.py b/rigify/rigs/basic/pivot.py
index c0625c1a..e5d31659 100644
--- a/rigify/rigs/basic/pivot.py
+++ b/rigify/rigs/basic/pivot.py
@@ -23,7 +23,9 @@ import bpy
 from ...base_rig import BaseRig
 
 from ...utils.naming import make_derived_name
+from ...utils.bones import set_bone_widget_transform
 from ...utils.widgets_basic import create_cube_widget, create_pivot_widget
+from ...utils.switch_parent import SwitchParentBuilder
 
 
 class Rig(BaseRig):
@@ -34,54 +36,134 @@ class Rig(BaseRig):
 
     def initialize(self):
         self.make_control = self.params.make_extra_control
+        self.make_pivot = self.params.make_control or not self.make_control
         self.make_deform  = self.params.make_extra_deform
 
 
     def generate_bones(self):
         org = self.bones.org
 
-        self.bones.ctrl.pivot = self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=not self.make_control)
-
         if self.make_control:
-            self.bones.ctrl.master = self.copy_bone(org, make_derived_name(org, 'ctrl', '_master'), parent=True)
+            self.bones.ctrl.master = name = self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=True)
+
+            if self.make_pivot:
+                self.bones.ctrl.pivot = self.copy_bone(org, make_derived_name(org, 'ctrl', '_pivot'))
+
+            if self.params.make_parent_switch:
+                self.build_parent_switch(name)
+
+            if self.params.register_parent:
+                self.register_parent(name, self.get_parent_tags())
+
+        else:
+            self.bones.ctrl.pivot = self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=True)
 
         if self.make_deform:
             self.bones.deform = self.copy_bone(org, make_derived_name(org, 'def'), bbone=True)
 
 
+    def build_parent_switch(self, master_name):
+        pbuilder = SwitchParentBuilder(self.generator)
+
+        org_parent = self.get_bone_parent(self.bones.org)
+        parents = [org_parent] if org_parent else []
+
+        pbuilder.build_child(
+            self, master_name,
+            context_rig=self.rigify_parent, allow_self=True,
+            prop_name="Parent ({})".format(master_name),
+            extra_parents=parents, select_parent=org_parent,
+            controls=lambda: self.bones.ctrl.flatten()
+        )
+
+    def get_parent_tags(self):
+        tags = {t.strip() for t in self.params.register_parent_tags.split(',')}
+
+        if self.params.make_parent_switch:
+            tags.add('child')
+
+        tags.discard('')
+        return tags
+
+    def register_parent(self, master_name, tags):
+        pbuilder = SwitchParentBuilder(self.generator)
+
+        inject = self.rigify_parent if 'injected' in tags else None
+
+        pbuilder.register_parent(
+            self, self.bones.org, name=master_name,
+            inject_into=inject, tags=tags
+        )
+
+
     def parent_bones(self):
-        if self.make_control:
-            self.set_bone_parent(self.bones.ctrl.pivot, self.bones.ctrl.master, use_connect=False)
+        ctrl = self.bones.ctrl
+
+        if self.make_pivot:
+            if self.make_control:
+                self.set_bone_parent(ctrl.pivot, ctrl.master, use_connect=False)
 
-        self.set_bone_parent(self.bones.org, self.bones.ctrl.pivot, use_connect=False)
+            self.set_bone_parent(self.bones.org, ctrl.pivot, use_connect=False)
+
+        else:
+            self.set_bone_parent(self.bones.org, ctrl.master, use_connect=False)
 
         if self.make_deform:
             self.set_bone_parent(self.bones.deform, self.bones.org, use_connect=False)
 
 
     def configure_bones(self):
-        self.copy_bone_properties(self.bones.org, self.bones.ctrl.pivot)
-
         if self.make_control:
             self.copy_bone_properties(self.bones.org, self.bones.ctrl.master)
 
+        else:
+            self.copy_bone_properties(self.bones.org, self.bones.ctrl.pivot)
+
 
     def rig_bones(self):
-        self.make_constraint(
-            self.bones.org, 'COPY_LOCATION', self.bones.ctrl.pivot,
-            space='LOCAL', invert_xyz=(True,)*3
-        )
+        if self.make_pivot:
+            self.make_constraint(
+                self.bones.org, 'COPY_LOCATION', self.bones.ctrl.pivot,
+                space='LOCAL', invert_xyz=(True,)*3
+            )
 
 
     def generate_widgets(self):
-        create_pivot_widget(self.obj, self.bones.ctrl.pivot, square=True, axis_size=2.0)
+        if self.make_pivot:
+            create_pivot_widget(self.obj, self.bones.ctrl.pivot, square=True, axis_size=2.0)
 
         if self.make_control:
+            set_bone_widget_transform(self.obj, self.bones.ctrl.master, self.bones.org)
+
             create_cube_widget(self.obj, self.bones.ctrl.master, radius=0.5)
 
 
     @classmethod
     def add_parameters(self, params):
+        params.make_control = bpy.props.BoolProperty(
+            name        = "Control",
+            default     = True,
+            description = "Create a control bone for the copy"
+        )
+
+        params.make_parent_switch = bpy.props.BoolProperty(
+            name        = "Switchable Parent",
+            default     = False,
+            description = "Allow switching the parent of the master control"
+        )
+
+        params.register_parent = bpy.props.BoolProperty(
+            name        = "Register Parent",
+            default     = False,
+            description = "Register the control as a switchable parent candidate"
+        )
+
+        params.register_parent_tags = bpy.props.StringProperty(
+            name        = "Parent Tags",
+            default     = "",
+            description = "Comma-separated tags to use for the registered parent"
+        )
+
         params.make_extra_control = bpy.props.BoolProperty(
             name        = "Extra Control",
             default     = False,
@@ -98,7 +180,18 @@ class Rig(BaseRig):
     @classmethod
     def parameters_ui(self, layout, params):
         r = layout.row()
-        r.prop(params, "make_extra_control", text="Extra Master Control")
+        r.prop(params, "make_extra_control", text="Master Control")
+
+        if params.make_extra_control:
+            layout.prop(params, "make_parent_switch")
+            layout.prop(params, "register_parent")
+
+            r = layout.row()
+            r.active = params.register_parent
+            r.prop(params, "register_parent_tags", text="Tags")
+
+            layout.prop(params, "make_control", text="Pivot Control")
+
         r = layout.row()
         r.prop(params, "make_extra_deform", text="Deform Bone")
 
@@ -112,15 +205,15 @@ def create_sample(obj):
 
     bones = {}
 
-    bone = arm.edit_bones.new('Bone')
+    bone = arm.edit_bones.new('pivot')
     bone.head[:] = 0.0000, 0.0000, 0.0000
-    bone.tail[:] = 0.0000, 0.0000, 0.2000
+    bone.tail[:] = 0.0000, 0.5000, 0.0000
     bone.roll = 0.0000
     bone.use_connect = False
-    bones['Bone'] = bone.name
+    bones['pivot'] = bone.name
 
     bpy.ops.object.mode_set(mode='OBJECT')
-    pbone = obj.pose.bones[bones['Bone']]
+    pbone = obj.pose.bones[bones['pivot']]
     pbone.rigify_type = 'basic.pivot'
     pbone.lock_location = (False, False, False)
     pbone.lock_rotation = (False, False, False)
diff --git a/rigify/rigs/limbs/super_palm.py b/rigify/rigs/limbs/super_palm.py
index 8bcbabf8..9c03b2fe 100644
--- a/rigify/rigs/limbs/super_palm.py
+++ b/rigify/rigs/limbs/super_palm.py
@@ -24,6 +24,7 @@ import re
 from math import cos, pi
 from itertools import count, repeat
 
+from rigify.utils.rig import is_rig_base_bone
 from rigify.utils.naming import strip_org, make_derived_name
 from rigify.utils.widgets import create_widget
 from rigify.utils.misc import map_list
@@ -43,7 +44,7 @@ def bone_siblings(obj, bone):
     bones = []
 
     for b in parent.children:
-        if b.name != bone:
+        if b.name != bone and not is_rig_base_bone(obj, b.name):
             bones += [b.name]
 
     return bones
diff --git a/rigify/rigs/spines/super_head.py b/rigify/rigs/spines/super_head.py
index 65db79cc..15f011f7 100644
--- a/rigify/rigs/spines/super_head.py
+++ b/rigify/rigs/spines/super_head.py
@@ -322,7 +322,10 @@ class Rig(BaseHeadTailRig):
     def register_parent_bones(self):
         rig = self.rigify_parent or self
         builder = SwitchParentBuilder(self.generator)
-        builder.register_parent(rig, self.bones.org[-1], name='Head', exclude_self=True, tags={'head'})
+        builder.register_parent(
+            self, self.bones.org[-1], name='Head',
+            inject_into=rig, exclude_self=True, tags={'head'},
+        )
 
     @stage.configure_bones
     def configure_bbone_chain(self):
diff --git a/rigify/utils/switch_parent.py b/rigify/utils/switch_parent.py
index 8247a7c8..61721266 100644
--- a/rigify/utils/switch_parent.py
+++ b/rigify/utils/switch_parent.py
@@ -51,7 +51,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
     ##############################
     # API
 
-    def register_parent(self, rig, bone, *, name=None, is_global=False, exclude_self=False, tags=None):
+    def register_parent(self, rig, bone, *, name=None, is_global=False, exclude_self=False, inject_into=None, tags=None):
         """
         Registers a bone of the specified rig as a possible parent.
 
@@ -61,6 +61,7 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
           name              Name of the parent for mouse-over hint.
           is_global         The parent is accessible to all rigs, instead of just children of owner.
           exclude_self      The parent is invisible to the owner rig itself.
+          inject_into       Make this parent available to children of the specified rig.
           tags              Set of tags to use for default parent selection.
 
         Lazy creation:
@@ -70,10 +71,19 @@ class SwitchParentBuilder(GeneratorPlugin, MechanismUtilityMixin):
 
         assert not self.frozen
         assert isinstance(bone, str) or callable(bone)
+        assert callable(bone) or _rig_is_child(rig, self.generator.bone_owners[bone])
+        assert _rig_is_child(rig, inject_into)
+
+        real_rig = rig
+
+        if inject_into an

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list