Scanfill: skip checks for loose edges when they can't occur
authorCampbell Barton <ideasman42@gmail.com>
Mon, 3 Feb 2014 15:54:19 +0000 (02:54 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 3 Feb 2014 15:57:27 +0000 (02:57 +1100)
Only editmesh needs this, text, curves, masks - can all skip this check

source/blender/blenlib/BLI_scanfill.h
source/blender/blenlib/intern/scanfill.c
source/blender/bmesh/operators/bmo_triangulate.c

index 52f5decb4f4fe026c79b46995aead3c0e7215e9a..3caa69f91c6b66ec6dfd052bde1a705cdc508e4a 100644 (file)
@@ -98,7 +98,10 @@ enum {
 
        /* note: This flag removes checks for overlapping polygons.
         * when this flag is set, we'll never get back more faces then (totvert - 2) */
-       BLI_SCANFILL_CALC_HOLES            = (1 << 2)
+       BLI_SCANFILL_CALC_HOLES            = (1 << 2),
+
+       /* checks valid edge users - can skip for simple loops */
+       BLI_SCANFILL_CALC_LOOSE            = (1 << 3),
 };
 void BLI_scanfill_begin(ScanFillContext *sf_ctx);
 unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag);
index 54c8b0f5b729002e7a9ef25f6cef42f93d83d310..b12e982c70873de956380d159726222e42c0c036 100644 (file)
@@ -337,7 +337,7 @@ static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
 
 static void testvertexnearedge(ScanFillContext *sf_ctx)
 {
-       /* only vertices with (->h == 1) are being tested for
+       /* only vertices with (->edge_tot == 1) are being tested for
         * being close to an edge, if true insert */
 
        ScanFillVert *eve;
@@ -927,48 +927,64 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
        }
 
        /* STEP 2: remove loose edges and strings of edges */
-       for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
-               if (eed->v1->edge_tot++ > 250) break;
-               if (eed->v2->edge_tot++ > 250) break;
-       }
-       if (eed) {
-               /* otherwise it's impossible to be sure you can clear vertices */
+       if (flag & BLI_SCANFILL_CALC_LOOSE) {
+               for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+                       if (eed->v1->edge_tot++ > 250) break;
+                       if (eed->v2->edge_tot++ > 250) break;
+               }
+               if (eed) {
+                       /* otherwise it's impossible to be sure you can clear vertices */
 #ifdef DEBUG
-               printf("No vertices with 250 edges allowed!\n");
+                       printf("No vertices with 250 edges allowed!\n");
 #endif
-               return 0;
-       }
-       
-       /* does it only for vertices with (->h == 1) */
-       testvertexnearedge(sf_ctx);
-
-       ok = true;
-       while (ok) {
-               ok = false;
-
-               toggle++;
-               for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last;
-                    eed;
-                    eed = eed_next)
-               {
-                       eed_next = (toggle & 1) ? eed->next : eed->prev;
-                       if (eed->v1->edge_tot == 1) {
-                               eed->v2->edge_tot--;
-                               BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
-                               BLI_remlink(&sf_ctx->filledgebase, eed);
-                               ok = true;
-                       }
-                       else if (eed->v2->edge_tot == 1) {
-                               eed->v1->edge_tot--;
-                               BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
-                               BLI_remlink(&sf_ctx->filledgebase, eed);
-                               ok = true;
+                       return 0;
+               }
+
+               /* does it only for vertices with (->edge_tot == 1) */
+               testvertexnearedge(sf_ctx);
+
+               ok = true;
+               while (ok) {
+                       ok = false;
+
+                       toggle++;
+                       for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last;
+                            eed;
+                            eed = eed_next)
+                       {
+                               eed_next = (toggle & 1) ? eed->next : eed->prev;
+                               if (eed->v1->edge_tot == 1) {
+                                       eed->v2->edge_tot--;
+                                       BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
+                                       BLI_remlink(&sf_ctx->filledgebase, eed);
+                                       ok = true;
+                               }
+                               else if (eed->v2->edge_tot == 1) {
+                                       eed->v1->edge_tot--;
+                                       BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
+                                       BLI_remlink(&sf_ctx->filledgebase, eed);
+                                       ok = true;
+                               }
                        }
                }
+               if (sf_ctx->filledgebase.first == NULL) {
+                       /* printf("All edges removed\n"); */
+                       return 0;
+               }
        }
-       if (sf_ctx->filledgebase.first == NULL) {
-               /* printf("All edges removed\n"); */
-               return 0;
+       else {
+               /* skip checks for loose edges */
+               for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+                       eed->v1->edge_tot++;
+                       eed->v2->edge_tot++;
+               }
+#ifdef DEBUG
+               /* ensure we're right! */
+               for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+                       BLI_assert(eed->v1->edge_tot != 1);
+                       BLI_assert(eed->v2->edge_tot != 1);
+               }
+#endif
        }
 
 
index 30ae01ef7134ad8fccb172c21bbe033743ac2cbb..b66c91678c0b61fc91afb670fa7f0a558978fa1f 100644 (file)
@@ -104,7 +104,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
                normal_pt = normal;
        }
 
-       BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_HOLES, normal_pt);
+       BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_HOLES | BLI_SCANFILL_CALC_LOOSE, normal_pt);
        
        for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
                BMFace *f = BM_face_create_quad_tri(bm,