4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): Joshua Leung, Blender Foundation
27 * ***** END GPL LICENSE BLOCK *****
33 #include "MEM_guardedalloc.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37 #include "BLI_dynstr.h"
39 #include "DNA_action_types.h"
40 #include "DNA_armature_types.h"
41 #include "DNA_constraint_types.h"
42 #include "DNA_curve_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_text_types.h"
47 #include "DNA_view3d_types.h"
49 #include "BKE_action.h"
50 #include "BKE_armature.h"
51 #include "BKE_constraint.h"
52 #include "BKE_context.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_global.h"
56 #include "BKE_object.h"
57 #include "BKE_report.h"
58 #include "BKE_utildefines.h"
60 #ifndef DISABLE_PYTHON
61 #include "BPY_extern.h"
67 #include "RNA_access.h"
68 #include "RNA_define.h"
69 #include "RNA_enum_types.h"
70 #include "RNA_types.h"
72 #include "ED_object.h"
73 #include "ED_screen.h"
75 #include "UI_interface.h"
77 #include "object_intern.h"
80 static int pupmenu() {return 0;}
82 /* -------------- Get Active Constraint Data ---------------------- */
84 /* if object in posemode, active bone constraints, else object constraints */
85 ListBase *get_active_constraints (Object *ob)
90 if (ob->flag & OB_POSEMODE) {
93 pchan = get_active_posechannel(ob);
95 return &pchan->constraints;
98 return &ob->constraints;
103 /* single constraint */
104 bConstraint *get_active_constraint (Object *ob)
106 ListBase *lb= get_active_constraints(ob);
111 for (con= lb->first; con; con=con->next) {
112 if (con->flag & CONSTRAINT_ACTIVE)
119 /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
120 /* ------------- PyConstraints ------------------ */
122 /* this callback sets the text-file to be used for selected menu item */
123 void validate_pyconstraint_cb (void *arg1, void *arg2)
125 bPythonConstraint *data = arg1;
127 int index = *((int *)arg2);
130 /* exception for no script */
132 /* innovative use of a for...loop to search */
133 for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
138 #ifndef DISABLE_PYTHON
139 /* this returns a string for the list of usable pyconstraint script names */
140 char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
142 DynStr *pupds= BLI_dynstr_new();
148 /* add title first */
149 sprintf(buf, "Scripts: %%t|[None]%%x0|");
150 BLI_dynstr_append(pupds, buf);
152 /* init active-index first */
153 if (con_text == NULL)
156 /* loop through markers, adding them */
157 for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
158 /* this is important to ensure that right script is shown as active */
159 if (text == con_text) *pyconindex = i;
161 /* only include valid pyconstraint scripts */
162 if (BPY_is_pyconstraint(text)) {
163 BLI_dynstr_append(pupds, text->id.name+2);
165 sprintf(buf, "%%x%d", i);
166 BLI_dynstr_append(pupds, buf);
169 BLI_dynstr_append(pupds, "|");
173 /* convert to normal MEM_malloc'd string */
174 str= BLI_dynstr_get_cstring(pupds);
175 BLI_dynstr_free(pupds);
179 #endif /* DISABLE_PYTHON */
181 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
182 void update_pyconstraint_cb (void *arg1, void *arg2)
184 Object *owner= (Object *)arg1;
185 bConstraint *con= (bConstraint *)arg2;
186 #ifndef DISABLE_PYTHON
188 BPY_pyconstraint_update(owner, con);
192 /* Creates a new constraint, initialises its data, and returns it */
193 bConstraint *add_new_constraint (short type)
196 bConstraintTypeInfo *cti;
198 con = MEM_callocN(sizeof(bConstraint), "Constraint");
200 /* Set up a generic constraint datablock */
202 con->flag |= CONSTRAINT_EXPAND;
204 strcpy(con->name, "Const");
206 /* Load the data for it */
207 cti = constraint_get_typeinfo(con);
209 con->data = MEM_callocN(cti->size, cti->structName);
211 /* only constraints that change any settings need this */
213 cti->new_data(con->data);
219 /* Adds the given constraint to the Object-level set of constraints for the given Object */
220 void add_constraint_to_object (bConstraint *con, Object *ob)
223 list = &ob->constraints;
226 unique_constraint_name(con, list);
227 BLI_addtail(list, con);
229 if (proxylocked_constraints_owner(ob, NULL))
230 con->flag |= CONSTRAINT_PROXY_LOCAL;
232 con->flag |= CONSTRAINT_ACTIVE;
233 for (con= con->prev; con; con= con->prev)
234 con->flag &= ~CONSTRAINT_ACTIVE;
238 /* helper function for add_constriant - sets the last target for the active constraint */
239 static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
241 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
242 ListBase targets = {NULL, NULL};
243 bConstraintTarget *ct;
246 if (cti && cti->get_constraint_targets) {
247 cti->get_constraint_targets(con, &targets);
248 num_targets= BLI_countlist(&targets);
251 if (abs(index) < num_targets)
252 index= num_targets - abs(index);
254 index= num_targets - 1;
256 else if (index >= num_targets) {
257 index= num_targets - 1;
260 for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
263 strcpy(ct->subtarget, subtarget);
268 if (cti->flush_constraint_targets)
269 cti->flush_constraint_targets(con, &targets, 0);
273 /* ------------- Constraint Sanity Testing ------------------- */
275 /* checks validity of object pointers, and NULLs,
276 * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag
278 static void test_constraints (Object *owner, const char substring[])
281 ListBase *conlist= NULL;
284 if (owner==NULL) return;
287 if (strlen(substring)) {
288 switch (owner->type) {
290 type = CONSTRAINT_OBTYPE_BONE;
293 type = CONSTRAINT_OBTYPE_OBJECT;
298 type = CONSTRAINT_OBTYPE_OBJECT;
300 /* Get the constraint list for this object */
302 case CONSTRAINT_OBTYPE_OBJECT:
303 conlist = &owner->constraints;
305 case CONSTRAINT_OBTYPE_BONE:
310 bone = get_named_bone( ((bArmature *)owner->data), substring );
311 chan = get_pose_channel(owner->pose, substring);
313 conlist = &chan->constraints;
319 /* Check all constraints - is constraint valid? */
321 for (curcon = conlist->first; curcon; curcon=curcon->next) {
322 bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
323 ListBase targets = {NULL, NULL};
324 bConstraintTarget *ct;
326 /* clear disabled-flag first */
327 curcon->flag &= ~CONSTRAINT_DISABLE;
329 if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
330 bKinematicConstraint *data = curcon->data;
332 /* bad: we need a separate set of checks here as poletarget is
333 * optional... otherwise poletarget must exist too or else
334 * the constraint is deemed invalid
336 if (exist_object(data->tar) == 0) {
338 curcon->flag |= CONSTRAINT_DISABLE;
340 else if (data->tar == owner) {
341 if (!get_named_bone(get_armature(owner), data->subtarget)) {
342 curcon->flag |= CONSTRAINT_DISABLE;
347 if (exist_object(data->poletar) == 0) {
348 data->poletar = NULL;
349 curcon->flag |= CONSTRAINT_DISABLE;
351 else if (data->poletar == owner) {
352 if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
353 curcon->flag |= CONSTRAINT_DISABLE;
358 /* targets have already been checked for this */
361 else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
362 bActionConstraint *data = curcon->data;
364 /* validate action */
365 if (data->act == NULL)
366 curcon->flag |= CONSTRAINT_DISABLE;
368 else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
369 bFollowPathConstraint *data = curcon->data;
371 /* don't allow track/up axes to be the same */
372 if (data->upflag==data->trackflag)
373 curcon->flag |= CONSTRAINT_DISABLE;
374 if (data->upflag+3==data->trackflag)
375 curcon->flag |= CONSTRAINT_DISABLE;
377 else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
378 bTrackToConstraint *data = curcon->data;
380 /* don't allow track/up axes to be the same */
381 if (data->reserved2==data->reserved1)
382 curcon->flag |= CONSTRAINT_DISABLE;
383 if (data->reserved2+3==data->reserved1)
384 curcon->flag |= CONSTRAINT_DISABLE;
386 else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
387 bLockTrackConstraint *data = curcon->data;
389 if (data->lockflag==data->trackflag)
390 curcon->flag |= CONSTRAINT_DISABLE;
391 if (data->lockflag+3==data->trackflag)
392 curcon->flag |= CONSTRAINT_DISABLE;
395 /* Check targets for constraints */
396 if (cti && cti->get_constraint_targets) {
397 cti->get_constraint_targets(curcon, &targets);
399 /* disable and clear constraints targets that are incorrect */
400 for (ct= targets.first; ct; ct= ct->next) {
401 /* general validity checks (for those constraints that need this) */
402 if (exist_object(ct->tar) == 0) {
404 curcon->flag |= CONSTRAINT_DISABLE;
406 else if (ct->tar == owner) {
407 if (!get_named_bone(get_armature(owner), ct->subtarget)) {
408 curcon->flag |= CONSTRAINT_DISABLE;
412 /* target checks for specific constraints */
413 if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
415 if (ct->tar->type != OB_CURVE) {
417 curcon->flag |= CONSTRAINT_DISABLE;
420 Curve *cu= ct->tar->data;
422 /* auto-set 'Path' setting on curve so this works */
429 /* free any temporary targets */
430 if (cti->flush_constraint_targets)
431 cti->flush_constraint_targets(curcon, &targets, 0);
437 static void test_bonelist_constraints (Object *owner, ListBase *list)
441 for (bone = list->first; bone; bone = bone->next) {
442 test_constraints(owner, bone->name);
443 test_bonelist_constraints(owner, &bone->childbase);
447 void object_test_constraints (Object *owner)
449 test_constraints(owner, "");
451 if (owner->type==OB_ARMATURE) {
452 bArmature *arm= get_armature(owner);
455 test_bonelist_constraints(owner, &arm->bonebase);
459 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
461 /* ------------- Child-Of Constraint ------------------ */
463 /* ChildOf Constraint - set inverse callback */
464 static int childof_set_inverse_exec (bContext *C, wmOperator *op)
466 PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
467 Scene *scene= CTX_data_scene(C);
468 Object *ob= ptr.id.data;
469 bConstraint *con= ptr.data;
470 bChildOfConstraint *data= (bChildOfConstraint *)con->data;
471 bPoseChannel *pchan= NULL;
473 /* try to find a pose channel */
474 // TODO: get from context instead?
476 pchan= get_active_posechannel(ob);
478 /* calculate/set inverse matrix */
480 float pmat[4][4], cinf;
481 float imat[4][4], tmat[4][4];
483 /* make copy of pchan's original pose-mat (for use later) */
484 Mat4CpyMat4(pmat, pchan->pose_mat);
486 /* disable constraint for pose to be solved without it */
490 /* solve pose without constraint */
491 where_is_pose(scene, ob);
493 /* determine effect of constraint by removing the newly calculated
494 * pchan->pose_mat from the original pchan->pose_mat, thus determining
495 * the effect of the constraint
497 Mat4Invert(imat, pchan->pose_mat);
498 Mat4MulMat4(tmat, imat, pmat);
499 Mat4Invert(data->invmat, tmat);
501 /* recalculate pose with new inv-mat */
503 where_is_pose(scene, ob);
507 /* use what_does_parent to find inverse - just like for normal parenting.
508 * NOTE: what_does_parent uses a static workob defined in object.c
510 what_does_parent(scene, ob, &workob);
511 Mat4Invert(data->invmat, workob.obmat);
514 Mat4One(data->invmat);
516 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
518 return OPERATOR_FINISHED;
521 void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot)
524 ot->name= "Set Inverse";
525 ot->idname= "CONSTRAINT_OT_childof_set_inverse";
526 ot->description= "Set inverse correction for ChildOf constraint.";
528 ot->exec= childof_set_inverse_exec;
531 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
535 /* ChildOf Constraint - clear inverse callback */
536 static int childof_clear_inverse_exec (bContext *C, wmOperator *op)
538 PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
539 Object *ob= ptr.id.data;
540 bConstraint *con= ptr.data;
541 bChildOfConstraint *data= (bChildOfConstraint *)con->data;
543 /* simply clear the matrix */
544 Mat4One(data->invmat);
546 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
548 return OPERATOR_FINISHED;
551 void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot)
554 ot->name= "Clear Inverse";
555 ot->idname= "CONSTRAINT_OT_childof_clear_inverse";
556 ot->description= "Clear inverse correction for ChildOf constraint.";
558 ot->exec= childof_clear_inverse_exec;
561 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
564 /***************************** BUTTONS ****************************/
566 /* Rename the given constraint, con already has the new name */
567 void ED_object_constraint_rename(Object *ob, bConstraint *con, char *oldname)
570 ListBase *conlist= NULL;
573 /* get context by searching for con (primitive...) */
574 for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
580 conlist= &ob->constraints;
586 for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
587 for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
596 conlist= &pchan->constraints;
601 printf("rename constraint failed\n"); /* should not happen in UI */
605 /* first make sure it's a unique name within context */
606 unique_constraint_name(con, conlist);
612 void ED_object_constraint_set_active(Object *ob, bConstraint *con)
615 bConstraint *origcon= con;
617 /* lets be nice and escape if its active already */
618 if(con && (con->flag & CONSTRAINT_ACTIVE))
621 lb= get_active_constraints(ob);
625 for(con= lb->first; con; con= con->next) {
626 if(con==origcon) con->flag |= CONSTRAINT_ACTIVE;
627 else con->flag &= ~CONSTRAINT_ACTIVE;
631 static int constraint_delete_exec (bContext *C, wmOperator *op)
633 PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
634 Object *ob= ptr.id.data;
635 bConstraint *con= ptr.data;
638 /* remove constraint itself */
639 lb= get_active_constraints(ob);
640 free_constraint_data(con);
641 BLI_freelinkN(lb, con);
643 ED_object_constraint_set_active(ob, NULL);
644 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
646 return OPERATOR_FINISHED;
649 void CONSTRAINT_OT_delete (wmOperatorType *ot)
652 ot->name= "Delete Constraint";
653 ot->idname= "CONSTRAINT_OT_delete";
654 ot->description= "Remove constraitn from constraint stack.";
657 ot->exec= constraint_delete_exec;
660 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
663 static int constraint_move_down_exec (bContext *C, wmOperator *op)
665 PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
666 Object *ob= ptr.id.data;
667 bConstraint *con= ptr.data;
670 ListBase *conlist= get_active_constraints(ob);
671 bConstraint *nextCon= con->next;
673 /* insert the nominated constraint after the one that used to be after it */
674 BLI_remlink(conlist, con);
675 BLI_insertlinkafter(conlist, nextCon, con);
677 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
679 return OPERATOR_FINISHED;
682 return OPERATOR_CANCELLED;
685 void CONSTRAINT_OT_move_down (wmOperatorType *ot)
688 ot->name= "Move Constraint Down";
689 ot->idname= "CONSTRAINT_OT_move_down";
690 ot->description= "Move constraint down constraint stack.";
693 ot->exec= constraint_move_down_exec;
696 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
700 static int constraint_move_up_exec (bContext *C, wmOperator *op)
702 PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
703 Object *ob= ptr.id.data;
704 bConstraint *con= ptr.data;
707 ListBase *conlist= get_active_constraints(ob);
708 bConstraint *prevCon= con->prev;
710 /* insert the nominated constraint before the one that used to be before it */
711 BLI_remlink(conlist, con);
712 BLI_insertlinkbefore(conlist, prevCon, con);
714 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
716 return OPERATOR_FINISHED;
719 return OPERATOR_CANCELLED;
722 void CONSTRAINT_OT_move_up (wmOperatorType *ot)
725 ot->name= "Move Constraint Up";
726 ot->idname= "CONSTRAINT_OT_move_up";
727 ot->description= "Move constraint up constraint stack.";
730 ot->exec= constraint_move_up_exec;
733 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
736 /***************************** OPERATORS ****************************/
738 /************************ remove constraint operators *********************/
740 static int pose_constraints_clear_exec(bContext *C, wmOperator *op)
742 Scene *scene= CTX_data_scene(C);
743 Object *ob= CTX_data_active_object(C);
745 /* free constraints for all selected bones */
746 CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
748 free_constraints(&pchan->constraints);
753 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
754 WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob);
756 return OPERATOR_FINISHED;
759 void POSE_OT_constraints_clear(wmOperatorType *ot)
762 ot->name = "Clear Constraints";
763 ot->idname= "POSE_OT_constraints_clear";
764 ot->description= "Clear all the constraints for the selected bones.";
767 ot->exec= pose_constraints_clear_exec;
768 ot->poll= ED_operator_posemode; // XXX - do we want to ensure there are selected bones too?
772 static int object_constraints_clear_exec(bContext *C, wmOperator *op)
774 Scene *scene= CTX_data_scene(C);
775 Object *ob= CTX_data_active_object(C);
778 // TODO: we should free constraints for all selected objects instead (to be more consistent with bones)
779 free_constraints(&ob->constraints);
782 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
783 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
785 return OPERATOR_FINISHED;
788 void OBJECT_OT_constraints_clear(wmOperatorType *ot)
791 ot->name = "Clear Constraints";
792 ot->idname= "OBJECT_OT_constraints_clear";
793 ot->description= "Clear all the constraints for the active Object only.";
796 ot->exec= object_constraints_clear_exec;
797 ot->poll= ED_operator_object_active;
800 /************************ add constraint operators *********************/
802 /* get the Object and/or PoseChannel to use as target */
803 static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add)
805 Object *obact= CTX_data_active_object(C);
806 short only_curve= 0, only_mesh= 0, only_ob= 0;
809 /* clear tar_ob and tar_pchan fields before use
810 * - assume for now that both always exist...
815 /* check if constraint type doesn't requires a target
816 * - if so, no need to get any targets
819 /* no-target constraints --------------------------- */
820 /* null constraint - shouldn't even be added! */
821 case CONSTRAINT_TYPE_NULL:
822 /* limit constraints - no targets needed */
823 case CONSTRAINT_TYPE_LOCLIMIT:
824 case CONSTRAINT_TYPE_ROTLIMIT:
825 case CONSTRAINT_TYPE_SIZELIMIT:
828 /* restricted target-type constraints -------------- */
829 /* curve-based constraints - set the only_curve and only_ob flags */
830 case CONSTRAINT_TYPE_TRACKTO:
831 case CONSTRAINT_TYPE_CLAMPTO:
832 case CONSTRAINT_TYPE_FOLLOWPATH:
838 case CONSTRAINT_TYPE_SHRINKWRAP:
844 case CONSTRAINT_TYPE_RIGIDBODYJOINT:
849 /* if the active Object is Armature, and we can search for bones, do so... */
850 if ((obact->type == OB_ARMATURE) && (only_ob == 0)) {
851 /* search in list of selected Pose-Channels for target */
852 CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
854 /* just use the first one that we encounter... */
864 /* if not yet found, try selected Objects... */
866 /* search in selected objects context */
867 CTX_DATA_BEGIN(C, Object*, ob, selected_objects)
869 /* just use the first object we encounter (that isn't the active object)
870 * and which fulfills the criteria for the object-target that we've got
872 if ( (ob != obact) &&
873 ((!only_curve) || (ob->type == OB_CURVE)) &&
874 ((!only_mesh) || (ob->type == OB_MESH)) )
880 /* perform some special operations on the target */
882 /* Curve-Path option must be enabled for follow-path constraints to be able to work */
883 Curve *cu= (Curve *)ob->data;
893 /* if still not found, add a new empty to act as a target (if allowed) */
894 if ((found == 0) && (add)) {
895 #if 0 // XXX old code to be fixed
896 Base *base= BASACT, *newbase;
899 obt= add_object(scene, OB_EMPTY);
902 newbase->lay= base->lay;
903 obt->lay= newbase->lay;
905 /* transform cent to global coords for loc */
908 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
910 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
913 VECCOPY(obt->loc, ob->obmat[3]);
915 //set_constraint_nth_target(con, obt, "", 0);
917 /* restore, add_object sets active */
919 base->flag |= SELECT;
920 #endif // XXX old code to be ported
923 /* return whether there's any target */
927 /* used by add constraint operators to add the constraint required */
928 static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget)
930 Scene *scene= CTX_data_scene(C);
931 bPoseChannel *pchan= get_active_posechannel(ob);
934 /* check if constraint to be added is valid for the given constraints stack */
935 if (type == CONSTRAINT_TYPE_NULL) {
936 return OPERATOR_CANCELLED;
938 if ( (type == CONSTRAINT_TYPE_RIGIDBODYJOINT) && (list != &ob->constraints) ) {
939 BKE_report(op->reports, RPT_ERROR, "Rigid Body Joint Constraint can only be added to Objects.");
940 return OPERATOR_CANCELLED;
942 if ( (type == CONSTRAINT_TYPE_KINEMATIC) && ((!pchan) || (list != &pchan->constraints)) ) {
943 BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones.");
944 return OPERATOR_CANCELLED;
947 /* create a new constraint of the type requried, and add it to the active/given constraints list */
948 con = add_new_constraint(type);
951 bConstraint *coniter;
953 /* add new constraint to end of list of constraints before ensuring that it has a unique name
954 * (otherwise unique-naming code will fail, since it assumes element exists in list)
956 BLI_addtail(list, con);
957 unique_constraint_name(con, list);
959 /* if the target list is a list on some PoseChannel belonging to a proxy-protected
960 * Armature layer, we must tag newly added constraints with a flag which allows them
961 * to persist after proxy syncing has been done
963 if (proxylocked_constraints_owner(ob, pchan))
964 con->flag |= CONSTRAINT_PROXY_LOCAL;
966 /* make this constraint the active one
967 * - since constraint was added at end of stack, we can just go
968 * through deactivating all previous ones
970 con->flag |= CONSTRAINT_ACTIVE;
971 for (coniter= con->prev; coniter; coniter= coniter->prev)
972 coniter->flag &= ~CONSTRAINT_ACTIVE;
975 /* get the first selected object/bone, and make that the target
976 * - apart from the buttons-window add buttons, we shouldn't add in this way
979 Object *tar_ob= NULL;
980 bPoseChannel *tar_pchan= NULL;
982 /* get the target objects, adding them as need be */
983 if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) {
984 /* method of setting target depends on the type of target we've got
985 * - by default, just set the first target (distinction here is only for multiple-targetted constraints)
988 set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0);
990 set_constraint_nth_target(con, tar_ob, "", 0);
994 /* do type-specific tweaking to the constraint settings */
996 case CONSTRAINT_TYPE_CHILDOF:
998 /* if this constraint is being added to a posechannel, make sure
999 * the constraint gets evaluated in pose-space */
1000 if (ob->flag & OB_POSEMODE) {
1001 con->ownspace = CONSTRAINT_SPACE_POSE;
1002 con->flag |= CONSTRAINT_SPACEONCE;
1007 case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore
1011 #ifndef DISABLE_PYTHON
1012 /* popup a list of usable scripts */
1013 menustr = buildmenu_pyconstraints(NULL, &scriptint);
1014 scriptint = pupmenu(menustr);
1017 /* only add constraint if a script was chosen */
1019 /* add constraint */
1020 validate_pyconstraint_cb(con->data, &scriptint);
1022 /* make sure target allowance is set correctly */
1023 BPY_pyconstraint_update(ob, con);
1031 /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */
1032 object_test_constraints(ob);
1035 update_pose_constraint_flags(ob->pose);
1038 /* force depsgraph to get recalculated since new relationships added */
1039 DAG_scene_sort(scene); /* sort order of objects */
1041 if ((ob->type==OB_ARMATURE) && (pchan)) {
1042 ob->pose->flag |= POSE_RECALC; /* sort pose channels */
1043 DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
1046 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1048 /* notifiers for updates */
1049 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob);
1051 return OPERATOR_FINISHED;
1054 /* ------------------ */
1056 /* dummy operator callback */
1057 static int object_constraint_add_exec(bContext *C, wmOperator *op)
1059 ScrArea *sa= CTX_wm_area(C);
1061 int type= RNA_enum_get(op->ptr, "type");
1062 short with_targets= 0;
1064 /* get active object from context */
1065 if (sa->spacetype == SPACE_BUTS)
1066 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1068 ob= CTX_data_active_object(C);
1071 BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to.");
1072 return OPERATOR_CANCELLED;
1075 /* hack: set constraint targets from selected objects in context is allowed when
1076 * operator name included 'with_targets', since the menu doesn't allow multiple properties
1078 if (strstr(op->idname, "with_targets"))
1081 return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets);
1084 /* dummy operator callback */
1085 static int pose_constraint_add_exec(bContext *C, wmOperator *op)
1087 ScrArea *sa= CTX_wm_area(C);
1089 int type= RNA_enum_get(op->ptr, "type");
1090 short with_targets= 0;
1092 /* get active object from context */
1093 if (sa->spacetype == SPACE_BUTS)
1094 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1096 ob= CTX_data_active_object(C);
1099 BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to.");
1100 return OPERATOR_CANCELLED;
1103 /* hack: set constraint targets from selected objects in context is allowed when
1104 * operator name included 'with_targets', since the menu doesn't allow multiple properties
1106 if (strstr(op->idname, "with_targets"))
1109 return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets);
1112 /* ------------------ */
1114 void OBJECT_OT_constraint_add(wmOperatorType *ot)
1117 ot->name= "Add Constraint";
1118 ot->description = "Add a constraint to the active object.";
1119 ot->idname= "OBJECT_OT_constraint_add";
1122 ot->invoke= WM_menu_invoke;
1123 ot->exec= object_constraint_add_exec;
1124 ot->poll= ED_operator_object_active;
1127 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1130 RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1133 void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
1136 ot->name= "Add Constraint (with Targets)";
1137 ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones.";
1138 ot->idname= "OBJECT_OT_constraint_add_with_targets";
1141 ot->invoke= WM_menu_invoke;
1142 ot->exec= object_constraint_add_exec;
1143 ot->poll= ED_operator_object_active;
1146 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1149 RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1152 void POSE_OT_constraint_add(wmOperatorType *ot)
1155 ot->name= "Add Constraint";
1156 ot->description = "Add a constraint to the active bone.";
1157 ot->idname= "POSE_OT_constraint_add";
1160 ot->invoke= WM_menu_invoke;
1161 ot->exec= pose_constraint_add_exec;
1162 ot->poll= ED_operator_posemode;
1165 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1168 RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1171 void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
1174 ot->name= "Add Constraint (with Targets)";
1175 ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones.";
1176 ot->idname= "POSE_OT_constraint_add_with_targets";
1179 ot->invoke= WM_menu_invoke;
1180 ot->exec= pose_constraint_add_exec;
1181 ot->poll= ED_operator_posemode;
1184 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1187 RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");