Commit: 6636edbb00942a1a04bdf6f3cb843a1636ffa8b4
Author: Jacques Lucke
Date:   Wed Jul 6 15:20:25 2022 +0200
Branches: master
https://developer.blender.org/rB6636edbb00942a1a04bdf6f3cb843a1636ffa8b4

BLI: improve reverse uv sample in edge cases

Allow for a small epsilon to improve handling of uvs that are on edges.
Generally, when using reverse uv sampling, we expect that the sampling
is supposed to succeed.

===================================================================

M       source/blender/geometry/intern/reverse_uv_sampler.cc

===================================================================

diff --git a/source/blender/geometry/intern/reverse_uv_sampler.cc 
b/source/blender/geometry/intern/reverse_uv_sampler.cc
index 87ba2c77657..54df43db4ea 100644
--- a/source/blender/geometry/intern/reverse_uv_sampler.cc
+++ b/source/blender/geometry/intern/reverse_uv_sampler.cc
@@ -45,6 +45,11 @@ ReverseUVSampler::Result ReverseUVSampler::sample(const 
float2 &query_uv) const
 {
   const int2 cell_key = uv_to_cell_key(query_uv, resolution_);
   const Span<int> looptri_indices = looptris_by_cell_.lookup(cell_key);
+
+  float best_dist = FLT_MAX;
+  float3 best_bary_weights;
+  const MLoopTri *best_looptri;
+
   for (const int looptri_index : looptri_indices) {
     const MLoopTri &looptri = looptris_[looptri_index];
     const float2 &uv_0 = uv_map_[looptri.tri[0]];
@@ -54,11 +59,31 @@ ReverseUVSampler::Result ReverseUVSampler::sample(const 
float2 &query_uv) const
     if (!barycentric_coords_v2(uv_0, uv_1, uv_2, query_uv, bary_weights)) {
       continue;
     }
-    if (IN_RANGE_INCL(bary_weights.x, 0.0f, 1.0f) && 
IN_RANGE_INCL(bary_weights.y, 0.0f, 1.0f) &&
-        IN_RANGE_INCL(bary_weights.z, 0.0f, 1.0f)) {
+
+    /* If #query_uv is in the triangle, the distance is <= 0. Otherwise, the 
larger the distance,
+     * the further away the uv is from the triangle. */
+    const float x_dist = std::max(-bary_weights.x, bary_weights.x - 1.0f);
+    const float y_dist = std::max(-bary_weights.y, bary_weights.y - 1.0f);
+    const float z_dist = std::max(-bary_weights.z, bary_weights.z - 1.0f);
+    const float dist = MAX3(x_dist, y_dist, z_dist);
+
+    if (dist <= 0.0f) {
+      /* Return early if the uv coordinate is in the triangle. */
       return Result{ResultType::Ok, &looptri, bary_weights};
     }
+
+    if (dist < best_dist) {
+      best_dist = dist;
+      best_bary_weights = bary_weights;
+      best_looptri = &looptri;
+    }
+  }
+
+  /* Allow for a small epsilon in case the uv is on th edge. */
+  if (best_dist < 0.00001f) {
+    return Result{ResultType::Ok, best_looptri, math::clamp(best_bary_weights, 
0.0f, 1.0f)};
   }
+
   return Result{};
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to