blender/release/scripts/ui/properties_data_bone.py

381 lines
12 KiB
Python
Raw Normal View History

# ##### 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,
2010-02-12 13:34:04 +00:00
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
from rna_prop_ui import PropertyPanel
class BoneButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "bone"
@classmethod
def poll(cls, context):
return (context.bone or context.edit_bone)
class BONE_PT_context_bone(BoneButtonsPanel, bpy.types.Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
def draw(self, context):
layout = self.layout
bone = context.bone
if not bone:
bone = context.edit_bone
row = layout.row()
row.label(text="", icon='BONE_DATA')
row.prop(bone, "name", text="")
class BONE_PT_transform(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Transform"
@classmethod
def poll(cls, context):
if context.edit_bone:
return True
2011-01-01 07:20:34 +00:00
ob = context.object
return ob and ob.mode == 'POSE' and context.bone
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
if bone and ob:
2010-12-04 06:21:08 +00:00
pchan = ob.pose.bones[bone.name]
row = layout.row()
col = row.column()
col.prop(pchan, "location")
2010-08-18 07:45:32 +00:00
col.active = not (bone.parent and bone.use_connect)
col = row.column()
if pchan.rotation_mode == 'QUATERNION':
col.prop(pchan, "rotation_quaternion", text="Rotation")
elif pchan.rotation_mode == 'AXIS_ANGLE':
#col.label(text="Rotation")
#col.prop(pchan, "rotation_angle", text="Angle")
#col.prop(pchan, "rotation_axis", text="Axis")
col.prop(pchan, "rotation_axis_angle", text="Rotation")
else:
col.prop(pchan, "rotation_euler", text="Rotation")
row.column().prop(pchan, "scale")
layout.prop(pchan, "rotation_mode")
elif context.edit_bone:
2010-12-04 06:21:08 +00:00
bone = context.edit_bone
row = layout.row()
row.column().prop(bone, "head")
row.column().prop(bone, "tail")
col = row.column()
sub = col.column(align=True)
sub.label(text="Roll:")
sub.prop(bone, "roll", text="")
sub.label()
sub.prop(bone, "lock")
class BONE_PT_transform_locks(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Transform Locks"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
ob = context.object
return ob and ob.mode == 'POSE' and context.bone
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
2010-12-04 06:21:08 +00:00
pchan = ob.pose.bones[bone.name]
row = layout.row()
col = row.column()
col.prop(pchan, "lock_location")
2010-08-18 07:45:32 +00:00
col.active = not (bone.parent and bone.use_connect)
col = row.column()
if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
col.prop(pchan, "lock_rotations_4d", text="Lock Rotation")
if pchan.lock_rotations_4d:
col.prop(pchan, "lock_rotation_w", text="W")
col.prop(pchan, "lock_rotation", text="")
else:
col.prop(pchan, "lock_rotation", text="Rotation")
row.column().prop(pchan, "lock_scale")
class BONE_PT_relations(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Relations"
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
arm = context.armature
pchan = None
if ob and bone:
2010-12-04 06:21:08 +00:00
pchan = ob.pose.bones[bone.name]
elif bone is None:
bone = context.edit_bone
split = layout.split()
col = split.column()
col.label(text="Layers:")
2010-08-18 07:45:32 +00:00
col.prop(bone, "layers", text="")
col.separator()
if ob and pchan:
col.label(text="Bone Group:")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
col = split.column()
col.label(text="Parent:")
if context.bone:
col.prop(bone, "parent", text="")
else:
col.prop_search(bone, "parent", arm, "edit_bones", text="")
sub = col.column()
sub.active = (bone.parent is not None)
2010-08-18 07:45:32 +00:00
sub.prop(bone, "use_connect")
sub.prop(bone, "use_inherit_rotation", text="Inherit Rotation")
2010-08-18 07:45:32 +00:00
sub.prop(bone, "use_inherit_scale", text="Inherit Scale")
sub = col.column()
2010-08-18 07:45:32 +00:00
sub.active = (not bone.parent or not bone.use_connect)
sub.prop(bone, "use_local_location", text="Local Location")
class BONE_PT_display(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Display"
@classmethod
def poll(cls, context):
return context.bone
def draw(self, context):
2010-12-04 06:21:08 +00:00
# note. this works ok in editmode but isnt
# all that useful so disabling for now.
layout = self.layout
ob = context.object
bone = context.bone
pchan = None
if ob and bone:
2010-12-04 06:21:08 +00:00
pchan = ob.pose.bones[bone.name]
elif bone is None:
bone = context.edit_bone
2010-12-04 06:21:08 +00:00
if bone:
split = layout.split()
col = split.column()
col.prop(bone, "show_wire", text="Wireframe")
Apply first pass of edits to rna values from rna_booleans.txt. These are not animated and are best not change names like this too late in the release. ActionGroup.selected -> select: boolean Action Group is selected BezierSplinePoint.hidden -> hide: boolean Visibility status BezierSplinePoint.selected_control_point -> select_control_point: boolean Control point selection status BezierSplinePoint.selected_handle1 -> select_left_handle: boolean Handle 1 selection status BezierSplinePoint.selected_handle2 -> select_right_handle: boolean Handle 2 selection status Bone.restrict_select -> hide_select: boolean Bone is able to be selected Bone.selected -> select: boolean CurveMapPoint.selected -> select: boolean Selection state of the curve point EditBone.restrict_select -> hide_select: boolean Bone is able to be selected EditBone.selected -> select: boolean EditBone.selected_head -> select_head: boolean EditBone.selected_tail -> select_tail: boolean EditBone.locked -> lock: boolean Bone is not able to be transformed when in Edit Mode EditBone.hidden -> hide: boolean Bone is not visible when in Edit Mode NEGATE * FCurve.disabled -> enabled: boolean F-Curve could not be evaluated in past, so should be skipped when evaluating FCurve.locked -> lock: boolean F-Curve's settings cannot be edited FCurve.muted -> mute: boolean F-Curve is not evaluated FCurve.selected -> select: boolean F-Curve is selected for editing NEGATE * FCurve.visible -> hide: boolean F-Curve and its keyframes are shown in the Graph Editor graphs FCurveSample.selected -> select: boolean Selection status GPencilFrame.selected -> select: boolean Frame is selected for editing in the DopeSheet GPencilLayer.locked -> lock: boolean Protect layer from further editing and/or frame changes GPencilLayer.selected -> select: boolean Layer is selected for editing in the DopeSheet Keyframe.selected -> select: boolean Control point selection status Keyframe.selected_handle1 -> select_left_handle: boolean Handle 1 selection status Keyframe.selected_handle2 -> select_right_handle: boolean Handle 2 selection status MeshEdge.selected -> select: boolean MeshEdge.hidden -> hide: boolean MeshFace.hidden -> hide: boolean MeshFace.selected -> select: boolean MeshVertex.hidden -> hide: boolean MeshVertex.selected -> select: boolean MotionPathVert.selected -> select: boolean Path point is selected for editing NlaStrip.selected -> select: boolean NLA Strip is selected NlaTrack.locked -> lock: boolean NLA Track is locked NlaTrack.muted -> mute: boolean NLA Track is not evaluated NlaTrack.selected -> select: boolean NLA Track is selected Object.restrict_render -> hide_render: boolean Restrict renderability Object.restrict_select -> hide_select: boolean Restrict selection in the viewport Object.restrict_view -> hide: boolean Restrict visibility in the viewport Object.selected -> select: boolean Object selection state ObjectBase.selected -> select: boolean Object base selection state PoseBone.selected -> select: boolean Sequence.right_handle_selected -> select_right_handle: boolean Sequence.selected -> select: boolean SplinePoint.selected -> select_control_point: boolean Selection status TimelineMarker.selected -> select: boolean Marker selection state Sequence.left_handle_selected -> select_left_handle: boolean ActionGroup.locked -> lock: boolean Action Group is locked Bone.hidden -> hide: boolean Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes) SplinePoint.hidden -> hide: boolean Visibility status FModifier.muted -> mute: boolean F-Curve Modifier will not be evaluated note: rebaned uv_select to select_uv
2010-07-15 16:56:04 +00:00
col.prop(bone, "hide", text="Hide")
2010-12-04 06:21:08 +00:00
if pchan:
col = split.column()
2010-12-04 06:21:08 +00:00
col.label(text="Custom Shape:")
col.prop(pchan, "custom_shape", text="")
if pchan.custom_shape:
col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Inverse Kinematics"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
ob = context.object
return ob and ob.mode == 'POSE' and context.bone
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
pchan = ob.pose.bones[bone.name]
2010-03-07 09:53:59 +00:00
row = layout.row()
row.prop(ob.pose, "ik_solver")
split = layout.split(percentage=0.25)
split.prop(pchan, "lock_ik_x", icon='LOCKED' if pchan.lock_ik_x else 'UNLOCKED', text="X")
2010-08-18 08:26:18 +00:00
split.active = pchan.is_in_ik_chain
row = split.row()
row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
2010-08-20 02:08:43 +00:00
row.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
sub = split.row()
sub.prop(pchan, "use_ik_limit_x", text="Limit")
2010-08-20 02:08:43 +00:00
sub.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain
sub = split.row(align=True)
sub.prop(pchan, "ik_min_x", text="")
sub.prop(pchan, "ik_max_x", text="")
sub.active = pchan.lock_ik_x == False and pchan.use_ik_limit_x and pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
split.prop(pchan, "lock_ik_y", icon='LOCKED' if pchan.lock_ik_y else 'UNLOCKED', text="Y")
split.active = pchan.is_in_ik_chain
row = split.row()
row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
2010-08-20 02:08:43 +00:00
row.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
sub = split.row()
sub.prop(pchan, "use_ik_limit_y", text="Limit")
2010-08-20 02:08:43 +00:00
sub.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain
sub = split.row(align=True)
sub.prop(pchan, "ik_min_y", text="")
sub.prop(pchan, "ik_max_y", text="")
sub.active = pchan.lock_ik_y == False and pchan.use_ik_limit_y and pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
split.prop(pchan, "lock_ik_z", icon='LOCKED' if pchan.lock_ik_z else 'UNLOCKED', text="Z")
split.active = pchan.is_in_ik_chain
sub = split.row()
sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
2010-08-20 02:08:43 +00:00
sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
sub = split.row()
sub.prop(pchan, "use_ik_limit_z", text="Limit")
2010-08-20 02:08:43 +00:00
sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain
sub = split.row(align=True)
sub.prop(pchan, "ik_min_z", text="")
sub.prop(pchan, "ik_max_z", text="")
sub.active = pchan.lock_ik_z == False and pchan.use_ik_limit_z and pchan.is_in_ik_chain
2010-09-07 15:17:42 +00:00
split = layout.split(percentage=0.25)
split.label(text="Stretch:")
sub = split.row()
sub.prop(pchan, "ik_stretch", text="", slider=True)
sub.active = pchan.is_in_ik_chain
if ob.pose.ik_solver == 'ITASC':
split = layout.split()
col = split.column()
col.prop(pchan, "use_ik_rotation_control", text="Control Rotation")
2010-08-18 08:26:18 +00:00
col.active = pchan.is_in_ik_chain
col = split.column()
col.prop(pchan, "ik_rotation_weight", text="Weight", slider=True)
2010-08-18 08:26:18 +00:00
col.active = pchan.is_in_ik_chain
# not supported yet
#row = layout.row()
#row.prop(pchan, "use_ik_linear_control", text="Joint Size")
#row.prop(pchan, "ik_linear_weight", text="Weight", slider=True)
class BONE_PT_deform(BoneButtonsPanel, bpy.types.Panel):
bl_label = "Deform"
bl_options = {'DEFAULT_CLOSED'}
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="")
def draw(self, context):
layout = self.layout
bone = context.bone
if not bone:
bone = context.edit_bone
2010-08-18 07:45:32 +00:00
layout.active = bone.use_deform
split = layout.split()
col = split.column()
col.label(text="Envelope:")
sub = col.column(align=True)
sub.prop(bone, "envelope_distance", text="Distance")
sub.prop(bone, "envelope_weight", text="Weight")
2010-08-18 07:45:32 +00:00
col.prop(bone, "use_envelope_multiply", text="Multiply")
sub = col.column(align=True)
sub.label(text="Radius:")
sub.prop(bone, "head_radius", text="Head")
sub.prop(bone, "tail_radius", text="Tail")
col = split.column()
col.label(text="Curved Bones:")
sub = col.column(align=True)
sub.prop(bone, "bbone_segments", text="Segments")
sub.prop(bone, "bbone_in", text="Ease In")
sub.prop(bone, "bbone_out", text="Ease Out")
col.label(text="Offset:")
2010-08-18 07:45:32 +00:00
col.prop(bone, "use_cyclic_offset")
class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, bpy.types.Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone
@property
def _context_path(self):
obj = bpy.context.object
if obj and obj.mode == 'POSE':
return "active_pose_bone"
else:
return "active_bone"
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()