[Bf-blender-cvs] [510235a1409] temp-T101739-fix-seam-bleeding-non-manifold: Move structs to header file.

Jeroen Bakker noreply at git.blender.org
Tue Jan 10 14:19:58 CET 2023


Commit: 510235a1409a7796fd33c5a09b8447724ddc4904
Author: Jeroen Bakker
Date:   Thu Jan 5 12:44:04 2023 +0100
Branches: temp-T101739-fix-seam-bleeding-non-manifold
https://developer.blender.org/rB510235a1409a7796fd33c5a09b8447724ddc4904

Move structs to header file.

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

M	source/blender/blenkernel/BKE_pbvh_pixels.hh
M	source/blender/blenkernel/intern/pbvh_pixels_copy.cc

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

diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index 1b0d51fd37d..28e02dbef8e 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include <functional>
+
 #include "BLI_math.h"
 #include "BLI_math_vec_types.hh"
 #include "BLI_rect.h"
@@ -242,10 +244,130 @@ struct NodeData {
   }
 };
 
+template<typename T, int Channels = 4> struct ImageBufferAccessor {
+  ImBuf &image_buffer;
+
+  ImageBufferAccessor(ImBuf &image_buffer) : image_buffer(image_buffer)
+  {
+  }
+
+  float4 read_pixel(const int2 coordinate)
+  {
+    int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
+    return float4(&image_buffer.rect_float[offset]);
+  }
+
+  void write_pixel(const int2 coordinate, float4 new_value)
+  {
+    int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
+    copy_v4_v4(&image_buffer.rect_float[offset], new_value);
+  }
+};
+
+struct PixelCopyItem {
+  uint8_t delta_destination_x;
+  char2 delta_source_1;
+  char2 delta_source_2;
+  uint8_t mix_factor;
+};
+
+struct PixelCopyGroup {
+  int2 destination;
+  Vector<PixelCopyItem> items;
+};
+
+/** Pixel copy command to mix 2 source pixels and write to a destination pixel. */
+struct PixelCopyCommand {
+  /** Pixel coordinate to write to. */
+  int2 destination;
+  /** Pixel coordinate to read first source from. */
+  int2 source_1;
+  /** Pixel coordinate to read second source from. */
+  int2 source_2;
+  /** Factor to mix between first and second source. */
+  float mix_factor;
+
+  PixelCopyCommand(const PixelCopyGroup &group)
+      : destination(group.destination),
+        source_1(group.destination),
+        source_2(group.destination),
+        mix_factor(0.0f)
+  {
+  }
+
+  template<typename T>
+  void mix_source_and_write_destination(ImageBufferAccessor<T> &tile_buffer) const
+  {
+    float4 source_color_1 = tile_buffer.read_pixel(source_1);
+    float4 source_color_2 = tile_buffer.read_pixel(source_2);
+    float4 destination_color = source_color_1 * (1.0f - mix_factor) + source_color_2 * mix_factor;
+    tile_buffer.write_pixel(destination, destination_color);
+  }
+
+  void apply(const PixelCopyItem &item)
+  {
+    destination.x += int(item.delta_destination_x);
+    source_1 += int2(item.delta_source_1);
+    source_2 += int2(item.delta_source_2);
+    mix_factor = float(item.mix_factor) / 255.0f;
+  }
+};
+
+struct PixelCopyTile {
+  image::TileNumber tile_number;
+  Vector<PixelCopyGroup> groups;
+
+  void copy_pixels(ImBuf &tile_buffer) const
+  {
+    if (tile_buffer.rect_float) {
+      ImageBufferAccessor<float4> accessor(tile_buffer);
+      copy_pixels<float4>(accessor);
+    }
+    else {
+      ImageBufferAccessor<int> accessor(tile_buffer);
+      copy_pixels<int>(accessor);
+    }
+  }
+
+ private:
+  template<typename T> void copy_pixels(ImageBufferAccessor<T> &image_buffer) const
+  {
+    for (const PixelCopyGroup &group : groups) {
+      PixelCopyCommand copy_command(group);
+      for (const PixelCopyItem &item : group.items) {
+        copy_command.apply(item);
+        copy_command.mix_source_and_write_destination<T>(image_buffer);
+      }
+    }
+  }
+};
+
+struct PixelCopyTiles {
+  Vector<PixelCopyTile> tiles;
+
+  std::optional<std::reference_wrapper<PixelCopyTile>> find_tile(image::TileNumber tile_number)
+  {
+    for (PixelCopyTile &tile : tiles) {
+      if (tile.tile_number == tile_number) {
+        return tile;
+      }
+    }
+    return std::nullopt;
+  }
+
+  void clear()
+  {
+    tiles.clear();
+  }
+};
+
 struct PBVHData {
   /* Per UVPRimitive contains the paint data. */
   PaintGeometryPrimitives geom_primitives;
 
+  /** Per ImageTile the pixels to copy to fix non-manifold bleeding. */
+  PixelCopyTiles tiles_copy_pixels;
+
   void clear_data()
   {
     geom_primitives.clear();
@@ -256,4 +378,9 @@ NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node);
 void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
 PBVHData &BKE_pbvh_pixels_data_get(PBVH &pbvh);
 
+void BKE_pbvh_pixels_copy_update(PBVH &pbvh, Image &image, ImageUser &image_user);
+void BKE_pbvh_pixels_copy_pixels(PBVH &pbvh,
+                                 Image &image,
+                                 ImageUser &image_user,
+                                 image::TileNumber tile_number);
 }  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
index a80e6606037..ca850812f02 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
@@ -1,109 +1,66 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later
  * Copyright 2022 Blender Foundation. All rights reserved. */
 
+#include "BLI_math.h"
 #include "BLI_math_vec_types.hh"
 #include "BLI_vector.hh"
-#include "BLI_math.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
-namespace blender::kernel::pbvh::pixels {
-template<typename T, int Channels = 4> struct ImageBufferAccessor {
-  ImBuf &image_buffer;
+#include "BKE_image_wrappers.hh"
+#include "BKE_pbvh.h"
+#include "BKE_pbvh_pixels.hh"
 
-  ImageBufferAccessor(ImBuf &image_buffer) : image_buffer(image_buffer)
-  {
-  }
-
-  float4 read_pixel(const int2 coordinate)
-  {
-    int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
-    return float4(&image_buffer.rect_float[offset]);
-  }
+namespace blender::bke::pbvh::pixels {
 
-  void write_pixel(const int2 coordinate, float4 new_value)
-  {
-    int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
-    copy_v4_v4(&image_buffer.rect_float[offset], new_value);
-  }
-};
+static void copy_pixels_reinit(PixelCopyTiles &tiles)
+{
+  tiles.clear();
+}
 
-struct PixelCopyItem {
-  uint8_t delta_destination_x;
-  char2 delta_source_1;
-  char2 delta_source_2;
-  uint8_t mix_factor;
-};
+void BKE_pbvh_pixels_copy_update(PBVH &pbvh, Image &image, ImageUser &image_user)
+{
+  PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
+  copy_pixels_reinit(pbvh_data.tiles_copy_pixels);
 
-struct PixelCopyGroup {
-  int2 destination;
-  Vector<PixelCopyItem> items;
-};
+  ImageUser tile_user = image_user;
+  LISTBASE_FOREACH (ImageTile *, tile, &image.tiles) {
+    image::ImageTileWrapper image_tile = image::ImageTileWrapper(tile);
+    tile_user.tile = image_tile.get_tile_number();
 
-/** Pixel copy command to mix 2 source pixels and write to a destination pixel. */
-struct PixelCopyCommand {
-  /** Pixel coordinate to write to. */
-  int2 destination;
-  /** Pixel coordinate to read first source from. */
-  int2 source_1;
-  /** Pixel coordinate to read second source from. */
-  int2 source_2;
-  /** Factor to mix between first and second source. */
-  float mix_factor;
+    ImBuf *tile_buffer = BKE_image_acquire_ibuf(&image, &tile_user, nullptr);
+    if (tile_buffer == nullptr) {
+      continue;
+    }
 
-  PixelCopyCommand(const PixelCopyGroup &group)
-      : destination(group.destination),
-        source_1(group.destination),
-        source_2(group.destination),
-        mix_factor(0.0f)
-  {
-  }
+    ushort2 tile_resolution(tile_buffer->x, tile_buffer->y);
 
-  template<typename T> void mix_source_and_write_destination(ImageBufferAccessor<T> &tile_buffer) const
-  {
-    float4 source_color_1 = tile_buffer.read_pixel(source_1);
-    float4 source_color_2 = tile_buffer.read_pixel(source_2);
-    float4 destination_color = source_color_1 * (1.0f - mix_factor) + source_color_2 * mix_factor;
-    tile_buffer.write_pixel(destination, destination_color);
+    BKE_image_release_ibuf(&image, tile_buffer, nullptr);
   }
-};
-
-PixelCopyCommand &operator+=(PixelCopyCommand &command, const PixelCopyItem &item)
-{
-  command.destination.x += int(item.delta_destination_x);
-  command.source_1 += int2(item.delta_source_1);
-  command.source_2 += int2(item.delta_source_2);
-  command.mix_factor = float(item.mix_factor) / 255.0f;
-  return command;
 }
 
-struct PixelCopyGroups {
-  Vector<PixelCopyGroup> groups;
-
-  void copy_pixels(ImBuf &tile_buffer) const
-  {
-    if (tile_buffer.rect_float) {
-      ImageBufferAccessor<float4> accessor(tile_buffer);
-      copy_pixels<float4>(accessor);
-    }
-    else {
-      ImageBufferAccessor<int> accessor(tile_buffer);
-      copy_pixels<int>(accessor);
-    }
+void BKE_pbvh_pixels_copy_pixels(PBVH &pbvh,
+                                 Image &image,
+                                 ImageUser &image_user,
+                                 image::TileNumber tile_number)
+{
+  PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
+  std::optional<std::reference_wrapper<PixelCopyTile>> pixel_tile =
+      pbvh_data.tiles_copy_pixels.find_tile(tile_number);
+  if (!pixel_tile.has_value()) {
+    return;
   }
 
- private:
-  template<typename T> void copy_pixels(ImageBufferAccessor<T> &image_buffer) const
-  {
-    for (const PixelCopyGroup &group : groups) {
-      PixelCopyCommand copy_command(group);
-      for (const PixelCopyItem &item : group.items) {
-        copy_command += item;
-        copy_command.mix_source_and_write_destination<T>(image_buffer);
-      }
-    }
+  ImageUser tile_user = image_user;
+  tile_user.tile = tile_number;
+  ImBuf *tile_buffer = BKE_image_acquire_ibuf(&image, &tile_user, nullptr);
+  if (tile_buffer == nullptr) {
+    return;
   }
-};
+  pixel_tile->get().copy_pixels(*tile_buffer);
+
+  BKE_image_release_ibuf(&image, tile_buffer, nullptr);
+}
 
-}  // namespace blender::kernel::pbvh::pixels
+}  // namespace blender::bke::pbvh::pixels



More information about the Bf-blender-cvs mailing list