Subdiv: Use index instead of pointer for grid to face map
Switch from face pointers to indices, with the following benefits: - Halve memory usage required for array (saves 16 MB with 1 million quads). - Allow better code reuse with index-based utilities. - Ease future replacement of `SubdivCCGFace` with mesh's face offsets. - Allow future replacement of array with `Mesh::corner_to_face_map()` - Potentially lower memory bandwidth required during multires evaluation - Simplify retrieval of index in `BKE_subdiv_ccg_grid_to_face_index`. For clarity, `gridfaces` was renamed to `grid_to_face_map`. Pull Request: https://projects.blender.org/blender/blender/pulls/111078
This commit is contained in:
@@ -210,7 +210,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
int totgrid,
|
||||
CCGKey *key,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
Mesh *me,
|
||||
@@ -445,7 +445,7 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]);
|
||||
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface);
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
CCGKey *key);
|
||||
|
||||
@@ -160,7 +160,7 @@ struct SubdivCCG {
|
||||
int num_faces = -1;
|
||||
SubdivCCGFace *faces = nullptr;
|
||||
/* Indexed by grid index, points to corresponding face from `faces`. */
|
||||
SubdivCCGFace **grid_faces = nullptr;
|
||||
blender::Array<int> grid_to_face_map;
|
||||
|
||||
/* Edges which are adjacent to faces.
|
||||
* Used for faster grid stitching, in the cost of extra memory.
|
||||
|
||||
@@ -2215,7 +2215,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
|
||||
subdiv_ccg->grids,
|
||||
subdiv_ccg->num_grids,
|
||||
&key,
|
||||
(void **)subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
subdiv_ccg->grid_hidden,
|
||||
base_mesh,
|
||||
@@ -2304,7 +2304,7 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
|
||||
|
||||
BKE_pbvh_grids_update(pbvh,
|
||||
subdiv_ccg->grids,
|
||||
(void **)subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
subdiv_ccg->grid_hidden,
|
||||
&key);
|
||||
|
||||
@@ -914,7 +914,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
int totgrid,
|
||||
CCGKey *key,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
Mesh *me,
|
||||
@@ -924,7 +924,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
||||
|
||||
pbvh->header.type = PBVH_GRIDS;
|
||||
pbvh->grids = grids;
|
||||
pbvh->gridfaces = gridfaces;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
pbvh->totgrid = totgrid;
|
||||
pbvh->gridkey = *key;
|
||||
@@ -1715,10 +1715,11 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, {});
|
||||
|
||||
SubdivCCGFace *all_faces = pbvh->subdiv_ccg->faces;
|
||||
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
for (const int grid : node->prim_indices) {
|
||||
void *face = pbvh->gridfaces[grid];
|
||||
void *face = &all_faces[pbvh->grid_to_face_map[grid]];
|
||||
BLI_gset_add(face_set, face);
|
||||
}
|
||||
|
||||
@@ -2944,14 +2945,14 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
|
||||
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
CCGKey *key)
|
||||
{
|
||||
pbvh->gridkey = *key;
|
||||
pbvh->grids = grids;
|
||||
pbvh->gridfaces = gridfaces;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
|
||||
if (flagmats != pbvh->grid_flag_mats || pbvh->grid_hidden != grid_hidden) {
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
|
||||
@@ -175,7 +175,7 @@ struct PBVH {
|
||||
/* Grid Data */
|
||||
CCGKey gridkey;
|
||||
CCGElem **grids;
|
||||
void **gridfaces;
|
||||
blender::Span<int> grid_to_face_map;
|
||||
const DMFlagMat *grid_flag_mats;
|
||||
int totgrid;
|
||||
BLI_bitmap **grid_hidden;
|
||||
|
||||
@@ -155,8 +155,7 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
|
||||
if (num_faces) {
|
||||
subdiv_ccg->faces = static_cast<SubdivCCGFace *>(
|
||||
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
|
||||
subdiv_ccg->grid_faces = static_cast<SubdivCCGFace **>(
|
||||
MEM_calloc_arrayN(num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces"));
|
||||
subdiv_ccg->grid_to_face_map.reinitialize(num_grids);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +234,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
|
||||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
SubdivCCGFace *faces = subdiv_ccg->faces;
|
||||
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg->grid_to_face_map;
|
||||
const SubdivCCGFace *face = &faces[face_index];
|
||||
for (int corner = 0; corner < face->num_grids; corner++) {
|
||||
const int grid_index = face->start_grid_index + corner;
|
||||
@@ -252,7 +251,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
|
||||
}
|
||||
}
|
||||
/* Assign grid's face. */
|
||||
grid_faces[grid_index] = &faces[face_index];
|
||||
grid_to_face_map[grid_index] = face_index;
|
||||
/* Assign material flags. */
|
||||
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
|
||||
data->material_flags_evaluator, face_index);
|
||||
@@ -266,7 +265,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
|
||||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
SubdivCCGFace *faces = subdiv_ccg->faces;
|
||||
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg->grid_to_face_map;
|
||||
const SubdivCCGFace *face = &faces[face_index];
|
||||
for (int corner = 0; corner < face->num_grids; corner++) {
|
||||
const int grid_index = face->start_grid_index + corner;
|
||||
@@ -282,7 +281,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
|
||||
}
|
||||
}
|
||||
/* Assign grid's face. */
|
||||
grid_faces[grid_index] = &faces[face_index];
|
||||
grid_to_face_map[grid_index] = face_index;
|
||||
/* Assign material flags. */
|
||||
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
|
||||
data->material_flags_evaluator, face_index);
|
||||
@@ -596,7 +595,6 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
|
||||
BKE_subdiv_free(subdiv_ccg->subdiv);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->faces);
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_faces);
|
||||
/* Free map of adjacent edges. */
|
||||
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
|
||||
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
|
||||
@@ -1452,7 +1450,7 @@ static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG *subdiv_cc
|
||||
BLI_INLINE
|
||||
int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_grid_index = coord->grid_index;
|
||||
int next_face_grid_index = face_grid_index + 1 - face->start_grid_index;
|
||||
if (next_face_grid_index == face->num_grids) {
|
||||
@@ -1462,7 +1460,7 @@ int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord
|
||||
}
|
||||
BLI_INLINE int prev_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_grid_index = coord->grid_index;
|
||||
int prev_face_grid_index = face_grid_index - 1 - face->start_grid_index;
|
||||
if (prev_face_grid_index < 0) {
|
||||
@@ -1478,7 +1476,7 @@ static void neighbor_coords_corner_center_get(const SubdivCCG *subdiv_ccg,
|
||||
const bool include_duplicates,
|
||||
SubdivCCGNeighbors *r_neighbors)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int num_adjacent_grids = face->num_grids;
|
||||
|
||||
subdiv_ccg_neighbors_init(
|
||||
@@ -1506,7 +1504,7 @@ static int adjacent_vertex_index_from_coord(const SubdivCCG *subdiv_ccg,
|
||||
Subdiv *subdiv = subdiv_ccg->subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
|
||||
const SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
const int face_grid_index = coord->grid_index - face->start_grid_index;
|
||||
const int num_face_grids = face->num_grids;
|
||||
@@ -1583,7 +1581,7 @@ static int adjacent_edge_index_from_coord(const SubdivCCG *subdiv_ccg, const Sub
|
||||
{
|
||||
Subdiv *subdiv = subdiv_ccg->subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
|
||||
const int face_grid_index = coord->grid_index - face->start_grid_index;
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
@@ -1876,9 +1874,7 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
|
||||
|
||||
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index)
|
||||
{
|
||||
const SubdivCCGFace *face = subdiv_ccg->grid_faces[grid_index];
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
return face_index;
|
||||
return subdiv_ccg->grid_to_face_map[grid_index];
|
||||
}
|
||||
|
||||
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)
|
||||
|
||||
Reference in New Issue
Block a user