static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList *reports) { /* TODO: enable access to providing a list of overrides (dsources)? */ int success = ANIM_validate_keyingset(C, NULL, ks); if (success != 0) { switch (success) { case MODIFYKEY_INVALID_CONTEXT: BKE_report(reports, RPT_ERROR, "Invalid context for Keying Set"); break; case MODIFYKEY_MISSING_TYPEINFO: BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set. Appears to be missing type info"); break; } } }
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets. * Returns the number of channels that keyframes were added to */ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra) { Scene *scene = CTX_data_scene(C); ReportList *reports = CTX_wm_reports(C); KS_Path *ksp; int kflag = 0, success = 0; char *groupname = NULL; /* sanity checks */ if (ks == NULL) return 0; /* get flags to use */ if (mode == MODIFYKEY_MODE_INSERT) { /* use KeyingSet's flags as base */ kflag = ks->keyingflag; /* suppliment with info from the context */ kflag |= ANIM_get_keyframing_flags(scene, 1); } else if (mode == MODIFYKEY_MODE_DELETE) kflag = 0; /* if relative Keying Sets, poll and build up the paths */ success = ANIM_validate_keyingset(C, dsources, ks); if (success != 0) { /* return error code if failed */ return success; } /* apply the paths as specified in the KeyingSet now */ for (ksp = ks->paths.first; ksp; ksp = ksp->next) { int arraylen, i; short kflag2; /* skip path if no ID pointer is specified */ if (ksp->id == NULL) { BKE_reportf(reports, RPT_WARNING, "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')", ks->name, ksp->rna_path, ksp->array_index); continue; } /* since keying settings can be defined on the paths too, extend the path before using it */ kflag2 = (kflag | ksp->keyingflag); /* get pointer to name of group to add channels to */ if (ksp->groupmode == KSP_GROUP_NONE) groupname = NULL; else if (ksp->groupmode == KSP_GROUP_KSNAME) groupname = ks->name; else groupname = ksp->group; /* init arraylen and i - arraylen should be greater than i so that * normal non-array entries get keyframed correctly */ i = ksp->array_index; arraylen = i; /* get length of array if whole array option is enabled */ if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) { PointerRNA id_ptr, ptr; PropertyRNA *prop; RNA_id_pointer_create(ksp->id, &id_ptr); if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) arraylen = RNA_property_array_length(&ptr, prop); } /* we should do at least one step */ if (arraylen == i) arraylen++; /* for each possible index, perform operation * - assume that arraylen is greater than index */ for (; i < arraylen; i++) { /* action to take depends on mode */ if (mode == MODIFYKEY_MODE_INSERT) success += insert_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2); else if (mode == MODIFYKEY_MODE_DELETE) success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2); } /* set recalc-flags */ switch (GS(ksp->id->name)) { case ID_OB: /* Object (or Object-Related) Keyframes */ { Object *ob = (Object *)ksp->id; // XXX: only object transforms? DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; } } /* send notifiers for updates (this doesn't require context to work!) */ WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } /* return the number of channels successfully affected */ return success; }