From efa4c5be4bb11604e211f8eb26eee9d54ca09cb4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 3 Apr 2013 10:45:13 +0000 Subject: [PATCH] new ruler option to be able to interactively measure surface thichness as you drag the ruler about. Request from Bart Veldhuizen. Access with Shift+Drag --- .../editors/space_view3d/view3d_ruler.c | 82 ++++++++++++++----- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 86e19b07840..b5b64cef850 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -60,12 +60,42 @@ /* NOTE - this is not very nice use of transform snapping */ #include "ED_transform.h" -static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2], +static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2], float r_no[3], bool use_vert, bool use_edge, bool use_face) { float dist_px = 12; /* snap dist */ float r_no_dummy[3]; bool ret = false; + float *r_no_ptr = r_no ? r_no : r_no_dummy; + + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + struct Object *obedit = CTX_data_edit_object(C); + + /* try snap edge, then face if it fails */ + if (use_vert) { + ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_VERTEX, + co_ss, &dist_px, r_co, r_no_ptr, SNAP_ALL); + } + if (use_edge && (ret == false)) { + ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_EDGE, + co_ss, &dist_px, r_co, r_no_ptr, SNAP_ALL); + } + if (use_face && (ret == false)) { + ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, + co_ss, &dist_px, r_co, r_no_ptr, SNAP_ALL); + } + + return ret; +} + +static bool ED_view3d_snap_ray(bContext *C, float r_co[3], + const float ray_start[3], const float ray_normal[3]) +{ + float dist_px = 12; /* snap dist */ + float r_no_dummy[3]; + bool ret = false; Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -73,18 +103,9 @@ static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2], struct Object *obedit = CTX_data_edit_object(C); /* try snap edge, then face if it fails */ - if (use_vert) { - ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_VERTEX, - co_ss, &dist_px, r_co, r_no_dummy, SNAP_ALL); - } - if (use_edge && (ret == false)) { - ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_EDGE, - co_ss, &dist_px, r_co, r_no_dummy, SNAP_ALL); - } - if (use_face && (ret == false)) { - ret = snapObjectsEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, - co_ss, &dist_px, r_co, r_no_dummy, SNAP_ALL); - } + ret = snapObjectsRayEx(scene, NULL, v3d, ar, obedit, SCE_SNAP_MODE_FACE, + ray_start, ray_normal, + NULL, &dist_px, r_co, r_no_dummy, SNAP_ALL); return ret; } @@ -646,16 +667,36 @@ static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3], } /* use for mousemove events */ -static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_snap) +static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], + const bool do_thickness, const bool do_snap) { RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { float *co = ruler_item->co[ruler_item->co_index]; view3d_ruler_item_project(ruler_info, co, mval); - if (do_snap) { + if (do_thickness && ruler_item->co_index != 1) { const float mval_fl[2] = {UNPACK2(mval)}; - ED_view3d_snap_co(C, co, mval_fl, true, true, true); + float ray_normal[3]; + float ray_start[3]; + float *co_other; + + co_other = ruler_item->co[ruler_item->co_index == 0 ? 2 : 0]; + + if (ED_view3d_snap_co(C, co, mval_fl, ray_normal, + false, false, true)) + { + negate_v3(ray_normal); + /* add some bias */ + madd_v3_v3v3fl(ray_start, co, ray_normal, 0.0001f); + ED_view3d_snap_ray(C, co_other, + ray_start, ray_normal); + } + } + else if (do_snap) { + const float mval_fl[2] = {UNPACK2(mval)}; + ED_view3d_snap_co(C, co, mval_fl, NULL, + true, true, true); } return true; } @@ -669,6 +710,7 @@ static void view3d_ruler_header_update(ScrArea *sa) const char *text = "Ctrl+LMB: Add, " "Del: Remove, " "Ctrl+Drag: Snap, " + "Shift+Drag: Thickness, " "Ctrl+C: Copy Value, " "Enter: Store, " "Esc: Cancel"; @@ -763,7 +805,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) /* snap the first point added, not essential but handy */ { ruler_item->co_index = 0; - view3d_ruler_item_mousemove(C, ruler_info, event->mval, true); + view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, true); } copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); @@ -803,7 +845,8 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* update the new location */ - view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0); + view3d_ruler_item_mousemove(C, ruler_info, event->mval, + event->shift != 0, event->ctrl != 0); do_draw = true; } } @@ -846,7 +889,8 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) case MOUSEMOVE: { if (ruler_info->state == RULER_STATE_DRAG) { - if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0)) { + if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, + event->shift != 0, event->ctrl != 0)) { do_draw = true; } }