forked from bartvdbraak/blender
Move Inverse Kinematics panel to Constraint context. Make iTaSC parameter panel more readable.
This commit is contained in:
parent
ba2f052a37
commit
14619ec98d
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user