[Bf-blender-cvs] [bf70ba2efc4] temp-T101739-fix-seam-bleeding-non-manifold: Use correct bounds.
Jeroen Bakker
noreply at git.blender.org
Tue Jan 10 14:19:58 CET 2023
Commit: bf70ba2efc4bb5b8f50297bc21263f7e223a3d65
Author: Jeroen Bakker
Date: Tue Jan 10 10:47:40 2023 +0100
Branches: temp-T101739-fix-seam-bleeding-non-manifold
https://developer.blender.org/rBbf70ba2efc4bb5b8f50297bc21263f7e223a3d65
Use correct bounds.
===================================================================
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 c4ea851ad9a..dfe716ffc6a 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc
@@ -4,7 +4,7 @@
#include "BLI_array.hh"
#include "BLI_bit_vector.hh"
#include "BLI_math.h"
-#include "BLI_math_vector_types.hh"
+#include "BLI_math_vector.hh"
#include "BLI_vector.hh"
#include "IMB_imbuf.h"
@@ -34,6 +34,49 @@ template<CoordSpace Space> struct Edge {
Vertex<Space> v2;
};
+rcti get_bounds(const Edge<CoordSpace::Tile> &tile_edge)
+{
+ rcti bounds;
+ BLI_rcti_init_minmax(&bounds);
+ BLI_rcti_do_minmax_v(&bounds, int2(tile_edge.v1.co));
+ BLI_rcti_do_minmax_v(&bounds, int2(tile_edge.v2.co));
+ return bounds;
+}
+
+void add_margin(rcti &bounds, int margin)
+{
+ bounds.xmin -= margin;
+ bounds.xmax += margin;
+ bounds.ymin -= margin;
+ bounds.ymax += margin;
+}
+
+void clamp(rcti &bounds, int2 resolution)
+{
+ rcti clamping_bounds;
+ int2 xy;
+ BLI_rcti_init(&clamping_bounds, 0, resolution.x - 1, 0, resolution.y - 1);
+ BLI_rcti_clamp(&bounds, &clamping_bounds, xy);
+}
+
+const Vertex<CoordSpace::Tile> convert_coord_space(const Vertex<CoordSpace::UV> &uv_vertex,
+ const image::ImageTileWrapper image_tile,
+ const int2 tile_resolution)
+{
+ return Vertex<CoordSpace::Tile>{(uv_vertex.co - float2(image_tile.get_tile_offset())) *
+ float2(tile_resolution)};
+}
+
+const Edge<CoordSpace::Tile> convert_coord_space(const Edge<CoordSpace::UV> &uv_edge,
+ const image::ImageTileWrapper image_tile,
+ const int2 tile_resolution)
+{
+ return Edge<CoordSpace::Tile>{
+ convert_coord_space(uv_edge.v1, image_tile, tile_resolution),
+ convert_coord_space(uv_edge.v2, image_tile, tile_resolution),
+ };
+}
+
class NonManifoldTileEdges : public Vector<Edge<CoordSpace::Tile>> {};
class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> {
@@ -50,18 +93,24 @@ class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> {
}
Edge<CoordSpace::UV> edge;
edge.v1.co = find_uv_vert(mesh_primitive, mesh_edge.vert1).uv;
- edge.v2.co = find_uv_vert(mesh_primitive, mesh_edge.vert1).uv;
+ edge.v2.co = find_uv_vert(mesh_primitive, mesh_edge.vert2).uv;
append(edge);
}
}
}
NonManifoldTileEdges extract_tile_edges(const image::ImageTileWrapper image_tile,
- const int2 tile_resolution)
+ const int2 tile_resolution) const
{
NonManifoldTileEdges result;
- // TODO add edges that intersects with the given tile.
- // Convert the space from uv to tile.
+ // TODO: Only add edges that intersects with the given tile.
+ // TODO: Clamp edges to tile bounds.
+
+ for (const Edge<CoordSpace::UV> &uv_edge : *this) {
+ const Edge<CoordSpace::Tile> tile_edge = convert_coord_space(
+ uv_edge, image_tile, tile_resolution);
+ result.append(tile_edge);
+ }
return result;
}
@@ -148,73 +197,150 @@ class PixelNodesTileData : public Vector<std::reference_wrapper<UDIMTilePixels>>
* encode pixels.
*/
-struct Row {
- enum class PixelType {
- Undecided,
- /** This pixel is directly affected by a brush and doesn't need to be solved. */
- Brush,
- /** This pixel will be copid from another pixel to solve non-manifold edge bleeding. */
- CopyFromClosestEdge,
- };
-
- struct Elem {
- PixelType type = PixelType::Undecided;
- /**
- * Distance to the closest edge that can be sourced to fix an edge bleed.
- * A distance of 0.0 means that the pixel is being drawn on directly and
- * doesn't need to be checked.
- */
- float distance = 0.0f;
- PixelCopyCommand copy_command;
-
- Elem() = default;
+struct Rows {
+
+ struct Row {
+ enum class PixelType {
+ Undecided,
+ /** This pixel is directly affected by a brush and doesn't need to be solved. */
+ Brush,
+ /** This pixel will be copid from another pixel to solve non-manifold edge bleeding. */
+ CopyFromClosestEdge,
+ };
+
+ struct Elem {
+ PixelType type = PixelType::Undecided;
+ /**
+ * Distance to the closest edge that can be sourced to fix an edge bleed.
+ * A distance of 0.0 means that the pixel is being drawn on directly and
+ * doesn't need to be checked.
+ */
+ float distance = std::numeric_limits<float>::max();
+ PixelCopyCommand copy_command;
+
+ Elem() = default;
+
+ Elem(int2 co)
+ {
+ copy_command.destination = co;
+ copy_command.source_1 = co;
+ copy_command.source_2 = co;
+ copy_command.mix_factor = 0.0f;
+ }
+ };
- Elem(int2 co)
+ int row_number = 0;
+ Array<Elem> pixels;
+ Row() = delete;
+ Row(int64_t width) : pixels(width)
{
- copy_command.destination = co;
- copy_command.source_1 = co;
- copy_command.source_2 = co;
- copy_command.mix_factor = 0.0f;
}
- };
- int row_number = 0;
- Array<Elem> pixels;
-
- Row(int64_t width) : pixels(width)
- {
- }
+ void reinit(int y)
+ {
+ row_number = y;
+ for (int x = 0; x < pixels.size(); x++) {
+ pixels[x] = Elem(int2(x, y));
+ }
+ }
- void reinit(int y)
- {
- row_number = y;
- for (int x = 0; x < pixels.size(); x++) {
- pixels[x] = Elem(int2(x, y));
+ void mask_brush_pixels(const PixelNodesTileData &nodes_tile_pixels)
+ {
+ for (const UDIMTilePixels &tile_pixels : nodes_tile_pixels) {
+ for (const PackedPixelRow &encoded_pixels : tile_pixels.pixel_rows) {
+ if (encoded_pixels.start_image_coordinate.y != row_number) {
+ continue;
+ }
+ for (int x = encoded_pixels.start_image_coordinate.x;
+ x < encoded_pixels.start_image_coordinate.x + encoded_pixels.num_pixels;
+ x++) {
+ pixels[x].type = PixelType::Brush;
+ pixels[x].distance = 0.0f;
+ }
+ }
+ }
}
- }
- void mask_brush_pixels(const PixelNodesTileData &nodes_tile_pixels)
- {
- for (const UDIMTilePixels &tile_pixels : nodes_tile_pixels) {
- for (const PackedPixelRow &encoded_pixels : tile_pixels.pixel_rows) {
- if (encoded_pixels.start_image_coordinate.y != row_number) {
+ void determine_copy_pixels(const NonManifoldTileEdges &tile_edges,
+ int search_margin,
+ const int2 tile_resolution)
+ {
+ 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);
+
+ if (edge_bounds.ymax < row_number) {
+ continue;
+ }
+ if (edge_bounds.ymin > row_number) {
continue;
}
- for (int x = encoded_pixels.start_image_coordinate.x;
- x < encoded_pixels.start_image_coordinate.x + encoded_pixels.num_pixels;
- x++) {
- pixels[x].type = PixelType::Brush;
+
+ for (const int x : IndexRange(edge_bounds.xmin, edge_bounds.xmax - edge_bounds.xmin)) {
+ Elem &pixel = pixels[x];
+ switch (pixel.type) {
+ case PixelType::Brush: {
+ break;
+ }
+ case PixelType::Undecided:
+ case PixelType::CopyFromClosestEdge: {
+ 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) {
+ 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;
+
+ break;
+ }
+ }
}
}
}
+
+ void print_debug() const
+ {
+ for (const Elem &pixel : pixels) {
+ printf("%d", pixel.type);
+ }
+ printf("\n");
+ }
+ };
+
+ int2 resolution;
+ int margin;
+ int current_row_;
+ Vector<Row> rows;
+
+ Row ¤t_row()
+ {
+ return rows[current_row_];
}
- void print_debug() const
+ Rows(int2 resolution, int margin, const PixelNodesTileData &node_tile_pixels)
+ : resolution(resolution), margin(margin), current_row_(0)
{
- for (const Elem &pixel : pixels) {
- printf("%d", pixel.type);
+ Row row_template(resolution.x);
+ rows.resize(resolution.y, row_template);
+ for (int row_number : rows.index_range()) {
+ rows[row_number].reinit(row_number);
+ rows[row_number].mask_brush_pixels(node_tile_pixels);
}
- printf("\n");
+ }
+
+ void advance_to_row(int row_number)
+ {
+ current_row_ = row_number;
}
};
@@ -230,7 +356,7 @@ void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
{
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
copy_pixels_reinit(pbvh_data.tiles_copy_pixels);
- NonManifoldUVEdges non_manifold_edges(mesh_data);
+ const NonManifoldUVEdges non_manifold_edges(mesh_data);
if (non_manifold_edges.is_empty()) {
printf("Early exit: No non manifold edges detected\n");
return;
@@ -247,16 +373,20 @@ void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
}
const PixelNodesTileData nodes_tile_pixels(pbvh, image_tile);
- ushort2 tile_resolution(tile_buffer->x, tile_buffer->y);
+ int2 tile_resolution(tile_buffer->x, tile_buffer->y);
BKE_image_release_ibuf(&image, tile_buffer, nullptr);
+ NonManifoldTileEdges til
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list