4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
33 * - here initialize and free and handling SPACE data
43 #include "MEM_guardedalloc.h"
44 #include "MEM_CacheLimiterC-Api.h"
47 #include "BIF_language.h"
50 #include "IMB_imbuf_types.h"
51 #include "IMB_imbuf.h"
53 #include "BLI_blenlib.h"
54 #include "BLI_arithb.h"
55 #include "BLI_gsqueue.h"
56 #include "BLI_linklist.h"
58 #include "DNA_action_types.h"
59 #include "DNA_armature_types.h"
60 #include "DNA_curve_types.h"
61 #include "DNA_group_types.h" /* used for select_same_group */
62 #include "DNA_image_types.h"
63 #include "DNA_ipo_types.h"
64 #include "DNA_mesh_types.h"
65 #include "DNA_meshdata_types.h"
66 #include "DNA_modifier_types.h" /* used for select grouped hooks */
67 #include "DNA_object_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"
77 #include "BKE_blender.h"
78 #include "BKE_colortools.h"
79 #include "BKE_curve.h"
80 #include "BKE_depsgraph.h"
81 #include "BKE_displist.h"
82 #include "BKE_global.h"
83 #include "BKE_group.h"
88 #include "BKE_scene.h"
89 #include "BKE_utildefines.h"
90 #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
92 #include "BIF_spacetypes.h" /* first, nasty dependency with typedef */
94 #include "BIF_butspace.h"
95 #include "BIF_drawimage.h"
96 #include "BIF_drawseq.h"
97 #include "BIF_drawtext.h"
98 #include "BIF_drawscript.h"
99 #include "BIF_editarmature.h"
100 #include "BIF_editconstraint.h"
101 #include "BIF_editdeform.h"
102 #include "BIF_editfont.h"
103 #include "BIF_editgroup.h"
104 #include "BIF_editkey.h"
105 #include "BIF_editlattice.h"
106 #include "BIF_editmesh.h"
107 #include "BIF_editmode_undo.h"
108 #include "BIF_editnla.h"
109 #include "BIF_editoops.h"
110 #include "BIF_editseq.h"
111 #include "BIF_editsima.h"
112 #include "BIF_editsound.h"
113 #include "BIF_editview.h"
114 #include "BIF_filelist.h"
116 #include "BIF_imasel.h"
117 #include "BIF_interface.h"
118 #include "BIF_interface_icons.h"
119 #include "BIF_meshtools.h"
120 #include "BIF_mywindow.h"
121 #include "BIF_oops.h"
122 #include "BIF_poseobject.h"
123 #include "BIF_outliner.h"
124 #include "BIF_resources.h"
125 #include "BIF_retopo.h"
126 #include "BIF_screen.h"
127 #include "BIF_space.h"
128 #include "BIF_toets.h"
129 #include "BIF_toolbox.h"
130 #include "BIF_usiblender.h"
131 #include "BIF_previewrender.h"
133 #include "BSE_edit.h"
134 #include "BSE_view.h"
135 #include "BSE_editipo.h"
136 #include "BSE_drawipo.h"
137 #include "BSE_drawview.h"
138 #include "BSE_drawnla.h"
139 #include "BSE_filesel.h"
140 #include "BSE_headerbuttons.h"
141 #include "BSE_editnla_types.h"
142 #include "BSE_time.h"
144 #include "BDR_vpaint.h"
145 #include "BDR_editmball.h"
146 #include "BDR_editobject.h"
147 #include "BDR_editcurve.h"
148 #include "BDR_editface.h"
149 #include "BDR_drawmesh.h"
150 #include "BDR_drawobject.h"
151 #include "BDR_imagepaint.h"
152 #include "BDR_sculptmode.h"
153 #include "BDR_unwrapper.h"
155 #include "BLO_readfile.h" /* for BLO_blendhandle_close */
157 #include "PIL_time.h"
159 #include "BPY_extern.h"
161 #include "butspace.h"
162 #include "mydevice.h"
165 #include "multires.h"
167 #include "BIF_transform.h"
169 #include "BKE_depsgraph.h"
171 #include "BSE_trans_types.h"
173 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
175 /* maybe we need this defined somewhere else */
176 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
177 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);/*rcruiz*/
180 * When the mipmap setting changes, we want to redraw the view right
181 * away to reflect this setting.
183 void space_mipmap_button_function(int event);
185 void free_soundspace(SpaceSound *ssound);
187 /* *************************************** */
189 /* don't know yet how the handlers will evolve, for simplicity
190 i choose for an array with eventcodes, this saves in a file!
192 void add_blockhandler(ScrArea *sa, short eventcode, short val)
194 SpaceLink *sl= sa->spacedata.first;
197 /* find empty spot */
198 for(a=0; a<SPACE_MAXHANDLER; a+=2) {
199 if( sl->blockhandler[a]==eventcode ) {
200 sl->blockhandler[a+1]= val;
203 else if( sl->blockhandler[a]==0) {
204 sl->blockhandler[a]= eventcode;
205 sl->blockhandler[a+1]= val;
209 if(a==SPACE_MAXHANDLER) printf("error; max (4) blockhandlers reached!\n");
212 void rem_blockhandler(ScrArea *sa, short eventcode)
214 SpaceLink *sl= sa->spacedata.first;
217 for(a=0; a<SPACE_MAXHANDLER; a+=2) {
218 if( sl->blockhandler[a]==eventcode) {
219 sl->blockhandler[a]= 0;
221 /* specific free calls */
222 if(eventcode==IMAGE_HANDLER_PREVIEW)
223 image_preview_event(0);
229 void toggle_blockhandler(ScrArea *sa, short eventcode, short val)
231 SpaceLink *sl= sa->spacedata.first;
234 /* find if it exists */
235 for(a=0; a<SPACE_MAXHANDLER; a+=2) {
236 if( sl->blockhandler[a]==eventcode ) {
237 sl->blockhandler[a]= 0;
239 /* specific free calls */
240 if(eventcode==VIEW3D_HANDLER_PREVIEW)
241 BIF_view3d_previewrender_free(sa->spacedata.first);
242 else if(eventcode==IMAGE_HANDLER_PREVIEW)
243 image_preview_event(0);
249 add_blockhandler(sa, eventcode, val);
251 /* specific add new calls */
252 if(eventcode==IMAGE_HANDLER_PREVIEW)
253 image_preview_event(1);
259 /* ************* SPACE: VIEW3D ************* */
261 /* extern void drawview3dspace(ScrArea *sa, void *spacedata); BSE_drawview.h */
264 void copy_view3d_lock(short val)
269 /* from G.scene copy to the other views */
270 sc= G.main->screen.first;
273 if(sc->scene==G.scene) {
274 ScrArea *sa= sc->areabase.first;
276 SpaceLink *sl= sa->spacedata.first;
278 if(sl->spacetype==SPACE_OOPS && val==REDRAW) {
279 if(sa->win) scrarea_queue_winredraw(sa);
281 else if(sl->spacetype==SPACE_VIEW3D) {
282 View3D *vd= (View3D*) sl;
283 if(vd->scenelock && vd->localview==0) {
284 vd->lay= G.scene->lay;
285 vd->camera= G.scene->camera;
287 if(vd->camera==0 && vd->persp>1) vd->persp= 1;
289 if( (vd->lay & vd->layact) == 0) {
292 if(vd->lay & (1<<bit)) {
300 if(val==REDRAW && vd==sa->spacedata.first) {
301 if(sa->win) scrarea_queue_redraw(sa);
314 void handle_view3d_around()
318 if ((U.uiflag & USER_LOCKAROUND)==0) return;
320 /* copies from G.vd->around to other view3ds */
322 sc= G.main->screen.first;
325 if(sc->scene==G.scene) {
326 ScrArea *sa= sc->areabase.first;
328 SpaceLink *sl= sa->spacedata.first;
330 if(sl->spacetype==SPACE_VIEW3D) {
331 View3D *vd= (View3D*) sl;
333 vd->around= G.vd->around;
334 if (G.vd->flag & V3D_ALIGN)
335 vd->flag |= V3D_ALIGN;
337 vd->flag &= ~V3D_ALIGN;
338 scrarea_queue_headredraw(sa);
350 void handle_view3d_lock()
352 if (G.vd != NULL && curarea != NULL ) {
353 if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) {
356 G.scene->lay= G.vd->lay;
357 G.scene->camera= G.vd->camera;
359 copy_view3d_lock(REDRAW);
364 void space_set_commmandline_options(void) {
365 SYS_SystemHandle syshandle;
368 if ( (syshandle = SYS_GetSystem()) ) {
369 /* User defined settings */
370 a= (U.gameflags & USER_VERTEX_ARRAYS);
371 SYS_WriteCommandLineInt(syshandle, "vertexarrays", a);
373 a= (U.gameflags & USER_DISABLE_SOUND);
374 SYS_WriteCommandLineInt(syshandle, "noaudio", a);
376 a= (U.gameflags & USER_DISABLE_MIPMAP);
378 SYS_WriteCommandLineInt(syshandle, "nomipmap", a);
380 /* File specific settings: */
381 /* Only test the first one. These two are switched
383 a= (G.fileflags & G_FILE_SHOW_FRAMERATE);
384 SYS_WriteCommandLineInt(syshandle, "show_framerate", a);
385 SYS_WriteCommandLineInt(syshandle, "show_profile", a);
387 /* When in wireframe mode, always draw debug props. */
389 a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS)
390 || (G.vd->drawtype == OB_WIRE)
391 || (G.vd->drawtype == OB_SOLID) );
392 SYS_WriteCommandLineInt(syshandle, "show_properties", a);
395 a= (G.fileflags & G_FILE_SHOW_PHYSICS);
396 SYS_WriteCommandLineInt(syshandle, "show_physics", a);
398 a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES);
399 SYS_WriteCommandLineInt(syshandle, "fixedtime", a);
401 a= (G.fileflags & G_FILE_GAME_TO_IPO);
402 SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
404 a=(G.fileflags & G_FILE_GAME_MAT);
405 SYS_WriteCommandLineInt(syshandle, "blender_material", a);
406 a=(G.fileflags & G_FILE_DIAPLAY_LISTS);
407 SYS_WriteCommandLineInt(syshandle, "displaylists", a);
415 * These two routines imported from the gameengine,
416 * I suspect a lot of the resetting stuff is cruft
417 * and can be removed, but it should be checked.
419 static void SaveState(void)
421 glPushAttrib(GL_ALL_ATTRIB_BITS);
426 if(G.f & G_TEXTUREPAINT)
427 texpaint_enable_mipmap();
429 if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA)
430 error("no (correct) camera");
435 static void RestoreState(void)
437 if(G.f & G_TEXTUREPAINT)
438 texpaint_disable_mipmap();
440 curarea->win_swap = 0;
441 curarea->head_swap=0;
442 allqueue(REDRAWVIEW3D, 1);
443 allqueue(REDRAWBUTSALL, 0);
450 static LinkNode *save_and_reset_all_scene_cfra(void)
452 LinkNode *storelist= NULL;
455 for (sc= G.main->scene.first; sc; sc= sc->id.next) {
456 BLI_linklist_prepend(&storelist, (void*) (long) sc->r.cfra);
458 /* why is this reset to 1 ?*/
464 BLI_linklist_reverse(&storelist);
469 static void restore_all_scene_cfra(LinkNode *storelist) {
470 LinkNode *sc_store= storelist;
473 for (sc= G.main->scene.first; sc; sc= sc->id.next) {
474 int stored_cfra= (long) sc_store->link;
476 sc->r.cfra= stored_cfra;
479 sc_store= sc_store->next;
482 BLI_linklist_free(storelist, NULL);
486 void start_game(void)
490 Scene *sc, *startscene = G.scene;
491 LinkNode *scene_cfra_store;
493 /* XXX, silly code - the game engine can
494 * access any scene through logic, so we try
495 * to make sure each scene has a valid camera,
496 * just in case the game engine tries to use it.
498 * Better would be to make a better routine
499 * in the game engine for finding the camera.
501 * Note: yes, this is all very badly hacked! (ton)
503 for (sc= G.main->scene.first; sc; sc= sc->id.next) {
507 for (base= sc->base.first; base; base= base->next)
508 if (base->object->type==OB_CAMERA)
511 sc->camera= base?base->object:NULL;
515 /* these two lines make sure front and backbuffer are equal. for swapbuffers */
517 screen_swapbuffers();
519 /* can start from header */
520 mywinset(curarea->win);
522 scene_cfra_store= save_and_reset_all_scene_cfra();
525 /* game engine will do its own sounds. */
526 sound_stop_all_sounds();
529 /* Before jumping into Ketsji, we configure some settings. */
530 space_set_commmandline_options();
533 StartKetsjiShell(curarea, startscene->id.name+2, G.main,G.sipo, 1);
536 /* Restart BPY - unload the game engine modules. */
538 BPY_start_python(0, NULL); /* argc, argv stored there already */
539 BPY_post_start_python(); /* userpref path and menus init */
541 restore_all_scene_cfra(scene_cfra_store);
542 set_scene_bg(startscene);
543 scene_update_for_newframe(G.scene, G.scene->lay);
545 if (G.flags & G_FILE_AUTOPLAY)
548 /* groups could have changed ipo */
549 allqueue(REDRAWNLA, 0);
550 allqueue(REDRAWACTION, 0);
551 allspace(REMAKEIPO, 0);
552 allqueue(REDRAWIPO, 0);
555 notice("Game engine is disabled in this release!");
559 void start_RBSimulation(void)
563 Scene *sc, *startscene = G.scene;
564 LinkNode *scene_cfra_store;
566 /* XXX, silly code - the game engine can
567 * access any scene through logic, so we try
568 * to make sure each scene has a valid camera,
569 * just in case the game engine tries to use it.
571 * Better would be to make a better routine
572 * in the game engine for finding the camera.
574 * Note: yes, this is all very badly hacked! (ton)
576 for (sc= G.main->scene.first; sc; sc= sc->id.next) {
580 for (base= sc->base.first; base; base= base->next)
581 if (base->object->type==OB_CAMERA)
584 sc->camera= base?base->object:NULL;
588 /* these two lines make sure front and backbuffer are equal. for swapbuffers */
590 screen_swapbuffers();
592 /* can start from header */
593 mywinset(curarea->win);
595 scene_cfra_store= save_and_reset_all_scene_cfra();
598 /* game engine will do its own sounds. */
599 sound_stop_all_sounds();
602 /* Before jumping into Ketsji, we configure some settings. */
603 space_set_commmandline_options();
606 StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
608 /* Restart BPY - unload the game engine modules. */
610 BPY_start_python(0, NULL); /* argc, argv stored there already */
611 BPY_post_start_python(); /* userpref path and menus init */
613 restore_all_scene_cfra(scene_cfra_store);
614 set_scene_bg(startscene);
615 scene_update_for_newframe(G.scene, G.scene->lay);
617 if (G.flags & G_FILE_AUTOPLAY)
620 /* groups could have changed ipo */
621 allqueue(REDRAWNLA, 0);
622 allqueue(REDRAWACTION, 0);
623 allspace(REMAKEIPO, 0);
624 allqueue(REDRAWIPO, 0);
627 notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!");
631 static void changeview3dspace(ScrArea *sa, void *spacedata)
633 setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */
636 /* Callable from editmode and faceselect mode from the
637 * moment, would be nice (and is easy) to generalize
640 static void align_view_to_selected(View3D *v3d)
642 int nr= pupmenu("Align View (Ctrl flips)%t|To Selected (top)%x3|To Selected (front)%x2|To Selected (side)%x1");
646 /* opposite axis in case ctrl is pressed */
647 if(G.qual==LR_CTRLKEY) axis= -axis;
649 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
650 editmesh_align_view_to_selected(v3d, axis);
651 addqueue(v3d->area->win, REDRAW, 1);
652 } else if (FACESEL_PAINT_TEST) {
653 Object *obact= OBACT;
654 if (obact && obact->type==OB_MESH) {
655 Mesh *me= obact->data;
656 faceselect_align_view_to_selected(v3d, me, axis);
657 addqueue(v3d->area->win, REDRAW, 1);
664 static short select_children(Object *ob, int recursive)
669 for (base= FIRSTBASE; base; base= base->next) {
670 if (ob == base->object->parent) {
671 if (BASE_SELECTABLE(base) && !(base->flag & SELECT)) {
672 base->flag |= SELECT;
673 base->object->flag |= SELECT;
678 changed |= select_children(base->object, 1);
684 static short select_parent(void) /* Makes parent active and de-selected OBACT */
687 Base *base, *startbase, *basact=NULL, *oldbasact;
689 if (!(OBACT) || !(OBACT->parent)) return 0;
690 BASACT->flag &= (~SELECT);
691 BASACT->object->flag &= (~SELECT);
692 startbase= FIRSTBASE;
693 if(BASACT && BASACT->next) startbase= BASACT->next;
696 if(base->object==BASACT->object->parent) { basact=base; break; }
698 if(base==NULL) base= FIRSTBASE;
699 if(base==startbase) break;
701 /* can be NULL if parent in other scene */
702 if(basact && BASE_SELECTABLE(basact)) {
705 basact->flag |= SELECT;
707 basact->object->flag= basact->flag;
709 set_active_base(basact);
716 #define GROUP_MENU_MAX 24
717 static short select_same_group(Object *ob) /* Select objects in the same group as the active */
721 Group *group, *ob_groups[GROUP_MENU_MAX];
722 char str[10 + (24*GROUP_MENU_MAX)];
724 int group_count=0, menu, i;
729 for ( group=G.main->group.first;
730 group && group_count < GROUP_MENU_MAX;
733 if (object_in_group (ob, group)) {
734 ob_groups[group_count] = group;
742 else if (group_count == 1) {
743 group = ob_groups[0];
744 for (base= FIRSTBASE; base; base= base->next) {
745 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && object_in_group(base->object, group)) {
746 base->flag |= SELECT;
747 base->object->flag |= SELECT;
754 /* build the menu. */
755 p += sprintf(str, "Groups%%t");
756 for (i=0; i<group_count; i++) {
757 group = ob_groups[i];
758 p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
761 menu = pupmenu (str);
765 group = ob_groups[menu];
766 for (base= FIRSTBASE; base; base= base->next) {
767 if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
768 base->flag |= SELECT;
769 base->object->flag |= SELECT;
776 static short select_object_hooks(Object *ob)
781 HookModifierData *hmd;
786 for (md = ob->modifiers.first; md; md=md->next) {
787 if (md->type==eModifierType_Hook) {
788 hmd= (HookModifierData*) md;
789 if (hmd->object && !(hmd->object->flag & SELECT)) {
790 base= object_in_scene(hmd->object, G.scene);
791 if (base && BASE_SELECTABLE(base)) {
792 base->flag |= SELECT;
793 base->object->flag |= SELECT;
802 /* Select objects woth the same parent as the active (siblings),
803 * parent can be NULL also */
804 static short select_same_parent(Object *ob)
811 for (base= FIRSTBASE; base; base= base->next) {
812 if (BASE_SELECTABLE(base) && (base->object->parent==ob->parent) && !(base->flag & SELECT)) {
813 base->flag |= SELECT;
814 base->object->flag |= SELECT;
821 static short select_same_type(Object *ob)
828 for (base= FIRSTBASE; base; base= base->next) {
829 if (BASE_SELECTABLE(base) && (base->object->type == ob->type) && !(base->flag & SELECT)) {
830 base->flag |= SELECT;
831 base->object->flag |= SELECT;
838 static short select_same_layer(Object *ob)
841 Base *base = FIRSTBASE;
847 if (BASE_SELECTABLE(base) && (base->lay & ob->lay) && !(base->flag & SELECT)) {
848 base->flag |= SELECT;
849 base->object->flag |= SELECT;
857 void select_object_grouped(short nr)
860 if(nr==1) changed = select_children(OBACT, 1);
861 else if(nr==2) changed = select_children(OBACT, 0);
862 else if(nr==3) changed = select_parent();
863 else if(nr==4) changed = select_same_parent(OBACT);
864 else if(nr==5) changed = select_same_type(OBACT);
865 else if(nr==6) changed = select_same_layer(OBACT);
866 else if(nr==7) changed = select_same_group(OBACT);
867 else if(nr==8) changed = select_object_hooks(OBACT);
871 allqueue(REDRAWVIEW3D, 0);
872 allqueue(REDRAWBUTSOBJECT, 0);
873 allspace(REMAKEIPO, 0);
874 allqueue(REDRAWIPO, 0);
875 BIF_undo_push("Select Grouped");
879 static void select_object_grouped_menu(void)
884 /* make menu string */
886 str= MEM_mallocN(512, "groupmenu");
887 strcpy(str, "Select Grouped%t|Children%x1|"
888 "Immediate Children%x2|Parent%x3|"
889 "Siblings (Shared Parent)%x4|"
890 "Objects of Same Type%x5|"
891 "Objects on Shared Layers%x6|"
892 "Objects in Same Group%x7|"
900 select_object_grouped(nr);
907 error("This data does not support joining in editmode");
911 error("Can't join unless there is an active object");
915 if(ob->type == OB_MESH) {
916 if(okee("Join selected meshes")==0) return;
918 } else if(ob->type == OB_CURVE) {
919 if(okee("Join selected curves")==0) return;
920 join_curve(OB_CURVE);
921 } else if(ob->type == OB_SURF) {
922 if(okee("Join selected NURBS")==0) return;
924 } else if(ob->type == OB_ARMATURE) {
925 /* Make sure the user wants to continue*/
926 if(okee("Join selected armatures")==0) return;
929 error("This object type doesn't support joining");
933 static unsigned short convert_for_nonumpad(unsigned short event)
935 if (event>=ZEROKEY && event<=NINEKEY) {
936 return event - ZEROKEY + PAD0;
937 } else if (event==MINUSKEY) {
939 } else if (event==EQUALKEY) {
941 } else if (event==BACKSLASHKEY) {
948 /* *************** */
950 void BIF_undo_push(char *str)
953 if (U.undosteps == 0) return;
955 if(G.obedit->type==OB_MESH)
957 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
958 undo_push_curve(str);
959 else if (G.obedit->type==OB_FONT)
961 else if (G.obedit->type==OB_MBALL)
962 undo_push_mball(str);
963 else if (G.obedit->type==OB_LATTICE)
964 undo_push_lattice(str);
965 else if (G.obedit->type==OB_ARMATURE)
966 undo_push_armature(str);
969 if(U.uiflag & USER_GLOBALUNDO)
977 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
978 undo_editmode_step(1);
981 if(G.f & G_TEXTUREPAINT)
983 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
986 /* now also in faceselect mode */
987 if(U.uiflag & USER_GLOBALUNDO) {
989 sound_initialize_sounds();
998 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
999 undo_editmode_step(-1);
1002 if(G.f & G_TEXTUREPAINT)
1004 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1007 /* includes faceselect now */
1008 if(U.uiflag & USER_GLOBALUNDO) {
1010 sound_initialize_sounds();
1016 void BIF_undo_menu(void)
1019 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1020 undo_editmode_menu();
1021 allqueue(REDRAWALL, 0);
1024 if(U.uiflag & USER_GLOBALUNDO) {
1025 char *menu= BKE_undo_menu_string();
1027 short event= pupmenu_col(menu, 20);
1029 if(event>0) BKE_undo_number(event);
1035 /* *************** */
1037 void handle_view_middlemouse() {
1038 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1039 if(U.flag & USER_VIEWMOVE) {
1040 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1042 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1044 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1048 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1050 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1052 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1057 void handle_view_wheelup()
1059 /* Regular: Zoom in */
1060 /* Shift: Scroll up */
1061 /* Ctrl: Scroll right */
1062 /* Alt-Shift: Rotate up */
1063 /* Alt-Ctrl: Rotate right */
1065 if( G.qual & LR_SHIFTKEY ) {
1066 if( G.qual & LR_ALTKEY ) {
1067 G.qual &= ~LR_SHIFTKEY;
1069 G.qual |= LR_SHIFTKEY;
1073 } else if( G.qual & LR_CTRLKEY ) {
1074 if( G.qual & LR_ALTKEY ) {
1075 G.qual &= ~LR_CTRLKEY;
1077 G.qual |= LR_CTRLKEY;
1081 } else if(U.uiflag & USER_WHEELZOOMDIR)
1082 persptoetsen(PADMINUS);
1084 persptoetsen(PADPLUSKEY);
1087 void handle_view_wheeldown()
1089 /* Regular: Zoom out */
1090 /* Shift: Scroll down */
1091 /* Ctrl: Scroll left */
1092 /* Alt-Shift: Rotate down */
1093 /* Alt-Ctrl: Rotate left */
1095 if( G.qual & LR_SHIFTKEY ) {
1096 if( G.qual & LR_ALTKEY ) {
1097 G.qual &= ~LR_SHIFTKEY;
1099 G.qual |= LR_SHIFTKEY;
1103 } else if( G.qual & LR_CTRLKEY ) {
1104 if( G.qual & LR_ALTKEY ) {
1105 G.qual &= ~LR_CTRLKEY;
1107 G.qual |= LR_CTRLKEY;
1111 } else if(U.uiflag & USER_WHEELZOOMDIR)
1112 persptoetsen(PADPLUSKEY);
1114 persptoetsen(PADMINUS);
1117 int mouse_in_header(ScrArea *sa)
1120 getmouseco_sc(mouse);
1121 return mouse[0] >= sa->headrct.xmin &&
1122 mouse[0] <= sa->headrct.xmax &&
1123 mouse[1] >= sa->headrct.ymin &&
1124 mouse[1] <= sa->headrct.ymax;
1127 static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
1129 View3D *v3d= sa->spacedata.first;
1130 Object *ob= OBACT; /* do not change! */
1132 int doredraw= 0, pupval;
1133 unsigned short event= evt->event;
1134 short val= evt->val;
1135 char ascii= evt->ascii;
1137 if(curarea->win==0) return; /* when it comes from sa->headqread() */
1141 if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
1143 if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
1145 /* we consider manipulator a button, defaulting to leftmouse */
1146 if(event==LEFTMOUSE) if(BIF_do_manipulator(sa)) return;
1148 /* swap mouse buttons based on user preference */
1149 if (U.flag & USER_LMOUSESELECT) {
1150 /* only swap mouse button for selection, in modes where it is relevant.
1151 * painting/sculpting stays on LEFTMOUSE */
1152 if ( !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) ||
1153 (G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT)) ||
1156 if (event==LEFTMOUSE) event = RIGHTMOUSE;
1157 else if (event==RIGHTMOUSE) event = LEFTMOUSE;
1161 if(!mouse_in_header(sa)) {
1162 if(!G.obedit && (G.f & G_SCULPTMODE)) {
1163 SculptSession *ss= sculpt_session();
1164 if(ss && ss->propset) {
1165 sculptmode_propset(event);
1168 else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
1169 if(!bwin_qtest(sa->win))
1170 allqueue(REDRAWVIEW3D, 0);
1174 /* Handle retopo painting */
1175 if(retopo_mesh_paint_check()) {
1176 if(!retopo_paint(event))
1181 /* run any view3d event handler script links */
1182 if (event && sa->scriptlink.totscript)
1183 if (BPY_do_spacehandlers(sa, event, SPACEHANDLER_VIEW3D_EVENT))
1184 return; /* return if event was processed (swallowed) by handler(s) */
1187 if((G.obedit) && G.obedit->type==OB_FONT) {
1194 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1195 if(U.flag & USER_VIEWMOVE) {
1196 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1198 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1200 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1204 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1206 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1214 /* Regular: Zoom in */
1215 /* Shift: Scroll up */
1216 /* Ctrl: Scroll right */
1217 /* Alt-Shift: Rotate up */
1218 /* Alt-Ctrl: Rotate right */
1220 if( G.qual & LR_SHIFTKEY ) {
1221 if( G.qual & LR_ALTKEY ) {
1222 G.qual &= ~LR_SHIFTKEY;
1224 G.qual |= LR_SHIFTKEY;
1228 } else if( G.qual & LR_CTRLKEY ) {
1229 if( G.qual & LR_ALTKEY ) {
1230 G.qual &= ~LR_CTRLKEY;
1232 G.qual |= LR_CTRLKEY;
1236 } else if(U.uiflag & USER_WHEELZOOMDIR)
1237 persptoetsen(PADMINUS);
1239 persptoetsen(PADPLUSKEY);
1244 case WHEELDOWNMOUSE:
1245 /* Regular: Zoom out */
1246 /* Shift: Scroll down */
1247 /* Ctrl: Scroll left */
1248 /* Alt-Shift: Rotate down */
1249 /* Alt-Ctrl: Rotate left */
1251 if( G.qual & LR_SHIFTKEY ) {
1252 if( G.qual & LR_ALTKEY ) {
1253 G.qual &= ~LR_SHIFTKEY;
1255 G.qual |= LR_SHIFTKEY;
1259 } else if( G.qual & LR_CTRLKEY ) {
1260 if( G.qual & LR_ALTKEY ) {
1261 G.qual &= ~LR_CTRLKEY;
1263 G.qual |= LR_CTRLKEY;
1267 } else if(U.uiflag & USER_WHEELZOOMDIR)
1268 persptoetsen(PADPLUSKEY);
1270 persptoetsen(PADMINUS);
1276 if(G.qual==LR_ALTKEY) {
1281 do_textedit(event, val, ascii);
1285 if(G.qual==LR_ALTKEY) {
1290 do_textedit(event, val, ascii);
1293 case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1294 case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1296 persptoetsen(event);
1301 do_textedit(event, val, ascii);
1305 else if(!G.obedit && (G.f & G_SCULPTMODE)) {
1306 SculptData *sd= sculpt_data();
1307 SculptSession *ss= sculpt_session();
1308 BrushData *br= sculptmode_brush();
1309 Mesh *me= get_mesh(OBACT);
1310 char update_prop= 0;
1312 if(U.flag & USER_NONUMPAD) {
1313 event= convert_for_nonumpad(event);
1318 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1320 else if(!(ss && ss->propset))
1325 handle_view_middlemouse();
1328 handle_view_wheelup();
1331 case WHEELDOWNMOUSE:
1332 handle_view_wheeldown();
1336 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1340 if(G.qual==LR_SHIFTKEY) {
1342 curs= give_cursor();
1343 curs[0]=curs[1]=curs[2]= 0.0;
1344 allqueue(REDRAWVIEW3D, 0);
1346 else if(G.qual==0) {
1348 /* center the camera offset */
1349 G.vd->camdx= G.vd->camdy= 0.0;
1351 /*non camera center*/
1353 curs= give_cursor();
1354 new_ofs[0]= -curs[0];
1355 new_ofs[1]= -curs[1];
1356 new_ofs[2]= -curs[2];
1357 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1362 case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1363 case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1367 persptoetsen(event);
1371 if(G.qual==LR_ALTKEY)
1372 view3d_edit_clipping(v3d);
1373 else if(G.qual==LR_SHIFTKEY) {
1375 set_render_border();
1377 view3d_border_zoom();
1382 if(G.vd->localview) {
1384 endlocalview(curarea);
1390 allqueue(REDRAWVIEW3D, 1);
1393 /* Brush properties */
1395 br->airbrush= !br->airbrush;
1396 update_prop= 1; break;
1399 sculptmode_propset_init(PropsetSize);
1400 if(G.qual==LR_SHIFTKEY)
1401 sculptmode_propset_init(PropsetStrength);
1402 if(G.qual==LR_CTRLKEY)
1403 sculptmode_propset_init(PropsetTexRot);
1406 br->dir= br->dir==1 ? 2 : 1;
1407 update_prop= 1; break;
1410 sd->brush_type= DRAW_BRUSH;
1411 update_prop= 1; break;
1413 sd->brush_type= SMOOTH_BRUSH;
1414 update_prop= 1; break;
1416 sd->brush_type= PINCH_BRUSH;
1417 update_prop= 1; break;
1419 sd->brush_type= INFLATE_BRUSH;
1420 update_prop= 1; break;
1422 sd->brush_type= GRAB_BRUSH;
1423 update_prop= 1; break;
1425 sd->brush_type= LAYER_BRUSH;
1426 update_prop= 1; break;
1428 sd->brush_type= FLATTEN_BRUSH;
1429 update_prop= 1; break;
1433 update_prop= 1; break;
1436 update_prop= 1; break;
1439 update_prop= 1; break;
1443 toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1444 allqueue(REDRAWVIEW3D, 0);
1450 me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
1451 multires_set_level(ob, ob->data, 0);
1456 me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
1457 multires_set_level(ob, ob->data, 0);
1460 /* Partial Visibility */
1462 if(G.qual==LR_ALTKEY) {
1464 sculptmode_pmv_off(get_mesh(ob));
1465 BIF_undo_push("Partial mesh hide");
1466 allqueue(REDRAWVIEW3D,0);
1472 do_layer_buttons(0); break;
1474 do_layer_buttons(1); break;
1476 do_layer_buttons(2); break;
1478 do_layer_buttons(3); break;
1480 do_layer_buttons(4); break;
1482 do_layer_buttons(5); break;
1484 do_layer_buttons(6); break;
1486 do_layer_buttons(7); break;
1488 do_layer_buttons(8); break;
1490 do_layer_buttons(9); break;
1492 do_layer_buttons(10); break;
1494 do_layer_buttons(11); break;
1495 case ACCENTGRAVEKEY:
1496 do_layer_buttons(-1); break;
1499 /* Redraw buttons window as well as view 3d (for floating panel) */
1501 allqueue(REDRAWVIEW3D, 0);
1502 allqueue(REDRAWBUTSEDIT, 0);
1506 if (U.flag & USER_NONUMPAD) {
1507 event= convert_for_nonumpad(event);
1512 /* Afterqueue events */
1517 BIF_view3d_previewrender(sa);
1521 /* Shift-Tabe handling (other cases are in toets) */
1522 if (G.qual == LR_SHIFTKEY)
1524 /* Snap toggle (only edit mesh right now) */
1525 if (G.obedit && G.obedit->type==OB_MESH)
1527 G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
1528 allqueue(REDRAWHEADERS, 0);
1533 /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
1534 * based on user preference USER_LMOUSESELECT
1537 if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) {
1540 else if (G.f & G_WEIGHTPAINT) {
1543 else if (G.f & G_VERTEXPAINT) {
1546 else if (G.f & G_TEXTUREPAINT) {
1547 imagepaint_paint(L_MOUSE, 1);
1551 handle_view_middlemouse();
1554 if((G.obedit) && (G.qual & LR_CTRLKEY)==0) {
1555 if(G.obedit->type==OB_MESH)
1557 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1559 else if(G.obedit->type==OB_MBALL)
1561 else if(G.obedit->type==OB_LATTICE)
1563 else if(G.obedit->type==OB_ARMATURE)
1566 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
1567 mouse_mesh(); /* loop select for 1 mousebutton dudes */
1568 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
1569 mouse_mesh(); /* loop select for 1 mousebutton dudes */
1570 else if(G.qual==LR_CTRLKEY)
1571 mouse_select(); /* also allow in editmode, for vertex parenting */
1572 else if(FACESEL_PAINT_TEST)
1574 else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
1577 mouse_select(); /* does poses too */
1580 handle_view_wheelup();
1583 case WHEELDOWNMOUSE:
1584 handle_view_wheeldown();
1589 if(G.qual==LR_CTRLKEY) {
1592 else do_layer_buttons(0);
1596 if(G.qual==LR_CTRLKEY) {
1599 else do_layer_buttons(1);
1603 if(G.qual==LR_CTRLKEY) {
1606 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1607 if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1608 select_faces_by_numverts(3);
1610 else do_layer_buttons(2);
1614 if(G.qual==LR_CTRLKEY) {
1617 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1618 if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1619 select_faces_by_numverts(4);
1621 else do_layer_buttons(3);
1625 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1626 if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1627 select_faces_by_numverts(5);
1629 else do_layer_buttons(4);
1633 do_layer_buttons(5); break;
1635 do_layer_buttons(6); break;
1637 do_layer_buttons(7); break;
1639 do_layer_buttons(8); break;
1641 do_layer_buttons(9); break;
1643 do_layer_buttons(10); break;
1645 do_layer_buttons(11); break;
1646 case ACCENTGRAVEKEY:
1647 do_layer_buttons(-1); break;
1650 if(G.qual == LR_CTRLKEY) {
1651 val= pupmenu("Manipulator%t|Enable/Disable|Translate|Rotate|Scale|Combo");
1653 if(val==1) v3d->twflag ^= V3D_USE_MANIPULATOR;
1655 if(val==2) v3d->twtype= V3D_MANIP_TRANSLATE;
1656 else if(val==3) v3d->twtype= V3D_MANIP_ROTATE;
1657 else if(val==4) v3d->twtype= V3D_MANIP_SCALE;
1658 else if(val==5) v3d->twtype= V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE|V3D_MANIP_SCALE;
1659 v3d->twflag |= V3D_USE_MANIPULATOR;
1664 else if(G.qual == LR_ALTKEY) {
1665 BIF_selectOrientation();
1672 if(G.qual & LR_CTRLKEY) apply_object(); /* also with shift! */
1673 else if((G.qual==LR_SHIFTKEY)) {
1678 if(G.obedit->type==OB_MESH)
1680 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1682 else if(G.obedit->type==OB_MBALL)
1683 deselectall_mball();
1684 else if(G.obedit->type==OB_LATTICE)
1686 else if(G.obedit->type==OB_ARMATURE)
1687 deselectall_armature(1, 1); /* 1 == toggle */
1689 else if (ob && (ob->flag & OB_POSEMODE)){
1690 deselectall_posearmature(ob, 1, 1);
1693 if(FACESEL_PAINT_TEST) deselectall_tface();
1695 /* by design, the center of the active object
1696 * (which need not necessarily by selected) will
1697 * still be drawn as if it were selected.
1705 if(G.qual==LR_ALTKEY)
1706 view3d_edit_clipping(v3d);
1707 else if(G.qual==LR_SHIFTKEY)
1710 set_render_border();
1712 view3d_border_zoom();
1714 else if(G.qual==LR_CTRLKEY) {
1715 if(okee("Bake all selected")) {
1716 extern void softbody_bake(Object *ob);
1717 extern void fluidsimBake(Object *ob);
1718 softbody_bake(NULL);
1719 /* also bake first domain of selected objects... */
1723 else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
1724 objects_bake_render_menu();
1729 if(G.qual==LR_CTRLKEY) {
1730 if(ob && (ob->flag & OB_POSEMODE))
1731 pose_copy_menu(); /* poseobject.c */
1735 else if(G.qual==LR_ALTKEY) {
1736 if(ob && (ob->flag & OB_POSEMODE))
1737 pose_clear_constraints(); /* poseobject.c */
1739 convertmenu(); /* editobject.c */
1741 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
1742 add_constraint(0); /* editconstraint.c, generic for objects and posemode */
1743 else if((G.qual==LR_SHIFTKEY)) {
1745 curs= give_cursor();
1746 curs[0]=curs[1]=curs[2]= 0.0;
1747 allqueue(REDRAWVIEW3D, 0);
1749 else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) {
1751 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1752 allqueue(REDRAWVIEW3D, 0);
1754 else if((G.qual==0)){
1756 /* center the camera offset */
1757 G.vd->camdx= G.vd->camdy= 0.0;
1759 /*non camera center*/
1761 curs= give_cursor();
1762 new_ofs[0]= -curs[0];
1763 new_ofs[1]= -curs[1];
1764 new_ofs[2]= -curs[2];
1765 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1767 scrarea_queue_winredraw(curarea);
1771 if((G.qual==LR_SHIFTKEY)) {
1772 duplicate_context_selected();
1774 else if(G.qual==LR_ALTKEY) {
1775 if(ob && (ob->flag & OB_POSEMODE))
1776 error ("Duplicate not possible in posemode.");
1777 else if((G.obedit==NULL))
1780 else if(G.qual==LR_CTRLKEY) {
1783 else if((G.qual==0)){
1784 pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
1786 G.vd->drawtype= pupval;
1795 if(G.obedit->type==OB_MESH)
1797 else if(G.obedit->type==OB_CURVE)
1799 else if(G.obedit->type==OB_SURF)
1801 else if(G.obedit->type==OB_ARMATURE)
1802 extrude_armature(0);
1805 else if (G.qual==LR_CTRLKEY) {
1806 if(G.obedit && G.obedit->type==OB_MESH)
1808 else if (FACESEL_PAINT_TEST)
1809 seam_mark_clear_tface(0);
1811 else if (G.qual==LR_SHIFTKEY) {
1812 if (G.obedit && G.obedit->type==OB_MESH &&
1813 !multires_level1_test()) {
1814 initTransform(TFM_CREASE, CTX_EDGE);
1817 else if (G.obedit && G.obedit->type==OB_ARMATURE) {
1818 extrude_armature(1);
1824 if(G.obedit->type==OB_MESH) {
1825 if(G.qual == LR_CTRLKEY)
1827 else if((G.qual==LR_SHIFTKEY))
1829 else if(G.qual==LR_ALTKEY)
1831 else if(G.qual & (LR_CTRLKEY|LR_SHIFTKEY))
1836 (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1837 select_linked_flat_faces();
1841 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb();
1843 else if(G.qual==LR_CTRLKEY)
1845 else if((G.qual==LR_SHIFTKEY)) {
1846 if(ob && (ob->flag & OB_POSEMODE))
1847 pose_activate_flipped_bone();
1848 else if(G.f & G_WEIGHTPAINT)
1849 pose_activate_flipped_bone();
1854 if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)){
1855 G.f ^= G_FACESELECT;
1856 allqueue(REDRAWVIEW3D, 1);
1862 if((G.qual == LR_CTRLKEY)) {
1864 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
1865 vgroup_assign_with_menu();
1868 group_operation_with_menu();
1870 else if((G.qual == (LR_CTRLKEY|LR_SHIFTKEY))) {
1872 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
1873 vgroup_operation_with_menu();
1876 else if((G.qual==LR_SHIFTKEY))
1878 if(G.obedit->type==OB_MESH)
1879 select_mesh_group_menu();
1881 select_object_grouped_menu();
1882 else if((G.obedit==0) && G.qual==LR_ALTKEY) {
1883 if(okee("Clear location")) {
1887 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
1888 v3d->twtype= V3D_MANIP_TRANSLATE;
1891 else if((G.qual==0)) {
1892 initTransform(TFM_TRANSLATION, CTX_NONE);
1898 if(G.obedit->type==OB_MESH) {
1899 if(G.qual==LR_CTRLKEY)
1901 else if(G.qual==LR_ALTKEY)
1903 else if((G.qual==LR_SHIFTKEY))
1905 else if((G.qual==0))
1908 else if(G.obedit->type== OB_SURF) {
1909 if(G.qual==LR_CTRLKEY)
1911 else if(G.qual==LR_ALTKEY)
1913 else if((G.qual==LR_SHIFTKEY))
1915 else if((G.qual==0))
1918 else if(G.obedit->type==OB_CURVE) {
1919 if(G.qual==LR_CTRLKEY)
1921 else if(G.qual==LR_ALTKEY)
1923 /* should be G.qual==LR_SHIFTKEY, but that is taken fro handles already */
1924 else if((G.qual==(LR_ALTKEY|LR_SHIFTKEY)))
1926 /* should be G.qual==0, but that is taken for handles already */
1927 else if((G.qual==(LR_ALTKEY|LR_CTRLKEY)))
1930 if(G.qual==LR_CTRLKEY) /* conflict */
1931 autocalchandlesNurb_all(1); /* flag=1, selected */
1932 else if((G.qual==LR_SHIFTKEY))
1934 else if((G.qual==0))
1937 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1938 BIF_undo_push("Handle change");
1939 allqueue(REDRAWVIEW3D, 0);
1942 else if(G.obedit->type==OB_LATTICE) {
1943 if(G.qual==LR_CTRLKEY) add_hook();
1945 else if(G.obedit->type==OB_MBALL) {
1946 if(G.qual==LR_ALTKEY)
1948 else if((G.qual==LR_SHIFTKEY))
1950 else if((G.qual==0))
1953 else if(G.obedit->type==OB_ARMATURE) {
1955 hide_selected_armature_bones();
1956 else if (G.qual==LR_SHIFTKEY)
1957 hide_unselected_armature_bones();
1958 else if (G.qual==LR_ALTKEY)
1959 show_all_armature_bones();
1962 else if(FACESEL_PAINT_TEST)
1964 else if(ob && (ob->flag & OB_POSEMODE)) {
1966 hide_selected_pose_bones();
1967 else if (G.qual==LR_SHIFTKEY)
1968 hide_unselected_pose_bones();
1969 else if (G.qual==LR_ALTKEY)
1970 show_all_pose_bones();
1972 /* Object mode only, other modes are accounted for above */
1973 else if ((G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
1974 if(G.qual==LR_CTRLKEY)hookmenu();
1975 else if(G.qual==LR_ALTKEY) show_objects();
1976 else if(G.qual==LR_SHIFTKEY) hide_objects(0);
1977 else hide_objects(1);
1982 if(G.qual==LR_CTRLKEY)
1984 } else if(G.qual==LR_CTRLKEY) {
1985 if(ob && ob->type==OB_ARMATURE)
1986 if(ob->flag & OB_POSEMODE)
1989 else if(G.qual==LR_ALTKEY) {
1990 if(ob && ob->type==OB_ARMATURE)
1991 if(ob->flag & OB_POSEMODE)
1997 if(G.qual==LR_CTRLKEY) {
2001 else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
2004 error("Can't join unless there is an active object");
2009 if(G.obedit->type==OB_MESH) {
2017 if (G.obedit->type==OB_MESH) {
2018 if (G.qual==LR_SHIFTKEY)
2019 KnifeSubdivide(KNIFE_PROMPT);
2023 else if(G.obedit->type==OB_SURF)
2027 if((G.qual==LR_SHIFTKEY)) {
2028 if(FACESEL_PAINT_TEST)
2029 if (G.f & G_WEIGHTPAINT)
2030 clear_wpaint_selectedfaces();
2032 clear_vpaint_selectedfaces();
2033 else if(G.f & G_VERTEXPAINT)
2036 select_select_keys();
2045 if(G.obedit->type==OB_MESH) {
2046 if (G.qual & LR_CTRLKEY) {
2047 if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2048 selectconnected_mesh_all(); /* normal select linked */
2050 selectconnected_delimit_mesh_all(); /* select linked with edge crease delimiting */
2053 if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2054 selectconnected_mesh();
2056 selectconnected_delimit_mesh();
2060 if(G.obedit->type==OB_ARMATURE)
2061 selectconnected_armature();
2062 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
2063 selectconnected_nurb();
2065 else if(ob && (ob->flag & OB_POSEMODE)) {
2066 selectconnected_posearmature();
2069 if(FACESEL_PAINT_TEST) {
2071 select_linked_tfaces(0);
2072 else if((G.qual==LR_SHIFTKEY))
2073 select_linked_tfaces(1);
2074 else if(G.qual==LR_CTRLKEY)
2075 select_linked_tfaces(2);
2080 else if((G.qual==LR_SHIFTKEY))
2082 else if(G.qual==LR_CTRLKEY)
2089 if(G.qual==LR_ALTKEY) {
2090 if(G.obedit->type==OB_MESH) {
2092 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2095 else if((G.qual==0) || (G.qual==LR_CTRLKEY)) {
2098 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2099 if(G.obedit->type==OB_MESH) select_non_manifold();
2102 else if(G.qual & LR_CTRLKEY) {
2105 else if(G.qual==0 || G.qual==LR_SHIFTKEY) {
2106 if(ob && (ob->flag & OB_POSEMODE))
2114 toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
2115 allqueue(REDRAWVIEW3D, 0);
2118 switch (G.obedit->type){
2120 if(G.qual==LR_CTRLKEY) {
2121 pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
2123 auto_align_armature(pupval - 1);
2124 allqueue(REDRAWVIEW3D, 0);
2129 if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2130 if(okee("Recalculate normals inside")) {
2132 allqueue(REDRAWVIEW3D, 0);
2133 BIF_undo_push("Recalculate normals inside");
2136 else if(G.qual==LR_CTRLKEY){
2137 if(okee("Recalculate normals outside")) {
2139 allqueue(REDRAWVIEW3D, 0);
2140 BIF_undo_push("Recalculate normals outside");
2150 if (G.qual==LR_SHIFTKEY) {
2151 G.scene->prop_mode = (G.scene->prop_mode+1)%7;
2152 allqueue(REDRAWHEADERS, 0);
2154 else if((G.qual==LR_ALTKEY)) {
2155 if(G.scene->proportional==2) G.scene->proportional= 1;
2156 else G.scene->proportional= 2;
2157 allqueue(REDRAWHEADERS, 0);
2159 else if((G.qual==0)) {
2160 G.scene->proportional= !G.scene->proportional;
2161 allqueue(REDRAWHEADERS, 0);
2164 else if((G.qual==LR_SHIFTKEY || G.qual==(LR_ALTKEY|LR_SHIFTKEY))) {
2165 flip_subdivison(-1);
2167 else if(G.qual==LR_ALTKEY) {
2168 if(okee("Clear origin")) {
2176 if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2177 if(G.obedit->type==OB_ARMATURE)
2183 else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
2184 clear_bone_parent();
2185 else if((G.qual==0) && (G.obedit->type==OB_ARMATURE))
2186 select_bone_parent();
2187 else if((G.qual==0) && G.obedit->type==OB_MESH)
2189 else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
2191 else if (G.qual==LR_SHIFTKEY) {
2192 initTransform(TFM_PUSHPULL, CTX_NONE);
2196 else if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
2198 else if(G.qual==LR_SHIFTKEY) {
2199 toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
2202 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) {
2203 initTransform(TFM_PUSHPULL, CTX_NONE);
2206 else if(G.qual==LR_ALTKEY)
2208 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
2210 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
2211 start_RBSimulation();
2213 else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE))
2214 select_bone_parent();
2215 else if((G.qual==0)) {
2220 if((G.obedit==0) && G.qual==LR_ALTKEY) {
2221 if(okee("Clear rotation")) {
2225 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2226 v3d->twtype= V3D_MANIP_ROTATE;
2229 else if (G.obedit) {
2230 if((G.qual==LR_SHIFTKEY)) {
2231 if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
2234 else if(G.qual==LR_CTRLKEY) {
2235 if (G.obedit->type==OB_MESH) {
2237 BIF_undo_push("Cut Edgeloop");
2239 else if (G.obedit->type==OB_ARMATURE) {
2240 initTransform(TFM_BONE_ROLL, CTX_NONE);
2244 else if((G.qual==0)) {
2245 initTransform(TFM_ROTATION, CTX_NONE);
2249 else if((G.qual==0)) {
2250 initTransform(TFM_ROTATION, CTX_NONE);
2255 if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2256 v3d->twtype= V3D_MANIP_SCALE;
2261 if(G.qual==LR_ALTKEY) {
2262 if(G.obedit->type==OB_ARMATURE) {
2263 initTransform(TFM_BONESIZE, CTX_NONE);
2265 else if (G.obedit->type==OB_CURVE) {
2266 initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
2268 initTransform(TFM_SHRINKFATTEN, CTX_NONE);
2272 else if(G.qual==LR_CTRLKEY) {
2273 initTransform(TFM_SHEAR, CTX_NONE);
2276 else if(G.qual==LR_SHIFTKEY)
2278 else if(G.qual==0) {
2279 if(G.obedit->type==OB_ARMATURE) {
2280 bArmature *arm= G.obedit->data;
2281 if(arm->drawtype==ARM_ENVELOPE)
2282 initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
2284 initTransform(TFM_RESIZE, CTX_NONE);
2287 initTransform(TFM_RESIZE, CTX_NONE);
2290 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
2291 initTransform(TFM_TOSPHERE, CTX_NONE);
2294 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2295 if(G.obedit->type==OB_MESH) select_sharp_edges();
2298 else if(G.qual==LR_ALTKEY) {
2299 if(G.f & G_WEIGHTPAINT)
2301 if(ob && (ob->flag & OB_POSEMODE)) {
2302 bArmature *arm= ob->data;
2303 if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
2304 initTransform(TFM_BONESIZE, CTX_NONE);
2310 if(okee("Clear scale")) {
2314 else if(G.qual==LR_SHIFTKEY) {
2317 else if((G.qual==0)) {
2318 initTransform(TFM_RESIZE, CTX_NONE);
2321 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2322 initTransform(TFM_TOSPHERE, CTX_NONE);
2325 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)) {
2326 initTransform(TFM_SHEAR, CTX_NONE);
2331 if(G.qual == LR_SHIFTKEY) { /* toggle texture in solid draw mode */
2332 G.vd->flag2 ^= V3D_SOLID_TEX;
2333 allqueue(REDRAWVIEW3D, 0);
2334 } else if(G.obedit){
2335 if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
2336 convert_to_triface(G.qual & LR_SHIFTKEY);
2337 allqueue(REDRAWVIEW3D, 0);
2339 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2341 if (G.obedit->type==OB_CURVE) {
2342 if (G.qual==LR_ALTKEY) {
2345 else if (G.qual==0) {
2346 initTransform(TFM_TILT, CTX_NONE);
2351 else if(G.qual==LR_CTRLKEY) {
2352 if(ob && (ob->flag & OB_POSEMODE));
2355 else if(G.qual==LR_ALTKEY) {
2356 if(ob && (ob->flag & OB_POSEMODE));
2359 else if((G.qual==0)){
2365 /*// Use Ctrl Z like everybody else
2367 if(G.obedit->type==OB_MESH) {
2368 if(G.qual==0) BIF_undo(); else BIF_redo();
2370 else if ELEM5(G.obedit->type, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
2371 if(G.qual==0) BIF_undo(); else BIF_redo();
2376 uv_autocalc_tface();
2379 else if((G.qual==0)) {
2380 if(G.f & G_WEIGHTPAINT)
2382 else if(G.f & G_VERTEXPAINT)
2384 else if(G.f & G_TEXTUREPAINT)
2393 if ((G.qual==LR_CTRLKEY)) {
2394 if ((G.obedit) && G.obedit->type==OB_MESH) {
2397 } else if((G.qual==LR_SHIFTKEY)) {
2398 if ((G.obedit) && G.obedit->type==OB_MESH) {
2399 align_view_to_selected(v3d);
2401 else if (FACESEL_PAINT_TEST) {
2402 align_view_to_selected(v3d);
2405 else if(G.qual==LR_ALTKEY)
2407 else if (G.qual==0){
2409 if(G.obedit->type==OB_MESH) {
2412 else if(G.obedit->type==OB_CURVE) {
2414 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2415 allqueue(REDRAWVIEW3D, 0);
2416 BIF_undo_push("Handle change");
2419 else if(ob && ob->type == OB_MESH)
2424 if((G.qual==LR_SHIFTKEY)) {
2425 initTransform(TFM_WARP, CTX_NONE);
2428 /*else if(G.qual==LR_ALTKEY) {}*/
2429 else if(G.qual==LR_CTRLKEY) {
2431 if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2432 switchdirectionNurb2();
2436 else if((G.qual==0))
2442 if(G.qual==0 || G.qual==LR_SHIFTKEY)
2443 delete_context_selected();
2446 if((G.qual==0) && (G.obedit)) {
2447 if(G.obedit->type==OB_MESH) split_mesh();
2453 scrarea_queue_headredraw(curarea);
2454 scrarea_queue_winredraw(curarea);
2462 if(G.qual==LR_CTRLKEY) {
2463 G.vd->around= V3D_CENTROID;
2464 } else if(G.qual==LR_SHIFTKEY) {
2465 G.vd->around= V3D_CENTROID;
2466 } else if(G.qual==0) {
2467 G.vd->around= V3D_CENTER;
2469 handle_view3d_around();
2471 scrarea_queue_headredraw(curarea);
2472 scrarea_queue_winredraw(curarea);
2476 if(G.qual==LR_CTRLKEY) {
2477 G.vd->around= V3D_LOCAL;
2478 } else if(G.qual==0) {
2479 G.vd->around= V3D_CURSOR;
2481 handle_view3d_around();
2483 scrarea_queue_headredraw(curarea);
2484 scrarea_queue_winredraw(curarea);
2489 if(G.vd->localview) {
2491 endlocalview(curarea);
2497 scrarea_queue_headredraw(curarea);
2500 case PADASTERKEY: /* '*' */
2503 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
2504 editmesh_align_view_to_selected(G.vd, 3);
2506 else if (FACESEL_PAINT_TEST) {
2507 if(ob->type==OB_MESH) {
2509 faceselect_align_view_to_selected(G.vd, me, 3);
2513 obmat_to_viewmat(ob, 1);
2515 if(G.vd->persp==2) G.vd->persp= 1;
2516 scrarea_queue_winredraw(curarea);
2520 case PADPERIOD: /* '.' */
2526 if(G.qual==LR_CTRLKEY)
2528 else if((G.qual==0))
2529 nextkey_obipo(1); /* in editipo.c */
2533 if(G.qual==LR_CTRLKEY)
2535 else if((G.qual==0))
2539 case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
2540 case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
2542 persptoetsen(event);
2546 if ( (G.qual==LR_CTRLKEY)
2547 && (G.obedit) && (G.obedit->type==OB_MESH) )
2549 else if ( (G.qual==LR_CTRLKEY)
2550 && (G.obedit) && (G.obedit->type==OB_CURVE) )
2552 else if ( (G.qual==LR_CTRLKEY)
2553 && (G.obedit) && (G.obedit->type==OB_SURF) )
2556 persptoetsen(event);
2562 if ( (G.qual==LR_CTRLKEY)
2563 && (G.obedit) && (G.obedit->type==OB_MESH) )
2565 else if ( (G.qual==LR_CTRLKEY)
2566 && (G.obedit) && (G.obedit->type==OB_CURVE) )
2568 else if ( (G.qual==LR_CTRLKEY)
2569 && (G.obedit) && (G.obedit->type==OB_SURF) )
2572 persptoetsen(event);
2579 if (G.vd->flag & V3D_DISPIMAGE) {
2580 G.vd->flag &= ~V3D_DISPIMAGE;
2590 scrarea_queue_winredraw(curarea);
2591 scrarea_queue_headredraw(curarea);
2595 static void initview3d(ScrArea *sa)
2599 vd= MEM_callocN(sizeof(View3D), "initview3d");
2600 BLI_addhead(&sa->spacedata, vd); /* addhead! not addtail */
2602 vd->spacetype= SPACE_VIEW3D;
2603 vd->blockscale= 0.7f;
2604 vd->viewquat[0]= 1.0f;
2605 vd->viewquat[1]= vd->viewquat[2]= vd->viewquat[3]= 0.0f;
2607 vd->drawtype= OB_WIRE;
2615 vd->lay= vd->layact= 1;
2617 vd->lay= vd->layact= G.scene->lay;
2618 vd->camera= G.scene->camera;
2621 vd->gridflag |= V3D_SHOW_X;
2622 vd->gridflag |= V3D_SHOW_Y;
2623 vd->gridflag |= V3D_SHOW_FLOOR;
2624 vd->gridflag &= ~V3D_SHOW_Z;
2630 /* ******************** SPACE: IPO ********************** */
2632 static void changeview2dspace(ScrArea *sa, void *spacedata)
2634 if(G.v2d==0) return;
2636 test_view2d(G.v2d, curarea->winx, curarea->winy);
2637 myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
2640 static int get_cfra_from_dx(SpaceIpo * sipo, int dx)
2642 if (sipo->blocktype == ID_SEQ) {
2643 Sequence * seq = (Sequence*) sipo->from;
2647 if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
2650 float m= (seq->enddisp - seq->startdisp)/100.0f;
2651 float cfra = dx * m + seq->startdisp;
2660 static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
2662 extern void do_ipobuts(unsigned short event); /* drawipo.c */
2663 unsigned short event= evt->event;
2664 short val= evt->val;
2665 SpaceIpo *sipo= curarea->spacedata.first;
2666 View2D *v2d= &sipo->v2d;
2668 int cfra, doredraw= 0;
2670 short mousebut = L_MOUSE;
2672 if(sa->win==0) return;
2675 if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
2677 /* swap mouse buttons based on user preference */
2678 if (U.flag & USER_LMOUSESELECT) {
2679 if (event == LEFTMOUSE) {
2682 } else if (event == RIGHTMOUSE) {
2690 /* note: bad bad code, will be cleaned! is because event queues are all shattered */
2691 if(val>0 && val < 256) do_ipowin_buts(val-1);
2692 else do_ipobuts(val);
2696 if( in_ipo_buttons() ) {
2697 do_ipo_selectbuttons();
2700 else if(view2dmove(LEFTMOUSE)); /* only checks for sliders */
2701 else if((G.qual & LR_CTRLKEY) && (sipo->showkey==0)) add_vert_ipo();
2704 getmouseco_areawin(mval);
2705 areamouseco_to_ipoco(v2d, mval, &dx, &dy);
2707 cfra = get_cfra_from_dx(sipo, (int)dx);
2708 if(cfra< 1) cfra= 1;
2712 update_for_newframe_nodraw(0); /* 1 = nosound */