[Bf-blender-cvs] [47f46637be1] master: Sculpt: New Layer Brush

Pablo Dobarro noreply at git.blender.org
Tue Apr 14 21:07:51 CEST 2020


Commit: 47f46637be1bef9672ede0ab6795a7e9ea97fc6a
Author: Pablo Dobarro
Date:   Tue Apr 14 21:06:49 2020 +0200
Branches: master
https://developer.blender.org/rB47f46637be1bef9672ede0ab6795a7e9ea97fc6a

Sculpt: New Layer Brush

The Layer brush was in Blender before 2.81, when the sculpt API was
introduced. It had a huge amount of bugs and glitches which made it
almost unusable for anything but the most trivial cases. Also, it needed
some hacks in the code just to support the persistent base.

The brush was completely rewritten using the Sculpt API. It fulfills the
same use case as the old one, but it has:
- All previous artifacts fixed
- Simpler code
- Persistent base now works with multires thanks to the sculpt API
- Small cursor widget to preview the layer height
- More controllable and smoother strength and deformation
- More correct masking support
- More predictable invert support. When using persistent base, the brush invert mode resets to layer height 0, instead of jumping from +1 to -1. The brush can still be inverted in the brush direction property.

Reviewed By: jbakker

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

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/editors/sculpt_paint/paint_cursor.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 32b386bf0ab..a13f39da4a9 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -600,19 +600,10 @@ def brush_settings(layout, context, brush, popover=False):
         # use_persistent, set_persistent_base
         if capabilities.has_persistence:
             ob = context.sculpt_object
-            do_persistent = True
-
-            # not supported yet for this case
-            for md in ob.modifiers:
-                if md.type == 'MULTIRES':
-                    do_persistent = False
-                    break
-
-            if do_persistent:
-                layout.separator()
-                layout.prop(brush, "use_persistent")
-                layout.operator("sculpt.set_persistent_base")
-                layout.separator()
+            layout.separator()
+            layout.prop(brush, "use_persistent")
+            layout.operator("sculpt.set_persistent_base")
+            layout.separator()
 
         if brush.sculpt_tool == 'CLAY_STRIPS':
             row = layout.row()
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 012188bed96..f78a142704b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -279,6 +279,12 @@ typedef struct SculptClothSimulation {
 
 } SculptClothSimulation;
 
+typedef struct SculptLayerPersistentBase {
+  float co[3];
+  float no[3];
+  float disp;
+} SculptLayerPersistentBase;
+
 /* Session data (mode-specific) */
 
 typedef struct SculptSession {
@@ -329,9 +335,6 @@ typedef struct SculptSession {
   unsigned int texcache_side, *texcache, texcache_actual;
   struct ImagePool *tex_pool;
 
-  /* Layer brush persistence between strokes */
-  float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
-
   struct StrokeCache *cache;
   struct FilterCache *filter_cache;
 
@@ -359,6 +362,10 @@ typedef struct SculptSession {
   float pose_origin[3];
   SculptPoseIKChain *pose_ik_chain_preview;
 
+  /* Layer brush persistence between strokes */
+  /* This is freed with the PBVH, so it is always in sync with the mesh. */
+  SculptLayerPersistentBase *layer_base;
+
   /* Transform operator */
   float pivot_pos[3];
   float pivot_rot[4];
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index a59ce816e26..94f0e544a6b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -122,7 +122,6 @@ void BKE_pbvh_build_bmesh(PBVH *bvh,
                           const int cd_vert_node_offset,
                           const int cd_face_node_offset);
 void BKE_pbvh_free(PBVH *bvh);
-void BKE_pbvh_free_layer_disp(PBVH *bvh);
 
 /* Hierarchical Search in the BVH, two methods:
  * - for each hit calling a callback
@@ -310,14 +309,6 @@ void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets);
 
 void BKE_pbvh_face_sets_color_set(PBVH *bvh, int seed, int color_default);
 
-/* Layer displacement */
-
-/* Get the node's displacement layer, creating it if necessary */
-float *BKE_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
-
-/* If the node has a displacement layer, free it and set to null */
-void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
-
 /* vertex deformer */
 float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3];
 void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], const int totvert);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e1303b8d723..d775598f420 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1422,6 +1422,12 @@ void BKE_brush_sculpt_reset(Brush *br)
       br->cloth_deform_type = BRUSH_CLOTH_DEFORM_DRAG;
       br->flag &= ~(BRUSH_ALPHA_PRESSURE | BRUSH_SIZE_PRESSURE);
       break;
+    case SCULPT_TOOL_LAYER:
+      br->flag &= ~BRUSH_SPACE_ATTEN;
+      br->hardness = 0.35f;
+      br->alpha = 1.0f;
+      br->height = 0.05f;
+      break;
     default:
       break;
   }
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index c5d60b29aca..420538061bb 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1306,9 +1306,10 @@ static void sculptsession_free_pbvh(Object *object)
   }
 
   MEM_SAFE_FREE(ss->pmap);
-
   MEM_SAFE_FREE(ss->pmap_mem);
 
+  MEM_SAFE_FREE(ss->layer_base);
+
   MEM_SAFE_FREE(ss->preview_vert_index_list);
   ss->preview_vert_index_count = 0;
 }
@@ -1353,31 +1354,17 @@ void BKE_sculptsession_free(Object *ob)
       BM_log_free(ss->bm_log);
     }
 
-    if (ss->texcache) {
-      MEM_freeN(ss->texcache);
-    }
+    MEM_SAFE_FREE(ss->texcache);
 
     if (ss->tex_pool) {
       BKE_image_pool_free(ss->tex_pool);
     }
 
-    if (ss->layer_co) {
-      MEM_freeN(ss->layer_co);
-    }
+    MEM_SAFE_FREE(ss->orig_cos);
+    MEM_SAFE_FREE(ss->deform_cos);
+    MEM_SAFE_FREE(ss->deform_imats);
 
-    if (ss->orig_cos) {
-      MEM_freeN(ss->orig_cos);
-    }
-    if (ss->deform_cos) {
-      MEM_freeN(ss->deform_cos);
-    }
-    if (ss->deform_imats) {
-      MEM_freeN(ss->deform_imats);
-    }
-
-    if (ss->preview_vert_index_list) {
-      MEM_freeN(ss->preview_vert_index_list);
-    }
+    MEM_SAFE_FREE(ss->preview_vert_index_list);
 
     if (ss->pose_ik_chain_preview) {
       for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 06622f0d009..977e70745a3 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -685,8 +685,6 @@ void BKE_pbvh_free(PBVH *bvh)
       if (node->face_vert_indices) {
         MEM_freeN((void *)node->face_vert_indices);
       }
-      BKE_pbvh_node_layer_disp_free(node);
-
       if (node->bm_faces) {
         BLI_gset_free(node->bm_faces, NULL);
       }
@@ -722,13 +720,6 @@ void BKE_pbvh_free(PBVH *bvh)
   MEM_freeN(bvh);
 }
 
-void BKE_pbvh_free_layer_disp(PBVH *bvh)
-{
-  for (int i = 0; i < bvh->totnode; i++) {
-    BKE_pbvh_node_layer_disp_free(&bvh->nodes[i]);
-  }
-}
-
 static void pbvh_iter_begin(PBVHIter *iter,
                             PBVH *bvh,
                             BKE_pbvh_SearchCallback scb,
@@ -2768,26 +2759,6 @@ void BKE_pbvh_grids_update(
   }
 }
 
-/* Get the node's displacement layer, creating it if necessary */
-float *BKE_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
-{
-  if (!node->layer_disp) {
-    int totvert = 0;
-    BKE_pbvh_node_num_verts(bvh, node, &totvert, NULL);
-    node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
-  }
-  return node->layer_disp;
-}
-
-/* If the node has a displacement layer, free it and set to null */
-void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
-{
-  if (node->layer_disp) {
-    MEM_freeN(node->layer_disp);
-    node->layer_disp = NULL;
-  }
-}
-
 float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3]
 {
   float(*vertCos)[3] = NULL;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 04ca5770a97..33372a0d7cf 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1216,6 +1216,34 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession
   }
 }
 
+void SCULPT_layer_brush_height_preview_draw(const uint gpuattr,
+                                            const Brush *brush,
+                                            const float obmat[4][4],
+                                            const float location[3],
+                                            const float normal[3],
+                                            const float rds,
+                                            const float line_width,
+                                            const float outline_col[3],
+                                            const float alpha)
+{
+  float cursor_trans[4][4], cursor_rot[4][4];
+  float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+  float quat[4];
+  float height_preview_trans[3];
+  copy_m4_m4(cursor_trans, obmat);
+  madd_v3_v3v3fl(height_preview_trans, location, normal, brush->height);
+  translate_m4(
+      cursor_trans, height_preview_trans[0], height_preview_trans[1], height_preview_trans[2]);
+  rotation_between_vecs_to_quat(quat, z_axis, normal);
+  quat_to_mat4(cursor_rot, quat);
+  GPU_matrix_mul(cursor_trans);
+  GPU_matrix_mul(cursor_rot);
+
+  GPU_line_width(line_width);
+  immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
+  imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
+}
+
 static bool paint_use_2d_cursor(ePaintMode mode)
 {
   if (mode >= PAINT_MODE_TEXTURE_3D) {
@@ -1476,6 +1504,21 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
             GPU_matrix_pop();
           }
 
+          /* Layer brush height. */
+          if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+            GPU_matrix_push();
+            SCULPT_layer_brush_height_preview_draw(pos,
+                                                   brush,
+                                                   vc.obact->obmat,
+                                                   gi.location,
+                                                   gi.normal,
+                                                   rds,
+                                                   1.0f,
+                                                   outline_col,
+                                                   outline_alpha);
+            GPU_matrix_pop();
+          }
+
           /* Update and draw dynamic mesh preview lines. */
           GPU_matrix_push();
           GPU_matrix_mul(vc.obact->obmat);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index b8c6e97fcc1..66f66bfceb8 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/scu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list