Another step in the undo evolution.
[blender.git] / source / blender / src / editview.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * cursor/gestures/selecteren
32  */
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <string.h>
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #ifdef WIN32
44 #include "BLI_winstuff.h"
45 #endif
46
47 #include "IMB_imbuf.h"
48 #include "PIL_time.h"
49
50 #include "DNA_armature_types.h"
51 #include "DNA_meta_types.h"
52 #include "DNA_mesh_types.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_lattice_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_screen_types.h"
58 #include "DNA_view3d_types.h"
59 #include "DNA_userdef_types.h"
60
61 #include "BLI_blenlib.h"
62 #include "BLI_arithb.h"
63 #include "BLI_editVert.h"
64
65 #include "BKE_utildefines.h"
66 #include "BKE_global.h"
67 #include "BKE_armature.h"
68 #include "BKE_lattice.h"
69
70 #include "BIF_gl.h"
71 #include "BIF_mywindow.h"
72 #include "BIF_space.h"
73 #include "BIF_screen.h"
74 #include "BIF_butspace.h"
75 #include "BIF_editgroup.h"
76 #include "BIF_editmesh.h"
77 #include "BIF_editoops.h"
78 #include "BIF_editsima.h"
79 #include "BIF_editview.h"
80 #include "BIF_glutil.h"
81 #include "BIF_editarmature.h"
82 #include "BIF_toolbox.h"
83
84 #include "BDR_editobject.h"     /* For headerprint */
85 #include "BDR_vpaint.h"
86 #include "BDR_editface.h"
87 #include "BDR_drawobject.h"
88 #include "BDR_editcurve.h"
89
90 #include "BSE_edit.h"
91 #include "BSE_view.h"           /* give_cursor() */
92 #include "BSE_editipo.h"
93 #include "BSE_drawview.h"
94 #include "BSE_editaction.h"
95
96 #include "blendef.h"
97 #include "mydevice.h"
98
99 extern ListBase editNurb; /* originally from exports.h, memory from editcurve.c*/
100 /* editmball.c */
101 extern ListBase editelems;
102
103
104
105 void arrows_move_cursor(unsigned short event)
106 {
107         short mval[2];
108
109         getmouseco_sc(mval);
110
111         if(event==UPARROWKEY) {
112                 warp_pointer(mval[0], mval[1]+1);
113         } else if(event==DOWNARROWKEY) {
114                 warp_pointer(mval[0], mval[1]-1);
115         } else if(event==LEFTARROWKEY) {
116                 warp_pointer(mval[0]-1, mval[1]);
117         } else if(event==RIGHTARROWKEY) {
118                 warp_pointer(mval[0]+1, mval[1]);
119         }
120 }
121
122 #define MOVES 50
123
124
125 static char interpret_move(short mcord[][2], int count)
126 {
127         float x1, x2, y1, y2, d1, d2, inp, sq, mouse[MOVES][2];
128         int i, j, dir = 0;
129         
130         if (count <= 10) return ('g');
131
132         /* from short to float (drawing is with shorts) */
133         for(j=0; j<count; j++) {
134                 mouse[j][0]= mcord[j][0];
135                 mouse[j][1]= mcord[j][1];
136         }
137         
138         /* new method:
139          * 
140          * starting from end points, calculate centre with maximum distance
141          * dependant at the angle s / g / r is defined
142          */
143         
144
145         /* filter */
146         
147         for( j = 3 ; j > 0; j--){
148                 x1 = mouse[1][0];
149                 y1 = mouse[1][1];
150                 for (i = 2; i < count; i++){
151                         x2 = mouse[i-1][0];
152                         y2 = mouse[i-1][1];
153                         mouse[i-1][0] = ((x1 + mouse[i][0]) /4.0) + (x2 / 2.0);
154                         mouse[i-1][1] = ((y1 + mouse[i][1]) /4.0) + (y2 / 2.0);
155                         x1 = x2;
156                         y1 = y2;
157                 }
158         }
159
160         /* make overview of directions */
161         for (i = 0; i <= count - 2; i++){
162                 x1 = mouse[i][0] - mouse[i + 1][0];
163                 y1 = mouse[i][1] - mouse[i + 1][1];
164
165                 if (x1 < -0.5){
166                         if (y1 < -0.5) dir |= 32;
167                         else if (y1 > 0.5) dir |= 128;
168                         else dir |= 64;
169                 } else if (x1 > 0.5){
170                         if (y1 < -0.5) dir |= 8;
171                         else if (y1 > 0.5) dir |= 2;
172                         else dir |= 4;
173                 } else{
174                         if (y1 < -0.5) dir |= 16;
175                         else if (y1 > 0.5) dir |= 1;
176                         else dir |= 0;
177                 }
178         }
179         
180         /* move all crosses to the right */
181         for (i = 7; i>=0 ; i--){
182                 if (dir & 128) dir = (dir << 1) + 1;
183                 else break;
184         }
185         dir &= 255;
186         for (i = 7; i>=0 ; i--){
187                 if ((dir & 1) == 0) dir >>= 1;
188                 else break;
189         }
190         
191         /* in theory: 1 direction: straight line
192      * multiple sequential directions: circle
193      * non-sequential, and 1 bit set in upper 4 bits: size
194      */
195         switch(dir){
196         case 1:
197                 return ('g');
198                 break;
199         case 3:
200         case 7:
201                 x1 = mouse[0][0] - mouse[count >> 1][0];
202                 y1 = mouse[0][1] - mouse[count >> 1][1];
203                 x2 = mouse[count >> 1][0] - mouse[count - 1][0];
204                 y2 = mouse[count >> 1][1] - mouse[count - 1][1];
205                 d1 = (x1 * x1) + (y1 * y1);
206                 d2 = (x2 * x2) + (y2 * y2);
207                 sq = sqrt(d1);
208                 x1 /= sq; 
209                 y1 /= sq;
210                 sq = sqrt(d2);
211                 x2 /= sq; 
212                 y2 /= sq;
213                 inp = (x1 * x2) + (y1 * y2);
214                 /*printf("%f\n", inp);*/
215                 if (inp > 0.9) return ('g');
216                 else return ('r');
217                 break;
218         case 15:
219         case 31:
220         case 63:
221         case 127:
222         case 255:
223                 return ('r');
224                 break;
225         default:
226                 /* for size at least one of the higher bits has to be set */
227                 if (dir < 16) return ('r');
228                 else return ('s');
229         }
230
231         return (0);
232 }
233
234 int gesture(void)
235 {
236         short mcords[MOVES][2];
237         int i= 1, end= 0, a;
238         unsigned short event=0;
239         short mval[2], val, timer=0, mousebut;
240         
241         glDrawBuffer(GL_FRONT);
242         persp(0);       /*  ortho at pixel level */
243         
244         getmouseco_areawin(mval);
245         
246         mcords[0][0] = mval[0];
247         mcords[0][1] = mval[1];
248         
249         if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
250         else mousebut = L_MOUSE;
251         
252         while(get_mbut() & mousebut) {
253                 
254                 if(qtest()) event= extern_qread(&val);
255                 else if(i==1) {
256                         /* not drawing yet... check for toolbox */
257                         PIL_sleep_ms(10);
258                         timer++;
259                         if(timer>=10*U.tb_leftmouse) {
260                                 toolbox_n();
261                                 return 1;
262                         }
263                 }
264                 
265                 switch (event) {
266                 case MOUSEY:
267                         getmouseco_areawin(mval);
268                         if( abs(mval[0]-mcords[i-1][0])>3 || abs(mval[1]-mcords[i-1][1])>3 ) {
269                                 mcords[i][0] = mval[0];
270                                 mcords[i][1] = mval[1];
271                                 if(i) {
272                                         sdrawXORline(mcords[i-1][0], mcords[i-1][1], mcords[i][0], mcords[i][1]);
273                                         glFlush();
274                                 }
275                                 i++;
276                         }
277                         break;
278                 case MOUSEX:
279                         break;
280                 case LEFTMOUSE:
281                         break;
282                 default:
283                         if(event) end= 1;       /* blender returns 0 */
284                         break;
285                 }
286                 if (i == MOVES || end == 1) break;
287         }
288
289         for(a=1; a<i; a++) {
290                 sdrawXORline(mcords[a-1][0], mcords[a-1][1], mcords[a][0], mcords[a][1]);
291         }
292         
293         persp(1);
294         glDrawBuffer(GL_BACK);
295         
296         if (i > 2) {
297                 i = interpret_move(mcords, i);
298                 
299                 if(i) {
300                         if(curarea->spacetype==SPACE_IPO) transform_ipo(i);
301                         else if(curarea->spacetype==SPACE_IMAGE) transform_tface_uv(i);
302                         else if(curarea->spacetype==SPACE_OOPS) transform_oops('g');
303                         else transform(i);
304                 }
305                 
306                 return 1;
307         }
308         else return 0;
309 }
310
311 void mouse_cursor(void)
312 {
313         extern float zfac;      /* view.c */
314         float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3];
315         short mval[2], mx, my, lr_click=0;
316         
317         if(gesture()) return;
318         
319         getmouseco_areawin(mval);
320         
321         if(mval[0]!=G.vd->mx || mval[1]!=G.vd->my) {
322
323                 mx= mval[0];
324                 my= mval[1];
325                 
326                 fp= give_cursor();
327                 
328                 if(G.obedit && ((G.qual & LR_CTRLKEY) || get_mbut()&R_MOUSE )) lr_click= 1;
329                 VECCOPY(oldcurs, fp);
330                 
331                 project_short_noclip(fp, mval);
332
333                 initgrabz(fp[0], fp[1], fp[2]);
334                 
335                 if(mval[0]!=3200) {
336                         
337                         window_to_3d(dvec, mval[0]-mx, mval[1]-my);
338                         VecSubf(fp, fp, dvec);
339                         
340                 }
341                 else {
342
343                         dx= ((float)(mx-(curarea->winx/2)))*zfac/(curarea->winx/2);
344                         dy= ((float)(my-(curarea->winy/2)))*zfac/(curarea->winy/2);
345                         
346                         fz= G.vd->persmat[0][3]*fp[0]+ G.vd->persmat[1][3]*fp[1]+ G.vd->persmat[2][3]*fp[2]+ G.vd->persmat[3][3];
347                         fz= fz/zfac;
348                         
349                         fp[0]= (G.vd->persinv[0][0]*dx + G.vd->persinv[1][0]*dy+ G.vd->persinv[2][0]*fz)-G.vd->ofs[0];
350                         fp[1]= (G.vd->persinv[0][1]*dx + G.vd->persinv[1][1]*dy+ G.vd->persinv[2][1]*fz)-G.vd->ofs[1];
351                         fp[2]= (G.vd->persinv[0][2]*dx + G.vd->persinv[1][2]*dy+ G.vd->persinv[2][2]*fz)-G.vd->ofs[2];
352                 }
353                 
354                 allqueue(REDRAWVIEW3D, 1);
355         }
356         
357         if(lr_click) {
358                 if(G.obedit->type==OB_MESH) addvert_mesh();
359                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addvert_Nurb(0);
360                 else if (G.obedit->type==OB_ARMATURE) addvert_armature();
361                 VECCOPY(fp, oldcurs);
362         }
363         
364 }
365
366 void deselectall(void)  /* is toggle */
367 {
368         Base *base;
369         int a=0;
370
371         base= FIRSTBASE;
372         while(base) {
373                 if TESTBASE(base) {
374                         a= 1;
375                         break;
376                 }
377                 base= base->next;
378         }
379         
380         base= FIRSTBASE;
381         while(base) {
382                 if(base->lay & G.vd->lay) {
383                         if(a) base->flag &= ~SELECT;
384                         else base->flag |= SELECT;
385                         base->object->flag= base->flag;
386                 }
387                 base= base->next;
388         }
389
390         allqueue(REDRAWVIEW3D, 0);
391         allqueue(REDRAWDATASELECT, 0);
392         allqueue(REDRAWNLA, 0);
393         
394         countall();
395         BIF_undo_push("(De)select all");
396 }
397
398 /* selects all objects of a particular type, on currently visible layers */
399 void selectall_type(short obtype) 
400 {
401         Base *base;
402         
403         base= FIRSTBASE;
404         while(base) {
405                 if((base->lay & G.vd->lay) && (base->object->type == obtype)) {
406                         base->flag |= SELECT;
407                         base->object->flag= base->flag;
408                 }
409                 base= base->next;
410         }
411
412         allqueue(REDRAWVIEW3D, 0);
413         allqueue(REDRAWDATASELECT, 0);
414         allqueue(REDRAWNLA, 0);
415         
416         countall();
417         BIF_undo_push("Select all per type");
418 }
419 /* selects all objects on a particular layer */
420 void selectall_layer(int layernum) 
421 {
422         Base *base;
423         
424         base= FIRSTBASE;
425         while(base) {
426                 if (base->lay == (1<< (layernum -1))) {
427                         base->flag |= SELECT;
428                         base->object->flag= base->flag;
429                 }
430                 base= base->next;
431         }
432
433         allqueue(REDRAWVIEW3D, 0);
434         allqueue(REDRAWDATASELECT, 0);
435         allqueue(REDRAWNLA, 0);
436         
437         countall();
438         BIF_undo_push("Select all per layer");
439 }
440
441 static void deselectall_except(Base *b)   /* deselect all except b */
442 {
443         Base *base;
444
445         base= FIRSTBASE;
446         while(base) {
447                 if (base->flag & SELECT) {
448                         if(b!=base) {
449                                 base->flag &= ~SELECT;
450                                 base->object->flag= base->flag;
451                         }
452                 }
453                 base= base->next;
454         }
455 }
456
457 #if 0
458 /* smart function to sample a rect spiralling outside, nice for backbuf selection */
459 static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
460 {
461         Base *base;
462         unsigned int *bufmin,*bufmax;
463         int a,b,rc,tel,aantal,dirvec[4][2],maxob;
464         unsigned int retval=0;
465         
466         base= LASTBASE;
467         if(base==0) return 0;
468         maxob= base->selcol;
469
470         aantal= (size-1)/2;
471         rc= 0;
472
473         dirvec[0][0]= 1;
474         dirvec[0][1]= 0;
475         dirvec[1][0]= 0;
476         dirvec[1][1]= -size;
477         dirvec[2][0]= -1;
478         dirvec[2][1]= 0;
479         dirvec[3][0]= 0;
480         dirvec[3][1]= size;
481
482         bufmin= buf;
483         bufmax= buf+ size*size;
484         buf+= aantal*size+ aantal;
485
486         for(tel=1;tel<=size;tel++) {
487
488                 for(a=0;a<2;a++) {
489                         for(b=0;b<tel;b++) {
490
491                                 if(*buf && *buf<=maxob && *buf!=dontdo) return *buf;
492                                 if( *buf==dontdo ) retval= dontdo;      /* if only color dontdo is available, still return dontdo */
493                                 
494                                 buf+= (dirvec[rc][0]+dirvec[rc][1]);
495
496                                 if(buf<bufmin || buf>=bufmax) return retval;
497                         }
498                         rc++;
499                         rc &= 3;
500                 }
501         }
502         return retval;
503 }
504 #endif
505
506 #define SELECTSIZE      51
507
508 void set_active_base(Base *base)
509 {
510         
511         BASACT= base;
512         
513         /* signals to buttons */
514         redraw_test_buttons(base);
515
516         set_active_group();
517         
518         /* signal to ipo */
519
520         if (base) {
521                 allqueue(REDRAWIPO, base->object->ipowin);
522                 allqueue(REDRAWACTION, 0);
523                 allqueue(REDRAWNLA, 0);
524         }
525
526
527 }
528
529 void set_active_object(Object *ob)
530 {
531         Base *base;
532         
533         base= FIRSTBASE;
534         while(base) {
535                 if(base->object==ob) {
536                         set_active_base(base);
537                         return;
538                 }
539                 base= base->next;
540         }
541 }
542
543 void mouse_select(void)
544 {
545         Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
546         unsigned int buffer[MAXPICKBUF];
547         int temp, a, dist=100;
548         short hits, mval[2];
549
550         /* always start list from basact */
551         startbase=  FIRSTBASE;
552         if(BASACT && BASACT->next) startbase= BASACT->next;
553
554         getmouseco_areawin(mval);
555
556         if(G.obedit==0 && (G.qual & LR_CTRLKEY)) {
557
558                 base= startbase;
559                 while(base) {
560                         
561                         if(base->lay & G.vd->lay) {
562                                 
563                                 project_short(base->object->obmat[3], &base->sx);
564                                 
565                                 temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
566                                 if(base==BASACT) temp+=10;
567                                 if(temp<dist ) {
568                                         basact= base;
569                                         dist= temp;
570                                 }
571                         }
572                         base= base->next;
573                         
574                         if(base==0) base= FIRSTBASE;
575                         if(base==startbase) break;
576                 }
577
578                 /* complete redraw when: */
579                 if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) allqueue(REDRAWVIEW3D, 0);
580                 
581         }
582         else {
583                 hits= selectprojektie(buffer, mval[0]-7, mval[1]-7, mval[0]+7, mval[1]+7);
584                 if(hits==0) hits= selectprojektie(buffer, mval[0]-21, mval[1]-21, mval[0]+21, mval[1]+21);
585
586                 if(hits>0) {
587
588                         base= startbase;
589                         while(base) {
590                                 if(base->lay & G.vd->lay) {
591                                         for(a=0; a<hits; a++) {
592                                                 /* index was converted */
593                                                 if(base->selcol==buffer[ (4 * a) + 3 ]) basact= base;
594                                         }
595                                 }
596                                 if(basact) break;
597                                 
598                                 base= base->next;
599                                 if(base==0) base= FIRSTBASE;
600                                 if(base==startbase) break;
601                         }
602                 }
603         }
604         
605         if(basact) {
606                 if(G.obedit) {
607                         /* only do select */
608                         deselectall_except(basact);
609                         basact->flag |= SELECT;
610                         draw_object_ext(basact);
611                 }
612                 else {
613                         oldbasact= BASACT;
614                         BASACT= basact;
615                         
616                         if((G.qual & LR_SHIFTKEY)==0) {
617                                 deselectall_except(basact);
618                                 basact->flag |= SELECT;
619                         }
620                         else {
621                                 if(basact->flag & SELECT) {
622                                         if(basact==oldbasact)
623                                                 basact->flag &= ~SELECT;
624                                 }
625                                 else basact->flag |= SELECT;
626                         }
627
628                         // copy
629                         basact->object->flag= basact->flag;
630                         
631                         if(oldbasact != basact) {
632                                 set_active_base(basact);
633                         }
634
635                         // for visual speed, only in wire mode
636                         if(G.vd->drawtype==OB_WIRE) {
637                                 if(oldbasact && oldbasact != basact && (oldbasact->lay & G.vd->lay)) 
638                                         draw_object_ext(oldbasact);
639                                 draw_object_ext(basact);
640                         }
641                         
642                         if(basact->object->type!=OB_MESH) {
643                                 if(G.f & G_WEIGHTPAINT) {
644                                         set_wpaint();   /* toggle */
645                                 }
646                                 if(G.f & G_VERTEXPAINT) {
647                                         set_vpaint();   /* toggle */
648                                 }
649                                 if(G.f & G_FACESELECT) {
650                                         set_faceselect();       /* toggle */
651                                 }
652                         }
653                         /* also because multiple 3d windows can be open */
654                         allqueue(REDRAWVIEW3D, 0);
655
656                         allqueue(REDRAWBUTSLOGIC, 0);
657                         allqueue(REDRAWDATASELECT, 0);
658                         allqueue(REDRAWBUTSOBJECT, 0);
659                         allqueue(REDRAWACTION, 0);
660                         allqueue(REDRAWNLA, 0);
661                         allqueue(REDRAWHEADERS, 0);     /* To force display update for the posebutton */
662                         
663                 }
664                 
665         }
666
667         countall();
668
669         rightmouse_transform(); // does undo push!
670 }
671
672 /* ------------------------------------------------------------------------- */
673 /**
674  * Does the 'borderselect' command. (Select verts based on selecting with a 
675  * border: key 'b'). All selecting seems to be done in the get_border part.
676  */
677 void borderselect(void)
678 {
679         EditMesh *em = G.editMesh;
680         rcti rect;
681         Base *base;
682         Nurb *nu;
683         BezTriple *bezt;
684         BPoint *bp;
685         MetaElem *ml;
686         struct EditVert *eve;
687         unsigned int buffer[MAXPICKBUF];
688         int a, index;
689         short hits, val, tel;
690
691         if(G.obedit==0 && (G.f & G_FACESELECT)) {
692                 face_borderselect();
693                 return;
694         }
695
696         val= get_border(&rect, 3);
697         if(val) {
698                 if (G.obpose){
699                         if(G.obpose->type==OB_ARMATURE) {
700                                 Bone    *bone;
701                                 hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
702                                 base= FIRSTBASE;
703                                 for (a=0; a<hits; a++){
704                                         index = buffer[(4*a)+3];
705                                         if (val==LEFTMOUSE){
706                                                 if (index != -1){
707                                                         bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT));
708                                                         bone->flag |= BONE_SELECTED;
709                                                         select_actionchannel_by_name(G.obpose->action, bone->name, 1);
710                                                 }
711                                         }
712                                         else{   
713                                                 if (index != -1){
714                                                         bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT));
715                                                         bone->flag &= ~BONE_SELECTED;
716                                                         select_actionchannel_by_name(G.obpose->action, bone->name, 0);
717                                                 }
718                                         }
719                                 }
720                                 
721                                 allqueue(REDRAWBUTSEDIT, 0);
722                                 allqueue(REDRAWBUTSOBJECT, 0);
723                                 allqueue(REDRAWACTION, 0);
724                                 allqueue(REDRAWNLA, 0);
725                                 allqueue(REDRAWVIEW3D, 0);
726                         }
727                 }
728                 else
729                 if(G.obedit) {
730                         /* used to be a bigger test, also included sector and life */
731                         if(G.obedit->type==OB_MESH) {
732                                 
733                                 calc_meshverts_ext();   /* drawobject.c */
734                                 eve= em->verts.first;
735                                 while(eve) {            
736                                         if(eve->h==0 && eve->xs>rect.xmin && eve->xs<rect.xmax) {
737                                                 if(eve->ys>rect.ymin && eve->ys<rect.ymax) {
738                                                         if(val==LEFTMOUSE) eve->f|= 1;
739                                                         else eve->f&= 254;
740                                                 }
741                                         }
742                                         eve= eve->next;
743                                 }
744                                 allqueue(REDRAWVIEW3D, 0);
745                                 
746                         }
747                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
748                                 
749                                 calc_nurbverts_ext();   /* drawobject.c */
750                                 nu= editNurb.first;
751                                 while(nu) {
752                                         if((nu->type & 7)==CU_BEZIER) {
753                                                 bezt= nu->bezt;
754                                                 a= nu->pntsu;
755                                                 while(a--) {
756                                                         if(bezt->hide==0) {
757                                                                 if(bezt->s[0][0]>rect.xmin && bezt->s[0][0]<rect.xmax) {
758                                                                         if(bezt->s[0][1]>rect.ymin && bezt->s[0][1]<rect.ymax) {
759                                                                                 if(val==LEFTMOUSE) bezt->f1|= 1;
760                                                                                 else bezt->f1 &= ~1;
761                                                                         }
762                                                                 }
763                                                                 if(bezt->s[1][0]>rect.xmin && bezt->s[1][0]<rect.xmax) {
764                                                                         if(bezt->s[1][1]>rect.ymin && bezt->s[1][1]<rect.ymax) {
765                                                                                 if(val==LEFTMOUSE) {
766                                                                                         bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1;
767                                                                                 }
768                                                                                 else {
769                                                                                         bezt->f1 &= ~1; bezt->f2 &= ~1; bezt->f3 &= ~1;
770                                                                                 }
771                                                                         }
772                                                                 }
773                                                                 if(bezt->s[2][0]>rect.xmin && bezt->s[2][0]<rect.xmax) {
774                                                                         if(bezt->s[2][1]>rect.ymin && bezt->s[2][1]<rect.ymax) {
775                                                                                 if(val==LEFTMOUSE) bezt->f3|= 1;
776                                                                                 else bezt->f3 &= ~1;
777                                                                         }
778                                                                 }
779                                                         }
780                                                         bezt++;
781                                                 }
782                                         }
783                                         else {
784                                                 bp= nu->bp;
785                                                 a= nu->pntsu*nu->pntsv;
786                                                 while(a--) {
787                                                         if(bp->hide==0) {
788                                                                 if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) {
789                                                                         if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) {
790                                                                                 if(val==LEFTMOUSE) bp->f1|= 1;
791                                                                                 else bp->f1 &= ~1;
792                                                                         }
793                                                                 }
794                                                         }
795                                                         bp++;
796                                                 }
797                                         }
798                                         nu= nu->next;
799                                 }
800                                 allqueue(REDRAWVIEW3D, 0);
801                         }
802                         else if(G.obedit->type==OB_MBALL) {
803                                 hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
804                                 
805                                 ml= editelems.first;
806                                 
807                                 while(ml) {
808                                         for(a=0; a<hits; a++) {
809                                                 if(ml->selcol==buffer[ (4 * a) + 3 ]) {
810                                                         if(val==LEFTMOUSE) ml->flag |= SELECT;
811                                                         else ml->flag &= ~SELECT;
812                                                         break;
813                                                 }
814                                         }
815                                         ml= ml->next;
816                                 }
817                                 allqueue(REDRAWVIEW3D, 0);
818                         }
819                         else if(G.obedit->type==OB_ARMATURE) {
820                                 EditBone *ebone;
821
822                                 hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
823
824                                 base= FIRSTBASE;
825                                 for (a=0; a<hits; a++){
826                                         index = buffer[(4*a)+3];
827                                         if (val==LEFTMOUSE){
828                                                 if (index!=-1){
829                                                         ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT));
830                                                         if (index & BONESEL_TIP)
831                                                                 ebone->flag |= BONE_TIPSEL;
832                                                         if (index & BONESEL_ROOT)
833                                                                 ebone->flag |= BONE_ROOTSEL;
834                                                 }
835                                         }
836                                         else{
837                                                 if (index!=-1){
838                                                         ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT));
839                                                         if (index & BONESEL_TIP)
840                                                                 ebone->flag &= ~BONE_TIPSEL;
841                                                         if (index & BONESEL_ROOT)
842                                                                 ebone->flag &= ~BONE_ROOTSEL;
843                                                 }
844                                         }
845                                 }
846                                 
847                                 allqueue(REDRAWBUTSEDIT, 0);
848                                 allqueue(REDRAWBUTSOBJECT, 0);
849                                 allqueue(REDRAWACTION, 0);
850                                 allqueue(REDRAWVIEW3D, 0);
851                         }
852                         else if(G.obedit->type==OB_LATTICE) {
853                                 
854                                 calc_lattverts_ext();
855                                 
856                                 bp= editLatt->def;
857         
858                                 a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
859                                 while(a--) {
860                                         if(bp->hide==0) {
861                                                 if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) {
862                                                         if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) {
863                                                                 if(val==LEFTMOUSE) bp->f1|= 1;
864                                                                 else bp->f1 &= ~1;
865                                                         }
866                                                 }
867                                         }
868                                         bp++;
869                                 }
870                                 allqueue(REDRAWVIEW3D, 0);
871                         }
872
873                 }
874                 else {
875                         
876                         hits= selectprojektie(buffer, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
877
878                         base= FIRSTBASE;
879                         while(base) {
880                                 if(base->lay & G.vd->lay) {
881                                         for(a=0; a<hits; a++) {
882                                                 /* converted index */
883                                                 if(base->selcol==buffer[ (4 * a) + 3 ]) {
884                                                         if(val==LEFTMOUSE) base->flag |= SELECT;
885                                                         else base->flag &= ~SELECT;
886                                                         base->object->flag= base->flag;
887
888                                                         draw_object_ext(base);
889                                                         break;
890                                                 }
891                                         }
892                                 }
893                                 
894                                 base= base->next;
895                         }
896                         /* frontbuffer flush */
897                         glFlush();
898                         
899                         allqueue(REDRAWDATASELECT, 0);
900                         
901                         /* because backbuf drawing */
902                         tel= 1;
903                         base= FIRSTBASE;
904                         while(base) {
905                                 /* each base because of multiple windows */
906                                 base->selcol = ((tel & 0xF00)<<12) 
907                                         + ((tel & 0xF0)<<8) 
908                                         + ((tel & 0xF)<<4);
909                                 tel++;
910                                 base= base->next;
911                         }
912                         /* new */
913                         allqueue(REDRAWBUTSLOGIC, 0);
914                         allqueue(REDRAWNLA, 0);
915                 }
916                 countall();
917                 
918                 allqueue(REDRAWINFO, 0);
919         }
920         /* remove obedit check later */
921         if(G.obedit==NULL) BIF_undo_push("Border select");
922         
923 } /* end of borderselect() */
924
925 /* ------------------------------------------------------------------------- */
926
927 /** The following functions are quick & dirty callback functions called
928   * on the Circle select function (press B twice in Editmode)
929   * They were torn out of the circle_select to make the latter more reusable
930   * The callback version of circle_select (called circle_selectCB) was moved
931   * to edit.c because of it's (wanted) generality.
932
933         XXX These callback functions are still dirty, because they call globals... 
934   */
935
936 void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad)
937 {
938         EditMesh *em = G.editMesh;
939         EditVert *eve;
940         float x, y, r;
941
942         calc_meshverts_ext();   /* drawobject.c */
943         eve= em->verts.first;
944         while(eve) {
945                 if(eve->h==0) {
946                         x= eve->xs-mval[0];
947                         y= eve->ys-mval[1];
948                         r= sqrt(x*x+y*y);
949                         if(r<=rad) {
950                                 if(selecting==LEFTMOUSE) eve->f|= 1;
951                                 else eve->f&= 254;
952                         }
953                 }
954                 eve= eve->next;
955         }
956
957         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
958         force_draw();
959
960 }
961
962
963 void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad)
964 {
965         Nurb *nu;
966         BPoint *bp;
967         BezTriple *bezt;
968         float x, y, r;
969         int a;
970
971         calc_nurbverts_ext();   /* drawobject.c */
972         nu= editNurb.first;
973         while(nu) {
974                 if((nu->type & 7)==CU_BEZIER) {
975                         bezt= nu->bezt;
976                         a= nu->pntsu;
977                         while(a--) {
978                                 if(bezt->hide==0) {
979                                         x= bezt->s[0][0]-mval[0];
980                                         y= bezt->s[0][1]-mval[1];
981                                         r= sqrt(x*x+y*y);
982                                         if(r<=rad) {
983                                                 if(selecting==LEFTMOUSE) bezt->f1|= 1;
984                                                 else bezt->f1 &= ~1;
985                                         }
986                                         x= bezt->s[1][0]-mval[0];
987                                         y= bezt->s[1][1]-mval[1];
988                                         r= sqrt(x*x+y*y);
989                                         if(r<=rad) {
990                                                 if(selecting==LEFTMOUSE) bezt->f2|= 1;
991                                                 else bezt->f2 &= ~1;
992                                         }
993                                         x= bezt->s[2][0]-mval[0];
994                                         y= bezt->s[2][1]-mval[1];
995                                         r= sqrt(x*x+y*y);
996                                         if(r<=rad) {
997                                                 if(selecting==LEFTMOUSE) bezt->f3|= 1;
998                                                 else bezt->f3 &= ~1;
999                                         }
1000                                         
1001                                 }
1002                                 bezt++;
1003                         }
1004                 }
1005                 else {
1006                         bp= nu->bp;
1007                         a= nu->pntsu*nu->pntsv;
1008                         while(a--) {
1009                                 if(bp->hide==0) {
1010                                         x= bp->s[0]-mval[0];
1011                                         y= bp->s[1]-mval[1];
1012                                         r= sqrt(x*x+y*y);
1013                                         if(r<=rad) {
1014                                                 if(selecting==LEFTMOUSE) bp->f1|= 1;
1015                                                 else bp->f1 &= ~1;
1016                                         }
1017                                 }
1018                                 bp++;
1019                         }
1020                 }
1021                 nu= nu->next;
1022         }
1023         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1024         force_draw();
1025
1026
1027 }
1028
1029 void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad)
1030 {
1031         BPoint *bp;
1032         float x, y, r;
1033         int a;
1034
1035         calc_lattverts_ext();
1036         
1037         bp= editLatt->def;
1038
1039         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1040         while(a--) {
1041                 if(bp->hide==0) {
1042                         x= bp->s[0]-mval[0];
1043                         y= bp->s[1]-mval[1];
1044                         r= sqrt(x*x+y*y);
1045                         if(r<=rad) {
1046                                 if(selecting==LEFTMOUSE) bp->f1|= 1;
1047                                 else bp->f1 &= ~1;
1048                         }
1049                 }
1050                 bp++;
1051         }
1052         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1053         force_draw();
1054 }
1055
1056 /** Callbacks for selection in Editmode */
1057
1058 void obedit_selectionCB(short selecting, Object *editobj, short *mval, float rad) 
1059 {
1060         switch(editobj->type) {         
1061         case OB_MESH:
1062                 mesh_selectionCB(selecting, editobj, mval, rad);
1063                 break;
1064         case OB_CURVE:
1065         case OB_SURF:
1066                 nurbscurve_selectionCB(selecting, editobj, mval, rad);
1067                 break;
1068         case OB_LATTICE:
1069                 lattice_selectionCB(selecting, editobj, mval, rad);
1070                 break;
1071         }
1072 }
1073
1074 /** The circle select function - should be replaced by the callback 
1075   * version circle_selectCB(). Why ? Because it's not nice as it is!
1076   * 
1077   */
1078
1079 void circle_select(void)
1080 {
1081         EditMesh *em = G.editMesh;
1082         Nurb *nu;
1083         BPoint *bp;
1084         BezTriple *bezt;
1085         EditVert *eve;
1086         static float rad= 40.0;
1087         float rado, x, y, trad;
1088         int a, firsttime=1;
1089         unsigned short event;
1090         short mvalo[2], mval[2], val;
1091         short selecting=0;
1092         
1093         if(G.obedit==0) return;
1094         
1095         getmouseco_areawin(mvalo);
1096         draw_sel_circle(mvalo, 0, rad, 0.0, selecting);
1097         
1098         rado= rad;
1099         
1100         while(TRUE) {
1101                 
1102                 /* when a renderwindow is open and mouse enters it (activates sometimes) */
1103
1104                 mywinset(curarea->win);
1105
1106                 getmouseco_areawin(mval);
1107                 
1108                 if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || rado!=rad || firsttime) {
1109                         firsttime= 0;
1110                         
1111                         draw_sel_circle(mval, mvalo, rad, rado, selecting);
1112                 
1113                         mvalo[0]= mval[0];
1114                         mvalo[1]= mval[1];
1115                         rado= rad;
1116
1117                         if(selecting) {
1118                                 
1119                                 if(G.obedit->type==OB_MESH) {
1120                                         
1121                                         calc_meshverts_ext();   /* drawobject.c */
1122                                         eve= em->verts.first;
1123                                         while(eve) {
1124                                                 if(eve->h==0) {
1125                                                         x= eve->xs-mval[0];
1126                                                         y= eve->ys-mval[1];
1127                                                         trad= sqrt(x*x+y*y);
1128                                                         if(trad<=rad) {
1129                                                                 if(selecting==LEFTMOUSE) eve->f|= 1;
1130                                                                 else eve->f&= 254;
1131                                                         }
1132                                                 }
1133                                                 eve= eve->next;
1134                                         }
1135                                         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1136                                         force_draw();
1137                                 }
1138                                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
1139                                         
1140                                         calc_nurbverts_ext();   /* drawobject.c */
1141                                         nu= editNurb.first;
1142                                         while(nu) {
1143                                                 if((nu->type & 7)==CU_BEZIER) {
1144                                                         bezt= nu->bezt;
1145                                                         a= nu->pntsu;
1146                                                         while(a--) {
1147                                                                 if(bezt->hide==0) {
1148                                                                         x= bezt->s[0][0]-mval[0];
1149                                                                         y= bezt->s[0][1]-mval[1];
1150                                                                         trad= sqrt(x*x+y*y);
1151                                                                         if(trad<=rad) {
1152                                                                                 if(selecting==LEFTMOUSE) bezt->f1|= 1;
1153                                                                                 else bezt->f1 &= ~1;
1154                                                                         }
1155                                                                         x= bezt->s[1][0]-mval[0];
1156                                                                         y= bezt->s[1][1]-mval[1];
1157                                                                         trad= sqrt(x*x+y*y);
1158                                                                         if(trad<=rad) {
1159                                                                                 if(selecting==LEFTMOUSE) bezt->f2|= 1;
1160                                                                                 else bezt->f2 &= ~1;
1161                                                                         }
1162                                                                         x= bezt->s[2][0]-mval[0];
1163                                                                         y= bezt->s[2][1]-mval[1];
1164                                                                         trad= sqrt(x*x+y*y);
1165                                                                         if(trad<=rad) {
1166                                                                                 if(selecting==LEFTMOUSE) bezt->f3|= 1;
1167                                                                                 else bezt->f3 &= ~1;
1168                                                                         }
1169                                                                         
1170                                                                 }
1171                                                                 bezt++;
1172                                                         }
1173                                                 }
1174                                                 else {
1175                                                         bp= nu->bp;
1176                                                         a= nu->pntsu*nu->pntsv;
1177                                                         while(a--) {
1178                                                                 if(bp->hide==0) {
1179                                                                         x= bp->s[0]-mval[0];
1180                                                                         y= bp->s[1]-mval[1];
1181                                                                         trad= sqrt(x*x+y*y);
1182                                                                         if(trad<=rad) {
1183                                                                                 if(selecting==LEFTMOUSE) bp->f1|= 1;
1184                                                                                 else bp->f1 &= ~1;
1185                                                                         }
1186                                                                 }
1187                                                                 bp++;
1188                                                         }
1189                                                 }
1190                                                 nu= nu->next;
1191                                         }
1192                                         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1193                                         force_draw();
1194                                 }
1195                                 else if(G.obedit->type==OB_LATTICE) {
1196                                         calc_lattverts_ext();
1197                                         
1198                                         bp= editLatt->def;
1199                 
1200                                         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1201                                         while(a--) {
1202                                                 if(bp->hide==0) {
1203                                                         x= bp->s[0]-mval[0];
1204                                                         y= bp->s[1]-mval[1];
1205                                                         trad= sqrt(x*x+y*y);
1206                                                         if(trad<=rad) {
1207                                                                 if(selecting==LEFTMOUSE) bp->f1|= 1;
1208                                                                 else bp->f1 &= ~1;
1209                                                         }
1210                                                 }
1211                                                 bp++;
1212                                         }
1213                                         draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1214                                         force_draw();
1215                                 }
1216                         }
1217                 }
1218
1219                 event= extern_qread(&val);
1220                 if (event) {
1221                         int afbreek= 0;
1222                         
1223                         switch(event) {
1224                         case LEFTMOUSE:
1225                         case MIDDLEMOUSE:
1226                                 if(val) selecting= event;
1227                                 else selecting= 0;
1228                                 firsttime= 1;
1229                                 
1230                                 break;
1231                         case PADPLUSKEY:
1232                                 if(val) if(rad<200.0) rad*= 1.2;
1233                                 break;
1234                         case PADMINUS:
1235                                 if(val) if(rad>5.0) rad/= 1.2;
1236                                 break;
1237                         
1238                         case ESCKEY: case SPACEKEY: case RIGHTMOUSE:
1239                         case GKEY: case SKEY: case RKEY: case XKEY: case EKEY: case TABKEY:
1240                                 afbreek= 1;
1241                                 break;
1242
1243                         }
1244                         
1245                         if(afbreek) break;
1246                 }
1247         }
1248         
1249         /* clear circle */
1250         draw_sel_circle(0, mvalo, 0, rad, 1);
1251
1252         countall();
1253         allqueue(REDRAWINFO, 0);
1254 }
1255
1256 void set_render_border(void)
1257 {
1258         rcti rect;
1259         short val;
1260
1261         if(G.vd->persp!=2) return;
1262         
1263         val= get_border(&rect, 2);
1264         if(val) {
1265                 rcti vb;
1266
1267                 calc_viewborder(G.vd, &vb);
1268
1269                 G.scene->r.border.xmin= (float) (rect.xmin-vb.xmin)/(vb.xmax-vb.xmin);
1270                 G.scene->r.border.ymin= (float) (rect.ymin-vb.ymin)/(vb.ymax-vb.ymin);
1271                 G.scene->r.border.xmax= (float) (rect.xmax-vb.xmin)/(vb.xmax-vb.xmin);
1272                 G.scene->r.border.ymax= (float) (rect.ymax-vb.ymin)/(vb.ymax-vb.ymin);
1273                 
1274                 CLAMP(G.scene->r.border.xmin, 0.0, 1.0);
1275                 CLAMP(G.scene->r.border.ymin, 0.0, 1.0);
1276                 CLAMP(G.scene->r.border.xmax, 0.0, 1.0);
1277                 CLAMP(G.scene->r.border.ymax, 0.0, 1.0);
1278                 
1279                 allqueue(REDRAWVIEWCAM, 1);
1280                 // if it was not set, we do this
1281                 G.scene->r.mode |= R_BORDER;
1282                 allqueue(REDRAWBUTSSCENE, 1);
1283         }
1284 }
1285
1286
1287
1288 void fly(void)
1289 {
1290         float speed=0.0, speedo=1.0, zspeed=0.0, dvec[3], *quat, mat[3][3];
1291         float oldvec[3], oldrot[3];
1292         int loop=1;
1293         unsigned short toets;
1294         short val, cent[2];
1295         short mval[2];
1296         
1297         if(curarea->spacetype!=SPACE_VIEW3D) return;
1298         if(G.vd->camera == 0) return;
1299         if(G.vd->persp<2) return;
1300         
1301         VECCOPY(oldvec, G.vd->camera->loc);
1302         VECCOPY(oldrot, G.vd->camera->rot);
1303         
1304         cent[0]= curarea->winrct.xmin+(curarea->winx)/2;
1305         cent[1]= curarea->winrct.ymin+(curarea->winy)/2;
1306         
1307         warp_pointer(cent[0], cent[1]);
1308         
1309         cent[0]=  (curarea->winx)/2;
1310         cent[1]=  (curarea->winy)/2;
1311         
1312         headerprint("Fly");
1313         
1314         while(loop) {
1315                 getmouseco_areawin(mval);
1316
1317                 while(qtest()) {
1318                         
1319                         toets= extern_qread(&val);
1320                         
1321                         if(val) {
1322                                 if(toets==ESCKEY) {
1323                                         VECCOPY(G.vd->camera->loc, oldvec);
1324                                         VECCOPY(G.vd->camera->rot, oldrot);
1325                                         loop= 0;
1326                                         break;
1327                                 }
1328                                 else if(toets==SPACEKEY) {
1329                                         loop= 0;
1330                                         BIF_undo_push("Fly camera");
1331                                         break;
1332                                 }
1333                                 else if(toets==LEFTMOUSE) {
1334                                         speed+= G.vd->grid/75.0;
1335                                         if(get_mbut()&M_MOUSE) speed= 0.0;
1336                                 }
1337                                 else if(toets==MIDDLEMOUSE) {
1338                                         speed-= G.vd->grid/75.0;
1339                                         if(get_mbut()&L_MOUSE) speed= 0.0;
1340                                 }
1341                         }
1342                 }
1343                 if(loop==0) break;
1344                 
1345                 /* define dvec */
1346                 val= mval[0]-cent[0];
1347                 if(val>20) val-= 20; else if(val< -20) val+= 20; else val= 0;
1348                 dvec[0]= 0.000001*val*val;
1349                 if(val>0) dvec[0]= -dvec[0];
1350                 
1351                 val= mval[1]-cent[1];
1352                 if(val>20) val-= 20; else if(val< -20) val+= 20; else val= 0;
1353                 dvec[1]= 0.000001*val*val;
1354                 if(val>0) dvec[1]= -dvec[1];
1355                 
1356                 dvec[2]= 1.0;
1357                 
1358                 zspeed= 0.0;
1359                 if(get_qual()&LR_CTRLKEY) zspeed= -G.vd->grid/25.0;
1360                 if(get_qual()&LR_ALTKEY) zspeed= G.vd->grid/25.0;
1361                 
1362                 if(speedo!=0.0 || zspeed!=0.0 || dvec[0]!=0.0 || dvec[1]!=0.0) {
1363                 
1364                         Normalise(dvec);
1365                         
1366                         Mat3CpyMat4(mat, G.vd->viewinv);
1367                         Mat3MulVecfl(mat, dvec);
1368                         quat= vectoquat(dvec, 5, 1);    /* track and upflag, not from the base: camera view calculation does not use that */
1369                         
1370                         QuatToEul(quat, G.vd->camera->rot);
1371                         
1372                         compatible_eul(G.vd->camera->rot, oldrot);
1373                         
1374                         VecMulf(dvec, speed);
1375                         G.vd->camera->loc[0]-= dvec[0];
1376                         G.vd->camera->loc[1]-= dvec[1];
1377                         G.vd->camera->loc[2]-= (dvec[2]-zspeed);
1378                         
1379                         scrarea_do_windraw(curarea);
1380                         screen_swapbuffers();
1381                 }
1382                 speedo= speed;
1383         }
1384         
1385         allqueue(REDRAWVIEW3D, 0);
1386         scrarea_queue_headredraw(curarea);
1387         
1388 }
1389