[Bf-blender-cvs] [ab6c400d149] temp-T96710-pbvh-pixels: Extending using line segment intersection.
Jeroen Bakker
noreply at git.blender.org
Fri Apr 8 14:53:29 CEST 2022
Commit: ab6c400d149f4539e5d8ddbfe59b78c330daa776
Author: Jeroen Bakker
Date: Fri Apr 8 14:53:12 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rBab6c400d149f4539e5d8ddbfe59b78c330daa776
Extending using line segment intersection.
===================================================================
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 05ff9a53199..42f745890bd 100644
--- a/source/blender/blenkernel/BKE_pbvh.hh
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -8,6 +8,7 @@
#include "BLI_vector.hh"
#include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
#include "BKE_image.h"
#include "BKE_image_wrappers.hh"
@@ -183,11 +184,6 @@ struct Triangles {
return paint_input[index];
}
- void cleanup_after_init()
- {
- loop_indices.clear();
- }
-
void clear()
{
paint_input.clear();
@@ -306,6 +302,9 @@ TileData *BKE_pbvh_pixels_tile_data_get(PBVHNode &node, const image::ImageTileWr
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);
+void BKE_pbvh_pixels_fix_seams(PBVH &pbvh,
+ Image &image,
+ ImageUser &image_user,
+ const MLoopUV *ldata_uv);
} // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 05a44f8aa04..57259973438 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -25,6 +25,7 @@ namespace blender::bke::pbvh::pixels::extractor {
/** Durind debugging this check could be enabled. It will write to each image pixel that is covered
* by the pbvh. */
constexpr bool USE_WATERTIGHT_CHECK = false;
+constexpr bool USE_WATERTIGHT_SEAM_CHECK = true;
/**
* Keep track of visited polygons.
@@ -212,8 +213,6 @@ static void do_encode_pixels(void *__restrict userdata,
tile_data.packages.sort();
node_data->tiles.append(tile_data);
}
-
- node_data->triangles.cleanup_after_init();
}
static bool should_pixels_be_updated(PBVHNode *node)
@@ -334,7 +333,12 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us
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 (USE_WATERTIGHT_SEAM_CHECK) {
+ image_buffer->rect_float[pixel_offset * 4] += 0.5;
+ }
+ else {
+ copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
+ }
}
if (image_buffer->rect) {
uint8_t *dest = static_cast<uint8_t *>(
@@ -385,7 +389,10 @@ 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 (USE_WATERTIGHT_CHECK && USE_WATERTIGHT_SEAM_CHECK) {
+ apply_watertight_check(pbvh, image, image_user);
+ }
+ BKE_pbvh_pixels_fix_seams(*pbvh, *image, *image_user, ldata_uv);
if (USE_WATERTIGHT_CHECK) {
apply_watertight_check(pbvh, image, image_user);
}
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index 694299062cd..ad5b12edfe2 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -6,9 +6,43 @@
#include "pbvh_intern.h"
+#include "BLI_math_geom.h"
+
namespace blender::bke::pbvh::pixels {
using namespace blender::bke::image;
+bool intersect_uv_pixel(const ushort2 &pixel_coordinate,
+ const ImBuf &image_buffer,
+ const float2 triangle_uvs[3])
+{
+
+ float2 uv_bottom_left = float2(pixel_coordinate.x / float(image_buffer.x),
+ pixel_coordinate.y / float(image_buffer.y));
+ float2 uv_top_right = float2((pixel_coordinate.x + 1) / float(image_buffer.x),
+ (pixel_coordinate.y + 1) / float(image_buffer.y));
+ float2 uv_bottom_right(uv_top_right[0], uv_bottom_left[1]);
+ float2 uv_top_left(uv_bottom_left[0], uv_top_right[1]);
+
+ return (isect_seg_seg_v2_simple(
+ uv_bottom_left, uv_bottom_right, triangle_uvs[0], triangle_uvs[1]) ||
+ isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[0], triangle_uvs[1]) ||
+ isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[0], triangle_uvs[1]) ||
+ isect_seg_seg_v2_simple(
+ uv_bottom_right, uv_top_right, triangle_uvs[0], triangle_uvs[1])) ||
+ (isect_seg_seg_v2_simple(
+ uv_bottom_left, uv_bottom_right, triangle_uvs[1], triangle_uvs[2]) ||
+ isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[1], triangle_uvs[2]) ||
+ isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[1], triangle_uvs[2]) ||
+ isect_seg_seg_v2_simple(
+ uv_bottom_right, uv_top_right, triangle_uvs[1], triangle_uvs[2])) ||
+ (isect_seg_seg_v2_simple(
+ uv_bottom_left, uv_bottom_right, triangle_uvs[2], triangle_uvs[0]) ||
+ isect_seg_seg_v2_simple(uv_bottom_left, uv_top_left, triangle_uvs[2], triangle_uvs[0]) ||
+ isect_seg_seg_v2_simple(uv_top_left, uv_top_right, triangle_uvs[2], triangle_uvs[0]) ||
+ isect_seg_seg_v2_simple(
+ uv_bottom_right, uv_top_right, triangle_uvs[2], triangle_uvs[0]));
+}
+
struct UVSeamExtenderRowPackage {
/** Amount of pixels to extend beyond the determined extension to reduce rendering artifacts. */
static const int ADDITIONAL_EXTEND_X = 1;
@@ -21,10 +55,13 @@ struct UVSeamExtenderRowPackage {
UVSeamExtenderRowPackage(PixelsPackage *package,
TrianglePaintInput *triangle_paint_data,
- bool is_new)
+ const ImBuf &image_buffer,
+ bool is_new,
+ const int3 loop_indices,
+ const MLoopUV *ldata_uv)
: package(package), triangle_paint_data(triangle_paint_data), is_new(is_new)
{
- init_extend_x_len();
+ init_extend_x_len(image_buffer, loop_indices, ldata_uv);
}
bool should_extend_start() const
@@ -54,56 +91,59 @@ struct UVSeamExtenderRowPackage {
}
private:
- void init_extend_x_len()
+ void init_extend_x_len(const ImBuf &image_buffer,
+ const int3 loop_indices,
+ const MLoopUV *ldata_uv)
{
if (!is_new) {
return;
}
- init_extend_xmin_len();
- init_extend_xmax_len();
+ float2 triangle_uvs[3];
+ triangle_uvs[0] = ldata_uv[loop_indices[0]].uv;
+ triangle_uvs[1] = ldata_uv[loop_indices[1]].uv;
+ triangle_uvs[2] = ldata_uv[loop_indices[2]].uv;
+
+ init_extend_xmin_len(image_buffer, triangle_uvs);
+ init_extend_xmax_len(image_buffer, triangle_uvs);
BLI_assert(extend_xmin_len);
BLI_assert(extend_xmax_len);
}
- void init_extend_xmin_len()
+ void init_extend_xmin_len(const ImBuf &image_buffer, const float2 triangle_uvs[3])
{
int result = 0;
- while (should_extend_xmin(result)) {
+ while (should_extend_xmin(image_buffer, result, triangle_uvs)) {
result++;
}
extend_xmin_len = result + ADDITIONAL_EXTEND_X;
}
- bool should_extend_xmin(int offset) const
+ bool should_extend_xmin(const ImBuf &image_buffer,
+ int offset,
+ const float2 triangle_uvs[3]) const
{
- BarycentricWeights weights = package->start_barycentric_coord.decode();
- weights -= triangle_paint_data->add_barycentric_coord_x * offset;
- return (weights.is_inside_triangle() ||
- (weights + triangle_paint_data->add_barycentric_coord_y).is_inside_triangle());
+ uint16_t pixel_offset = offset + 1;
+ ushort2 pixel = package->start_image_coordinate - ushort2(pixel_offset, 0);
+ return intersect_uv_pixel(pixel, image_buffer, triangle_uvs);
}
- void init_extend_xmax_len()
+ void init_extend_xmax_len(const ImBuf &image_buffer, const float2 triangle_uvs[3])
{
int result = 0;
- while (should_extend_xmax(result)) {
+ while (should_extend_xmax(image_buffer, result, triangle_uvs)) {
result++;
}
extend_xmax_len = result + ADDITIONAL_EXTEND_X;
}
- bool should_extend_xmax(int offset) const
+ bool should_extend_xmax(const ImBuf &image_buffer,
+ int offset,
+ const float2 triangle_uvs[3]) const
{
- BarycentricWeights weights = package->start_barycentric_coord.decode();
- weights += triangle_paint_data->add_barycentric_coord_x * (package->num_pixels + offset);
- if (weights.is_inside_triangle()) {
- return true;
- }
- weights += triangle_paint_data->add_barycentric_coord_y;
- if (weights.is_inside_triangle()) {
- return true;
- }
- return false;
+ uint16_t pixel_offset = offset + 1;
+ ushort2 pixel = package->start_image_coordinate + ushort2(pixel_offset, 0);
+ return intersect_uv_pixel(pixel, image_buffer, triangle_uvs);
}
};
@@ -183,11 +223,14 @@ class UVSeamExtender {
int image_buffer_width_;
public:
- explicit UVSeamExtender(PBVH &pbvh, ImageTileWrapper &image_tile, ImBuf &image_buffer)
+ explicit UVSeamExtender(PBVH &pbvh,
+ const ImageTileWrapper &image_tile,
+ const ImBuf &image_buffer,
+ const MLoopUV *ldata_uv)
: image_buffer_width_(image_buffer.x)
{
rows.resize(image_buffer.y);
- init(pbvh, image_tile);
+ init(pbvh, image_tile, image_buffer, ldata_uv);
}
void extend_x()
@@ -200,34 +243,47 @@ class UVSeamExtender {
}
private:
- void init(PBVH &pbvh, ImageTileWrapper &image_tile)
+ void init(PBVH &pbvh,
+ const ImageTileWrapper &image_tile,
+ const Im
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list