Blender V2.61 - r43446

object_constraint.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Joshua Leung, Blender Foundation
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <stdio.h>
00034 #include <string.h>
00035 
00036 #include "MEM_guardedalloc.h"
00037 
00038 #include "BLI_blenlib.h"
00039 #include "BLI_math.h"
00040 #include "BLI_dynstr.h"
00041 #include "BLI_utildefines.h"
00042 
00043 #include "DNA_constraint_types.h"
00044 #include "DNA_curve_types.h"
00045 #include "DNA_scene_types.h"
00046 #include "DNA_text_types.h"
00047 #include "DNA_object_types.h"
00048 
00049 #include "BKE_action.h"
00050 #include "BKE_armature.h"
00051 #include "BKE_constraint.h"
00052 #include "BKE_context.h"
00053 #include "BKE_depsgraph.h"
00054 #include "BKE_global.h"
00055 #include "BKE_main.h"
00056 #include "BKE_object.h"
00057 #include "BKE_report.h"
00058 #include "BKE_tracking.h"
00059 #include "BIK_api.h"
00060 
00061 #ifdef WITH_PYTHON
00062 #include "BPY_extern.h"
00063 #endif
00064 
00065 #include "WM_api.h"
00066 #include "WM_types.h"
00067 
00068 #include "RNA_access.h"
00069 #include "RNA_define.h"
00070 #include "RNA_enum_types.h"
00071 
00072 #include "ED_object.h"
00073 #include "ED_armature.h"
00074 #include "ED_screen.h"
00075 
00076 #include "UI_interface.h"
00077 #include "UI_resources.h"
00078 
00079 #include "object_intern.h"
00080 
00081 /* -------------- Get Active Constraint Data ---------------------- */
00082 
00083 /* if object in posemode, active bone constraints, else object constraints */
00084 ListBase *get_active_constraints (Object *ob)
00085 {
00086     if (ob == NULL)
00087         return NULL;
00088     
00089     if (ob->mode & OB_MODE_POSE) {
00090         bPoseChannel *pchan;
00091         
00092         pchan = get_active_posechannel(ob);
00093         if (pchan)
00094             return &pchan->constraints;
00095     }
00096     else 
00097         return &ob->constraints;
00098     
00099     return NULL;
00100 }
00101 
00102 /* Find the list that a given constraint belongs to, and/or also get the posechannel this is from (if applicable) */
00103 ListBase *get_constraint_lb (Object *ob, bConstraint *con, bPoseChannel **pchan_r)
00104 {
00105     if (pchan_r)
00106         *pchan_r= NULL;
00107     
00108     if (ELEM(NULL, ob, con))
00109         return NULL;
00110     
00111     /* try object constraints first */
00112     if ((BLI_findindex(&ob->constraints, con) != -1)) {
00113         return &ob->constraints;
00114     }
00115     
00116     /* if armature, try pose bones too */
00117     if (ob->pose) {
00118         bPoseChannel *pchan;
00119         
00120         /* try each bone in order 
00121          * NOTE: it's not possible to directly look up the active bone yet, so this will have to do
00122          */
00123         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
00124             if ((BLI_findindex(&pchan->constraints, con) != -1)) {
00125                 
00126                 if (pchan_r)
00127                     *pchan_r= pchan;
00128                 
00129                 return &pchan->constraints;
00130             }
00131         }
00132     }
00133     
00134     /* done */
00135     return NULL;
00136 }
00137 
00138 /* single constraint */
00139 bConstraint *get_active_constraint (Object *ob)
00140 {
00141     return constraints_get_active(get_active_constraints(ob));
00142 }
00143 
00144 /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
00145 /* ------------- PyConstraints ------------------ */
00146 
00147 /* this callback sets the text-file to be used for selected menu item */
00148 static void validate_pyconstraint_cb (void *arg1, void *arg2)
00149 {
00150     bPythonConstraint *data = arg1;
00151     Text *text= NULL;
00152     int index = *((int *)arg2);
00153     int i;
00154     
00155     /* exception for no script */
00156     if (index) {
00157         /* innovative use of a for...loop to search */
00158         for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
00159     }
00160     data->text = text;
00161 }
00162 
00163 #ifdef WITH_PYTHON
00164 /* this returns a string for the list of usable pyconstraint script names */
00165 static char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
00166 {
00167     DynStr *pupds= BLI_dynstr_new();
00168     Text *text;
00169     char *str;
00170     char buf[64];
00171     int i;
00172     
00173     /* add title first */
00174     sprintf(buf, "Scripts: %%t|[None]%%x0|");
00175     BLI_dynstr_append(pupds, buf);
00176     
00177     /* init active-index first */
00178     if (con_text == NULL)
00179         *pyconindex= 0;
00180     
00181     /* loop through markers, adding them */
00182     for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
00183         /* this is important to ensure that right script is shown as active */
00184         if (text == con_text) *pyconindex = i;
00185         
00186         /* only include valid pyconstraint scripts */
00187         if (BPY_is_pyconstraint(text)) {
00188             BLI_dynstr_append(pupds, text->id.name+2);
00189             
00190             sprintf(buf, "%%x%d", i);
00191             BLI_dynstr_append(pupds, buf);
00192             
00193             if (text->id.next)
00194                 BLI_dynstr_append(pupds, "|");
00195         }
00196     }
00197     
00198     /* convert to normal MEM_malloc'd string */
00199     str= BLI_dynstr_get_cstring(pupds);
00200     BLI_dynstr_free(pupds);
00201     
00202     return str;
00203 }
00204 #endif /* WITH_PYTHON */
00205 
00206 #if 0 // UNUSED, until pyconstraints are added back.
00207 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
00208 static void update_pyconstraint_cb (void *arg1, void *arg2)
00209 {
00210 #ifndef WITH_PYTHON
00211     (void)arg1; /* unused */
00212     (void)arg2; /* unused */
00213 #else
00214     Object *owner= (Object *)arg1;
00215     bConstraint *con= (bConstraint *)arg2;
00216     if (owner && con)
00217         BPY_pyconstraint_update(owner, con);
00218 #endif
00219 }
00220 #endif // UNUSED
00221 
00222 /* helper function for add_constriant - sets the last target for the active constraint */
00223 static void set_constraint_nth_target (bConstraint *con, Object *target, const char subtarget[], int index)
00224 {
00225     bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
00226     ListBase targets = {NULL, NULL};
00227     bConstraintTarget *ct;
00228     int num_targets, i;
00229     
00230     if (cti && cti->get_constraint_targets) {
00231         cti->get_constraint_targets(con, &targets);
00232         num_targets= BLI_countlist(&targets);
00233         
00234         if (index < 0) {
00235             if (abs(index) < num_targets)
00236                 index= num_targets - abs(index);
00237             else
00238                 index= num_targets - 1;
00239         }
00240         else if (index >= num_targets) {
00241             index= num_targets - 1;
00242         }
00243         
00244         for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
00245             if (i == index) {
00246                 ct->tar= target;
00247                 BLI_strncpy(ct->subtarget, subtarget, sizeof(ct->subtarget));
00248                 break;
00249             }
00250         }
00251         
00252         if (cti->flush_constraint_targets)
00253             cti->flush_constraint_targets(con, &targets, 0);
00254     }
00255 }
00256 
00257 /* ------------- Constraint Sanity Testing ------------------- */
00258 
00259 /* checks validity of object pointers, and NULLs,
00260  * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag.
00261  */
00262 static void test_constraints (Object *owner, bPoseChannel *pchan)
00263 {
00264     bConstraint *curcon;
00265     ListBase *conlist= NULL;
00266     int type;
00267     
00268     if (owner==NULL) return;
00269     
00270     /* Check parents */
00271     if (pchan) {
00272         switch (owner->type) {
00273             case OB_ARMATURE:
00274                 type = CONSTRAINT_OBTYPE_BONE;
00275                 break;
00276             default:
00277                 type = CONSTRAINT_OBTYPE_OBJECT;
00278                 break;
00279         }
00280     }
00281     else
00282         type = CONSTRAINT_OBTYPE_OBJECT;
00283     
00284     /* Get the constraint list for this object */
00285     switch (type) {
00286         case CONSTRAINT_OBTYPE_OBJECT:
00287             conlist = &owner->constraints;
00288             break;
00289         case CONSTRAINT_OBTYPE_BONE:
00290             conlist = &pchan->constraints;
00291             break;
00292     }
00293     
00294     /* Check all constraints - is constraint valid? */
00295     if (conlist) {
00296         for (curcon = conlist->first; curcon; curcon=curcon->next) {
00297             bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
00298             ListBase targets = {NULL, NULL};
00299             bConstraintTarget *ct;
00300             
00301             /* clear disabled-flag first */
00302             curcon->flag &= ~CONSTRAINT_DISABLE;
00303             
00304             if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
00305                 bKinematicConstraint *data = curcon->data;
00306                 
00307                 /* bad: we need a separate set of checks here as poletarget is 
00308                  *      optional... otherwise poletarget must exist too or else
00309                  *      the constraint is deemed invalid
00310                  */
00311                 /* default IK check ... */
00312                 if (exist_object(data->tar) == 0) {
00313                     data->tar = NULL;
00314                     curcon->flag |= CONSTRAINT_DISABLE;
00315                 }
00316                 else if (data->tar == owner) {
00317                     if (!get_named_bone(get_armature(owner), data->subtarget)) {
00318                         curcon->flag |= CONSTRAINT_DISABLE;
00319                     }
00320                 }
00321                 
00322                 if (data->poletar) {
00323                     if (exist_object(data->poletar) == 0) {
00324                         data->poletar = NULL;
00325                         curcon->flag |= CONSTRAINT_DISABLE;
00326                     }
00327                     else if (data->poletar == owner) {
00328                         if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
00329                             curcon->flag |= CONSTRAINT_DISABLE;
00330                         }
00331                     }
00332                 }
00333                 /* ... can be overwritten here */
00334                 BIK_test_constraint(owner, curcon);
00335                 /* targets have already been checked for this */
00336                 continue;
00337             }
00338             else if (curcon->type == CONSTRAINT_TYPE_PIVOT) {
00339                 bPivotConstraint *data = curcon->data;
00340                 
00341                 /* target doesn't have to exist, but if it is non-null, it must exist! */
00342                 if (data->tar && exist_object(data->tar)==0) {
00343                     data->tar = NULL;
00344                     curcon->flag |= CONSTRAINT_DISABLE;
00345                 }
00346                 else if (data->tar == owner) {
00347                     if (!get_named_bone(get_armature(owner), data->subtarget)) {
00348                         curcon->flag |= CONSTRAINT_DISABLE;
00349                     }
00350                 }
00351                 
00352                 /* targets have already been checked for this */
00353                 continue;
00354             }
00355             else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
00356                 bActionConstraint *data = curcon->data;
00357                 
00358                 /* validate action */
00359                 if (data->act == NULL) 
00360                     curcon->flag |= CONSTRAINT_DISABLE;
00361             }
00362             else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
00363                 bFollowPathConstraint *data = curcon->data;
00364                 
00365                 /* don't allow track/up axes to be the same */
00366                 if (data->upflag==data->trackflag)
00367                     curcon->flag |= CONSTRAINT_DISABLE;
00368                 if (data->upflag+3==data->trackflag)
00369                     curcon->flag |= CONSTRAINT_DISABLE;
00370             }
00371             else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
00372                 bTrackToConstraint *data = curcon->data;
00373                 
00374                 /* don't allow track/up axes to be the same */
00375                 if (data->reserved2==data->reserved1)
00376                     curcon->flag |= CONSTRAINT_DISABLE;
00377                 if (data->reserved2+3==data->reserved1)
00378                     curcon->flag |= CONSTRAINT_DISABLE;
00379             }
00380             else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
00381                 bLockTrackConstraint *data = curcon->data;
00382                 
00383                 if (data->lockflag==data->trackflag)
00384                     curcon->flag |= CONSTRAINT_DISABLE;
00385                 if (data->lockflag+3==data->trackflag)
00386                     curcon->flag |= CONSTRAINT_DISABLE;
00387             }
00388             else if (curcon->type == CONSTRAINT_TYPE_SPLINEIK) {
00389                 bSplineIKConstraint *data = curcon->data;
00390                 
00391                 /* if the number of points does not match the amount required by the chain length,
00392                  * free the points array and request a rebind...
00393                  */
00394                 if ((data->points == NULL) || (data->numpoints != data->chainlen+1))
00395                 {
00396                     /* free the points array */
00397                     if (data->points) {
00398                         MEM_freeN(data->points);
00399                         data->points = NULL;
00400                     }
00401                     
00402                     /* clear the bound flag, forcing a rebind next time this is evaluated */
00403                     data->flag &= ~CONSTRAINT_SPLINEIK_BOUND;
00404                 }
00405             }
00406             else if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
00407                 bFollowTrackConstraint *data = curcon->data;
00408 
00409                 if((data->flag&CAMERASOLVER_ACTIVECLIP)==0) {
00410                     if(data->clip != NULL && data->track[0]) {
00411                         MovieTracking *tracking= &data->clip->tracking;
00412                         MovieTrackingObject *tracking_object;
00413 
00414                         if(data->object[0])
00415                             tracking_object= BKE_tracking_named_object(tracking, data->object);
00416                         else
00417                             tracking_object= BKE_tracking_get_camera_object(tracking);
00418 
00419                         if(!tracking_object) {
00420                             curcon->flag |= CONSTRAINT_DISABLE;
00421                         }
00422                         else {
00423                             if (!BKE_tracking_named_track(tracking, tracking_object, data->track))
00424                                 curcon->flag |= CONSTRAINT_DISABLE;
00425                         }
00426                     }
00427                     else curcon->flag |= CONSTRAINT_DISABLE;
00428                 }
00429             }
00430             else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) {
00431                 bCameraSolverConstraint *data = curcon->data;
00432 
00433                 if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL)
00434                     curcon->flag |= CONSTRAINT_DISABLE;
00435             }
00436             else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
00437                 bObjectSolverConstraint *data = curcon->data;
00438 
00439                 if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL)
00440                     curcon->flag |= CONSTRAINT_DISABLE;
00441             }
00442             
00443             /* Check targets for constraints */
00444             if (cti && cti->get_constraint_targets) {
00445                 cti->get_constraint_targets(curcon, &targets);
00446                 
00447                 /* disable and clear constraints targets that are incorrect */
00448                 for (ct= targets.first; ct; ct= ct->next) {
00449                     /* general validity checks (for those constraints that need this) */
00450                     if (exist_object(ct->tar) == 0) {
00451                         /* object doesn't exist, but constraint requires target */
00452                         ct->tar = NULL;
00453                         curcon->flag |= CONSTRAINT_DISABLE;
00454                     }
00455                     else if (ct->tar == owner) {
00456                         if (type == CONSTRAINT_OBTYPE_BONE) {
00457                             if (!get_named_bone(get_armature(owner), ct->subtarget)) {
00458                                 /* bone must exist in armature... */
00459                                 // TODO: clear subtarget?
00460                                 curcon->flag |= CONSTRAINT_DISABLE;
00461                             }
00462                             else if (strcmp(pchan->name, ct->subtarget) == 0) {
00463                                 /* cannot target self */
00464                                 ct->subtarget[0] = '\0';
00465                                 curcon->flag |= CONSTRAINT_DISABLE;
00466                             }
00467                         }
00468                         else {
00469                             /* cannot use self as target */
00470                             ct->tar = NULL;
00471                             curcon->flag |= CONSTRAINT_DISABLE;
00472                         }
00473                     }
00474                     
00475                     /* target checks for specific constraints */
00476                     if (ELEM3(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) {
00477                         if (ct->tar) {
00478                             if (ct->tar->type != OB_CURVE) {
00479                                 ct->tar= NULL;
00480                                 curcon->flag |= CONSTRAINT_DISABLE;
00481                             }
00482                             else {
00483                                 Curve *cu= ct->tar->data;
00484                                 
00485                                 /* auto-set 'Path' setting on curve so this works  */
00486                                 cu->flag |= CU_PATH;
00487                             }
00488                         }                       
00489                     }
00490                 }   
00491                 
00492                 /* free any temporary targets */
00493                 if (cti->flush_constraint_targets)
00494                     cti->flush_constraint_targets(curcon, &targets, 0);
00495             }
00496         }
00497     }
00498 }
00499 
00500 void object_test_constraints (Object *owner)
00501 {
00502     if (owner->constraints.first)
00503         test_constraints(owner, NULL);
00504     
00505     if (owner->type==OB_ARMATURE && owner->pose) {
00506         bPoseChannel *pchan;
00507         
00508         for (pchan= owner->pose->chanbase.first; pchan; pchan= pchan->next) {
00509             if (pchan->constraints.first)
00510                 test_constraints(owner, pchan);
00511         }
00512     }
00513 }
00514 
00515 
00516 /************************ generic functions for operators using constraint names and data context *********************/
00517 
00518 #define EDIT_CONSTRAINT_OWNER_OBJECT    0
00519 #define EDIT_CONSTRAINT_OWNER_BONE      1
00520 
00521 static EnumPropertyItem constraint_owner_items[] = {
00522     {EDIT_CONSTRAINT_OWNER_OBJECT, "OBJECT", 0, "Object", "Edit a constraint on the active object"},
00523     {EDIT_CONSTRAINT_OWNER_BONE, "BONE", 0, "Bone", "Edit a constraint on the active bone"},
00524     {0, NULL, 0, NULL, NULL}};
00525 
00526 
00527 static int edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
00528 {
00529     PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", rna_type);
00530     Object *ob= (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
00531 
00532     if (!ob || ob->id.lib) return 0;
00533     if (ptr.id.data && ((ID*)ptr.id.data)->lib) return 0;
00534 
00535     return 1;
00536 }
00537 
00538 static int edit_constraint_poll(bContext *C)
00539 {
00540     return edit_constraint_poll_generic(C, &RNA_Constraint);
00541 }
00542 
00543 static void edit_constraint_properties(wmOperatorType *ot)
00544 {
00545     RNA_def_string(ot->srna, "constraint", "", MAX_NAME, "Constraint", "Name of the constraint to edit");
00546     RNA_def_enum(ot->srna, "owner", constraint_owner_items, 0, "Owner", "The owner of this constraint");
00547 }
00548 
00549 static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
00550 {
00551     PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
00552     Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
00553     bConstraint *con;
00554     ListBase *list;
00555     
00556     if (RNA_struct_property_is_set(op->ptr, "constraint") && RNA_struct_property_is_set(op->ptr, "owner"))
00557         return 1;
00558     
00559     if (ptr.data) {
00560         con = ptr.data;
00561         RNA_string_set(op->ptr, "constraint", con->name);
00562         
00563         list = get_constraint_lb(ob, con, NULL);
00564         
00565         if (&ob->constraints == list)
00566             RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_OBJECT);
00567         else
00568             RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_BONE);
00569         
00570         return 1;
00571     }
00572     
00573     return 0;
00574 }
00575 
00576 static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type)
00577 {
00578     char constraint_name[MAX_NAME];
00579     int owner = RNA_enum_get(op->ptr, "owner");
00580     bConstraint *con;
00581     ListBase *list=NULL;
00582     
00583     RNA_string_get(op->ptr, "constraint", constraint_name);
00584     
00585     if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) {
00586         list = &ob->constraints;
00587     } 
00588     else if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
00589         bPoseChannel *pchan= get_active_posechannel(ob);
00590         if (pchan)
00591             list = &pchan->constraints;
00592         else {
00593             //if (G.f & G_DEBUG)
00594             //printf("edit_constraint_property_get: No active bone for object '%s'\n", (ob)? ob->id.name+2 : "<None>");
00595             return NULL;
00596         }
00597     }
00598     else {
00599         //if (G.f & G_DEBUG)
00600         //printf("edit_constraint_property_get: defaulting to getting list in the standard way\n");
00601         list = get_active_constraints(ob);
00602     }
00603     
00604     con = constraints_findByName(list, constraint_name);
00605     //if (G.f & G_DEBUG)
00606     //printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>");
00607 
00608     if (con && (type != 0) && (con->type != type))
00609         con = NULL;
00610     
00611     return con;
00612 }
00613 
00614 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
00615 
00616 /* ---------- Distance-Dependent Constraints ---------- */
00617 /* StretchTo, Limit Distance */
00618 
00619 static int stretchto_reset_exec (bContext *C, wmOperator *op)
00620 {
00621     Object *ob = ED_object_active_context(C);
00622     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_STRETCHTO);
00623     bStretchToConstraint *data= (con) ? (bStretchToConstraint *)con->data : NULL;
00624     
00625     /* despite 3 layers of checks, we may still not be able to find a constraint */
00626     if (data == NULL)
00627         return OPERATOR_CANCELLED;
00628     
00629     /* just set original length to 0.0, which will cause a reset on next recalc */
00630     data->orglength = 0.0f;
00631     ED_object_constraint_update(ob);
00632     
00633     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL);
00634     return OPERATOR_FINISHED;
00635 }
00636 
00637 static int stretchto_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00638 {
00639     if (edit_constraint_invoke_properties(C, op))
00640         return stretchto_reset_exec(C, op);
00641     else
00642         return OPERATOR_CANCELLED;
00643 }
00644 
00645 void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot)
00646 {
00647     /* identifiers */
00648     ot->name= "Reset Original Length";
00649     ot->idname= "CONSTRAINT_OT_stretchto_reset";
00650     ot->description= "Reset original length of bone for Stretch To Constraint";
00651     
00652     ot->exec= stretchto_reset_exec;
00653     ot->invoke= stretchto_reset_invoke;
00654     ot->poll= edit_constraint_poll;
00655     
00656     /* flags */
00657     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00658     edit_constraint_properties(ot);
00659 }
00660 
00661 
00662 static int limitdistance_reset_exec (bContext *C, wmOperator *op)
00663 {
00664     Object *ob = ED_object_active_context(C);
00665     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_DISTLIMIT);
00666     bDistLimitConstraint *data= (con) ? (bDistLimitConstraint *)con->data : NULL;
00667     
00668     /* despite 3 layers of checks, we may still not be able to find a constraint */
00669     if (data == NULL)
00670         return OPERATOR_CANCELLED;
00671     
00672     /* just set original length to 0.0, which will cause a reset on next recalc */
00673     data->dist = 0.0f;
00674     ED_object_constraint_update(ob);
00675     
00676     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL);
00677     return OPERATOR_FINISHED;
00678 }
00679 
00680 static int limitdistance_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00681 {
00682     if (edit_constraint_invoke_properties(C, op))
00683         return limitdistance_reset_exec(C, op);
00684     else
00685         return OPERATOR_CANCELLED;
00686 }
00687 
00688 void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot)
00689 {
00690     /* identifiers */
00691     ot->name= "Reset Distance";
00692     ot->idname= "CONSTRAINT_OT_limitdistance_reset";
00693     ot->description= "Reset limiting distance for Limit Distance Constraint";
00694     
00695     ot->exec= limitdistance_reset_exec;
00696     ot->invoke= limitdistance_reset_invoke;
00697     ot->poll= edit_constraint_poll;
00698     
00699     /* flags */
00700     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00701     edit_constraint_properties(ot);
00702 }
00703 
00704 /* ------------- Child-Of Constraint ------------------ */
00705 
00706 static void child_get_inverse_matrix (Scene *scene, Object *ob, bConstraint *con, float invmat[4][4])
00707 {
00708     bConstraint *lastcon = NULL;
00709     bPoseChannel *pchan= NULL;
00710     
00711     /* nullify inverse matrix first */
00712     unit_m4(invmat);
00713     
00714     /* try to find a pose channel - assume that this is the constraint owner */
00715     // TODO: get from context instead?
00716     if (ob && ob->pose)
00717         pchan= get_active_posechannel(ob);
00718     
00719     /* calculate/set inverse matrix:
00720      *  We just calculate all transform-stack eval up to but not including this constraint.
00721      *  This is because inverse should just inverse correct for just the constraint's influence
00722      *  when it gets applied; that is, at the time of application, we don't know anything about
00723      *  what follows.
00724      */
00725     if (pchan) {
00726         float imat[4][4], tmat[4][4];
00727         float pmat[4][4];
00728         
00729         /* 1. calculate posemat where inverse doesn't exist yet (inverse was cleared above), 
00730          * to use as baseline ("pmat") to derive delta from. This extra calc saves users 
00731          * from having pressing "Clear Inverse" first
00732          */
00733         where_is_pose(scene, ob);
00734         copy_m4_m4(pmat, pchan->pose_mat);
00735         
00736         /* 2. knock out constraints starting from this one */
00737         lastcon = pchan->constraints.last;
00738         pchan->constraints.last = con->prev;
00739         
00740         if (con->prev) {
00741             /* new end must not point to this one, else this chain cutting is useless */
00742             con->prev->next = NULL;
00743         }
00744         else {
00745             /* constraint was first */
00746             pchan->constraints.first = NULL;
00747         }
00748         
00749         /* 3. solve pose without disabled constraints */
00750         where_is_pose(scene, ob);
00751         
00752         /* 4. determine effect of constraint by removing the newly calculated 
00753          * pchan->pose_mat from the original pchan->pose_mat, thus determining 
00754          * the effect of the constraint
00755          */
00756         invert_m4_m4(imat, pchan->pose_mat);
00757         mult_m4_m4m4(tmat, pmat, imat);
00758         invert_m4_m4(invmat, tmat);
00759         
00760         /* 5. restore constraints */
00761         pchan->constraints.last = lastcon;
00762         
00763         if (con->prev) {
00764             /* hook up prev to this one again */
00765             con->prev->next = con;
00766         }
00767         else {
00768             /* set as first again */
00769             pchan->constraints.first = con;
00770         }
00771         
00772         /* 6. recalculate pose with new inv-mat applied */
00773         where_is_pose(scene, ob);
00774     }
00775     else if (ob) {
00776         Object workob;
00777         
00778         /* use what_does_parent to find inverse - just like for normal parenting */
00779         what_does_parent(scene, ob, &workob);
00780         invert_m4_m4(invmat, workob.obmat);
00781     }
00782 }
00783 
00784 /* ChildOf Constraint - set inverse callback */
00785 static int childof_set_inverse_exec (bContext *C, wmOperator *op)
00786 {
00787     Scene *scene= CTX_data_scene(C);
00788     Object *ob = ED_object_active_context(C);
00789     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
00790     bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL;
00791 
00792     /* despite 3 layers of checks, we may still not be able to find a constraint */
00793     if (data == NULL) {
00794         printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : "<None>");
00795         BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse");
00796         return OPERATOR_CANCELLED;
00797     }
00798     
00799     child_get_inverse_matrix(scene, ob, con, data->invmat);
00800 
00801     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
00802     
00803     return OPERATOR_FINISHED;
00804 }
00805 
00806 static int childof_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00807 {
00808     if (edit_constraint_invoke_properties(C, op))
00809         return childof_set_inverse_exec(C, op);
00810     else
00811         return OPERATOR_CANCELLED;
00812 }
00813 
00814 void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot)
00815 {
00816     /* identifiers */
00817     ot->name= "Set Inverse";
00818     ot->idname= "CONSTRAINT_OT_childof_set_inverse";
00819     ot->description= "Set inverse correction for ChildOf constraint";
00820     
00821     ot->exec= childof_set_inverse_exec;
00822     ot->invoke= childof_set_inverse_invoke;
00823     ot->poll= edit_constraint_poll;
00824     
00825     /* flags */
00826     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00827     edit_constraint_properties(ot);
00828 }
00829 
00830 /* ChildOf Constraint - clear inverse callback */
00831 static int childof_clear_inverse_exec (bContext *C, wmOperator *op)
00832 {
00833     Object *ob = ED_object_active_context(C);
00834     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
00835     bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL;
00836     
00837     if(data==NULL) {
00838         BKE_report(op->reports, RPT_ERROR, "Childof constraint not found");
00839         return OPERATOR_CANCELLED;
00840     }
00841     
00842     /* simply clear the matrix */
00843     unit_m4(data->invmat);
00844     
00845     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
00846     
00847     return OPERATOR_FINISHED;
00848 }
00849 
00850 static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00851 {
00852     if (edit_constraint_invoke_properties(C, op))
00853         return childof_clear_inverse_exec(C, op);
00854     else
00855         return OPERATOR_CANCELLED;
00856 }
00857 
00858 void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot)
00859 {
00860     /* identifiers */
00861     ot->name= "Clear Inverse";
00862     ot->idname= "CONSTRAINT_OT_childof_clear_inverse";
00863     ot->description= "Clear inverse correction for ChildOf constraint";
00864     
00865     ot->exec= childof_clear_inverse_exec;
00866     ot->invoke= childof_clear_inverse_invoke;
00867     ot->poll= edit_constraint_poll;
00868     
00869     /* flags */
00870     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00871     edit_constraint_properties(ot);
00872 }
00873 
00874 /* ------------- Object Solver Constraint ------------------ */
00875 
00876 static int objectsolver_set_inverse_exec (bContext *C, wmOperator *op)
00877 {
00878     Scene *scene= CTX_data_scene(C);
00879     Object *ob = ED_object_active_context(C);
00880     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
00881     bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL;
00882 
00883     /* despite 3 layers of checks, we may still not be able to find a constraint */
00884     if (data == NULL) {
00885         printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : "<None>");
00886         BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse");
00887         return OPERATOR_CANCELLED;
00888     }
00889 
00890     child_get_inverse_matrix(scene, ob, con, data->invmat);
00891 
00892     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
00893 
00894     return OPERATOR_FINISHED;
00895 }
00896 
00897 static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00898 {
00899     if (edit_constraint_invoke_properties(C, op))
00900         return objectsolver_set_inverse_exec(C, op);
00901     else
00902         return OPERATOR_CANCELLED;
00903 }
00904 
00905 void CONSTRAINT_OT_objectsolver_set_inverse (wmOperatorType *ot)
00906 {
00907     /* identifiers */
00908     ot->name= "Set Inverse";
00909     ot->idname= "CONSTRAINT_OT_objectsolver_set_inverse";
00910     ot->description= "Set inverse correction for ObjectSolver constraint";
00911 
00912     ot->exec= objectsolver_set_inverse_exec;
00913     ot->invoke= objectsolver_set_inverse_invoke;
00914     ot->poll= edit_constraint_poll;
00915 
00916     /* flags */
00917     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00918     edit_constraint_properties(ot);
00919 }
00920 
00921 static int objectsolver_clear_inverse_exec (bContext *C, wmOperator *op)
00922 {
00923     Object *ob = ED_object_active_context(C);
00924     bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
00925     bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL;
00926 
00927     if(data==NULL) {
00928         BKE_report(op->reports, RPT_ERROR, "Childof constraint not found");
00929         return OPERATOR_CANCELLED;
00930     }
00931 
00932     /* simply clear the matrix */
00933     unit_m4(data->invmat);
00934 
00935     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
00936 
00937     return OPERATOR_FINISHED;
00938 }
00939 
00940 static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
00941 {
00942     if (edit_constraint_invoke_properties(C, op))
00943         return objectsolver_clear_inverse_exec(C, op);
00944     else
00945         return OPERATOR_CANCELLED;
00946 }
00947 
00948 void CONSTRAINT_OT_objectsolver_clear_inverse (wmOperatorType *ot)
00949 {
00950     /* identifiers */
00951     ot->name= "Clear Inverse";
00952     ot->idname= "CONSTRAINT_OT_objectsolver_clear_inverse";
00953     ot->description= "Clear inverse correction for ObjectSolver constraint";
00954 
00955     ot->exec= objectsolver_clear_inverse_exec;
00956     ot->invoke= objectsolver_clear_inverse_invoke;
00957     ot->poll= edit_constraint_poll;
00958 
00959     /* flags */
00960     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00961     edit_constraint_properties(ot);
00962 }
00963 
00964 /***************************** BUTTONS ****************************/
00965 
00966 void ED_object_constraint_set_active(Object *ob, bConstraint *con)
00967 {   
00968     ListBase *lb = get_constraint_lb(ob, con, NULL);
00969     
00970     /* lets be nice and escape if its active already */
00971     // NOTE: this assumes that the stack doesn't have other active ones set...
00972     if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE))
00973         return;
00974     
00975     constraints_set_active(lb, con);
00976 }
00977 
00978 void ED_object_constraint_update(Object *ob)
00979 {
00980 
00981     if(ob->pose) update_pose_constraint_flags(ob->pose);
00982 
00983     object_test_constraints(ob);
00984 
00985     if(ob->type==OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
00986     else DAG_id_tag_update(&ob->id, OB_RECALC_OB);
00987 }
00988 
00989 void ED_object_constraint_dependency_update(Main *bmain, Scene *scene, Object *ob)
00990 {
00991     ED_object_constraint_update(ob);
00992 
00993     if(ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
00994     DAG_scene_sort(bmain, scene);
00995 }
00996 
00997 static int constraint_poll(bContext *C)
00998 {
00999     PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
01000     return (ptr.id.data && ptr.data);
01001 }
01002 
01003 static int constraint_delete_exec (bContext *C, wmOperator *UNUSED(op))
01004 {
01005     PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
01006     Object *ob= ptr.id.data;
01007     bConstraint *con= ptr.data;
01008     ListBase *lb = get_constraint_lb(ob, con, NULL);
01009     const short is_ik= ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
01010 
01011     /* free the constraint */
01012     if (remove_constraint(lb, con)) {
01013         /* there's no active constraint now, so make sure this is the case */
01014         constraints_set_active(lb, NULL);
01015         
01016         ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
01017 
01018         /* ITASC needs to be rebuilt once a constraint is removed [#26920] */
01019         if(is_ik) {
01020             BIK_clear_data(ob->pose);
01021         }
01022 
01023         /* notifiers */
01024         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
01025         
01026         return OPERATOR_FINISHED;
01027     }
01028     else {
01029         /* couldn't remove due to some invalid data */
01030         return OPERATOR_CANCELLED;
01031     }
01032 }
01033 
01034 void CONSTRAINT_OT_delete (wmOperatorType *ot)
01035 {
01036     /* identifiers */
01037     ot->name= "Delete Constraint";
01038     ot->idname= "CONSTRAINT_OT_delete";
01039     ot->description= "Remove constraint from constraint stack";
01040     
01041     /* callbacks */
01042     ot->exec= constraint_delete_exec;
01043     ot->poll= constraint_poll;
01044     
01045     /* flags */
01046     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
01047 }
01048 
01049 static int constraint_move_down_exec (bContext *C, wmOperator *op)
01050 {
01051     Object *ob = ED_object_active_context(C);
01052     bConstraint *con = edit_constraint_property_get(op, ob, 0);
01053     
01054     if (con && con->next) {
01055         ListBase *conlist= get_constraint_lb(ob, con, NULL);
01056         bConstraint *nextCon= con->next;
01057         
01058         /* insert the nominated constraint after the one that used to be after it */
01059         BLI_remlink(conlist, con);
01060         BLI_insertlinkafter(conlist, nextCon, con);
01061         
01062         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
01063         
01064         return OPERATOR_FINISHED;
01065     }
01066     
01067     return OPERATOR_CANCELLED;
01068 }
01069 
01070 static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01071 {
01072     if (edit_constraint_invoke_properties(C, op))
01073         return constraint_move_down_exec(C, op);
01074     else
01075         return OPERATOR_CANCELLED;
01076 }
01077 
01078 
01079 void CONSTRAINT_OT_move_down (wmOperatorType *ot)
01080 {
01081     /* identifiers */
01082     ot->name= "Move Constraint Down";
01083     ot->idname= "CONSTRAINT_OT_move_down";
01084     ot->description= "Move constraint down in constraint stack";
01085     
01086     /* callbacks */
01087     ot->exec= constraint_move_down_exec;
01088     ot->invoke= constraint_move_down_invoke;
01089     ot->poll= edit_constraint_poll;
01090     
01091     /* flags */
01092     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
01093     edit_constraint_properties(ot);
01094 }
01095 
01096 
01097 static int constraint_move_up_exec (bContext *C, wmOperator *op)
01098 {
01099     Object *ob = ED_object_active_context(C);
01100     bConstraint *con = edit_constraint_property_get(op, ob, 0);
01101     
01102     if (con && con->prev) {
01103         ListBase *conlist= get_constraint_lb(ob, con, NULL);
01104         bConstraint *prevCon= con->prev;
01105         
01106         /* insert the nominated constraint before the one that used to be before it */
01107         BLI_remlink(conlist, con);
01108         BLI_insertlinkbefore(conlist, prevCon, con);
01109         
01110         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
01111         
01112         return OPERATOR_FINISHED;
01113     }
01114     
01115     return OPERATOR_CANCELLED;
01116 }
01117 
01118 static int constraint_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
01119 {
01120     if (edit_constraint_invoke_properties(C, op))
01121         return constraint_move_up_exec(C, op);
01122     else
01123         return OPERATOR_CANCELLED;
01124 }
01125 
01126 void CONSTRAINT_OT_move_up (wmOperatorType *ot)
01127 {
01128     /* identifiers */
01129     ot->name= "Move Constraint Up";
01130     ot->idname= "CONSTRAINT_OT_move_up";
01131     ot->description= "Move constraint up in constraint stack";
01132     
01133     /* callbacks */
01134     ot->exec= constraint_move_up_exec;
01135     ot->invoke= constraint_move_up_invoke;
01136     ot->poll= edit_constraint_poll;
01137     
01138     /* flags */
01139     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
01140     edit_constraint_properties(ot);
01141 }
01142 
01143 /***************************** OPERATORS ****************************/
01144 
01145 /************************ remove constraint operators *********************/
01146 
01147 static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
01148 {
01149     Main *bmain= CTX_data_main(C);
01150     Scene *scene= CTX_data_scene(C);
01151     Object *ob= object_pose_armature_get(CTX_data_active_object(C));
01152     
01153     /* free constraints for all selected bones */
01154     CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
01155     {
01156         free_constraints(&pchan->constraints);
01157         pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_SPLINEIK|PCHAN_HAS_CONST);
01158     }
01159     CTX_DATA_END;
01160     
01161     /* force depsgraph to get recalculated since relationships removed */
01162     DAG_scene_sort(bmain, scene);       /* sort order of objects */ 
01163     
01164     /* note, calling BIK_clear_data() isnt needed here */
01165 
01166     /* do updates */
01167     DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01168     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
01169     
01170     return OPERATOR_FINISHED;
01171 }
01172 
01173 void POSE_OT_constraints_clear(wmOperatorType *ot)
01174 {
01175     /* identifiers */
01176     ot->name = "Clear Pose Constraints";
01177     ot->idname= "POSE_OT_constraints_clear";
01178     ot->description= "Clear all the constraints for the selected bones";
01179     
01180     /* callbacks */
01181     ot->exec= pose_constraints_clear_exec;
01182     ot->poll= ED_operator_posemode; // XXX - do we want to ensure there are selected bones too?
01183 }
01184 
01185 
01186 static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
01187 {
01188     Main *bmain= CTX_data_main(C);
01189     Scene *scene= CTX_data_scene(C);
01190     
01191     /* do freeing */
01192     CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) 
01193     {
01194         free_constraints(&ob->constraints);
01195         DAG_id_tag_update(&ob->id, OB_RECALC_OB);
01196     }
01197     CTX_DATA_END;
01198     
01199     /* force depsgraph to get recalculated since relationships removed */
01200     DAG_scene_sort(bmain, scene);       /* sort order of objects */ 
01201     
01202     /* do updates */
01203     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL);
01204     
01205     return OPERATOR_FINISHED;
01206 }
01207 
01208 void OBJECT_OT_constraints_clear(wmOperatorType *ot)
01209 {
01210     /* identifiers */
01211     ot->name = "Clear Object Constraints";
01212     ot->idname= "OBJECT_OT_constraints_clear";
01213     ot->description= "Clear all the constraints for the active Object only";
01214     
01215     /* callbacks */
01216     ot->exec= object_constraints_clear_exec;
01217     ot->poll= ED_operator_object_active_editable;
01218 }
01219 
01220 /************************ copy all constraints operators *********************/
01221 
01222 static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
01223 {
01224     Main *bmain= CTX_data_main(C);
01225     Scene *scene = CTX_data_scene(C);
01226     bPoseChannel *pchan = CTX_data_active_pose_bone(C);
01227     
01228     /* don't do anything if bone doesn't exist or doesn't have any constraints */
01229     if (ELEM(NULL, pchan, pchan->constraints.first)) {
01230         BKE_report(op->reports, RPT_ERROR, "No active bone with constraints for copying");
01231         return OPERATOR_CANCELLED;
01232     }
01233     
01234     /* copy all constraints from active posebone to all selected posebones */
01235     CTX_DATA_BEGIN(C, bPoseChannel*, chan, selected_pose_bones) 
01236     {
01237         /* if we're not handling the object we're copying from, copy all constraints over */
01238         if (pchan != chan) {
01239             copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
01240             /* update flags (need to add here, not just copy) */
01241             chan->constflag |= pchan->constflag;
01242         }
01243     }
01244     CTX_DATA_END;
01245     
01246     /* force depsgraph to get recalculated since new relationships added */
01247     DAG_scene_sort(bmain, scene);       /* sort order of objects/bones */
01248 
01249     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL);
01250     
01251     return OPERATOR_FINISHED;
01252 }
01253 
01254 void POSE_OT_constraints_copy(wmOperatorType *ot)
01255 {
01256     /* identifiers */
01257     ot->name= "Copy Constraints to Selected";
01258     ot->idname= "POSE_OT_constraints_copy";
01259     ot->description = "Copy constraints to other selected bones";
01260     
01261     /* api callbacks */
01262     ot->exec= pose_constraint_copy_exec;
01263     ot->poll= ED_operator_posemode;
01264 
01265     /* flags */
01266     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01267 }
01268 
01269 static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
01270 {
01271     Main *bmain= CTX_data_main(C);
01272     Scene *scene = CTX_data_scene(C);
01273     Object *obact = ED_object_active_context(C);
01274     
01275     /* copy all constraints from active object to all selected objects */
01276     CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) 
01277     {
01278         /* if we're not handling the object we're copying from, copy all constraints over */
01279         if (obact != ob) {
01280             copy_constraints(&ob->constraints, &obact->constraints, TRUE);
01281             DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01282         }
01283     }
01284     CTX_DATA_END;
01285     
01286     /* force depsgraph to get recalculated since new relationships added */
01287     DAG_scene_sort(bmain, scene);       /* sort order of objects */
01288     
01289     /* notifiers for updates */
01290     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, NULL);
01291     
01292     return OPERATOR_FINISHED;
01293 }
01294 
01295 void OBJECT_OT_constraints_copy(wmOperatorType *ot)
01296 {
01297     /* identifiers */
01298     ot->name= "Copy Constraints to Selected";
01299     ot->idname= "OBJECT_OT_constraints_copy";
01300     ot->description = "Copy constraints to other selected objects";
01301     
01302     /* api callbacks */
01303     ot->exec= object_constraint_copy_exec;
01304     ot->poll= ED_operator_object_active_editable;
01305 
01306     /* flags */
01307     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01308 }
01309 
01310 /************************ add constraint operators *********************/
01311 
01312 /* get the Object and/or PoseChannel to use as target */
01313 static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add)
01314 {
01315     Object *obact= ED_object_active_context(C);
01316     bPoseChannel *pchanact= get_active_posechannel(obact);
01317     short only_curve= 0, only_mesh= 0, only_ob= 0;
01318     short found= 0;
01319     
01320     /* clear tar_ob and tar_pchan fields before use 
01321      *  - assume for now that both always exist...
01322      */
01323     *tar_ob= NULL;
01324     *tar_pchan= NULL;
01325     
01326     /* check if constraint type doesn't requires a target
01327      *  - if so, no need to get any targets 
01328      */
01329     switch (con_type) {
01330         /* no-target constraints --------------------------- */
01331             /* null constraint - shouldn't even be added! */
01332         case CONSTRAINT_TYPE_NULL:
01333             /* limit constraints - no targets needed */
01334         case CONSTRAINT_TYPE_LOCLIMIT:
01335         case CONSTRAINT_TYPE_ROTLIMIT:
01336         case CONSTRAINT_TYPE_SIZELIMIT:
01337         case CONSTRAINT_TYPE_SAMEVOL:
01338             return 0;
01339             
01340         /* restricted target-type constraints -------------- */
01341         /* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */
01342             /* curve-based constraints - set the only_curve and only_ob flags */
01343         case CONSTRAINT_TYPE_CLAMPTO:
01344         case CONSTRAINT_TYPE_FOLLOWPATH:
01345         case CONSTRAINT_TYPE_SPLINEIK:
01346             only_curve= 1;
01347             only_ob= 1;
01348             add= 0;
01349             break;
01350             
01351             /* mesh only? */
01352         case CONSTRAINT_TYPE_SHRINKWRAP:
01353             only_mesh= 1;
01354             only_ob= 1;
01355             add= 0;
01356             break;
01357             
01358             /* object only - add here is ok? */
01359         case CONSTRAINT_TYPE_RIGIDBODYJOINT:
01360             only_ob= 1;
01361             break;
01362     }
01363     
01364     /* if the active Object is Armature, and we can search for bones, do so... */
01365     if ((obact->type == OB_ARMATURE) && (only_ob == 0)) {
01366         /* search in list of selected Pose-Channels for target */
01367         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
01368         {
01369             /* just use the first one that we encounter, as long as it is not the active one */
01370             if (pchan != pchanact) {
01371                 *tar_ob= obact;
01372                 *tar_pchan= pchan;
01373                 found= 1;
01374                 
01375                 break;
01376             }
01377         }
01378         CTX_DATA_END;
01379     }
01380     
01381     /* if not yet found, try selected Objects... */
01382     if (found == 0) {
01383         /* search in selected objects context */
01384         CTX_DATA_BEGIN(C, Object*, ob, selected_objects) 
01385         {
01386             /* just use the first object we encounter (that isn't the active object) 
01387              * and which fulfills the criteria for the object-target that we've got 
01388              */
01389             if ( (ob != obact) &&
01390                  ((!only_curve) || (ob->type == OB_CURVE)) && 
01391                  ((!only_mesh) || (ob->type == OB_MESH)) )
01392             {
01393                 /* set target */
01394                 *tar_ob= ob;
01395                 found= 1;
01396                 
01397                 /* perform some special operations on the target */
01398                 if (only_curve) {
01399                     /* Curve-Path option must be enabled for follow-path constraints to be able to work */
01400                     Curve *cu= (Curve *)ob->data;
01401                     cu->flag |= CU_PATH;
01402                 }
01403                 
01404                 break;
01405             }
01406         }
01407         CTX_DATA_END;
01408     }
01409     
01410     /* if still not found, add a new empty to act as a target (if allowed) */
01411     if ((found == 0) && (add)) {
01412         Scene *scene= CTX_data_scene(C);
01413         Base *base= BASACT, *newbase=NULL;
01414         Object *obt;
01415         
01416         /* add new target object */
01417         obt= add_object(scene, OB_EMPTY);
01418         
01419         /* set layers OK */
01420         newbase= BASACT;
01421         newbase->lay= base->lay;
01422         obt->lay= newbase->lay;
01423         
01424         /* transform cent to global coords for loc */
01425         if (pchanact) {
01426             /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel 
01427              * if adding a target for an IK Constraint
01428              */
01429             if (con_type == CONSTRAINT_TYPE_KINEMATIC)
01430                 mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_tail);
01431             else
01432                 mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_head);
01433         }
01434         else {
01435             copy_v3_v3(obt->loc, obact->obmat[3]);
01436         }
01437 
01438         /* restore, add_object sets active */
01439         BASACT= base;
01440         base->flag |= SELECT;
01441         
01442         /* make our new target the new object */
01443         *tar_ob= obt;
01444         found= 1;
01445     }
01446     
01447     /* return whether there's any target */
01448     return found;
01449 }
01450 
01451 /* used by add constraint operators to add the constraint required */
01452 static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget)
01453 {
01454     Main *bmain= CTX_data_main(C);
01455     Scene *scene= CTX_data_scene(C);
01456     bPoseChannel *pchan;
01457     bConstraint *con;
01458     
01459     if (list == &ob->constraints) {
01460         pchan= NULL;
01461     }
01462     else {
01463         pchan= get_active_posechannel(ob);
01464         
01465         /* ensure not to confuse object/pose adding */
01466         if (pchan == NULL) {
01467             BKE_report(op->reports, RPT_ERROR, "No active pose bone to add a constraint to");
01468             return OPERATOR_CANCELLED;
01469         }
01470     }
01471     /* check if constraint to be added is valid for the given constraints stack */
01472     if (type == CONSTRAINT_TYPE_NULL) {
01473         return OPERATOR_CANCELLED;
01474     }
01475     if ( (type == CONSTRAINT_TYPE_RIGIDBODYJOINT) && (list != &ob->constraints) ) {
01476         BKE_report(op->reports, RPT_ERROR, "Rigid Body Joint Constraint can only be added to Objects");
01477         return OPERATOR_CANCELLED;
01478     }
01479     if ( (type == CONSTRAINT_TYPE_KINEMATIC) && ((!pchan) || (list != &pchan->constraints)) ) {
01480         BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones");
01481         return OPERATOR_CANCELLED;
01482     }
01483     if ( (type == CONSTRAINT_TYPE_SPLINEIK) && ((!pchan) || (list != &pchan->constraints)) ) {
01484         BKE_report(op->reports, RPT_ERROR, "Spline IK Constraint can only be added to Bones");
01485         return OPERATOR_CANCELLED;
01486     }
01487     
01488     /* create a new constraint of the type requried, and add it to the active/given constraints list */
01489     if (pchan)
01490         con = add_pose_constraint(ob, pchan, NULL, type);
01491     else
01492         con = add_ob_constraint(ob, NULL, type);
01493     
01494     /* get the first selected object/bone, and make that the target
01495      *  - apart from the buttons-window add buttons, we shouldn't add in this way
01496      */
01497     if (setTarget) {
01498         Object *tar_ob= NULL;
01499         bPoseChannel *tar_pchan= NULL;
01500         
01501         /* get the target objects, adding them as need be */
01502         if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) {
01503             /* method of setting target depends on the type of target we've got 
01504              *  - by default, just set the first target (distinction here is only for multiple-targetted constraints)
01505              */
01506             if (tar_pchan)
01507                 set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0);
01508             else
01509                 set_constraint_nth_target(con, tar_ob, "", 0);
01510         }
01511     }
01512     
01513     /* do type-specific tweaking to the constraint settings  */
01514     switch (type) {
01515         case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore
01516         {
01517 #ifdef WITH_PYTHON
01518             char *menustr;
01519             int scriptint= 0;
01520             /* popup a list of usable scripts */
01521             menustr = buildmenu_pyconstraints(NULL, &scriptint);
01522             // XXX scriptint = pupmenu(menustr);
01523             MEM_freeN(menustr);
01524             
01525             /* only add constraint if a script was chosen */
01526             if (scriptint) {
01527                 /* add constraint */
01528                 validate_pyconstraint_cb(con->data, &scriptint);
01529                 
01530                 /* make sure target allowance is set correctly */
01531                 BPY_pyconstraint_update(ob, con);
01532             }
01533 #endif
01534             break;
01535         }
01536 
01537         default:
01538             break;
01539     }
01540     
01541     /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */
01542     object_test_constraints(ob);
01543 
01544     if (pchan)
01545         update_pose_constraint_flags(ob->pose);
01546 
01547 
01548     /* force depsgraph to get recalculated since new relationships added */
01549     DAG_scene_sort(bmain, scene);       /* sort order of objects */
01550     
01551     if ((ob->type==OB_ARMATURE) && (pchan)) {
01552         ob->pose->flag |= POSE_RECALC;  /* sort pose channels */
01553         DAG_id_tag_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB);
01554     }
01555     else
01556         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01557     
01558     /* notifiers for updates */
01559     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob);
01560     
01561     return OPERATOR_FINISHED;
01562 }
01563 
01564 /* ------------------ */
01565 
01566 /* dummy operator callback */
01567 static int object_constraint_add_exec(bContext *C, wmOperator *op)
01568 {
01569     Object *ob=ED_object_active_context(C);
01570     int type= RNA_enum_get(op->ptr, "type");
01571     short with_targets= 0;
01572     
01573     if (!ob) {
01574         BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
01575         return OPERATOR_CANCELLED;
01576     }
01577         
01578     /* hack: set constraint targets from selected objects in context is allowed when
01579      *      operator name included 'with_targets', since the menu doesn't allow multiple properties
01580      */
01581     if (strstr(op->idname, "with_targets"))
01582         with_targets= 1;
01583 
01584     return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets);
01585 }
01586 
01587 /* dummy operator callback */
01588 static int pose_constraint_add_exec(bContext *C, wmOperator *op)
01589 {
01590     Object *ob= object_pose_armature_get(ED_object_active_context(C));
01591     int type= RNA_enum_get(op->ptr, "type");
01592     short with_targets= 0;
01593     
01594     if (!ob) {
01595         BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
01596         return OPERATOR_CANCELLED;
01597     }
01598         
01599     /* hack: set constraint targets from selected objects in context is allowed when
01600      *      operator name included 'with_targets', since the menu doesn't allow multiple properties
01601      */
01602     if (strstr(op->idname, "with_targets"))
01603         with_targets= 1;
01604     
01605     return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets);
01606 }
01607 
01608 /* ------------------ */
01609 
01610 void OBJECT_OT_constraint_add(wmOperatorType *ot)
01611 {
01612     /* identifiers */
01613     ot->name= "Add Constraint";
01614     ot->description = "Add a constraint to the active object";
01615     ot->idname= "OBJECT_OT_constraint_add";
01616     
01617     /* api callbacks */
01618     ot->invoke= WM_menu_invoke;
01619     ot->exec= object_constraint_add_exec;
01620     ot->poll= ED_operator_object_active_editable;
01621     
01622     /* flags */
01623     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01624     
01625     /* properties */
01626     ot->prop= RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
01627 }
01628 
01629 void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
01630 {
01631     /* identifiers */
01632     ot->name= "Add Constraint (with Targets)";
01633     ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones";
01634     ot->idname= "OBJECT_OT_constraint_add_with_targets";
01635     
01636     /* api callbacks */
01637     ot->invoke= WM_menu_invoke;
01638     ot->exec= object_constraint_add_exec;
01639     ot->poll= ED_operator_object_active_editable;
01640     
01641     /* flags */
01642     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01643     
01644     /* properties */
01645     ot->prop= RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
01646 }
01647 
01648 void POSE_OT_constraint_add(wmOperatorType *ot)
01649 {
01650     /* identifiers */
01651     ot->name= "Add Constraint";
01652     ot->description = "Add a constraint to the active bone";
01653     ot->idname= "POSE_OT_constraint_add";
01654     
01655     /* api callbacks */
01656     ot->invoke= WM_menu_invoke;
01657     ot->exec= pose_constraint_add_exec;
01658     ot->poll= ED_operator_posemode;
01659     
01660     /* flags */
01661     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01662     
01663     /* properties */
01664     ot->prop= RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
01665 }
01666 
01667 void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
01668 {
01669     /* identifiers */
01670     ot->name= "Add Constraint (with Targets)";
01671     ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones";
01672     ot->idname= "POSE_OT_constraint_add_with_targets";
01673     
01674     /* api callbacks */
01675     ot->invoke= WM_menu_invoke;
01676     ot->exec= pose_constraint_add_exec;
01677     ot->poll= ED_operator_posemode;
01678     
01679     /* flags */
01680     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01681     
01682     /* properties */
01683     ot->prop= RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
01684 }
01685 
01686 /************************ IK Constraint operators *********************/
01687 /* NOTE: only for Pose-Channels */
01688 // TODO: should these be here, or back in editors/armature/poseobject.c again?
01689 
01690 /* present menu with options + validation for targets to use */
01691 static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
01692 {
01693     Object *ob= object_pose_armature_get(CTX_data_active_object(C));
01694     bPoseChannel *pchan= get_active_posechannel(ob);
01695     bConstraint *con= NULL;
01696     
01697     uiPopupMenu *pup;
01698     uiLayout *layout;
01699     Object *tar_ob= NULL;
01700     bPoseChannel *tar_pchan= NULL;
01701     
01702     /* must have active bone */
01703     if (ELEM(NULL, ob, pchan)) {
01704         BKE_report(op->reports, RPT_ERROR, "Must have active bone to add IK Constraint to");
01705         return OPERATOR_CANCELLED;
01706     }
01707     
01708     /* bone must not have any constraints already */
01709     for (con= pchan->constraints.first; con; con= con->next) {
01710         if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
01711     }
01712     if (con) {
01713         BKE_report(op->reports, RPT_ERROR, "Bone already has IK Constraint");
01714         return OPERATOR_CANCELLED;
01715     }
01716     
01717     /* prepare popup menu to choose targetting options */
01718     pup= uiPupMenuBegin(C, "Add IK", ICON_NONE);
01719     layout= uiPupMenuLayout(pup);
01720     
01721     /* the type of targets we'll set determines the menu entries to show... */
01722     if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) {
01723         /* bone target, or object target? 
01724          *  - the only thing that matters is that we want a target...
01725          */
01726         if (tar_pchan)
01727             uiItemBooleanO(layout, "To Active Bone", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
01728         else
01729             uiItemBooleanO(layout, "To Active Object", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
01730     }
01731     else {
01732         /* we have a choice of adding to a new empty, or not setting any target (targetless IK) */
01733         uiItemBooleanO(layout, "To New Empty Object", ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
01734         uiItemBooleanO(layout, "Without Targets", ICON_NONE, "POSE_OT_ik_add", "with_targets", 0);
01735     }
01736     
01737     /* finish building the menu, and process it (should result in calling self again) */
01738     uiPupMenuEnd(C, pup);
01739     
01740     return OPERATOR_CANCELLED;
01741 }
01742 
01743 /* call constraint_add_exec() to add the IK constraint */
01744 static int pose_ik_add_exec(bContext *C, wmOperator *op)
01745 {
01746     Object *ob= CTX_data_active_object(C);
01747     int with_targets= RNA_boolean_get(op->ptr, "with_targets");
01748     
01749     /* add the constraint - all necessary checks should have been done by the invoke() callback already... */
01750     return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
01751 }
01752 
01753 void POSE_OT_ik_add(wmOperatorType *ot)
01754 {
01755     /* identifiers */
01756     ot->name= "Add IK to Bone";
01757     ot->description= "Add IK Constraint to the active Bone";
01758     ot->idname= "POSE_OT_ik_add";
01759     
01760     /* api callbacks */
01761     ot->invoke= pose_ik_add_invoke;
01762     ot->exec= pose_ik_add_exec;
01763     ot->poll= ED_operator_posemode;
01764     
01765     /* flags */
01766     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01767     
01768     /* properties */
01769     RNA_def_boolean(ot->srna, "with_targets", 1, "With Targets", "Assign IK Constraint with targets derived from the select bones/objects");
01770 }
01771 
01772 /* ------------------ */
01773 
01774 /* remove IK constraints from selected bones */
01775 static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
01776 {
01777     Object *ob= object_pose_armature_get(CTX_data_active_object(C));
01778     
01779     /* only remove IK Constraints */
01780     CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
01781     {
01782         bConstraint *con, *next;
01783         
01784         // TODO: should we be checking if these contraints were local before we try and remove them?
01785         for (con= pchan->constraints.first; con; con= next) {
01786             next= con->next;
01787             if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
01788                 remove_constraint(&pchan->constraints, con);
01789             }
01790         }
01791         pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
01792     }
01793     CTX_DATA_END;
01794     
01795     /* refresh depsgraph */
01796     DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01797 
01798     /* note, notifier might evolve */
01799     WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
01800     
01801     return OPERATOR_FINISHED;
01802 }
01803 
01804 void POSE_OT_ik_clear(wmOperatorType *ot)
01805 {
01806     /* identifiers */
01807     ot->name= "Remove IK";
01808     ot->description= "Remove all IK Constraints from selected bones";
01809     ot->idname= "POSE_OT_ik_clear";
01810     
01811     /* api callbacks */
01812     ot->exec= pose_ik_clear_exec;
01813     ot->poll= ED_operator_posemode;
01814     
01815     /* flags */
01816     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01817 }
01818