WIP: Animation: Select Grouped operator #104758
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_dlrbTree.h"
|
#include "BLI_dlrbTree.h"
|
||||||
|
#include "BLI_ghash.h"
|
||||||
#include "BLI_lasso_2d.h"
|
#include "BLI_lasso_2d.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
|
@ -1963,7 +1964,8 @@ static short select_grouped_datablock(KeyframeEditData *ked, struct BezTriple *b
|
||||||
|
|
||||||
static short select_grouped_active_datablock(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_active_datablock(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
/* Stop after the first selected bezt was found. */
|
/* Cancel iteration if we found any selected key. The key will be added to the set in the loop,
|
||||||
|
* since the info comes from the anim data list. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,29 +1973,32 @@ static short select_grouped_active_datablock(KeyframeEditData *ked, struct BezTr
|
||||||
|
|
||||||
static short select_grouped_handle_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_handle_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
/* TODO(redmser): Should this compare left and right handle individually? In dopesheet, you can't
|
short ok = 0;
|
||||||
* select individual handles to clarify the intent. */
|
if (BLI_gset_haskey(ked->data, POINTER_FROM_INT(bezt->h1))) {
|
||||||
char handle = *(char *)ked->data;
|
ok |= KEYFRAME_OK_H1;
|
||||||
if (bezt->h1 == handle && bezt->h2 == handle) {
|
|
||||||
return KEYFRAME_OK_ALL;
|
|
||||||
}
|
}
|
||||||
return 0;
|
if (BLI_gset_haskey(ked->data, POINTER_FROM_INT(bezt->h2))) {
|
||||||
|
ok |= KEYFRAME_OK_H2;
|
||||||
|
}
|
||||||
|
if (ok == (KEYFRAME_OK_H1 | KEYFRAME_OK_H2)) {
|
||||||
|
ok |= KEYFRAME_OK_KEY;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static short select_grouped_active_handle_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_active_handle_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
if (bezt->h1 == bezt->h2) {
|
if (bezt->h1 == bezt->h2) {
|
||||||
*((uint8_t *)ked->data) = bezt->h1;
|
BLI_gset_add(ked->data, POINTER_FROM_INT(bezt->h1));
|
||||||
}
|
}
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ACTKEYS_SELECT_GROUP_INTERPOLATION_TYPE */
|
/* ACTKEYS_SELECT_GROUP_INTERPOLATION_TYPE */
|
||||||
|
|
||||||
static short select_grouped_interpolation_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_interpolation_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
char ipo = *(char *)ked->data;
|
if (BLI_gset_haskey(ked->data, POINTER_FROM_INT(bezt->ipo))) {
|
||||||
if (bezt->ipo == ipo) {
|
|
||||||
return KEYFRAME_OK_ALL;
|
return KEYFRAME_OK_ALL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2002,16 +2007,15 @@ static short select_grouped_interpolation_type(KeyframeEditData *ked, struct Bez
|
||||||
static short select_grouped_active_interpolation_type(KeyframeEditData *ked,
|
static short select_grouped_active_interpolation_type(KeyframeEditData *ked,
|
||||||
struct BezTriple *bezt)
|
struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
*((char *)ked->data) = bezt->ipo;
|
BLI_gset_add(ked->data, POINTER_FROM_INT(bezt->ipo));
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ACTKEYS_SELECT_GROUP_KEY_TYPE */
|
/* ACTKEYS_SELECT_GROUP_KEY_TYPE */
|
||||||
|
|
||||||
static short select_grouped_key_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_key_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
char key_type = *(char *)ked->data;
|
if (BLI_gset_haskey(ked->data, POINTER_FROM_INT(BEZKEYTYPE(bezt)))) {
|
||||||
if (BEZKEYTYPE(bezt) == key_type) {
|
|
||||||
return KEYFRAME_OK_ALL;
|
return KEYFRAME_OK_ALL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2019,30 +2023,41 @@ static short select_grouped_key_type(KeyframeEditData *ked, struct BezTriple *be
|
||||||
|
|
||||||
static short select_grouped_active_key_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
static short select_grouped_active_key_type(KeyframeEditData *ked, struct BezTriple *bezt)
|
||||||
{
|
{
|
||||||
*((char *)ked->data) = BEZKEYTYPE(bezt);
|
BLI_gset_add(ked->data, POINTER_FROM_INT(BEZKEYTYPE(bezt)));
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(redmser): These filters could all allow multi-selection. Instead of setting ked->data, add
|
|
||||||
* the filter (if unique) to ked->list and do an "includes" check instead. */
|
|
||||||
|
|
||||||
static KeyframeEditFunc select_grouped_get_filter_callback(ListBase *anim_data,
|
static KeyframeEditFunc select_grouped_get_filter_callback(ListBase *anim_data,
|
||||||
KeyframeEditData *ked,
|
KeyframeEditData *ked,
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
|
KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
|
||||||
|
GSet *comp_set;
|
||||||
|
|
||||||
|
if (type == ACTKEYS_SELECT_GROUP_DATABLOCK) {
|
||||||
|
comp_set = BLI_gset_str_new(__func__);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
comp_set = BLI_gset_int_new(__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
ked->data = comp_set;
|
||||||
|
|
||||||
|
/* Last iteration of this loop will be used to return a callback based on type. */
|
||||||
bAnimListElem *ale;
|
bAnimListElem *ale;
|
||||||
for (ale = anim_data->first; ale; ale = ale->next) {
|
for (ale = anim_data->first;; ale = ale->next) {
|
||||||
/* TODO(redmser): Other types (GP, mask, etc.). */
|
FCurve *fcu;
|
||||||
if (ale->datatype != ALE_FCURVE) {
|
if (ale != NULL) {
|
||||||
continue;
|
/* TODO(redmser): Other types (GP, mask, etc.). */
|
||||||
}
|
if (ale->datatype != ALE_FCURVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only continue if F-Curve has keyframes. */
|
/* Only continue if F-Curve has keyframes. */
|
||||||
FCurve *fcu = (FCurve *)ale->key_data;
|
fcu = (FCurve *)ale->key_data;
|
||||||
if (fcu->bezt == NULL) {
|
if (fcu->bezt == NULL) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find first selected keyframe for context info. */
|
/* Find first selected keyframe for context info. */
|
||||||
|
@ -2052,33 +2067,28 @@ static KeyframeEditFunc select_grouped_get_filter_callback(ListBase *anim_data,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTKEYS_SELECT_GROUP_HANDLE_TYPE: {
|
case ACTKEYS_SELECT_GROUP_HANDLE_TYPE: {
|
||||||
char handle = 0;
|
if (ale == NULL) {
|
||||||
ked->data = &handle;
|
|
||||||
short result = ANIM_fcurve_keyframes_loop(
|
|
||||||
ked, fcu, ok_cb, select_grouped_active_handle_type, NULL);
|
|
||||||
if (result == 1) {
|
|
||||||
return select_grouped_handle_type;
|
return select_grouped_handle_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANIM_fcurve_keyframes_loop(ked, fcu, ok_cb, select_grouped_active_handle_type, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTKEYS_SELECT_GROUP_INTERPOLATION_TYPE: {
|
case ACTKEYS_SELECT_GROUP_INTERPOLATION_TYPE: {
|
||||||
char ipo = 0;
|
if (ale == NULL) {
|
||||||
ked->data = &ipo;
|
|
||||||
short result = ANIM_fcurve_keyframes_loop(
|
|
||||||
ked, fcu, ok_cb, select_grouped_active_interpolation_type, NULL);
|
|
||||||
if (result == 1) {
|
|
||||||
return select_grouped_interpolation_type;
|
return select_grouped_interpolation_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANIM_fcurve_keyframes_loop(
|
||||||
|
ked, fcu, ok_cb, select_grouped_active_interpolation_type, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTKEYS_SELECT_GROUP_KEY_TYPE: {
|
case ACTKEYS_SELECT_GROUP_KEY_TYPE: {
|
||||||
char key_type = 0;
|
if (ale == NULL) {
|
||||||
ked->data = &key_type;
|
|
||||||
short result = ANIM_fcurve_keyframes_loop(
|
|
||||||
ked, fcu, ok_cb, select_grouped_active_key_type, NULL);
|
|
||||||
if (result == 1) {
|
|
||||||
return select_grouped_key_type;
|
return select_grouped_key_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANIM_fcurve_keyframes_loop(ked, fcu, ok_cb, select_grouped_active_key_type, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTKEYS_SELECT_GROUP_MODIFIERS: {
|
case ACTKEYS_SELECT_GROUP_MODIFIERS: {
|
||||||
|
@ -2087,11 +2097,15 @@ static KeyframeEditFunc select_grouped_get_filter_callback(ListBase *anim_data,
|
||||||
}
|
}
|
||||||
case ACTKEYS_SELECT_GROUP_DATABLOCK: {
|
case ACTKEYS_SELECT_GROUP_DATABLOCK: {
|
||||||
/* Same datablock, identified by name. */
|
/* Same datablock, identified by name. */
|
||||||
|
if (ale == NULL) {
|
||||||
|
return select_grouped_datablock;
|
||||||
|
}
|
||||||
|
|
||||||
short result = ANIM_fcurve_keyframes_loop(
|
short result = ANIM_fcurve_keyframes_loop(
|
||||||
ked, fcu, ok_cb, select_grouped_active_datablock, NULL);
|
ked, fcu, ok_cb, select_grouped_active_datablock, NULL);
|
||||||
if (result == 1) {
|
if (result == 1) {
|
||||||
ked->data = ale->id->name;
|
/* Found a selected key in this datablock, add its id. */
|
||||||
return select_grouped_datablock;
|
BLI_gset_add(ked->data, BLI_strdup(ale->id->name));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2102,10 +2116,6 @@ static KeyframeEditFunc select_grouped_get_filter_callback(ListBase *anim_data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ACTKEYS_SELECT_GROUP_DATABLOCK) {
|
|
||||||
char empty[1] = {'\0'};
|
|
||||||
ked->data = empty;
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2157,7 +2167,7 @@ static int actkeys_select_grouped_exec(bContext *C, wmOperator *op)
|
||||||
/* Filtering by datablock has to be done on anim data level. */
|
/* Filtering by datablock has to be done on anim data level. */
|
||||||
/* TODO(redmser): This will not work for datablocks from different libraries, since they have
|
/* TODO(redmser): This will not work for datablocks from different libraries, since they have
|
||||||
* the same name. */
|
* the same name. */
|
||||||
if (type == ACTKEYS_SELECT_GROUP_DATABLOCK && !STREQ(ale->id->name, (char *)ked.data)) {
|
if (type == ACTKEYS_SELECT_GROUP_DATABLOCK && !BLI_gset_haskey(ked.data, ale->id->name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2166,6 +2176,13 @@ static int actkeys_select_grouped_exec(bContext *C, wmOperator *op)
|
||||||
|
|
||||||
ANIM_animdata_freelist(&anim_data);
|
ANIM_animdata_freelist(&anim_data);
|
||||||
|
|
||||||
|
if (type == ACTKEYS_SELECT_GROUP_DATABLOCK) {
|
||||||
|
BLI_gset_free(ked.data, MEM_freeN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_gset_free(ked.data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue