[Bf-blender-cvs] [d9c7e240ed7] temp-T97352-3d-texturing-seam-bleeding-b2: Reduce pixel extraction based on the uv island dilated mask.
Jeroen Bakker
noreply at git.blender.org
Fri Jun 17 11:34:00 CEST 2022
Commit: d9c7e240ed74ee1d303ea17149d3419c3de29735
Author: Jeroen Bakker
Date: Fri Jun 17 11:27:45 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rBd9c7e240ed74ee1d303ea17149d3419c3de29735
Reduce pixel extraction based on the uv island dilated mask.
===================================================================
M source/blender/blenkernel/BKE_uv_islands.hh
M source/blender/blenkernel/intern/paint_canvas.cc
M source/blender/blenkernel/intern/pbvh_pixels.cc
M source/blender/blenkernel/intern/uv_islands.cc
M source/blender/blenloader/intern/versioning_300.c
M source/blender/editors/space_image/image_buttons.c
M source/blender/makesdna/DNA_image_defaults.h
M source/blender/makesdna/DNA_image_types.h
M source/blender/makesrna/intern/rna_image.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_uv_islands.hh b/source/blender/blenkernel/BKE_uv_islands.hh
index caf18a2b29b..1c6607da15d 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -11,6 +11,7 @@
#include "BLI_float3x3.hh"
#include "BLI_math.h"
#include "BLI_math_vec_types.hh"
+#include "BLI_rect.h"
#include "BLI_vector.hh"
#include "DNA_meshdata_types.h"
@@ -95,6 +96,16 @@ struct MeshPrimitive {
}
return nullptr;
}
+
+ rctf uv_bounds() const
+ {
+ rctf result;
+ BLI_rctf_init_minmax(&result);
+ for (const MeshUVVert &uv_vertex : vertices) {
+ BLI_rctf_do_minmax_v(&result, uv_vertex.uv);
+ }
+ return result;
+ }
};
/** Wrapper to contain all required mesh data. */
@@ -892,33 +903,39 @@ struct UVIslandsMask {
void add(short island_index, const UVIsland &island)
{
- for (const UVEdge &edge : island.uv_edges) {
- add(island_index, edge);
- }
- }
-
- void add(short island_index, const UVEdge &edge)
- {
- float2 p;
- for (int i = 0; i < 10; i++) {
- float f = i / 10.0f;
- interp_v2_v2v2(p, edge.vertices[0]->uv, edge.vertices[1]->uv, f);
- add(island_index, p);
- }
- }
+ for (const UVPrimitive &uv_primitive : island.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;
+ }
- void add(short island_index, const float2 uv)
- {
- float2 udim_corrected_uv = uv - udim_offset;
- ushort2 mask_uv(udim_corrected_uv.x * resolution.x, udim_corrected_uv.y * resolution.y);
- if (mask_uv.x < 0 || mask_uv.y < 0 || mask_uv.x >= resolution.x || mask_uv.y >= resolution.y) {
- return;
+ uint64_t offset = resolution.x * y + x;
+ mask[offset] = island_index;
+ }
+ }
}
- uint64_t offset = resolution.x * mask_uv.y + mask_uv.x;
- mask[offset] = island_index;
}
- void dilate();
+ void dilate(int max_iterations);
void print() const
{
diff --git a/source/blender/blenkernel/intern/paint_canvas.cc b/source/blender/blenkernel/intern/paint_canvas.cc
index b72418d88c0..497d98dcab3 100644
--- a/source/blender/blenkernel/intern/paint_canvas.cc
+++ b/source/blender/blenkernel/intern/paint_canvas.cc
@@ -113,6 +113,7 @@ char *BKE_paint_canvas_key_get(struct PaintModeSettings *settings, struct Object
Image *image;
ImageUser *image_user;
if (BKE_paint_canvas_image_get(settings, ob, &image, &image_user)) {
+ ss << ",SEAM_DIST:" << image->seamfix_iter;
ImageUser tile_user = *image_user;
LISTBASE_FOREACH (ImageTile *, image_tile, &image->tiles) {
tile_user.tile = image_tile->tile_number;
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 3acc49eada3..f613f962522 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -29,25 +29,6 @@ namespace blender::bke::pbvh::pixels {
*/
constexpr bool USE_WATERTIGHT_CHECK = false;
-/* -------------------------------------------------------------------- */
-
-/** \name UV Islands
- * \{ */
-
-/** Build UV islands from PBVH primitives. */
-static uv_islands::UVIslands build_uv_islands(uv_islands::MeshData &mesh_data)
-{
- uv_islands::UVIslands islands(mesh_data);
- uv_islands::UVIslandsMask uv_masks(float2(0.0, 0.0), ushort2(256, 256));
- uv_masks.add(islands);
- uv_masks.dilate();
- islands.extract_borders();
- islands.extend_borders(uv_masks, mesh_data);
- return islands;
-}
-
-/** \} */
-
/**
* Calculate the delta of two neighbor UV coordinates in the given image buffer.
*/
@@ -76,6 +57,8 @@ static float2 calc_barycentric_delta_x(const ImBuf *image_buffer,
static void extract_barycentric_pixels(UDIMTilePixels &tile_data,
const ImBuf *image_buffer,
+ const uv_islands::UVIslandsMask &uv_mask,
+ const int64_t uv_island_index,
const int64_t uv_primitive_index,
const float2 uvs[3],
const int minx,
@@ -96,12 +79,13 @@ 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);
- if (!start_detected && is_inside) {
+ const bool is_masked = uv_mask.is_masked(uv_island_index, uv);
+ if (!start_detected && is_inside && is_masked) {
start_detected = true;
pixel_row.start_image_coordinate = ushort2(x, y);
pixel_row.start_barycentric_coord = float2(barycentric_weights.x, barycentric_weights.y);
}
- else if (start_detected && !is_inside) {
+ else if (start_detected && (!is_inside || !is_masked)) {
break;
}
}
@@ -133,6 +117,7 @@ struct EncodePixelsUserData {
Vector<PBVHNode *> *nodes;
const MLoopUV *ldata_uv;
const uv_islands::UVIslands *uv_islands;
+ const uv_islands::UVIslandsMask *uv_masks;
};
static void do_encode_pixels(void *__restrict userdata,
@@ -144,6 +129,8 @@ static void do_encode_pixels(void *__restrict userdata,
ImageUser image_user = *data->image_user;
PBVHNode *node = (*data->nodes)[n];
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+ const uv_islands::UVIslandsMask &uv_masks = *data->uv_masks;
+
LISTBASE_FOREACH (ImageTile *, tile, &data->image->tiles) {
image::ImageTileWrapper image_tile(tile);
image_user.tile = image_tile.get_tile_number();
@@ -159,6 +146,7 @@ static void do_encode_pixels(void *__restrict userdata,
for (int pbvh_node_prim_index = 0; pbvh_node_prim_index < node->totprim;
pbvh_node_prim_index++) {
int64_t geom_prim_index = node->prim_indices[pbvh_node_prim_index];
+ int64_t uv_island_index = 0;
for (const uv_islands::UVIsland &island : data->uv_islands->islands) {
for (const uv_islands::UVPrimitive &uv_primitive : island.uv_primitives) {
if (uv_primitive.primitive->index != geom_prim_index) {
@@ -189,9 +177,18 @@ static void do_encode_pixels(void *__restrict userdata,
image_buffer, uvs, minx, miny);
/* Extract the pixels. */
- extract_barycentric_pixels(
- tile_data, image_buffer, uv_prim_index, uvs, minx, miny, maxx, maxy);
+ extract_barycentric_pixels(tile_data,
+ image_buffer,
+ uv_masks,
+ uv_island_index,
+ uv_prim_index,
+ uvs,
+ minx,
+ miny,
+ maxx,
+ maxy);
}
+ uv_island_index++;
}
}
BKE_image_release_ibuf(image, image_buffer, nullptr);
@@ -335,9 +332,18 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
if (ldata_uv == nullptr) {
return;
}
+
uv_islands::MeshData mesh_data(
pbvh->looptri, pbvh->totprim, pbvh->totvert, pbvh->mloop, ldata_uv);
- uv_islands::UVIslands islands = build_uv_islands(mesh_data);
+ uv_islands::UVIslands islands(mesh_data);
+
+ // TODO: Currenly uv_masks only supports a single udim tile. We should create one for each tile.
+ uv_islands::UVIslandsMask uv_masks(float2(0.0, 0.0), ushort2(256, 256));
+ uv_masks.add(islands);
+ uv_masks.dilate(image->seamfix_iter);
+
+ islands.extract_borders();
+ islands.extend_borders(uv_masks, mesh_data);
update_geom_primitives(*pbvh, mesh_data);
EncodePixelsUserData user_data;
@@ -347,6 +353,7 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
user_data.ldata_uv = ldata_uv;
user_data.nodes = &nodes_to_update;
user_data.uv_islands = &islands;
+ user_data.uv_masks = &uv_masks;
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, nodes_to_update.size());
diff --git a/source/blender/blenkernel/intern/uv_islands.cc b/source/blender/blenkernel/intern/uv_islands.cc
index f03d123fb37..dbe0c546170 100644
--- a/source/blender/blenkernel/intern/uv_islands.cc
+++ b/source/blender/blenkernel/intern/uv_islands.cc
@@ -741,26 +741,27 @@ static bool dilate_y(UVIslandsMask &islands_mask)
return changed;
}
-void UVIslandsMask::dilate()
+void UVIslandsMask::dilate(int max_iterations)
{
#ifdef DEBUG_SVG
std::ofstream of;
of.open("/tmp/dilate.svg");
svg_header(of);
- int index = 0;
#endif
- while (true) {
+
+ int index = 0;
+ while (index < max_iterations) {
bool changed = dilate_x(*this);
changed |= dilate_y(*this);
if (!changed) {
break;
}
#ifdef DEBUG_SVG
- svg(of, *this, index++);
+ svg(of, *thi
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list