|
Blender
V2.59
|
00001 /* 00002 * $Id: space_view3d.c 37327 2011-06-09 03:56:32Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <string.h> 00035 #include <stdio.h> 00036 00037 #include "DNA_object_types.h" 00038 #include "DNA_scene_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_rand.h" 00045 #include "BLI_utildefines.h" 00046 00047 #include "BKE_object.h" 00048 #include "BKE_context.h" 00049 #include "BKE_screen.h" 00050 00051 #include "ED_space_api.h" 00052 #include "ED_screen.h" 00053 #include "ED_object.h" 00054 00055 #include "BIF_gl.h" 00056 00057 00058 #include "WM_api.h" 00059 #include "WM_types.h" 00060 00061 00062 #include "RNA_access.h" 00063 00064 #include "UI_resources.h" 00065 00066 #include "view3d_intern.h" // own include 00067 00068 /* ******************** manage regions ********************* */ 00069 00070 ARegion *view3d_has_buttons_region(ScrArea *sa) 00071 { 00072 ARegion *ar, *arnew; 00073 00074 ar= BKE_area_find_region_type(sa, RGN_TYPE_UI); 00075 if(ar) return ar; 00076 00077 /* add subdiv level; after header */ 00078 ar= BKE_area_find_region_type(sa, RGN_TYPE_HEADER); 00079 00080 /* is error! */ 00081 if(ar==NULL) return NULL; 00082 00083 arnew= MEM_callocN(sizeof(ARegion), "buttons for view3d"); 00084 00085 BLI_insertlinkafter(&sa->regionbase, ar, arnew); 00086 arnew->regiontype= RGN_TYPE_UI; 00087 arnew->alignment= RGN_ALIGN_RIGHT; 00088 00089 arnew->flag = RGN_FLAG_HIDDEN; 00090 00091 return arnew; 00092 } 00093 00094 ARegion *view3d_has_tools_region(ScrArea *sa) 00095 { 00096 ARegion *ar, *artool=NULL, *arprops=NULL, *arhead; 00097 00098 for(ar= sa->regionbase.first; ar; ar= ar->next) { 00099 if(ar->regiontype==RGN_TYPE_TOOLS) 00100 artool= ar; 00101 if(ar->regiontype==RGN_TYPE_TOOL_PROPS) 00102 arprops= ar; 00103 } 00104 00105 /* tool region hide/unhide also hides props */ 00106 if(arprops && artool) return artool; 00107 00108 if(artool==NULL) { 00109 /* add subdiv level; after header */ 00110 for(arhead= sa->regionbase.first; arhead; arhead= arhead->next) 00111 if(arhead->regiontype==RGN_TYPE_HEADER) 00112 break; 00113 00114 /* is error! */ 00115 if(arhead==NULL) return NULL; 00116 00117 artool= MEM_callocN(sizeof(ARegion), "tools for view3d"); 00118 00119 BLI_insertlinkafter(&sa->regionbase, arhead, artool); 00120 artool->regiontype= RGN_TYPE_TOOLS; 00121 artool->alignment= RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT; 00122 artool->flag = RGN_FLAG_HIDDEN; 00123 } 00124 00125 if(arprops==NULL) { 00126 /* add extra subdivided region for tool properties */ 00127 arprops= MEM_callocN(sizeof(ARegion), "tool props for view3d"); 00128 00129 BLI_insertlinkafter(&sa->regionbase, artool, arprops); 00130 arprops->regiontype= RGN_TYPE_TOOL_PROPS; 00131 arprops->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV; 00132 } 00133 00134 return artool; 00135 } 00136 00137 /* ****************************************************** */ 00138 00139 /* function to always find a regionview3d context inside 3D window */ 00140 RegionView3D *ED_view3d_context_rv3d(bContext *C) 00141 { 00142 RegionView3D *rv3d= CTX_wm_region_view3d(C); 00143 00144 if(rv3d==NULL) { 00145 ScrArea *sa =CTX_wm_area(C); 00146 if(sa && sa->spacetype==SPACE_VIEW3D) { 00147 ARegion *ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00148 if(ar) { 00149 rv3d= ar->regiondata; 00150 } 00151 } 00152 } 00153 return rv3d; 00154 } 00155 00156 /* ideally would return an rv3d but in some cases the region is needed too 00157 * so return that, the caller can then access the ar->regiondata */ 00158 ARegion *ED_view3d_context_region_unlock(bContext *C) 00159 { 00160 ScrArea *sa= CTX_wm_area(C); 00161 if(sa && sa->spacetype==SPACE_VIEW3D) { 00162 ARegion *ar= CTX_wm_region(C); 00163 if(ar) { 00164 RegionView3D *rv3d= ar->regiondata; 00165 if(rv3d && rv3d->viewlock == 0) { 00166 return ar; 00167 } 00168 else { 00169 ARegion *ar_unlock_user= NULL; 00170 ARegion *ar_unlock= NULL; 00171 for(ar= sa->regionbase.first; ar; ar= ar->next) { 00172 /* find the first unlocked rv3d */ 00173 if(ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) { 00174 rv3d= ar->regiondata; 00175 if(rv3d->viewlock == 0) { 00176 ar_unlock= ar; 00177 if(rv3d->persp==RV3D_PERSP || rv3d->persp==RV3D_CAMOB) { 00178 ar_unlock_user= ar; 00179 break; 00180 } 00181 } 00182 } 00183 } 00184 00185 /* camera/perspective view get priority when the active region is locked */ 00186 if(ar_unlock_user) return ar_unlock_user; 00187 if(ar_unlock) return ar_unlock; 00188 } 00189 } 00190 } 00191 return NULL; 00192 } 00193 00194 /* Most of the time this isn't needed since you could assume the view matrix was 00195 * set while drawing, however when functions like mesh_foreachScreenVert are 00196 * called by selection tools, we can't be sure this object was the last. 00197 * 00198 * for example, transparent objects are drawn after editmode and will cause 00199 * the rv3d mat's to change and break selection. 00200 * 00201 * 'ED_view3d_init_mats_rv3d' should be called before 00202 * view3d_project_short_clip and view3d_project_short_noclip in cases where 00203 * these functions are not used during draw_object 00204 */ 00205 void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d) 00206 { 00207 /* local viewmat and persmat, to calculate projections */ 00208 mul_m4_m4m4(rv3d->viewmatob, ob->obmat, rv3d->viewmat); 00209 mul_m4_m4m4(rv3d->persmatob, ob->obmat, rv3d->persmat); 00210 00211 /* initializes object space clipping, speeds up clip tests */ 00212 ED_view3d_local_clipping(rv3d, ob->obmat); 00213 } 00214 00215 void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d) 00216 { 00217 ED_view3d_init_mats_rv3d(ob, rv3d); 00218 00219 /* we have to multiply instead of loading viewmatob to make 00220 it work with duplis using displists, otherwise it will 00221 override the dupli-matrix */ 00222 glMultMatrixf(ob->obmat); 00223 } 00224 00225 /* ******************** default callbacks for view3d space ***************** */ 00226 00227 static SpaceLink *view3d_new(const bContext *C) 00228 { 00229 Scene *scene= CTX_data_scene(C); 00230 ARegion *ar; 00231 View3D *v3d; 00232 RegionView3D *rv3d; 00233 00234 v3d= MEM_callocN(sizeof(View3D), "initview3d"); 00235 v3d->spacetype= SPACE_VIEW3D; 00236 v3d->blockscale= 0.7f; 00237 v3d->lay= v3d->layact= 1; 00238 if(scene) { 00239 v3d->lay= v3d->layact= scene->lay; 00240 v3d->camera= scene->camera; 00241 } 00242 v3d->scenelock= TRUE; 00243 v3d->grid= 1.0f; 00244 v3d->gridlines= 16; 00245 v3d->gridsubdiv = 10; 00246 v3d->drawtype= OB_SOLID; 00247 00248 v3d->gridflag |= V3D_SHOW_X; 00249 v3d->gridflag |= V3D_SHOW_Y; 00250 v3d->gridflag |= V3D_SHOW_FLOOR; 00251 v3d->gridflag &= ~V3D_SHOW_Z; 00252 00253 v3d->flag |= V3D_SELECT_OUTLINE; 00254 00255 v3d->lens= 35.0f; 00256 v3d->near= 0.01f; 00257 v3d->far= 1000.0f; 00258 00259 v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR; 00260 v3d->twtype= V3D_MANIP_TRANSLATE; 00261 v3d->around= V3D_CENTROID; 00262 00263 /* header */ 00264 ar= MEM_callocN(sizeof(ARegion), "header for view3d"); 00265 00266 BLI_addtail(&v3d->regionbase, ar); 00267 ar->regiontype= RGN_TYPE_HEADER; 00268 ar->alignment= RGN_ALIGN_BOTTOM; 00269 00270 /* tool shelf */ 00271 ar= MEM_callocN(sizeof(ARegion), "toolshelf for view3d"); 00272 00273 BLI_addtail(&v3d->regionbase, ar); 00274 ar->regiontype= RGN_TYPE_TOOLS; 00275 ar->alignment= RGN_ALIGN_LEFT; 00276 ar->flag = RGN_FLAG_HIDDEN; 00277 00278 /* tool properties */ 00279 ar= MEM_callocN(sizeof(ARegion), "tool properties for view3d"); 00280 00281 BLI_addtail(&v3d->regionbase, ar); 00282 ar->regiontype= RGN_TYPE_TOOL_PROPS; 00283 ar->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV; 00284 ar->flag = RGN_FLAG_HIDDEN; 00285 00286 /* buttons/list view */ 00287 ar= MEM_callocN(sizeof(ARegion), "buttons for view3d"); 00288 00289 BLI_addtail(&v3d->regionbase, ar); 00290 ar->regiontype= RGN_TYPE_UI; 00291 ar->alignment= RGN_ALIGN_RIGHT; 00292 ar->flag = RGN_FLAG_HIDDEN; 00293 00294 /* main area */ 00295 ar= MEM_callocN(sizeof(ARegion), "main area for view3d"); 00296 00297 BLI_addtail(&v3d->regionbase, ar); 00298 ar->regiontype= RGN_TYPE_WINDOW; 00299 00300 ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region view3d"); 00301 rv3d= ar->regiondata; 00302 rv3d->viewquat[0]= 1.0f; 00303 rv3d->persp= RV3D_PERSP; 00304 rv3d->view= RV3D_VIEW_PERSPORTHO; 00305 rv3d->dist= 10.0; 00306 00307 return (SpaceLink *)v3d; 00308 } 00309 00310 /* not spacelink itself */ 00311 static void view3d_free(SpaceLink *sl) 00312 { 00313 View3D *vd= (View3D *) sl; 00314 00315 BGpic *bgpic; 00316 for(bgpic= vd->bgpicbase.first; bgpic; bgpic= bgpic->next) { 00317 if(bgpic->ima) bgpic->ima->id.us--; 00318 } 00319 BLI_freelistN(&vd->bgpicbase); 00320 00321 if(vd->localvd) MEM_freeN(vd->localvd); 00322 00323 if(vd->properties_storage) MEM_freeN(vd->properties_storage); 00324 } 00325 00326 00327 /* spacetype; init callback */ 00328 static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) 00329 { 00330 00331 } 00332 00333 static SpaceLink *view3d_duplicate(SpaceLink *sl) 00334 { 00335 View3D *v3do= (View3D *)sl; 00336 View3D *v3dn= MEM_dupallocN(sl); 00337 BGpic *bgpic; 00338 00339 /* clear or remove stuff from old */ 00340 00341 // XXX BIF_view3d_previewrender_free(v3do); 00342 00343 if(v3do->localvd) { 00344 v3do->localvd= NULL; 00345 v3do->properties_storage= NULL; 00346 v3do->lay= v3dn->localvd->lay; 00347 v3do->lay &= 0xFFFFFF; 00348 } 00349 00350 /* copy or clear inside new stuff */ 00351 00352 BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase); 00353 for(bgpic= v3dn->bgpicbase.first; bgpic; bgpic= bgpic->next) 00354 if(bgpic->ima) 00355 bgpic->ima->id.us++; 00356 00357 v3dn->properties_storage= NULL; 00358 00359 return (SpaceLink *)v3dn; 00360 } 00361 00362 /* add handlers, stuff you only do once or on area/region changes */ 00363 static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) 00364 { 00365 ListBase *lb; 00366 wmKeyMap *keymap; 00367 00368 /* object ops. */ 00369 00370 /* important to be before Pose keymap since they can both be enabled at once */ 00371 keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0); 00372 WM_event_add_keymap_handler(&ar->handlers, keymap); 00373 00374 /* pose is not modal, operator poll checks for this */ 00375 keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); 00376 WM_event_add_keymap_handler(&ar->handlers, keymap); 00377 00378 keymap= WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0); 00379 WM_event_add_keymap_handler(&ar->handlers, keymap); 00380 00381 keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0); 00382 WM_event_add_keymap_handler(&ar->handlers, keymap); 00383 00384 keymap= WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0); 00385 WM_event_add_keymap_handler(&ar->handlers, keymap); 00386 00387 keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0); 00388 WM_event_add_keymap_handler(&ar->handlers, keymap); 00389 00390 keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0); 00391 WM_event_add_keymap_handler(&ar->handlers, keymap); 00392 00393 keymap= WM_keymap_find(wm->defaultconf, "Mesh", 0, 0); 00394 WM_event_add_keymap_handler(&ar->handlers, keymap); 00395 00396 keymap= WM_keymap_find(wm->defaultconf, "Curve", 0, 0); 00397 WM_event_add_keymap_handler(&ar->handlers, keymap); 00398 00399 keymap= WM_keymap_find(wm->defaultconf, "Armature", 0, 0); 00400 WM_event_add_keymap_handler(&ar->handlers, keymap); 00401 00402 keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); 00403 WM_event_add_keymap_handler(&ar->handlers, keymap); 00404 00405 keymap= WM_keymap_find(wm->defaultconf, "Metaball", 0, 0); 00406 WM_event_add_keymap_handler(&ar->handlers, keymap); 00407 00408 keymap= WM_keymap_find(wm->defaultconf, "Lattice", 0, 0); 00409 WM_event_add_keymap_handler(&ar->handlers, keymap); 00410 00411 /* armature sketching needs to take over mouse */ 00412 keymap= WM_keymap_find(wm->defaultconf, "Armature Sketch", 0, 0); 00413 WM_event_add_keymap_handler(&ar->handlers, keymap); 00414 00415 keymap= WM_keymap_find(wm->defaultconf, "Particle", 0, 0); 00416 WM_event_add_keymap_handler(&ar->handlers, keymap); 00417 00418 /* editfont keymap swallows all... */ 00419 keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0); 00420 WM_event_add_keymap_handler(&ar->handlers, keymap); 00421 00422 keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0); 00423 WM_event_add_keymap_handler(&ar->handlers, keymap); 00424 00425 keymap= WM_keymap_find(wm->defaultconf, "Frames", 0, 0); 00426 WM_event_add_keymap_handler(&ar->handlers, keymap); 00427 00428 /* own keymap, last so modes can override it */ 00429 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0); 00430 WM_event_add_keymap_handler(&ar->handlers, keymap); 00431 00432 keymap= WM_keymap_find(wm->defaultconf, "3D View", SPACE_VIEW3D, 0); 00433 WM_event_add_keymap_handler(&ar->handlers, keymap); 00434 00435 /* add drop boxes */ 00436 lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW); 00437 00438 WM_event_add_dropbox_handler(&ar->handlers, lb); 00439 00440 } 00441 00442 static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) 00443 { 00444 if(drag->type==WM_DRAG_ID) { 00445 ID *id= (ID *)drag->poin; 00446 if( GS(id->name)==ID_OB ) 00447 return 1; 00448 } 00449 return 0; 00450 } 00451 00452 static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) 00453 { 00454 if(drag->type==WM_DRAG_ID) { 00455 ID *id= (ID *)drag->poin; 00456 if( GS(id->name)==ID_MA ) 00457 return 1; 00458 } 00459 return 0; 00460 } 00461 00462 static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event)) 00463 { 00464 if(drag->type==WM_DRAG_ID) { 00465 ID *id= (ID *)drag->poin; 00466 if( GS(id->name)==ID_IM ) 00467 return 1; 00468 } 00469 else if(drag->type==WM_DRAG_PATH){ 00470 if(ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ 00471 return 1; 00472 } 00473 return 0; 00474 } 00475 00476 00477 static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) 00478 { 00479 if( ED_view3d_give_base_under_cursor(C, event->mval) ) { 00480 return 0; 00481 } 00482 return view3d_ima_drop_poll(C, drag, event); 00483 } 00484 00485 static int view3d_ima_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) 00486 { 00487 if( ED_view3d_give_base_under_cursor(C, event->mval) ) { 00488 return view3d_ima_drop_poll(C, drag, event); 00489 } 00490 return 0; 00491 } 00492 00493 static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop) 00494 { 00495 ID *id= (ID *)drag->poin; 00496 PointerRNA ptr; 00497 00498 /* need to put name in sub-operator in macro */ 00499 ptr= RNA_pointer_get(drop->ptr, "OBJECT_OT_add_named"); 00500 if(ptr.data) 00501 RNA_string_set(&ptr, "name", id->name+2); 00502 else 00503 RNA_string_set(drop->ptr, "name", id->name+2); 00504 } 00505 00506 static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop) 00507 { 00508 ID *id= (ID *)drag->poin; 00509 00510 RNA_string_set(drop->ptr, "name", id->name+2); 00511 } 00512 00513 static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) 00514 { 00515 ID *id= (ID *)drag->poin; 00516 00517 if(id) 00518 RNA_string_set(drop->ptr, "name", id->name+2); 00519 if(drag->path[0]) 00520 RNA_string_set(drop->ptr, "filepath", drag->path); 00521 } 00522 00523 00524 /* region dropbox definition */ 00525 static void view3d_dropboxes(void) 00526 { 00527 ListBase *lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW); 00528 00529 WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy); 00530 WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy); 00531 WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy); 00532 WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy); 00533 } 00534 00535 00536 00537 /* type callback, not region itself */ 00538 static void view3d_main_area_free(ARegion *ar) 00539 { 00540 RegionView3D *rv3d= ar->regiondata; 00541 00542 if(rv3d) { 00543 if(rv3d->localvd) MEM_freeN(rv3d->localvd); 00544 if(rv3d->clipbb) MEM_freeN(rv3d->clipbb); 00545 00546 // XXX retopo_free_view_data(rv3d); 00547 if(rv3d->ri) { 00548 // XXX BIF_view3d_previewrender_free(rv3d); 00549 } 00550 00551 if(rv3d->depths) { 00552 if(rv3d->depths->depths) MEM_freeN(rv3d->depths->depths); 00553 MEM_freeN(rv3d->depths); 00554 } 00555 MEM_freeN(rv3d); 00556 ar->regiondata= NULL; 00557 } 00558 } 00559 00560 /* copy regiondata */ 00561 static void *view3d_main_area_duplicate(void *poin) 00562 { 00563 if(poin) { 00564 RegionView3D *rv3d= poin, *new; 00565 00566 new= MEM_dupallocN(rv3d); 00567 if(rv3d->localvd) 00568 new->localvd= MEM_dupallocN(rv3d->localvd); 00569 if(rv3d->clipbb) 00570 new->clipbb= MEM_dupallocN(rv3d->clipbb); 00571 00572 new->depths= NULL; 00573 new->ri= NULL; 00574 new->gpd= NULL; 00575 new->sms= NULL; 00576 new->smooth_timer= NULL; 00577 00578 return new; 00579 } 00580 return NULL; 00581 } 00582 00583 static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene) 00584 { 00585 wmWindow *win= wmn->wm->winactive; 00586 ScrArea *sa; 00587 unsigned int lay_used= 0; 00588 Base *base; 00589 00590 if (!win) return; 00591 00592 base= scene->base.first; 00593 while(base) { 00594 lay_used |= base->lay & ((1<<20)-1); /* ignore localview */ 00595 00596 if (lay_used == (1<<20)-1) 00597 break; 00598 00599 base= base->next; 00600 } 00601 00602 for(sa= win->screen->areabase.first; sa; sa= sa->next) { 00603 if(sa->spacetype == SPACE_VIEW3D) { 00604 if(BLI_findindex(&sa->regionbase, ar) != -1) { 00605 View3D *v3d= sa->spacedata.first; 00606 v3d->lay_used= lay_used; 00607 break; 00608 } 00609 } 00610 } 00611 } 00612 00613 static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) 00614 { 00615 bScreen *sc; 00616 00617 /* context changes */ 00618 switch(wmn->category) { 00619 case NC_ANIMATION: 00620 switch(wmn->data) { 00621 case ND_KEYFRAME_PROP: 00622 case ND_NLA_ACTCHANGE: 00623 ED_region_tag_redraw(ar); 00624 break; 00625 case ND_NLA: 00626 case ND_KEYFRAME: 00627 if (wmn->action == NA_EDITED) 00628 ED_region_tag_redraw(ar); 00629 break; 00630 case ND_ANIMCHAN: 00631 if (wmn->action == NA_SELECTED) 00632 ED_region_tag_redraw(ar); 00633 break; 00634 } 00635 break; 00636 case NC_SCENE: 00637 switch(wmn->data) { 00638 case ND_LAYER_CONTENT: 00639 view3d_recalc_used_layers(ar, wmn, wmn->reference); 00640 ED_region_tag_redraw(ar); 00641 break; 00642 case ND_FRAME: 00643 case ND_TRANSFORM: 00644 case ND_OB_ACTIVE: 00645 case ND_OB_SELECT: 00646 case ND_OB_VISIBLE: 00647 case ND_LAYER: 00648 case ND_RENDER_OPTIONS: 00649 case ND_MODE: 00650 ED_region_tag_redraw(ar); 00651 break; 00652 case ND_WORLD: 00653 /* handled by space_view3d_listener() for v3d access */ 00654 break; 00655 } 00656 if (wmn->action == NA_EDITED) 00657 ED_region_tag_redraw(ar); 00658 break; 00659 case NC_OBJECT: 00660 switch(wmn->data) { 00661 case ND_BONE_ACTIVE: 00662 case ND_BONE_SELECT: 00663 case ND_TRANSFORM: 00664 case ND_POSE: 00665 case ND_DRAW: 00666 case ND_MODIFIER: 00667 case ND_CONSTRAINT: 00668 case ND_KEYS: 00669 case ND_PARTICLE: 00670 ED_region_tag_redraw(ar); 00671 break; 00672 } 00673 switch(wmn->action) { 00674 case NA_ADDED: 00675 ED_region_tag_redraw(ar); 00676 break; 00677 } 00678 break; 00679 case NC_GEOM: 00680 switch(wmn->data) { 00681 case ND_DATA: 00682 case ND_SELECT: 00683 ED_region_tag_redraw(ar); 00684 break; 00685 } 00686 switch(wmn->action) { 00687 case NA_EDITED: 00688 ED_region_tag_redraw(ar); 00689 break; 00690 } 00691 break; 00692 case NC_GROUP: 00693 /* all group ops for now */ 00694 ED_region_tag_redraw(ar); 00695 break; 00696 case NC_BRUSH: 00697 if(wmn->action == NA_EDITED) 00698 ED_region_tag_redraw_overlay(ar); 00699 break; 00700 case NC_MATERIAL: 00701 switch(wmn->data) { 00702 case ND_SHADING_DRAW: 00703 ED_region_tag_redraw(ar); 00704 break; 00705 } 00706 break; 00707 case NC_WORLD: 00708 switch(wmn->data) { 00709 case ND_WORLD_DRAW: 00710 /* handled by space_view3d_listener() for v3d access */ 00711 break; 00712 case ND_WORLD_STARS: 00713 { 00714 RegionView3D *rv3d= ar->regiondata; 00715 if(rv3d->persp == RV3D_CAMOB) { 00716 ED_region_tag_redraw(ar); 00717 } 00718 } 00719 } 00720 break; 00721 case NC_LAMP: 00722 switch(wmn->data) { 00723 case ND_LIGHTING_DRAW: 00724 ED_region_tag_redraw(ar); 00725 break; 00726 } 00727 break; 00728 case NC_IMAGE: 00729 /* this could be more fine grained checks if we had 00730 * more context than just the region */ 00731 ED_region_tag_redraw(ar); 00732 break; 00733 case NC_TEXTURE: 00734 /* same as above */ 00735 ED_region_tag_redraw(ar); 00736 break; 00737 case NC_SPACE: 00738 if(wmn->data == ND_SPACE_VIEW3D) { 00739 if (wmn->subtype == NS_VIEW3D_GPU) { 00740 RegionView3D *rv3d= ar->regiondata; 00741 rv3d->rflag |= RV3D_GPULIGHT_UPDATE; 00742 } 00743 ED_region_tag_redraw(ar); 00744 } 00745 break; 00746 case NC_ID: 00747 if(wmn->action == NA_RENAME) 00748 ED_region_tag_redraw(ar); 00749 break; 00750 case NC_SCREEN: 00751 switch(wmn->data) { 00752 case ND_GPENCIL: 00753 case ND_ANIMPLAY: 00754 case ND_SKETCH: 00755 ED_region_tag_redraw(ar); 00756 break; 00757 case ND_SCREENBROWSE: 00758 case ND_SCREENDELETE: 00759 case ND_SCREENSET: 00760 /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ 00761 /* updates used layers only for View3D in active screen */ 00762 sc= wmn->reference; 00763 view3d_recalc_used_layers(ar, wmn, sc->scene); 00764 ED_region_tag_redraw(ar); 00765 break; 00766 } 00767 00768 break; 00769 } 00770 } 00771 00772 /* concept is to retrieve cursor type context-less */ 00773 static void view3d_main_area_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar)) 00774 { 00775 Scene *scene= win->screen->scene; 00776 00777 if(scene->obedit) { 00778 WM_cursor_set(win, CURSOR_EDIT); 00779 } 00780 else { 00781 WM_cursor_set(win, CURSOR_STD); 00782 } 00783 } 00784 00785 /* add handlers, stuff you only do once or on area/region changes */ 00786 static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar) 00787 { 00788 wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0); 00789 00790 WM_event_add_keymap_handler(&ar->handlers, keymap); 00791 00792 ED_region_header_init(ar); 00793 } 00794 00795 static void view3d_header_area_draw(const bContext *C, ARegion *ar) 00796 { 00797 ED_region_header(C, ar); 00798 } 00799 00800 static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) 00801 { 00802 /* context changes */ 00803 switch(wmn->category) { 00804 case NC_SCENE: 00805 switch(wmn->data) { 00806 case ND_FRAME: 00807 case ND_OB_ACTIVE: 00808 case ND_OB_SELECT: 00809 case ND_OB_VISIBLE: 00810 case ND_MODE: 00811 case ND_LAYER: 00812 case ND_TOOLSETTINGS: 00813 case ND_LAYER_CONTENT: 00814 ED_region_tag_redraw(ar); 00815 break; 00816 } 00817 break; 00818 case NC_SPACE: 00819 if(wmn->data == ND_SPACE_VIEW3D) 00820 ED_region_tag_redraw(ar); 00821 break; 00822 } 00823 } 00824 00825 /* add handlers, stuff you only do once or on area/region changes */ 00826 static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar) 00827 { 00828 wmKeyMap *keymap; 00829 00830 ED_region_panels_init(wm, ar); 00831 00832 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0); 00833 WM_event_add_keymap_handler(&ar->handlers, keymap); 00834 } 00835 00836 static void view3d_buttons_area_draw(const bContext *C, ARegion *ar) 00837 { 00838 ED_region_panels(C, ar, 1, NULL, -1); 00839 } 00840 00841 static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) 00842 { 00843 /* context changes */ 00844 switch(wmn->category) { 00845 case NC_ANIMATION: 00846 switch(wmn->data) { 00847 case ND_KEYFRAME_PROP: 00848 case ND_NLA_ACTCHANGE: 00849 ED_region_tag_redraw(ar); 00850 break; 00851 case ND_NLA: 00852 case ND_KEYFRAME: 00853 if (wmn->action == NA_EDITED) 00854 ED_region_tag_redraw(ar); 00855 break; 00856 } 00857 break; 00858 case NC_SCENE: 00859 switch(wmn->data) { 00860 case ND_FRAME: 00861 case ND_OB_ACTIVE: 00862 case ND_OB_SELECT: 00863 case ND_OB_VISIBLE: 00864 case ND_MODE: 00865 case ND_LAYER: 00866 case ND_LAYER_CONTENT: 00867 ED_region_tag_redraw(ar); 00868 break; 00869 } 00870 switch(wmn->action) { 00871 case NA_EDITED: 00872 ED_region_tag_redraw(ar); 00873 break; 00874 } 00875 break; 00876 case NC_OBJECT: 00877 switch(wmn->data) { 00878 case ND_BONE_ACTIVE: 00879 case ND_BONE_SELECT: 00880 case ND_TRANSFORM: 00881 case ND_POSE: 00882 case ND_DRAW: 00883 case ND_KEYS: 00884 case ND_MODIFIER: 00885 ED_region_tag_redraw(ar); 00886 break; 00887 } 00888 break; 00889 case NC_GEOM: 00890 switch(wmn->data) { 00891 case ND_DATA: 00892 case ND_SELECT: 00893 ED_region_tag_redraw(ar); 00894 break; 00895 } 00896 if (wmn->action == NA_EDITED) 00897 ED_region_tag_redraw(ar); 00898 break; 00899 case NC_TEXTURE: 00900 /* for brush textures */ 00901 ED_region_tag_redraw(ar); 00902 break; 00903 case NC_BRUSH: 00904 if(wmn->action==NA_EDITED) 00905 ED_region_tag_redraw(ar); 00906 break; 00907 case NC_SPACE: 00908 if(wmn->data == ND_SPACE_VIEW3D) 00909 ED_region_tag_redraw(ar); 00910 break; 00911 case NC_ID: 00912 if(wmn->action == NA_RENAME) 00913 ED_region_tag_redraw(ar); 00914 break; 00915 case NC_SCREEN: 00916 if(wmn->data == ND_GPENCIL) 00917 ED_region_tag_redraw(ar); 00918 break; 00919 } 00920 } 00921 00922 /* add handlers, stuff you only do once or on area/region changes */ 00923 static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar) 00924 { 00925 wmKeyMap *keymap; 00926 00927 ED_region_panels_init(wm, ar); 00928 00929 keymap= WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0); 00930 WM_event_add_keymap_handler(&ar->handlers, keymap); 00931 } 00932 00933 static void view3d_tools_area_draw(const bContext *C, ARegion *ar) 00934 { 00935 ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1); 00936 } 00937 00938 static void view3d_props_area_listener(ARegion *ar, wmNotifier *wmn) 00939 { 00940 /* context changes */ 00941 switch(wmn->category) { 00942 case NC_WM: 00943 if(wmn->data == ND_HISTORY) 00944 ED_region_tag_redraw(ar); 00945 break; 00946 case NC_SCENE: 00947 if(wmn->data == ND_MODE) 00948 ED_region_tag_redraw(ar); 00949 break; 00950 case NC_SPACE: 00951 if(wmn->data == ND_SPACE_VIEW3D) 00952 ED_region_tag_redraw(ar); 00953 break; 00954 } 00955 } 00956 00957 /*area (not region) level listener*/ 00958 static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn) 00959 { 00960 View3D *v3d = sa->spacedata.first; 00961 00962 /* context changes */ 00963 switch(wmn->category) { 00964 case NC_SCENE: 00965 switch(wmn->data) { 00966 case ND_WORLD: 00967 if(v3d->flag2 & V3D_RENDER_OVERRIDE) 00968 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); 00969 break; 00970 } 00971 break; 00972 case NC_WORLD: 00973 switch(wmn->data) { 00974 case ND_WORLD_DRAW: 00975 if(v3d->flag2 & V3D_RENDER_OVERRIDE) 00976 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); 00977 break; 00978 } 00979 break; 00980 case NC_MATERIAL: 00981 switch(wmn->data) { 00982 case ND_NODES: 00983 if(v3d->drawtype == OB_TEXTURE) 00984 ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); 00985 break; 00986 } 00987 break; 00988 } 00989 00990 #if 0 // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier. 00991 if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { 00992 View3D *v3d = area->spacedata.first; 00993 BGpic *bgpic = v3d->bgpicbase.first; 00994 00995 for (; bgpic; bgpic = bgpic->next) { 00996 if (bgpic->ima) { 00997 Scene *scene = wmn->reference; 00998 BKE_image_user_calc_frame(&bgpic->iuser, scene->r.cfra, 0); 00999 } 01000 } 01001 } 01002 #endif 01003 } 01004 01005 const char *view3d_context_dir[] = { 01006 "selected_objects", "selected_bases", "selected_editable_objects", 01007 "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", 01008 "active_base", "active_object", NULL}; 01009 01010 static int view3d_context(const bContext *C, const char *member, bContextDataResult *result) 01011 { 01012 View3D *v3d= CTX_wm_view3d(C); 01013 Scene *scene= CTX_data_scene(C); 01014 Base *base; 01015 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 */ 01016 01017 if(CTX_data_dir(member)) { 01018 CTX_data_dir_set(result, view3d_context_dir); 01019 } 01020 else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { 01021 int selected_objects= CTX_data_equals(member, "selected_objects"); 01022 01023 for(base=scene->base.first; base; base=base->next) { 01024 if((base->flag & SELECT) && (base->lay & lay)) { 01025 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { 01026 if(selected_objects) 01027 CTX_data_id_list_add(result, &base->object->id); 01028 else 01029 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); 01030 } 01031 } 01032 } 01033 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); 01034 return 1; 01035 } 01036 else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { 01037 int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects"); 01038 01039 for(base=scene->base.first; base; base=base->next) { 01040 if((base->flag & SELECT) && (base->lay & lay)) { 01041 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { 01042 if(0==object_is_libdata(base->object)) { 01043 if(selected_editable_objects) 01044 CTX_data_id_list_add(result, &base->object->id); 01045 else 01046 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); 01047 } 01048 } 01049 } 01050 } 01051 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); 01052 return 1; 01053 } 01054 else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { 01055 int visible_objects= CTX_data_equals(member, "visible_objects"); 01056 01057 for(base=scene->base.first; base; base=base->next) { 01058 if(base->lay & lay) { 01059 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { 01060 if(visible_objects) 01061 CTX_data_id_list_add(result, &base->object->id); 01062 else 01063 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); 01064 } 01065 } 01066 } 01067 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); 01068 return 1; 01069 } 01070 else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { 01071 int selectable_objects= CTX_data_equals(member, "selectable_objects"); 01072 01073 for(base=scene->base.first; base; base=base->next) { 01074 if(base->lay & lay) { 01075 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) { 01076 if(selectable_objects) 01077 CTX_data_id_list_add(result, &base->object->id); 01078 else 01079 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); 01080 } 01081 } 01082 } 01083 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); 01084 return 1; 01085 } 01086 else if(CTX_data_equals(member, "active_base")) { 01087 if(scene->basact && (scene->basact->lay & lay)) 01088 if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0) 01089 CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact); 01090 01091 return 1; 01092 } 01093 else if(CTX_data_equals(member, "active_object")) { 01094 if(scene->basact && (scene->basact->lay & lay)) 01095 if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0) 01096 CTX_data_id_pointer_set(result, &scene->basact->object->id); 01097 01098 return 1; 01099 } 01100 else { 01101 return 0; /* not found */ 01102 } 01103 01104 return -1; /* found but not available */ 01105 } 01106 01107 01108 /* only called once, from space/spacetypes.c */ 01109 void ED_spacetype_view3d(void) 01110 { 01111 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype view3d"); 01112 ARegionType *art; 01113 01114 st->spaceid= SPACE_VIEW3D; 01115 strncpy(st->name, "View3D", BKE_ST_MAXNAME); 01116 01117 st->new= view3d_new; 01118 st->free= view3d_free; 01119 st->init= view3d_init; 01120 st->listener = space_view3d_listener; 01121 st->duplicate= view3d_duplicate; 01122 st->operatortypes= view3d_operatortypes; 01123 st->keymap= view3d_keymap; 01124 st->dropboxes= view3d_dropboxes; 01125 st->context= view3d_context; 01126 01127 /* regions: main window */ 01128 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d main region"); 01129 art->regionid = RGN_TYPE_WINDOW; 01130 art->keymapflag= ED_KEYMAP_GPENCIL; 01131 art->draw= view3d_main_area_draw; 01132 art->init= view3d_main_area_init; 01133 art->free= view3d_main_area_free; 01134 art->duplicate= view3d_main_area_duplicate; 01135 art->listener= view3d_main_area_listener; 01136 art->cursor= view3d_main_area_cursor; 01137 art->lock= 1; /* can become flag, see BKE_spacedata_draw_locks */ 01138 BLI_addhead(&st->regiontypes, art); 01139 01140 /* regions: listview/buttons */ 01141 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region"); 01142 art->regionid = RGN_TYPE_UI; 01143 art->prefsizex= 180; // XXX 01144 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; 01145 art->listener= view3d_buttons_area_listener; 01146 art->init= view3d_buttons_area_init; 01147 art->draw= view3d_buttons_area_draw; 01148 BLI_addhead(&st->regiontypes, art); 01149 01150 view3d_buttons_register(art); 01151 01152 /* regions: tool(bar) */ 01153 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); 01154 art->regionid = RGN_TYPE_TOOLS; 01155 art->prefsizex= 160; // XXX 01156 art->prefsizey= 50; // XXX 01157 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; 01158 art->listener= view3d_buttons_area_listener; 01159 art->init= view3d_tools_area_init; 01160 art->draw= view3d_tools_area_draw; 01161 BLI_addhead(&st->regiontypes, art); 01162 01163 #if 0 01164 /* unfinished still */ 01165 view3d_toolshelf_register(art); 01166 #endif 01167 01168 /* regions: tool properties */ 01169 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d tool properties region"); 01170 art->regionid = RGN_TYPE_TOOL_PROPS; 01171 art->prefsizex= 0; 01172 art->prefsizey= 120; 01173 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; 01174 art->listener= view3d_props_area_listener; 01175 art->init= view3d_tools_area_init; 01176 art->draw= view3d_tools_area_draw; 01177 BLI_addhead(&st->regiontypes, art); 01178 01179 view3d_tool_props_register(art); 01180 01181 01182 /* regions: header */ 01183 art= MEM_callocN(sizeof(ARegionType), "spacetype view3d header region"); 01184 art->regionid = RGN_TYPE_HEADER; 01185 art->prefsizey= HEADERY; 01186 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; 01187 art->listener= view3d_header_area_listener; 01188 art->init= view3d_header_area_init; 01189 art->draw= view3d_header_area_draw; 01190 BLI_addhead(&st->regiontypes, art); 01191 01192 BKE_spacetype_register(st); 01193 } 01194