[Bf-blender-cvs] [4a6a65f2144] temp-T96710-pbvh-pixels: extend seams.

Jeroen Bakker noreply at git.blender.org
Wed Apr 6 17:43:40 CEST 2022


Commit: 4a6a65f214421db371dc09b8a1d17c5cc874518f
Author: Jeroen Bakker
Date:   Wed Apr 6 17:43:28 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB4a6a65f214421db371dc09b8a1d17c5cc874518f

extend seams.

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

M	source/blender/blenkernel/BKE_pbvh.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/pbvh_pixels.cc
A	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 bcfd9c1d1df..f598d9da58a 100644
--- a/source/blender/blenkernel/BKE_pbvh.hh
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -81,6 +81,12 @@ class EncodedBarycentricWeights {
   {
     return BarycentricWeights(float3(encoded.x, encoded.y, 1.0 - encoded.x - encoded.y));
   }
+
+  EncodedBarycentricWeights &operator-=(const float2 &other)
+  {
+    encoded -= other;
+    return *this;
+  }
 };
 
 /**
@@ -286,5 +292,7 @@ Triangles &BKE_pbvh_pixels_triangles_get(PBVHNode &node);
 TileData *BKE_pbvh_pixels_tile_data_get(PBVHNode &node, const image::ImageTileWrapper &image_tile);
 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);
 
 }  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 7c6693b48d8..d2c9de8fdcd 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -243,6 +243,7 @@ set(SRC
   intern/pbvh.c
   intern/pbvh_bmesh.c
   intern/pbvh_pixels.cc
+  intern/pbvh_pixels_seams.cc
   intern/pointcache.c
   intern/pointcloud.cc
   intern/preferences.c
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 740870612bc..30da876391a 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -196,7 +196,6 @@ static void do_encode_pixels(void *__restrict userdata,
   }
 
   node_data->triangles.cleanup_after_init();
-  node->flag = static_cast<PBVHNodeFlags>(node->flag & ~PBVH_UpdatePixels);
 }
 
 static bool should_pixels_be_updated(PBVHNode *node)
@@ -267,6 +266,7 @@ static bool find_nodes_to_update(PBVH *pbvh,
     PBVHNode *node = &pbvh->nodes[n];
     if (should_pixels_be_updated(node)) {
       r_nodes_to_update.append(node);
+      node->flag = static_cast<PBVHNodeFlags>(node->flag | PBVH_UpdatePixels);
 
       if (node->pixels.node_data == nullptr) {
         NodeData *node_data = MEM_new<NodeData>(__func__);
@@ -325,6 +325,12 @@ 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);
+
+  /* Clear the UpdatePixels flag. */
+  for (PBVHNode *node : nodes_to_update) {
+    node->flag = static_cast<PBVHNodeFlags>(node->flag & ~PBVH_UpdatePixels);
+  }
 
 //#define DO_PRINT_STATISTICS
 #ifdef DO_PRINT_STATISTICS
@@ -353,20 +359,46 @@ static void update_pixels(PBVH *pbvh,
   }
 #endif
 
-//#define DO_WATERTIGHT_CHECK
+#define DO_WATERTIGHT_CHECK
 #ifdef DO_WATERTIGHT_CHECK
-  for (int n = 0; n < nodes_to_initialize.size(); n++) {
-    PBVHNode *node = nodes[n];
-    NodeData *node_data = static_cast<NodeData *>(BKE_pbvh_node_texture_paint_data_get(node));
-    for (PixelsPackage &encoded_pixels : node_data->encoded_pixels) {
-      int pixel_offset = encoded_pixels.start_image_coordinate.y * image_buffer->x +
-                         encoded_pixels.start_image_coordinate.x;
-      for (int x = 0; x < encoded_pixels.num_pixels; x++) {
-        copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
-        pixel_offset += 1;
+  ImageUser watertight = *image_user;
+  LISTBASE_FOREACH (ImageTile *, tile_data, &image->tiles) {
+    image::ImageTileWrapper image_tile(tile_data);
+    watertight.tile = image_tile.get_tile_number();
+    ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &watertight, NULL);
+    if (image_buffer == nullptr) {
+      continue;
+    }
+    for (int n = 0; n < pbvh->totnode; n++) {
+      PBVHNode *node = &pbvh->nodes[n];
+      if ((node->flag & PBVH_Leaf) == 0) {
+        continue;
+      }
+      NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+      TileData *tile_node_data = node_data->find_tile_data(image_tile);
+      if (tile_node_data == nullptr) {
+        continue;
+      }
+
+      for (PixelsPackage &encoded_pixels : tile_node_data->packages) {
+        int pixel_offset = encoded_pixels.start_image_coordinate.y * image_buffer->x +
+                           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 (image_buffer->rect) {
+            uint8_t *dest = static_cast<uint8_t *>(
+                static_cast<void *>(&image_buffer->rect[pixel_offset]));
+            copy_v4_uchar(dest, 255);
+          }
+          pixel_offset += 1;
+        }
       }
     }
+    BKE_image_release_ibuf(image, image_buffer, NULL);
   }
+  BKE_image_partial_update_mark_full_update(image);
 
 #endif
 }
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
new file mode 100644
index 00000000000..9fe945e476c
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+#include "BKE_pbvh.h"
+#include "BKE_pbvh.hh"
+
+#include "pbvh_intern.h"
+
+namespace blender::bke::pbvh::pixels {
+using namespace blender::bke::image;
+
+struct UVSeamExtenderRowPackage {
+
+  PixelsPackage *package;
+  TrianglePaintInput *triangle_paint_data;
+  bool is_new;
+
+  UVSeamExtenderRowPackage(PixelsPackage *package,
+                           TrianglePaintInput *triangle_paint_data,
+                           bool is_new)
+      : package(package), triangle_paint_data(triangle_paint_data), is_new(is_new)
+  {
+  }
+
+  void extend_x_start()
+  {
+    package->num_pixels += 1;
+    package->start_image_coordinate[0] -= 1;
+    package->start_barycentric_coord -= float2(triangle_paint_data->add_barycentric_coord_x);
+  }
+};
+
+class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
+
+ public:
+  bool has_packages_that_needs_fixing = false;
+
+  void append(UVSeamExtenderRowPackage &package)
+  {
+    has_packages_that_needs_fixing |= package.is_new;
+    Vector<UVSeamExtenderRowPackage>::append(package);
+  }
+
+  void extend_x()
+  {
+    std::sort(
+        begin(), end(), [](const UVSeamExtenderRowPackage &a, const UVSeamExtenderRowPackage &b) {
+          return a.package->start_image_coordinate[0] < b.package->start_image_coordinate[0];
+        });
+
+    int prev_package_x = 0;
+    int index = 0;
+    for (UVSeamExtenderRowPackage &package : *this) {
+      if (package.is_new) {
+        if (package.package->start_image_coordinate[0] - 1 > prev_package_x) {
+          package.extend_x_start();
+        }
+      }
+
+      prev_package_x = package.package->start_image_coordinate[0] + package.package->num_pixels;
+      index++;
+    }
+  }
+};
+
+class UVSeamExtender {
+  Vector<UVSeamExtenderRow> rows;
+
+ public:
+  explicit UVSeamExtender(PBVH &pbvh, ImageTileWrapper &image_tile, ImBuf &image_buffer)
+  {
+    rows.resize(image_buffer.y);
+    init(pbvh, image_tile);
+  }
+
+  void extend_x()
+  {
+    for (UVSeamExtenderRow &row : rows) {
+      if (row.has_packages_that_needs_fixing) {
+        row.extend_x();
+      }
+    }
+  }
+
+ private:
+  void init(PBVH &pbvh, ImageTileWrapper &image_tile)
+  {
+    for (int n = 0; n < pbvh.totnode; n++) {
+      PBVHNode &node = pbvh.nodes[n];
+      if ((node.flag & PBVH_Leaf) == 0) {
+        continue;
+      }
+      init(node, image_tile);
+    }
+  }
+
+  void init(PBVHNode &node, ImageTileWrapper &image_tile)
+  {
+    NodeData &node_data = *static_cast<NodeData *>(node.pixels.node_data);
+    TileData *tile_node_data = node_data.find_tile_data(image_tile);
+    if (tile_node_data == nullptr) {
+      return;
+    }
+    init(node, node_data, *tile_node_data);
+  }
+
+  void init(PBVHNode &node, NodeData &node_data, TileData &tile_data)
+  {
+    for (PixelsPackage &package : tile_data.packages) {
+      UVSeamExtenderRowPackage row_package(
+          &package,
+          &node_data.triangles.get_paint_input(package.triangle_index),
+          (node.flag & PBVH_Leaf) == 0);
+      append(row_package);
+    }
+  }
+
+  void append(UVSeamExtenderRowPackage &package)
+  {
+    rows[package.package->start_image_coordinate[1]].append(package);
+  }
+};
+
+/** Extend pixels to fix uv seams for the given nodes. */
+void BKE_pbvh_pixels_fix_seams(PBVH &pbvh, Image &image, ImageUser &image_user)
+{
+  ImageUser local_image_user = image_user;
+  LISTBASE_FOREACH (ImageTile *, tile_data, &image.tiles) {
+    image::ImageTileWrapper image_tile(tile_data);
+    local_image_user.tile = image_tile.get_tile_number();
+    ImBuf *image_buffer = BKE_image_acquire_ibuf(&image, &local_image_user, NULL);
+    if (image_buffer == nullptr) {
+      continue;
+    }
+    UVSeamExtender extender(pbvh, image_tile, *image_buffer);
+    extender.extend_x();
+    BKE_image_release_ibuf(&image, image_buffer, NULL);
+  }
+}
+
+}  // namespace blender::bke::pbvh::pixels



More information about the Bf-blender-cvs mailing list