[Bf-blender-cvs] [2e046183a2a] temp-T97352-3d-texturing-seam-bleeding: Use source blending with a mask.
Jeroen Bakker
noreply at git.blender.org
Wed May 4 18:47:57 CEST 2022
Commit: 2e046183a2a9cb8cc4477d4cecbe13312fe8cd41
Author: Jeroen Bakker
Date: Wed May 4 18:47:30 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding
https://developer.blender.org/rB2e046183a2a9cb8cc4477d4cecbe13312fe8cd41
Use source blending with a mask.
===================================================================
M source/blender/blenkernel/BKE_pbvh_pixels.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_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index 6d4f5db819c..2786a57d118 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -132,15 +132,21 @@ struct UDIMTilePixels {
}
};
-struct SeamFix {
+struct SeamFixCopy {
int2 src_pixel;
int2 dst_pixel;
};
+struct SeamFixBlend {
+ float2 src_pixel;
+ int2 dst_pixel;
+ char src_bit_mask;
+};
struct UDIMSeamFixes {
uint16_t src_tile_number;
uint16_t dst_tile_number;
- Vector<SeamFix> pixels;
+ Vector<SeamFixCopy> pixels_to_copy;
+ Vector<SeamFixBlend> pixels_to_blend;
UDIMSeamFixes(uint16_t src_tile_number, uint16_t dst_tile_number)
: src_tile_number(src_tile_number), dst_tile_number(dst_tile_number)
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index a8a8a1c9325..31e1c17184f 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -275,7 +275,19 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us
if (fixes.dst_tile_number != image_tile.get_tile_number()) {
continue;
}
- for (SeamFix &fix : fixes.pixels) {
+ for (SeamFixCopy &fix : fixes.pixels_to_copy) {
+ int pixel_offset = fix.dst_pixel.y * image_buffer->x + fix.dst_pixel.x;
+ if (image_buffer->rect_float != nullptr) {
+ copy_v4_fl4(&image_buffer->rect_float[pixel_offset * 4], 1.0f, 0.0f, 0.0f, 1.0f);
+ }
+ else if (image_buffer->rect != nullptr) {
+ uint8_t *dest = static_cast<uint8_t *>(
+ static_cast<void *>(&image_buffer->rect[pixel_offset]));
+ static uint8_t seam_color[] = {255, 0, 0, 255};
+ copy_v4_v4_uchar(dest, seam_color);
+ }
+ }
+ for (SeamFixBlend &fix : fixes.pixels_to_blend) {
int pixel_offset = fix.dst_pixel.y * image_buffer->x + fix.dst_pixel.x;
if (image_buffer->rect_float != nullptr) {
copy_v4_fl4(&image_buffer->rect_float[pixel_offset * 4], 1.0f, 0.0f, 0.0f, 1.0f);
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index c598a10f17c..f23ff555bd4 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -183,6 +183,18 @@ struct Bitmap {
return bitmap[offset];
}
+ const PixelInfo &get_pixel_info_safe(int2 image_coordinate) const
+ {
+ static PixelInfo coordinate_out_of_bounds_result;
+ if (image_coordinate.x < 0 || image_coordinate.y < 0 || image_coordinate.x >= resolution.x ||
+ image_coordinate.y >= resolution.y) {
+ return coordinate_out_of_bounds_result;
+ }
+
+ int offset = image_coordinate.y * resolution.x + image_coordinate.x;
+ return bitmap[offset];
+ }
+
bool contains(const float2 &uv) const
{
int2 tile_offset = image_tile.get_tile_offset();
@@ -311,7 +323,19 @@ static void add_seam_fix(PBVHNode &node,
{
NodeData &node_data = BKE_pbvh_pixels_node_data_get(node);
UDIMSeamFixes &seam_fixes = node_data.ensure_seam_fixes(src_tile_number, dst_tile_number);
- seam_fixes.pixels.append(SeamFix{src_pixel, dst_pixel});
+ seam_fixes.pixels_to_copy.append(SeamFixCopy{src_pixel, dst_pixel});
+}
+
+static void add_seam_fix(PBVHNode &node,
+ uint16_t src_tile_number,
+ float2 src_pixel,
+ char src_bit_mask,
+ uint16_t dst_tile_number,
+ int2 dst_pixel)
+{
+ NodeData &node_data = BKE_pbvh_pixels_node_data_get(node);
+ UDIMSeamFixes &seam_fixes = node_data.ensure_seam_fixes(src_tile_number, dst_tile_number);
+ seam_fixes.pixels_to_blend.append(SeamFixBlend{src_pixel, dst_pixel, src_bit_mask});
}
/* -------------------------------------------------------------------- */
@@ -321,9 +345,10 @@ static void add_seam_fix(PBVHNode &node,
struct Projection {
const Bitmap *bitmap;
- int2 pixel;
- PixelInfo pixel_info;
- bool is_valid;
+ int node_index;
+ float2 pixel;
+ char bit_mask;
+ float score;
};
/*
@@ -338,7 +363,9 @@ static void find_projection_source(const Bitmaps &bitmaps,
const float scale_factor,
Projection &r_projection)
{
- r_projection.is_valid = false;
+ r_projection.bit_mask = 0;
+ r_projection.score = 0;
+ r_projection.node_index = -1;
float2 closest_point;
interp_v2_v2v2(closest_point, uv1.uv, uv2.uv, lambda);
@@ -361,9 +388,49 @@ static void find_projection_source(const Bitmaps &bitmaps,
float2 projected_coord = closest_point + perpedicular * distance_to_edge * scale_factor;
projected_coord.x *= r_projection.bitmap->resolution.x;
projected_coord.y *= r_projection.bitmap->resolution.y;
- r_projection.pixel = find_source_pixel(*r_projection.bitmap, projected_coord);
- r_projection.pixel_info = r_projection.bitmap->get_pixel_info(r_projection.pixel);
- r_projection.is_valid = r_projection.pixel_info.is_extracted();
+ r_projection.pixel = projected_coord;
+
+ /* Check neighbouring pixels and extract mask. Pixels should be part of the same node. */
+ int2 pixel(std::floor(projected_coord.x), std::floor(projected_coord.y));
+ PixelInfo pixel_info = r_projection.bitmap->get_pixel_info_safe(pixel);
+ int node_index = pixel_info.get_node_index();
+ if (pixel_info.is_extracted() &&
+ (r_projection.node_index == -1 || r_projection.node_index == node_index)) {
+ r_projection.bit_mask |= 1;
+ r_projection.score += 1.0;
+ r_projection.node_index = node_index;
+ }
+
+ pixel.x += 1;
+ pixel_info = r_projection.bitmap->get_pixel_info_safe(pixel);
+ node_index = pixel_info.get_node_index();
+ if (pixel_info.is_extracted() &&
+ (r_projection.node_index == -1 || r_projection.node_index == node_index)) {
+ r_projection.bit_mask |= 2;
+ r_projection.score += 1.0;
+ r_projection.node_index = node_index;
+ }
+
+ pixel.x -= 1;
+ pixel.y += 1;
+ pixel_info = r_projection.bitmap->get_pixel_info_safe(pixel);
+ node_index = pixel_info.get_node_index();
+ if (pixel_info.is_extracted() &&
+ (r_projection.node_index == -1 || r_projection.node_index == node_index)) {
+ r_projection.bit_mask |= 4;
+ r_projection.score += 1.0;
+ r_projection.node_index = node_index;
+ }
+
+ pixel.x += 1;
+ pixel_info = r_projection.bitmap->get_pixel_info_safe(pixel);
+ node_index = pixel_info.get_node_index();
+ if (pixel_info.is_extracted() &&
+ (r_projection.node_index == -1 || r_projection.node_index == node_index)) {
+ r_projection.bit_mask |= 8;
+ r_projection.score += 1.0;
+ r_projection.node_index = node_index;
+ }
}
static void build_fixes(PBVH &pbvh,
@@ -414,25 +481,25 @@ static void build_fixes(PBVH &pbvh,
continue;
}
- Projection solution;
+ Projection solution1;
+ Projection solution2;
find_projection_source(
- bitmaps, distance_to_edge, lambda, luv_b_1, luv_b_2, scale_factor, solution);
- if (!solution.is_valid) {
- find_projection_source(
- bitmaps, distance_to_edge, 1.0f - lambda, luv_b_2, luv_b_1, scale_factor, solution);
- }
- if (!solution.is_valid) {
+ bitmaps, distance_to_edge, lambda, luv_b_1, luv_b_2, scale_factor, solution1);
+ find_projection_source(
+ bitmaps, distance_to_edge, 1.0f - lambda, luv_b_2, luv_b_1, scale_factor, solution2);
+ if (solution1.score == 0.0 && solution2.score == 0.0) {
/* No solution found skip this pixel. */
continue;
}
+ Projection &best_solution = solution1.score > solution2.score ? solution1 : solution2;
int2 destination_pixel(u, v);
- int src_node = solution.pixel_info.get_node_index();
-
+ int src_node = best_solution.node_index;
PBVHNode &node = pbvh.nodes[src_node];
add_seam_fix(node,
- solution.bitmap->image_tile.get_tile_number(),
- solution.pixel,
+ best_solution.bitmap->image_tile.get_tile_number(),
+ best_solution.pixel,
+ best_solution.bit_mask,
bitmap.image_tile.get_tile_number(),
destination_pixel);
bitmap.mark_seam_fix(destination_pixel);
@@ -615,6 +682,45 @@ void BKE_pbvh_pixels_rebuild_seams(
build_fixes(*pbvh, unconnected, bitmaps, ldata_uv, image->seamfix_distance);
}
+static float4 blend_source(ImBuf *src_image_buffer, float2 src_coordinate, char src_bit_mask)
+{
+ int2 src_pixel(std::floor(src_coordinate.x), std::floor(src_coordinate.y));
+ int src_offset = src_pixel.y * src_image_buffer->x + src_pixel.x;
+ float2 frac(src_coordinate.x - src_pixel.x, src_coordinate.y - src_pixel.y);
+ float4 color(0.0f, 0.0f, 0.0f, 0.0f);
+ float sum_factor = 0.0f;
+ if (src_bit_mask & 1) {
+ float4 c1(src_image_buffer->rect_float[src_offset * 4]);
+ float f1 = std::sqrt(std::pow(1.0f - frac.x, 2)) + std::pow(1.0f - frac.y, 2);
+ color = color + c1 * f1;
+ sum_factor += f1;
+ }
+ if (src_bit_mask & 2) {
+ float4 c2(src_image_buffer->rect_float[(src_offset + 1) * 4]);
+ float f2 = std::sqrt(std::pow(frac.x, 2)) + std::pow(1.0f - frac.y, 2);
+ color = color + c2 * f2;
+ sum_factor += f2;
+ }
+ if (src_bit_mask & 4) {
+ float4 c3(src_image_buffer->rect_float[(src_offset + src_image_buffer->x) * 4]);
+ float f3 = std::sqrt(std::pow(1.0 - frac.x, 2)) + std::pow(frac.y, 2);
+ color = color + c3 * f3;
+ sum_factor += f3;
+ }
+ if (src_bit_mask & 8) {
+ float4 c4(src_image_buffer->rect_float[(src_offset + src_image_buffer->x + 1) * 4]);
+ float f4 = std::sqrt(std::pow(frac.x, 2)) + std::pow(frac.y, 2);
+ color = color + c4 * f4;
+ sum_factor += f4;
+ }
+ color.x /= sum_factor;
+ color.y /= sum_factor;
+ color.z /= sum_factor;
+ color.w = 1.0f;
+
+ return color;
+}
+
void BKE_pbvh_pixels_fix_seams(PBVHNode *node, Image *image, ImageUser
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list