[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