[Bf-blender-cvs] [caed9482538] temp-3d-texturing-brush-b: Use a templated painting kernel.
Jeroen Bakker
noreply at git.blender.org
Wed Mar 16 14:10:47 CET 2022
Commit: caed9482538aa3bb33d86ecddb5576d61c1e18e3
Author: Jeroen Bakker
Date: Wed Mar 16 10:31:07 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rBcaed9482538aa3bb33d86ecddb5576d61c1e18e3
Use a templated painting kernel.
===================================================================
M source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
M source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
===================================================================
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 6232ca7c7dd..90631246e4d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_d.cc
@@ -40,45 +40,146 @@
namespace blender::ed::sculpt_paint::texture_paint {
namespace painting {
-static Pixel init_pixel(const Triangle &triangle,
- const float3 weights,
- const MVert *mvert,
- const MLoopUV *ldata_uv)
-{
- Pixel result;
- interp_v3_v3v3v3(result.pos,
- mvert[triangle.vert_indices[0]].co,
- mvert[triangle.vert_indices[1]].co,
- mvert[triangle.vert_indices[2]].co,
- weights);
- interp_v3_v3v3v3(result.uv,
- ldata_uv[triangle.loop_indices[0]].uv,
- ldata_uv[triangle.loop_indices[1]].uv,
- ldata_uv[triangle.loop_indices[2]].uv,
- weights);
- return result;
-}
+/** Reading and writing to image buffer with 4 float channels. */
+class ImagePixelAccessorFloat4 {
+ private:
+ int pixel_offset;
-static Pixel get_start_pixel(const PixelsPackage &encoded_pixels,
- const Triangle &triangle,
- const MVert *mvert,
- const MLoopUV *ldata_uv)
-{
- return init_pixel(triangle, encoded_pixels.start_barycentric_coord, mvert, ldata_uv);
-}
+ public:
+ void set_image_position(ImBuf *image_buffer, int2 image_pixel_position)
+ {
+ pixel_offset = image_pixel_position.y * image_buffer->x + image_pixel_position.x;
+ }
+
+ void goto_next_pixel()
+ {
+ pixel_offset += 1;
+ }
-static Pixel get_delta_pixel(const PixelsPackage &encoded_pixels,
- const Triangle &triangle,
- const Pixel &start_pixel,
- const MVert *mvert,
- const MLoopUV *ldata_uv
+ float4 read_pixel(ImBuf *image_buffer) const
+ {
+ return &image_buffer->rect_float[pixel_offset * 4];
+ }
-)
-{
- Pixel result = init_pixel(
- triangle, encoded_pixels.start_barycentric_coord + triangle.add_barycentric_coord_x, mvert, ldata_uv);
- return result - start_pixel;
-}
+ void store_pixel(ImBuf *image_buffer, const float4 pixel_data) const
+ {
+ copy_v4_v4(&image_buffer->rect_float[pixel_offset * 4], pixel_data);
+ }
+};
+
+template<typename ImagePixelAccessor> class PaintingKernel {
+ ImagePixelAccessor image_accessor;
+
+ SculptSession *ss;
+ const Brush *brush;
+ const int thread_id;
+ const MVert *mvert;
+ const MLoopUV *ldata_uv;
+
+ float4 brush_color;
+ float brush_strength;
+
+ SculptBrushTestFn brush_test_fn;
+ SculptBrushTest test;
+
+ public:
+ explicit PaintingKernel(SculptSession *ss,
+ const Brush *brush,
+ const int thread_id,
+ const MVert *mvert,
+ const MLoopUV *ldata_uv)
+ : ss(ss), brush(brush), thread_id(thread_id), mvert(mvert), ldata_uv(ldata_uv)
+ {
+ init_brush_color();
+ init_brush_strength();
+ init_brush_test();
+ }
+
+ bool paint(const Triangle &triangle, const PixelsPackage &encoded_pixels, ImBuf *image_buffer)
+ {
+ image_accessor.set_image_position(image_buffer, encoded_pixels.start_image_coordinate);
+ Pixel pixel = get_start_pixel(triangle, encoded_pixels);
+ const Pixel add_pixel = get_delta_pixel(triangle, encoded_pixels, pixel);
+ bool pixels_painted = false;
+ for (int x = 0; x < encoded_pixels.num_pixels; x++) {
+ if (!brush_test_fn(&test, pixel.pos)) {
+ pixel += add_pixel;
+ image_accessor.goto_next_pixel();
+ continue;
+ }
+
+ float4 color = image_accessor.read_pixel(image_buffer);
+ const float3 normal(0.0f, 0.0f, 0.0f);
+ const float3 face_normal(0.0f, 0.0f, 0.0f);
+ const float mask = 0.0f;
+ const float falloff_strength = SCULPT_brush_strength_factor_custom_automask(
+ ss,
+ brush,
+ pixel.pos,
+ sqrtf(test.dist),
+ normal,
+ face_normal,
+ mask,
+ triangle.automasking_factor,
+ thread_id);
+
+ blend_color_interpolate_float(color, color, brush_color, falloff_strength * brush_strength);
+ image_accessor.store_pixel(image_buffer, color);
+ pixels_painted = true;
+
+ image_accessor.goto_next_pixel();
+ pixel += add_pixel;
+ }
+ return pixels_painted;
+ }
+
+ private:
+ void init_brush_color()
+ {
+ float3 brush_srgb(brush->rgb[0], brush->rgb[1], brush->rgb[2]);
+ srgb_to_linearrgb_v3_v3(brush_color, brush_srgb);
+ brush_color[3] = 1.0f;
+ }
+
+ void init_brush_strength()
+ {
+ brush_strength = ss->cache->bstrength;
+ }
+ void init_brush_test()
+ {
+ brush_test_fn = SCULPT_brush_test_init_with_falloff_shape(ss, &test, brush->falloff_shape);
+ }
+
+ Pixel init_pixel(const Triangle &triangle, const float3 weights) const
+ {
+ Pixel result;
+ interp_v3_v3v3v3(result.pos,
+ mvert[triangle.vert_indices[0]].co,
+ mvert[triangle.vert_indices[1]].co,
+ mvert[triangle.vert_indices[2]].co,
+ weights);
+ interp_v3_v3v3v3(result.uv,
+ ldata_uv[triangle.loop_indices[0]].uv,
+ ldata_uv[triangle.loop_indices[1]].uv,
+ ldata_uv[triangle.loop_indices[2]].uv,
+ weights);
+ return result;
+ }
+
+ Pixel get_start_pixel(const Triangle &triangle, const PixelsPackage &encoded_pixels) const
+ {
+ return init_pixel(triangle, encoded_pixels.start_barycentric_coord);
+ }
+
+ Pixel get_delta_pixel(const Triangle &triangle,
+ const PixelsPackage &encoded_pixels,
+ const Pixel &start_pixel) const
+ {
+ Pixel result = init_pixel(
+ triangle, encoded_pixels.start_barycentric_coord + triangle.add_barycentric_coord_x);
+ return result - start_pixel;
+ }
+};
static void do_vertex_brush_test(void *__restrict userdata,
const int n,
@@ -117,20 +218,6 @@ static void do_task_cb_ex(void *__restrict userdata,
NodeData *node_data = static_cast<NodeData *>(BKE_pbvh_node_texture_paint_data_get(node));
BLI_assert(node_data != nullptr);
- const int thread_id = BLI_task_parallel_thread_id(tls);
-
- SculptBrushTest test;
- SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
- ss, &test, brush->falloff_shape);
-
- float3 brush_srgb(brush->rgb[0], brush->rgb[1], brush->rgb[2]);
- float4 brush_linear;
- srgb_to_linearrgb_v3_v3(brush_linear, brush_srgb);
- brush_linear[3] = 1.0f;
- MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
- Mesh *mesh = static_cast<Mesh *>(ob->data);
- MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
-
/* Propagate vertex brush test to triangle. This should be extended with brush overlapping edges
* and faces only. */
std::vector<bool> triangle_brush_test_results(node_data->triangles.size());
@@ -165,50 +252,20 @@ static void do_task_cb_ex(void *__restrict userdata,
triangle_index += 1;
}
- const float brush_strength = ss->cache->bstrength;
- int packages_clipped = 0;
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+ MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
+ MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
+ PaintingKernel<ImagePixelAccessorFloat4> kernel(ss, brush, thread_id, mvert, ldata_uv);
- for (PixelsPackage &encoded_pixels : node_data->encoded_pixels) {
+ 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;
continue;
}
- Triangle &triangle = node_data->triangles[encoded_pixels.triangle_index];
- int pixel_offset = encoded_pixels.start_image_coordinate.y * image_buffer->x +
- encoded_pixels.start_image_coordinate.x;
- float3 edge_coord = encoded_pixels.start_barycentric_coord;
- Pixel pixel = get_start_pixel(encoded_pixels, triangle, mvert, ldata_uv);
- const Pixel add_pixel = get_delta_pixel(encoded_pixels, triangle, pixel, mvert, ldata_uv);
- bool pixels_painted = false;
- for (int x = 0; x < encoded_pixels.num_pixels; x++) {
- if (!sculpt_brush_test_sq_fn(&test, pixel.pos)) {
- pixel += add_pixel;
- pixel_offset += 1;
- continue;
- }
-
- float *color = &image_buffer->rect_float[pixel_offset * 4];
- const float3 normal(0.0f, 0.0f, 0.0f);
- const float3 face_normal(0.0f, 0.0f, 0.0f);
- const float mask = 0.0f;
- const float falloff_strength = SCULPT_brush_strength_factor_custom_automask(
- ss,
- brush,
- pixel.pos,
- sqrtf(test.dist),
- normal,
- face_normal,
- mask,
- triangle.automasking_factor,
- thread_id);
-
- blend_color_interpolate_float(color, color, brush_linear, falloff_strength * brush_strength);
- pixels_painted = true;
-
- edge_coord += triangle.add_barycentric_coord_x;
- pixel += add_pixel;
- pixel_offset++;
- }
+ 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);
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 eba2c1aeff6..76f4a7bbdc5 100644
--- a/source/blender/editors/sculpt_paint/sculpt_texture_paint_intern.hh
+++ b/source/blender/editors/sculpt_paint/sculpt_tex
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list