[Bf-blender-cvs] [94659489021] temp-T97352-3d-texturing-seam-bleeding-b2: Use ptr to understand better what is needed.

Jeroen Bakker noreply at git.blender.org
Fri Jun 3 15:54:20 CEST 2022


Commit: 946594890212b53064a3e04a71a5dc4cf032fdcc
Author: Jeroen Bakker
Date:   Fri Jun 3 15:54:17 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rB946594890212b53064a3e04a71a5dc4cf032fdcc

Use ptr to understand better what is needed.

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

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 df4eb93abdc..9992c0da4a9 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -6,6 +6,7 @@
 #include <fstream>
 
 #include "BLI_array.hh"
+#include "BLI_edgehash.h"
 #include "BLI_math.h"
 #include "BLI_math_vec_types.hh"
 #include "BLI_vector.hh"
@@ -25,19 +26,165 @@ namespace blender::bke::uv_islands {
 
 struct UVIslands;
 struct UVIslandsMask;
+struct MeshEdge;
+struct MeshPrimitive;
+struct UVPrimitive;
+struct UVPrimitiveEdge;
 struct UVBorder;
 
+struct MeshEdge;
+struct MeshPrimitive;
+
+struct MeshVertex {
+  int64_t v;
+  Vector<MeshEdge *> edges;
+};
+
+struct MeshUVVert {
+  MeshVertex *vertex;
+  float2 uv;
+  int64_t loop;
+};
+
+struct MeshEdge {
+  MeshVertex *vert1;
+  MeshVertex *vert2;
+  Vector<MeshPrimitive *> primitives;
+};
+
+/** Represents a triangle in 3d space (MLoopTri) */
+struct MeshPrimitive {
+  int64_t index;
+  int64_t poly;
+  Vector<MeshEdge *> edges;
+  Vector<MeshUVVert> vertices;
+
+  const MeshUVVert &get_uv_vert(const MeshVertex *vert)
+  {
+    for (const MeshUVVert &uv_vert : vertices) {
+      if (uv_vert.vertex == vert) {
+        return uv_vert;
+      }
+    }
+    BLI_assert_unreachable();
+    return vertices[0];
+  }
+};
+
+/** Wrapper to contain all required mesh data. */
+struct MeshData {
+ public:
+  const MLoopTri *looptri;
+  const int64_t looptri_len;
+  const int64_t vert_len;
+  const MLoop *mloop;
+  const MLoopUV *mloopuv;
+
+ public:
+  Vector<MeshPrimitive> primitives;
+  Vector<MeshEdge> edges;
+  Vector<MeshVertex> vertices;
+
+  explicit MeshData(const MLoopTri *looptri,
+                    const int64_t looptri_len,
+                    const int64_t vert_len,
+                    const MLoop *mloop,
+                    const MLoopUV *mloopuv)
+      : looptri(looptri),
+        looptri_len(looptri_len),
+        vert_len(vert_len),
+        mloop(mloop),
+        mloopuv(mloopuv)
+  {
+    init_vertices();
+    init_primitives();
+    init_edges();
+  }
+  void init_vertices()
+  {
+    vertices.reserve(vert_len);
+    for (int64_t i = 0; i < vert_len; i++) {
+      MeshVertex vert;
+      vert.v = i;
+      vertices.append(vert);
+    }
+  }
+  void init_primitives()
+  {
+    primitives.reserve(looptri_len);
+    for (int64_t i = 0; i < looptri_len; i++) {
+      const MLoopTri &tri = looptri[i];
+      MeshPrimitive primitive;
+      primitive.index = i;
+      primitive.poly = tri.poly;
+
+      for (int j = 0; j < 3; j++) {
+        MeshUVVert uv_vert;
+        uv_vert.loop = tri.tri[j];
+        uv_vert.vertex = &vertices[mloop[uv_vert.loop].v];
+        uv_vert.uv = mloopuv[uv_vert.loop].uv;
+        primitive.vertices.append(uv_vert);
+      }
+      primitives.append(primitive);
+    }
+  }
+
+  void init_edges()
+  {
+    /* TODO: use actual sized. */
+    edges.reserve(looptri_len * 2);
+    EdgeHash *eh = BLI_edgehash_new_ex(__func__, looptri_len * 2);
+    for (int64_t i = 0; i < looptri_len; i++) {
+      const MLoopTri &tri = looptri[i];
+      MeshPrimitive &primitive = primitives[i];
+      for (int j = 0; j < 3; j++) {
+        int v1 = mloop[tri.tri[j]].v;
+        int v2 = mloop[tri.tri[(j + 1) % 3]].v;
+        void *v = BLI_edgehash_lookup(eh, v1, v2);
+        int64_t edge_index;
+        if (v == nullptr) {
+          edge_index = edges.size();
+          BLI_edgehash_insert(eh, v1, v2, POINTER_FROM_INT(edge_index));
+          MeshEdge edge;
+          edge.vert1 = &vertices[v1];
+          edge.vert2 = &vertices[v2];
+          edges.append(edge);
+          MeshEdge *edge_ptr = &edges.last();
+          vertices[v1].edges.append(edge_ptr);
+          vertices[v2].edges.append(edge_ptr);
+        }
+        else {
+          edge_index = POINTER_AS_INT(v);
+        }
+
+        MeshEdge *edge = &edges[edge_index];
+        edge->primitives.append(&primitive);
+        primitive.edges.append(edge);
+      }
+    }
+    BLI_edgehash_free(eh, nullptr);
+  }
+};
+
 struct UVVertex {
   /* Loop index of the loop vertex in the original mesh. */
   uint64_t loop;
-  uint64_t v;
+  MeshVertex *vertex;
   /* Position in uv space. */
   float2 uv;
+
+  explicit UVVertex()
+  {
+  }
+
+  explicit UVVertex(const MeshUVVert &vert) : loop(vert.loop), vertex(vert.vertex), uv(vert.uv)
+  {
+  }
 };
 
 struct UVEdge {
   UVVertex vertices[2];
-  int64_t adjacent_uv_primitive = -1;
+  Vector<UVPrimitive *, 2> uv_primitives;
 
   bool has_shared_edge(const UVEdge &other) const
   {
@@ -45,9 +192,15 @@ struct UVEdge {
            (vertices[0].uv == other.vertices[1].uv && vertices[1].uv == other.vertices[0].uv);
   }
 
+  bool has_shared_edge(const MeshUVVert &v1, const MeshUVVert &v2) const
+  {
+    return (vertices[0].uv == v1.uv && vertices[1].uv == v2.uv) ||
+           (vertices[0].uv == v2.uv && vertices[1].uv == v1.uv);
+  }
+
   bool is_border_edge() const
   {
-    return adjacent_uv_primitive == -1;
+    return uv_primitives.size() == 1;
   }
 };
 
@@ -55,49 +208,48 @@ struct UVPrimitive {
   /**
    * Index of the primitive in the original mesh.
    */
-  uint64_t index;
-  UVEdge edges[3];
+  MeshPrimitive *primitive;
+  Vector<UVEdge *, 3> edges;
 
-  explicit UVPrimitive(uint64_t prim_index) : index(prim_index)
+  explicit UVPrimitive(MeshPrimitive *primitive) : primitive(primitive)
   {
   }
 
-  explicit UVPrimitive(uint64_t prim_index,
-                       const MLoopTri &tri,
-                       const MLoop *mloop,
-                       const MLoopUV *mloopuv)
-      : index(prim_index)
+  Vector<std::pair<UVEdge *, UVEdge *>> shared_edges(UVPrimitive &other)
   {
+    Vector<std::pair<UVEdge *, UVEdge *>> result;
     for (int i = 0; i < 3; i++) {
-      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];
-      edges[i].vertices[0].v = mloop[tri.tri[i]].v;
-      edges[i].vertices[1].v = mloop[tri.tri[(i + 1) % 3]].v;
+      for (int j = 0; j < 3; j++) {
+        if (edges[i]->has_shared_edge(*other.edges[j])) {
+          result.append(std::pair<UVEdge *, UVEdge *>(edges[i], other.edges[j]));
+        }
+      }
     }
+    return result;
   }
 
-  Vector<std::pair<UVEdge &, UVEdge &>> shared_edges(UVPrimitive &other)
+  bool has_shared_edge(const UVPrimitive &other) const
   {
-    Vector<std::pair<UVEdge &, UVEdge &>> result;
     for (int i = 0; i < 3; i++) {
       for (int j = 0; j < 3; j++) {
-        if (edges[i].has_shared_edge(other.edges[j])) {
-          result.append(std::pair<UVEdge &, UVEdge &>(edges[i], other.edges[j]));
+        if (edges[i]->has_shared_edge(*other.edges[j])) {
+          return true;
         }
       }
     }
-    return result;
+    return false;
   }
 
-  bool has_shared_edge(const UVPrimitive &other) const
+  bool has_shared_edge(const MeshPrimitive &primitive) const
   {
-    for (int i = 0; i < 3; i++) {
-      for (int j = 0; j < 3; j++) {
-        if (edges[i].has_shared_edge(other.edges[j])) {
+    for (const UVEdge *uv_edge : edges) {
+      const MeshUVVert *v1 = &primitive.vertices.last();
+      for (int i = 0; i < primitive.vertices.size(); i++) {
+        const MeshUVVert *v2 = &primitive.vertices[i];
+        if (uv_edge->has_shared_edge(*v1, *v2)) {
           return true;
         }
+        v1 = v2;
       }
     }
     return false;
@@ -108,7 +260,7 @@ struct UVBorderVert {
   float2 uv;
 
   /* Index of this vert in the vertices of the original mesh. */
-  int64_t vert;
+  MeshVertex *vertex;
 
   /* Indexes of connected border verts. */
   int64_t index;
@@ -124,7 +276,7 @@ struct UVBorderVert {
     bool extendable : 1;
   } flags;
 
-  explicit UVBorderVert(float2 &uv, int64_t vert) : uv(uv), vert(vert)
+  explicit UVBorderVert(float2 &uv, MeshVertex *vertex) : uv(uv), vertex(vertex)
   {
     flags.extendable = true;
   }
@@ -160,38 +312,85 @@ struct UVBorder {
 };
 
 struct UVIsland {
-  Vector<UVPrimitive> primitives;
+  Vector<UVVertex> uv_vertices;
+  Vector<UVEdge> uv_edges;
+  Vector<UVPrimitive> uv_primitives;
   /**
    * List of borders of this island. There can be multiple borders per island as a border could be
    * completely encapsulated by another one.
    */
   Vector<UVBorder> borders;
 
-  UVIsland(const UVPrimitive &primitive)
+  UVIsland()
+  {
+    uv_vertices.reserve(100000);
+    uv_edges.reserve(100000);
+    uv_primitives.reserve(100000);
+  }
+
+  UVPrimitive *add_primitive(MeshPrimitive &primitive)
+  {
+    UVPrimitive uv_primitive(&primitive);
+    uv_primitives.append(uv_primitive);
+    UVPrimitive *uv_primitive_ptr = &uv_primitives.last();
+    for (MeshEdge *edge : primitive.edges) {
+      const MeshUVVert &v1 = primitive.get_uv_vert(edge->vert1);
+      const MeshUVVert &v2 = primitive.get_uv_vert(edge->vert2);
+      UVEdge uv_edge_template;
+      uv_edge_template.vertices[0] = UVVertex(v1);
+      uv_edge_template.vertices[1] = UVVertex(v2);
+      UVEdge *uv_edge = lookup_or_create(uv_edge_template);
+      uv_primitive_ptr->edges.append(uv_edge);
+      uv_edge->uv_primitives.append(uv_primitive_ptr);
+    }
+    return uv_primitive_ptr;
+  }
+
+  UVEdge *lookup_or_create(const UVEdge &edge)
   {
-    append(primitive);
+    for (UVEdge &uv_edge : uv_edges) {
+      if (uv_edge.has_shared_edge(edge)) {
+        return &uv_edge;
+      }
+    }
+
+    uv_edges.append(edge);
+    UVEdge *result = &uv_edges.last();
+    result->uv_primitives.clear();
+    return result;
   }
 
   /** Initialize the border attribute. */
-  void extract_border(const MLoop *mloop);
+  void extract_border();
   /** Iterative extend border to fit the mask. */
   void extend_border(const UVIslandsMask &mask,
                      const short island_index,
-                     const MLoopTri *looptris,
-                     const int64_t looptri_len,
-                     const MLoop *mloop,
-                     const MVert *mvert);
+                     const MeshData &mesh_data);
 
  private:
   void append(const UVPrimitive &primitive)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list