2009-11-01 15:21:20 +00:00
|
|
|
# ##### 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.
|
2009-11-03 07:23:02 +00:00
|
|
|
#
|
2009-11-01 15:21:20 +00:00
|
|
|
# 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.
|
2009-11-03 07:23:02 +00:00
|
|
|
#
|
2009-11-01 15:21:20 +00:00
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-11-01 15:21:20 +00:00
|
|
|
#
|
|
|
|
# ##### END GPL LICENSE BLOCK #####
|
2009-10-31 20:16:59 +00:00
|
|
|
|
2009-10-31 23:35:56 +00:00
|
|
|
# <pep8 compliant>
|
2011-03-21 12:35:49 +00:00
|
|
|
|
2009-05-19 15:38:36 +00:00
|
|
|
import bpy
|
2011-08-12 06:57:00 +00:00
|
|
|
from bpy.types import Panel
|
2010-01-08 08:54:41 +00:00
|
|
|
from rna_prop_ui import PropertyPanel
|
2009-11-14 13:35:44 +00:00
|
|
|
|
2011-09-20 18:29:19 +00:00
|
|
|
|
2015-01-29 15:35:06 +11:00
|
|
|
class BoneButtonsPanel:
|
2009-10-31 19:31:45 +00:00
|
|
|
bl_space_type = 'PROPERTIES'
|
|
|
|
bl_region_type = 'WINDOW'
|
|
|
|
bl_context = "bone"
|
|
|
|
|
2010-08-09 01:37:09 +00:00
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
2009-10-31 19:31:45 +00:00
|
|
|
return (context.bone or context.edit_bone)
|
2009-05-20 02:17:53 +00:00
|
|
|
|
2009-10-31 23:35:56 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_context_bone(BoneButtonsPanel, Panel):
|
2009-10-31 19:31:45 +00:00
|
|
|
bl_label = ""
|
2010-08-26 01:05:37 +00:00
|
|
|
bl_options = {'HIDE_HEADER'}
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
bone = context.bone
|
|
|
|
if not bone:
|
|
|
|
bone = context.edit_bone
|
|
|
|
|
|
|
|
row = layout.row()
|
2009-12-10 10:23:53 +00:00
|
|
|
row.label(text="", icon='BONE_DATA')
|
2009-11-23 00:27:30 +00:00
|
|
|
row.prop(bone, "name", text="")
|
2009-07-09 09:07:25 +00:00
|
|
|
|
2009-10-31 23:35:56 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_transform(BoneButtonsPanel, Panel):
|
2011-09-15 13:20:18 +00:00
|
|
|
bl_label = "Transform"
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-12-17 17:51:43 +00:00
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
|
|
|
if context.edit_bone:
|
|
|
|
return True
|
2011-01-01 07:20:34 +00:00
|
|
|
|
2010-12-17 17:51:43 +00:00
|
|
|
ob = context.object
|
2018-04-05 18:20:27 +02:00
|
|
|
return ob and ob.mode == 'POSE' and context.bone
|
2010-12-17 17:51:43 +00:00
|
|
|
|
2009-10-31 19:31:45 +00:00
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
2009-11-14 13:35:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
|
2010-12-17 17:51:43 +00:00
|
|
|
if bone and ob:
|
2010-12-04 06:21:08 +00:00
|
|
|
pchan = ob.pose.bones[bone.name]
|
2010-08-18 07:45:32 +00:00
|
|
|
col.active = not (bone.parent and bone.use_connect)
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2019-08-13 18:15:43 +10:00
|
|
|
row = col.row(align=True)
|
|
|
|
row.prop(pchan, "location")
|
|
|
|
row.use_property_decorate = False
|
|
|
|
row.prop(pchan, "lock_location", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
2018-06-01 18:44:06 +02:00
|
|
|
|
2019-02-26 14:13:30 +11:00
|
|
|
rotation_mode = pchan.rotation_mode
|
|
|
|
if rotation_mode == 'QUATERNION':
|
2019-08-13 18:15:43 +10:00
|
|
|
col = layout.column()
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.prop(pchan, "rotation_quaternion", text="Rotation")
|
|
|
|
sub = row.column(align=True)
|
|
|
|
sub.use_property_decorate = False
|
|
|
|
sub.prop(pchan, "lock_rotation_w", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
|
|
|
sub.prop(pchan, "lock_rotation", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
2019-02-26 14:13:30 +11:00
|
|
|
elif rotation_mode == 'AXIS_ANGLE':
|
2019-08-13 18:15:43 +10:00
|
|
|
col = layout.column()
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.prop(pchan, "rotation_axis_angle", text="Rotation")
|
|
|
|
|
|
|
|
sub = row.column(align=True)
|
|
|
|
sub.use_property_decorate = False
|
|
|
|
sub.prop(pchan, "lock_rotation_w", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
|
|
|
sub.prop(pchan, "lock_rotation", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
2009-10-31 19:31:45 +00:00
|
|
|
else:
|
2019-08-13 18:15:43 +10:00
|
|
|
col = layout.column()
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.prop(pchan, "rotation_euler", text="Rotation")
|
|
|
|
row.use_property_decorate = False
|
|
|
|
row.prop(pchan, "lock_rotation", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
|
|
|
row = layout.row(align=True)
|
|
|
|
row.prop(pchan, "rotation_mode", text='Mode')
|
|
|
|
row.label(text="", icon='BLANK1')
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
2019-08-13 18:15:43 +10:00
|
|
|
row = col.row(align=True)
|
|
|
|
row.prop(pchan, "scale")
|
|
|
|
row.use_property_decorate = False
|
|
|
|
row.prop(pchan, "lock_scale", text="", emboss=False, icon='DECORATE_UNLOCKED')
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-12-17 17:51:43 +00:00
|
|
|
elif context.edit_bone:
|
2010-12-04 06:21:08 +00:00
|
|
|
bone = context.edit_bone
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
col.prop(bone, "head")
|
|
|
|
col.prop(bone, "tail")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
col.prop(bone, "roll")
|
|
|
|
col.prop(bone, "lock")
|
2012-06-19 22:17:19 +00:00
|
|
|
|
2009-10-31 23:35:56 +00:00
|
|
|
|
2016-05-18 03:19:06 +12:00
|
|
|
class BONE_PT_curved(BoneButtonsPanel, Panel):
|
|
|
|
bl_label = "Bendy Bones"
|
2018-10-18 12:13:06 +02:00
|
|
|
bl_options = {'DEFAULT_CLOSED'}
|
2016-05-18 03:19:06 +12:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
2018-12-10 11:26:37 +01:00
|
|
|
arm = context.armature
|
2018-10-31 19:12:59 +03:00
|
|
|
bone_list = "bones"
|
2016-05-18 03:19:06 +12:00
|
|
|
|
|
|
|
if ob and bone:
|
2018-12-10 11:26:37 +01:00
|
|
|
bbone = ob.pose.bones[bone.name]
|
2016-05-18 03:19:06 +12:00
|
|
|
elif bone is None:
|
|
|
|
bone = context.edit_bone
|
|
|
|
bbone = bone
|
2018-10-31 19:12:59 +03:00
|
|
|
bone_list = "edit_bones"
|
2016-05-18 03:19:06 +12:00
|
|
|
else:
|
|
|
|
bbone = bone
|
|
|
|
|
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
|
|
|
|
2016-05-18 03:19:06 +12:00
|
|
|
layout.prop(bone, "bbone_segments", text="Segments")
|
|
|
|
|
2019-08-13 15:45:54 +02:00
|
|
|
col = layout.column(align=True)
|
2019-08-13 18:15:43 +10:00
|
|
|
col.prop(bone, "bbone_x", text="Display Size X")
|
|
|
|
col.prop(bone, "bbone_z", text="Z")
|
|
|
|
|
2019-08-13 15:45:54 +02:00
|
|
|
topcol = layout.column()
|
|
|
|
topcol.active = bone.bbone_segments > 1
|
|
|
|
|
2018-08-23 22:37:30 +03:00
|
|
|
col = topcol.column(align=True)
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(bbone, "bbone_curveinx", text="Curve In X")
|
|
|
|
col.prop(bbone, "bbone_curveiny", text="In Y")
|
|
|
|
|
2018-08-23 22:37:30 +03:00
|
|
|
col = topcol.column(align=True)
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(bbone, "bbone_curveoutx", text="Curve Out X")
|
|
|
|
col.prop(bbone, "bbone_curveouty", text="Out Y")
|
|
|
|
|
2018-08-23 22:37:30 +03:00
|
|
|
col = topcol.column(align=True)
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(bbone, "bbone_rollin", text="Roll In")
|
|
|
|
col.prop(bbone, "bbone_rollout", text="Out")
|
|
|
|
col.prop(bone, "use_endroll_as_inroll")
|
|
|
|
|
2018-08-23 22:37:30 +03:00
|
|
|
col = topcol.column(align=True)
|
2019-04-20 18:06:31 +03:00
|
|
|
col.prop(bbone, "bbone_scaleinx", text="Scale In X")
|
|
|
|
col.prop(bbone, "bbone_scaleiny", text="In Y")
|
|
|
|
|
|
|
|
col = topcol.column(align=True)
|
|
|
|
col.prop(bbone, "bbone_scaleoutx", text="Scale Out X")
|
|
|
|
col.prop(bbone, "bbone_scaleouty", text="Out Y")
|
2018-06-01 18:44:06 +02:00
|
|
|
|
2018-08-23 22:37:30 +03:00
|
|
|
col = topcol.column(align=True)
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(bbone, "bbone_easein", text="Ease In")
|
|
|
|
col.prop(bbone, "bbone_easeout", text="Out")
|
2016-05-18 03:19:06 +12:00
|
|
|
|
2018-08-05 18:48:05 +03:00
|
|
|
col = topcol.column(align=True)
|
|
|
|
col.prop(bone, "bbone_handle_type_start", text="Start Handle")
|
2016-05-18 03:19:06 +12:00
|
|
|
|
2018-08-05 18:48:05 +03:00
|
|
|
col = col.column(align=True)
|
2019-03-04 22:06:23 +11:00
|
|
|
col.active = (bone.bbone_handle_type_start != 'AUTO')
|
2018-12-10 11:26:37 +01:00
|
|
|
col.prop_search(bone, "bbone_custom_handle_start", arm, bone_list, text="Custom")
|
2016-05-18 03:19:06 +12:00
|
|
|
|
2018-08-05 18:48:05 +03:00
|
|
|
col = topcol.column(align=True)
|
|
|
|
col.prop(bone, "bbone_handle_type_end", text="End Handle")
|
2016-05-18 03:19:06 +12:00
|
|
|
|
2018-08-05 18:48:05 +03:00
|
|
|
col = col.column(align=True)
|
2019-03-04 22:06:23 +11:00
|
|
|
col.active = (bone.bbone_handle_type_end != 'AUTO')
|
2018-12-10 11:26:37 +01:00
|
|
|
col.prop_search(bone, "bbone_custom_handle_end", arm, bone_list, text="Custom")
|
2016-05-18 03:19:06 +12:00
|
|
|
|
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_relations(BoneButtonsPanel, Panel):
|
2018-10-18 12:13:06 +02:00
|
|
|
bl_options = {'DEFAULT_CLOSED'}
|
2011-09-15 13:20:18 +00:00
|
|
|
bl_label = "Relations"
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
|
|
|
arm = context.armature
|
2010-12-17 17:51:43 +00:00
|
|
|
pchan = None
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-12-17 10:33:28 +00:00
|
|
|
if ob and bone:
|
2010-12-04 06:21:08 +00:00
|
|
|
pchan = ob.pose.bones[bone.name]
|
2010-12-17 17:51:43 +00:00
|
|
|
elif bone is None:
|
2009-10-31 19:31:45 +00:00
|
|
|
bone = context.edit_bone
|
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
col.use_property_split = False
|
2010-08-18 07:45:32 +00:00
|
|
|
col.prop(bone, "layers", text="")
|
2018-06-01 18:44:06 +02:00
|
|
|
col.use_property_split = True
|
|
|
|
col = layout.column()
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2009-11-23 00:27:30 +00:00
|
|
|
col.separator()
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
if context.bone:
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(bone, "parent")
|
2009-10-31 19:31:45 +00:00
|
|
|
else:
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop_search(bone, "parent", arm, "edit_bones")
|
|
|
|
|
|
|
|
if ob and pchan:
|
|
|
|
col.prop(bone, "use_relative_parent")
|
|
|
|
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="Bone Group")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
sub = col.column()
|
2009-11-22 17:41:35 +00:00
|
|
|
sub.active = (bone.parent is not None)
|
2010-08-18 07:45:32 +00:00
|
|
|
sub.prop(bone, "use_connect")
|
2009-11-25 18:48:29 +00:00
|
|
|
sub = col.column()
|
2010-08-18 07:45:32 +00:00
|
|
|
sub.active = (not bone.parent or not bone.use_connect)
|
2012-12-21 12:07:28 +00:00
|
|
|
sub.prop(bone, "use_local_location")
|
Armature: add Inherit Scale options to remove shear or average the scale.
As an inherent property of matrix-based transformation math, non-
uniform scaling of a parent bone induces shear into the transform
matrix of any rotated child. Such matrices cannot be cleanly
decomposed into a combination of location/rotation/scale, which
causes issues for rigging and animation tools.
Blender bones have options to exclude rotation and/or scale from the
inherited transformation, but don't have any support for removing the
often undesired shear component. That goal requires replacing simple
parenting with a combination of multiple bones and constraints. The
same is true about the goal of inheriting some scale, but completely
avoiding shear.
This patch replaces the old Inherit Scale checkbox with a enum that
supports multiple options:
* Full: inherit all effects of scale, like with enabled Inherit Scale.
* Fix Shear: removes shear from the final inherited transformation.
The cleanup math is specifically designed to preserve the main
axis of the bone, its length and total volume, and minimally
affect roll on average. It however will not prevent reappearance
of shear due to local rotation of the child or its children.
* Average: inherit uniform scale that represents the parent volume.
This is the simplest foolproof solution that will inherit some
scale without ever causing shear.
* None: completely remove scale and shear.
* None (Legacy): old disabled Inherit Scale checkbox.
This mode does not handle parent shear in any way, so the child
is likely to end up having both scale and shear. It is retained
for backward compatibility.
Since many rigging-related addons access the use_inherit_scale
property from Python, it is retained as a backward compatibility
stub that provides the old functionality.
As a side effect of reworking the code, this also fixes a matrix
multiplication order bug in the Inherit Rotation code, which caused
the parent local scale to be applied in world space. In rigger
opinion this option is useless in production rigs, so this fix
should not be a problem.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5588
2019-09-04 10:10:27 +03:00
|
|
|
sub = col.column()
|
|
|
|
sub.active = (bone.parent is not None)
|
|
|
|
sub.prop(bone, "use_inherit_rotation")
|
|
|
|
sub.prop(bone, "inherit_scale")
|
2009-10-31 23:35:56 +00:00
|
|
|
|
2009-11-28 23:37:56 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_display(BoneButtonsPanel, Panel):
|
2019-02-27 19:01:29 +01:00
|
|
|
bl_label = "Viewport Display"
|
2018-10-18 12:13:06 +02:00
|
|
|
bl_options = {'DEFAULT_CLOSED'}
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-08-09 01:37:09 +00:00
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
2009-10-31 19:31:45 +00:00
|
|
|
return context.bone
|
|
|
|
|
|
|
|
def draw(self, context):
|
2011-10-17 06:58:07 +00:00
|
|
|
# note. this works ok in edit-mode but isn't
|
2010-12-04 06:21:08 +00:00
|
|
|
# all that useful so disabling for now.
|
2009-10-31 19:31:45 +00:00
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
2010-12-17 17:51:43 +00:00
|
|
|
pchan = None
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-12-17 10:33:28 +00:00
|
|
|
if ob and bone:
|
2010-12-04 06:21:08 +00:00
|
|
|
pchan = ob.pose.bones[bone.name]
|
2010-12-17 17:51:43 +00:00
|
|
|
elif bone is None:
|
2009-10-31 19:31:45 +00:00
|
|
|
bone = context.edit_bone
|
|
|
|
|
2010-12-04 06:21:08 +00:00
|
|
|
if bone:
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
2011-09-21 15:18:38 +00:00
|
|
|
col.prop(bone, "hide", text="Hide")
|
2020-02-10 10:53:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
class BONE_PT_display_custom_shape(BoneButtonsPanel, Panel):
|
|
|
|
bl_label = "Custom Shape"
|
|
|
|
bl_parent_id = "BONE_PT_display"
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
|
|
|
return context.bone
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
layout.use_property_split = True
|
|
|
|
|
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
|
|
|
pchan = None
|
|
|
|
|
|
|
|
if ob and bone:
|
|
|
|
pchan = ob.pose.bones[bone.name]
|
|
|
|
elif bone is None:
|
|
|
|
bone = context.edit_bone
|
|
|
|
|
|
|
|
if bone and pchan:
|
|
|
|
col = layout.column()
|
|
|
|
col.prop(pchan, "custom_shape")
|
|
|
|
|
2012-03-20 20:06:10 +00:00
|
|
|
sub = col.column()
|
2015-10-25 05:50:40 +11:00
|
|
|
sub.active = bool(pchan and pchan.custom_shape)
|
2020-02-10 10:53:59 +01:00
|
|
|
sub.separator()
|
|
|
|
sub.prop(pchan, "custom_shape_scale", text="Scale")
|
|
|
|
sub.prop_search(pchan, "custom_shape_transform",
|
|
|
|
ob.pose, "bones", text="Override Transform")
|
|
|
|
sub.prop(pchan, "use_custom_shape_bone_size")
|
|
|
|
sub.separator()
|
2012-03-20 20:06:10 +00:00
|
|
|
sub.prop(bone, "show_wire", text="Wireframe")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2009-12-14 20:56:19 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
|
2011-09-15 13:20:18 +00:00
|
|
|
bl_label = "Inverse Kinematics"
|
2010-08-26 01:05:37 +00:00
|
|
|
bl_options = {'DEFAULT_CLOSED'}
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2010-08-09 01:37:09 +00:00
|
|
|
@classmethod
|
|
|
|
def poll(cls, context):
|
2010-12-17 17:51:43 +00:00
|
|
|
ob = context.object
|
2018-04-05 18:20:27 +02:00
|
|
|
return ob and ob.mode == 'POSE' and context.bone
|
2009-12-14 03:01:42 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2010-12-17 17:51:43 +00:00
|
|
|
ob = context.object
|
|
|
|
bone = context.bone
|
|
|
|
pchan = ob.pose.bones[bone.name]
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2012-10-24 22:36:06 +00:00
|
|
|
active = pchan.is_in_ik_chain
|
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
col.prop(pchan, "ik_stretch", slider=True)
|
|
|
|
col.active = active
|
|
|
|
|
|
|
|
layout.separator()
|
|
|
|
|
|
|
|
col = layout.column(align=True)
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col.prop(pchan, "lock_ik_x", text="Lock IK X")
|
|
|
|
col.prop(pchan, "lock_ik_y", text="Y")
|
|
|
|
col.prop(pchan, "lock_ik_z", text="Z")
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column(align=True)
|
|
|
|
|
|
|
|
sub = col.column(align=True)
|
2012-10-24 22:36:06 +00:00
|
|
|
sub.active = pchan.lock_ik_x is False and active
|
2018-06-01 18:44:06 +02:00
|
|
|
sub.prop(pchan, "ik_stiffness_x", text="Stiffness X", slider=True)
|
|
|
|
sub = col.column(align=True)
|
|
|
|
sub.active = pchan.lock_ik_y is False and active
|
|
|
|
sub.prop(pchan, "ik_stiffness_y", text="Y", slider=True)
|
|
|
|
sub = col.column(align=True)
|
|
|
|
sub.active = pchan.lock_ik_z is False and active
|
|
|
|
sub.prop(pchan, "ik_stiffness_z", text="Z", slider=True)
|
|
|
|
|
|
|
|
col = layout.column(align=True)
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
sub = col.column()
|
|
|
|
sub.active = pchan.lock_ik_x is False and active
|
|
|
|
sub.prop(pchan, "use_ik_limit_x", text="Limit X")
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
sub = col.column(align=True)
|
|
|
|
sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and active
|
|
|
|
sub.prop(pchan, "ik_min_x", text="Min")
|
|
|
|
sub.prop(pchan, "ik_max_x", text="Max")
|
|
|
|
|
|
|
|
col.separator()
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
sub = col.column()
|
2012-10-24 22:36:06 +00:00
|
|
|
sub.active = pchan.lock_ik_y is False and active
|
2018-06-01 18:44:06 +02:00
|
|
|
sub.prop(pchan, "use_ik_limit_y", text="Limit Y")
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
sub = col.column(align=True)
|
2012-10-24 22:36:06 +00:00
|
|
|
sub.active = pchan.lock_ik_y is False and pchan.use_ik_limit_y and active
|
2018-06-01 18:44:06 +02:00
|
|
|
sub.prop(pchan, "ik_min_y", text="Min")
|
|
|
|
sub.prop(pchan, "ik_max_y", text="Max")
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col.separator()
|
2010-08-06 15:17:44 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
sub = col.column()
|
2012-10-24 22:36:06 +00:00
|
|
|
sub.active = pchan.lock_ik_z is False and active
|
2018-06-01 18:44:06 +02:00
|
|
|
sub.prop(pchan, "use_ik_limit_z", text="Limit Z")
|
|
|
|
|
|
|
|
sub = col.column(align=True)
|
2012-10-24 22:36:06 +00:00
|
|
|
sub.active = pchan.lock_ik_z is False and pchan.use_ik_limit_z and active
|
2018-06-01 18:44:06 +02:00
|
|
|
sub.prop(pchan, "ik_min_z", text="Min")
|
|
|
|
sub.prop(pchan, "ik_max_z", text="Max")
|
2010-09-07 15:17:42 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col.separator()
|
2009-12-14 03:01:42 +00:00
|
|
|
|
|
|
|
if ob.pose.ik_solver == 'ITASC':
|
2018-06-01 18:44:06 +02:00
|
|
|
|
|
|
|
col = layout.column()
|
2011-09-21 15:18:38 +00:00
|
|
|
col.prop(pchan, "use_ik_rotation_control", text="Control Rotation")
|
2012-10-24 22:36:06 +00:00
|
|
|
col.active = active
|
2018-06-01 18:44:06 +02:00
|
|
|
|
|
|
|
col = layout.column()
|
|
|
|
|
|
|
|
col.prop(pchan, "ik_rotation_weight", text="IK Rotation Weight", slider=True)
|
2012-10-24 22:36:06 +00:00
|
|
|
col.active = active
|
2009-12-14 03:01:42 +00:00
|
|
|
# not supported yet
|
|
|
|
#row = layout.row()
|
2011-09-21 15:18:38 +00:00
|
|
|
#row.prop(pchan, "use_ik_linear_control", text="Joint Size")
|
|
|
|
#row.prop(pchan, "ik_linear_weight", text="Weight", slider=True)
|
2009-12-14 03:01:42 +00:00
|
|
|
|
2009-10-31 23:35:56 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_deform(BoneButtonsPanel, Panel):
|
2011-09-15 13:20:18 +00:00
|
|
|
bl_label = "Deform"
|
2010-08-26 01:05:37 +00:00
|
|
|
bl_options = {'DEFAULT_CLOSED'}
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
def draw_header(self, context):
|
|
|
|
bone = context.bone
|
|
|
|
|
|
|
|
if not bone:
|
|
|
|
bone = context.edit_bone
|
|
|
|
|
2010-08-18 07:45:32 +00:00
|
|
|
self.layout.prop(bone, "use_deform", text="")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
2018-06-01 18:44:06 +02:00
|
|
|
layout.use_property_split = True
|
2009-10-31 19:31:45 +00:00
|
|
|
|
|
|
|
bone = context.bone
|
|
|
|
|
|
|
|
if not bone:
|
|
|
|
bone = context.edit_bone
|
|
|
|
|
2010-08-18 07:45:32 +00:00
|
|
|
layout.active = bone.use_deform
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column()
|
|
|
|
col.prop(bone, "envelope_distance", text="Envelope Distance")
|
|
|
|
col.prop(bone, "envelope_weight", text="Envelope Weight")
|
|
|
|
col.prop(bone, "use_envelope_multiply", text="Envelope Multiply")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col.separator()
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2018-06-01 18:44:06 +02:00
|
|
|
col = layout.column(align=True)
|
|
|
|
col.prop(bone, "head_radius", text="Radius Head")
|
2016-05-18 03:19:06 +12:00
|
|
|
col.prop(bone, "tail_radius", text="Tail")
|
2009-10-31 19:31:45 +00:00
|
|
|
|
2010-02-22 23:32:58 +00:00
|
|
|
|
2011-08-12 06:57:00 +00:00
|
|
|
class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
|
2018-11-26 19:00:01 +01:00
|
|
|
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
2010-12-17 10:33:28 +00:00
|
|
|
_property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone
|
2010-08-12 19:36:10 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def _context_path(self):
|
|
|
|
obj = bpy.context.object
|
2018-04-05 18:20:27 +02:00
|
|
|
if obj and obj.mode == 'POSE':
|
2010-08-12 19:36:10 +00:00
|
|
|
return "active_pose_bone"
|
|
|
|
else:
|
|
|
|
return "active_bone"
|
2011-04-04 10:13:04 +00:00
|
|
|
|
2017-03-18 20:03:24 +11:00
|
|
|
|
|
|
|
classes = (
|
|
|
|
BONE_PT_context_bone,
|
2017-03-20 02:34:32 +11:00
|
|
|
BONE_PT_transform,
|
2017-03-18 20:03:24 +11:00
|
|
|
BONE_PT_curved,
|
2017-03-20 02:34:32 +11:00
|
|
|
BONE_PT_relations,
|
2017-03-18 20:03:24 +11:00
|
|
|
BONE_PT_inverse_kinematics,
|
2017-03-20 02:34:32 +11:00
|
|
|
BONE_PT_deform,
|
2019-02-27 19:01:29 +01:00
|
|
|
BONE_PT_display,
|
2020-02-10 11:04:34 +01:00
|
|
|
BONE_PT_display_custom_shape,
|
2017-03-20 02:34:32 +11:00
|
|
|
BONE_PT_custom_props,
|
2017-03-18 20:03:24 +11:00
|
|
|
)
|
|
|
|
|
2011-04-04 10:13:04 +00:00
|
|
|
if __name__ == "__main__": # only for live edit.
|
2017-03-18 20:03:24 +11:00
|
|
|
from bpy.utils import register_class
|
|
|
|
for cls in classes:
|
|
|
|
register_class(cls)
|