[Bf-blender-cvs] [6c9ec1c893f] master: Sculpt: Render Mask and Face Sets with modifiers active

Pablo Dobarro noreply at git.blender.org
Fri Sep 18 19:31:22 CEST 2020


Commit: 6c9ec1c893f98c2349edd3aaae4b606b55b393c9
Author: Pablo Dobarro
Date:   Fri Sep 18 19:30:02 2020 +0200
Branches: master
https://developer.blender.org/rB6c9ec1c893f98c2349edd3aaae4b606b55b393c9

Sculpt: Render Mask and Face Sets with modifiers active

This removes the limitation of the sculpt overlays not being visible
with modifiers active.

Reviewed By: fclem

Maniphest Tasks: T68900

Differential Revision: https://developer.blender.org/D8673

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/draw/engines/overlay/overlay_sculpt.c
M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index dfc75e2fd54..5af9c35cab6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -204,6 +204,8 @@ bool paint_is_bmesh_face_hidden(struct BMFace *f);
 /* paint masks */
 float paint_grid_paint_mask(const struct GridPaintMask *gpm, uint level, uint x, uint y);
 
+void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4]);
+
 /* stroke related */
 bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups,
                                    struct Brush *brush,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 681e46ed24e..bfdc8ad37e5 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1054,7 +1054,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
         }
         continue;
       }
-      BKE_modifier_set_error(md, "Sculpt: Hide, Mask and optimized display disabled");
     }
 
     if (need_mapping && !BKE_modifier_supports_mapping(md)) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index c5cc8448d1b..4757b0d5c1e 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1994,7 +1994,8 @@ const CustomData_MeshMasks CD_MASK_EDITMESH = {
 };
 const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
     .vmask = (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
-              CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR),
+              CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL |
+              CD_MASK_PROP_COLOR),
     .emask = (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
     .fmask = (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
     .lmask = (CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL |
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index c9b3b3cc516..3ac9db0eb78 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -38,6 +38,7 @@
 #include "DNA_workspace_types.h"
 
 #include "BLI_bitmap.h"
+#include "BLI_hash.h"
 #include "BLI_listbase.h"
 #include "BLI_math_vector.h"
 #include "BLI_utildefines.h"
@@ -2101,3 +2102,21 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *v3d)
   /* Multires and dyntopo always draw directly from the PBVH. */
   return true;
 }
+
+/* Returns the Face Set random color for rendering in the overlay given its ID and a color seed. */
+#define GOLDEN_RATIO_CONJUGATE 0.618033988749895f
+void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4])
+{
+  float rgba[4];
+  float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (abs(face_set) + (seed % 10));
+  random_mod_hue = random_mod_hue - floorf(random_mod_hue);
+  const float random_mod_sat = BLI_hash_int_01(abs(face_set) + seed + 1);
+  const float random_mod_val = BLI_hash_int_01(abs(face_set) + seed + 2);
+  hsv_to_rgb(random_mod_hue,
+             0.6f + (random_mod_sat * 0.25f),
+             1.0f - (random_mod_val * 0.35f),
+             &rgba[0],
+             &rgba[1],
+             &rgba[2]);
+  rgba_float_to_uchar(r_color, rgba);
+}
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt.c b/source/blender/draw/engines/overlay/overlay_sculpt.c
index b36252ead30..c6c617fd29b 100644
--- a/source/blender/draw/engines/overlay/overlay_sculpt.c
+++ b/source/blender/draw/engines/overlay/overlay_sculpt.c
@@ -22,6 +22,7 @@
 
 #include "DRW_render.h"
 
+#include "draw_cache_impl.h"
 #include "overlay_private.h"
 
 #include "BKE_paint.h"
@@ -48,14 +49,21 @@ void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
 {
   OVERLAY_PrivateData *pd = vedata->stl->pd;
   const DRWContextState *draw_ctx = DRW_context_state_get();
+  struct GPUBatch *sculpt_overlays;
   PBVH *pbvh = ob->sculpt->pbvh;
 
   const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
 
-  if (use_pbvh || !ob->sculpt->deform_modifiers_active || ob->sculpt->shapekey_active) {
-    if (!use_pbvh || pbvh_has_mask(pbvh) || pbvh_has_face_sets(pbvh)) {
+  if (pbvh_has_mask(pbvh) || pbvh_has_face_sets(pbvh)) {
+    if (use_pbvh) {
       DRW_shgroup_call_sculpt(pd->sculpt_mask_grp, ob, false, true);
     }
+    else {
+      sculpt_overlays = DRW_mesh_batch_cache_get_sculpt_overlays(ob->data);
+      if (sculpt_overlays) {
+        DRW_shgroup_call(pd->sculpt_mask_grp, sculpt_overlays, ob);
+      }
+    }
   }
 }
 
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 5f77dac98be..2094da0328b 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -55,6 +55,7 @@ typedef struct DRW_MeshCDMask {
   uint32_t sculpt_vcol : 8;
   uint32_t orco : 1;
   uint32_t tan_orco : 1;
+  uint32_t sculpt_overlays : 1;
   /** Edit uv layer is from the base edit mesh as
    *  modifiers could remove it. (see T68857) */
   uint32_t edit_uv : 1;
@@ -103,6 +104,7 @@ typedef struct MeshBufferCache {
     GPUVertBuf *uv;
     GPUVertBuf *tan;
     GPUVertBuf *vcol;
+    GPUVertBuf *sculpt_data;
     GPUVertBuf *orco;
     /* Only for edit mode. */
     GPUVertBuf *edit_data; /* extend */
@@ -170,6 +172,7 @@ typedef enum DRWBatchFlag {
   MBC_WIRE_LOOPS = (1 << 24),
   MBC_WIRE_LOOPS_UVS = (1 << 25),
   MBC_SKIN_ROOTS = (1 << 26),
+  MBC_SCULPT_OVERLAYS = (1 << 27),
 } DRWBatchFlag;
 
 #define MBC_EDITUV \
@@ -219,6 +222,7 @@ typedef struct MeshBatchCache {
     GPUBatch *wire_edges;     /* Individual edges with face normals. */
     GPUBatch *wire_loops;     /* Loops around faces. no edges between selected faces */
     GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
+    GPUBatch *sculpt_overlays;
   } batch;
 
   GPUBatch **surface_per_mat;
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index cb716b3130a..657cb2061bd 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -53,6 +53,7 @@
 #include "BKE_mesh_tangent.h"
 #include "BKE_modifier.h"
 #include "BKE_object_deform.h"
+#include "BKE_paint.h"
 
 #include "atomic_ops.h"
 
@@ -2564,6 +2565,106 @@ static const MeshExtract extract_tan_hq = {
 
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract Sculpt Data
+ * \{ */
+
+static void *extract_sculpt_data_init(const MeshRenderData *mr,
+                                      struct MeshBatchCache *UNUSED(cache),
+                                      void *buf)
+{
+  GPUVertFormat format = {0};
+
+  CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
+  CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
+  CustomData *cd_pdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->pdata : &mr->me->pdata;
+
+  float *cd_mask = CustomData_get_layer(cd_vdata, CD_PAINT_MASK);
+  int *cd_face_set = CustomData_get_layer(cd_pdata, CD_SCULPT_FACE_SETS);
+
+  if (format.attr_len == 0) {
+    GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+    GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+  }
+
+  GPUVertBuf *vbo = buf;
+  GPU_vertbuf_init_with_format(vbo, &format);
+  GPU_vertbuf_data_alloc(vbo, mr->loop_len);
+
+  typedef struct gpuSculptData {
+    uint8_t face_set_color[4];
+    float mask;
+  } gpuSculptData;
+
+  gpuSculptData *vbo_data = (gpuSculptData *)GPU_vertbuf_get_data(vbo);
+  MLoop *loops = CustomData_get_layer(cd_ldata, CD_MLOOP);
+
+  if (mr->extract_type == MR_EXTRACT_BMESH) {
+    int cd_mask_ofs = CustomData_get_offset(cd_vdata, CD_PAINT_MASK);
+    int cd_face_set_ofs = CustomData_get_offset(cd_pdata, CD_SCULPT_FACE_SETS);
+    BMIter f_iter;
+    BMFace *efa;
+    BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) {
+      BMLoop *l_iter, *l_first;
+      l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+      do {
+        float v_mask = 0.0f;
+        if (cd_mask) {
+          v_mask = BM_ELEM_CD_GET_FLOAT(l_iter->v, cd_mask_ofs);
+        }
+        vbo_data->mask = v_mask;
+        uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+        if (cd_face_set) {
+          const int face_set_id = BM_ELEM_CD_GET_INT(l_iter->f, cd_face_set_ofs);
+          if (face_set_id != mr->me->face_sets_color_default) {
+            BKE_paint_face_set_overlay_color_get(
+                face_set_id, mr->me->face_sets_color_seed, face_set_color);
+          }
+        }
+        copy_v3_v3_uchar(vbo_data->face_set_color, face_set_color);
+        vbo_data++;
+      } while ((l_iter = l_iter->next) != l_first);
+    }
+  }
+  else {
+    int mp_loop = 0;
+    for (int mp_index = 0; mp_index < mr->poly_len; mp_index++) {
+      const MPoly *p = &mr->mpoly[mp_index];
+      for (int l = 0; l < p->totloop; l++) {
+        float v_mask = 0.0f;
+        if (cd_mask) {
+          v_mask = cd_mask[loops[mp_loop].v];
+        }
+        vbo_data->mask = v_mask;
+
+        uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+        if (cd_face_set) {
+          const int face_set_id = cd_face_set[mp_index];
+          /* Skip for the default color Face Set to render it white. */
+          if (face_set_id != mr->me->face_sets_color_default) {
+            BKE_paint_face_set_overlay_color_get(
+                face_set_id, mr->me->face_sets_color_seed, face_set_color);
+          }
+        }
+        copy_v3_v3_uchar(vbo_data->face_set_color, face_set_color);
+        mp_loop++;
+        vbo_data++;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+static const MeshExtract extract_sculpt_data = {
+    .init = extract_sculpt_d

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list