[Bf-blender-cvs] [bfb9faaded1] temp-T96710-pbvh-pixels: Extend seams in x direction.
Jeroen Bakker
noreply at git.blender.org
Fri Apr 8 11:07:50 CEST 2022
Commit: bfb9faaded1747bc1ccfd37816cfa38634692412
Author: Jeroen Bakker
Date: Fri Apr 8 11:07:32 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rBbfb9faaded1747bc1ccfd37816cfa38634692412
Extend seams in x direction.
===================================================================
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 f598d9da58a..05ff9a53199 100644
--- a/source/blender/blenkernel/BKE_pbvh.hh
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -49,6 +49,18 @@ class BarycentricWeights {
return BarycentricWeights(weights + rhs);
}
+ BarycentricWeights &operator-=(const float3 &rhs)
+ {
+ weights -= rhs;
+ return *this;
+ }
+
+ BarycentricWeights &operator+=(const float3 &rhs)
+ {
+ weights += rhs;
+ return *this;
+ }
+
operator const float *() const
{
return weights;
@@ -116,6 +128,7 @@ struct Triangle {
struct TrianglePaintInput {
int3 vert_indices;
float3 add_barycentric_coord_x;
+ float3 add_barycentric_coord_y;
TrianglePaintInput(const Triangle &triangle)
: vert_indices(triangle.vert_indices),
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 30da876391a..b7badb5674d 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -22,6 +22,8 @@
namespace blender::bke::pbvh::pixels::extractor {
+#define DO_WATERTIGHT_CHECK
+
/**
* Keep track of visited polygons.
*
@@ -49,10 +51,10 @@ class VisitedPolygons : std::vector<bool> {
/**
* @brief Calculate the delta of two neighbour uv coordinates in the given image buffer.
*/
-static float3 calc_barycentric_delta(const ImBuf *image_buffer,
- const float2 uvs[3],
- const int x,
- const int y)
+static float3 calc_barycentric_delta_x(const ImBuf *image_buffer,
+ const float2 uvs[3],
+ const int x,
+ const int y)
{
const float2 start_uv(float(x) / image_buffer->x, float(y) / image_buffer->y);
const float2 end_uv(float(x + 1) / image_buffer->x, float(y) / image_buffer->y);
@@ -62,6 +64,19 @@ static float3 calc_barycentric_delta(const ImBuf *image_buffer,
return delta_barycentric;
}
+static float3 calc_barycentric_delta_y(const ImBuf *image_buffer,
+ const float2 uvs[3],
+ const int x,
+ const int y)
+{
+ const float2 start_uv(float(x) / image_buffer->x, float(y) / image_buffer->y);
+ const float2 end_uv(float(x) / image_buffer->x, float(y + 1) / image_buffer->y);
+ const BarycentricWeights start_barycentric(uvs[0], uvs[1], uvs[2], start_uv);
+ const BarycentricWeights end_barycentric(uvs[0], uvs[1], uvs[2], end_uv);
+ const float3 delta_barycentric = end_barycentric - start_barycentric;
+ return delta_barycentric;
+}
+
static void extract_barycentric_pixels(TileData &tile_data,
const ImBuf *image_buffer,
const int triangle_index,
@@ -179,7 +194,8 @@ static void do_encode_pixels(void *__restrict userdata,
const int maxx = min_ii(ceil(maxu * image_buffer->x), image_buffer->x);
TrianglePaintInput &triangle = triangles.get_paint_input(triangle_index);
- triangle.add_barycentric_coord_x = calc_barycentric_delta(image_buffer, uvs, minx, miny);
+ triangle.add_barycentric_coord_x = calc_barycentric_delta_x(image_buffer, uvs, minx, miny);
+ triangle.add_barycentric_coord_y = calc_barycentric_delta_y(image_buffer, uvs, minx, miny);
extract_barycentric_pixels(
tile_data, image_buffer, triangle_index, uvs, minx, miny, maxx, maxy);
}
@@ -290,6 +306,56 @@ static bool find_nodes_to_update(PBVH *pbvh,
return true;
}
+/** Durind debugging this check could be enabled. It will write to each image pixel that is covered
+ * by the pbvh. */
+constexpr bool do_watertight_check()
+{
+ return false;
+}
+
+static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_user)
+{
+ 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) {
+ image_buffer->rect_float[pixel_offset * 4] += 0.5;
+ // 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);
+}
+
static void update_pixels(PBVH *pbvh,
const MeshElemMap *pmap,
const struct MPoly *mpoly,
@@ -325,7 +391,13 @@ 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 (do_watertight_check()) {
+ apply_watertight_check(pbvh, image, image_user);
+ }
+ BKE_pbvh_pixels_fix_seams(*pbvh, *image, *image_user);
+ if (do_watertight_check()) {
+ apply_watertight_check(pbvh, image, image_user);
+ }
/* Clear the UpdatePixels flag. */
for (PBVHNode *node : nodes_to_update) {
@@ -358,49 +430,6 @@ static void update_pixels(PBVH *pbvh,
float(compressed_data_len) / num_pixels);
}
#endif
-
-#define DO_WATERTIGHT_CHECK
-#ifdef DO_WATERTIGHT_CHECK
- 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
}
} // namespace blender::bke::pbvh::pixels::extractor
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index 9fe945e476c..423fa90869a 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -22,12 +22,46 @@ struct UVSeamExtenderRowPackage {
{
}
+ /**
+ * Check if any of the corners of the extended pixels is inside the triangle. In this case we
+ * should extend.
+ *
+ * This could be improved by using the triangle uv coordinates and using triangle intersection in
+ * UV space. Currently it can fail near the triangle vertices based on how the triangulation
+ * happens.
+ */
+ bool should_extend_start() const
+ {
+ BarycentricWeights weights = package->start_barycentric_coord.decode();
+ return (weights.is_inside_triangle() ||
+ (weights + triangle_paint_data->add_barycentric_coord_y).is_inside_triangle());
+ }
+
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);
}
+
+ bool should_extend_end() const
+ {
+ BarycentricWeights weights = package->start_barycentric_coord.decode();
+ weights += triangle_paint_data->add_barycentric_coord_x * package->num_pixels;
+ if (weights.is_inside_triangle()) {
+ return true;
+ }
+ weights += triangle_paint_data->add_barycentric_coord_y;
+ if (weights.is_inside_triangle()) {
+ return true;
+ }
+ return false;
+ }
+
+ void extend_x_end()
+ {
+ package->num_pixels += 1;
+ }
};
class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
@@ -41,18 +75,29 @@ class UVSeamExtenderRow : public Vector<UVSeamExtenderRowPackage> {
Vector<UVSeamExtenderRowPackage>::append(package);
}
- void extend_x()
+ void extend_x(int image_buffer_width)
{
std::sort(
begin(), end(), [](const UVSeamExtender
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list