add hook now has option to add to active bone (mango request).
authorCampbell Barton <ideasman42@gmail.com>
Mon, 13 Aug 2012 08:54:33 +0000 (08:54 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 13 Aug 2012 08:54:33 +0000 (08:54 +0000)
release/scripts/startup/bl_ui/space_view3d.py
source/blender/editors/interface/view2d_ops.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_intern.h

index 2d9c9467a013f3d856ae84ac4386c40bdc47a005..9368d3ab5db4d50db88497354e5cbd1b385ba04a 100644 (file)
@@ -1183,6 +1183,7 @@ class VIEW3D_MT_hook(Menu):
         layout.operator_context = 'EXEC_AREA'
         layout.operator("object.hook_add_newob")
         layout.operator("object.hook_add_selob")
+        layout.operator("object.hook_add_selob", text="Hook to Selected Object Bone").use_bone = True
 
         if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
             layout.separator()
index d7f61b90cfa956c927ca03772071a35cc4baed36..33b72b3478465e519d0f3510991db3e24f848057 100644 (file)
@@ -1198,13 +1198,13 @@ struct SmoothView2DStore {
 static float smooth_view_rect_to_fac(const rctf *rect_a, const rctf *rect_b)
 {
        float size_a[2] = {rect_a->xmax - rect_a->xmin,
-                                          rect_a->ymax - rect_a->ymin};
+                          rect_a->ymax - rect_a->ymin};
        float size_b[2] = {rect_b->xmax - rect_b->xmin,
-                                          rect_b->ymax - rect_b->ymin};
+                          rect_b->ymax - rect_b->ymin};
        float cent_a[2] = {(rect_a->xmax + rect_a->xmin) * 0.5f,
-                                          (rect_a->ymax + rect_a->ymin) * 0.5f};
+                          (rect_a->ymax + rect_a->ymin) * 0.5f};
        float cent_b[2] = {(rect_b->xmax + rect_b->xmin) * 0.5f,
-                                          (rect_b->ymax + rect_b->ymin) * 0.5f};
+                          (rect_b->ymax + rect_b->ymin) * 0.5f};
 
        float fac_max = 0.0f;
        float tfac;
@@ -1228,7 +1228,7 @@ static float smooth_view_rect_to_fac(const rctf *rect_a, const rctf *rect_b)
 /* will start timer if appropriate */
 /* the arguments are the desired situation */
 void UI_view2d_smooth_view(bContext *C, ARegion *ar,
-                                                  const rctf *cur)
+                           const rctf *cur)
 {
        wmWindowManager *wm = CTX_wm_manager(C);
        wmWindow *win = CTX_wm_window(C);
index 65dd9a12d3b8a85ccb00b2bd0b048bd5ec61795f..7c8386d55dcbd919bad086482dc6a6eb1064b2e2 100644 (file)
@@ -38,6 +38,7 @@
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
+#include "DNA_armature_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_mesh_types.h"
@@ -430,7 +431,7 @@ static Object *add_hook_object_new(Scene *scene, Object *obedit)
        return ob;
 }
 
-static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode)
+static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode, ReportList *reports)
 {
        ModifierData *md = NULL;
        HookModifierData *hmd = NULL;
@@ -439,9 +440,12 @@ static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *o
        char name[MAX_NAME];
        
        ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent);
-       
-       if (!ok) return;    // XXX error("Requires selected vertices or active Vertex Group");
-       
+
+       if (!ok) {
+               BKE_report(reports, RPT_ERROR, "Requires selected vertices or active Vertex Group");
+               return FALSE;
+       }
+
        if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
                
                ob = add_hook_object_new(scene, obedit);
@@ -466,6 +470,17 @@ static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *o
        hmd->totindex = tot;
        BLI_strncpy(hmd->name, name, sizeof(hmd->name));
        
+       if (mode == OBJECT_ADDHOOK_SELOB_BONE) {
+               bArmature *arm = ob->data;
+               BLI_assert(ob->type == OB_ARMATURE);
+               if (arm->act_bone) {
+                       BLI_strncpy(hmd->subtarget, arm->act_bone->name, sizeof(hmd->subtarget));
+               }
+               else {
+                       BKE_report(reports, RPT_WARNING, "Armature has no active object bone");
+               }
+       }
+
        /* matrix calculus */
        /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
        /*        (parentinv         )                          */
@@ -477,6 +492,8 @@ static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *o
                     NULL, NULL, NULL, NULL, NULL);
        
        DAG_scene_sort(bmain, scene);
+
+       return TRUE;
 }
 
 static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
@@ -485,6 +502,8 @@ 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;
+       const int use_bone = RNA_boolean_get(op->ptr, "use_bone");
+       const int mode = use_bone ? OBJECT_ADDHOOK_SELOB_BONE : OBJECT_ADDHOOK_SELOB;
        
        CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
        {
@@ -499,11 +518,19 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
                BKE_report(op->reports, RPT_ERROR, "Can't add hook with no other selected objects");
                return OPERATOR_CANCELLED;
        }
+
+       if (use_bone && obsel->type != OB_ARMATURE) {
+               BKE_report(op->reports, RPT_ERROR, "Can't add hook bone for a non armature object");
+               return OPERATOR_CANCELLED;
+       }
        
-       add_hook_object(bmain, scene, obedit, obsel, OBJECT_ADDHOOK_SELOB);
-       
-       WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
-       return OPERATOR_FINISHED;
+       if (add_hook_object(bmain, scene, obedit, obsel, mode, op->reports)) {
+               WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
+               return OPERATOR_FINISHED;
+       }
+       else {
+               return OPERATOR_CANCELLED;
+       }
 }
 
 void OBJECT_OT_hook_add_selobj(wmOperatorType *ot)
@@ -519,19 +546,25 @@ void OBJECT_OT_hook_add_selobj(wmOperatorType *ot)
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "use_bone", FALSE, "Active Bone",
+                       "Assign the hook to the hook objects active bone");
 }
 
-static int object_add_hook_newob_exec(bContext *C, wmOperator *UNUSED(op))
+static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
 {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
        Object *obedit = CTX_data_edit_object(C);
 
-       add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB);
-       
-       WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-       WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
-       return OPERATOR_FINISHED;
+       if (add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) {
+               WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+               WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
+               return OPERATOR_FINISHED;
+       }
+       else {
+               return OPERATOR_CANCELLED;
+       }
 }
 
 void OBJECT_OT_hook_add_newobj(wmOperatorType *ot)
index f7e7c87d9563a4427077f68e5874d9c12488dff0..b62ff67606601c3b334d33b24b4fa466994e161a 100644 (file)
@@ -43,6 +43,7 @@ struct HookModifierData;
 enum {
        OBJECT_ADDHOOK_NEWOB = 1,
        OBJECT_ADDHOOK_SELOB,
+       OBJECT_ADDHOOK_SELOB_BONE
 } eObject_Hook_Add_Mode;
 
 /* internal exports only */