[Bf-blender-cvs] [54bd4f31371] temp-T101739-fix-seam-bleeding-non-manifold: Performance improvement: only evaluate pixels that are near non-manifold areas.
Jeroen Bakker
noreply at git.blender.org
Tue Jan 10 14:19:59 CET 2023
Commit: 54bd4f3137126cc61f166e19f3d2d0f46e617b5f
Author: Jeroen Bakker
Date: Tue Jan 10 14:14:24 2023 +0100
Branches: temp-T101739-fix-seam-bleeding-non-manifold
https://developer.blender.org/rB54bd4f3137126cc61f166e19f3d2d0f46e617b5f
Performance improvement: only evaluate pixels that are near non-manifold areas.
===================================================================
M source/blender/blenkernel/intern/pbvh_pixels_copy.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
index dc66405adda..30da7c64cca 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
@@ -205,6 +205,7 @@ struct Rows {
Brush,
/** This pixel will be copid from another pixel to solve non-manifold edge bleeding. */
CopyFromClosestEdge,
+ Selected,
};
struct Elem {
@@ -260,14 +261,12 @@ struct Rows {
}
}
- void determine_copy_pixels(const NonManifoldTileEdges &tile_edges,
- int search_margin,
- const int2 tile_resolution)
+ void mark_for_evaluation(const Rows &rows, const NonManifoldTileEdges &tile_edges)
{
for (const Edge<CoordSpace::Tile> &tile_edge : tile_edges) {
rcti edge_bounds = get_bounds(tile_edge);
- add_margin(edge_bounds, search_margin);
- clamp(edge_bounds, tile_resolution);
+ add_margin(edge_bounds, rows.margin);
+ clamp(edge_bounds, rows.resolution);
if (edge_bounds.ymax < row_number) {
continue;
@@ -282,24 +281,22 @@ struct Rows {
case PixelType::Brush: {
break;
}
- case PixelType::Undecided:
case PixelType::CopyFromClosestEdge: {
+ BLI_assert_unreachable();
+ break;
+ }
+ case PixelType::Selected: {
+ break;
+ }
+ case PixelType::Undecided: {
const float2 point(pixel.copy_command.destination);
float2 closest_edge_point;
closest_to_line_v2(closest_edge_point, point, tile_edge.v1.co, tile_edge.v2.co);
float distance_to_edge = blender::math::distance_squared(closest_edge_point, point);
- if (distance_to_edge > pixel.distance) {
+ if (distance_to_edge > rows.margin) {
break;
}
-
- // TODO:
- // Find upto 2 valid pixels to copy from.
- // Determine the mix factor between the two pixels
- // Store result in the pixel.command.
-
- pixel.distance = distance_to_edge;
- pixel.type = PixelType::CopyFromClosestEdge;
-
+ pixel.type = PixelType::Selected;
break;
}
}
@@ -307,12 +304,50 @@ struct Rows {
}
}
- void solution2(Rows &rows, int margin)
+ int2 find_second_source(Rows &rows, int2 destination, int2 first_source)
+ {
+ rcti search_bounds;
+ BLI_rcti_init(&search_bounds,
+ max_ii(destination.x - 1, 0),
+ min_ii(destination.x + 1, rows.resolution.x - 1),
+ max_ii(destination.y - 1, 0),
+ min_ii(destination.y + 1, rows.resolution.y - 1));
+ /* Initialize to the first source, so when no other source could be found it will use the
+ * first_source. */
+ int2 found_source = first_source;
+ float found_distance = std::numeric_limits<float>().max();
+ for (int sy : IndexRange(search_bounds.ymin, BLI_rcti_size_y(&search_bounds))) {
+ for (int sx : IndexRange(search_bounds.xmin, BLI_rcti_size_x(&search_bounds))) {
+ int2 source(sx, sy);
+ /* Skip first source as it should be the closest and already selected. */
+ if (source == first_source) {
+ continue;
+ }
+ if (rows.rows[sy].pixels[sx].type != PixelType::Brush) {
+ continue;
+ }
+
+ float new_distance = blender::math::distance(destination, source);
+ if (new_distance < found_distance) {
+ found_distance = new_distance;
+ found_source = source;
+ }
+ }
+ }
+ return found_source;
+ }
+
+ float determine_mix_factor(int2 destination, int2 source_1, int2 source_2)
+ {
+ return dist_to_line_segment_v2(float2(destination), float2(source_1), float2(source_2));
+ }
+
+ void find_copy_source(Rows &rows, int margin)
{
for (int x : pixels.index_range()) {
Elem &elem = pixels[x];
- /* Skip pixels that already used directly via a brush. */
- if (elem.type == PixelType::Brush) {
+ /* Skip pixels that are not selected for evaluation. */
+ if (elem.type != PixelType::Selected) {
continue;
}
@@ -345,9 +380,10 @@ struct Rows {
elem.type = PixelType::CopyFromClosestEdge;
elem.distance = found_distance;
elem.copy_command.source_1 = found_source;
- // TODO: find second source by looking at neighbouring pixels of source_1.
- elem.copy_command.source_2 = found_source;
- elem.copy_command.mix_factor = 0.0f;
+ elem.copy_command.source_2 = find_second_source(
+ rows, elem.copy_command.destination, found_source);
+ elem.copy_command.mix_factor = determine_mix_factor(
+ elem.copy_command.destination, elem.copy_command.source_1, elem.copy_command.source_2);
}
}
@@ -418,9 +454,24 @@ struct Rows {
void find_copy_source(int margin)
{
for (Row &row : rows) {
- row.solution2(*this, margin);
+ row.find_copy_source(*this, margin);
+ }
+ }
+
+ void mark_for_evaluation(const NonManifoldTileEdges &tile_edges)
+ {
+ for (Row &row : rows) {
+ row.mark_for_evaluation(*this, tile_edges);
}
}
+
+ void pack_into(Vector<PixelCopyGroup> &groups) const
+ {
+ for (const Row &row : rows) {
+ row.pack_into(groups);
+ }
+ }
+
}; // namespace blender::bke::pbvh::pixels
static void copy_pixels_reinit(PixelCopyTiles &tiles)
@@ -460,14 +511,9 @@ void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
PixelCopyTile copy_tile(image_tile.get_tile_number());
Rows rows(tile_resolution, image.seam_margin, nodes_tile_pixels);
+ rows.mark_for_evaluation(tile_edges);
rows.find_copy_source(image.seam_margin);
-
- for (int y = 0; y < tile_resolution.y; y++) {
- Rows::Row &row = rows.rows[y];
- // row.determine_copy_pixels(tile_edges, image.seam_margin, tile_resolution);
- row.pack_into(copy_tile.groups);
- }
-
+ rows.pack_into(copy_tile.groups);
pbvh_data.tiles_copy_pixels.tiles.append(copy_tile);
}
}
More information about the Bf-blender-cvs
mailing list