Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert.c
| Show First 20 Lines • Show All 915 Lines • ▼ Show 20 Lines | typedef struct tRetainedKeyframe { | ||||
| struct tRetainedKeyframe *next, *prev; | struct tRetainedKeyframe *next, *prev; | ||||
| float frame; /* frame to cluster around */ | float frame; /* frame to cluster around */ | ||||
| float val; /* average value */ | float val; /* average value */ | ||||
| size_t tot_count; /* number of keyframes that have been averaged */ | size_t tot_count; /* number of keyframes that have been averaged */ | ||||
| size_t del_count; /* number of keyframes of this sort that have been deleted so far */ | size_t del_count; /* number of keyframes of this sort that have been deleted so far */ | ||||
| } tRetainedKeyframe; | } tRetainedKeyframe; | ||||
| /* Called during special_aftertrans_update to make sure selected keyframes replace | /** | ||||
| * Called during special_aftertrans_update to make sure selected keyframes replace | |||||
| * any other keyframes which may reside on that frame (that is not selected). | * any other keyframes which may reside on that frame (that is not selected). | ||||
| */ | * | ||||
| static void posttrans_fcurve_clean(FCurve *fcu, const bool use_handle) | * \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`, | ||||
| * but may want to use a different one at times (if caller does not operate on | |||||
| * selection). | |||||
| */ | |||||
| static void posttrans_fcurve_clean(FCurve *fcu, | |||||
| const eBezTriple_Flag sel_flag, | |||||
| const bool use_handle) | |||||
| { | { | ||||
| /* NOTE: We assume that all keys are sorted */ | /* NOTE: We assume that all keys are sorted */ | ||||
| ListBase retained_keys = {NULL, NULL}; | ListBase retained_keys = {NULL, NULL}; | ||||
| const bool can_average_points = ((fcu->flag & (FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES)) == | const bool can_average_points = ((fcu->flag & (FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES)) == | ||||
| 0); | 0); | ||||
| /* sanity checks */ | /* sanity checks */ | ||||
| if ((fcu->totvert == 0) || (fcu->bezt == NULL)) { | if ((fcu->totvert == 0) || (fcu->bezt == NULL)) { | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | for (tRetainedKeyframe *rk = retained_keys.last; rk; rk = rk->prev) { | ||||
| /* Stop the RK search... we've found our match now */ | /* Stop the RK search... we've found our match now */ | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* 3) Recalculate handles */ | /* 3) Recalculate handles */ | ||||
| testhandles_fcurve(fcu, use_handle); | testhandles_fcurve(fcu, sel_flag, use_handle); | ||||
| /* cleanup */ | /* cleanup */ | ||||
| BLI_freelistN(&retained_keys); | BLI_freelistN(&retained_keys); | ||||
| } | } | ||||
| /* Called by special_aftertrans_update to make sure selected keyframes replace | /* Called by special_aftertrans_update to make sure selected keyframes replace | ||||
| * any other keyframes which may reside on that frame (that is not selected). | * any other keyframes which may reside on that frame (that is not selected). | ||||
| * remake_action_ipos should have already been called | * remake_action_ipos should have already been called | ||||
| Show All 11 Lines | static void posttrans_action_clean(bAnimContext *ac, bAction *act) | ||||
| /* loop through relevant data, removing keyframes as appropriate | /* loop through relevant data, removing keyframes as appropriate | ||||
| * - all keyframes are converted in/out of global time | * - all keyframes are converted in/out of global time | ||||
| */ | */ | ||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| AnimData *adt = ANIM_nla_mapping_get(ac, ale); | AnimData *adt = ANIM_nla_mapping_get(ac, ale); | ||||
| if (adt) { | if (adt) { | ||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0); | ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0); | ||||
| posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */ | posttrans_fcurve_clean(ale->key_data, SELECT, false); /* only use handles in graph editor */ | ||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0); | ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0); | ||||
| } | } | ||||
| else { | else { | ||||
| posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */ | posttrans_fcurve_clean(ale->key_data, SELECT, false); /* only use handles in graph editor */ | ||||
| } | } | ||||
| } | } | ||||
| /* free temp data */ | /* free temp data */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| } | } | ||||
| /* ********************* GRAPH EDITOR ************************* */ | /* ********************* GRAPH EDITOR ************************* */ | ||||
| /* struct for use in re-sorting BezTriples during Graph Editor transform */ | /* struct for use in re-sorting BezTriples during Graph Editor transform */ | ||||
| typedef struct BeztMap { | typedef struct BeztMap { | ||||
| BezTriple *bezt; | BezTriple *bezt; | ||||
| unsigned int oldIndex; /* index of bezt in fcu->bezt array before sorting */ | unsigned int oldIndex; /* index of bezt in fcu->bezt array before sorting */ | ||||
| unsigned int newIndex; /* index of bezt in fcu->bezt array after sorting */ | unsigned int newIndex; /* index of bezt in fcu->bezt array after sorting */ | ||||
| short swapHs; /* swap order of handles (-1=clear; 0=not checked, 1=swap) */ | short swapHs; /* swap order of handles (-1=clear; 0=not checked, 1=swap) */ | ||||
| char pipo, cipo; /* interpolation of current and next segments */ | char pipo, cipo; /* interpolation of current and next segments */ | ||||
| } BeztMap; | } BeztMap; | ||||
| /* This function converts an FCurve's BezTriple array to a BeztMap array | /* This function converts an FCurve's BezTriple array to a BeztMap array | ||||
| * NOTE: this allocates memory that will need to get freed later | * NOTE: this allocates memory that will need to get freed later | ||||
| */ | */ | ||||
| static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert, const short UNUSED(use_handle)) | static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert) | ||||
| { | { | ||||
| BezTriple *bezt = bezts; | BezTriple *bezt = bezts; | ||||
| BezTriple *prevbezt = NULL; | BezTriple *prevbezt = NULL; | ||||
| BeztMap *bezm, *bezms; | BeztMap *bezm, *bezms; | ||||
| int i; | int i; | ||||
| /* allocate memory for this array */ | /* allocate memory for this array */ | ||||
| if (totvert == 0 || bezts == NULL) { | if (totvert == 0 || bezts == NULL) { | ||||
| Show All 11 Lines | for (i = 0; i < totvert; i++, bezm++, prevbezt = bezt, bezt++) { | ||||
| bezm->pipo = (prevbezt) ? prevbezt->ipo : bezt->ipo; | bezm->pipo = (prevbezt) ? prevbezt->ipo : bezt->ipo; | ||||
| bezm->cipo = bezt->ipo; | bezm->cipo = bezt->ipo; | ||||
| } | } | ||||
| return bezms; | return bezms; | ||||
| } | } | ||||
| /* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */ | /* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */ | ||||
| static void sort_time_beztmaps(BeztMap *bezms, int totvert, const short UNUSED(use_handle)) | static void sort_time_beztmaps(BeztMap *bezms, int totvert) | ||||
| { | { | ||||
| BeztMap *bezm; | BeztMap *bezm; | ||||
| int i, ok = 1; | int i, ok = 1; | ||||
| /* keep repeating the process until nothing is out of place anymore */ | /* keep repeating the process until nothing is out of place anymore */ | ||||
| while (ok) { | while (ok) { | ||||
| ok = 0; | ok = 0; | ||||
| Show All 28 Lines | while (i--) { | ||||
| } | } | ||||
| bezm++; | bezm++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* This function firstly adjusts the pointers that the transdata has to each BezTriple */ | /* This function firstly adjusts the pointers that the transdata has to each BezTriple */ | ||||
| static void beztmap_to_data( | static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert) | ||||
| TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle)) | |||||
| { | { | ||||
| BezTriple *bezts = fcu->bezt; | BezTriple *bezts = fcu->bezt; | ||||
| BeztMap *bezm; | BeztMap *bezm; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| TransData *td; | TransData *td; | ||||
| int i, j; | int i, j; | ||||
| char *adjusted; | char *adjusted; | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | void remake_graph_transdata(TransInfo *t, ListBase *anim_data) | ||||
| for (ale = anim_data->first; ale; ale = ale->next) { | for (ale = anim_data->first; ale; ale = ale->next) { | ||||
| FCurve *fcu = (FCurve *)ale->key_data; | FCurve *fcu = (FCurve *)ale->key_data; | ||||
| if (fcu->bezt) { | if (fcu->bezt) { | ||||
| BeztMap *bezm; | BeztMap *bezm; | ||||
| /* adjust transform-data pointers */ | /* adjust transform-data pointers */ | ||||
| /* note, none of these functions use 'use_handle', it could be removed */ | /* note, none of these functions use 'use_handle', it could be removed */ | ||||
| bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert, use_handle); | bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert); | ||||
| sort_time_beztmaps(bezm, fcu->totvert, use_handle); | sort_time_beztmaps(bezm, fcu->totvert); | ||||
| beztmap_to_data(t, fcu, bezm, fcu->totvert, use_handle); | beztmap_to_data(t, fcu, bezm, fcu->totvert); | ||||
| /* free mapping stuff */ | /* free mapping stuff */ | ||||
| MEM_freeN(bezm); | MEM_freeN(bezm); | ||||
| /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */ | /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */ | ||||
| sort_time_fcurve(fcu); | sort_time_fcurve(fcu); | ||||
| /* make sure handles are all set correctly */ | /* make sure handles are all set correctly */ | ||||
| testhandles_fcurve(fcu, use_handle); | testhandles_fcurve(fcu, BEZT_FLAG_TEMP_TAG, use_handle); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* *********************** Transform data ******************* */ | /* *********************** Transform data ******************* */ | ||||
| /* Little helper function for ObjectToTransData used to give certain | /* Little helper function for ObjectToTransData used to give certain | ||||
| * constraints (ChildOf, FollowPath, and others that may be added) | * constraints (ChildOf, FollowPath, and others that may be added) | ||||
| ▲ Show 20 Lines • Show All 661 Lines • ▼ Show 20 Lines | if (ELEM(ac.datatype, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY, ANIMCONT_TIMELINE)) { | ||||
| * 2) canceled == 0 -> user confirmed the transform, | * 2) canceled == 0 -> user confirmed the transform, | ||||
| * so duplicates should be removed | * so duplicates should be removed | ||||
| * 3) canceled + duplicate -> user canceled the transform, | * 3) canceled + duplicate -> user canceled the transform, | ||||
| * but we made duplicates, so get rid of these | * but we made duplicates, so get rid of these | ||||
| */ | */ | ||||
| if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { | if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { | ||||
| if (adt) { | if (adt) { | ||||
| ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); | ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); | ||||
| posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */ | posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ | ||||
| ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); | ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); | ||||
| } | } | ||||
| else { | else { | ||||
| posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */ | posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */ | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* free temp memory */ | /* free temp memory */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| } | } | ||||
| else if (ac.datatype == ANIMCONT_ACTION) { // TODO: just integrate into the above... | else if (ac.datatype == ANIMCONT_ACTION) { // TODO: just integrate into the above... | ||||
| ▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | if (ac.datatype) { | ||||
| * 2) canceled == 0 -> user confirmed the transform, | * 2) canceled == 0 -> user confirmed the transform, | ||||
| * so duplicates should be removed | * so duplicates should be removed | ||||
| * 3) canceled + duplicate -> user canceled the transform, | * 3) canceled + duplicate -> user canceled the transform, | ||||
| * but we made duplicates, so get rid of these | * but we made duplicates, so get rid of these | ||||
| */ | */ | ||||
| if ((sipo->flag & SIPO_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { | if ((sipo->flag & SIPO_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) { | ||||
| if (adt) { | if (adt) { | ||||
| ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); | ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); | ||||
| posttrans_fcurve_clean(fcu, use_handle); | posttrans_fcurve_clean(fcu, BEZT_FLAG_TEMP_TAG, use_handle); | ||||
| ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); | ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); | ||||
| } | } | ||||
| else { | else { | ||||
| posttrans_fcurve_clean(fcu, use_handle); | posttrans_fcurve_clean(fcu, BEZT_FLAG_TEMP_TAG, use_handle); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* free temp memory */ | /* free temp memory */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 626 Lines • Show Last 20 Lines | |||||