Commit: d2da8aa27aad3e97365e6cae80d3c516073529c9
Author: Campbell Barton
Date:   Mon Apr 13 20:40:52 2015 +1000
Branches: master
https://developer.blender.org/rBd2da8aa27aad3e97365e6cae80d3c516073529c9

BMesh: resolve skinny face artifacts /w dyntopo

Dyntopo can currently create skinny faces,
especially when the faces are much larger then the resolution.

To get the old behavior, set debug value to 1234

===================================================================

M       source/blender/blenkernel/intern/pbvh_bmesh.c

===================================================================

diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c 
b/source/blender/blenkernel/intern/pbvh_bmesh.c
index fb4ad70..f7edd34 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -41,6 +41,12 @@
 
 #include <assert.h>
 
+/* Avoid skinny faces */
+#define USE_EDGEQUEUE_EVEN_SUBDIV
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+#  include "BKE_global.h"
+#endif
+
 // #define USE_VERIFY
 
 #ifdef USE_VERIFY
@@ -570,6 +576,9 @@ typedef struct {
        const float *center;
        float radius_squared;
        float limit_len_squared;
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+       float limit_len;
+#endif
 } EdgeQueue;
 
 typedef struct {
@@ -633,6 +642,57 @@ static void long_edge_queue_edge_add(EdgeQueueContext 
*eq_ctx,
                edge_queue_insert(eq_ctx, e, -len_sq);
 }
 
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+static void long_edge_queue_edge_add_recursive(
+        EdgeQueueContext *eq_ctx,
+        BMLoop *l_edge, BMLoop *l_end,
+        const float len_sq, float limit_len)
+{
+       BLI_assert(len_sq > SQUARE(limit_len));
+       edge_queue_insert(eq_ctx, l_edge->e, -len_sq);
+
+       /* temp support previous behavior! */
+       if (UNLIKELY(G.debug_value == 1234)) {
+               return;
+       }
+
+       if ((l_edge->radial_next != l_edge)) {
+               /* how much longer we need to be to consider for subdividing
+                * (avoids subdividing faces which are only *slightly* skinny) 
*/
+#define EVEN_EDGELEN_THRESHOLD  1.2f
+               /* how much the limit increases per recursion
+                * (avoids performing subdvisions too far away) */
+#define EVEN_GENERATION_SCALE   1.6f
+
+               const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
+               float limit_len_sq;
+               BMLoop *l_iter;
+
+               limit_len *= EVEN_GENERATION_SCALE;
+               limit_len_sq = SQUARE(limit_len);
+
+               l_iter = l_edge;
+               do {
+                       float len_sq_other;
+                       BMLoop *l_adjacent[2] = {l_iter->next, l_iter->prev};
+                       int i;
+                       for (i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
+                               len_sq_other = 
BM_edge_calc_length_squared(l_adjacent[i]->e);
+                               if (len_sq_other > max_ff(len_sq_cmp, 
limit_len_sq)) {
+//                                     edge_queue_insert(eq_ctx, 
l_adjacent[i]->e, -len_sq_other);
+                                       long_edge_queue_edge_add_recursive(
+                                               eq_ctx, 
l_adjacent[i]->radial_next, l_adjacent[i],
+                                               len_sq_other, limit_len);
+                               }
+                       }
+               } while ((l_iter = l_iter->radial_next) != l_end);
+
+#undef EVEN_EDGELEN_THRESHOLD
+#undef EVEN_GENERATION_SCALE
+       }
+}
+#endif  /* USE_EDGEQUEUE_EVEN_SUBDIV */
+
 static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx,
                                       BMEdge *e)
 {
@@ -651,7 +711,16 @@ static void long_edge_queue_face_add(EdgeQueueContext 
*eq_ctx,
                /* Check each edge of the face */
                l_iter = l_first = BM_FACE_FIRST_LOOP(f);
                do {
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+                       const float len_sq = 
BM_edge_calc_length_squared(l_iter->e);
+                       if (len_sq > eq_ctx->q->limit_len_squared) {
+                               long_edge_queue_edge_add_recursive(
+                                       eq_ctx, l_iter->radial_next, l_iter,
+                                       len_sq, eq_ctx->q->limit_len_squared);
+                       }
+#else
                        long_edge_queue_edge_add(eq_ctx, l_iter->e);
+#endif
                } while ((l_iter = l_iter->next) != l_first);
        }
 }
@@ -690,6 +759,9 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
        eq_ctx->q->center = center;
        eq_ctx->q->radius_squared = radius * radius;
        eq_ctx->q->limit_len_squared = bvh->bm_max_edge_len * 
bvh->bm_max_edge_len;
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+       eq_ctx->q->limit_len = bvh->bm_max_edge_len;
+#endif
 
        for (n = 0; n < bvh->totnode; n++) {
                PBVHNode *node = &bvh->nodes[n];
@@ -730,6 +802,9 @@ static void short_edge_queue_create(EdgeQueueContext 
*eq_ctx,
        eq_ctx->q->center = center;
        eq_ctx->q->radius_squared = radius * radius;
        eq_ctx->q->limit_len_squared = bvh->bm_min_edge_len * 
bvh->bm_min_edge_len;
+#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
+       eq_ctx->q->limit_len = bvh->bm_min_edge_len;
+#endif
 
        for (n = 0; n < bvh->totnode; n++) {
                PBVHNode *node = &bvh->nodes[n];

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to