/* Selects all visible keyframes in the same frames as the specified elements */ static void columnselect_action_keys(bAnimContext *ac, short mode) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; Scene *scene = ac->scene; CfraElem *ce; KeyframeEditFunc select_cb, ok_cb; KeyframeEditData ked = {{NULL}}; /* initialize keyframe editing data */ /* build list of columns */ switch (mode) { case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */ if (ac->datatype == ANIMCONT_GPENCIL) { filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) ED_gplayer_make_cfra_list(ale->data, &ked.list, 1); } else { filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL); } BLI_freelistN(&anim_data); break; case ACTKEYS_COLUMNSEL_CFRA: /* current frame */ /* make a single CfraElem for storing this */ ce = MEM_callocN(sizeof(CfraElem), "cfraElem"); BLI_addtail(&ked.list, ce); ce->cfra = (float)CFRA; break; case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */ ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT); break; default: /* invalid option */ return; } /* set up BezTriple edit callbacks */ select_cb = ANIM_editkeyframes_select(SELECT_ADD); ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME); /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* loop over cfraelems (stored in the KeyframeEditData->list) * - we need to do this here, as we can apply fewer NLA-mapping conversions */ for (ce = ked.list.first; ce; ce = ce->next) { /* set frame for validation callback to refer to */ if (adt) ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP); else ked.f1 = ce->cfra; /* select elements with frame number matching cfraelem */ if (ale->type == ANIMTYPE_GPLAYER) ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD); else if (ale->type == ANIMTYPE_MASKLAYER) ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } } /* free elements */ BLI_freelistN(&ked.list); BLI_freelistN(&anim_data); }
static int pose_propagate_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bAction *act = (ob && ob->adt) ? ob->adt->action : NULL; ListBase pflinks = {NULL, NULL}; tPChanFCurveLink *pfl; tPosePropagate_ModeData modeData; const int mode = RNA_enum_get(op->ptr, "mode"); /* sanity checks */ if (ob == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to propagate poses for"); return OPERATOR_CANCELLED; } if (act == NULL) { BKE_report(op->reports, RPT_ERROR, "No keyframed poses to propagate to"); return OPERATOR_CANCELLED; } /* isolate F-Curves related to the selected bones */ poseAnim_mapping_get(C, &pflinks, ob, act); /* mode-specific data preprocessing (requiring no access to curves) */ if (mode == POSE_PROPAGATE_SELECTED_MARKERS) { /* get a list of selected markers */ ED_markers_make_cfra_list(&scene->markers, &modeData.sel_markers, SELECT); } else { /* assume everything else wants endFrame */ modeData.end_frame = RNA_float_get(op->ptr, "end_frame"); } /* for each bone, perform the copying required */ for (pfl = pflinks.first; pfl; pfl = pfl->next) { LinkData *ld; /* mode-specific data preprocessing (requiring access to all curves) */ if (mode == POSE_PROPAGATE_SMART_HOLDS) { /* we store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting * from the keyframe that occurs after the current frame */ modeData.end_frame = pose_propagate_get_boneHoldEndFrame(ob, pfl, (float)CFRA); } /* go through propagating pose to keyframes, curve by curve */ for (ld = pfl->fcurves.first; ld; ld = ld->next) pose_propagate_fcurve(op, ob, (FCurve *)ld->data, (float)CFRA, modeData); } /* free temp data */ poseAnim_mapping_free(&pflinks); if (mode == POSE_PROPAGATE_SELECTED_MARKERS) BLI_freelistN(&modeData.sel_markers); /* updates + notifiers */ poseAnim_mapping_refresh(C, scene, ob); return OPERATOR_FINISHED; }