[Bf-blender-cvs] [de4ebcbe436] master: Fix T70390: dyntopo smooth shading broken after recent changes

Brecht Van Lommel noreply at git.blender.org
Wed Oct 2 18:28:41 CEST 2019


Commit: de4ebcbe4368e2e71dc14effaf2733a4a0138570
Author: Brecht Van Lommel
Date:   Wed Oct 2 18:02:41 2019 +0200
Branches: master
https://developer.blender.org/rBde4ebcbe4368e2e71dc14effaf2733a4a0138570

Fix T70390: dyntopo smooth shading broken after recent changes

Made the code fully thread safe now.

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

M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index ed606ccb8c6..78202158852 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -729,47 +729,36 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hid
 /** \name BMesh PBVH
  * \{ */
 
-/* Output a BMVert into a VertexBufferFormat array
- *
- * The vertex is skipped if hidden, otherwise the output goes into
- * index '*v_index' in the 'vert_data' array and '*v_index' is
- * incremented.
- */
-static void gpu_bmesh_vert_to_buffer_copy__gwn(BMVert *v,
-                                               GPUVertBuf *vert_buf,
-                                               int *v_index,
-                                               const float fno[3],
-                                               const float *fmask,
-                                               const int cd_vert_mask_offset,
-                                               const bool show_mask,
-                                               const bool show_vcol,
-                                               bool *empty_mask)
+/* Output a BMVert into a VertexBufferFormat array at v_index. */
+static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
+                                          GPUVertBuf *vert_buf,
+                                          int v_index,
+                                          const float fno[3],
+                                          const float *fmask,
+                                          const int cd_vert_mask_offset,
+                                          const bool show_mask,
+                                          const bool show_vcol,
+                                          bool *empty_mask)
 {
-  if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
-
-    /* Set coord, normal, and mask */
-    GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co);
+  /* Vertex should always be visible if it's used by a visible face. */
+  BLI_assert(!BM_elem_flag_test(v, BM_ELEM_HIDDEN));
 
-    short no_short[3];
-    normal_float_to_short_v3(no_short, fno ? fno : v->no);
-    GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short);
+  /* Set coord, normal, and mask */
+  GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, v_index, v->co);
 
-    if (show_mask) {
-      float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
-      GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask);
-      *empty_mask = *empty_mask && (effective_mask == 0.0f);
-    }
-
-    if (show_vcol) {
-      static char vcol[4] = {255, 255, 255, 255};
-      GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, *v_index, &vcol);
-    }
+  short no_short[3];
+  normal_float_to_short_v3(no_short, fno ? fno : v->no);
+  GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, v_index, no_short);
 
-    /* Assign index for use in the triangle index buffer */
-    /* note: caller must set:  bm->elem_index_dirty |= BM_VERT; */
-    BM_elem_index_set(v, (*v_index)); /* set_dirty! */
+  if (show_mask) {
+    float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
+    GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, v_index, &effective_mask);
+    *empty_mask = *empty_mask && (effective_mask == 0.0f);
+  }
 
-    (*v_index)++;
+  if (show_vcol) {
+    static char vcol[4] = {255, 255, 255, 255};
+    GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol);
   }
 }
 
@@ -839,7 +828,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
 {
   const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
   const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
-  int tottri, totvert, maxvert = 0;
+  int tottri, totvert;
   bool empty_mask = true;
   BMFace *f = NULL;
 
@@ -869,135 +858,118 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
   const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
 
   /* Fill vertex buffer */
-  if (gpu_pbvh_vert_buf_data_set(buffers, totvert)) {
-    int v_index = 0;
-
-    if (buffers->smooth) {
-      GSetIterator gs_iter;
-
-      /* Vertices get an index assigned for use in the triangle
-       * index buffer */
-      bm->elem_index_dirty |= BM_VERT;
-
-      GSET_ITER (gs_iter, bm_unique_verts) {
-        gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter),
-                                           buffers->vert_buf,
-                                           &v_index,
-                                           NULL,
-                                           NULL,
-                                           cd_vert_mask_offset,
-                                           show_mask,
-                                           show_vcol,
-                                           &empty_mask);
-      }
-
-      GSET_ITER (gs_iter, bm_other_verts) {
-        gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter),
-                                           buffers->vert_buf,
-                                           &v_index,
-                                           NULL,
-                                           NULL,
-                                           cd_vert_mask_offset,
-                                           show_mask,
-                                           show_vcol,
-                                           &empty_mask);
-      }
+  if (!gpu_pbvh_vert_buf_data_set(buffers, totvert)) {
+    /* Memory map failed */
+    return;
+  }
 
-      maxvert = v_index;
-    }
-    else {
-      GSetIterator gs_iter;
+  int v_index = 0;
 
-      GPUIndexBufBuilder elb_lines;
-      GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
+  if (buffers->smooth) {
+    /* Fill the vertex and triangle buffer in one pass over faces. */
+    GPUIndexBufBuilder elb, elb_lines;
+    GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, totvert);
+    GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
 
-      GSET_ITER (gs_iter, bm_faces) {
-        f = BLI_gsetIterator_getKey(&gs_iter);
+    GHash *bm_vert_to_index = BLI_ghash_int_new_ex("bm_vert_to_index", totvert);
 
-        BLI_assert(f->len == 3);
+    GSetIterator gs_iter;
+    GSET_ITER (gs_iter, bm_faces) {
+      f = BLI_gsetIterator_getKey(&gs_iter);
 
-        if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
-          BMVert *v[3];
-          float fmask = 0.0f;
-          int i;
+      if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+        BMVert *v[3];
+        BM_face_as_array_vert_tri(f, v);
 
-          BM_face_as_array_vert_tri(f, v);
+        uint idx[3];
+        for (int i = 0; i < 3; i++) {
+          void **idx_p;
+          if (!BLI_ghash_ensure_p(bm_vert_to_index, v[i], &idx_p)) {
+            /* Add vertex to the vertex buffer each time a new one is encountered */
+            *idx_p = POINTER_FROM_UINT(v_index);
 
-          /* Average mask value */
-          for (i = 0; i < 3; i++) {
-            fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
+            gpu_bmesh_vert_to_buffer_copy(v[i],
+                                          buffers->vert_buf,
+                                          v_index,
+                                          NULL,
+                                          NULL,
+                                          cd_vert_mask_offset,
+                                          show_mask,
+                                          show_vcol,
+                                          &empty_mask);
+
+            idx[i] = v_index;
+            v_index++;
           }
-          fmask /= 3.0f;
-
-          GPU_indexbuf_add_line_verts(&elb_lines, v_index + 0, v_index + 1);
-          GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
-          GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
-
-          for (i = 0; i < 3; i++) {
-            gpu_bmesh_vert_to_buffer_copy__gwn(v[i],
-                                               buffers->vert_buf,
-                                               &v_index,
-                                               f->no,
-                                               &fmask,
-                                               cd_vert_mask_offset,
-                                               show_mask,
-                                               show_vcol,
-                                               &empty_mask);
+          else {
+            /* Vertex already in the vertex buffer, just get the index. */
+            idx[i] = POINTER_AS_UINT(*idx_p);
           }
         }
-      }
 
-      buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
-      buffers->tot_tri = tottri;
+        GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
+
+        GPU_indexbuf_add_line_verts(&elb_lines, idx[0], idx[1]);
+        GPU_indexbuf_add_line_verts(&elb_lines, idx[1], idx[2]);
+        GPU_indexbuf_add_line_verts(&elb_lines, idx[2], idx[0]);
+      }
     }
 
-    /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
-    bm->elem_index_dirty |= BM_VERT;
+    BLI_ghash_free(bm_vert_to_index, NULL, NULL);
+
+    buffers->tot_tri = tottri;
+    if (buffers->index_buf == NULL) {
+      buffers->index_buf = GPU_indexbuf_build(&elb);
+    }
+    else {
+      GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
+    }
+    buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
   }
   else {
-    /* Memory map failed */
-    return;
-  }
-
-  if (buffers->smooth) {
-    /* Fill the triangle buffer */
-    GPUIndexBufBuilder elb, elb_lines;
-    GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert);
-    GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, maxvert);
+    GSetIterator gs_iter;
 
-    /* Fill triangle index buffer */
-    {
-      GSetIterator gs_iter;
+    GPUIndexBufBuilder elb_lines;
+    GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, tottri * 3);
 
-      GSET_ITER (gs_iter, bm_faces) {
-        f = BLI_gsetIterator_getKey(&gs_iter);
+    GSET_ITER (gs_iter, bm_faces) {
+      f = BLI_gsetIterator_getKey(&gs_iter);
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list