Cleanup: Use C++ arrays to store subdiv ccg data

Decrease the amount of manual memory management
and pointer arithmetic.
This commit is contained in:
Hans Goudey
2023-11-29 12:34:24 -05:00
parent d3ff658b66
commit 8c59532106
13 changed files with 136 additions and 202 deletions

View File

@@ -216,12 +216,11 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh);
* Do a full rebuild with on Grids data structure.
*/
void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
blender::Span<CCGElem *> grids,
CCGKey *key,
blender::Span<int> grid_to_face_map,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
blender::Span<DMFlagMat> flagmats,
blender::Span<BLI_bitmap *> grid_hidden,
Mesh *me,
SubdivCCG *subdiv_ccg);
/**
@@ -333,14 +332,14 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]);
/**
* Multi-res hidden data, only valid for type == PBVH_GRIDS.
*/
unsigned int **BKE_pbvh_grid_hidden(const PBVH *pbvh);
blender::Span<const BLI_bitmap *> BKE_pbvh_get_grid_visibility(const PBVH *pbvh);
void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *me);
/**
* Returns the number of visible quads in the nodes' grids.
*/
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
int BKE_pbvh_count_grid_quads(blender::Span<const BLI_bitmap *> grid_hidden,
const int *grid_indices,
int totgrid,
int gridsize,
@@ -351,8 +350,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
*/
const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh);
CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh);
BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh);
blender::Span<CCGElem *> BKE_pbvh_get_grids(const PBVH *pbvh);
int BKE_pbvh_get_grid_num_verts(const PBVH *pbvh);
int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh);
@@ -405,7 +403,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
int *totgrid,
int *maxgrid,
int *gridsize,
CCGElem ***r_griddata);
CCGElem *const **r_griddata);
void BKE_pbvh_node_num_verts(const PBVH *pbvh,
const PBVHNode *node,
int *r_uniquevert,
@@ -463,10 +461,10 @@ blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
blender::Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory);
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<CCGElem *> grids,
blender::Span<int> grid_to_face_map,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
blender::Span<DMFlagMat> flagmats,
blender::Span<BLI_bitmap *> grid_hidden,
CCGKey *key);
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg);
@@ -505,9 +503,9 @@ struct PBVHVertexIter {
/* grid */
CCGKey key;
CCGElem **grids;
CCGElem *const *grids;
CCGElem *grid;
BLI_bitmap **grid_hidden, *gh;
BLI_bitmap *const *grid_hidden, *gh;
const int *grid_indices;
int totgrid;
int gridsize;

View File

@@ -132,10 +132,9 @@ struct SubdivCCG {
*/
/* Indexed by a grid index, points to a grid data which is stored in
* grids_storage. */
CCGElem **grids = nullptr;
blender::Array<CCGElem *> grids;
/* Flat array of all grids' data. */
unsigned char *grids_storage = nullptr;
int num_grids = -1;
blender::Array<uchar> grids_storage;
/* Loose edges, each array element contains grid_size elements
* corresponding to vertices created by subdividing coarse edges. */
CCGElem **edges = nullptr;
@@ -157,25 +156,22 @@ struct SubdivCCG {
int mask_offset = -1;
/* Faces from which grids are emitted. */
int num_faces = -1;
SubdivCCGFace *faces = nullptr;
blender::Array<SubdivCCGFace> faces;
/* Indexed by grid index, points to corresponding face from `faces`. */
blender::Array<int> grid_to_face_map;
/* Edges which are adjacent to faces.
* Used for faster grid stitching, in the cost of extra memory.
*/
int num_adjacent_edges = -1;
SubdivCCGAdjacentEdge *adjacent_edges = nullptr;
blender::Array<SubdivCCGAdjacentEdge> adjacent_edges;
/* Vertices which are adjacent to faces
* Used for faster grid stitching, in the cost of extra memory.
*/
int num_adjacent_vertices = -1;
SubdivCCGAdjacentVertex *adjacent_vertices = nullptr;
blender::Array<SubdivCCGAdjacentVertex> adjacent_verts;
DMFlagMat *grid_flag_mats = nullptr;
BLI_bitmap **grid_hidden = nullptr;
blender::Array<DMFlagMat> grid_flag_mats;
blender::Array<BLI_bitmap *> grid_hidden;
/* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
* to make integration with draw manager and such easy.
@@ -198,7 +194,7 @@ struct SubdivCCG {
/* 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 = nullptr;
blender::Array<int> start_face_grid_index;
} cache_;
};

View File

@@ -24,7 +24,7 @@ bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext
const int reshape_grid_size = reshape_context->reshape.grid_size;
const float reshape_grid_size_1_inv = 1.0f / (float(reshape_grid_size) - 1.0f);
int num_grids = subdiv_ccg->num_grids;
int num_grids = subdiv_ccg->grids.size();
for (int grid_index = 0; grid_index < num_grids; ++grid_index) {
CCGElem *ccg_grid = subdiv_ccg->grids[grid_index];
for (int y = 0; y < reshape_grid_size; ++y) {

View File

@@ -2150,7 +2150,7 @@ void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
".hide_poly", ATTR_DOMAIN_FACE, false);
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
/* Nothing is hidden, so we can just remove all visibility bitmaps. */
for (const int i : IndexRange(subdiv_ccg->num_grids)) {
for (const int i : subdiv_ccg->grid_hidden.index_range()) {
BKE_subdiv_ccg_grid_hidden_free(*subdiv_ccg, i);
}
return;
@@ -2217,7 +2217,6 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,
&key,
subdiv_ccg->grid_to_face_map,
subdiv_ccg->grid_flag_mats,

View File

@@ -254,7 +254,7 @@ static int partition_indices_material(
PBVH *pbvh, const int *material_indices, const bool *sharp_faces, int lo, int hi)
{
const Span<int> looptri_faces = pbvh->looptri_faces;
const DMFlagMat *flagmats = pbvh->grid_flag_mats;
const Span<DMFlagMat> flagmats = pbvh->grid_flag_mats;
MutableSpan<int> indices = pbvh->prim_indices;
int i = lo, j = hi;
@@ -374,7 +374,7 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, const Span<BBC> prim_bbc, int
node->orig_vb = node->vb;
}
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
int BKE_pbvh_count_grid_quads(const Span<const BLI_bitmap *> grid_hidden,
const int *grid_indices,
int totgrid,
int gridsize,
@@ -661,7 +661,6 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg
memset((void *)args, 0, sizeof(*args));
args->pbvh_type = pbvh->header.type;
args->mesh_grids_num = pbvh->totgrid;
args->node = node;
args->grid_hidden = pbvh->grid_hidden;
@@ -707,7 +706,6 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg
args->subdiv_ccg = pbvh->subdiv_ccg;
args->faces = pbvh->faces;
args->mesh_grids_num = pbvh->totgrid;
args->grids = pbvh->grids;
args->grid_flag_mats = pbvh->grid_flag_mats;
args->vert_normals = pbvh->vert_normals;
@@ -900,12 +898,11 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh)
}
void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
const Span<CCGElem *> grids,
CCGKey *key,
blender::Span<int> grid_to_face_map,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
const Span<int> grid_to_face_map,
const Span<DMFlagMat> flagmats,
const Span<BLI_bitmap *> grid_hidden,
Mesh *me,
SubdivCCG *subdiv_ccg)
{
@@ -915,7 +912,6 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->grids = grids;
pbvh->grid_to_face_map = grid_to_face_map;
pbvh->grid_flag_mats = flagmats;
pbvh->totgrid = totgrid;
pbvh->gridkey = *key;
pbvh->grid_hidden = grid_hidden;
pbvh->subdiv_ccg = subdiv_ccg;
@@ -946,11 +942,11 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->mesh = me;
/* For each grid, store the AABB and the AABB centroid */
blender::Array<BBC> prim_bbc(totgrid);
blender::Array<BBC> prim_bbc(grids.size());
BB cb;
BB_reset(&cb);
cb = blender::threading::parallel_reduce(
blender::IndexRange(totgrid),
grids.index_range(),
1024,
cb,
[&](const blender::IndexRange range, const BB &init) {
@@ -973,12 +969,12 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
return current;
});
if (totgrid) {
if (!grids.is_empty()) {
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(&me->face_data, CD_PROP_INT32, "material_index"));
const bool *sharp_faces = (const bool *)CustomData_get_layer_named(
&me->face_data, CD_PROP_BOOL, "sharp_face");
pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, totgrid);
pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, grids.size());
#ifdef TEST_PBVH_FACE_SPLIT
test_face_boundaries(pbvh);
@@ -1602,18 +1598,17 @@ static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
static void pbvh_grids_node_visibility_update(PBVH *pbvh, PBVHNode *node)
{
CCGElem **grids;
BLI_bitmap **grid_hidden;
CCGElem *const *grids;
const int *grid_indices;
int totgrid, i;
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids);
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
const Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(pbvh);
CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
for (i = 0; i < totgrid; i++) {
int g = grid_indices[i], x, y;
BLI_bitmap *gh = grid_hidden[g];
const BLI_bitmap *gh = grid_hidden[g];
if (!gh) {
BKE_pbvh_node_fully_hidden_set(node, false);
@@ -1755,7 +1750,7 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3])
copy_v3_v3(max, bb->bmax);
}
BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *pbvh)
Span<const BLI_bitmap *> BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
{
BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grid_hidden;
@@ -1767,28 +1762,22 @@ const CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh)
return &pbvh->gridkey;
}
CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh)
Span<CCGElem *> BKE_pbvh_get_grids(const PBVH *pbvh)
{
BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grids;
}
BLI_bitmap **BKE_pbvh_get_grid_visibility(const PBVH *pbvh)
{
BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->grid_hidden;
}
int BKE_pbvh_get_grid_num_verts(const PBVH *pbvh)
{
BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->totgrid * pbvh->gridkey.grid_area;
return pbvh->grids.size() * pbvh->gridkey.grid_area;
}
int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh)
{
BLI_assert(pbvh->header.type == PBVH_GRIDS);
return pbvh->totgrid * (pbvh->gridkey.grid_size - 1) * (pbvh->gridkey.grid_size - 1);
return pbvh->grids.size() * (pbvh->gridkey.grid_size - 1) * (pbvh->gridkey.grid_size - 1);
}
/***************************** Node Access ***********************************/
@@ -2034,7 +2023,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
int *r_totgrid,
int *r_maxgrid,
int *r_gridsize,
CCGElem ***r_griddata)
CCGElem *const **r_griddata)
{
switch (pbvh->header.type) {
case PBVH_GRIDS:
@@ -2045,13 +2034,13 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh,
*r_totgrid = node->prim_indices.size();
}
if (r_maxgrid) {
*r_maxgrid = pbvh->totgrid;
*r_maxgrid = pbvh->grids.size();
}
if (r_gridsize) {
*r_gridsize = pbvh->gridkey.grid_size;
}
if (r_griddata) {
*r_griddata = pbvh->grids;
*r_griddata = pbvh->grids.data();
}
break;
case PBVH_FACES:
@@ -2961,17 +2950,19 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
}
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<int> grid_to_face_map,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
const blender::Span<CCGElem *> grids,
const blender::Span<int> grid_to_face_map,
const blender::Span<DMFlagMat> flagmats,
const blender::Span<BLI_bitmap *> grid_hidden,
CCGKey *key)
{
pbvh->gridkey = *key;
pbvh->grids = grids;
pbvh->grid_to_face_map = grid_to_face_map;
if (flagmats != pbvh->grid_flag_mats || pbvh->grid_hidden != grid_hidden) {
if (flagmats.data() != pbvh->grid_flag_mats.data() ||
pbvh->grid_hidden.data() != grid_hidden.data())
{
pbvh->grid_flag_mats = flagmats;
pbvh->grid_hidden = grid_hidden;
@@ -3076,7 +3067,7 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
{
CCGElem **grids;
CCGElem *const *grids;
const int *grid_indices;
int totgrid, gridsize, uniq_verts, totvert;
@@ -3117,7 +3108,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->gh = nullptr;
if (vi->grids && mode == PBVH_ITER_UNIQUE) {
vi->grid_hidden = pbvh->grid_hidden;
vi->grid_hidden = pbvh->grid_hidden.data();
}
vi->mask = 0.0f;

View File

@@ -178,11 +178,10 @@ struct PBVH {
/* Grid Data */
CCGKey gridkey;
CCGElem **grids;
blender::Span<CCGElem *> grids;
blender::Span<int> grid_to_face_map;
const DMFlagMat *grid_flag_mats;
int totgrid;
BLI_bitmap **grid_hidden;
blender::Span<DMFlagMat> grid_flag_mats;
blender::Span<BLI_bitmap *> grid_hidden;
/* Used during BVH build and later to mark that a vertex needs to update
* (its normal must be recalculated). */

View File

@@ -129,40 +129,28 @@ static int topology_refiner_count_face_corners(OpenSubdiv_TopologyRefiner *topol
static void subdiv_ccg_alloc_elements(SubdivCCG &subdiv_ccg, Subdiv &subdiv)
{
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv.topology_refiner;
const int element_size = element_size_bytes_get(subdiv_ccg);
const int64_t element_size = element_size_bytes_get(subdiv_ccg);
/* Allocate memory for surface grids. */
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
const int num_grids = topology_refiner_count_face_corners(topology_refiner);
const int grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg.level);
const int grid_area = grid_size * grid_size;
const int64_t num_faces = topology_refiner->getNumFaces(topology_refiner);
const int64_t num_grids = topology_refiner_count_face_corners(topology_refiner);
const int64_t grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg.level);
const int64_t grid_area = grid_size * grid_size;
subdiv_ccg.grid_element_size = element_size;
subdiv_ccg.num_grids = num_grids;
subdiv_ccg.grids = static_cast<CCGElem **>(
MEM_calloc_arrayN(num_grids, sizeof(CCGElem *), "subdiv ccg grids"));
subdiv_ccg.grids_storage = static_cast<uchar *>(
MEM_calloc_arrayN(num_grids, size_t(grid_area) * element_size, "subdiv ccg grids storage"));
subdiv_ccg.grids.reinitialize(num_grids);
subdiv_ccg.grids_storage.reinitialize(num_grids * grid_area * element_size);
const size_t grid_size_in_bytes = size_t(grid_area) * element_size;
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
const size_t grid_offset = grid_size_in_bytes * grid_index;
subdiv_ccg.grids[grid_index] = (CCGElem *)&subdiv_ccg.grids_storage[grid_offset];
}
/* Grid material flags. */
subdiv_ccg.grid_flag_mats = static_cast<DMFlagMat *>(
MEM_calloc_arrayN(num_grids, sizeof(DMFlagMat), "ccg grid material flags"));
/* Grid hidden flags. */
subdiv_ccg.grid_hidden = static_cast<BLI_bitmap **>(
MEM_calloc_arrayN(num_grids, sizeof(BLI_bitmap *), "ccg grid material flags"));
subdiv_ccg.grid_flag_mats.reinitialize(num_grids);
subdiv_ccg.grid_hidden.reinitialize(num_grids);
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
subdiv_ccg.grid_hidden[grid_index] = BLI_BITMAP_NEW(grid_area, "ccg grid hidden");
}
/* TODO(sergey): Allocate memory for loose elements. */
/* Allocate memory for faces. */
subdiv_ccg.num_faces = num_faces;
if (num_faces) {
subdiv_ccg.faces = static_cast<SubdivCCGFace *>(
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
subdiv_ccg.grid_to_face_map.reinitialize(num_grids);
}
subdiv_ccg.faces.reinitialize(num_faces);
subdiv_ccg.grid_to_face_map.reinitialize(num_grids);
}
/** \} */
@@ -236,9 +224,8 @@ static void subdiv_ccg_eval_regular_grid(Subdiv &subdiv,
const int grid_size = subdiv_ccg.grid_size;
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
const SubdivCCGFace *faces = subdiv_ccg.faces;
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
const SubdivCCGFace &face = faces[face_index];
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
for (int corner = 0; corner < face.num_grids; corner++) {
const int grid_index = face.start_grid_index + corner;
uchar *grid = (uchar *)subdiv_ccg.grids[grid_index];
@@ -272,9 +259,8 @@ static void subdiv_ccg_eval_special_grid(Subdiv &subdiv,
const int grid_size = subdiv_ccg.grid_size;
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
const SubdivCCGFace *faces = subdiv_ccg.faces;
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
const SubdivCCGFace &face = faces[face_index];
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
for (int corner = 0; corner < face.num_grids; corner++) {
const int grid_index = face.start_grid_index + corner;
const int ptex_face_index = face_ptex_offset[face_index] + corner;
@@ -305,7 +291,8 @@ static bool subdiv_ccg_evaluate_grids(SubdivCCG &subdiv_ccg,
using namespace blender;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv.topology_refiner;
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
const Span<int> face_ptex_offset(BKE_subdiv_face_ptex_offset_get(&subdiv), subdiv_ccg.num_faces);
const Span<int> face_ptex_offset(BKE_subdiv_face_ptex_offset_get(&subdiv),
subdiv_ccg.faces.size());
threading::parallel_for(IndexRange(num_faces), 1024, [&](const IndexRange range) {
for (const int face_index : range) {
if (subdiv_ccg.faces[face_index].num_grids == 4) {
@@ -340,7 +327,7 @@ static void subdiv_ccg_init_faces(SubdivCCG &subdiv_ccg)
{
Subdiv *subdiv = subdiv_ccg.subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const int num_faces = subdiv_ccg.num_faces;
const int num_faces = subdiv_ccg.faces.size();
int corner_index = 0;
for (int face_index = 0; face_index < num_faces; face_index++) {
const int num_corners = topology_refiner->getNumFaceVertices(topology_refiner, face_index);
@@ -352,9 +339,7 @@ static void subdiv_ccg_init_faces(SubdivCCG &subdiv_ccg)
static void subdiv_ccg_allocate_adjacent_edges(SubdivCCG &subdiv_ccg, const int num_edges)
{
subdiv_ccg.num_adjacent_edges = num_edges;
subdiv_ccg.adjacent_edges = static_cast<SubdivCCGAdjacentEdge *>(MEM_calloc_arrayN(
subdiv_ccg.num_adjacent_edges, sizeof(*subdiv_ccg.adjacent_edges), "ccg adjacent edges"));
subdiv_ccg.adjacent_edges = Array<SubdivCCGAdjacentEdge>(num_edges, SubdivCCGAdjacentEdge{});
}
static SubdivCCGCoord subdiv_ccg_coord(int grid_index, int x, int y)
@@ -392,7 +377,7 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_edge_add_face(SubdivCCG &subdiv_ccg,
static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
{
Subdiv *subdiv = subdiv_ccg.subdiv;
const SubdivCCGFace *faces = subdiv_ccg.faces;
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const int num_edges = topology_refiner->getNumEdges(topology_refiner);
const int grid_size = subdiv_ccg.grid_size;
@@ -405,8 +390,7 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
Vector<int, 64> face_vertices;
Vector<int, 64> face_edges;
/* Store adjacency for all faces. */
const int num_faces = subdiv_ccg.num_faces;
for (int face_index = 0; face_index < num_faces; face_index++) {
for (const int face_index : faces.index_range()) {
const SubdivCCGFace &face = faces[face_index];
const int num_face_grids = face.num_grids;
face_vertices.reinitialize(num_face_grids);
@@ -458,11 +442,8 @@ static void subdiv_ccg_init_faces_edge_neighborhood(SubdivCCG &subdiv_ccg)
static void subdiv_ccg_allocate_adjacent_vertices(SubdivCCG &subdiv_ccg, const int num_vertices)
{
subdiv_ccg.num_adjacent_vertices = num_vertices;
subdiv_ccg.adjacent_vertices = static_cast<SubdivCCGAdjacentVertex *>(
MEM_calloc_arrayN(subdiv_ccg.num_adjacent_vertices,
sizeof(*subdiv_ccg.adjacent_vertices),
"ccg adjacent vertices"));
subdiv_ccg.adjacent_verts = Array<SubdivCCGAdjacentVertex>(num_vertices,
SubdivCCGAdjacentVertex{});
}
/* Returns storage where corner elements are to be stored. This is a pointer
@@ -482,7 +463,7 @@ static SubdivCCGCoord *subdiv_ccg_adjacent_vertex_add_face(
static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
{
Subdiv *subdiv = subdiv_ccg.subdiv;
const SubdivCCGFace *faces = subdiv_ccg.faces;
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const int num_vertices = topology_refiner->getNumVertices(topology_refiner);
const int grid_size = subdiv_ccg.grid_size;
@@ -496,8 +477,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
CCGKey key;
BKE_subdiv_ccg_key_top_level(key, subdiv_ccg);
/* Store adjacency for all faces. */
const int num_faces = subdiv_ccg.num_faces;
for (int face_index = 0; face_index < num_faces; face_index++) {
for (const int face_index : faces.index_range()) {
const SubdivCCGFace &face = faces[face_index];
const int num_face_grids = face.num_grids;
face_vertices.reinitialize(num_face_grids);
@@ -507,7 +487,7 @@ static void subdiv_ccg_init_faces_vertex_neighborhood(SubdivCCG &subdiv_ccg)
/* Grid which is adjacent to the current corner. */
const int grid_index = face.start_grid_index + corner;
/* Add new face to the adjacent edge. */
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_vertices[vertex_index];
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_verts[vertex_index];
SubdivCCGCoord *corner_coord = subdiv_ccg_adjacent_vertex_add_face(adjacent_vertex);
*corner_coord = subdiv_ccg_coord(grid_index, grid_size - 1, grid_size - 1);
}
@@ -583,38 +563,27 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv &subdiv,
void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
{
const int num_grids = subdiv_ccg->num_grids;
MEM_SAFE_FREE(subdiv_ccg->grids);
MEM_SAFE_FREE(subdiv_ccg->grids_storage);
MEM_SAFE_FREE(subdiv_ccg->edges);
MEM_SAFE_FREE(subdiv_ccg->vertices);
MEM_SAFE_FREE(subdiv_ccg->grid_flag_mats);
if (subdiv_ccg->grid_hidden != nullptr) {
for (int grid_index = 0; grid_index < num_grids; grid_index++) {
MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
}
MEM_SAFE_FREE(subdiv_ccg->grid_hidden);
for (const int grid_index : subdiv_ccg->grid_hidden.index_range()) {
MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
}
if (subdiv_ccg->subdiv != nullptr) {
BKE_subdiv_free(subdiv_ccg->subdiv);
}
MEM_SAFE_FREE(subdiv_ccg->faces);
/* Free map of adjacent edges. */
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
for (const int i : subdiv_ccg->adjacent_edges.index_range()) {
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
for (int face_index = 0; face_index < adjacent_edge->num_adjacent_faces; face_index++) {
MEM_SAFE_FREE(adjacent_edge->boundary_coords[face_index]);
}
MEM_SAFE_FREE(adjacent_edge->boundary_coords);
}
MEM_SAFE_FREE(subdiv_ccg->adjacent_edges);
/* Free map of adjacent vertices. */
for (int i = 0; i < subdiv_ccg->num_adjacent_vertices; i++) {
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[i];
for (const int i : subdiv_ccg->adjacent_verts.index_range()) {
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_verts[i];
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_delete(subdiv_ccg);
}
@@ -727,7 +696,7 @@ static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG &subdiv_ccg, const In
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
Array<float3>(grid_size_1 * grid_size_1));
const SubdivCCGFace *faces = subdiv_ccg.faces;
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
face_mask.foreach_segment(GrainSize(512), [&](const IndexMaskSegment segment) {
MutableSpan<float3> face_normals = face_normals_tls.local();
for (const int face_index : segment) {
@@ -747,7 +716,7 @@ void BKE_subdiv_ccg_recalc_normals(SubdivCCG &subdiv_ccg)
/* Grids don't have normals, can do early output. */
return;
}
subdiv_ccg_recalc_inner_grid_normals(subdiv_ccg, IndexMask(subdiv_ccg.num_faces));
subdiv_ccg_recalc_inner_grid_normals(subdiv_ccg, subdiv_ccg.faces.index_range());
BKE_subdiv_ccg_average_grids(subdiv_ccg);
}
@@ -854,7 +823,7 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG &subdiv_ccg,
CCGKey &key,
const SubdivCCGFace &face)
{
CCGElem **grids = subdiv_ccg.grids;
const Span<CCGElem *> grids = subdiv_ccg.grids;
const int num_face_grids = face.num_grids;
const int grid_size = subdiv_ccg.grid_size;
CCGElem *prev_grid = grids[face.start_grid_index + num_face_grids - 1];
@@ -923,7 +892,7 @@ struct AverageGridsCornerData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
/* Optional lookup table. Maps task range index to index in `subdiv_ccg.adjacent_vertices`. */
/* Optional lookup table. Maps task range index to index in `subdiv_ccg.adjacent_verts`. */
const int *adjacent_vert_index_map;
};
@@ -975,7 +944,7 @@ static void subdiv_ccg_average_corners(SubdivCCG &subdiv_ccg,
{
using namespace blender;
adjacent_vert_mask.foreach_index(GrainSize(1024), [&](const int i) {
SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_vertices[i];
SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_verts[i];
subdiv_ccg_average_grids_corners(subdiv_ccg, key, adjacent_vert);
});
}
@@ -987,9 +956,9 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg)
BKE_subdiv_ccg_key_top_level(key, subdiv_ccg);
/* Average inner boundaries of grids (within one face), across faces
* from different face-corners. */
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, IndexRange(subdiv_ccg.num_faces));
subdiv_ccg_average_boundaries(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_edges));
subdiv_ccg_average_corners(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_vertices));
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, subdiv_ccg.faces.index_range());
subdiv_ccg_average_boundaries(subdiv_ccg, key, subdiv_ccg.adjacent_edges.index_range());
subdiv_ccg_average_corners(subdiv_ccg, key, subdiv_ccg.adjacent_verts.index_range());
}
static void subdiv_ccg_affected_face_adjacency(SubdivCCG &subdiv_ccg,
@@ -1041,8 +1010,8 @@ void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG &subdiv_ccg, const IndexMask
});
/* TODO(sergey): Only average elements which are adjacent to modified
* faces. */
subdiv_ccg_average_boundaries(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_edges));
subdiv_ccg_average_corners(subdiv_ccg, key, IndexMask(subdiv_ccg.num_adjacent_vertices));
subdiv_ccg_average_boundaries(subdiv_ccg, key, subdiv_ccg.adjacent_edges.index_range());
subdiv_ccg_average_corners(subdiv_ccg, key, subdiv_ccg.adjacent_verts.index_range());
}
void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
@@ -1051,7 +1020,7 @@ void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
int &r_num_faces,
int &r_num_loops)
{
const int num_grids = subdiv_ccg.num_grids;
const int num_grids = subdiv_ccg.grids.size();
const int grid_size = subdiv_ccg.grid_size;
const int grid_area = grid_size * grid_size;
const int num_edges_per_grid = 2 * (grid_size * (grid_size - 1));
@@ -1074,7 +1043,7 @@ void BKE_subdiv_ccg_print_coord(const char *message, const SubdivCCGCoord &coord
bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord)
{
if (coord.grid_index < 0 || coord.grid_index >= subdiv_ccg.num_grids) {
if (coord.grid_index < 0 || coord.grid_index >= subdiv_ccg.grids.size()) {
return false;
}
const int grid_size = subdiv_ccg.grid_size;
@@ -1244,15 +1213,15 @@ static void neighbor_coords_corner_center_get(const SubdivCCG &subdiv_ccg,
}
}
/* Get index within adjacent_vertices array for the given CCG coordinate. */
/* Get index within adjacent_verts array for the given CCG coordinate. */
static int adjacent_vertex_index_from_coord(const SubdivCCG &subdiv_ccg,
const SubdivCCGCoord &coord)
{
Subdiv *subdiv = subdiv_ccg.subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
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_index = subdiv_ccg.grid_to_face_map[coord.grid_index];
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
const int face_grid_index = coord.grid_index - face.start_grid_index;
const int num_face_grids = face.num_grids;
@@ -1278,8 +1247,8 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg,
const int num_vertex_edges = topology_refiner->getNumVertexEdges(topology_refiner,
adjacent_vertex_index);
SubdivCCGAdjacentVertex &adjacent_vertex = subdiv_ccg.adjacent_vertices[adjacent_vertex_index];
const int num_adjacent_faces = adjacent_vertex.num_adjacent_faces;
const SubdivCCGAdjacentVertex &adjacent_vert = subdiv_ccg.adjacent_verts[adjacent_vertex_index];
const int num_adjacent_faces = adjacent_vert.num_adjacent_faces;
subdiv_ccg_neighbors_init(
r_neighbors, num_vertex_edges, (include_duplicates) ? num_adjacent_faces - 1 : 0);
@@ -1309,14 +1278,14 @@ static void neighbor_coords_corner_vertex_get(const SubdivCCG &subdiv_ccg,
edge_point_index = duplicate_edge_point_index - 1;
}
SubdivCCGAdjacentEdge &adjacent_edge = subdiv_ccg.adjacent_edges[edge_index];
const SubdivCCGAdjacentEdge &adjacent_edge = subdiv_ccg.adjacent_edges[edge_index];
r_neighbors.coords[i] = adjacent_edge.boundary_coords[edge_face_index][edge_point_index];
}
if (include_duplicates) {
/* Add duplicates of the current grid vertex in adjacent faces if requested. */
for (int i = 0, duplicate_i = num_vertex_edges; i < num_adjacent_faces; i++) {
SubdivCCGCoord neighbor_coord = adjacent_vertex.corner_coords[i];
SubdivCCGCoord neighbor_coord = adjacent_vert.corner_coords[i];
if (neighbor_coord.grid_index != coord.grid_index) {
r_neighbors.coords[duplicate_i++] = neighbor_coord;
}
@@ -1328,10 +1297,10 @@ 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;
const SubdivCCGFace &face = subdiv_ccg.faces[subdiv_ccg.grid_to_face_map[coord.grid_index]];
const int face_index = subdiv_ccg.grid_to_face_map[coord.grid_index];
const SubdivCCGFace &face = subdiv_ccg.faces[face_index];
const int face_grid_index = coord.grid_index - face.start_grid_index;
const int face_index = &face - subdiv_ccg.faces;
const int num_face_edges = topology_refiner->getNumFaceEdges(topology_refiner, face_index);
Array<int, 64> face_edges(num_face_edges);
@@ -1626,7 +1595,7 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int gri
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
{
if (subdiv_ccg.cache_.start_face_grid_index == nullptr) {
if (subdiv_ccg.cache_.start_face_grid_index.is_empty()) {
const Subdiv *subdiv = subdiv_ccg.subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
if (topology_refiner == nullptr) {
@@ -1635,8 +1604,7 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner);
subdiv_ccg.cache_.start_face_grid_index = static_cast<int *>(
MEM_malloc_arrayN(num_coarse_faces, sizeof(int), "start_face_grid_index"));
subdiv_ccg.cache_.start_face_grid_index.reinitialize(num_coarse_faces);
int start_grid_index = 0;
for (int face_index = 0; face_index < num_coarse_faces; face_index++) {
@@ -1647,12 +1615,12 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
}
}
return subdiv_ccg.cache_.start_face_grid_index;
return subdiv_ccg.cache_.start_face_grid_index.data();
}
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG &subdiv_ccg)
{
return subdiv_ccg.cache_.start_face_grid_index;
return subdiv_ccg.cache_.start_face_grid_index.data();
}
static void adjacent_vertices_index_from_adjacent_edge(const SubdivCCG &subdiv_ccg,
@@ -1745,7 +1713,7 @@ static void subdiv_ccg_coord_to_ptex_coord(const SubdivCCG &subdiv_ccg,
const float grid_v = coord.y * grid_size_1_inv;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, coord.grid_index);
const SubdivCCGFace *faces = subdiv_ccg.faces;
const Span<SubdivCCGFace> faces = subdiv_ccg.faces;
const SubdivCCGFace &face = faces[face_index];
const int *face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
*r_ptex_face_index = face_ptex_offset[face_index];

View File

@@ -41,7 +41,6 @@ struct PBVH_GPU_Args {
blender::OffsetIndices<int> faces;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
int mesh_grids_num;
const CustomData *vert_data;
const CustomData *loop_data;
const CustomData *face_data;
@@ -54,11 +53,11 @@ struct PBVH_GPU_Args {
int face_sets_color_seed, face_sets_color_default;
SubdivCCG *subdiv_ccg;
const DMFlagMat *grid_flag_mats;
blender::Span<DMFlagMat> grid_flag_mats;
blender::Span<int> grid_indices;
CCGKey ccg_key;
CCGElem **grids;
BLI_bitmap **grid_hidden;
blender::Span<CCGElem *> grids;
blender::Span<const BLI_bitmap *> grid_hidden;
blender::Span<int> prim_indices;

View File

@@ -358,7 +358,7 @@ struct PBVHBatches {
break;
}
case PBVH_GRIDS: {
count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
count = BKE_pbvh_count_grid_quads(args.grid_hidden,
args.grid_indices.data(),
args.grid_indices.size(),
args.ccg_key.grid_size,
@@ -1170,7 +1170,7 @@ struct PBVHBatches {
for (const int grid_index : args.grid_indices) {
bool smooth = !args.grid_flag_mats[grid_index].sharp;
BLI_bitmap *gh = args.grid_hidden[grid_index];
const BLI_bitmap *gh = args.grid_hidden[grid_index];
for (int y = 0; y < gridsize - 1; y += skip) {
for (int x = 0; x < gridsize - 1; x += skip) {
@@ -1194,11 +1194,8 @@ struct PBVHBatches {
const CCGKey *key = &args.ccg_key;
uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
args.grid_indices.data(),
totgrid,
key->grid_size,
display_gridsize);
uint visible_quad_len = BKE_pbvh_count_grid_quads(
args.grid_hidden, args.grid_indices.data(), totgrid, key->grid_size, display_gridsize);
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
GPU_indexbuf_init(&elb_lines,
@@ -1213,7 +1210,7 @@ struct PBVHBatches {
uint v0, v1, v2, v3;
bool grid_visible = false;
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
const BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
for (int j = 0; j < gridsize - skip; j += skip) {
for (int k = 0; k < gridsize - skip; k += skip) {
@@ -1251,7 +1248,7 @@ struct PBVHBatches {
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
bool grid_visible = false;
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
const BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
uint v0, v1, v2, v3;
for (int j = 0; j < gridsize - skip; j += skip) {

View File

@@ -28,6 +28,7 @@
#include "BKE_multires.hh"
#include "BKE_paint.hh"
#include "BKE_pbvh_api.hh"
#include "BKE_subdiv_ccg.hh"
#include "BKE_subsurf.hh"
#include "DEG_depsgraph.hh"
@@ -120,15 +121,17 @@ static void partialvis_update_grids(Depsgraph *depsgraph,
PartialVisArea area,
float planes[4][4])
{
CCGElem **grids;
BLI_bitmap **grid_hidden;
CCGElem *const *grids;
const int *grid_indices;
int totgrid;
bool any_changed = false, any_visible = false;
/* Get PBVH data. */
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids);
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
blender::MutableSpan<BLI_bitmap *> grid_hidden = subdiv_ccg->grid_hidden;
CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);

View File

@@ -415,8 +415,8 @@ bool SCULPT_vertex_visible_get(const SculptSession *ss, PBVHVertRef vertex)
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
const int grid_index = vertex.i / key->grid_area;
const int vertex_index = vertex.i - grid_index * key->grid_area;
BLI_bitmap **grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh);
if (grid_hidden && grid_hidden[grid_index]) {
const blender::Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh);
if (grid_hidden[grid_index]) {
return !BLI_BITMAP_TEST(grid_hidden[grid_index], vertex_index);
}
}

View File

@@ -470,7 +470,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
CCGKey key;
int gridsize;
grids = subdiv_ccg->grids;
grids = subdiv_ccg->grids.data();
gridsize = subdiv_ccg->grid_size;
BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg);
@@ -511,7 +511,7 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool
}
}
else if (unode->maxgrid && subdiv_ccg != nullptr) {
BLI_bitmap **grid_hidden = subdiv_ccg->grid_hidden;
blender::MutableSpan<BLI_bitmap *> grid_hidden = subdiv_ccg->grid_hidden;
for (int i = 0; i < unode->totgrid; i++) {
SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]);
@@ -588,7 +588,7 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m
CCGKey key;
int gridsize;
grids = subdiv_ccg->grids;
grids = subdiv_ccg->grids.data();
gridsize = subdiv_ccg->grid_size;
BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg);
@@ -927,8 +927,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
}
else if (unode->maxgrid && subdiv_ccg != nullptr) {
if ((subdiv_ccg->num_grids != unode->maxgrid) || (subdiv_ccg->grid_size != unode->gridsize))
{
if ((subdiv_ccg->grids.size() != unode->maxgrid) ||
(subdiv_ccg->grid_size != unode->gridsize)) {
continue;
}
@@ -1166,7 +1166,7 @@ SculptUndoNode *SCULPT_undo_get_first_node()
static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode)
{
PBVHNode *node = static_cast<PBVHNode *>(unode->node);
BLI_bitmap **grid_hidden = BKE_pbvh_grid_hidden(pbvh);
const blender::Span<const BLI_bitmap *> grid_hidden = BKE_pbvh_get_grid_visibility(pbvh);
const int *grid_indices;
int totgrid;

View File

@@ -262,19 +262,3 @@ extern "C" bool IMB_saveiff(struct ImBuf * /*ibuf*/, const char * /*filepath*/,
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_pbvh.hh
* \{ */
int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/,
const int * /*grid_indices*/,
int /*totgrid*/,
int /*gridsize*/,
int /*display_gridsize*/)
{
BLI_assert_unreachable();
return 0;
}
/** \} */