[Bf-blender-cvs] [5c25182aff6] temp-T96710-pbvh-pixels: Seams extension in x.

Jeroen Bakker noreply at git.blender.org
Fri Apr 8 12:52:55 CEST 2022


Commit: 5c25182aff6e973915f6e2973d5fb502900b3e6e
Author: Jeroen Bakker
Date:   Fri Apr 8 12:52:49 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB5c25182aff6e973915f6e2973d5fb502900b3e6e

Seams extension in x.

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

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

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

diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index b7badb5674d..05a44f8aa04 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -22,7 +22,9 @@
 
 namespace blender::bke::pbvh::pixels::extractor {
 
-#define DO_WATERTIGHT_CHECK
+/** Durind 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;
 
 /**
  * Keep track of visited polygons.
@@ -306,13 +308,6 @@ static bool find_nodes_to_update(PBVH *pbvh,
   return true;
 }
 
-/** Durind debugging this check could be enabled. It will write to each image pixel that is covered
- * by the pbvh. */
-constexpr bool do_watertight_check()
-{
-  return false;
-}
-
 static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_user)
 {
   ImageUser watertight = *image_user;
@@ -339,8 +334,7 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us
                            encoded_pixels.start_image_coordinate.x;
         for (int x = 0; x < encoded_pixels.num_pixels; x++) {
           if (image_buffer->rect_float) {
-            image_buffer->rect_float[pixel_offset * 4] += 0.5;
-            // copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
+            copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
           }
           if (image_buffer->rect) {
             uint8_t *dest = static_cast<uint8_t *>(
@@ -391,11 +385,8 @@ static void update_pixels(PBVH *pbvh,
   TaskParallelSettings 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);
-  if (do_watertight_check()) {
-    apply_watertight_check(pbvh, image, image_user);
-  }
   BKE_pbvh_pixels_fix_seams(*pbvh, *image, *image_user);
-  if (do_watertight_check()) {
+  if (USE_WATERTIGHT_CHECK) {
     apply_watertight_check(pbvh, image, image_user);
   }
 
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index 423fa90869a..694299062cd 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -10,44 +10,92 @@ namespace blender::bke::pbvh::pixels {
 using namespace blender::bke::image;
 
 struct UVSeamExtenderRowPackage {
+  /** Amount of pixels to extend beyond the determined extension to reduce rendering artifacts. */
+  static const int ADDITIONAL_EXTEND_X = 1;
 
   PixelsPackage *package;
   TrianglePaintInput *triangle_paint_data;
   bool is_new;
+  int extend_xmin_len = 0;
+  int extend_xmax_len = 0;
 
   UVSeamExtenderRowPackage(PixelsPackage *package,
                            TrianglePaintInput *triangle_paint_data,
                            bool is_new)
       : package(package), triangle_paint_data(triangle_paint_data), is_new(is_new)
   {
+    init_extend_x_len();
   }
 
-  /**
-   * Check if any of the corners of the extended pixels is inside the triangle. In this case we
-   * should extend.
-   *
-   * This could be improved by using the triangle uv coordinates and using triangle intersection in
-   * UV space. Currently it can fail near the triangle vertices based on how the triangulation
-   * happens.
-   */
   bool should_extend_start() const
   {
-    BarycentricWeights weights = package->start_barycentric_coord.decode();
-    return (weights.is_inside_triangle() ||
-            (weights + triangle_paint_data->add_barycentric_coord_y).is_inside_triangle());
+    return extend_xmin_len != 0;
   }
 
   void extend_x_start()
   {
+    BLI_assert(extend_xmin_len != 0);
     package->num_pixels += 1;
     package->start_image_coordinate[0] -= 1;
     package->start_barycentric_coord -= float2(triangle_paint_data->add_barycentric_coord_x);
+    extend_xmin_len--;
   }
 
   bool should_extend_end() const
+  {
+    return extend_xmax_len != 0;
+  }
+
+  void extend_x_end()
+  {
+    BLI_assert(extend_xmax_len != 0);
+    package->num_pixels += 1;
+    extend_xmax_len--;
+  }
+
+ private:
+  void init_extend_x_len()
+  {
+    if (!is_new) {
+      return;
+    }
+
+    init_extend_xmin_len();
+    init_extend_xmax_len();
+    BLI_assert(extend_xmin_len);
+    BLI_assert(extend_xmax_len);
+  }
+
+  void init_extend_xmin_len()
+  {
+    int result = 0;
+    while (should_extend_xmin(result)) {
+      result++;
+    }
+    extend_xmin_len = result + ADDITIONAL_EXTEND_X;
+  }
+
+  bool should_extend_xmin(int offset) const
   {
     BarycentricWeights weights = package->start_barycentric_coord.decode();
-    weights += triangle_paint_data->add_barycentric_coord_x * package->num_pixels;
+    weights -= triangle_paint_data->add_barycentric_coord_x * offset;
+    return (weights.is_inside_triangle() ||
+            (weights + triangle_paint_data->add_barycentric_coord_y).is_inside_triangle());
+  }
+
+  void init_extend_xmax_len()
+  {
+    int result = 0;
+    while (should_extend_xmax(result)) {
+      result++;
+    }
+    extend_xmax_len = result + ADDITIONAL_EXTEND_X;
+  }
+
+  bool should_extend_xmax(int offset) const
+  {
+    BarycentricWeights weights = package->start_barycentric_coord.decode();
+    weights += triangle_paint_data->add_barycentric_coord_x * (package->num_pixels + offset);
     if (weights.is_inside_triangle()) {
       return true;
     }
@@ -57,11 +105,6 @@ struct UVSeamExtenderRowPackage {
     }
     return false;
   }
-
-  void extend_x_end()
-  {
-    package->num_pixels += 1;
-  }
 };
 
 class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
@@ -88,7 +131,7 @@ class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
  private:
   void extend_x_start()
   {
-    int prev_package_x = 0;
+    int prev_package_x = -1;
     int index = 0;
 
     for (UVSeamExtenderRowPackage &package : *this) {
@@ -118,17 +161,15 @@ class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
           next_package_x = next_package.package->start_image_coordinate[0];
         }
         else {
-          next_package_x = image_buffer_width;
+          next_package_x = image_buffer_width + 1;
         }
-        int extension_len = 0;
-        while (package.should_extend_end() && extension_len < 3) {
-          if (package.package->start_image_coordinate[0] + package.package->num_pixels <
+        while (package.should_extend_end()) {
+          if (package.package->start_image_coordinate[0] + package.package->num_pixels >=
               next_package_x - 1) {
-            package.extend_x_end();
-            extension_len++;
-            continue;
+            /* No room left for extending */
+            break;
           }
-          break;
+          package.extend_x_end();
         }
       }



More information about the Bf-blender-cvs mailing list