[Bf-blender-cvs] [81f6998d65e] temp-T96710-pbvh-pixels: Paint brush on images.

Jeroen Bakker noreply at git.blender.org
Fri Apr 1 12:31:27 CEST 2022


Commit: 81f6998d65e1e65253dfe6c291cbd176b46ce032
Author: Jeroen Bakker
Date:   Fri Apr 1 12:31:07 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB81f6998d65e1e65253dfe6c291cbd176b46ce032

Paint brush on images.

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

M	source/blender/blenkernel/BKE_pbvh.hh
M	source/blender/blenkernel/intern/pbvh_pixels.cc
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_paint_color.c
A	source/blender/editors/sculpt_paint/sculpt_paint_image.cc

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

diff --git a/source/blender/blenkernel/BKE_pbvh.hh b/source/blender/blenkernel/BKE_pbvh.hh
index f2663056ed8..2b0cf954b61 100644
--- a/source/blender/blenkernel/BKE_pbvh.hh
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -200,4 +200,9 @@ struct NodeData {
   }
 };
 
+Triangles &BKE_pbvh_pixels_triangles_get(PBVHNode &node);
+TileData *BKE_pbvh_pixels_tile_data_get(PBVHNode &node, const image::ImageTileWrapper &image_tile);
+void BKE_pbvh_pixels_mark_dirty(PBVHNode &node);
+void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
+
 }  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 2323ac271b8..82cde7f94bf 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -11,6 +11,8 @@
 #include "BLI_math.h"
 #include "BLI_task.h"
 
+#include "BKE_image_wrappers.hh"
+
 #include "bmesh.h"
 
 #include "pbvh_intern.h"
@@ -285,6 +287,53 @@ static void init(PBVH *pbvh,
 
 }  // namespace blender::bke::pbvh::pixels::extractor
 
+namespace blender::bke::pbvh::pixels {
+
+Triangles &BKE_pbvh_pixels_triangles_get(PBVHNode &node)
+{
+  BLI_assert(node.pixels.node_data != nullptr);
+  NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
+  return node_data->triangles;
+}
+
+TileData *BKE_pbvh_pixels_tile_data_get(PBVHNode &node, const image::ImageTileWrapper &image_tile)
+{
+  BLI_assert(node.pixels.node_data != nullptr);
+  NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
+  return node_data->find_tile_data(image_tile);
+}
+
+void BKE_pbvh_pixels_mark_dirty(PBVHNode &node)
+{
+  BLI_assert(node.pixels.node_data != nullptr);
+  NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
+  node_data->flags.dirty |= true;
+}
+
+void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user)
+{
+  BLI_assert(node.pixels.node_data != nullptr);
+  NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
+  if (node_data->flags.dirty) {
+    ImageUser local_image_user = image_user;
+    void *image_lock;
+    LISTBASE_FOREACH (ImageTile *, tile, &image.tiles) {
+      image::ImageTileWrapper image_tile(tile);
+      local_image_user.tile = image_tile.get_tile_number();
+      ImBuf *image_buffer = BKE_image_acquire_ibuf(&image, &local_image_user, &image_lock);
+      if (image_buffer == nullptr) {
+        continue;
+      }
+
+      node_data->mark_region(image, image_tile, *image_buffer);
+      BKE_image_release_ibuf(&image, image_buffer, image_lock);
+    }
+    node_data->flags.dirty = false;
+  }
+}
+
+}  // namespace blender::bke::pbvh::pixels
+
 extern "C" {
 using namespace blender::bke::pbvh::pixels::extractor;
 using namespace blender::bke::pbvh::pixels;
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index c422c8c2033..3b3f376970d 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -70,6 +70,7 @@ set(SRC
   sculpt_multiplane_scrape.c
   sculpt_ops.c
   sculpt_paint_color.c
+  sculpt_paint_image.cc
   sculpt_pose.c
   sculpt_smooth.c
   sculpt_transform.c
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 3a97e7fcc05..0565faee77d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -25,7 +25,6 @@
 
 #include "DNA_brush_types.h"
 #include "DNA_customdata_types.h"
-#include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_node_types.h"
@@ -41,7 +40,6 @@
 #include "BKE_key.h"
 #include "BKE_lib_id.h"
 #include "BKE_main.h"
-#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_mesh_mirror.h"
@@ -2745,10 +2743,13 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob)
 /** \name Texture painting
  * \{ */
 
-static bool sculpt_needs_pbvh_pixels(const Brush *brush /*, const PaintModeSettings *settings*/)
+static bool sculpt_needs_pbvh_pixels(const Brush *brush,
+                                     Object *ob /*, const PaintModeSettings *settings*/)
 {
   if (brush->sculpt_tool == SCULPT_TOOL_PAINT /*&& U.experimental.use_sculpt_texture_paint*/) {
-    return true;
+    Image *image;
+    ImageUser *image_user;
+    return SCULPT_paint_image_canvas_get(ob, &image, &image_user);
   }
 
   return false;
@@ -2758,28 +2759,12 @@ static void sculpt_pbvh_update_pixels(SculptSession *ss, Object *ob)
 {
   BLI_assert(ob->type == OB_MESH);
   Mesh *mesh = (Mesh *)ob->data;
-  /* TODO: should be determined from PaintModeSettings */
-  Material *mat = BKE_object_material_get(ob, ob->actcol);
-  if (mat == NULL) {
-    return;
-  }
-  if (mat->use_nodes == false) {
-    return;
-  }
-  bNode *node = nodeGetActiveTexture(mat->nodetree);
-  if (node == NULL) {
-    return;
-  }
-  if (node->type != SH_NODE_TEX_IMAGE) {
-    return;
-  }
 
-  Image *image = (Image *)node->id;
-  if (image == NULL) {
+  Image *image;
+  ImageUser *image_user;
+  if (!SCULPT_paint_image_canvas_get(ob, &image, &image_user)) {
     return;
   }
-  NodeTexImage *storage = node->storage;
-  ImageUser *image_user = &storage->iuser;
 
   BKE_pbvh_build_pixels(ss->pbvh,
                         ss->pmap,
@@ -3256,7 +3241,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
     nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode);
   }
 
-  if (sculpt_needs_pbvh_pixels(brush)) {
+  if (sculpt_needs_pbvh_pixels(brush, ob)) {
     sculpt_pbvh_update_pixels(ss, ob);
   }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 6f9df4d8252..d1cd0963c0d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -11,23 +11,29 @@
 #include "DNA_key_types.h"
 #include "DNA_listBase.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_vec_types.h"
 
 #include "BKE_paint.h"
 #include "BKE_pbvh.h"
 #include "BLI_bitmap.h"
+#include "BLI_compiler_attrs.h"
 #include "BLI_compiler_compat.h"
 #include "BLI_gsqueue.h"
 #include "BLI_threads.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct AutomaskingCache;
+struct Image;
+struct ImageUser;
 struct KeyBlock;
 struct Object;
 struct SculptUndoNode;
 struct bContext;
 
-enum ePaintSymmetryFlags;
-
 /* Updates */
 
 /* -------------------------------------------------------------------- */
@@ -1607,7 +1613,24 @@ void SCULPT_multiplane_scrape_preview_draw(uint gpuattr,
 void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
 
 /* Paint Brush. */
-void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) ATTR_NONNULL();
+
+/**
+ * @brief Get the image canvas for painting on the given object.
+ *
+ * @note this is a temporary function. Would actually need to be replaced by logic provided by
+ * {D14455}.
+ *
+ * @return #true if an image is found. The #r_image and #r_image_user fields are filled with the
+ * image and image user. Returns false when the image isn't found. In the later case the r_image
+ * and r_image_user would not be modified.
+ */
+bool SCULPT_paint_image_canvas_get(struct Object *ob,
+                                   struct Image **r_image,
+                                   struct ImageUser **r_image_user) ATTR_NONNULL();
+void SCULPT_do_paint_brush_image(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+    ATTR_NONNULL();
+bool SCULPT_use_image_paint_brush(Sculpt *sd, Object *ob) ATTR_NONNULL();
 
 /* Smear Brush. */
 void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
@@ -1719,3 +1742,7 @@ void SCULPT_bmesh_topology_rake(
 void SCULPT_OT_brush_stroke(struct wmOperatorType *ot);
 
 /* end sculpt_ops.c */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 5d248cb520a..aedd05696f6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -233,6 +233,12 @@ static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata),
 
 void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
 {
+  /* TODO: Should be determined by the painting canvas. */
+  if (SCULPT_use_image_paint_brush(sd, ob)) {
+    SCULPT_do_paint_brush_image(sd, ob, nodes, totnode);
+    return;
+  }
+
   Brush *brush = BKE_paint_brush(&sd->paint);
   SculptSession *ss = ob->sculpt;
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
new file mode 100644
index 00000000000..e6cb63891e2
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -0,0 +1,447 @@
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "ED_uvedit.h"
+
+#include "PIL_time_utildefines.h"
+
+#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
+#include "BLI_task.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+
+#include "BKE_image_wrappers.hh"
+#include "BKE_material.h"
+#include "BKE_pbvh.h"
+#include "BKE_pbvh.hh"
+
+#include "bmesh.h"
+
+#include "NOD_shader.h"
+
+#include "sculpt_intern.h"
+
+namespace blender::ed::sculpt_paint::paint::image {
+
+using namespace blender::bke::pbvh::pixels;
+using namespace blender::bke::image;
+
+struct ImageData {
+  void *lock = nullptr;
+  Image *image = nullptr;
+  ImageUser *image_user = nullptr;
+
+  ~ImageData()
+  {
+  }
+
+  static bool init_active_image(Object *ob, ImageData *r_image_data)
+  {
+    ED_object_get_active_image(
+        ob, ob->actcol, &r_image_data-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list