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