Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation/anim_keyframes_draw.c')
-rw-r--r--source/blender/editors/animation/anim_keyframes_draw.c701
1 files changed, 701 insertions, 0 deletions
diff --git a/source/blender/editors/animation/anim_keyframes_draw.c b/source/blender/editors/animation/anim_keyframes_draw.c
new file mode 100644
index 00000000000..2f8d1be784e
--- /dev/null
+++ b/source/blender/editors/animation/anim_keyframes_draw.c
@@ -0,0 +1,701 @@
+/**
+ * $Id: drawaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* System includes ----------------------------------------------------- */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+/* Types --------------------------------------------------------------- */
+
+#include "DNA_listBase.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_action.h"
+#include "BKE_depsgraph.h"
+#include "BKE_ipo.h"
+#include "BKE_key.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
+#include "BKE_global.h" // XXX remove me!
+#include "BKE_context.h"
+#include "BKE_utildefines.h"
+
+/* Everything from source (BIF, BDR, BSE) ------------------------------ */
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+#include "UI_text.h"
+#include "UI_view2d.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframing.h"
+#include "ED_keyframes_draw.h"
+#include "ED_screen.h"
+#include "ED_space_api.h"
+
+
+#if 0 // XXX old includes for reference only
+ #include "BIF_editaction.h"
+ #include "BIF_editkey.h"
+ #include "BIF_editnla.h"
+ #include "BIF_drawgpencil.h"
+ #include "BIF_keyframing.h"
+ #include "BIF_language.h"
+ #include "BIF_space.h"
+
+ #include "BDR_editcurve.h"
+ #include "BDR_gpencil.h"
+
+ #include "BSE_drawnla.h"
+ #include "BSE_drawipo.h"
+ #include "BSE_drawview.h"
+ #include "BSE_editaction_types.h"
+ #include "BSE_editipo.h"
+ #include "BSE_headerbuttons.h"
+ #include "BSE_time.h"
+ #include "BSE_view.h"
+#endif // XXX old defines for reference only
+
+/* *************************** Keyframe Drawing *************************** */
+
+static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
+{
+ /* The equivilant of add_to_cfra_elem except this version
+ * makes ActKeyColumns - one of the two datatypes required
+ * for action editor drawing.
+ */
+ ActKeyColumn *ak, *akn;
+
+ if (ELEM(NULL, keys, bezt)) return;
+
+ /* try to any existing key to replace, or where to insert after */
+ for (ak= keys->last; ak; ak= ak->prev) {
+ /* do because of double keys */
+ if (ak->cfra == bezt->vec[1][0]) {
+ /* set selection status and 'touched' status */
+ if (BEZSELECTED(bezt)) ak->sel = SELECT;
+ ak->modified += 1;
+
+ return;
+ }
+ else if (ak->cfra < bezt->vec[1][0]) break;
+ }
+
+ /* add new block */
+ akn= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+ if (ak) BLI_insertlinkafter(keys, ak, akn);
+ else BLI_addtail(keys, akn);
+
+ akn->cfra= bezt->vec[1][0];
+ akn->modified += 1;
+
+ // TODO: handle type = bezt->h1 or bezt->h2
+ akn->handle_type= 0;
+
+ if (BEZSELECTED(bezt))
+ akn->sel = SELECT;
+ else
+ akn->sel = 0;
+}
+
+static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index)
+{
+ /* The equivilant of add_to_cfra_elem except this version
+ * makes ActKeyBlocks - one of the two datatypes required
+ * for action editor drawing.
+ */
+ ActKeyBlock *ab, *abn;
+ BezTriple *beztn=NULL, *prev=NULL;
+ BezTriple *bezt;
+ int v;
+
+ /* get beztriples */
+ beztn= (icu->bezt + index);
+
+ /* we need to go through all beztriples, as they may not be in order (i.e. during transform) */
+ for (v=0, bezt=icu->bezt; v<icu->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;
+
+ /* try to find a keyblock that starts on the previous beztriple
+ * 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->first; ab; ab= ab->next) {
+ /* check if alter existing block or add new block */
+ if (ab->start == prev->vec[1][0]) {
+ /* set selection status and 'touched' status */
+ if (BEZSELECTED(beztn)) ab->sel = SELECT;
+ ab->modified += 1;
+
+ return;
+ }
+ else if (ab->start < prev->vec[1][0]) break;
+ }
+
+ /* add new block */
+ abn= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
+ if (ab) BLI_insertlinkbefore(blocks, ab, abn);
+ else BLI_addtail(blocks, abn);
+
+ abn->start= prev->vec[1][0];
+ abn->end= beztn->vec[1][0];
+ abn->val= beztn->vec[1][1];
+
+ if (BEZSELECTED(prev) || BEZSELECTED(beztn))
+ abn->sel = SELECT;
+ else
+ abn->sel = 0;
+ abn->modified = 1;
+}
+
+/* helper function - find actkeycolumn that occurs on cframe */
+static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
+{
+ ActKeyColumn *ak, *ak2;
+
+ if (keys==NULL)
+ return NULL;
+
+ /* search from both ends at the same time, and stop if we find match or if both ends meet */
+ for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
+ /* return whichever end encounters the frame */
+ if (ak->cfra == cframe)
+ return ak;
+ if (ak2->cfra == cframe)
+ return ak2;
+
+ /* no matches on either end, so return NULL */
+ if (ak == ak2)
+ return NULL;
+ }
+
+ return NULL;
+}
+
+#if 0 // disabled, as some intel cards have problems with this
+/* Draw a simple diamond shape with a filled in center (in screen space) */
+static void draw_key_but(int x, int y, short w, short h, int sel)
+{
+ int xmin= x, ymin= y;
+ int xmax= x+w-1, ymax= y+h-1;
+ int xc= (xmin+xmax)/2, yc= (ymin+ymax)/2;
+
+ /* interior - hardcoded colors (for selected and unselected only) */
+ if (sel) glColor3ub(0xF1, 0xCA, 0x13);
+ else glColor3ub(0xE9, 0xE9, 0xE9);
+
+ glBegin(GL_QUADS);
+ glVertex2i(xc, ymin);
+ glVertex2i(xmax, yc);
+ glVertex2i(xc, ymax);
+ glVertex2i(xmin, yc);
+ glEnd();
+
+
+ /* outline */
+ glColor3ub(0, 0, 0);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(xc, ymin);
+ glVertex2i(xmax, yc);
+ glVertex2i(xc, ymax);
+ glVertex2i(xmin, yc);
+ glEnd();
+}
+#endif
+
+static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
+{
+ ActKeyColumn *ak;
+ ActKeyBlock *ab;
+
+ glEnable(GL_BLEND);
+
+ /* draw keyblocks */
+ if (blocks) {
+ for (ab= blocks->first; ab; ab= ab->next) {
+ short startCurves, endCurves, totCurves;
+
+ /* find out how many curves occur at each keyframe */
+ ak= cfra_find_actkeycolumn(keys, ab->start);
+ startCurves = (ak)? ak->totcurve: 0;
+
+ ak= cfra_find_actkeycolumn(keys, ab->end);
+ endCurves = (ak)? ak->totcurve: 0;
+
+ /* only draw keyblock if it appears in at all of the keyframes at lowest end */
+ if (!startCurves && !endCurves)
+ continue;
+ else
+ totCurves = (startCurves>endCurves)? endCurves: startCurves;
+
+ if (ab->totcurve >= totCurves) {
+ int sc_xa, sc_xb, sc_y;
+
+ /* get co-ordinates of block */
+ // XXX only use x-coordinates... y are dummy ones!
+ gla2DDrawTranslatePt(di, ab->start, ypos, &sc_xa, &sc_y);
+ gla2DDrawTranslatePt(di, ab->end, ypos, &sc_xb, &sc_y);
+
+ /* draw block */
+ if (ab->sel)
+ UI_ThemeColor4(TH_STRIP_SELECT);
+ else
+ UI_ThemeColor4(TH_STRIP);
+ glRectf((float)sc_xa, (float)ypos-3, (float)sc_xb, (float)ypos+5);
+ }
+ }
+ }
+
+ /* draw keys */
+ if (keys) {
+ for (ak= keys->first; ak; ak= ak->next) {
+ int sc_x, sc_y;
+
+ /* get co-ordinate to draw at */
+ // XXX only use x-coordinates... y are dummy ones!
+ gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
+
+ /* draw using icons - old way which is slower but more proven */
+ if (ak->sel & SELECT)UI_icon_draw_aspect((float)sc_x-7, (float)ypos-6, ICON_SPACE2, 1.0f);
+ else UI_icon_draw_aspect((float)sc_x-7, (float)ypos-6, ICON_SPACE3, 1.0f);
+
+ /* draw using OpenGL - slightly uglier but faster */
+ // NOTE: disabled for now, as some intel cards seem to have problems with this
+ //draw_key_but(sc_x-5, sc_y-4, 11, 11, (ak->sel & SELECT));
+ }
+ }
+
+ glDisable(GL_BLEND);
+}
+
+void draw_object_channel(gla2DDrawInfo *di, ActKeysInc *aki, Object *ob, float ypos)
+{
+ ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+
+ ob_to_keylist(ob, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
+
+ BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
+}
+
+void draw_ipo_channel(gla2DDrawInfo *di, ActKeysInc *aki, Ipo *ipo, float ypos)
+{
+ ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+
+ ipo_to_keylist(ipo, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
+
+ BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
+}
+
+void draw_icu_channel(gla2DDrawInfo *di, ActKeysInc *aki, IpoCurve *icu, float ypos)
+{
+ ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+
+ icu_to_keylist(icu, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
+
+ BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
+}
+
+void draw_agroup_channel(gla2DDrawInfo *di, ActKeysInc *aki, bActionGroup *agrp, float ypos)
+{
+ ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+
+ agroup_to_keylist(agrp, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
+
+ BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
+}
+
+void draw_action_channel(gla2DDrawInfo *di, ActKeysInc *aki, bAction *act, float ypos)
+{
+ ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+
+ action_to_keylist(act, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
+
+ BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
+}
+
+void draw_gpl_channel(gla2DDrawInfo *di, ActKeysInc *aki, bGPDlayer *gpl, float ypos)
+{
+ ListBase keys = {0, 0};
+
+ gpl_to_keylist(gpl, &keys, NULL, aki);
+ draw_keylist(di, &keys, NULL, ypos);
+ BLI_freelistN(&keys);
+}
+
+/* --------------- Conversion: data -> keyframe list ------------------ */
+
+void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bConstraintChannel *conchan;
+ Key *key= ob_get_key(ob);
+
+ if (ob) {
+ bDopeSheet *ads= (aki)? (aki->ads) : NULL;
+ int filterflag;
+
+ /* get filterflag */
+ if (ads)
+ filterflag= ads->filterflag;
+ else if ((aki) && (aki->actmode == -1)) /* only set like this by NLA */
+ filterflag= ADS_FILTER_NLADUMMY;
+ else
+ filterflag= 0;
+
+ /* Add object keyframes */
+ if ((ob->ipo) && !(filterflag & ADS_FILTER_NOIPOS))
+ ipo_to_keylist(ob->ipo, keys, blocks, aki);
+
+ /* Add action keyframes */
+ if ((ob->action) && !(filterflag & ADS_FILTER_NOACTS))
+ action_nlascaled_to_keylist(ob, ob->action, keys, blocks, aki);
+
+ /* Add shapekey keyframes (only if dopesheet allows, if it is available) */
+ if ((key && key->ipo) && !(filterflag & ADS_FILTER_NOSHAPEKEYS))
+ ipo_to_keylist(key->ipo, keys, blocks, aki);
+
+ /* Add material keyframes (only if dopesheet allows, if it is available) */
+ if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
+ short a;
+
+ for (a=0; a<ob->totcol; a++) {
+ Material *ma= give_current_material(ob, a);
+
+ if (ELEM(NULL, ma, ma->ipo) == 0)
+ ipo_to_keylist(ma->ipo, keys, blocks, aki);
+ }
+ }
+
+ /* Add object data keyframes */
+ switch (ob->type) {
+ case OB_CAMERA: /* ------- Camera ------------ */
+ {
+ Camera *ca= (Camera *)ob->data;
+ if ((ca->ipo) && !(ads->filterflag & ADS_FILTER_NOCAM))
+ ipo_to_keylist(ca->ipo, keys, blocks, aki);
+ }
+ break;
+ case OB_LAMP: /* ---------- Lamp ----------- */
+ {
+ Lamp *la= (Lamp *)ob->data;
+ if ((la->ipo) && !(ads->filterflag & ADS_FILTER_NOLAM))
+ ipo_to_keylist(la->ipo, keys, blocks, aki);
+ }
+ break;
+ case OB_CURVE: /* ------- Curve ---------- */
+ {
+ Curve *cu= (Curve *)ob->data;
+ if ((cu->ipo) && !(ads->filterflag & ADS_FILTER_NOCUR))
+ ipo_to_keylist(cu->ipo, keys, blocks, aki);
+ }
+ break;
+ }
+
+ /* Add constraint keyframes */
+ if (!(filterflag & ADS_FILTER_NOCONSTRAINTS)) {
+ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ }
+ }
+ }
+}
+
+static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
+{
+ /* when aki == NULL, we don't care about range */
+ if (aki == NULL)
+ return 1;
+
+ /* if start and end are both 0, then don't care about range */
+ if (IS_EQ(aki->start, 0) && IS_EQ(aki->end, 0))
+ return 1;
+
+ /* if nla-scaling is in effect, apply appropriate scaling adjustments */
+ if (aki->ob) {
+ float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
+ return IN_RANGE(frame, aki->start, aki->end);
+ }
+ else {
+ /* check if in range */
+ return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
+ }
+}
+
+void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ BezTriple *bezt;
+ ActKeyColumn *ak, *ak2;
+ ActKeyBlock *ab, *ab2;
+ int v;
+
+ if (icu && icu->totvert) {
+ /* loop through beztriples, making ActKeys and ActKeyBlocks */
+ bezt= icu->bezt;
+
+ for (v=0; v<icu->totvert; v++, bezt++) {
+ /* only if keyframe is in range (optimisation) */
+ if (bezt_in_aki_range(aki, bezt)) {
+ add_bezt_to_keycolumnslist(keys, bezt);
+ if (blocks) add_bezt_to_keyblockslist(blocks, icu, v);
+ }
+ }
+
+ /* update the number of curves that elements have appeared in */
+ if (keys) {
+ for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
+ if (ak->modified) {
+ ak->modified = 0;
+ ak->totcurve += 1;
+ }
+
+ if (ak == ak2)
+ break;
+
+ if (ak2->modified) {
+ ak2->modified = 0;
+ ak2->totcurve += 1;
+ }
+ }
+ }
+ if (blocks) {
+ for (ab=blocks->first, ab2=blocks->last; ab && ab2; ab=ab->next, ab2=ab2->prev) {
+ if (ab->modified) {
+ ab->modified = 0;
+ ab->totcurve += 1;
+ }
+
+ if (ab == ab2)
+ break;
+
+ if (ab2->modified) {
+ ab2->modified = 0;
+ ab2->totcurve += 1;
+ }
+ }
+ }
+ }
+}
+
+void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ IpoCurve *icu;
+
+ if (ipo) {
+ for (icu= ipo->curve.first; icu; icu= icu->next)
+ icu_to_keylist(icu, keys, blocks, aki);
+ }
+}
+
+void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ if (agrp) {
+ /* loop through action channels */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan)) {
+ /* firstly, add keys from action channel's ipo block */
+ if (achan->ipo)
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ }
+ }
+ }
+ }
+}
+
+void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ if (act) {
+ /* loop through action channels */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ /* firstly, add keys from action channel's ipo block */
+ if (achan->ipo)
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ }
+ }
+ }
+}
+
+void action_nlascaled_to_keylist(Object *ob, bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+ Object *oldob= NULL;
+
+ /* although apply and clearing NLA-scaling pre-post creating keylist does impact on performance,
+ * the effects should be fairly minimal, as we're already going through the keyframes multiple times
+ * already for blocks too...
+ */
+ if (act) {
+ /* if 'aki' is provided, store it's current ob to restore later as it might not be the same */
+ if (aki) {
+ oldob= aki->ob;
+ aki->ob= ob;
+ }
+
+ /* loop through action channels */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ /* firstly, add keys from action channel's ipo block
+ * - scaling correction only does times for center-points, so should be faster
+ */
+ if (achan->ipo) {
+ //actstrip_map_ipo_keys(ob, achan->ipo, 0, 1); // XXX
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
+ //actstrip_map_ipo_keys(ob, achan->ipo, 1, 1); // XXX
+ }
+
+ /* then, add keys from constraint channels
+ * - scaling correction only does times for center-points, so should be faster
+ */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo) {
+ //actstrip_map_ipo_keys(ob, conchan->ipo, 0, 1); // XXX
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ //actstrip_map_ipo_keys(ob, conchan->ipo, 1, 1); // XXX
+ }
+ }
+ }
+
+ /* if 'aki' is provided, restore ob */
+ if (aki)
+ aki->ob= oldob;
+ }
+}
+
+void gpl_to_keylist(bGPDlayer *gpl, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bGPDframe *gpf;
+ ActKeyColumn *ak;
+
+ if (gpl && keys) {
+ /* loop over frames, converting directly to 'keyframes' (should be in order too) */
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+ ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+ BLI_addtail(keys, ak);
+
+ ak->cfra= (float)gpf->framenum;
+ ak->modified = 1;
+ ak->handle_type= 0;
+
+ if (gpf->flag & GP_FRAME_SELECT)
+ ak->sel = SELECT;
+ else
+ ak->sel = 0;
+ }
+ }
+}
+