changes to ruler
authorCampbell Barton <ideasman42@gmail.com>
Fri, 8 Mar 2013 18:17:12 +0000 (18:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 8 Mar 2013 18:17:12 +0000 (18:17 +0000)
- click-drag adds a ruler if there are none.
- pressing enter stores the ruler for re-use when activating again (saves as a grease-pencil layer).
- add to toolbar.

release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/editors/space_view3d/view3d_ruler.c

index 91a5589..a677c9d 100644 (file)
@@ -64,6 +64,8 @@ def draw_gpencil_tools(context, layout):
     row = col.row()
     row.prop(context.tool_settings, "use_grease_pencil_sessions")
 
+    col.operator("view3d.ruler")
+
 
 # ********** default tools for object-mode ****************
 
@@ -102,8 +104,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
 
         col = layout.column(align=True)
         col.label(text="Motion Paths:")
-        col.operator("object.paths_calculate", text="Calculate Paths")
-        col.operator("object.paths_clear", text="Clear Paths")
+        row = col.row(align=True)
+        row.operator("object.paths_calculate", text="Calculate")
+        row.operator("object.paths_clear", text="Clear")
 
         draw_repeat_tools(context, layout)
 
index 45e4a4e..b74d47a 100644 (file)
@@ -27,6 +27,7 @@
 /* defines VIEW3D_OT_ruler modal operator */
 
 #include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -35,6 +36,7 @@
 
 #include "BKE_context.h"
 #include "BKE_unit.h"
+#include "BKE_gpencil.h"
 
 #include "BIF_gl.h"
 
@@ -246,6 +248,105 @@ static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
        }
 }
 
+#define RULER_ID "RulerData3D"
+static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+       Scene *scene = CTX_data_scene(C);
+       bGPDlayer *gpl;
+       bGPDframe *gpf;
+       bGPDstroke *gps;
+       RulerItem *ruler_item;
+       const char *ruler_name = RULER_ID;
+       bool change = false;
+
+       if (scene->gpd == NULL) {
+               scene->gpd = gpencil_data_addnew("GPencil");
+       }
+
+       gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+       if (gpl == NULL) {
+               gpl = gpencil_layer_addnew(scene->gpd, ruler_name, false);
+               gpl->thickness = 1;
+               gpl->flag |= GP_LAYER_HIDE;
+       }
+
+       gpf = gpencil_layer_getframe(gpl, CFRA, true);
+       free_gpencil_strokes(gpf);
+
+       for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
+               bGPDspoint *pt;
+               int j;
+
+               /* allocate memory for a new stroke */
+               gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+               if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+                       gps->totpoints = 3;
+                       pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+                       for (j = 0; j < 3; j++) {
+                               copy_v3_v3(&pt->x, ruler_item->co[j]);
+                               pt->pressure = 1.0f;
+                               pt++;
+                       }
+               }
+               else {
+                       gps->totpoints = 2;
+                       pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+                       for (j = 0; j < 3; j += 2) {
+                               copy_v3_v3(&pt->x, ruler_item->co[j]);
+                               pt->pressure = 1.0f;
+                               pt++;
+                       }
+               }
+               gps->flag = GP_STROKE_3DSPACE;
+               BLI_addtail(&gpf->strokes, gps);
+               change = true;
+       }
+
+       return change;
+}
+
+static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+       Scene *scene = CTX_data_scene(C);
+       bool change = false;
+
+       if (scene->gpd) {
+               bGPDlayer *gpl;
+               const char *ruler_name = RULER_ID;
+               gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+               if (gpl) {
+                       bGPDframe *gpf;
+                       gpf = gpencil_layer_getframe(gpl, CFRA, false);
+                       if (gpf) {
+                               bGPDstroke *gps;
+                               for (gps = gpf->strokes.first; gps; gps = gps->next) {
+                                       bGPDspoint *pt = gps->points;
+                                       int j;
+                                       if (gps->totpoints == 3) {
+                                               RulerItem *ruler_item = ruler_item_add(ruler_info);
+                                               for (j = 0; j < 3; j++) {
+                                                       copy_v3_v3(ruler_item->co[j], &pt->x);
+                                                       pt++;
+                                               }
+                                               ruler_item->flag |= RULERITEM_USE_ANGLE;
+                                               change = true;
+                                       }
+                                       else if (gps->totpoints == 2) {
+                                               RulerItem *ruler_item = ruler_item_add(ruler_info);
+                                               for (j = 0; j < 3; j++) {
+                                                       copy_v3_v3(ruler_item->co[j], &pt->x);
+                                                       pt++;
+                                               }
+                                               change = true;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return change;
+}
+
 /* -------------------------------------------------------------------- */
 /* local callbacks */
 
@@ -593,6 +694,10 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
        ruler_info = MEM_callocN(sizeof(RulerInfo), "RulerInfo");
 
+       if (view3d_ruler_from_gpencil(C, ruler_info)) {
+               WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+       }
+
        op->customdata = ruler_info;
 
        ruler_info->ar = ar;
@@ -642,7 +747,10 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
                        else {
                                if (ruler_info->state == RULER_STATE_NORMAL) {
 
-                                       if (event->ctrl) {
+                                       if (event->ctrl ||
+                                           /* weak - but user friendly */
+                                           (ruler_info->items.first == NULL))
+                                       {
                                                /* Create new line */
                                                RulerItem *ruler_item;
                                                /* check if we want to drag an existing point or add a new one */
@@ -730,6 +838,13 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
                        exit_code = OPERATOR_CANCELLED;
                        break;
                }
+               case RETKEY:
+               {
+                       view3d_ruler_to_gpencil(C, ruler_info);
+                       do_draw = true;
+                       exit_code = OPERATOR_FINISHED;
+                       break;
+               }
                case DELKEY:
                {
                        if (event->val == KM_PRESS) {
@@ -751,7 +866,10 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
        }
 
        if (do_draw) {
-               ED_region_tag_redraw(ar);
+               // ED_region_tag_redraw(ar);
+
+               /* all 3d views draw rulers */
+               WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
        }
 
        if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
@@ -766,7 +884,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
 void VIEW3D_OT_ruler(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name = "3D Ruler";
+       ot->name = "3D Ruler & Protractor";
        ot->description = "Interactive ruler";
        ot->idname = "VIEW3D_OT_ruler";
 
@@ -777,5 +895,5 @@ void VIEW3D_OT_ruler(wmOperatorType *ot)
        ot->poll = ED_operator_view3d_active;
 
        /* flags */
-       ot->flag = OPTYPE_BLOCKING;
+       ot->flag = 0;
 }