diff options
author | Matt Ebb <matt@mke3.net> | 2009-11-22 09:20:56 +0300 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2009-11-22 09:20:56 +0300 |
commit | 8e76e2d09c388383cd1ed34ab30699068a5b7fdb (patch) | |
tree | 1ecbc7a28fdfa25b957aa552fbcb668559d2dcfd | |
parent | bb43bee5f54a2a82d0714182469cfc2c8f05b2b4 (diff) |
* Re-implemented/refactored 3D View hooks menu.
Now shares the same operators as the modifier buttons, works context-sensitive, and uses Python menu too.
* Cleanups/tweaks in 3D View vertex group menu
-rw-r--r-- | release/scripts/ui/space_view3d.py | 39 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_hook.c | 647 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 22 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 151 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 15 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 51 |
7 files changed, 468 insertions, 463 deletions
diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 48d3ea6689a..6f7d97b828a 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -746,9 +746,40 @@ class VIEW3D_MT_hook(bpy.types.Menu): def draw(self, context): layout = self.layout layout.operator_context = 'EXEC_AREA' - layout.items_enumO("object.hook_add", "type") - # layout.itemS() - # Other operators still need porting + layout.itemO("object.hook_add_newob") + layout.itemO("object.hook_add_selob") + + if [mod.type == 'HOOK' for mod in context.active_object.modifiers]: + layout.itemS() + layout.item_menu_enumO("object.hook_assign", "modifier") + layout.item_menu_enumO("object.hook_remove", "modifier") + layout.itemS() + layout.item_menu_enumO("object.hook_select", "modifier") + layout.item_menu_enumO("object.hook_reset", "modifier") + layout.item_menu_enumO("object.hook_recenter", "modifier") + + +class VIEW3D_MT_vertex_group(bpy.types.Menu): + bl_label = "Vertex Groups" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'EXEC_AREA' + layout.item_booleanO("object.vertex_group_assign", "new", True, text="Assign to New Group") + + ob = context.active_object + if ob.mode == 'EDIT': + if ob.vertex_groups and ob.active_vertex_group: + layout.itemS() + layout.itemO("object.vertex_group_assign", text="Assign to Active Group") + layout.itemO("object.vertex_group_remove_from", text="Remove from Active Group") + layout.item_booleanO("object.vertex_group_remove_from", "all", True, text="Remove from All") + layout.itemS() + + if ob.vertex_groups and ob.active_vertex_group: + layout.item_menu_enumO("object.vertex_group_set_active", "group", text="Set Active Group") + layout.itemO("object.vertex_group_remove", text="Remove Active Group") + layout.item_booleanO("object.vertex_group_remove", "all", True, text="Remove All Groups") # ********** Sculpt menu ********** @@ -1062,6 +1093,7 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): layout.itemS() + layout.itemM("VIEW3D_MT_vertex_group") layout.itemM("VIEW3D_MT_hook") @@ -1830,6 +1862,7 @@ bpy.types.register(VIEW3D_MT_make_single_user) bpy.types.register(VIEW3D_MT_make_links) bpy.types.register(VIEW3D_MT_hook) +bpy.types.register(VIEW3D_MT_vertex_group) bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index d436bcb207c..dfc4ba8c6b8 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -297,9 +297,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY); - // TODO: this should probably be made to a menu instead... - WM_keymap_add_item(keymap, "OBJECT_OT_vertex_group_menu", GKEY, KM_PRESS, KM_CTRL, 0); - /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_specials", WKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_faces", FKEY, KM_PRESS, KM_CTRL, 0); @@ -307,7 +304,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_vertices", VKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_uv_map", UKEY, KM_PRESS, 0, 0); - + WM_keymap_add_menu(keymap, "VIEW3D_MT_vertex_group", GKEY, KM_PRESS, KM_CTRL, 0); + ED_object_generic_keymap(keyconf, keymap, TRUE); } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index d2c5a14b589..e4b62f58902 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -35,6 +35,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -45,12 +46,15 @@ #include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" +#include "BKE_action.h" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_scene.h" #include "RNA_define.h" #include "RNA_access.h" @@ -59,13 +63,15 @@ #include "ED_mesh.h" #include "ED_object.h" #include "ED_view3d.h" +#include "ED_screen.h" #include "WM_types.h" #include "WM_api.h" -#include "object_intern.h" +#include "UI_interface.h" +#include "UI_resources.h" -/* XXX operators for this are not implemented yet */ +#include "object_intern.h" static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent) { @@ -286,7 +292,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo return totvert; } -int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r) +static int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r) { *indexar= NULL; *tot= 0; @@ -368,7 +374,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) } } -void object_hook_select(Object *ob, HookModifierData *hmd) +static void object_hook_select(Object *ob, HookModifierData *hmd) { if (hmd->indexar == NULL) return; @@ -379,281 +385,440 @@ void object_hook_select(Object *ob, HookModifierData *hmd) else if(ob->type==OB_SURF) select_editcurve_hook(ob, hmd); } +static Object *add_hook_object_new(Scene *scene, Object *obedit) +{ + Base *base, *basedit; + Object *ob; + + ob= add_object(scene, OB_EMPTY); + + basedit = object_in_scene(obedit, scene); + base = object_in_scene(ob, scene); + base->lay = ob->lay = obedit->lay; + + /* icky, add_object sets new base as active. + * so set it back to the original edit object */ + scene->basact = basedit; + + return ob; +} + -void add_hook(Scene *scene, View3D *v3d, int mode) +static void add_hook_object(Scene *scene, Object *obedit, Object *ob, int mode) { - ModifierData *md = NULL; + ModifierData *md=NULL; HookModifierData *hmd = NULL; - Object *ob=NULL; - Object *obedit= scene->obedit; // XXX get from context - - if(obedit==NULL) return; - - /* preconditions */ - if(mode==2) { /* selected object */ - Base *base; - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - ob= base->object; - break; - } - } - } - if(ob==NULL) { - // XXX error("Requires selected Object"); - return; - } - } - else if(mode!=1) { - int maxlen=0, a, nr; - char *cp; - - /* make pupmenu with hooks */ - for(md=obedit->modifiers.first; md; md= md->next) { - if (md->type==eModifierType_Hook) - maxlen+=32; - } - - if(maxlen==0) { - // XXX error("Object has no hooks yet"); - return; - } - - cp= MEM_callocN(maxlen+32, "temp string"); - if(mode==3) strcpy(cp, "Remove %t|"); - else if(mode==4) strcpy(cp, "Reassign %t|"); - else if(mode==5) strcpy(cp, "Select %t|"); - else if(mode==6) strcpy(cp, "Clear Offset %t|"); - - for(md=obedit->modifiers.first; md; md= md->next) { - if (md->type==eModifierType_Hook) { - strcat(cp, md->name); - strcat(cp, " |"); - } - } - - nr= 0; // XXX pupmenu(cp); - MEM_freeN(cp); - - if(nr<1) return; + float cent[3]; + int tot, ok, *indexar; + char name[32]; + + ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); + + if (!ok) return; // XXX error("Requires selected vertices or active Vertex Group"); + + if (mode==OBJECT_ADDHOOK_NEWOB && !ob) { - a= 1; - for(md=obedit->modifiers.first; md; md=md->next) { - if (md->type==eModifierType_Hook) { - if(a==nr) break; - a++; - } - } + ob = add_hook_object_new(scene, obedit); - hmd = (HookModifierData*) md; - ob= hmd->object; + /* transform cent to global coords for loc */ + mul_v3_m4v3(ob->loc, obedit->obmat, cent); + } + + md = obedit->modifiers.first; + while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { + md = md->next; } + + hmd = (HookModifierData*) modifier_new(eModifierType_Hook); + BLI_insertlinkbefore(&obedit->modifiers, md, hmd); + sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); + modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); + + hmd->object= ob; + hmd->indexar= indexar; + copy_v3_v3(hmd->cent, cent); + hmd->totindex= tot; + BLI_strncpy(hmd->name, name, 32); + + /* matrix calculus */ + /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ + /* (parentinv ) */ + where_is_object(scene, ob); + + invert_m4_m4(ob->imat, ob->obmat); + /* apparently this call goes from right to left... */ + mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, + NULL, NULL, NULL, NULL, NULL); + + DAG_scene_sort(scene); +} - /* do it, new hooks or reassign */ - if(mode==1 || mode==2 || mode==4) { - float cent[3]; - int tot, ok, *indexar; - char name[32]; - - ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); - - if(ok==0) { - // XXX error("Requires selected vertices or active Vertex Group"); - } - else { - - if(mode==1) { - Base *base= BASACT, *newbase; - - ob= add_object(scene, OB_EMPTY); - /* set layers OK */ - newbase= BASACT; - newbase->lay= base->lay; - ob->lay= newbase->lay; - - /* transform cent to global coords for loc */ - mul_v3_m4v3(ob->loc, obedit->obmat, cent); - - /* restore, add_object sets active */ - BASACT= base; - } - /* if mode is 2 or 4, ob has been set */ - - /* new hook */ - if(mode==1 || mode==2) { - ModifierData *md = obedit->modifiers.first; - - while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { - md = md->next; - } - - hmd = (HookModifierData*) modifier_new(eModifierType_Hook); - BLI_insertlinkbefore(&obedit->modifiers, md, hmd); - sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); - modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); - } - else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */ - - hmd->object= ob; - hmd->indexar= indexar; - copy_v3_v3(hmd->cent, cent); - hmd->totindex= tot; - BLI_strncpy(hmd->name, name, 32); - - // TODO: need to take into account bone targets here too now... - if(mode==1 || mode==2) { - /* matrix calculus */ - /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ - /* (parentinv ) */ - - where_is_object(scene, ob); - - invert_m4_m4(ob->imat, ob->obmat); - /* apparently this call goes from right to left... */ - mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, - NULL, NULL, NULL, NULL, NULL); - } +static int object_add_hook_selob_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + Object *obsel=NULL; + + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) + { + if (ob != obedit) { + obsel = ob; + break; } } - else if(mode==3) { /* remove */ - BLI_remlink(&obedit->modifiers, md); - modifier_free(md); - } - else if(mode==5) { /* select */ - // FIXME: this is now OBJECT_OT_hook_select - object_hook_select(obedit, hmd); - } - else if(mode==6) { /* clear offset */ - // FIXME: this is now OBJECT_OT_hook_reset operator - where_is_object(scene, ob); /* ob is hook->parent */ - - invert_m4_m4(ob->imat, ob->obmat); - /* this call goes from right to left... */ - mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, - NULL, NULL, NULL, NULL, NULL); + CTX_DATA_END; + + if (!obsel) { + BKE_report(op->reports, RPT_ERROR, "Can't add hook with no other selected objects."); + return OPERATOR_CANCELLED; } - - DAG_scene_sort(scene); + + add_hook_object(scene, obedit, obsel, OBJECT_ADDHOOK_SELOB); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + return OPERATOR_FINISHED; } -void add_hook_menu(Scene *scene, View3D *v3d) +void OBJECT_OT_hook_add_selobj(wmOperatorType *ot) { - Object *obedit= scene->obedit; // XXX get from context - int mode; + /* identifiers */ + ot->name= "Hook to Selected Object"; + ot->description= "Hook selected vertices to the first selected Object."; + ot->idname= "OBJECT_OT_hook_add_selob"; - if(obedit==NULL) return; + /* api callbacks */ + ot->exec= object_add_hook_selob_exec; + ot->poll= ED_operator_editmesh; - if(modifiers_findByType(obedit, eModifierType_Hook)) - mode= 0; // XXX pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6"); - else - mode= 0; // XXX pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2"); + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} - if(mode<1) return; - - /* do operations */ - add_hook(scene, v3d, mode); +static int object_add_hook_newob_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + + add_hook_object(scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + return OPERATOR_FINISHED; } -void hookmenu(Scene *scene, View3D *v3d) +void OBJECT_OT_hook_add_newobj(wmOperatorType *ot) { - /* only called in object mode */ - short event, changed=0; - Object *ob; - Base *base; - ModifierData *md; - HookModifierData *hmd; - - event= 0; // XXX pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2"); - if (event==-1) return; - if (event==2 && !(v3d)) { - // XXX error("Cannot perform this operation without a 3d view"); - return; + /* identifiers */ + ot->name= "Hook to New Object"; + ot->description= "Hook selected vertices to the first selected Object."; + ot->idname= "OBJECT_OT_hook_add_newob"; + + /* api callbacks */ + ot->exec= object_add_hook_newob_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static EnumPropertyItem hook_mod_items[]= { +{0, NULL, 0, NULL, NULL}}; + +static int object_hook_remove_exec(bContext *C, wmOperator *op) +{ + int num= RNA_enum_get(op->ptr, "modifier"); + Object *ob=NULL; + HookModifierData *hmd=NULL; + + ob = CTX_data_edit_object(C); + hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); + + if (!ob || !hmd) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); + return OPERATOR_CANCELLED; } - for (base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - for (md = base->object->modifiers.first; md; md=md->next) { - if (md->type==eModifierType_Hook) { - ob = base->object; - hmd = (HookModifierData*) md; - - /* - * Copied from modifiers_cursorHookCenter and - * modifiers_clearHookOffset, should consolidate - * */ - - if (event==1) { - if(hmd->object) { - invert_m4_m4(hmd->object->imat, hmd->object->obmat); - mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - - changed= 1; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } else { - float *curs = give_cursor(scene, v3d); - float bmat[3][3], imat[3][3]; - - where_is_object(scene, ob); - - copy_m3_m4(bmat, ob->obmat); - invert_m3_m3(imat, bmat); - - curs= give_cursor(scene, v3d); - 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]; - mul_m3_v3(imat, hmd->cent); - - changed= 1; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } - } + /* remove functionality */ + + BLI_remlink(&ob->modifiers, (ModifierData *)hmd); + modifier_free((ModifierData *)hmd); + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +static EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *ob = CTX_data_edit_object(C); + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + ModifierData *md = NULL; + int a, totitem= 0; + + if(!ob) + return hook_mod_items; + + for(a=0, md=ob->modifiers.first; md; md= md->next, a++) { + if (md->type==eModifierType_Hook) { + tmp.value= a; + tmp.icon = ICON_HOOK; + tmp.identifier= md->name; + tmp.name= md->name; + RNA_enum_item_add(&item, &totitem, &tmp); } } - if (changed) { - } + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; } -static int object_add_hook_exec(bContext *C, wmOperator *op) +void OBJECT_OT_hook_remove(wmOperatorType *ot) { - Scene *scene= CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Remove Hook"; + ot->idname= "OBJECT_OT_hook_remove"; + ot->description= "Remove a hook from the active object."; + + /* api callbacks */ + ot->poll= ED_operator_editmesh; + ot->exec= object_hook_remove_exec; + ot->invoke= WM_menu_invoke; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove."); + RNA_def_enum_funcs(prop, hook_mod_itemf); +} - int mode= RNA_enum_get(op->ptr, "type"); +static int object_hook_reset_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + int num= RNA_enum_get(op->ptr, "modifier"); + Object *ob=NULL; + HookModifierData *hmd=NULL; + + if (ptr.data) { /* if modifier context is available, use that */ + ob = ptr.id.data; + hmd= ptr.data; + } else { /* use the provided property */ + ob = CTX_data_edit_object(C); + hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); + } + if (!ob || !hmd) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); + return OPERATOR_CANCELLED; + } + + /* reset functionality */ + + if(hmd->object) { + bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); + + if(hmd->subtarget[0] && pchan) { + float imat[4][4], mat[4][4]; + + /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ + mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat); + + invert_m4_m4(imat, mat); + mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + } + else { + invert_m4_m4(hmd->object->imat, hmd->object->obmat); + mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + } + } + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} - // XXX - todo, break up this function for different operators - // and detect if this finished correctly or not, - add_hook(scene, v3d, mode); +void OBJECT_OT_hook_reset(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name= "Reset Hook"; + ot->description= "Recalculate and and clear offset transformation."; + ot->idname= "OBJECT_OT_hook_reset"; + + ot->poll= ED_operator_editmesh; + ot->exec= object_hook_reset_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + RNA_def_enum_funcs(prop, hook_mod_itemf); +} - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); +static int object_hook_recenter_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + int num= RNA_enum_get(op->ptr, "modifier"); + Object *ob=NULL; + HookModifierData *hmd=NULL; + Scene *scene = CTX_data_scene(C); + float bmat[3][3], imat[3][3]; + + if (ptr.data) { /* if modifier context is available, use that */ + ob = ptr.id.data; + hmd= ptr.data; + } else { /* use the provided property */ + ob = CTX_data_edit_object(C); + hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); + } + if (!ob || !hmd) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); + return OPERATOR_CANCELLED; + } + + /* recenter functionality */ + + copy_m3_m4(bmat, ob->obmat); + invert_m3_m3(imat, bmat); + + sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]); + mul_m3_v3(imat, hmd->cent); + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + return OPERATOR_FINISHED; } -void OBJECT_OT_hook_add(wmOperatorType *ot) +void OBJECT_OT_hook_recenter(wmOperatorType *ot) { - static EnumPropertyItem prop_new_hook_types[] = { - {1, "NEW", 0, "New Object", "Create a new object and assign the verts to it."}, - {2, "SELECTED", 0, "Selection", "Add the hook to the selected object."}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name= "Add Hook"; - ot->description= "Add hook to selected verts."; - ot->idname= "OBJECT_OT_hook_add"; + PropertyRNA *prop; + + ot->name= "Recenter Hook"; + ot->description= "Set hook center to cursor position."; + ot->idname= "OBJECT_OT_hook_recenter"; + + ot->poll= ED_operator_editmesh; + ot->exec= object_hook_recenter_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + RNA_def_enum_funcs(prop, hook_mod_itemf); +} - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_hook_exec; -// ot->poll= ED_operator_editmesh; +static int object_hook_assign_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + int num= RNA_enum_get(op->ptr, "modifier"); + Object *ob=NULL; + HookModifierData *hmd=NULL; + float cent[3]; + char name[32]; + int *indexar, tot; + + if (ptr.data) { /* if modifier context is available, use that */ + ob = ptr.id.data; + hmd= ptr.data; + } else { /* use the provided property */ + ob = CTX_data_edit_object(C); + hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); + } + if (!ob || !hmd) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); + return OPERATOR_CANCELLED; + } + + /* assign functionality */ + + 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(hmd->indexar) + MEM_freeN(hmd->indexar); + + copy_v3_v3(hmd->cent, cent); + hmd->indexar= indexar; + hmd->totindex= tot; + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} +void OBJECT_OT_hook_assign(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name= "Assign to Hook"; + ot->description= "Assign the selected vertices to a hook."; + ot->idname= "OBJECT_OT_hook_assign"; + + ot->poll= ED_operator_editmesh; + ot->exec= object_hook_assign_exec; + /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + RNA_def_enum_funcs(prop, hook_mod_itemf); +} + +static int object_hook_select_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + int num= RNA_enum_get(op->ptr, "modifier"); + Object *ob=NULL; + HookModifierData *hmd=NULL; + + if (ptr.data) { /* if modifier context is available, use that */ + ob = ptr.id.data; + hmd= ptr.data; + } else { /* use the provided property */ + ob = CTX_data_edit_object(C); + hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); + } + if (!ob || !hmd) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); + return OPERATOR_CANCELLED; + } + + /* select functionality */ + + object_hook_select(ob, hmd); + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); + + return OPERATOR_FINISHED; +} - RNA_def_enum(ot->srna, "type", prop_new_hook_types, 0, "Type", ""); +void OBJECT_OT_hook_select(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name= "Select Hook"; + ot->description= "Selects effected vertices on mesh."; + ot->idname= "OBJECT_OT_hook_select"; + + ot->poll= ED_operator_editmesh; + ot->exec= object_hook_select_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove."); + RNA_def_enum_funcs(prop, hook_mod_itemf); } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 41d4af60a03..046dd8939ba 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -36,6 +36,12 @@ struct Object; struct Mesh; struct HookModifierData; +/* add hook menu */ +enum { + OBJECT_ADDHOOK_NEWOB = 1, + OBJECT_ADDHOOK_SELOB, +} eObject_Hook_Add_Mode; + /* internal exports only */ /* object_transform.c */ @@ -103,10 +109,13 @@ void OBJECT_OT_join(struct wmOperatorType *ot); void OBJECT_OT_convert(struct wmOperatorType *ot); /* object_hook.c */ -int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r); -void object_hook_select(Object *obedit, struct HookModifierData *hmd); - -void OBJECT_OT_hook_add(struct wmOperatorType *ot); +void OBJECT_OT_hook_add_selobj(struct wmOperatorType *ot); +void OBJECT_OT_hook_add_newobj(struct wmOperatorType *ot); +void OBJECT_OT_hook_remove(struct wmOperatorType *ot); +void OBJECT_OT_hook_select(struct wmOperatorType *ot); +void OBJECT_OT_hook_assign(struct wmOperatorType *ot); +void OBJECT_OT_hook_reset(struct wmOperatorType *ot); +void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_lattice.c */ void free_editLatt(Object *ob); @@ -134,10 +143,6 @@ void OBJECT_OT_modifier_copy(struct wmOperatorType *ot); void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot); void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); -void OBJECT_OT_hook_reset(struct wmOperatorType *ot); -void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); -void OBJECT_OT_hook_select(struct wmOperatorType *ot); -void OBJECT_OT_hook_assign(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); /* object_constraint.c */ @@ -177,7 +182,6 @@ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_menu(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_game_property_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index b84fb47e5ee..f65153d09ad 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -822,157 +822,6 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/******************** hook operators ************************/ - -static int hook_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); - ID *id= ptr.id.data; - return (ptr.data && id && !id->lib); -} - -static int hook_reset_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; - - if(hmd->object) { - bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); - - if(hmd->subtarget[0] && pchan) { - float imat[4][4], mat[4][4]; - - /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ - mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat); - - invert_m4_m4(imat, mat); - mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - } - else { - invert_m4_m4(hmd->object->imat, hmd->object->obmat); - mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - } - } - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hook_reset(wmOperatorType *ot) -{ - 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]; - - copy_m3_m4(bmat, ob->obmat); - invert_m3_m3(imat, bmat); - - VECSUB(hmd->cent, scene->cursor, ob->obmat[3]); - mul_m3_v3(imat, hmd->cent); - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - - return OPERATOR_FINISHED; -} - -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"; - - ot->exec= hook_recenter_exec; - ot->poll= hook_poll; - - /* 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; - - object_hook_select(ob, hmd); - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hook_select(wmOperatorType *ot) -{ - ot->name= "Hook Select"; - ot->description= "Selects effected vertices on mesh."; - ot->idname= "OBJECT_OT_hook_select"; - - ot->exec= hook_select_exec; - ot->poll= hook_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int hook_assign_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; - float cent[3]; - char name[32]; - int *indexar, tot; - - 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(hmd->indexar) - MEM_freeN(hmd->indexar); - - VECCOPY(hmd->cent, cent); - hmd->indexar= indexar; - hmd->totindex= tot; - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hook_assign(wmOperatorType *ot) -{ - ot->name= "Hook Assign"; - ot->description= "Reassigns selected vertices to hook."; - ot->idname= "OBJECT_OT_hook_assign"; - - ot->exec= hook_assign_exec; - ot->poll= hook_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /****************** explode refresh operator *********************/ static int explode_refresh_poll(bContext *C) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 5dd2c5773dd..44dc5b06ea8 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -136,12 +136,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_multires_subdivide); WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete); WM_operatortype_append(OBJECT_OT_meshdeform_bind); - WM_operatortype_append(OBJECT_OT_hook_reset); - WM_operatortype_append(OBJECT_OT_hook_recenter); - WM_operatortype_append(OBJECT_OT_hook_select); - WM_operatortype_append(OBJECT_OT_hook_assign); WM_operatortype_append(OBJECT_OT_explode_refresh); - + WM_operatortype_append(OBJECT_OT_constraint_add); WM_operatortype_append(OBJECT_OT_constraint_add_with_targets); WM_operatortype_append(POSE_OT_constraint_add); @@ -172,7 +168,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); WM_operatortype_append(OBJECT_OT_vertex_group_clean); - WM_operatortype_append(OBJECT_OT_vertex_group_menu); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_game_property_new); @@ -190,7 +185,13 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_remove); - WM_operatortype_append(OBJECT_OT_hook_add); + WM_operatortype_append(OBJECT_OT_hook_add_selobj); + WM_operatortype_append(OBJECT_OT_hook_add_newobj); + WM_operatortype_append(OBJECT_OT_hook_remove); + WM_operatortype_append(OBJECT_OT_hook_select); + WM_operatortype_append(OBJECT_OT_hook_assign); + WM_operatortype_append(OBJECT_OT_hook_reset); + WM_operatortype_append(OBJECT_OT_hook_recenter); } void ED_operatormacros_object(void) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 5e5390b7d70..99bfea38c49 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -69,6 +69,7 @@ #include "ED_view3d.h" #include "UI_interface.h" +#include "UI_resources.h" #include "object_intern.h" @@ -1753,6 +1754,7 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) for(a=0, def=ob->defbase.first; def; def=def->next, a++) { tmp.value= a; + tmp.icon= ICON_GROUP_VERTEX; tmp.identifier= def->name; tmp.name= def->name; RNA_enum_item_add(&item, &totitem, &tmp); @@ -1784,51 +1786,4 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) /* properties */ prop= RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active."); RNA_def_enum_funcs(prop, vgroup_itemf); -} - -static int vertex_group_menu_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Vertex Groups", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - if(vgroup_object_in_edit_mode(ob)) { - uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1); - - if(BLI_countlist(&ob->defbase) && ob->actdef) { - uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign"); - uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from"); - uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1); - } - } - - if(BLI_countlist(&ob->defbase) && ob->actdef) { - if(vgroup_object_in_edit_mode(ob)) - uiItemS(layout); - - uiItemMenuEnumO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active", "group"); - uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove"); - uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1); - } - - uiPupMenuEnd(C, pup); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_vertex_group_menu(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Vertex Group Menu"; - ot->idname= "OBJECT_OT_vertex_group_menu"; - ot->description= "Menu showing the operators available for editing Vertex Groups"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_menu_exec; -} - +}
\ No newline at end of file |