2.5 - Armatures Code
[blender.git] / source / blender / editors / space_view3d / space_view3d.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) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_action_types.h"
33 #include "DNA_armature_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_space_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
38 #include "DNA_view3d_types.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_arithb.h"
44 #include "BLI_rand.h"
45
46 #include "BKE_action.h"
47 #include "BKE_context.h"
48 #include "BKE_global.h"
49 #include "BKE_screen.h"
50 #include "BKE_utildefines.h"
51
52 #include "ED_armature.h"
53 #include "ED_space_api.h"
54 #include "ED_screen.h"
55
56 #include "BIF_gl.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "UI_interface.h"
62 #include "UI_resources.h"
63 #include "UI_view2d.h"
64
65 #include "view3d_intern.h"      // own include
66
67 /* ******************** default callbacks for view3d space ***************** */
68
69 static SpaceLink *view3d_new(const bContext *C)
70 {
71         Scene *scene= CTX_data_scene(C);
72         ARegion *ar;
73         View3D *v3d;
74         RegionView3D *rv3d;
75         
76         v3d= MEM_callocN(sizeof(View3D), "initview3d");
77         v3d->spacetype= SPACE_VIEW3D;
78         v3d->blockscale= 0.7f;
79         v3d->lay= v3d->layact= 1;
80         if(scene) {
81                 v3d->lay= v3d->layact= scene->lay;
82                 v3d->camera= scene->camera;
83         }
84         v3d->scenelock= 1;
85         v3d->grid= 1.0f;
86         v3d->gridlines= 16;
87         v3d->gridsubdiv = 10;
88         v3d->drawtype= OB_WIRE;
89         
90         v3d->gridflag |= V3D_SHOW_X;
91         v3d->gridflag |= V3D_SHOW_Y;
92         v3d->gridflag |= V3D_SHOW_FLOOR;
93         v3d->gridflag &= ~V3D_SHOW_Z;
94         
95         v3d->lens= 35.0f;
96         v3d->near= 0.01f;
97         v3d->far= 500.0f;
98         
99         /* header */
100         ar= MEM_callocN(sizeof(ARegion), "header for view3d");
101         
102         BLI_addtail(&v3d->regionbase, ar);
103         ar->regiontype= RGN_TYPE_HEADER;
104         ar->alignment= RGN_ALIGN_BOTTOM;
105         
106         /* main area */
107         ar= MEM_callocN(sizeof(ARegion), "main area for view3d");
108         
109         BLI_addtail(&v3d->regionbase, ar);
110         ar->regiontype= RGN_TYPE_WINDOW;
111         
112         ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region view3d");
113         rv3d= ar->regiondata;
114         rv3d->viewquat[0]= 1.0f;
115         rv3d->persp= 1;
116         rv3d->view= 7;
117         rv3d->dist= 10.0;
118         Mat4One(rv3d->twmat);
119         
120         return (SpaceLink *)v3d;
121 }
122
123 /* not spacelink itself */
124 static void view3d_free(SpaceLink *sl)
125 {
126         View3D *vd= (View3D *) sl;
127         
128         if(vd->bgpic) {
129                 if(vd->bgpic->ima) vd->bgpic->ima->id.us--;
130                 MEM_freeN(vd->bgpic);
131         }
132         
133         if(vd->localvd) MEM_freeN(vd->localvd);
134         
135         if(vd->properties_storage) MEM_freeN(vd->properties_storage);
136         
137 }
138
139
140 /* spacetype; init callback */
141 static void view3d_init(struct wmWindowManager *wm, ScrArea *sa)
142 {
143
144 }
145
146 static SpaceLink *view3d_duplicate(SpaceLink *sl)
147 {
148         View3D *v3do= (View3D *)sl;
149         View3D *v3dn= MEM_dupallocN(sl);
150         
151         /* clear or remove stuff from old */
152         
153 // XXX  BIF_view3d_previewrender_free(v3do);
154         
155         if(v3do->localvd) {
156 // XXX          restore_localviewdata(v3do);
157                 v3do->localvd= NULL;
158                 v3do->properties_storage= NULL;
159                 v3do->localview= 0;
160                 v3do->lay &= 0xFFFFFF;
161         }
162         
163         /* copy or clear inside new stuff */
164
165         if(v3dn->bgpic) {
166                 v3dn->bgpic= MEM_dupallocN(v3dn->bgpic);
167                 if(v3dn->bgpic->ima) v3dn->bgpic->ima->id.us++;
168         }
169         v3dn->properties_storage= NULL;
170         
171         return (SpaceLink *)v3dn;
172 }
173
174 /* add handlers, stuff you only do once or on area/region changes */
175 static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
176 {
177         ListBase *keymap;
178         
179         /* own keymap */
180         keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
181         WM_event_add_keymap_handler(&ar->handlers, keymap);
182         
183         /* object ops. */
184         keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0);
185         WM_event_add_keymap_handler(&ar->handlers, keymap);
186         
187         /* pose is not modal, operator poll checks for this */
188         keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
189         WM_event_add_keymap_handler(&ar->handlers, keymap);
190         
191         /* object modal ops default */
192         keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
193         WM_event_add_keymap_handler(&ar->handlers, keymap);
194         
195 }
196
197 /* type callback, not region itself */
198 static void view3d_main_area_free(ARegion *ar)
199 {
200         RegionView3D *rv3d= ar->regiondata;
201         
202         if(rv3d) {
203                 if(rv3d->localvd) MEM_freeN(rv3d->localvd);
204                 if(rv3d->clipbb) MEM_freeN(rv3d->clipbb);
205
206                 // XXX  retopo_free_view_data(rv3d);
207                 if(rv3d->ri) { 
208                         // XXX          BIF_view3d_previewrender_free(rv3d);
209                 }
210                 
211                 if(rv3d->depths) {
212                         if(rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
213                         MEM_freeN(rv3d->depths);
214                 }
215                 MEM_freeN(rv3d);
216                 ar->regiondata= NULL;
217         }
218 }
219
220 /* copy regiondata */
221 static void *view3d_main_area_duplicate(void *poin)
222 {
223         if(poin) {
224                 RegionView3D *rv3d= poin, *new;
225         
226                 new= MEM_dupallocN(rv3d);
227                 if(rv3d->localvd) 
228                         new->localvd= MEM_dupallocN(rv3d->localvd);
229                 if(rv3d->clipbb) 
230                         new->clipbb= MEM_dupallocN(rv3d->clipbb);
231                 
232                 new->depths= NULL;
233                 new->retopo_view_data= NULL;
234                 new->ri= NULL;
235                 new->gpd= NULL;
236                 new->sms= NULL;
237                 new->smooth_timer= NULL;
238                 
239                 return new;
240         }
241         return NULL;
242 }
243
244
245 static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
246 {
247         ListBase *keymap;
248         
249         keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
250         if(stype==NS_MODE_OBJECT)
251                 WM_event_add_keymap_handler(&ar->handlers, keymap);
252         else
253                 WM_event_remove_keymap_handler(&ar->handlers, keymap);
254         
255         keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
256         if(stype==NS_EDITMODE_MESH)
257                 WM_event_add_keymap_handler(&ar->handlers, keymap);
258         else
259                 WM_event_remove_keymap_handler(&ar->handlers, keymap);
260
261         keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
262         if(stype==NS_EDITMODE_CURVE)
263                 WM_event_add_keymap_handler(&ar->handlers, keymap);
264         else
265                 WM_event_remove_keymap_handler(&ar->handlers, keymap);
266         
267         keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
268         if(stype==NS_EDITMODE_ARMATURE)
269                 WM_event_add_keymap_handler(&ar->handlers, keymap);
270         else
271                 WM_event_remove_keymap_handler(&ar->handlers, keymap);
272         
273         /* editfont keymap swallows all... */
274         keymap= WM_keymap_listbase(wm, "Font", 0, 0);
275         if(stype==NS_EDITMODE_TEXT)
276                 WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
277         else
278                 WM_event_remove_keymap_handler(&ar->handlers, keymap);
279         
280 }
281
282 static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
283 {
284         /* context changes */
285         switch(wmn->category) {
286                 case NC_SCENE:
287                         switch(wmn->data) {
288                                 case ND_FRAME:
289                                 case ND_OB_ACTIVE:
290                                 case ND_OB_SELECT:
291                                         ED_region_tag_redraw(ar);
292                                         break;
293                                 case ND_MODE:
294                                         view3d_modal_keymaps(wmn->wm, ar, wmn->subtype);
295                                         ED_region_tag_redraw(ar);
296                                         break;
297                         }
298                         break;
299                 case NC_OBJECT:
300                         switch(wmn->data) {
301                                 case ND_BONE_ACTIVE:
302                                 case ND_BONE_SELECT:
303                                 case ND_TRANSFORM:
304                                 case ND_GEOM_SELECT:
305                                 case ND_DRAW:
306                                 case ND_MODIFIER:
307                                 case ND_KEYS:
308                                         ED_region_tag_redraw(ar);
309                                         break;
310                         }
311                 case NC_GROUP:
312                         /* all group ops for now */
313                         ED_region_tag_redraw(ar);
314                         break;
315                 case NC_MATERIAL:
316                         switch(wmn->data) {
317                                 case ND_SHADING_DRAW:
318                                         ED_region_tag_redraw(ar);
319                                         break;
320                         }
321                 case NC_LAMP:
322                         switch(wmn->data) {
323                                 case ND_LIGHTING_DRAW:
324                                         ED_region_tag_redraw(ar);
325                                         break;
326                         }
327         }
328 }
329
330 /* concept is to retrieve cursor type context-less */
331 static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
332 {
333         Scene *scene= win->screen->scene;
334
335         if(scene->obedit) {
336                 WM_cursor_set(win, CURSOR_EDIT);
337         }
338         else {
339                 WM_cursor_set(win, CURSOR_STD);
340         }
341 }
342
343 /* add handlers, stuff you only do once or on area/region changes */
344 static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
345 {
346         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
347 }
348
349 static void view3d_header_area_draw(const bContext *C, ARegion *ar)
350 {
351         float col[3];
352         
353         /* clear */
354         if(ED_screen_area_active(C))
355                 UI_GetThemeColor3fv(TH_HEADER, col);
356         else
357                 UI_GetThemeColor3fv(TH_HEADERDESEL, col);
358         
359         glClearColor(col[0], col[1], col[2], 0.0);
360         glClear(GL_COLOR_BUFFER_BIT);
361         
362         /* set view2d view matrix for scrolling (without scrollers) */
363         UI_view2d_view_ortho(C, &ar->v2d);
364         
365         view3d_header_buttons(C, ar);
366         
367         /* restore view matrix? */
368         UI_view2d_view_restore(C);
369 }
370
371 static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn)
372 {
373         /* context changes */
374         switch(wmn->category) {
375                 case NC_SCENE:
376                         switch(wmn->data) {
377                                 case ND_FRAME:
378                                 case ND_OB_ACTIVE:
379                                 case ND_OB_SELECT:
380                                 case ND_MODE:
381                                         ED_region_tag_redraw(ar);
382                                         break;
383                         }
384                         break;
385         }
386 }
387
388 /*
389  * Returns true if the Object is a from an external blend file (libdata)
390  */
391 static int object_is_libdata(Object *ob)
392 {
393         if (!ob) return 0;
394         if (ob->proxy) return 0;
395         if (ob->id.lib) return 1;
396         return 0;
397 }
398
399 static int view3d_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
400 {
401         View3D *v3d= CTX_wm_view3d(C);
402         Scene *scene= CTX_data_scene(C);
403         Base *base;
404
405         if(v3d==NULL) return 0;
406
407         if(ELEM(member, CTX_DATA_SELECTED_OBJECTS, CTX_DATA_SELECTED_BASES)) {
408                 for(base=scene->base.first; base; base=base->next) {
409                         if((base->flag & SELECT) && (base->lay & v3d->lay)) {
410                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
411                                         if(member == CTX_DATA_SELECTED_OBJECTS)
412                                                 CTX_data_list_add(result, base->object);
413                                         else
414                                                 CTX_data_list_add(result, base);
415                                 }
416                         }
417                 }
418
419                 return 1;
420         }
421         else if(ELEM(member, CTX_DATA_SELECTED_EDITABLE_OBJECTS, CTX_DATA_SELECTED_EDITABLE_BASES)) {
422                 for(base=scene->base.first; base; base=base->next) {
423                         if((base->flag & SELECT) && (base->lay & v3d->lay)) {
424                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
425                                         if(0==object_is_libdata(base->object)) {
426                                                 if(member == CTX_DATA_SELECTED_EDITABLE_OBJECTS)
427                                                         CTX_data_list_add(result, base->object);
428                                                 else
429                                                         CTX_data_list_add(result, base);
430                                         }
431                                 }
432                         }
433                 }
434                 
435                 return 1;
436         }
437         else if(ELEM(member, CTX_DATA_VISIBLE_OBJECTS, CTX_DATA_VISIBLE_BASES)) {
438                 for(base=scene->base.first; base; base=base->next) {
439                         if(base->lay & v3d->lay) {
440                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
441                                         if(member == CTX_DATA_VISIBLE_OBJECTS)
442                                                 CTX_data_list_add(result, base->object);
443                                         else
444                                                 CTX_data_list_add(result, base);
445                                 }
446                         }
447                 }
448                 
449                 return 1;
450         }
451         else if(member == CTX_DATA_ACTIVE_BASE) {
452                 if(scene->basact && (scene->basact->lay & v3d->lay))
453                         if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
454                                 CTX_data_pointer_set(result, scene->basact);
455
456                 return 1;
457         }
458         else if(member == CTX_DATA_ACTIVE_OBJECT) {
459                 if(scene->basact && (scene->basact->lay & v3d->lay))
460                         if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
461                                 CTX_data_pointer_set(result, scene->basact->object);
462
463                 return 1;
464         }
465         else if(ELEM(member, CTX_DATA_SELECTED_BONES, CTX_DATA_SELECTED_EDITABLE_BONES)) {
466                 Object *obedit= scene->obedit; // XXX get from context?
467                 bArmature *arm= (obedit) ? obedit->data : NULL;
468                 EditBone *ebone, *flipbone=NULL;
469                 
470                 if (arm && arm->edbo) {
471                         /* Attention: X-Axis Mirroring is also handled here... */
472                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
473                                 /* first and foremost, bone must be visible and selected */
474                                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
475                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
476                                          * so that most users of this data don't need to explicitly check for it themselves.
477                                          * 
478                                          * We need to make sure that these mirrored copies are not selected, otherwise some
479                                          * bones will be operated on twice.
480                                          */
481                                         if (arm->flag & ARM_MIRROR_EDIT)
482                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
483                                         
484                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
485                                         if (member == CTX_DATA_SELECTED_EDITABLE_BONES) {
486                                                 /* only selected + editable */
487                                                 if (EBONE_EDITABLE(ebone)) {
488                                                         CTX_data_list_add(result, ebone);
489                                                 
490                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
491                                                                 CTX_data_list_add(result, flipbone);
492                                                 }
493                                         }
494                                         else {
495                                                 /* only include bones if selected */
496                                                 CTX_data_list_add(result, ebone);
497                                                 
498                                                 if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
499                                                         CTX_data_list_add(result, flipbone);
500                                         }
501                                 }
502                         }       
503                         
504                         return 1;
505                 }
506         }
507         else if(member == CTX_DATA_SELECTED_PCHANS) {
508                 Object *obact= OBACT;
509                 bArmature *arm= (obact) ? obact->data : NULL;
510                 bPoseChannel *pchan;
511                 
512                 if (obact && arm) {
513                         for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
514                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
515                                 if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
516                                         if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) 
517                                                 CTX_data_list_add(result, pchan);
518                                 }
519                         }
520                         
521                         return 1;
522                 }
523         }
524         else if(member == CTX_DATA_ACTIVE_BONE) {
525                 Object *obedit= scene->obedit; // XXX get from context?
526                 bArmature *arm= (obedit) ? obedit->data : NULL;
527                 EditBone *ebone;
528                 
529                 if (arm && arm->edbo) {
530                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
531                                 if (EBONE_VISIBLE(arm, ebone)) {
532                                         if (ebone->flag & BONE_ACTIVE) {
533                                                 CTX_data_pointer_set(result, ebone);
534                                                 
535                                                 return 1;
536                                         }
537                                 }
538                         }
539                 }
540                 
541         }
542         else if(member == CTX_DATA_ACTIVE_PCHAN) {
543                 Object *obact= OBACT;
544                 bArmature *arm= (obact) ? obact->data : NULL;
545                 bPoseChannel *pchan;
546                 
547                 pchan= get_active_posechannel(obact);
548                 if (pchan) {
549                         CTX_data_pointer_set(result, pchan);
550                         return 1;
551                 }
552         }
553
554         return 0;
555 }
556
557 /* only called once, from space/spacetypes.c */
558 void ED_spacetype_view3d(void)
559 {
560         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype view3d");
561         ARegionType *art;
562         
563         st->spaceid= SPACE_VIEW3D;
564         
565         st->new= view3d_new;
566         st->free= view3d_free;
567         st->init= view3d_init;
568         st->duplicate= view3d_duplicate;
569         st->operatortypes= view3d_operatortypes;
570         st->keymap= view3d_keymap;
571         st->context= view3d_context;
572         
573         /* regions: main window */
574         art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region");
575         art->regionid = RGN_TYPE_WINDOW;
576         art->keymapflag= ED_KEYMAP_FRAMES;
577         art->draw= view3d_main_area_draw;
578         art->init= view3d_main_area_init;
579         art->free= view3d_main_area_free;
580         art->duplicate= view3d_main_area_duplicate;
581         art->listener= view3d_main_area_listener;
582         art->cursor= view3d_main_area_cursor;
583         BLI_addhead(&st->regiontypes, art);
584         
585         /* regions: header */
586         art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region");
587         art->regionid = RGN_TYPE_HEADER;
588         art->minsizey= HEADERY;
589         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
590         art->listener= view3d_header_area_listener;
591         
592         art->init= view3d_header_area_init;
593         art->draw= view3d_header_area_draw;
594         
595         BLI_addhead(&st->regiontypes, art);
596         
597         BKE_spacetype_register(st);
598 }
599