[Bf-blender-cvs] [d2fa1daea64] temp-pbvh-split: temp-pbvh-split: PBVH texpaint node splitting

Joseph Eagar noreply at git.blender.org
Sat May 7 01:13:12 CEST 2022


Commit: d2fa1daea64f605fe6660675e293a1f09f885559
Author: Joseph Eagar
Date:   Fri May 6 16:08:20 2022 -0700
Branches: temp-pbvh-split
https://developer.blender.org/rBd2fa1daea64f605fe6660675e293a1f09f885559

temp-pbvh-split: PBVH texpaint node splitting

* Texture paint now has its own special
  PBVH nodes leaf node flag, PBVH_TexLeaf.
* There is a new version of BKE_pbvh_search_gather
  (BKE_pbvh_search_gather_ex) that takes the leaf
  test flag as an extra argument.

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

M	source/blender/blenkernel/BKE_pbvh.h
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/draw/intern/draw_manager_data.c
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
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 291b9b6b778..857c5c994c5 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -79,7 +79,7 @@ typedef enum {
   PBVH_UpdateTopology = 1 << 13,
   PBVH_UpdateColor = 1 << 14,
   PBVH_RebuildPixels = 1 << 15,
-
+  PBVH_TexLeaf = 1 << 16,
 } PBVHNodeFlags;
 
 typedef struct PBVHFrustumPlanes {
@@ -160,7 +160,12 @@ void BKE_pbvh_search_callback(PBVH *pbvh,
 
 void BKE_pbvh_search_gather(
     PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot);
-
+void BKE_pbvh_search_gather_ex(PBVH *pbvh,
+                               BKE_pbvh_SearchCallback scb,
+                               void *search_data,
+                               PBVHNode ***r_array,
+                               int *r_tot,
+                               PBVHNodeFlags leaf_flag);
 /* Ray-cast
  * the hit callback is called for all leaf nodes intersecting the ray;
  * it's up to the callback to find the primitive within the leaves that is
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index e1ab4ccfb0a..db6ab27f62a 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -759,7 +759,7 @@ static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting)
   iter->stacksize++;
 }
 
-static PBVHNode *pbvh_iter_next(PBVHIter *iter)
+static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
 {
   /* purpose here is to traverse tree, visiting child nodes before their
    * parents, this order is necessary for e.g. computing bounding boxes */
@@ -786,7 +786,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
       continue; /* don't traverse, outside of search zone */
     }
 
-    if (node->flag & PBVH_Leaf) {
+    if (node->flag & leaf_flag) {
       /* immediately hit leaf node */
       return node;
     }
@@ -831,8 +831,12 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
   return NULL;
 }
 
-void BKE_pbvh_search_gather(
-    PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot)
+void BKE_pbvh_search_gather_ex(PBVH *pbvh,
+                               BKE_pbvh_SearchCallback scb,
+                               void *search_data,
+                               PBVHNode ***r_array,
+                               int *r_tot,
+                               PBVHNodeFlags leaf_flag)
 {
   PBVHIter iter;
   PBVHNode **array = NULL, *node;
@@ -840,8 +844,8 @@ void BKE_pbvh_search_gather(
 
   pbvh_iter_begin(&iter, pbvh, scb, search_data);
 
-  while ((node = pbvh_iter_next(&iter))) {
-    if (node->flag & PBVH_Leaf) {
+  while ((node = pbvh_iter_next(&iter, leaf_flag))) {
+    if (node->flag & leaf_flag) {
       if (UNLIKELY(tot == space)) {
         /* resize array if needed */
         space = (tot == 0) ? 32 : space * 2;
@@ -864,6 +868,12 @@ void BKE_pbvh_search_gather(
   *r_tot = tot;
 }
 
+void BKE_pbvh_search_gather(
+    PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot)
+{
+  BKE_pbvh_search_gather_ex(pbvh, scb, search_data, r_array, r_tot, PBVH_Leaf);
+}
+
 void BKE_pbvh_search_callback(PBVH *pbvh,
                               BKE_pbvh_SearchCallback scb,
                               void *search_data,
@@ -875,7 +885,7 @@ void BKE_pbvh_search_callback(PBVH *pbvh,
 
   pbvh_iter_begin(&iter, pbvh, scb, search_data);
 
-  while ((node = pbvh_iter_next(&iter))) {
+  while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
     if (node->flag & PBVH_Leaf) {
       hcb(node, hit_data);
     }
@@ -1648,7 +1658,7 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3])
 
   pbvh_iter_begin(&iter, pbvh, NULL, NULL);
 
-  while ((node = pbvh_iter_next(&iter))) {
+  while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
     if (node->flag & PBVH_UpdateRedraw) {
       BB_expand_with_bb(&bb, &node->vb);
     }
@@ -1668,7 +1678,7 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int
 
   pbvh_iter_begin(&iter, pbvh, NULL, NULL);
 
-  while ((node = pbvh_iter_next(&iter))) {
+  while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
     if (node->flag & PBVH_UpdateNormals) {
       for (uint i = 0; i < node->totprim; i++) {
         void *face = pbvh->gridfaces[node->prim_indices[i]];
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index b5480673653..d17bcdaf1f0 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -89,7 +89,7 @@ struct PBVHNode {
 
   /* Indicates whether this node is a leaf or not; also used for
    * marking various updates that need to be applied. */
-  PBVHNodeFlags flag : 16;
+  PBVHNodeFlags flag : 32;
 
   /* Used for raycasting: how close bb is to the ray point. */
   float tmin;
@@ -137,6 +137,8 @@ struct PBVH {
   int totvert;
 
   int leaf_limit;
+  int pixel_leaf_limit;
+  int depth_limit;
 
   /* Mesh data */
   const struct Mesh *mesh;
@@ -275,6 +277,19 @@ void pbvh_pixels_free(PBVHNode *node);
 void pbvh_pixels_free_brush_test(PBVHNode *node);
 void pbvh_free_draw_buffers(PBVH *pbvh, PBVHNode *node);
 
+
+/* Disable optimization for a function (for debugging use only!)*/
+#ifdef __clang__
+#  define ATTR_NO_OPT __attribute__((optnone))
+#elif defined(_MSC_VER)
+#  define ATTR_NO_OPT __pragma(optimize("", off))
+#elif defined(__GNUC__)
+#  define ATTR_NO_OPT __attribute__((optimize("O0")))
+#else
+#  define ATTR_NO_OPT
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 5623cac44ac..a35f7267161 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -14,6 +14,7 @@
 #include "BLI_math.h"
 #include "BLI_task.h"
 
+#include "BKE_global.h"
 #include "BKE_image_wrappers.hh"
 
 #include "bmesh.h"
@@ -22,12 +23,6 @@
 
 namespace blender::bke::pbvh::pixels {
 
-/**
- * During debugging this check could be enabled.
- * It will write to each image pixel that is covered by the PBVH.
- */
-constexpr bool USE_WATERTIGHT_CHECK = false;
-
 /**
  * Calculate the delta of two neighbor UV coordinates in the given image buffer.
  */
@@ -54,6 +49,192 @@ static float2 calc_barycentric_delta_x(const ImBuf *image_buffer,
   return calc_barycentric_delta(uvs, start_uv, end_uv);
 }
 
+int count_node_pixels(PBVHNode &node)
+{
+  if (!node.pixels.node_data) {
+    return 0;
+  }
+
+  NodeData &data = BKE_pbvh_pixels_node_data_get(node);
+
+  int totpixel = 0;
+
+  for (UDIMTilePixels &tile : data.tiles) {
+    for (PackedPixelRow &row : tile.pixel_rows) {
+      totpixel += row.num_pixels;
+    }
+  }
+
+  return totpixel;
+}
+
+ATTR_NO_OPT void split_pixel_node(
+    PBVH *pbvh, int node_i, Mesh *mesh, Image *image, ImageUser *image_user)
+{
+  BB cb;
+  PBVHNode *node = pbvh->nodes + node_i;
+
+  cb = node->vb;
+
+  /* Find widest axis and its midpoint */
+  const int axis = BB_widest_axis(&cb);
+  const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
+
+  const int child1_i = pbvh->totnode;
+  const int child2_i = child1_i + 1;
+
+  node->flag = (PBVHNodeFlags)((int)node->flag & (int)~PBVH_TexLeaf);
+  pbvh_grow_nodes(pbvh, pbvh->totnode + 2);
+
+  node = pbvh->nodes + node_i;
+  PBVHNode *child1 = pbvh->nodes + child1_i;
+  PBVHNode *child2 = pbvh->nodes + child2_i;
+
+  node->children_offset = child1_i;
+
+  child1->flag = PBVH_TexLeaf;
+  child2->flag = PBVH_TexLeaf;
+
+  child1->vb = cb;
+  child1->vb.bmax[axis] = mid;
+
+  child2->vb = cb;
+  child2->vb.bmin[axis] = mid;
+
+  NodeData &data = BKE_pbvh_pixels_node_data_get(pbvh->nodes[node_i]);
+
+  NodeData *data1 = MEM_new<NodeData>(__func__);
+  NodeData *data2 = MEM_new<NodeData>(__func__);
+  child1->pixels.node_data = static_cast<void *>(data1);
+  child2->pixels.node_data = static_cast<void *>(data2);
+
+  data1->triangles = data.triangles;
+  data2->triangles = data.triangles;
+
+  data1->tiles.resize(data.tiles.size());
+  data2->tiles.resize(data.tiles.size());
+
+  for (int i : IndexRange(data.tiles.size())) {
+    UDIMTilePixels &tile = data.tiles[i];
+    UDIMTilePixels &tile1 = data1->tiles[i];
+    UDIMTilePixels &tile2 = data2->tiles[i];
+
+    tile1.tile_number = tile2.tile_number = tile.tile_number;
+    tile1.flags.dirty = tile2.flags.dirty = 0;
+  }
+
+  ImageUser image_user2 = *image_user;
+
+  for (int i : IndexRange(data.tiles.size())) {
+    const UDIMTilePixels &tile = data.tiles[i];
+
+    image_user2.tile = tile.tile_number;
+
+    ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user2, nullptr);
+    if (image_buffer == nullptr) {
+      continue;
+    }
+
+    for (const PackedPixelRow &row : tile.pixel_rows) {
+      UDIMTilePixels *tile1 = &data1->tiles[i];
+      UDIMTilePixels *tile2 = &data2->tiles[i];
+
+      TrianglePaintInput &tri = data.triangles.paint_input[row.triangle_index];
+
+      float verts[3][3];
+
+      copy_v3_v3(verts[0], mesh->mvert[tri.vert_indices[0]].co);
+      copy_v3_v3(verts[1], mesh->mvert[tri.vert_indices[1]].co);
+      copy_v3_v3(verts[2], mesh->mvert[tri.vert_indices[2]].co);
+
+      float2 delta = tri.delta_barycentric_coord_u;
+      float2 uv1 = row.start_barycentric_coord;
+      float2 uv2 = row.start_barycentric_coord + delta * (float)row.num_pixels;
+
+      float co1[3];
+      float co2[3];
+
+      interp_barycentric_tri_v3(verts, uv1[0], uv1[1], co1);
+      interp_barycentric_tri_v3(verts, uv2[0], uv2[1], co2);
+
+      /* Are we spanning the midpoint? */
+      if ((co1[axis] <= mid) != (co2[axis] <= mid)) {
+        PackedPixelRow row1 = row;
+        float t;
+
+        if (mid < co1[axis]) {
+          t = 1.0f - (mid - co2[axis]) / (co1[axis] - co2[axis]);
+        }
+        else {
+          t = (mid - co1[axis]) / (co2[axis] - co1[axis]);
+        }
+
+        int num_pixels = (int)floorf((float)row.num_pixels * t);
+
+        if (num_pixels) {
+          row1.num_pixels = num_pixels;
+          tile1->pixel_rows.appe

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list