Reduced number of MSVC compiler warnings (mostly just casting issues).
[blender.git] / source / blender / src / poselib.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) 2007, Blender Foundation
21  * This is a new part of Blender
22  *
23  * Contributor(s): Joshua Leung
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27  
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <stddef.h>
31 #include <string.h>
32 #include <math.h>
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_arithb.h"
41 #include "BLI_blenlib.h"
42 #include "BLI_dynstr.h"
43
44 #include "DNA_listBase.h"
45 #include "DNA_action_types.h"
46 #include "DNA_armature_types.h"
47 #include "DNA_curve_types.h"
48 #include "DNA_ipo_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_object_force.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_userdef_types.h"
53
54 #include "BKE_action.h"
55 #include "BKE_armature.h"
56 #include "BKE_depsgraph.h"
57 #include "BKE_ipo.h"
58 #include "BKE_modifier.h"
59 #include "BKE_object.h"
60
61 #include "BKE_global.h"
62 #include "BKE_utildefines.h"
63
64 #include "BIF_keyframing.h"
65 #include "BSE_editipo.h"
66
67 #include "BDR_drawaction.h"
68 #include "BSE_time.h"
69
70 #include "BIF_poselib.h"
71 #include "BIF_interface.h"
72 #include "BIF_editaction.h"
73 #include "BIF_space.h"
74 #include "BIF_screen.h"
75 #include "BIF_toets.h"
76 #include "BIF_toolbox.h"
77
78
79 #include "blendef.h"
80
81 #include "PIL_time.h"                   /* sleep                                */
82 #include "mydevice.h"
83
84 /* ************************************************************* */
85 /* == POSE-LIBRARY TOOL FOR BLENDER == 
86  *      
87  * Overview: 
88  *      This tool allows animators to store a set of frequently used poses to dump into
89  *      the active action to help in "budget" productions to quickly block out new actions.
90  *      It acts as a kind of "glorified clipboard for poses", allowing for naming of poses.
91  *
92  * Features:
93  *      - PoseLibs are simply normal Actions
94  *      - Each "pose" is simply a set of keyframes that occur on a particular frame
95  *              -> a set of TimeMarkers that belong to each Action, help 'label' where a 'pose' can be
96  *                 found in the Action
97  *      - The Scrollwheel or PageUp/Down buttons when used in a special mode or after pressing/holding
98  *        [a modifier] key, cycles through the poses available for the active pose's poselib, allowing the
99  *        animator to preview what action best suits that pose
100  */
101 /* ************************************************************* */
102
103 /* gets list of poses in poselib as a string usable for pupmenu() */
104 char *poselib_build_poses_menu (bAction *act, char title[])
105 {
106         DynStr *pupds= BLI_dynstr_new();
107         TimeMarker *marker;
108         char *str;
109         char buf[64];
110         int i;
111         
112         /* add title first */
113         sprintf(buf, "%s%%t|", title);
114         BLI_dynstr_append(pupds, buf);
115         
116         /* loop through markers, adding them */
117         for (marker=act->markers.first, i=1; marker; marker=marker->next, i++) {
118                 BLI_dynstr_append(pupds, marker->name);
119                 
120                 sprintf(buf, "%%x%d", i);
121                 BLI_dynstr_append(pupds, buf);
122                 
123                 if (marker->next)
124                         BLI_dynstr_append(pupds, "|");
125         }
126         
127         /* convert to normal MEM_malloc'd string */
128         str= BLI_dynstr_get_cstring(pupds);
129         BLI_dynstr_free(pupds);
130         
131         return str;
132 }
133
134 /* gets the first available frame in poselib to store a pose on 
135  *      - frames start from 1, and a pose should occur on every frame... 0 is error!
136  */
137 int poselib_get_free_index (bAction *act)
138 {
139         TimeMarker *marker;
140         int low=0, high=0;
141         
142         /* sanity checks */
143         if (ELEM(NULL, act, act->markers.first)) return 1;
144         
145         /* loop over poses finding various values (poses are not stored in chronological order) */
146         for (marker= act->markers.first; marker; marker= marker->next) {
147                 /* only increase low if value is 1 greater than low, to find "gaps" where
148                  * poses were removed from the poselib
149                  */
150                 if (marker->frame == (low + 1)) 
151                         low++;
152                 
153                 /* value replaces high if it is the highest value encountered yet */
154                 if (marker->frame > high) 
155                         high= marker->frame;
156         }
157         
158         /* - if low is not equal to high, then low+1 is a gap 
159          * - if low is equal to high, then high+1 is the next index (add at end) 
160          */
161         if (low < high) 
162                 return (low + 1);
163         else 
164                 return (high + 1);
165 }
166
167 /* returns the active pose for a poselib */
168 TimeMarker *poselib_get_active_pose (bAction *act)
169 {       
170         if ((act) && (act->active_marker))
171                 return BLI_findlink(&act->markers, act->active_marker-1);
172         else
173                 return NULL;
174 }
175
176 /* ************************************************************* */
177
178 /* Initialise a new poselib (whether it is needed or not) */
179 bAction *poselib_init_new (Object *ob)
180 {
181         /* sanity checks - only for armatures */
182         if (ELEM(NULL, ob, ob->pose))
183                 return NULL;
184         
185         /* init object's poselib action (unlink old one if there) */
186         if (ob->poselib)
187                 ob->poselib->id.us--;
188         ob->poselib= add_empty_action("PoseLib");
189         
190         return ob->poselib;
191 }
192
193 /* Initialise a new poselib (checks if that needs to happen) */
194 bAction *poselib_validate (Object *ob)
195 {
196         if (ELEM(NULL, ob, ob->pose))
197                 return NULL;
198         else if (ob->poselib == NULL)
199                 return poselib_init_new(ob);
200         else
201                 return ob->poselib;
202 }
203
204
205 /* This tool automagically generates/validates poselib data so that it corresponds to the data 
206  * in the action. This is for use in making existing actions usable as poselibs.
207  */
208 void poselib_validate_act (bAction *act)
209 {
210         ListBase keys = {NULL, NULL};
211         ActKeyColumn *ak;
212         TimeMarker *marker, *markern;
213         
214         /* validate action and poselib */
215         if (act == NULL)  {
216                 error("No Action to validate");
217                 return;
218         }
219         
220         /* determine which frames have keys */
221         action_to_keylist(act, &keys, NULL, NULL);
222         
223         /* for each key, make sure there is a correspnding pose */
224         for (ak= keys.first; ak; ak= ak->next) {
225                 /* check if any pose matches this */
226                 for (marker= act->markers.first; marker; marker= marker->next) {
227                         if (IS_EQ(marker->frame, ak->cfra)) {
228                                 marker->flag = -1;
229                                 break;
230                         }
231                 }
232                 
233                 /* add new if none found */
234                 if (marker == NULL) {
235                         char name[64];
236                         
237                         /* add pose to poselib */
238                         marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
239                         
240                         strcpy(name, "Pose");
241                         BLI_strncpy(marker->name, name, sizeof(marker->name));
242                         
243                         marker->frame= (int)ak->cfra;
244                         marker->flag= -1;
245                         
246                         BLI_addtail(&act->markers, marker);
247                 }
248         }
249         
250         /* remove all untagged poses (unused), and remove all tags */
251         for (marker= act->markers.first; marker; marker= markern) {
252                 markern= marker->next;
253                 
254                 if (marker->flag != -1)
255                         BLI_freelinkN(&act->markers, marker);
256                 else
257                         marker->flag = 0;
258         }
259         
260         /* free temp memory */
261         BLI_freelistN(&keys);
262         
263         BIF_undo_push("PoseLib Validate Action");
264 }
265
266 /* ************************************************************* */
267
268 /* This function adds an ipo-curve of the right type where it's needed */
269 static IpoCurve *poselib_verify_icu (Ipo *ipo, int adrcode)
270 {
271         IpoCurve *icu;
272         
273         for (icu= ipo->curve.first; icu; icu= icu->next) {
274                 if (icu->adrcode==adrcode) break;
275         }
276         if (icu==NULL) {
277                 icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
278                 
279                 icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
280                 if (ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE;    /* first one added active */
281                 
282                 icu->blocktype= ID_PO;
283                 icu->adrcode= adrcode;
284                 
285                 set_icu_vars(icu);
286                 
287                 BLI_addtail(&ipo->curve, icu);
288         }
289         
290         return icu;
291 }
292
293 /* This tool adds the current pose to the poselib 
294  *      Note: Standard insertkey cannot be used for this due to its limitations
295  */
296 void poselib_add_current_pose (Object *ob, int val)
297 {
298         bArmature *arm= (ob) ? ob->data : NULL;
299         bPose *pose= (ob) ? ob->pose : NULL;
300         bPoseChannel *pchan;
301         TimeMarker *marker;
302         bAction *act;
303         bActionChannel *achan;
304         IpoCurve *icu;
305         int frame;
306         char name[64];
307         
308         /* sanity check */
309         if (ELEM3(NULL, ob, arm, pose)) 
310                 return;
311         
312         /* mode - add new or replace existing */
313         if (val == 0) {
314                 if ((ob->poselib) && (ob->poselib->markers.first)) {
315                         val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Add New (Current Frame)%x3|Replace Existing%x2");
316                         if (val <= 0) return;
317                 }
318                 else 
319                         val= 1;
320         }
321         
322         if ((ob->poselib) && (val == 2)) {
323                 char *menustr;
324                 
325                 /* get poselib */
326                 act= ob->poselib;
327                 
328                 /* get the pose to replace */
329                 menustr= poselib_build_poses_menu(act, "Replace PoseLib Pose");
330                 val= pupmenu_col(menustr, 20);
331                 if (menustr) MEM_freeN(menustr);
332                 
333                 if (val <= 0) return;
334                 marker= BLI_findlink(&act->markers, val-1);
335                 if (marker == NULL) return;
336                 
337                 /* get the frame from the poselib */
338                 frame= marker->frame;
339         }
340         else {
341                 /* get name of pose */
342                 sprintf(name, "Pose");
343                 if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
344                         return;
345                         
346                 /* get/initialise poselib */
347                 act= poselib_validate(ob);
348                 
349                 /* get frame */
350                 if (val == 3)
351                         frame= CFRA;
352                 else /* if (val == 1) */
353                         frame= poselib_get_free_index(act);
354                 
355                 /* add pose to poselib - replaces any existing pose there */
356                 for (marker= act->markers.first; marker; marker= marker->next) {
357                         if (marker->frame == frame) {
358                                 BLI_strncpy(marker->name, name, sizeof(marker->name));
359                                 break;
360                         }
361                 }
362                 if (marker == NULL) {
363                         marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
364                         
365                         BLI_strncpy(marker->name, name, sizeof(marker->name));
366                         marker->frame= frame;
367                         
368                         BLI_addtail(&act->markers, marker);
369                 }
370                 
371                 /* validate name */
372                 BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
373         }       
374         
375         /* loop through selected posechannels, keying their pose to the action */
376         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
377                 /* check if available */
378                 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
379                         if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
380                                 /* make action-channel if needed (action groups are also created) */
381                                 achan= verify_action_channel(act, pchan->name);
382                                 verify_pchan2achan_grouping(act, pose, pchan->name);
383                                 
384                                 /* make ipo if needed... */
385                                 if (achan->ipo == NULL)
386                                         achan->ipo= add_ipo(achan->name, ID_PO);
387                                         
388                                 /* add missing ipo-curves and insert keys */
389                                 #define INSERT_KEY_ICU(adrcode, data) {\
390                                                 icu= poselib_verify_icu(achan->ipo, adrcode); \
391                                                 insert_vert_icu(icu, (float)frame, data, 1); \
392                                         }
393                                         
394                                 INSERT_KEY_ICU(AC_LOC_X, pchan->loc[0])
395                                 INSERT_KEY_ICU(AC_LOC_Y, pchan->loc[1])
396                                 INSERT_KEY_ICU(AC_LOC_Z, pchan->loc[2])
397                                 INSERT_KEY_ICU(AC_SIZE_X, pchan->size[0])
398                                 INSERT_KEY_ICU(AC_SIZE_Y, pchan->size[1])
399                                 INSERT_KEY_ICU(AC_SIZE_Z, pchan->size[2])
400                                 INSERT_KEY_ICU(AC_QUAT_W, pchan->quat[0])
401                                 INSERT_KEY_ICU(AC_QUAT_X, pchan->quat[1])
402                                 INSERT_KEY_ICU(AC_QUAT_Y, pchan->quat[2])
403                                 INSERT_KEY_ICU(AC_QUAT_Z, pchan->quat[3])
404                         }
405                 }
406         }
407         
408         /* store new 'active' pose number */
409         act->active_marker= BLI_countlist(&act->markers);
410         
411         BIF_undo_push("PoseLib Add Pose");
412         allqueue(REDRAWBUTSEDIT, 0);
413 }
414
415
416 /* This tool removes the pose that the user selected from the poselib (or the provided pose) */
417 void poselib_remove_pose (Object *ob, TimeMarker *marker)
418 {
419         bPose *pose= (ob) ? ob->pose : NULL;
420         bAction *act= (ob) ? ob->poselib : NULL;
421         bActionChannel *achan;
422         char *menustr;
423         int val;
424         
425         /* check if valid poselib */
426         if (ELEM(NULL, ob, pose)) {
427                 error("PoseLib is only for Armatures in PoseMode");
428                 return;
429         }
430         if (act == NULL) {
431                 error("Object doesn't have PoseLib data");
432                 return;
433         }
434         
435         /* get index (and pointer) of pose to remove */
436         if (marker == NULL) {
437                 menustr= poselib_build_poses_menu(act, "Remove PoseLib Pose");
438                 val= pupmenu_col(menustr, 20);
439                 if (menustr) MEM_freeN(menustr);
440                 
441                 if (val <= 0) return;
442                 marker= BLI_findlink(&act->markers, val-1);
443                 if (marker == NULL) return;
444         }
445         else {
446                 /* only continue if pose belongs to poselib */
447                 if (BLI_findindex(&act->markers, marker) == -1) 
448                         return;
449         }
450         
451         /* remove relevant keyframes */
452         for (achan= act->chanbase.first; achan; achan= achan->next) {
453                 Ipo *ipo= achan->ipo;
454                 IpoCurve *icu;
455                 BezTriple *bezt;
456                 int i;
457                 
458                 for (icu= ipo->curve.first; icu; icu= icu->next) {
459                         for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
460                                 /* check if remove... */
461                                 if (IS_EQ(bezt->vec[1][0], marker->frame)) {
462                                         delete_icu_key(icu, i, 1);
463                                         break;
464                                 }
465                         }       
466                 }
467         }
468         
469         /* remove poselib from list */
470         BLI_freelinkN(&act->markers, marker);
471         
472         /* fix active pose number */
473         act->active_marker= 0;
474         
475         /* undo + redraw */
476         BIF_undo_push("PoseLib Remove Pose");
477         allqueue(REDRAWBUTSEDIT, 0);
478         allqueue(REDRAWACTION, 0);
479 }
480
481
482 /* This tool renames the pose that the user selected from the poselib */
483 void poselib_rename_pose (Object *ob)
484 {
485         bPose *pose= (ob) ? ob->pose : NULL;
486         bAction *act= (ob) ? ob->poselib : NULL;
487         TimeMarker *marker;
488         char *menustr, name[64];
489         int val;
490         
491         /* check if valid poselib */
492         if (ELEM(NULL, ob, pose)) {
493                 error("PoseLib is only for Armatures in PoseMode");
494                 return;
495         }
496         if (act == NULL) {
497                 error("Object doesn't have a valid PoseLib");
498                 return;
499         }
500         
501         /* get index of pose to remove */
502         menustr= poselib_build_poses_menu(act, "Rename PoseLib Pose");
503         val= pupmenu_col(menustr, 20);
504         if (menustr) MEM_freeN(menustr);
505         
506         if (val <= 0) return;
507         marker= BLI_findlink(&act->markers, val-1);
508         if (marker == NULL) return;
509         
510         /* get name of pose */
511         sprintf(name, marker->name);
512         if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
513                 return;
514         
515         /* copy name and validate it */
516         BLI_strncpy(marker->name, name, sizeof(marker->name));
517         BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
518         
519         /* undo and update */
520         BIF_undo_push("PoseLib Rename Pose");
521         allqueue(REDRAWBUTSEDIT, 0);
522         allqueue(REDRAWACTION, 0);
523 }
524
525
526 /* ************************************************************* */
527
528 /* Simple struct for storing settings/data for use during PoseLib preview */
529 typedef struct tPoseLib_PreviewData {
530         ListBase backups;               /* tPoseLib_Backup structs for restoring poses */
531         ListBase searchp;               /* LinkData structs storing list of poses which match the current search-string */
532         
533         Object *ob;                             /* object to work on */
534         bArmature *arm;                 /* object's armature data */
535         bPose *pose;                    /* object's pose */
536         bAction *act;                   /* poselib to use */
537         TimeMarker *marker;             /* 'active' pose */
538         
539         short state;                    /* state of main loop */
540         short redraw;                   /* redraw/update settings during main loop */
541         short flag;                             /* flags for various settings */
542         
543         int selcount;                   /* number of selected elements to work on */
544         int totcount;                   /* total number of elements to work on */
545         
546         char headerstr[200];    /* Info-text to print in header */
547         
548         char searchstr[64];             /* (Part of) Name to search for to filter poses that get shown */
549         char searchold[64];             /* Previously set searchstr (from last loop run), so that we can detected when to rebuild searchp */
550         short search_cursor;    /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
551 } tPoseLib_PreviewData;
552
553 /* defines for tPoseLib_PreviewData->state values */
554 enum {
555         PL_PREVIEW_ERROR = -1,
556         PL_PREVIEW_RUNNING,
557         PL_PREVIEW_CONFIRM,
558         PL_PREVIEW_CANCEL,
559         PL_PREVIEW_RUNONCE 
560 };
561
562 /* defines for tPoseLib_PreviewData->redraw values */
563 enum {
564         PL_PREVIEW_NOREDRAW = 0,
565         PL_PREVIEW_REDRAWALL,
566         PL_PREVIEW_REDRAWHEADER,
567 };
568
569 /* defines for tPoseLib_PreviewData->flag values */
570 enum {
571         PL_PREVIEW_FIRSTTIME    = (1<<0),
572         PL_PREVIEW_SHOWORIGINAL = (1<<1)
573 };
574
575 /* ---------------------------- */
576
577 /* simple struct for storing backup info */
578 typedef struct tPoseLib_Backup {
579         struct tPoseLib_Backup *next, *prev;
580         
581         bPoseChannel *pchan;
582         bPoseChannel olddata;
583 } tPoseLib_Backup;
584
585 /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
586 static void poselib_backup_posecopy (tPoseLib_PreviewData *pld)
587 {
588         bActionChannel *achan;
589         bPoseChannel *pchan;
590         
591         /* for each posechannel that has an actionchannel in */
592         for (achan= pld->act->chanbase.first; achan; achan= achan->next) {
593                 /* try to find posechannel */
594                 pchan= get_pose_channel(pld->pose, achan->name);
595                 
596                 /* backup data if available */
597                 if (pchan) {
598                         tPoseLib_Backup *plb;
599                         
600                         /* store backup */
601                         plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
602                         
603                         plb->pchan= pchan;
604                         memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
605                         
606                         BLI_addtail(&pld->backups, plb);
607                         
608                         /* mark as being affected */
609                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
610                                 pld->selcount++;
611                         pld->totcount++;
612                 }
613         }
614 }
615
616 /* Restores original pose - doesn't do constraints currently */
617 static void poselib_backup_restore (tPoseLib_PreviewData *pld)
618 {
619         tPoseLib_Backup *plb;
620         
621         for (plb= pld->backups.first; plb; plb= plb->next) {
622                 memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
623         }
624 }
625
626 /* ---------------------------- */
627
628 /* Applies the appropriate stored pose from the pose-library to the current pose
629  *      - assumes that a valid object, with a poselib has been supplied
630  *      - gets the string to print in the header
631  *      - this code is based on the code for extract_pose_from_action in blenkernel/action.c
632  */
633 static void poselib_apply_pose (tPoseLib_PreviewData *pld)
634 {
635         bPose *pose= pld->pose;
636         bPoseChannel *pchan;
637         bAction *act= pld->act;
638         bActionChannel *achan;
639         IpoCurve *icu;
640         int frame;
641         
642         if (pld->marker)
643                 frame= pld->marker->frame;
644         else
645                 return; 
646         
647         /* start applying - only those channels which have a key at this point in time! */
648         for (achan= act->chanbase.first; achan; achan= achan->next) {
649                 short found= 0;
650                 
651                 /* apply this achan? */
652                 if (achan->ipo) {
653                         /* find a keyframe at this frame - users may not have defined the pose on every channel, so this is necessary */
654                         // TODO: this may be bad for user-defined poses...
655                         for (icu= achan->ipo->curve.first; icu; icu= icu->next) {
656                                 BezTriple *bezt;
657                                 int i;
658                                 
659                                 for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
660                                         if (IN_RANGE(bezt->vec[1][0], (frame-0.5f), (frame+0.5f))) {
661                                                 found= 1;
662                                                 break;
663                                         }
664                                 }
665                                 
666                                 if (found) break;
667                         }
668                         
669                         /* apply pose - only if posechannel selected? */
670                         if (found) {
671                                 pchan= get_pose_channel(pose, achan->name);
672                                 
673                                 if (pchan) {    
674                                         short ok= 0;
675                                         
676                                         if (pchan->bone) {
677                                                 if ( (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) &&
678                                                          (pchan->bone->flag & BONE_HIDDEN_P)==0 )
679                                                         ok = 1;
680                                                 else if (pld->selcount == 0)
681                                                         ok= 1;
682                                         }
683                                         else if (pld->selcount == 0)
684                                                 ok= 1;
685                                         
686                                         if (ok) {
687                                                 /* Evaluates and sets the internal ipo values   */
688                                                 calc_ipo(achan->ipo, (float)frame);
689                                                 /* This call also sets the pchan flags */
690                                                 execute_action_ipo(achan, pchan);
691                                         }
692                                 }
693                         }
694                 }
695                 
696                 /* tag achan as having been used or not... */
697                 if (found)
698                         achan->flag |= ACHAN_SELECTED;
699                 else
700                         achan->flag &= ~ACHAN_SELECTED;
701         }
702 }
703
704 /* Auto-keys/tags bones affected by the pose used from the poselib */
705 static void poselib_keytag_pose (tPoseLib_PreviewData *pld)
706 {
707         bPose *pose= pld->pose;
708         bPoseChannel *pchan;
709         bAction *act= pld->act;
710         bActionChannel *achan;
711         
712         /* start tagging/keying */
713         for (achan= act->chanbase.first; achan; achan= achan->next) {
714                 /* only for selected action channels */
715                 if (achan->flag & ACHAN_SELECTED) {
716                         pchan= get_pose_channel(pose, achan->name);
717                         
718                         if (pchan) {
719                                 // TODO: use a standard autokeying function in future (to allow autokeying-editkeys to work)
720                                 if (IS_AUTOKEY_MODE(NORMAL)) {
721                                         ID *id= &pld->ob->id;
722                                         
723                                         /* Set keys on pose */
724                                         if (pchan->flag & POSE_ROT) {
725                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
726                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
727                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
728                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
729                                         }
730                                         if (pchan->flag & POSE_SIZE) {
731                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
732                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
733                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
734                                         }
735                                         if (pchan->flag & POSE_LOC) {
736                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
737                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
738                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
739                                         }
740                                         
741                                         /* clear any unkeyed tags */
742                                         if (pchan->bone)
743                                                 pchan->bone->flag &= ~BONE_UNKEYED;
744                                 }
745                                 else {
746                                         /* add unkeyed tags */
747                                         if (pchan->bone)
748                                                 pchan->bone->flag |= BONE_UNKEYED;
749                                 }
750                         }
751                 }
752         }
753 }
754
755 /* ---------------------------- */
756
757 /* This helper function is called during poselib_preview_poses to find the 
758  * pose to preview next (after a change event)
759  */
760 static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step)
761 {
762         /* check if we no longer have search-string, but don't have any marker */
763         if (pld->marker == NULL) {
764                 if ((step) && (pld->searchstr[0] == 0))
765                         pld->marker= pld->act->markers.first;
766         }       
767         
768         /* the following operations assume that there is a starting point and direction */
769         if ((pld->marker) && (step)) {
770                 /* search-string dictates a special approach */
771                 if (pld->searchstr[0]) {
772                         TimeMarker *marker;
773                         LinkData *ld, *ldn, *ldc;
774                         
775                         /* free and rebuild if needed (i.e. if search-str changed) */
776                         if (strcmp(pld->searchstr, pld->searchold)) {
777                                 /* free list of temporary search matches */
778                                 BLI_freelistN(&pld->searchp);
779                                 
780                                 /* generate a new list of search matches */
781                                 for (marker= pld->act->markers.first; marker; marker= marker->next) {
782                                         /* does the name partially match? 
783                                          *      - don't worry about case, to make it easier for users to quickly input a name (or 
784                                          *        part of one), which is the whole point of this feature
785                                          */
786                                         if (BLI_strcasestr(marker->name, pld->searchstr)) {
787                                                 /* make link-data to store reference to it */
788                                                 ld= MEM_callocN(sizeof(LinkData), "PoseMatch");
789                                                 ld->data= marker;
790                                                 BLI_addtail(&pld->searchp, ld);
791                                         }
792                                 }
793                                 
794                                 /* set current marker to NULL (so that we start from first) */
795                                 pld->marker= NULL;
796                         }
797                         
798                         /* check if any matches */
799                         if (pld->searchp.first == NULL) { 
800                                 pld->marker= NULL;
801                                 return;
802                         }
803                         
804                         /* find first match */
805                         for (ldc= pld->searchp.first; ldc; ldc= ldc->next) {
806                                 if (ldc->data == pld->marker)
807                                         break;
808                         }
809                         if (ldc == NULL)
810                                 ldc= pld->searchp.first;
811                                 
812                         /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate 
813                          * until step == 0. At this point, marker should be the correct marker.
814                          */
815                         if (step > 0) {
816                                 for (ld=ldc; ld && step; ld=ldn, step--)
817                                         ldn= (ld->next) ? ld->next : pld->searchp.first;
818                         }
819                         else {
820                                 for (ld=ldc; ld && step; ld=ldn, step++)
821                                         ldn= (ld->prev) ? ld->prev : pld->searchp.last;
822                         }
823                         
824                         /* set marker */
825                         if (ld)
826                                 pld->marker= ld->data;
827                 }
828                 else {
829                         TimeMarker *marker, *next;
830                         
831                         /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate 
832                          * until step == 0. At this point, marker should be the correct marker.
833                          */
834                         if (step > 0) {
835                                 for (marker=pld->marker; marker && step; marker=next, step--)
836                                         next= (marker->next) ? marker->next : pld->act->markers.first;
837                         }
838                         else {
839                                 for (marker=pld->marker; marker && step; marker=next, step++)
840                                         next= (marker->prev) ? marker->prev : pld->act->markers.last;
841                         }
842                         
843                         /* it should be fairly impossible for marker to be NULL */
844                         if (marker)
845                                 pld->marker= marker;
846                 }
847         }
848 }
849
850 /* specially handle events for searching */
851 static void poselib_preview_handle_search (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
852 {
853         if (ascii) {
854                 /* character to add to the string */
855                 short index= pld->search_cursor;
856                 short len= (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
857                 short i;
858                 
859                 if (len) {
860                         for (i = len; i > index; i--)  
861                                 pld->searchstr[i]= pld->searchstr[i-1];
862                 }
863                 else
864                         pld->searchstr[1]= 0;
865                         
866                 pld->searchstr[index]= ascii;
867                 pld->search_cursor++;
868                 
869                 poselib_preview_get_next(pld, 1);
870                 pld->redraw = PL_PREVIEW_REDRAWALL;
871         }
872         else {
873                 /* some form of string manipulation */
874                 switch (event) {
875                         case BACKSPACEKEY:
876                                 if (pld->searchstr[0] && pld->search_cursor) {
877                                         short len= strlen(pld->searchstr);
878                                         short index= pld->search_cursor;
879                                         short i;
880                                         
881                                         for (i = index; i <= len; i++) 
882                                                 pld->searchstr[i-1] = pld->searchstr[i];
883                                         
884                                         pld->search_cursor--;
885                                         
886                                         poselib_preview_get_next(pld, 1);
887                                         pld->redraw = PL_PREVIEW_REDRAWALL;
888                                 }       
889                                 break;
890                                 
891                         case DELKEY:
892                                 if (pld->searchstr[0] && pld->searchstr[1]) {
893                                         short len= strlen(pld->searchstr);
894                                         short index= pld->search_cursor;
895                                         int i;
896                                         
897                                         if (index < len) {
898                                                 for (i = index; i < len; i++) 
899                                                         pld->searchstr[i] = pld->searchstr[i+1];
900                                                         
901                                                 poselib_preview_get_next(pld, 1);
902                                                 pld->redraw = PL_PREVIEW_REDRAWALL;
903                                         }
904                                 }
905                                 break;
906                 }
907         }
908 }
909
910 /* handle events for poselib_preview_poses */
911 static void poselib_preview_handle_event (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
912 {
913         /* backup stuff that needs to occur before every operation
914          *      - make a copy of searchstr, so that we know if cache needs to be rebuilt
915          */
916         strcpy(pld->searchold, pld->searchstr);
917         
918         /* if we're currently showing the original pose, only certain events are handled */
919         if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
920                 switch (event) {
921                         /* exit - cancel */
922                         case ESCKEY:
923                         case RIGHTMOUSE:
924                                 pld->state= PL_PREVIEW_CANCEL;
925                                 break;
926                                 
927                         /* exit - confirm */
928                         case LEFTMOUSE:
929                         case RETKEY:
930                         case PADENTER:
931                         case SPACEKEY:
932                                 pld->state= PL_PREVIEW_CONFIRM;
933                                 break;
934                         
935                         /* view manipulation */
936                         case MIDDLEMOUSE:
937                                 // there's a little bug here that causes the normal header to get drawn while view is manipulated 
938                                 handle_view_middlemouse();
939                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
940                                 break;
941                                 
942                         /* view manipulation, or searching */
943                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
944                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
945                         case PADPLUSKEY: case PADMINUS:
946                                 persptoetsen(event);
947                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
948                                 break;
949                                 
950                         case TABKEY:
951                                 pld->flag &= ~PL_PREVIEW_SHOWORIGINAL;
952                                 pld->redraw= PL_PREVIEW_REDRAWALL;
953                                 break;
954                 }
955                 
956                 /* EXITS HERE... */
957                 return;
958         }
959         
960         /* NORMAL EVENT HANDLING... */
961         /* searching takes priority over normal activity */
962         switch (event) {
963                 /* exit - cancel */
964                 case ESCKEY:
965                 case RIGHTMOUSE:
966                         pld->state= PL_PREVIEW_CANCEL;
967                         break;
968                         
969                 /* exit - confirm */
970                 case LEFTMOUSE:
971                 case RETKEY:
972                 case PADENTER:
973                 case SPACEKEY:
974                         pld->state= PL_PREVIEW_CONFIRM;
975                         break;
976                         
977                 /* toggle between original pose and poselib pose*/
978                 case TABKEY:
979                         pld->flag |= PL_PREVIEW_SHOWORIGINAL;
980                         pld->redraw= PL_PREVIEW_REDRAWALL;
981                         break;
982                 
983                 /* change to previous pose (cyclic) */
984                 case PAGEUPKEY:
985                 case WHEELUPMOUSE:
986                         poselib_preview_get_next(pld, -1);
987                         pld->redraw= PL_PREVIEW_REDRAWALL;
988                         break;
989                 
990                 /* change to next pose (cyclic) */
991                 case PAGEDOWNKEY:
992                 case WHEELDOWNMOUSE:
993                         poselib_preview_get_next(pld, 1);
994                         pld->redraw= PL_PREVIEW_REDRAWALL;
995                         break;
996                 
997                 /* jump 5 poses (cyclic, back) */
998                 case DOWNARROWKEY:
999                         poselib_preview_get_next(pld, -5);
1000                         pld->redraw= PL_PREVIEW_REDRAWALL;
1001                         break;
1002                 
1003                 /* jump 5 poses (cyclic, forward) */
1004                 case UPARROWKEY:
1005                         poselib_preview_get_next(pld, 5);
1006                         pld->redraw= PL_PREVIEW_REDRAWALL;
1007                         break;
1008                 
1009                 /* change to next pose or searching cursor control */
1010                 case RIGHTARROWKEY:
1011                         if (pld->searchstr[0]) {
1012                                 /* move text-cursor to the right */
1013                                 if (pld->search_cursor < strlen(pld->searchstr))
1014                                         pld->search_cursor++;
1015                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
1016                         }
1017                         else {
1018                                 /* change to next pose (cyclic) */
1019                                 poselib_preview_get_next(pld, 1);
1020                                 pld->redraw= PL_PREVIEW_REDRAWALL;
1021                         }
1022                         break;
1023                         
1024                 /* change to next pose or searching cursor control */
1025                 case LEFTARROWKEY:
1026                         if (pld->searchstr[0]) {
1027                                 /* move text-cursor to the left */
1028                                 if (pld->search_cursor)
1029                                         pld->search_cursor--;
1030                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
1031                         }
1032                         else {
1033                                 /* change to previous pose (cyclic) */
1034                                 poselib_preview_get_next(pld, -1);
1035                                 pld->redraw= PL_PREVIEW_REDRAWALL;
1036                         }
1037                         break;
1038                         
1039                 /* change to first pose or start of searching string */
1040                 case HOMEKEY:
1041                         if (pld->searchstr[0]) {
1042                                 pld->search_cursor= 0;
1043                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
1044                         }
1045                         else {
1046                                 /* change to first pose */
1047                                 pld->marker= pld->act->markers.first;
1048                                 pld->act->active_marker= 1;
1049                                 
1050                                 pld->redraw= PL_PREVIEW_REDRAWALL;
1051                         }
1052                         break;
1053                         
1054                 /* change to last pose or start of searching string */
1055                 case ENDKEY:
1056                         if (pld->searchstr[0]) {
1057                                 pld->search_cursor= strlen(pld->searchstr);
1058                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
1059                         }
1060                         else {
1061                                 /* change to last pose */
1062                                 pld->marker= pld->act->markers.last;
1063                                 pld->act->active_marker= BLI_countlist(&pld->act->markers);
1064                                 
1065                                 pld->redraw= PL_PREVIEW_REDRAWALL;
1066                         }
1067                         break;
1068                         
1069                 /* view manipulation */
1070                 case MIDDLEMOUSE:
1071                         // there's a little bug here that causes the normal header to get drawn while view is manipulated 
1072                         handle_view_middlemouse();
1073                         pld->redraw= PL_PREVIEW_REDRAWHEADER;
1074                         break;
1075                         
1076                 /* view manipulation, or searching */
1077                 case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1078                 case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1079                 case PADPLUSKEY: case PADMINUS:
1080                         if (pld->searchstr[0]) {
1081                                 poselib_preview_handle_search(pld, event, ascii);
1082                         }
1083                         else {
1084                                 persptoetsen(event);
1085                                 pld->redraw= PL_PREVIEW_REDRAWHEADER;
1086                         }
1087                         break;
1088                         
1089                 /* otherwise, assume that searching might be able to handle it */
1090                 default:
1091                         poselib_preview_handle_search(pld, event, ascii);
1092                         break;
1093         }
1094 }
1095
1096 /* ---------------------------- */
1097
1098 /* Init PoseLib Previewing data */
1099 static void poselib_preview_init_data (tPoseLib_PreviewData *pld, Object *ob, short apply_active)
1100 {
1101         /* clear pld first as it resides on the stack */
1102         memset(pld, 0, sizeof(tPoseLib_PreviewData));
1103         
1104         /* get basic data */
1105         pld->ob= ob;
1106         pld->arm= (ob) ? (ob->data) : NULL;
1107         pld->pose= (ob) ? (ob->pose) : NULL;
1108         pld->act= (ob) ? (ob->poselib) : NULL;
1109         pld->marker= poselib_get_active_pose(pld->act);
1110         
1111         /* check if valid poselib */
1112         if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) {
1113                 error("PoseLib is only for Armatures in PoseMode");
1114                 pld->state= PL_PREVIEW_ERROR;
1115                 return;
1116         }
1117         if (pld->act == NULL) {
1118                 error("Object doesn't have a valid PoseLib");
1119                 pld->state= PL_PREVIEW_ERROR;
1120                 return;
1121         }
1122         if (pld->marker == NULL) {
1123                 if ((apply_active==0) && (pld->act->markers.first)) {
1124                         /* just use first one then... */
1125                         pld->marker= pld->act->markers.first;
1126                         printf("PoseLib had no active pose\n");
1127                 }
1128                 else {
1129                         error("PoseLib has no poses to preview/apply");
1130                         pld->state= PL_PREVIEW_ERROR;
1131                         return;
1132                 }
1133         }
1134         
1135         /* make backups for restoring pose */
1136         poselib_backup_posecopy(pld);
1137         
1138         /* set flags for running */
1139         pld->state= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING;
1140         pld->redraw= PL_PREVIEW_REDRAWALL;
1141         pld->flag= PL_PREVIEW_FIRSTTIME;
1142         
1143         /* set depsgraph flags */
1144                 /* make sure the lock is set OK, unlock can be accidentally saved? */
1145         pld->pose->flag |= POSE_LOCKED;
1146         pld->pose->flag &= ~POSE_DO_UNLOCK;
1147         
1148         /* clear strings + search */
1149         strcpy(pld->headerstr, "");
1150         strcpy(pld->searchstr, "");
1151         strcpy(pld->searchold, "");
1152         pld->search_cursor= 0;
1153 }
1154
1155 /* After previewing poses */
1156 static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
1157 {
1158         Object *ob= pld->ob;
1159         bPose *pose= pld->pose;
1160         bArmature *arm= pld->arm;
1161         bAction *act= pld->act;
1162         TimeMarker *marker= pld->marker;
1163         
1164         /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
1165         pose->flag |= POSE_DO_UNLOCK;
1166         
1167         /* clear pose if cancelled */
1168         if (pld->state == PL_PREVIEW_CANCEL) {
1169                 poselib_backup_restore(pld);
1170                 
1171                 /* old optimize trick... this enforces to bypass the depgraph 
1172                  *      - note: code copied from transform_generics.c -> recalcData()
1173                  */
1174                 if ((arm->flag & ARM_DELAYDEFORM)==0)
1175                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
1176                 else
1177                         where_is_pose(ob);
1178                 
1179                 allqueue(REDRAWVIEW3D, 0);
1180                 allqueue(REDRAWBUTSEDIT, 0);
1181         }
1182         else if (pld->state == PL_PREVIEW_CONFIRM) {
1183                 /* tag poses as appropriate */
1184                 poselib_keytag_pose(pld);
1185                 
1186                 /* change active pose setting */
1187                 act->active_marker= BLI_findindex(&act->markers, marker) + 1;
1188                 action_set_activemarker(act, marker, 0);
1189                 
1190                 /* Update event for pose and deformation children */
1191                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1192                 
1193                 /* updates */
1194                 if (IS_AUTOKEY_MODE(NORMAL)) {
1195                         remake_action_ipos(ob->action);
1196                         
1197                         allqueue(REDRAWIPO, 0);
1198                         allqueue(REDRAWVIEW3D, 0);
1199                         allqueue(REDRAWBUTSEDIT, 0);
1200                         allqueue(REDRAWACTION, 0);              
1201                         allqueue(REDRAWNLA, 0);
1202                 }
1203                 else {
1204                         /* need to trick depgraph, action is not allowed to execute on pose */
1205                         where_is_pose(ob);
1206                         ob->recalc= 0;
1207                         
1208                         allqueue(REDRAWVIEW3D, 0);
1209                         allqueue(REDRAWBUTSEDIT, 0);
1210                 }
1211         }
1212         
1213         /* free memory used for backups */
1214         BLI_freelistN(&pld->backups);
1215         BLI_freelistN(&pld->searchp);
1216 }
1217
1218
1219
1220 /* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown
1221  * It is also used to apply the active poselib pose only
1222  */
1223 void poselib_preview_poses (Object *ob, short apply_active)
1224 {
1225         tPoseLib_PreviewData pld;
1226         
1227         unsigned short event;
1228         short val=0;
1229         char ascii;
1230         
1231         /* check if valid poselib */
1232         poselib_preview_init_data(&pld, ob, apply_active);
1233         if (pld.state == PL_PREVIEW_ERROR)
1234                 return;
1235                 
1236         /* start preview loop */
1237         while (ELEM(pld.state, PL_PREVIEW_RUNNING, PL_PREVIEW_RUNONCE)) {
1238                 /* preview a pose */
1239                 if (pld.redraw) {
1240                         /* only recalc pose (and its dependencies) if pose has changed */
1241                         if (pld.redraw == PL_PREVIEW_REDRAWALL) {
1242                                 /* don't clear pose if firsttime */
1243                                 if ((pld.flag & PL_PREVIEW_FIRSTTIME)==0)
1244                                         poselib_backup_restore(&pld);
1245                                 else
1246                                         pld.flag &= ~PL_PREVIEW_FIRSTTIME;
1247                                         
1248                                 /* pose should be the right one to draw (unless we're temporarily not showing it) */
1249                                 if ((pld.flag & PL_PREVIEW_SHOWORIGINAL)==0)
1250                                         poselib_apply_pose(&pld);
1251                                 
1252                                 /* old optimize trick... this enforces to bypass the depgraph 
1253                                  *      - note: code copied from transform_generics.c -> recalcData()
1254                                  */
1255                                 if ((pld.arm->flag & ARM_DELAYDEFORM)==0)
1256                                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
1257                                 else
1258                                         where_is_pose(ob);
1259                         }
1260                         
1261                         /* do header print - if interactively previewing */
1262                         if (pld.state == PL_PREVIEW_RUNNING) {
1263                                 if (pld.flag & PL_PREVIEW_SHOWORIGINAL) {
1264                                         sprintf(pld.headerstr, "PoseLib Previewing Pose: [Showing Original Pose] | Use Tab to start previewing poses again");
1265                                         headerprint(pld.headerstr);
1266                                 }
1267                                 else if (pld.searchstr[0]) {
1268                                         char tempstr[65];
1269                                         char markern[64];
1270                                         short index;
1271                                         
1272                                         /* get search-string */
1273                                         index= pld.search_cursor;
1274                                         
1275                                         if (IN_RANGE(index, 0, 64)) {
1276                                                 memcpy(&tempstr[0], &pld.searchstr[0], index);
1277                                                 tempstr[index]= '|';
1278                                                 memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
1279                                         }
1280                                         else {
1281                                                 strncpy(tempstr, pld.searchstr, 64);
1282                                         }
1283                                         
1284                                         /* get marker name */
1285                                         if (pld.marker)
1286                                                 strcpy(markern, pld.marker->name);
1287                                         else
1288                                                 strcpy(markern, "No Matches");
1289                                         
1290                                         sprintf(pld.headerstr, "PoseLib Previewing Pose: Filter - [%s] | Current Pose - \"%s\"  | Use ScrollWheel or PageUp/Down to change", tempstr, markern);
1291                                         headerprint(pld.headerstr);
1292                                 }
1293                                 else {
1294                                         sprintf(pld.headerstr, "PoseLib Previewing Pose: \"%s\"  | Use ScrollWheel or PageUp/Down to change", pld.marker->name);
1295                                         headerprint(pld.headerstr);
1296                                 }
1297                         }
1298                         
1299                         /* force drawing of view + clear redraw flag */
1300                         force_draw(0);
1301                         pld.redraw= PL_PREVIEW_NOREDRAW;
1302                 }
1303                 
1304                 /* stop now if only running once */
1305                 if (pld.state == PL_PREVIEW_RUNONCE) {
1306                         pld.state = PL_PREVIEW_CONFIRM;
1307                         break;
1308                 }
1309                 
1310                 /* essential for idling subloop */
1311                 if (qtest() == 0) 
1312                         PIL_sleep_ms(2);
1313                 
1314                 /* emptying queue and reading events */
1315                 while ( qtest() ) {
1316                         event= extern_qread_ext(&val, &ascii);
1317                         
1318                         /* event processing */
1319                         if (val) {
1320                                 poselib_preview_handle_event(&pld, event, ascii);
1321                         }
1322                 }
1323         }
1324         
1325         /* finish up */
1326         poselib_preview_cleanup(&pld);
1327         
1328         BIF_undo_push("PoseLib Apply Pose");
1329 }