diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-21 06:51:56 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-21 06:51:56 +0400 |
commit | 1be67b60fd08f640b56db23e08ad0469318f26b3 (patch) | |
tree | 4f262c2f9ca66cfeec5fecb2be1a313ed357e057 /source/blender/editors/object/object_modifier.c | |
parent | 2881393fbb42cca81ee4d36895fc248a22c54823 (diff) |
2.5: Modifiers & Menus
* Popup menus now remember the last clicked item again.
* Modifier and File Format menus are now organized in multiple
columns with categories.
* Hook, explode, uv project modifiers have all their buttons
again with the relevant operators implemented.
* Modifiers that can't be added by the user, or don't work on
curves for example, are not in the menu anymore.
* Fix search menu overlapping buttons when near the bottom of
the screen.
* Fix uv layers search menu not working in some modifiers.
* Cleanup popup menu code a bit, layout engine is used in more
cases now instead of ugly position calculation code.
Diffstat (limited to 'source/blender/editors/object/object_modifier.c')
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 290 |
1 files changed, 203 insertions, 87 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 16900d6d894..32a1297aaf4 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -39,6 +39,7 @@ #include "DNA_object_force.h" #include "DNA_scene_types.h" +#include "BLI_arithb.h" #include "BLI_listbase.h" #include "BKE_curve.h" @@ -410,6 +411,11 @@ int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md) /***************************** OPERATORS ****************************/ +static int modifier_poll(bContext *C) +{ + return (CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier).data != NULL); +} + /************************ add modifier operator *********************/ static int modifier_add_exec(bContext *C, wmOperator *op) @@ -426,8 +432,46 @@ static int modifier_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + EnumPropertyItem *item= NULL, *md_item; + ModifierTypeInfo *mti; + Object *ob; + int totitem= 0, a; + + if(!C) /* needed for docs */ + return modifier_type_items; + + ob= CTX_data_active_object(C); + + for(a=0; modifier_type_items[a].identifier; a++) { + md_item= &modifier_type_items[a]; + + if(md_item->identifier[0]) { + mti= modifierType_getInfo(md_item->value); + + if(mti->flags & eModifierTypeFlag_NoUserAdd) + continue; + + if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) || + (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) + continue; + } + + RNA_enum_item_add(&item, &totitem, md_item); + } + + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; +} + void OBJECT_OT_modifier_add(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name= "Add Modifier"; ot->description = "Add a modifier to the active object."; @@ -436,14 +480,14 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot) /* api callbacks */ ot->invoke= WM_menu_invoke; ot->exec= modifier_add_exec; - ot->poll= ED_operator_object_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - /* XXX only some types should be here */ - RNA_def_enum(ot->srna, "type", modifier_type_items, 0, "Type", ""); + /* properties */ + prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", ""); + RNA_def_enum_funcs(prop, modifier_add_itemf); } /************************ remove modifier operator *********************/ @@ -455,7 +499,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) Object *ob= ptr.id.data; ModifierData *md= ptr.data; - if(!ob || !md || !ED_object_modifier_remove(op->reports, scene, ob, md)) + if(!ED_object_modifier_remove(op->reports, scene, ob, md)) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); @@ -471,6 +515,7 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_remove_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -485,7 +530,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) Object *ob= ptr.id.data; ModifierData *md= ptr.data; - if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md)) + if(!ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; DAG_object_flush_update(scene, ob, OB_RECALC_DATA); @@ -502,6 +547,7 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_move_up_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -533,6 +579,7 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_move_down_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -564,6 +611,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_apply_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -595,6 +643,7 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_convert_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -626,6 +675,7 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot) ot->poll= ED_operator_object_active; ot->exec= modifier_copy_exec; + ot->poll= modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -639,17 +689,15 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) Object *ob= ptr.id.data; MultiresModifierData *mmd= ptr.data; - if(mmd) { - multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - } + multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } static int multires_subdivide_poll(bContext *C) { - return NULL != CTX_data_active_object(C) && NULL == CTX_data_edit_object(C); + return (CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier).data != NULL); } void OBJECT_OT_multires_subdivide(wmOperatorType *ot) @@ -667,12 +715,12 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot) /************************ mdef bind operator *********************/ -static int modifier_mdef_bind_poll(bContext *C) +static int meshdeform_poll(bContext *C) { return CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier).data != NULL; } -static int modifier_mdef_bind_exec(bContext *C, wmOperator *op) +static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get(C, "modifier"); @@ -723,41 +771,22 @@ static int modifier_mdef_bind_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void OBJECT_OT_modifier_mdef_bind(wmOperatorType *ot) +void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) { /* identifiers */ ot->name= "Mesh Deform Bind"; ot->description = "Bind mesh to cage in mesh deform modifier."; - ot->idname= "OBJECT_OT_modifier_mdef_bind"; + ot->idname= "OBJECT_OT_meshdeform_bind"; /* api callbacks */ - ot->poll= modifier_mdef_bind_poll; - ot->exec= modifier_mdef_bind_exec; + ot->poll= meshdeform_poll; + ot->exec= meshdeform_bind_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } #if 0 -static void modifiers_add(void *ob_v, int type) -{ - Object *ob = ob_v; - ModifierTypeInfo *mti = modifierType_getInfo(type); - - if (mti->flags&eModifierTypeFlag_RequiresOriginalData) { - ModifierData *md = ob->modifiers.first; - - while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { - md = md->next; - } - - BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type)); - } else { - BLI_addtail(&ob->modifiers, modifier_new(type)); - } - ED_undo_push("Add modifier"); -} - typedef struct MenuEntry { char *name; int ID; @@ -809,89 +838,176 @@ static uiBlock *modifiers_add_menu(void *ob_v) } #endif -#if 0 -static void modifiers_clearHookOffset(bContext *C, void *ob_v, void *md_v) +/******************** hook operators ************************/ + +static int hook_poll(bContext *C) { - Object *ob = ob_v; - ModifierData *md = md_v; - HookModifierData *hmd = (HookModifierData*) md; - - if (hmd->object) { + return CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier).data != NULL; +} + +static int hook_reset_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + Object *ob= ptr.id.data; + HookModifierData *hmd= ptr.data; + + if(hmd->object) { Mat4Invert(hmd->object->imat, hmd->object->obmat); Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - ED_undo_push(C, "Clear hook offset"); } + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; } -static void modifiers_cursorHookCenter(bContext *C, void *ob_v, void *md_v) +void OBJECT_OT_hook_reset(wmOperatorType *ot) { - /* XXX - Object *ob = ob_v; - ModifierData *md = md_v; - HookModifierData *hmd = (HookModifierData*) md; + ot->name= "Hook Reset"; + ot->description= "Recalculate and and clear offset transformation."; + ot->idname= "OBJECT_OT_hook_reset"; + + ot->exec= hook_reset_exec; + ot->poll= hook_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int hook_recenter_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + Object *ob= ptr.id.data; + HookModifierData *hmd= ptr.data; + float bmat[3][3], imat[3][3]; + + Mat3CpyMat4(bmat, ob->obmat); + Mat3Inv(imat, bmat); + + VECSUB(hmd->cent, scene->cursor, ob->obmat[3]); + Mat3MulVecfl(imat, hmd->cent); + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} - if(G.vd) { - float *curs = give_cursor(); - float bmat[3][3], imat[3][3]; +void OBJECT_OT_hook_recenter(wmOperatorType *ot) +{ + ot->name= "Hook Recenter"; + ot->description= "Set hook center to cursor position."; + ot->idname= "OBJECT_OT_hook_recenter"; - where_is_object(ob); + ot->exec= hook_recenter_exec; + ot->poll= hook_poll; - Mat3CpyMat4(bmat, ob->obmat); - Mat3Inv(imat, bmat); + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int hook_select_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + Object *ob= ptr.id.data; + HookModifierData *hmd= ptr.data; - curs= give_cursor(); - hmd->cent[0]= curs[0]-ob->obmat[3][0]; - hmd->cent[1]= curs[1]-ob->obmat[3][1]; - hmd->cent[2]= curs[2]-ob->obmat[3][2]; - Mat3MulVecfl(imat, hmd->cent); + object_hook_select(ob, hmd); - ED_undo_push(C, "Hook cursor center"); - }*/ + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + + return OPERATOR_FINISHED; } -static void modifiers_selectHook(bContext *C, void *ob_v, void *md_v) +void OBJECT_OT_hook_select(wmOperatorType *ot) { - /* XXX ModifierData *md = md_v; - HookModifierData *hmd = (HookModifierData*) md; + ot->name= "Hook Select"; + ot->description= "Selects effected vertices on mesh."; + ot->idname= "OBJECT_OT_hook_select"; - hook_select(hmd);*/ + ot->exec= hook_select_exec; + ot->poll= hook_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static void modifiers_reassignHook(bContext *C, void *ob_v, void *md_v) +static int hook_assign_exec(bContext *C, wmOperator *op) { - /* XXX ModifierData *md = md_v; - HookModifierData *hmd = (HookModifierData*) md; + Scene *scene= CTX_data_scene(C); + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + Object *ob= ptr.id.data; + HookModifierData *hmd= ptr.data; float cent[3]; - int *indexar, tot, ok; char name[32]; + int *indexar, tot; - ok= hook_getIndexArray(&tot, &indexar, name, cent); + if(!object_hook_index_array(ob, &tot, &indexar, name, cent)) { + BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group"); + return OPERATOR_CANCELLED; + } - if (!ok) { - uiPupMenuError(C, "Requires selected vertices or active Vertex Group"); - } else { - if (hmd->indexar) { - MEM_freeN(hmd->indexar); - } + if(hmd->indexar) + MEM_freeN(hmd->indexar); + + VECCOPY(hmd->cent, cent); + hmd->indexar= indexar; + hmd->totindex= tot; - VECCOPY(hmd->cent, cent); - hmd->indexar = indexar; - hmd->totindex = tot; - }*/ + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; } -void modifiers_explodeFacepa(bContext *C, void *arg1, void *arg2) +void OBJECT_OT_hook_assign(wmOperatorType *ot) { - ExplodeModifierData *emd=arg1; + ot->name= "Hook Assign"; + ot->description= "Reassigns selected vertices to hook."; + ot->idname= "OBJECT_OT_hook_assign"; - emd->flag |= eExplodeFlag_CalcFaces; + ot->exec= hook_assign_exec; + ot->poll= hook_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -void modifiers_explodeDelVg(bContext *C, void *arg1, void *arg2) +/****************** explode refresh operator *********************/ + +static int explode_refresh_poll(bContext *C) { - ExplodeModifierData *emd=arg1; - emd->vgroup = 0; + return CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier).data != NULL; } -#endif +static int explode_refresh_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier); + Object *ob= ptr.id.data; + ExplodeModifierData *emd= ptr.data; + + emd->flag |= eExplodeFlag_CalcFaces; + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_explode_refresh(wmOperatorType *ot) +{ + ot->name= "Explode Refresh"; + ot->description= "Refresh data in the Explode modifier."; + ot->idname= "OBJECT_OT_explode_refresh"; + + ot->exec= explode_refresh_exec; + ot->poll= explode_refresh_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} |