diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-14 09:17:30 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-14 09:30:00 +0300 |
commit | 8b1df843703fdb51ffa5758625c117c4f10bc6dd (patch) | |
tree | 949e84f80116132eab3ad5f3bac46e745c3a9195 /rigify/rigs/spines/spine_rigs.py | |
parent | 9b693a6be0aa2b0b4825d30ac5034655dce9c0dd (diff) |
Rigify: replace rigs with new implementations using the new base rig.
Spine is split into parts. Limbs and tentacles simply converted.
Differential Revision: https://developer.blender.org/D4624
Diffstat (limited to 'rigify/rigs/spines/spine_rigs.py')
-rw-r--r-- | rigify/rigs/spines/spine_rigs.py | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/rigify/rigs/spines/spine_rigs.py b/rigify/rigs/spines/spine_rigs.py new file mode 100644 index 00000000..47a72287 --- /dev/null +++ b/rigify/rigs/spines/spine_rigs.py @@ -0,0 +1,208 @@ +#====================== BEGIN GPL LICENSE BLOCK ====================== +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +#======================= END GPL LICENSE BLOCK ======================== + +# <pep8 compliant> + +import bpy + +from itertools import count + +from ...utils.layers import ControlLayersOption +from ...utils.naming import make_derived_name +from ...utils.bones import align_bone_orientation, align_bone_to_axis +from ...utils.widgets_basic import create_cube_widget +from ...utils.switch_parent import SwitchParentBuilder + +from ...base_rig import stage + +from ..chain_rigs import TweakChainRig, ConnectingChainRig + + +class BaseSpineRig(TweakChainRig): + """ + Spine rig with tweaks. + """ + + bbone_segments = 8 + + def initialize(self): + if len(self.bones.org) < 3: + self.raise_error("Input to rig type must be a chain of 3 or more bones.") + + self.length = sum([self.get_bone(b).length for b in self.bones.org]) + + #################################################### + # BONES + # + # ctrl: + # master + # Main control. + # + #################################################### + + #################################################### + # Master control bone + + @stage.generate_bones + def make_master_control(self): + self.bones.ctrl.master = name = self.copy_bone(self.bones.org[0], 'torso') + + align_bone_to_axis(self.obj, name, 'y', length=self.length * 0.6) + + SwitchParentBuilder(self.generator).register_parent(self, name) + + @stage.parent_bones + def parent_master_control(self): + self.set_bone_parent(self.bones.ctrl.master, self.rig_parent_bone) + + @stage.configure_bones + def configure_master_control(self): + pass + + @stage.generate_widgets + def make_master_control_widget(self): + create_cube_widget( + self.obj, self.bones.ctrl.master, + radius=0.5, + bone_transform_name=None + ) + + #################################################### + # Tweak bones + + @stage.configure_bones + def configure_tweak_chain(self): + super().configure_tweak_chain() + + ControlLayersOption.TWEAK.assign(self.params, self.obj, self.bones.ctrl.tweak) + + #################################################### + # Deform bones + + @stage.configure_bones + def configure_bbone_chain(self): + self.get_bone(self.bones.deform[0]).bone.bbone_easein = 0.0 + + #################################################### + # SETTINGS + + @classmethod + def add_parameters(self, params): + # Setting up extra layers for the FK and tweak + ControlLayersOption.TWEAK.add_parameters(params) + + @classmethod + def parameters_ui(self, layout, params): + ControlLayersOption.TWEAK.parameters_ui(layout, params) + + +class BaseHeadTailRig(ConnectingChainRig): + """ Base for head and tail rigs. """ + + def initialize(self): + super().initialize() + + self.rotation_bones = [] + + #################################################### + # Utilities + + def get_parent_master(self, default_bone): + """ Return the parent's master control bone if connecting and found. """ + + if self.use_connect_chain and 'master' in self.rigify_parent.bones.ctrl: + return self.rigify_parent.bones.ctrl.master + else: + return default_bone + + def get_parent_master_panel(self, default_bone): + """ Return the parent's master control bone if connecting and found, and script panel. """ + + controls = self.bones.ctrl.flatten() + prop_bone = self.get_parent_master(default_bone) + + if prop_bone != default_bone: + owner = self.rigify_parent + controls += self.rigify_parent.bones.ctrl.flatten() + else: + owner = self + + return prop_bone, self.script.panel_with_selected_check(owner, controls) + + #################################################### + # Rotation follow + + def make_mch_follow_bone(self, org, name, defval, *, 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)) + 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: + 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' + + self.make_property(self.prop_bone, name+'_follow', default=float(defval)) + panel.custom_prop(self.prop_bone, name+'_follow', text=textname, slider=True) + + @stage.rig_bones + def rig_mch_follow_bones(self): + for org, name, bone, defval, 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): + con = self.make_constraint(mch, 'COPY_ROTATION', self.follow_bone) + + 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) + + #################################################### + # Tweak chain + + @stage.configure_bones + def configure_tweak_chain(self): + super().configure_tweak_chain() + + ControlLayersOption.TWEAK.assign(self.params, self.obj, self.bones.ctrl.tweak) + + #################################################### + # Settings + + @classmethod + def add_parameters(self, 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): + super().parameters_ui(layout, params) + + ControlLayersOption.TWEAK.parameters_ui(layout, params) |