[Bf-blender-cvs] [27a2c1c2612] temp-T96710-pbvh-pixels: Code style. Extracted into multiple functions to improve readability.

Jeroen Bakker noreply at git.blender.org
Fri Apr 1 15:02:41 CEST 2022


Commit: 27a2c1c2612568fcd3e7e84281cc3dea38edc333
Author: Jeroen Bakker
Date:   Fri Apr 1 15:02:37 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB27a2c1c2612568fcd3e7e84281cc3dea38edc333

Code style. Extracted into multiple functions to improve readability.

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

M	source/blender/blenkernel/intern/pbvh_pixels.cc

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

diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 92912797f89..d7076a7cd30 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -42,9 +42,24 @@ static bool has_been_visited(std::vector<bool> &visited_polygons, const int poly
   return visited;
 }
 
+/**
+ * @brief Calculate the delta of two neighbour uv coordinates in the given image buffer.
+ */
+static float3 calc_barycentric_delta(const ImBuf *image_buffer,
+                                     const float2 uvs[3],
+                                     const int x,
+                                     const int y)
+{
+  const float2 start_uv(float(x) / image_buffer->x, float(y) / image_buffer->y);
+  const float2 end_uv(float(x + 1) / image_buffer->x, float(y) / image_buffer->y);
+  const float3 start_barycentric = barycentric_weights(uvs[0], uvs[1], uvs[2], start_uv);
+  const float3 end_barycentric = barycentric_weights(uvs[0], uvs[1], uvs[2], end_uv);
+  const float3 delta_barycentric = end_barycentric - start_barycentric;
+  return delta_barycentric;
+}
+
 static void extract_barycentric_pixels(TileData &tile_data,
                                        const ImBuf *image_buffer,
-                                       TrianglePaintInput &triangle,
                                        const int triangle_index,
                                        const float2 uvs[3],
                                        const int minx,
@@ -52,7 +67,6 @@ static void extract_barycentric_pixels(TileData &tile_data,
                                        const int maxx,
                                        const int maxy)
 {
-  int best_num_pixels = 0;
   for (int y = miny; y < maxy; y++) {
     bool start_detected = false;
     float3 barycentric;
@@ -79,13 +93,6 @@ static void extract_barycentric_pixels(TileData &tile_data,
       continue;
     }
     package.num_pixels = x - package.start_image_coordinate.x;
-    if (package.num_pixels > best_num_pixels) {
-      // TODO(jbakker): this could be done even when barycentric coordinates are outside the
-      // triangle, no need to find best location to perform the calculation.
-      triangle.add_barycentric_coord_x = (barycentric - package.start_barycentric_coord.decode()) /
-                                         package.num_pixels;
-      best_num_pixels = package.num_pixels;
-    }
     tile_data.encoded_pixels.append(package);
   }
 }
@@ -169,8 +176,9 @@ static void do_encode_pixels(void *__restrict userdata,
       const int maxx = min_ii(ceil(maxu * image_buffer->x), image_buffer->x);
 
       TrianglePaintInput &triangle = triangles.get_paint_input(triangle_index);
+      triangle.add_barycentric_coord_x = calc_barycentric_delta(image_buffer, uvs, minx, miny);
       extract_barycentric_pixels(
-          tile_data, image_buffer, triangle, triangle_index, uvs, minx, miny, maxx, maxy);
+          tile_data, image_buffer, triangle_index, uvs, minx, miny, maxx, maxy);
     }
 
     BKE_image_release_ibuf(image, image_buffer, nullptr);
@@ -185,42 +193,105 @@ static void do_encode_pixels(void *__restrict userdata,
   node_data->triangles.cleanup_after_init();
 }
 
-static void init(PBVH *pbvh,
-                 const MeshElemMap *pmap,
-                 const struct MPoly *mpoly,
-                 const struct MLoop *mloop,
-                 struct CustomData *ldata,
-                 int tot_poly,
-                 struct Image *image,
-                 struct ImageUser *image_user)
+static bool should_pixels_be_updated(PBVHNode *node)
+{
+  if ((node->flag & PBVH_Leaf) == 0) {
+    return false;
+  }
+  NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+  if (node_data != nullptr) {
+    return false;
+  }
+  return true;
+}
+
+static bool contains_triangles(PBVHNode *node)
 {
-  Vector<PBVHNode *> nodes_to_initialize;
+  if ((node->flag & PBVH_Leaf) == 0) {
+    return false;
+  }
+  NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+  if (node_data == nullptr) {
+    return false;
+  }
+  return true;
+}
+
+static int64_t count_nodes_to_update(PBVH *pbvh)
+{
+  int64_t result = 0;
   for (int n = 0; n < pbvh->totnode; n++) {
     PBVHNode *node = &pbvh->nodes[n];
-    if ((node->flag & PBVH_Leaf) == 0) {
-      continue;
+    if (should_pixels_be_updated(node)) {
+      result++;
     }
-    NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
-    if (node_data != nullptr) {
-      continue;
+  }
+  return result;
+}
+
+/**
+ * Find the nodes that needs to be updated.
+ *
+ * The nodes that require updated are added to the r_nodes_to_update parameter.
+ * Will fill in r_visited_polygons with polygons that are owned by nodes that do not require
+ * updates.
+ *
+ * returns if there were any nodes found (true).
+ */
+static bool find_nodes_to_update(PBVH *pbvh,
+                                 Vector<PBVHNode *> &r_nodes_to_update,
+                                 std::vector<bool> &r_visited_polygons)
+{
+  int64_t nodes_to_update_len = count_nodes_to_update(pbvh);
+  if (nodes_to_update_len == 0) {
+    return false;
+  }
+
+  r_nodes_to_update.reserve(nodes_to_update_len);
+
+  for (int n = 0; n < pbvh->totnode; n++) {
+    PBVHNode *node = &pbvh->nodes[n];
+    if (should_pixels_be_updated(node)) {
+      if (node->pixels.node_data == nullptr) {
+        NodeData *node_data = MEM_new<NodeData>(__func__);
+        node->pixels.node_data = node_data;
+        r_nodes_to_update.append(node);
+      }
+    }
+    else if (contains_triangles(node)) {
+      /* Mark polygons that are owned by other leafs, so they don't be added twice. */
+      Triangles &triangles = BKE_pbvh_pixels_triangles_get(*node);
+      for (int &poly_index : triangles.poly_indices) {
+        r_visited_polygons[poly_index] = true;
+      }
     }
-    node_data = MEM_new<NodeData>(__func__);
-    node->pixels.node_data = node_data;
-    nodes_to_initialize.append(node);
   }
-  if (nodes_to_initialize.size() == 0) {
+
+  return true;
+}
+
+static void update_pixels(PBVH *pbvh,
+                          const MeshElemMap *pmap,
+                          const struct MPoly *mpoly,
+                          const struct MLoop *mloop,
+                          struct CustomData *ldata,
+                          int tot_poly,
+                          struct Image *image,
+                          struct ImageUser *image_user)
+{
+  Vector<PBVHNode *> nodes_to_update;
+  std::vector<bool> visited_polygons(tot_poly);
+
+  if (!find_nodes_to_update(pbvh, nodes_to_update, visited_polygons)) {
     return;
   }
-  printf("%lld nodes to initialize\n", nodes_to_initialize.size());
 
   MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(ldata, CD_MLOOPUV));
   if (ldata_uv == nullptr) {
     return;
   }
-  std::vector<bool> visited_polygons(tot_poly);
 
-  for (int n = 0; n < nodes_to_initialize.size(); n++) {
-    PBVHNode *node = nodes_to_initialize[n];
+  for (PBVHNode *node : nodes_to_update) {
     NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
     init_triangles(pbvh, node, node_data, pmap, mpoly, mloop, visited_polygons);
   }
@@ -229,11 +300,11 @@ static void init(PBVH *pbvh,
   user_data.image = image;
   user_data.image_user = image_user;
   user_data.ldata_uv = ldata_uv;
-  user_data.nodes = &nodes_to_initialize;
+  user_data.nodes = &nodes_to_update;
 
   TaskParallelSettings settings;
-  BKE_pbvh_parallel_range_settings(&settings, true, nodes_to_initialize.size());
-  BLI_task_parallel_range(0, nodes_to_initialize.size(), &user_data, do_encode_pixels, &settings);
+  BKE_pbvh_parallel_range_settings(&settings, true, nodes_to_update.size());
+  BLI_task_parallel_range(0, nodes_to_update.size(), &user_data, do_encode_pixels, &settings);
 
 //#define DO_PRINT_STATISTICS
 #ifdef DO_PRINT_STATISTICS
@@ -342,7 +413,7 @@ void BKE_pbvh_build_pixels(PBVH *pbvh,
                            struct Image *image,
                            struct ImageUser *image_user)
 {
-  init(pbvh, pmap, mpoly, mloop, ldata, tot_poly, image, image_user);
+  update_pixels(pbvh, pmap, mpoly, mloop, ldata, tot_poly, image, image_user);
 }
 
 void pbvh_pixels_free(PBVHNode *node)



More information about the Bf-blender-cvs mailing list