[Bf-blender-cvs] [69f765dcdae] temp-3d-texturing-brush-b: WIP Initial texture painting.

Jeroen Bakker noreply at git.blender.org
Fri Mar 4 14:14:29 CET 2022


Commit: 69f765dcdae3cdf7a78730a0bc9fe65b1185c611
Author: Jeroen Bakker
Date:   Fri Mar 4 12:04:43 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rB69f765dcdae3cdf7a78730a0bc9fe65b1185c611

WIP Initial texture painting.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenlib/BLI_utildefines.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
A	source/blender/editors/sculpt_paint/sculpt_texture_paint.cc
M	source/blender/imbuf/IMB_rasterizer.hh
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 8ab89b6c244..246f67735f6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -29,6 +29,7 @@ struct EnumPropertyItem;
 struct GHash;
 struct GridPaintMask;
 struct ImagePool;
+struct ImBuf;
 struct ListBase;
 struct MLoop;
 struct MLoopTri;
@@ -620,6 +621,10 @@ typedef struct SculptSession {
       struct MDeformVert *dvert_prev;
     } wpaint;
 
+    struct {
+      struct ImBuf *drawing_target;
+    } texture_paint;
+
     /* TODO: identify sculpt-only fields */
     // struct { ... } sculpt;
   } mode;
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index eadbe52d091..6c8880fea7c 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -409,6 +409,26 @@ typedef struct PBVHVertexIter {
   bool visible;
 } PBVHVertexIter;
 
+#ifdef __cplusplus
+BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
+{
+  return static_cast<BMVert *>(src);
+}
+BLI_INLINE float *PBVH_cast_float_ptr(void *src)
+{
+  return static_cast<float*>(src);
+}
+#else
+BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
+{
+  return src;
+}
+BLI_INLINE float *PBVH_cast_float_ptr(void *src)
+{
+  return src;
+}
+#endif
+
 void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode);
 
 #define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \
@@ -467,11 +487,11 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
         } \
         else { \
           if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \
-            vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_unique_verts); \
+            vi.bm_vert = PBVH_cast_bmvert(BLI_gsetIterator_getKey(&vi.bm_unique_verts)); \
             BLI_gsetIterator_step(&vi.bm_unique_verts); \
           } \
           else { \
-            vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \
+            vi.bm_vert = PBVH_cast_bmvert(BLI_gsetIterator_getKey(&vi.bm_other_verts)); \
             BLI_gsetIterator_step(&vi.bm_other_verts); \
           } \
           vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \
@@ -481,7 +501,7 @@ 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 = 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 \
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 51f0d3f486a..60756b2213b 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -283,6 +283,8 @@ extern "C" {
   (_VA_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) || _VA_ELEM2(v, o))
 #define _VA_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
   (_VA_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) || _VA_ELEM2(v, p))
+#define _VA_ELEM18(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \
+  (_VA_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) || _VA_ELEM2(v, q))
 /* clang-format on */
 
 /* reusable ELEM macro */
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 59fbc3a64fb..16e8fdc8bca 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -65,6 +65,7 @@ set(SRC
   sculpt_paint_color.c
   sculpt_pose.c
   sculpt_smooth.c
+  sculpt_texture_paint.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 70ff7596d6d..525e1be5520 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3387,6 +3387,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
     case SCULPT_TOOL_SMEAR:
       SCULPT_do_smear_brush(sd, ob, nodes, totnode);
       break;
+    case SCULPT_TOOL_TEXTURE_PAINT:
+      SCULPT_do_texture_paint_brush(sd, ob, nodes, totnode);
+      break;
   }
 
   if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
@@ -3935,6 +3938,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
       return "Paint Brush";
     case SCULPT_TOOL_SMEAR:
       return "Smear Brush";
+    case SCULPT_TOOL_TEXTURE_PAINT:
+      return "Texture Paint Brush";
   }
 
   return "Sculpting";
@@ -4589,7 +4594,8 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd,
           (brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
           (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
           (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) ||
-          (brush->sculpt_tool == SCULPT_TOOL_DISPLACEMENT_SMEAR));
+          (brush->sculpt_tool == SCULPT_TOOL_DISPLACEMENT_SMEAR) ||
+          (brush->sculpt_tool == SCULPT_TOOL_TEXTURE_PAINT));
 }
 
 void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush)
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 6f9df4d8252..ad4f13fc438 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -20,6 +20,10 @@
 #include "BLI_gsqueue.h"
 #include "BLI_threads.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct AutomaskingCache;
 struct KeyBlock;
 struct Object;
@@ -1608,6 +1612,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);
 
 /* Smear Brush. */
 void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
@@ -1719,3 +1724,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_texture_paint.cc b/source/blender/editors/sculpt_paint/sculpt_texture_paint.cc
new file mode 100644
index 00000000000..ada1cc1dd43
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint.cc
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup edsculpt
+ */
+
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_image.h"
+#include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "BLI_task.h"
+
+#include "IMB_rasterizer.hh"
+
+#include "WM_types.h"
+
+#include "bmesh.h"
+
+#include "ED_uvedit.h"
+
+#include "sculpt_intern.h"
+
+namespace blender::ed::sculpt_paint::texture_paint {
+
+using namespace imbuf::rasterizer;
+
+struct VertexInput {
+  float2 uv;
+
+  VertexInput(float2 uv) : uv(uv)
+  {
+  }
+};
+
+class VertexShader : public AbstractVertexShader<VertexInput, int> {
+ public:
+  float2 image_size;
+  void vertex(const VertexInputType &input, VertexOutputType *r_output) override
+  {
+    r_output->coord = input.uv * image_size;
+  }
+};
+
+class FragmentShader : public AbstractFragmentShader<int, float4> {
+ public:
+  float4 color;
+  void fragment(const FragmentInputType &UNUSED(input), FragmentOutputType *r_output) override
+  {
+    copy_v4_v4(*r_output, color);
+  }
+};
+
+using RasterizerType = Rasterizer<VertexShader, FragmentShader>;
+
+static void do_task_cb_ex(void *__restrict userdata,
+                          const int n,
+                          const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata);
+  SculptSession *ss = data->ob->sculpt;
+  // const Brush *brush = data->brush;
+  // ss->cache->bstrength;
+  ImBuf *drawing_target = ss->mode.texture_paint.drawing_target;
+  RasterizerType rasterizer;
+  rasterizer.activate_drawing_target(drawing_target);
+  rasterizer.vertex_shader().image_size = float2(drawing_target->x, drawing_target->y);
+  rasterizer.fragment_shader().color = float4(1.0f, 1.0f, 1.0f, 1.0f);
+
+  PBVHVertexIter vd;
+
+  SculptBrushTest test;
+  SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+      ss, &test, data->brush->falloff_shape);
+
+  MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+
+  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+    MeshElemMap *vert_map = &ss->pmap[vd.index];
+    for (int j = 0; j < ss->pmap[vd.index].count; j++) {
+      const MPoly *p = &ss->mpoly[vert_map->indices[j]];
+
+      float poly_center[3];
+      const MLoop *loopstart = &ss->mloop[p->loopstart];
+      BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center);
+
+      if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
+        continue;
+      }
+      if (p->totloop < 3) {
+        continue;
+      }
+
+      VertexInput v1(mvert[loopstart[0].v].co);
+      VertexInput v2(mvert[loopstart[1].v].co);
+      VertexInput v3(mvert[loopstart[2].v].co);
+      rasterizer.draw_triangle(v1, v2, v3);
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+
+  rasterizer.deactivate_drawing_target();
+}
+
+extern "C" {
+void SCULPT_do_texture_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+  SculptSession *ss = ob->sculpt;
+  Brush *brush = BKE_paint_brush(&sd->paint);
+
+  void *lock;
+  Image *image;
+  ImageUser *image_user;
+
+  ED_object_get_active_image(ob, 1, &image, &image_user, nullptr, nullptr);
+  if (image == nullptr) {
+    return;
+  }
+  ImBuf *image_buffer = BKE_image_acquire_ibuf(image, image_user, &lock);
+  if (image_bu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list