diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 4ac83b452b0..9aa8072302e 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -110,6 +110,7 @@ void auto_timeoffs(void); void texspace_edit(void); void flip_subdivison(int); void mirrormenu(void); +void hookmenu(void); /* object mode hook menu */ void add_hook(void); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index d6f5ae5091b..96e4ed4454d 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1342,7 +1342,7 @@ static void modifiers_clearHookOffset(void *ob_v, void *md_v) if (hmd->object) { Mat4Invert(hmd->object->imat, hmd->object->obmat); Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - BIF_undo_push("Clear hook"); + BIF_undo_push("Clear hook offset"); } } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 22c29bf7d91..b65787fe687 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -5384,3 +5384,74 @@ void mirrormenu(void) Mirror(mode); /* separating functionality from interface | call*/ } } + +void hookmenu(void) +{ + /* only called in object mode */ + short event, changed=0; + Object *ob; + Base *base; + ModifierData *md; + HookModifierData *hmd; + + event= pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2"); + if (event==-1) return; + if (event==2 && !(G.vd)) { + error("Cannot perform this operation without a 3d view"); + return; + } + + for (base= FIRSTBASE; base; base= base->next) { + if TESTBASELIB(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) { + Mat4Invert(hmd->object->imat, hmd->object->obmat); + Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + + changed= 1; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + } else { + float *curs = give_cursor(); + float bmat[3][3], imat[3][3]; + + where_is_object(ob); + + Mat3CpyMat4(bmat, ob->obmat); + Mat3Inv(imat, bmat); + + 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); + + changed= 1; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + } + } + } + } + + if (changed) { + if (event==1) + BIF_undo_push("Clear hook offset for selected"); + else if (event==2) + BIF_undo_push("Hook cursor center for selected"); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + } +} + diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 22c178ad2dd..335c636b987 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1924,6 +1924,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) hide_unselected_pose_bones(); else if (G.qual==LR_ALTKEY) show_all_pose_bones(); + } else { + hookmenu(); } break; case IKEY: