From c5a13ffcb4b98bbd46dca7637051a966d18cd46f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 Oct 2021 11:16:24 +1100 Subject: Cleanup: spelling in comments --- source/blender/blenkernel/BKE_pbvh.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/BKE_pbvh.h') diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 056a7e2d897..3a0e9d48af7 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -128,8 +128,8 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh, void BKE_pbvh_free(PBVH *pbvh); /* Hierarchical Search in the BVH, two methods: - * - for each hit calling a callback - * - gather nodes in an array (easy to multithread) */ + * - For each hit calling a callback. + * - Gather nodes in an array (easy to multi-thread). */ void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_SearchCallback scb, @@ -140,7 +140,7 @@ void BKE_pbvh_search_callback(PBVH *pbvh, void BKE_pbvh_search_gather( PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot); -/* Raycast +/* Ray-cast * the hit callback is called for all leaf nodes intersecting the ray; * it's up to the callback to find the primitive within the leaves that is * hit first */ -- cgit v1.2.3 From ffc4c126f5416b04a01653e7a03451797b98aba4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Dec 2021 17:19:15 +1100 Subject: Cleanup: move public doc-strings into headers for 'blenkernel' - Added space below non doc-string comments to make it clear these aren't comments for the symbols directly below them. - Use doxy sections for some headers. - Minor improvements to doc-strings. Ref T92709 --- source/blender/blenkernel/BKE_pbvh.h | 75 +++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 14 deletions(-) (limited to 'source/blender/blenkernel/BKE_pbvh.h') diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 3a0e9d48af7..5e7a9883de6 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -90,7 +90,9 @@ void BKE_pbvh_get_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes); /* Callbacks */ -/* returns 1 if the search should continue from this node, 0 otherwise */ +/** + * Returns true if the search should continue from this node, false otherwise. + */ typedef bool (*BKE_pbvh_SearchCallback)(PBVHNode *node, void *data); typedef void (*BKE_pbvh_HitCallback)(PBVHNode *node, void *data); @@ -101,6 +103,12 @@ typedef void (*BKE_pbvh_SearchNearestCallback)(PBVHNode *node, void *data, float /* Building */ PBVH *BKE_pbvh_new(void); +/** + * Do a full rebuild with on Mesh data structure. + * + * \note Unlike mpoly/mloop/verts, looptri is *totally owned* by PBVH + * (which means it may rewrite it if needed, see #BKE_pbvh_vert_coords_apply(). + */ void BKE_pbvh_build_mesh(PBVH *pbvh, const struct Mesh *mesh, const struct MPoly *mpoly, @@ -112,6 +120,9 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, struct CustomData *pdata, const struct MLoopTri *looptri, int looptri_num); +/** + * Do a full rebuild with on Grids data structure. + */ void BKE_pbvh_build_grids(PBVH *pbvh, struct CCGElem **grids, int totgrid, @@ -119,6 +130,9 @@ void BKE_pbvh_build_grids(PBVH *pbvh, void **gridfaces, struct DMFlagMat *flagmats, unsigned int **grid_hidden); +/** + * Build a PBVH from a BMesh. + */ void BKE_pbvh_build_bmesh(PBVH *pbvh, struct BMesh *bm, bool smooth_shading, @@ -170,8 +184,10 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node, float *depth, float *r_edge_length); -/* for orthographic cameras, project the far away ray segment points to the root node so - * we can have better precision. */ +/** + * For orthographic cameras, project the far away ray segment points to the root node so + * we can have better precision. + */ void BKE_pbvh_raycast_project_ray_root( PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]); @@ -215,12 +231,19 @@ typedef enum { PBVHType BKE_pbvh_type(const PBVH *pbvh); bool BKE_pbvh_has_faces(const PBVH *pbvh); -/* Get the PBVH root's bounding box */ +/** + * Get the PBVH root's bounding box. + */ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]); -/* multires hidden data, only valid for type == PBVH_GRIDS */ +/** + * Multi-res hidden data, only valid for type == PBVH_GRIDS. + */ unsigned int **BKE_pbvh_grid_hidden(const PBVH *pbvh); +/** + * Returns the number of visible quads in the nodes' grids. + */ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, const int *grid_indices, int totgrid, @@ -228,7 +251,9 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh); -/* multires level, only valid for type == PBVH_GRIDS */ +/** + * Multi-res level, only valid for type == #PBVH_GRIDS. + */ const struct CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh); struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh); @@ -236,7 +261,9 @@ BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh); int BKE_pbvh_get_grid_num_vertices(const PBVH *pbvh); int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh); -/* Only valid for type == PBVH_BMESH */ +/** + * Only valid for type == #PBVH_BMESH. + */ struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh); void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size); @@ -244,6 +271,9 @@ typedef enum { PBVH_Subdivide = 1, PBVH_Collapse = 2, } PBVHTopologyUpdateMode; +/** + * Collapse short edges, subdivide long edges. + */ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh, PBVHTopologyUpdateMode mode, const float center[3], @@ -287,18 +317,28 @@ void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max float BKE_pbvh_node_get_tmin(PBVHNode *node); -/* test if AABB is at least partially inside the PBVHFrustumPlanes volume */ +/** + * Test if AABB is at least partially inside the #PBVHFrustumPlanes volume. + */ bool BKE_pbvh_node_frustum_contain_AABB(PBVHNode *node, void *frustum); -/* test if AABB is at least partially outside the PBVHFrustumPlanes volume */ +/** + * Test if AABB is at least partially outside the #PBVHFrustumPlanes volume. + */ bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *frustum); struct GSet *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node); struct GSet *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node); struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node); +/** + * In order to perform operations on the original node coordinates + * (currently just ray-cast), store the node's triangles and vertices. + * + * Skips triangles that are hidden. + */ void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm, PBVHNode *node); void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh); -/* Update Bounding Box/Redraw and clear flags */ +/* Update Bounding Box/Redraw and clear flags. */ void BKE_pbvh_update_bounds(PBVH *pbvh, int flags); void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags); @@ -318,14 +358,15 @@ void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default); void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide); -/* vertex deformer */ +/* Vertex Deformer. */ + float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3]; void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], const int totvert); bool BKE_pbvh_is_deformed(struct PBVH *pbvh); -/* Vertex Iterator */ +/* Vertex Iterator. */ -/* this iterator has quite a lot of code, but it's designed to: +/* This iterator has quite a lot of code, but it's designed to: * - allow the compiler to eliminate dead code and variables * - spend most of the time in the relatively simple inner loop */ @@ -469,6 +510,11 @@ void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node, int *r_orco_tris_num, float (**r_orco_coords)[3]); +/** + * \note doing a full search on all vertices here seems expensive, + * however this is important to avoid having to recalculate bound-box & sync the buffers to the + * GPU (which is far more expensive!) See: T47232. + */ bool BKE_pbvh_node_vert_update_check_any(PBVH *pbvh, PBVHNode *node); // void BKE_pbvh_node_BB_reset(PBVHNode *node); @@ -480,7 +526,8 @@ void pbvh_show_mask_set(PBVH *pbvh, bool show_mask); bool pbvh_has_face_sets(PBVH *pbvh); void pbvh_show_face_sets_set(PBVH *pbvh, bool show_face_sets); -/* Parallelization */ +/* Parallelization. */ + void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode); -- cgit v1.2.3 From 3d3bc748849834ef74563deb603ab43859cffeeb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 7 Jan 2022 11:38:08 +1100 Subject: Cleanup: remove redundant const qualifiers for POD types MSVC used to warn about const mismatch for arguments passed by value. Remove these as newer versions of MSVC no longer show this warning. --- source/blender/blenkernel/BKE_pbvh.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/BKE_pbvh.h') diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 5e7a9883de6..692c935ae5f 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -137,8 +137,8 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, - const int cd_vert_node_offset, - const int cd_face_node_offset); + int cd_vert_node_offset, + int cd_face_node_offset); void BKE_pbvh_free(PBVH *pbvh); /* Hierarchical Search in the BVH, two methods: @@ -279,8 +279,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh, const float center[3], const float view_normal[3], float radius, - const bool use_frontface, - const bool use_projected); + bool use_frontface, + bool use_projected); /* Node Access */ @@ -361,7 +361,7 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide); /* Vertex Deformer. */ float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3]; -void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], const int totvert); +void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], int totvert); bool BKE_pbvh_is_deformed(struct PBVH *pbvh); /* Vertex Iterator. */ -- cgit v1.2.3 From cfa53e0fbeed7178c7876413e2010fd3347d7f72 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 13 Jan 2022 14:37:58 -0600 Subject: Refactor: Move normals out of MVert, lazy calculation As described in T91186, this commit moves mesh vertex normals into a contiguous array of float vectors in a custom data layer, how face normals are currently stored. The main interface is documented in `BKE_mesh.h`. Vertex and face normals are now calculated on-demand and cached, retrieved with an "ensure" function. Since the logical state of a mesh is now "has normals when necessary", they can be retrieved from a `const` mesh. The goal is to use on-demand calculation for all derived data, but leave room for eager calculation for performance purposes (modifier evaluation is threaded, but viewport data generation is not). **Benefits** This moves us closer to a SoA approach rather than the current AoS paradigm. Accessing a contiguous `float3` is much more efficient than retrieving data from a larger struct. The memory requirements for accessing only normals or vertex locations are smaller, and at the cost of more memory usage for just normals, they now don't have to be converted between float and short, which also simplifies code In the future, the remaining items can be removed from `MVert`, leaving only `float3`, which has similar benefits (see T93602). Removing the combination of derived and original data makes it conceptually simpler to only calculate normals when necessary. This is especially important now that we have more opportunities for temporary meshes in geometry nodes. **Performance** In addition to the theoretical future performance improvements by making `MVert == float3`, I've done some basic performance testing on this patch directly. The data is fairly rough, but it gives an idea about where things stand generally. - Mesh line primitive 4m Verts: 1.16x faster (36 -> 31 ms), showing that accessing just `MVert` is now more efficient. - Spring Splash Screen: 1.03-1.06 -> 1.06-1.11 FPS, a very slight change that at least shows there is no regression. - Sprite Fright Snail Smoosh: 3.30-3.40 -> 3.42-3.50 FPS, a small but observable speedup. - Set Position Node with Scaled Normal: 1.36x faster (53 -> 39 ms), shows that using normals in geometry nodes is faster. - Normal Calculation 1.6m Vert Cube: 1.19x faster (25 -> 21 ms), shows that calculating normals is slightly faster now. - File Size of 1.6m Vert Cube: 1.03x smaller (214.7 -> 208.4 MB), Normals are not saved in files, which can help with large meshes. As for memory usage, it may be slightly more in some cases, but I didn't observe any difference in the production files I tested. **Tests** Some modifiers and cycles test results need to be updated with this commit, for two reasons: - The subdivision surface modifier is not responsible for calculating normals anymore. In master, the modifier creates different normals than the result of the `Mesh` normal calculation, so this is a bug fix. - There are small differences in the results of some modifiers that use normals because they are not converted to and from `short` anymore. **Future improvements** - Remove `ModifierTypeInfo::dependsOnNormals`. Code in each modifier already retrieves normals if they are needed anyway. - Copy normals as part of a better CoW system for attributes. - Make more areas use lazy instead of eager normal calculation. - Remove `BKE_mesh_normals_tag_dirty` in more places since that is now the default state of a new mesh. - Possibly apply a similar change to derived face corner normals. Differential Revision: https://developer.blender.org/D12770 --- source/blender/blenkernel/BKE_pbvh.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/BKE_pbvh.h') diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 692c935ae5f..1ef1c98ce83 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -110,7 +110,7 @@ PBVH *BKE_pbvh_new(void); * (which means it may rewrite it if needed, see #BKE_pbvh_vert_coords_apply(). */ void BKE_pbvh_build_mesh(PBVH *pbvh, - const struct Mesh *mesh, + struct Mesh *mesh, const struct MPoly *mpoly, const struct MLoop *mloop, struct MVert *verts, @@ -397,6 +397,7 @@ typedef struct PBVHVertexIter { /* mesh */ struct MVert *mverts; + float (*vert_normals)[3]; int totvert; const int *vert_indices; struct MPropCol *vcol; @@ -413,7 +414,7 @@ typedef struct PBVHVertexIter { struct MVert *mvert; struct BMVert *bm_vert; float *co; - short *no; + float *no; float *fno; float *mask; float *col; @@ -467,7 +468,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m BLI_assert(vi.visible); \ } \ vi.co = vi.mvert->co; \ - vi.no = vi.mvert->no; \ + vi.no = vi.vert_normals[vi.vert_indices[vi.gx]]; \ vi.index = vi.vert_indices[vi.i]; \ if (vi.vmask) { \ vi.mask = &vi.vmask[vi.index]; \ @@ -533,6 +534,7 @@ void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, int totnode); struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh); +const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]; PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node); void BKE_pbvh_node_color_buffer_free(PBVH *pbvh); -- cgit v1.2.3