[Bf-blender-cvs] [83d4cf9db1c] temp-T96710-pbvh-pixels: PBVH: triangle brush test.

Jeroen Bakker noreply at git.blender.org
Wed Apr 13 10:53:41 CEST 2022


Commit: 83d4cf9db1c95ec9f784aa64ab69b27bbcf106be
Author: Jeroen Bakker
Date:   Wed Apr 13 10:53:18 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB83d4cf9db1c95ec9f784aa64ab69b27bbcf106be

PBVH: triangle brush test.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/BKE_pbvh_pixels.hh
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenkernel/intern/pbvh_pixels.cc
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_image.cc

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index ea4a4efca87..7c5ff94f188 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -308,6 +308,7 @@ void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
 bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node);
 
 void BKE_pbvh_mark_update_pixels(PBVH *pbvh);
+void BKE_pbvh_pixels_free_brush_test(PBVH *pbvh);
 void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index);
 
 void BKE_pbvh_node_get_grids(PBVH *pbvh,
diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index b2cdb9353e3..3df78d7cdfb 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -53,6 +53,12 @@ struct Triangles {
   /** Data accessed by the inner loop of the painting brush. */
   Vector<TrianglePaintInput> paint_input;
 
+  /**
+   * For storing brush tests per triangle during painting.
+   * Will be freed after a painting a stroke.
+   */
+  std::vector<bool> brush_test;
+
  public:
   void append(const int3 vert_indices)
   {
@@ -74,6 +80,18 @@ struct Triangles {
     paint_input.clear();
   }
 
+  void init_brush_test()
+  {
+    if (brush_test.size() != size()) {
+      brush_test.resize(size(), false);
+    }
+  }
+
+  void clear_brush_test()
+  {
+    brush_test.resize(0, false);
+  }
+
   uint64_t size() const
   {
     return paint_input.size();
@@ -81,7 +99,7 @@ struct Triangles {
 
   uint64_t mem_size() const
   {
-    return paint_input.size() * sizeof(TrianglePaintInput);
+    return paint_input.size() * sizeof(TrianglePaintInput) + brush_test.size() / 8;
   }
 };
 
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 979446a496e..08dcd8f34b6 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1496,6 +1496,16 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
   }
 }
 
+void BKE_pbvh_pixels_free_brush_test(PBVH *pbvh)
+{
+  for (int n = 0; n < pbvh->totnode; n++) {
+    PBVHNode *node = &pbvh->nodes[n];
+    if (node->flag & PBVH_Leaf && node->pixels.node_data != NULL) {
+      pbvh_pixels_free_brush_test(node);
+    }
+  }
+}
+
 static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
 {
   MVert *mvert;
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index f75bd1e36f8..1dcc62fb260 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -258,6 +258,7 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
 
 /* pbvh_pixels.hh */
 void pbvh_pixels_free(PBVHNode *node);
+void pbvh_pixels_free_brush_test(PBVHNode *node);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 52f16cdb3fa..576fb5504e7 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -410,4 +410,11 @@ void pbvh_pixels_free(PBVHNode *node)
   MEM_delete(node_data);
   node->pixels.node_data = nullptr;
 }
+
+void pbvh_pixels_free_brush_test(PBVHNode *node)
+{
+  NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+  BLI_assert(node_data);
+  node_data->triangles.clear_brush_test();
+}
 }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index fc1df1635bd..1ceda950e45 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5214,6 +5214,10 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
     }
   }
 
+  if (update_flags & SCULPT_FREE_BRUSH_TEST) {
+    BKE_pbvh_pixels_free_brush_test(ss->pbvh);
+  }
+
   if (update_flags & SCULPT_UPDATE_COORDS) {
     BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateOriginalBB);
 
@@ -5420,7 +5424,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
   }
   else if (brush->sculpt_tool == SCULPT_TOOL_PAINT) {
     if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
-      SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE);
+      SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE | SCULPT_FREE_BRUSH_TEST);
     }
   }
   else {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 4c11be18758..39ce22b21b8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -47,6 +47,7 @@ typedef enum SculptUpdateType {
   SCULPT_UPDATE_VISIBILITY = 1 << 2,
   SCULPT_UPDATE_COLOR = 1 << 3,
   SCULPT_UPDATE_IMAGE = 1 << 4,
+  SCULPT_FREE_BRUSH_TEST = 1 << 5,
 } SculptUpdateType;
 
 typedef struct SculptCursorGeometryInfo {
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 13cfad1c9ae..d47fa2e8482 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -256,6 +256,36 @@ template<typename ImageBuffer> class PaintingKernel {
   }
 };
 
+static void update_triangle_brush_test(SculptSession *ss, Triangles &triangles, const MVert *mvert)
+{
+  triangles.init_brush_test();
+  SculptBrushTest test;
+  SCULPT_brush_test_init(ss, &test);
+  float3 brush_min_bounds(test.location[0] - test.radius,
+                          test.location[1] - test.radius,
+                          test.location[2] - test.radius);
+  float3 brush_max_bounds(test.location[0] + test.radius,
+                          test.location[1] + test.radius,
+                          test.location[2] + test.radius);
+  for (int triangle_index = 0; triangle_index < triangles.size(); triangle_index++) {
+    TrianglePaintInput &triangle = triangles.get_paint_input(triangle_index);
+
+    float3 triangle_min_bounds(mvert[triangle.vert_indices[0]].co);
+    float3 triangle_max_bounds(triangle_min_bounds);
+    for (int i = 1; i < 3; i++) {
+      const float3 &pos = mvert[triangle.vert_indices[i]].co;
+      triangle_min_bounds.x = min_ff(triangle_min_bounds.x, pos.x);
+      triangle_min_bounds.y = min_ff(triangle_min_bounds.y, pos.y);
+      triangle_min_bounds.z = min_ff(triangle_min_bounds.z, pos.z);
+      triangle_max_bounds.x = max_ff(triangle_max_bounds.x, pos.x);
+      triangle_max_bounds.y = max_ff(triangle_max_bounds.y, pos.y);
+      triangle_max_bounds.z = max_ff(triangle_max_bounds.z, pos.z);
+    }
+    triangles.brush_test[triangle_index] = isect_aabb_aabb_v3(
+        brush_min_bounds, brush_max_bounds, triangle_min_bounds, triangle_max_bounds);
+  }
+}
+
 static void do_paint_pixels(void *__restrict userdata,
                             const int n,
                             const TaskParallelTLS *__restrict tls)
@@ -267,9 +297,11 @@ static void do_paint_pixels(void *__restrict userdata,
   PBVHNode *node = data->nodes[n];
 
   NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
-
   const int thread_id = BLI_task_parallel_thread_id(tls);
   MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+
+  update_triangle_brush_test(ss, node_data.triangles, mvert);
+
   PaintingKernel<ImageBufferFloat4> kernel_float4(ss, brush, thread_id, mvert);
   PaintingKernel<ImageBufferByte4> kernel_byte4(ss, brush, thread_id, mvert);
 
@@ -294,6 +326,9 @@ static void do_paint_pixels(void *__restrict userdata,
         }
 
         for (const PackedPixelRow &pixel_row : tile_data.pixel_rows) {
+          if (!node_data.triangles.brush_test[pixel_row.triangle_index]) {
+            continue;
+          }
           bool pixels_painted = false;
           if (image_buffer->rect_float != nullptr) {
             pixels_painted = kernel_float4.paint(node_data.triangles, pixel_row, image_buffer);



More information about the Bf-blender-cvs mailing list