Commit: d27fb4671512a3834b61c5c350f428ddccc4669e Author: mano-wii Date: Wed Jan 1 21:06:59 2020 -0300 Branches: master https://developer.blender.org/rBd27fb4671512a3834b61c5c350f428ddccc4669e
EditMesh: Improve AutoMerge with Split Edges & Faces Previously, compared to `Auto Merge` without `Split Edges & Faces`, `Auto Merge` with this option ignored duplicates between selected vertices. It only considered duplicates between selected vertices and unselected vertices. This is a regress and not a progress. This commit implements this behavior, so this option matches the other `Auto Merge`. =================================================================== M source/blender/bmesh/tools/bmesh_intersect_edges.c M source/blender/editors/include/ED_mesh.h M source/blender/editors/mesh/editmesh_automerge.c =================================================================== diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c index 82e2151dc01..27102694e88 100644 --- a/source/blender/bmesh/tools/bmesh_intersect_edges.c +++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c @@ -240,20 +240,15 @@ struct EDBMSplitElem { struct EDBMSplitData { BMesh *bm; BLI_Stack *pair_stack; - int cut_edges_a_len; - int cut_edges_b_len; + int cut_edges_len; float dist_sq; float dist_sq_sq; }; /* Utils */ -static void bm_vert_pair_elem_setup_ex(BMVert *v, - float edge_index, - struct EDBMSplitElem *r_pair_elem) +static void bm_vert_pair_elem_setup_ex(BMVert *v, struct EDBMSplitElem *r_pair_elem) { - BLI_assert(v->head.index == -1); - v->head.index = edge_index; r_pair_elem->vert = v; } @@ -274,21 +269,23 @@ static void bm_edge_pair_elem_setup(BMEdge *e, } /* Util for Vert x Edge and Edge x Edge callbacks */ -static bool bm_vertxedge_isect_impl_ex(BMVert *v, - BMEdge *e, - int edge_index, - const float co[3], - const float dir[3], - float lambda, - float data_dist_sq, - int *data_cut_edges_len, - struct EDBMSplitElem r_pair[2]) +static bool bm_edgexvert_isect_impl(BMVert *v, + BMEdge *e, + const float co[3], + const float dir[3], + float lambda, + float data_dist_sq, + int *data_cut_edges_len, + struct EDBMSplitElem r_pair[2]) { - BLI_assert(v->head.index == -1); - BMVert *e_v; float dist_sq_vert_factor; + if (!IN_RANGE_INCL(lambda, 0.0f, 1.0f)) { + /* Vert x Vert is already handled elsewhere. */ + return false; + } + if (lambda < 0.5f) { e_v = e->v1; dist_sq_vert_factor = lambda; @@ -299,27 +296,19 @@ static bool bm_vertxedge_isect_impl_ex(BMVert *v, } if (v != e_v) { - CLAMP(lambda, 0.0f, 1.0f); + float dist_sq_vert = SQUARE(dist_sq_vert_factor) * len_squared_v3(dir); + if (dist_sq_vert < data_dist_sq) { + /* Vert x Vert is already handled elsewhere. */ + return false; + } float near[3]; madd_v3_v3v3fl(near, co, dir, lambda); float dist_sq = len_squared_v3v3(v->co, near); if (dist_sq < data_dist_sq) { - float dist_sq_vert = SQUARE(dist_sq_vert_factor) * len_squared_v3(dir); - if (dist_sq_vert < data_dist_sq) { - if (e_v->head.index != -1) { - /* Vertex already has an intersection. */ - return false; - } - - bm_vert_pair_elem_setup_ex(e_v, -2, &r_pair[1]); - } - else { - bm_edge_pair_elem_setup(e, lambda, data_cut_edges_len, &r_pair[1]); - } - - bm_vert_pair_elem_setup_ex(v, edge_index, &r_pair[0]); + bm_edge_pair_elem_setup(e, lambda, data_cut_edges_len, &r_pair[0]); + bm_vert_pair_elem_setup_ex(v, &r_pair[1]); return true; } } @@ -340,75 +329,48 @@ static bool bm_vertxvert_isect_cb(void *userdata, int index_a, int index_b, int BLI_assert(v_a->head.index == -1); /* Set index -2 for sure that it will not repeat keys in `targetmap`. */ - bm_vert_pair_elem_setup_ex(v_a, -2, &pair[0]); - bm_vert_pair_elem_setup_ex(v_b, -1, &pair[1]); + bm_vert_pair_elem_setup_ex(v_a, &pair[0]); + bm_vert_pair_elem_setup_ex(v_b, &pair[1]); return true; } +static bool bm_vertxvert_self_isect_cb(void *userdata, int index_a, int index_b, int thread) +{ + if (index_a < index_b) { + return bm_vertxvert_isect_cb(userdata, index_a, index_b, thread); + } + return false; +} + /* Vertex x Edge and Edge x Vertex Callbacks */ -static int bm_vertxedge_isect_impl(BMesh *bm, - int vert_index, - int edge_index, - float data_dist_sq, - int *data_cut_edges_len, - struct EDBMSplitElem r_pair[2]) +static bool bm_edgexvert_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - BMVert *v = BM_vert_at_index(bm, vert_index); - BMEdge *e = BM_edge_at_index(bm, edge_index); - - if (v->head.index != -1) { - /* Only one vertex per edge. */ - return false; - } + struct EDBMSplitData *data = userdata; + BMEdge *e = BM_edge_at_index(data->bm, index_a); + BMVert *v = BM_vert_at_index(data->bm, index_b); float co[3], dir[3], lambda; copy_v3_v3(co, e->v1->co); sub_v3_v3v3(dir, e->v2->co, co); lambda = ray_point_factor_v3_ex(v->co, co, dir, 0.0f, -1.0f); - return bm_vertxedge_isect_impl_ex( - v, e, edge_index, co, dir, lambda, data_dist_sq, data_cut_edges_len, r_pair); -} - -static bool bm_vertxedge_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) -{ - struct EDBMSplitData *data = userdata; struct EDBMSplitElem pair_tmp[2]; - if (bm_vertxedge_isect_impl( - data->bm, index_a, index_b, data->dist_sq, &data->cut_edges_b_len, pair_tmp)) { + if (bm_edgexvert_isect_impl( + v, e, co, dir, lambda, data->dist_sq, &data->cut_edges_len, pair_tmp)) { struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack); pair[0] = pair_tmp[0]; pair[1] = pair_tmp[1]; - - return true; - } - - return false; -} - -static bool bm_edgexvert_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) -{ - struct EDBMSplitData *data = userdata; - struct EDBMSplitElem pair_tmp[2]; - if (bm_vertxedge_isect_impl( - data->bm, index_b, index_a, data->dist_sq, &data->cut_edges_a_len, pair_tmp)) { - struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack); - pair[0] = pair_tmp[1]; - pair[1] = pair_tmp[0]; - - return true; } + /* Always return false with edges. */ return false; } /* Edge x Edge Callbacks */ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data, - int index_a, - int index_b, BMEdge *e_a, BMEdge *e_b, const float co_a[3], @@ -439,8 +401,18 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data, } if (e_a_v != e_b_v) { - CLAMP(lambda_a, 0.0f, 1.0f); - CLAMP(lambda_b, 0.0f, 1.0f); + if (!IN_RANGE_INCL(lambda_a, 0.0f, 1.0f) || !IN_RANGE_INCL(lambda_b, 0.0f, 1.0f)) { + /* Vert x Edge is already handled elsewhere. */ + return; + } + + float dist_sq_va = SQUARE(dist_sq_va_factor) * len_squared_v3(dir_a); + float dist_sq_vb = SQUARE(dist_sq_vb_factor) * len_squared_v3(dir_b); + + if (dist_sq_va < data->dist_sq || dist_sq_vb < data->dist_sq) { + /* Vert x Edge is already handled elsewhere. */ + return; + } float near_a[3], near_b[3]; madd_v3_v3v3fl(near_a, co_a, dir_a, lambda_a); @@ -450,32 +422,8 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data, if (dist_sq < data->dist_sq) { struct EDBMSplitElem pair_tmp[2]; - float dist_sq_va = SQUARE(dist_sq_va_factor) * len_squared_v3(dir_a); - float dist_sq_vb = SQUARE(dist_sq_vb_factor) * len_squared_v3(dir_b); - - if (dist_sq_va < data->dist_sq) { - if (e_a_v->head.index != -1) { - /* Only one vertex per edge. */ - return; - } - bm_vert_pair_elem_setup_ex(e_a_v, index_b, &pair_tmp[0]); - } - - if (dist_sq_vb < data->dist_sq) { - if (e_b_v->head.index != -1) { - /* Only one vertex per edge. */ - return; - } - bm_vert_pair_elem_setup_ex(e_b_v, index_a, &pair_tmp[1]); - } - else { - bm_edge_pair_elem_setup(e_b, lambda_b, &data->cut_edges_b_len, &pair_tmp[1]); - } - - /* Don't setup edges before a return. */ - if (dist_sq_va >= data->dist_sq) { - bm_edge_pair_elem_setup(e_a, lambda_a, &data->cut_edges_a_len, &pair_tmp[0]); - } + bm_edge_pair_elem_setup(e_a, lambda_a, &data->cut_edges_len, &pair_tmp[0]); + bm_edge_pair_elem_setup(e_b, lambda_b, &data->cut_edges_len, &pair_tmp[1]); struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack); pair[0] = pair_tmp[0]; @@ -486,11 +434,15 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data, static bool bm_edgexedge_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - bool ret = false; struct EDBMSplitData *data = userdata; BMEdge *e_a = BM_edge_at_index(data->bm, index_a); BMEdge *e_b = BM_edge_at_index(data->bm, index_b); + if (BM_edge_share_vert_check(e_a, e_b)) { + /* The other vertices may intersect but Vert x Edge is already handled elsewhere. */ + return false; + } + float co_a[3], dir_a[3], co_b[3], dir_b[3]; copy_v3_v3(co_a, e_a->v1->co); sub_v3_v3v3(dir_a, e_a->v2->co, co_a); @@ -501,99 +453,19 @@ static bool bm_edgexedge_isect_cb(void *userdata, int index_a, int index_b, int float lambda_a, lambda_b; /* Using with dist^4 as `epsilon` is not the best solution, but it fits in most cases. */ if (isect_ray_ray_epsilon_v3(co_a, dir_a, co_b, dir_b, data->dist_sq_sq, &lambda_a, &lambda_b)) { - if (ELEM(index_b, e_a->v1->head.index, e_a->v2->head.index) || - ELEM(index_a, e_b->v1->head.index, e_b->v2->head.index)) { - return ret; - } - - /* Edge x Edge returns always false. */ - bm_edgexedge_isect_impl( - data, index_a, index_b, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b); + bm_edgexedge_isect_impl(data, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b); } - else { - /* Parallel */ - struct EDBMSplitElem pair_tmp[2]; - float vec[3], len_sq_a, len_sq_b, lambda; - @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs