[Bf-blender-cvs] [d27fb467151] master: EditMesh: Improve AutoMerge with Split Edges & Faces
mano-wii
noreply at git.blender.org
Thu Jan 2 01:08:56 CET 2020
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. @@
More information about the Bf-blender-cvs
mailing list