[Bf-blender-cvs] [57286eed8d6] temp_bmesh_multires: Sculpt dyntopo: Add support for multiple materials to dyntopo pbvh drawing.

Joseph Eagar noreply at git.blender.org
Fri Jul 2 22:15:44 CEST 2021


Commit: 57286eed8d67e59dd799a4de6d80fb9a0ce037ab
Author: Joseph Eagar
Date:   Fri Jul 2 13:14:00 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB57286eed8d67e59dd799a4de6d80fb9a0ce037ab

Sculpt dyntopo: Add support for multiple materials to dyntopo
pbvh drawing.

* Dyntopo now stores a list of PBVHTriBufs in leaf nodes, one per material
  used by the node.
* Actual drawing buffers live in a new mat_draw_buffers PBVHNode member.

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

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

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 5a0893535b0..d84144f53e8 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -64,10 +64,11 @@ typedef struct PBVHTriBuf {
   PBVHTri *tris;
   SculptVertRef *verts;
   int tottri, totvert;
+  int tris_size, verts_size;
 
   // private field
   intptr_t *loops;
-  int totloop;
+  int totloop, mat_nr;
   float min[3], max[3];
 } PBVHTriBuf;
 
@@ -703,7 +704,7 @@ bool BKE_pbvh_curvature_update_get(PBVHNode *node);
 
 int BKE_pbvh_get_totnodes(PBVH *pbvh);
 
-void BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node);
+bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node);
 PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node);
 void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node);
 
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 5b0a5cbf29e..03f520741cf 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -705,9 +705,8 @@ void BKE_pbvh_free(PBVH *pbvh)
     PBVHNode *node = &pbvh->nodes[i];
 
     if (node->flag & PBVH_Leaf) {
-      if (node->draw_buffers) {
-        GPU_pbvh_buffers_free(node->draw_buffers);
-      }
+      pbvh_free_all_draw_buffers(node);
+
       if (node->vert_indices) {
         MEM_freeN((void *)node->vert_indices);
       }
@@ -1320,10 +1319,23 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
             node->totprim,
             pbvh->mesh);
         break;
-      case PBVH_BMESH:
-        node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
-                                                          PBVH_DYNTOPO_SMOOTH_SHADING);
+      case PBVH_BMESH: {
+        BKE_pbvh_bmesh_check_tris(pbvh, node);
+
+        node->tot_mat_draw_buffers = node->tot_tri_buffers;
+
+        if (node->tot_tri_buffers) {
+          node->mat_draw_buffers = MEM_malloc_arrayN(
+              node->tot_tri_buffers, sizeof(void *), "node->mat_draw_buffers");
+        }
+
+        for (int i = 0; i < node->tot_tri_buffers; i++) {
+          node->mat_draw_buffers[i] = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
+                                                                   PBVH_DYNTOPO_SMOOTH_SHADING);
+        }
+
         break;
+      }
     }
   }
 
@@ -1357,19 +1369,41 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
                                      update_flags);
         break;
       case PBVH_BMESH:
-        BKE_pbvh_bmesh_check_tris(pbvh, node);
-        GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
-                                      pbvh->bm,
-                                      node->bm_faces,
-                                      node->bm_unique_verts,
-                                      node->bm_other_verts,
-                                      node->tribuf,
-                                      update_flags,
-                                      pbvh->cd_vert_node_offset,
-                                      pbvh->face_sets_color_seed,
-                                      pbvh->face_sets_color_default,
-                                      data->flat_vcol_shading,
-                                      data->active_vcol_only);
+        if (BKE_pbvh_bmesh_check_tris(pbvh, node)) {
+          pbvh_free_all_draw_buffers(node);
+          node->tot_mat_draw_buffers = node->tot_tri_buffers;
+
+          if (node->tot_tri_buffers) {
+            node->mat_draw_buffers = MEM_malloc_arrayN(
+                node->tot_tri_buffers, sizeof(void *), "node->mat_draw_buffers");
+
+            for (int i = 0; i < node->tot_tri_buffers; i++) {
+              node->mat_draw_buffers[i] = GPU_pbvh_bmesh_buffers_build(
+                  pbvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
+            }
+          }
+        }
+
+        for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+          if (i >= node->tot_tri_buffers) {
+            printf("pbvh corruption!\n");
+            continue;
+          }
+
+          GPU_pbvh_bmesh_buffers_update(node->mat_draw_buffers[i],
+                                        pbvh->bm,
+                                        node->bm_faces,
+                                        node->bm_unique_verts,
+                                        node->bm_other_verts,
+                                        node->tri_buffers + i,
+                                        update_flags,
+                                        pbvh->cd_vert_node_offset,
+                                        pbvh->face_sets_color_seed,
+                                        pbvh->face_sets_color_default,
+                                        data->flat_vcol_shading,
+                                        data->active_vcol_only,
+                                        node->tri_buffers[i].mat_nr);
+        }
         break;
     }
   }
@@ -1392,6 +1426,36 @@ void BKE_pbvh_set_flat_vcol_shading(PBVH *pbvh, bool value)
   pbvh->flat_vcol_shading = value;
 }
 
+void pbvh_free_all_draw_buffers(PBVHNode *node)
+{
+  if (node->draw_buffers) {
+    GPU_pbvh_buffers_free(node->draw_buffers);
+    node->draw_buffers = NULL;
+  }
+
+  for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+    GPU_pbvh_buffers_free(node->mat_draw_buffers[i]);
+  }
+
+  MEM_SAFE_FREE(node->mat_draw_buffers);
+
+  node->mat_draw_buffers = NULL;
+  node->tot_mat_draw_buffers = 0;
+}
+
+void pbvh_update_free_all_draw_buffers(PBVH *pbvh, PBVHNode *node)
+{
+  if (pbvh->type == PBVH_GRIDS) {
+    GPU_pbvh_grid_buffers_update_free(
+        node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
+  }
+  else if (pbvh->type == PBVH_BMESH) {
+    for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+      GPU_pbvh_bmesh_buffers_update_free(node->mat_draw_buffers[i]);
+    }
+  }
+}
+
 static void pbvh_update_draw_buffers(
     PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag, bool active_vcol_only)
 {
@@ -1400,17 +1464,10 @@ static void pbvh_update_draw_buffers(
     for (int n = 0; n < totnode; n++) {
       PBVHNode *node = nodes[n];
       if (node->flag & PBVH_RebuildDrawBuffers) {
-        GPU_pbvh_buffers_free(node->draw_buffers);
-        node->draw_buffers = NULL;
+        pbvh_free_all_draw_buffers(node);
       }
-      else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) {
-        if (pbvh->type == PBVH_GRIDS) {
-          GPU_pbvh_grid_buffers_update_free(
-              node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
-        }
-        else if (pbvh->type == PBVH_BMESH) {
-          GPU_pbvh_bmesh_buffers_update_free(node->draw_buffers);
-        }
+      else if ((node->flag & PBVH_UpdateDrawBuffers)) {
+        pbvh_update_free_all_draw_buffers(pbvh, node);
       }
     }
   }
@@ -1449,7 +1506,13 @@ static void pbvh_update_draw_buffers(
 
     if (node->flag & PBVH_UpdateDrawBuffers) {
       /* Flush buffers uses OpenGL, so not in parallel. */
-      GPU_pbvh_buffers_update_flush(node->draw_buffers);
+      if (node->draw_buffers) {
+        GPU_pbvh_buffers_update_flush(node->draw_buffers);
+      }
+
+      for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+        GPU_pbvh_buffers_update_flush(node->mat_draw_buffers[i]);
+      }
     }
 
     node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
@@ -2898,7 +2961,13 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
   for (int i = 0; i < totnode; i++) {
     PBVHNode *node = nodes[i];
     if (!(node->flag & PBVH_FullyHidden)) {
-      draw_fn(user_data, node->draw_buffers);
+      if (node->draw_buffers) {
+        draw_fn(user_data, node->draw_buffers);
+      }
+
+      for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+        draw_fn(user_data, node->mat_draw_buffers[i]);
+      }
     }
   }
 
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 14919bd5386..b99bbaeb62f 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -53,6 +53,8 @@ Topology rake:
 #include "PIL_time.h"
 #include "atomic_ops.h"
 
+#include "DNA_material_types.h"
+
 #include "BKE_DerivedMesh.h"
 #include "BKE_ccg.h"
 #include "BKE_pbvh.h"
@@ -506,10 +508,7 @@ static void pbvh_bmesh_node_split(
   n->bm_other_verts = NULL;
   n->layer_disp = NULL;
 
-  if (n->draw_buffers) {
-    GPU_pbvh_buffers_free(n->draw_buffers);
-    n->draw_buffers = NULL;
-  }
+  pbvh_free_all_draw_buffers(n);
   n->flag &= ~PBVH_Leaf;
 
   /* Recurse */
@@ -3999,6 +3998,20 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
   return modified;
 }
 
+static void pbvh_free_tribuf(PBVHTriBuf *tribuf)
+{
+  MEM_SAFE_FREE(tribuf->verts);
+  MEM_SAFE_FREE(tribuf->tris);
+  MEM_SAFE_FREE(tribuf->loops);
+
+  tribuf->verts = NULL;
+  tribuf->tris = NULL;
+  tribuf->loops = NULL;
+
+  tribuf->verts_size = 0;
+  tribuf->tris_size = 0;
+}
+
 PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node)
 {
   BKE_pbvh_bmesh_check_tris(pbvh, node);
@@ -4009,12 +4022,21 @@ PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node)
 void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node)
 {
   if (node->tribuf) {
-    MEM_SAFE_FREE(node->tribuf->verts);
-    MEM_SAFE_FREE(node->tribuf->tris);
-    MEM_SAFE_FREE(node->tribuf->loops);
+    pbvh_free_tribuf(node->tribuf);
     MEM_freeN(node->tribuf);
     node->tribuf = NULL;
   }
+
+  if (node->tri_buffers) {
+    for (int i = 0; i < node->tot_tri_buffers; i++) {
+      pbvh_free_tribuf(node->tri_buffers + i);
+    }
+
+    MEM_SAFE_FREE(node->tri_buffers);
+
+    node->tri_buffers = NULL;
+    node->tot_tri_buffers = 0;
+  }
 }
 
 /*
@@ -4138,41 +4160,87 @@ static bool pbvh_bmesh_split_tris(PBVH *pbvh, PBVHNode *node)
 
   return true;
 }
+
+ATTR_NO_OPT BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
+{
+  tribuf->tottri++;
+
+  if (tribuf->tottri >= tribuf->tris_size) {
+    size_t newsize = (size_t)32 + (size_t)tribuf->tris_size + (size_t)(tribuf->tris_size >> 1);
+
+    if (!tribuf->tris) {
+      tribuf->tris = MEM_mallocN(sizeof(*tribuf->tris) * newsize, "

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list