[Bf-blender-cvs] [78935ed2baa] temp-3d-texturing-brush-b: Initial support for tiled textures.

Jeroen Bakker noreply at git.blender.org
Wed Mar 16 14:10:48 CET 2022


Commit: 78935ed2baafdd829651d59a910f919a90bd21b8
Author: Jeroen Bakker
Date:   Wed Mar 16 13:14:16 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rB78935ed2baafdd829651d59a910f919a90bd21b8

Initial support for tiled textures.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
M	source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
M	source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_d.cc
A	source/blender/imbuf/IMB_imbuf_wrappers.hh

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 246f67735f6..6fd9d604b07 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -622,7 +622,8 @@ typedef struct SculptSession {
     } wpaint;
 
     struct {
-      struct ImBuf *drawing_target;
+      struct Image *image;
+      struct ImageUser *image_user;
     } texture_paint;
 
     /* TODO: identify sculpt-only fields */
diff --git a/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc b/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
index 0dcaecddd84..3287d549a0b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
@@ -30,6 +30,7 @@
 
 #include "IMB_colormanagement.h"
 #include "IMB_imbuf_types.h"
+#include "IMB_imbuf_wrappers.hh"
 
 #include "WM_types.h"
 
@@ -264,7 +265,6 @@ static void do_vertex_brush_test(void *__restrict userdata,
   BKE_pbvh_vertex_iter_end;
 }
 
-template<typename PaintingKernelType>
 static void do_task_cb_ex(void *__restrict userdata,
                           const int n,
                           const TaskParallelTLS *__restrict tls)
@@ -272,7 +272,6 @@ static void do_task_cb_ex(void *__restrict userdata,
   TexturePaintingUserData *data = static_cast<TexturePaintingUserData *>(userdata);
   Object *ob = data->ob;
   SculptSession *ss = ob->sculpt;
-  ImBuf *image_buffer = ss->mode.texture_paint.drawing_target;
   const Brush *brush = data->brush;
   PBVHNode *node = data->nodes[n];
   NodeData *node_data = static_cast<NodeData *>(BKE_pbvh_node_texture_paint_data_get(node));
@@ -314,27 +313,55 @@ static void do_task_cb_ex(void *__restrict userdata,
 
   const int thread_id = BLI_task_parallel_thread_id(tls);
   MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
-  PaintingKernelType kernel(ss, brush, thread_id, mvert);
+  PaintingKernel<ImageBufferFloat4> kernel_float4(ss, brush, thread_id, mvert);
+  PaintingKernel<ImageBufferByte4> kernel_byte4(ss, brush, thread_id, mvert);
+
+  Image *image = ss->mode.texture_paint.image;
+  ImageUser image_user = *ss->mode.texture_paint.image_user;
+
+  /* TODO: should we lock? */
+  void *image_lock;
+  LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+    imbuf::ImageTileWrapper image_tile(tile);
+    image_user.tile = image_tile.get_tile_number();
+    TileData *tile_data = node_data->find_tile_data(image_tile);
+    if (tile_data == nullptr) {
+      /* This node doesn't paint on this tile. */
+      continue;
+    }
 
-  int packages_clipped = 0;
-  for (const PixelsPackage &encoded_pixels : node_data->encoded_pixels) {
-    if (!triangle_brush_test_results[encoded_pixels.triangle_index]) {
-      packages_clipped += 1;
+    ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user, &image_lock);
+    if (image_buffer == nullptr) {
       continue;
     }
-    const Triangle &triangle = node_data->triangles[encoded_pixels.triangle_index];
-    const bool pixels_painted = kernel.paint(triangle, encoded_pixels, image_buffer);
-
-    if (pixels_painted) {
-      BLI_rcti_do_minmax_v(&node_data->dirty_region, encoded_pixels.start_image_coordinate);
-      BLI_rcti_do_minmax_v(
-          &node_data->dirty_region,
-          int2(encoded_pixels.start_image_coordinate.x + encoded_pixels.num_pixels + 1,
-               encoded_pixels.start_image_coordinate.y));
-      node_data->flags.dirty = true;
+
+    for (const PixelsPackage &encoded_pixels : tile_data->encoded_pixels) {
+      if (!triangle_brush_test_results[encoded_pixels.triangle_index]) {
+        continue;
+      }
+      const Triangle &triangle = node_data->triangles[encoded_pixels.triangle_index];
+      bool pixels_painted = false;
+      if (image_buffer->rect_float != nullptr) {
+        pixels_painted = kernel_float4.paint(triangle, encoded_pixels, image_buffer);
+      }
+      else {
+        pixels_painted = kernel_byte4.paint(triangle, encoded_pixels, image_buffer);
+      }
+
+      if (pixels_painted) {
+        BLI_rcti_do_minmax_v(&tile_data->dirty_region, encoded_pixels.start_image_coordinate);
+        BLI_rcti_do_minmax_v(
+            &tile_data->dirty_region,
+            int2(encoded_pixels.start_image_coordinate.x + encoded_pixels.num_pixels + 1,
+                 encoded_pixels.start_image_coordinate.y));
+        node_data->flags.dirty = true;
+      }
     }
+
+    BKE_image_release_ibuf(image, image_buffer, image_lock);
+
+    node_data->flags.dirty |= tile_data->flags.dirty;
   }
-  printf("%d of %ld pixel packages clipped\n", packages_clipped, node_data->encoded_pixels.size());
 }
 }  // namespace painting
 
@@ -342,11 +369,9 @@ struct ImageData {
   void *lock = nullptr;
   Image *image = nullptr;
   ImageUser *image_user = nullptr;
-  ImBuf *image_buffer = nullptr;
 
   ~ImageData()
   {
-    BKE_image_release_ibuf(image, image_buffer, lock);
   }
 
   static bool init_active_image(Object *ob, ImageData *r_image_data)
@@ -356,11 +381,6 @@ struct ImageData {
     if (r_image_data->image == nullptr) {
       return false;
     }
-    r_image_data->image_buffer = BKE_image_acquire_ibuf(
-        r_image_data->image, r_image_data->image_user, &r_image_data->lock);
-    if (r_image_data->image_buffer == nullptr) {
-      return false;
-    }
     return true;
   }
 };
@@ -376,7 +396,8 @@ void SCULPT_do_texture_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int
     return;
   }
 
-  ss->mode.texture_paint.drawing_target = image_data.image_buffer;
+  ss->mode.texture_paint.image = image_data.image;
+  ss->mode.texture_paint.image_user = image_data.image_user;
 
   Mesh *mesh = (Mesh *)ob->data;
 
@@ -392,25 +413,11 @@ void SCULPT_do_texture_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int
 
   TIMEIT_START(texture_painting);
   BLI_task_parallel_range(0, totnode, &data, painting::do_vertex_brush_test, &settings);
-  if (image_data.image_buffer->rect_float) {
-    BLI_task_parallel_range(
-        0,
-        totnode,
-        &data,
-        painting::do_task_cb_ex<painting::PaintingKernel<painting::ImageBufferFloat4>>,
-        &settings);
-  }
-  else {
-    BLI_task_parallel_range(
-        0,
-        totnode,
-        &data,
-        painting::do_task_cb_ex<painting::PaintingKernel<painting::ImageBufferByte4>>,
-        &settings);
-  }
+  BLI_task_parallel_range(0, totnode, &data, painting::do_task_cb_ex, &settings);
   TIMEIT_END(texture_painting);
 
-  ss->mode.texture_paint.drawing_target = nullptr;
+  ss->mode.texture_paint.image = nullptr;
+  ss->mode.texture_paint.image_user = nullptr;
 }
 
 void SCULPT_init_texture_paint(Object *ob)
@@ -420,15 +427,17 @@ void SCULPT_init_texture_paint(Object *ob)
   if (!ImageData::init_active_image(ob, &image_data)) {
     return;
   }
-  ss->mode.texture_paint.drawing_target = image_data.image_buffer;
+  ss->mode.texture_paint.image = image_data.image;
+  ss->mode.texture_paint.image_user = image_data.image_user;
+
   PBVHNode **nodes;
   int totnode;
   BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
   SCULPT_extract_pixels(ob, nodes, totnode);
-
   MEM_freeN(nodes);
 
-  ss->mode.texture_paint.drawing_target = nullptr;
+  ss->mode.texture_paint.image = nullptr;
+  ss->mode.texture_paint.image_user = nullptr;
 }
 
 void SCULPT_flush_texture_paint(Object *ob)
@@ -450,8 +459,21 @@ void SCULPT_flush_texture_paint(Object *ob)
     }
 
     if (data->flags.dirty) {
-      data->mark_region(*image_data.image, *image_data.image_buffer);
-      data->flags.dirty = false;
+      Image *image = image_data.image;
+      ImageUser image_user = *image_data.image_user;
+      void *image_lock;
+      LISTBASE_FOREACH (ImageTile *, tile, &image_data.image->tiles) {
+        imbuf::ImageTileWrapper image_tile(tile);
+        image_user.tile = image_tile.get_tile_number();
+        ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user, &image_lock);
+        if (image_buffer == nullptr) {
+          continue;
+        }
+
+        data->mark_region(*image_data.image, image_tile, *image_buffer);
+        data->flags.dirty = false;
+        BKE_image_release_ibuf(image, image_buffer, image_lock);
+      }
     }
   }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh b/source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
index 902fd7515e4..41934241fbc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
@@ -1,3 +1,5 @@
+#include "IMB_imbuf_wrappers.hh"
+
 namespace blender::ed::sculpt_paint::texture_paint {
 
 struct Polygon {
@@ -135,49 +137,64 @@ struct Pixels {
     dirty.push_back(false);
   }
 };
+struct TileData {
+  short tile_number;
+  struct {
+    bool dirty : 1;
+  } flags;
+
+  /* Dirty region of the tile in image space. */
+  rcti dirty_region;
+
+  Vector<PixelsPackage> encoded_pixels;
 
+  TileData()
+  {
+    flags.dirty = false;
+    BLI_rcti_init_minmax(&dirty_region);
+  }
+
+  void mark_region(Image &image, const imbuf::ImageTileWrapper &image_tile, ImBuf &image_buffer)
+  {
+    print_rcti_id(&dirty_region);
+    BKE_image_partial_update_mark_region(
+        &image, image_tile.image_tile, &image_buffer, &dirty_region);
+    BLI_rcti_init_minmax(&dirty_region);
+  }
+};
 struct NodeData {
   struct {
     bool dirty : 1;
   } flags;
 
-  // Vector<PixelData> pixels;
-  Pixels pixels;
-  rcti dirty_region;
   rctf uv_region;
 
+  Vector<TileData> tiles;
   Vector<Triangle> triangles;
-  Vector<PixelsPackage> encoded_pixels;
 
   NodeData()
   {
     flags.dirty = false;
-    BLI_rcti_init_minmax(&dirty_region);
   }
 
   void init_pixels_rasterization(Object *ob, PBVHNode *node, ImBuf *image_buffer);
 
-  void flush(ImBuf &image_buffer)
+  TileData *find_tile_data(const imbuf::ImageTileWrapper &image_tile)
   {
-    flags.dirty = false;
-    for (int i = 0; i < pixels.size(); i++) {
-
-      if (pixels.is_dirty(i)) {
-        const int2 &image_coord = pixels.image_coord(i);
-        const int pixel_offset = (image_coord[1] * image_buffer.x + image_coord[0]);
-        const float4 &color = p

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list