Move Inverse Kinematics panel to Constraint context. Make iTaSC parameter panel more readable.

This commit is contained in:
Benoit Bolsee 2009-10-02 07:20:07 +00:00
parent ba2f052a37
commit 14619ec98d
4 changed files with 160 additions and 156 deletions

@ -149,94 +149,6 @@ class BONE_PT_bone(BoneButtonsPanel):
col.itemL(text="Custom Shape:") col.itemL(text="Custom Shape:")
col.itemR(pchan, "custom_shape", text="") col.itemR(pchan, "custom_shape", text="")
class BONE_PT_inverse_kinematics(BoneButtonsPanel):
__label__ = "Inverse Kinematics"
__default_closed__ = True
def poll(self, context):
ob = context.object
bone = context.bone
if ob and context.bone:
pchan = ob.pose.pose_channels[context.bone.name]
return pchan.has_ik
return False
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
pchan = ob.pose.pose_channels[context.bone.name]
row = layout.row()
row.itemR(ob.pose, "ik_solver")
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_x", text="X")
row = split.row()
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
row.active = pchan.ik_dof_x
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_x", text="Limit")
row.active = pchan.ik_dof_x
row = split.row(align=True)
row.itemR(pchan, "ik_min_x", text="")
row.itemR(pchan, "ik_max_x", text="")
row.active = pchan.ik_dof_x and pchan.ik_limit_x
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_y", text="Y")
row = split.row()
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
row.active = pchan.ik_dof_y
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_y", text="Limit")
row.active = pchan.ik_dof_y
row = split.row(align=True)
row.itemR(pchan, "ik_min_y", text="")
row.itemR(pchan, "ik_max_y", text="")
row.active = pchan.ik_dof_y and pchan.ik_limit_y
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_z", text="Z")
row = split.row()
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
row.active = pchan.ik_dof_z
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_z", text="Limit")
row.active = pchan.ik_dof_z
row = split.row(align=True)
row.itemR(pchan, "ik_min_z", text="")
row.itemR(pchan, "ik_max_z", text="")
row.active = pchan.ik_dof_z and pchan.ik_limit_z
split = layout.split()
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
split.itemL()
if ob.pose.ik_solver == "ITASC":
layout.itemL(text="Joint constraint:")
split = layout.split(percentage=0.3)
row = split.row()
row.itemR(pchan, "ik_rot_control", text="Rotation")
row = split.row()
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
row.active = pchan.ik_rot_control
# not supported yet
#split = layout.split(percentage=0.3)
#row = split.row()
#row.itemR(pchan, "ik_lin_control", text="Size")
#row = split.row()
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
#row.active = pchan.ik_lin_control
class BONE_PT_deform(BoneButtonsPanel): class BONE_PT_deform(BoneButtonsPanel):
__label__ = "Deform" __label__ = "Deform"
__default_closed__ = True __default_closed__ = True
@ -285,65 +197,9 @@ class BONE_PT_deform(BoneButtonsPanel):
col.itemL(text="Offset:") col.itemL(text="Offset:")
col.itemR(bone, "cyclic_offset") col.itemR(bone, "cyclic_offset")
class BONE_PT_iksolver_itasc(BoneButtonsPanel):
__idname__ = "BONE_PT_iksolver_itasc"
__label__ = "iTaSC parameters"
__default_closed__ = True
def poll(self, context):
ob = context.object
bone = context.bone
if ob and context.bone:
pchan = ob.pose.pose_channels[context.bone.name]
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
return False
def draw(self, context):
layout = self.layout
ob = context.object
itasc = ob.pose.ik_param
layout.row().itemR(itasc, "simulation")
if itasc.simulation:
split = layout.split()
row = split.row()
row.itemR(itasc, "reiteration")
row = split.row()
if itasc.reiteration:
itasc.initial_reiteration = True
row.itemR(itasc, "initial_reiteration")
row.active = not itasc.reiteration
flow = layout.column_flow()
flow.itemR(itasc, "precision")
flow.itemR(itasc, "num_iter")
flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
if itasc.simulation:
layout.itemR(itasc, "auto_step")
row = layout.row()
if itasc.auto_step:
row.itemR(itasc, "min_step")
row.itemR(itasc, "max_step")
else:
row.itemR(itasc, "num_step")
layout.itemR(itasc, "solver")
if itasc.simulation:
layout.itemR(itasc, "feedback")
layout.itemR(itasc, "max_velocity")
if itasc.solver == "DLS":
row = layout.row()
row.itemR(itasc, "dampmax")
row.itemR(itasc, "dampeps")
bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_context_bone)
bpy.types.register(BONE_PT_transform) bpy.types.register(BONE_PT_transform)
bpy.types.register(BONE_PT_transform_locks) bpy.types.register(BONE_PT_transform_locks)
bpy.types.register(BONE_PT_bone) bpy.types.register(BONE_PT_bone)
bpy.types.register(BONE_PT_deform) bpy.types.register(BONE_PT_deform)
bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_iksolver_itasc)

@ -536,6 +536,145 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
for con in ob.constraints: for con in ob.constraints:
self.draw_constraint(context, con) self.draw_constraint(context, con)
class BONE_PT_inverse_kinematics(ConstraintButtonsPanel):
__label__ = "Inverse Kinematics"
__default_closed__ = True
__context__ = "bone_constraint"
def poll(self, context):
ob = context.object
bone = context.bone
if ob and bone:
pchan = ob.pose.pose_channels[bone.name]
return pchan.has_ik
return False
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
pchan = ob.pose.pose_channels[bone.name]
row = layout.row()
row.itemR(ob.pose, "ik_solver")
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_x", text="X")
row = split.row()
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
row.active = pchan.ik_dof_x
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_x", text="Limit")
row.active = pchan.ik_dof_x
row = split.row(align=True)
row.itemR(pchan, "ik_min_x", text="")
row.itemR(pchan, "ik_max_x", text="")
row.active = pchan.ik_dof_x and pchan.ik_limit_x
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_y", text="Y")
row = split.row()
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
row.active = pchan.ik_dof_y
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_y", text="Limit")
row.active = pchan.ik_dof_y
row = split.row(align=True)
row.itemR(pchan, "ik_min_y", text="")
row.itemR(pchan, "ik_max_y", text="")
row.active = pchan.ik_dof_y and pchan.ik_limit_y
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_z", text="Z")
row = split.row()
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
row.active = pchan.ik_dof_z
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_z", text="Limit")
row.active = pchan.ik_dof_z
row = split.row(align=True)
row.itemR(pchan, "ik_min_z", text="")
row.itemR(pchan, "ik_max_z", text="")
row.active = pchan.ik_dof_z and pchan.ik_limit_z
split = layout.split()
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
split.itemL()
if ob.pose.ik_solver == "ITASC":
layout.itemL(text="Joint constraint:")
split = layout.split(percentage=0.3)
row = split.row()
row.itemR(pchan, "ik_rot_control", text="Rotation")
row = split.row()
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
row.active = pchan.ik_rot_control
# not supported yet
#split = layout.split(percentage=0.3)
#row = split.row()
#row.itemR(pchan, "ik_lin_control", text="Size")
#row = split.row()
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
#row.active = pchan.ik_lin_control
class BONE_PT_iksolver_itasc(ConstraintButtonsPanel):
__label__ = "iTaSC parameters"
__default_closed__ = True
__context__ = "bone_constraint"
def poll(self, context):
ob = context.object
bone = context.bone
if ob and bone:
pchan = ob.pose.pose_channels[bone.name]
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
return False
def draw(self, context):
layout = self.layout
ob = context.object
itasc = ob.pose.ik_param
layout.itemR(itasc, "mode", expand=True)
simulation = itasc.mode == "SIMULATION"
if simulation:
layout.itemL(text="Reiteration:")
layout.itemR(itasc, "reiteration", expand=True)
flow = layout.column_flow()
flow.itemR(itasc, "precision", text="Prec")
flow.itemR(itasc, "num_iter", text="Iter")
flow.active = not simulation or itasc.reiteration != "NEVER"
if simulation:
layout.itemR(itasc, "auto_step")
row = layout.row()
if itasc.auto_step:
row.itemR(itasc, "min_step", text="Min")
row.itemR(itasc, "max_step", text="Max")
else:
row.itemR(itasc, "num_step")
layout.itemR(itasc, "solver")
if simulation:
layout.itemR(itasc, "feedback")
layout.itemR(itasc, "max_velocity")
if itasc.solver == "DLS":
row = layout.row()
row.itemR(itasc, "dampmax", text="Damp", slider=True)
row.itemR(itasc, "dampeps", text="Eps", slider=True)
class BONE_PT_constraints(ConstraintButtonsPanel): class BONE_PT_constraints(ConstraintButtonsPanel):
__label__ = "Constraints" __label__ = "Constraints"
__context__ = "bone_constraint" __context__ = "bone_constraint"
@ -558,4 +697,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel):
self.draw_constraint(context, con) self.draw_constraint(context, con)
bpy.types.register(OBJECT_PT_constraints) bpy.types.register(OBJECT_PT_constraints)
bpy.types.register(BONE_PT_iksolver_itasc)
bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_constraints) bpy.types.register(BONE_PT_constraints)

@ -535,7 +535,7 @@ void init_pose_itasc(bItasc *itasc)
itasc->numiter = 100; itasc->numiter = 100;
itasc->numstep = 4; itasc->numstep = 4;
itasc->precision = 0.005f; itasc->precision = 0.005f;
itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION|ITASC_SIMULATION; itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION;
itasc->feedback = 20.f; itasc->feedback = 20.f;
itasc->maxvel = 50.f; itasc->maxvel = 50.f;
itasc->solver = ITASC_SOLVER_SDLS; itasc->solver = ITASC_SOLVER_SDLS;

@ -801,6 +801,16 @@ static void rna_def_pose_channel(BlenderRNA *brna)
static void rna_def_pose_itasc(BlenderRNA *brna) static void rna_def_pose_itasc(BlenderRNA *brna)
{ {
static const EnumPropertyItem prop_itasc_mode_items[]= {
{0, "ANIMATION", 0, "Animation", "Stateless solver computing pose starting from current action and non-IK constraints."},
{ITASC_SIMULATION, "SIMULATION", 0, "Simulation", "Statefull solver running in real-time context and ignoring actions and non-IK constraints."},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem prop_itasc_reiteration_items[]= {
{0, "NEVER", 0, "Never", "The solver does not reiterate, not even on first frame (starts from rest pose)."},
{ITASC_INITIAL_REITERATION, "INITIAL", 0, "Initial", "The solver reiterates (converges) on the first frame but not on subsequent frame."},
{ITASC_INITIAL_REITERATION|ITASC_REITERATION, "ALWAYS", 0, "Always", "The solver reiterates (converges) on all frames."},
{0, NULL, 0, NULL, NULL}};
StructRNA *srna; StructRNA *srna;
PropertyRNA *prop; PropertyRNA *prop;
@ -826,19 +836,16 @@ static void rna_def_pose_itasc(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Num steps", "Divides the frame interval into this many steps."); RNA_def_property_ui_text(prop, "Num steps", "Divides the frame interval into this many steps.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
prop= RNA_def_property(srna, "simulation", PROP_BOOLEAN, PROP_NONE); prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_SIMULATION); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_ui_text(prop, "Simulation", "Simulation mode: solver is statefull, runs in real-time context and ignores actions and non-IK constraints (i.e. solver is in full charge of the IK chain)."); RNA_def_property_enum_items(prop, prop_itasc_mode_items);
RNA_def_property_ui_text(prop, "Mode", NULL);
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update_rebuild"); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update_rebuild");
prop= RNA_def_property(srna, "initial_reiteration", PROP_BOOLEAN, PROP_NONE); prop= RNA_def_property(srna, "reiteration", PROP_ENUM, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_INITIAL_REITERATION); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_ui_text(prop, "Initial Reiteration", "Allow reiteration for initial frame."); RNA_def_property_enum_items(prop, prop_itasc_reiteration_items);
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); RNA_def_property_ui_text(prop, "Reiteration", "Defines if the solver is allowed to reiterate (converges until precision is met) on none, first or all frames");
prop= RNA_def_property(srna, "reiteration", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_REITERATION);
RNA_def_property_ui_text(prop, "Reiteration", "Allow reiteration for all frames.");
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE); prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);