[Bf-extensions-cvs] [ad222633] master: Rigify: annotate and fix warnings in skin rigs.

Alexander Gavrilov noreply at git.blender.org
Mon Nov 21 00:24:22 CET 2022


Commit: ad22263327d99f828772922daaa00505f528df0a
Author: Alexander Gavrilov
Date:   Wed Nov 16 19:29:03 2022 +0200
Branches: master
https://developer.blender.org/rBAad22263327d99f828772922daaa00505f528df0a

Rigify: annotate and fix warnings in skin rigs.

- Extract an even more bare version of ControlBoneParentBase that can
  act as a common superclass of no-op parent builders like Org.
- Introduce ControlBoneParentBase.replace_nested for proper polymorphism.
- Introduce BaseSkinNode.control_node to fix armature parent builder.
- Annotate types and fix warnings in all skin and new face rigs.

This should cause no behavior changes. Now rigify/rigs/ is warning free.

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

M	rigify/rigs/face/basic_tongue.py
M	rigify/rigs/face/skin_eye.py
M	rigify/rigs/face/skin_jaw.py
M	rigify/rigs/skin/anchor.py
M	rigify/rigs/skin/basic_chain.py
M	rigify/rigs/skin/glue.py
M	rigify/rigs/skin/skin_nodes.py
M	rigify/rigs/skin/skin_parents.py
M	rigify/rigs/skin/skin_rigs.py
M	rigify/rigs/skin/stretchy_chain.py
M	rigify/rigs/skin/transform/basic.py
M	rigify/utils/misc.py
M	rigify/utils/node_merger.py

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

diff --git a/rigify/rigs/face/basic_tongue.py b/rigify/rigs/face/basic_tongue.py
index 62a31022..3acfc624 100644
--- a/rigify/rigs/face/basic_tongue.py
+++ b/rigify/rigs/face/basic_tongue.py
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 import bpy
-import math
 
 from itertools import count
 
@@ -17,7 +16,7 @@ from ..widgets import create_jaw_widget
 
 
 class Rig(TweakChainRig):
-    """Basic tongue from the original PitchiPoy face rig."""
+    """Basic tongue from the original PitchiPoy face rig."""  # noqa
 
     min_chain_length = 3
 
@@ -28,15 +27,19 @@ class Rig(TweakChainRig):
 
     ####################################################
     # BONES
-    #
-    # ctrl:
-    #   master:
-    #     Master control.
-    # mch:
-    #   follow[]:
-    #     Partial follow master bones.
-    #
-    ####################################################
+
+    class CtrlBones(TweakChainRig.CtrlBones):
+        master: str                    # Master control.
+
+    class MchBones(TweakChainRig.MchBones):
+        follow: list[str]              # Partial follow master bones.
+
+    bones: TweakChainRig.ToplevelBones[
+        list[str],
+        'Rig.CtrlBones',
+        'Rig.MchBones',
+        list[str]
+    ]
 
     ####################################################
     # Control chain
@@ -71,7 +74,7 @@ class Rig(TweakChainRig):
     def make_follow_chain(self):
         self.bones.mch.follow = map_list(self.make_mch_follow_bone, count(1), self.bones.org[1:])
 
-    def make_mch_follow_bone(self, i, org):
+    def make_mch_follow_bone(self, _i: int, org: str):
         name = self.copy_bone(org, make_derived_name(org, 'mch'))
         copy_bone_position(self.obj, self.base_bone, name)
         flip_bone(self.obj, name)
@@ -104,7 +107,7 @@ class Rig(TweakChainRig):
     # SETTINGS
 
     @classmethod
-    def add_parameters(self, params):
+    def add_parameters(cls, params):
         params.bbones = bpy.props.IntProperty(
             name='B-Bone Segments',
             default=10,
@@ -115,7 +118,7 @@ class Rig(TweakChainRig):
         ControlLayersOption.SKIN_PRIMARY.add_parameters(params)
 
     @classmethod
-    def parameters_ui(self, layout, params):
+    def parameters_ui(cls, layout, params):
         layout.prop(params, 'bbones')
 
         ControlLayersOption.SKIN_PRIMARY.parameters_ui(layout, params)
diff --git a/rigify/rigs/face/skin_eye.py b/rigify/rigs/face/skin_eye.py
index 154b555c..b02fc9f0 100644
--- a/rigify/rigs/face/skin_eye.py
+++ b/rigify/rigs/face/skin_eye.py
@@ -2,24 +2,26 @@
 
 import bpy
 import math
-import functools
 import mathutils
 
-from itertools import count
+from typing import Optional
+
+from bpy.types import PoseBone
 from mathutils import Vector, Matrix
 
+from ...rig_ui_template import PanelLayout
 from ...utils.naming import make_derived_name, mirror_name, change_name_side, Side, SideZ
-from ...utils.bones import align_bone_z_axis, put_bone
+from ...utils.bones import align_bone_z_axis, put_bone, TypedBoneDict
 from ...utils.widgets import (widget_generator, generate_circle_geometry,
                               generate_circle_hull_geometry)
 from ...utils.widgets_basic import create_circle_widget
 from ...utils.switch_parent import SwitchParentBuilder
-from ...utils.misc import map_list, matrix_from_axis_pair, LazyRef
+from ...utils.misc import matrix_from_axis_pair, LazyRef
 
 from ...base_rig import stage, RigComponent
 
-from ..skin.skin_nodes import ControlBoneNode
-from ..skin.skin_parents import ControlBoneParentOffset
+from ..skin.skin_nodes import ControlBoneNode, BaseSkinNode
+from ..skin.skin_parents import ControlBoneParentOffset, ControlBoneParentBase
 from ..skin.skin_rigs import BaseSkinRig
 
 from ..skin.basic_chain import Rig as BasicChainRig
@@ -31,11 +33,20 @@ class Rig(BaseSkinRig):
     connect at their ends using T/B symmetry.
     """
 
-    def find_org_bones(self, bone):
+    def find_org_bones(self, bone: PoseBone) -> str:
         return bone.name
 
     cluster_control = None
 
+    center: Vector
+    axis: Vector
+
+    eye_corner_nodes: list[ControlBoneNode]
+    eye_corner_matrix: Optional[Matrix]
+    eye_corner_range: tuple[float, float]
+
+    child_chains: list[BasicChainRig]
+
     def initialize(self):
         super().initialize()
 
@@ -58,10 +69,11 @@ class Rig(BaseSkinRig):
     ####################################################
     # UTILITIES
 
-    def is_eye_control_node(self, node):
+    def is_eye_control_node(self, node: ControlBoneNode) -> bool:
         return node.rig in self.child_chains and node.is_master_node
 
-    def is_eye_corner_node(self, node):
+    # noinspection PyMethodMayBeStatic
+    def is_eye_corner_node(self, node: ControlBoneNode) -> bool:
         # Corners are nodes where the two T and B chains merge
         sides = set(n.name_split.side_z for n in node.get_merged_siblings())
         return {SideZ.BOTTOM, SideZ.TOP}.issubset(sides)
@@ -82,67 +94,68 @@ class Rig(BaseSkinRig):
         self.eye_corner_matrix = matrix.inverted()
 
         # Compute signed angles from space_axis to the eye corners
-        amin, amax = self.eye_corner_range = list(
-            sorted(map(self.get_eye_corner_angle, self.eye_corner_nodes)))
+        angle_min, angle_max = sorted(map(self.get_eye_corner_angle, self.eye_corner_nodes))
+
+        self.eye_corner_range = (angle_min, angle_max)
 
-        if not (amin <= 0 <= amax):
+        if not (angle_min <= 0 <= angle_max):
             self.raise_error('Bad relative angles of eye corners: {}..{}',
-                             math.degrees(amin), math.degrees(amax))
+                             math.degrees(angle_min), math.degrees(angle_max))
 
-    def get_eye_corner_angle(self, node):
+    def get_eye_corner_angle(self, node: ControlBoneNode) -> float:
         """Compute a signed Z rotation angle from the eye axis to the node."""
         pt = self.eye_corner_matrix @ node.point
         return math.atan2(pt.x, pt.y)
 
-    def get_master_control_position(self):
+    def get_master_control_position(self) -> Vector:
         """Compute suitable position for the master control."""
         self.init_eye_corner_space()
 
         # Place the control between the two corners on the eye axis
-        pcorners = [node.point for node in self.eye_corner_nodes]
+        corner_points = [node.point for node in self.eye_corner_nodes]
 
         point, _ = mathutils.geometry.intersect_line_line(
-            self.center, self.center + self.axis, pcorners[0], pcorners[1]
+            self.center, self.center + self.axis, corner_points[0], corner_points[1]
         )
         return point
 
-    def get_lid_follow_influence(self, node):
+    def get_lid_follow_influence(self, node: ControlBoneNode):
         """Compute the influence factor of the eye movement on this eyelid control node."""
         self.init_eye_corner_space()
 
         # Interpolate from axis to corners based on Z angle
         angle = self.get_eye_corner_angle(node)
-        amin, amax = self.eye_corner_range
+        angle_min, angle_max = self.eye_corner_range
 
-        if amin < angle < 0:
-            return 1 - min(1, angle/amin) ** 2
-        elif 0 < angle < amax:
-            return 1 - min(1, angle/amax) ** 2
+        if angle_min < angle < 0:
+            return 1 - min(1.0, angle/angle_min) ** 2
+        elif 0 < angle < angle_max:
+            return 1 - min(1.0, angle/angle_max) ** 2
         else:
             return 0
 
     ####################################################
     # BONES
-    #
-    # ctrl:
-    #   master:
-    #     Parent control for moving the whole eye.
-    #   target:
-    #     Individual target this eye aims for.
-    # mch:
-    #   master:
-    #     Bone that rotates to track ctrl.target.
-    #   track:
-    #     Bone that translates to follow mch.master tail.
-    # deform:
-    #   master:
-    #     Deform mirror of ctrl.master.
-    #   eye:
-    #     Deform bone that rotates with mch.master.
-    #   iris:
-    #     Iris deform bone at master tail that scales with ctrl.target
-    #
-    ####################################################
+
+    class CtrlBones(BaseSkinRig.CtrlBones):
+        master: str                    # Parent control for moving the whole eye.
+        target: str                    # Individual target this eye aims for.
+
+    class MchBones(BaseSkinRig.MchBones):
+        master: str                    # Bone that rotates to track ctrl.target.
+        track: str                     # Bone that translates to follow mch.master tail.
+
+    class DeformBones(TypedBoneDict):
+        master: str                    # Deform mirror of ctrl.master.
+        eye: str                       # Deform bone that rotates with mch.master.
+        iris: str                      # Iris deform bone at master tail that scales with ctrl.target
+
+    bones: BaseSkinRig.ToplevelBones[
+        str,
+        'Rig.CtrlBones',
+        'Rig.MchBones',
+        'Rig.DeformBones'
+    ]
 
     ####################################################
     # CHILD CHAINS
@@ -154,13 +167,16 @@ class Rig(BaseSkinRig):
         for child in self.child_chains:
             self.patch_chain(child)
 
-    def patch_chain(self, child):
+    def patch_chain(self, child: BasicChainRig):
         return EyelidChainPatch(child, self)
 
     ####################################################
     # CONTROL NODES
 
-    def extend_control_node_parent(self, parent, node):
+    def extend_control_node_parent(self, parent, node: BaseSkinNode):
+        if not isinstance(node, ControlBoneNode):
+            return parent
+
         if self.is_eye_control_node(node):
             if self.is_eye_corner_node(node):
                 # Remember corners for later computations
@@ -172,7 +188,7 @@ class Rig(BaseSkinRig):
 
         return parent
 
-    def extend_mid_node_parent(self, parent, node):
+    def extend_mid_node_parent(self, parent: ControlBoneParentBase, node: ControlBoneNode):
         parent = ControlBoneParentOffset(self, node, parent)
 
         # Add movement of the eye to the eyelid controls
@@ -183,6 +199,7 @@ class Rig(BaseSkinRig):
 
         # If Limit Distance 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list