static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt, BezTriple *beztn) { ActKeyBlock *new_ab = NULL; BezTriple *prev = NULL; /* get the BezTriple immediately before the given one which has the same value */ if (beztn != first_bezt) { /* XXX: Unless I'm overlooking some details from the past, this should be sufficient? * The old code did some elaborate stuff trying to find keyframe columns for * the given BezTriple, then step backwards to the column before that, and find * an appropriate BezTriple with matching values there. Maybe that was warranted * in the past, but now, that list is only ever filled with keyframes from the * current FCurve. * * -- Aligorith (20140415) */ prev = beztn - 1; } /* check if block needed - same value(s)? * -> firstly, handles must have same central value as each other * -> secondly, handles which control that section of the curve must be constant */ if (prev == NULL) return; if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return; if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return; if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return; /* if there are no blocks already, just add as root */ if (blocks->root == NULL) { /* just add this as the root, then call the tree-balancing functions to validate */ new_ab = bezts_to_new_actkeyblock(prev, beztn); blocks->root = (DLRBT_Node *)new_ab; } else { ActKeyBlock *ab, *abn = NULL; /* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there * Note: we perform a tree traversal here NOT a standard linked-list traversal... * Note: we can't search from end to try to optimize this as it causes errors there's * an A ___ B |---| B situation */ // FIXME: here there is a bug where we are trying to get the summary for the following channels // A|--------------|A ______________ B|--------------|B // A|------------------------------------------------|A // A|----|A|---|A|-----------------------------------|A for (ab = blocks->root; ab; ab = abn) { /* check if this is a match, or whether we go left or right * NOTE: we now use a float threshold to prevent precision errors causing problems with summaries */ if (IS_EQT(ab->start, prev->vec[1][0], BEZT_BINARYSEARCH_THRESH)) { /* set selection status and 'touched' status */ if (BEZSELECTED(beztn)) ab->sel = SELECT; ab->modified++; /* done... no need to insert */ return; } else { ActKeyBlock **abnp = NULL; /* branch to go down - used to hook new blocks to parents */ /* check if go left or right, but if not available, add new node */ if (ab->start < prev->vec[1][0]) abnp = &ab->right; else abnp = &ab->left; /* if this does not exist, add a new node, otherwise continue... */ if (*abnp == NULL) { /* add a new node representing this, and attach it to the relevant place */ new_ab = bezts_to_new_actkeyblock(prev, beztn); new_ab->parent = ab; *abnp = new_ab; break; } else abn = *abnp; } } } /* now, balance the tree taking into account this newly added node */ BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab); }
static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, FCurve *fcu, int index) { ActKeyBlock *new_ab= NULL; BezTriple *beztn=NULL, *prev=NULL; BezTriple *bezt; int v; /* get beztriples */ beztn= (fcu->bezt + index); /* we need to go through all beztriples, as they may not be in order (i.e. during transform) */ // TODO: this seems to be a bit of a bottleneck for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) { /* skip if beztriple is current */ if (v != index) { /* check if beztriple is immediately before */ if (beztn->vec[1][0] > bezt->vec[1][0]) { /* check if closer than previous was */ if (prev) { if (prev->vec[1][0] < bezt->vec[1][0]) prev= bezt; } else { prev= bezt; } } } } /* check if block needed - same value(s)? * -> firstly, handles must have same central value as each other * -> secondly, handles which control that section of the curve must be constant */ if ((!prev) || (!beztn)) return; if (IS_EQ(beztn->vec[1][1], prev->vec[1][1])==0) return; if (IS_EQ(beztn->vec[1][1], beztn->vec[0][1])==0) return; if (IS_EQ(prev->vec[1][1], prev->vec[2][1])==0) return; /* if there are no blocks already, just add as root */ if (blocks->root == NULL) { /* just add this as the root, then call the tree-balancing functions to validate */ new_ab= bezts_to_new_actkeyblock(prev, beztn); blocks->root= (DLRBT_Node *)new_ab; } else { ActKeyBlock *ab, *abp=NULL, *abn=NULL; /* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there * Note: we can't search from end to try to optimise this as it causes errors there's * an A ___ B |---| B situation */ // FIXME: here there is a bug where we are trying to get the summary for the following channels // A|--------------|A ______________ B|--------------|B // A|------------------------------------------------|A // A|----|A|---|A|-----------------------------------|A for (ab= blocks->root; ab; abp= ab, ab= abn) { /* check if this is a match, or whether we go left or right */ if (ab->start == prev->vec[1][0]) { /* set selection status and 'touched' status */ if (BEZSELECTED(beztn)) ab->sel = SELECT; ab->modified += 1; /* done... no need to insert */ return; } else { ActKeyBlock **abnp= NULL; /* check if go left or right, but if not available, add new node */ if (ab->start < prev->vec[1][0]) abnp= &ab->right; else abnp= &ab->left; /* if this does not exist, add a new node, otherwise continue... */ if (*abnp == NULL) { /* add a new node representing this, and attach it to the relevant place */ new_ab= bezts_to_new_actkeyblock(prev, beztn); new_ab->parent= ab; *abnp= new_ab; break; } else abn= *abnp; } } } /* now, balance the tree taking into account this newly added node */ BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab); }