[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