[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