static FCurve *rna_Driver_from_existing(AnimData *adt, bContext *C, FCurve *src_driver) { /* verify that we've got a driver to duplicate */ if (ELEM(NULL, src_driver, src_driver->driver)) { BKE_report(CTX_wm_reports(C), RPT_ERROR, "No valid driver data to create copy of"); return NULL; } else { /* just make a copy of the existing one and add to self */ FCurve *new_fcu = copy_fcurve(src_driver); /* XXX: if we impose any ordering on these someday, this will be problematic */ BLI_addtail(&adt->drivers, new_fcu); return new_fcu; } }
/* Main Driver Management API calls: * Make a copy of the driver for the specified property on the given ID block */ bool ANIM_copy_driver( ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag)) { PointerRNA id_ptr, ptr; PropertyRNA *prop; FCurve *fcu; /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) { BKE_reportf(reports, RPT_ERROR, "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, " "path = %s)", id->name, rna_path); return 0; } /* try to get F-Curve with Driver */ fcu = verify_driver_fcurve(id, rna_path, array_index, 0); /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */ ANIM_drivers_copybuf_free(); /* copy this to the copy/paste buf if it exists */ if (fcu && fcu->driver) { /* Make copies of some info such as the rna_path, then clear this info from the * F-Curve temporarily so that we don't end up wasting memory storing the path * which won't get used ever. */ char *tmp_path = fcu->rna_path; fcu->rna_path = NULL; /* make a copy of the F-Curve with */ channeldriver_copypaste_buf = copy_fcurve(fcu); /* restore the path */ fcu->rna_path = tmp_path; /* copied... */ return 1; } /* done */ return 0; }
bAction *BKE_action_copy(Main *bmain, bAction *src) { bAction *dst = NULL; bActionGroup *dgrp, *sgrp; FCurve *dfcu, *sfcu; if (src == NULL) return NULL; dst = BKE_libblock_copy(bmain, &src->id); /* duplicate the lists of groups and markers */ BLI_duplicatelist(&dst->groups, &src->groups); BLI_duplicatelist(&dst->markers, &src->markers); /* copy F-Curves, fixing up the links as we go */ BLI_listbase_clear(&dst->curves); for (sfcu = src->curves.first; sfcu; sfcu = sfcu->next) { /* duplicate F-Curve */ dfcu = copy_fcurve(sfcu); BLI_addtail(&dst->curves, dfcu); /* fix group links (kindof bad list-in-list search, but this is the most reliable way) */ for (dgrp = dst->groups.first, sgrp = src->groups.first; dgrp && sgrp; dgrp = dgrp->next, sgrp = sgrp->next) { if (sfcu->grp == sgrp) { dfcu->grp = dgrp; if (dgrp->channels.first == sfcu) dgrp->channels.first = dfcu; if (dgrp->channels.last == sfcu) dgrp->channels.last = dfcu; break; } } } BKE_id_copy_ensure_local(bmain, &src->id, &dst->id); return dst; }