diff options
-rw-r--r-- | source/blender/blenkernel/BKE_subdiv_ccg.h | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_ccg.c | 32 |
2 files changed, 47 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h index 8d2565c31f7..78e91d3ad2f 100644 --- a/source/blender/blenkernel/BKE_subdiv_ccg.h +++ b/source/blender/blenkernel/BKE_subdiv_ccg.h @@ -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 diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index 4d12ea1d54f..a1e218390c3 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -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; +} + /** \} */ |