/* helper for time_draw_keyframes() */ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel) { bDopeSheet ads = {NULL}; DLRBT_Tree keys; ActKeyColumn *ak; float fac1 = (GS(id->name) == ID_GD) ? 0.8f : 0.6f; /* draw GPencil keys taller, to help distinguish them */ float fac2 = 1.0f - fac1; float ymin = v2d->tot.ymin; float ymax = v2d->tot.ymax * fac1 + ymin * fac2; /* init binarytree-list for getting keyframes */ BLI_dlrbTree_init(&keys); /* init dopesheet settings */ if (onlysel) ads.filterflag |= ADS_FILTER_ONLYSEL; /* populate tree with keyframe nodes */ switch (GS(id->name)) { case ID_SCE: scene_to_keylist(&ads, (Scene *)id, &keys, NULL); break; case ID_OB: ob_to_keylist(&ads, (Object *)id, &keys, NULL); break; case ID_GD: gpencil_to_keylist(&ads, (bGPdata *)id, &keys); break; case ID_CF: cachefile_to_keylist(&ads, (CacheFile *)id, &keys, NULL); break; default: break; } /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); /* start drawing keyframes * - we use the binary-search capabilities of the tree to only start from * the first visible keyframe (last one can then be easily checked) * - draw within a single GL block to be faster */ glBegin(GL_LINES); for (ak = time_cfra_find_ak(keys.root, v2d->cur.xmin); (ak) && (ak->cfra <= v2d->cur.xmax); ak = ak->next) { glVertex2f(ak->cfra, ymin); glVertex2f(ak->cfra, ymax); } glEnd(); // GL_LINES /* free temp stuff */ BLI_dlrbTree_free(&keys); }
void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos) { DLRBT_Tree keys; BLI_dlrbTree_init(&keys); gpencil_to_keylist(ads, gpd, &keys); BLI_dlrbTree_linkedlist_sync(&keys); draw_keylist(v2d, &keys, NULL, ypos, 0); BLI_dlrbTree_free(&keys); }
static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prevfra) { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); bGPdata *gpd = CTX_data_gpencil_data(C); Mask *mask = CTX_data_edit_mask(C); bDopeSheet ads = {NULL}; DLRBT_Tree keys; ActKeyColumn *aknext, *akprev; float cfranext, cfraprev; bool donenext = false, doneprev = false; int nextcount = 0, prevcount = 0; cfranext = cfraprev = (float)(CFRA); /* init binarytree-list for getting keyframes */ BLI_dlrbTree_init(&keys); /* seed up dummy dopesheet context with flags to perform necessary filtering */ if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) { /* only selected channels are included */ ads.filterflag |= ADS_FILTER_ONLYSEL; } /* populate tree with keyframe nodes */ scene_to_keylist(&ads, scene, &keys, NULL); if (ob) ob_to_keylist(&ads, ob, &keys, NULL); gpencil_to_keylist(&ads, gpd, &keys); if (mask) { MaskLayer *masklay = BKE_mask_layer_active(mask); mask_to_keylist(&ads, masklay, &keys); } /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); /* find matching keyframe in the right direction */ do { aknext = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfranext); if (aknext) { if (CFRA == (int)aknext->cfra) { /* make this the new starting point for the search and ignore */ cfranext = aknext->cfra; } else { /* this changes the frame, so set the frame and we're done */ if (++nextcount == U.view_frame_keyframes) donenext = true; } cfranext = aknext->cfra; } } while ((aknext != NULL) && (donenext == false)); do { akprev = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfraprev); if (akprev) { if (CFRA == (int)akprev->cfra) { /* make this the new starting point for the search */ } else { /* this changes the frame, so set the frame and we're done */ if (++prevcount == U.view_frame_keyframes) doneprev = true; } cfraprev = akprev->cfra; } } while ((akprev != NULL) && (doneprev == false)); /* free temp stuff */ BLI_dlrbTree_free(&keys); /* any success? */ if (doneprev || donenext) { if (doneprev) *prevfra = cfraprev; else *prevfra = CFRA - (cfranext - CFRA); if (donenext) *nextfra = cfranext; else *nextfra = CFRA + (CFRA - cfraprev); return true; } return false; }