Partial fix for T37604: Deadlock when stopping rendered viewport (Blender Internal)
[blender.git] / source / blender / editors / space_view3d / space_view3d.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_view3d/space_view3d.c
28  *  \ingroup spview3d
29  */
30
31
32 #include <string.h>
33 #include <stdio.h>
34
35 #include "DNA_material_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_utildefines.h"
44
45 #include "BKE_context.h"
46 #include "BKE_icons.h"
47 #include "BKE_main.h"
48 #include "BKE_object.h"
49 #include "BKE_scene.h"
50 #include "BKE_screen.h"
51
52 #include "ED_render.h"
53 #include "ED_space_api.h"
54 #include "ED_screen.h"
55 #include "ED_object.h"
56
57 #include "GPU_extensions.h"
58 #include "GPU_material.h"
59
60 #include "BIF_gl.h"
61
62 #include "WM_api.h"
63 #include "WM_types.h"
64
65 #include "RE_engine.h"
66 #include "RE_pipeline.h"
67
68 #include "RNA_access.h"
69
70 #include "UI_resources.h"
71
72 #ifdef WITH_PYTHON
73 #  include "BPY_extern.h"
74 #endif
75
76 #include "view3d_intern.h"  /* own include */
77
78 /* ******************** manage regions ********************* */
79
80 ARegion *view3d_has_buttons_region(ScrArea *sa)
81 {
82         ARegion *ar, *arnew;
83
84         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
85         if (ar) return ar;
86         
87         /* add subdiv level; after header */
88         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
89
90         /* is error! */
91         if (ar == NULL) return NULL;
92         
93         arnew = MEM_callocN(sizeof(ARegion), "buttons for view3d");
94         
95         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
96         arnew->regiontype = RGN_TYPE_UI;
97         arnew->alignment = RGN_ALIGN_RIGHT;
98         
99         arnew->flag = RGN_FLAG_HIDDEN;
100         
101         return arnew;
102 }
103
104 ARegion *view3d_has_tools_region(ScrArea *sa)
105 {
106         ARegion *ar, *artool = NULL, *arprops = NULL, *arhead;
107         
108         for (ar = sa->regionbase.first; ar; ar = ar->next) {
109                 if (ar->regiontype == RGN_TYPE_TOOLS)
110                         artool = ar;
111                 if (ar->regiontype == RGN_TYPE_TOOL_PROPS)
112                         arprops = ar;
113         }
114         
115         /* tool region hide/unhide also hides props */
116         if (arprops && artool) return artool;
117         
118         if (artool == NULL) {
119                 /* add subdiv level; after header */
120                 for (arhead = sa->regionbase.first; arhead; arhead = arhead->next)
121                         if (arhead->regiontype == RGN_TYPE_HEADER)
122                                 break;
123                 
124                 /* is error! */
125                 if (arhead == NULL) return NULL;
126                 
127                 artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
128                 
129                 BLI_insertlinkafter(&sa->regionbase, arhead, artool);
130                 artool->regiontype = RGN_TYPE_TOOLS;
131                 artool->alignment = RGN_ALIGN_LEFT;
132                 artool->flag = RGN_FLAG_HIDDEN;
133         }
134
135         if (arprops == NULL) {
136                 /* add extra subdivided region for tool properties */
137                 arprops = MEM_callocN(sizeof(ARegion), "tool props for view3d");
138                 
139                 BLI_insertlinkafter(&sa->regionbase, artool, arprops);
140                 arprops->regiontype = RGN_TYPE_TOOL_PROPS;
141                 arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
142         }
143         
144         return artool;
145 }
146
147 /* ****************************************************** */
148
149 /* function to always find a regionview3d context inside 3D window */
150 RegionView3D *ED_view3d_context_rv3d(bContext *C)
151 {
152         RegionView3D *rv3d = CTX_wm_region_view3d(C);
153         
154         if (rv3d == NULL) {
155                 ScrArea *sa = CTX_wm_area(C);
156                 if (sa && sa->spacetype == SPACE_VIEW3D) {
157                         ARegion *ar = BKE_area_find_region_active_win(sa);
158                         if (ar) {
159                                 rv3d = ar->regiondata;
160                         }
161                 }
162         }
163         return rv3d;
164 }
165
166 /* ideally would return an rv3d but in some cases the region is needed too
167  * so return that, the caller can then access the ar->regiondata */
168 bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
169 {
170         ScrArea *sa = CTX_wm_area(C);
171
172         *r_v3d = NULL;
173         *r_ar = NULL;
174
175         if (sa && sa->spacetype == SPACE_VIEW3D) {
176                 ARegion *ar = CTX_wm_region(C);
177                 View3D *v3d = (View3D *)sa->spacedata.first;
178
179                 if (ar) {
180                         RegionView3D *rv3d = ar->regiondata;
181                         if (rv3d && rv3d->viewlock == 0) {
182                                 *r_v3d = v3d;
183                                 *r_ar = ar;
184                                 return true;
185                         }
186                         else {
187                                 ARegion *ar_unlock_user = NULL;
188                                 ARegion *ar_unlock = NULL;
189                                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
190                                         /* find the first unlocked rv3d */
191                                         if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) {
192                                                 rv3d = ar->regiondata;
193                                                 if (rv3d->viewlock == 0) {
194                                                         ar_unlock = ar;
195                                                         if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) {
196                                                                 ar_unlock_user = ar;
197                                                                 break;
198                                                         }
199                                                 }
200                                         }
201                                 }
202
203                                 /* camera/perspective view get priority when the active region is locked */
204                                 if (ar_unlock_user) {
205                                         *r_v3d = v3d;
206                                         *r_ar = ar_unlock_user;
207                                         return true;
208                                 }
209
210                                 if (ar_unlock) {
211                                         *r_v3d = v3d;
212                                         *r_ar = ar_unlock;
213                                         return true;
214                                 }
215                         }
216                 }
217         }
218
219         return false;
220 }
221
222 /* Most of the time this isn't needed since you could assume the view matrix was
223  * set while drawing, however when functions like mesh_foreachScreenVert are
224  * called by selection tools, we can't be sure this object was the last.
225  *
226  * for example, transparent objects are drawn after editmode and will cause
227  * the rv3d mat's to change and break selection.
228  *
229  * 'ED_view3d_init_mats_rv3d' should be called before
230  * view3d_project_short_clip and view3d_project_short_noclip in cases where
231  * these functions are not used during draw_object
232  */
233 void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
234 {
235         /* local viewmat and persmat, to calculate projections */
236         mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat);
237         mul_m4_m4m4(rv3d->persmatob, rv3d->persmat, ob->obmat);
238
239         /* initializes object space clipping, speeds up clip tests */
240         ED_view3d_clipping_local(rv3d, ob->obmat);
241 }
242
243 void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
244 {
245         ED_view3d_init_mats_rv3d(ob, rv3d);
246
247         /* we have to multiply instead of loading viewmatob to make
248          * it work with duplis using displists, otherwise it will
249          * override the dupli-matrix */
250         glMultMatrixf(ob->obmat);
251 }
252
253 #ifdef DEBUG
254 /* ensure we correctly initialize */
255 void ED_view3d_clear_mats_rv3d(struct RegionView3D *rv3d)
256 {
257         zero_m4(rv3d->viewmatob);
258         zero_m4(rv3d->persmatob);
259 }
260
261 void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d)
262 {
263         BLI_ASSERT_ZERO_M4(rv3d->viewmatob);
264         BLI_ASSERT_ZERO_M4(rv3d->persmatob);
265 }
266 #endif
267
268 static void view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
269 {
270         RegionView3D *rv3d = ar->regiondata;
271
272         if (rv3d->render_engine) {
273 #ifdef WITH_PYTHON
274                 BPy_BEGIN_ALLOW_THREADS;
275 #endif
276
277                 WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW);
278
279 #ifdef WITH_PYTHON
280                 BPy_END_ALLOW_THREADS;
281 #endif
282
283                 if (rv3d->render_engine->re)
284                         RE_Database_Free(rv3d->render_engine->re);
285                 RE_engine_free(rv3d->render_engine);
286                 rv3d->render_engine = NULL;
287         }
288 }
289
290 void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
291 {
292         wmWindowManager *wm = bmain->wm.first;
293
294         if (v3d->drawtype != OB_RENDER) {
295                 ARegion *ar;
296
297                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
298                         if (ar->regiondata)
299                                 view3d_stop_render_preview(wm, ar);
300                 }
301         }
302 }
303
304 /* ******************** default callbacks for view3d space ***************** */
305
306 static SpaceLink *view3d_new(const bContext *C)
307 {
308         Scene *scene = CTX_data_scene(C);
309         ARegion *ar;
310         View3D *v3d;
311         RegionView3D *rv3d;
312         
313         v3d = MEM_callocN(sizeof(View3D), "initview3d");
314         v3d->spacetype = SPACE_VIEW3D;
315         v3d->blockscale = 0.7f;
316         v3d->lay = v3d->layact = 1;
317         if (scene) {
318                 v3d->lay = v3d->layact = scene->lay;
319                 v3d->camera = scene->camera;
320         }
321         v3d->scenelock = TRUE;
322         v3d->grid = 1.0f;
323         v3d->gridlines = 16;
324         v3d->gridsubdiv = 10;
325         v3d->drawtype = OB_SOLID;
326
327         v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
328         
329         v3d->flag = V3D_SELECT_OUTLINE;
330         v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
331         
332         v3d->lens = 35.0f;
333         v3d->near = 0.01f;
334         v3d->far = 1000.0f;
335
336         v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
337         v3d->twtype = V3D_MANIP_TRANSLATE;
338         v3d->around = V3D_CENTROID;
339         
340         v3d->bundle_size = 0.2f;
341         v3d->bundle_drawtype = OB_PLAINAXES;
342         
343         /* header */
344         ar = MEM_callocN(sizeof(ARegion), "header for view3d");
345         
346         BLI_addtail(&v3d->regionbase, ar);
347         ar->regiontype = RGN_TYPE_HEADER;
348         ar->alignment = RGN_ALIGN_BOTTOM;
349         
350         /* tool shelf */
351         ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
352         
353         BLI_addtail(&v3d->regionbase, ar);
354         ar->regiontype = RGN_TYPE_TOOLS;
355         ar->alignment = RGN_ALIGN_LEFT;
356         ar->flag = RGN_FLAG_HIDDEN;
357         
358         /* tool properties */
359         ar = MEM_callocN(sizeof(ARegion), "tool properties for view3d");
360         
361         BLI_addtail(&v3d->regionbase, ar);
362         ar->regiontype = RGN_TYPE_TOOL_PROPS;
363         ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
364         ar->flag = RGN_FLAG_HIDDEN;
365         
366         /* buttons/list view */
367         ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
368         
369         BLI_addtail(&v3d->regionbase, ar);
370         ar->regiontype = RGN_TYPE_UI;
371         ar->alignment = RGN_ALIGN_RIGHT;
372         ar->flag = RGN_FLAG_HIDDEN;
373         
374         /* main area */
375         ar = MEM_callocN(sizeof(ARegion), "main area for view3d");
376         
377         BLI_addtail(&v3d->regionbase, ar);
378         ar->regiontype = RGN_TYPE_WINDOW;
379         
380         ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
381         rv3d = ar->regiondata;
382         rv3d->viewquat[0] = 1.0f;
383         rv3d->persp = RV3D_PERSP;
384         rv3d->view = RV3D_VIEW_PERSPORTHO;
385         rv3d->dist = 10.0;
386         
387         return (SpaceLink *)v3d;
388 }
389
390 /* not spacelink itself */
391 static void view3d_free(SpaceLink *sl)
392 {
393         View3D *vd = (View3D *) sl;
394
395         BLI_freelistN(&vd->bgpicbase);
396
397         if (vd->localvd) MEM_freeN(vd->localvd);
398         
399         if (vd->properties_storage) MEM_freeN(vd->properties_storage);
400         
401         /* matcap material, its preview rect gets freed via icons */
402         if (vd->defmaterial) {
403                 if (vd->defmaterial->gpumaterial.first)
404                         GPU_material_free(vd->defmaterial);
405                 BKE_previewimg_free(&vd->defmaterial->preview);
406                 MEM_freeN(vd->defmaterial);
407         }
408 }
409
410
411 /* spacetype; init callback */
412 static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
413 {
414
415 }
416
417 static SpaceLink *view3d_duplicate(SpaceLink *sl)
418 {
419         View3D *v3do = (View3D *)sl;
420         View3D *v3dn = MEM_dupallocN(sl);
421         
422         /* clear or remove stuff from old */
423         
424 // XXX  BIF_view3d_previewrender_free(v3do);
425         
426         if (v3dn->localvd) {
427                 v3dn->localvd = NULL;
428                 v3dn->properties_storage = NULL;
429                 v3dn->lay = v3do->localvd->lay & 0xFFFFFF;
430         }
431
432         if (v3dn->drawtype == OB_RENDER)
433                 v3dn->drawtype = OB_SOLID;
434         
435         /* copy or clear inside new stuff */
436
437         v3dn->defmaterial = NULL;
438         
439         BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
440
441         v3dn->properties_storage = NULL;
442         
443         return (SpaceLink *)v3dn;
444 }
445
446 /* add handlers, stuff you only do once or on area/region changes */
447 static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
448 {
449         ListBase *lb;
450         wmKeyMap *keymap;
451
452         /* object ops. */
453         
454         /* important to be before Pose keymap since they can both be enabled at once */
455         keymap = WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0);
456         WM_event_add_keymap_handler(&ar->handlers, keymap);
457         
458         
459         keymap = WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
460         WM_event_add_keymap_handler(&ar->handlers, keymap);
461
462         /* pose is not modal, operator poll checks for this */
463         keymap = WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
464         WM_event_add_keymap_handler(&ar->handlers, keymap);
465         
466         keymap = WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
467         WM_event_add_keymap_handler(&ar->handlers, keymap);
468
469         keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
470         WM_event_add_keymap_handler(&ar->handlers, keymap);
471
472         keymap = WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0);
473         WM_event_add_keymap_handler(&ar->handlers, keymap);
474
475         keymap = WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0);
476         WM_event_add_keymap_handler(&ar->handlers, keymap);
477
478         keymap = WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0);
479         WM_event_add_keymap_handler(&ar->handlers, keymap);
480         
481         keymap = WM_keymap_find(wm->defaultconf, "Mesh", 0, 0);
482         WM_event_add_keymap_handler(&ar->handlers, keymap);
483         
484         keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
485         WM_event_add_keymap_handler(&ar->handlers, keymap);
486         
487         keymap = WM_keymap_find(wm->defaultconf, "Armature", 0, 0);
488         WM_event_add_keymap_handler(&ar->handlers, keymap);
489
490         keymap = WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
491         WM_event_add_keymap_handler(&ar->handlers, keymap);
492
493         keymap = WM_keymap_find(wm->defaultconf, "Metaball", 0, 0);
494         WM_event_add_keymap_handler(&ar->handlers, keymap);
495         
496         keymap = WM_keymap_find(wm->defaultconf, "Lattice", 0, 0);
497         WM_event_add_keymap_handler(&ar->handlers, keymap);
498
499         /* armature sketching needs to take over mouse */
500         keymap = WM_keymap_find(wm->defaultconf, "Armature Sketch", 0, 0);
501         WM_event_add_keymap_handler(&ar->handlers, keymap);
502
503         keymap = WM_keymap_find(wm->defaultconf, "Particle", 0, 0);
504         WM_event_add_keymap_handler(&ar->handlers, keymap);
505
506         /* editfont keymap swallows all... */
507         keymap = WM_keymap_find(wm->defaultconf, "Font", 0, 0);
508         WM_event_add_keymap_handler(&ar->handlers, keymap);
509
510         keymap = WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0);
511         WM_event_add_keymap_handler(&ar->handlers, keymap);
512
513         keymap = WM_keymap_find(wm->defaultconf, "Frames", 0, 0);
514         WM_event_add_keymap_handler(&ar->handlers, keymap);
515
516         /* own keymap, last so modes can override it */
517         keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
518         WM_event_add_keymap_handler(&ar->handlers, keymap);
519
520         keymap = WM_keymap_find(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
521         WM_event_add_keymap_handler(&ar->handlers, keymap);
522         
523         /* add drop boxes */
524         lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
525         
526         WM_event_add_dropbox_handler(&ar->handlers, lb);
527         
528 }
529
530 static void view3d_main_area_exit(wmWindowManager *wm, ARegion *ar)
531 {
532         RegionView3D *rv3d = ar->regiondata;
533
534         view3d_stop_render_preview(wm, ar);
535
536         if (rv3d->gpuoffscreen) {
537                 GPU_offscreen_free(rv3d->gpuoffscreen);
538                 rv3d->gpuoffscreen = NULL;
539         }
540 }
541
542 static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
543 {
544         if (drag->type == WM_DRAG_ID) {
545                 ID *id = (ID *)drag->poin;
546                 if (GS(id->name) == ID_OB)
547                         return 1;
548         }
549         return 0;
550 }
551
552 static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
553 {
554         if (drag->type == WM_DRAG_ID) {
555                 ID *id = (ID *)drag->poin;
556                 if (GS(id->name) == ID_GR)
557                         return 1;
558         }
559         return 0;
560 }
561
562 static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
563 {
564         if (drag->type == WM_DRAG_ID) {
565                 ID *id = (ID *)drag->poin;
566                 if (GS(id->name) == ID_MA)
567                         return 1;
568         }
569         return 0;
570 }
571
572 static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
573 {
574         if (drag->type == WM_DRAG_ID) {
575                 ID *id = (ID *)drag->poin;
576                 if (GS(id->name) == ID_IM)
577                         return 1;
578         }
579         else if (drag->type == WM_DRAG_PATH) {
580                 if (ELEM(drag->icon, 0, ICON_FILE_IMAGE))   /* rule might not work? */
581                         return 1;
582         }
583         return 0;
584 }
585
586 static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
587 {
588         if (event->ctrl)
589                 return false;
590
591         if (!ED_view3d_give_base_under_cursor(C, event->mval)) {
592                 return view3d_ima_drop_poll(C, drag, event);
593         }
594         return 0;
595 }
596
597 static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
598 {
599         Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
600
601         /* either holding and ctrl and no object, or dropping to empty */
602         if ((event->ctrl && !base) || (base && base->object->type == OB_EMPTY))
603                 return view3d_ima_drop_poll(C, drag, event);
604
605         return 0;
606 }
607
608 static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
609 {
610         Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
611
612         if (base && base->object->type == OB_MESH)
613                 return view3d_ima_drop_poll(C, drag, event);
614         return 0;
615 }
616
617 static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
618 {
619         ID *id = (ID *)drag->poin;
620
621         RNA_string_set(drop->ptr, "name", id->name + 2);
622 }
623
624 static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
625 {
626         ID *id = (ID *)drag->poin;
627         
628         drop->opcontext = WM_OP_EXEC_DEFAULT;
629         RNA_string_set(drop->ptr, "name", id->name + 2);
630 }
631
632 static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
633 {
634         ID *id = (ID *)drag->poin;
635         
636         RNA_string_set(drop->ptr, "name", id->name + 2);
637 }
638
639 static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
640 {
641         ID *id = (ID *)drag->poin;
642         
643         if (id)
644                 RNA_string_set(drop->ptr, "name", id->name + 2);
645         if (drag->path[0])
646                 RNA_string_set(drop->ptr, "filepath", drag->path);
647 }
648
649
650 /* region dropbox definition */
651 static void view3d_dropboxes(void)
652 {
653         ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
654         
655         WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
656         WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
657         WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
658         WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
659         WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
660         WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
661 }
662
663
664
665 /* type callback, not region itself */
666 static void view3d_main_area_free(ARegion *ar)
667 {
668         RegionView3D *rv3d = ar->regiondata;
669         
670         if (rv3d) {
671                 if (rv3d->localvd) MEM_freeN(rv3d->localvd);
672                 if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
673
674                 if (rv3d->ri) {
675                         // XXX          BIF_view3d_previewrender_free(rv3d);
676                 }
677
678                 if (rv3d->render_engine)
679                         RE_engine_free(rv3d->render_engine);
680                 
681                 if (rv3d->depths) {
682                         if (rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
683                         MEM_freeN(rv3d->depths);
684                 }
685                 if (rv3d->sms) {
686                         MEM_freeN(rv3d->sms);
687                 }
688                 if (rv3d->gpuoffscreen) {
689                         GPU_offscreen_free(rv3d->gpuoffscreen);
690                 }
691
692                 MEM_freeN(rv3d);
693                 ar->regiondata = NULL;
694         }
695 }
696
697 /* copy regiondata */
698 static void *view3d_main_area_duplicate(void *poin)
699 {
700         if (poin) {
701                 RegionView3D *rv3d = poin, *new;
702         
703                 new = MEM_dupallocN(rv3d);
704                 if (rv3d->localvd)
705                         new->localvd = MEM_dupallocN(rv3d->localvd);
706                 if (rv3d->clipbb)
707                         new->clipbb = MEM_dupallocN(rv3d->clipbb);
708                 
709                 new->depths = NULL;
710                 new->gpuoffscreen = NULL;
711                 new->ri = NULL;
712                 new->render_engine = NULL;
713                 new->gpd = NULL;
714                 new->sms = NULL;
715                 new->smooth_timer = NULL;
716                 
717                 return new;
718         }
719         return NULL;
720 }
721
722 static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene)
723 {
724         wmWindow *win = wmn->wm->winactive;
725         ScrArea *sa;
726         unsigned int lay_used = 0;
727         Base *base;
728
729         if (!win) return;
730
731         base = scene->base.first;
732         while (base) {
733                 lay_used |= base->lay & ((1 << 20) - 1); /* ignore localview */
734
735                 if (lay_used == (1 << 20) - 1)
736                         break;
737
738                 base = base->next;
739         }
740
741         for (sa = win->screen->areabase.first; sa; sa = sa->next) {
742                 if (sa->spacetype == SPACE_VIEW3D) {
743                         if (BLI_findindex(&sa->regionbase, ar) != -1) {
744                                 View3D *v3d = sa->spacedata.first;
745                                 v3d->lay_used = lay_used;
746                                 break;
747                         }
748                 }
749         }
750 }
751
752 static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *wmn)
753 {
754         Scene *scene = sc->scene;
755         View3D *v3d = sa->spacedata.first;
756         
757         /* context changes */
758         switch (wmn->category) {
759                 case NC_ANIMATION:
760                         switch (wmn->data) {
761                                 case ND_KEYFRAME_PROP:
762                                 case ND_NLA_ACTCHANGE:
763                                         ED_region_tag_redraw(ar);
764                                         break;
765                                 case ND_NLA:
766                                 case ND_KEYFRAME:
767                                         if (wmn->action == NA_EDITED)
768                                                 ED_region_tag_redraw(ar);
769                                         break;
770                                 case ND_ANIMCHAN:
771                                         if (wmn->action == NA_SELECTED)
772                                                 ED_region_tag_redraw(ar);
773                                         break;
774                         }
775                         break;
776                 case NC_SCENE:
777                         switch (wmn->data) {
778                                 case ND_LAYER_CONTENT:
779                                         if (wmn->reference)
780                                                 view3d_recalc_used_layers(ar, wmn, wmn->reference);
781                                         ED_region_tag_redraw(ar);
782                                         break;
783                                 case ND_FRAME:
784                                 case ND_TRANSFORM:
785                                 case ND_OB_ACTIVE:
786                                 case ND_OB_SELECT:
787                                 case ND_OB_VISIBLE:
788                                 case ND_LAYER:
789                                 case ND_RENDER_OPTIONS:
790                                 case ND_MARKERS:
791                                 case ND_MODE:
792                                         ED_region_tag_redraw(ar);
793                                         break;
794                                 case ND_WORLD:
795                                         /* handled by space_view3d_listener() for v3d access */
796                                         break;
797                         }
798                         if (wmn->action == NA_EDITED)
799                                 ED_region_tag_redraw(ar);
800                         break;
801                 case NC_OBJECT:
802                         switch (wmn->data) {
803                                 case ND_BONE_ACTIVE:
804                                 case ND_BONE_SELECT:
805                                 case ND_TRANSFORM:
806                                 case ND_POSE:
807                                 case ND_DRAW:
808                                 case ND_MODIFIER:
809                                 case ND_CONSTRAINT:
810                                 case ND_KEYS:
811                                 case ND_PARTICLE:
812                                         ED_region_tag_redraw(ar);
813                                         break;
814                         }
815                         switch (wmn->action) {
816                                 case NA_ADDED:
817                                         ED_region_tag_redraw(ar);
818                                         break;
819                         }
820                         break;
821                 case NC_GEOM:
822                         switch (wmn->data) {
823                                 case ND_DATA:
824                                 case ND_VERTEX_GROUP:
825                                 case ND_SELECT:
826                                         ED_region_tag_redraw(ar);
827                                         break;
828                         }
829                         switch (wmn->action) {
830                                 case NA_EDITED:
831                                         ED_region_tag_redraw(ar);
832                                         break;
833                         }
834                         break;
835                 case NC_GROUP:
836                         /* all group ops for now */
837                         ED_region_tag_redraw(ar);
838                         break;
839                 case NC_BRUSH:
840                         if (wmn->action == NA_EDITED)
841                                 ED_region_tag_redraw_overlay(ar);
842                         break;
843                 case NC_MATERIAL:
844                         switch (wmn->data) {
845                                 case ND_SHADING:
846                                 case ND_NODES:
847                                         if ((v3d->drawtype == OB_MATERIAL) ||
848                                             (v3d->drawtype == OB_TEXTURE &&
849                                                  (scene->gm.matmode == GAME_MAT_GLSL ||
850                                                   BKE_scene_use_new_shading_nodes(scene))))
851                                         {
852                                                 ED_region_tag_redraw(ar);
853                                         }
854                                         break;
855                                 case ND_SHADING_DRAW:
856                                 case ND_SHADING_LINKS:
857                                         ED_region_tag_redraw(ar);
858                                         break;
859                         }
860                         break;
861                 case NC_WORLD:
862                         switch (wmn->data) {
863                                 case ND_WORLD_DRAW:
864                                         /* handled by space_view3d_listener() for v3d access */
865                                         break;
866                         }
867                         break;
868                 case NC_LAMP:
869                         switch (wmn->data) {
870                                 case ND_LIGHTING:
871                                         if ((v3d->drawtype == OB_MATERIAL) ||
872                                             (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)))
873                                         {
874                                                 ED_region_tag_redraw(ar);
875                                         }
876                                         break;
877                                 case ND_LIGHTING_DRAW:
878                                         ED_region_tag_redraw(ar);
879                                         break;
880                         }
881                         break;
882                 case NC_IMAGE:
883                         /* this could be more fine grained checks if we had
884                          * more context than just the region */
885                         ED_region_tag_redraw(ar);
886                         break;
887                 case NC_TEXTURE:
888                         /* same as above */
889                         ED_region_tag_redraw(ar);
890                         break;
891                 case NC_MOVIECLIP:
892                         if (wmn->data == ND_DISPLAY)
893                                 ED_region_tag_redraw(ar);
894                         break;
895                 case NC_SPACE:
896                         if (wmn->data == ND_SPACE_VIEW3D) {
897                                 if (wmn->subtype == NS_VIEW3D_GPU) {
898                                         RegionView3D *rv3d = ar->regiondata;
899                                         rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
900                                 }
901                                 ED_region_tag_redraw(ar);
902                         }
903                         break;
904                 case NC_ID:
905                         if (wmn->action == NA_RENAME)
906                                 ED_region_tag_redraw(ar);
907                         break;
908                 case NC_SCREEN:
909                         switch (wmn->data) {
910                                 case ND_ANIMPLAY:
911                                 case ND_SKETCH:
912                                         ED_region_tag_redraw(ar);
913                                         break;
914                                 case ND_SCREENBROWSE:
915                                 case ND_SCREENDELETE:
916                                 case ND_SCREENSET:
917                                         /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
918                                         /* updates used layers only for View3D in active screen */
919                                         if (wmn->reference) {
920                                                 bScreen *sc_ref = wmn->reference;
921                                                 view3d_recalc_used_layers(ar, wmn, sc_ref->scene);
922                                         }
923                                         ED_region_tag_redraw(ar);
924                                         break;
925                         }
926
927                         break;
928                 case NC_GPENCIL:
929                         if (wmn->action == NA_EDITED)
930                                 ED_region_tag_redraw(ar);
931                         break;
932         }
933 }
934
935 /* concept is to retrieve cursor type context-less */
936 static void view3d_main_area_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
937 {
938         Scene *scene = win->screen->scene;
939
940         if (scene->obedit) {
941                 WM_cursor_set(win, CURSOR_EDIT);
942         }
943         else {
944                 WM_cursor_set(win, CURSOR_STD);
945         }
946 }
947
948 /* add handlers, stuff you only do once or on area/region changes */
949 static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
950 {
951         wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
952         
953         WM_event_add_keymap_handler(&ar->handlers, keymap);
954
955         ED_region_header_init(ar);
956 }
957
958 static void view3d_header_area_draw(const bContext *C, ARegion *ar)
959 {
960         ED_region_header(C, ar);
961 }
962
963 static void view3d_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
964 {
965         /* context changes */
966         switch (wmn->category) {
967                 case NC_SCENE:
968                         switch (wmn->data) {
969                                 case ND_FRAME:
970                                 case ND_OB_ACTIVE:
971                                 case ND_OB_SELECT:
972                                 case ND_OB_VISIBLE:
973                                 case ND_MODE:
974                                 case ND_LAYER:
975                                 case ND_TOOLSETTINGS:
976                                 case ND_LAYER_CONTENT:
977                                         ED_region_tag_redraw(ar);
978                                         break;
979                         }
980                         break;
981                 case NC_SPACE:
982                         if (wmn->data == ND_SPACE_VIEW3D)
983                                 ED_region_tag_redraw(ar);
984                         break;
985         }
986 }
987
988 /* add handlers, stuff you only do once or on area/region changes */
989 static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar)
990 {
991         wmKeyMap *keymap;
992
993         ED_region_panels_init(wm, ar);
994         
995         keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
996         WM_event_add_keymap_handler(&ar->handlers, keymap);
997 }
998
999 static void view3d_buttons_area_draw(const bContext *C, ARegion *ar)
1000 {
1001         ED_region_panels(C, ar, 1, NULL, -1);
1002 }
1003
1004 static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
1005 {
1006         /* context changes */
1007         switch (wmn->category) {
1008                 case NC_ANIMATION:
1009                         switch (wmn->data) {
1010                                 case ND_KEYFRAME_PROP:
1011                                 case ND_NLA_ACTCHANGE:
1012                                         ED_region_tag_redraw(ar);
1013                                         break;
1014                                 case ND_NLA:
1015                                 case ND_KEYFRAME:
1016                                         if (wmn->action == NA_EDITED)
1017                                                 ED_region_tag_redraw(ar);
1018                                         break;
1019                         }
1020                         break;
1021                 case NC_SCENE:
1022                         switch (wmn->data) {
1023                                 case ND_FRAME:
1024                                 case ND_OB_ACTIVE:
1025                                 case ND_OB_SELECT:
1026                                 case ND_OB_VISIBLE:
1027                                 case ND_MODE:
1028                                 case ND_LAYER:
1029                                 case ND_LAYER_CONTENT:
1030                                 case ND_TOOLSETTINGS:
1031                                         ED_region_tag_redraw(ar);
1032                                         break;
1033                         }
1034                         switch (wmn->action) {
1035                                 case NA_EDITED:
1036                                         ED_region_tag_redraw(ar);
1037                                         break;
1038                         }
1039                         break;
1040                 case NC_OBJECT:
1041                         switch (wmn->data) {
1042                                 case ND_BONE_ACTIVE:
1043                                 case ND_BONE_SELECT:
1044                                 case ND_TRANSFORM:
1045                                 case ND_POSE:
1046                                 case ND_DRAW:
1047                                 case ND_KEYS:
1048                                 case ND_MODIFIER:
1049                                         ED_region_tag_redraw(ar);
1050                                         break;
1051                         }
1052                         break;
1053                 case NC_GEOM:
1054                         switch (wmn->data) {
1055                                 case ND_DATA:
1056                                 case ND_VERTEX_GROUP:
1057                                 case ND_SELECT:
1058                                         ED_region_tag_redraw(ar);
1059                                         break;
1060                         }
1061                         if (wmn->action == NA_EDITED)
1062                                 ED_region_tag_redraw(ar);
1063                         break;
1064                 case NC_TEXTURE:
1065                 case NC_MATERIAL:
1066                         /* for brush textures */
1067                         ED_region_tag_redraw(ar);
1068                         break;
1069                 case NC_BRUSH:
1070                         if (wmn->action == NA_EDITED)
1071                                 ED_region_tag_redraw(ar);
1072                         break;
1073                 case NC_SPACE:
1074                         if (wmn->data == ND_SPACE_VIEW3D)
1075                                 ED_region_tag_redraw(ar);
1076                         break;
1077                 case NC_ID:
1078                         if (wmn->action == NA_RENAME)
1079                                 ED_region_tag_redraw(ar);
1080                         break;
1081                 case NC_GPENCIL:
1082                         if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
1083                                 ED_region_tag_redraw(ar);
1084                         break;
1085         }
1086 }
1087
1088 /* add handlers, stuff you only do once or on area/region changes */
1089 static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
1090 {
1091         wmKeyMap *keymap;
1092         
1093         ED_region_panels_init(wm, ar);
1094
1095         keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
1096         WM_event_add_keymap_handler(&ar->handlers, keymap);
1097 }
1098
1099 static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
1100 {
1101         ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
1102 }
1103
1104 static void view3d_props_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
1105 {
1106         /* context changes */
1107         switch (wmn->category) {
1108                 case NC_WM:
1109                         if (wmn->data == ND_HISTORY)
1110                                 ED_region_tag_redraw(ar);
1111                         break;
1112                 case NC_SCENE:
1113                         if (wmn->data == ND_MODE)
1114                                 ED_region_tag_redraw(ar);
1115                         break;
1116                 case NC_SPACE:
1117                         if (wmn->data == ND_SPACE_VIEW3D)
1118                                 ED_region_tag_redraw(ar);
1119                         break;
1120         }
1121 }
1122
1123 /*area (not region) level listener*/
1124 static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNotifier *wmn)
1125 {
1126         View3D *v3d = sa->spacedata.first;
1127
1128         /* context changes */
1129         switch (wmn->category) {
1130                 case NC_SCENE:
1131                         switch (wmn->data) {
1132                                 case ND_WORLD:
1133                                         if (v3d->flag2 & V3D_RENDER_OVERRIDE)
1134                                                 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
1135                                         break;
1136                         }
1137                         break;
1138                 case NC_WORLD:
1139                         switch (wmn->data) {
1140                                 case ND_WORLD_DRAW:
1141                                         if (v3d->flag2 & V3D_RENDER_OVERRIDE)
1142                                                 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
1143                                         break;
1144                         }
1145                         break;
1146                 case NC_MATERIAL:
1147                         switch (wmn->data) {
1148                                 case ND_NODES:
1149                                         if (v3d->drawtype == OB_TEXTURE)
1150                                                 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
1151                                         break;
1152                         }
1153                         break;
1154         }
1155
1156         /* removed since BKE_image_user_frame_calc is now called in view3d_draw_bgpic because screen_ops doesnt call the notifier. */
1157 #if 0
1158         if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) {
1159                 View3D *v3d = area->spacedata.first;
1160                 BGpic *bgpic = v3d->bgpicbase.first;
1161
1162                 for (; bgpic; bgpic = bgpic->next) {
1163                         if (bgpic->ima) {
1164                                 Scene *scene = wmn->reference;
1165                                 BKE_image_user_frame_calc(&bgpic->iuser, scene->r.cfra, 0);
1166                         }
1167                 }
1168         }
1169 #endif
1170 }
1171
1172 const char *view3d_context_dir[] = {
1173         "selected_objects", "selected_bases", "selected_editable_objects",
1174         "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
1175         "active_base", "active_object", NULL
1176 };
1177
1178 static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
1179 {
1180         /* fallback to the scene layer, allows duplicate and other object operators to run outside the 3d view */
1181
1182         if (CTX_data_dir(member)) {
1183                 CTX_data_dir_set(result, view3d_context_dir);
1184         }
1185         else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
1186                 View3D *v3d = CTX_wm_view3d(C);
1187                 Scene *scene = CTX_data_scene(C);
1188                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1189                 Base *base;
1190                 const bool selected_objects = CTX_data_equals(member, "selected_objects");
1191
1192                 for (base = scene->base.first; base; base = base->next) {
1193                         if ((base->flag & SELECT) && (base->lay & lay)) {
1194                                 if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
1195                                         if (selected_objects)
1196                                                 CTX_data_id_list_add(result, &base->object->id);
1197                                         else
1198                                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1199                                 }
1200                         }
1201                 }
1202                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1203                 return 1;
1204         }
1205         else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
1206                 View3D *v3d = CTX_wm_view3d(C);
1207                 Scene *scene = CTX_data_scene(C);
1208                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1209                 Base *base;
1210                 const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
1211
1212                 for (base = scene->base.first; base; base = base->next) {
1213                         if ((base->flag & SELECT) && (base->lay & lay)) {
1214                                 if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
1215                                         if (0 == BKE_object_is_libdata(base->object)) {
1216                                                 if (selected_editable_objects)
1217                                                         CTX_data_id_list_add(result, &base->object->id);
1218                                                 else
1219                                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1220                                         }
1221                                 }
1222                         }
1223                 }
1224                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1225                 return 1;
1226         }
1227         else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
1228                 View3D *v3d = CTX_wm_view3d(C);
1229                 Scene *scene = CTX_data_scene(C);
1230                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1231                 Base *base;
1232                 const bool visible_objects = CTX_data_equals(member, "visible_objects");
1233
1234                 for (base = scene->base.first; base; base = base->next) {
1235                         if (base->lay & lay) {
1236                                 if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
1237                                         if (visible_objects)
1238                                                 CTX_data_id_list_add(result, &base->object->id);
1239                                         else
1240                                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1241                                 }
1242                         }
1243                 }
1244                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1245                 return 1;
1246         }
1247         else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
1248                 View3D *v3d = CTX_wm_view3d(C);
1249                 Scene *scene = CTX_data_scene(C);
1250                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1251                 Base *base;
1252                 const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
1253
1254                 for (base = scene->base.first; base; base = base->next) {
1255                         if (base->lay & lay) {
1256                                 if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
1257                                         if (selectable_objects)
1258                                                 CTX_data_id_list_add(result, &base->object->id);
1259                                         else
1260                                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1261                                 }
1262                         }
1263                 }
1264                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1265                 return 1;
1266         }
1267         else if (CTX_data_equals(member, "active_base")) {
1268                 View3D *v3d = CTX_wm_view3d(C);
1269                 Scene *scene = CTX_data_scene(C);
1270                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1271                 if (scene->basact && (scene->basact->lay & lay)) {
1272                         Object *ob = scene->basact->object;
1273                         /* if hidden but in edit mode, we still display, can happen with animation */
1274                         if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
1275                                 CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
1276                 }
1277                 
1278                 return 1;
1279         }
1280         else if (CTX_data_equals(member, "active_object")) {
1281                 View3D *v3d = CTX_wm_view3d(C);
1282                 Scene *scene = CTX_data_scene(C);
1283                 const unsigned int lay = v3d ? v3d->lay : scene->lay;
1284                 if (scene->basact && (scene->basact->lay & lay)) {
1285                         Object *ob = scene->basact->object;
1286                         if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
1287                                 CTX_data_id_pointer_set(result, &scene->basact->object->id);
1288                 }
1289                 
1290                 return 1;
1291         }
1292         else {
1293                 return 0; /* not found */
1294         }
1295
1296         return -1; /* found but not available */
1297 }
1298
1299
1300 /* only called once, from space/spacetypes.c */
1301 void ED_spacetype_view3d(void)
1302 {
1303         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype view3d");
1304         ARegionType *art;
1305         
1306         st->spaceid = SPACE_VIEW3D;
1307         strncpy(st->name, "View3D", BKE_ST_MAXNAME);
1308         
1309         st->new = view3d_new;
1310         st->free = view3d_free;
1311         st->init = view3d_init;
1312         st->listener = space_view3d_listener;
1313         st->duplicate = view3d_duplicate;
1314         st->operatortypes = view3d_operatortypes;
1315         st->keymap = view3d_keymap;
1316         st->dropboxes = view3d_dropboxes;
1317         st->context = view3d_context;
1318         
1319         /* regions: main window */
1320         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
1321         art->regionid = RGN_TYPE_WINDOW;
1322         art->keymapflag = ED_KEYMAP_GPENCIL;
1323         art->draw = view3d_main_area_draw;
1324         art->init = view3d_main_area_init;
1325         art->exit = view3d_main_area_exit;
1326         art->free = view3d_main_area_free;
1327         art->duplicate = view3d_main_area_duplicate;
1328         art->listener = view3d_main_area_listener;
1329         art->cursor = view3d_main_area_cursor;
1330         art->lock = 1;   /* can become flag, see BKE_spacedata_draw_locks */
1331         BLI_addhead(&st->regiontypes, art);
1332         
1333         /* regions: listview/buttons */
1334         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
1335         art->regionid = RGN_TYPE_UI;
1336         art->prefsizex = 180; /* XXX */
1337         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1338         art->listener = view3d_buttons_area_listener;
1339         art->init = view3d_buttons_area_init;
1340         art->draw = view3d_buttons_area_draw;
1341         BLI_addhead(&st->regiontypes, art);
1342
1343         view3d_buttons_register(art);
1344
1345         /* regions: tool(bar) */
1346         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
1347         art->regionid = RGN_TYPE_TOOLS;
1348         art->prefsizex = 160; /* XXX */
1349         art->prefsizey = 50; /* XXX */
1350         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1351         art->listener = view3d_buttons_area_listener;
1352         art->init = view3d_tools_area_init;
1353         art->draw = view3d_tools_area_draw;
1354         BLI_addhead(&st->regiontypes, art);
1355         
1356 #if 0
1357         /* unfinished still */
1358         view3d_toolshelf_register(art);
1359 #endif
1360
1361         /* regions: tool properties */
1362         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tool properties region");
1363         art->regionid = RGN_TYPE_TOOL_PROPS;
1364         art->prefsizex = 0;
1365         art->prefsizey = 120;
1366         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1367         art->listener = view3d_props_area_listener;
1368         art->init = view3d_tools_area_init;
1369         art->draw = view3d_tools_area_draw;
1370         BLI_addhead(&st->regiontypes, art);
1371         
1372         view3d_tool_props_register(art);
1373         
1374         
1375         /* regions: header */
1376         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
1377         art->regionid = RGN_TYPE_HEADER;
1378         art->prefsizey = HEADERY;
1379         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
1380         art->listener = view3d_header_area_listener;
1381         art->init = view3d_header_area_init;
1382         art->draw = view3d_header_area_draw;
1383         BLI_addhead(&st->regiontypes, art);
1384         
1385         BKE_spacetype_register(st);
1386 }
1387