Commit: 7db0f4ae34da659c39c2cf1fe437d7e5616e6863 Author: Jeroen Bakker Date: Thu Jan 19 13:54:07 2023 +0100 Branches: temp-T101739-fix-seam-bleeding-non-manifold https://developer.blender.org/rB7db0f4ae34da659c39c2cf1fe437d7e5616e6863
Improved performance. =================================================================== M source/blender/blenkernel/BKE_pbvh_pixels.hh M source/blender/blenkernel/intern/pbvh_pixels_copy.cc =================================================================== diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index c40df2c8e50..f5d43710206 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -6,7 +6,7 @@ #include <functional> #include "BLI_math.h" -#include "BLI_math_vector_types.hh" +#include "BLI_math_vector.hh" #include "BLI_rect.h" #include "BLI_vector.hh" @@ -359,6 +359,21 @@ struct CopyPixelCommand { char2(next_command.source_2 - next_command.source_1), uint8_t(next_command.mix_factor * 255)); } + + bool can_be_extended(const CopyPixelCommand &command) const + { + /* Can only extend sequential pixels. */ + if (destination.x != command.destination.x - 1 || destination.y != command.destination.y) { + return false; + } + + /* Can only extend when the delta between with the previous source fits in a single byte.*/ + int2 delta_source_1 = source_1 - command.source_1; + if (max_ii(UNPACK2(blender::math::abs(delta_source_1))) > 127) { + return false; + } + return true; + } }; struct CopyPixelTile { diff --git a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc index c0e9bc91087..d4ab23c8dba 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc @@ -101,7 +101,6 @@ class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> { public: NonManifoldUVEdges(const uv_islands::MeshData &mesh_data) { - TIMEIT_START(det_edges); int num_non_manifold_edges = count_non_manifold_edges(mesh_data); reserve(num_non_manifold_edges); for (const int primitive_id : mesh_data.looptris.index_range()) { @@ -120,14 +119,12 @@ class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> { } BLI_assert_msg(size() == num_non_manifold_edges, "Incorrect number of non manifold edges added. "); - TIMEIT_END(det_edges); } NonManifoldTileEdges extract_tile_edges(const image::ImageTileWrapper image_tile, const int2 tile_resolution) const { NonManifoldTileEdges result; - TIMEIT_START(extract_edges); // TODO: Only add edges that intersects with the given tile. // TODO: Clamp edges to tile bounds. @@ -136,7 +133,6 @@ class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> { uv_edge, image_tile, tile_resolution); result.append(tile_edge); } - TIMEIT_END(extract_edges); return result; } @@ -180,7 +176,6 @@ class PixelNodesTileData : public Vector<std::reference_wrapper<UDIMTilePixels>> public: PixelNodesTileData(PBVH &pbvh, const image::ImageTileWrapper &image_tile) { - TIMEIT_START(pixel_nodes_tile_data); reserve(count_nodes(pbvh, image_tile)); for (PBVHNode &node : MutableSpan(pbvh.nodes, pbvh.totnode)) { @@ -190,7 +185,6 @@ class PixelNodesTileData : public Vector<std::reference_wrapper<UDIMTilePixels>> append(tile_pixels); } } - TIMEIT_END(pixel_nodes_tile_data); } private: @@ -231,7 +225,7 @@ struct Rows { Undecided, /** This pixel is directly affected by a brush and doesn't need to be solved. */ Brush, - Selected, + SelectedForCloserExamination, /** This pixel will be copid from another pixel to solve non-manifold edge bleeding. */ CopyFromClosestEdge, }; @@ -264,7 +258,7 @@ struct Rows { int2 resolution; int margin; - Vector<Pixel> pixels; + Array<Pixel> pixels; struct RowView { int row_number = 0; @@ -277,210 +271,6 @@ struct Rows { MutableSpan<Pixel>(&rows.pixels[row_number * rows.resolution.x], rows.resolution.x)) { } - - /** - * Look for a second source pixel that will be blended with the first source pixel to improve - * the quality of the fix. - * - * - The second source pixel must be a neighbour pixel of the first source, or the same as the - * first source when no second pixel could be found. - * - The second source pixel must be a pixel that is painted on by the brush. - * - The second source pixel must be the second closest pixel , or the first source - * when no second pixel could be found. - */ - int2 find_second_source(Rows &rows, int2 destination, int2 first_source) - { - rcti search_bounds; - BLI_rcti_init(&search_bounds, - max_ii(first_source.x - 1, 0), - min_ii(first_source.x + 1, rows.resolution.x - 1), - max_ii(first_source.y - 1, 0), - min_ii(first_source.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) + 1)) { - for (int sx : IndexRange(search_bounds.xmin, BLI_rcti_size_x(&search_bounds) + 1)) { - int2 source(sx, sy); - /* Skip first source as it should be the closest and already selected. */ - if (source == first_source) { - continue; - } - int pixel_index = sy * rows.resolution.y + sx; - if (rows.pixels[pixel_index].type != PixelType::Brush) { - continue; - } - - float new_distance = blender::math::distance(float2(destination), float2(source)); - if (new_distance < found_distance) { - found_distance = new_distance; - found_source = source; - } - } - } - return found_source; - } - - float determine_mix_factor(const int2 destination, - const int2 source_1, - const int2 source_2, - const Edge<CoordSpace::Tile> &edge) - { - /* Use stable result when both sources are the same. */ - if (source_1 == source_2) { - return 0.0f; - } - - float2 clamped_to_edge; - float destination_lambda = closest_to_line_v2(clamped_to_edge, - float2(destination), - edge.vertex_1.coordinate, - edge.vertex_2.coordinate); - float source_1_lambda = closest_to_line_v2( - clamped_to_edge, float2(source_1), edge.vertex_1.coordinate, edge.vertex_2.coordinate); - float source_2_lambda = closest_to_line_v2( - clamped_to_edge, float2(source_2), edge.vertex_1.coordinate, edge.vertex_2.coordinate); - - return clamp_f((destination_lambda - source_1_lambda) / (source_2_lambda - source_1_lambda), - 0.0f, - 1.0f); - } - - void find_copy_source(Rows &rows, const NonManifoldTileEdges &tile_edges) - { - for (int x : pixels.index_range()) { - Pixel &elem = pixels[x]; - /* Skip pixels that are not selected for evaluation. */ - if (elem.type != PixelType::Selected) { - continue; - } - - rcti bounds; - BLI_rcti_init(&bounds, x, x, row_number, row_number); - add_margin(bounds, rows.margin); - clamp(bounds, rows.resolution); - - float found_distance = std::numeric_limits<float>().max(); - int2 found_source(0); - - for (int sy : IndexRange(bounds.ymin, BLI_rcti_size_y(&bounds))) { - RowView row(rows, sy); - for (int sx : IndexRange(bounds.xmin, BLI_rcti_size_x(&bounds))) { - Pixel &source = row.pixels[sx]; - if (source.type != PixelType::Brush) { - continue; - } - float new_distance = blender::math::distance(float2(sx, sy), float2(x, row_number)); - if (new_distance < found_distance) { - found_source = int2(sx, sy); - found_distance = new_distance; - } - } - } - - if (found_distance == std::numeric_limits<float>().max()) { - continue; - } - elem.type = PixelType::CopyFromClosestEdge; - elem.distance = found_distance; - elem.copy_command.source_1 = found_source; - 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, - tile_edges[elem.edge_index]); - } - } - - static bool can_extend_last_group(const CopyPixelTile &tile_pixels, - const CopyPixelCommand &command) - { - if (tile_pixels.groups.is_empty()) { - return false; - } - const CopyPixelGroup &group = tile_pixels.groups.last(); - CopyPixelCommand last_command = last_copy_command(tile_pixels, group); - /* Can only extend when pushing the next pixel. */ - if (last_command.destination.x != command.destination.x - 1 || - last_command.destination.y != command.destination.y) { - return false; - } - /* Can only extend when */ - int2 delta_source_1 = last_command.source_1 - command.source_1; - if (max_ii(UNPACK2(blender::math::abs(delta_source_1))) > 127) { - return false; - } - return true; - } - - static void extend_last_group(CopyPixelTile &tile_pixels, const CopyPixelCommand &command) - { - CopyPixelGroup &group = tile_pixels.groups.last(); - CopyPixelCommand last_command = last_copy_command(tile_pixels, group); - DeltaCopyPixelCommand delta_command = last_command.encode_delta(command); - tile_pixels.command_deltas.append(delta_command); - group.num_deltas += 1; - -#ifndef NDEBUG - @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs