[Bf-blender-cvs] [63d0916dfd2] temp-T97352-3d-texturing-seam-bleeding-b: New method. building via faces.

Jeroen Bakker noreply at git.blender.org
Fri May 20 14:22:20 CEST 2022


Commit: 63d0916dfd29433efc15093a7db0e837e2dd7215
Author: Jeroen Bakker
Date:   Fri May 20 12:23:54 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b
https://developer.blender.org/rB63d0916dfd29433efc15093a7db0e837e2dd7215

New method. building via faces.

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

M	source/blender/blenkernel/BKE_uv_islands.hh
M	source/blender/blenkernel/intern/pbvh_pixels.cc

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

diff --git a/source/blender/blenkernel/BKE_uv_islands.hh b/source/blender/blenkernel/BKE_uv_islands.hh
index 6af47d029c7..0b7cad8160f 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include <fstream>
+
 #include "BLI_math_vec_types.hh"
 #include "BLI_vector.hh"
 
@@ -13,368 +15,186 @@ namespace blender::bke::uv_islands {
 // TODO: Joining uv island should check where the borders could be merged.
 // TODO: this isn't optimized for performance.
 
-struct UVIslandEdge {
-  float2 uv1;
-  float2 uv2;
-
-  UVIslandEdge() : uv1(float2(0.0f, 0.0f)), uv2(float2(0.0f, 0.0f))
-  {
-  }
-
-  UVIslandEdge(const float2 &uv1, const float2 &uv2) : uv1(uv1), uv2(uv2)
-  {
-  }
+struct UVVertex {
+  /* Loop index of the vertex in the original mesh. */
+  uint64_t loop;
+  /* Position in uv space. */
+  float2 uv;
+};
 
-  bool operator==(const UVIslandEdge &other) const
-  {
-    return (uv1 == other.uv1 && uv2 == other.uv2) || (uv1 == other.uv2 && uv2 == other.uv1);
-  }
+struct UVEdge {
+  UVVertex vertices[2];
+  int64_t adjacent_uv_primitive = -1;
 
-  void print() const
+  bool has_shared_edge(const UVEdge &other) const
   {
-    printf("UVIslandEdge(float2(%f, %f), float2(%f, %f))\n", uv1.x, uv1.y, uv2.x, uv2.y);
+    return (vertices[0].uv == other.vertices[0].uv && vertices[1].uv == other.vertices[1].uv) ||
+           (vertices[0].uv == other.vertices[1].uv && vertices[1].uv == other.vertices[0].uv);
   }
 };
 
-struct Primitive {
+struct UVPrimitive {
+  /**
+   * Index of the primitive in the original mesh.
+   */
   uint64_t index;
-  UVIslandEdge edge[3];
-
-  Primitive()
-  {
-  }
+  UVEdge edges[3];
 
-  Primitive(uint64_t index,
-            const UVIslandEdge &edge1,
-            const UVIslandEdge &edge2,
-            const UVIslandEdge &edge3)
-      : index(index), edge({edge1, edge2, edge3})
+  explicit UVPrimitive(uint64_t prim_index, const MLoopTri &tri, const MLoopUV *mloopuv)
+      : index(prim_index)
   {
-  }
-
-  Primitive(uint64_t index, const MLoopTri &tri, const MLoopUV *mloopuv) : index(index)
-  {
-    const float2 uv1(mloopuv[tri.tri[0]].uv);
-    const float2 uv2(mloopuv[tri.tri[1]].uv);
-    const float2 uv3(mloopuv[tri.tri[2]].uv);
-    edge[0] = UVIslandEdge(uv1, uv2);
-    edge[1] = UVIslandEdge(uv2, uv3);
-    edge[2] = UVIslandEdge(uv3, uv1);
-  }
-
-  void print() const
-  {
-    printf(">>>> Primitive(start)\n");
     for (int i = 0; i < 3; i++) {
-      edge[i].print();
+      edges[i].vertices[0].uv = mloopuv[tri.tri[i]].uv;
+      edges[i].vertices[1].uv = mloopuv[tri.tri[(i + 1) % 3]].uv;
+      edges[i].vertices[0].loop = tri.tri[i];
+      edges[i].vertices[1].loop = tri.tri[(i + 1) % 3];
     }
-    printf("<<<< Primitive(end)\n");
   }
-};
-
-/* Mapping between generated primitives and original primitives. */
-struct UVIslandPrimitive {
-  uint64_t orig_prim;
 
-  UVIslandPrimitive(uint64_t orig_prim) : orig_prim(orig_prim)
-  {
-  }
-};
-
-class UVIsland {
-  // We might want to use a linked list as there are more edits then reads.
-  Vector<UVIslandEdge> borders;
-  Vector<UVIslandPrimitive> primitives;
-
- public:
-  void print() const
-  {
-    printf(">>>> UVIsland(start)\n");
-    for (int i = 0; i < borders.size(); i++) {
-      const UVIslandEdge &border = borders[i];
-      printf("island.add(");
-      border.print();
-      printf("); // %d\n", i);
-    }
-    printf("<<<< UVIsland(end)\n");
-  }
-  /* Join a given UVIsland into self by using the given tri as the edges that needs to be merged.
-   */
-  void join(const UVIsland &other, const Primitive &primitive)
+  std::optional<std::pair<UVEdge &, UVEdge &>> shared_edge(UVPrimitive &other)
   {
-    printf("Before joining");
-    print();
-    other.print();
-    primitive.print();
-
-    int64_t a_edge_index[3];
-    int64_t b_edge_index[3];
-    for (int i = 0; i < 3; i++) {
-      a_edge_index[i] = borders.first_index_of_try(primitive.edge[i]);
-      b_edge_index[i] = other.borders.first_index_of_try(primitive.edge[i]);
-    }
-
-    // CHeck the number of edges. Based on this a different way should be used for joining.
-    // these are the cases:
-    // * self contains a single edge, other contains a single edge.
-    // * self contains a single edge, other contains a double edge.
-    // * self contains a double edge, other contains a single edge.
-    // * self contains a double edge, other contains a double edge.
-    int a_border_len = 0;
-    int b_border_len = 0;
     for (int i = 0; i < 3; i++) {
-      if (a_edge_index[i] != -1) {
-        a_border_len += 1;
-      }
-      if (b_edge_index[i] != -1) {
-        b_border_len += 1;
-      }
-    }
-    BLI_assert_msg(a_border_len == 1 || a_border_len == 2, "Incorrect number of borders.");
-    BLI_assert_msg(b_border_len == 1 || b_border_len == 2, "Incorrect number of borders.");
-
-    if (a_border_len == 1 && b_border_len == 1) {
-      printf("1-1 join\n");
-      BLI_assert_unreachable();
-    }
-    if (a_border_len == 1 && b_border_len == 2) {
-      printf("1-2 join\n");
-      BLI_assert_unreachable();
-    }
-    if (a_border_len == 2 && b_border_len == 1) {
-      printf("2-1 join\n");
-      BLI_assert_unreachable();
-    }
-    if (a_border_len == 2 && b_border_len == 2) {
-      printf("2-2 join\n");
-      int common_edge_len = 0;
-      for (int i = 0; i < 3; i++) {
-        if (a_edge_index[i] != -1 && b_edge_index[i] != -1) {
-          common_edge_len++;
-        }
-      }
-
-      Vector<uint64_t> edges_to_remove_from_dst;
-      uint64_t insert;
-      uint64_t start;
-      uint64_t end;
-
-      switch (common_edge_len) {
-        case 0:
-          BLI_assert_unreachable();
-          break;
-
-        case 1: {
-          /* Determine the common edge. */
-          int common_edge = -1;
-          for (int i = 0; i < 3; i++) {
-            if (a_edge_index[i] != -1 && b_edge_index[i] != -1) {
-              BLI_assert(common_edge == -1);
-              common_edge = i;
-            }
-          }
-
-          int next_edge = (common_edge + 1) % 3;
-          int prev_edge = 3 - common_edge - next_edge;
-          BLI_assert(common_edge != -1);
-          int other_b_edge = b_edge_index[next_edge] != -1 ? next_edge : prev_edge;
-
-          // In this case there should be a single common edge. This edge will still be an edge
-          // in the merged island. find the index where to insert the other. find the start and
-          // end to the other to insert.
-          end = b_edge_index[common_edge];
-          start = b_edge_index[other_b_edge];
-
-          int other_a_edge = a_edge_index[next_edge] != -1 ? next_edge : prev_edge;
-          insert = a_edge_index[common_edge];
-          if (other_a_edge == common_edge - 1) {
-            edges_to_remove_from_dst.append(insert);
-            insert--;
-          }
-          break;
-        }
-
-        case 2: {
-          // find edge that isn't common.
-          int unshared_edge = -1;
-          for (int i = 0; i < 3; i++) {
-            if (a_edge_index[i] == -1 || b_edge_index[i] == -1) {
-              unshared_edge = i;
-            }
-          }
-          int next_edge = (unshared_edge + 1) % 3;
-          int prev_edge = 3 - unshared_edge - next_edge;
-          edges_to_remove_from_dst.append(a_edge_index[next_edge]);
-          edges_to_remove_from_dst.append(a_edge_index[prev_edge]);
-          insert = prev_edge;
-
-          break;
-        }
-      }
-
-      // TODO: It could be that different edge should be removed and copies start at other
-      // locations depending on next_edge/prev_edge selection.
-      // TODO: sort_reversed?
-      for (uint64_t index_to_remove : edges_to_remove_from_dst) {
-        borders.remove(index_to_remove);
-        printf("removed %d: ", index_to_remove);
-        print();
-      }
-
-      printf("i:%d s:%d e:%d\n", insert, start, end);
-
-      if (end < start) {
-        // TODO: these loops can be done with a single call and an iterator. For debugging and need
-        // to look how to use the iterators this hasn't been done.
-        for (int i = end - 1; i >= 0; i--) {
-          borders.insert(insert, other.borders[i]);
-          printf("insert: %d->%d", i, insert);
-          print();
-          BLI_assert(borders[insert].uv2 == borders[insert + 1].uv1);
-        }
-        for (int i = other.borders.size() - 1; i > start; i--) {
-          borders.insert(insert, other.borders[i]);
-          printf("insert: %d->%d", i, insert);
-          print();
-          BLI_assert(borders[insert].uv2 == borders[insert + 1].uv1);
-        }
-      }
-      else {
-        for (int i = end; i >= start; i--) {
-          borders.insert(insert, other.borders[i]);
-          printf("insert: %d->%d", i, insert);
-          print();
-          BLI_assert(borders[insert].uv2 == borders[insert + 1].uv1);
+      for (int j = 0; j < 3; j++) {
+        if (edges[i].has_shared_edge(other.edges[j])) {
+          return std::pair<UVEdge &, UVEdge &>(edges[i], other.edges[j]);
         }
       }
     }
-
-    printf("After joining");
-    print();
-
-    BLI_assert(validate());
+    return std::nullopt;
   }
 
-  void add(const UVIslandEdge &border)
+  bool has_shared_edge(const UVPrimitive &other) const
   {
-    borders.append(border);
+    for (int i = 0; i < 3; i++) {
+      for (int j = 0; j < 3; j++) {
+        if (edges[i].has_shared_edge(other.edges[j])) {
+          return true;
+        }
+      }
+    }
+    return false;
   }
+};
 
-  void extend_border(const int64_t edge_to_remove,
-                     const UVIslandEdge &border1,
-                     const UVIslandEdge &border2)
-  {
-    BLI_assert_msg(border1.uv2 == border2.uv1,
-                   "Winding order of replacement borders is not correct.");
-    borders[edge_to_remove] = border2;
-    borders.insert(edge_to_remove, border1);
-    BLI_assert(validate());
-  }
+struct UVIsland {
+  Vector<UVPrimitive> primitives;
 
-  void extend_border(const int64_t edge1_to_remove,
-                     const int64_t edge2_to_remove,
-                     const UVIslandEdge &border)
+  UVIsland(const UVPrimit

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list