BMesh: add checks for duplicates in a face
authorCampbell Barton <ideasman42@gmail.com>
Sat, 26 Dec 2015 03:49:07 +0000 (14:49 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 26 Dec 2015 04:34:55 +0000 (15:34 +1100)
These could go un-noticed, causing errors later on.

source/blender/bmesh/intern/bmesh_core.c
source/blender/bmesh/intern/bmesh_private.h

index b166d60ce8fec2da80d259e743ab03c044a76bfb..d5896dd0b314d0d5a9f0d69d404a81cd56ab3b0b 100644 (file)
@@ -553,7 +553,10 @@ int bmesh_elem_check(void *element, const char htype)
                IS_FACE_LOOP_VERT_NOT_IN_EDGE               = (1 << 20),
                IS_FACE_LOOP_WRONG_RADIAL_LENGTH            = (1 << 21),
                IS_FACE_LOOP_WRONG_DISK_LENGTH              = (1 << 22),
-               IS_FACE_WRONG_LENGTH                        = (1 << 23),
+               IS_FACE_LOOP_DUPE_LOOP                      = (1 << 23),
+               IS_FACE_LOOP_DUPE_VERT                      = (1 << 24),
+               IS_FACE_LOOP_DUPE_EDGE                      = (1 << 25),
+               IS_FACE_WRONG_LENGTH                        = (1 << 26),
        } err = 0;
 
        if (!element)
@@ -688,9 +691,39 @@ int bmesh_elem_check(void *element, const char htype)
                                        }
                                }
 
+                               /* check for duplicates */
+                               if (BM_ELEM_API_FLAG_TEST(l_iter, _FLAG_ELEM_CHECK)) {
+                                       err |= IS_FACE_LOOP_DUPE_LOOP;
+                               }
+                               BM_ELEM_API_FLAG_ENABLE(l_iter, _FLAG_ELEM_CHECK);
+                               if (l_iter->v) {
+                                       if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_ELEM_CHECK)) {
+                                               err |= IS_FACE_LOOP_DUPE_VERT;
+                                       }
+                                       BM_ELEM_API_FLAG_ENABLE(l_iter->v, _FLAG_ELEM_CHECK);
+                               }
+                               if (l_iter->e) {
+                                       if (BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_ELEM_CHECK)) {
+                                               err |= IS_FACE_LOOP_DUPE_EDGE;
+                                       }
+                                       BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_ELEM_CHECK);
+                               }
+
                                len++;
                        } while ((l_iter = l_iter->next) != l_first);
 
+                       /* cleanup duplicates flag */
+                       l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+                       do {
+                               BM_ELEM_API_FLAG_DISABLE(l_iter, _FLAG_ELEM_CHECK);
+                               if (l_iter->v) {
+                                       BM_ELEM_API_FLAG_DISABLE(l_iter->v, _FLAG_ELEM_CHECK);
+                               }
+                               if (l_iter->e) {
+                                       BM_ELEM_API_FLAG_DISABLE(l_iter->e, _FLAG_ELEM_CHECK);
+                               }
+                       } while ((l_iter = l_iter->next) != l_first);
+
                        if (len != f->len) {
                                err |= IS_FACE_WRONG_LENGTH;
                        }
index 814015a2a7434fda8b96a8c8b1f44348c0e0bd35..9b3a147301d36e27ac43581d76820e8e8b1a0da4 100644 (file)
@@ -67,6 +67,8 @@ enum {
        _FLAG_MV       = (1 << 1),  /* make face, vertex */
        _FLAG_OVERLAP  = (1 << 2),  /* general overlap flag  */
        _FLAG_WALK     = (1 << 3),  /* general walk flag (keep clean) */
+
+       _FLAG_ELEM_CHECK = (1 << 7),  /* reserved for bmesh_elem_check */
 };
 
 #define BM_ELEM_API_FLAG_ENABLE(element, f)  { ((element)->head.api_flag |=  (f)); } (void)0