[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