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