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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editconstraint.c')
-rw-r--r--source/blender/src/editconstraint.c1103
1 files changed, 0 insertions, 1103 deletions
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
deleted file mode 100644
index e0588b4c2a0..00000000000
--- a/source/blender/src/editconstraint.c
+++ /dev/null
@@ -1,1103 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
-
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_text_types.h"
-#include "DNA_view3d_types.h"
-
-#include "BKE_action.h"
-#include "BKE_armature.h"
-#include "BKE_constraint.h"
-#include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_ipo.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
-
-#include "BIF_editaction.h"
-#include "BIF_editarmature.h"
-#include "BIF_editconstraint.h"
-#include "BIF_poseobject.h"
-#include "BIF_interface.h"
-#include "BIF_screen.h"
-#include "BIF_space.h"
-#include "BIF_toolbox.h"
-
-#include "BPY_extern.h"
-
-#include "blendef.h"
-#include "nla.h"
-#include "mydevice.h"
-
-
-ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
-{
- char ipstr[64];
-
- if (!ob)
- return NULL;
-
- /* See if we are a bone constraint */
- if (ob->flag & OB_POSEMODE) {
- bActionChannel *achan;
- bPoseChannel *pchan;
-
- pchan = get_active_posechannel(ob);
- if (pchan) {
-
- /* Make sure we have an action */
- if (!ob->action){
- if (!forcevalid)
- return NULL;
-
- ob->action=add_empty_action("Action");
- }
-
- /* Make sure we have an actionchannel */
- achan = get_action_channel(ob->action, pchan->name);
- if (!achan){
- if (!forcevalid)
- return NULL;
-
- achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
-
- strcpy (achan->name, pchan->name);
- sprintf (ipstr, "%s.%s", ob->action->id.name+2, achan->name);
- ipstr[23]=0;
- achan->ipo= add_ipo(ipstr, ID_AC);
-
- BLI_addtail (&ob->action->chanbase, achan);
- }
-
- return &achan->constraintChannels;
- }
- else return NULL;
- }
- /* else we return object constraints */
- else {
- if(ob->ipoflag & OB_ACTION_OB) {
- bActionChannel *achan = get_action_channel(ob->action, "Object");
- if(achan)
- return &achan->constraintChannels;
- else
- return NULL;
- }
-
- return &ob->constraintChannels;
- }
-}
-
-
-/* if object in posemode, active bone constraints, else object constraints */
-ListBase *get_active_constraints(Object *ob)
-{
- if (!ob)
- return NULL;
-
- if (ob->flag & OB_POSEMODE) {
- bPoseChannel *pchan;
-
- pchan = get_active_posechannel(ob);
- if (pchan)
- return &pchan->constraints;
- }
- else
- return &ob->constraints;
-
- return NULL;
-}
-
-/* single constraint */
-bConstraint *get_active_constraint(Object *ob)
-{
- ListBase *lb= get_active_constraints(ob);
-
- if (lb) {
- bConstraint *con;
- for (con= lb->first; con; con=con->next)
- if (con->flag & CONSTRAINT_ACTIVE)
- return con;
- }
- return NULL;
-}
-
-/* single channel, for ipo */
-bConstraintChannel *get_active_constraint_channel(Object *ob)
-{
- bConstraint *con;
- bConstraintChannel *chan;
-
- if (ob->flag & OB_POSEMODE) {
- if(ob->action) {
- bPoseChannel *pchan;
-
- pchan = get_active_posechannel(ob);
- if (pchan) {
- for (con= pchan->constraints.first; con; con= con->next)
- if (con->flag & CONSTRAINT_ACTIVE)
- break;
- if (con) {
- bActionChannel *achan = get_action_channel(ob->action, pchan->name);
- if (achan) {
- for (chan= achan->constraintChannels.first; chan; chan= chan->next)
- if (!strcmp(chan->name, con->name))
- break;
- return chan;
- }
- }
- }
- }
- }
- else {
- for(con= ob->constraints.first; con; con= con->next)
- if(con->flag & CONSTRAINT_ACTIVE)
- break;
- if(con) {
- ListBase *lb= get_active_constraint_channels(ob, 0);
-
- if(lb) {
- for(chan= lb->first; chan; chan= chan->next)
- if(!strcmp(chan->name, con->name))
- break;
- return chan;
- }
- }
- }
-
- return NULL;
-}
-
-
-bConstraint *add_new_constraint(short type)
-{
- bConstraint *con;
- bConstraintTypeInfo *cti;
-
- con = MEM_callocN(sizeof(bConstraint), "constraint");
-
- /* Set up a generic constraint datablock */
- con->type = type;
- con->flag |= CONSTRAINT_EXPAND;
- con->enforce = 1.0F;
- strcpy(con->name, "Const");
-
- /* Load the data for it */
- cti = constraint_get_typeinfo(con);
- if (cti) {
- con->data = MEM_callocN(cti->size, cti->structName);
-
- /* only constraints that change any settings need this */
- if (cti->new_data)
- cti->new_data(con->data);
- }
-
- return con;
-}
-
-void add_constraint_to_object(bConstraint *con, Object *ob)
-{
- ListBase *list;
- list = &ob->constraints;
-
- if (list) {
- unique_constraint_name(con, list);
- BLI_addtail(list, con);
-
- con->flag |= CONSTRAINT_ACTIVE;
- for (con= con->prev; con; con= con->prev)
- con->flag &= ~CONSTRAINT_ACTIVE;
- }
-}
-
-/* checks validity of object pointers, and NULLs,
- * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag
- */
-static void test_constraints (Object *owner, const char substring[])
-{
-
- bConstraint *curcon;
- ListBase *conlist= NULL;
- int type;
-
- if (owner==NULL) return;
-
- /* Check parents */
- /* Get the constraint list for this object */
-
- if (strlen (substring)) {
- switch (owner->type) {
- case OB_ARMATURE:
- type = CONSTRAINT_OBTYPE_BONE;
- break;
- default:
- type = CONSTRAINT_OBTYPE_OBJECT;
- break;
- }
- }
- else
- type = CONSTRAINT_OBTYPE_OBJECT;
-
-
- switch (type) {
- case CONSTRAINT_OBTYPE_OBJECT:
- conlist = &owner->constraints;
- break;
- case CONSTRAINT_OBTYPE_BONE:
- {
- Bone *bone;
- bPoseChannel *chan;
-
- bone = get_named_bone( ((bArmature *)owner->data ), substring );
- chan = get_pose_channel(owner->pose, substring);
- if (bone && chan) {
- conlist = &chan->constraints;
- }
- }
- break;
- }
-
- /* Check all constraints - is constraint valid? */
- if (conlist) {
- for (curcon = conlist->first; curcon; curcon=curcon->next) {
- curcon->flag &= ~CONSTRAINT_DISABLE;
-
- switch (curcon->type) {
- case CONSTRAINT_TYPE_PYTHON:
- {
- bPythonConstraint *data = curcon->data;
-
- /* is there are valid script? */
- if (!data->text) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- else if (!BPY_is_pyconstraint(data->text)) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- /* does the constraint require target input... also validates targets */
- BPY_pyconstraint_update(owner, curcon);
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- }
- else if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- }
-
- if (data->poletar && !exist_object(data->poletar)) {
- data->poletar = NULL;
- }
- else if ( (data->poletar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->polesubtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- }
-
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = curcon->data;
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->reserved2==data->reserved1) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->reserved2+3==data->reserved1) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if (data->lockflag==data->trackflag) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->lockflag+3==data->trackflag) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->tar->type != OB_CURVE) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->upflag==data->trackflag) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->upflag+3==data->trackflag) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if (data->tar->type != OB_CURVE) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- else {
- Curve *cu= data->tar->data;
-
- /* auto-set 'Path' setting on curve so this works */
- cu->flag |= CU_PATH;
- }
- }
- break;
- case CONSTRAINT_TYPE_TRANSFORM:
- {
- bTransformConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- }
- }
- }
-}
-
-static void test_bonelist_constraints (Object *owner, ListBase *list)
-{
- Bone *bone;
-
- for (bone = list->first; bone; bone=bone->next) {
-
- test_constraints(owner, bone->name);
- test_bonelist_constraints (owner, &bone->childbase);
- }
-}
-
-void object_test_constraints (Object *owner)
-{
- test_constraints(owner, "");
-
- if(owner->type==OB_ARMATURE) {
- bArmature *arm;
- arm = get_armature(owner);
- if (arm)
- test_bonelist_constraints (owner, &arm->bonebase);
- }
-
-}
-
-/* helper function for add_constriant - sets the last target for the active constraint */
-static void set_constraint_nth_target(bConstraint *con, Object *target, char subtarget[], int index)
-{
- bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
- int num_targets, i;
-
- if (cti && cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
- num_targets= BLI_countlist(&targets);
-
- if (index < 0) {
- if (abs(index) < num_targets)
- index= num_targets - abs(index);
- else
- index= num_targets - 1;
- }
- else if (index >= num_targets) {
- index= num_targets - 1;
- }
-
- for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
- if (i == index) {
- ct->tar= target;
- strcpy(ct->subtarget, subtarget);
- break;
- }
- }
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 0);
- }
-}
-
-/* context: active object in posemode, active channel, optional selected channel */
-void add_constraint(int only_IK)
-{
- Object *ob= OBACT, *obsel=NULL;
- bPoseChannel *pchanact=NULL, *pchansel=NULL;
- bConstraint *con=NULL;
- Base *base;
- short nr;
-
- /* paranoia checks */
- if(ob==NULL || ob==G.obedit) return;
-
- if(ob->pose && (ob->flag & OB_POSEMODE)) {
- bArmature *arm= ob->data;
-
- /* find active channel */
- pchanact= get_active_posechannel(ob);
- if(pchanact==NULL) return;
-
- /* check protection */
- if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
- error("Bone is Proxy protected");
- return;
- }
-
- /* find selected bone */
- for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
- if(pchansel!=pchanact)
- if(pchansel->bone->flag & BONE_SELECTED)
- if(pchansel->bone->layer & arm->layer)
- break;
- }
- }
-
- /* find selected object */
- for(base= FIRSTBASE; base; base= base->next)
- if( TESTBASE(base) && base->object!=ob )
- obsel= base->object;
-
- /* the only_IK caller has checked for posemode! */
- if(only_IK) {
- for(con= pchanact->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
- }
- if(con) {
- error("Pose Channel already has IK");
- return;
- }
-
- if(pchansel)
- nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
- else if(obsel)
- nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
- else
- nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
- }
- else {
- if(pchanact) {
- if(pchansel)
- nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
- else if(obsel && obsel->type==OB_CURVE)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
- else if(obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
- else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
- }
- else {
- if(obsel && obsel->type==OB_CURVE)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
- else if(obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
- else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
- }
- }
-
- if(nr<1) return;
-
- /* handle IK separate */
- if(nr==10 || nr==11) {
-
- /* prevent weird chains... */
- if(pchansel) {
- bPoseChannel *pchan= pchanact;
- while(pchan) {
- if(pchan==pchansel) break;
- pchan= pchan->parent;
- }
- if(pchan) {
- error("IK root cannot be linked to IK tip");
- return;
- }
- pchan= pchansel;
- while(pchan) {
- if(pchan==pchanact) break;
- pchan= pchan->parent;
- }
- if(pchan) {
- error("IK tip cannot be linked to IK root");
- return;
- }
- }
-
- con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
- BLI_addtail(&pchanact->constraints, con);
- unique_constraint_name(con, &pchanact->constraints);
- pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
- if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
- }
- else {
-
- if (nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
- else if (nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
- else if (nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
- else if (nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
- else if (nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
- else if (nr==6) {
- Curve *cu= obsel->data;
- cu->flag |= CU_PATH;
- con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
- }
- else if (nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
- else if (nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
- else if (nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
- else if (nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
- else if (nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
- else if (nr==16) {
- /* TODO: add a popup-menu to display list of available actions to use (like for pyconstraints) */
- con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
- }
- else if (nr==17) {
- Curve *cu= obsel->data;
- cu->flag |= CU_PATH;
- con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
- }
- else if (nr==18) {
- char *menustr;
- int scriptint= 0;
-
- /* popup a list of usable scripts */
- menustr = buildmenu_pyconstraints(NULL, &scriptint);
- scriptint = pupmenu(menustr);
- MEM_freeN(menustr);
-
- /* only add constraint if a script was chosen */
- if (scriptint) {
- /* add constraint */
- con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
- validate_pyconstraint_cb(con->data, &scriptint);
-
- /* make sure target allowance is set correctly */
- BPY_pyconstraint_update(ob, con);
- }
- }
- else if (nr==19) {
- con = add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
-
- /* if this constraint is being added to a posechannel, make sure
- * the constraint gets evaluated in pose-space
- */
- if (pchanact) {
- con->ownspace = CONSTRAINT_SPACE_POSE;
- con->flag |= CONSTRAINT_SPACEONCE;
- }
- }
- else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
-
- if (con==NULL) return; /* paranoia */
-
- if (pchanact) {
- BLI_addtail(&pchanact->constraints, con);
- unique_constraint_name(con, &pchanact->constraints);
- pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
- }
- else {
- BLI_addtail(&ob->constraints, con);
- unique_constraint_name(con, &ob->constraints);
- }
- }
-
- /* set the target */
- if (pchansel) {
- set_constraint_nth_target(con, ob, pchansel->name, 0);
- }
- else if(obsel) {
- set_constraint_nth_target(con, obsel, "", 0);
- }
- else if (ELEM4(nr, 11, 13, 14, 15)==0) { /* add new empty as target */
- Base *base= BASACT, *newbase;
- Object *obt;
-
- obt= add_object(OB_EMPTY);
- /* set layers OK */
- newbase= BASACT;
- newbase->lay= base->lay;
- obt->lay= newbase->lay;
-
- /* transform cent to global coords for loc */
- if (pchanact) {
- if(only_IK)
- VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
- else
- VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
- }
- else
- VECCOPY(obt->loc, ob->obmat[3]);
-
- set_constraint_nth_target(con, obt, "", 0);
-
- /* restore, add_object sets active */
- BASACT= base;
- base->flag |= SELECT;
- }
-
- /* active flag */
- con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
- con->flag &= ~CONSTRAINT_ACTIVE;
-
- DAG_scene_sort(G.scene); // sort order of objects
-
- if (pchanact) {
- ob->pose->flag |= POSE_RECALC; // sort pose channels
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
- }
- else
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); // and all its relations
-
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
-
- if (only_IK)
- BIF_undo_push("Add IK Constraint");
- else
- BIF_undo_push("Add Constraint");
-
-}
-
-void ob_clear_constraints(void)
-{
- Object *ob= OBACT;
-
- /* paranoia checks */
- if(!ob) return;
- if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
-
- if(okee("Clear Constraints")==0) return;
-
- free_constraints(&ob->constraints);
-
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
-
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
-
- BIF_undo_push("Clear Constraint(s)");
-
-}
-
-/* con already has the new name */
-void rename_constraint(Object *ob, bConstraint *con, char *oldname)
-{
- bConstraint *tcon;
- bConstraintChannel *conchan;
- ListBase *conlist= NULL;
- int from_object= 0;
- char *channame="";
-
- /* get context by searching for con (primitive...) */
- for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
- if(tcon==con)
- break;
-
- if(tcon) {
- conlist= &ob->constraints;
- channame= "Object";
- from_object= 1;
- }
- else if(ob->pose) {
- bPoseChannel *pchan;
-
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
- if(tcon==con)
- break;
- }
- if(tcon)
- break;
- }
- if(tcon) {
- conlist= &pchan->constraints;
- channame= pchan->name;
- }
- }
-
- if(conlist==NULL) {
- printf("rename constraint failed\n"); /* should not happen in UI */
- return;
- }
-
- /* first make sure it's a unique name within context */
- unique_constraint_name (con, conlist);
-
- /* own channels */
- if(from_object) {
- for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
- if( strcmp(oldname, conchan->name)==0 )
- BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
- }
- }
- /* own action */
- if(ob->action) {
- bActionChannel *achan= get_action_channel(ob->action, channame);
- if(achan) {
- conchan= get_constraint_channel(&achan->constraintChannels, oldname);
- if(conchan)
- BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
- }
- }
-
-}
-
-/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
-/* ------------- PyConstraints ------------------ */
-
-/* this callback sets the text-file to be used for selected menu item */
-void validate_pyconstraint_cb(void *arg1, void *arg2)
-{
- bPythonConstraint *data = arg1;
- Text *text;
- int index = *((int *)arg2);
- int i;
-
- /* innovative use of a for...loop to search */
- for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
- data->text = text;
-}
-
-/* this returns a string for the list of usable pyconstraint script names */
-char *buildmenu_pyconstraints(Text *con_text, int *pyconindex)
-{
- Text *text;
- char *menustr = MEM_callocN(128, "menustr pyconstraints");
- char *name, stmp[128];
- int buf = 128;
- int used = strlen("Scripts: %t") + 1;
- int i;
-
- sprintf(menustr, "%s", "Scripts: %t");
-
- for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
- /* this is important to ensure that right script is shown as active */
- if (text == con_text) *pyconindex = i;
-
- /* menu entry is length of name + 3(len(|%X)) + 6 characters for the int.*/
- if (BPY_is_pyconstraint(text)) {
- name= text->id.name;
- if (strlen(name)+used+10 >= buf) {
- char *newbuf = MEM_callocN(buf+128, "menustr pyconstraints 2");
- memcpy(newbuf, menustr, used);
- MEM_freeN(menustr);
- menustr = newbuf;
- buf += 128;
- }
- sprintf(stmp, "|%s%%x%d", name, i);
- strcat(menustr, stmp);
- used += strlen(name)+10;
- }
- }
-
- return menustr;
-}
-
-/* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
-void update_pyconstraint_cb(void *arg1, void *arg2)
-{
- Object *owner= (Object *)arg1;
- bConstraint *con= (bConstraint *)arg2;
-
- if (owner && con)
- BPY_pyconstraint_update(owner, con);
-}
-
-/* ------------- Child-Of Constraint ------------------ */
-
-/* ChildOf Constraint - set inverse callback */
-void childof_const_setinv (void *conv, void *unused)
-{
- bChildOfConstraint *data= (bChildOfConstraint *)conv;
- Object *ob= OBACT;
- bPoseChannel *pchan= NULL;
-
- /* try to find a pose channel */
- if (ob && ob->pose)
- pchan= get_active_posechannel(ob);
-
- /* calculate/set inverse matrix */
- if (pchan) {
- bConstraintOb *cob;
- float ctime= bsystem_time(ob, (float)G.scene->r.cfra, 0.0); /* not accurate... */
- float pmat[4][4], chmat[4][4], cimat[4][4];
- float vec0[3]={0,0,0}, vec1[3]={1,1,1};
-
- /* make copies of pchan's original matrices (to be restored later) */
- Mat4CpyMat4(pmat, pchan->pose_mat);
- Mat4CpyMat4(chmat, pchan->chan_mat);
- Mat4CpyMat4(cimat, pchan->constinv);
-
-
- /* clear pchan's transform (for constraint solving) */
- LocEulSizeToMat4(pchan->chan_mat, vec0, vec0, vec1);
- Mat4MulMat4(pchan->pose_mat, pmat, cimat);
- Mat4One(pchan->constinv);
- Mat4One(data->invmat);
-
-
- /* do constraint solving on pose-matrix containing no transforms
- * N.B. code is copied from armature.c (where_is_pose_bone)
- */
- cob= constraints_make_evalob(ob, pchan, CONSTRAINT_OBTYPE_BONE);
- solve_constraints(&pchan->constraints, cob, ctime);
- constraints_clear_evalob(cob);
-
-
- /* parent-inverse matrix for this constraint is given by taking the
- * local-space (i.e. without any standard parents + restpose) pose_matrix
- * (that was calulated with no transforms applied), and inverting it.
- */
- Mat4CpyMat4(pchan->constinv, pchan->pose_mat);
-
- constraint_mat_convertspace(ob, pchan, pchan->constinv,
- CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
-
- Mat4Invert(data->invmat, pchan->constinv);
-
-
- /* restore original matrices of pchan */
- Mat4CpyMat4(pchan->pose_mat, pmat);
- Mat4CpyMat4(pchan->chan_mat, chmat);
- Mat4CpyMat4(pchan->constinv, cimat);
- }
- else if (ob) {
- /* use what_does_parent to find inverse - just like for normal parenting.
- * NOTE: what_does_parent uses a static workob defined in object.c
- */
- what_does_parent(ob);
- Mat4Invert(data->invmat, workob.obmat);
- }
- else
- Mat4One(data->invmat);
-}
-
-/* ChildOf Constraint - clear inverse callback */
-void childof_const_clearinv (void *conv, void *unused)
-{
- bChildOfConstraint *data= (bChildOfConstraint *)conv;
-
- /* simply clear the matrix */
- Mat4One(data->invmat);
-}