[Bf-blender-cvs] [7820729053e] temp-T97352-3d-texturing-seam-bleeding-b2: Support for seam fixing with UDIM tiles.
Jeroen Bakker
noreply at git.blender.org
Fri Jul 8 15:24:49 CEST 2022
Commit: 7820729053e974ddf78fb22a67e69a6490cbcde5
Author: Jeroen Bakker
Date: Fri Jul 8 15:21:29 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rB7820729053e974ddf78fb22a67e69a6490cbcde5
Support for seam fixing with UDIM tiles.
===================================================================
M source/blender/blenkernel/BKE_uv_islands.hh
M source/blender/blenkernel/intern/pbvh_pixels.cc
M source/blender/blenkernel/intern/uv_islands.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_uv_islands.hh b/source/blender/blenkernel/BKE_uv_islands.hh
index 3b266a7870a..38e2f0523fa 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -943,20 +943,67 @@ struct UVIslands {
/* Bitmask containing the num of the nearest Island. */
// TODO: this is a really quick implementation.
struct UVIslandsMask {
- float2 udim_offset;
- ushort2 resolution;
- Array<uint16_t> mask;
- UVIslandsMask(float2 udim_offset, ushort2 resolution)
- : udim_offset(udim_offset), resolution(resolution), mask(resolution.x * resolution.y)
- {
- clear();
- }
+ struct Tile {
+ float2 udim_offset;
+ ushort2 resolution;
+ Array<uint16_t> mask;
+
+ Tile(float2 udim_offset, ushort2 resolution)
+ : udim_offset(udim_offset), resolution(resolution), mask(resolution.x * resolution.y)
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ mask.fill(0xffff);
+ }
+
+ void add(short island_index, const UVIsland &island)
+ {
+ for (const VectorList<UVPrimitive>::UsedVector &uv_primitives : island.uv_primitives)
+ for (const UVPrimitive &uv_primitive : uv_primitives) {
+ const MeshPrimitive *mesh_primitive = uv_primitive.primitive;
+
+ rctf uv_bounds = mesh_primitive->uv_bounds();
+ rcti buffer_bounds;
+ buffer_bounds.xmin = max_ii(floor((uv_bounds.xmin - udim_offset.x) * resolution.x), 0);
+ buffer_bounds.xmax = min_ii(ceil((uv_bounds.xmax - udim_offset.x) * resolution.x),
+ resolution.x - 1);
+ buffer_bounds.ymin = max_ii(floor((uv_bounds.ymin - udim_offset.y) * resolution.y), 0);
+ buffer_bounds.ymax = min_ii(ceil((uv_bounds.ymax - udim_offset.y) * resolution.y),
+ resolution.y - 1);
+
+ for (int y = buffer_bounds.ymin; y < buffer_bounds.ymax + 1; y++) {
+ for (int x = buffer_bounds.xmin; x < buffer_bounds.xmax + 1; x++) {
+ float2 uv(float(x) / resolution.x, float(y) / resolution.y);
+ float3 weights;
+ barycentric_weights_v2(mesh_primitive->vertices[0].uv,
+ mesh_primitive->vertices[1].uv,
+ mesh_primitive->vertices[2].uv,
+ uv + udim_offset,
+ weights);
+ if (!barycentric_inside_triangle_v2(weights)) {
+ continue;
+ }
+
+ uint64_t offset = resolution.x * y + x;
+ mask[offset] = island_index;
+ }
+ }
+ }
+ }
+ bool is_masked(const uint16_t island_index, const float2 uv) const;
+ };
+
+ Vector<Tile> tiles;
- void clear()
+ void add_tile(float2 udim_offset, ushort2 resolution)
{
- mask.fill(0xffff);
+ tiles.append_as(Tile(udim_offset, resolution));
}
+
/**
* Is the given uv coordinate part of the given island_index mask.
*
@@ -967,44 +1014,11 @@ struct UVIslandsMask {
void add(const UVIslands &islands)
{
- for (int index = 0; index < islands.islands.size(); index++) {
- add(index, islands.islands[index]);
- }
- }
-
- void add(short island_index, const UVIsland &island)
- {
- for (const VectorList<UVPrimitive>::UsedVector &uv_primitives : island.uv_primitives)
- for (const UVPrimitive &uv_primitive : uv_primitives) {
- const MeshPrimitive *mesh_primitive = uv_primitive.primitive;
-
- rctf uv_bounds = mesh_primitive->uv_bounds();
- rcti buffer_bounds;
- buffer_bounds.xmin = max_ii(floor((uv_bounds.xmin - udim_offset.x) * resolution.x), 0);
- buffer_bounds.xmax = min_ii(ceil((uv_bounds.xmax - udim_offset.x) * resolution.x),
- resolution.x - 1);
- buffer_bounds.ymin = max_ii(floor((uv_bounds.ymin - udim_offset.y) * resolution.y), 0);
- buffer_bounds.ymax = min_ii(ceil((uv_bounds.ymax - udim_offset.y) * resolution.y),
- resolution.y - 1);
-
- for (int y = buffer_bounds.ymin; y < buffer_bounds.ymax + 1; y++) {
- for (int x = buffer_bounds.xmin; x < buffer_bounds.xmax + 1; x++) {
- float2 uv(float(x) / resolution.x, float(y) / resolution.y);
- float3 weights;
- barycentric_weights_v2(mesh_primitive->vertices[0].uv,
- mesh_primitive->vertices[1].uv,
- mesh_primitive->vertices[2].uv,
- uv,
- weights);
- if (!barycentric_inside_triangle_v2(weights)) {
- continue;
- }
-
- uint64_t offset = resolution.x * y + x;
- mask[offset] = island_index;
- }
- }
+ for (Tile &tile : tiles) {
+ for (int index = 0; index < islands.islands.size(); index++) {
+ tile.add(index, islands.islands[index]);
}
+ }
}
void dilate(int max_iterations);
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index cf51b595746..6caba4f8c79 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -61,6 +61,7 @@ static void extract_barycentric_pixels(UDIMTilePixels &tile_data,
const int64_t uv_island_index,
const int64_t uv_primitive_index,
const float2 uvs[3],
+ const float2 tile_offset,
const int minx,
const int miny,
const int maxx,
@@ -79,7 +80,7 @@ static void extract_barycentric_pixels(UDIMTilePixels &tile_data,
barycentric_weights_v2(uvs[0], uvs[1], uvs[2], uv, barycentric_weights);
const bool is_inside = barycentric_inside_triangle_v2(barycentric_weights);
- const bool is_masked = uv_mask.is_masked(uv_island_index, uv);
+ const bool is_masked = uv_mask.is_masked(uv_island_index, uv + tile_offset);
if (!start_detected && is_inside && is_masked) {
start_detected = true;
pixel_row.start_image_coordinate = ushort2(x, y);
@@ -210,6 +211,7 @@ static void do_encode_pixels(void *__restrict userdata,
entry.uv_island_index,
uv_prim_index,
uvs,
+ tile_offset,
minx,
miny,
maxx,
@@ -365,7 +367,12 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
// TODO: Currently uv_masks only supports a single udim tile. We should create one for each tile.
// TODO: mask resolution should be based on the actual resolution of the image buffer (or a
// factor of it).
- uv_islands::UVIslandsMask uv_masks(float2(0.0, 0.0), ushort2(256, 256));
+ uv_islands::UVIslandsMask uv_masks;
+ LISTBASE_FOREACH (ImageTile *, tile_data, &image->tiles) {
+ image::ImageTileWrapper image_tile(tile_data);
+ uv_masks.add_tile(float2(image_tile.get_tile_x_offset(), image_tile.get_tile_y_offset()),
+ ushort2(256, 256));
+ }
uv_masks.add(islands);
uv_masks.dilate(image->seamfix_iter);
diff --git a/source/blender/blenkernel/intern/uv_islands.cc b/source/blender/blenkernel/intern/uv_islands.cc
index ec8bd3e0db8..a5b6ab947d5 100644
--- a/source/blender/blenkernel/intern/uv_islands.cc
+++ b/source/blender/blenkernel/intern/uv_islands.cc
@@ -719,7 +719,7 @@ UVBorder UVPrimitive::extract_border() const
/** \name UVIslandsMask
* \{ */
-static bool dilate_x(UVIslandsMask &islands_mask)
+static bool dilate_x(UVIslandsMask::Tile &islands_mask)
{
bool changed = false;
const Array<uint16_t> prev_mask = islands_mask.mask;
@@ -742,7 +742,7 @@ static bool dilate_x(UVIslandsMask &islands_mask)
return changed;
}
-static bool dilate_y(UVIslandsMask &islands_mask)
+static bool dilate_y(UVIslandsMask::Tile &islands_mask)
{
bool changed = false;
const Array<uint16_t> prev_mask = islands_mask.mask;
@@ -766,33 +766,27 @@ static bool dilate_y(UVIslandsMask &islands_mask)
return changed;
}
-void UVIslandsMask::dilate(int max_iterations)
+static void dilate_tile(UVIslandsMask::Tile &tile, int max_iterations)
{
-#ifdef DEBUG_SVG
- std::ofstream of;
- of.open("/tmp/dilate.svg");
- svg_header(of);
-#endif
-
int index = 0;
while (index < max_iterations) {
- bool changed = dilate_x(*this);
- changed |= dilate_y(*this);
+ bool changed = dilate_x(tile);
+ changed |= dilate_y(tile);
if (!changed) {
break;
}
-#ifdef DEBUG_SVG
- svg(of, *this, index);
-#endif
index++;
}
-#ifdef DEBUG_SVG
- svg_footer(of);
- of.close();
-#endif
}
-bool UVIslandsMask::is_masked(const short island_index, const float2 uv) const
+void UVIslandsMask::dilate(int max_iterations)
+{
+ for (Tile &tile : tiles) {
+ dilate_tile(tile, max_iterations);
+ }
+}
+
+bool UVIslandsMask::Tile::is_masked(const uint16_t island_index, const float2 uv) const
{
float2 local_uv = uv - udim_offset;
if (local_uv.x < 0.0f || local_uv.y < 0.0f || local_uv.x >= 1.0f || local_uv.y >= 1.0f) {
@@ -804,6 +798,17 @@ bool UVIslandsMask::is_masked(const short island_index, const float2 uv) const
return mask[offset] == island_index;
}
+bool UVIslandsMask::is_masked(const short island_index, const float2 uv) const
+{
+ // TODO: should find tile containing the uv coords not going over all of them.
+ for (const Tile &tile : tiles) {
+ if (tile.is_masked(island_index, uv)) {
+ return true;
+ }
+ }
+ return false;
+}
+
/** \} */
#ifdef DEBUG_SVG
More information about the Bf-blender-cvs
mailing list