[Bf-blender-cvs] [b2d30c95f89] refactor-mesh-uv-map-generic: Merge branch 'master' into refactor-mesh-uv-map-generic

Martijn Versteegh noreply at git.blender.org
Tue Dec 6 14:03:47 CET 2022


Commit: b2d30c95f8954082a382dfa36c7a2704de33a8ef
Author: Martijn Versteegh
Date:   Tue Dec 6 13:59:19 2022 +0100
Branches: refactor-mesh-uv-map-generic
https://developer.blender.org/rBb2d30c95f8954082a382dfa36c7a2704de33a8ef

Merge branch 'master' into refactor-mesh-uv-map-generic

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



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

diff --cc release/scripts/addons
index 63e1e6227af,0b0052bd53a..90c87dd771e
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 63e1e6227af42c1090fadc116e19b604d734a56c
 -Subproject commit 0b0052bd53ad8249ed07dfb87705c338af698bde
++Subproject commit 90c87dd771e027e0ffa157a0e294399bfd605d99
diff --cc source/blender/blenkernel/BKE_uv_islands.hh
index 00000000000,406ecf39b71..3dc842bd510
mode 000000,100644..100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@@ -1,0 -1,746 +1,746 @@@
+ /* SPDX-License-Identifier: GPL-2.0-or-later */
+ 
+ #pragma once
+ 
+ #include <fstream>
+ #include <optional>
+ 
+ #include "BLI_array.hh"
+ #include "BLI_edgehash.h"
+ #include "BLI_float3x3.hh"
+ #include "BLI_map.hh"
+ #include "BLI_math.h"
+ #include "BLI_math_vec_types.hh"
+ #include "BLI_rect.h"
+ #include "BLI_vector.hh"
+ #include "BLI_vector_list.hh"
+ 
+ #include "DNA_meshdata_types.h"
+ 
+ namespace blender::bke::uv_islands {
+ 
+ struct MeshEdge;
+ struct MeshPrimitive;
+ struct UVBorder;
+ struct UVEdge;
+ struct UVIslands;
+ struct UVIslandsMask;
+ struct UVPrimitive;
+ struct UVPrimitiveEdge;
+ struct UVVertex;
+ 
+ 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 *, 3> edges;
+   Vector<MeshUVVert, 3> vertices;
+ 
+   /**
+    * UV island this primitive belongs to. This is used to speed up the initial uv island
+    * extraction, but should not be used when extending uv islands.
+    */
+   int64_t uv_island_id;
+ 
+   MeshUVVert *get_other_uv_vertex(const MeshVertex *v1, const MeshVertex *v2)
+   {
+     BLI_assert(vertices[0].vertex == v1 || vertices[1].vertex == v1 || vertices[2].vertex == v1);
+     BLI_assert(vertices[0].vertex == v2 || vertices[1].vertex == v2 || vertices[2].vertex == v2);
+     for (MeshUVVert &uv_vertex : vertices) {
+       if (uv_vertex.vertex != v1 && uv_vertex.vertex != v2) {
+         return &uv_vertex;
+       }
+     }
+     return nullptr;
+   }
+ 
+   rctf uv_bounds() const;
+ 
+   bool has_shared_uv_edge(const MeshPrimitive *other) const
+   {
+     int shared_uv_verts = 0;
+     for (const MeshUVVert &vert : vertices) {
+       for (const MeshUVVert &other_vert : other->vertices) {
+         if (vert.uv == other_vert.uv) {
+           shared_uv_verts += 1;
+         }
+       }
+     }
+     return shared_uv_verts >= 2;
+   }
+ };
+ 
+ /**
+  * MeshData contains input geometry data converted in a list of primitives, edges and vertices for
+  * quick access for both local space and uv space.
+  */
+ struct MeshData {
+  public:
+   const MLoopTri *looptri;
+   const int64_t looptri_len;
+   const int64_t vert_len;
+   const MLoop *mloop;
 -  const MLoopUV *mloopuv;
++  const float2 *mloopuv;
+ 
+  public:
+   Vector<MeshPrimitive> primitives;
+   Vector<MeshEdge> edges;
+   Vector<MeshVertex> vertices;
+   /** Total number of uv islands detected. */
+   int64_t uv_island_len;
+ 
+   explicit MeshData(const MLoopTri *looptri,
+                     const int64_t looptri_len,
+                     const int64_t vert_len,
+                     const MLoop *mloop,
 -                    const MLoopUV *mloopuv)
++                    const float2 *mloopuv)
+       : looptri(looptri),
+         looptri_len(looptri_len),
+         vert_len(vert_len),
+         mloop(mloop),
+         mloopuv(mloopuv)
+   {
+     init_vertices();
+     init_primitives();
+     init_edges();
+     init_primitive_uv_island_ids();
+   }
+ 
+   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;
++        uv_vert.uv = mloopuv[uv_vert.loop];
+         primitive.vertices.append(uv_vert);
+       }
+       primitives.append(primitive);
+     }
+   }
+ 
+   void init_edges()
+   {
+     edges.reserve(looptri_len * 2);
+     EdgeHash *eh = BLI_edgehash_new_ex(__func__, looptri_len * 3);
+     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;
+         /* TODO: Use lookup_ptr to be able to store edge 0. */
+         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 + 1));
+           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) - 1;
+         }
+ 
+         MeshEdge *edge = &edges[edge_index];
+         edge->primitives.append(&primitive);
+         primitive.edges.append(edge);
+       }
+     }
+     BLI_edgehash_free(eh, nullptr);
+   }
+ 
+   static const int64_t INVALID_UV_ISLAND_ID = -1;
+   /**
+    * NOTE: doesn't support weird topology where unconnected mesh primitives share the same uv
+    * island. For a accurate implementation we should use implement an uv_prim_lookup.
+    */
+   static void extract_uv_neighbors(Vector<MeshPrimitive *> &prims_to_add, MeshPrimitive *primitive)
+   {
+     for (MeshEdge *edge : primitive->edges) {
+       for (MeshPrimitive *other_primitive : edge->primitives) {
+         if (primitive == other_primitive) {
+           continue;
+         }
+         if (other_primitive->uv_island_id != MeshData::INVALID_UV_ISLAND_ID) {
+           continue;
+         }
+ 
+         if (primitive->has_shared_uv_edge(other_primitive)) {
+           prims_to_add.append(other_primitive);
+         }
+       }
+     }
+   }
+ 
+   void init_primitive_uv_island_ids()
+   {
+     for (MeshPrimitive &primitive : primitives) {
+       primitive.uv_island_id = INVALID_UV_ISLAND_ID;
+     }
+ 
+     int64_t uv_island_id = 0;
+     Vector<MeshPrimitive *> prims_to_add;
+     for (MeshPrimitive &primitive : primitives) {
+       /* Early exit when uv island id is already extracted during uv neighbor extractions. */
+       if (primitive.uv_island_id != INVALID_UV_ISLAND_ID) {
+         continue;
+       }
+ 
+       prims_to_add.append(&primitive);
+       while (!prims_to_add.is_empty()) {
+         MeshPrimitive *primitive = prims_to_add.pop_last();
+         primitive->uv_island_id = uv_island_id;
+         extract_uv_neighbors(prims_to_add, primitive);
+       }
+       uv_island_id++;
+     }
+     uv_island_len = uv_island_id;
+   }
+ };
+ 
+ struct UVVertex {
+   MeshVertex *vertex;
+   /* Position in uv space. */
+   float2 uv;
+ 
+   /* uv edges that share this UVVertex. */
+   Vector<UVEdge *> uv_edges;
+ 
+   struct {
+     bool is_border : 1;
+     bool is_extended : 1;
+   } flags;
+ 
+   explicit UVVertex()
+   {
+     flags.is_border = false;
+     flags.is_extended = false;
+   }
+ 
+   explicit UVVertex(const MeshUVVert &vert) : vertex(vert.vertex), uv(vert.uv)
+   {
+     flags.is_border = false;
+     flags.is_extended = false;
+   }
+ };
+ 
+ struct UVEdge {
+   std::array<UVVertex *, 2> vertices;
+   Vector<UVPrimitive *, 2> uv_primitives;
+ 
+   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 has_shared_edge(const UVVertex &v1, const UVVertex &v2) const
+   {
+     return (vertices[0]->uv == v1.uv && vertices[1]->uv == v2.uv) ||
+            (vertices[0]->uv == v2.uv && vertices[1]->uv == v1.uv);
+   }
+ 
+   bool has_shared_edge(const UVEdge &other) const
+   {
+     return has_shared_edge(*other.vertices[0], *other.vertices[1]);
+   }
+ 
+   bool has_same_vertices(const MeshVertex &vert1, const MeshVertex &vert2) const
+   {
+     return (vertices[0]->vertex == &vert1 && vertices[1]->vertex == &vert2) ||
+            (vertices[0]->vertex == &vert2 && vertices[1]->vertex == &vert1);
+   }
+ 
+   bool has_same_uv_vertices(const UVEdge &other) const
+   {
+     return has_shared_edge(other) &&
+            has_same_vertices(*other.vertices[0]->vertex, *other.vertices[1]->vertex);
+     ;
+   }
+ 
+   bool has_same_vertices(const MeshEdge &edge) const
+   {
+     return has_same_vertices(*edge.vert1, *edge.vert2);
+   }
+ 
+   bool is_border_edge() const
+   {
+     return uv_primitives.size() == 1;
+   }
+ 
+   void append_to_uv_vertices()
+   {
+     for (UVVertex *vertex : vertices) {
+       vertex->uv_edges.append_non_duplicates(this);
+     }
+   }
+ 
+   UVVertex *get_other_uv_vertex(const MeshVertex *vertex)
+   {
+     if (vertices[0]->vertex == vertex) {
+       return vertices[1];
+     }
+     return vertices[0];
+   }
+ };
+ 
+ struct UVPrimitive {
+   /**
+    * Index of the primitive in the original mesh.
+    */
+   MeshPrimitive *primitive;
+   Vector<UVEdge *, 3> edges;
+ 
+   explicit UVPrimitive(MeshPrimitive *primitive) : primitive(primitive)
+   {
+   }
+ 
+   void append_to_uv_edges()
+   {
+     for (UVEdge *uv_edge : edges) {
+       uv_edge->uv_primitives.append_non_du

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list