merge trunk 17122:17213
[blender.git] / source / blender / src / space.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  *
30  * - here initialize and free and handling SPACE data
31  */
32
33 #include <string.h>
34 #include <stdio.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include "MEM_guardedalloc.h"
41 #include "MEM_CacheLimiterC-Api.h"
42
43 #ifdef INTERNATIONAL
44 #include "BIF_language.h"
45 #endif
46
47 #include "IMB_imbuf_types.h"
48 #include "IMB_imbuf.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_gsqueue.h"
53 #include "BLI_linklist.h"
54
55 #include "DNA_action_types.h"
56 #include "DNA_armature_types.h"
57 #include "DNA_curve_types.h"
58 #include "DNA_group_types.h" /* used for select_same_group */
59 #include "DNA_gpencil_types.h"
60 #include "DNA_image_types.h"
61 #include "DNA_ipo_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_modifier_types.h" /* used for select grouped hooks */
65 #include "DNA_object_types.h"
66 #include "DNA_particle_types.h"
67 #include "DNA_property_types.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_screen_types.h"
70 #include "DNA_sequence_types.h"
71 #include "DNA_sound_types.h"
72 #include "DNA_space_types.h"
73 #include "DNA_userdef_types.h"
74 #include "DNA_view2d_types.h"
75 #include "DNA_view3d_types.h"
76
77 #include "BKE_blender.h"
78 #include "BKE_colortools.h"
79 #include "BKE_curve.h"
80 #include "BKE_depsgraph.h"
81 #include "BKE_DerivedMesh.h"
82 #include "BKE_displist.h"
83 #include "BKE_global.h"
84 #include "BKE_group.h"
85 #include "BKE_ipo.h"
86 #include "BKE_main.h"
87 #include "BKE_mesh.h"
88 #include "BKE_multires.h"
89 #include "BKE_node.h"
90 #include "BKE_pointcache.h"
91 #include "BKE_property.h"
92 #include "BKE_scene.h"
93 #include "BKE_sculpt.h"
94 #include "BKE_texture.h"
95 #include "BKE_utildefines.h"
96 #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
97 #include "BKE_particle.h"
98 #include "BIF_spacetypes.h"  /* first, nasty dependency with typedef */
99
100 #include "BIF_butspace.h"
101 #include "BIF_drawimage.h"
102 #include "BIF_drawseq.h"
103 #include "BIF_drawtext.h"
104 #include "BIF_drawscript.h"
105 #include "BIF_editarmature.h"
106 #include "BIF_editparticle.h"
107 #include "BIF_editconstraint.h"
108 #include "BIF_editdeform.h"
109 #include "BIF_editfont.h"
110 #include "BIF_editgroup.h"
111 #include "BIF_editkey.h"
112 #include "BIF_editlattice.h"
113 #include "BIF_editmesh.h"
114 #include "BIF_editmode_undo.h"
115 #include "BIF_editnla.h"
116 #include "BIF_editoops.h"
117 #include "BIF_editseq.h"
118 #include "BIF_editsima.h"
119 #include "BIF_editsound.h"
120 #include "BIF_editview.h"
121 #include "BIF_filelist.h"
122 #include "BIF_gl.h"
123 #include "BIF_imasel.h"
124 #include "BIF_interface.h"
125 #include "BIF_interface_icons.h"
126 #include "BIF_keyframing.h"
127 #include "BIF_meshtools.h"
128 #include "BIF_mywindow.h"
129 #include "BIF_oops.h"
130 #include "BIF_poselib.h"
131 #include "BIF_poseobject.h"
132 #include "BIF_outliner.h"
133 #include "BIF_radialcontrol.h"
134 #include "BIF_resources.h"
135 #include "BIF_retopo.h"
136 #include "BIF_screen.h"
137 #include "BIF_space.h"
138 #include "BIF_toets.h"
139 #include "BIF_toolbox.h"
140 #include "BIF_usiblender.h"
141 #include "BIF_previewrender.h"
142 #include "BIF_sketch.h"
143
144 #include "BSE_edit.h"
145 #include "BSE_view.h"
146 #include "BSE_editipo.h"
147 #include "BSE_drawipo.h"
148 #include "BSE_drawview.h"
149 #include "BSE_drawnla.h"
150 #include "BSE_filesel.h"
151 #include "BSE_headerbuttons.h"
152 #include "BSE_editnla_types.h"
153 #include "BSE_time.h"
154 #include "BSE_trans_types.h"
155
156 #include "BDR_vpaint.h"
157 #include "BDR_editmball.h"
158 #include "BDR_editobject.h"
159 #include "BDR_editcurve.h"
160 #include "BDR_editface.h"
161 #include "BDR_drawmesh.h"
162 #include "BDR_drawobject.h"
163 #include "BDR_imagepaint.h"
164 #include "BDR_sculptmode.h"
165 #include "BDR_unwrapper.h"
166 #include "BDR_gpencil.h"
167 #include "BDR_sketch.h"
168
169 #include "BLO_readfile.h" /* for BLO_blendhandle_close */
170
171 #include "PIL_time.h"
172
173 #ifndef DISABLE_PYTHON
174 #include "BPY_extern.h"
175 #endif
176
177 #include "butspace.h"
178 #include "mydevice.h"
179 #include "blendef.h"
180 #include "datatoc.h"
181 #include "multires.h"
182
183 #include "BIF_transform.h"
184
185 #include "BKE_depsgraph.h"
186
187 #include "BSE_trans_types.h"
188
189 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
190
191 #include "GPU_extensions.h"
192 #include "GPU_draw.h"
193
194 #include "BLO_sys_types.h" // for intptr_t support
195
196 /* maybe we need this defined somewhere else */
197 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
198 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);/*rcruiz*/
199
200 /**
201  * When the mipmap setting changes, we want to redraw the view right
202  * away to reflect this setting.
203  */
204 //static void space_mipmap_button_function(int event);
205
206 static void free_soundspace(SpaceSound *ssound);
207
208 /* *************************************** */
209
210 /* don't know yet how the handlers will evolve, for simplicity
211    i choose for an array with eventcodes, this saves in a file!
212    */
213 void add_blockhandler(ScrArea *sa, short eventcode, short val)
214 {
215         SpaceLink *sl= sa->spacedata.first;
216         short a;
217         
218         /* find empty spot */
219         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
220                 if( sl->blockhandler[a]==eventcode ) {
221                         sl->blockhandler[a+1]= val;
222                         break;
223                 }
224                 else if( sl->blockhandler[a]==0) {
225                         sl->blockhandler[a]= eventcode;
226                         sl->blockhandler[a+1]= val;
227                         break;
228                 }
229         }
230         if(a==SPACE_MAXHANDLER) {
231                 error("Only %i floating panels allowed", SPACE_MAXHANDLER/2);
232         }
233                 
234 }
235
236 void rem_blockhandler(ScrArea *sa, short eventcode)
237 {
238         SpaceLink *sl= sa->spacedata.first;
239         short a;
240         
241         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
242                 if( sl->blockhandler[a]==eventcode) {
243                         sl->blockhandler[a]= 0;
244                         
245                         /* specific free calls */
246                         if(eventcode==IMAGE_HANDLER_PREVIEW)
247                                 image_preview_event(0);
248                         break;
249                 }
250         }
251 }
252
253 void toggle_blockhandler(ScrArea *sa, short eventcode, short val)
254 {
255         SpaceLink *sl= sa->spacedata.first;
256         short a, addnew=1;
257         
258         /* find if it exists */
259         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
260                 if( sl->blockhandler[a]==eventcode ) {
261                         sl->blockhandler[a]= 0;
262                         
263                         /* specific free calls */
264                         if(eventcode==VIEW3D_HANDLER_PREVIEW)
265                                 BIF_view3d_previewrender_free(sa->spacedata.first);
266                         else if(eventcode==IMAGE_HANDLER_PREVIEW)
267                                 image_preview_event(0);
268                         
269                         addnew= 0;
270                 }
271         }
272         if(addnew) {
273                 add_blockhandler(sa, eventcode, val);
274                 
275                 /* specific add new calls */
276                 if(eventcode==IMAGE_HANDLER_PREVIEW)
277                         image_preview_event(1);
278         }
279 }
280
281
282
283 /* ************* SPACE: VIEW3D  ************* */
284
285 /*  extern void drawview3dspace(ScrArea *sa, void *spacedata); BSE_drawview.h */
286
287
288 void copy_view3d_lock(short val)
289 {
290         bScreen *sc;
291         int bit;
292         
293         /* from G.scene copy to the other views */
294         sc= G.main->screen.first;
295         
296         while(sc) {
297                 if(sc->scene==G.scene) {
298                         ScrArea *sa= sc->areabase.first;
299                         while(sa) {
300                                 SpaceLink *sl= sa->spacedata.first;
301                                 while(sl) {
302                                         if(sl->spacetype==SPACE_OOPS && val==REDRAW) {
303                                                 if(sa->win) scrarea_queue_winredraw(sa);
304                                         }
305                                         else if(sl->spacetype==SPACE_VIEW3D) {
306                                                 View3D *vd= (View3D*) sl;
307                                                 if(vd->scenelock && vd->localview==0) {
308                                                         vd->lay= G.scene->lay;
309                                                         vd->camera= G.scene->camera;
310                                                         
311                                                         if(vd->camera==0 && vd->persp==V3D_CAMOB) vd->persp= V3D_PERSP;
312                                                         
313                                                         if( (vd->lay & vd->layact) == 0) {
314                                                                 bit= 0;
315                                                                 while(bit<32) {
316                                                                         if(vd->lay & (1<<bit)) {
317                                                                                 vd->layact= 1<<bit;
318                                                                                 break;
319                                                                         }
320                                                                         bit++;
321                                                                 }
322                                                         }
323                                                         
324                                                         if(val==REDRAW && vd==sa->spacedata.first) {
325                                                                 if(sa->win) scrarea_queue_redraw(sa);
326                                                         }
327                                                 }
328                                         }
329                                         sl= sl->next;
330                                 }
331                                 sa= sa->next;
332                         }
333                 }
334                 sc= sc->id.next;
335         }
336 }
337
338 void handle_view3d_around()
339 {
340         bScreen *sc;
341         
342         if ((U.uiflag & USER_LOCKAROUND)==0) return;
343         
344         /* copies from G.vd->around to other view3ds */
345         
346         sc= G.main->screen.first;
347         
348         while(sc) {
349                 if(sc->scene==G.scene) {
350                         ScrArea *sa= sc->areabase.first;
351                         while(sa) {
352                                 SpaceLink *sl= sa->spacedata.first;
353                                 while(sl) {
354                                         if(sl->spacetype==SPACE_VIEW3D) {
355                                                 View3D *vd= (View3D*) sl;
356                                                 if (vd != G.vd) {
357                                                         vd->around= G.vd->around;
358                                                         if (G.vd->flag & V3D_ALIGN)
359                                                                 vd->flag |= V3D_ALIGN;
360                                                         else
361                                                                 vd->flag &= ~V3D_ALIGN;
362                                                         scrarea_queue_headredraw(sa);
363                                                 }
364                                         }
365                                         sl= sl->next;
366                                 }
367                                 sa= sa->next;
368                         }
369                 }
370                 sc= sc->id.next;
371         }
372 }
373
374 void handle_view3d_lock()
375 {       
376         if (G.vd != NULL && curarea != NULL ) {
377                 if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) {
378
379                         /* copy to scene */
380                         G.scene->lay= G.vd->lay;
381                         G.scene->camera= G.vd->camera;
382         
383                         copy_view3d_lock(REDRAW);
384                 }
385         }
386 }
387
388 void space_set_commmandline_options(void) {
389         SYS_SystemHandle syshandle;
390         int a;
391                 
392         if ( (syshandle = SYS_GetSystem()) ) {
393                 /* User defined settings */
394                 a= (U.gameflags & USER_DISABLE_SOUND);
395                 /* if user already disabled audio at the command-line, don't re-enable it */
396                 if (a)
397                 {
398                         SYS_WriteCommandLineInt(syshandle, "noaudio", a);
399                 }
400
401                 a= (U.gameflags & USER_DISABLE_MIPMAP);
402                 GPU_set_mipmap(!a);
403                 SYS_WriteCommandLineInt(syshandle, "nomipmap", a);
404
405                 /* File specific settings: */
406                 /* Only test the first one. These two are switched
407                  * simultaneously. */
408                 a= (G.fileflags & G_FILE_SHOW_FRAMERATE);
409                 SYS_WriteCommandLineInt(syshandle, "show_framerate", a);
410                 SYS_WriteCommandLineInt(syshandle, "show_profile", a);
411
412                 /* When in wireframe mode, always draw debug props. */
413                 if (G.vd) {
414                         a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS) 
415                                   || (G.vd->drawtype == OB_WIRE)          
416                                   || (G.vd->drawtype == OB_SOLID)         );
417                         SYS_WriteCommandLineInt(syshandle, "show_properties", a);
418                 }
419                 
420                 a= (G.fileflags & G_FILE_SHOW_PHYSICS);
421                 SYS_WriteCommandLineInt(syshandle, "show_physics", a);
422
423                 a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES);
424                 SYS_WriteCommandLineInt(syshandle, "fixedtime", a);
425
426                 a= (G.fileflags & G_FILE_GAME_TO_IPO);
427                 SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
428
429                 a=(G.fileflags & G_FILE_GAME_MAT);
430                 SYS_WriteCommandLineInt(syshandle, "blender_material", a);
431                 a=(G.fileflags & G_FILE_GAME_MAT_GLSL);
432                 SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", a);
433                 a=(G.fileflags & G_FILE_DISPLAY_LISTS);
434                 SYS_WriteCommandLineInt(syshandle, "displaylists", a);
435
436
437         }
438 }
439
440 #if GAMEBLENDER == 1
441         /**
442          * These two routines imported from the gameengine, 
443          * I suspect a lot of the resetting stuff is cruft
444          * and can be removed, but it should be checked.
445          */
446 static void SaveState(void)
447 {
448         glPushAttrib(GL_ALL_ATTRIB_BITS);
449
450         GPU_state_init();
451
452         if(G.f & G_TEXTUREPAINT)
453                 GPU_paint_set_mipmap(1);
454
455         waitcursor(1);
456 }
457
458 static void RestoreState(void)
459 {
460         if(G.f & G_TEXTUREPAINT)
461                 GPU_paint_set_mipmap(0);
462
463         curarea->win_swap = 0;
464         curarea->head_swap=0;
465         allqueue(REDRAWVIEW3D, 1);
466         allqueue(REDRAWBUTSALL, 0);
467         reset_slowparents();
468         waitcursor(0);
469         G.qual= 0;
470         glPopAttrib();
471 }
472
473 static LinkNode *save_and_reset_all_scene_cfra(void)
474 {
475         LinkNode *storelist= NULL;
476         Scene *sc;
477         
478         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
479                 BLI_linklist_prepend(&storelist, (void*) (intptr_t) sc->r.cfra);
480
481                 /* why is this reset to 1 ?*/
482                 /* sc->r.cfra= 1;*/
483
484                 set_scene_bg(sc);
485         }
486         
487         BLI_linklist_reverse(&storelist);
488         
489         return storelist;
490 }
491
492 static void restore_all_scene_cfra(LinkNode *storelist) {
493         LinkNode *sc_store= storelist;
494         Scene *sc;
495         
496         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
497                 int stored_cfra= (intptr_t) sc_store->link;
498                 
499                 sc->r.cfra= stored_cfra;
500                 set_scene_bg(sc);
501                 
502                 sc_store= sc_store->next;
503         }
504         
505         BLI_linklist_free(storelist, NULL);
506 }
507 #endif
508
509 void start_game(void)
510 {
511 #if GAMEBLENDER == 1
512 #ifndef NO_KETSJI
513         Scene *sc, *startscene = G.scene;
514         LinkNode *scene_cfra_store;
515
516                 /* XXX, silly code -  the game engine can
517                  * access any scene through logic, so we try 
518                  * to make sure each scene has a valid camera, 
519                  * just in case the game engine tries to use it.
520                  * 
521                  * Better would be to make a better routine
522                  * in the game engine for finding the camera.
523                  *  - zr
524                  * Note: yes, this is all very badly hacked! (ton)
525                  */
526         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
527                 if (!sc->camera) {
528                         Base *base;
529         
530                         for (base= sc->base.first; base; base= base->next)
531                                 if (base->object->type==OB_CAMERA)
532                                         break;
533                         
534                         sc->camera= base?base->object:NULL;
535                 }
536         }
537
538         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
539         markdirty_all();
540         screen_swapbuffers();
541
542         /* can start from header */
543         mywinset(curarea->win);
544     
545         scene_cfra_store= save_and_reset_all_scene_cfra();
546         
547
548         /* game engine will do its own sounds. */
549         sound_stop_all_sounds();
550         sound_exit_audio();
551         
552         /* Before jumping into Ketsji, we configure some settings. */
553         space_set_commmandline_options();
554
555         SaveState();
556         StartKetsjiShell(curarea, startscene->id.name+2, G.main,G.sipo, 1);
557         RestoreState();
558
559         /* Restart BPY - unload the game engine modules. */
560
561         /* Commented out: testing before Blender 2.46 if it's ok to keep
562          * these modules around, they give access to relevant info for
563          * exporters to other engines...
564         BPY_end_python();
565         BPY_start_python(0, NULL); 
566         BPY_post_start_python();
567         */
568
569         restore_all_scene_cfra(scene_cfra_store);
570         set_scene_bg(startscene);
571         scene_update_for_newframe(G.scene, G.scene->lay);
572
573         if (G.flags & G_FILE_AUTOPLAY)
574                 exit_usiblender();
575
576                 /* groups could have changed ipo */
577         allqueue(REDRAWNLA, 0);
578         allqueue(REDRAWACTION, 0);
579         allspace(REMAKEIPO, 0);
580         allqueue(REDRAWIPO, 0);
581 #endif
582 #else
583         notice("Game engine is disabled in this release!");
584 #endif
585 }
586
587 void start_RBSimulation(void)
588 {
589 #if GAMEBLENDER == 1
590 #ifndef NO_KETSJI
591         Scene *sc, *startscene = G.scene;
592         LinkNode *scene_cfra_store;
593
594                 /* XXX, silly code -  the game engine can
595                  * access any scene through logic, so we try
596                  * to make sure each scene has a valid camera,
597                  * just in case the game engine tries to use it.
598                  *
599                  * Better would be to make a better routine
600                  * in the game engine for finding the camera.
601                  *  - zr
602                  * Note: yes, this is all very badly hacked! (ton)
603                  */
604         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
605                 if (!sc->camera) {
606                         Base *base;
607
608                         for (base= sc->base.first; base; base= base->next)
609                                 if (base->object->type==OB_CAMERA)
610                                         break;
611
612                         sc->camera= base?base->object:NULL;
613                 }
614         }
615
616         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
617         markdirty_all();
618         screen_swapbuffers();
619
620         /* can start from header */
621         mywinset(curarea->win);
622
623         scene_cfra_store= save_and_reset_all_scene_cfra();
624
625
626         /* game engine will do its own sounds. */
627         sound_stop_all_sounds();
628         sound_exit_audio();
629
630         /* Before jumping into Ketsji, we configure some settings. */
631         space_set_commmandline_options();
632
633         SaveState();
634         StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
635         RestoreState();
636
637         /* Restart BPY - unload the game engine modules. */
638
639         /* Commented out: testing before Blender 2.46 if it's ok to keep
640          * these modules around, they give access to relevant info for
641          * exporters to other engines...
642         BPY_end_python();
643         BPY_start_python(0, NULL); 
644         BPY_post_start_python();
645         */
646
647         restore_all_scene_cfra(scene_cfra_store);
648         set_scene_bg(startscene);
649         scene_update_for_newframe(G.scene, G.scene->lay);
650
651         if (G.flags & G_FILE_AUTOPLAY)
652                 exit_usiblender();
653
654                 /* groups could have changed ipo */
655         allqueue(REDRAWNLA, 0);
656         allqueue(REDRAWACTION, 0);
657         allspace(REMAKEIPO, 0);
658         allqueue(REDRAWIPO, 0);
659 #endif
660 #else
661         notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!");
662 #endif
663 }
664
665 static void changeview3dspace(ScrArea *sa, void *spacedata)
666 {
667         setwinmatrixview3d(sa->winx, sa->winy, NULL);   /* 0= no pick rect */
668 }
669
670         /* Callable from editmode and faceselect mode from the
671          * moment, would be nice (and is easy) to generalize
672          * to any mode.
673          */
674 static void align_view_to_selected(View3D *v3d)
675 {
676         int nr= pupmenu("Align View (Ctrl flips)%t|To Selected (top)%x3|To Selected (front)%x2|To Selected (side)%x1");
677         if (nr!=-1) {
678                 int axis= nr;
679                 
680                 /* opposite axis in case ctrl is pressed */
681                 if(G.qual==LR_CTRLKEY) axis= -axis;
682                 
683                 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
684                         editmesh_align_view_to_selected(v3d, axis);
685                         addqueue(v3d->area->win, REDRAW, 1);
686                 } else if (FACESEL_PAINT_TEST) {
687                         Object *obact= OBACT;
688                         if (obact && obact->type==OB_MESH) {
689                                 Mesh *me= obact->data;
690                                 faceselect_align_view_to_selected(v3d, me, axis);
691                                 addqueue(v3d->area->win, REDRAW, 1);
692                         }
693                 }
694         }
695 }
696
697
698 static short select_children(Object *ob, int recursive)
699 {
700         short changed = 0;
701         Base *base;
702         
703         for (base= FIRSTBASE; base; base= base->next) {
704                 if (ob == base->object->parent) {
705                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT)) {
706                                 base->flag |= SELECT;
707                                 base->object->flag |= SELECT;
708                                 changed = 1;
709                         }
710                         
711                         if (recursive)
712                                 changed |= select_children(base->object, 1);
713                 }
714         }
715         return changed;
716 }
717
718 static short select_parent(void)        /* Makes parent active and de-selected OBACT */
719 {
720         short changed = 0;
721         Base *base, *startbase, *basact=NULL, *oldbasact;
722         
723         if (!(OBACT->parent)) return 0; /* we know OBACT is valid */
724         BASACT->flag &= (~SELECT);
725         BASACT->object->flag &= (~SELECT);
726         startbase=  FIRSTBASE;
727         if(BASACT && BASACT->next) startbase= BASACT->next;
728         base = startbase;
729         while(base) {
730                 if(base->object==BASACT->object->parent) { basact=base; break; }
731                 base=base->next;
732                 if(base==NULL) base= FIRSTBASE;
733                 if(base==startbase) break;
734         }
735         /* can be NULL if parent in other scene */
736         if(basact && BASE_SELECTABLE(basact)) {
737                 oldbasact = BASACT;
738                 BASACT = basact;
739                 basact->flag |= SELECT;         
740                 
741                 basact->object->flag= basact->flag;
742                 
743                 set_active_base(basact);
744                 changed = 1;
745         }
746         return changed;
747 }
748
749
750 #define GROUP_MENU_MAX  24
751 static short select_same_group(Object *ob)      /* Select objects in the same group as the active */
752 {
753         short changed = 0;
754         Base *base;
755         Group *group, *ob_groups[GROUP_MENU_MAX];
756         char str[10 + (24*GROUP_MENU_MAX)];
757         char *p = str;
758         int group_count=0, menu, i;
759         
760         for (   group=G.main->group.first;
761                         group && group_count < GROUP_MENU_MAX;
762                         group=group->id.next
763                 ) {
764                 if (object_in_group (ob, group)) {
765                         ob_groups[group_count] = group;
766                         group_count++;
767                 }
768         }
769         
770         if (!group_count)
771                 return 0;
772         
773         else if (group_count == 1) {
774                 group = ob_groups[0];
775                 for (base= FIRSTBASE; base; base= base->next) {
776                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && object_in_group(base->object, group)) {
777                                 base->flag |= SELECT;
778                                 base->object->flag |= SELECT;
779                                 changed = 1;
780                         }
781                 }
782                 return changed;
783         }
784         
785         /* build the menu. */
786         p += sprintf(str, "Groups%%t"); 
787         for (i=0; i<group_count; i++) {
788                 group = ob_groups[i];
789                 p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
790         }
791         
792         menu = pupmenu (str);
793         if (menu == -1)
794                 return 0;
795         
796         group = ob_groups[menu];
797         for (base= FIRSTBASE; base; base= base->next) {
798                 if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
799                         base->flag |= SELECT;
800                         base->object->flag |= SELECT;
801                         changed = 1;
802                 }
803         }
804         return changed;
805 }
806
807 static short select_object_hooks(Object *ob)
808 {
809         short changed = 0;
810         Base *base;
811         ModifierData *md;
812         HookModifierData *hmd;
813         
814         for (md = ob->modifiers.first; md; md=md->next) {
815                 if (md->type==eModifierType_Hook) {
816                         hmd= (HookModifierData*) md;
817                         if (hmd->object && !(hmd->object->flag & SELECT)) {
818                                 base= object_in_scene(hmd->object, G.scene);
819                                 if (base && BASE_SELECTABLE(base)) {
820                                         base->flag |= SELECT;
821                                         base->object->flag |= SELECT;
822                                         changed = 1;
823                                 }
824                         }
825                 }
826         }
827         return changed;
828 }
829
830 /* Select objects woth the same parent as the active (siblings),
831  * parent can be NULL also */
832 static short select_same_parent(Object *ob)     
833 {
834         short changed = 0;
835         Base *base;
836         
837         for (base= FIRSTBASE; base; base= base->next) {
838                 if (BASE_SELECTABLE(base) && (base->object->parent==ob->parent)  && !(base->flag & SELECT)) {
839                         base->flag |= SELECT;
840                         base->object->flag |= SELECT;
841                         changed = 1;
842                 }
843         }
844         return changed;
845 }
846
847 static short select_same_type(Object *ob)
848 {
849         short changed = 0;
850         Base *base;
851         
852         for (base= FIRSTBASE; base; base= base->next) {
853                 if (BASE_SELECTABLE(base) && (base->object->type == ob->type) && !(base->flag & SELECT)) {
854                         base->flag |= SELECT;
855                         base->object->flag |= SELECT;
856                         changed = 1;
857                 }
858         }
859         return changed;
860 }
861
862 static short select_same_layer(Object *ob)
863 {
864         char changed = 0;
865         Base *base = FIRSTBASE;
866         
867         while(base) {
868                 if (BASE_SELECTABLE(base) && (base->lay & ob->lay) && !(base->flag & SELECT)) {
869                         base->flag |= SELECT;
870                         base->object->flag |= SELECT;
871                         changed = 1;
872                 }
873                 base= base->next;
874         }
875         return changed;
876 }
877
878 static short select_same_index_object(Object *ob)
879 {
880         char changed = 0;
881         Base *base = FIRSTBASE;
882         
883         while(base) {
884                 if (BASE_SELECTABLE(base) && (base->object->index == ob->index) && !(base->flag & SELECT)) {
885                         base->flag |= SELECT;
886                         base->object->flag |= SELECT;
887                         changed = 1;
888                 }
889                 base= base->next;
890         }
891         return changed;
892 }
893
894 static short select_same_color(Object *ob)
895 {
896         char changed = 0;
897         Base *base = FIRSTBASE;
898         
899         while(base) {
900                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) {
901                         base->flag |= SELECT;
902                         base->object->flag |= SELECT;
903                         changed = 1;
904                 }
905                 base= base->next;
906         }
907         return changed;
908 }
909
910 static short objects_share_gameprop(Object *a, Object *b)
911 {
912         bProperty *prop;
913         /*make a copy of all its properties*/
914         
915         for( prop= a->prop.first; prop; prop = prop->next ) {
916                 if ( get_ob_property(b, prop->name) )
917                         return 1;
918         }
919         return 0;
920 }
921
922 static short select_same_gameprops(Object *ob)
923 {
924         char changed = 0;
925         Base *base = FIRSTBASE;
926         
927         while(base) {
928                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
929                         base->flag |= SELECT;
930                         base->object->flag |= SELECT;
931                         changed = 1;
932                 }
933                 base= base->next;
934         }
935         return changed;
936 }
937
938 void select_object_grouped(short nr)
939 {
940         Object *ob = OBACT;
941         short changed = 0;
942         
943         if (ob==NULL) return;
944         
945         if(nr==1)               changed = select_children(ob, 1);
946         else if(nr==2)  changed = select_children(ob, 0);
947         else if(nr==3)  changed = select_parent();
948         else if(nr==4)  changed = select_same_parent(ob);       
949         else if(nr==5)  changed = select_same_type(ob);
950         else if(nr==6)  changed = select_same_layer(ob);        
951         else if(nr==7)  changed = select_same_group(ob);
952         else if(nr==8)  changed = select_object_hooks(ob);
953         else if(nr==9)  changed = select_same_index_object(ob);
954         else if(nr==10) changed = select_same_color(ob);
955         else if(nr==11) changed = select_same_gameprops(ob);
956         
957         if (changed) {
958                 countall();
959                 allqueue(REDRAWVIEW3D, 0);
960                 allqueue(REDRAWBUTSOBJECT, 0);
961                 allspace(REMAKEIPO, 0);
962                 allqueue(REDRAWIPO, 0);
963                 BIF_undo_push("Select Grouped");
964         }
965 }
966
967 static void select_object_grouped_menu(void)
968 {
969         char *str;
970         short nr;
971
972         /* make menu string */
973         
974         str= MEM_mallocN(512, "groupmenu");
975         strcpy(str, "Select Grouped%t|Children%x1|"
976                     "Immediate Children%x2|Parent%x3|"
977                     "Siblings (Shared Parent)%x4|"
978                     "Objects of Same Type%x5|"
979                                 "Objects on Shared Layers%x6|"
980                 "Objects in Same Group%x7|"
981                 "Object Hooks%x8|"
982                                 "Object PassIndex%x9|"
983                                 "Object Color%x10|"
984                                 "Game Properties%x11");
985
986         /* here we go */
987         
988         nr= pupmenu(str);
989         MEM_freeN(str);
990         
991         select_object_grouped(nr);
992 }
993
994 void join_menu(void)
995 {
996         Object *ob= OBACT;
997         if (G.obedit) {
998                 error("This data does not support joining in editmode");
999                 return;
1000         }
1001         if (!ob) {
1002                 error("Can't join unless there is an active object");
1003                 return;
1004         }
1005         
1006         if(ob->type == OB_MESH) {
1007                 if(okee("Join selected meshes")==0) return;
1008                 join_mesh();
1009         } else if(ob->type == OB_CURVE) {
1010                 if(okee("Join selected curves")==0) return;
1011                 join_curve(OB_CURVE);
1012         } else if(ob->type == OB_SURF) {
1013                 if(okee("Join selected NURBS")==0) return;
1014                 join_curve(OB_SURF);
1015         } else if(ob->type == OB_ARMATURE) {
1016                 /*      Make sure the user wants to continue*/
1017                 if(okee("Join selected armatures")==0) return;
1018                 join_armature ();
1019         } else {
1020                 error("This object type doesn't support joining");
1021         }
1022 }
1023
1024 static unsigned short convert_for_nonumpad(unsigned short event)
1025 {
1026         if (event>=ZEROKEY && event<=NINEKEY) {
1027                 return event - ZEROKEY + PAD0;
1028         } else if (event==MINUSKEY) {
1029                 return PADMINUS;
1030         } else if (event==EQUALKEY) {
1031                 return PADPLUSKEY;
1032         } else if (event==BACKSLASHKEY) {
1033                 return PADSLASHKEY;
1034         } else {
1035                 return event;
1036         }
1037 }
1038
1039 /* *************** */
1040
1041 void BIF_undo_push(char *str)
1042 {
1043         if(G.obedit) {
1044                 if (U.undosteps == 0) return;
1045
1046                 if(G.obedit->type==OB_MESH)
1047                         undo_push_mesh(str);
1048                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1049                         undo_push_curve(str);
1050                 else if (G.obedit->type==OB_FONT)
1051                         undo_push_font(str);
1052                 else if (G.obedit->type==OB_MBALL)
1053                         undo_push_mball(str);
1054                 else if (G.obedit->type==OB_LATTICE)
1055                         undo_push_lattice(str);
1056                 else if (G.obedit->type==OB_ARMATURE)
1057                         undo_push_armature(str);
1058         }
1059         else if(G.f & G_PARTICLEEDIT) {
1060                 if (U.undosteps == 0) return;
1061
1062                 PE_undo_push(str);
1063         }
1064         else {
1065                 if(U.uiflag & USER_GLOBALUNDO) 
1066                         BKE_write_undo(str);
1067         }
1068 }
1069
1070 void BIF_undo(void)
1071 {       
1072         if(G.obedit) {
1073                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1074                         undo_editmode_step(1);
1075         }
1076         else {
1077                 if(G.f & G_TEXTUREPAINT)
1078                         undo_imagepaint_step(1);
1079                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1080                         undo_imagepaint_step(1);
1081                 else if(G.f & G_PARTICLEEDIT)
1082                         PE_undo();
1083                 else {
1084                         /* now also in faceselect mode */
1085                         if(U.uiflag & USER_GLOBALUNDO) {
1086 #ifndef DISABLE_PYTHON
1087                                 BPY_scripts_clear_pyobjects();
1088 #endif
1089                                 BKE_undo_step(1);
1090                                 sound_initialize_sounds();
1091                         }
1092                 }
1093         }
1094 }
1095
1096 void BIF_redo(void)
1097 {
1098         if(G.obedit) {
1099                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1100                         undo_editmode_step(-1);
1101         }
1102         else {
1103                 if(G.f & G_TEXTUREPAINT)
1104                         undo_imagepaint_step(-1);
1105                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1106                         undo_imagepaint_step(-1);
1107                 else if(G.f & G_PARTICLEEDIT)
1108                         PE_redo();
1109                 else {
1110                         /* includes faceselect now */
1111                         if(U.uiflag & USER_GLOBALUNDO) {
1112                                 BKE_undo_step(-1);
1113                                 sound_initialize_sounds();
1114                         }
1115                 }
1116         }
1117 }
1118
1119 void BIF_undo_menu(void)
1120 {
1121         if(G.obedit) {
1122                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1123                         undo_editmode_menu();
1124                 allqueue(REDRAWALL, 0);
1125         }
1126         else {
1127                 if(G.f & G_PARTICLEEDIT)
1128                         PE_undo_menu();
1129                 else if(U.uiflag & USER_GLOBALUNDO) {
1130                         char *menu= BKE_undo_menu_string();
1131                         if(menu) {
1132                                 short event= pupmenu_col(menu, 20);
1133                                 MEM_freeN(menu);
1134                                 if(event>0) {
1135                                         BKE_undo_number(event);
1136                                         sound_initialize_sounds();
1137                                 }
1138                         }
1139                 }
1140         }
1141 }
1142
1143 /* *************** */
1144
1145 void handle_view_middlemouse() {
1146         /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1147         if(U.flag & USER_VIEWMOVE) {
1148                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1149                         viewmove(0);
1150                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1151                         viewmove(2);
1152                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1153                         viewmove(1);
1154         }
1155         else {
1156                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1157                         viewmove(1);
1158                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1159                         viewmove(2);
1160                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1161                         viewmove(0);
1162         }
1163 }
1164
1165 void handle_view_wheelup()
1166 {
1167         /* Regular:   Zoom in */
1168         /* Shift:     Scroll up */
1169         /* Ctrl:      Scroll right */
1170         /* Alt-Shift: Rotate up */
1171         /* Alt-Ctrl:  Rotate right */
1172
1173         if( G.qual & LR_SHIFTKEY ) {
1174                 if( G.qual & LR_ALTKEY ) { 
1175                         G.qual &= ~LR_SHIFTKEY;
1176                         persptoetsen(PAD2);
1177                         G.qual |= LR_SHIFTKEY;
1178                 } else {
1179                         persptoetsen(PAD2);
1180                 }
1181         } else if( G.qual & LR_CTRLKEY ) {
1182                 if( G.qual & LR_ALTKEY ) { 
1183                         G.qual &= ~LR_CTRLKEY;
1184                         persptoetsen(PAD4);
1185                         G.qual |= LR_CTRLKEY;
1186                 } else {
1187                         persptoetsen(PAD4);
1188                 }
1189         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1190                 persptoetsen(PADMINUS);
1191         else
1192                 persptoetsen(PADPLUSKEY);
1193 }
1194
1195 void handle_view_wheeldown()
1196 {
1197         /* Regular:   Zoom out */
1198         /* Shift:     Scroll down */
1199         /* Ctrl:      Scroll left */
1200         /* Alt-Shift: Rotate down */
1201         /* Alt-Ctrl:  Rotate left */
1202
1203         if( G.qual & LR_SHIFTKEY ) {
1204                 if( G.qual & LR_ALTKEY ) { 
1205                         G.qual &= ~LR_SHIFTKEY;
1206                         persptoetsen(PAD8);
1207                         G.qual |= LR_SHIFTKEY;
1208                 } else {
1209                         persptoetsen(PAD8);
1210                 }
1211         } else if( G.qual & LR_CTRLKEY ) {
1212                 if( G.qual & LR_ALTKEY ) { 
1213                         G.qual &= ~LR_CTRLKEY;
1214                         persptoetsen(PAD6);
1215                         G.qual |= LR_CTRLKEY;
1216                 } else {
1217                         persptoetsen(PAD6);
1218                 }
1219         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1220                 persptoetsen(PADPLUSKEY);
1221         else
1222                 persptoetsen(PADMINUS);
1223 }
1224
1225 int mouse_in_header(ScrArea *sa)
1226 {
1227         short mouse[2];
1228         getmouseco_sc(mouse);
1229         return mouse[0] >= sa->headrct.xmin &&
1230                mouse[0] <= sa->headrct.xmax &&
1231                mouse[1] >= sa->headrct.ymin &&
1232                mouse[1] <= sa->headrct.ymax;
1233 }
1234
1235 static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
1236 {
1237         View3D *v3d= sa->spacedata.first;
1238         Object *ob= OBACT;      /* do not change! */
1239         float *curs;
1240         int doredraw= 0, pupval;
1241         unsigned short event= evt->event;
1242         short val= evt->val;
1243         char ascii= evt->ascii;
1244         
1245         if(curarea->win==0) return;     /* when it comes from sa->headqread() */
1246         
1247         if(val) {
1248
1249                 if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
1250                 
1251                 if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
1252                 
1253                 /* - we consider manipulator a button, defaulting to leftmouse 
1254                  * - grease-pencil also defaults to leftmouse
1255                  */
1256                 if(event==LEFTMOUSE) {
1257 #ifndef DISABLE_PYTHON
1258                         /* run any view3d event handler script links */
1259                         if (sa->scriptlink.totscript) {
1260                                 if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1261                                         return; /* return if event was processed (swallowed) by handler(s) */
1262                         }
1263 #endif
1264                         if(BIF_paintSketch(LEFTMOUSE)) return;
1265                         if(gpencil_do_paint(sa, L_MOUSE)) return;
1266                         if(BIF_do_manipulator(sa)) return;
1267                 }
1268                 else if(event==RIGHTMOUSE) {
1269                         if(gpencil_do_paint(sa, R_MOUSE)) return;
1270                         if(BIF_paintSketch(RIGHTMOUSE)) return;
1271                 }
1272                 
1273                 /* swap mouse buttons based on user preference */
1274                 if (U.flag & USER_LMOUSESELECT) {
1275                         /* only swap mouse button for selection, in modes where it is relevant.
1276                          * painting/sculpting stays on LEFTMOUSE */
1277                         if (   !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) || (G.f & G_GREASEPENCIL) ||
1278                                 (G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_PARTICLEEDIT)) ||
1279                                 (G.obedit) )
1280                         {                       
1281                                 if (event==LEFTMOUSE) event = RIGHTMOUSE;
1282                                 else if (event==RIGHTMOUSE) event = LEFTMOUSE;
1283                         }
1284                 }
1285
1286                 if(!mouse_in_header(sa)) {
1287                         if(!G.obedit && (G.f & G_SCULPTMODE)) {
1288                                 SculptSession *ss= sculpt_session();
1289                                 if(ss && ss->radialcontrol) {
1290                                         radialcontrol_do_events(ss->radialcontrol, event);
1291                                         return;
1292                                 }
1293                                 else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
1294                                         if(!bwin_qtest(sa->win))
1295                                                 allqueue(REDRAWVIEW3D, 0);
1296                                 }
1297                         }
1298                         else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
1299                                 ParticleSystem *psys=PE_get_current(OBACT);
1300                                 ParticleEditSettings *pset=PE_settings();
1301                                 if(*PE_radialcontrol()) {
1302                                         radialcontrol_do_events(*PE_radialcontrol(), event);
1303                                         return;
1304                                 }
1305                                 if(psys && psys->edit){
1306                                         if(pset->brushtype>=0 &&
1307                                                 event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
1308                                                 (event==MOUSEY || event==MOUSEX) && bwin_qtest(sa->win)==0) {
1309                                                 allqueue(REDRAWVIEW3D, 0);
1310                                         }
1311                                 }
1312                         }
1313                         
1314                         BDR_queueDrawSketch();
1315
1316                         /* Handle retopo painting */
1317                         if(retopo_mesh_paint_check()) {
1318                                 if(!retopo_paint(event))
1319                                         return;
1320                         }
1321                 }
1322
1323 #ifndef DISABLE_PYTHON
1324                 /* run any view3d event handler script links */
1325                 if (event && sa->scriptlink.totscript)
1326                         if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1327                                 return; /* return if event was processed (swallowed) by handler(s) */
1328 #endif
1329
1330                 /* TEXTEDITING?? */
1331                 if((G.obedit) && G.obedit->type==OB_FONT) {
1332                         switch(event) {
1333                         
1334                         case LEFTMOUSE:
1335                                 mouse_cursor();
1336                                 break;
1337                         case MIDDLEMOUSE:
1338                                 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1339                                 if(U.flag & USER_VIEWMOVE) {
1340                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1341                                                 viewmove(0);
1342                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1343                                                 viewmove(2);
1344                                         else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1345                                                 viewmove(1);
1346                                 }
1347                                 else {
1348                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1349                                                 viewmove(1);
1350                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1351                                                 viewmove(2);
1352                                         else
1353                                                 viewmove(0);
1354                                 }
1355                                 break;
1356                                 
1357                         case WHEELUPMOUSE:
1358                                 /* Regular:   Zoom in */
1359                                 /* Shift:     Scroll up */
1360                                 /* Ctrl:      Scroll right */
1361                                 /* Alt-Shift: Rotate up */
1362                                 /* Alt-Ctrl:  Rotate right */
1363
1364                                 if( G.qual & LR_SHIFTKEY ) {
1365                                         if( G.qual & LR_ALTKEY ) { 
1366                                                 G.qual &= ~LR_SHIFTKEY;
1367                                                 persptoetsen(PAD2);
1368                                                 G.qual |= LR_SHIFTKEY;
1369                                         } else {
1370                                                 persptoetsen(PAD2);
1371                                         }
1372                                 } else if( G.qual & LR_CTRLKEY ) {
1373                                         if( G.qual & LR_ALTKEY ) { 
1374                                                 G.qual &= ~LR_CTRLKEY;
1375                                                 persptoetsen(PAD4);
1376                                                 G.qual |= LR_CTRLKEY;
1377                                         } else {
1378                                                 persptoetsen(PAD4);
1379                                         }
1380                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1381                                         persptoetsen(PADMINUS);
1382                                 else
1383                                         persptoetsen(PADPLUSKEY);
1384
1385                                 doredraw= 1;
1386                                 break;
1387
1388                         case WHEELDOWNMOUSE:
1389                                 /* Regular:   Zoom out */
1390                                 /* Shift:     Scroll down */
1391                                 /* Ctrl:      Scroll left */
1392                                 /* Alt-Shift: Rotate down */
1393                                 /* Alt-Ctrl:  Rotate left */
1394
1395                                 if( G.qual & LR_SHIFTKEY ) {
1396                                         if( G.qual & LR_ALTKEY ) { 
1397                                                 G.qual &= ~LR_SHIFTKEY;
1398                                                 persptoetsen(PAD8);
1399                                                 G.qual |= LR_SHIFTKEY;
1400                                         } else {
1401                                                 persptoetsen(PAD8);
1402                                         }
1403                                 } else if( G.qual & LR_CTRLKEY ) {
1404                                         if( G.qual & LR_ALTKEY ) { 
1405                                                 G.qual &= ~LR_CTRLKEY;
1406                                                 persptoetsen(PAD6);
1407                                                 G.qual |= LR_CTRLKEY;
1408                                         } else {
1409                                                 persptoetsen(PAD6);
1410                                         }
1411                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1412                                         persptoetsen(PADPLUSKEY);
1413                                 else
1414                                         persptoetsen(PADMINUS);
1415                                 
1416                                 doredraw= 1;
1417                                 break;
1418
1419                         case UKEY:
1420                                 if(G.qual==LR_ALTKEY) {
1421                                         remake_editText();
1422                                         doredraw= 1;
1423                                 } 
1424                                 else {
1425                                         do_textedit(event, val, ascii);
1426                                 }
1427                                 break;
1428                         case VKEY:
1429                                 if(G.qual==LR_ALTKEY) {
1430                                         paste_editText();
1431                                         doredraw= 1;
1432                                 } 
1433                                 else {
1434                                         do_textedit(event, val, ascii);
1435                                 }
1436                                 break;
1437                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1438                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1439                         case PADENTER:
1440                                 persptoetsen(event);
1441                                 doredraw= 1;
1442                                 break;
1443                                 
1444                         default:
1445                                 do_textedit(event, val, ascii);
1446                                 break;
1447                         }
1448                 }
1449                 else if(!G.obedit && (G.f & G_SCULPTMODE)) {
1450                         SculptData *sd= sculpt_data();
1451                         SculptSession *ss= sculpt_session();
1452                         BrushData *br= sculptmode_brush();
1453                         Mesh *me= get_mesh(OBACT);
1454                         char update_prop= 0;
1455                         
1456                         if(U.flag & USER_NONUMPAD) {
1457                                 event= convert_for_nonumpad(event);
1458                         }
1459                         
1460                         switch(event) {
1461                         case LEFTMOUSE:
1462                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1463                                         sculptmode_pmv(0);
1464                                 else if(!(ss && ss->radialcontrol))
1465                                         sculpt();
1466                                 break;
1467                         /* View */
1468                         case MIDDLEMOUSE:
1469                                 handle_view_middlemouse();
1470                                 break;
1471                         case WHEELUPMOUSE:
1472                                 handle_view_wheelup();
1473                                 doredraw= 1;
1474                                 break;
1475                         case WHEELDOWNMOUSE:
1476                                 handle_view_wheeldown();
1477                                 doredraw= 1;
1478                                 break;
1479                         case RIGHTMOUSE:
1480                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1481                                         sculptmode_pmv(1);
1482                                 break;
1483                         case CKEY:
1484                                 if(G.qual==LR_SHIFTKEY) {
1485                                         view3d_home(1);
1486                                         curs= give_cursor();
1487                                         curs[0]=curs[1]=curs[2]= 0.0;
1488                                         allqueue(REDRAWVIEW3D, 0);
1489                                 }
1490                                 else if(G.qual==0) {
1491                                         if (G.vd->persp==V3D_CAMOB)
1492                                                 /* center the camera offset */
1493                                                 G.vd->camdx= G.vd->camdy= 0.0;
1494                                         else {
1495                                                 /*non camera center*/
1496                                                 float new_ofs[3];
1497                                                 curs= give_cursor();
1498                                                 new_ofs[0]= -curs[0];
1499                                                 new_ofs[1]= -curs[1];
1500                                                 new_ofs[2]= -curs[2];
1501                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1502                                         }
1503                                 }
1504                                 doredraw= 1;
1505                                 break;
1506                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1507                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1508                         case PADPLUSKEY:
1509                         case PADMINUS:
1510                         case PADENTER:
1511                                 persptoetsen(event);
1512                                 doredraw= 1;
1513                                 break;
1514                         case BKEY:
1515                                 if(G.qual==LR_ALTKEY)
1516                                         view3d_edit_clipping(v3d);
1517                                 else if(G.qual==LR_SHIFTKEY) {
1518                                         if(G.vd->persp==V3D_CAMOB)
1519                                                 set_render_border();
1520                                         else
1521                                                 view3d_border_zoom();
1522                                 }
1523                                 break;
1524                         case PADSLASHKEY:
1525                                 if(!G.qual) {
1526                                         if(G.vd->localview) {
1527                                                 G.vd->localview= 0;
1528                                                 endlocalview(curarea);
1529                                         }
1530                                         else {
1531                                                 G.vd->localview= 1;
1532                                                 initlocalview();
1533                                         }
1534                                         allqueue(REDRAWVIEW3D, 1);
1535                                 }
1536                                 break;
1537                         /* Brush properties */
1538                         case AKEY:
1539                                 if(G.qual==LR_SHIFTKEY)
1540                                         br->flag ^= SCULPT_BRUSH_ANCHORED;
1541                                 else
1542                                         br->flag ^= SCULPT_BRUSH_AIRBRUSH;
1543                                 update_prop= 1; break;
1544                         case FKEY:
1545                                 if(ss) {
1546                                         sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
1547                                                                    G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
1548                                                                    G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
1549                                                                    RADIALCONTROL_NONE);
1550                                 }
1551                                 break;
1552                         case VKEY:
1553                                 br->dir= br->dir==1 ? 2 : 1;
1554                                 update_prop= 1; break;
1555                         /* Set brush */
1556                         case DKEY:
1557                                 sd->brush_type= DRAW_BRUSH;
1558                                 update_prop= 1; break;
1559                         case SKEY:
1560                                 if(G.qual==LR_SHIFTKEY)
1561                                         sd->flags ^= SCULPT_INPUT_SMOOTH;
1562                                 else {
1563                                         sd->brush_type= SMOOTH_BRUSH;
1564                                         update_prop= 1;
1565                                 }
1566                                 break;
1567                         case PKEY:
1568                                 sd->brush_type= PINCH_BRUSH;
1569                                 update_prop= 1; break;
1570                         case IKEY:
1571                                 sd->brush_type= INFLATE_BRUSH;
1572                                 update_prop= 1; break;
1573                         case GKEY:
1574                                 sd->brush_type= GRAB_BRUSH;
1575                                 update_prop= 1; break;
1576                         case LKEY:
1577                                 sd->brush_type= LAYER_BRUSH;
1578                                 update_prop= 1; break;
1579                         case TKEY:
1580                                 sd->brush_type= FLATTEN_BRUSH;
1581                                 update_prop= 1; break;
1582                         /* Symmetry */
1583                         case XKEY:
1584                                 sd->symm^= SYMM_X;
1585                                 update_prop= 1; break;
1586                         case YKEY:
1587                                 sd->symm^= SYMM_Y;
1588                                 update_prop= 1; break;
1589                         case ZKEY:
1590                                 sd->symm^= SYMM_Z;
1591                                 update_prop= 1; break;
1592                         /* Interface */
1593                         case NKEY:
1594                                 if(G.qual==0) {
1595                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1596                                         allqueue(REDRAWVIEW3D, 0);
1597                                 }
1598                                 break;
1599                         /* Multires */
1600                         case PAGEUPKEY:
1601                                 if(me && me->mr) {
1602                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
1603                                         multires_set_level_cb(ob, ob->data);
1604                                 }
1605                                 break;
1606                         case PAGEDOWNKEY:
1607                                 if(me && me->mr) {
1608                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
1609                                         multires_set_level_cb(ob, ob->data);
1610                                 }
1611                                 break;
1612                         /* Partial Visibility */
1613                         case HKEY:
1614                                 if(G.qual==LR_ALTKEY) {
1615                                         waitcursor(1);
1616                                         mesh_pmv_off(ob, get_mesh(ob));
1617                                         BIF_undo_push("Partial mesh hide");
1618                                         allqueue(REDRAWVIEW3D,0);
1619                                         waitcursor(0);
1620                                 }
1621                                 break;
1622                         /* Layers */
1623                         case ONEKEY:
1624                                 do_layer_buttons(0); break;
1625                         case TWOKEY:
1626                                 do_layer_buttons(1); break;
1627                         case THREEKEY:
1628                                 do_layer_buttons(2); break;
1629                         case FOURKEY:
1630                                 do_layer_buttons(3); break;
1631                         case FIVEKEY:
1632                                 do_layer_buttons(4); break;
1633                         case SIXKEY:
1634                                 do_layer_buttons(5); break;
1635                         case SEVENKEY:
1636                                 do_layer_buttons(6); break;
1637                         case EIGHTKEY:
1638                                 do_layer_buttons(7); break;
1639                         case NINEKEY:
1640                                 do_layer_buttons(8); break;
1641                         case ZEROKEY:
1642                                 do_layer_buttons(9); break;
1643                         case MINUSKEY:
1644                                 do_layer_buttons(10); break;
1645                         case EQUALKEY:
1646                                 do_layer_buttons(11); break;
1647                         case ACCENTGRAVEKEY:
1648                                 do_layer_buttons(-1); break;
1649                         
1650                         case NDOFMOTION:                
1651                                 if (G.vd->ndofmode == 0) {
1652                                         viewmoveNDOF(1);
1653                                 } else if (G.vd->ndofmode == 1) {
1654                                         viewmoveNDOFfly(1);
1655                                 } else {
1656                                         NDofTransform();
1657                                 }
1658                 break;
1659                                 
1660             case NDOFBUTTON:
1661                                 if (val == 1) {
1662                                         G.vd->ndofmode +=1;
1663                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1664                                                 G.vd->ndofmode = 0;
1665                                 }
1666                                 if (val == 2) {
1667                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1668                                 }
1669                                 allqueue(REDRAWHEADERS, 0);
1670                 break;
1671                                 
1672                         }
1673                         
1674                         /* Redraw buttons window as well as view 3d (for floating panel) */
1675                         if(update_prop) {
1676                                 allqueue(REDRAWVIEW3D, 0);
1677                                 allqueue(REDRAWBUTSEDIT, 0);
1678                         }
1679                 } else {
1680
1681                         if (U.flag & USER_NONUMPAD) {
1682                                 event= convert_for_nonumpad(event);
1683                         }
1684
1685                         switch(event) {
1686                         
1687                         /* Afterqueue events */
1688                         case BACKBUFDRAW:
1689                                 backdrawview3d(1);
1690                                 break;
1691                         case RENDERPREVIEW:
1692                                 BIF_view3d_previewrender(sa);
1693                                 break;
1694                                 
1695                         case TABKEY:
1696                                 /* Shift-Tabe handling (other cases are in toets) */
1697                                 if (G.qual == LR_SHIFTKEY)
1698                                 {
1699                                         /* Snap toggle only when supported */
1700                                         if (BIF_snappingSupported())
1701                                         {
1702                                                 G.scene->snap_flag ^= SCE_SNAP;
1703                                                 allqueue(REDRAWHEADERS, 0);
1704                                         }                                       
1705                                 }
1706                                 break;
1707                                 
1708                         /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
1709                          * based on user preference USER_LMOUSESELECT
1710                          */
1711                         case LEFTMOUSE: 
1712                                 if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_PARTICLEEDIT))) {
1713                                         mouse_cursor();
1714                                 }
1715                                 else if (G.f & G_WEIGHTPAINT) {
1716                                         weight_paint();
1717                                 }
1718                                 else if (G.f & G_VERTEXPAINT) {
1719                                         vertex_paint();
1720                                 }
1721                                 else if (G.f & G_TEXTUREPAINT) {
1722                                         imagepaint_paint(L_MOUSE, 1);
1723                                 }
1724                                 else if (G.f & G_PARTICLEEDIT) {
1725                                         if(G.qual & LR_CTRLKEY)
1726                                                 mouse_cursor();
1727                                         else if(!PE_brush_particles())
1728                                                 mouse_cursor();
1729                                 }
1730                                 break;
1731                         case MIDDLEMOUSE:
1732                                 handle_view_middlemouse();
1733                                 break;
1734                         case RIGHTMOUSE:
1735                                 if((G.obedit) && (G.qual & LR_CTRLKEY)==0) {
1736                                         if(G.obedit->type==OB_MESH)
1737                                                 mouse_mesh();
1738                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1739                                                 mouse_nurb();
1740                                         else if(G.obedit->type==OB_MBALL)
1741                                                 mouse_mball();
1742                                         else if(G.obedit->type==OB_LATTICE)
1743                                                 mouse_lattice();
1744                                         else if(G.obedit->type==OB_ARMATURE)
1745                                                 mouse_armature();
1746                                 }
1747                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
1748                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1749                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
1750                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1751                                 else if(G.qual==LR_CTRLKEY)
1752                                         mouse_select(); /* also allow in editmode, for vertex parenting */
1753                                 else if(FACESEL_PAINT_TEST)
1754                                         face_select();
1755                                 else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
1756                                         sample_vpaint();
1757                                 else if( G.f & G_PARTICLEEDIT)
1758                                         PE_mouse_particles();
1759                                 else
1760                                         mouse_select(); /* does poses too */
1761                                 break;
1762                         case WHEELUPMOUSE:
1763                                 handle_view_wheelup();
1764                                 doredraw= 1;
1765                                 break;
1766                         case WHEELDOWNMOUSE:
1767                                 handle_view_wheeldown();
1768                                 doredraw= 1;
1769                                 break;
1770
1771             case NDOFMOTION:            
1772                                 if (G.vd->ndofmode == 0) {
1773                                         viewmoveNDOF(1);
1774                                 } else if (G.vd->ndofmode == 1) {
1775                                         viewmoveNDOFfly(1);
1776                                 } else {
1777                                         NDofTransform();
1778                                 }
1779                 break;
1780
1781             case NDOFBUTTON:
1782                                 if (val == 1) {
1783                                         G.vd->ndofmode +=1;
1784                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1785                                                 G.vd->ndofmode = 0;
1786                                 }
1787                                 if (val == 2) {
1788                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1789                                 }
1790                                 allqueue(REDRAWHEADERS, 0);
1791                 break;
1792                                 
1793                         case ONEKEY:
1794                                 if(G.qual==LR_CTRLKEY) {
1795                                         flip_subdivison(1);
1796                                 }
1797                                 else do_layer_buttons(0); 
1798                                 break;
1799                                 
1800                         case TWOKEY:
1801                                 if(G.qual==LR_CTRLKEY) {
1802                                         flip_subdivison(2);
1803                                 }
1804                                 else do_layer_buttons(1); 
1805                                 break;
1806                                 
1807                         case THREEKEY:
1808                                 if(G.qual==LR_CTRLKEY) {
1809                                         flip_subdivison(3);
1810                                 }
1811                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1812                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1813                                                 select_faces_by_numverts(3);
1814                                 }
1815                                 else do_layer_buttons(2); 
1816                                 break;
1817                                 
1818                         case FOURKEY:
1819                                 if(G.qual==LR_CTRLKEY) {
1820                                         flip_subdivison(4);
1821                                 }
1822                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1823                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1824                                                 select_faces_by_numverts(4);
1825                                 }
1826                                 else do_layer_buttons(3); 
1827                                 break;
1828                                 
1829                         case FIVEKEY:
1830                                 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1831                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1832                                                 select_faces_by_numverts(5);
1833                                 }
1834                                 
1835                                 else if(G.qual==LR_CTRLKEY) {}
1836                                 else do_layer_buttons(4);
1837                                 break;
1838
1839                         case SIXKEY:
1840                                 if(G.qual==LR_CTRLKEY) {}
1841                                 else do_layer_buttons(5);
1842                                 break;
1843                         case SEVENKEY:
1844                                 if(G.qual==LR_CTRLKEY) {}
1845                                 else do_layer_buttons(6);
1846                                 break;
1847                         case EIGHTKEY:
1848                                 if(G.qual==LR_CTRLKEY) {}
1849                                 else do_layer_buttons(7);
1850                                 break;
1851                         case NINEKEY:
1852                                 if(G.qual==LR_CTRLKEY) {}
1853                                 else do_layer_buttons(8);
1854                                 break;
1855                         case ZEROKEY:
1856                                 if(G.qual==LR_CTRLKEY) {}
1857                                 else do_layer_buttons(9);
1858                                 break;
1859                         case MINUSKEY:
1860                                 if(G.qual==LR_CTRLKEY) {}
1861                                 else do_layer_buttons(10);
1862                                 break;
1863                         case EQUALKEY:
1864                                 if(G.qual==LR_CTRLKEY) {}
1865                                 else do_layer_buttons(11);
1866                                 break;
1867                         case ACCENTGRAVEKEY:
1868                                 do_layer_buttons(-1);
1869                                 break;
1870                         
1871                         case SPACEKEY:
1872                                 if(G.qual == LR_CTRLKEY) {
1873                                         val= pupmenu("Manipulator%t|Enable/Disable|Translate|Rotate|Scale|Combo");
1874                                         if(val>0) {
1875                                                 if(val==1) v3d->twflag ^= V3D_USE_MANIPULATOR;
1876                                                 else {
1877                                                         if(val==2) v3d->twtype= V3D_MANIP_TRANSLATE;
1878                                                         else if(val==3) v3d->twtype= V3D_MANIP_ROTATE;
1879                                                         else if(val==4) v3d->twtype= V3D_MANIP_SCALE;
1880                                                         else if(val==5) v3d->twtype= V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE|V3D_MANIP_SCALE;
1881                                                         v3d->twflag |= V3D_USE_MANIPULATOR;
1882                                                 }
1883                                                 doredraw= 1;
1884                                         }
1885                                 }
1886                                 else if(G.qual == LR_ALTKEY) {
1887                                         BIF_selectOrientation();
1888                                         doredraw= 1;
1889                                 }
1890
1891                                 break;
1892                                 
1893                         case AKEY:
1894                                 if(G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
1895                                         if(G.obedit == 0)
1896                                                 alignmenu();
1897                                         else if(G.obedit->type==OB_ARMATURE)
1898                                                 align_selected_bones();
1899                                 }
1900                                 else if(G.qual & LR_CTRLKEY) { /* also with shift! */
1901                                         apply_object(); 
1902                                 }
1903                                 else if((G.qual==LR_SHIFTKEY)) {
1904                                         toolbox_n_add();
1905                                 }
1906                                 else {
1907                                         if(G.obedit) {
1908                                                 if(G.obedit->type==OB_MESH)
1909                                                         deselectall_mesh();
1910                                                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1911                                                         deselectall_nurb();
1912                                                 else if(G.obedit->type==OB_MBALL)
1913                                                         deselectall_mball();
1914                                                 else if(G.obedit->type==OB_LATTICE)
1915                                                         deselectall_Latt();
1916                                                 else if(G.obedit->type==OB_ARMATURE)
1917                                                 {
1918                                                         if (BIF_fullSketchMode())
1919                                                         {
1920                                                                 BIF_selectAllSketch(1);
1921                                                         }
1922                                                         else
1923                                                         {
1924                                                                 deselectall_armature(1, 1);     /* 1 == toggle */
1925                                                         }
1926                                                 }
1927                                         }
1928                                         else if (ob && (ob->flag & OB_POSEMODE)){
1929                                                 deselectall_posearmature(ob, 1, 1);
1930                                         }
1931                                         else {
1932                                                 if(FACESEL_PAINT_TEST) deselectall_tface();
1933                                                 else if(G.f & G_PARTICLEEDIT) PE_deselectall();
1934                                                 else {
1935                                                         /* by design, the center of the active object 
1936                                                          * (which need not necessarily by selected) will
1937                                                          * still be drawn as if it were selected.
1938                                                          */
1939                                                         deselectall();
1940                                                 }
1941                                         }
1942                                 }
1943                                 break;
1944                         case BKEY:
1945                                 if(G.qual==LR_ALTKEY)
1946                                         view3d_edit_clipping(v3d);
1947                                 else if(G.qual==LR_SHIFTKEY)
1948                                 {
1949                                         if(G.vd->persp==V3D_CAMOB)
1950                                                 set_render_border();
1951                                         else
1952                                                 view3d_border_zoom();
1953                                 }
1954                                 else if(G.qual==LR_CTRLKEY) {
1955                                         extern void pointcache_bake(PTCacheID *pid, int startframe);
1956                                         extern void pointcache_free(PTCacheID *pid, int cacheonly);
1957                                         extern void fluidsimBake(Object *ob);
1958                                         extern void fluidsimFreeBake(Object *ob);
1959                                         int pupval;
1960
1961                                         pupval= pupmenu("Physics Baking%t|Bake selected %x1|Free bake selected %x2|Free cache selected %x3");
1962
1963                                         if(pupval > 0) {
1964                                                 if(pupval == 1) {
1965                                                         pointcache_bake(NULL, 0);
1966                                                         /* also bake first domain of selected objects... */
1967                                                         fluidsimBake(NULL);
1968                                                 }
1969                                                 else if(pupval == 2) {
1970                                                         pointcache_free(NULL, 0);
1971                                                         fluidsimFreeBake(NULL);
1972                                                 }
1973                                                 else if(pupval == 3)
1974                                                         pointcache_free(NULL, 1);
1975                                         }
1976                                 }
1977                                 else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
1978                                         objects_bake_render_menu();
1979                                 else if(G.qual==0)
1980                                         borderselect();
1981                                 break;
1982                         case CKEY:
1983                                 if(G.qual==LR_CTRLKEY) {
1984                                         if(ob && (ob->flag & OB_POSEMODE))
1985                                                 pose_copy_menu();       /* poseobject.c */
1986                                         else
1987                                                 copy_attr_menu();
1988                                 }
1989                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) 
1990                                         gpencil_convert_menu(); /* gpencil.c */
1991                                 else if(G.qual==LR_ALTKEY) {
1992                                         if(ob && (ob->flag & OB_POSEMODE))
1993                                                 pose_clear_constraints();       /* poseobject.c */
1994                                         else if (BIF_fullSketchMode())
1995                                         {
1996                                                 BIF_convertSketch();
1997                                         }
1998                                         else
1999                                                 convertmenu();  /* editobject.c */
2000                                 }
2001                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) 
2002                                         add_constraint(0);      /* editconstraint.c, generic for objects and posemode */
2003                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) {
2004                                         BIF_manageTransformOrientation(0, 1);
2005                                         allqueue(REDRAWVIEW3D, 0);
2006                                 }
2007                                 else if((G.qual==LR_SHIFTKEY)) {
2008                                         view3d_home(1);
2009                                         curs= give_cursor();
2010                                         curs[0]=curs[1]=curs[2]= 0.0;
2011                                         allqueue(REDRAWVIEW3D, 0);
2012                                 }
2013                                 else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) {
2014                                         makecyclicNurb();
2015                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2016                                         allqueue(REDRAWVIEW3D, 0);
2017                                 }
2018                                 else if((G.qual==0)){
2019                                         if (G.vd->persp==V3D_CAMOB)
2020                                                 /* center the camera offset */
2021                                                 G.vd->camdx= G.vd->camdy= 0.0;
2022                                         else {
2023                                                 /*non camera center*/
2024                                                 float new_ofs[3];
2025                                                 curs= give_cursor();
2026                                                 new_ofs[0]= -curs[0];
2027                                                 new_ofs[1]= -curs[1];
2028                                                 new_ofs[2]= -curs[2];
2029                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
2030                                         }
2031                                         scrarea_queue_winredraw(curarea);
2032                                 }
2033                                 break;
2034                         case DKEY:
2035                                 if((G.qual==LR_SHIFTKEY)) {
2036                                         duplicate_context_selected();
2037                                 }
2038                                 else if(G.qual==LR_ALTKEY) {
2039                                         if(ob && (ob->flag & OB_POSEMODE))
2040                                                 error ("Duplicate not possible in posemode.");
2041                                         else if((G.obedit==NULL))
2042                                                 adduplicate(0, 0);
2043                                 }
2044                                 else if(G.qual==LR_CTRLKEY) {
2045                                         imagestodisplist(); // removed
2046                                 }
2047                                 else if((G.qual==0)){
2048                                         pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
2049                                         if(pupval>0) {
2050                                                 G.vd->drawtype= pupval;
2051                                                 doredraw= 1;
2052                                         }
2053                 }
2054                                 
2055                                 break;
2056                         case EKEY:
2057                                 if (G.qual==0){
2058                                         if(G.obedit) {
2059                                                 if(G.obedit->type==OB_MESH)
2060                                                         extrude_mesh();
2061                                                 else if(G.obedit->type==OB_CURVE)
2062                                                         addvert_Nurb('e');
2063                                                 else if(G.obedit->type==OB_SURF)
2064                                                         extrude_nurb();
2065                                                 else if(G.obedit->type==OB_ARMATURE)
2066                                                         extrude_armature(0);
2067                                         }
2068                                 }
2069                                 else if (G.qual==LR_CTRLKEY) {
2070                                         if(G.obedit && G.obedit->type==OB_MESH)
2071                                                 Edge_Menu();
2072                                         else if (FACESEL_PAINT_TEST)
2073                                                 seam_mark_clear_tface(0);
2074                                 }
2075                                 else if (G.qual==LR_SHIFTKEY) {
2076                                         if (G.obedit && G.obedit->type==OB_MESH &&
2077                                             !multires_level1_test()) {
2078                                                 initTransform(TFM_CREASE, CTX_EDGE);
2079                                                 Transform();
2080                                         }
2081                                         else if (G.obedit && G.obedit->type==OB_ARMATURE) {
2082                                                 extrude_armature(1);
2083                                         }
2084                                 }
2085                                 else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
2086                                         if (G.obedit && G.obedit->type==OB_MESH &&
2087                                             !multires_level1_test()) {
2088                                                 if (G.scene->selectmode & SCE_SELECT_VERTEX) {
2089                                                         initTransform(TFM_BWEIGHT, CTX_NONE);
2090                                                 }
2091                                                 else {
2092                                                         initTransform(TFM_BWEIGHT, CTX_EDGE);
2093                                                 }
2094                                                 Transform();
2095                                         }
2096                                 }
2097                                 break;
2098                         case FKEY:
2099                                 if(G.obedit) {
2100                                         if(G.obedit->type==OB_MESH) {
2101                                                 if(G.qual == LR_CTRLKEY)
2102                                                         Face_Menu();
2103                                                 else if((G.qual==LR_SHIFTKEY))
2104                                                         fill_mesh();
2105                                                 else if(G.qual==LR_ALTKEY)
2106                                                         beauty_fill();
2107                                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY))
2108                                                         edge_flip();
2109                                                 else if (G.qual==0)
2110                                                         addedgeface_mesh();
2111                                                 else if ( G.qual == 
2112                                                          (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2113                                                         select_linked_flat_faces();
2114                                                 }
2115
2116                                         }
2117                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2118                                                 addsegment_nurb();
2119                                         }
2120                                         else if(G.obedit->type == OB_ARMATURE) {
2121                                                 fill_bones_armature();
2122                                         }
2123                                 }
2124                                 else if(G.qual==LR_CTRLKEY)
2125                                         sort_faces();
2126                                 else if((G.qual==LR_SHIFTKEY)) {
2127                                         if(ob && (ob->flag & OB_POSEMODE))
2128                                            pose_activate_flipped_bone();
2129                                         else if(G.f & G_WEIGHTPAINT)
2130                                                 pose_activate_flipped_bone();
2131                                         else if(G.f & G_PARTICLEEDIT)
2132                                                 PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
2133                                         else
2134                                                 fly();
2135                                 }
2136                                 else if((G.qual==LR_ALTKEY)) {
2137                                         if(ob && (ob->flag & OB_POSEMODE))
2138                                                 if(okee("Flip quaternion rotations"))
2139                                                         pose_flipquats();
2140                                 }
2141                                 else {
2142                                         if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)){
2143                                                 G.f ^= G_FACESELECT;
2144                                                 allqueue(REDRAWVIEW3D, 1);
2145                                                 allqueue(REDRAWBUTSEDIT, 1);
2146                                         }
2147                                         else if(G.f & G_PARTICLEEDIT) {
2148                                                 PE_radialcontrol_start(RADIALCONTROL_SIZE);
2149                                         } else {
2150                                                 pupmenu("Note%t|UV/Face Select was removed. Editmode now allows UV editing, Add a UV layer or Unwrap (UKey)");
2151                                         }
2152                                 }
2153                                 
2154                                 break;
2155                         case GKEY:
2156                                 if((G.qual == LR_CTRLKEY)) {
2157                                         if(G.obedit) {
2158                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2159                                                         vgroup_assign_with_menu();
2160                                         }
2161                                         else if(ob && (ob->flag & OB_POSEMODE))
2162                                                 pgroup_operation_with_menu();
2163                                         else
2164                                                 group_operation_with_menu();
2165                                 }
2166                                 else if((G.qual == (LR_CTRLKEY|LR_SHIFTKEY))) {
2167                                         if(G.obedit) {
2168                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2169                                                         vgroup_operation_with_menu();
2170                                         }
2171                                 }
2172                                 else if((G.qual==LR_SHIFTKEY)) {
2173                                         if(G.obedit) {
2174                                                 if(G.obedit->type==OB_MESH)
2175                                                         select_mesh_group_menu();
2176                                         } 
2177                                         else if(ob && (ob->flag & OB_POSEMODE))
2178                                                 pose_select_grouped_menu();
2179                                         else if (ob)
2180                                                 select_object_grouped_menu();
2181                                 }
2182                                 else if((G.obedit==0) && G.qual==LR_ALTKEY) {
2183                                         if(okee("Clear location")) {
2184                                                 clear_object('g');
2185                                         }
2186                                 }
2187                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2188                                         v3d->twtype= V3D_MANIP_TRANSLATE;
2189                                         doredraw= 1;
2190                                 }
2191                                 else if((G.qual==0)) {
2192                                         initTransform(TFM_TRANSLATION, CTX_NONE);
2193                                         Transform();
2194                                 }
2195                                 break;
2196                         case HKEY:
2197                                 if(G.obedit) {
2198                                         if(G.obedit->type==OB_MESH) {
2199                                                 if(G.qual==LR_CTRLKEY)
2200                                                         add_hook_menu();
2201                                                 else if(G.qual==LR_ALTKEY)
2202                                                         reveal_mesh();
2203                                                 else if((G.qual==LR_SHIFTKEY))
2204                                                         hide_mesh(1);
2205                                                 else if((G.qual==0)) 
2206                                                         hide_mesh(0);
2207                                         }
2208                                         else if(G.obedit->type== OB_SURF) {
2209                                                 if(G.qual==LR_CTRLKEY)
2210                                                         add_hook_menu();
2211                                                 else if(G.qual==LR_ALTKEY)
2212                                                         revealNurb();
2213                                                 else if((G.qual==LR_SHIFTKEY))
2214                                                         hideNurb(1);
2215                                                 else if((G.qual==0))
2216                                                         hideNurb(0);
2217                                         }
2218                                         else if(G.obedit->type==OB_CURVE) {
2219                                                 if(G.qual==LR_CTRLKEY)
2220                                                         add_hook_menu();
2221                                                 else if(G.qual==LR_ALTKEY)
2222                                                         revealNurb();
2223                                                 /* should be G.qual==LR_SHIFTKEY, but that is taken fro handles already */
2224                                                 else if((G.qual==(LR_ALTKEY|LR_SHIFTKEY))) 
2225                                                         hideNurb(1);
2226                                                 /* should be G.qual==0, but that is taken for handles already */
2227                                                 else if((G.qual==(LR_ALTKEY|LR_CTRLKEY))) 
2228                                                         hideNurb(0);
2229                                                 else {
2230                                                         if(G.qual==LR_CTRLKEY) /* conflict */
2231                                                                 autocalchandlesNurb_all(1);     /* flag=1, selected */
2232                                                         else if((G.qual==LR_SHIFTKEY))
2233                                                                 sethandlesNurb(1);
2234                                                         else if((G.qual==0))
2235                                                                 sethandlesNurb(3);
2236                                                         
2237                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2238                                                         BIF_undo_push("Handle change");
2239                                                         allqueue(REDRAWVIEW3D, 0);
2240                                                 }
2241                                         }
2242                                         else if(G.obedit->type==OB_LATTICE) {
2243                                                 if(G.qual==LR_CTRLKEY) add_hook_menu();
2244                                         }
2245                                         else if(G.obedit->type==OB_MBALL) {
2246                                                 if(G.qual==LR_ALTKEY)
2247                                                         reveal_mball();
2248                                                 else if((G.qual==LR_SHIFTKEY))
2249                                                         hide_mball(1);
2250                                                 else if((G.qual==0)) 
2251                                                         hide_mball(0);
2252                                         }
2253                                         else if(G.obedit->type==OB_ARMATURE) {
2254                                                 if (G.qual==0)
2255                                                         hide_selected_armature_bones();
2256                                                 else if (G.qual==LR_SHIFTKEY)
2257                                                         hide_unselected_armature_bones();
2258                                                 else if (G.qual==LR_ALTKEY)
2259                                                         show_all_armature_bones();
2260                                         }
2261                                 }
2262                                 else if(FACESEL_PAINT_TEST)
2263                                         hide_tface();
2264                                 else if(G.f & G_PARTICLEEDIT) {
2265                                         if(G.qual == LR_ALTKEY)
2266                                                 PE_hide(0);
2267                                         else if(G.qual == LR_SHIFTKEY)
2268                                                 PE_hide(1);
2269                                         else if(G.qual == 0)
2270                                                 PE_hide(2);
2271                                 }
2272                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2273                                         if (G.qual==0)
2274                                                 hide_selected_pose_bones();
2275                                         else if (G.qual==LR_SHIFTKEY)
2276                                                 hide_unselected_pose_bones();
2277                                         else if (G.qual==LR_ALTKEY)
2278                                                 show_all_pose_bones();
2279                                 }
2280                                 /* Object mode only, other modes are accounted for above */
2281                                 else if ((G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
2282                                         if(G.qual==LR_CTRLKEY)hookmenu();
2283                                         else if(G.qual==LR_ALTKEY) show_objects();
2284                                         else if(G.qual==LR_SHIFTKEY) hide_objects(0);
2285                                         else hide_objects(1);
2286                                 }
2287                                 break;
2288                         case IKEY:
2289                                 if(G.qual==LR_CTRLKEY) {
2290                                         if((ob) && (ob->flag & OB_POSEMODE) && (ob->type==OB_ARMATURE))
2291                                                 deselectall_posearmature(ob, 3, 1);
2292                                         else if(ob && G.obedit) {
2293                                                 if(G.obedit->type == OB_ARMATURE)
2294                                                         deselectall_armature(3, 1);
2295                                                 else
2296                                                         selectswap_mesh();
2297                                         }
2298                                         else
2299                                                 selectswap();
2300                                 }
2301                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY)) {
2302                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2303                                                 pose_clear_IK();
2304                                 }
2305                                 else if(G.qual==LR_SHIFTKEY) {
2306                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2307                                                 pose_add_IK();
2308                                 }
2309                                 break;
2310                                 
2311                         case JKEY:
2312                                 if(G.qual==LR_CTRLKEY) {
2313                                         if( ob ) {
2314                                                 join_menu();
2315                                         }
2316                                         else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
2317                                                 addsegment_nurb();
2318                                         } else {
2319                                                 error("Can't join unless there is an active object");
2320                                         }
2321                                         
2322                                 }
2323                                 else if(G.obedit) {
2324                                         if(G.obedit->type==OB_MESH) {
2325                                                 join_triangles();
2326                                         }
2327                                 }
2328
2329                                 break;
2330                         case KKEY:
2331                                 if(G.obedit) {
2332                                         if (G.obedit->type==OB_MESH) {
2333                                                 if (G.qual==LR_SHIFTKEY)
2334                                                         KnifeSubdivide(KNIFE_PROMPT);
2335                                                 else if (G.qual==0)
2336                                                         LoopMenu();
2337                                         }
2338                                         else if(G.obedit->type==OB_SURF)
2339                                                 printknots();
2340                                 }
2341                                 else {
2342                                         if((G.qual==LR_SHIFTKEY)) {
2343                                                 if(FACESEL_PAINT_TEST)
2344                                                         if (G.f & G_WEIGHTPAINT)
2345                                                                 clear_wpaint_selectedfaces();
2346                                                         else
2347                                                                 clear_vpaint_selectedfaces();
2348                                                 else if(G.f & G_VERTEXPAINT)
2349                                                         clear_vpaint();
2350                                                 else
2351                                                         select_select_keys();
2352                                         }
2353                                         else if (G.qual==0)
2354                                                 set_ob_ipoflags();
2355                                 }
2356                                 
2357                                 break;
2358                         case LKEY:
2359                                 if(G.obedit) {
2360                                         if(G.obedit->type==OB_MESH) {
2361                                                 if (G.qual & LR_CTRLKEY) {
2362                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2363                                                                 selectconnected_mesh_all(); /* normal select linked */
2364                                                         } else {
2365                                                                 selectconnected_delimit_mesh_all(); /* select linked with edge crease delimiting */
2366                                                         }
2367                                                 } else {
2368                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2369                                                                 selectconnected_mesh();
2370                                                         } else {
2371                                                                 selectconnected_delimit_mesh();
2372                                                         }
2373                                                 }
2374                                         }
2375                                         if(G.obedit->type==OB_ARMATURE)
2376                                                 selectconnected_armature();
2377                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
2378                                                 selectconnected_nurb();
2379                                 }
2380                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2381                                         if (G.qual == LR_CTRLKEY) 
2382                                                 poselib_preview_poses(ob, 0);
2383                                         else if (G.qual == LR_SHIFTKEY) 
2384                                                 poselib_add_current_pose(ob, 0);
2385                                         else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
2386                                                 poselib_rename_pose(ob);
2387                                         else if (G.qual == LR_ALTKEY)
2388                                                 poselib_remove_pose(ob, NULL);
2389                                         else
2390                                                 selectconnected_posearmature();
2391                                 }
2392                                 else {
2393                                         if(FACESEL_PAINT_TEST) {
2394                                                 if((G.qual==0))
2395                                                         select_linked_tfaces(0);
2396                                                 else if((G.qual==LR_SHIFTKEY))
2397                                                         select_linked_tfaces(1);
2398                                                 else if(G.qual==LR_CTRLKEY)
2399                                                         select_linked_tfaces(2);
2400                                         }
2401                                         else if(G.f & G_PARTICLEEDIT) {
2402                                                 if(G.qual==0)
2403                                                         PE_select_linked();
2404                                         }
2405                                         else {
2406                                                 if((G.qual==0))
2407                                                         make_local_menu();
2408                                                 else if((G.qual==LR_SHIFTKEY))
2409                                                         selectlinks_menu();
2410                                                 else if(G.qual==LR_CTRLKEY)
2411                                                         make_links_menu();
2412                                         }
2413                                 }
2414                                 break;
2415                         case MKEY:
2416                                 if(G.obedit){
2417                                         if (ELEM(G.qual, 0, LR_SHIFTKEY) && (G.obedit->type==OB_ARMATURE)) {
2418                                                 pose_movetolayer();
2419                                         }
2420                                         else if (G.qual==LR_ALTKEY) {
2421                                                 if (G.obedit->type == OB_MESH) {
2422                                                         mergemenu();
2423                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2424                                                 }
2425                                                 else if (G.obedit->type == OB_ARMATURE) {
2426                                                         merge_armature();
2427                                                 }
2428                                         }
2429                                         else if ((G.qual==0) || (G.qual==LR_CTRLKEY)) {
2430                                                 mirrormenu();
2431                                         }
2432                                         else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2433                                                 if(G.obedit->type==OB_MESH) select_non_manifold();
2434                                         }
2435                                 }
2436                                 else if(G.qual & LR_CTRLKEY) {
2437                                         mirrormenu();
2438                                 }
2439                                 else if(G.qual==0 || G.qual==LR_SHIFTKEY) {
2440                                         if(ob && (ob->flag & OB_POSEMODE))
2441                                                 pose_movetolayer();
2442                                         else
2443                                                 movetolayer();
2444                                 }
2445                                 break;
2446                         case NKEY:
2447                                 if((G.qual==0)) {
2448                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
2449                                         allqueue(REDRAWVIEW3D, 0);
2450                                 }
2451                                 else if(G.obedit) {
2452                                         switch (G.obedit->type){
2453                                         case OB_ARMATURE:
2454                                                 if(G.qual==LR_CTRLKEY) {
2455                                                         pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
2456                                                         if (pupval > 0) {
2457                                                                 auto_align_armature(pupval - 1);
2458                                                                 allqueue(REDRAWVIEW3D, 0);
2459                                                         }
2460                                                 }
2461                                                 break;
2462                                         case OB_MESH: 
2463                                                 if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2464                                                         if(okee("Recalculate normals inside")) {
2465                                                                 righthandfaces(2);
2466                                                                 allqueue(REDRAWVIEW3D, 0);
2467                                                                 BIF_undo_push("Recalculate normals inside");
2468                                                         }
2469                                                 }
2470                                                 else if(G.qual==LR_CTRLKEY){
2471                                                         if(okee("Recalculate normals outside")) {
2472                                                                 righthandfaces(1);
2473                                                                 allqueue(REDRAWVIEW3D, 0);
2474                                                                 BIF_undo_push("Recalculate normals outside");
2475                                                         }
2476                                                 }
2477                                                 break;
2478                                         }
2479                                 }
2480                                 
2481                                 break;
2482                         case OKEY:
2483                                 if (G.obedit || G.f&G_PARTICLEEDIT) {
2484                                         if (G.qual==LR_SHIFTKEY) {
2485                                                 G.scene->prop_mode = (G.scene->prop_mode+1)%7;
2486                                                 allqueue(REDRAWHEADERS, 0);
2487                                         }
2488                                         else if((G.qual==LR_ALTKEY)) {
2489                                                 if(G.scene->proportional==2) G.scene->proportional= 1;
2490                                                 else G.scene->proportional= 2;
2491                                                 allqueue(REDRAWHEADERS, 0);
2492                                         }
2493                                         else if((G.qual==0)) {
2494                                                 G.scene->proportional= !G.scene->proportional;
2495                                                 allqueue(REDRAWHEADERS, 0);
2496                                         }
2497                                 }
2498                                 else if((G.qual==LR_SHIFTKEY || G.qual==(LR_ALTKEY|LR_SHIFTKEY))) {
2499                                         flip_subdivison(-1);
2500                                 }
2501                                 else if(G.qual==LR_ALTKEY) {
2502                                         if(okee("Clear origin")) {
2503                                                 clear_object('o');
2504                                         }
2505                                 }
2506                                 break;
2507
2508                         case PKEY:
2509                                 if(G.obedit) {
2510                                         if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2511                                                 if(G.obedit->type==OB_ARMATURE)
2512                                                         make_bone_parent();
2513                                                 else
2514                                                         make_parent();
2515                                         }
2516                                         
2517                                         else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
2518                                                 clear_bone_parent();
2519                                         else if((G.qual==0) && (G.obedit->type==OB_ARMATURE)) 
2520                                                 armature_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2521                                         else if((G.qual==(LR_CTRLKEY|LR_ALTKEY)) && (G.obedit->type==OB_ARMATURE))
2522                                                 separate_armature();
2523                                         else if((G.qual==0) && G.obedit->type==OB_MESH)
2524                                                 separatemenu();
2525                                         else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
2526                                                 separate_nurb();
2527                                         else if (G.qual==LR_SHIFTKEY) {
2528                                                 initTransform(TFM_PUSHPULL, CTX_NONE);
2529                                                 Transform();
2530                                         }
2531                                 }
2532                                 else if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
2533                                         make_parent();
2534                                 else if(G.qual==LR_SHIFTKEY) {
2535                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
2536                                         doredraw= 1;
2537                                 }
2538                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) {
2539                                         initTransform(TFM_PUSHPULL, CTX_NONE);
2540                                         Transform();
2541                                 }
2542                                 else if(G.qual==LR_ALTKEY)
2543                                         clear_parent();
2544                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
2545                                         make_proxy();
2546                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
2547                         start_RBSimulation();
2548                                 }
2549                                 else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE))
2550                                         pose_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2551                                 else if((G.qual==0)) {
2552                         start_game();
2553                                 }
2554                                 break;                          
2555                         case RKEY:
2556                                 if((G.obedit==0) && G.qual==LR_ALTKEY) {
2557                                         if(okee("Clear rotation")) {
2558                                                 clear_object('r');
2559                                         }
2560                                 } 
2561                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2562                                         v3d->twtype= V3D_MANIP_ROTATE;
2563                                         doredraw= 1;
2564                                 }
2565                                 else if (G.obedit) {
2566                                         if((G.qual==LR_SHIFTKEY)) {
2567                                                 if ELEM(G.obedit->type,  OB_CURVE, OB_SURF)                                     
2568                                                         selectrow_nurb();
2569                                         }
2570                                         else if(G.qual==LR_CTRLKEY) {
2571                                                 if (G.obedit->type==OB_MESH) {
2572                                                         CutEdgeloop(1);
2573                                                         BIF_undo_push("Cut Edgeloop");
2574                                                 }
2575                                                 else if (G.obedit->type==OB_ARMATURE) {
2576                                                         initTransform(TFM_BONE_ROLL, CTX_NONE);
2577                                                         Transform();
2578                                                 }
2579                                         }
2580                                         else if((G.qual==0)) {
2581                                                 initTransform(TFM_ROTATION, CTX_NONE);
2582                                                 Transform();
2583                                         }
2584                                 }
2585                                 else if((G.qual==0)) {
2586                                         initTransform(TFM_ROTATION, CTX_NONE);
2587                                         Transform();
2588                                 }
2589                                 break;
2590                         case SKEY:
2591                                 if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2592                                         v3d->twtype= V3D_MANIP_SCALE;
2593                                         doredraw= 1;
2594                                 }
2595                                 else if(G.obedit) {
2596                                         
2597                                         if(G.qual==LR_ALTKEY) {
2598                                                 if(G.obedit->type==OB_ARMATURE) {
2599                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2600                                                 }
2601                                                 else if (G.obedit->type==OB_CURVE) {
2602                                                         initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
2603                                                 } else {
2604                                                         initTransform(TFM_SHRINKFATTEN, CTX_NONE);
2605                                                 }
2606                                                 Transform();
2607                                         }
2608                                         else if(G.qual==LR_CTRLKEY) {
2609                                                 initTransform(TFM_SHEAR, CTX_NONE);
2610                                                 Transform();
2611                                         }
2612                                         else if(G.qual==LR_SHIFTKEY)
2613                                                 snapmenu();
2614                                         else if(G.qual==0) {
2615                                                 if(G.obedit->type==OB_ARMATURE) {
2616                                                         bArmature *arm= G.obedit->data;
2617                                                         if(arm->drawtype==ARM_ENVELOPE)
2618                                                                 initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
2619                                                         else
2620                                                                 initTransform(TFM_RESIZE, CTX_NONE);
2621                                                 }
2622                                                 else
2623                                                         initTransform(TFM_RESIZE, CTX_NONE);
2624                                                 Transform();
2625                                         }
2626                                         else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
2627                                                 initTransform(TFM_TOSPHERE, CTX_NONE);
2628                                                 Transform();
2629                                         }
2630                                         if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2631                                                 if(G.obedit->type==OB_MESH) select_sharp_edges();
2632                                         }
2633                                 }
2634                                 else if(G.qual==LR_ALTKEY) {
2635                                         if(G.f & G_WEIGHTPAINT)
2636                                                 ob= ob->parent;
2637                                         if(ob && (ob->flag & OB_POSEMODE)) {
2638                                                 bArmature *arm= ob->data;
2639                                                 if( arm->drawtype==ARM_ENVELOPE) {
2640                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2641                                                         Transform();
2642                                                         break;
2643                                                 }
2644                                         }
2645                                         
2646                                         if(okee("Clear scale")) {
2647                                                 clear_object('s');
2648                                         }
2649                                 }
2650                                 else if(G.qual==LR_SHIFTKEY) {
2651                                         snapmenu();
2652                                 }
2653                                 else if((G.qual==0)) {
2654                                         initTransform(TFM_RESIZE, CTX_NONE);
2655                                         Transform();
2656                                 }
2657                                 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2658                                         initTransform(TFM_TOSPHERE, CTX_NONE);
2659                                         Transform();
2660                                 }
2661                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)) {
2662                                         initTransform(TFM_SHEAR, CTX_NONE);
2663                                         Transform();
2664                                 }
2665                                 break;
2666                         case TKEY:
2667                                 if(G.qual == LR_SHIFTKEY) { /* toggle texture in solid draw mode */
2668                                         G.vd->flag2 ^= V3D_SOLID_TEX;
2669                                         allqueue(REDRAWVIEW3D, 0);
2670                                 } else if(G.obedit){
2671                                         if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
2672                                                 convert_to_triface(G.qual & LR_SHIFTKEY);
2673                                                 allqueue(REDRAWVIEW3D, 0);
2674                                                 if (EM_texFaceCheck())
2675                                                         allqueue(REDRAWIMAGE, 0);
2676                                                 
2677                                                 countall();
2678                                                 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2679                                         }
2680                                         if (G.obedit->type==OB_CURVE) {
2681                                                 if (G.qual==LR_ALTKEY) {
2682                                                         clear_tilt();
2683                                                 }
2684                                                 else if (G.qual==0) {
2685                                                         initTransform(TFM_TILT, CTX_NONE);
2686                                                         Transform();
2687                                                 }
2688                                         }
2689                                 }
2690                                 else if(G.f & G_PARTICLEEDIT) {
2691                                         initTransform(TFM_BAKE_TIME, CTX_NONE);
2692                                         Transform();
2693                                 }
2694                                 else if(G.qual==LR_CTRLKEY) {
2695                                         if(ob && (ob->flag & OB_POSEMODE));
2696                                         else make_track();
2697                                 }
2698                                 else if(G.qual==LR_ALTKEY) {
2699                                         if(ob && (ob->flag & OB_POSEMODE));
2700                                         else clear_track();
2701                                 }
2702                                 else if((G.qual==0)){
2703                                         texspace_edit();
2704