[Bf-blender-cvs] [21e446cc9d7] temp-trimesh-sculpt: * PBVH node join code is now enabled for dyntopo bmesh * Fixed bug in dyntopo bmesh time limiting code

Joseph Eagar noreply at git.blender.org
Sat Oct 24 11:17:36 CEST 2020


Commit: 21e446cc9d771921523678bb18ec508022cf14ea
Author: Joseph Eagar
Date:   Sat Oct 24 02:16:49 2020 -0700
Branches: temp-trimesh-sculpt
https://developer.blender.org/rB21e446cc9d771921523678bb18ec508022cf14ea

* PBVH node join code is now enabled for dyntopo bmesh
* Fixed bug in dyntopo bmesh time limiting code

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

M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 3140837ebac..a9ec91a39bc 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1364,7 +1364,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
                                       node->bm_faces,
                                       node->bm_unique_verts,
                                       node->bm_other_verts,
-                                      update_flags);
+                                      update_flags,
+                                      pbvh->cd_vert_node_offset);
         break;
       case PBVH_TRIMESH:
         GPU_pbvh_trimesh_buffers_update(node->draw_buffers,
@@ -1388,7 +1389,7 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
       PBVHNode *node = nodes[n];
 
       if (node->flag & PBVH_Delete) {
-        printf("corrupted node! %p\n", node);
+        printf("corrupted node! %p %d\n", node, node->flag);
         return;
       }
 
@@ -2441,7 +2442,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
                                      face_normal);
       break;
     case PBVH_BMESH:
-      //BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
+      // BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
       hit = pbvh_bmesh_node_raycast(node,
                                     ray_start,
                                     ray_normal,
@@ -3027,7 +3028,6 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
   for (int n = 0; n < pbvh->totnode; n++) {
     PBVHNode *node = pbvh->nodes + n;
 
-
     if (node->proxy_count > 0) {
       if (tot == space) {
         /* resize array if needed */
@@ -3424,10 +3424,12 @@ void BKE_pbvh_ensure_proxyarray(SculptSession *ss,
       if (vd.no) {
         copy_v3_v3_short(p->no[i], vd.no);
         normal_short_to_float_v3(p->fno[i], vd.no);
-      } else if (vd.fno) {
+      }
+      else if (vd.fno) {
         copy_v3_v3(p->fno[i], vd.fno);
         normal_float_to_short_v3(p->no[i], p->fno[i]);
-      } else {
+      }
+      else {
         zero_v3(p->fno[i]);
         p->fno[i][2] = 1.0f;
         normal_float_to_short_v3(p->no[i], p->fno[i]);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 0d31494daa8..05d1d2c3e2b 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -20,11 +20,13 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_array.h"
 #include "BLI_buffer.h"
 #include "BLI_ghash.h"
 #include "BLI_heap_simple.h"
 #include "BLI_math.h"
 #include "BLI_memarena.h"
+#include "BLI_rand.h"
 #include "BLI_utildefines.h"
 #include "PIL_time.h"
 
@@ -40,17 +42,36 @@
 #define DYNTOPO_TIME_LIMIT 0.015
 #define DYNTOPO_RUN_INTERVAL 0.01
 
+#define DYNTOPO_USE_HEAP
+
+#ifndef DYNTOPO_USE_HEAP
+/* don't add edges into the queue multiple times */
+#  define USE_EDGEQUEUE_TAG
+#endif
+
 /* Avoid skinny faces */
 #define USE_EDGEQUEUE_EVEN_SUBDIV
+
 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
 #  include "BKE_global.h"
 #endif
 
+#ifdef WIN32
+#  include "crtdbg.h"
+#endif
+
+static void check_heap()
+{
+#ifdef WIN32
+  if (!_CrtCheckMemory()) {
+    printf("Memory corruption!");
+    _CrtDbgBreak();
+  }
+#endif
+}
 /* Support for only operating on front-faces */
 #define USE_EDGEQUEUE_FRONTFACE
 
-/* don't add edges into the queue multiple times */
-#define USE_EDGEQUEUE_TAG
 /**
  * Ensure we don't have dirty tags for the edge queue, and that they are left cleared.
  * (slow, even for debug mode, so leave disabled for now).
@@ -204,7 +225,8 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
 static void pbvh_bmesh_node_finalize(PBVH *pbvh,
                                      const int node_index,
                                      const int cd_vert_node_offset,
-                                     const int cd_face_node_offset)
+                                     const int cd_face_node_offset,
+                                     bool add_orco)
 {
   GSetIterator gs_iter;
   PBVHNode *n = &pbvh->nodes[node_index];
@@ -255,19 +277,24 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
   BKE_pbvh_node_mark_rebuild_draw(n);
 
   BKE_pbvh_node_fully_hidden_set(n, !has_visible);
-  n->flag |= PBVH_UpdateNormals;
+  n->flag |= PBVH_UpdateNormals | PBVH_UpdateTopology;
+
+  if (add_orco) {
+    BKE_pbvh_bmesh_node_save_orig(pbvh->bm, n);
+  }
 }
 
 /* Recursively split the node if it exceeds the leaf_limit */
-static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_index)
+static void pbvh_bmesh_node_split(
+    PBVH *pbvh, const BBC *bbc_array, int node_index, bool add_orco, int depth)
 {
   const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
   const int cd_face_node_offset = pbvh->cd_face_node_offset;
   PBVHNode *n = &pbvh->nodes[node_index];
 
-  if (BLI_gset_len(n->bm_faces) <= pbvh->leaf_limit) {
+  if (depth > 6 || BLI_gset_len(n->bm_faces) <= pbvh->leaf_limit) {
     /* Node limit not exceeded */
-    pbvh_bmesh_node_finalize(pbvh, node_index, cd_vert_node_offset, cd_face_node_offset);
+    pbvh_bmesh_node_finalize(pbvh, node_index, cd_vert_node_offset, cd_face_node_offset, add_orco);
     return;
   }
 
@@ -286,6 +313,10 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
   const int axis = BB_widest_axis(&cb);
   const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
 
+  if (isnan(mid)) {
+    printf("NAN ERROR! %s\n", __func__);
+  }
+
   /* Add two new child nodes */
   const int children = pbvh->totnode;
   n->children_offset = children;
@@ -313,7 +344,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
       BLI_gset_insert(c2->bm_faces, f);
     }
   }
-
+#if 0
   /* Enforce at least one primitive in each node */
   GSet *empty = NULL, *other;
   if (BLI_gset_len(c1->bm_faces) == 0) {
@@ -324,6 +355,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
     empty = c2->bm_faces;
     other = c1->bm_faces;
   }
+
   if (empty) {
     GSET_ITER (gs_iter, other) {
       void *key = BLI_gsetIterator_getKey(&gs_iter);
@@ -332,7 +364,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
       break;
     }
   }
-
+#endif
   /* Clear this node */
 
   /* Mark this node's unique verts as unclaimed */
@@ -371,8 +403,8 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
   n->flag &= ~PBVH_Leaf;
 
   /* Recurse */
-  pbvh_bmesh_node_split(pbvh, bbc_array, children);
-  pbvh_bmesh_node_split(pbvh, bbc_array, children + 1);
+  pbvh_bmesh_node_split(pbvh, bbc_array, children, add_orco, depth + 1);
+  pbvh_bmesh_node_split(pbvh, bbc_array, children + 1, add_orco, depth + 1);
 
   /* Array maybe reallocated, update current node pointer */
   n = &pbvh->nodes[node_index];
@@ -389,6 +421,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
 {
   GSet *bm_faces = pbvh->nodes[node_index].bm_faces;
   const int bm_faces_size = BLI_gset_len(bm_faces);
+
   if (bm_faces_size <= pbvh->leaf_limit) {
     /* Node limit not exceeded */
     return false;
@@ -417,7 +450,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
   /* Likely this is already dirty. */
   pbvh->bm->elem_index_dirty |= BM_FACE;
 
-  pbvh_bmesh_node_split(pbvh, bbc_array, node_index);
+  pbvh_bmesh_node_split(pbvh, bbc_array, node_index, pbvh->nodes[node_index].bm_ortri != NULL, 0);
 
   MEM_freeN(bbc_array);
 
@@ -480,12 +513,18 @@ BLI_INLINE int pbvh_bmesh_node_index_from_face(PBVH *pbvh, const BMFace *key)
 
 BLI_INLINE PBVHNode *pbvh_bmesh_node_from_vert(PBVH *pbvh, const BMVert *key)
 {
-  return &pbvh->nodes[pbvh_bmesh_node_index_from_vert(pbvh, key)];
+  int ni = pbvh_bmesh_node_index_from_vert(pbvh, key);
+
+  return ni >= 0 ? pbvh->nodes + ni : NULL;
+  // return &pbvh->nodes[pbvh_bmesh_node_index_from_vert(pbvh, key)];
 }
 
 BLI_INLINE PBVHNode *pbvh_bmesh_node_from_face(PBVH *pbvh, const BMFace *key)
 {
-  return &pbvh->nodes[pbvh_bmesh_node_index_from_face(pbvh, key)];
+  int ni = pbvh_bmesh_node_index_from_face(pbvh, key);
+
+  return ni >= 0 ? pbvh->nodes + ni : NULL;
+  // return &pbvh->nodes[pbvh_bmesh_node_index_from_face(pbvh, key)];
 }
 
 static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
@@ -640,6 +679,10 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
   BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
     const int f_node_index = pbvh_bmesh_node_index_from_face(pbvh, f);
 
+    if (f_node_index == DYNTOPO_NODE_NONE) {
+      continue;
+    }
+
     /* faces often share the same node,
      * quick check to avoid redundant #BLI_gset_remove calls */
     if (f_node_index_prev != f_node_index) {
@@ -662,6 +705,11 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f)
 {
   PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
 
+  if (!f_node) {
+    printf("pbvh corruption\n");
+    fflush(stdout);
+    return;
+  }
   /* Check if any of this face's vertices need to be removed
    * from the node */
   BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
@@ -733,6 +781,10 @@ struct EdgeQueue;
 
 typedef struct EdgeQueue {
   HeapSimple *heap;
+
+  void **elems;
+  int totelems;
+
   const float *center;
   float center_proj[3]; /* for when we use projected coords. */
   float radius_squared;
@@ -742,6 +794,7 @@ typedef struct EdgeQueue {
 #endif
 
   bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMFace *f);
+  bool (*edge_queue_vert_in_range)(const struct EdgeQueue *q, BMVert *v);
 
   const float *view_normal;
 #ifdef USE_EDGEQUEUE_FRONTFACE
@@ -758,6 +811,17 @@ typedef struct {
   int cd_face_node_offset;
 } EdgeQueueContext;
 
+static float calc_weighted_edge(EdgeQueueContext *eq_ctx, BMEdge *e)
+{
+  float l = BM_edge_calc_length_squared(e);
+  float n;
+
+  n = (float)(BM_vert_edge_count(e->v1) + BM_vert_edge_count(e->v2)) * 0.5f;
+  n = MAX2(n - 5.0f, 1.0f);
+
+  return l * powf(n, 5.0f);
+}
+
 /* only tag'd edges are in the queue */
 #ifdef USE_EDGEQUEUE_TAG
 #  define EDGE_QUEUE_TEST(e) (BM

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list