|
Blender
V2.59
|
00001 /* 00002 * $Id: view3d_header.c 38855 2011-07-30 15:45:27Z ton $ 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) 2004-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 #include <stdlib.h> 00037 00038 #include "DNA_scene_types.h" 00039 #include "DNA_object_types.h" 00040 00041 #include "RNA_access.h" 00042 00043 #include "MEM_guardedalloc.h" 00044 00045 #include "BLI_math.h" 00046 #include "BLI_blenlib.h" 00047 #include "BLI_editVert.h" 00048 #include "BLI_utildefines.h" 00049 00050 #include "BKE_context.h" 00051 #include "BKE_depsgraph.h" 00052 #include "BKE_effect.h" 00053 #include "BKE_main.h" 00054 #include "BKE_mesh.h" 00055 #include "BKE_modifier.h" 00056 #include "BKE_paint.h" 00057 #include "BKE_screen.h" 00058 00059 #include "ED_mesh.h" 00060 #include "ED_util.h" 00061 #include "ED_screen.h" 00062 #include "ED_transform.h" 00063 #include "ED_types.h" 00064 00065 #include "WM_api.h" 00066 #include "WM_types.h" 00067 00068 #include "RNA_define.h" 00069 #include "RNA_enum_types.h" 00070 00071 #include "UI_interface.h" 00072 #include "UI_resources.h" 00073 00074 #include "view3d_intern.h" 00075 00076 00077 /* View3d->modeselect 00078 * This is a bit of a dodgy hack to enable a 'mode' menu with icons+labels 00079 * rather than those buttons. 00080 * I know the implementation's not good - it's an experiment to see if this 00081 * approach would work well 00082 * 00083 * This can be cleaned when I make some new 'mode' icons. 00084 */ 00085 00086 #define TEST_EDITMESH if(obedit==0) return; \ 00087 if( (v3d->lay & obedit->lay)==0 ) return; 00088 00089 /* view3d handler codes */ 00090 #define VIEW3D_HANDLER_BACKGROUND 1 00091 #define VIEW3D_HANDLER_PROPERTIES 2 00092 #define VIEW3D_HANDLER_OBJECT 3 00093 #define VIEW3D_HANDLER_PREVIEW 4 00094 #define VIEW3D_HANDLER_MULTIRES 5 00095 #define VIEW3D_HANDLER_TRANSFORM 6 00096 #define VIEW3D_HANDLER_GREASEPENCIL 7 00097 #define VIEW3D_HANDLER_BONESKETCH 8 00098 00099 /* end XXX ************* */ 00100 00101 static void do_view3d_header_buttons(bContext *C, void *arg, int event); 00102 00103 #define B_SCENELOCK 101 00104 #define B_FULL 102 00105 #define B_HOME 103 00106 #define B_VIEWBUT 104 00107 #define B_PERSP 105 00108 #define B_MODESELECT 108 00109 #define B_SEL_VERT 110 00110 #define B_SEL_EDGE 111 00111 #define B_SEL_FACE 112 00112 #define B_MAN_TRANS 116 00113 #define B_MAN_ROT 117 00114 #define B_MAN_SCALE 118 00115 #define B_NDOF 119 00116 #define B_MAN_MODE 120 00117 #define B_REDR 122 00118 #define B_NOP 123 00119 00120 // XXX quickly ported across 00121 static void handle_view3d_lock(bContext *C) 00122 { 00123 Main *bmain= CTX_data_main(C); 00124 Scene *scene= CTX_data_scene(C); 00125 ScrArea *sa= CTX_wm_area(C); 00126 View3D *v3d= CTX_wm_view3d(C); 00127 00128 if (v3d != NULL && sa != NULL) { 00129 if(v3d->localvd==NULL && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) { 00130 /* copy to scene */ 00131 scene->lay= v3d->lay; 00132 scene->layact= v3d->layact; 00133 scene->camera= v3d->camera; 00134 00135 /* not through notifiery, listener don't have context 00136 and non-open screens or spaces need to be updated too */ 00137 BKE_screen_view3d_main_sync(&bmain->screen, scene); 00138 00139 /* notifiers for scene update */ 00140 WM_event_add_notifier(C, NC_SCENE|ND_LAYER, scene); 00141 } 00142 } 00143 } 00144 00145 /* layer code is on three levels actually: 00146 - here for operator 00147 - uiTemplateLayers in interface/ code for buttons 00148 - ED_view3d_scene_layer_set for RNA 00149 */ 00150 static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d) 00151 { 00152 /* sanity check - when in editmode disallow switching the editmode layer off since its confusing 00153 * an alternative would be to always draw the editmode object. */ 00154 if(scene->obedit && (scene->obedit->lay & v3d->lay)==0) { 00155 int bit; 00156 for(bit=0; bit<32; bit++) { 00157 if(scene->obedit->lay & (1<<bit)) { 00158 v3d->lay |= 1<<bit; 00159 break; 00160 } 00161 } 00162 } 00163 } 00164 00165 static int view3d_layers_exec(bContext *C, wmOperator *op) 00166 { 00167 Scene *scene= CTX_data_scene(C); 00168 ScrArea *sa= CTX_wm_area(C); 00169 View3D *v3d= sa->spacedata.first; 00170 int nr= RNA_int_get(op->ptr, "nr"); 00171 int toggle= RNA_boolean_get(op->ptr, "toggle"); 00172 00173 if(nr < 0) 00174 return OPERATOR_CANCELLED; 00175 00176 if(nr == 0) { 00177 /* all layers */ 00178 if(!v3d->layact) 00179 v3d->layact= 1; 00180 00181 if (toggle && v3d->lay == ((1<<20)-1)) { 00182 /* return to active layer only */ 00183 v3d->lay = v3d->layact; 00184 00185 view3d_layers_editmode_ensure(scene, v3d); 00186 } 00187 else { 00188 v3d->lay |= (1<<20)-1; 00189 } 00190 } 00191 else { 00192 int bit; 00193 nr--; 00194 00195 if(RNA_boolean_get(op->ptr, "extend")) { 00196 if(toggle && v3d->lay & (1<<nr) && (v3d->lay & ~(1<<nr))) 00197 v3d->lay &= ~(1<<nr); 00198 else 00199 v3d->lay |= (1<<nr); 00200 } else { 00201 v3d->lay = (1<<nr); 00202 } 00203 00204 view3d_layers_editmode_ensure(scene, v3d); 00205 00206 /* set active layer, ensure to always have one */ 00207 if(v3d->lay & (1<<nr)) 00208 v3d->layact= 1<<nr; 00209 else if((v3d->lay & v3d->layact)==0) { 00210 for(bit=0; bit<32; bit++) { 00211 if(v3d->lay & (1<<bit)) { 00212 v3d->layact= 1<<bit; 00213 break; 00214 } 00215 } 00216 } 00217 } 00218 00219 if(v3d->scenelock) handle_view3d_lock(C); 00220 00221 DAG_on_visible_update(CTX_data_main(C), FALSE); 00222 00223 ED_area_tag_redraw(sa); 00224 00225 return OPERATOR_FINISHED; 00226 } 00227 00228 /* applies shift and alt, lazy coding or ok? :) */ 00229 /* the local per-keymap-entry keymap will solve it */ 00230 static int view3d_layers_invoke(bContext *C, wmOperator *op, wmEvent *event) 00231 { 00232 if(event->ctrl || event->oskey) 00233 return OPERATOR_PASS_THROUGH; 00234 00235 if(event->shift) 00236 RNA_boolean_set(op->ptr, "extend", 1); 00237 00238 if(event->alt) { 00239 int nr= RNA_int_get(op->ptr, "nr") + 10; 00240 RNA_int_set(op->ptr, "nr", nr); 00241 } 00242 view3d_layers_exec(C, op); 00243 00244 return OPERATOR_FINISHED; 00245 } 00246 00247 static int view3d_layers_poll(bContext *C) 00248 { 00249 return (ED_operator_view3d_active(C) && CTX_wm_view3d(C)->localvd==NULL); 00250 } 00251 00252 void VIEW3D_OT_layers(wmOperatorType *ot) 00253 { 00254 /* identifiers */ 00255 ot->name= "Layers"; 00256 ot->description= "Toggle layer(s) visibility"; 00257 ot->idname= "VIEW3D_OT_layers"; 00258 00259 /* api callbacks */ 00260 ot->invoke= view3d_layers_invoke; 00261 ot->exec= view3d_layers_exec; 00262 ot->poll= view3d_layers_poll; 00263 00264 /* flags */ 00265 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00266 00267 RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20); 00268 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers"); 00269 RNA_def_boolean(ot->srna, "toggle", 1, "Toggle", "Toggle the layer"); 00270 } 00271 00272 static char *view3d_modeselect_pup(Scene *scene) 00273 { 00274 Object *ob= OBACT; 00275 static char string[256]; 00276 static char formatstr[] = "|%s %%x%d %%i%d"; 00277 char *str = string; 00278 00279 str += sprintf(str, "Mode: %%t"); 00280 00281 str += sprintf(str, formatstr, "Object Mode", OB_MODE_OBJECT, ICON_OBJECT_DATA); 00282 00283 if(ob==NULL || ob->data==NULL) return string; 00284 if(ob->id.lib || ((ID *)ob->data)->lib) return string; 00285 00286 /* if active object is editable */ 00287 if ( ((ob->type == OB_MESH) 00288 || (ob->type == OB_CURVE) || (ob->type == OB_SURF) || (ob->type == OB_FONT) 00289 || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) { 00290 00291 str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); 00292 } 00293 else if (ob->type == OB_ARMATURE) { 00294 if (ob->mode & OB_MODE_POSE) 00295 str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT|OB_MODE_POSE, ICON_EDITMODE_HLT); 00296 else 00297 str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); 00298 } 00299 00300 if (ob->type == OB_MESH) { 00301 00302 str += sprintf(str, formatstr, "Sculpt Mode", OB_MODE_SCULPT, ICON_SCULPTMODE_HLT); 00303 str += sprintf(str, formatstr, "Vertex Paint", OB_MODE_VERTEX_PAINT, ICON_VPAINT_HLT); 00304 str += sprintf(str, formatstr, "Texture Paint", OB_MODE_TEXTURE_PAINT, ICON_TPAINT_HLT); 00305 str += sprintf(str, formatstr, "Weight Paint", OB_MODE_WEIGHT_PAINT, ICON_WPAINT_HLT); 00306 } 00307 00308 00309 /* if active object is an armature */ 00310 if (ob->type==OB_ARMATURE) { 00311 str += sprintf(str, formatstr, "Pose Mode", OB_MODE_POSE, ICON_POSE_HLT); 00312 } 00313 00314 if (ob->particlesystem.first || modifiers_findByType(ob, eModifierType_Cloth) || modifiers_findByType(ob, eModifierType_Softbody)) { 00315 str += sprintf(str, formatstr, "Particle Mode", OB_MODE_PARTICLE_EDIT, ICON_PARTICLEMODE); 00316 } 00317 (void)str; 00318 return (string); 00319 } 00320 00321 00322 static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event) 00323 { 00324 wmWindow *win= CTX_wm_window(C); 00325 ToolSettings *ts= CTX_data_tool_settings(C); 00326 ScrArea *sa= CTX_wm_area(C); 00327 View3D *v3d= sa->spacedata.first; 00328 Object *obedit = CTX_data_edit_object(C); 00329 EditMesh *em= NULL; 00330 int ctrl= win->eventstate->ctrl, shift= win->eventstate->shift; 00331 PointerRNA props_ptr; 00332 00333 if(obedit && obedit->type==OB_MESH) { 00334 em= BKE_mesh_get_editmesh((Mesh *)obedit->data); 00335 } 00336 /* watch it: if sa->win does not exist, check that when calling direct drawing routines */ 00337 00338 switch(event) { 00339 case B_REDR: 00340 ED_area_tag_redraw(sa); 00341 break; 00342 00343 case B_MODESELECT: 00344 WM_operator_properties_create(&props_ptr, "OBJECT_OT_mode_set"); 00345 RNA_enum_set(&props_ptr, "mode", v3d->modeselect); 00346 WM_operator_name_call(C, "OBJECT_OT_mode_set", WM_OP_EXEC_REGION_WIN, &props_ptr); 00347 WM_operator_properties_free(&props_ptr); 00348 break; 00349 00350 case B_SEL_VERT: 00351 if(em) { 00352 if(shift==0 || em->selectmode==0) 00353 em->selectmode= SCE_SELECT_VERTEX; 00354 ts->selectmode= em->selectmode; 00355 EM_selectmode_set(em); 00356 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); 00357 ED_undo_push(C, "Selectmode Set: Vertex"); 00358 } 00359 break; 00360 case B_SEL_EDGE: 00361 if(em) { 00362 if(shift==0 || em->selectmode==0){ 00363 if( (em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX){ 00364 if(ctrl) EM_convertsel(em, SCE_SELECT_VERTEX,SCE_SELECT_EDGE); 00365 } 00366 em->selectmode = SCE_SELECT_EDGE; 00367 } 00368 ts->selectmode= em->selectmode; 00369 EM_selectmode_set(em); 00370 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); 00371 ED_undo_push(C, "Selectmode Set: Edge"); 00372 } 00373 break; 00374 case B_SEL_FACE: 00375 if(em) { 00376 if( shift==0 || em->selectmode==0){ 00377 if( ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){ 00378 if(ctrl) 00379 EM_convertsel(em, (em->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE); 00380 } 00381 em->selectmode = SCE_SELECT_FACE; 00382 } 00383 ts->selectmode= em->selectmode; 00384 EM_selectmode_set(em); 00385 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); 00386 ED_undo_push(C, "Selectmode Set: Face"); 00387 } 00388 break; 00389 00390 case B_MAN_TRANS: 00391 if( shift==0 || v3d->twtype==0) { 00392 v3d->twtype= V3D_MANIP_TRANSLATE; 00393 } 00394 ED_area_tag_redraw(sa); 00395 break; 00396 case B_MAN_ROT: 00397 if( shift==0 || v3d->twtype==0) { 00398 v3d->twtype= V3D_MANIP_ROTATE; 00399 } 00400 ED_area_tag_redraw(sa); 00401 break; 00402 case B_MAN_SCALE: 00403 if( shift==0 || v3d->twtype==0) { 00404 v3d->twtype= V3D_MANIP_SCALE; 00405 } 00406 ED_area_tag_redraw(sa); 00407 break; 00408 case B_NDOF: 00409 ED_area_tag_redraw(sa); 00410 break; 00411 case B_MAN_MODE: 00412 ED_area_tag_redraw(sa); 00413 break; 00414 default: 00415 break; 00416 } 00417 00418 if(obedit && obedit->type==OB_MESH) 00419 BKE_mesh_end_editmesh(obedit->data, em); 00420 } 00421 00422 /* Returns the icon associated with an object mode */ 00423 static int object_mode_icon(int mode) 00424 { 00425 EnumPropertyItem *item = object_mode_items; 00426 00427 while(item->name != NULL) { 00428 if(item->value == mode) 00429 return item->icon; 00430 ++item; 00431 } 00432 00433 return ICON_OBJECT_DATAMODE; 00434 } 00435 00436 void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) 00437 { 00438 Object *obedit = CTX_data_edit_object(C); 00439 uiBlock *block= uiLayoutGetBlock(layout); 00440 00441 uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); 00442 00443 if(obedit && (obedit->type == OB_MESH)) { 00444 EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); 00445 uiLayout *row; 00446 00447 row= uiLayoutRow(layout, 1); 00448 block= uiLayoutGetBlock(row); 00449 uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode"); 00450 uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode"); 00451 uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode"); 00452 00453 BKE_mesh_end_editmesh(obedit->data, em); 00454 } 00455 } 00456 00457 void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) 00458 { 00459 bScreen *screen= CTX_wm_screen(C); 00460 ScrArea *sa= CTX_wm_area(C); 00461 View3D *v3d= sa->spacedata.first; 00462 Scene *scene= CTX_data_scene(C); 00463 ToolSettings *ts= CTX_data_tool_settings(C); 00464 PointerRNA v3dptr, toolsptr, sceneptr; 00465 Object *ob= OBACT; 00466 Object *obedit = CTX_data_edit_object(C); 00467 uiBlock *block; 00468 uiLayout *row; 00469 const float dpi_fac= UI_DPI_FAC; 00470 00471 RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr); 00472 RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr); 00473 RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr); 00474 00475 block= uiLayoutGetBlock(layout); 00476 uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); 00477 00478 /* other buttons: */ 00479 uiBlockSetEmboss(block, UI_EMBOSS); 00480 00481 /* mode */ 00482 if(ob) 00483 v3d->modeselect = ob->mode; 00484 else 00485 v3d->modeselect = OB_MODE_OBJECT; 00486 00487 uiBlockBeginAlign(block); 00488 uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene) , 00489 0,0,126 * dpi_fac, UI_UNIT_Y, &(v3d->modeselect), 0, 0, 0, 0, "Mode"); 00490 uiBlockEndAlign(block); 00491 00492 /* Draw type */ 00493 uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00494 00495 if (obedit==NULL && ((ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)))) { 00496 /* Manipulators aren't used in weight paint mode */ 00497 00498 PointerRNA meshptr; 00499 00500 RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); 00501 uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00502 } else { 00503 const char *str_menu; 00504 00505 row= uiLayoutRow(layout, 1); 00506 uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00507 uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00508 00509 /* Transform widget / manipulators */ 00510 row= uiLayoutRow(layout, 1); 00511 uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00512 block= uiLayoutGetBlock(row); 00513 00514 if(v3d->twflag & V3D_USE_MANIPULATOR) { 00515 uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode"); 00516 uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode"); 00517 uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode"); 00518 } 00519 00520 if (v3d->twmode > (BIF_countTransformOrientation(C) - 1) + V3D_MANIP_CUSTOM) { 00521 v3d->twmode = 0; 00522 } 00523 00524 str_menu = BIF_menustringTransformOrientation(C, "Orientation"); 00525 uiDefButC(block, MENU, B_MAN_MODE, str_menu,0,0,70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation"); 00526 MEM_freeN((void *)str_menu); 00527 } 00528 00529 if(obedit==NULL && v3d->localvd==NULL) { 00530 unsigned int ob_lay = ob ? ob->lay : 0; 00531 00532 /* Layers */ 00533 if (v3d->scenelock) 00534 uiTemplateLayers(layout, &sceneptr, "layers", &v3dptr, "layers_used", ob_lay); 00535 else 00536 uiTemplateLayers(layout, &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); 00537 00538 /* Scene lock */ 00539 uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); 00540 } 00541 00542 uiTemplateEditModeSelection(layout, C); 00543 } 00544