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:
Diffstat (limited to 'rigify/rigs/limbs/paw.py')
-rw-r--r--rigify/rigs/limbs/paw.py246
1 files changed, 169 insertions, 77 deletions
diff --git a/rigify/rigs/limbs/paw.py b/rigify/rigs/limbs/paw.py
index c01f2f0d..8c79503e 100644
--- a/rigify/rigs/limbs/paw.py
+++ b/rigify/rigs/limbs/paw.py
@@ -7,6 +7,7 @@ from ...utils import strip_org, make_deformer_name, create_widget
from ...utils import create_circle_widget, create_sphere_widget, create_line_widget
from ...utils import MetarigError, make_mechanism_name, org
from ...utils import create_limb_widget, connected_children_names
+from ...utils import align_bone_y_axis, align_bone_x_axis, align_bone_z_axis
from rna_prop_ui import rna_idprop_ui_prop_get
from ..widgets import create_ikarrow_widget, create_gear_widget
from ..widgets import create_foot_widget, create_ballsocket_widget
@@ -18,13 +19,14 @@ ctrl = '%s'
if is_selected( controls ):
layout.prop( pose_bones[ ctrl ], '["%s"]')
- layout.prop( pose_bones[ ctrl ], '["%s"]')
+ if '%s' in pose_bones[ctrl].keys():
+ layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True )
if '%s' in pose_bones[ctrl].keys():
layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True )
"""
-IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class
- # add_parameters and parameters_ui are unused for implementation classes
+IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class
+ # add_parameters and parameters_ui are unused for implementation classes
class Rig:
@@ -42,6 +44,7 @@ class Rig:
self.bbones = params.bbones
self.limb_type = params.limb_type
self.rot_axis = params.rotation_axis
+ self.auto_align_extremity = params.auto_align_extremity
# Assign values to tweak/FK layers props if opted by user
if params.tweak_extra_layers:
@@ -54,6 +57,50 @@ class Rig:
else:
self.fk_layers = None
+ def orient_org_bones(self):
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ thigh = self.org_bones[0]
+ org_bones = list(
+ [thigh] + connected_children_names(self.obj, thigh)
+ ) # All the provided orgs
+
+ org_thigh = eb[org_bones[0]]
+ org_shin = eb[org_bones[1]]
+ org_foot = eb[org_bones[2]]
+ org_toe = eb[org_bones[3]]
+
+ foot_projection_on_xy = Vector((org_foot.y_axis[0], org_foot.y_axis[1], 0))
+ foot_x = foot_projection_on_xy.cross(Vector((0, 0, 1))).normalized()
+
+ if self.rot_axis != 'automatic':
+
+ # Orient foot and toe
+ if self.auto_align_extremity:
+ if self.rot_axis == 'x':
+ align_bone_x_axis(self.obj, org_foot.name, foot_x)
+ align_bone_x_axis(self.obj, org_toe.name, foot_x)
+ elif self.rot_axis == 'z':
+ align_bone_z_axis(self.obj, org_foot.name, -foot_x)
+ align_bone_z_axis(self.obj, org_toe.name, -foot_x)
+ else:
+ raise MetarigError(message='IK on %s has forbidden rotation axis (Y)' % self.org_bones[0])
+
+ return
+
+ # Orient thigh and shin bones
+ chain_y_axis = org_thigh.y_axis + org_shin.y_axis
+ chain_rot_axis = org_thigh.y_axis.cross(chain_y_axis).normalized() # ik-plane normal axis (rotation)
+
+ align_bone_x_axis(self.obj, org_thigh.name, chain_rot_axis)
+ align_bone_x_axis(self.obj, org_shin.name, chain_rot_axis)
+
+ # # Orient foot and toe
+ align_bone_x_axis(self.obj, org_foot.name, chain_rot_axis)
+ align_bone_x_axis(self.obj, org_toe.name, chain_rot_axis)
+
def create_parent(self):
org_bones = self.org_bones
@@ -308,11 +355,11 @@ class Rig:
# Rubber hose drivers
pb = self.obj.pose.bones
- for i,t in enumerate( tweaks[1:-1] ):
+ for i, t in enumerate(tweaks[1:-1]):
# Create custom property on tweak bone to control rubber hose
name = 'rubber_tweak'
- if i == trunc( len( tweaks[1:-1] ) / 2 ):
+ if not (i+1) % self.segments:
pb[t][name] = 0.0
else:
pb[t][name] = 1.0
@@ -385,17 +432,25 @@ class Rig:
lo_vector = eb[org_bones[1]].tail - eb[org_bones[1]].head
tot_vector = eb[org_bones[0]].head - eb[org_bones[1]].tail
tot_vector.normalize()
- elbow_vector = lo_vector.dot(tot_vector)*tot_vector - lo_vector # elbow_vec as regression of lo on tot
+ elbow_vector = lo_vector.dot(tot_vector)*tot_vector - lo_vector # elbow_vec as rejection of lo on tot
elbow_vector.normalize()
elbow_vector *= (eb[org_bones[1]].tail - eb[org_bones[0]].head).length
- z_vector = eb[org_bones[0]].z_axis + eb[org_bones[1]].z_axis
- alfa = elbow_vector.angle(z_vector)
+
+ if self.rot_axis == 'x' or self.rot_axis == 'automatic':
+ z_vector = eb[org_bones[0]].z_axis + eb[org_bones[1]].z_axis
+ alfa = elbow_vector.angle(z_vector)
+ elif self.rot_axis == 'z':
+ x_vector = eb[org_bones[0]].x_axis + eb[org_bones[1]].x_axis
+ alfa = elbow_vector.angle(x_vector)
if alfa > pi/2:
pole_angle = -pi/2
else:
pole_angle = pi/2
+ if self.rot_axis == 'z':
+ pole_angle = 0
+
eb[pole_target].head = eb[org_bones[0]].tail + elbow_vector
eb[pole_target].tail = eb[pole_target].head - elbow_vector/8
eb[pole_target].roll = 0.0
@@ -445,21 +500,28 @@ class Rig:
pb[ ctrl ].ik_stretch = 0.1
# IK constraint Rotation locks
- for axis in ['x','y','z']:
- if axis != self.rot_axis:
- setattr( pb[ mch_ik ], 'lock_ik_' + axis, True )
+ if self.rot_axis == 'z':
+ pb[mch_ik].lock_ik_x = True
+ pb[mch_ik].lock_ik_y = True
+ else:
+ pb[mch_ik].lock_ik_y = True
+ pb[mch_ik].lock_ik_z = True
# Locks and Widget
- pb[ ctrl ].lock_rotation = True, False, True
- create_ikarrow_widget( self.obj, ctrl, bone_transform_name=None )
+ pb[ctrl].lock_rotation = True, False, True
+ if self.rot_axis == 'x' or self.rot_axis == 'automatic':
+ roll = 0
+ else:
+ roll = pi/2
+ create_ikarrow_widget(self.obj, ctrl, bone_transform_name=None, roll=roll)
create_sphere_widget(self.obj, pole_target, bone_transform_name=None)
create_line_widget(self.obj, vispole)
return {'ctrl': {'limb': ctrl, 'ik_target': pole_target},
- 'mch_ik': mch_ik,
- 'mch_target': mch_target,
- 'mch_str': mch_str,
- 'visuals': {'vispole': vispole}
+ 'mch_ik': mch_ik,
+ 'mch_target': mch_target,
+ 'mch_str': mch_str,
+ 'visuals': {'vispole': vispole}
}
def create_fk(self, parent):
@@ -528,8 +590,8 @@ class Rig:
pb_parent = pb[parent]
# Create ik/fk switch property
- pb_parent['IK/FK'] = 0.0
- prop = rna_idprop_ui_prop_get(pb_parent, 'IK/FK', create=True)
+ pb_parent['IK_FK'] = 0.0
+ prop = rna_idprop_ui_prop_get(pb_parent, 'IK_FK', create=True)
prop["min"] = 0.0
prop["max"] = 1.0
prop["soft_min"] = 0.0
@@ -575,7 +637,7 @@ class Rig:
# Create IK paw control
ctrl = get_bone_name(org_bones[2], 'ctrl', 'ik')
- ctrl = copy_bone(self.obj, org_bones[2], ctrl)
+ ctrl = copy_bone(self.obj, org_bones[3], ctrl)
# clear parent (so that rigify will parent to root)
eb[ctrl].parent = None
@@ -612,7 +674,12 @@ class Rig:
# Create heel ctrl bone
heel = get_bone_name(org_bones[2], 'ctrl', 'heel_ik')
- heel = copy_bone( self.obj, org_bones[2], heel )
+ heel = copy_bone(self.obj, org_bones[2], heel)
+
+ if self.rot_axis == 'x' or self.rot_axis == 'automatic':
+ align_bone_x_axis(self.obj, heel, eb[org_bones[2]].x_axis)
+ elif self.rot_axis == 'z':
+ align_bone_z_axis(self.obj, heel, eb[org_bones[2]].z_axis)
# clear parent
eb[ heel ].parent = None
@@ -628,9 +695,35 @@ class Rig:
eb[ bones['ik']['mch_target'] ].use_connect = False
# Reset control position and orientation
- l = eb[ctrl].length
- orient_bone(self, eb[ctrl], 'y', reverse=True)
- eb[ctrl].length = eb[org_bones[-1]].length
+ if self.rot_axis == 'automatic' or self.auto_align_extremity:
+ orient_bone(self, eb[ctrl], 'y', reverse=True)
+ else:
+ flip_bone(self.obj, ctrl)
+ eb[ctrl].tail[2] = eb[ctrl].head[2]
+ eb[ctrl].roll = 0
+ v = eb[org_bones[-1]].tail - eb[org_bones[-2]].head
+ eb[ctrl].length = Vector((v[0], v[1], 0)).length
+
+ # make mch toe bone
+ toes_mch = get_bone_name(org_bones[3], 'mch')
+ toes_mch = copy_bone(self.obj, org_bones[3], toes_mch)
+
+ eb[toes_mch].use_connect = False
+ eb[toes_mch].parent = eb[ctrl]
+
+ eb[toes_mch].length /= 4
+
+ # make mch toe parent bone
+ toes_mch_parent = get_bone_name(org_bones[3], 'mch', 'parent')
+ toes_mch_parent = copy_bone(self.obj, org_bones[3], toes_mch_parent)
+
+ eb[toes_mch_parent].use_connect = False
+ eb[toes_mch_parent].parent = eb[org_bones[2]]
+
+ eb[toes_mch_parent].length /= 2
+
+ eb[org_bones[3]].use_connect = False
+ eb[org_bones[3]].parent = eb[toes_mch_parent]
# Set up constraints
@@ -714,8 +807,8 @@ class Rig:
drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
drv_modifier.coefficients[0] = 1.0
drv_modifier.coefficients[1] = -1.0
@@ -723,7 +816,8 @@ class Rig:
create_foot_widget(self.obj, ctrl, bone_transform_name=None)
# Create heel ctrl locks
- pb[ heel ].lock_location = True, True, True
+ pb[heel].lock_location = True, True, True
+ pb[heel].lock_scale = True, True, True
# Add ballsocket widget to heel
create_ballsocket_widget(self.obj, heel, bone_transform_name=None)
@@ -736,24 +830,21 @@ class Rig:
toes = get_bone_name( org_bones[3], 'ctrl' )
toes = copy_bone( self.obj, org_bones[3], toes )
- eb[ toes ].use_connect = False
- eb[ toes ].parent = eb[ org_bones[3] ]
-
- # Create toes mch bone
- toes_mch = get_bone_name( org_bones[3], 'mch' )
- toes_mch = copy_bone( self.obj, org_bones[3], toes_mch )
-
- eb[ toes_mch ].use_connect = False
- eb[ toes_mch ].parent = eb[ ctrl ]
-
- eb[ toes_mch ].length /= 4
+ eb[toes].use_connect = False
+ eb[toes].parent = eb[toes_mch_parent]
# Constrain 4th ORG to toes MCH bone
- make_constraint( self, org_bones[3], {
+ make_constraint( self, toes_mch_parent, {
'constraint' : 'COPY_TRANSFORMS',
'subtarget' : toes_mch
})
+ # Constrain 4th ORG to toes MCH bone
+ make_constraint(self, org_bones[3], {
+ 'constraint': 'COPY_TRANSFORMS',
+ 'subtarget': toes
+ })
+
make_constraint( self, bones['def'][-1], {
'constraint' : 'DAMPED_TRACK',
'subtarget' : toes,
@@ -766,9 +857,8 @@ class Rig:
})
# Find IK/FK switch property
- pb = self.obj.pose.bones
- #prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' )
- prop = rna_idprop_ui_prop_get(pb[bones['fk']['ctrl'][-1]], 'IK/FK')
+ pb = self.obj.pose.bones
+ prop = rna_idprop_ui_prop_get( pb[bones['fk']['ctrl'][-1]], 'IK_FK' )
# Modify rotation mode for ik and tweak controls
pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY'
@@ -777,8 +867,8 @@ class Rig:
pb[b].rotation_mode = 'ZXY'
# Add driver to limit scale constraint influence
- b = org_bones[3]
- drv = pb[b].constraints[-1].driver_add("influence").driver
+ b = toes_mch_parent
+ drv = pb[b].constraints[-1].driver_add("influence").driver
drv.type = 'AVERAGE'
var = drv.variables.new()
@@ -790,15 +880,15 @@ class Rig:
drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
drv_modifier.coefficients[0] = 1.0
drv_modifier.coefficients[1] = -1.0
# Create toe circle widget
create_circle_widget(self.obj, toes, radius=0.4, head_tail=0.5)
- bones['ik']['ctrl']['terminal'] += [ toes ]
+ bones['ik']['ctrl']['terminal'] += [toes]
bones['ik']['ctrl']['terminal'] += [ heel, ctrl ]
@@ -915,11 +1005,11 @@ class Rig:
owner[prop] = True
rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True)
- rna_prop["min"] = False
- rna_prop["max"] = True
+ rna_prop["min"] = False
+ rna_prop["max"] = True
rna_prop["description"] = prop
- drv = ctrl.constraints[ 0 ].driver_add("mute").driver
+ drv = ctrl.constraints[0].driver_add("mute").driver
drv.type = 'AVERAGE'
var = drv.variables.new()
@@ -931,8 +1021,8 @@ class Rig:
drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
drv_modifier.coefficients[0] = 1.0
drv_modifier.coefficients[1] = -1.0
@@ -949,8 +1039,8 @@ class Rig:
drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
drv_modifier.coefficients[0] = 1.0
drv_modifier.coefficients[1] = -1.0
@@ -993,10 +1083,10 @@ class Rig:
if len(ctrl.constraints) > 1:
owner[prop] = 0.0
rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True)
- rna_prop["min"] = 0.0
- rna_prop["max"] = 1.0
- rna_prop["soft_min"] = 0.0
- rna_prop["soft_max"] = 1.0
+ rna_prop["min"] = 0.0
+ rna_prop["max"] = 1.0
+ rna_prop["soft_min"] = 0.0
+ rna_prop["soft_max"] = 1.0
rna_prop["description"] = prop
drv = ctrl.constraints[1].driver_add("influence").driver
@@ -1033,6 +1123,9 @@ class Rig:
bpy.ops.object.mode_set(mode='EDIT')
eb = self.obj.data.edit_bones
+ # Adjust org-bones rotation
+ self.orient_org_bones()
+
# Clear parents for org bones
for bone in self.org_bones[1:]:
eb[bone].use_connect = False
@@ -1062,7 +1155,8 @@ class Rig:
controls_string = ", ".join(["'" + x + "'" for x in controls])
script = create_script(bones, 'paw')
- script += extra_script % (controls_string, bones['main_parent'], 'IK_follow', 'pole_follow', 'root/parent','root/parent')
+ script += extra_script % (controls_string, bones['main_parent'], 'IK_follow',
+ 'pole_follow', 'pole_follow', 'root/parent', 'root/parent')
return [script]
@@ -1072,26 +1166,22 @@ def add_parameters(params):
RigifyParameters PropertyGroup
"""
- # items = [
- # ('arm', 'Arm', ''),
- # ('leg', 'Leg', ''),
- # ('paw', 'Paw', '')
- # ]
- # params.limb_type = bpy.props.EnumProperty(
- # items = items,
- # name = "Limb Type",
- # default = 'paw'
- # )
-
items = [
- ('x', 'X', ''),
- ('y', 'Y', ''),
- ('z', 'Z', '')
+ ('x', 'X manual', ''),
+ ('z', 'Z manual', ''),
+ ('automatic', 'Automatic', '')
]
+
params.rotation_axis = bpy.props.EnumProperty(
items = items,
name = "Rotation Axis",
- default = 'x'
+ default = 'automatic'
+ )
+
+ params.auto_align_extremity = bpy.props.BoolProperty(
+ name='auto_align_extremity',
+ default=False,
+ description="Auto Align Extremity Bone"
)
params.segments = bpy.props.IntProperty(
@@ -1138,12 +1228,14 @@ def add_parameters(params):
def parameters_ui(layout, params):
""" Create the ui for the rig parameters."""
- # r = layout.row()
- # r.prop(params, "limb_type")
-
r = layout.row()
r.prop(params, "rotation_axis")
+ if 'auto' not in params.rotation_axis.lower():
+ r = layout.row()
+ text = "Auto align Claw"
+ r.prop(params, "auto_align_extremity", text=text)
+
r = layout.row()
r.prop(params, "segments")