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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs