At last... this merge should finally do the trick!
[blender.git] / source / blender / editors / animation / keyframes_draw.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /* System includes ----------------------------------------------------- */
31
32 #include <math.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <float.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_arithb.h"
45
46 /* Types --------------------------------------------------------------- */
47
48 #include "DNA_listBase.h"
49 #include "DNA_anim_types.h"
50 #include "DNA_action_types.h"
51 #include "DNA_armature_types.h"
52 #include "DNA_camera_types.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_ipo_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_screen_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_space_types.h"
59 #include "DNA_constraint_types.h"
60 #include "DNA_key_types.h"
61 #include "DNA_lamp_types.h"
62 #include "DNA_material_types.h"
63 #include "DNA_userdef_types.h"
64 #include "DNA_gpencil_types.h"
65 #include "DNA_windowmanager_types.h"
66 #include "DNA_world_types.h"
67
68 #include "BKE_action.h"
69 #include "BKE_depsgraph.h"
70 #include "BKE_fcurve.h"
71 #include "BKE_key.h"
72 #include "BKE_material.h"
73 #include "BKE_object.h"
74 #include "BKE_global.h"         // XXX remove me!
75 #include "BKE_context.h"
76 #include "BKE_utildefines.h"
77
78 /* Everything from source (BIF, BDR, BSE) ------------------------------ */ 
79
80 #include "BIF_gl.h"
81 #include "BIF_glutil.h"
82
83 #include "UI_interface.h"
84 #include "UI_interface_icons.h"
85 #include "UI_resources.h"
86 #include "UI_view2d.h"
87
88 #include "ED_anim_api.h"
89 #include "ED_keyframing.h"
90 #include "ED_keyframes_draw.h"
91 #include "ED_screen.h"
92 #include "ED_space_api.h"
93
94 /* *************************** Keyframe Drawing *************************** */
95
96 static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
97 {
98         /* The equivalent of add_to_cfra_elem except this version 
99          * makes ActKeyColumns - one of the two datatypes required
100          * for action editor drawing.
101          */
102         ActKeyColumn *ak, *akn;
103         
104         if (ELEM(NULL, keys, bezt)) return;
105         
106         /* try to any existing key to replace, or where to insert after */
107         for (ak= keys->last; ak; ak= ak->prev) {
108                 /* do because of double keys */
109                 if (ak->cfra == bezt->vec[1][0]) {                      
110                         /* set selection status and 'touched' status */
111                         if (BEZSELECTED(bezt)) ak->sel = SELECT;
112                         ak->modified += 1;
113                         
114                         return;
115                 }
116                 else if (ak->cfra < bezt->vec[1][0]) break;
117         }
118         
119         /* add new block */
120         akn= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
121         if (ak) BLI_insertlinkafter(keys, ak, akn);
122         else BLI_addtail(keys, akn);
123         
124         akn->cfra= bezt->vec[1][0];
125         akn->modified += 1;
126         
127         // TODO: handle type = bezt->h1 or bezt->h2
128         akn->handle_type= 0; 
129         
130         if (BEZSELECTED(bezt))
131                 akn->sel = SELECT;
132         else
133                 akn->sel = 0;
134 }
135
136 static void add_bezt_to_keyblockslist(ListBase *blocks, FCurve *fcu, int index)
137 {
138         /* The equivalent of add_to_cfra_elem except this version 
139          * makes ActKeyBlocks - one of the two datatypes required
140          * for action editor drawing.
141          */
142         ActKeyBlock *ab, *abn;
143         BezTriple *beztn=NULL, *prev=NULL;
144         BezTriple *bezt;
145         int v;
146         
147         /* get beztriples */
148         beztn= (fcu->bezt + index);
149         
150         /* we need to go through all beztriples, as they may not be in order (i.e. during transform) */
151         for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) {
152                 /* skip if beztriple is current */
153                 if (v != index) {
154                         /* check if beztriple is immediately before */
155                         if (beztn->vec[1][0] > bezt->vec[1][0]) {
156                                 /* check if closer than previous was */
157                                 if (prev) {
158                                         if (prev->vec[1][0] < bezt->vec[1][0])
159                                                 prev= bezt;
160                                 }
161                                 else {
162                                         prev= bezt;
163                                 }
164                         }
165                 }
166         }
167         
168         /* check if block needed - same value(s)?
169          *      -> firstly, handles must have same central value as each other
170          *      -> secondly, handles which control that section of the curve must be constant
171          */
172         if ((!prev) || (!beztn)) return;
173         if (IS_EQ(beztn->vec[1][1], prev->vec[1][1])==0) return;
174         if (IS_EQ(beztn->vec[1][1], beztn->vec[0][1])==0) return;
175         if (IS_EQ(prev->vec[1][1], prev->vec[2][1])==0) return;
176         
177         /* try to find a keyblock that starts on the previous beztriple 
178          * Note: we can't search from end to try to optimise this as it causes errors there's
179          *              an A ___ B |---| B situation
180          */
181         // FIXME: here there is a bug where we are trying to get the summary for the following channels
182         //              A|--------------|A ______________ B|--------------|B
183         //              A|------------------------------------------------|A
184         //              A|----|A|---|A|-----------------------------------|A
185         for (ab= blocks->first; ab; ab= ab->next) {
186                 /* check if alter existing block or add new block */
187                 if (ab->start == prev->vec[1][0]) {                     
188                         /* set selection status and 'touched' status */
189                         if (BEZSELECTED(beztn)) ab->sel = SELECT;
190                         ab->modified += 1;
191                         
192                         return;
193                 }
194                 else if (ab->start < prev->vec[1][0]) break;
195         }
196         
197         /* add new block */
198         abn= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
199         if (ab) BLI_insertlinkbefore(blocks, ab, abn);
200         else BLI_addtail(blocks, abn);
201         
202         abn->start= prev->vec[1][0];
203         abn->end= beztn->vec[1][0];
204         abn->val= beztn->vec[1][1];
205         
206         if (BEZSELECTED(prev) || BEZSELECTED(beztn))
207                 abn->sel = SELECT;
208         else
209                 abn->sel = 0;
210         abn->modified = 1;
211 }
212
213 /* helper function - find actkeycolumn that occurs on cframe */
214 static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
215 {
216         ActKeyColumn *ak, *ak2;
217         
218         if (keys==NULL) 
219                 return NULL;
220          
221         /* search from both ends at the same time, and stop if we find match or if both ends meet */ 
222         for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
223                 /* return whichever end encounters the frame */
224                 if (ak->cfra == cframe)
225                         return ak;
226                 if (ak2->cfra == cframe)
227                         return ak2;
228                 
229                 /* no matches on either end, so return NULL */
230                 if (ak == ak2)
231                         return NULL;
232         }
233         
234         return NULL;
235 }
236
237 #if 0  // disabled, as some intel cards have problems with this
238 /* Draw a simple diamond shape with a filled in center (in screen space) */
239 static void draw_key_but(int x, int y, short w, short h, int sel)
240 {
241         int xmin= x, ymin= y;
242         int xmax= x+w-1, ymax= y+h-1;
243         int xc= (xmin+xmax)/2, yc= (ymin+ymax)/2;
244         
245         /* interior - hardcoded colors (for selected and unselected only) */
246         if (sel) glColor3ub(0xF1, 0xCA, 0x13);
247         else glColor3ub(0xE9, 0xE9, 0xE9);
248         
249         glBegin(GL_QUADS);
250         glVertex2i(xc, ymin);
251         glVertex2i(xmax, yc);
252         glVertex2i(xc, ymax);
253         glVertex2i(xmin, yc);
254         glEnd();
255         
256         
257         /* outline */
258         glColor3ub(0, 0, 0);
259         
260         glBegin(GL_LINE_LOOP);
261         glVertex2i(xc, ymin);
262         glVertex2i(xmax, yc);
263         glVertex2i(xc, ymax);
264         glVertex2i(xmin, yc);
265         glEnd();
266 }
267 #endif
268
269 static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
270 {
271         ActKeyColumn *ak;
272         ActKeyBlock *ab;
273         
274         glEnable(GL_BLEND);
275         
276         /* draw keyblocks */
277         if (blocks) {
278                 for (ab= blocks->first; ab; ab= ab->next) {
279                         short startCurves, endCurves, totCurves;
280                         
281                         /* find out how many curves occur at each keyframe */
282                         ak= cfra_find_actkeycolumn(keys, ab->start);
283                         startCurves = (ak)? ak->totcurve: 0;
284                         
285                         ak= cfra_find_actkeycolumn(keys, ab->end);
286                         endCurves = (ak)? ak->totcurve: 0;
287                         
288                         /* only draw keyblock if it appears in at all of the keyframes at lowest end */
289                         if (!startCurves && !endCurves) 
290                                 continue;
291                         else
292                                 totCurves = (startCurves>endCurves)? endCurves: startCurves;
293                                 
294                         if (ab->totcurve >= totCurves) {
295                                 int sc_xa, sc_xb, sc_ya, sc_yb;
296                                 
297                                 /* get co-ordinates of block */
298                                 gla2DDrawTranslatePt(di, ab->start, ypos, &sc_xa, &sc_ya);
299                                 gla2DDrawTranslatePt(di, ab->end, ypos, &sc_xb, &sc_yb);
300                                 
301                                 /* draw block */
302                                 if (ab->sel)
303                                         UI_ThemeColor4(TH_STRIP_SELECT);
304                                 else
305                                         UI_ThemeColor4(TH_STRIP);
306                                 glRectf((float)sc_xa, (float)sc_ya-3, (float)sc_xb, (float)sc_yb+5);
307                         }
308                 }
309         }
310         
311         /* draw keys */
312         if (keys) {
313                 for (ak= keys->first; ak; ak= ak->next) {
314                         int sc_x, sc_y;
315                         
316                         /* get co-ordinate to draw at */
317                         gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
318                         
319                         /* draw using icons - old way which is slower but more proven */
320                         if (ak->sel & SELECT) UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE2, 1.0f);
321                         else UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE3, 1.0f);
322                         
323                         /* draw using OpenGL - slightly uglier but faster */
324                         //      NOTE: disabled for now, as some intel cards seem to have problems with this
325                         //draw_key_but(sc_x-5, sc_y-4, 11, 11, (ak->sel & SELECT));
326                 }       
327         }
328         
329         glDisable(GL_BLEND);
330 }
331
332 /* *************************** Channel Drawing Funcs *************************** */
333
334 void draw_scene_channel(gla2DDrawInfo *di, ActKeysInc *aki, Scene *sce, float ypos)
335 {
336         ListBase keys = {0, 0};
337         ListBase blocks = {0, 0};
338
339         scene_to_keylist(sce, &keys, &blocks, aki);
340         draw_keylist(di, &keys, &blocks, ypos);
341         
342         BLI_freelistN(&keys);
343         BLI_freelistN(&blocks);
344 }
345
346 void draw_object_channel(gla2DDrawInfo *di, ActKeysInc *aki, Object *ob, float ypos)
347 {
348         ListBase keys = {0, 0};
349         ListBase blocks = {0, 0};
350
351         ob_to_keylist(ob, &keys, &blocks, aki);
352         draw_keylist(di, &keys, &blocks, ypos);
353         
354         BLI_freelistN(&keys);
355         BLI_freelistN(&blocks);
356 }
357
358 void draw_fcurve_channel(gla2DDrawInfo *di, ActKeysInc *aki, FCurve *fcu, float ypos)
359 {
360         ListBase keys = {0, 0};
361         ListBase blocks = {0, 0};
362
363         fcurve_to_keylist(fcu, &keys, &blocks, aki);
364         draw_keylist(di, &keys, &blocks, ypos);
365         
366         BLI_freelistN(&keys);
367         BLI_freelistN(&blocks);
368 }
369
370 void draw_agroup_channel(gla2DDrawInfo *di, ActKeysInc *aki, bActionGroup *agrp, float ypos)
371 {
372         ListBase keys = {0, 0};
373         ListBase blocks = {0, 0};
374
375         agroup_to_keylist(agrp, &keys, &blocks, aki);
376         draw_keylist(di, &keys, &blocks, ypos);
377         
378         BLI_freelistN(&keys);
379         BLI_freelistN(&blocks);
380 }
381
382 void draw_action_channel(gla2DDrawInfo *di, ActKeysInc *aki, bAction *act, float ypos)
383 {
384         ListBase keys = {0, 0};
385         ListBase blocks = {0, 0};
386
387         action_to_keylist(act, &keys, &blocks, aki);
388         draw_keylist(di, &keys, &blocks, ypos);
389         
390         BLI_freelistN(&keys);
391         BLI_freelistN(&blocks);
392 }
393
394 void draw_gpl_channel(gla2DDrawInfo *di, ActKeysInc *aki, bGPDlayer *gpl, float ypos)
395 {
396         ListBase keys = {0, 0};
397         
398         gpl_to_keylist(gpl, &keys, NULL, aki);
399         draw_keylist(di, &keys, NULL, ypos);
400         BLI_freelistN(&keys);
401 }
402
403 /* *************************** Keyframe List Conversions *************************** */
404
405 void scene_to_keylist(Scene *sce, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
406 {
407         if (sce) {
408                 bDopeSheet *ads= (aki)? (aki->ads) : NULL;
409                 AnimData *adt;
410                 int filterflag;
411                 
412                 /* get filterflag */
413                 if (ads)
414                         filterflag= ads->filterflag;
415                 else
416                         filterflag= 0;
417                         
418                 /* scene animdata */
419                 if ((sce->adt) && !(filterflag & ADS_FILTER_NOSCE)) {
420                         adt= sce->adt;
421                         
422                         // TODO: when we adapt NLA system, this needs to be the NLA-scaled version
423                         if (adt->action) 
424                                 action_to_keylist(adt->action, keys, blocks, aki);
425                 }
426                 
427                 /* world animdata */
428                 if ((sce->world) && (sce->world->adt) && !(filterflag & ADS_FILTER_NOWOR)) {
429                         adt= sce->world->adt;
430                         
431                         // TODO: when we adapt NLA system, this needs to be the NLA-scaled version
432                         if (adt->action) 
433                                 action_to_keylist(adt->action, keys, blocks, aki);
434                 }
435         }
436 }
437
438 void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
439 {
440         Key *key= ob_get_key(ob);
441
442         if (ob) {
443                 bDopeSheet *ads= (aki)? (aki->ads) : NULL;
444                 int filterflag;
445                 
446                 /* get filterflag */
447                 if (ads)
448                         filterflag= ads->filterflag;
449                 else
450                         filterflag= 0;
451                 
452                 /* Add action keyframes */
453                 if (ob->adt && ob->adt->action)
454                         action_nlascaled_to_keylist(ob->adt, ob->adt->action, keys, blocks, aki);
455                 
456                 /* Add shapekey keyframes (only if dopesheet allows, if it is available) */
457                 // TODO: when we adapt NLA system, this needs to be the NLA-scaled version
458                 if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS))
459                         action_to_keylist(key->adt->action, keys, blocks, aki);
460                         
461 #if 0 // XXX old animation system
462                 /* Add material keyframes (only if dopesheet allows, if it is available) */
463                 if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
464                         short a;
465                         
466                         for (a=0; a<ob->totcol; a++) {
467                                 Material *ma= give_current_material(ob, a);
468                                 
469                                 if (ELEM(NULL, ma, ma->ipo) == 0)
470                                         ipo_to_keylist(ma->ipo, keys, blocks, aki);
471                         }
472                 }
473                         
474                 /* Add object data keyframes */
475                 switch (ob->type) {
476                         case OB_CAMERA: /* ------- Camera ------------ */
477                         {
478                                 Camera *ca= (Camera *)ob->data;
479                                 if ((ca->ipo) && !(filterflag & ADS_FILTER_NOCAM))
480                                         ipo_to_keylist(ca->ipo, keys, blocks, aki);
481                         }
482                                 break;
483                         case OB_LAMP: /* ---------- Lamp ----------- */
484                         {
485                                 Lamp *la= (Lamp *)ob->data;
486                                 if ((la->ipo) && !(filterflag & ADS_FILTER_NOLAM))
487                                         ipo_to_keylist(la->ipo, keys, blocks, aki);
488                         }
489                                 break;
490                         case OB_CURVE: /* ------- Curve ---------- */
491                         {
492                                 Curve *cu= (Curve *)ob->data;
493                                 if ((cu->ipo) && !(filterflag & ADS_FILTER_NOCUR))
494                                         ipo_to_keylist(cu->ipo, keys, blocks, aki);
495                         }
496                                 break;
497                 }
498 #endif // XXX old animation system
499         }
500 }
501
502 static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
503 {
504         /* when aki == NULL, we don't care about range */
505         if (aki == NULL) 
506                 return 1;
507                 
508         /* if start and end are both 0, then don't care about range */
509         if (IS_EQ(aki->start, 0) && IS_EQ(aki->end, 0))
510                 return 1;
511                 
512         /* if nla-scaling is in effect, apply appropriate scaling adjustments */
513 #if 0 // XXX this was from some buggy code... do not port for now
514         if (aki->ob) {
515                 float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
516                 return IN_RANGE(frame, aki->start, aki->end);
517         }
518         else {
519                 /* check if in range */
520                 return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
521         }
522 #endif // XXX this was from some buggy code... do not port for now
523         return 1;
524 }
525
526 void fcurve_to_keylist(FCurve *fcu, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
527 {
528         BezTriple *bezt;
529         ActKeyColumn *ak, *ak2;
530         ActKeyBlock *ab, *ab2;
531         int v;
532         
533         if (fcu && fcu->totvert && fcu->bezt) {
534                 /* loop through beztriples, making ActKeys and ActKeyBlocks */
535                 bezt= fcu->bezt;
536                 
537                 for (v=0; v < fcu->totvert; v++, bezt++) {
538                         /* only if keyframe is in range (optimisation) */
539                         if (bezt_in_aki_range(aki, bezt)) {
540                                 add_bezt_to_keycolumnslist(keys, bezt);
541                                 if (blocks) add_bezt_to_keyblockslist(blocks, fcu, v);
542                         }
543                 }
544                 
545                 /* update the number of curves that elements have appeared in  */
546                 if (keys) {
547                         for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
548                                 if (ak->modified) {
549                                         ak->modified = 0;
550                                         ak->totcurve += 1;
551                                 }
552                                 
553                                 if (ak == ak2)
554                                         break;
555                                 
556                                 if (ak2->modified) {
557                                         ak2->modified = 0;
558                                         ak2->totcurve += 1;
559                                 }
560                         }
561                 }
562                 if (blocks) {
563                         for (ab=blocks->first, ab2=blocks->last; ab && ab2; ab=ab->next, ab2=ab2->prev) {
564                                 if (ab->modified) {
565                                         ab->modified = 0;
566                                         ab->totcurve += 1;
567                                 }
568                                 
569                                 if (ab == ab2)
570                                         break;
571                                 
572                                 if (ab2->modified) {
573                                         ab2->modified = 0;
574                                         ab2->totcurve += 1;
575                                 }
576                         }
577                 }
578         }
579 }
580
581 void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
582 {
583         FCurve *fcu;
584
585         if (agrp) {
586                 /* loop through F-Curves */
587                 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
588                         fcurve_to_keylist(fcu, keys, blocks, aki);
589                 }
590         }
591 }
592
593 void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
594 {
595         FCurve *fcu;
596
597         if (act) {
598                 /* loop through F-Curves */
599                 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
600                         fcurve_to_keylist(fcu, keys, blocks, aki);
601                 }
602         }
603 }
604
605 void action_nlascaled_to_keylist(AnimData *adt, bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
606 {
607         FCurve *fcu;
608         AnimData *oldadt= NULL;
609         
610         /* although apply and clearing NLA-mapping pre-post creating keylist does impact on performance,
611          * the effects should be fairly minimal, as we're already going through the keyframes multiple times 
612          * already for blocks too...
613          */
614         if (act) {      
615                 /* if 'aki' is provided, store it's current ob to restore later as it might not be the same */
616                 if (aki) {
617                         oldadt= aki->adt;
618                         aki->adt= adt;
619                 }
620                 
621                 /* loop through F-Curves 
622                  *      - scaling correction only does times for center-points, so should be faster
623                  */
624                 for (fcu= act->curves.first; fcu; fcu= fcu->next) {     
625                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1);
626                         fcurve_to_keylist(fcu, keys, blocks, aki);
627                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1);
628                 }
629                 
630                 /* if 'aki' is provided, restore ob */
631                 if (aki)
632                         aki->adt= oldadt;
633         }
634 }
635
636 void gpl_to_keylist(bGPDlayer *gpl, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
637 {
638         bGPDframe *gpf;
639         ActKeyColumn *ak;
640         
641         if (gpl && keys) {
642                 /* loop over frames, converting directly to 'keyframes' (should be in order too) */
643                 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
644                         ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
645                         BLI_addtail(keys, ak);
646                         
647                         ak->cfra= (float)gpf->framenum;
648                         ak->modified = 1;
649                         ak->handle_type= 0; 
650                         
651                         if (gpf->flag & GP_FRAME_SELECT)
652                                 ak->sel = SELECT;
653                         else
654                                 ak->sel = 0;
655                 }
656         }
657 }
658