Subdiv CCG: Add access to first grid index of a face

Is lazily-initialized array owned by the SubdivCCG. Allows to access
index of a first grid of a given face in the flat array of grids.

Currently unused, but is needed for multires bake.
This commit is contained in:
Sergey Sharybin 2020-06-22 17:15:20 +02:00
parent 41158a91f2
commit b175bb2503
2 changed files with 47 additions and 0 deletions

View File

@ -214,6 +214,12 @@ typedef struct SubdivCCG {
/* Corresponds to MULTIRES_HIDDEN_MODIFIED. */
bool hidden;
} dirty;
/* Cached values, are not supposed to be accessed directly. */
struct {
/* Indexed by face, indicates index of the first grid which corresponds to the face. */
int *start_face_grid_index;
} cache_;
} SubdivCCG;
/* Create CCG representation of subdivision surface.
@ -307,6 +313,15 @@ 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);
/* Get array which is indexed by face index and contains index of a first grid of the face.
*
* The "ensure" version allocates the mapping if it's not know yet and stores it in the subdiv_ccg
* descriptor. This function is NOT safe for threading.
*
* The "get" version simply returns cached array. */
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
#ifdef __cplusplus
}
#endif

View File

@ -655,6 +655,7 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
MEM_SAFE_FREE(adjacent_vertex->corner_coords);
}
MEM_SAFE_FREE(subdiv_ccg->adjacent_vertices);
MEM_SAFE_FREE(subdiv_ccg->cache_.start_face_grid_index);
MEM_freeN(subdiv_ccg);
}
@ -1802,4 +1803,35 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int gri
return face_index;
}
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)
{
if (subdiv_ccg->cache_.start_face_grid_index == NULL) {
const Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
if (topology_refiner == NULL) {
return NULL;
}
const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner);
subdiv_ccg->cache_.start_face_grid_index = MEM_malloc_arrayN(
sizeof(int), num_coarse_faces, "start_face_grid_index");
int start_grid_index = 0;
for (int face_index = 0; face_index < num_coarse_faces; face_index++) {
const int num_face_grids = topology_refiner->getNumFaceVertices(topology_refiner,
face_index);
subdiv_ccg->cache_.start_face_grid_index[face_index] = start_grid_index;
start_grid_index += num_face_grids;
}
}
return subdiv_ccg->cache_.start_face_grid_index;
}
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg)
{
return subdiv_ccg->cache_.start_face_grid_index;
}
/** \} */