[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