[Bf-blender-cvs] [5866a4680da] temp_bmesh_multires: Dyntopo Sculpt: Wrote new edge split code, currently disabled

Joseph Eagar noreply at git.blender.org
Mon Aug 23 10:20:32 CEST 2021


Commit: 5866a4680da16bdb34ec5ca316473d5e93e362f4
Author: Joseph Eagar
Date:   Mon Aug 23 01:19:55 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB5866a4680da16bdb34ec5ca316473d5e93e362f4

Dyntopo Sculpt: Wrote new edge split code, currently disabled

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/bmesh/intern/bmesh_core.c

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

diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 013e10d65eb..da3e42e629d 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -5,6 +5,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 
+#include "BLI_alloca.h"
 #include "BLI_array.h"
 #include "BLI_bitmap.h"
 #include "BLI_buffer.h"
@@ -31,6 +32,7 @@
 
 #include <stdio.h>
 
+//#define USE_NEW_SPLIT
 #define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
 
 #define DYNTOPO_MAX_ITER 4096
@@ -144,6 +146,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
 
 static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
 static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
+static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge);
 
 BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
 {
@@ -1688,6 +1691,9 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
       BMEdge *e = edges[j];
       e->head.hflag &= ~BM_ELEM_TAG;
 
+      check_vert_fan_are_tris(pbvh, e->v1);
+      check_vert_fan_are_tris(pbvh, e->v2);
+
       float w = -calc_weighted_edge_split(eq_ctx, e->v1, e->v2);
       float w2 = maskcb_get(eq_ctx, e);
 
@@ -1838,9 +1844,6 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
 
   // pbvh_bmesh_check_nodes(pbvh);
 
-  check_vert_fan_are_tris(pbvh, e->v1);
-  check_vert_fan_are_tris(pbvh, e->v2);
-
   // pbvh_bmesh_check_nodes(pbvh);
 
   float co_mid[3], no_mid[3];
@@ -2046,6 +2049,11 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
   RNG *rng = BLI_rng_new((int)(time * 1000.0f));
   int step = 0;
 
+#ifdef USE_NEW_SPLIT
+  BMEdge **edges = NULL;
+  BLI_array_staticdeclare(edges, 1024);
+#endif
+
   while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
     if (step++ > max_steps) {
       break;
@@ -2105,8 +2113,12 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
     }
 
     any_subdivided = true;
+#ifdef USE_NEW_SPLIT
+    BLI_array_append(edges, e);
+#else
 
     pbvh_bmesh_split_edge(eq_ctx, pbvh, e, edge_loops);
+#endif
   }
 
 #if !defined(DYNTOPO_USE_HEAP) && defined(USE_EDGEQUEUE_TAG)
@@ -2126,6 +2138,11 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
   pbvh_bmesh_edge_tag_verify(pbvh);
 #endif
 
+#ifdef USE_NEW_SPLIT
+  pbvh_split_edges(pbvh, pbvh->bm, edges, BLI_array_len(edges));
+  BLI_array_free(edges);
+#endif
+
   BLI_rng_free(rng);
 
   return any_subdivided;
@@ -3014,3 +3031,311 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
 
   return modified;
 }
+
+#ifdef USE_NEW_SPLIT
+#  define SPLIT_TAG BM_ELEM_TAG_ALT
+
+/*
+#generate shifted and mirrored patterns
+
+table = [
+  [4, 3, -1, -1, -1],
+  [5, -1, 3, -1, 4, -1],
+  [6, -1, 3, -1, 5, -1, 1, -1]
+]
+
+table2 = {}
+
+def getmask(row):
+  mask = 0
+  for i in range(len(row)):
+    if row[i] >= 0:
+      mask |= 1 << i
+  return mask
+
+for row in table:
+  #table2.append(row)
+
+  n = row[0]
+  row = row[1:]
+
+  mask = getmask(row)
+  table2[mask] = [n] + row
+
+  for step in range(2):
+    for i in range(n):
+      row2 = []
+      for j in range(n):
+        j2 = row[(j + i) % n]
+        if j2 >= 0:
+          j2 = (j2 + i) % n
+        row2.append(j2)
+
+      mask = getmask(row2)
+      if mask not in table2:
+        table2[mask] = [n] + row2
+
+    row.reverse()
+
+maxk = 0
+for k in table2:
+  maxk = max(maxk, k)
+
+buf = 'static const int splitmap[%i][16] = {\n' % (maxk+1)
+buf += '  //{numverts, vert_connections...}\n'
+
+for k in range(maxk+1):
+  if k not in table2:
+    buf += '  {-1},\n'
+    continue
+
+  buf += '  {'
+  row = table2[k]
+  for j in range(len(row)):
+    if j > 0:
+      buf += ", "
+    buf += str(row[j])
+  buf += '},\n'
+buf += '};\n'
+print(buf)
+
+*/
+
+static const int splitmap[43][16] = {
+    //{numverts, vert_connections...}
+    {-1},                          // 0
+    {4, 2, -1, -1, -1},            // 1
+    {4, -1, 3, -1, -1},            // 2
+    {-1},                          // 3
+    {4, -1, -1, 0, -1},            // 4
+    {5, 2, -1, 4, -1, -1},         // 5
+    {-1},                          // 6
+    {-1},                          // 7
+    {4, -1, -1, -1, 1},            // 8
+    {5, 2, -1, -1, 0, -1},         // 9
+    {5, -1, 3, -1, 0, -1},         // 10
+    {-1},                          // 11
+    {-1},                          // 12
+    {-1},                          // 13
+    {-1},                          // 14
+    {-1},                          // 15
+    {-1},                          // 16
+    {-1},                          // 17
+    {5, -1, 3, -1, -1, 1},         // 18
+    {-1},                          // 19
+    {5, -1, -1, 4, -1, 1},         // 20
+    {6, 2, -1, 4, -1, 0, -1},      // 21
+    {-1},                          // 22
+    {-1},                          // 23
+    {-1},                          // 24
+    {-1},                          // 25
+    {-1},                          // 26
+    {-1},                          // 27
+    {-1},                          // 28
+    {-1},                          // 29
+    {-1},                          // 30
+    {-1},                          // 31
+    {-1},                          // 32
+    {-1},                          // 33
+    {-1},                          // 34
+    {-1},                          // 35
+    {-1},                          // 36
+    {-1},                          // 37
+    {-1},                          // 38
+    {-1},                          // 39
+    {-1},                          // 40
+    {-1},                          // 41
+    {6, -1, 3, -1, 5, -1, 1, -1},  // 42
+};
+
+static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
+{
+  BMFace **faces = NULL;
+  BLI_array_staticdeclare(faces, 512);
+
+  for (int i = 0; i < totedge; i++) {
+    BMEdge *e = edges[i];
+    BMLoop *l = e->l;
+
+#  if 0
+    int ni = BM_ELEM_CD_GET_INT(e->v1, pbvh->cd_vert_node_offset);
+    if (ni >= 0) {
+      PBVHNode *node = pbvh->nodes + ni;
+
+      BLI_table_gset_remove(node->bm_unique_verts, e->v1, NULL);
+      BM_ELEM_CD_SET_INT(e->v1, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
+    }
+
+    ni = BM_ELEM_CD_GET_INT(e->v2, pbvh->cd_vert_node_offset);
+    if (ni >= 0) {
+      PBVHNode *node = pbvh->nodes + ni;
+
+      BLI_table_gset_remove(node->bm_unique_verts, e->v2, NULL);
+      BM_ELEM_CD_SET_INT(e->v2, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
+    }
+#  endif
+
+    check_vert_fan_are_tris(pbvh, e->v1);
+    check_vert_fan_are_tris(pbvh, e->v2);
+
+    if (!l) {
+      continue;
+    }
+
+    do {
+      BMLoop *l2 = l->f->l_first;
+      do {
+        l2->e->head.hflag &= ~SPLIT_TAG;
+        l2->v->head.hflag &= ~SPLIT_TAG;
+      } while ((l2 = l2->next) != l->f->l_first);
+
+      l->f->head.hflag &= ~SPLIT_TAG;
+    } while ((l = l->radial_next) != e->l);
+  }
+
+  for (int i = 0; i < totedge; i++) {
+    BMEdge *e = edges[i];
+    BMLoop *l = e->l;
+
+    e->head.hflag |= SPLIT_TAG;
+
+    if (!l) {
+      continue;
+    }
+
+    do {
+      if (!(l->f->head.hflag & SPLIT_TAG)) {
+        l->f->head.hflag |= SPLIT_TAG;
+        BLI_array_append(faces, l->f);
+      }
+
+    } while ((l = l->radial_next) != e->l);
+  }
+
+  int totface = BLI_array_len(faces);
+  for (int i = 0; i < totface; i++) {
+    BMFace *f = faces[i];
+    BMLoop *l = f->l_first;
+
+    pbvh_bmesh_face_remove(pbvh, f, true, false, false);
+
+    int mask = 0;
+    int j = 0;
+
+    do {
+      if (l->e->head.hflag & SPLIT_TAG) {
+        mask |= 1 << j;
+      }
+
+      j++;
+    } while ((l = l->next) != f->l_first);
+
+    f->head.index = mask;
+  }
+
+  for (int i = 0; i < totedge; i++) {
+    BMEdge *e = edges[i];
+    BMEdge *newe = NULL;
+
+    if (!(e->head.hflag & SPLIT_TAG)) {
+      // printf("error split\n");
+      continue;
+    }
+
+    e->head.hflag &= ~SPLIT_TAG;
+
+    BMVert *newv = BM_edge_split(bm, e, e->v1, &newe, 0.5f);
+
+    newv->head.hflag |= SPLIT_TAG;
+
+    BM_ELEM_CD_SET_INT(newv, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
+    BM_log_vert_added(pbvh->bm_log, newv, pbvh->cd_vert_mask_offset);
+  }
+
+  for (int i = 0; i < totface; i++) {
+    BMFace *f = faces[i];
+    int mask = 0;
+
+    BMLoop *l = f->l_first;
+    int j = 0;
+    do {
+      if (l->v->head.hflag & SPLIT_TAG) {
+        mask |= 1 << j;
+      }
+      j++;
+    } while ((l = l->next) != f->l_first);
+
+    if (mask >= ARRAY_SIZE(splitmap)) {
+      printf("splitmap error!\n");
+      continue;
+    }
+
+    const int *pat = splitmap[mask];
+    int n = pat[0];
+
+    if (n < 0) {
+      continue;
+    }
+
+    if (n != f->len) {
+      printf("error!\n");
+      continue;
+    }
+
+    BMFace *f2 = f;
+    BMVert **vs = BLI_array_alloca(vs, n);
+
+    l = f->l_first;
+    j = 0;
+    do {
+      vs[j++] = l->v;
+    } while ((l = l->next) != f->l_first);
+
+    BMFace **newfaces = BLI_array_alloca(newfaces, n);
+    int count = 0;
+
+    for (j = 0; j < n; j++) {
+      if (pat[j + 1] < 0) {
+        continue;
+      }
+
+      BMVert *v1 = vs[j], *v2 = vs[pat[j + 1]];
+      BMLoop *l1 = NULL, *l2 = NULL;
+      BMLoop *rl = NULL;
+
+      BMLoop *l3 = f2->l_first;
+      do {
+        if (l3->v == v1) {
+          l1 = l3;
+        }
+        else if (l3->v == v2) {
+          l2 = l3;
+        }
+      } while ((l3 = l3->next) != f2->l_first);
+
+      if (l1 == l2 || !l1 || !l2) {
+        printf("errorl!\n");
+        continue;
+      }
+
+      BMFace *newf = BM_face_split(bm, f2, l1, l2, &rl, NULL, false);
+      if (newf) {
+        newfaces[count++] = newf;
+        f2 = newf;
+      }
+      else {
+        printf("error!\n");
+        continue;
+      }
+    }
+
+    for (j = 0; j < count; j++) {
+      BKE_pbvh_bmesh_add_face(pbvh, newfaces[j], true, false);
+    }
+
+    BKE_pbvh_bmesh_add_face(pbvh, f, true, false);
+  }
+
+  BLI_array_free(faces);
+}
+#endif
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 9cf96ed320e..329028faef6 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blende

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list