[Bf-blender-cvs] [c4b20425bd8] temp-T97352-3d-texturing-seam-bleeding: Improve quality seam fixing (step distance)

Jeroen Bakker noreply at git.blender.org
Fri May 13 12:40:19 CEST 2022


Commit: c4b20425bd8715f98aea0c6b7edfbb8524fbca20
Author: Jeroen Bakker
Date:   Fri May 13 12:38:23 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding
https://developer.blender.org/rBc4b20425bd8715f98aea0c6b7edfbb8524fbca20

Improve quality seam fixing (step distance)

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

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

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

diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index f23ff555bd4..b7ff3cc258f 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -272,9 +272,11 @@ Bitmaps create_tile_bitmap(const PBVH &pbvh, Image &image, ImageUser &image_user
   return result;
 }
 
-int2 find_source_pixel(const Bitmap &bitmap, float2 near_image_coord)
+int2 find_source_pixel(const Bitmap &bitmap,
+                       float2 near_image_coord,
+                       const float seam_fix_distance)
 {
-  const int SEARCH_RADIUS = 2;
+  const int SEARCH_RADIUS = std::ceil(seam_fix_distance);
   float min_distance = FLT_MAX;
   int2 result(0, 0);
   int2 image_coord(int(near_image_coord.x), int(near_image_coord.y));
@@ -290,8 +292,9 @@ int2 find_source_pixel(const Bitmap &bitmap, float2 near_image_coord)
       if (!pixel_info.is_extracted()) {
         continue;
       }
+      float2 center_pixel_uv(u + 0.5f, v + 0.5f);
 
-      float distance = len_v2v2_int(uv, image_coord);
+      float distance = len_v2v2(center_pixel_uv, near_image_coord);
       if (distance < min_distance) {
         result = uv;
         min_distance = distance;
@@ -344,11 +347,11 @@ static void add_seam_fix(PBVHNode &node,
  * \{ */
 
 struct Projection {
-  const Bitmap *bitmap;
-  int node_index;
-  float2 pixel;
-  char bit_mask;
-  float score;
+  const Bitmap *bitmap = nullptr;
+  int node_index = -1;
+  float2 pixel = float2(0.0f, 0.0f);
+  char bit_mask = 0;
+  float score = 0.0f;
 };
 
 /*
@@ -455,6 +458,9 @@ static void build_fixes(PBVH &pbvh,
         /** Pixel not part of this tile. */
         continue;
       }
+      if (u == 18 && v == 530) {
+        printf("error");
+      }
 
       int pixel_offset = v * bitmap.resolution.x + u;
       PixelInfo &pixel_info = bitmap.bitmap[pixel_offset];
@@ -466,27 +472,38 @@ static void build_fixes(PBVH &pbvh,
       float2 dst_uv_offset(bitmap.image_tile.get_tile_x_offset(),
                            bitmap.image_tile.get_tile_y_offset());
       float2 uv_coord(u, v);
-      float2 uv(uv_coord.x / bitmap.resolution.x, uv_coord.y / bitmap.resolution.y);
+      float2 center_uv_coord(u + 0.5f, v + 0.5f);
+      float2 center_uv(center_uv_coord.x / bitmap.resolution.x,
+                       center_uv_coord.y / bitmap.resolution.y);
       float2 closest_point;
       const float lambda = closest_to_line_v2(closest_point,
-                                              uv,
+                                              center_uv,
                                               float2(luv_a_1.uv) - dst_uv_offset,
                                               float2(luv_a_2.uv) - dst_uv_offset);
       float2 closest_coord(closest_point.x * bitmap.resolution.x,
                            closest_point.y * bitmap.resolution.y);
 
       /* Distance to the edge in pixel space. */
-      float distance_to_edge = len_v2v2(closest_coord, uv_coord);
+      float distance_to_edge = len_v2v2(closest_coord, center_uv_coord);
       if (distance_to_edge > seamfix_distance) {
         continue;
       }
 
       Projection solution1;
       Projection solution2;
-      find_projection_source(
-          bitmaps, distance_to_edge, lambda, luv_b_1, luv_b_2, scale_factor, solution1);
-      find_projection_source(
-          bitmaps, distance_to_edge, 1.0f - lambda, luv_b_2, luv_b_1, scale_factor, solution2);
+      /* When distance to edge is small, it could happen that the solution is pointing to a pixel
+       * that also needs to be fixed. In this case we increase the distance until we find a
+       * solution or skip this pixel after some iterations. */
+      while (solution1.score == 0.0f && solution2.score == 0.0f) {
+        find_projection_source(
+            bitmaps, distance_to_edge, lambda, luv_b_1, luv_b_2, scale_factor, solution1);
+        find_projection_source(
+            bitmaps, distance_to_edge, 1.0f - lambda, luv_b_2, luv_b_1, scale_factor, solution2);
+        if (distance_to_edge > 1.4f) {
+          break;
+        }
+        distance_to_edge += 0.25f;
+      }
       if (solution1.score == 0.0 && solution2.score == 0.0) {
         /* No solution found skip this pixel. */
         continue;
@@ -513,6 +530,7 @@ static void build_fixes(PBVH &pbvh,
                         const MLoopUV *ldata_uv,
                         const float seamfix_distance)
 {
+  const int margin = std::ceil(seamfix_distance);
   for (const std::pair<EdgeLoop, EdgeLoop> &pair : connected) {
     // determine bounding rect in uv space + margin of 1;
     rctf uvbounds;
@@ -529,19 +547,19 @@ static void build_fixes(PBVH &pbvh,
 
     for (Bitmap &bitmap : bitmaps.bitmaps) {
       rcti uvbounds_i;
-      const int MARGIN = 2;
       uvbounds_i.xmin = (uvbounds.xmin - bitmap.image_tile.get_tile_x_offset()) *
-                            bitmap.resolution[0] -
-                        MARGIN;
+                        bitmap.resolution[0];
       uvbounds_i.ymin = (uvbounds.ymin - bitmap.image_tile.get_tile_y_offset()) *
-                            bitmap.resolution[1] -
-                        MARGIN;
+                        bitmap.resolution[1];
       uvbounds_i.xmax = (uvbounds.xmax - bitmap.image_tile.get_tile_x_offset()) *
-                            bitmap.resolution[0] +
-                        MARGIN;
+                        bitmap.resolution[0];
       uvbounds_i.ymax = (uvbounds.ymax - bitmap.image_tile.get_tile_y_offset()) *
-                            bitmap.resolution[1] +
-                        MARGIN;
+                        bitmap.resolution[1];
+
+      uvbounds_i.xmin -= margin;
+      uvbounds_i.xmax += margin;
+      uvbounds_i.ymin -= margin;
+      uvbounds_i.ymax += margin;
 
       build_fixes(pbvh,
                   bitmaps,
@@ -605,7 +623,7 @@ static void build_fixes(PBVH &pbvh,
         continue;
       }
 
-      int2 source_pixel = find_source_pixel(bitmap, closest_coord);
+      int2 source_pixel = find_source_pixel(bitmap, closest_coord, seamfix_distance);
       int2 destination_pixel(u, v);
 
       PixelInfo src_pixel_info = bitmap.get_pixel_info(source_pixel);



More information about the Bf-blender-cvs mailing list