[Bf-blender-cvs] [ab6c400d149] temp-T96710-pbvh-pixels: Extending using line segment intersection.

Jeroen Bakker noreply at git.blender.org
Fri Apr 8 14:53:29 CEST 2022


Commit: ab6c400d149f4539e5d8ddbfe59b78c330daa776
Author: Jeroen Bakker
Date:   Fri Apr 8 14:53:12 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rBab6c400d149f4539e5d8ddbfe59b78c330daa776

Extending using line segment intersection.

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

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

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

diff --git a/source/blender/blenkernel/BKE_pbvh.hh b/source/blender/blenkernel/BKE_pbvh.hh
index 05ff9a53199..42f745890bd 100644
--- a/source/blender/blenkernel/BKE_pbvh.hh
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -8,6 +8,7 @@
 #include "BLI_vector.hh"
 
 #include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
 
 #include "BKE_image.h"
 #include "BKE_image_wrappers.hh"
@@ -183,11 +184,6 @@ struct Triangles {
     return paint_input[index];
   }
 
-  void cleanup_after_init()
-  {
-    loop_indices.clear();
-  }
-
   void clear()
   {
     paint_input.clear();
@@ -306,6 +302,9 @@ TileData *BKE_pbvh_pixels_tile_data_get(PBVHNode &node, const image::ImageTileWr
 void BKE_pbvh_pixels_mark_dirty(PBVHNode &node);
 void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
 /** Extend pixels to fix uv seams for the given nodes. */
-void BKE_pbvh_pixels_fix_seams(PBVH &pbvh, Image &image, ImageUser &image_user);
+void BKE_pbvh_pixels_fix_seams(PBVH &pbvh,
+                               Image &image,
+                               ImageUser &image_user,
+                               const MLoopUV *ldata_uv);
 
 }  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 05a44f8aa04..57259973438 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -25,6 +25,7 @@ namespace blender::bke::pbvh::pixels::extractor {
 /** 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;
+constexpr bool USE_WATERTIGHT_SEAM_CHECK = true;
 
 /**
  * Keep track of visited polygons.
@@ -212,8 +213,6 @@ static void do_encode_pixels(void *__restrict userdata,
     tile_data.packages.sort();
     node_data->tiles.append(tile_data);
   }
-
-  node_data->triangles.cleanup_after_init();
 }
 
 static bool should_pixels_be_updated(PBVHNode *node)
@@ -334,7 +333,12 @@ 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) {
-            copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
+            if (USE_WATERTIGHT_SEAM_CHECK) {
+              image_buffer->rect_float[pixel_offset * 4] += 0.5;
+            }
+            else {
+              copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
+            }
           }
           if (image_buffer->rect) {
             uint8_t *dest = static_cast<uint8_t *>(
@@ -385,7 +389,10 @@ 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);
-  BKE_pbvh_pixels_fix_seams(*pbvh, *image, *image_user);
+  if (USE_WATERTIGHT_CHECK && USE_WATERTIGHT_SEAM_CHECK) {
+    apply_watertight_check(pbvh, image, image_user);
+  }
+  BKE_pbvh_pixels_fix_seams(*pbvh, *image, *image_user, ldata_uv);
   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 694299062cd..ad5b12edfe2 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -6,9 +6,43 @@
 
 #include "pbvh_intern.h"
 
+#include "BLI_math_geom.h"
+
 namespace blender::bke::pbvh::pixels {
 using namespace blender::bke::image;
 
+bool intersect_uv_pixel(const ushort2 &pixel_coordinate,
+                        const ImBuf &image_buffer,
+                        const float2 triangle_uvs[3])
+{
+
+  float2 uv_bottom_left = float2(pixel_coordinate.x / float(image_buffer.x),
+                                 pixel_coordinate.y / float(image_buffer.y));
+  float2 uv_top_right = float2((pixel_coordinate.x + 1) / float(image_buffer.x),
+                               (pixel_coordinate.y + 1) / float(image_buffer.y));
+  float2 uv_bottom_right(uv_top_right[0], uv_bottom_left[1]);
+  float2 uv_top_left(uv_bottom_left[0], uv_top_right[1]);
+
+  return (isect_seg_seg_v2_simple(
+              uv_bottom_left, uv_bottom_right, triangle_uvs[0], triangle_uvs[1]) ||
+          isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[0], triangle_uvs[1]) ||
+          isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[0], triangle_uvs[1]) ||
+          isect_seg_seg_v2_simple(
+              uv_bottom_right, uv_top_right, triangle_uvs[0], triangle_uvs[1])) ||
+         (isect_seg_seg_v2_simple(
+              uv_bottom_left, uv_bottom_right, triangle_uvs[1], triangle_uvs[2]) ||
+          isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[1], triangle_uvs[2]) ||
+          isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[1], triangle_uvs[2]) ||
+          isect_seg_seg_v2_simple(
+              uv_bottom_right, uv_top_right, triangle_uvs[1], triangle_uvs[2])) ||
+         (isect_seg_seg_v2_simple(
+              uv_bottom_left, uv_bottom_right, triangle_uvs[2], triangle_uvs[0]) ||
+          isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[2], triangle_uvs[0]) ||
+          isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[2], triangle_uvs[0]) ||
+          isect_seg_seg_v2_simple(
+              uv_bottom_right, uv_top_right, triangle_uvs[2], triangle_uvs[0]));
+}
+
 struct UVSeamExtenderRowPackage {
   /** Amount of pixels to extend beyond the determined extension to reduce rendering artifacts. */
   static const int ADDITIONAL_EXTEND_X = 1;
@@ -21,10 +55,13 @@ struct UVSeamExtenderRowPackage {
 
   UVSeamExtenderRowPackage(PixelsPackage *package,
                            TrianglePaintInput *triangle_paint_data,
-                           bool is_new)
+                           const ImBuf &image_buffer,
+                           bool is_new,
+                           const int3 loop_indices,
+                           const MLoopUV *ldata_uv)
       : package(package), triangle_paint_data(triangle_paint_data), is_new(is_new)
   {
-    init_extend_x_len();
+    init_extend_x_len(image_buffer, loop_indices, ldata_uv);
   }
 
   bool should_extend_start() const
@@ -54,56 +91,59 @@ struct UVSeamExtenderRowPackage {
   }
 
  private:
-  void init_extend_x_len()
+  void init_extend_x_len(const ImBuf &image_buffer,
+                         const int3 loop_indices,
+                         const MLoopUV *ldata_uv)
   {
     if (!is_new) {
       return;
     }
 
-    init_extend_xmin_len();
-    init_extend_xmax_len();
+    float2 triangle_uvs[3];
+    triangle_uvs[0] = ldata_uv[loop_indices[0]].uv;
+    triangle_uvs[1] = ldata_uv[loop_indices[1]].uv;
+    triangle_uvs[2] = ldata_uv[loop_indices[2]].uv;
+
+    init_extend_xmin_len(image_buffer, triangle_uvs);
+    init_extend_xmax_len(image_buffer, triangle_uvs);
     BLI_assert(extend_xmin_len);
     BLI_assert(extend_xmax_len);
   }
 
-  void init_extend_xmin_len()
+  void init_extend_xmin_len(const ImBuf &image_buffer, const float2 triangle_uvs[3])
   {
     int result = 0;
-    while (should_extend_xmin(result)) {
+    while (should_extend_xmin(image_buffer, result, triangle_uvs)) {
       result++;
     }
     extend_xmin_len = result + ADDITIONAL_EXTEND_X;
   }
 
-  bool should_extend_xmin(int offset) const
+  bool should_extend_xmin(const ImBuf &image_buffer,
+                          int offset,
+                          const float2 triangle_uvs[3]) const
   {
-    BarycentricWeights weights = package->start_barycentric_coord.decode();
-    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());
+    uint16_t pixel_offset = offset + 1;
+    ushort2 pixel = package->start_image_coordinate - ushort2(pixel_offset, 0);
+    return intersect_uv_pixel(pixel, image_buffer, triangle_uvs);
   }
 
-  void init_extend_xmax_len()
+  void init_extend_xmax_len(const ImBuf &image_buffer, const float2 triangle_uvs[3])
   {
     int result = 0;
-    while (should_extend_xmax(result)) {
+    while (should_extend_xmax(image_buffer, result, triangle_uvs)) {
       result++;
     }
     extend_xmax_len = result + ADDITIONAL_EXTEND_X;
   }
 
-  bool should_extend_xmax(int offset) const
+  bool should_extend_xmax(const ImBuf &image_buffer,
+                          int offset,
+                          const float2 triangle_uvs[3]) 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;
-    }
-    weights += triangle_paint_data->add_barycentric_coord_y;
-    if (weights.is_inside_triangle()) {
-      return true;
-    }
-    return false;
+    uint16_t pixel_offset = offset + 1;
+    ushort2 pixel = package->start_image_coordinate + ushort2(pixel_offset, 0);
+    return intersect_uv_pixel(pixel, image_buffer, triangle_uvs);
   }
 };
 
@@ -183,11 +223,14 @@ class UVSeamExtender {
   int image_buffer_width_;
 
  public:
-  explicit UVSeamExtender(PBVH &pbvh, ImageTileWrapper &image_tile, ImBuf &image_buffer)
+  explicit UVSeamExtender(PBVH &pbvh,
+                          const ImageTileWrapper &image_tile,
+                          const ImBuf &image_buffer,
+                          const MLoopUV *ldata_uv)
       : image_buffer_width_(image_buffer.x)
   {
     rows.resize(image_buffer.y);
-    init(pbvh, image_tile);
+    init(pbvh, image_tile, image_buffer, ldata_uv);
   }
 
   void extend_x()
@@ -200,34 +243,47 @@ class UVSeamExtender {
   }
 
  private:
-  void init(PBVH &pbvh, ImageTileWrapper &image_tile)
+  void init(PBVH &pbvh,
+            const ImageTileWrapper &image_tile,
+            const Im

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list