[Bf-blender-cvs] [7b4bc72a49b] temp-T97352-3d-texturing-seam-bleeding: Remove BMesh.
Jeroen Bakker
noreply at git.blender.org
Fri Apr 22 13:51:50 CEST 2022
Commit: 7b4bc72a49bae77477ecf93ceec11ec53e8d8915
Author: Jeroen Bakker
Date: Fri Apr 22 13:51:45 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding
https://developer.blender.org/rB7b4bc72a49bae77477ecf93ceec11ec53e8d8915
Remove BMesh.
===================================================================
M source/blender/blenkernel/BKE_pbvh_pixels.hh
M source/blender/blenkernel/intern/pbvh_pixels.cc
M source/blender/blenkernel/intern/pbvh_pixels_seams.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index 07c17279a44..6d4f5db819c 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -210,7 +210,7 @@ NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node);
void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
void BKE_pbvh_pixels_rebuild_seams(
- PBVH *pbvh, Mesh *me, Image *image, ImageUser *image_user, int cd_loop_uv_offset);
+ PBVH *pbvh, const Mesh *me, Image *image, ImageUser *image_user, const MLoopUV *ldata_uv);
void BKE_pbvh_pixels_fix_seams(PBVHNode *node, Image *image, ImageUser *image_user);
} // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index d3c1f71931a..a8a8a1c9325 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -323,8 +323,7 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
BKE_pbvh_parallel_range_settings(&settings, true, nodes_to_update.size());
BLI_task_parallel_range(0, nodes_to_update.size(), &user_data, do_encode_pixels, &settings);
- int cd_loop_uv_offset = CustomData_get_offset(&mesh->ldata, CD_MLOOPUV);
- BKE_pbvh_pixels_rebuild_seams(pbvh, mesh, image, image_user, cd_loop_uv_offset);
+ BKE_pbvh_pixels_rebuild_seams(pbvh, mesh, image, image_user, ldata_uv);
if (USE_WATERTIGHT_CHECK) {
apply_watertight_check(pbvh, image, image_user);
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index 685ed16372b..effa06d5588 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -11,56 +11,105 @@
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
+#include "BLI_edgehash.h"
#include "BLI_vector.hh"
-#include "bmesh.h"
-
#include "pbvh_intern.h"
-using BMLoopConnection = std::pair<BMLoop *, BMLoop *>;
-
namespace blender::bke::pbvh::pixels {
-/**
- * Find loops that are connected in 3d space, but not in uv space. Or loops that don't have any
- * connection at all.
- *
- * TODO better name would be to find loops that need uv seam fixes.
- */
-void find_connected_loops(BMesh *bm,
- const int cd_loop_uv_offset,
- Vector<BMLoopConnection> &r_connected,
- Vector<BMLoop *> &r_unconnected)
+struct EdgeLoop {
+ /** Loop indexes that form an edge. */
+ int l[2];
+};
+
+enum class EdgeCheckFlag {
+ /** No connecting edge loop found. */
+ Unconnected,
+ /** A connecting edge loop found. */
+ Connected,
+};
+
+struct EdgeCheck {
+ EdgeCheckFlag flag;
+ EdgeLoop first;
+ EdgeLoop second;
+};
+
+/** Do the two given EdgeLoops share the same uv coordinates. */
+bool share_uv(const MLoopUV *ldata_uvs, EdgeLoop &edge1, EdgeLoop &edge2)
+{
+ const float2 &uv_1_a = ldata_uvs[edge1.l[0]].uv;
+ const float2 &uv_1_b = ldata_uvs[edge1.l[1]].uv;
+ const float2 &uv_2_a = ldata_uvs[edge2.l[0]].uv;
+ const float2 &uv_2_b = ldata_uvs[edge2.l[1]].uv;
+ const float limit = 0.0001f;
+
+ return (compare_v2v2(uv_1_a, uv_2_a, limit) && compare_v2v2(uv_1_b, uv_2_b, limit)) ||
+ (compare_v2v2(uv_1_a, uv_2_b, limit) && compare_v2v2(uv_1_b, uv_2_a, limit));
+}
+
+/** Make a list of connected and unconnected edgeloops that require UV Seam fixes. */
+void find_edges_that_need_fixing(const Mesh *mesh,
+ const MLoopUV *ldata_uvs,
+ Vector<std::pair<EdgeLoop, EdgeLoop>> &r_connected,
+ Vector<EdgeLoop> &r_unconnected)
{
- BMEdge *e;
- BMIter eiter;
- BMLoop *l;
- BMIter liter;
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- bool first = true;
- bool connection_found = false;
- BMLoop *l_first;
-
- BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- if (first) {
- l_first = l;
- first = false;
+ EdgeHash *eh = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh->totpoly));
+
+ for (int p = 0; p < mesh->totpoly; p++) {
+ MPoly &mpoly = mesh->mpoly[p];
+ int prev_l = mpoly.loopstart + mpoly.totloop - 1;
+ for (int l = 0; l < mpoly.totloop; l++) {
+ MLoop &prev_mloop = mesh->mloop[prev_l];
+ int current_l = mpoly.loopstart + l;
+ MLoop &mloop = mesh->mloop[current_l];
+
+ void **value_ptr;
+
+ if (!BLI_edgehash_ensure_p(eh, prev_mloop.v, mloop.v, &value_ptr)) {
+ EdgeCheck *value = MEM_cnew<EdgeCheck>(__func__);
+ value->flag = EdgeCheckFlag::Unconnected;
+ value->first.l[0] = min_ii(prev_l, current_l);
+ value->first.l[1] = max_ii(prev_l, current_l);
+ *value_ptr = value;
}
else {
- connection_found = true;
- if (!BM_loop_uv_share_edge_check(l_first, l, cd_loop_uv_offset)) {
- /* Edge detected that is connected in 3d space, but not in uv space. */
- r_connected.append(BMLoopConnection(l_first, l));
- r_connected.append(BMLoopConnection(l, l_first));
- break;
+ EdgeCheck *value = static_cast<EdgeCheck *>(*value_ptr);
+ if (value->flag == EdgeCheckFlag::Unconnected) {
+ value->flag = EdgeCheckFlag::Connected;
+ value->second.l[0] = min_ii(prev_l, current_l);
+ value->second.l[1] = max_ii(prev_l, current_l);
}
}
+
+ prev_l = current_l;
}
- if (!connection_found) {
- BLI_assert(!first);
- r_unconnected.append(l_first);
+ }
+
+ EdgeHashIterator iter;
+ BLI_edgehashIterator_init(&iter, eh);
+ while (!BLI_edgehashIterator_isDone(&iter)) {
+ EdgeCheck *value = static_cast<EdgeCheck *>(BLI_edgehashIterator_getValue(&iter));
+ switch (value->flag) {
+ case EdgeCheckFlag::Unconnected: {
+ r_unconnected.append(value->first);
+ break;
+ }
+ case EdgeCheckFlag::Connected: {
+ // check for uv space to add to r_connected
+ if (!share_uv(ldata_uvs, value->first, value->second)) {
+ r_connected.append(std::pair<EdgeLoop, EdgeLoop>(value->first, value->second));
+ r_connected.append(std::pair<EdgeLoop, EdgeLoop>(value->second, value->first));
+ }
+ break;
+ }
}
+
+ BLI_edgehashIterator_step(&iter);
}
+
+ BLI_edgehash_free(eh, MEM_freeN);
}
struct PixelInfo {
@@ -239,7 +288,6 @@ static void add_seam_fix(PBVHNode &node,
/** \name Build fixes for connected edges.
* \{ */
-
static void build_fixes(PBVH &pbvh,
Bitmap &bitmap,
const rcti &uvbounds,
@@ -281,7 +329,7 @@ static void build_fixes(PBVH &pbvh,
* difference.
*/
float2 other_closest_point;
- interp_v2_v2v2(other_closest_point, luv_b_2.uv, luv_b_1.uv, lambda);
+ interp_v2_v2v2(other_closest_point, luv_b_1.uv, luv_b_2.uv, lambda);
float2 direction_b;
sub_v2_v2v2(direction_b, luv_b_2.uv, luv_b_1.uv);
float2 perpedicular_b(direction_b.y, -direction_b.x);
@@ -323,28 +371,23 @@ static void build_fixes(PBVH &pbvh,
}
static void build_fixes(PBVH &pbvh,
- const Vector<BMLoopConnection> &connected,
+ const Vector<std::pair<EdgeLoop, EdgeLoop>> &connected,
Bitmaps &bitmaps,
- const int cd_loop_uv_offset)
+ const MLoopUV *ldata_uvs)
{
- for (const BMLoopConnection &pair : connected) {
+ for (const std::pair<EdgeLoop, EdgeLoop> &pair : connected) {
// determine bounding rect in uv space + margin of 1;
rctf uvbounds;
BLI_rctf_init_minmax(&uvbounds);
- MLoopUV *luv_a_1 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(pair.first, cd_loop_uv_offset));
- MLoopUV *luv_a_2 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(pair.first->next, cd_loop_uv_offset));
- BLI_rctf_do_minmax_v(&uvbounds, luv_a_1->uv);
- BLI_rctf_do_minmax_v(&uvbounds, luv_a_2->uv);
+ const MLoopUV &luv_a_1 = ldata_uvs[pair.first.l[0]];
+ const MLoopUV &luv_a_2 = ldata_uvs[pair.first.l[1]];
+ BLI_rctf_do_minmax_v(&uvbounds, luv_a_1.uv);
+ BLI_rctf_do_minmax_v(&uvbounds, luv_a_2.uv);
- MLoopUV *luv_b_1 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(pair.second, cd_loop_uv_offset));
- MLoopUV *luv_b_2 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(pair.second->next, cd_loop_uv_offset));
+ const MLoopUV &luv_b_1 = ldata_uvs[pair.second.l[0]];
+ const MLoopUV &luv_b_2 = ldata_uvs[pair.second.l[1]];
- const float scale_factor = len_v2v2(luv_b_1->uv, luv_b_2->uv) /
- len_v2v2(luv_a_1->uv, luv_a_2->uv);
+ const float scale_factor = len_v2v2(luv_b_1.uv, luv_b_2.uv) / len_v2v2(luv_a_1.uv, luv_a_2.uv);
for (Bitmap &bitmap : bitmaps.bitmaps) {
rcti uvbounds_i;
@@ -362,7 +405,7 @@ static void build_fixes(PBVH &pbvh,
bitmap.resolution[1] +
MARGIN;
- build_fixes(pbvh, bitmap, uvbounds_i, *luv_a_1, *luv_a_2, *luv_b_1, *luv_b_2, scale_factor);
+ build_fixes(pbvh, bitmap, uvbounds_i, luv_a_1, luv_a_2, luv_b_1, luv_b_2, scale_factor);
}
}
}
@@ -426,20 +469,18 @@ static void build_fixes(
}
static void build_fixes(PBVH &pbvh,
- const Vector<BMLoop *> &unconnected,
+ const Vector<EdgeLoop> &unconnected,
Bitmaps &bitmaps,
- const int cd_loop_uv_offset)
+ const MLoopUV *ldata_uv)
{
- for (const BMLoop *unconnected_loop : unconnected) {
+ for (const EdgeLoop &unconnected_loop : unconnected) {
// determine bounding rect in uv space + margin of 1;
rctf uvbounds;
BLI_rctf_init_minmax(&uvbounds);
- MLoopUV *luv_1 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(unconnected_loop, cd_loop_uv_offset));
- MLoopUV *luv_2 = static_cast<MLoopUV *>(
- BM_ELEM_CD_GE
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list