4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
29 /** \file blender/editors/space_view3d/space_view3d.c
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
40 #include "MEM_guardedalloc.h"
42 #include "BLI_blenlib.h"
45 #include "BLI_utildefines.h"
47 #include "BKE_object.h"
48 #include "BKE_context.h"
49 #include "BKE_screen.h"
51 #include "ED_space_api.h"
52 #include "ED_screen.h"
53 #include "ED_object.h"
62 #include "RNA_access.h"
64 #include "UI_resources.h"
66 #include "view3d_intern.h" // own include
68 /* ******************** manage regions ********************* */
70 ARegion *view3d_has_buttons_region(ScrArea *sa)
74 for(ar= sa->regionbase.first; ar; ar= ar->next)
75 if(ar->regiontype==RGN_TYPE_UI)
78 /* add subdiv level; after header */
79 for(ar= sa->regionbase.first; ar; ar= ar->next)
80 if(ar->regiontype==RGN_TYPE_HEADER)
84 if(ar==NULL) return NULL;
86 arnew= MEM_callocN(sizeof(ARegion), "buttons for view3d");
88 BLI_insertlinkafter(&sa->regionbase, ar, arnew);
89 arnew->regiontype= RGN_TYPE_UI;
90 arnew->alignment= RGN_ALIGN_RIGHT;
92 arnew->flag = RGN_FLAG_HIDDEN;
97 ARegion *view3d_has_tools_region(ScrArea *sa)
99 ARegion *ar, *artool=NULL, *arprops=NULL, *arhead;
101 for(ar= sa->regionbase.first; ar; ar= ar->next) {
102 if(ar->regiontype==RGN_TYPE_TOOLS)
104 if(ar->regiontype==RGN_TYPE_TOOL_PROPS)
108 /* tool region hide/unhide also hides props */
109 if(arprops && artool) return artool;
112 /* add subdiv level; after header */
113 for(arhead= sa->regionbase.first; arhead; arhead= arhead->next)
114 if(arhead->regiontype==RGN_TYPE_HEADER)
118 if(arhead==NULL) return NULL;
120 artool= MEM_callocN(sizeof(ARegion), "tools for view3d");
122 BLI_insertlinkafter(&sa->regionbase, arhead, artool);
123 artool->regiontype= RGN_TYPE_TOOLS;
124 artool->alignment= RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT;
125 artool->flag = RGN_FLAG_HIDDEN;
129 /* add extra subdivided region for tool properties */
130 arprops= MEM_callocN(sizeof(ARegion), "tool props for view3d");
132 BLI_insertlinkafter(&sa->regionbase, artool, arprops);
133 arprops->regiontype= RGN_TYPE_TOOL_PROPS;
134 arprops->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
140 /* ****************************************************** */
142 /* function to always find a regionview3d context inside 3D window */
143 RegionView3D *ED_view3d_context_rv3d(bContext *C)
145 RegionView3D *rv3d= CTX_wm_region_view3d(C);
148 ScrArea *sa =CTX_wm_area(C);
149 if(sa && sa->spacetype==SPACE_VIEW3D) {
151 for(ar= sa->regionbase.first; ar; ar= ar->next)
152 if(ar->regiontype==RGN_TYPE_WINDOW)
153 return ar->regiondata;
159 /* Most of the time this isn't needed since you could assume the view matrix was
160 * set while drawing, however when functions like mesh_foreachScreenVert are
161 * called by selection tools, we can't be sure this object was the last.
163 * for example, transparent objects are drawn after editmode and will cause
164 * the rv3d mat's to change and break selection.
166 * 'ED_view3d_init_mats_rv3d' should be called before
167 * view3d_project_short_clip and view3d_project_short_noclip in cases where
168 * these functions are not used during draw_object
170 void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
172 /* local viewmat and persmat, to calculate projections */
173 mul_m4_m4m4(rv3d->viewmatob, ob->obmat, rv3d->viewmat);
174 mul_m4_m4m4(rv3d->persmatob, ob->obmat, rv3d->persmat);
176 /* we have to multiply instead of loading viewmatob to make
177 it work with duplis using displists, otherwise it will
178 override the dupli-matrix */
179 glMultMatrixf(ob->obmat);
181 /* initializes object space clipping, speeds up clip tests */
182 ED_view3d_local_clipping(rv3d, ob->obmat);
185 /* ******************** default callbacks for view3d space ***************** */
187 static SpaceLink *view3d_new(const bContext *C)
189 Scene *scene= CTX_data_scene(C);
194 v3d= MEM_callocN(sizeof(View3D), "initview3d");
195 v3d->spacetype= SPACE_VIEW3D;
196 v3d->blockscale= 0.7f;
197 v3d->lay= v3d->layact= 1;
199 v3d->lay= v3d->layact= scene->lay;
200 v3d->camera= scene->camera;
202 v3d->scenelock= TRUE;
205 v3d->gridsubdiv = 10;
206 v3d->drawtype= OB_SOLID;
208 v3d->gridflag |= V3D_SHOW_X;
209 v3d->gridflag |= V3D_SHOW_Y;
210 v3d->gridflag |= V3D_SHOW_FLOOR;
211 v3d->gridflag &= ~V3D_SHOW_Z;
213 v3d->flag |= V3D_SELECT_OUTLINE;
219 v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
220 v3d->twtype= V3D_MANIP_TRANSLATE;
221 v3d->around= V3D_CENTROID;
224 ar= MEM_callocN(sizeof(ARegion), "header for view3d");
226 BLI_addtail(&v3d->regionbase, ar);
227 ar->regiontype= RGN_TYPE_HEADER;
228 ar->alignment= RGN_ALIGN_BOTTOM;
231 ar= MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
233 BLI_addtail(&v3d->regionbase, ar);
234 ar->regiontype= RGN_TYPE_TOOLS;
235 ar->alignment= RGN_ALIGN_LEFT;
236 ar->flag = RGN_FLAG_HIDDEN;
238 /* tool properties */
239 ar= MEM_callocN(sizeof(ARegion), "tool properties for view3d");
241 BLI_addtail(&v3d->regionbase, ar);
242 ar->regiontype= RGN_TYPE_TOOL_PROPS;
243 ar->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
244 ar->flag = RGN_FLAG_HIDDEN;
246 /* buttons/list view */
247 ar= MEM_callocN(sizeof(ARegion), "buttons for view3d");
249 BLI_addtail(&v3d->regionbase, ar);
250 ar->regiontype= RGN_TYPE_UI;
251 ar->alignment= RGN_ALIGN_RIGHT;
252 ar->flag = RGN_FLAG_HIDDEN;
255 ar= MEM_callocN(sizeof(ARegion), "main area for view3d");
257 BLI_addtail(&v3d->regionbase, ar);
258 ar->regiontype= RGN_TYPE_WINDOW;
260 ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region view3d");
261 rv3d= ar->regiondata;
262 rv3d->viewquat[0]= 1.0f;
263 rv3d->persp= RV3D_PERSP;
264 rv3d->view= RV3D_VIEW_PERSPORTHO;
267 return (SpaceLink *)v3d;
270 /* not spacelink itself */
271 static void view3d_free(SpaceLink *sl)
273 View3D *vd= (View3D *) sl;
276 for(bgpic= vd->bgpicbase.first; bgpic; bgpic= bgpic->next) {
277 if(bgpic->ima) bgpic->ima->id.us--;
279 BLI_freelistN(&vd->bgpicbase);
281 if(vd->localvd) MEM_freeN(vd->localvd);
283 if(vd->properties_storage) MEM_freeN(vd->properties_storage);
287 /* spacetype; init callback */
288 static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
293 static SpaceLink *view3d_duplicate(SpaceLink *sl)
295 View3D *v3do= (View3D *)sl;
296 View3D *v3dn= MEM_dupallocN(sl);
299 /* clear or remove stuff from old */
301 // XXX BIF_view3d_previewrender_free(v3do);
305 v3do->properties_storage= NULL;
306 v3do->lay= v3dn->localvd->lay;
307 v3do->lay &= 0xFFFFFF;
310 /* copy or clear inside new stuff */
312 BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
313 for(bgpic= v3dn->bgpicbase.first; bgpic; bgpic= bgpic->next)
317 v3dn->properties_storage= NULL;
319 return (SpaceLink *)v3dn;
322 /* add handlers, stuff you only do once or on area/region changes */
323 static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
330 /* important to be before Pose keymap since they can both be enabled at once */
331 keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0);
332 WM_event_add_keymap_handler(&ar->handlers, keymap);
334 /* pose is not modal, operator poll checks for this */
335 keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
336 WM_event_add_keymap_handler(&ar->handlers, keymap);
338 keymap= WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
339 WM_event_add_keymap_handler(&ar->handlers, keymap);
341 keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
342 WM_event_add_keymap_handler(&ar->handlers, keymap);
344 keymap= WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0);
345 WM_event_add_keymap_handler(&ar->handlers, keymap);
347 keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0);
348 WM_event_add_keymap_handler(&ar->handlers, keymap);
350 keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0);
351 WM_event_add_keymap_handler(&ar->handlers, keymap);
353 keymap= WM_keymap_find(wm->defaultconf, "Mesh", 0, 0);
354 WM_event_add_keymap_handler(&ar->handlers, keymap);
356 keymap= WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
357 WM_event_add_keymap_handler(&ar->handlers, keymap);
359 keymap= WM_keymap_find(wm->defaultconf, "Armature", 0, 0);
360 WM_event_add_keymap_handler(&ar->handlers, keymap);
362 keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
363 WM_event_add_keymap_handler(&ar->handlers, keymap);
365 keymap= WM_keymap_find(wm->defaultconf, "Metaball", 0, 0);
366 WM_event_add_keymap_handler(&ar->handlers, keymap);
368 keymap= WM_keymap_find(wm->defaultconf, "Lattice", 0, 0);
369 WM_event_add_keymap_handler(&ar->handlers, keymap);
371 /* armature sketching needs to take over mouse */
372 keymap= WM_keymap_find(wm->defaultconf, "Armature Sketch", 0, 0);
373 WM_event_add_keymap_handler(&ar->handlers, keymap);
375 keymap= WM_keymap_find(wm->defaultconf, "Particle", 0, 0);
376 WM_event_add_keymap_handler(&ar->handlers, keymap);
378 /* editfont keymap swallows all... */
379 keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0);
380 WM_event_add_keymap_handler(&ar->handlers, keymap);
382 keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0);
383 WM_event_add_keymap_handler(&ar->handlers, keymap);
385 keymap= WM_keymap_find(wm->defaultconf, "Frames", 0, 0);
386 WM_event_add_keymap_handler(&ar->handlers, keymap);
388 /* own keymap, last so modes can override it */
389 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
390 WM_event_add_keymap_handler(&ar->handlers, keymap);
392 keymap= WM_keymap_find(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
393 WM_event_add_keymap_handler(&ar->handlers, keymap);
396 lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
398 WM_event_add_dropbox_handler(&ar->handlers, lb);
402 static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
404 if(drag->type==WM_DRAG_ID) {
405 ID *id= (ID *)drag->poin;
406 if( GS(id->name)==ID_OB )
412 static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
414 if(drag->type==WM_DRAG_ID) {
415 ID *id= (ID *)drag->poin;
416 if( GS(id->name)==ID_MA )
422 static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
424 if(drag->type==WM_DRAG_ID) {
425 ID *id= (ID *)drag->poin;
426 if( GS(id->name)==ID_IM )
429 else if(drag->type==WM_DRAG_PATH){
430 if(ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */
437 static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
439 if( ED_view3d_give_base_under_cursor(C, event->mval) ) {
442 return view3d_ima_drop_poll(C, drag, event);
445 static int view3d_ima_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
447 if( ED_view3d_give_base_under_cursor(C, event->mval) ) {
448 return view3d_ima_drop_poll(C, drag, event);
453 static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
455 ID *id= (ID *)drag->poin;
458 /* need to put name in sub-operator in macro */
459 ptr= RNA_pointer_get(drop->ptr, "OBJECT_OT_add_named");
461 RNA_string_set(&ptr, "name", id->name+2);
463 RNA_string_set(drop->ptr, "name", id->name+2);
466 static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
468 ID *id= (ID *)drag->poin;
470 RNA_string_set(drop->ptr, "name", id->name+2);
473 static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
475 ID *id= (ID *)drag->poin;
478 RNA_string_set(drop->ptr, "name", id->name+2);
480 RNA_string_set(drop->ptr, "filepath", drag->path);
484 /* region dropbox definition */
485 static void view3d_dropboxes(void)
487 ListBase *lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
489 WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy);
490 WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
491 WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy);
492 WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
497 /* type callback, not region itself */
498 static void view3d_main_area_free(ARegion *ar)
500 RegionView3D *rv3d= ar->regiondata;
503 if(rv3d->localvd) MEM_freeN(rv3d->localvd);
504 if(rv3d->clipbb) MEM_freeN(rv3d->clipbb);
506 // XXX retopo_free_view_data(rv3d);
508 // XXX BIF_view3d_previewrender_free(rv3d);
512 if(rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
513 MEM_freeN(rv3d->depths);
516 ar->regiondata= NULL;
520 /* copy regiondata */
521 static void *view3d_main_area_duplicate(void *poin)
524 RegionView3D *rv3d= poin, *new;
526 new= MEM_dupallocN(rv3d);
528 new->localvd= MEM_dupallocN(rv3d->localvd);
530 new->clipbb= MEM_dupallocN(rv3d->clipbb);
536 new->smooth_timer= NULL;
543 static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene)
545 wmWindow *win= wmn->wm->winactive;
547 unsigned int lay_used= 0;
552 base= scene->base.first;
554 lay_used |= base->lay & ((1<<20)-1); /* ignore localview */
556 if (lay_used == (1<<20)-1)
562 for(sa= win->screen->areabase.first; sa; sa= sa->next) {
563 if(sa->spacetype == SPACE_VIEW3D) {
564 if(BLI_findindex(&sa->regionbase, ar) != -1) {
565 View3D *v3d= sa->spacedata.first;
566 v3d->lay_used= lay_used;
573 static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
577 /* context changes */
578 switch(wmn->category) {
581 case ND_KEYFRAME_PROP:
582 case ND_NLA_ACTCHANGE:
583 ED_region_tag_redraw(ar);
587 if (wmn->action == NA_EDITED)
588 ED_region_tag_redraw(ar);
591 if (wmn->action == NA_SELECTED)
592 ED_region_tag_redraw(ar);
598 case ND_LAYER_CONTENT:
599 view3d_recalc_used_layers(ar, wmn, wmn->reference);
600 ED_region_tag_redraw(ar);
608 case ND_RENDER_OPTIONS:
610 ED_region_tag_redraw(ar);
613 /* handled by space_view3d_listener() for v3d access */
616 if (wmn->action == NA_EDITED)
617 ED_region_tag_redraw(ar);
630 ED_region_tag_redraw(ar);
633 switch(wmn->action) {
635 ED_region_tag_redraw(ar);
643 ED_region_tag_redraw(ar);
646 switch(wmn->action) {
648 ED_region_tag_redraw(ar);
653 /* all group ops for now */
654 ED_region_tag_redraw(ar);
657 if(wmn->action == NA_EDITED)
658 ED_region_tag_redraw_overlay(ar);
662 case ND_SHADING_DRAW:
663 ED_region_tag_redraw(ar);
670 /* handled by space_view3d_listener() for v3d access */
674 RegionView3D *rv3d= ar->regiondata;
675 if(rv3d->persp == RV3D_CAMOB) {
676 ED_region_tag_redraw(ar);
683 case ND_LIGHTING_DRAW:
684 ED_region_tag_redraw(ar);
689 /* this could be more fine grained checks if we had
690 * more context than just the region */
691 ED_region_tag_redraw(ar);
695 ED_region_tag_redraw(ar);
698 if(wmn->data == ND_SPACE_VIEW3D) {
699 if (wmn->subtype == NS_VIEW3D_GPU) {
700 RegionView3D *rv3d= ar->regiondata;
701 rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
703 ED_region_tag_redraw(ar);
707 if(wmn->action == NA_RENAME)
708 ED_region_tag_redraw(ar);
715 ED_region_tag_redraw(ar);
717 case ND_SCREENBROWSE:
718 case ND_SCREENDELETE:
720 /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
721 /* updates used layers only for View3D in active screen */
723 view3d_recalc_used_layers(ar, wmn, sc->scene);
724 ED_region_tag_redraw(ar);
732 /* concept is to retrieve cursor type context-less */
733 static void view3d_main_area_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
735 Scene *scene= win->screen->scene;
738 WM_cursor_set(win, CURSOR_EDIT);
741 WM_cursor_set(win, CURSOR_STD);
745 /* add handlers, stuff you only do once or on area/region changes */
746 static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
748 wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
750 WM_event_add_keymap_handler(&ar->handlers, keymap);
752 ED_region_header_init(ar);
755 static void view3d_header_area_draw(const bContext *C, ARegion *ar)
757 ED_region_header(C, ar);
760 static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn)
762 /* context changes */
763 switch(wmn->category) {
772 case ND_TOOLSETTINGS:
773 case ND_LAYER_CONTENT:
774 ED_region_tag_redraw(ar);
779 if(wmn->data == ND_SPACE_VIEW3D)
780 ED_region_tag_redraw(ar);
785 /* add handlers, stuff you only do once or on area/region changes */
786 static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar)
790 ED_region_panels_init(wm, ar);
792 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
793 WM_event_add_keymap_handler(&ar->handlers, keymap);
796 static void view3d_buttons_area_draw(const bContext *C, ARegion *ar)
798 ED_region_panels(C, ar, 1, NULL, -1);
801 static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
803 /* context changes */
804 switch(wmn->category) {
807 case ND_KEYFRAME_PROP:
808 case ND_NLA_ACTCHANGE:
809 ED_region_tag_redraw(ar);
813 if (wmn->action == NA_EDITED)
814 ED_region_tag_redraw(ar);
826 case ND_LAYER_CONTENT:
827 ED_region_tag_redraw(ar);
830 switch(wmn->action) {
832 ED_region_tag_redraw(ar);
845 ED_region_tag_redraw(ar);
853 ED_region_tag_redraw(ar);
856 if (wmn->action == NA_EDITED)
857 ED_region_tag_redraw(ar);
860 /* for brush textures */
861 ED_region_tag_redraw(ar);
864 if(wmn->action==NA_EDITED)
865 ED_region_tag_redraw(ar);
868 if(wmn->data == ND_SPACE_VIEW3D)
869 ED_region_tag_redraw(ar);
872 if(wmn->action == NA_RENAME)
873 ED_region_tag_redraw(ar);
876 if(wmn->data == ND_GPENCIL)
877 ED_region_tag_redraw(ar);
882 /* add handlers, stuff you only do once or on area/region changes */
883 static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
887 ED_region_panels_init(wm, ar);
889 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
890 WM_event_add_keymap_handler(&ar->handlers, keymap);
893 static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
895 ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
898 static void view3d_props_area_listener(ARegion *ar, wmNotifier *wmn)
900 /* context changes */
901 switch(wmn->category) {
903 if(wmn->data == ND_HISTORY)
904 ED_region_tag_redraw(ar);
907 if(wmn->data == ND_MODE)
908 ED_region_tag_redraw(ar);
911 if(wmn->data == ND_SPACE_VIEW3D)
912 ED_region_tag_redraw(ar);
917 /*area (not region) level listener*/
918 static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn)
920 View3D *v3d = sa->spacedata.first;
922 /* context changes */
923 switch(wmn->category) {
927 if(v3d->flag2 & V3D_RENDER_OVERRIDE)
928 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
935 if(v3d->flag2 & V3D_RENDER_OVERRIDE)
936 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
943 #if 0 // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier.
944 if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) {
945 View3D *v3d = area->spacedata.first;
946 BGpic *bgpic = v3d->bgpicbase.first;
948 for (; bgpic; bgpic = bgpic->next) {
950 Scene *scene = wmn->reference;
951 BKE_image_user_calc_frame(&bgpic->iuser, scene->r.cfra, 0);
958 const char *view3d_context_dir[] = {
959 "selected_objects", "selected_bases", "selected_editable_objects",
960 "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
961 "active_base", "active_object", NULL};
963 static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
965 View3D *v3d= CTX_wm_view3d(C);
966 Scene *scene= CTX_data_scene(C);
968 unsigned int lay = v3d ? v3d->lay:scene->lay; /* fallback to the scene layer, allows duplicate and other oject operators to run outside the 3d view */
970 if(CTX_data_dir(member)) {
971 CTX_data_dir_set(result, view3d_context_dir);
973 else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
974 int selected_objects= CTX_data_equals(member, "selected_objects");
976 for(base=scene->base.first; base; base=base->next) {
977 if((base->flag & SELECT) && (base->lay & lay)) {
978 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
980 CTX_data_id_list_add(result, &base->object->id);
982 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
986 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
989 else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
990 int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
992 for(base=scene->base.first; base; base=base->next) {
993 if((base->flag & SELECT) && (base->lay & lay)) {
994 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
995 if(0==object_is_libdata(base->object)) {
996 if(selected_editable_objects)
997 CTX_data_id_list_add(result, &base->object->id);
999 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1004 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1007 else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
1008 int visible_objects= CTX_data_equals(member, "visible_objects");
1010 for(base=scene->base.first; base; base=base->next) {
1011 if(base->lay & lay) {
1012 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
1014 CTX_data_id_list_add(result, &base->object->id);
1016 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1020 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1023 else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
1024 int selectable_objects= CTX_data_equals(member, "selectable_objects");
1026 for(base=scene->base.first; base; base=base->next) {
1027 if(base->lay & lay) {
1028 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) {
1029 if(selectable_objects)
1030 CTX_data_id_list_add(result, &base->object->id);
1032 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
1036 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
1039 else if(CTX_data_equals(member, "active_base")) {
1040 if(scene->basact && (scene->basact->lay & lay))
1041 if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
1042 CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
1046 else if(CTX_data_equals(member, "active_object")) {
1047 if(scene->basact && (scene->basact->lay & lay))
1048 if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
1049 CTX_data_id_pointer_set(result, &scene->basact->object->id);
1054 return 0; /* not found */
1057 return -1; /* found but not available */
1061 /* only called once, from space/spacetypes.c */
1062 void ED_spacetype_view3d(void)
1064 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype view3d");
1067 st->spaceid= SPACE_VIEW3D;
1068 strncpy(st->name, "View3D", BKE_ST_MAXNAME);
1070 st->new= view3d_new;
1071 st->free= view3d_free;
1072 st->init= view3d_init;
1073 st->listener = space_view3d_listener;
1074 st->duplicate= view3d_duplicate;
1075 st->operatortypes= view3d_operatortypes;
1076 st->keymap= view3d_keymap;
1077 st->dropboxes= view3d_dropboxes;
1078 st->context= view3d_context;
1080 /* regions: main window */
1081 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
1082 art->regionid = RGN_TYPE_WINDOW;
1083 art->keymapflag= ED_KEYMAP_GPENCIL;
1084 art->draw= view3d_main_area_draw;
1085 art->init= view3d_main_area_init;
1086 art->free= view3d_main_area_free;
1087 art->duplicate= view3d_main_area_duplicate;
1088 art->listener= view3d_main_area_listener;
1089 art->cursor= view3d_main_area_cursor;
1090 art->lock= 1; /* can become flag, see BKE_spacedata_draw_locks */
1091 BLI_addhead(&st->regiontypes, art);
1093 /* regions: listview/buttons */
1094 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
1095 art->regionid = RGN_TYPE_UI;
1096 art->prefsizex= 180; // XXX
1097 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
1098 art->listener= view3d_buttons_area_listener;
1099 art->init= view3d_buttons_area_init;
1100 art->draw= view3d_buttons_area_draw;
1101 BLI_addhead(&st->regiontypes, art);
1103 view3d_buttons_register(art);
1105 /* regions: tool(bar) */
1106 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
1107 art->regionid = RGN_TYPE_TOOLS;
1108 art->prefsizex= 160; // XXX
1109 art->prefsizey= 50; // XXX
1110 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
1111 art->listener= view3d_buttons_area_listener;
1112 art->init= view3d_tools_area_init;
1113 art->draw= view3d_tools_area_draw;
1114 BLI_addhead(&st->regiontypes, art);
1117 /* unfinished still */
1118 view3d_toolshelf_register(art);
1121 /* regions: tool properties */
1122 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d tool properties region");
1123 art->regionid = RGN_TYPE_TOOL_PROPS;
1125 art->prefsizey= 120;
1126 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
1127 art->listener= view3d_props_area_listener;
1128 art->init= view3d_tools_area_init;
1129 art->draw= view3d_tools_area_draw;
1130 BLI_addhead(&st->regiontypes, art);
1132 view3d_tool_props_register(art);
1135 /* regions: header */
1136 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
1137 art->regionid = RGN_TYPE_HEADER;
1138 art->prefsizey= HEADERY;
1139 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
1140 art->listener= view3d_header_area_listener;
1141 art->init= view3d_header_area_init;
1142 art->draw= view3d_header_area_draw;
1143 BLI_addhead(&st->regiontypes, art);
1145 BKE_spacetype_register(st);