[Bf-blender-cvs] [9a2b06bad8f] temp-T96710-pbvh-pixels: PBVH Pixel extractor.

Jeroen Bakker noreply at git.blender.org
Wed Mar 30 14:26:48 CEST 2022


Commit: 9a2b06bad8f7a1771ffaf6c3bdc3063495bf6f25
Author: Jeroen Bakker
Date:   Wed Mar 30 14:26:42 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB9a2b06bad8f7a1771ffaf6c3bdc3063495bf6f25

PBVH Pixel extractor.

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

A	source/blender/blenkernel/BKE_image_wrappers.hh
M	source/blender/blenkernel/BKE_pbvh.h
A	source/blender/blenkernel/BKE_pbvh.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/pbvh_intern.h
A	source/blender/blenkernel/intern/pbvh_pixels.cc
M	source/blender/blenlib/BLI_math_vec_types.hh

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

diff --git a/source/blender/blenkernel/BKE_image_wrappers.hh b/source/blender/blenkernel/BKE_image_wrappers.hh
new file mode 100644
index 00000000000..291a79cb7ff
--- /dev/null
+++ b/source/blender/blenkernel/BKE_image_wrappers.hh
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup imbuf
+ */
+
+/* TODO: should be reused by image engine. */
+#pragma once
+
+#include "DNA_image_types.h"
+
+#include "BLI_math_vec_types.hh"
+
+namespace blender::bke::image {
+
+struct ImageTileWrapper {
+  ImageTile *image_tile;
+  ImageTileWrapper(ImageTile *image_tile) : image_tile(image_tile)
+  {
+  }
+
+  int get_tile_number() const
+  {
+    return image_tile->tile_number;
+  }
+
+  int2 get_tile_offset() const
+  {
+    return int2(get_tile_x_offset(), get_tile_y_offset());
+  }
+
+  int get_tile_x_offset() const
+  {
+    int tile_number = get_tile_number();
+    return (tile_number - 1001) % 10;
+  }
+
+  int get_tile_y_offset() const
+  {
+    int tile_number = get_tile_number();
+    return (tile_number - 1001) / 10;
+  }
+};
+}  // namespace blender::bke::image
\ No newline at end of file
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index eadbe52d091..e766e838a65 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -30,10 +30,13 @@ struct MLoopTri;
 struct MPoly;
 struct MVert;
 struct Mesh;
+struct MeshElemMap;
 struct PBVH;
 struct PBVHNode;
 struct SubdivCCG;
 struct TaskParallelSettings;
+struct Image;
+struct ImageUser;
 
 typedef struct PBVH PBVH;
 typedef struct PBVHNode PBVHNode;
@@ -46,6 +49,11 @@ typedef struct {
   float (*color)[4];
 } PBVHColorBufferNode;
 
+typedef struct PBVHPixelsNode {
+  /* points to blender::bke::pbvh::pixels::NodeData */
+  void *node_data;
+} PBVHPixelsNode;
+
 typedef enum {
   PBVH_Leaf = 1 << 0,
 
@@ -64,6 +72,7 @@ typedef enum {
 
   PBVH_UpdateTopology = 1 << 13,
   PBVH_UpdateColor = 1 << 14,
+  PBVH_TexLeaf = 1 << 15,
 } PBVHNodeFlags;
 
 typedef struct PBVHFrustumPlanes {
@@ -125,6 +134,20 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
                           struct BMLog *log,
                           int cd_vert_node_offset,
                           int cd_face_node_offset);
+
+void BKE_pbvh_build_pixels(PBVH *pbvh,
+                           const struct MeshElemMap *pmap,
+                           const struct MPoly *mpoly,
+                           const struct MLoop *mloop,
+                           struct MVert *verts,
+                           int totvert,
+                           struct CustomData *vdata,
+                           struct CustomData *ldata,
+                           struct CustomData *pdata,
+                           const struct MLoopTri *looptri,
+                           int totpoly,
+                           struct Image *image,
+                           struct ImageUser *image_user);
 void BKE_pbvh_free(PBVH *pbvh);
 
 /* Hierarchical Search in the BVH, two methods:
@@ -409,6 +432,26 @@ typedef struct PBVHVertexIter {
   bool visible;
 } PBVHVertexIter;
 
+#ifdef __cplusplus
+BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
+{
+  return static_cast<BMVert *>(src);
+}
+BLI_INLINE float *PBVH_cast_float_ptr(void *src)
+{
+  return static_cast<float *>(src);
+}
+#else
+BLI_INLINE struct BMVert *PBVH_cast_bmvert(void *src)
+{
+  return src;
+}
+BLI_INLINE float *PBVH_cast_float_ptr(void *src)
+{
+  return src;
+}
+#endif
+
 void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode);
 
 #define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \
@@ -467,11 +510,11 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
         } \
         else { \
           if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \
-            vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_unique_verts); \
+            vi.bm_vert = PBVH_cast_bmvert(BLI_gsetIterator_getKey(&vi.bm_unique_verts)); \
             BLI_gsetIterator_step(&vi.bm_unique_verts); \
           } \
           else { \
-            vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \
+            vi.bm_vert = PBVH_cast_bmvert(BLI_gsetIterator_getKey(&vi.bm_other_verts)); \
             BLI_gsetIterator_step(&vi.bm_other_verts); \
           } \
           vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \
@@ -481,7 +524,8 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
           vi.co = vi.bm_vert->co; \
           vi.fno = vi.bm_vert->no; \
           vi.index = BM_elem_index_get(vi.bm_vert); \
-          vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \
+          vi.mask = PBVH_cast_float_ptr( \
+              BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset)); \
         }
 
 #define BKE_pbvh_vertex_iter_end \
diff --git a/source/blender/blenkernel/BKE_pbvh.hh b/source/blender/blenkernel/BKE_pbvh.hh
new file mode 100644
index 00000000000..f2663056ed8
--- /dev/null
+++ b/source/blender/blenkernel/BKE_pbvh.hh
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_math_vec_types.hh"
+#include "BLI_rect.h"
+#include "BLI_vector.hh"
+
+#include "DNA_image_types.h"
+
+#include "BKE_image.h"
+#include "BKE_image_wrappers.hh"
+
+#include "IMB_imbuf_types.h"
+
+namespace blender::bke::pbvh::pixels {
+
+/* TODO(jbakker): move encoders to blenlib. */
+
+/* Stores a barycentric coordinate in a float2. */
+struct EncodedBarycentricCoord {
+  float2 encoded;
+
+  EncodedBarycentricCoord &operator=(const float3 decoded)
+  {
+    encoded = float2(decoded.x, decoded.y);
+    return *this;
+  }
+
+  float3 decode() const
+  {
+    return float3(encoded.x, encoded.y, 1.0 - encoded.x - encoded.y);
+  }
+};
+
+/**
+ * Loop incides. Only stores 2 indices, the third one is always `loop_indices[1] + 1`.
+ * Second could be delta encoded with the first loop index.
+ */
+struct EncodedLoopIndices {
+  int2 encoded;
+
+  EncodedLoopIndices(const int3 decoded) : encoded(decoded.x, decoded.y)
+  {
+  }
+
+  int3 decode() const
+  {
+    return int3(encoded.x, encoded.y, encoded.y + 1);
+  }
+};
+
+struct Triangle {
+  int3 loop_indices;
+  int3 vert_indices;
+  int poly_index;
+  float3 add_barycentric_coord_x;
+};
+
+struct TrianglePaintInput {
+  int3 vert_indices;
+  float3 add_barycentric_coord_x;
+
+  TrianglePaintInput(const Triangle &triangle)
+      : vert_indices(triangle.vert_indices),
+        add_barycentric_coord_x(triangle.add_barycentric_coord_x)
+  {
+  }
+};
+
+struct Triangles {
+  Vector<TrianglePaintInput> paint_input;
+  Vector<EncodedLoopIndices> loop_indices;
+  Vector<int> poly_indices;
+
+ public:
+  void append(const Triangle &triangle)
+  {
+    paint_input.append(TrianglePaintInput(triangle));
+    loop_indices.append(triangle.loop_indices);
+    poly_indices.append(triangle.poly_index);
+  }
+
+  int3 get_loop_indices(const int index) const
+  {
+    return loop_indices[index].decode();
+  }
+  int get_poly_index(const int index)
+  {
+    return poly_indices[index];
+  }
+
+  TrianglePaintInput &get_paint_input(const int index)
+  {
+    return paint_input[index];
+  }
+
+  const TrianglePaintInput &get_paint_input(const int index) const
+  {
+    return paint_input[index];
+  }
+
+  void cleanup_after_init()
+  {
+    loop_indices.clear();
+  }
+
+  uint64_t size() const
+  {
+    return paint_input.size();
+  }
+
+  uint64_t mem_size() const
+  {
+    return loop_indices.size() * sizeof(EncodedLoopIndices) +
+           paint_input.size() * sizeof(TrianglePaintInput) + poly_indices.size() * sizeof(int);
+  }
+};
+
+/**
+ * Encode multiple sequential pixels to reduce memory footprint.
+ */
+struct PixelsPackage {
+  /** Barycentric coordinate of the first encoded pixel. */
+  EncodedBarycentricCoord start_barycentric_coord;
+  /** Image coordinate starting of the first encoded pixel. */
+  ushort2 start_image_coordinate;
+  /** Number of sequetial pixels encoded in this package. */
+  ushort num_pixels;
+  /** Reference to the pbvh triangle index. */
+  ushort triangle_index;
+};
+
+struct TileData {
+  short tile_number;
+  struct {
+    bool dirty : 1;
+  } flags;
+
+  /* Dirty region of the tile in image space. */
+  rcti dirty_region;
+
+  Vector<PixelsPackage> encoded_pixels;
+
+  TileData()
+  {
+    flags.dirty = false;
+    BLI_rcti_init_minmax(&dirty_region);
+  }
+
+  void mark_region(Image &image, const image::ImageTileWrapper &image_tile, ImBuf &image_buffer)
+  {
+    print_rcti_id(&dirty_region);
+    BKE_image_partial_update_mark_region(
+        &image, image_tile.image_tile, &image_buffer, &dirty_region);
+    BLI_rcti_init_minmax(&dirty_region);
+    flags.dirty = false;
+  }
+};
+
+struct NodeData {
+  struct {
+    bool dirty : 1;
+  } flags;
+
+  rctf uv_region;
+
+  Vector<TileData> tiles;
+  Triangles triangles;
+
+  NodeData()
+  {
+    flags.dirty = false;
+  }
+
+  void init_pixels_rasterization(Object *ob, PBVHNode *node, ImBuf *image_buffer);
+
+  TileData *find_tile_data(const image::ImageTileWrapper &image_tile)
+  {
+    for (TileData &tile : tiles) {
+      if (tile.tile_number == image_tile.get_tile_number()) {
+        return &tile;
+      }
+    }
+    return nullptr;
+  }
+
+  void mark_region(Image &image, const image::ImageTileWrapper &image_tile, ImBuf &image_buffer)
+  {
+    TileData *tile = find_tile_data(image_tile);
+    if (tile) {
+      tile->mark_region(image, image_tile, image_buffer);
+    }
+  }
+
+  static void free_func(void *instance)
+  {
+    NodeData *node_data = static_cast<NodeData *>(instance);
+    MEM_delete(node_data);
+  }
+};
+
+}  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0c1601eeece..532858727ae 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -242,6 +242,7 @@ set(SRC
   intern/particle_system.c
   intern/pbvh.c
   intern/pbvh_bmesh.c
+  intern/pbvh_pixels.cc
   intern/pointcache.c
   intern/pointcloud.cc
   intern/preferences.c
dif

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list