From 01e8af3348fac2babe3b5218dbe4ecdaa0e1eace Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 12 Nov 2022 23:54:17 +0200 Subject: Rigify: annotate and fix warnings in basic rig components. Introduce a method to annotate types and names of entries in the `bones` container of rig components and apply it, and other type annotations, to a number of not very complex rig classes. - Introduce BaseRigMixin as a typed base class for mixins intended for use in rig classes (using BaseRig as a parent causes issues). - Introduce TypedBoneDict that does not suppress the unknown attribute analysis in PyCharm, and use it in a system of subclasses to annotate the bones in various rigs. BaseBoneDict is necessary because the annotation affects all subclasses, so TypedBoneDict cannot inherit from BoneDict with the annotation. - Add or adjust other type annotations of rig methods and utilities. - Fix other warnings, e.g. undeclared attributes, excessively long lines, whitespace style issues and typos. --- rigify/base_rig.py | 49 +++-- rigify/operators/action_layers.py | 8 +- rigify/rigs/basic/copy_chain.py | 14 +- rigify/rigs/basic/pivot.py | 80 ++++---- rigify/rigs/basic/raw_copy.py | 88 +++++---- rigify/rigs/basic/super_copy.py | 61 +++--- rigify/rigs/chain_rigs.py | 95 ++++----- rigify/rigs/limbs/simple_tentacle.py | 13 +- rigify/rigs/limbs/super_finger.py | 102 ++++++---- rigify/rigs/spines/basic_spine.py | 100 +++++----- rigify/rigs/spines/basic_tail.py | 20 +- rigify/rigs/spines/spine_rigs.py | 94 +++++---- rigify/rigs/spines/super_head.py | 85 ++++---- rigify/rigs/spines/super_spine.py | 22 +-- rigify/rigs/utils.py | 14 +- rigify/rigs/widgets.py | 370 +++++++++++++++++++++++++++++++++-- rigify/utils/animation.py | 29 ++- rigify/utils/bones.py | 46 +++-- rigify/utils/layers.py | 9 + rigify/utils/rig.py | 2 +- 20 files changed, 893 insertions(+), 408 deletions(-) diff --git a/rigify/base_rig.py b/rigify/base_rig.py index b0bcc027..c284cc20 100644 --- a/rigify/base_rig.py +++ b/rigify/base_rig.py @@ -2,11 +2,11 @@ import collections -from bpy.types import PoseBone -from typing import TYPE_CHECKING, Any, Callable, Optional +from bpy.types import PoseBone, UILayout, Context +from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Generic from .utils.errors import RaiseErrorMixin -from .utils.bones import BoneDict, BoneUtilityMixin +from .utils.bones import BoneDict, BoneUtilityMixin, TypedBoneDict, BaseBoneDict from .utils.mechanism import MechanismUtilityMixin from .utils.metaclass import BaseStagedClass from .utils.misc import ArmatureObject @@ -144,14 +144,19 @@ class GenerateCallbackHost(BaseStagedClass, define_stages=True): pass -class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, MechanismUtilityMixin): +_Org = TypeVar('_Org', bound=str | list[str] | BaseBoneDict) +_Ctrl = TypeVar('_Ctrl', bound=str | list[str] | BaseBoneDict) +_Mch = TypeVar('_Mch', bound=str | list[str] | BaseBoneDict) +_Deform = TypeVar('_Deform', bound=str | list[str] | BaseBoneDict) + + +class BaseRigMixin(RaiseErrorMixin, BoneUtilityMixin, MechanismUtilityMixin): generator: 'BaseGenerator' obj: ArmatureObject script: 'ScriptGenerator' base_bone: str params: Any - bones: BoneDict rigify_parent: Optional['BaseRig'] rigify_children: list['BaseRig'] @@ -160,6 +165,28 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism rigify_new_bones: dict[str, Optional[str]] rigify_derived_bones: dict[str, set[str]] + ############################################## + # Annotated bone containers + + class ToplevelBones(TypedBoneDict, Generic[_Org, _Ctrl, _Mch, _Deform]): + org: _Org + ctrl: _Ctrl + mch: _Mch + deform: _Deform + + class CtrlBones(TypedBoneDict): + pass + + class MchBones(TypedBoneDict): + pass + + bones: ToplevelBones[str | list[str] | BoneDict, + str | list[str] | BoneDict, # Use CtrlBones in overrides + str | list[str] | BoneDict, # Use MchBones in overrides + str | list[str] | BoneDict] + + +class BaseRig(GenerateCallbackHost, BaseRigMixin): """ Base class for all rigs. @@ -182,7 +209,7 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism self.params = get_rigify_params(pose_bone) # Collection of bone names for use in implementing the rig - self.bones = BoneDict( + self.bones = self.ToplevelBones( # ORG bone names org=self.find_org_bones(pose_bone), # Control bone names @@ -205,7 +232,7 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism self.rigify_new_bones = dict() self.rigify_derived_bones = collections.defaultdict(set) - def register_new_bone(self, new_name, old_name=None): + def register_new_bone(self, new_name: str, old_name: Optional[str] = None): """Registers this rig as the owner of this new bone.""" self.rigify_new_bones[new_name] = old_name self.generator.bone_owners[new_name] = self @@ -216,7 +243,7 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism ########################################################### # Bone ownership - def find_org_bones(self, pose_bone: PoseBone) -> str | list[str] | BoneDict: + def find_org_bones(self, pose_bone: PoseBone) -> str | list[str] | BaseBoneDict: """ Select bones directly owned by the rig. Returning the same bone from multiple rigs is an error. @@ -240,7 +267,7 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism pass @classmethod - def parameters_ui(cls, layout, params): + def parameters_ui(cls, layout: UILayout, params): """ This method draws the UI of the rigify_parameters defined on the pose_bone :param layout: @@ -250,7 +277,7 @@ class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, Mechanism pass @classmethod - def on_parameter_update(cls, context, pose_bone, params, param_name): + def on_parameter_update(cls, context: Context, pose_bone: PoseBone, params, param_name: str): """ A callback invoked whenever a parameter value is changed by the user. """ @@ -267,7 +294,7 @@ class RigUtility(BoneUtilityMixin, MechanismUtilityMixin): self.owner = owner self.obj = owner.obj - def register_new_bone(self, new_name, old_name=None): + def register_new_bone(self, new_name: str, old_name: Optional[str] = None): self.owner.register_new_bone(new_name, old_name) diff --git a/rigify/operators/action_layers.py b/rigify/operators/action_layers.py index c089722a..b81ac0ef 100644 --- a/rigify/operators/action_layers.py +++ b/rigify/operators/action_layers.py @@ -119,21 +119,21 @@ class ActionSlot(PropertyGroup, ActionSlotBase): trans_min: FloatProperty( name="Min", default=-0.05, - description="Value that the transformation value must reach to put the action's timeline" + description="Value that the transformation value must reach to put the action's timeline " "to the first frame. Rotations are in degrees" ) trans_max: FloatProperty( name="Max", default=0.05, - description="Value that the transformation value must reach to put the action's timeline" + description="Value that the transformation value must reach to put the action's timeline " "to the last frame. Rotations are in degrees" ) is_corrective: BoolProperty( name="Corrective", - description="Indicate that this is a corrective action. Corrective actions will activate" - "based on the activation of two other actions (using End Frame if both inputs" + description="Indicate that this is a corrective action. Corrective actions will activate " + "based on the activation of two other actions (using End Frame if both inputs " "are at their End Frame, and Start Frame if either is at Start Frame)" ) diff --git a/rigify/rigs/basic/copy_chain.py b/rigify/rigs/basic/copy_chain.py index cf77a834..3dbf79d4 100644 --- a/rigify/rigs/basic/copy_chain.py +++ b/rigify/rigs/basic/copy_chain.py @@ -11,6 +11,10 @@ class Rig(SimpleChainRig): and constrain it. This is a control and deformation rig. """ + + make_controls: bool + make_deforms: bool + def initialize(self): super().initialize() @@ -72,15 +76,17 @@ class Rig(SimpleChainRig): # Parameter UI @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ - 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.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") @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): """ Create the ui for the rig parameters. """ r = layout.row() diff --git a/rigify/rigs/basic/pivot.py b/rigify/rigs/basic/pivot.py index a129e1e8..6812cde5 100644 --- a/rigify/rigs/basic/pivot.py +++ b/rigify/rigs/basic/pivot.py @@ -13,15 +13,27 @@ from ...utils.switch_parent import SwitchParentBuilder class Rig(BaseRig): """ A rig providing a rotation pivot control that can be moved. """ - def find_org_bones(self, pose_bone): - return pose_bone.name + class CtrlBones(BaseRig.CtrlBones): + master: str + pivot: str + + class MchBones(BaseRig.MchBones): + pass + + bones: BaseRig.ToplevelBones[str, CtrlBones, MchBones, str] + + make_control: bool + make_pivot: bool + make_deform: bool + + def find_org_bones(self, pose_bone) -> str: + return pose_bone.name 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 - + self.make_deform = self.params.make_extra_deform def generate_bones(self): org = self.bones.org @@ -44,8 +56,7 @@ class Rig(BaseRig): 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): + def build_parent_switch(self, master_name: str): pbuilder = SwitchParentBuilder(self.generator) org_parent = self.get_bone_parent(self.bones.org) @@ -68,7 +79,7 @@ class Rig(BaseRig): tags.discard('') return tags - def register_parent(self, master_name, tags): + def register_parent(self, master_name: str, tags: set[str]): pbuilder = SwitchParentBuilder(self.generator) inject = self.rigify_parent if 'injected' in tags else None @@ -78,7 +89,6 @@ class Rig(BaseRig): inject_into=inject, tags=tags ) - def parent_bones(self): ctrl = self.bones.ctrl @@ -94,7 +104,6 @@ class Rig(BaseRig): if self.make_deform: self.set_bone_parent(self.bones.deform, self.bones.org, use_connect=False) - def configure_bones(self): org = self.bones.org ctrl = self.bones.ctrl @@ -102,7 +111,6 @@ class Rig(BaseRig): self.copy_bone_properties(org, main_ctl, ui_controls=True) - def rig_bones(self): if self.make_pivot: self.make_constraint( @@ -110,7 +118,6 @@ class Rig(BaseRig): space='LOCAL', invert_xyz=(True,)*3 ) - def generate_widgets(self): if self.make_pivot: create_pivot_widget(self.obj, self.bones.ctrl.pivot, square=True, axis_size=2.0) @@ -118,56 +125,55 @@ class Rig(BaseRig): if self.make_control: set_bone_widget_transform(self.obj, self.bones.ctrl.master, self.bones.org) - create_registered_widget(self.obj, self.bones.ctrl.master, self.params.pivot_master_widget_type or 'cube') - + create_registered_widget(self.obj, self.bones.ctrl.master, + self.params.pivot_master_widget_type or 'cube') @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): params.make_control = bpy.props.BoolProperty( - name = "Control", - default = True, - description = "Create a control bone for the copy" + name="Control", + default=True, + description="Create a control bone for the copy" ) params.pivot_master_widget_type = bpy.props.StringProperty( - name = "Widget Type", - default = 'cube', - description = "Choose the type of the widget to create" + name="Widget Type", + default='cube', + description="Choose the type of the widget to create" ) params.make_parent_switch = bpy.props.BoolProperty( - name = "Switchable Parent", - default = False, - description = "Allow switching the parent of the master control" + 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" + 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" + 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, - description = "Create an optional control" + name="Extra Control", + default=False, + description="Create an optional control" ) params.make_extra_deform = bpy.props.BoolProperty( - name = "Extra Deform", - default = False, - description = "Create an optional deform bone" + name="Extra Deform", + default=False, + description="Create an optional deform bone" ) - @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): r = layout.row() r.prop(params, "make_extra_control", text="Master Control") diff --git a/rigify/rigs/basic/raw_copy.py b/rigify/rigs/basic/raw_copy.py index 6a6153a3..f22f7533 100644 --- a/rigify/rigs/basic/raw_copy.py +++ b/rigify/rigs/basic/raw_copy.py @@ -2,15 +2,17 @@ import bpy -from ...utils.naming import strip_org, strip_prefix, choose_derived_bone, is_control_bone +from bpy.types import Constraint, ArmatureConstraint, UILayout + +from ...utils.naming import choose_derived_bone, is_control_bone from ...utils.mechanism import copy_custom_properties_with_ui, move_all_constraints from ...utils.widgets import layout_widget_dropdown, create_registered_widget -from ...base_rig import BaseRig -from ...base_generate import SubstitutionRig +from ...base_rig import BaseRig, BaseRigMixin from itertools import repeat + ''' Due to T80764, bone name handling for 'limbs.raw_copy' was hard-coded in generate.py @@ -25,18 +27,18 @@ class Rig(SubstitutionRig): return [ self.instantiate_rig(InstanceRig, new_name) ] ''' -class RelinkConstraintsMixin: + +class RelinkConstraintsMixin(BaseRigMixin): """ Utilities for constraint relinking. """ - def relink_bone_constraints(self, bone_name): + def relink_bone_constraints(self, bone_name: str): if self.params.relink_constraints: for con in self.get_bone(bone_name).constraints: self.relink_single_constraint(con) - relink_unmarked_constraints = False - def relink_single_constraint(self, con): + def relink_single_constraint(self, con: Constraint): if self.params.relink_constraints: parts = con.name.split('@') @@ -45,13 +47,11 @@ class RelinkConstraintsMixin: elif self.relink_unmarked_constraints: self.relink_constraint(con, ['']) - - def relink_move_constraints(self, from_bone, to_bone, *, prefix=''): + def relink_move_constraints(self, from_bone: str, to_bone: str, *, prefix=''): if self.params.relink_constraints: move_all_constraints(self.obj, from_bone, to_bone, prefix=prefix) - - def relink_bone_parent(self, bone_name): + def relink_bone_parent(self, bone_name: str): if self.params.relink_constraints: self.generator.disable_auto_parent(bone_name) @@ -62,13 +62,13 @@ class RelinkConstraintsMixin: self.set_bone_parent(bone_name, new_parent) return new_parent - - def relink_constraint(self, con, specs): - if con.type == 'ARMATURE': + def relink_constraint(self, con: Constraint, specs: list[str]): + if isinstance(con, ArmatureConstraint): if len(specs) == 1: specs = repeat(specs[0]) elif len(specs) != len(con.targets): - self.raise_error("Constraint {} actually has {} targets", con.name, len(con.targets)) + self.raise_error("Constraint {} actually has {} targets", + con.name, len(con.targets)) for tgt, spec in zip(con.targets, specs): if tgt.target == self.obj: @@ -76,44 +76,49 @@ class RelinkConstraintsMixin: elif hasattr(con, 'subtarget'): if len(specs) > 1: - self.raise_error("Only the Armature constraint can have multiple '@' targets: {}", con.name) + self.raise_error("Only the Armature constraint can have multiple '@' targets: {}", + con.name) + # noinspection PyUnresolvedReferences if con.target == self.obj: con.subtarget = self.find_relink_target(specs[0], con.subtarget) - - def find_relink_target(self, spec, old_target): + def find_relink_target(self, spec: str, old_target: str): if spec == '': return old_target elif spec in {'CTRL', 'DEF', 'MCH'}: result = choose_derived_bone(self.generator, old_target, spec.lower()) if not result: - result = choose_derived_bone(self.generator, old_target, spec.lower(), by_owner=False) + result = choose_derived_bone(self.generator, old_target, + spec.lower(), by_owner=False) if not result: - self.raise_error("Cannot find derived {} bone of bone '{}' for relinking", spec, old_target) + self.raise_error("Cannot find derived {} bone of bone '{}' for relinking", + spec, old_target) return result else: if spec not in self.obj.pose.bones: self.raise_error("Cannot find bone '{}' for relinking", spec) return spec - @classmethod - def add_relink_constraints_params(self, params): + def add_relink_constraints_params(cls, params): params.relink_constraints = bpy.props.BoolProperty( - name = "Relink Constraints", - default = False, - description = "For constraints with names formed like 'base@bonename', use the part after '@' as the new subtarget after all bones are created. Use '@CTRL', '@DEF' or '@MCH' to simply replace the prefix" + name="Relink Constraints", + default=False, + description="For constraints with names formed like 'base@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" + 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): + def add_relink_constraints_ui(cls, layout: UILayout, params): r = layout.row() r.prop(params, "relink_constraints") @@ -125,7 +130,11 @@ class RelinkConstraintsMixin: class Rig(BaseRig, RelinkConstraintsMixin): - def find_org_bones(self, pose_bone): + bones: BaseRig.ToplevelBones[str, BaseRig.CtrlBones, BaseRig.MchBones, str] + + relink: bool + + def find_org_bones(self, pose_bone) -> str: return pose_bone.name def initialize(self): @@ -149,23 +158,22 @@ class Rig(BaseRig, RelinkConstraintsMixin): create_registered_widget(self.obj, org, widget) @classmethod - def add_parameters(self, params): - self.add_relink_constraints_params(params) + def add_parameters(cls, params): + cls.add_relink_constraints_params(params) params.optional_widget_type = bpy.props.StringProperty( - name = "Widget Type", - default = '', - description = "Choose the type of the widget to create" + name="Widget Type", + default='', + description="Choose the type of the widget to create" ) - @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): col = layout.column() col.label(text='This rig type does not add the ORG prefix.') col.label(text='Manually add ORG, MCH or DEF as needed.') - self.add_relink_constraints_ui(layout, params) + cls.add_relink_constraints_ui(layout, params) pbone = bpy.context.active_pose_bone @@ -173,8 +181,8 @@ class Rig(BaseRig, RelinkConstraintsMixin): layout_widget_dropdown(layout, params, "optional_widget_type") -#add_parameters = InstanceRig.add_parameters -#parameters_ui = InstanceRig.parameters_ui +# add_parameters = InstanceRig.add_parameters +# parameters_ui = InstanceRig.parameters_ui def create_sample(obj): diff --git a/rigify/rigs/basic/super_copy.py b/rigify/rigs/basic/super_copy.py index fc4b4d33..450bda2c 100644 --- a/rigify/rigs/basic/super_copy.py +++ b/rigify/rigs/basic/super_copy.py @@ -15,21 +15,27 @@ class Rig(BaseRig, RelinkConstraintsMixin): """ A "copy" rig. All it does is duplicate the original bone and constrain it. This is a control and deformation rig. - """ - def find_org_bones(self, pose_bone): - return pose_bone.name + bones: BaseRig.ToplevelBones[str, str, str, str] + + org_name: str + + make_control: bool + make_widget: bool + make_deform: bool + + def find_org_bones(self, pose_bone) -> str: + return pose_bone.name def initialize(self): """ Gather and validate data about the rig. """ - self.org_name = strip_org(self.bones.org) + self.org_name = strip_org(self.bones.org) self.make_control = self.params.make_control - self.make_widget = self.params.make_widget - self.make_deform = self.params.make_deform - + self.make_widget = self.params.make_widget + self.make_deform = self.params.make_deform def generate_bones(self): bones = self.bones @@ -42,7 +48,6 @@ class Rig(BaseRig, RelinkConstraintsMixin): if self.make_deform: bones.deform = self.copy_bone(bones.org, make_deformer_name(self.org_name), bbone=True) - def parent_bones(self): bones = self.bones @@ -54,14 +59,12 @@ class Rig(BaseRig, RelinkConstraintsMixin): if self.make_control and new_parent: self.set_bone_parent(bones.ctrl, new_parent) - def configure_bones(self): bones = self.bones if self.make_control: self.copy_bone_properties(bones.org, bones.ctrl) - def rig_bones(self): bones = self.bones @@ -76,52 +79,50 @@ class Rig(BaseRig, RelinkConstraintsMixin): if self.make_deform: self.relink_move_constraints(bones.org, bones.deform, prefix='DEF:') - def generate_widgets(self): bones = self.bones if self.make_control: # Create control widget if self.make_widget: - create_registered_widget(self.obj, bones.ctrl, self.params.super_copy_widget_type or 'circle') + create_registered_widget(self.obj, bones.ctrl, + self.params.super_copy_widget_type or 'circle') else: create_bone_widget(self.obj, bones.ctrl) - @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ params.make_control = bpy.props.BoolProperty( - name = "Control", - default = True, - description = "Create a control bone for the copy" + name="Control", + default=True, + description="Create a control bone for the copy" ) params.make_widget = bpy.props.BoolProperty( - name = "Widget", - default = True, - description = "Choose a widget for the bone control" + name="Widget", + default=True, + description="Choose a widget for the bone control" ) params.super_copy_widget_type = bpy.props.StringProperty( - name = "Widget Type", - default = 'circle', - description = "Choose the type of the widget to create" + name="Widget Type", + default='circle', + description="Choose the type of the widget to create" ) params.make_deform = bpy.props.BoolProperty( - name = "Deform", - default = True, - description = "Create a deform bone for the copy" + name="Deform", + default=True, + description="Create a deform bone for the copy" ) - self.add_relink_constraints_params(params) - + cls.add_relink_constraints_params(params) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): """ Create the ui for the rig parameters. """ layout.prop(params, "make_control") @@ -136,7 +137,7 @@ class Rig(BaseRig, RelinkConstraintsMixin): layout.prop(params, "make_deform") - self.add_relink_constraints_ui(layout, params) + cls.add_relink_constraints_ui(layout, params) if params.relink_constraints and (params.make_control or params.make_deform): col = layout.column() diff --git a/rigify/rigs/chain_rigs.py b/rigify/rigs/chain_rigs.py index f0aeb124..fea3b56f 100644 --- a/rigify/rigs/chain_rigs.py +++ b/rigify/rigs/chain_rigs.py @@ -1,11 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later import bpy + +from typing import Optional from itertools import count +from bpy.types import PoseBone + from ..utils.rig import connected_children_names from ..utils.naming import strip_org, make_derived_name -from ..utils.bones import put_bone, flip_bone, flip_bone_chain, is_same_position, is_connected_position +from ..utils.bones import (put_bone, flip_bone, flip_bone_chain, is_same_position, + is_connected_position) from ..utils.bones import copy_bone_position, connect_bbone_chain_handles from ..utils.widgets_basic import create_bone_widget, create_sphere_widget from ..utils.misc import map_list @@ -15,32 +20,32 @@ from ..base_rig import BaseRig, stage class SimpleChainRig(BaseRig): """A rig that consists of 3 connected chains of control, org and deform bones.""" - def find_org_bones(self, bone): + def find_org_bones(self, bone: PoseBone): return [bone.name] + connected_children_names(self.obj, bone.name) min_chain_length = 2 + bbone_segments = None + + rig_parent_bone: str # Bone to be used as parent of the whole rig def initialize(self): if len(self.bones.org) < self.min_chain_length: - self.raise_error("Input to rig type must be a chain of {} or more bones.", self.min_chain_length) + self.raise_error( + "Input to rig type must be a chain of {} or more bones.", self.min_chain_length) def parent_bones(self): self.rig_parent_bone = self.get_bone_parent(self.bones.org[0]) - bbone_segments = None - ############################## # BONES - # - # org[]: - # ORG bones - # ctrl: - # fk[]: - # FK control chain. - # deform[]: - # DEF bones - # - ############################## + + class CtrlBones(BaseRig.CtrlBones): + fk: list[str] # FK control chain + + class MchBones(BaseRig.MchBones): + pass + + bones: BaseRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] ############################## # Control chain @@ -49,7 +54,7 @@ class SimpleChainRig(BaseRig): def make_control_chain(self): self.bones.ctrl.fk = map_list(self.make_control_bone, count(0), self.bones.org) - def make_control_bone(self, i, org): + def make_control_bone(self, i: int, org: str): return self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=True) @stage.parent_bones @@ -61,7 +66,7 @@ class SimpleChainRig(BaseRig): for args in zip(count(0), self.bones.ctrl.fk, self.bones.org): self.configure_control_bone(*args) - def configure_control_bone(self, i, ctrl, org): + def configure_control_bone(self, i: int, ctrl: str, org: str): self.copy_bone_properties(org, ctrl) @stage.generate_widgets @@ -69,7 +74,7 @@ class SimpleChainRig(BaseRig): for args in zip(count(0), self.bones.ctrl.fk): self.make_control_widget(*args) - def make_control_widget(self, i, ctrl): + def make_control_widget(self, i: int, ctrl: str): create_bone_widget(self.obj, ctrl) ############################## @@ -84,7 +89,7 @@ class SimpleChainRig(BaseRig): for args in zip(count(0), self.bones.org, self.bones.ctrl.fk): self.rig_org_bone(*args) - def rig_org_bone(self, i, org, ctrl): + def rig_org_bone(self, i: int, org: str, ctrl: str): self.make_constraint(org, 'COPY_TRANSFORMS', ctrl) ############################## @@ -94,7 +99,7 @@ class SimpleChainRig(BaseRig): def make_deform_chain(self): self.bones.deform = map_list(self.make_deform_bone, count(0), self.bones.org) - def make_deform_bone(self, i, org): + def make_deform_bone(self, i: int, org: str): name = self.copy_bone(org, make_derived_name(org, 'def'), parent=True, bbone=True) if self.bbone_segments: self.get_bone(name).bbone_segments = self.bbone_segments @@ -109,7 +114,7 @@ class SimpleChainRig(BaseRig): for args in zip(count(0), self.bones.deform, self.bones.org): self.rig_deform_bone(*args) - def rig_deform_bone(self, i, deform, org): + def rig_deform_bone(self, i: int, deform: str, org: str): self.make_constraint(deform, 'COPY_TRANSFORMS', org) @@ -118,18 +123,14 @@ class TweakChainRig(SimpleChainRig): ############################## # BONES - # - # org[]: - # ORG bones - # ctrl: - # fk[]: - # FK control chain. - # tweak[]: - # Tweak control chain. - # deform[]: - # DEF bones - # - ############################## + + class CtrlBones(SimpleChainRig.CtrlBones): + tweak: list[str] # Tweak control chain + + class MchBones(SimpleChainRig.MchBones): + pass + + bones: BaseRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] ############################## # Tweak chain @@ -139,7 +140,7 @@ class TweakChainRig(SimpleChainRig): orgs = self.bones.org self.bones.ctrl.tweak = map_list(self.make_tweak_bone, count(0), orgs + orgs[-1:]) - def make_tweak_bone(self, i, org): + def make_tweak_bone(self, i: int, org: str): name = self.copy_bone(org, 'tweak_' + strip_org(org), parent=False, scale=0.5) if i == len(self.bones.org): @@ -158,7 +159,7 @@ class TweakChainRig(SimpleChainRig): for args in zip(count(0), self.bones.ctrl.tweak): self.configure_tweak_bone(*args) - def configure_tweak_bone(self, i, tweak): + def configure_tweak_bone(self, i: int, tweak: str): tweak_pb = self.get_bone(tweak) tweak_pb.rotation_mode = 'ZXY' @@ -176,7 +177,7 @@ class TweakChainRig(SimpleChainRig): for tweak in self.bones.ctrl.tweak: self.make_tweak_widget(tweak) - def make_tweak_widget(self, tweak): + def make_tweak_widget(self, tweak: str): create_sphere_widget(self.obj, tweak) ############################## @@ -188,7 +189,8 @@ class TweakChainRig(SimpleChainRig): for args in zip(count(0), self.bones.org, tweaks, tweaks[1:]): self.rig_org_bone(*args) - def rig_org_bone(self, i, org, tweak, next_tweak): + # noinspection PyMethodOverriding + def rig_org_bone(self, i: int, org: str, tweak: str, next_tweak: Optional[str]): self.make_constraint(org, 'COPY_TRANSFORMS', tweak) if next_tweak: self.make_constraint(org, 'STRETCH_TO', next_tweak, keep_axis='SWING_Y') @@ -200,6 +202,9 @@ class ConnectingChainRig(TweakChainRig): bbone_segments = 8 use_connect_reverse = None + use_connect_chain: bool + connected_tweak: Optional[str] + def initialize(self): super().initialize() @@ -256,7 +261,7 @@ class ConnectingChainRig(TweakChainRig): ############################## # Tweak chain - def check_connect_tweak(self, org): + def check_connect_tweak(self, org: str): """ Check if it is possible to share the last parent tweak control. """ assert self.connected_tweak is None @@ -281,7 +286,7 @@ class ConnectingChainRig(TweakChainRig): else: return None - def make_tweak_bone(self, i, org): + def make_tweak_bone(self, i: int, org: str): if i == 0 and self.check_connect_tweak(org): return self.connected_tweak else: @@ -294,7 +299,7 @@ class ConnectingChainRig(TweakChainRig): if i > 0 or not (self.connected_tweak and self.use_connect_reverse): self.set_bone_parent(tweak, main) - def configure_tweak_bone(self, i, tweak): + def configure_tweak_bone(self, i: int, tweak: str): super().configure_tweak_bone(i, tweak) if self.use_connect_chain and self.use_connect_reverse and i == len(self.bones.org): @@ -317,7 +322,7 @@ class ConnectingChainRig(TweakChainRig): else: self.set_bone_parent(self.bones.org[0], self.rig_parent_bone) - def rig_org_bone(self, i, org, tweak, next_tweak): + def rig_org_bone(self, i: int, org: str, tweak: str, next_tweak: Optional[str]): if self.use_connect_chain and self.use_connect_reverse: self.make_constraint(org, 'STRETCH_TO', tweak, keep_axis='SWING_Y') else: @@ -326,7 +331,7 @@ class ConnectingChainRig(TweakChainRig): ############################## # Deform chain - def make_deform_bone(self, i, org): + def make_deform_bone(self, i: int, org: str): name = super().make_deform_bone(i, org) if self.use_connect_chain and self.use_connect_reverse: @@ -345,7 +350,7 @@ class ConnectingChainRig(TweakChainRig): self.set_bone_parent(deform[-1], self.bones.org[-1]) self.parent_bone_chain(reversed(deform), use_connect=True) - connect_bbone_chain_handles(self.obj, [ deform[0], parent_deform[0] ]) + connect_bbone_chain_handles(self.obj, [deform[0], parent_deform[0]]) return else: @@ -357,7 +362,7 @@ class ConnectingChainRig(TweakChainRig): # Settings @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): params.connect_chain = bpy.props.BoolProperty( name='Connect chain', default=False, @@ -365,6 +370,6 @@ class ConnectingChainRig(TweakChainRig): ) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): r = layout.row() r.prop(params, "connect_chain") diff --git a/rigify/rigs/limbs/simple_tentacle.py b/rigify/rigs/limbs/simple_tentacle.py index d26d009d..9be9bd07 100644 --- a/rigify/rigs/limbs/simple_tentacle.py +++ b/rigify/rigs/limbs/simple_tentacle.py @@ -3,6 +3,7 @@ import bpy from itertools import count +from typing import Optional from ...utils.bones import align_chain_x_axis from ...utils.widgets_basic import create_circle_widget @@ -14,6 +15,8 @@ from ..chain_rigs import TweakChainRig class Rig(TweakChainRig): + copy_rotation_axes: tuple[bool, bool, bool] + def initialize(self): super().initialize() @@ -50,7 +53,7 @@ class Rig(TweakChainRig): for args in zip(count(0), ctrls, [None] + ctrls): self.rig_control_bone(*args) - def rig_control_bone(self, i, ctrl, prev_ctrl): + def rig_control_bone(self, _i: int, ctrl: str, prev_ctrl: Optional[str]): if prev_ctrl: self.make_constraint( ctrl, 'COPY_ROTATION', prev_ctrl, @@ -59,12 +62,11 @@ class Rig(TweakChainRig): ) # Widgets - def make_control_widget(self, i, ctrl): + def make_control_widget(self, i: int, ctrl: str): create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5) - @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ @@ -80,9 +82,8 @@ class Rig(TweakChainRig): items = [('automatic', 'Automatic', ''), ('manual', 'Manual', '')] params.roll_alignment = bpy.props.EnumProperty(items=items, name="Bone roll alignment", default='automatic') - @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): """ Create the ui for the rig parameters. """ diff --git a/rigify/rigs/limbs/super_finger.py b/rigify/rigs/limbs/super_finger.py index 4fc1bc9c..0e7bfbd3 100644 --- a/rigify/rigs/limbs/super_finger.py +++ b/rigify/rigs/limbs/super_finger.py @@ -3,8 +3,10 @@ import bpy import json +from typing import Optional from itertools import count +from ...rig_ui_template import PanelLayout from ...utils.bones import put_bone, flip_bone, align_chain_x_axis, set_bone_widget_transform from ...utils.naming import make_derived_name from ...utils.widgets import create_widget @@ -21,6 +23,9 @@ from ..chain_rigs import SimpleChainRig class Rig(SimpleChainRig): """A finger rig with master control.""" + + make_ik: bool + def initialize(self): super().initialize() @@ -34,6 +39,19 @@ class Rig(SimpleChainRig): def parent_bones(self): self.rig_parent_bone = self.get_bone_parent(self.bones.org[0]) + ############################## + # BONES + + class CtrlBones(SimpleChainRig.CtrlBones): + master: str # Master control + ik: str # IK control (@make_ik) + + class MchBones(SimpleChainRig.MchBones): + stretch: list[str] # Stretch system + bend: list[str] # Bend system + + bones: SimpleChainRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] + ############################## # Master Control @@ -83,10 +101,10 @@ class Rig(SimpleChainRig): self.bones.ctrl.fk = map_list(self.make_control_bone, count(0), orgs) self.bones.ctrl.fk += [self.make_tip_control_bone(orgs[-1], orgs[0])] - def make_control_bone(self, i, org): + def make_control_bone(self, i: int, org: str): return self.copy_bone(org, make_derived_name(org, 'ctrl'), inherit_scale=True) - def make_tip_control_bone(self, org, name_org): + def make_tip_control_bone(self, org: str, name_org: str): name = self.copy_bone(org, make_derived_name(name_org, 'ctrl'), parent=False) flip_bone(self.obj, name) @@ -102,12 +120,12 @@ class Rig(SimpleChainRig): @stage.configure_bones def configure_control_chain(self): - for args in zip(count(0), self.bones.ctrl.fk, self.bones.org + [None]): + for args in zip(count(0), self.bones.ctrl.fk, [*self.bones.org, None]): self.configure_control_bone(*args) ControlLayersOption.TWEAK.assign(self.params, self.obj, self.bones.ctrl.fk) - def configure_control_bone(self, i, ctrl, org): + def configure_control_bone(self, i: int, ctrl: str, org: Optional[str]): if org: self.copy_bone_properties(org, ctrl) else: @@ -116,7 +134,7 @@ class Rig(SimpleChainRig): bone.lock_rotation = (True, True, True) bone.lock_scale = (True, True, True) - def make_control_widget(self, i, ctrl): + def make_control_widget(self, i: int, ctrl: str): if ctrl == self.bones.ctrl.fk[-1]: # Tip control create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.0) @@ -135,18 +153,18 @@ class Rig(SimpleChainRig): self.build_ik_parent_switch(SwitchParentBuilder(self.generator)) - def make_ik_control_bone(self, orgs): + def make_ik_control_bone(self, orgs: list[str]): name = self.copy_bone(orgs[-1], make_derived_name(orgs[0], 'ctrl', '_ik'), scale=0.7) put_bone(self.obj, name, self.get_bone(orgs[-1]).tail) return name - def build_ik_parent_switch(self, pbuilder): + def build_ik_parent_switch(self, pbuilder: SwitchParentBuilder): ctrl = self.bones.ctrl pbuilder.build_child( self, ctrl.ik, prop_bone=ctrl.ik, select_tags=['held_object', 'limb_ik', {'child', 'limb_end'}], only_selected=True, - prop_id='IK_parent', prop_name='IK Parent', controls=[ ctrl.ik ], + prop_id='IK_parent', prop_name='IK Parent', controls=[ctrl.ik], no_fix_rotation=True, no_fix_scale=True, ) @@ -194,10 +212,9 @@ class Rig(SimpleChainRig): panel, output_bones=[ctrl.ik], input_bones=ctrl.fk[-1:], input_ctrl_bones=[ctrl.master, *ctrl.fk], label='IK->FK', rig_name=rig_name, tooltip='IK to FK', - compact=True, locks=(False,True,True), + compact=True, locks=(False, True, True), ) - @stage.generate_widgets def make_ik_control_widget(self): if self.make_ik: @@ -210,7 +227,7 @@ class Rig(SimpleChainRig): def make_mch_bend_chain(self): self.bones.mch.bend = map_list(self.make_mch_bend_bone, self.bones.org) - def make_mch_bend_bone(self, org): + def make_mch_bend_bone(self, org: str): return self.copy_bone(org, make_derived_name(org, 'mch', '_drv'), inherit_scale=True, scale=0.3) @stage.parent_bones @@ -242,7 +259,7 @@ class Rig(SimpleChainRig): for args in zip(count(0), self.bones.mch.bend): self.rig_mch_bend_bone(*args) - def rig_mch_bend_bone(self, i, mch): + def rig_mch_bend_bone(self, i: int, mch: str): master = self.bones.ctrl.master if i == 0: self.make_constraint(mch, 'COPY_LOCATION', master) @@ -267,7 +284,7 @@ class Rig(SimpleChainRig): def make_mch_stretch_chain(self): self.bones.mch.stretch = map_list(self.make_mch_stretch_bone, self.bones.org) - def make_mch_stretch_bone(self, org): + def make_mch_stretch_bone(self, org: str): return self.copy_bone(org, make_derived_name(org, 'mch'), parent=False) @stage.parent_bones @@ -282,7 +299,7 @@ class Rig(SimpleChainRig): for args in zip(count(0), self.bones.mch.stretch, ctrls, ctrls[1:]): self.rig_mch_stretch_bone(*args) - def rig_mch_stretch_bone(self, i, mch, ctrl, ctrl_next): + def rig_mch_stretch_bone(self, i: int, mch: str, ctrl: str, ctrl_next: str): if i == 0: self.make_constraint(mch, 'COPY_LOCATION', ctrl) self.make_constraint(mch, 'COPY_SCALE', ctrl) @@ -300,7 +317,7 @@ class Rig(SimpleChainRig): if self.make_ik: self.rig_org_ik(self.bones.org, self.bones.ctrl.ik) - def rig_org_ik(self, orgs, ik_ctrl): + def rig_org_ik(self, orgs: list[str], ik_ctrl: str): axis = self.params.primary_rotation_axis options = self.axis_options[axis] @@ -335,7 +352,8 @@ class Rig(SimpleChainRig): panel = self.script.panel_with_selected_check(self, self.bones.ctrl.flatten()) panel.custom_prop(master, 'finger_curve', text="Curvature", slider=True) - def rig_deform_bone(self, i, deform, org): + # noinspection SpellCheckingInspection + def rig_deform_bone(self, i: int, deform: str, org: str): master = self.bones.ctrl.master bone = self.get_bone(deform) @@ -349,38 +367,43 @@ class Rig(SimpleChainRig): # OPTIONS @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ - items = [('automatic', 'Automatic', ''), ('X', 'X manual', ''), ('Y', 'Y manual', ''), ('Z', 'Z manual', ''), - ('-X', '-X manual', ''), ('-Y', '-Y manual', ''), ('-Z', '-Z manual', '')] - params.primary_rotation_axis = bpy.props.EnumProperty(items=items, name="Primary Rotation Axis", default='automatic') + items = [('automatic', 'Automatic', ''), + ('X', 'X manual', ''), ('Y', 'Y manual', ''), ('Z', 'Z manual', ''), + ('-X', '-X manual', ''), ('-Y', '-Y manual', ''), ('-Z', '-Z manual', '')] + + params.primary_rotation_axis = bpy.props.EnumProperty( + items=items, name="Primary Rotation Axis", default='automatic') params.bbones = bpy.props.IntProperty( - name = 'B-Bone Segments', - default = 10, - min = 1, - description = 'Number of B-Bone segments' + name='B-Bone Segments', + default=10, + min=1, + description='Number of B-Bone segments' ) params.make_extra_ik_control = bpy.props.BoolProperty( - name = "Extra IK Control", - default = False, - description = "Create an optional IK control" + name="Extra IK Control", + default=False, + description="Create an optional IK control" ) params.ik_local_location = bpy.props.BoolProperty( - name = 'IK Local Location', - default = True, - description = "Specifies the value of the Local Location option for IK controls, which decides if the location channels are aligned to the local control orientation or world", + name='IK Local Location', + default=True, + description="Specifies the value of the Local Location option for IK controls, " + "which decides if the location channels are aligned to the local control " + "orientation or world", ) ControlLayersOption.TWEAK.add_parameters(params) ControlLayersOption.EXTRA_IK.add_parameters(params) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): """ Create the ui for the rig parameters. """ r = layout.row() @@ -398,12 +421,14 @@ class Rig(SimpleChainRig): if params.make_extra_ik_control: ControlLayersOption.EXTRA_IK.parameters_ui(layout, params) + ############################# # Finger FK to IK operator ## ############################# SCRIPT_REGISTER_OP_SNAP_FK_IK = ['POSE_OT_rigify_finger_fk2ik', 'POSE_OT_rigify_finger_fk2ik_bake'] +# noinspection SpellCheckingInspection SCRIPT_UTILITIES_OP_SNAP_FK_IK = [''' ######################## ## Limb Snap IK to FK ## @@ -558,7 +583,14 @@ class POSE_OT_rigify_finger_fk2ik_bake(RigifyFingerFk2IkBase, RigifyBakeKeyframe return self.bake_get_all_bone_curves(fk_bones, TRANSFORM_PROPS_ALL) '''] -def add_finger_snap_fk_to_ik(panel, *, master=None, fk_bones=[], ik_bones=[], ik_control=None, ik_constraint_bone=None, axis='+X', rig_name='', compact=None): + +# noinspection PyDefaultArgument +def add_finger_snap_fk_to_ik( + panel: 'PanelLayout', *, master: Optional[str] = None, + fk_bones: list[str] = [], ik_bones: list[str] = [], + ik_control: Optional[str] = None, + ik_constraint_bone: Optional[str] = None, + axis='+X', rig_name='', compact: Optional[bool] = None): panel.use_bake_settings() panel.script.add_utilities(SCRIPT_UTILITIES_OP_SNAP_FK_IK) panel.script.register_classes(SCRIPT_REGISTER_OP_SNAP_FK_IK) @@ -578,6 +610,7 @@ def add_finger_snap_fk_to_ik(panel, *, master=None, fk_bones=[], ik_bones=[], ik clear_bones=[master, *fk_bones], compact=compact, ) + def create_sample(obj): # generated by rigify.utils.write_metarig bpy.ops.object.mode_set(mode='EDIT') @@ -629,7 +662,10 @@ def create_sample(obj): pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.extra_layers = [ + False, False, False, False, False, True, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False] except AttributeError: pass try: diff --git a/rigify/rigs/spines/basic_spine.py b/rigify/rigs/spines/basic_spine.py index 6b069c64..355b55f3 100644 --- a/rigify/rigs/spines/basic_spine.py +++ b/rigify/rigs/spines/basic_spine.py @@ -8,7 +8,8 @@ from mathutils import Matrix from ...utils.layers import ControlLayersOption from ...utils.naming import strip_org, make_mechanism_name, make_derived_name -from ...utils.bones import BoneDict, put_bone, align_bone_to_axis, align_bone_orientation, set_bone_widget_transform +from ...utils.bones import (put_bone, align_bone_to_axis, align_bone_orientation, + set_bone_widget_transform, TypedBoneDict) from ...utils.widgets import adjust_widget_transform_mesh from ...utils.widgets_basic import create_circle_widget from ...utils.misc import map_list @@ -22,6 +23,9 @@ class Rig(BaseSpineRig): Spine rig with fixed pivot, hip/chest controls and tweaks. """ + pivot_pos: int + use_fk: bool + def initialize(self): super().initialize() @@ -34,34 +38,28 @@ class Rig(BaseSpineRig): #################################################### # BONES - # - # org[]: - # ORG bones - # ctrl: - # master, hips, chest: - # Main controls. - # fk: - # chest[], hips[]: - # FK controls. - # tweak[]: - # Tweak control chain. - # mch: - # pivot: - # Pivot tweak parent. - # chain: - # chest[], hips[]: - # Tweak parents, distributing master deform. - # wgt_hips, wgt_chest: - # Widget position bones. - # deform[]: - # DEF bones - # - #################################################### + + class SplitChainBones(TypedBoneDict): + chest: list[str] + hips: list[str] + + class CtrlBones(BaseSpineRig.CtrlBones): + hips: str # Hip control + chest: str # Chest control + fk: 'Rig.SplitChainBones' # FK controls + + class MchBones(BaseSpineRig.MchBones): + pivot: str # Central pivot between sub-chains + chain: 'Rig.SplitChainBones' # Tweak parents, distributing master deform. + wgt_hips: str # Hip widget position bone. + wgt_chest: str # Chest widget position bone. + + bones: BaseSpineRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] #################################################### # Master control bone - def get_master_control_pos(self, orgs): + def get_master_control_pos(self, orgs: list[str]): base_bone = self.get_bone(orgs[0]) return (base_bone.head + base_bone.tail) / 2 @@ -76,12 +74,12 @@ class Rig(BaseSpineRig): self.bones.ctrl.hips = self.make_hips_control_bone(orgs[pivot-1], 'hips') self.bones.ctrl.chest = self.make_chest_control_bone(orgs[pivot], 'chest') - def make_hips_control_bone(self, org, name): + def make_hips_control_bone(self, org: str, name: str): name = self.copy_bone(org, name, parent=False) align_bone_to_axis(self.obj, name, 'y', length=self.length / 4, flip=True) return name - def make_chest_control_bone(self, org, name): + def make_chest_control_bone(self, org: str, name: str): name = self.copy_bone(org, name, parent=False) align_bone_to_axis(self.obj, name, 'y', length=self.length / 3) return name @@ -100,7 +98,7 @@ class Rig(BaseSpineRig): self.make_end_control_widget(ctrl.hips, mch.wgt_hips) self.make_end_control_widget(ctrl.chest, mch.wgt_chest) - def make_end_control_widget(self, ctrl, wgt_mch): + def make_end_control_widget(self, ctrl: str, wgt_mch: str): shape_bone = self.get_bone(wgt_mch) is_horizontal = abs(shape_bone.z_axis.normalized().y) < 0.7 @@ -117,22 +115,27 @@ class Rig(BaseSpineRig): if is_horizontal: # Tilt the widget toward the ground for horizontal (animal) spines angle = math.copysign(28, shape_bone.x_axis.x) - rotmat = Matrix.Rotation(math.radians(angle), 4, 'X') - adjust_widget_transform_mesh(obj, rotmat, local=True) + rot_mat = Matrix.Rotation(math.radians(angle), 4, 'X') + adjust_widget_transform_mesh(obj, rot_mat, local=True) #################################################### # FK control bones + fk_result: 'Rig.SplitChainBones' # ctrl.fk or mch.chain depending on use_fk + @stage.generate_bones def make_control_chain(self): if self.use_fk: orgs = self.bones.org - self.bones.ctrl.fk = self.fk_result = BoneDict( - hips = map_list(self.make_control_bone, count(0), orgs[0:self.pivot_pos], repeat(True)), - chest = map_list(self.make_control_bone, count(self.pivot_pos), orgs[self.pivot_pos:], repeat(False)), + self.bones.ctrl.fk = self.fk_result = self.SplitChainBones( + hips=map_list(self.make_control_bone, + count(0), orgs[0:self.pivot_pos], repeat(True)), + chest=map_list(self.make_control_bone, + count(self.pivot_pos), orgs[self.pivot_pos:], repeat(False)), ) - def make_control_bone(self, i, org, is_hip): + # noinspection PyMethodOverriding + def make_control_bone(self, i: int, org: str, is_hip: bool): name = self.copy_bone(org, make_derived_name(org, 'ctrl', '_fk'), parent=False) if is_hip: put_bone(self.obj, name, self.get_bone(name).tail) @@ -166,7 +169,7 @@ class Rig(BaseSpineRig): for ctrl in fk.chest: self.make_control_widget(ctrl, False) - def make_control_widget(self, ctrl, is_hip): + def make_control_widget(self, ctrl: str, is_hip: bool): obj = create_circle_widget(self.obj, ctrl, radius=1.0, head_tail=0.5) if is_hip: adjust_widget_transform_mesh(obj, Matrix.Diagonal((1, -1, 1, 1)), local=True) @@ -183,12 +186,12 @@ class Rig(BaseSpineRig): mch.wgt_hips = self.make_mch_widget_bone(orgs[0], 'WGT-hips') mch.wgt_chest = self.make_mch_widget_bone(orgs[-1], 'WGT-chest') - def make_mch_pivot_bone(self, org, name): + def make_mch_pivot_bone(self, org: str, name: str): name = self.copy_bone(org, make_mechanism_name(name), parent=False) align_bone_to_axis(self.obj, name, 'y', length=self.length * 0.6 / 4) return name - def make_mch_widget_bone(self, org, name): + def make_mch_widget_bone(self, org: str, name: str): return self.copy_bone(org, make_mechanism_name(name), parent=False) @stage.parent_bones @@ -211,14 +214,14 @@ class Rig(BaseSpineRig): @stage.generate_bones def make_mch_chain(self): orgs = self.bones.org - self.bones.mch.chain = BoneDict( - hips = map_list(self.make_mch_bone, orgs[0:self.pivot_pos], repeat(True)), - chest = map_list(self.make_mch_bone, orgs[self.pivot_pos:], repeat(False)), + self.bones.mch.chain = self.SplitChainBones( + hips=map_list(self.make_mch_bone, orgs[0:self.pivot_pos], repeat(True)), + chest=map_list(self.make_mch_bone, orgs[self.pivot_pos:], repeat(False)), ) if not self.use_fk: self.fk_result = self.bones.mch.chain - def make_mch_bone(self, org, is_hip): + def make_mch_bone(self, org: str, is_hip: bool): name = self.copy_bone(org, make_mechanism_name(strip_org(org)), parent=False) align_bone_to_axis(self.obj, name, 'y', length=self.length / 10, flip=is_hip) return name @@ -242,8 +245,9 @@ class Rig(BaseSpineRig): for mch in chain.chest: self.rig_mch_bone(mch, ctrl.chest, len(chain.chest)) - def rig_mch_bone(self, mch, control, count): - self.make_constraint(mch, 'COPY_TRANSFORMS', control, space='LOCAL', influence=1/count) + def rig_mch_bone(self, mch: str, control: str, chain_len: int): + self.make_constraint(mch, 'COPY_TRANSFORMS', control, + space='LOCAL', influence=1 / chain_len) #################################################### # Tweak bones @@ -260,7 +264,7 @@ class Rig(BaseSpineRig): # SETTINGS @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): params.pivot_pos = bpy.props.IntProperty( name='pivot_position', default=2, @@ -278,7 +282,7 @@ class Rig(BaseSpineRig): ControlLayersOption.FK.add_parameters(params) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): r = layout.row() r.prop(params, "pivot_pos") @@ -328,7 +332,6 @@ def create_sample(obj): bone.parent = arm.edit_bones[bones['spine.002']] bones['spine.003'] = bone.name - bpy.ops.object.mode_set(mode='OBJECT') pbone = obj.pose.bones[bones['spine']] pbone.rigify_type = 'spines.basic_spine' @@ -339,7 +342,10 @@ def create_sample(obj): pbone.rotation_mode = 'QUATERNION' try: - pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_layers = [ + False, False, False, False, True, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['spine.001']] diff --git a/rigify/rigs/spines/basic_tail.py b/rigify/rigs/spines/basic_tail.py index 72c5ad8b..dbbdd9f3 100644 --- a/rigify/rigs/spines/basic_tail.py +++ b/rigify/rigs/spines/basic_tail.py @@ -17,6 +17,8 @@ from .spine_rigs import BaseHeadTailRig class Rig(BaseHeadTailRig): + copy_rotation_axes: tuple[bool, bool, bool] + def initialize(self): super().initialize() @@ -66,7 +68,7 @@ class Rig(BaseHeadTailRig): for args in zip(count(0), ctrls, [self.bones.ctrl.master] + ctrls): self.rig_control_bone(*args) - def rig_control_bone(self, i, ctrl, prev_ctrl): + def rig_control_bone(self, _i: int, ctrl: str, prev_ctrl: str): self.make_constraint( ctrl, 'COPY_ROTATION', prev_ctrl, use_xyz=self.copy_rotation_axes, @@ -74,7 +76,7 @@ class Rig(BaseHeadTailRig): ) # Widgets - def make_control_widget(self, i, ctrl): + def make_control_widget(self, i: int, ctrl: str): create_circle_widget(self.obj, ctrl, radius=0.5, head_tail=0.75) #################################################### @@ -96,7 +98,7 @@ class Rig(BaseHeadTailRig): orgs = self.bones.org self.bones.ctrl.tweak = map_list(self.make_tweak_bone, count(0), orgs[0:1] + orgs) - def make_tweak_bone(self, i, org): + def make_tweak_bone(self, i: int, org: str): if i == 0: if self.check_connect_tweak(org): return self.connected_tweak @@ -113,6 +115,7 @@ class Rig(BaseHeadTailRig): #################################################### # Deform chain + # noinspection SpellCheckingInspection @stage.configure_bones def configure_deform_chain(self): if self.use_connect_chain and self.use_connect_reverse: @@ -121,12 +124,11 @@ class Rig(BaseHeadTailRig): else: self.get_bone(self.bones.deform[-1]).bone.bbone_easeout = 0.0 - #################################################### # SETTINGS @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ @@ -139,9 +141,8 @@ class Rig(BaseHeadTailRig): default=tuple([i == 0 for i in range(0, 3)]) ) - @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): """ Create the ui for the rig parameters. """ @@ -195,7 +196,10 @@ def create_sample(obj, *, parent=None): except AttributeError: pass try: - pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_layers = [ + False, False, False, False, True, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['tail.001']] diff --git a/rigify/rigs/spines/spine_rigs.py b/rigify/rigs/spines/spine_rigs.py index a221089b..13cc48dd 100644 --- a/rigify/rigs/spines/spine_rigs.py +++ b/rigify/rigs/spines/spine_rigs.py @@ -2,6 +2,7 @@ import bpy +from typing import Optional, NamedTuple from itertools import count from ...utils.layers import ControlLayersOption @@ -24,6 +25,9 @@ class BaseSpineRig(TweakChainRig): bbone_segments = 8 min_chain_length = 3 + use_torso_pivot: bool # Generate the custom pivot control + length: float # Total length of the chain bones + def initialize(self): super().initialize() @@ -32,21 +36,21 @@ class BaseSpineRig(TweakChainRig): #################################################### # BONES - # - # ctrl: - # master - # Main control. - # master_pivot - # Custom pivot under the master control. - # mch: - # master_pivot - # Final output of the custom pivot. - # - #################################################### + + class CtrlBones(TweakChainRig.CtrlBones): + master: str # Master control + master_pivot: str # Custom pivot under the master control (conditional) + + class MchBones(TweakChainRig.MchBones): + master_pivot: str # Final output of the custom pivot (conditional) + + bones: TweakChainRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] #################################################### # Master control bone + component_torso_pivot: Optional[CustomPivotControl] + @stage.generate_bones def make_master_control(self): self.bones.ctrl.master = name = self.make_master_control_bone(self.bones.org) @@ -54,16 +58,16 @@ class BaseSpineRig(TweakChainRig): self.component_torso_pivot = self.build_master_pivot(name) self.build_parent_switch(name) - def get_master_control_pos(self, orgs): + def get_master_control_pos(self, orgs: list[str]): return self.get_bone(orgs[0]).head - def make_master_control_bone(self, orgs): + def make_master_control_bone(self, orgs: list[str]): name = self.copy_bone(orgs[0], 'torso') put_bone(self.obj, name, self.get_master_control_pos(orgs)) align_bone_to_axis(self.obj, name, 'y', length=self.length * 0.6) return name - def build_master_pivot(self, master_name, **args): + def build_master_pivot(self, master_name: str, **args): if self.use_torso_pivot: return CustomPivotControl( self, 'master_pivot', master_name, parent=master_name, **args @@ -75,7 +79,7 @@ class BaseSpineRig(TweakChainRig): else: return self.bones.ctrl.master - def build_parent_switch(self, master_name): + def build_parent_switch(self, master_name: str): pbuilder = SwitchParentBuilder(self.generator) org_parent = self.get_bone_parent(self.bones.org[0]) @@ -92,7 +96,7 @@ class BaseSpineRig(TweakChainRig): self.register_parent_bones(pbuilder) - def register_parent_bones(self, pbuilder): + def register_parent_bones(self, pbuilder: SwitchParentBuilder): pbuilder.register_parent(self, self.bones.org[0], name='Hips', exclude_self=True, tags={'hips'}) pbuilder.register_parent(self, self.bones.org[-1], name='Chest', exclude_self=True, tags={'chest'}) @@ -121,7 +125,7 @@ class BaseSpineRig(TweakChainRig): self.set_bone_parent(org, tweak) def rig_org_bone(self, i, org, tweak, next_tweak): - # For spine rigs, these constraints go on the deform bones. See T74483#902192. + # For spine rigs, these constraints go on the deformation bones. See T74483#902192. pass #################################################### @@ -142,31 +146,33 @@ class BaseSpineRig(TweakChainRig): for args in zip(count(0), self.bones.deform, tweaks, tweaks[1:]): self.rig_deform_bone(*args) - def rig_deform_bone(self, i, deform, tweak, next_tweak): + # noinspection PyMethodOverriding + def rig_deform_bone(self, i: int, deform: str, tweak: str, next_tweak: Optional[str]): self.make_constraint(deform, 'COPY_TRANSFORMS', tweak) if next_tweak: self.make_constraint(deform, 'STRETCH_TO', next_tweak, keep_axis='SWING_Y') @stage.configure_bones def configure_bbone_chain(self): + # noinspection SpellCheckingInspection self.get_bone(self.bones.deform[0]).bone.bbone_easein = 0.0 #################################################### # SETTINGS @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): params.make_custom_pivot = bpy.props.BoolProperty( - name = "Custom Pivot Control", - default = False, - description = "Create a rotation pivot control that can be repositioned arbitrarily" + name="Custom Pivot Control", + default=False, + description="Create a rotation pivot control that can be repositioned arbitrarily" ) # Setting up extra layers for the FK and tweak ControlLayersOption.TWEAK.add_parameters(params) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): layout.prop(params, 'make_custom_pivot') ControlLayersOption.TWEAK.parameters_ui(layout, params) @@ -175,6 +181,19 @@ class BaseSpineRig(TweakChainRig): class BaseHeadTailRig(ConnectingChainRig): """ Base for head and tail rigs. """ + class RotationBone(NamedTuple): + org: str + name: str + bone: str + def_val: float # Default value of the follow slider + copy_scale: bool + + rotation_bones: list[RotationBone] + + follow_bone: str + default_prop_bone: str + prop_bone: str + def initialize(self): super().initialize() @@ -183,7 +202,7 @@ class BaseHeadTailRig(ConnectingChainRig): #################################################### # Utilities - def get_parent_master(self, default_bone): + def get_parent_master(self, default_bone: str) -> str: """ Return the parent's master control bone if connecting and found. """ if self.use_connect_chain and 'master' in self.rigify_parent.bones.ctrl: @@ -191,7 +210,7 @@ class BaseHeadTailRig(ConnectingChainRig): else: return default_bone - def get_parent_master_panel(self, default_bone): + def get_parent_master_panel(self, default_bone: str): """ Return the parent's master control bone if connecting and found, and script panel. """ controls = self.bones.ctrl.flatten() @@ -208,37 +227,38 @@ class BaseHeadTailRig(ConnectingChainRig): #################################################### # Rotation follow - def make_mch_follow_bone(self, org, name, defval, *, copy_scale=False): + def make_mch_follow_bone(self, org: str, name: str, def_val: float, *, copy_scale=False): bone = self.copy_bone(org, make_derived_name('ROT-'+name, 'mch'), parent=True) - self.rotation_bones.append((org, name, bone, defval, copy_scale)) + self.rotation_bones.append(self.RotationBone(org, name, bone, def_val, copy_scale)) return bone @stage.parent_bones def align_mch_follow_bones(self): self.follow_bone = self.get_parent_master('root') - for org, name, bone, defval, copy_scale in self.rotation_bones: + for org, name, bone, def_val, copy_scale in self.rotation_bones: align_bone_orientation(self.obj, bone, self.follow_bone) @stage.configure_bones def configure_mch_follow_bones(self): self.prop_bone, panel = self.get_parent_master_panel(self.default_prop_bone) - for org, name, bone, defval, copy_scale in self.rotation_bones: - textname = name.replace('_',' ').title() + ' Follow' + for org, name, bone, def_val, copy_scale in self.rotation_bones: + text_name = name.replace('_', ' ').title() + ' Follow' - self.make_property(self.prop_bone, name+'_follow', default=float(defval)) - panel.custom_prop(self.prop_bone, name+'_follow', text=textname, slider=True) + self.make_property(self.prop_bone, name+'_follow', default=float(def_val)) + panel.custom_prop(self.prop_bone, name+'_follow', text=text_name, slider=True) @stage.rig_bones def rig_mch_follow_bones(self): - for org, name, bone, defval, copy_scale in self.rotation_bones: + for org, name, bone, def_val, copy_scale in self.rotation_bones: self.rig_mch_rotation_bone(bone, name+'_follow', copy_scale) - def rig_mch_rotation_bone(self, mch, prop_name, copy_scale): + def rig_mch_rotation_bone(self, mch: str, prop_name: str, copy_scale: bool): con = self.make_constraint(mch, 'COPY_ROTATION', self.follow_bone) - self.make_driver(con, 'influence', variables=[(self.prop_bone, prop_name)], polynomial=[1,-1]) + self.make_driver(con, 'influence', + variables=[(self.prop_bone, prop_name)], polynomial=[1, -1]) if copy_scale: self.make_constraint(mch, 'COPY_SCALE', self.follow_bone) @@ -256,14 +276,14 @@ class BaseHeadTailRig(ConnectingChainRig): # Settings @classmethod - def add_parameters(self, params): + def add_parameters(cls, params): super().add_parameters(params) # Setting up extra layers for the FK and tweak ControlLayersOption.TWEAK.add_parameters(params) @classmethod - def parameters_ui(self, layout, params): + def parameters_ui(cls, layout, params): super().parameters_ui(layout, params) ControlLayersOption.TWEAK.parameters_ui(layout, params) diff --git a/rigify/rigs/spines/super_head.py b/rigify/rigs/spines/super_head.py index 49f1ce3e..22a8873d 100644 --- a/rigify/rigs/spines/super_head.py +++ b/rigify/rigs/spines/super_head.py @@ -24,6 +24,9 @@ class Rig(BaseHeadTailRig): use_connect_reverse = False min_chain_length = 1 + long_neck: bool + has_neck: bool + def initialize(self): super().initialize() @@ -32,27 +35,20 @@ class Rig(BaseHeadTailRig): #################################################### # BONES - # - # org[]: - # ORG bones - # ctrl: - # neck, head, neck_bend: - # Main controls. - # tweak[]: - # Tweak control chain. - # mch: - # rot_neck, rot_head: - # Main control parents, implement FK follow. - # stretch - # Long neck stretch behavior. - # ik[] - # Long neck IK behavior. - # chain[] - # Tweak parents. - # deform[]: - # DEF bones - # - #################################################### + + class CtrlBones(BaseHeadTailRig.CtrlBones): + neck: str # Main neck control + head: str # Main head control + neck_bend: str # Extra neck bend control for long neck + + class MchBones(BaseHeadTailRig.MchBones): + rot_neck: str # Main neck control parent for FK follow + rot_head: str # Main head control parent for FK follow + stretch: str # Long neck stretch helper + ik: list[str] # Long neck IK system + chain: list[str] # Tweak parents + + bones: BaseHeadTailRig.ToplevelBones[list[str], CtrlBones, MchBones, list[str]] #################################################### # Main control bones @@ -72,7 +68,7 @@ class Rig(BaseHeadTailRig): self.default_prop_bone = ctrl.head - def make_neck_control_bone(self, org, name, org_head): + def make_neck_control_bone(self, org: str, name: str, org_head: str): name = self.copy_bone(org, name, parent=False) # Neck spans all neck bones (except head) @@ -80,7 +76,7 @@ class Rig(BaseHeadTailRig): return name - def make_neck_bend_control_bone(self, org, name, neck): + def make_neck_bend_control_bone(self, org: str, name: str, neck: str): name = self.copy_bone(org, name, parent=False) neck_bend_eb = self.get_bone(name) @@ -98,7 +94,7 @@ class Rig(BaseHeadTailRig): return name - def make_head_control_bone(self, org, name): + def make_head_control_bone(self, org: str, name: str): return self.copy_bone(org, name, parent=False) @stage.parent_bones @@ -119,7 +115,7 @@ class Rig(BaseHeadTailRig): if self.long_neck: self.configure_neck_bend_bone(self.bones.ctrl.neck_bend, self.bones.org[0]) - def configure_neck_bend_bone(self, ctrl, org): + def configure_neck_bend_bone(self, ctrl: str, _org: str): bone = self.get_bone(ctrl) bone.lock_rotation = (True, True, True) bone.lock_rotation_w = True @@ -134,7 +130,7 @@ class Rig(BaseHeadTailRig): if self.long_neck: self.make_neck_bend_widget(ctrl.neck_bend) - def make_neck_widget(self, ctrl): + def make_neck_widget(self, ctrl: str): radius = 1/max(1, len(self.bones.mch.chain)) create_circle_widget( @@ -143,7 +139,7 @@ class Rig(BaseHeadTailRig): head_tail=0.5, ) - def make_neck_bend_widget(self, ctrl): + def make_neck_bend_widget(self, ctrl: str): radius = 1/max(1, len(self.bones.mch.chain)) create_neck_bend_widget( @@ -152,7 +148,7 @@ class Rig(BaseHeadTailRig): head_tail=0.0, ) - def make_head_widget(self, ctrl): + def make_head_widget(self, ctrl: str): # place wgt @ middle of head bone for long necks if self.long_neck: head_tail = 0.5 @@ -161,9 +157,9 @@ class Rig(BaseHeadTailRig): create_circle_widget( self.obj, ctrl, - radius = 0.5, - head_tail = head_tail, - with_line = False, + radius=0.5, + head_tail=head_tail, + with_line=False, ) #################################################### @@ -179,7 +175,7 @@ class Rig(BaseHeadTailRig): mch.stretch = self.make_mch_stretch_bone(orgs[0], 'STR-neck', orgs[-1]) mch.rot_head = self.make_mch_follow_bone(orgs[-1], 'head', 0.0, copy_scale=True) - def make_mch_stretch_bone(self, org, name, org_head): + def make_mch_stretch_bone(self, org: str, name: str, org_head: str): name = self.copy_bone(org, make_derived_name(name, 'mch'), parent=False) self.get_bone(name).tail = self.get_bone(org_head).head return name @@ -198,7 +194,7 @@ class Rig(BaseHeadTailRig): if self.has_neck: self.rig_mch_stretch_bone(self.bones.mch.stretch, self.bones.ctrl.head) - def rig_mch_stretch_bone(self, mch, head): + def rig_mch_stretch_bone(self, mch: str, head: str): self.make_constraint(mch, 'STRETCH_TO', head, keep_axis='SWING_Y') #################################################### @@ -210,7 +206,7 @@ class Rig(BaseHeadTailRig): if self.long_neck: self.bones.mch.ik = map_list(self.make_mch_ik_bone, orgs[0:-1]) - def make_mch_ik_bone(self, org): + def make_mch_ik_bone(self, org: str): return self.copy_bone(org, make_derived_name(org, 'mch', '_ik'), parent=False) @stage.parent_bones @@ -228,7 +224,7 @@ class Rig(BaseHeadTailRig): for args in zip(count(0), ik): self.rig_mch_ik_bone(*args, len(ik), head) - def rig_mch_ik_bone(self, i, mch, ik_len, head): + def rig_mch_ik_bone(self, i: int, mch: str, ik_len: int, head: str): if i == ik_len - 1: self.make_constraint(mch, 'IK', head, chain_count=ik_len) @@ -242,7 +238,7 @@ class Rig(BaseHeadTailRig): orgs = self.bones.org self.bones.mch.chain = map_list(self.make_mch_bone, orgs[1:-1]) - def make_mch_bone(self, org): + def make_mch_bone(self, org: str): return self.copy_bone(org, make_derived_name(org, 'mch'), parent=False, scale=1/4) @stage.parent_bones @@ -267,14 +263,14 @@ class Rig(BaseHeadTailRig): for args in zip(count(0), chain): self.rig_mch_bone(*args, len(chain)) - def rig_mch_bone_long(self, i, mch, ik, len_mch): + def rig_mch_bone_long(self, i: int, mch: str, ik: str, len_mch: int): ctrl = self.bones.ctrl self.make_constraint(mch, 'COPY_LOCATION', ik) step = 2/(len_mch+1) - xval = (i+1)*step - influence = 2*xval - xval**2 #parabolic influence of pivot + x_val = (i+1)*step + influence = 2*x_val - x_val**2 # parabolic influence of pivot self.make_constraint( mch, 'COPY_LOCATION', ctrl.neck_bend, @@ -286,10 +282,10 @@ class Rig(BaseHeadTailRig): def rig_mch_bone(self, i, mch, len_mch): ctrl = self.bones.ctrl - nfactor = float((i + 1) / (len_mch + 1)) + n_factor = float((i + 1) / (len_mch + 1)) self.make_constraint( mch, 'COPY_ROTATION', ctrl.head, - influence=nfactor, space='LOCAL' + influence=n_factor, space='LOCAL' ) self.make_constraint(mch, 'COPY_SCALE', ctrl.neck) @@ -345,7 +341,7 @@ class Rig(BaseHeadTailRig): else: tweaks = [self.connected_tweak or self.bones.ctrl.head] - for args in zip(count(0), self.bones.org, tweaks, tweaks[1:] + [None]): + for args in zip(count(0), self.bones.org, tweaks, [*tweaks[1:], None]): self.rig_org_bone(*args) @@ -392,7 +388,10 @@ def create_sample(obj, *, parent=None): except AttributeError: pass try: - pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_layers = [ + False, False, False, False, True, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['neck.001']] diff --git a/rigify/rigs/spines/super_spine.py b/rigify/rigs/spines/super_spine.py index 7d60a57e..dc56f7a2 100644 --- a/rigify/rigs/spines/super_spine.py +++ b/rigify/rigs/spines/super_spine.py @@ -32,8 +32,8 @@ class Rig(SubstitutionRig, BoneUtilityMixin): if neck_pos >= len(orgs): self.raise_error("Neck is too short.") - spine_orgs = orgs[0 : neck_pos-1] - head_orgs = orgs[neck_pos-1 : ] + spine_orgs = orgs[0: neck_pos-1] + head_orgs = orgs[neck_pos-1:] if self.params.use_tail: tail_pos = self.params.tail_pos @@ -42,8 +42,8 @@ class Rig(SubstitutionRig, BoneUtilityMixin): if tail_pos >= pivot_pos: self.raise_error("Tail cannot be above or the same as pivot.") - tail_orgs = list(reversed(spine_orgs[0 : tail_pos])) - spine_orgs = spine_orgs[tail_pos : ] + tail_orgs = list(reversed(spine_orgs[0: tail_pos])) + spine_orgs = spine_orgs[tail_pos:] pivot_pos -= tail_pos # Split the bone chain and flip the tail @@ -65,17 +65,17 @@ class Rig(SubstitutionRig, BoneUtilityMixin): # Create the parts self.assign_params(spine_orgs[0], params_copy, pivot_pos=pivot_pos, make_fk_controls=False) - result = [ self.instantiate_rig(basic_spine.Rig, spine_orgs[0]) ] + result = [self.instantiate_rig(basic_spine.Rig, spine_orgs[0])] if tail_orgs: self.assign_params(tail_orgs[0], params_copy, connect_chain=True) - result += [ self.instantiate_rig(basic_tail.Rig, tail_orgs[0]) ] + result += [self.instantiate_rig(basic_tail.Rig, tail_orgs[0])] if head_orgs: self.assign_params(head_orgs[0], params_copy, connect_chain=True) - result += [ self.instantiate_rig(super_head.Rig, head_orgs[0]) ] + result += [self.instantiate_rig(super_head.Rig, head_orgs[0])] return result @@ -86,10 +86,10 @@ def add_parameters(params): super_head.Rig.add_parameters(params) params.neck_pos = bpy.props.IntProperty( - name = 'neck_position', - default = 6, - min = 0, - description = 'Neck start position' + name='neck_position', + default=6, + min=0, + description='Neck start position' ) params.tail_pos = bpy.props.IntProperty( diff --git a/rigify/rigs/utils.py b/rigify/rigs/utils.py index cbc53e3a..9fd9a2c1 100644 --- a/rigify/rigs/utils.py +++ b/rigify/rigs/utils.py @@ -15,7 +15,7 @@ def get_future_names_arm(bones): farm = strip_mch(strip_org(bones[1].name)) hand = strip_mch(strip_org(bones[2].name)) - suffix='' + suffix = '' if uarm[-2:] == '.L' or uarm[-2:] == '.R': suffix = uarm[-2:] uarm = uarm.rstrip(suffix) @@ -33,7 +33,7 @@ def get_future_names_arm(bones): # pole = 'upper_arm_ik_target.L' names['controls'] = [uarm + '_ik', uarm + '_fk', farm + '_fk', hand + '_fk', hand + '_ik', - make_mechanism_name(hand + '_fk'), uarm + '_parent'] + make_mechanism_name(hand + '_fk'), uarm + '_parent'] names['ik_ctrl'] = [hand + '_ik', make_mechanism_name(uarm) + '_ik', make_mechanism_name(uarm) + '_ik_target'] names['fk_ctrl'] = uarm + '_fk' + suffix names['parent'] = uarm + '_parent' + suffix @@ -80,7 +80,7 @@ def get_future_names_leg(bones): # pole = 'thigh_ik_target.R' names['controls'] = [thigh + '_ik', thigh + '_fk', shin + '_fk', foot + '_fk', toe, foot + '_heel_ik', - foot + '_ik', make_mechanism_name(foot + '_fk'), thigh + '_parent'] + foot + '_ik', make_mechanism_name(foot + '_fk'), thigh + '_parent'] names['ik_ctrl'] = [foot + '_ik', make_mechanism_name(thigh) + '_ik', make_mechanism_name(thigh) + '_ik_target'] names['fk_ctrl'] = thigh + '_fk' + suffix names['parent'] = thigh + '_parent' + suffix @@ -128,7 +128,7 @@ def get_future_names_paw(bones): # pole = 'thigh_ik_target.R' names['controls'] = [thigh + '_ik', thigh + '_fk', shin + '_fk', foot + '_fk', toe, foot + '_heel_ik', - foot + '_ik', make_mechanism_name(foot + '_fk'), thigh + '_parent'] + foot + '_ik', make_mechanism_name(foot + '_fk'), thigh + '_parent'] names['ik_ctrl'] = [foot + '_ik', make_mechanism_name(thigh) + '_ik', make_mechanism_name(thigh) + '_ik_target'] names['fk_ctrl'] = thigh + '_fk' + suffix names['parent'] = thigh + '_parent' + suffix @@ -157,17 +157,17 @@ def get_future_names(bones): def get_limb_generated_names(rig): - pbones = rig.pose.bones + pose_bones = rig.pose.bones names = dict() - for b in pbones: + for b in pose_bones: super_limb_orgs = [] if re.match('^ORG', b.name) and b.rigify_type == 'limbs.super_limb': super_limb_orgs.append(b) children = connected_children_names(rig, b.name) for child in children: if re.match('^ORG', child) or re.match('^MCH', child): - super_limb_orgs.append(pbones[child]) + super_limb_orgs.append(pose_bones[child]) names[b.name] = get_future_names(super_limb_orgs) return names diff --git a/rigify/rigs/widgets.py b/rigify/rigs/widgets.py index acafe750..6abcf466 100644 --- a/rigify/rigs/widgets.py +++ b/rigify/rigs/widgets.py @@ -9,8 +9,33 @@ MODULE_NAME = "super_widgets" # Windows/Mac blender is weird, so __package__ do def create_eye_widget(rig, bone_name, size=1.0, bone_transform_name=None): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(1.1920928955078125e-07*size, 0.5000000596046448*size, 0.0*size), (-0.12940943241119385*size, 0.482962965965271*size, 0.0*size), (-0.24999988079071045*size, 0.4330127537250519*size, 0.0*size), (-0.35355329513549805*size, 0.35355344414711*size, 0.0*size), (-0.43301260471343994*size, 0.2500000596046448*size, 0.0*size), (-0.4829627275466919*size, 0.12940959632396698*size, 0.0*size), (-0.49999988079071045*size, 1.0094120739267964e-07*size, 0.0*size), (-0.482962965965271*size, -0.12940940260887146*size, 0.0*size), (-0.43301260471343994*size, -0.24999986588954926*size, 0.0*size), (-0.3535534143447876*size, -0.35355323553085327*size, 0.0*size), (-0.25*size, -0.43301257491111755*size, 0.0*size), (-0.1294095516204834*size, -0.48296281695365906*size, 0.0*size), (-1.1920928955078125e-07*size, -0.4999999403953552*size, 0.0*size), (0.12940943241119385*size, -0.4829629063606262*size, 0.0*size), (0.24999988079071045*size, -0.4330127537250519*size, 0.0*size), (0.35355329513549805*size, -0.35355353355407715*size, 0.0*size), (0.4330127239227295*size, -0.25000008940696716*size, 0.0*size), (0.482962965965271*size, -0.12940965592861176*size, 0.0*size), (0.5000001192092896*size, -1.6926388468618825e-07*size, 0.0*size), (0.48296308517456055*size, 0.1294093281030655*size, 0.0*size), (0.4330129623413086*size, 0.24999980628490448*size, 0.0*size), (0.35355377197265625*size, 0.35355323553085327*size, 0.0*size), (0.25000035762786865*size, 0.43301260471343994*size, 0.0*size), (0.1294100284576416*size, 0.48296287655830383*size, 0.0*size), ] - edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] + verts = [(1.1920928955078125e-07*size, 0.5000000596046448*size, 0.0*size), + (-0.12940943241119385*size, 0.482962965965271*size, 0.0*size), + (-0.24999988079071045*size, 0.4330127537250519*size, 0.0*size), + (-0.35355329513549805*size, 0.35355344414711*size, 0.0*size), + (-0.43301260471343994*size, 0.2500000596046448*size, 0.0*size), + (-0.4829627275466919*size, 0.12940959632396698*size, 0.0*size), + (-0.49999988079071045*size, 1.0094120739267964e-07*size, 0.0*size), + (-0.482962965965271*size, -0.12940940260887146*size, 0.0*size), + (-0.43301260471343994*size, -0.24999986588954926*size, 0.0*size), + (-0.3535534143447876*size, -0.35355323553085327*size, 0.0*size), + (-0.25*size, -0.43301257491111755*size, 0.0*size), + (-0.1294095516204834*size, -0.48296281695365906*size, 0.0*size), + (-1.1920928955078125e-07*size, -0.4999999403953552*size, 0.0*size), + (0.12940943241119385*size, -0.4829629063606262*size, 0.0*size), + (0.24999988079071045*size, -0.4330127537250519*size, 0.0*size), + (0.35355329513549805*size, -0.35355353355407715*size, 0.0*size), + (0.4330127239227295*size, -0.25000008940696716*size, 0.0*size), + (0.482962965965271*size, -0.12940965592861176*size, 0.0*size), + (0.5000001192092896*size, -1.6926388468618825e-07*size, 0.0*size), + (0.48296308517456055*size, 0.1294093281030655*size, 0.0*size), + (0.4330129623413086*size, 0.24999980628490448*size, 0.0*size), + (0.35355377197265625*size, 0.35355323553085327*size, 0.0*size), + (0.25000035762786865*size, 0.43301260471343994*size, 0.0*size), + (0.1294100284576416*size, 0.48296287655830383*size, 0.0*size), ] + edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), + (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), + (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] faces = [] mesh = obj.data @@ -24,8 +49,92 @@ def create_eye_widget(rig, bone_name, size=1.0, bone_transform_name=None): def create_eyes_widget(rig, bone_name, size=1.0, bone_transform_name=None): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(0.8928930759429932*size, -0.7071065902709961*size, 0.0*size), (0.8928932547569275*size, 0.7071067690849304*size, 0.0*size), (-1.8588197231292725*size, -0.9659252762794495*size, 0.0*size), (-2.100001096725464*size, -0.8660248517990112*size, 0.0*size), (-2.3071072101593018*size, -0.7071059942245483*size, 0.0*size), (-2.4660258293151855*size, -0.49999913573265076*size, 0.0*size), (-2.5659260749816895*size, -0.258818119764328*size, 0.0*size), (-2.5999999046325684*size, 8.575012770961621e-07*size, 0.0*size), (-2.5659255981445312*size, 0.2588198482990265*size, 0.0*size), (-2.4660253524780273*size, 0.5000006556510925*size, 0.0*size), (-2.3071064949035645*size, 0.7071075439453125*size, 0.0*size), (-2.099999189376831*size, 0.866025984287262*size, 0.0*size), (-1.8588184118270874*size, 0.9659261703491211*size, 0.0*size), (-1.5999996662139893*size, 1.000000238418579*size, 0.0*size), (-1.341180443763733*size, 0.9659258723258972*size, 0.0*size), (-1.0999995470046997*size, 0.8660253882408142*size, 0.0*size), (-0.8928929567337036*size, 0.7071067094802856*size, 0.0*size), (-0.892893373966217*size, -0.7071066498756409*size, 0.0*size), (-1.100000262260437*size, -0.8660252690315247*size, 0.0*size), (-1.3411810398101807*size, -0.9659255743026733*size, 0.0*size), (1.600000023841858*size, 1.0*size, 0.0*size), (1.3411810398101807*size, 0.9659258127212524*size, 0.0*size), (1.100000023841858*size, 0.8660253882408142*size, 0.0*size), (-1.600000262260437*size, -0.9999997615814209*size, 0.0*size), (1.0999997854232788*size, -0.8660252690315247*size, 0.0*size), (1.341180682182312*size, -0.9659257531166077*size, 0.0*size), (1.5999996662139893*size, -1.0*size, 0.0*size), (1.8588186502456665*size, -0.965925931930542*size, 0.0*size), (2.0999996662139893*size, -0.8660256266593933*size, 0.0*size), (2.3071064949035645*size, -0.7071071863174438*size, 0.0*size), (2.4660253524780273*size, -0.5000002980232239*size, 0.0*size), (2.5659255981445312*size, -0.25881943106651306*size, 0.0*size), (2.5999999046325684*size, -4.649122899991198e-07*size, 0.0*size), (2.5659260749816895*size, 0.25881853699684143*size, 0.0*size), (2.4660258293151855*size, 0.4999994933605194*size, 0.0*size), (2.3071072101593018*size, 0.707106351852417*size, 0.0*size), (2.1000006198883057*size, 0.8660250902175903*size, 0.0*size), (1.8588197231292725*size, 0.9659256339073181*size, 0.0*size), (-1.8070557117462158*size, -0.7727401852607727*size, 0.0*size), (-2.0000009536743164*size, -0.6928198337554932*size, 0.0*size), (-2.1656856536865234*size, -0.5656847357749939*size, 0.0*size), (-2.292820692062378*size, -0.3999992609024048*size, 0.0*size), (-2.3727407455444336*size, -0.20705445110797882*size, 0.0*size), (-2.3999998569488525*size, 7.336847716032935e-07*size, 0.0*size), (-2.3727405071258545*size, 0.207055926322937*size, 0.0*size), (-2.2928202152252197*size, 0.40000057220458984*size, 0.0*size), (-2.1656851768493652*size, 0.5656861066818237*size, 0.0*size), (-1.9999992847442627*size, 0.6928208470344543*size, 0.0*size), (-1.8070547580718994*size, 0.7727410197257996*size, 0.0*size), (-1.5999996662139893*size, 0.8000002503395081*size, 0.0*size), (-1.3929443359375*size, 0.7727407813072205*size, 0.0*size), (-1.1999995708465576*size, 0.6928203701972961*size, 0.0*size), (-1.0343143939971924*size, 0.5656854510307312*size, 0.0*size), (-1.0343146324157715*size, -0.5656852722167969*size, 0.0*size), (-1.2000001668930054*size, -0.6928201913833618*size, 0.0*size), (-1.3929448127746582*size, -0.7727404236793518*size, 0.0*size), (-1.6000001430511475*size, -0.7999997735023499*size, 0.0*size), (1.8070557117462158*size, 0.772739827632904*size, 0.0*size), (2.0000009536743164*size, 0.6928195953369141*size, 0.0*size), (2.1656856536865234*size, 0.5656843781471252*size, 0.0*size), (2.292820692062378*size, 0.39999890327453613*size, 0.0*size), (2.3727407455444336*size, 0.20705409348011017*size, 0.0*size), (2.3999998569488525*size, -1.0960745839838637e-06*size, 0.0*size), (2.3727405071258545*size, -0.20705628395080566*size, 0.0*size), (2.2928202152252197*size, -0.4000009298324585*size, 0.0*size), (2.1656851768493652*size, -0.5656863451004028*size, 0.0*size), (1.9999992847442627*size, -0.692821204662323*size, 0.0*size), (1.8070547580718994*size, -0.7727413773536682*size, 0.0*size), (1.5999996662139893*size, -0.8000004887580872*size, 0.0*size), (1.3929443359375*size, -0.7727410197257996*size, 0.0*size), (1.1999995708465576*size, -0.6928204894065857*size, 0.0*size), (1.0343143939971924*size, -0.5656855702400208*size, 0.0*size), (1.0343146324157715*size, 0.5656850337982178*size, 0.0*size), (1.2000004053115845*size, 0.6928199529647827*size, 0.0*size), (1.3929448127746582*size, 0.7727401852607727*size, 0.0*size), (1.6000001430511475*size, 0.7999995350837708*size, 0.0*size), ] - edges = [(24, 0), (1, 22), (16, 1), (17, 0), (23, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (21, 20), (22, 21), (13, 14), (14, 15), (15, 16), (17, 18), (18, 19), (19, 23), (25, 24), (26, 25), (27, 26), (28, 27), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (20, 37), (56, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49), (49, 50), (50, 51), (51, 52), (53, 54), (54, 55), (55, 56), (75, 57), (57, 58), (58, 59), (59, 60), (60, 61), (61, 62), (62, 63), (63, 64), (64, 65), (65, 66), (66, 67), (67, 68), (68, 69), (69, 70), (70, 71), (72, 73), (73, 74), (74, 75), (52, 72), (53, 71), ] + verts = [(0.8928930759429932*size, -0.7071065902709961*size, 0.0*size), + (0.8928932547569275*size, 0.7071067690849304*size, 0.0*size), + (-1.8588197231292725*size, -0.9659252762794495*size, 0.0*size), + (-2.100001096725464*size, -0.8660248517990112*size, 0.0*size), + (-2.3071072101593018*size, -0.7071059942245483*size, 0.0*size), + (-2.4660258293151855*size, -0.49999913573265076*size, 0.0*size), + (-2.5659260749816895*size, -0.258818119764328*size, 0.0*size), + (-2.5999999046325684*size, 8.575012770961621e-07*size, 0.0*size), + (-2.5659255981445312*size, 0.2588198482990265*size, 0.0*size), + (-2.4660253524780273*size, 0.5000006556510925*size, 0.0*size), + (-2.3071064949035645*size, 0.7071075439453125*size, 0.0*size), + (-2.099999189376831*size, 0.866025984287262*size, 0.0*size), + (-1.8588184118270874*size, 0.9659261703491211*size, 0.0*size), + (-1.5999996662139893*size, 1.000000238418579*size, 0.0*size), + (-1.341180443763733*size, 0.9659258723258972*size, 0.0*size), + (-1.0999995470046997*size, 0.8660253882408142*size, 0.0*size), + (-0.8928929567337036*size, 0.7071067094802856*size, 0.0*size), + (-0.892893373966217*size, -0.7071066498756409*size, 0.0*size), + (-1.100000262260437*size, -0.8660252690315247*size, 0.0*size), + (-1.3411810398101807*size, -0.9659255743026733*size, 0.0*size), + (1.600000023841858*size, 1.0*size, 0.0*size), + (1.3411810398101807*size, 0.9659258127212524*size, 0.0*size), + (1.100000023841858*size, 0.8660253882408142*size, 0.0*size), + (-1.600000262260437*size, -0.9999997615814209*size, 0.0*size), + (1.0999997854232788*size, -0.8660252690315247*size, 0.0*size), + (1.341180682182312*size, -0.9659257531166077*size, 0.0*size), + (1.5999996662139893*size, -1.0*size, 0.0*size), + (1.8588186502456665*size, -0.965925931930542*size, 0.0*size), + (2.0999996662139893*size, -0.8660256266593933*size, 0.0*size), + (2.3071064949035645*size, -0.7071071863174438*size, 0.0*size), + (2.4660253524780273*size, -0.5000002980232239*size, 0.0*size), + (2.5659255981445312*size, -0.25881943106651306*size, 0.0*size), + (2.5999999046325684*size, -4.649122899991198e-07*size, 0.0*size), + (2.5659260749816895*size, 0.25881853699684143*size, 0.0*size), + (2.4660258293151855*size, 0.4999994933605194*size, 0.0*size), + (2.3071072101593018*size, 0.707106351852417*size, 0.0*size), + (2.1000006198883057*size, 0.8660250902175903*size, 0.0*size), + (1.8588197231292725*size, 0.9659256339073181*size, 0.0*size), + (-1.8070557117462158*size, -0.7727401852607727*size, 0.0*size), + (-2.0000009536743164*size, -0.6928198337554932*size, 0.0*size), + (-2.1656856536865234*size, -0.5656847357749939*size, 0.0*size), + (-2.292820692062378*size, -0.3999992609024048*size, 0.0*size), + (-2.3727407455444336*size, -0.20705445110797882*size, 0.0*size), + (-2.3999998569488525*size, 7.336847716032935e-07*size, 0.0*size), + (-2.3727405071258545*size, 0.207055926322937*size, 0.0*size), + (-2.2928202152252197*size, 0.40000057220458984*size, 0.0*size), + (-2.1656851768493652*size, 0.5656861066818237*size, 0.0*size), + (-1.9999992847442627*size, 0.6928208470344543*size, 0.0*size), + (-1.8070547580718994*size, 0.7727410197257996*size, 0.0*size), + (-1.5999996662139893*size, 0.8000002503395081*size, 0.0*size), + (-1.3929443359375*size, 0.7727407813072205*size, 0.0*size), + (-1.1999995708465576*size, 0.6928203701972961*size, 0.0*size), + (-1.0343143939971924*size, 0.5656854510307312*size, 0.0*size), + (-1.0343146324157715*size, -0.5656852722167969*size, 0.0*size), + (-1.2000001668930054*size, -0.6928201913833618*size, 0.0*size), + (-1.3929448127746582*size, -0.7727404236793518*size, 0.0*size), + (-1.6000001430511475*size, -0.7999997735023499*size, 0.0*size), + (1.8070557117462158*size, 0.772739827632904*size, 0.0*size), + (2.0000009536743164*size, 0.6928195953369141*size, 0.0*size), + (2.1656856536865234*size, 0.5656843781471252*size, 0.0*size), + (2.292820692062378*size, 0.39999890327453613*size, 0.0*size), + (2.3727407455444336*size, 0.20705409348011017*size, 0.0*size), + (2.3999998569488525*size, -1.0960745839838637e-06*size, 0.0*size), + (2.3727405071258545*size, -0.20705628395080566*size, 0.0*size), + (2.2928202152252197*size, -0.4000009298324585*size, 0.0*size), + (2.1656851768493652*size, -0.5656863451004028*size, 0.0*size), + (1.9999992847442627*size, -0.692821204662323*size, 0.0*size), + (1.8070547580718994*size, -0.7727413773536682*size, 0.0*size), + (1.5999996662139893*size, -0.8000004887580872*size, 0.0*size), + (1.3929443359375*size, -0.7727410197257996*size, 0.0*size), + (1.1999995708465576*size, -0.6928204894065857*size, 0.0*size), + (1.0343143939971924*size, -0.5656855702400208*size, 0.0*size), + (1.0343146324157715*size, 0.5656850337982178*size, 0.0*size), + (1.2000004053115845*size, 0.6928199529647827*size, 0.0*size), + (1.3929448127746582*size, 0.7727401852607727*size, 0.0*size), + (1.6000001430511475*size, 0.7999995350837708*size, 0.0*size), ] + edges = [(24, 0), (1, 22), (16, 1), (17, 0), (23, 2), (2, 3), (3, 4), (4, 5), (5, 6), + (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (21, 20), (22, 21), + (13, 14), (14, 15), (15, 16), (17, 18), (18, 19), (19, 23), (25, 24), (26, 25), + (27, 26), (28, 27), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), + (35, 34), (36, 35), (37, 36), (20, 37), (56, 38), (38, 39), (39, 40), (40, 41), + (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49), + (49, 50), (50, 51), (51, 52), (53, 54), (54, 55), (55, 56), (75, 57), (57, 58), + (58, 59), (59, 60), (60, 61), (61, 62), (62, 63), (63, 64), (64, 65), (65, 66), + (66, 67), (67, 68), (68, 69), (69, 70), (70, 71), (72, 73), (73, 74), (74, 75), + (52, 72), (53, 71), ] faces = [] mesh = obj.data @@ -39,8 +148,33 @@ def create_eyes_widget(rig, bone_name, size=1.0, bone_transform_name=None): def create_ear_widget(rig, bone_name, size=1.0, bone_transform_name=None): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(-2.4903741291382175e-09*size, 1.0*size, -3.123863123732917e-08*size), (-7.450580596923828e-09*size, 0.9829629063606262*size, 0.0776456817984581*size), (-1.4901161193847656e-08*size, 0.9330127239227295*size, 0.1499999761581421*size), (-2.9802322387695312e-08*size, 0.8535534143447876*size, 0.2121320217847824*size), (-2.9802322387695312e-08*size, 0.75*size, 0.25980761647224426*size), (-2.9802322387695312e-08*size, 0.6294095516204834*size, 0.2897777259349823*size), (-2.9802322387695312e-08*size, 0.5000000596046448*size, 0.29999998211860657*size), (-5.960464477539063e-08*size, 0.37059056758880615*size, 0.2897777855396271*size), (-5.960464477539063e-08*size, 0.25000008940696716*size, 0.25980767607688904*size), (-4.470348358154297e-08*size, 0.14644670486450195*size, 0.21213211119174957*size), (-4.470348358154297e-08*size, 0.06698736548423767*size, 0.15000009536743164*size), (-4.470348358154297e-08*size, 0.017037123441696167*size, 0.07764581590890884*size), (-3.6718930118695425e-08*size, 0.0*size, 1.1981423142515268e-07*size), (-2.9802322387695312e-08*size, 0.017037034034729004*size, -0.07764559239149094*size), (-2.9802322387695312e-08*size, 0.06698718667030334*size, -0.14999987185001373*size), (-1.4901161193847656e-08*size, 0.14644640684127808*size, -0.21213191747665405*size), (0.0*size, 0.24999985098838806*size, -0.25980761647224426*size), (0.0*size, 0.3705902695655823*size, -0.2897777259349823*size), (0.0*size, 0.4999997615814209*size, -0.30000004172325134*size), (0.0*size, 0.6294092535972595*size, -0.2897777855396271*size), (0.0*size, 0.7499997615814209*size, -0.2598077356815338*size), (1.4901161193847656e-08*size, 0.8535531759262085*size, -0.21213220059871674*size), (0.0*size, 0.9330125451087952*size, -0.15000019967556*size), (0.0*size, 0.9829628467559814*size, -0.07764596492052078*size), ] - edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] + verts = [(-2.4903741291382175e-09*size, 1.0*size, -3.123863123732917e-08*size), + (-7.450580596923828e-09*size, 0.9829629063606262*size, 0.0776456817984581*size), + (-1.4901161193847656e-08*size, 0.9330127239227295*size, 0.1499999761581421*size), + (-2.9802322387695312e-08*size, 0.8535534143447876*size, 0.2121320217847824*size), + (-2.9802322387695312e-08*size, 0.75*size, 0.25980761647224426*size), + (-2.9802322387695312e-08*size, 0.6294095516204834*size, 0.2897777259349823*size), + (-2.9802322387695312e-08*size, 0.5000000596046448*size, 0.29999998211860657*size), + (-5.960464477539063e-08*size, 0.37059056758880615*size, 0.2897777855396271*size), + (-5.960464477539063e-08*size, 0.25000008940696716*size, 0.25980767607688904*size), + (-4.470348358154297e-08*size, 0.14644670486450195*size, 0.21213211119174957*size), + (-4.470348358154297e-08*size, 0.06698736548423767*size, 0.15000009536743164*size), + (-4.470348358154297e-08*size, 0.017037123441696167*size, 0.07764581590890884*size), + (-3.6718930118695425e-08*size, 0.0*size, 1.1981423142515268e-07*size), + (-2.9802322387695312e-08*size, 0.017037034034729004*size, -0.07764559239149094*size), + (-2.9802322387695312e-08*size, 0.06698718667030334*size, -0.14999987185001373*size), + (-1.4901161193847656e-08*size, 0.14644640684127808*size, -0.21213191747665405*size), + (0.0*size, 0.24999985098838806*size, -0.25980761647224426*size), + (0.0*size, 0.3705902695655823*size, -0.2897777259349823*size), + (0.0*size, 0.4999997615814209*size, -0.30000004172325134*size), + (0.0*size, 0.6294092535972595*size, -0.2897777855396271*size), + (0.0*size, 0.7499997615814209*size, -0.2598077356815338*size), + (1.4901161193847656e-08*size, 0.8535531759262085*size, -0.21213220059871674*size), + (0.0*size, 0.9330125451087952*size, -0.15000019967556*size), + (0.0*size, 0.9829628467559814*size, -0.07764596492052078*size), ] + edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), + (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), + (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] faces = [] mesh = obj.data @@ -53,21 +187,78 @@ def create_ear_widget(rig, bone_name, size=1.0, bone_transform_name=None): @widget_generator(register="jaw") def create_jaw_widget(geom, size=1.0): - geom.verts = [(0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), (0.0*size, 1.153113603591919*size, 0.0*size), (-0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (-0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.0*size, 1.153113603591919*size, 0.18649044632911682*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (-0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size)] - geom.edges = [(1, 0), (2, 1), (3, 2), (4, 3), (9, 4), (6, 5), (7, 6), (8, 7), (15, 8), (5, 0), (11, 10), (12, 11), (13, 12), (14, 13), (9, 14), (17, 16), (18, 17), (19, 18), (15, 19), (16, 10)] + geom.verts = [(0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), + (0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), + (0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), + (0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), + (0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), + (0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), + (0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), + (0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), + (0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), + (0.0*size, 1.153113603591919*size, 0.0*size), + (-0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), + (-0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), + (-0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), + (-0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), + (-0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), + (0.0*size, 1.153113603591919*size, 0.18649044632911682*size), + (-0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), + (-0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), + (-0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), + (-0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size)] + geom.edges = [(1, 0), (2, 1), (3, 2), (4, 3), (9, 4), (6, 5), (7, 6), (8, 7), (15, 8), (5, 0), + (11, 10), (12, 11), (13, 12), (14, 13), (9, 14), (17, 16), (18, 17), (19, 18), + (15, 19), (16, 10)] @widget_generator(register="teeth") def create_teeth_widget(geom, *, size=1.0): - geom.verts = [(0.6314387321472168*size, 0.4999997019767761*size, 0.09999999403953552*size), (0.5394065976142883*size, 0.29289281368255615*size, 0.09999999403953552*size), (0.3887903690338135*size, 0.1339743733406067*size, 0.09999999403953552*size), (0.19801488518714905*size, 0.03407406806945801*size, 0.09999999403953552*size), (-3.4034394502668874e-07*size, 0.0*size, 0.09999999403953552*size), (-0.19801555573940277*size, 0.034074246883392334*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, -0.10000000894069672*size), (-0.6778771877288818*size, 0.7411810755729675*size, -0.10000000894069672*size), (-0.6314389705657959*size, 0.5000001192092896*size, -0.10000000894069672*size), (-0.5394070148468018*size, 0.2928934097290039*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, -0.10000000894069672*size), (-0.19801555573940277*size, 0.034074246883392334*size, -0.10000000894069672*size), (-3.4034394502668874e-07*size, 0.0*size, -0.10000000894069672*size), (0.19801488518714905*size, 0.03407406806945801*size, -0.10000000894069672*size), (0.3887903690338135*size, 0.1339743733406067*size, -0.10000000894069672*size), (0.5394065976142883*size, 0.29289281368255615*size, -0.10000000894069672*size), (0.6314387321472168*size, 0.4999997019767761*size, -0.10000000894069672*size), (0.6778769493103027*size, 0.7411805391311646*size, -0.10000000894069672*size), (0.6999999284744263*size, 0.9999995231628418*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, 0.09999999403953552*size), (-0.5394070148468018*size, 0.2928934097290039*size, 0.09999999403953552*size), (-0.6314389705657959*size, 0.5000001192092896*size, 0.09999999403953552*size), (-0.6778771877288818*size, 0.7411810755729675*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, 0.09999999403953552*size), (0.6778769493103027*size, 0.7411805391311646*size, 0.09999999403953552*size), (0.6999999284744263*size, 0.9999995231628418*size, 0.09999999403953552*size)] - geom.edges = [(25, 24), (24, 0), (0, 1), (1, 2), (2, 3), (3, 4), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (4, 5), (5, 19), (19, 20), (20, 21), (21, 22), (22, 23), (18, 25), (6, 23)] + geom.verts = [(0.6314387321472168*size, 0.4999997019767761*size, 0.09999999403953552*size), + (0.5394065976142883*size, 0.29289281368255615*size, 0.09999999403953552*size), + (0.3887903690338135*size, 0.1339743733406067*size, 0.09999999403953552*size), + (0.19801488518714905*size, 0.03407406806945801*size, 0.09999999403953552*size), + (-3.4034394502668874e-07*size, 0.0*size, 0.09999999403953552*size), + (-0.19801555573940277*size, 0.034074246883392334*size, 0.09999999403953552*size), + (-0.7000000476837158*size, 1.0000001192092896*size, -0.10000000894069672*size), + (-0.6778771877288818*size, 0.7411810755729675*size, -0.10000000894069672*size), + (-0.6314389705657959*size, 0.5000001192092896*size, -0.10000000894069672*size), + (-0.5394070148468018*size, 0.2928934097290039*size, -0.10000000894069672*size), + (-0.38879096508026123*size, 0.13397473096847534*size, -0.10000000894069672*size), + (-0.19801555573940277*size, 0.034074246883392334*size, -0.10000000894069672*size), + (-3.4034394502668874e-07*size, 0.0*size, -0.10000000894069672*size), + (0.19801488518714905*size, 0.03407406806945801*size, -0.10000000894069672*size), + (0.3887903690338135*size, 0.1339743733406067*size, -0.10000000894069672*size), + (0.5394065976142883*size, 0.29289281368255615*size, -0.10000000894069672*size), + (0.6314387321472168*size, 0.4999997019767761*size, -0.10000000894069672*size), + (0.6778769493103027*size, 0.7411805391311646*size, -0.10000000894069672*size), + (0.6999999284744263*size, 0.9999995231628418*size, -0.10000000894069672*size), + (-0.38879096508026123*size, 0.13397473096847534*size, 0.09999999403953552*size), + (-0.5394070148468018*size, 0.2928934097290039*size, 0.09999999403953552*size), + (-0.6314389705657959*size, 0.5000001192092896*size, 0.09999999403953552*size), + (-0.6778771877288818*size, 0.7411810755729675*size, 0.09999999403953552*size), + (-0.7000000476837158*size, 1.0000001192092896*size, 0.09999999403953552*size), + (0.6778769493103027*size, 0.7411805391311646*size, 0.09999999403953552*size), + (0.6999999284744263*size, 0.9999995231628418*size, 0.09999999403953552*size)] + geom.edges = [(25, 24), (24, 0), (0, 1), (1, 2), (2, 3), (3, 4), (7, 6), (8, 7), (9, 8), + (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), + (18, 17), (4, 5), (5, 19), (19, 20), (20, 21), (21, 22), (22, 23), (18, 25), + (6, 23)] def create_face_widget(rig, bone_name, size=1.0, bone_transform_name=None): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(-0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, -0.25*size, -0.07499998807907104*size), (-0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, -0.25*size, -0.07499998807907104*size), ] - edges = [(4, 5), (5, 1), (1, 0), (0, 4), (5, 6), (6, 2), (2, 1), (6, 7), (7, 3), (3, 2), (7, 4), (0, 3), ] + verts = [(-0.25*size, -0.25*size, 0.07499998807907104*size), + (-0.25*size, 0.25*size, 0.07499998807907104*size), + (0.25*size, 0.25*size, 0.07499998807907104*size), + (0.25*size, -0.25*size, 0.07499998807907104*size), + (-0.25*size, -0.25*size, -0.07499998807907104*size), + (-0.25*size, 0.25*size, -0.07499998807907104*size), + (0.25*size, 0.25*size, -0.07499998807907104*size), + (0.25*size, -0.25*size, -0.07499998807907104*size), ] + edges = [(4, 5), (5, 1), (1, 0), (0, 4), (5, 6), (6, 2), (2, 1), (6, 7), (7, 3), + (3, 2), (7, 4), (0, 3), ] faces = [] mesh = obj.data @@ -78,11 +269,26 @@ def create_face_widget(rig, bone_name, size=1.0, bone_transform_name=None): return None +# noinspection SpellCheckingInspection def create_ikarrow_widget(rig, bone_name, size=1.0, bone_transform_name=None, roll=0): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.0*size, 1.0*size, -0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), (0.0*size, 1.0*size, 0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), ] - edges = [(0, 1), (2, 3), (1, 4), (4, 5), (3, 6), (5, 6), (0, 2), (7, 8), (9, 10), (8, 11), (11, 12), (10, 13), (12, 13), (7, 9), ] + verts = [(0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), + (0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), + (-0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), + (-0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), + (0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), + (0.0*size, 1.0*size, -0.30000001192092896*size), + (-0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), + (0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), + (0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), + (-0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), + (-0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), + (0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), + (0.0*size, 1.0*size, 0.30000001192092896*size), + (-0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), ] + edges = [(0, 1), (2, 3), (1, 4), (4, 5), (3, 6), (5, 6), (0, 2), (7, 8), (9, 10), + (8, 11), (11, 12), (10, 13), (12, 13), (7, 9), ] faces = [] mesh = obj.data @@ -101,7 +307,14 @@ def create_hand_widget(rig, bone_name, size=1.0, bone_transform_name=None): # Create hand widget obj = create_widget(rig, bone_name, bone_transform_name, subsurf=2) if obj is not None: - verts = [(0.0*size, 1.5*size, -0.7000000476837158*size), (1.1920928955078125e-07*size, -0.25*size, -0.6999999284744263*size), (0.0*size, -0.25*size, 0.7000000476837158*size), (-1.1920928955078125e-07*size, 1.5*size, 0.6999999284744263*size), (5.960464477539063e-08*size, 0.7229999899864197*size, -0.699999988079071*size), (-5.960464477539063e-08*size, 0.7229999899864197*size, 0.699999988079071*size), (1.1920928955078125e-07*size, -2.9802322387695312e-08*size, -0.699999988079071*size), (0.0*size, 2.9802322387695312e-08*size, 0.699999988079071*size), ] + verts = [(0.0*size, 1.5*size, -0.7000000476837158*size), + (1.1920928955078125e-07*size, -0.25*size, -0.6999999284744263*size), + (0.0*size, -0.25*size, 0.7000000476837158*size), + (-1.1920928955078125e-07*size, 1.5*size, 0.6999999284744263*size), + (5.960464477539063e-08*size, 0.7229999899864197*size, -0.699999988079071*size), + (-5.960464477539063e-08*size, 0.7229999899864197*size, 0.699999988079071*size), + (1.1920928955078125e-07*size, -2.9802322387695312e-08*size, -0.699999988079071*size), + (0.0*size, 2.9802322387695312e-08*size, 0.699999988079071*size), ] edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)] faces = [] @@ -118,7 +331,14 @@ def create_foot_widget(rig, bone_name, size=1.0, bone_transform_name=None): # Create hand widget obj = create_widget(rig, bone_name, bone_transform_name, subsurf=2) if obj is not None: - verts = [(-0.6999998688697815*size, -0.5242648720741272*size, 0.0*size), (-0.7000001072883606*size, 1.2257349491119385*size, 0.0*size), (0.6999998688697815*size, 1.2257351875305176*size, 0.0*size), (0.7000001072883606*size, -0.5242648720741272*size, 0.0*size), (-0.6999998688697815*size, 0.2527350187301636*size, 0.0*size), (0.7000001072883606*size, 0.2527352571487427*size, 0.0*size), (-0.7000001072883606*size, 0.975735068321228*size, 0.0*size), (0.6999998688697815*size, 0.9757352471351624*size, 0.0*size), ] + verts = [(-0.6999998688697815*size, -0.5242648720741272*size, 0.0*size), + (-0.7000001072883606*size, 1.2257349491119385*size, 0.0*size), + (0.6999998688697815*size, 1.2257351875305176*size, 0.0*size), + (0.7000001072883606*size, -0.5242648720741272*size, 0.0*size), + (-0.6999998688697815*size, 0.2527350187301636*size, 0.0*size), + (0.7000001072883606*size, 0.2527352571487427*size, 0.0*size), + (-0.7000001072883606*size, 0.975735068321228*size, 0.0*size), + (0.6999998688697815*size, 0.9757352471351624*size, 0.0*size), ] edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7), ] faces = [] @@ -131,11 +351,69 @@ def create_foot_widget(rig, bone_name, size=1.0, bone_transform_name=None): return None +# noinspection SpellCheckingInspection def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=None): obj = create_widget(rig, bone_name, bone_transform_name) if obj is not None: - verts = [(-0.050000108778476715*size, 0.779460072517395*size, -0.2224801927804947*size), (0.049999915063381195*size, 0.779460072517395*size, -0.22248023748397827*size), (0.09999985247850418*size, 0.6790841817855835*size, -0.3658318817615509*size), (-2.3089636158601934e-07*size, 0.5930476188659668*size, -0.488704651594162*size), (-0.10000013560056686*size, 0.6790841817855835*size, -0.3658317029476166*size), (0.04999981075525284*size, 0.6790841817855835*size, -0.36583182215690613*size), (-0.050000183284282684*size, 0.6790841817855835*size, -0.3658318519592285*size), (-0.3658319115638733*size, 0.6790841221809387*size, 0.05000019446015358*size), (-0.3658318817615509*size, 0.6790841221809387*size, -0.04999979957938194*size), (-0.36583176255226135*size, 0.6790841221809387*size, 0.10000018030405045*size), (-0.48870471119880676*size, 0.5930476188659668*size, 2.4472291215715813e-07*size), (-0.3658319413661957*size, 0.679084062576294*size, -0.0999998077750206*size), (-0.22248037159442902*size, 0.7794600129127502*size, -0.04999985918402672*size), (-0.22248034179210663*size, 0.7794600129127502*size, 0.05000016465783119*size), (0.3658319115638733*size, 0.6790841221809387*size, -0.05000000819563866*size), (0.3658319115638733*size, 0.6790841221809387*size, 0.05000000074505806*size), (0.36583179235458374*size, 0.6790841221809387*size, -0.09999998658895493*size), (0.4887046813964844*size, 0.5930476188659668*size, -3.8399143420519977e-08*size), (0.3658319413661957*size, 0.679084062576294*size, 0.10000000149011612*size), (0.050000034272670746*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.04999997466802597*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.09999992698431015*size, 0.679084062576294*size, 0.36583200097084045*size), (1.267315070663244e-07*size, 0.5930474996566772*size, 0.48870477080345154*size), (0.1000000610947609*size, 0.679084062576294*size, 0.3658318519592285*size), (-0.049999915063381195*size, 0.679084062576294*size, 0.3658319413661957*size), (0.05000007897615433*size, 0.679084062576294*size, 0.36583197116851807*size), (0.22248029708862305*size, 0.7794600129127502*size, 0.05000004544854164*size), (0.22248028218746185*size, 0.7794600129127502*size, -0.04999994859099388*size), (-4.752442350763886e-08*size, 0.8284152746200562*size, -0.1499999612569809*size), (-0.03882290795445442*size, 0.8284152746200562*size, -0.14488883316516876*size), (-0.07500004768371582*size, 0.8284152746200562*size, -0.12990377843379974*size), (-0.10606606304645538*size, 0.8284152746200562*size, -0.10606598109006882*size), (-0.1299038827419281*size, 0.8284152746200562*size, -0.07499996572732925*size), (-0.14488893747329712*size, 0.8284152746200562*size, -0.038822825998067856*size), (-0.15000006556510925*size, 0.8284152746200562*size, 2.4781975582754967e-08*size), (-0.1448889672756195*size, 0.8284152746200562*size, 0.038822878152132034*size), (-0.1299038827419281*size, 0.8284152746200562*size, 0.07500001043081284*size), (-0.10606609284877777*size, 0.8284152746200562*size, 0.1060660257935524*size), (-0.0750000923871994*size, 0.8284152746200562*size, 0.12990383803844452*size), (-0.038822952657938004*size, 0.8284152746200562*size, 0.14488889276981354*size), (-1.0593657862045802e-07*size, 0.8284152746200562*size, 0.15000005066394806*size), (0.03882275149226189*size, 0.8284152746200562*size, 0.14488892257213593*size), (0.07499989867210388*size, 0.8284152746200562*size, 0.1299038976430893*size), (0.10606591403484344*size, 0.8284152746200562*size, 0.10606611520051956*size), (0.12990373373031616*size, 0.8284152746200562*size, 0.0750000849366188*size), (0.14488881826400757*size, 0.8284152746200562*size, 0.038822952657938004*size), (0.1499999463558197*size, 0.8284152746200562*size, 1.0584351883835552e-07*size), (0.14488881826400757*size, 0.8284152746200562*size, -0.03882275149226189*size), (0.12990379333496094*size, 0.8284152746200562*size, -0.07499989122152328*size), (0.10606604814529419*size, 0.8284152746200562*size, -0.10606592148542404*size), (0.07500004768371582*size, 0.8284152746200562*size, -0.12990371882915497*size), (0.03882291540503502*size, 0.8284152746200562*size, -0.14488880336284637*size), ] - edges = [(1, 0), (3, 2), (5, 2), (4, 3), (6, 4), (1, 5), (0, 6), (13, 7), (12, 8), (7, 9), (9, 10), (8, 11), (27, 14), (26, 15), (14, 16), (16, 17), (15, 18), (17, 18), (10, 11), (12, 13), (20, 19), (22, 21), (24, 21), (23, 22), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (38, 37), (39, 38), (40, 39), (41, 40), (42, 41), (43, 42), (44, 43), (45, 44), (46, 45), (47, 46), (48, 47), (49, 48), (50, 49), (51, 50), (28, 51), (26, 27), (25, 23), (20, 24), (19, 25), ] + verts = [(-0.050000108778476715*size, 0.779460072517395*size, -0.2224801927804947*size), + (0.049999915063381195*size, 0.779460072517395*size, -0.22248023748397827*size), + (0.09999985247850418*size, 0.6790841817855835*size, -0.3658318817615509*size), + (-2.3089636158601934e-07*size, 0.5930476188659668*size, -0.488704651594162*size), + (-0.10000013560056686*size, 0.6790841817855835*size, -0.3658317029476166*size), + (0.04999981075525284*size, 0.6790841817855835*size, -0.36583182215690613*size), + (-0.050000183284282684*size, 0.6790841817855835*size, -0.3658318519592285*size), + (-0.3658319115638733*size, 0.6790841221809387*size, 0.05000019446015358*size), + (-0.3658318817615509*size, 0.6790841221809387*size, -0.04999979957938194*size), + (-0.36583176255226135*size, 0.6790841221809387*size, 0.10000018030405045*size), + (-0.48870471119880676*size, 0.5930476188659668*size, 2.4472291215715813e-07*size), + (-0.3658319413661957*size, 0.679084062576294*size, -0.0999998077750206*size), + (-0.22248037159442902*size, 0.7794600129127502*size, -0.04999985918402672*size), + (-0.22248034179210663*size, 0.7794600129127502*size, 0.05000016465783119*size), + (0.3658319115638733*size, 0.6790841221809387*size, -0.05000000819563866*size), + (0.3658319115638733*size, 0.6790841221809387*size, 0.05000000074505806*size), + (0.36583179235458374*size, 0.6790841221809387*size, -0.09999998658895493*size), + (0.4887046813964844*size, 0.5930476188659668*size, -3.8399143420519977e-08*size), + (0.3658319413661957*size, 0.679084062576294*size, 0.10000000149011612*size), + (0.050000034272670746*size, 0.7794599533081055*size, 0.2224804311990738*size), + (-0.04999997466802597*size, 0.7794599533081055*size, 0.2224804311990738*size), + (-0.09999992698431015*size, 0.679084062576294*size, 0.36583200097084045*size), + (1.267315070663244e-07*size, 0.5930474996566772*size, 0.48870477080345154*size), + (0.1000000610947609*size, 0.679084062576294*size, 0.3658318519592285*size), + (-0.049999915063381195*size, 0.679084062576294*size, 0.3658319413661957*size), + (0.05000007897615433*size, 0.679084062576294*size, 0.36583197116851807*size), + (0.22248029708862305*size, 0.7794600129127502*size, 0.05000004544854164*size), + (0.22248028218746185*size, 0.7794600129127502*size, -0.04999994859099388*size), + (-4.752442350763886e-08*size, 0.8284152746200562*size, -0.1499999612569809*size), + (-0.03882290795445442*size, 0.8284152746200562*size, -0.14488883316516876*size), + (-0.07500004768371582*size, 0.8284152746200562*size, -0.12990377843379974*size), + (-0.10606606304645538*size, 0.8284152746200562*size, -0.10606598109006882*size), + (-0.1299038827419281*size, 0.8284152746200562*size, -0.07499996572732925*size), + (-0.14488893747329712*size, 0.8284152746200562*size, -0.038822825998067856*size), + (-0.15000006556510925*size, 0.8284152746200562*size, 2.4781975582754967e-08*size), + (-0.1448889672756195*size, 0.8284152746200562*size, 0.038822878152132034*size), + (-0.1299038827419281*size, 0.8284152746200562*size, 0.07500001043081284*size), + (-0.10606609284877777*size, 0.8284152746200562*size, 0.1060660257935524*size), + (-0.0750000923871994*size, 0.8284152746200562*size, 0.12990383803844452*size), + (-0.038822952657938004*size, 0.8284152746200562*size, 0.14488889276981354*size), + (-1.0593657862045802e-07*size, 0.8284152746200562*size, 0.15000005066394806*size), + (0.03882275149226189*size, 0.8284152746200562*size, 0.14488892257213593*size), + (0.07499989867210388*size, 0.8284152746200562*size, 0.1299038976430893*size), + (0.10606591403484344*size, 0.8284152746200562*size, 0.10606611520051956*size), + (0.12990373373031616*size, 0.8284152746200562*size, 0.0750000849366188*size), + (0.14488881826400757*size, 0.8284152746200562*size, 0.038822952657938004*size), + (0.1499999463558197*size, 0.8284152746200562*size, 1.0584351883835552e-07*size), + (0.14488881826400757*size, 0.8284152746200562*size, -0.03882275149226189*size), + (0.12990379333496094*size, 0.8284152746200562*size, -0.07499989122152328*size), + (0.10606604814529419*size, 0.8284152746200562*size, -0.10606592148542404*size), + (0.07500004768371582*size, 0.8284152746200562*size, -0.12990371882915497*size), + (0.03882291540503502*size, 0.8284152746200562*size, -0.14488880336284637*size), ] + edges = [(1, 0), (3, 2), (5, 2), (4, 3), (6, 4), (1, 5), (0, 6), (13, 7), (12, 8), (7, 9), + (9, 10), (8, 11), (27, 14), (26, 15), (14, 16), (16, 17), (15, 18), (17, 18), + (10, 11), (12, 13), (20, 19), (22, 21), (24, 21), (23, 22), (29, 28), (30, 29), + (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (38, 37), + (39, 38), (40, 39), (41, 40), (42, 41), (43, 42), (44, 43), (45, 44), (46, 45), + (47, 46), (48, 47), (49, 48), (50, 49), (51, 50), (28, 51), (26, 27), (25, 23), + (20, 24), (19, 25), ] faces = [] mesh = obj.data @@ -149,5 +427,57 @@ def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=None) @widget_generator(register="gear") def create_gear_widget(geom, *, radius=0.5): size = radius * 10 - geom.verts = [(0.11251477152109146*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (0.018439611420035362*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (0.09270283579826355*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (0.08732416480779648*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), (0.07858962565660477*size, -2.295374557093055e-09*size, 0.05251204967498779*size), (0.052511852234601974*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), (0.03617073595523834*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), (0.018439611420035362*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), (0.09402976930141449*size, -2.937612375575327e-09*size, 0.06720473617315292*size), (0.08150213211774826*size, -3.513068946858766e-09*size, 0.08036965131759644*size), (0.06872907280921936*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), (-0.1125146746635437*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (-0.01843959279358387*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (1.078764189088588e-08*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (-0.09270282834768295*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (-0.0873241126537323*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), (-0.07858961820602417*size, -2.295374557093055e-09*size, 0.05251204967498779*size), (-0.05251181498169899*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), (-0.036170728504657745*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), (-0.01843959279358387*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), (-0.09402971714735031*size, -2.937612375575327e-09*size, 0.06720473617315292*size), (-0.08150212466716766*size, -3.513068946858766e-09*size, 0.08036965131759644*size), (-0.06872902065515518*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), (0.11251477152109146*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (0.11251477152109146*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), (0.018439611420035362*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (0.09270283579826355*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (0.08732416480779648*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), (0.07858962565660477*size, 2.29537477913766e-09*size, -0.05251205340027809*size), (0.052511852234601974*size, 3.435267403872899e-09*size, -0.07858975976705551*size), (0.03617073595523834*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), (0.018439611420035362*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), (0.09402976930141449*size, 2.937614596021376e-09*size, -0.0672047883272171*size), (0.08150213211774826*size, 3.513068946858766e-09*size, -0.08036965131759644*size), (0.06872907280921936*size, 4.099800055001879e-09*size, -0.09379249066114426*size), (-0.1125146746635437*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (-0.1125146746635437*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), (-0.01843959279358387*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (1.078764189088588e-08*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (-0.09270282834768295*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (-0.0873241126537323*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), (-0.07858961820602417*size, 2.29537477913766e-09*size, -0.05251205340027809*size), (-0.05251181498169899*size, 3.435267403872899e-09*size, -0.07858975976705551*size), (-0.036170728504657745*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), (-0.01843959279358387*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), (-0.09402971714735031*size, 2.937614596021376e-09*size, -0.0672047883272171*size), (-0.08150212466716766*size, 3.513068946858766e-09*size, -0.08036965131759644*size), (-0.06872902065515518*size, 4.099800055001879e-09*size, -0.09379249066114426*size), ] - geom.edges = [(0, 2), (0, 24), (7, 1), (13, 1), (3, 2), (4, 3), (6, 5), (7, 6), (9, 8), (10, 9), (10, 5), (4, 8), (11, 14), (11, 36), (19, 12), (13, 12), (15, 14), (16, 15), (18, 17), (19, 18), (21, 20), (22, 21), (22, 17), (16, 20), (23, 26), (23, 24), (31, 25), (38, 25), (27, 26), (28, 27), (30, 29), (31, 30), (33, 32), (34, 33), (34, 29), (28, 32), (35, 39), (35, 36), (44, 37), (38, 37), (40, 39), (41, 40), (43, 42), (44, 43), (46, 45), (47, 46), (47, 42), (41, 45), ] + geom.verts = [(0.11251477152109146*size, -8.06030631128607e-10*size, 0.01843983121216297*size), + (0.018439611420035362*size, -4.918176976786981e-09*size, 0.11251477152109146*size), + (0.09270283579826355*size, -8.06030631128607e-10*size, 0.01843983121216297*size), + (0.08732416480779648*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), + (0.07858962565660477*size, -2.295374557093055e-09*size, 0.05251204967498779*size), + (0.052511852234601974*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), + (0.03617073595523834*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), + (0.018439611420035362*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), + (0.09402976930141449*size, -2.937612375575327e-09*size, 0.06720473617315292*size), + (0.08150213211774826*size, -3.513068946858766e-09*size, 0.08036965131759644*size), + (0.06872907280921936*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), + (-0.1125146746635437*size, -8.06030631128607e-10*size, 0.01843983121216297*size), + (-0.01843959279358387*size, -4.918176976786981e-09*size, 0.11251477152109146*size), + (1.078764189088588e-08*size, -4.918176976786981e-09*size, 0.11251477152109146*size), + (-0.09270282834768295*size, -8.06030631128607e-10*size, 0.01843983121216297*size), + (-0.0873241126537323*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), + (-0.07858961820602417*size, -2.295374557093055e-09*size, 0.05251204967498779*size), + (-0.05251181498169899*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), + (-0.036170728504657745*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), + (-0.01843959279358387*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), + (-0.09402971714735031*size, -2.937612375575327e-09*size, 0.06720473617315292*size), + (-0.08150212466716766*size, -3.513068946858766e-09*size, 0.08036965131759644*size), + (-0.06872902065515518*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), + (0.11251477152109146*size, 8.06031352773573e-10*size, -0.018439847975969315*size), + (0.11251477152109146*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), + (0.018439611420035362*size, 4.918176532697771e-09*size, -0.11251476407051086*size), + (0.09270283579826355*size, 8.06031352773573e-10*size, -0.018439847975969315*size), + (0.08732416480779648*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), + (0.07858962565660477*size, 2.29537477913766e-09*size, -0.05251205340027809*size), + (0.052511852234601974*size, 3.435267403872899e-09*size, -0.07858975976705551*size), + (0.03617073595523834*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), + (0.018439611420035362*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), + (0.09402976930141449*size, 2.937614596021376e-09*size, -0.0672047883272171*size), + (0.08150213211774826*size, 3.513068946858766e-09*size, -0.08036965131759644*size), + (0.06872907280921936*size, 4.099800055001879e-09*size, -0.09379249066114426*size), + (-0.1125146746635437*size, 8.06031352773573e-10*size, -0.018439847975969315*size), + (-0.1125146746635437*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), + (-0.01843959279358387*size, 4.918176532697771e-09*size, -0.11251476407051086*size), + (1.078764189088588e-08*size, 4.918176532697771e-09*size, -0.11251476407051086*size), + (-0.09270282834768295*size, 8.06031352773573e-10*size, -0.018439847975969315*size), + (-0.0873241126537323*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), + (-0.07858961820602417*size, 2.29537477913766e-09*size, -0.05251205340027809*size), + (-0.05251181498169899*size, 3.435267403872899e-09*size, -0.07858975976705551*size), + (-0.036170728504657745*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), + (-0.01843959279358387*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), + (-0.09402971714735031*size, 2.937614596021376e-09*size, -0.0672047883272171*size), + (-0.08150212466716766*size, 3.513068946858766e-09*size, -0.08036965131759644*size), + (-0.06872902065515518*size, 4.099800055001879e-09*size, -0.09379249066114426*size), ] + geom.edges = [(0, 2), (0, 24), (7, 1), (13, 1), (3, 2), (4, 3), (6, 5), (7, 6), (9, 8), + (10, 9), (10, 5), (4, 8), (11, 14), (11, 36), (19, 12), (13, 12), (15, 14), + (16, 15), (18, 17), (19, 18), (21, 20), (22, 21), (22, 17), (16, 20), (23, 26), + (23, 24), (31, 25), (38, 25), (27, 26), (28, 27), (30, 29), (31, 30), (33, 32), + (34, 33), (34, 29), (28, 32), (35, 39), (35, 36), (44, 37), (38, 37), (40, 39), + (41, 40), (43, 42), (44, 43), (46, 45), (47, 46), (47, 42), (41, 45), ] diff --git a/rigify/utils/animation.py b/rigify/utils/animation.py index 21aa2a89..6e0a9739 100644 --- a/rigify/utils/animation.py +++ b/rigify/utils/animation.py @@ -7,11 +7,15 @@ import math # noinspection PyUnresolvedReferences from mathutils import Matrix, Vector -from typing import Callable, Any, Collection, Iterator +from typing import TYPE_CHECKING, Callable, Any, Collection, Iterator, Optional, Sequence from bpy.types import Action, bpy_struct, FCurve import json +if TYPE_CHECKING: + from ..rig_ui_template import PanelLayout + + rig_id = None @@ -849,7 +853,7 @@ class POSE_OT_rigify_clear_keyframes(bpy.types.Operator): # noinspection PyDefaultArgument,PyUnusedLocal -def add_clear_keyframes_button(panel, *, bones=[], label='', text=''): +def add_clear_keyframes_button(panel: 'PanelLayout', *, bones: list[str] = [], label='', text=''): panel.use_bake_settings() panel.script.add_utilities(SCRIPT_UTILITIES_OP_CLEAR_KEYS) panel.script.register_classes(SCRIPT_REGISTER_OP_CLEAR_KEYS) @@ -921,8 +925,10 @@ class POSE_OT_rigify_generic_snap_bake(RigifyGenericSnapBase, RigifyBakeKeyframe '''] -def add_fk_ik_snap_buttons(panel, op_single, op_bake, *, label=None, rig_name='', properties=None, - clear_bones=None, compact=None): +def add_fk_ik_snap_buttons(panel: 'PanelLayout', op_single: str, op_bake: str, *, + label, rig_name='', properties: dict[str, Any], + clear_bones: Optional[list[str]] = None, + compact: Optional[bool] = None): assert label and properties if rig_name: @@ -944,8 +950,12 @@ def add_fk_ik_snap_buttons(panel, op_single, op_bake, *, label=None, rig_name='' # noinspection PyDefaultArgument -def add_generic_snap(panel, *, output_bones=[], input_bones=[], input_ctrl_bones=[], label='Snap', - rig_name='', undo_copy_scale=False, compact=None, clear=True, locks=None, tooltip=None): +def add_generic_snap(panel: 'PanelLayout', *, + output_bones: list[str] = [], input_bones: list[str] = [], + input_ctrl_bones: list[str] = [], label='Snap', + rig_name='', undo_copy_scale=False, compact: Optional[bool] = None, + clear=True, locks: Optional[Sequence[bool]] = None, + tooltip: Optional[str] = None): panel.use_bake_settings() panel.script.add_utilities(SCRIPT_UTILITIES_OP_SNAP) panel.script.register_classes(SCRIPT_REGISTER_OP_SNAP) @@ -972,8 +982,11 @@ def add_generic_snap(panel, *, output_bones=[], input_bones=[], input_ctrl_bones # noinspection PyDefaultArgument -def add_generic_snap_fk_to_ik(panel, *, fk_bones=[], ik_bones=[], ik_ctrl_bones=[], label='FK->IK', - rig_name='', undo_copy_scale=False, compact=None, clear=True): +def add_generic_snap_fk_to_ik(panel: 'PanelLayout', *, + fk_bones: list[str] = [], ik_bones: list[str] = [], + ik_ctrl_bones: list[str] = [], label='FK->IK', + rig_name='', undo_copy_scale=False, + compact: Optional[bool] = None, clear=True): add_generic_snap( panel, output_bones=fk_bones, input_bones=ik_bones, input_ctrl_bones=ik_ctrl_bones, label=label, rig_name=rig_name, undo_copy_scale=undo_copy_scale, compact=compact, clear=clear diff --git a/rigify/utils/bones.py b/rigify/utils/bones.py index 8419eb90..8c39e57b 100644 --- a/rigify/utils/bones.py +++ b/rigify/utils/bones.py @@ -4,7 +4,7 @@ import bpy import math from mathutils import Vector, Matrix -from typing import Optional, Callable +from typing import Optional, Callable, Iterable from .errors import MetarigError from .naming import get_name, make_derived_name, is_control_bone @@ -15,26 +15,24 @@ from .misc import pairwise, ArmatureObject # Bone collection ######################## -class BoneDict(dict): +class BaseBoneDict(dict): """ Special dictionary for holding bone names in a structured way. Allows access to contained items as attributes, and only accepts certain types of values. - - @DynamicAttrs """ @staticmethod def __sanitize_attr(key, value): - if hasattr(BoneDict, key): + if hasattr(BaseBoneDict, key): raise KeyError(f"Invalid BoneDict key: {key}") - if value is None or isinstance(value, (str, list, BoneDict)): + if value is None or isinstance(value, (str, list, BaseBoneDict)): return value if isinstance(value, dict): - return BoneDict(value) + return BaseBoneDict(value) raise ValueError(f"Invalid BoneDict value: {repr(value)}") @@ -42,7 +40,7 @@ class BoneDict(dict): super().__init__() for key, value in dict(*args, **kwargs).items(): - dict.__setitem__(self, key, BoneDict.__sanitize_attr(key, value)) + dict.__setitem__(self, key, BaseBoneDict.__sanitize_attr(key, value)) self.__dict__ = self @@ -50,13 +48,13 @@ class BoneDict(dict): return "BoneDict(%s)" % (dict.__repr__(self)) def __setitem__(self, key, value): - dict.__setitem__(self, key, BoneDict.__sanitize_attr(key, value)) + dict.__setitem__(self, key, BaseBoneDict.__sanitize_attr(key, value)) def update(self, *args, **kwargs): for key, value in dict(*args, **kwargs).items(): - dict.__setitem__(self, key, BoneDict.__sanitize_attr(key, value)) + dict.__setitem__(self, key, BaseBoneDict.__sanitize_attr(key, value)) - def flatten(self, key=None): + def flatten(self, key: Optional[str] = None): """Return all contained bones or a single key as a list.""" items = [self[key]] if key is not None else self.values() @@ -64,7 +62,7 @@ class BoneDict(dict): all_bones = [] for item in items: - if isinstance(item, BoneDict): + if isinstance(item, BaseBoneDict): all_bones.extend(item.flatten()) elif isinstance(item, list): all_bones.extend(item) @@ -74,6 +72,22 @@ class BoneDict(dict): return all_bones +class TypedBoneDict(BaseBoneDict): + # Omit DynamicAttrs to ensure usages of undeclared attributes are highlighted + pass + + +class BoneDict(BaseBoneDict): + """ + Special dictionary for holding bone names in a structured way. + + Allows access to contained items as attributes, and only + accepts certain types of values. + + @DynamicAttrs + """ + + ######################## # Bone manipulation ######################## @@ -220,7 +234,7 @@ def flip_bone(obj: ArmatureObject, bone_name: str): raise MetarigError("Cannot flip bones outside of edit mode") -def flip_bone_chain(obj: ArmatureObject, bone_names: list[str]): +def flip_bone_chain(obj: ArmatureObject, bone_names: Iterable[str]): """Flips a connected bone chain.""" assert obj.mode == 'EDIT' @@ -282,7 +296,7 @@ def put_bone(obj: ArmatureObject, bone_name: str, pos: Optional[Vector], *, raise MetarigError("Cannot 'put' bones outside of edit mode") -def disable_bbones(obj: ArmatureObject, bone_names: list[str]): +def disable_bbones(obj: ArmatureObject, bone_names: Iterable[str]): """Disables B-Bone segments on the specified bones.""" assert(obj.mode != 'EDIT') for bone in bone_names: @@ -440,7 +454,7 @@ class BoneUtilityMixin(object): bone.inherit_scale = inherit_scale bone.parent = (eb[parent_name] if parent_name else None) - def parent_bone_chain(self, bone_names: list[str], + def parent_bone_chain(self, bone_names: Iterable[str], use_connect: Optional[bool] = None, inherit_scale: Optional[str] = None): """Link bones into a chain with parenting. First bone may be None.""" @@ -453,7 +467,7 @@ class BoneUtilityMixin(object): # B-Bones ############################################## -def connect_bbone_chain_handles(obj: ArmatureObject, bone_names: list[str]): +def connect_bbone_chain_handles(obj: ArmatureObject, bone_names: Iterable[str]): assert obj.mode == 'EDIT' for prev_name, next_name in pairwise(bone_names): diff --git a/rigify/utils/layers.py b/rigify/utils/layers.py index d1f56e90..cb013ee1 100644 --- a/rigify/utils/layers.py +++ b/rigify/utils/layers.py @@ -151,6 +151,15 @@ class ControlLayersOption: layout_layer_buttons(box, params, self.layers_option, active_layers) + # Declarations for auto-completion + FK: 'ControlLayersOption' + TWEAK: 'ControlLayersOption' + EXTRA_IK: 'ControlLayersOption' + FACE_PRIMARY: 'ControlLayersOption' + FACE_SECONDARY: 'ControlLayersOption' + SKIN_PRIMARY: 'ControlLayersOption' + SKIN_SECONDARY: 'ControlLayersOption' + ControlLayersOption.FK = ControlLayersOption( 'fk', description="Layers for the FK controls to be on") diff --git a/rigify/utils/rig.py b/rigify/utils/rig.py index d8f88430..7fb399a3 100644 --- a/rigify/utils/rig.py +++ b/rigify/utils/rig.py @@ -6,7 +6,7 @@ import importlib.util import re from itertools import count -from typing import TYPE_CHECKING, Any, Optional, Sequence, Mapping +from typing import TYPE_CHECKING, Any, Optional, Sequence from bpy.types import bpy_struct, Constraint, Object, PoseBone, Bone, Armature # noinspection PyUnresolvedReferences -- cgit v1.2.3