[Bf-extensions-cvs] [2acf22b5] master: Rigify: move new face rig components from the experimental feature set.
Alexander Gavrilov
noreply at git.blender.org
Tue Aug 10 20:21:49 CEST 2021
Commit: 2acf22b5932c57f7d29b578fc74542f81d4fb087
Author: Alexander Gavrilov
Date: Tue Aug 10 21:19:11 2021 +0300
Branches: master
https://developer.blender.org/rBA2acf22b5932c57f7d29b578fc74542f81d4fb087
Rigify: move new face rig components from the experimental feature set.
Apart from imports the files are identical to the latest version.
Ref T89808
===================================================================
A rigify/rigs/face/basic_tongue.py
A rigify/rigs/face/skin_eye.py
A rigify/rigs/face/skin_jaw.py
A rigify/rigs/skin/anchor.py
A rigify/rigs/skin/basic_chain.py
A rigify/rigs/skin/glue.py
A rigify/rigs/skin/skin_nodes.py
A rigify/rigs/skin/skin_parents.py
A rigify/rigs/skin/skin_rigs.py
A rigify/rigs/skin/stretchy_chain.py
A rigify/rigs/skin/transform/basic.py
M rigify/utils/layers.py
===================================================================
diff --git a/rigify/rigs/face/basic_tongue.py b/rigify/rigs/face/basic_tongue.py
new file mode 100644
index 00000000..380e14df
--- /dev/null
+++ b/rigify/rigs/face/basic_tongue.py
@@ -0,0 +1,206 @@
+# ====================== BEGIN GPL LICENSE BLOCK ======================
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ======================= END GPL LICENSE BLOCK ========================
+
+# <pep8 compliant>
+
+import bpy
+import math
+
+from itertools import count
+
+from ...utils.naming import make_derived_name
+from ...utils.bones import flip_bone, copy_bone_position
+from ...utils.layers import ControlLayersOption
+from ...utils.misc import map_list
+
+from ...base_rig import stage
+
+from ..chain_rigs import TweakChainRig
+from ..widgets import create_jaw_widget
+
+
+class Rig(TweakChainRig):
+ """Basic tongue from the original PitchiPoy face rig."""
+
+ min_chain_length = 3
+
+ def initialize(self):
+ super().initialize()
+
+ self.bbone_segments = self.params.bbones
+
+ ####################################################
+ # BONES
+ #
+ # ctrl:
+ # master:
+ # Master control.
+ # mch:
+ # follow[]:
+ # Partial follow master bones.
+ #
+ ####################################################
+
+ ####################################################
+ # Control chain
+
+ @stage.generate_bones
+ def make_control_chain(self):
+ org = self.bones.org[0]
+ name = self.copy_bone(org, make_derived_name(org, 'ctrl'), parent=True)
+ flip_bone(self.obj, name)
+ self.bones.ctrl.master = name
+
+ @stage.parent_bones
+ def parent_control_chain(self):
+ pass
+
+ @stage.configure_bones
+ def configure_control_chain(self):
+ master = self.bones.ctrl.master
+
+ self.copy_bone_properties(self.bones.org[0], master)
+
+ ControlLayersOption.SKIN_PRIMARY.assign(self.params, self.obj, [master])
+
+ @stage.generate_widgets
+ def make_control_widgets(self):
+ create_jaw_widget(self.obj, self.bones.ctrl.master)
+
+ ####################################################
+ # Mechanism chain
+
+ @stage.generate_bones
+ def make_follow_chain(self):
+ self.bones.mch.follow = map_list(self.make_mch_follow_bone, count(1), self.bones.org[1:])
+
+ def make_mch_follow_bone(self, i, org):
+ name = self.copy_bone(org, make_derived_name(org, 'mch'))
+ copy_bone_position(self.obj, self.base_bone, name)
+ flip_bone(self.obj, name)
+ return name
+
+ @stage.parent_bones
+ def parent_follow_chain(self):
+ for mch in self.bones.mch.follow:
+ self.set_bone_parent(mch, self.rig_parent_bone)
+
+ @stage.rig_bones
+ def rig_follow_chain(self):
+ master = self.bones.ctrl.master
+ num_orgs = len(self.bones.org)
+
+ for i, mch in enumerate(self.bones.mch.follow):
+ self.make_constraint(mch, 'COPY_TRANSFORMS', master, influence=1-(1+i)/num_orgs)
+
+ ####################################################
+ # Tweak chain
+
+ @stage.parent_bones
+ def parent_tweak_chain(self):
+ ctrl = self.bones.ctrl
+ parents = [ctrl.master, *self.bones.mch.follow, self.rig_parent_bone]
+ for tweak, main in zip(ctrl.tweak, parents):
+ self.set_bone_parent(tweak, main)
+
+ ####################################################
+ # SETTINGS
+
+ @classmethod
+ def add_parameters(self, params):
+ params.bbones = bpy.props.IntProperty(
+ name='B-Bone Segments',
+ default=10,
+ min=1,
+ description='Number of B-Bone segments'
+ )
+
+ ControlLayersOption.SKIN_PRIMARY.add_parameters(params)
+
+ @classmethod
+ def parameters_ui(self, layout, params):
+ layout.prop(params, 'bbones')
+
+ ControlLayersOption.SKIN_PRIMARY.parameters_ui(layout, params)
+
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('tongue')
+ bone.head = 0.0000, 0.0000, 0.0000
+ bone.tail = 0.0000, 0.0161, 0.0074
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['tongue'] = bone.name
+ bone = arm.edit_bones.new('tongue.001')
+ bone.head = 0.0000, 0.0161, 0.0074
+ bone.tail = 0.0000, 0.0375, 0.0091
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['tongue']]
+ bones['tongue.001'] = bone.name
+ bone = arm.edit_bones.new('tongue.002')
+ bone.head = 0.0000, 0.0375, 0.0091
+ bone.tail = 0.0000, 0.0605, -0.0029
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['tongue.001']]
+ bones['tongue.002'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['tongue']]
+ pbone.rigify_type = 'face.basic_tongue'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['tongue.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['tongue.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ bone.bbone_x = bone.bbone_z = bone.length * 0.05
+ arm.edit_bones.active = bone
+
+ return bones
diff --git a/rigify/rigs/face/skin_eye.py b/rigify/rigs/face/skin_eye.py
new file mode 100644
index 00000000..498a90c4
--- /dev/null
+++ b/rigify/rigs/face/skin_eye.py
@@ -0,0 +1,825 @@
+# ====================== BEGIN GPL LICENSE BLOCK ======================
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ======================= END GPL LICENSE BLOCK ========================
+
+# <pep8 compliant>
+
+import bpy
+import math
+import functools
+import mathutils
+
+from itertools import count
+from mathutils import Vector, Matrix
+
+from ...utils.naming import make_derived_name, mirror_name, change_name_side, Side, SideZ
+from ...utils.bones import align_bone_z_axis, put_bone
+from ...utils.widgets import (widget_generator, generate_circle_geometry,
+ generate_circle_hull_geometry)
+from ...utils.widgets_basic import create_circle_widget
+from ...utils.switch_parent import SwitchParentBuilder
+from ...utils.misc import map_list, matrix_from_axis_pair, LazyRef
+
+from ...base_rig import stage, RigComponent
+
+from ..skin.skin_nodes import ControlBoneNode
+from ..skin.skin_parents import ControlBoneParentOffset
+from ..skin.skin_rigs import BaseSkinRig
+
+from ..skin.basic_chain import Rig as BasicChainRig
+
+
+class Rig(BaseSkinRig):
+ """
+ Eye rig that manages two child eyelid chains. The chains must
+ connect at their ends using T/B symmetry.
+ """
+
+ def find_org_bones(self, bone):
+ return bone.name
+
+ cluster_control = None
+
+ def initialize(self):
+ super().initialize()
+
+ bone = self.get_bone(self.base_bone)
+ self.center = bone.head
+ self.axis = bone.vector
+
+ self.eye_corner_nodes = []
+ self.eye_corner_matrix = None
+
+ # Create the cluster control (it will assign self.cluster_control)
+ if not self.cluster_control:
+ self.create_cluster_control()
+
+ self.init_child_chains()
+
+ def create_cluster_control(self):
+ return EyeClusterControl(self)
+
+ ####################################################
+ # UTILITIES
+
+ def is_eye_control_node(self, node):
+ return node.rig in self.child_chains and node.is_master_node
+
+ def is_eye_corner_node(self, node):
+ # Corners are nodes where the two T and B chains merge
+ sides = set(n.name_split.side_z for n in node.get_merged_siblings())
+ return {SideZ.BOTTOM, SideZ.TOP}.issubset(sides)
+
+ def init_eye_corner_space(self):
+ """Initialize the coordinate space of the eye based on two corners."""
+ if self.eye_corner_matrix:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list