[Bf-blender-cvs] [4cbeae12fd7] temp-3d-texturing-brush-b: Texture painting second experiment.

Jeroen Bakker noreply at git.blender.org
Mon Mar 7 15:23:34 CET 2022


Commit: 4cbeae12fd7d2da0144674548c589b8bb3dc736e
Author: Jeroen Bakker
Date:   Mon Mar 7 15:23:30 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rB4cbeae12fd7d2da0144674548c589b8bb3dc736e

Texture painting second experiment.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/sculpt_paint/CMakeLists.txt
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_texture_paint_a.cc
M	source/blender/editors/sculpt_paint/sculpt_texture_paint_b.cc
M	source/blender/imbuf/IMB_rasterizer.hh
M	source/blender/imbuf/intern/rasterizer_target.hh

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 6c8880fea7c..9078db149f2 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -46,6 +46,12 @@ typedef struct {
   float (*color)[4];
 } PBVHColorBufferNode;
 
+typedef void (*PBVHNodeTexturePaintDataFreeFunc)(void *ptr);
+typedef struct PBVHTexturePaintingNode {
+  void *data;
+  PBVHNodeTexturePaintDataFreeFunc free_func;
+} PBVHTexturePaintingNode;
+
 typedef enum {
   PBVH_Leaf = 1 << 0,
 
@@ -416,7 +422,7 @@ BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
 }
 BLI_INLINE float *PBVH_cast_float_ptr(void *src)
 {
-  return static_cast<float*>(src);
+  return static_cast<float *>(src);
 }
 #else
 BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
@@ -501,7 +507,8 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
           vi.co = vi.bm_vert->co; \
           vi.fno = vi.bm_vert->no; \
           vi.index = BM_elem_index_get(vi.bm_vert); \
-          vi.mask = PBVH_cast_float_ptr(BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset)); \
+          vi.mask = PBVH_cast_float_ptr( \
+              BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset)); \
         }
 
 #define BKE_pbvh_vertex_iter_end \
@@ -547,6 +554,12 @@ const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3];
 PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
 void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
 
+/* Texture painting. */
+void *BKE_pbvh_node_texture_paint_data_get(const PBVHNode *node);
+void BKE_pbvh_node_texture_paint_data_set(PBVHNode *node,
+                                          void *texture_paint_data,
+                                          PBVHNodeTexturePaintDataFreeFunc free_func);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 3ed3c7badc3..3c379aaa411 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -679,6 +679,7 @@ void BKE_pbvh_free(PBVH *pbvh)
       if (node->bm_other_verts) {
         BLI_gset_free(node->bm_other_verts, NULL);
       }
+      BKE_pbvh_node_texture_paint_data_set(node, NULL, NULL);
     }
   }
 
@@ -3072,3 +3073,32 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
 {
   pbvh->respect_hide = respect_hide;
 }
+
+/* -------------------------------------------------------------------- */
+/** \name Texture painting operations
+ * \{ */
+
+void *BKE_pbvh_node_texture_paint_data_get(const PBVHNode *node)
+{
+  BLI_assert(node->flag & PBVH_Leaf);
+  return node->texture_painting.data;
+}
+
+void BKE_pbvh_node_texture_paint_data_set(PBVHNode *node,
+                                          void *texture_paint_data,
+                                          PBVHNodeTexturePaintDataFreeFunc free_func)
+{
+  BLI_assert(node->flag & PBVH_Leaf);
+
+  if (node->texture_painting.data != NULL) {
+    node->texture_painting.free_func(node->texture_painting.data);
+    node->texture_painting.data = NULL;
+    node->texture_painting.free_func = NULL;
+  }
+
+  if (texture_paint_data != NULL) {
+    BLI_assert(free_func);
+    node->texture_painting.data = texture_paint_data;
+    node->texture_painting.free_func = free_func;
+  }
+}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 123a6b1b829..6b3108e8460 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -93,6 +93,7 @@ struct PBVHNode {
 
   /* Used to store the brush color during a stroke and composite it over the original color */
   PBVHColorBufferNode color_buffer;
+  PBVHTexturePaintingNode texture_painting;
 };
 
 typedef enum {
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 41fdb37a005..55c90214ac1 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -65,7 +65,7 @@ set(SRC
   sculpt_paint_color.c
   sculpt_pose.c
   sculpt_smooth.c
-  sculpt_texture_paint_a.cc
+  sculpt_texture_paint_b.cc
   sculpt_transform.c
   sculpt_undo.c
   sculpt_uv.c
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 525e1be5520..f6b334f2175 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5041,6 +5041,14 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
     multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
   }
 
+  if (update_flags & SCULPT_UPDATE_TEXTURE) {
+    /* When using the texture paint brush only the texture changes. The Geometry and shading should
+     * not be touched.*/
+    SCULPT_flush_texture_paint(ob);
+    ED_region_tag_redraw(region);
+    return;
+  }
+
   DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
 
   /* Only current viewport matters, slower update for all viewports will
@@ -5256,6 +5264,9 @@ static void sculpt_stroke_update_step(bContext *C,
   else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
     SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
   }
+  else if (brush->sculpt_tool == SCULPT_TOOL_TEXTURE_PAINT) {
+    SCULPT_flush_update_step(C, SCULPT_UPDATE_TEXTURE);
+  }
   else {
     SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
   }
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index ad4f13fc438..39aaf4d1276 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -43,6 +43,7 @@ typedef enum SculptUpdateType {
   SCULPT_UPDATE_MASK = 1 << 1,
   SCULPT_UPDATE_VISIBILITY = 1 << 2,
   SCULPT_UPDATE_COLOR = 1 << 3,
+  SCULPT_UPDATE_TEXTURE = 1 << 4,
 } SculptUpdateType;
 
 typedef struct SculptCursorGeometryInfo {
@@ -1613,6 +1614,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
 /* Paint Brush. */
 void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
 void SCULPT_do_texture_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+void SCULPT_flush_texture_paint(Object *ob);
 
 /* Smear Brush. */
 void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
diff --git a/source/blender/editors/sculpt_paint/sculpt_texture_paint_a.cc b/source/blender/editors/sculpt_paint/sculpt_texture_paint_a.cc
index d3e93574c1a..6e643cdd9b1 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_a.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_a.cc
@@ -82,7 +82,6 @@ struct TexturePaintingUserData {
   Object *ob;
   Brush *brush;
   PBVHNode **nodes;
-  Vector<rctf> region_to_update;
 };
 
 static void do_task_cb_ex(void *__restrict userdata,
@@ -204,5 +203,9 @@ void SCULPT_do_texture_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int
   BKE_image_release_ibuf(image, image_buffer, lock);
   ss->mode.texture_paint.drawing_target = nullptr;
 }
+
+void SCULPT_flush_texture_paint(Object *UNUSED(ob))
+{
+}
 }
 }  // namespace blender::ed::sculpt_paint::texture_paint
diff --git a/source/blender/editors/sculpt_paint/sculpt_texture_paint_b.cc b/source/blender/editors/sculpt_paint/sculpt_texture_paint_b.cc
index d3e93574c1a..9ad8be1d8e1 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_b.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_b.cc
@@ -37,6 +37,63 @@
 
 namespace blender::ed::sculpt_paint::texture_paint {
 
+struct PixelData {
+  struct {
+    bool dirty : 1;
+  } flags;
+  int2 pixel_pos;
+  float3 local_pos;
+  float4 content;
+};
+
+struct NodeData {
+  struct {
+    bool dirty : 1;
+  } flags;
+
+  Vector<PixelData> pixels;
+  rcti dirty_region;
+
+  NodeData()
+  {
+    flags.dirty = false;
+    BLI_rcti_init_minmax(&dirty_region);
+  }
+
+  void init_pixels(Object *ob, PBVHNode *node, ImBuf *image_buffer);
+  void flush(ImBuf &image_buffer)
+  {
+    flags.dirty = false;
+    int pixels_flushed = 0;
+    for (PixelData &pixel : pixels) {
+      if (pixel.flags.dirty) {
+        const int pixel_offset = (pixel.pixel_pos[1] * image_buffer.x + pixel.pixel_pos[0]) * 4;
+        copy_v4_v4(&image_buffer.rect_float[pixel_offset], pixel.content);
+        pixel.flags.dirty = false;
+        pixels_flushed += 1;
+      }
+    }
+    printf("%s: %d pixels flushed\n", __func__, pixels_flushed);
+  }
+
+  void mark_region(Image &image, ImBuf &image_buffer)
+  {
+    printf("%s", __func__);
+    print_rcti_id(&dirty_region);
+    BKE_image_partial_update_mark_region(
+        &image, static_cast<ImageTile *>(image.tiles.first), &image_buffer, &dirty_region);
+    BLI_rcti_init_minmax(&dirty_region);
+  }
+
+  static void free_func(void *instance)
+  {
+    NodeData *node_data = static_cast<NodeData *>(instance);
+    MEM_delete(node_data);
+  }
+};
+
+namespace shaders {
+
 using namespace imbuf::rasterizer;
 
 struct VertexInput {
@@ -58,66 +115,110 @@ class VertexShader : public AbstractVertexShader<VertexInput, float3> {
   }
 };
 
-class FragmentShader : public AbstractFragmentShader<float3, float4> {
+struct FragmentOutput {
+  float3 local_pos;
+};
+
+class FragmentShader : public AbstractFragmentShader<float3, FragmentOutput> {
  public:
-  float4 color;
-  const Brush *brush = nullptr;
-  SculptBrushTest test;
-  SculptBrushTestFn sculpt_brush_test_sq_fn;
+  ImBuf *image_buffer;
 
+ public:
   void fragment(const FragmentInputType &input, FragmentOutputType *r_output) override
   {
-    copy_v4_v4(*r_output, color);
-    float strength = sculpt_brush_test_sq_fn(&test, input) ?
-                         BKE_brush_curve_strength(brush, sqrtf(test.dist), test.radius) :
-                         0.0f;
+    r_output->local_pos = input;
+  }
+};
+
+struct NodeDataPair {
+  ImBuf *image_buffer;
+  NodeData *node_data;
 
-    (*r_output)[3] *= strength;
+  struct {
+    /* Rasterizer doesn't support glCoord yet, so for now we just store them in a runtime s

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list