[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