Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-09-14 09:17:30 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-09-14 09:30:00 +0300
commit8b1df843703fdb51ffa5758625c117c4f10bc6dd (patch)
tree949e84f80116132eab3ad5f3bac46e745c3a9195 /rigify/rigs/spines/basic_spine.py
parent9b693a6be0aa2b0b4825d30ac5034655dce9c0dd (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/basic_spine.py')
-rw-r--r--rigify/rigs/spines/basic_spine.py321
1 files changed, 321 insertions, 0 deletions
diff --git a/rigify/rigs/spines/basic_spine.py b/rigify/rigs/spines/basic_spine.py
new file mode 100644
index 00000000..d90e4c8d
--- /dev/null
+++ b/rigify/rigs/spines/basic_spine.py
@@ -0,0 +1,321 @@
+#====================== 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, repeat
+
+from ...utils.errors import MetarigError
+from ...utils.layers import ControlLayersOption
+from ...utils.naming import strip_org, make_deformer_name, make_mechanism_name
+from ...utils.bones import BoneDict, put_bone, align_bone_to_axis
+from ...utils.widgets_basic import create_circle_widget
+from ...utils.misc import map_list
+
+from ...base_rig import stage
+from .spine_rigs import BaseSpineRig
+
+
+class Rig(BaseSpineRig):
+ """
+ Spine rig with fixed pivot, hip/chest controls and tweaks.
+ """
+
+ def initialize(self):
+ super().initialize()
+
+ # Check if user provided the pivot position
+ self.pivot_pos = self.params.pivot_pos
+
+ if not (0 < self.pivot_pos < len(self.bones.org)):
+ self.raise_error("Please specify a valid pivot bone position.")
+
+ ####################################################
+ # BONES
+ #
+ # org[]:
+ # ORG bones
+ # ctrl:
+ # master, hips, chest:
+ # Main 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
+ #
+ ####################################################
+
+ ####################################################
+ # Master control bone
+
+ @stage.generate_bones
+ def make_master_control(self):
+ super().make_master_control()
+
+ # Put the main control in the middle of the hip bone
+ base_bone = self.get_bone(self.bones.org[0])
+ put_bone(self.obj, self.bones.ctrl.master, (base_bone.head + base_bone.tail) / 2)
+
+ ####################################################
+ # Main control bones
+
+ @stage.generate_bones
+ def make_control_chain(self):
+ orgs = self.bones.org
+ pivot = self.pivot_pos
+
+ 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):
+ 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):
+ name = self.copy_bone(org, name, parent=False)
+ align_bone_to_axis(self.obj, name, 'y', length=self.length / 3)
+ return name
+
+ @stage.parent_bones
+ def parent_control_chain(self):
+ ctrl = self.bones.ctrl
+ self.set_bone_parent(ctrl.hips, ctrl.master)
+ self.set_bone_parent(ctrl.chest, ctrl.master)
+
+ @stage.configure_bones
+ def configure_control_chain(self):
+ pass
+
+ @stage.generate_widgets
+ def make_control_widgets(self):
+ ctrl = self.bones.ctrl
+ mch = self.bones.mch
+ self.make_control_widget(ctrl.hips, mch.wgt_hips)
+ self.make_control_widget(ctrl.chest, mch.wgt_chest)
+
+ def make_control_widget(self, ctrl, wgt_mch):
+ self.get_bone(ctrl).custom_shape_transform = self.get_bone(wgt_mch)
+
+ create_circle_widget(
+ self.obj, ctrl,
+ radius=1.0,
+ head_tail=0.75,
+ with_line=False,
+ bone_transform_name=wgt_mch
+ )
+
+ ####################################################
+ # MCH bones associated with main controls
+
+ @stage.generate_bones
+ def make_mch_control_bones(self):
+ orgs = self.bones.org
+ mch = self.bones.mch
+
+ mch.pivot = self.make_mch_pivot_bone(orgs[self.pivot_pos], 'pivot')
+ 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):
+ 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):
+ return self.copy_bone(org, make_mechanism_name(name), parent=False)
+
+ @stage.parent_bones
+ def parent_mch_control_bones(self):
+ mch = self.bones.mch
+ self.set_bone_parent(mch.pivot, mch.chain.chest[0])
+ self.set_bone_parent(mch.wgt_hips, mch.chain.hips[0])
+ self.set_bone_parent(mch.wgt_chest, mch.chain.chest[-1])
+
+ @stage.rig_bones
+ def rig_mch_control_bones(self):
+ mch = self.bones.mch
+ # Is it actually intending to compute average of these, or is this really intentional?
+ # This effectively adds rotations of the hip and chest controls.
+ self.make_constraint(mch.pivot, 'COPY_TRANSFORMS', mch.chain.hips[-1], space='LOCAL')
+
+ ####################################################
+ # MCH chain for distributing hip & chest transform
+
+ @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)),
+ )
+
+ def make_mch_bone(self, org, is_hip):
+ 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
+
+ @stage.parent_bones
+ def parent_mch_chain(self):
+ master = self.bones.ctrl.master
+ chain = self.bones.mch.chain
+ self.parent_bone_chain([master, *reversed(chain.hips)])
+ self.parent_bone_chain([master, *chain.chest])
+
+ @stage.rig_bones
+ def rig_mch_chain(self):
+ ctrl = self.bones.ctrl
+ chain = self.bones.mch.chain
+ for mch in chain.hips:
+ self.rig_mch_bone(mch, ctrl.hips, len(chain.hips))
+ 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)
+
+ ####################################################
+ # Tweak bones
+
+ @stage.parent_bones
+ def parent_tweak_chain(self):
+ mch = self.bones.mch
+ chain = mch.chain
+ parents = [chain.hips[0], *chain.hips[0:-1], mch.pivot, *chain.chest[1:], chain.chest[-1]]
+ for args in zip(self.bones.ctrl.tweak, parents):
+ self.set_bone_parent(*args)
+
+ ####################################################
+ # SETTINGS
+
+ @classmethod
+ def add_parameters(self, params):
+ params.pivot_pos = bpy.props.IntProperty(
+ name='pivot_position',
+ default=2,
+ min=0,
+ description='Position of the torso control and pivot point'
+ )
+
+ super().add_parameters(params)
+
+ @classmethod
+ def parameters_ui(self, layout, params):
+ r = layout.row()
+ r.prop(params, "pivot_pos")
+
+ super().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('spine')
+ bone.head[:] = 0.0000, 0.0552, 1.0099
+ bone.tail[:] = 0.0000, 0.0172, 1.1573
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['spine'] = bone.name
+
+ bone = arm.edit_bones.new('spine.001')
+ bone.head[:] = 0.0000, 0.0172, 1.1573
+ bone.tail[:] = 0.0000, 0.0004, 1.2929
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine']]
+ bones['spine.001'] = bone.name
+
+ bone = arm.edit_bones.new('spine.002')
+ bone.head[:] = 0.0000, 0.0004, 1.2929
+ bone.tail[:] = 0.0000, 0.0059, 1.4657
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine.001']]
+ bones['spine.002'] = bone.name
+
+ bone = arm.edit_bones.new('spine.003')
+ bone.head[:] = 0.0000, 0.0059, 1.4657
+ bone.tail[:] = 0.0000, 0.0114, 1.6582
+ bone.roll = 0.0000
+ bone.use_connect = True
+ 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'
+ 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'
+
+ 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]
+ except AttributeError:
+ pass
+ pbone = obj.pose.bones[bones['spine.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['spine.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'
+ pbone = obj.pose.bones[bones['spine.003']]
+ 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
+ arm.edit_bones.active = bone
+
+ return bones