/* Creates a new constraint, initialises its data, and returns it */ 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; /* 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); /* set the name based on the type of constraint */ strcpy(con->name, cti->name); } else strcpy(con->name, "Const"); return con; }
/* 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); } }
/* 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 */ 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; /* Get the constraint list for this 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) { bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* clear disabled-flag first */ curcon->flag &= ~CONSTRAINT_DISABLE; if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) { bKinematicConstraint *data = curcon->data; /* bad: we need a separate set of checks here as poletarget is * optional... otherwise poletarget must exist too or else * the constraint is deemed invalid */ /* default IK check ... */ if (exist_object(data->tar) == 0) { data->tar = NULL; curcon->flag |= CONSTRAINT_DISABLE; } else if (data->tar == owner) { if (!get_named_bone(get_armature(owner), data->subtarget)) { curcon->flag |= CONSTRAINT_DISABLE; } } if (data->poletar) { if (exist_object(data->poletar) == 0) { data->poletar = NULL; curcon->flag |= CONSTRAINT_DISABLE; } else if (data->poletar == owner) { if (!get_named_bone(get_armature(owner), data->polesubtarget)) { curcon->flag |= CONSTRAINT_DISABLE; } } } /* ... can be overwritten here */ BIK_test_constraint(owner, curcon); /* targets have already been checked for this */ continue; } else if (curcon->type == CONSTRAINT_TYPE_ACTION) { bActionConstraint *data = curcon->data; /* validate action */ if (data->act == NULL) curcon->flag |= CONSTRAINT_DISABLE; } else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) { bFollowPathConstraint *data = curcon->data; /* don't allow track/up axes to be the same */ if (data->upflag==data->trackflag) curcon->flag |= CONSTRAINT_DISABLE; if (data->upflag+3==data->trackflag) curcon->flag |= CONSTRAINT_DISABLE; } else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) { bTrackToConstraint *data = curcon->data; /* don't allow track/up axes to be the same */ if (data->reserved2==data->reserved1) curcon->flag |= CONSTRAINT_DISABLE; if (data->reserved2+3==data->reserved1) curcon->flag |= CONSTRAINT_DISABLE; } else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) { bLockTrackConstraint *data = curcon->data; if (data->lockflag==data->trackflag) curcon->flag |= CONSTRAINT_DISABLE; if (data->lockflag+3==data->trackflag) curcon->flag |= CONSTRAINT_DISABLE; } /* Check targets for constraints */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(curcon, &targets); /* disable and clear constraints targets that are incorrect */ for (ct= targets.first; ct; ct= ct->next) { /* general validity checks (for those constraints that need this) */ if (exist_object(ct->tar) == 0) { ct->tar = NULL; curcon->flag |= CONSTRAINT_DISABLE; } else if (ct->tar == owner) { if (!get_named_bone(get_armature(owner), ct->subtarget)) { curcon->flag |= CONSTRAINT_DISABLE; } } /* target checks for specific constraints */ if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) { if (ct->tar) { if (ct->tar->type != OB_CURVE) { ct->tar= NULL; curcon->flag |= CONSTRAINT_DISABLE; } else { Curve *cu= ct->tar->data; /* auto-set 'Path' setting on curve so this works */ cu->flag |= CU_PATH; } } } } /* free any temporary targets */ if (cti->flush_constraint_targets) cti->flush_constraint_targets(curcon, &targets, 0); } } } }
void BKE_movieclip_unlink(Main *bmain, MovieClip *clip) { bScreen *scr; ScrArea *area; SpaceLink *sl; Scene *sce; Object *ob; for (scr = bmain->screen.first; scr; scr = scr->id.next) { for (area = scr->areabase.first; area; area = area->next) { for (sl = area->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_CLIP) { SpaceClip *sc = (SpaceClip *) sl; if (sc->clip == clip) sc->clip = NULL; } else if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *) sl; BGpic *bgpic; for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { if (bgpic->clip == clip) bgpic->clip = NULL; } } } } } for (sce = bmain->scene.first; sce; sce = sce->id.next) { if (sce->clip == clip) sce->clip = NULL; } for (ob = bmain->object.first; ob; ob = ob->id.next) { bConstraint *con; for (con = ob->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = constraint_get_typeinfo(con); if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) { bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data; if (data->clip == clip) data->clip = NULL; } else if (cti->type == CONSTRAINT_TYPE_CAMERASOLVER) { bCameraSolverConstraint *data = (bCameraSolverConstraint *) con->data; if (data->clip == clip) data->clip = NULL; } else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = (bObjectSolverConstraint *) con->data; if (data->clip == clip) data->clip = NULL; } } } clip->id.us = 0; }