Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2005-10-23 16:18:32 +0400
committerTon Roosendaal <ton@blender.org>2005-10-23 16:18:32 +0400
commitd4f47002b835fb299fab05425456d34a8d24807e (patch)
tree37ab1325510105bb9b590bed8d982e1e67ec5d47 /source
parent84f66424379734dfd40c1f2cd69ff2f6e8652333 (diff)
New: Hotkey/menu access in 3D window to add constraints. Works in PoseMode
as well as for Objects. Hotkey: CTRL+ALT+C (bit clumsy I know, but I like to use the Ckey). Constraints are added to the active Object or Bone. Based on selection context, the menu has three versions: Pose Mode: - if another bone is selected, bone becomes target - else if another Object is selected, Object becomes target - else it adds a new Empty as target Object Mode - if another Object is selected: Object becomes target - else it adds a new Empty as target Same works this way now for CTRL+I, "Add IK". To be solved: ALT+C in PoseMode is "Clear Constraints", but in Object Mode it does "Convert" still...
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BIF_editconstraint.h2
-rw-r--r--source/blender/src/editconstraint.c196
-rw-r--r--source/blender/src/poseobject.c97
-rw-r--r--source/blender/src/space.c3
4 files changed, 197 insertions, 101 deletions
diff --git a/source/blender/include/BIF_editconstraint.h b/source/blender/include/BIF_editconstraint.h
index 4d14919ddaa..2ab72a304c2 100644
--- a/source/blender/include/BIF_editconstraint.h
+++ b/source/blender/include/BIF_editconstraint.h
@@ -50,6 +50,8 @@ struct bConstraintChannel *get_active_constraint_channel(struct Object *ob);
void object_test_constraints(struct Object *owner);
+void add_constraint(int only_IK);
+
char *get_con_subtarget_name(struct bConstraint *con, struct Object *target);
#endif
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index bac3099a718..95d037850c3 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -36,22 +36,25 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
+#include "DNA_view3d_types.h"
-#include "BKE_utildefines.h"
#include "BKE_action.h"
#include "BKE_armature.h"
-#include "BKE_object.h"
-#include "BKE_global.h"
#include "BKE_constraint.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
#include "BKE_ipo.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
#include "BIF_editaction.h"
#include "BIF_editarmature.h"
@@ -59,10 +62,12 @@
#include "BIF_poseobject.h"
#include "BIF_interface.h"
#include "BIF_screen.h"
+#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "blendef.h"
#include "nla.h"
+#include "mydevice.h"
ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
@@ -571,4 +576,185 @@ void object_test_constraints (Object *owner)
}
+/* context: active object in posemode, active channel, optional selected channel */
+void add_constraint(int only_IK)
+{
+ Object *ob= OBACT, *obsel=NULL;
+ bPoseChannel *pchanact=NULL, *pchansel=NULL;
+ bConstraint *con=NULL;
+ Base *base;
+ short nr;
+
+ /* paranoia checks */
+ if(ob==NULL || ob==G.obedit) return;
+
+ if(ob->pose && (ob->flag & OB_POSEMODE)) {
+
+ /* find active channel */
+ for(pchanact= ob->pose->chanbase.first; pchanact; pchanact= pchanact->next)
+ if(pchanact->bone->flag & BONE_ACTIVE) break;
+ if(pchanact==NULL) return;
+
+ /* find selected bone */
+ for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
+ if(pchansel!=pchanact)
+ if(pchansel->bone->flag & BONE_SELECTED) break;
+ }
+ }
+
+ /* find selected object */
+ for(base= FIRSTBASE; base; base= base->next)
+ if( TESTBASE(base) && base->object!=ob )
+ obsel= base->object;
+
+ /* the only_IK caller has checked for posemode! */
+ if(only_IK) {
+ for(con= pchanact->constraints.first; con; con= con->next) {
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
+ }
+ if(con) {
+ error("Pose Channel already has IK");
+ return;
+ }
+
+ if(pchansel)
+ nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10");
+ else if(obsel)
+ nr= pupmenu("Add IK Constraint%t|To Selected Object%x10");
+ else
+ nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10");
+ }
+ else {
+ if(pchanact) {
+ if(pchansel)
+ nr= pupmenu("Add Constraint to selected Bone%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+ else if(obsel && obsel->type==OB_CURVE)
+ nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
+ else if(obsel)
+ nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+ else
+ nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+ }
+ else {
+ if(obsel && obsel->type==OB_CURVE)
+ nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
+ else if(obsel)
+ nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
+ else
+ nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
+ }
+ }
+
+ if(nr<1) return;
+
+ /* handle IK separate */
+ if(nr==10) {
+
+ /* prevent weird chains... */
+ if(pchansel) {
+ bPoseChannel *pchan= pchanact;
+ while(pchan) {
+ if(pchan==pchansel) break;
+ pchan= pchan->parent;
+ }
+ if(pchan) {
+ error("IK root cannot be linked to IK tip");
+ return;
+ }
+ pchan= pchansel;
+ while(pchan) {
+ if(pchan==pchanact) break;
+ pchan= pchan->parent;
+ }
+ if(pchan) {
+ error("IK tip cannot be linked to IK root");
+ return;
+ }
+ }
+
+ con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
+ BLI_addtail(&pchanact->constraints, con);
+ pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
+ }
+ else {
+
+ if(nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
+ else if(nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
+ else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
+ else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
+ else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
+ else if(nr==6) con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
+ else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
+
+ if(con==NULL) return; /* paranoia */
+
+ if(pchanact) {
+ BLI_addtail(&pchanact->constraints, con);
+ pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
+ }
+ else {
+ BLI_addtail(&ob->constraints, con);
+ }
+ }
+
+ /* set the target */
+ if(pchansel) {
+ set_constraint_target(con, ob, pchansel->name);
+ }
+ else if(obsel) {
+ set_constraint_target(con, obsel, NULL);
+ }
+ else { /* add new empty as target */
+ Base *base= BASACT, *newbase;
+ Object *obt;
+
+ obt= add_object(OB_EMPTY);
+ /* set layers OK */
+ newbase= BASACT;
+ newbase->lay= base->lay;
+ obt->lay= newbase->lay;
+
+ /* transform cent to global coords for loc */
+ if(pchanact) {
+ if(only_IK)
+ VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
+ else
+ VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
+ }
+ else
+ VECCOPY(obt->loc, ob->obmat[3]);
+
+ set_constraint_target(con, obt, NULL);
+
+ /* restore, add_object sets active */
+ BASACT= base;
+ base->flag |= SELECT;
+ }
+
+
+ /* active flag */
+ con->flag |= CONSTRAINT_ACTIVE;
+ for(con= con->prev; con; con= con->prev)
+ con->flag &= ~CONSTRAINT_ACTIVE;
+
+ DAG_scene_sort(G.scene); // sort order of objects
+
+ if(pchanact) {
+ ob->pose->flag |= POSE_RECALC; // sort pose channels
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
+ }
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); // and all its relations
+
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWBUTSOBJECT, 0);
+ allqueue (REDRAWOOPS, 0);
+
+ if(only_IK)
+ BIF_undo_push("Add IK Constraint");
+ else
+ BIF_undo_push("Add Constraint");
+
+}
+
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index bc3012f343c..501c95bbd3d 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -320,110 +320,15 @@ void pose_special_editmenu(void)
}
}
-/* context: active object, active channel, optional selected channel */
void pose_add_IK(void)
{
Object *ob= OBACT;
- bPoseChannel *pchanact, *pchansel;
- bConstraint *con;
- short nr;
/* paranoia checks */
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
- /* find active */
- for(pchanact= ob->pose->chanbase.first; pchanact; pchanact= pchanact->next)
- if(pchanact->bone->flag & BONE_ACTIVE) break;
- if(pchanact==NULL) return;
-
- /* find selected */
- for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
- if(pchansel!=pchanact)
- if(pchansel->bone->flag & BONE_SELECTED) break;
- }
-
- for(con= pchanact->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
- }
- if(con) {
- error("Pose Channel already has IK");
- return;
- }
-
- if(pchansel)
- nr= pupmenu("Add IK Constraint%t|To new Empty Object%x1|To selected Bone%x2");
- else
- nr= pupmenu("Add IK Constraint%t|To new Empty Object%x1");
-
- if(nr<1) return;
-
- /* prevent weird chains... */
- if(nr==2) {
- bPoseChannel *pchan= pchanact;
- while(pchan) {
- if(pchan==pchansel) break;
- pchan= pchan->parent;
- }
- if(pchan) {
- error("IK root cannot be linked to IK tip");
- return;
- }
- pchan= pchansel;
- while(pchan) {
- if(pchan==pchanact) break;
- pchan= pchan->parent;
- }
- if(pchan) {
- error("IK tip cannot be linked to IK root");
- return;
- }
- }
-
- con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
- BLI_addtail(&pchanact->constraints, con);
- pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
-
- /* add new empty as target */
- if(nr==1) {
- Base *base= BASACT, *newbase;
- Object *obt;
-
- obt= add_object(OB_EMPTY);
- /* set layers OK */
- newbase= BASACT;
- newbase->lay= base->lay;
- obt->lay= newbase->lay;
-
- /* transform cent to global coords for loc */
- VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
-
- set_constraint_target(con, obt, NULL);
-
- /* restore, add_object sets active */
- BASACT= base;
- base->flag |= SELECT;
- }
- else if(nr==2) {
- set_constraint_target(con, ob, pchansel->name);
- }
-
- /* active flag */
- con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
- con->flag &= ~CONSTRAINT_ACTIVE;
-
-
- ob->pose->flag |= POSE_RECALC; // sort pose channels
- DAG_scene_sort(G.scene); // sort order of objects
-
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
-
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
-
- BIF_undo_push("Add IK constraint");
+ add_constraint(1); /* 1 means only IK */
}
/* context: all selected channels */
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 84ddf2c6aa7..db2ae93cb0a 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -87,6 +87,7 @@
#include "BIF_drawtext.h"
#include "BIF_drawscript.h"
#include "BIF_editarmature.h"
+#include "BIF_editconstraint.h"
#include "BIF_editfont.h"
#include "BIF_editkey.h"
#include "BIF_editlattice.h"
@@ -1157,6 +1158,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else
convertmenu(); /* editobject.c */
}
+ else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
+ add_constraint(0); /* editconstraint.c, generic for objects and posemode */
else if((G.qual==LR_SHIFTKEY)) {
view3d_home(1);
curs= give_cursor();