blender/scripts/startup/bl_ui/properties_constraint.py
2023-09-03 21:35:07 +10:00

1757 lines
56 KiB
Python

# SPDX-FileCopyrightText: 2009-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Panel
from bpy.app.translations import contexts as i18n_contexts
class ObjectConstraintPanel:
bl_context = "constraint"
@classmethod
def poll(cls, context):
return (context.object)
class BoneConstraintPanel:
bl_context = "bone_constraint"
@classmethod
def poll(cls, context):
return (context.pose_bone)
class OBJECT_PT_constraints(ObjectConstraintPanel, Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Object Constraints"
bl_options = {'HIDE_HEADER'}
def draw(self, _context):
layout = self.layout
layout.operator_menu_enum("object.constraint_add", "type", text="Add Object Constraint")
layout.template_constraints(use_bone_constraints=False)
class BONE_PT_constraints(BoneConstraintPanel, Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Bone Constraints"
bl_options = {'HIDE_HEADER'}
def draw(self, _context):
layout = self.layout
layout.operator_menu_enum("pose.constraint_add", "type", text="Add Bone Constraint")
layout.template_constraints(use_bone_constraints=True)
# Parent class for constraint panels, with templates and drawing methods
# shared between the bone and object constraint panels
class ConstraintButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = ""
bl_options = {'INSTANCED', 'HEADER_LAYOUT_EXPAND'}
@staticmethod
def draw_influence(layout, con):
layout.separator()
if con.type in {'IK', 'SPLINE_IK'}:
# constraint.disable_keep_transform doesn't work well
# for these constraints.
layout.prop(con, "influence")
else:
row = layout.row(align=True)
row.prop(con, "influence")
row.operator("constraint.disable_keep_transform", text="", icon='CANCEL')
@staticmethod
def space_template(layout, con, target=True, owner=True, separator=True):
if target or owner:
if separator:
layout.separator()
if target:
layout.prop(con, "target_space", text="Target")
if owner:
layout.prop(con, "owner_space", text="Owner")
if con.target_space == 'CUSTOM' or con.owner_space == 'CUSTOM':
col = layout.column()
col.prop(con, "space_object")
if con.space_object and con.space_object.type == 'ARMATURE':
col.prop_search(con, "space_subtarget", con.space_object.data, "bones", text="Bone")
elif con.space_object and con.space_object.type in {'MESH', 'LATTICE'}:
col.prop_search(con, "space_subtarget", con.space_object, "vertex_groups", text="Vertex Group")
@staticmethod
def target_template(layout, con, subtargets=True):
col = layout.column()
col.prop(con, "target") # XXX: limiting settings for only `curves` or some type of object.
if con.target and subtargets:
if con.target.type == 'ARMATURE':
col.prop_search(con, "subtarget", con.target.data, "bones", text="Bone")
if con.subtarget and hasattr(con, "head_tail"):
row = col.row(align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "head_tail")
# XXX icon, and only when bone has segments?
sub.prop(con, "use_bbone_shape", text="", icon='IPO_BEZIER')
row.prop_decorator(con, "head_tail")
elif con.target.type in {'MESH', 'LATTICE'}:
col.prop_search(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
def get_constraint(self, _context):
con = self.custom_data
self.layout.context_pointer_set("constraint", con)
return con
def draw_header(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.template_constraint_header(con)
# Drawing methods for specific constraints. (Shared by object and bone constraint panels)
def draw_childof(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
row = layout.row(heading="Location")
row.use_property_decorate = False
row.prop(con, "use_location_x", text="X", toggle=True)
row.prop(con, "use_location_y", text="Y", toggle=True)
row.prop(con, "use_location_z", text="Z", toggle=True)
row.label(icon='BLANK1')
row = layout.row(heading="Rotation")
row.use_property_decorate = False
row.prop(con, "use_rotation_x", text="X", toggle=True)
row.prop(con, "use_rotation_y", text="Y", toggle=True)
row.prop(con, "use_rotation_z", text="Z", toggle=True)
row.label(icon='BLANK1')
row = layout.row(heading="Scale")
row.use_property_decorate = False
row.prop(con, "use_scale_x", text="X", toggle=True)
row.prop(con, "use_scale_y", text="Y", toggle=True)
row.prop(con, "use_scale_z", text="Z", toggle=True)
row.label(icon='BLANK1')
row = layout.row()
row.operator("constraint.childof_set_inverse")
row.operator("constraint.childof_clear_inverse")
self.draw_influence(layout, con)
def draw_trackto(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "track_axis", expand=True)
layout.prop(con, "up_axis", text="Up", expand=True)
layout.prop(con, "use_target_z")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_follow_path(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
if con.use_fixed_location:
layout.prop(con, "offset_factor", text="Offset Factor")
else:
layout.prop(con, "offset")
layout.prop(con, "forward_axis", expand=True)
layout.prop(con, "up_axis", expand=True)
col = layout.column()
col.prop(con, "use_fixed_location")
col.prop(con, "use_curve_radius")
col.prop(con, "use_curve_follow")
layout.operator("constraint.followpath_path_animate", text="Animate Path", icon='ANIM_DATA')
self.draw_influence(layout, con)
def draw_rot_limit(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
# Decorators and property split are really buggy with these properties
row = layout.row(heading="Limit X", align=True)
row.use_property_decorate = False
row.prop(con, "use_limit_x", text="")
sub = row.column(align=True)
sub.active = con.use_limit_x
sub.prop(con, "min_x", text="Min")
sub.prop(con, "max_x", text="Max")
row.label(icon='BLANK1')
row = layout.row(heading="Y", align=True)
row.use_property_decorate = False
row.prop(con, "use_limit_y", text="")
sub = row.column(align=True)
sub.active = con.use_limit_y
sub.prop(con, "min_y", text="Min")
sub.prop(con, "max_y", text="Max")
row.label(icon='BLANK1')
row = layout.row(heading="Z", align=True)
row.use_property_decorate = False
row.prop(con, "use_limit_z", text="")
sub = row.column(align=True)
sub.active = con.use_limit_z
sub.prop(con, "min_z", text="Min")
sub.prop(con, "max_z", text="Max")
row.label(icon='BLANK1')
layout.prop(con, "euler_order", text="Order")
layout.prop(con, "use_transform_limit")
self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
def draw_loc_limit(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
col = layout.column()
row = col.row(heading="Minimum X", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_x", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_x
subsub.prop(con, "min_x", text="")
row.prop_decorator(con, "min_x")
row = col.row(heading="Y", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_y", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_y
subsub.prop(con, "min_y", text="")
row.prop_decorator(con, "min_y")
row = col.row(heading="Z", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_z", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_z
subsub.prop(con, "min_z", text="")
row.prop_decorator(con, "min_z")
col.separator()
row = col.row(heading="Maximum X", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_x", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_x
subsub.prop(con, "max_x", text="")
row.prop_decorator(con, "max_x")
row = col.row(heading="Y", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_y", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_y
subsub.prop(con, "max_y", text="")
row.prop_decorator(con, "max_y")
row = col.row(heading="Z", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_z", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_z
subsub.prop(con, "max_z", text="")
row.prop_decorator(con, "max_z")
layout.prop(con, "use_transform_limit")
self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
def draw_size_limit(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
col = layout.column()
row = col.row(heading="Minimum X", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_x", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_x
subsub.prop(con, "min_x", text="")
row.prop_decorator(con, "min_x")
row = col.row(heading="Y", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_y", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_y
subsub.prop(con, "min_y", text="")
row.prop_decorator(con, "min_y")
row = col.row(heading="Z", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_min_z", text="")
subsub = sub.row(align=True)
subsub.active = con.use_min_z
subsub.prop(con, "min_z", text="")
row.prop_decorator(con, "min_z")
col.separator()
row = col.row(heading="Maximum X", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_x", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_x
subsub.prop(con, "max_x", text="")
row.prop_decorator(con, "max_x")
row = col.row(heading="Y", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_y", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_y
subsub.prop(con, "max_y", text="")
row.prop_decorator(con, "max_y")
row = col.row(heading="Z", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_z", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_z
subsub.prop(con, "max_z", text="")
row.prop_decorator(con, "max_z")
layout.prop(con, "use_transform_limit")
self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
def draw_rotate_like(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "euler_order", text="Order")
row = layout.row(heading="Axis", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_x", text="X", toggle=True)
sub.prop(con, "use_y", text="Y", toggle=True)
sub.prop(con, "use_z", text="Z", toggle=True)
row.label(icon='BLANK1')
row = layout.row(heading="Invert", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "invert_x", text="X", toggle=True)
sub.prop(con, "invert_y", text="Y", toggle=True)
sub.prop(con, "invert_z", text="Z", toggle=True)
row.label(icon='BLANK1')
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_locate_like(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
row = layout.row(heading="Axis", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_x", text="X", toggle=True)
sub.prop(con, "use_y", text="Y", toggle=True)
sub.prop(con, "use_z", text="Z", toggle=True)
row.label(icon='BLANK1')
row = layout.row(heading="Invert", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "invert_x", text="X", toggle=True)
sub.prop(con, "invert_y", text="Y", toggle=True)
sub.prop(con, "invert_z", text="Z", toggle=True)
row.label(icon='BLANK1')
layout.prop(con, "use_offset")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_size_like(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
row = layout.row(heading="Axis", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_x", text="X", toggle=True)
sub.prop(con, "use_y", text="Y", toggle=True)
sub.prop(con, "use_z", text="Z", toggle=True)
row.label(icon='BLANK1')
col = layout.column()
col.prop(con, "power")
col.prop(con, "use_make_uniform")
col.prop(con, "use_offset")
row = col.row()
row.active = con.use_offset
row.prop(con, "use_add")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_same_volume(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
layout.prop(con, "mode")
row = layout.row(heading="Free Axis")
row.prop(con, "free_axis", expand=True)
layout.prop(con, "volume")
self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
def draw_trans_like(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "remove_target_shear")
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_action(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
target_row = layout.row(align=True)
target_row.active = not con.use_eval_time
self.target_template(target_row, con)
row = layout.row(align=True, heading="Evaluation Time")
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_eval_time", text="")
subsub = sub.row(align=True)
subsub.active = con.use_eval_time
subsub.prop(con, "eval_time", text="")
row.prop_decorator(con, "eval_time")
layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint)
self.draw_influence(layout, con)
def draw_lock_track(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "track_axis", expand=True)
layout.prop(con, "lock_axis", expand=True)
self.draw_influence(layout, con)
def draw_dist_limit(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
row = layout.row()
row.prop(con, "distance")
row.operator("constraint.limitdistance_reset", text="", icon='X')
layout.prop(con, "limit_mode", text="Clamp Region")
layout.prop(con, "use_transform_limit")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_stretch_to(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
row = layout.row()
row.prop(con, "rest_length")
row.operator("constraint.stretchto_reset", text="", icon='X')
layout.separator()
col = layout.column()
col.prop(con, "bulge", text="Volume Variation")
row = col.row(heading="Volume Min", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_bulge_min", text="")
subsub = sub.row(align=True)
subsub.active = con.use_bulge_min
subsub.prop(con, "bulge_min", text="")
row.prop_decorator(con, "bulge_min")
row = col.row(heading="Max", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_bulge_max", text="")
subsub = sub.row(align=True)
subsub.active = con.use_bulge_max
subsub.prop(con, "bulge_max", text="")
row.prop_decorator(con, "bulge_max")
row = col.row()
row.active = con.use_bulge_min or con.use_bulge_max
row.prop(con, "bulge_smooth", text="Smooth")
layout.prop(con, "volume", expand=True)
layout.prop(con, "keep_axis", text="Rotation", expand=True)
self.draw_influence(layout, con)
def draw_min_max(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "offset")
layout.prop(con, "floor_location", expand=True, text="Min/Max")
layout.prop(con, "use_rotation")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_clamp_to(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "main_axis", expand=True)
layout.prop(con, "use_cyclic")
self.draw_influence(layout, con)
def draw_transform(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "use_motion_extrapolate", text="Extrapolate")
self.space_template(layout, con)
self.draw_influence(layout, con)
def draw_shrinkwrap(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con, False)
layout.prop(con, "distance")
layout.prop(con, "shrinkwrap_type", text="Mode")
layout.separator()
if con.shrinkwrap_type == 'PROJECT':
layout.prop(con, "project_axis", expand=True, text="Project Axis")
layout.prop(con, "project_axis_space", text="Space")
layout.prop(con, "project_limit", text="Distance")
layout.prop(con, "use_project_opposite")
layout.separator()
col = layout.column()
row = col.row()
row.prop(con, "cull_face", expand=True)
row = col.row()
row.active = con.use_project_opposite and con.cull_face != 'OFF'
row.prop(con, "use_invert_cull")
layout.separator()
if con.shrinkwrap_type in {'PROJECT', 'NEAREST_SURFACE', 'TARGET_PROJECT'}:
layout.prop(con, "wrap_mode", text="Snap Mode")
row = layout.row(heading="Align to Normal", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_track_normal", text="")
subsub = sub.row(align=True)
subsub.active = con.use_track_normal
subsub.prop(con, "track_axis", text="")
row.prop_decorator(con, "track_axis")
self.draw_influence(layout, con)
def draw_damp_track(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
layout.prop(con, "track_axis", expand=True)
self.draw_influence(layout, con)
def draw_spline_ik(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
self.draw_influence(layout, con)
def draw_pivot(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
if con.target:
layout.prop(con, "offset", text="Pivot Offset")
else:
layout.prop(con, "use_relative_location")
if con.use_relative_location:
layout.prop(con, "offset", text="Pivot Point")
else:
layout.prop(con, "offset", text="Pivot Point")
col = layout.column()
col.prop(con, "rotation_range", text="Rotation Range")
self.draw_influence(layout, con)
def draw_follow_track(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
clip = None
if con.use_active_clip:
clip = context.scene.active_clip
else:
clip = con.clip
layout.prop(con, "use_active_clip")
layout.prop(con, "use_3d_position")
row = layout.row()
row.active = not con.use_3d_position
row.prop(con, "use_undistorted_position")
if not con.use_active_clip:
layout.prop(con, "clip")
layout.prop(con, "frame_method")
if clip:
tracking = clip.tracking
layout.prop_search(con, "object", tracking, "objects", icon='OBJECT_DATA')
tracking_object = tracking.objects.get(con.object, tracking.objects[0])
layout.prop_search(con, "track", tracking_object, "tracks", icon='ANIM_DATA')
layout.prop(con, "camera")
row = layout.row()
row.active = not con.use_3d_position
row.prop(con, "depth_object")
layout.operator("clip.constraint_to_fcurve")
self.draw_influence(layout, con)
def draw_camera_solver(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
layout.prop(con, "use_active_clip")
if not con.use_active_clip:
layout.prop(con, "clip")
layout.operator("clip.constraint_to_fcurve")
self.draw_influence(layout, con)
def draw_object_solver(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
clip = None
if con.use_active_clip:
clip = context.scene.active_clip
else:
clip = con.clip
layout.prop(con, "use_active_clip")
if not con.use_active_clip:
layout.prop(con, "clip")
if clip:
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
layout.prop(con, "camera")
row = layout.row()
row.operator("constraint.objectsolver_set_inverse")
row.operator("constraint.objectsolver_clear_inverse")
layout.operator("clip.constraint_to_fcurve")
self.draw_influence(layout, con)
def draw_transform_cache(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
layout.template_cache_file(con, "cache_file")
cache_file = con.cache_file
if cache_file is not None:
layout.prop_search(con, "object_path", cache_file, "object_paths")
self.draw_influence(layout, con)
def draw_python_constraint(self, _context):
layout = self.layout
layout.label(text="Blender 2.6 doesn't support Python constraints yet")
def draw_armature(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
col = layout.column()
col.prop(con, "use_deform_preserve_volume")
col.prop(con, "use_bone_envelopes")
if context.pose_bone:
col.prop(con, "use_current_location")
layout.operator("constraint.add_target", text="Add Target Bone")
layout.operator("constraint.normalize_target_weights")
self.draw_influence(layout, con)
if not con.targets:
layout.label(text="No target bones added", icon='ERROR')
def draw_kinematic(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
self.target_template(layout, con)
if context.object.pose.ik_solver == 'ITASC':
layout.prop(con, "ik_type")
# This button gives itself too much padding, so put it in a column with the subtarget
col = layout.column()
col.prop(con, "pole_target")
if con.pole_target and con.pole_target.type == 'ARMATURE':
col.prop_search(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
col = layout.column()
if con.pole_target:
col.prop(con, "pole_angle")
col.prop(con, "use_tail")
col.prop(con, "use_stretch")
col.prop(con, "chain_count")
if con.ik_type == 'COPY_POSE':
layout.prop(con, "reference_axis", expand=True)
# Use separate rows and columns here to avoid an alignment issue with the lock buttons
loc_col = layout.column()
loc_col.prop(con, "use_location")
row = loc_col.row()
row.active = con.use_location
row.prop(con, "weight", text="Weight", slider=True)
row = loc_col.row(heading="Lock", align=True)
row.use_property_decorate = False
row.active = con.use_location
sub = row.row(align=True)
sub.prop(con, "lock_location_x", text="X", toggle=True)
sub.prop(con, "lock_location_y", text="Y", toggle=True)
sub.prop(con, "lock_location_z", text="Z", toggle=True)
row.label(icon='BLANK1')
rot_col = layout.column()
rot_col.prop(con, "use_rotation")
row = rot_col.row()
row.active = con.use_rotation
row.prop(con, "orient_weight", text="Weight", slider=True)
row = rot_col.row(heading="Lock", align=True)
row.use_property_decorate = False
row.active = con.use_rotation
sub = row.row(align=True)
sub.prop(con, "lock_rotation_x", text="X", toggle=True)
sub.prop(con, "lock_rotation_y", text="Y", toggle=True)
sub.prop(con, "lock_rotation_z", text="Z", toggle=True)
row.label(icon='BLANK1')
elif con.ik_type == 'DISTANCE':
layout.prop(con, "limit_mode")
col = layout.column()
col.prop(con, "weight", text="Weight", slider=True)
col.prop(con, "distance", text="Distance", slider=True)
else:
# Standard IK constraint
col = layout.column()
col.prop(con, "pole_target")
if con.pole_target and con.pole_target.type == 'ARMATURE':
col.prop_search(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
col = layout.column()
if con.pole_target:
col.prop(con, "pole_angle")
col.prop(con, "iterations")
col.prop(con, "chain_count")
col.prop(con, "use_tail")
col.prop(con, "use_stretch")
col = layout.column()
row = col.row(align=True, heading="Weight Position")
row.prop(con, "use_location", text="")
sub = row.row(align=True)
sub.active = con.use_location
sub.prop(con, "weight", text="", slider=True)
row = col.row(align=True, heading="Rotation")
row.prop(con, "use_rotation", text="")
sub = row.row(align=True)
sub.active = con.use_rotation
sub.prop(con, "orient_weight", text="", slider=True)
self.draw_influence(layout, con)
# Parent class for constraint sub-panels.
class ConstraintButtonsSubPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = ""
def get_constraint(self, _context):
con = self.custom_data
self.layout.context_pointer_set("constraint", con)
return con
def draw_transform_from(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.prop(con, "map_from", expand=True)
layout.use_property_split = True
layout.use_property_decorate = True
from_axes = [con.map_to_x_from, con.map_to_y_from, con.map_to_z_from]
if con.map_from == 'ROTATION':
layout.prop(con, "from_rotation_mode", text="Mode")
ext = "" if con.map_from == 'LOCATION' else "_rot" if con.map_from == 'ROTATION' else "_scale"
col = layout.column(align=True)
col.active = "X" in from_axes
col.prop(con, "from_min_x" + ext, text="X Min")
col.prop(con, "from_max_x" + ext, text="Max")
col = layout.column(align=True)
col.active = "Y" in from_axes
col.prop(con, "from_min_y" + ext, text="Y Min")
col.prop(con, "from_max_y" + ext, text="Max")
col = layout.column(align=True)
col.active = "Z" in from_axes
col.prop(con, "from_min_z" + ext, text="Z Min")
col.prop(con, "from_max_z" + ext, text="Max")
def draw_transform_to(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.prop(con, "map_to", expand=True)
layout.use_property_split = True
layout.use_property_decorate = True
if con.map_to == 'ROTATION':
layout.prop(con, "to_euler_order", text="Order")
ext = "" if con.map_to == 'LOCATION' else "_rot" if con.map_to == 'ROTATION' else "_scale"
col = layout.column(align=True)
col.prop(con, "map_to_x_from", expand=False, text="X Source Axis")
col.prop(con, "to_min_x" + ext, text="Min")
col.prop(con, "to_max_x" + ext, text="Max")
col = layout.column(align=True)
col.prop(con, "map_to_y_from", expand=False, text="Y Source Axis")
col.prop(con, "to_min_y" + ext, text="Min")
col.prop(con, "to_max_y" + ext, text="Max")
col = layout.column(align=True)
col.prop(con, "map_to_z_from", expand=False, text="Z Source Axis")
col.prop(con, "to_min_z" + ext, text="Min")
col.prop(con, "to_max_z" + ext, text="Max")
layout.prop(con, "mix_mode" + ext, text="Mix", text_ctxt=i18n_contexts.constraint)
def draw_armature_bones(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
for i, tgt in enumerate(con.targets):
has_target = tgt.target is not None
box = layout.box()
header = box.row()
header.use_property_split = False
split = header.split(factor=0.45, align=True)
split.prop(tgt, "target", text="")
row = split.row(align=True)
row.active = has_target
if has_target:
row.prop_search(tgt, "subtarget", tgt.target.data, "bones", text="")
else:
row.prop(tgt, "subtarget", text="", icon='BONE_DATA')
header.operator("constraint.remove_target", text="", icon='X').index = i
row = box.row()
row.active = has_target and tgt.subtarget != ""
row.prop(tgt, "weight", slider=True, text="Weight")
def draw_spline_ik_fitting(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
col = layout.column()
col.prop(con, "chain_count")
col.prop(con, "use_even_divisions")
col.prop(con, "use_chain_offset")
def draw_spline_ik_chain_scaling(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
layout.prop(con, "use_curve_radius")
layout.prop(con, "y_scale_mode")
layout.prop(con, "xz_scale_mode")
if con.xz_scale_mode in {'INVERSE_PRESERVE', 'VOLUME_PRESERVE'}:
layout.prop(con, "use_original_scale")
if con.xz_scale_mode == 'VOLUME_PRESERVE':
col = layout.column()
col.prop(con, "bulge", text="Volume Variation")
row = col.row(heading="Volume Min")
row.prop(con, "use_bulge_min", text="")
sub = row.row()
sub.active = con.use_bulge_min
sub.prop(con, "bulge_min", text="")
row = col.row(heading="Max")
row.prop(con, "use_bulge_max", text="")
sub = row.row()
sub.active = con.use_bulge_max
sub.prop(con, "bulge_max", text="")
row = layout.row()
row.active = con.use_bulge_min or con.use_bulge_max
row.prop(con, "bulge_smooth", text="Smooth")
def draw_action_target(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
col = layout.column()
col.active = not con.use_eval_time
col.prop(con, "transform_channel", text="Channel")
ConstraintButtonsPanel.space_template(col, con, target=True, owner=False, separator=False)
sub = col.column(align=True)
sub.prop(con, "min", text="Range Min")
sub.prop(con, "max", text="Max")
def draw_action_action(self, context):
layout = self.layout
con = self.get_constraint(context)
layout.use_property_split = True
layout.use_property_decorate = True
layout.prop(con, "action")
layout.prop(con, "use_bone_object_action")
col = layout.column(align=True)
col.prop(con, "frame_start", text="Frame Start")
col.prop(con, "frame_end", text="End")
def draw_transform_cache_velocity(self, context):
self.draw_transform_cache_subpanel(
context, self.layout.template_cache_file_velocity
)
def draw_transform_cache_procedural(self, context):
self.draw_transform_cache_subpanel(
context, self.layout.template_cache_file_procedural
)
def draw_transform_cache_time(self, context):
self.draw_transform_cache_subpanel(
context, self.layout.template_cache_file_time_settings
)
def draw_transform_cache_layers(self, context):
self.draw_transform_cache_subpanel(
context, self.layout.template_cache_file_layers
)
def draw_transform_cache_subpanel(self, context, template_func):
con = self.get_constraint(context)
if con.cache_file is None:
return
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = True
template_func(con, "cache_file")
# Child Of Constraint
class OBJECT_PT_bChildOfConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_childof(context)
class BONE_PT_bChildOfConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_childof(context)
# Track To Constraint
class OBJECT_PT_bTrackToConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_trackto(context)
class BONE_PT_bTrackToConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_trackto(context)
# Follow Path Constraint
class OBJECT_PT_bFollowPathConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_follow_path(context)
class BONE_PT_bFollowPathConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_follow_path(context)
# Rotation Limit Constraint
class OBJECT_PT_bRotLimitConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_rot_limit(context)
class BONE_PT_bRotLimitConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_rot_limit(context)
# Location Limit Constraint
class OBJECT_PT_bLocLimitConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_loc_limit(context)
class BONE_PT_bLocLimitConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_loc_limit(context)
# Size Limit Constraint
class OBJECT_PT_bSizeLimitConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_size_limit(context)
class BONE_PT_bSizeLimitConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_size_limit(context)
# Rotate Like Constraint
class OBJECT_PT_bRotateLikeConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_rotate_like(context)
class BONE_PT_bRotateLikeConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_rotate_like(context)
# Locate Like Constraint
class OBJECT_PT_bLocateLikeConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_locate_like(context)
class BONE_PT_bLocateLikeConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_locate_like(context)
# Size Like Constraint
class OBJECT_PT_bSizeLikeConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_size_like(context)
class BONE_PT_bSizeLikeConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_size_like(context)
# Same Volume Constraint
class OBJECT_PT_bSameVolumeConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_same_volume(context)
class BONE_PT_bSameVolumeConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_same_volume(context)
# Trans Like Constraint
class OBJECT_PT_bTransLikeConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_trans_like(context)
class BONE_PT_bTransLikeConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_trans_like(context)
# Action Constraint
class OBJECT_PT_bActionConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_action(context)
class BONE_PT_bActionConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_action(context)
class OBJECT_PT_bActionConstraint_target(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bActionConstraint"
bl_label = "Target"
def draw(self, context):
self.draw_action_target(context)
class BONE_PT_bActionConstraint_target(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bActionConstraint"
bl_label = "Target"
def draw(self, context):
self.draw_action_target(context)
class OBJECT_PT_bActionConstraint_action(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bActionConstraint"
bl_label = "Action"
def draw(self, context):
self.draw_action_action(context)
class BONE_PT_bActionConstraint_action(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bActionConstraint"
bl_label = "Action"
def draw(self, context):
self.draw_action_action(context)
# Lock Track Constraint
class OBJECT_PT_bLockTrackConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_lock_track(context)
class BONE_PT_bLockTrackConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_lock_track(context)
# Distance Limit Constraint
class OBJECT_PT_bDistLimitConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_dist_limit(context)
class BONE_PT_bDistLimitConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_dist_limit(context)
# Stretch To Constraint
class OBJECT_PT_bStretchToConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_stretch_to(context)
class BONE_PT_bStretchToConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_stretch_to(context)
# Min Max Constraint
class OBJECT_PT_bMinMaxConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_min_max(context)
class BONE_PT_bMinMaxConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_min_max(context)
# Clamp To Constraint
class OBJECT_PT_bClampToConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_clamp_to(context)
class BONE_PT_bClampToConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_clamp_to(context)
# Transform Constraint
class OBJECT_PT_bTransformConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_transform(context)
class BONE_PT_bTransformConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_transform(context)
class OBJECT_PT_bTransformConstraint_source(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformConstraint"
bl_label = "Map From"
def draw(self, context):
self.draw_transform_from(context)
class BONE_PT_bTransformConstraint_from(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformConstraint"
bl_label = "Map From"
def draw(self, context):
self.draw_transform_from(context)
class OBJECT_PT_bTransformConstraint_destination(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformConstraint"
bl_label = "Map To"
def draw(self, context):
self.draw_transform_to(context)
class BONE_PT_bTransformConstraint_to(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformConstraint"
bl_label = "Map To"
def draw(self, context):
self.draw_transform_to(context)
# Shrink-wrap Constraint.
class OBJECT_PT_bShrinkwrapConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_shrinkwrap(context)
class BONE_PT_bShrinkwrapConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_shrinkwrap(context)
# Damp Track Constraint
class OBJECT_PT_bDampTrackConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_damp_track(context)
class BONE_PT_bDampTrackConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_damp_track(context)
# Spline IK Constraint
class BONE_PT_bSplineIKConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_spline_ik(context)
class BONE_PT_bSplineIKConstraint_fitting(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bSplineIKConstraint"
bl_label = "Fitting"
def draw(self, context):
self.draw_spline_ik_fitting(context)
class BONE_PT_bSplineIKConstraint_chain_scaling(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bSplineIKConstraint"
bl_label = "Chain Scaling"
def draw(self, context):
self.draw_spline_ik_chain_scaling(context)
# Pivot Constraint
class OBJECT_PT_bPivotConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_pivot(context)
class BONE_PT_bPivotConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_pivot(context)
# Follow Track Constraint
class OBJECT_PT_bFollowTrackConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_follow_track(context)
class BONE_PT_bFollowTrackConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_follow_track(context)
# Camera Solver Constraint
class OBJECT_PT_bCameraSolverConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_camera_solver(context)
class BONE_PT_bCameraSolverConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_camera_solver(context)
# Object Solver Constraint
class OBJECT_PT_bObjectSolverConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_object_solver(context)
class BONE_PT_bObjectSolverConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_object_solver(context)
# Transform Cache Constraint
class OBJECT_PT_bTransformCacheConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_transform_cache(context)
class BONE_PT_bTransformCacheConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_transform_cache(context)
class OBJECT_PT_bTransformCacheConstraint_velocity(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
bl_label = "Velocity"
def draw(self, context):
self.draw_transform_cache_velocity(context)
class BONE_PT_bTransformCacheConstraint_velocity(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
bl_label = "Velocity"
def draw(self, context):
self.draw_transform_cache_velocity(context)
class OBJECT_PT_bTransformCacheConstraint_layers(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
bl_label = "Override Layers"
def draw(self, context):
self.draw_transform_cache_layers(context)
class BONE_PT_bTransformCacheConstraint_layers(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
bl_label = "Override Layers"
def draw(self, context):
self.draw_transform_cache_layers(context)
class OBJECT_PT_bTransformCacheConstraint_procedural(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
bl_label = "Render Procedural"
def draw(self, context):
self.draw_transform_cache_procedural(context)
class BONE_PT_bTransformCacheConstraint_procedural(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
bl_label = "Render Procedural"
def draw(self, context):
self.draw_transform_cache_procedural(context)
class OBJECT_PT_bTransformCacheConstraint_time(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bTransformCacheConstraint"
bl_label = "Time"
def draw(self, context):
self.draw_transform_cache_time(context)
class BONE_PT_bTransformCacheConstraint_time(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bTransformCacheConstraint"
bl_label = "Time"
def draw(self, context):
self.draw_transform_cache_time(context)
# Python Constraint
class OBJECT_PT_bPythonConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_python_constraint(context)
class BONE_PT_bPythonConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_python_constraint(context)
# Armature Constraint
class OBJECT_PT_bArmatureConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_armature(context)
class BONE_PT_bArmatureConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_armature(context)
class OBJECT_PT_bArmatureConstraint_bones(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "OBJECT_PT_bArmatureConstraint"
bl_label = "Bones"
def draw(self, context):
self.draw_armature_bones(context)
class BONE_PT_bArmatureConstraint_bones(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel):
bl_parent_id = "BONE_PT_bArmatureConstraint"
bl_label = "Bones"
def draw(self, context):
self.draw_armature_bones(context)
# Inverse Kinematic Constraint
class OBJECT_PT_bKinematicConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_kinematic(context)
class BONE_PT_bKinematicConstraint(BoneConstraintPanel, ConstraintButtonsPanel, Panel):
def draw(self, context):
self.draw_kinematic(context)
classes = (
# Object Panels
OBJECT_PT_constraints,
BONE_PT_constraints,
OBJECT_PT_bChildOfConstraint,
OBJECT_PT_bTrackToConstraint,
OBJECT_PT_bKinematicConstraint,
OBJECT_PT_bFollowPathConstraint,
OBJECT_PT_bRotLimitConstraint,
OBJECT_PT_bLocLimitConstraint,
OBJECT_PT_bSizeLimitConstraint,
OBJECT_PT_bRotateLikeConstraint,
OBJECT_PT_bLocateLikeConstraint,
OBJECT_PT_bSizeLikeConstraint,
OBJECT_PT_bSameVolumeConstraint,
OBJECT_PT_bTransLikeConstraint,
OBJECT_PT_bActionConstraint,
OBJECT_PT_bActionConstraint_target,
OBJECT_PT_bActionConstraint_action,
OBJECT_PT_bLockTrackConstraint,
OBJECT_PT_bDistLimitConstraint,
OBJECT_PT_bStretchToConstraint,
OBJECT_PT_bMinMaxConstraint,
OBJECT_PT_bClampToConstraint,
OBJECT_PT_bTransformConstraint,
OBJECT_PT_bTransformConstraint_source,
OBJECT_PT_bTransformConstraint_destination,
OBJECT_PT_bShrinkwrapConstraint,
OBJECT_PT_bDampTrackConstraint,
OBJECT_PT_bPivotConstraint,
OBJECT_PT_bFollowTrackConstraint,
OBJECT_PT_bCameraSolverConstraint,
OBJECT_PT_bObjectSolverConstraint,
OBJECT_PT_bTransformCacheConstraint,
OBJECT_PT_bTransformCacheConstraint_time,
OBJECT_PT_bTransformCacheConstraint_procedural,
OBJECT_PT_bTransformCacheConstraint_velocity,
OBJECT_PT_bTransformCacheConstraint_layers,
OBJECT_PT_bPythonConstraint,
OBJECT_PT_bArmatureConstraint,
OBJECT_PT_bArmatureConstraint_bones,
# Bone panels
BONE_PT_bChildOfConstraint,
BONE_PT_bTrackToConstraint,
BONE_PT_bKinematicConstraint,
BONE_PT_bFollowPathConstraint,
BONE_PT_bRotLimitConstraint,
BONE_PT_bLocLimitConstraint,
BONE_PT_bSizeLimitConstraint,
BONE_PT_bRotateLikeConstraint,
BONE_PT_bLocateLikeConstraint,
BONE_PT_bSizeLikeConstraint,
BONE_PT_bSameVolumeConstraint,
BONE_PT_bTransLikeConstraint,
BONE_PT_bActionConstraint,
BONE_PT_bActionConstraint_target,
BONE_PT_bActionConstraint_action,
BONE_PT_bLockTrackConstraint,
BONE_PT_bDistLimitConstraint,
BONE_PT_bStretchToConstraint,
BONE_PT_bMinMaxConstraint,
BONE_PT_bClampToConstraint,
BONE_PT_bTransformConstraint,
BONE_PT_bTransformConstraint_from,
BONE_PT_bTransformConstraint_to,
BONE_PT_bShrinkwrapConstraint,
BONE_PT_bDampTrackConstraint,
BONE_PT_bSplineIKConstraint,
BONE_PT_bSplineIKConstraint_fitting,
BONE_PT_bSplineIKConstraint_chain_scaling,
BONE_PT_bPivotConstraint,
BONE_PT_bFollowTrackConstraint,
BONE_PT_bCameraSolverConstraint,
BONE_PT_bObjectSolverConstraint,
BONE_PT_bTransformCacheConstraint,
BONE_PT_bTransformCacheConstraint_time,
BONE_PT_bTransformCacheConstraint_procedural,
BONE_PT_bTransformCacheConstraint_velocity,
BONE_PT_bTransformCacheConstraint_layers,
BONE_PT_bPythonConstraint,
BONE_PT_bArmatureConstraint,
BONE_PT_bArmatureConstraint_bones,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)