Move Inverse Kinematics panel to Constraint context. Make iTaSC parameter panel more...
authorBenoit Bolsee <benoit.bolsee@online.be>
Fri, 2 Oct 2009 07:20:07 +0000 (07:20 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Fri, 2 Oct 2009 07:20:07 +0000 (07:20 +0000)
release/scripts/ui/buttons_data_bone.py
release/scripts/ui/buttons_object_constraint.py
source/blender/blenkernel/intern/action.c
source/blender/makesrna/intern/rna_pose.c

index 5971e4492cebf7ae08e30df179ebedae573eca99..12db3e7277ddaa3835bf3d606aa58366121ee631 100644 (file)
@@ -149,94 +149,6 @@ class BONE_PT_bone(BoneButtonsPanel):
                        col.itemL(text="Custom Shape:")
                        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):
        __label__ = "Deform"
        __default_closed__ = True
@@ -285,65 +197,9 @@ class BONE_PT_deform(BoneButtonsPanel):
                col.itemL(text="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_transform)
 bpy.types.register(BONE_PT_transform_locks)
 bpy.types.register(BONE_PT_bone)
 bpy.types.register(BONE_PT_deform)
-bpy.types.register(BONE_PT_inverse_kinematics)
-bpy.types.register(BONE_PT_iksolver_itasc)
index e089cff264fe86dc459223c5ef421712fc7e9deb..6be166e8af0158230c41b9bd57b2751af09bf4ba 100644 (file)
@@ -536,6 +536,145 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
                for con in ob.constraints:
                        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):
        __label__ = "Constraints"
        __context__ = "bone_constraint"
@@ -558,4 +697,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel):
                        self.draw_constraint(context, con)
 
 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)
index b8dc9fd049dab3eab830c436ae89c228789b672d..87868eff8124b7328b779fd0ee57faea88949514 100644 (file)
@@ -535,7 +535,7 @@ void init_pose_itasc(bItasc *itasc)
                itasc->numiter = 100;
                itasc->numstep = 4;
                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->maxvel = 50.f;
                itasc->solver = ITASC_SOLVER_SDLS;
index 03ced839ebe1580b5b0edfc6b623a87e27277d17..ecb2dba01979c0faa6a13e76a7d961afed185131 100644 (file)
@@ -801,6 +801,16 @@ static void rna_def_pose_channel(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;
        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_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
 
-       prop= RNA_def_property(srna, "simulation", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_SIMULATION);
-       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).");
+       prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+       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");
 
-       prop= RNA_def_property(srna, "initial_reiteration", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_INITIAL_REITERATION);
-       RNA_def_property_ui_text(prop, "Initial Reiteration", "Allow reiteration for initial frame.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
-
-       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.");
+       prop= RNA_def_property(srna, "reiteration", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+       RNA_def_property_enum_items(prop, prop_itasc_reiteration_items);
+       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");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update");
 
        prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);