From dd08d68df835e54ccd1fdf24ae154e461faab685 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Tue, 20 Aug 2019 19:18:25 -0300 Subject: Transform: New Snap Option: Edge Perpendicular Part of T66420 Option for snapping to the nearest point of a reference coordinate. The patch also adds Edge Center and Perpendicular snaps to the ruler. {F7675906} Reviewers: campbellbarton, brecht Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D5543 --- source/blender/editors/curve/editcurve.c | 1 + .../gizmo_library/gizmo_types/move3d_gizmo.c | 1 + .../include/ED_transform_snap_object_context.h | 2 + source/blender/editors/include/UI_icons.h | 2 +- source/blender/editors/mesh/editmesh_tools.c | 1 + source/blender/editors/space_view3d/view3d_edit.c | 1 + .../editors/space_view3d/view3d_gizmo_ruler.c | 18 +++++- source/blender/editors/transform/transform_snap.c | 4 +- .../editors/transform/transform_snap_object.c | 69 ++++++++++++++++++---- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_scene.c | 5 ++ 11 files changed, 89 insertions(+), 16 deletions(-) (limited to 'source') diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index eebc8893112..d7650db546d 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5680,6 +5680,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) }, mval, NULL, + NULL, location, NULL); diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c index 21f779b72b1..37ee95d5058 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c @@ -283,6 +283,7 @@ static int gizmo_move_modal(bContext *C, .use_occlusion_test = true, }, mval_fl, + NULL, &dist_px, co, NULL)) { diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index f27523bb1f8..97bef25dee8 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -125,6 +125,7 @@ short ED_transform_snap_object_project_view3d_ex(struct SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], + const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3], @@ -135,6 +136,7 @@ bool ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], + const float prev_co[3], float *dist_px, /* return args */ float r_loc[3], diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index bca0d8984c8..d615ea34bb1 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -667,7 +667,7 @@ DEF_ICON(PARTICLE_PATH) /* EDITING */ DEF_ICON_BLANK(669) DEF_ICON_BLANK(670) -DEF_ICON_BLANK(671) +DEF_ICON(SNAP_PERPENDICULAR) DEF_ICON(SNAP_MIDPOINT) DEF_ICON(SNAP_OFF) DEF_ICON(SNAP_ON) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 4e58fee61a2..2b0213dc1ef 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -437,6 +437,7 @@ void EDBM_project_snap_verts(bContext *C, Depsgraph *depsgraph, ARegion *ar, BME }, mval, NULL, + NULL, co_proj, NULL)) { mul_v3_m4v3(eve->co, obedit->imat, co_proj); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index b9adde6f60e..13001058fed 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4944,6 +4944,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, .use_object_edit_cage = false, }, mval_fl, + NULL, &dist_px, ray_co, ray_no, diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 97a12c7100e..f4e3dc85447 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -343,6 +343,7 @@ static bool view3d_ruler_item_mousemove(RulerInfo *ruler_info, .use_object_edit_cage = true, }, mval_fl, + NULL, &dist_px, co, ray_normal)) { @@ -363,16 +364,31 @@ static bool view3d_ruler_item_mousemove(RulerInfo *ruler_info, } else if (do_snap) { const float mval_fl[2] = {UNPACK2(mval)}; + float *prev_point = NULL; + + if (inter->co_index != 1) { + if (ruler_item->flag & RULERITEM_USE_ANGLE) { + prev_point = ruler_item->co[1]; + } + else if (inter->co_index == 0) { + prev_point = ruler_item->co[2]; + } + else { + prev_point = ruler_item->co[0]; + } + } if (ED_transform_snap_object_project_view3d( ruler_info->snap_context, - (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE), + (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | + SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR), &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, .use_object_edit_cage = true, .use_occlusion_test = true, }, mval_fl, + prev_point, &dist_px, co, NULL)) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 9d107527833..feaef9a17a1 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -328,6 +328,7 @@ void applyProject(TransInfo *t) .use_occlusion_test = false, }, mval_fl, + NULL, 0, loc, no)) { @@ -999,7 +1000,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) mval[1] = t->mval[1]; if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | - SCE_SNAP_MODE_EDGE_MIDPOINT)) { + SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { zero_v3(no); /* objects won't set this */ found = snapObjectsTransform(t, mval, &dist_px, loc, no); } @@ -1272,6 +1273,7 @@ bool snapObjectsTransform( .use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE, }, mval, + t->center_global, dist_px, r_loc, r_no); diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 4943e538590..761a13c1538 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -1260,7 +1260,8 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, const MPoly *mp = &((SnapObjectData_Mesh *)sod)->poly[*r_index]; const MLoop *ml = &treedata->loop[mp->loopstart]; - if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (snapdata->snap_to_flag & + (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { elem = SCE_SNAP_MODE_EDGE; BLI_assert(treedata->edge != NULL); for (int i = mp->totloop; i--; ml++) { @@ -1297,7 +1298,8 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, BMFace *f = BM_face_at_index(em->bm, *r_index); BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); - if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (snapdata->snap_to_flag & + (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { elem = SCE_SNAP_MODE_EDGE; BM_mesh_elem_index_ensure(em->bm, BM_EDGE); BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE); @@ -1352,6 +1354,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, Object *ob, float obmat[4][4], float original_dist_px, + const float prev_co[3], /* read/write args */ float *dist_px, /* return args */ @@ -1460,13 +1463,43 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, } } } + + if (prev_co && (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { + float v_near[3], va_g[3], vb_g[3]; + + mul_v3_m4v3(va_g, obmat, v_pair[0]); + mul_v3_m4v3(vb_g, obmat, v_pair[1]); + lambda = line_point_factor_v3(prev_co, va_g, vb_g); + + if (IN_RANGE(lambda, 0.0f, 1.0f)) { + interp_v3_v3v3(v_near, va_g, vb_g, lambda); + + if (test_projected_vert_dist(&neasrest_precalc, + NULL, + 0, + nearest2d.is_persp, + v_near, + &nearest.dist_sq, + nearest.co)) { + float v_nor[2][3]; + nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata); + nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata); + mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]); + + nearest.index = *r_index; + elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR; + } + } + } } if (nearest.index != -1) { *dist_px = sqrtf(nearest.dist_sq); copy_v3_v3(r_loc, nearest.co); - mul_m4_v3(obmat, r_loc); + if (elem != SCE_SNAP_MODE_EDGE_PERPENDICULAR) { + mul_m4_v3(obmat, r_loc); + } if (r_no) { float imat[4][4]; @@ -2092,7 +2125,8 @@ static short snapMesh(SnapObjectContext *sctx, last_index = nearest.index; } - if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (snapdata->snap_to_flag & + (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { if (bvhtree[0]) { /* snap to loose edges */ BLI_bvhtree_find_nearest_projected(bvhtree[0], @@ -2258,7 +2292,8 @@ static short snapEditMesh(SnapObjectContext *sctx, } } - if (snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (snapdata->snap_to_flag & + (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { if (sod->bvh_trees[1] == NULL) { sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees)); } @@ -2330,8 +2365,8 @@ static short snapEditMesh(SnapObjectContext *sctx, last_index = nearest.index; } - if (treedata_edge && - snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (treedata_edge && snapdata->snap_to_flag & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | + SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT); BLI_bvhtree_find_nearest_projected(treedata_edge->tree, lpmat, @@ -2727,6 +2762,7 @@ static short transform_snap_context_project_view3d_mixed_impl( const unsigned short snap_to_flag, const struct SnapObjectParams *params, const float mval[2], + const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3], @@ -2735,7 +2771,8 @@ static short transform_snap_context_project_view3d_mixed_impl( float r_obmat[4][4]) { BLI_assert((snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | - SCE_SNAP_MODE_EDGE_MIDPOINT)) != 0); + SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) != + 0); short retval = 0; bool has_hit = false; @@ -2773,7 +2810,8 @@ static short transform_snap_context_project_view3d_mixed_impl( } } - if (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT)) { + if (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | + SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { short elem; float dist_px_tmp = *dist_px; @@ -2827,9 +2865,10 @@ static short transform_snap_context_project_view3d_mixed_impl( } if ((retval == SCE_SNAP_MODE_EDGE) && - (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT))) { + (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT | + SCE_SNAP_MODE_EDGE_PERPENDICULAR))) { elem = snap_mesh_edge_verts_mixed( - sctx, &snapdata, ob, obmat, *dist_px, &dist_px_tmp, loc, no, &index); + sctx, &snapdata, ob, obmat, *dist_px, prev_co, &dist_px_tmp, loc, no, &index); } if (elem) { @@ -2864,6 +2903,7 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], + const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3], @@ -2872,7 +2912,8 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx, float r_obmat[4][4]) { return transform_snap_context_project_view3d_mixed_impl( - sctx, snap_to, params, mval, dist_px, r_loc, r_no, r_index, r_ob, r_obmat) != 0; + sctx, snap_to, params, mval, prev_co, dist_px, r_loc, r_no, r_index, r_ob, r_obmat) != + 0; } /** @@ -2882,6 +2923,7 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx, * * \param sctx: Snap context. * \param mval: Screenspace coordinate. + * \param prev_co: Coordinate for perpendicular point calculation (optional). * \param dist_px: Maximum distance to snap (in pixels). * \param r_co: hit location. * \param r_no: hit normal (optional). @@ -2891,12 +2933,13 @@ bool ED_transform_snap_object_project_view3d(SnapObjectContext *sctx, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], + const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3]) { return ED_transform_snap_object_project_view3d_ex( - sctx, snap_to, params, mval, dist_px, r_loc, r_no, NULL, NULL, NULL) != 0; + sctx, snap_to, params, mval, prev_co, dist_px, r_loc, r_no, NULL, NULL, NULL) != 0; } /** diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 8cf7b82e1ca..9ab9a0b650a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2048,6 +2048,7 @@ enum { #define SCE_SNAP_MODE_VOLUME (1 << 3) #define SCE_SNAP_MODE_INCREMENT (1 << 4) #define SCE_SNAP_MODE_EDGE_MIDPOINT (1 << 5) +#define SCE_SNAP_MODE_EDGE_PERPENDICULAR (1 << 6) /* ToolSettings.snap_node_mode */ #define SCE_SNAP_MODE_GRID (1 << 5) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 0da96a895a9..b1661e9a0eb 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -172,6 +172,11 @@ const EnumPropertyItem rna_enum_snap_element_items[] = { ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, + {SCE_SNAP_MODE_EDGE_PERPENDICULAR, + "EDGE_PERPENDICULAR", + ICON_SNAP_PERPENDICULAR, + "Edge Perpendicular", + "Snap to the nearest point on an edge"}, {0, NULL, 0, NULL, NULL}, }; -- cgit v1.2.3