diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-08-27 17:19:25 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-08-27 17:24:16 +0300 |
commit | d8baafd693ebf830d6153bd31bd63521c7569984 (patch) | |
tree | ee44ef834e826322e9de79cc943edb8be66041a3 /source/blender/editors/mesh/editmesh_select.c | |
parent | 2a2fd75ef90f18753d3d6ab33c30e60cd95bf174 (diff) |
Edit Mesh: Poly build tool improvements
This commit changes the functionality of the Poly build tool to make it more suitable for retopology tasks:
- Click and drag from a boundary edge extrudes a new quad
- Click and drag on vertices tweaks the position
- Ctrl + click adds geometry. There is a geometry preview in the gizmo. It also can automatically convert triangles to quads.
- Shift + click deletes mesh elements (faces or vertices)
- Updated preselection code. Different mesh elements take priority depending on the selected action.
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D5573
Diffstat (limited to 'source/blender/editors/mesh/editmesh_select.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 159 |
1 files changed, 101 insertions, 58 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index f1055103d16..4d511d45642 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1448,8 +1448,11 @@ bool EDBM_unified_findnearest(ViewContext *vc, bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, Base **bases, const uint bases_len, - bool use_boundary, - int *r_base_index, + bool use_boundary_vertices, + bool use_boundary_edges, + int *r_base_index_vert, + int *r_base_index_edge, + int *r_base_index_face, struct BMVert **r_eve, struct BMEdge **r_eed, struct BMFace **r_efa) @@ -1463,9 +1466,27 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, BMElem *ele; } best = {0, NULL}; + struct { + uint base_index; + BMElem *ele; + } best_vert = {0, NULL}; + + struct { + uint base_index; + BMElem *ele; + } best_edge = {0, NULL}; + + struct { + uint base_index; + BMElem *ele; + } best_face = {0, NULL}; + if (ED_view3d_win_to_ray_clipped( vc->depsgraph, vc->ar, vc->v3d, mval_fl, ray_origin, ray_direction, true)) { float dist_sq_best = FLT_MAX; + float dist_sq_best_vert = FLT_MAX; + float dist_sq_best_edge = FLT_MAX; + float dist_sq_best_face = FLT_MAX; const bool use_vert = (r_eve != NULL); const bool use_edge = (r_eed != NULL); @@ -1495,18 +1516,23 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, BM_mesh_elem_index_ensure(bm, BM_VERT); } - if (use_boundary && (use_vert || use_edge)) { + if ((use_boundary_vertices || use_boundary_edges) && (use_vert || use_edge)) { BMEdge *e; BMIter eiter; BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { if ((BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) && (BM_edge_is_boundary(e))) { - if (use_vert) { + if (use_vert && use_boundary_vertices) { for (uint j = 0; j < 2; j++) { BMVert *v = *((&e->v1) + j); float point[3]; mul_v3_m4v3(point, obedit->obmat, coords ? coords[BM_elem_index_get(v)] : v->co); const float dist_sq_test = dist_squared_to_ray_v3_normalized( ray_origin, ray_direction, point); + if (dist_sq_test < dist_sq_best_vert) { + dist_sq_best_vert = dist_sq_test; + best_vert.base_index = base_index; + best_vert.ele = (BMElem *)v; + } if (dist_sq_test < dist_sq_best) { dist_sq_best = dist_sq_test; best.base_index = base_index; @@ -1515,7 +1541,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, } } - if (use_edge) { + if (use_edge && use_boundary_edges) { float point[3]; #if 0 const float dist_sq_test = dist_squared_ray_to_seg_v3( @@ -1531,6 +1557,11 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, mul_m4_v3(obedit->obmat, point); const float dist_sq_test = dist_squared_to_ray_v3_normalized( ray_origin, ray_direction, point); + if (dist_sq_test < dist_sq_best_edge) { + dist_sq_best_edge = dist_sq_test; + best_edge.base_index = base_index; + best_edge.ele = (BMElem *)e; + } if (dist_sq_test < dist_sq_best) { dist_sq_best = dist_sq_test; best.base_index = base_index; @@ -1541,46 +1572,55 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, } } } - else { - /* Non boundary case. */ - if (use_vert) { - BMVert *v; - BMIter viter; - BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_HIDDEN) == false) { - float point[3]; - mul_v3_m4v3(point, obedit->obmat, v->co); - const float dist_sq_test = dist_squared_to_ray_v3_normalized( - ray_origin, ray_direction, v->co); - if (dist_sq_test < dist_sq_best) { - dist_sq_best = dist_sq_test; - best.base_index = base_index; - best.ele = (BMElem *)v; - } + /* Non boundary case. */ + if (use_vert && !use_boundary_vertices) { + BMVert *v; + BMIter viter; + BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_HIDDEN) == false) { + float point[3]; + mul_v3_m4v3(point, obedit->obmat, coords ? coords[BM_elem_index_get(v)] : v->co); + const float dist_sq_test = dist_squared_to_ray_v3_normalized( + ray_origin, ray_direction, point); + if (dist_sq_test < dist_sq_best_vert) { + dist_sq_best_vert = dist_sq_test; + best_vert.base_index = base_index; + best_vert.ele = (BMElem *)v; + } + if (dist_sq_test < dist_sq_best) { + dist_sq_best = dist_sq_test; + best.base_index = base_index; + best.ele = (BMElem *)v; } } } - if (use_edge) { - BMEdge *e; - BMIter eiter; - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) { - float point[3]; - if (coords) { - mid_v3_v3v3( - point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]); - } - else { - mid_v3_v3v3(point, e->v1->co, e->v2->co); - } - mul_m4_v3(obedit->obmat, point); - const float dist_sq_test = dist_squared_to_ray_v3_normalized( - ray_origin, ray_direction, point); - if (dist_sq_test < dist_sq_best) { - dist_sq_best = dist_sq_test; - best.base_index = base_index; - best.ele = (BMElem *)e; - } + } + + if (use_edge && !use_boundary_edges) { + BMEdge *e; + BMIter eiter; + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) { + float point[3]; + if (coords) { + mid_v3_v3v3( + point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]); + } + else { + mid_v3_v3v3(point, e->v1->co, e->v2->co); + } + mul_m4_v3(obedit->obmat, point); + const float dist_sq_test = dist_squared_to_ray_v3_normalized( + ray_origin, ray_direction, point); + if (dist_sq_test < dist_sq_best_edge) { + dist_sq_best_edge = dist_sq_test; + best_edge.base_index = base_index; + best_edge.ele = (BMElem *)e; + } + if (dist_sq_test < dist_sq_best) { + dist_sq_best = dist_sq_test; + best.base_index = base_index; + best.ele = (BMElem *)e; } } } @@ -1601,6 +1641,11 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, mul_m4_v3(obedit->obmat, point); const float dist_sq_test = dist_squared_to_ray_v3_normalized( ray_origin, ray_direction, point); + if (dist_sq_test < dist_sq_best_face) { + dist_sq_best_face = dist_sq_test; + best_face.base_index = base_index; + best_face.ele = (BMElem *)f; + } if (dist_sq_test < dist_sq_best) { dist_sq_best = dist_sq_test; best.base_index = base_index; @@ -1612,7 +1657,10 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, } } - *r_base_index = best.base_index; + *r_base_index_vert = best_vert.base_index; + *r_base_index_edge = best_edge.base_index; + *r_base_index_face = best_face.base_index; + if (r_eve) { *r_eve = NULL; } @@ -1623,22 +1671,17 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, *r_efa = NULL; } - if (best.ele) { - switch (best.ele->head.htype) { - case BM_VERT: - *r_eve = (BMVert *)best.ele; - break; - case BM_EDGE: - *r_eed = (BMEdge *)best.ele; - break; - case BM_FACE: - *r_efa = (BMFace *)best.ele; - break; - default: - BLI_assert(0); - } + if (best_vert.ele) { + *r_eve = (BMVert *)best_vert.ele; + } + if (best_edge.ele) { + *r_eed = (BMEdge *)best_edge.ele; } - return (best.ele != NULL); + if (best_face.ele) { + *r_efa = (BMFace *)best_face.ele; + } + + return (best_vert.ele != NULL || best_edge.ele != NULL || best_face.ele != NULL); } /** \} */ |