Commit: b9177014b6f0081534635347153a0a9380a1d018
Author: Jeroen Bakker
Date:   Thu Jan 12 08:35:14 2023 +0100
Branches: master
https://developer.blender.org/rBb9177014b6f0081534635347153a0a9380a1d018

3D Texturing: Replace pointers with indexes in pbvh_uv_islands

Replace the pointers in the MeshEdge with indexes, removing MeshPrimitive and 
MeshVertex.

Code cleanup proposed by the geometry nodes to make the data structures more 
reusable by
other areas of Blender as well. Old implementation was to focused to the 
texture painting.

Initial the idea was to do the same with the data structures in UVIslands, but 
there some
concerns were raised that requires a different design than expected from a 
clean-up patch.

Concerns raised about converting UVIslands:
* Maps between UVPrimitive, UVEdge and UVVertex will be stored inside the 
UVIsland.
   During UVIsland extraction detected islands can be merged. When they are 
merged all
   Indexes should be updated.
* It is not possible to pre-allocate all buffers as they grow, what will lead 
to more re-allocations. The current
   implementation uses a VectorList to ensure that re-allocations don't require 
the data to be
   moved to the newly allocated memory. We could store some information about 
last used
   sizes in runtime data to reduce the re-allocation overhead.
* Solution would require index based access inside a VectorList, which might 
increase the
   complexity.
* UVIslands during 3d texturing is used as intermediate data, the final data is 
stored as PackedPixelRows.
   We could proceed converting UVIslands as well, but that would lower the 
performance noticeably.
   3D texturing has performance requirements, so when doing so we should make 
sure that
   it matches that as well.

Reviewed By: HooglyBoogly

Maniphest Tasks: T101740

Differential Revision: https://developer.blender.org/D16752

===================================================================

M       source/blender/blenkernel/BKE_pbvh_pixels.hh
M       source/blender/blenkernel/intern/pbvh_pixels.cc
M       source/blender/blenkernel/intern/pbvh_uv_islands.cc
M       source/blender/blenkernel/intern/pbvh_uv_islands.hh

===================================================================

diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh 
b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index a6b5bb565c5..b6e006805ec 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -51,7 +51,7 @@ struct PaintGeometryPrimitives {
 
   int64_t mem_size() const
   {
-    return size() * sizeof(int3);
+    return this->vert_indices.as_span().size_in_bytes();
   }
 };
 
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc 
b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 884da8b89f0..39651349ae9 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later
  * Copyright 2022 Blender Foundation. All rights reserved. */
 
+#include "BKE_attribute.hh"
 #include "BKE_customdata.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
@@ -105,10 +106,10 @@ static void update_geom_primitives(PBVH &pbvh, const 
uv_islands::MeshData &mesh_
 {
   PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
   pbvh_data.clear_data();
-  for (const uv_islands::MeshPrimitive &mesh_primitive : mesh_data.primitives) 
{
-    pbvh_data.geom_primitives.append(int3(mesh_primitive.vertices[0].vertex->v,
-                                          mesh_primitive.vertices[1].vertex->v,
-                                          
mesh_primitive.vertices[2].vertex->v));
+  for (const MLoopTri &looptri : mesh_data.looptris) {
+    pbvh_data.geom_primitives.append(int3(mesh_data.loops[looptri.tri[0]].v,
+                                          mesh_data.loops[looptri.tri[1]].v,
+                                          mesh_data.loops[looptri.tri[2]].v));
   }
 }
 
@@ -134,7 +135,7 @@ struct UVPrimitiveLookup {
       for (VectorList<uv_islands::UVPrimitive>::UsedVector &uv_primitives :
            uv_island.uv_primitives) {
         for (uv_islands::UVPrimitive &uv_primitive : uv_primitives) {
-          lookup[uv_primitive.primitive->index].append_as(Entry(&uv_primitive, 
uv_island_index));
+          lookup[uv_primitive.primitive_i].append_as(Entry(&uv_primitive, 
uv_island_index));
         }
       }
       uv_island_index++;
@@ -143,11 +144,11 @@ struct UVPrimitiveLookup {
 };
 
 struct EncodePixelsUserData {
+  const uv_islands::MeshData *mesh_data;
   Image *image;
   ImageUser *image_user;
   PBVH *pbvh;
   Vector<PBVHNode *> *nodes;
-  const float2 *ldata_uv;
   const uv_islands::UVIslandsMask *uv_masks;
   /** Lookup to retrieve the UV primitives based on the primitive index. */
   const UVPrimitiveLookup *uv_primitive_lookup;
@@ -158,6 +159,7 @@ static void do_encode_pixels(void *__restrict userdata,
                              const TaskParallelTLS *__restrict /*tls*/)
 {
   EncodePixelsUserData *data = static_cast<EncodePixelsUserData *>(userdata);
+  const uv_islands::MeshData &mesh_data = *data->mesh_data;
   Image *image = data->image;
   ImageUser image_user = *data->image_user;
   PBVHNode *node = (*data->nodes)[n];
@@ -183,9 +185,9 @@ static void do_encode_pixels(void *__restrict userdata,
            data->uv_primitive_lookup->lookup[geom_prim_index]) {
         uv_islands::UVBorder uv_border = entry.uv_primitive->extract_border();
         float2 uvs[3] = {
-            entry.uv_primitive->get_uv_vertex(0)->uv - tile_offset,
-            entry.uv_primitive->get_uv_vertex(1)->uv - tile_offset,
-            entry.uv_primitive->get_uv_vertex(2)->uv - tile_offset,
+            entry.uv_primitive->get_uv_vertex(mesh_data, 0)->uv - tile_offset,
+            entry.uv_primitive->get_uv_vertex(mesh_data, 1)->uv - tile_offset,
+            entry.uv_primitive->get_uv_vertex(mesh_data, 2)->uv - tile_offset,
         };
         const float minv = clamp_f(min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 
0.0f, 1.0f);
         const int miny = floor(minv * image_buffer->y);
@@ -355,16 +357,16 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image 
*image, ImageUser *image
     return;
   }
 
-  const float2 *ldata_uv = static_cast<const float2 *>(
-      CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2));
-  if (ldata_uv == nullptr) {
+  const StringRef active_uv_name = 
CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
+  if (active_uv_name.is_empty()) {
     return;
   }
 
-  uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim},
-                                 {pbvh->mloop, mesh->totloop},
-                                 pbvh->totvert,
-                                 {ldata_uv, mesh->totloop});
+  const AttributeAccessor attributes = mesh->attributes();
+  const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, 
ATTR_DOMAIN_CORNER);
+
+  uv_islands::MeshData mesh_data(
+      {pbvh->looptri, pbvh->totprim}, {pbvh->mloop, mesh->totloop}, 
pbvh->totvert, uv_map);
   uv_islands::UVIslands islands(mesh_data);
 
   uv_islands::UVIslandsMask uv_masks;
@@ -380,20 +382,20 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image 
*image, ImageUser *image
                       ushort2(tile_buffer->x, tile_buffer->y));
     BKE_image_release_ibuf(image, tile_buffer, nullptr);
   }
-  uv_masks.add(islands);
+  uv_masks.add(mesh_data, islands);
   uv_masks.dilate(image->seam_margin);
 
   islands.extract_borders();
-  islands.extend_borders(uv_masks);
+  islands.extend_borders(mesh_data, uv_masks);
   update_geom_primitives(*pbvh, mesh_data);
 
   UVPrimitiveLookup uv_primitive_lookup(mesh_data.looptris.size(), islands);
 
   EncodePixelsUserData user_data;
+  user_data.mesh_data = &mesh_data;
   user_data.pbvh = pbvh;
   user_data.image = image;
   user_data.image_user = image_user;
-  user_data.ldata_uv = ldata_uv;
   user_data.nodes = &nodes_to_update;
   user_data.uv_primitive_lookup = &uv_primitive_lookup;
   user_data.uv_masks = &uv_masks;
diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc 
b/source/blender/blenkernel/intern/pbvh_uv_islands.cc
index 5f4a888805e..aac61750d47 100644
--- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc
+++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc
@@ -28,27 +28,40 @@ static void uv_primitive_append_to_uv_vertices(UVPrimitive 
&uv_primitive)
 }
 
 /* -------------------------------------------------------------------- */
-/** \name MeshPrimitive
+/** \name Mesh Primitives
  * \{ */
 
-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 (!ELEM(uv_vertex.vertex, v1, v2)) {
-      return &uv_vertex;
+int primitive_get_other_uv_vertex(const MeshData &mesh_data,
+                                  const MLoopTri &looptri,
+                                  const int v1,
+                                  const int v2)
+{
+  const Span<MLoop> mesh_loops = mesh_data.loops;
+  BLI_assert(ELEM(v1,
+                  mesh_loops[looptri.tri[0]].v,
+                  mesh_loops[looptri.tri[1]].v,
+                  mesh_loops[looptri.tri[2]].v));
+  BLI_assert(ELEM(v2,
+                  mesh_loops[looptri.tri[0]].v,
+                  mesh_loops[looptri.tri[1]].v,
+                  mesh_loops[looptri.tri[2]].v));
+  for (const int loop : looptri.tri) {
+    const int vert = mesh_loops[loop].v;
+    if (vert != v1 && vert != v2) {
+      return vert;
     }
   }
-  return nullptr;
+  return -1;
 }
 
-bool MeshPrimitive::has_shared_uv_edge(const MeshPrimitive *other) const
+bool primitive_has_shared_uv_edge(const Span<float2> uv_map,
+                                  const MLoopTri &looptri,
+                                  const MLoopTri &other)
 {
   int shared_uv_verts = 0;
-  for (const MeshUVVert &vert : vertices) {
-    for (const MeshUVVert &other_vert : other->vertices) {
-      if (vert.uv == other_vert.uv) {
+  for (const int loop : looptri.tri) {
+    for (const int other_loop : other.tri) {
+      if (uv_map[loop] == uv_map[other_loop]) {
         shared_uv_verts += 1;
       }
     }
@@ -56,33 +69,34 @@ bool MeshPrimitive::has_shared_uv_edge(const MeshPrimitive 
*other) const
   return shared_uv_verts >= 2;
 }
 
-static const MeshUVVert &get_uv_vert(const MeshPrimitive &mesh_primitive, 
const MeshVertex *vert)
+static int get_uv_loop(const MeshData &mesh_data, const MLoopTri &looptri, 
const int vert)
 {
-  for (const MeshUVVert &uv_vert : mesh_primitive.vertices) {
-    if (uv_vert.vertex == vert) {
-      return uv_vert;
+  for (const int loop : looptri.tri) {
+    if (mesh_data.loops[loop].v == vert) {
+      return loop;
     }
   }
   BLI_assert_unreachable();
-  return mesh_primitive.vertices[0];
+  return looptri.tri[0];
 }
 
-static bool has_vertex(const MeshPrimitive &mesh_primitive, const MeshVertex 
&mesh_vertex)
+static bool has_vertex(const MeshData &mesh_data, const MLoopTri &looptri, 
const int vert)
 {
   for (int i = 0; i < 3; i++) {
-    if (mesh_primitive.vertices[i].vertex == &mesh_vertex) {
+    const int vert_i = mesh_data.loops[looptri.tri[i]].v;
+    if (vert_i == vert) {
       return true;
     }
   }
   return false;
 }
 
-rctf MeshPrimitive::uv_bounds() const
+rctf primitive_uv_bounds(const MLoopTri &looptri, const Span<float2> uv_map)
 {
   rctf result;
   BLI_rctf_init_minmax(&result);
-  for (const MeshUVVert &uv_vertex : vertices) {
-    BLI_rctf_do_minmax_v(&result, uv_vertex.uv);
+  for (const int loop : looptri.tri) {
+    BLI_rctf_do_minmax_v(&result, uv_map[loop]);
   }
   return result;
 }
@@ -93,43 +107,13 @@ rctf MeshPrimitive::uv_bounds() const
 /** \name MeshData
  * \{ */
 
-static void mesh_data_init_vertices(MeshData &mesh_data)
-{
-  mesh_data.vertices.reserve(mesh_data.verts_num);
-  for (int64_t i = 0; i < mesh_data.verts_num; 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.looptris.size());
-  for (int64_t i = 0; i < mesh_data.looptris.size(); i++) {
-    const MLoopTri &tri = mesh_data.looptris[i];
-    MeshPri

@@ 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

Reply via email to