Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-09-12 16:52:03 +0300
committermano-wii <germano.costa@ig.com.br>2019-09-12 16:58:18 +0300
commitc168092014ef117abb1a6d38c6f6827dab181f09 (patch)
tree0a8d60a7dd0fa6b89b7643fdd7029e0749e1b2d1
parent62c820cdaa7c184851ac4ec80b4fe7cf28fc8060 (diff)
Fix T69792: Auto-merge split faces creates faces with unrelated wire edges.
-rw-r--r--source/blender/editors/mesh/editmesh_automerge.c82
1 files changed, 57 insertions, 25 deletions
diff --git a/source/blender/editors/mesh/editmesh_automerge.c b/source/blender/editors/mesh/editmesh_automerge.c
index 82f53aafad8..1d342c7e9a2 100644
--- a/source/blender/editors/mesh/editmesh_automerge.c
+++ b/source/blender/editors/mesh/editmesh_automerge.c
@@ -120,32 +120,35 @@ struct EDBMSplitEdgeData {
};
static bool edbm_vert_pair_share_best_splittable_face_cb(BMFace *f,
- BMLoop *UNUSED(l_a),
- BMLoop *UNUSED(l_b),
+ BMLoop *l_a,
+ BMLoop *l_b,
void *userdata)
{
struct EDBMSplitBestFaceData *data = userdata;
- float no[3], min = FLT_MAX, max = -FLT_MAX;
+ float no[3];
copy_v3_v3(no, f->no);
- BMVert *verts[2] = {NULL};
+ float min = dot_v3v3(l_a->v->co, no);
+ float max = dot_v3v3(l_b->v->co, no);
+ if (min > max) {
+ SWAP(float, min, max);
+ }
+
+ BMVert *v_test = l_b->v;
BMEdge **e_iter = &data->edgenet[0];
- for (int i = data->edgenet_len; i--; e_iter++) {
- BMIter iter;
- BMVert *v;
- BM_ITER_ELEM (v, &iter, *e_iter, BM_VERTS_OF_EDGE) {
- if (!ELEM(v, verts[0], verts[1])) {
- float dot = dot_v3v3(v->co, no);
- if (dot < min) {
- min = dot;
- }
- if (dot > max) {
- max = dot;
- }
- }
+ int verts_len = data->edgenet_len - 1;
+ for (int i = verts_len; i--; e_iter++) {
+ v_test = BM_edge_other_vert(*e_iter, v_test);
+ if (!BM_face_point_inside_test(f, v_test->co)) {
+ return false;
+ }
+ float dot = dot_v3v3(v_test->co, no);
+ if (dot < min) {
+ min = dot;
+ }
+ if (dot > max) {
+ max = dot;
}
- verts[0] = (*e_iter)->v1;
- verts[1] = (*e_iter)->v2;
}
const float test_face_range_on_normal_axis = max - min;
@@ -179,10 +182,8 @@ static bool edbm_vert_pair_share_splittable_face_cb(BMFace *UNUSED(f),
return false;
}
-static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
- BMVert *v,
- BMEdge **r_edgenet[],
- int *r_edgenet_alloc_len)
+static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(
+ BMesh *bm, BMVert *v, const float epsilon, BMEdge **r_edgenet[], int *r_edgenet_alloc_len)
{
BMEdge **edgenet = *r_edgenet;
int edgenet_alloc_len = *r_edgenet_alloc_len;
@@ -206,15 +207,26 @@ static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
BMEdge *e_next = BM_DISK_EDGE_NEXT(e, v_other);
if (e_next == e) {
- /* Vert is wire_endpoint */
+ /* Vert is wire_endpoint. */
edgenet_len = 0;
break;
}
+
+ BMEdge *e_test = e_next;
+ while ((e_test = BM_DISK_EDGE_NEXT(e_test, v_other)) != e) {
+ if (e_test->l) {
+ /* Vert is linked to a face. */
+ goto l_break;
+ }
+ }
+
e = e_next;
}
BMLoop *dummy;
BMFace *best_face;
+
+ l_break:
if (edgenet_len == 0) {
/* Nothing to do. */
continue;
@@ -236,6 +248,25 @@ static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
BM_vert_pair_shared_face_cb(
v_other, v, true, edbm_vert_pair_share_best_splittable_face_cb, &data, &dummy, &dummy);
+ if (data.r_best_face) {
+ float no[3], min = FLT_MAX, max = -FLT_MAX;
+ copy_v3_v3(no, data.r_best_face->no);
+ BMVert *v_test;
+ BMIter f_iter;
+ BM_ITER_ELEM (v_test, &f_iter, data.r_best_face, BM_VERTS_OF_FACE) {
+ float dot = dot_v3v3(v_test->co, no);
+ if (dot < min) {
+ min = dot;
+ }
+ if (dot > max) {
+ max = dot;
+ }
+ }
+ float range = max - min + 2 * epsilon;
+ if (range < data.best_face_range_on_normal_axis) {
+ data.r_best_face = NULL;
+ }
+ }
best_face = data.r_best_face;
}
@@ -498,7 +529,8 @@ void EDBM_automerge_and_split(Object *obedit,
GHASH_ITER (gh_iter, ghash_targetmap) {
v = BLI_ghashIterator_getValue(&gh_iter);
BLI_assert(BM_elem_flag_test(v, hflag) || hflag == BM_ELEM_TAG);
- edbm_automerge_weld_linked_wire_edges_into_linked_faces(bm, v, &edgenet, &edgenet_alloc_len);
+ edbm_automerge_weld_linked_wire_edges_into_linked_faces(
+ bm, v, dist, &edgenet, &edgenet_alloc_len);
}
}