[Bf-blender-cvs] [bfc3f68f7fb] temp-T97352-3d-texturing-seam-bleeding-b2: Hiding internal methods from API.
Jeroen Bakker
noreply at git.blender.org
Tue Sep 20 15:23:01 CEST 2022
Commit: bfc3f68f7fba775667171a6f002a6bdae982aef9
Author: Jeroen Bakker
Date: Tue Sep 20 14:34:53 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rBbfc3f68f7fba775667171a6f002a6bdae982aef9
Hiding internal methods from API.
===================================================================
M source/blender/blenkernel/BKE_uv_islands.hh
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 aa5c012919b..89efcdec69e 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -1,5 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+/** \file
+ * \ingroup bke
+ *
+ * UV Islands for PBVH Pixel extraction. When primitives share an edge they belong to the same UV
+ * Island.
+ *
+ * \note Similar to `uvedit_islands.cc`, but optimized for PBVH painting without using BMesh for
+ * performance reasons. Does not support manifold meshes or edges with more than 3 faces.
+ */
+
#pragma once
#include <fstream>
@@ -46,7 +56,7 @@ struct MeshEdge {
Vector<MeshPrimitive *> primitives;
};
-/** Represents a triangle in 3d space (MLoopTri) */
+/** Represents a triangle in 3d space (MLoopTri). */
struct MeshPrimitive {
int64_t index;
int64_t poly;
@@ -55,36 +65,18 @@ struct MeshPrimitive {
/**
* 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.
+ * extraction and should not be used afterwards.
*/
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;
- }
+ /** Get the vertex that is not given. Both given vertices must be part of the MeshPrimitive. */
+ MeshUVVert *get_other_uv_vertex(const MeshVertex *v1, const MeshVertex *v2);
+ /** Get the UV bounds for this MeshPrimitive. */
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;
- }
+ /** Is the given MeshPrimitive sharing an edge. */
+ bool has_shared_uv_edge(const MeshPrimitive *other) const;
};
/**
@@ -99,144 +91,18 @@ struct MeshData {
const MLoop *mloop;
const MLoopUV *mloopuv;
- public:
Vector<MeshPrimitive> primitives;
Vector<MeshEdge> edges;
Vector<MeshVertex> vertices;
- /** Total number of uv islands detected. */
+ /** Total number of found uv islands. */
int64_t uv_island_len;
+ public:
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();
- 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;
- 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;
-
- void **edge_index_ptr;
- int64_t edge_index;
- if (BLI_edgehash_ensure_p(eh, v1, v2, &edge_index_ptr)) {
- edge_index = POINTER_AS_INT(*edge_index_ptr) - 1;
- *edge_index_ptr = POINTER_FROM_INT(edge_index);
- }
- else {
- edge_index = edges.size();
- *edge_index_ptr = 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);
- }
-
- 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;
- }
+ const MLoopUV *mloopuv);
};
struct UVVertex {
diff --git a/source/blender/blenkernel/intern/uv_islands.cc b/source/blender/blenkernel/intern/uv_islands.cc
index 6ed8fd02f2c..d0ba8773289 100644
--- a/source/blender/blenkernel/intern/uv_islands.cc
+++ b/source/blender/blenkernel/intern/uv_islands.cc
@@ -9,6 +9,32 @@ namespace blender::bke::uv_islands {
/* -------------------------------------------------------------------- */
/** \name MeshPrimitive
* \{ */
+
+MeshUVVert *MeshPrimitive::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;
+}
+
+bool MeshPrimitive::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;
+}
+
static const MeshUVVert &get_uv_vert(const MeshPrimitive &mesh_primitive, const MeshVertex *vert)
{
for (const MeshUVVert &uv_vert : mesh_primitive.vertices) {
@@ -42,6 +68,148 @@ rctf MeshPrimitive::uv_bounds() const
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name MeshData
+ * \{ */
+
+static void mesh_data_init_vertices(MeshData &mesh_data)
+{
+ mesh_data.vertices.reserve(mesh_data.vert_len);
+ for (int64_t i = 0; i < mesh_data.vert_len; i++) {
+ MeshVertex vert;
+ vert.v = i;
+ mesh_data.vertices.append(vert);
+ }
+}
+
+static void mesh_data_init_primitives(MeshData &mesh_data)
+{
+ mesh_data.primitives.reserve(mesh_data.looptri_len);
+ for (int64_t i = 0; i < mesh_data.looptri_len; i++) {
+ const MLoopTri &tri = mesh_data.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 = &mesh_data.vertices[mesh_data.mloop[uv_vert.loop].v];
+ uv_vert.uv = mesh_data.mloopuv[uv_vert.loop].uv;
+ primitive.vertices.append(uv_vert);
+ }
+ mesh_data.primitives.append(primitive);
+ }
+}
+
+void mesh_data_init_edges(MeshData &mesh_data)
+{
+ mesh_data.edges.reserve(mesh_data.looptri_len * 2);
+ EdgeHash *eh = BLI_edgehash_new_ex(__func__, mesh_data.looptri_len * 3);
+ for (int64_t i = 0; i < mesh_data.looptri_len; i++) {
+ const MLoopTri &tri = mesh_data.looptri[i];
+ MeshPrimitive &primitive = mesh_data.primitives[i];
+ for (int j = 0; j < 3; j++) {
+ int v1 = mesh_data.mloop[tri.tri[j]].v;
+ int v2 = mesh_data.mloop[tri.tri[(j + 1) % 3]].v;
+
+ void **edge_index_ptr;
+ int64_t edge_index;
+ if (BLI_edgehash_ensure_p(eh, v1, v2, &edge_index_ptr)) {
+ edge_index = POINTER_AS_INT(*edge_index_ptr) - 1;
+ *edge_index_ptr = POINTER_FROM_INT(edge_index);
+ }
+ else {
+ edge_index = mesh_data.edges.size();
+ *edge_index_ptr = POINTER_FROM_INT(edge_index + 1);
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list