Refactor: Sculpt: Remove PBVH CCGKey storage

Part of #118145.
This commit is contained in:
Hans Goudey
2024-07-08 17:54:28 -04:00
parent 977e961067
commit 4817ff1d72
12 changed files with 99 additions and 130 deletions

View File

@@ -732,7 +732,6 @@ void BKE_sculpt_toolsettings_data_ensure(Main *bmain, Scene *scene);
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob);
void BKE_sculpt_bvh_update_from_ccg(PBVH &pbvh, SubdivCCG *subdiv_ccg);
void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);

View File

@@ -129,7 +129,7 @@ void update_mesh_pointers(PBVH &pbvh, Mesh *mesh);
/**
* Do a full rebuild with on Grids data structure.
*/
std::unique_ptr<PBVH> build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subdiv_ccg);
std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);
/**
* Build a PBVH from a BMesh.
*/
@@ -249,11 +249,6 @@ int count_grid_quads(const BitGroupVector<> &grid_visibility,
} // namespace blender::bke::pbvh
/**
* Multi-res level, only valid for type == #PBVH_GRIDS.
*/
const CCGKey *BKE_pbvh_get_grid_key(const PBVH &pbvh);
int BKE_pbvh_get_grid_num_verts(const PBVH &pbvh);
int BKE_pbvh_get_grid_num_faces(const PBVH &pbvh);
@@ -382,7 +377,6 @@ IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
Span<const PBVHNode *> nodes,
IndexMaskMemory &memory);
}
void BKE_pbvh_grids_update(PBVH &pbvh, const CCGKey *key);
void BKE_pbvh_subdiv_cgg_set(PBVH &pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_vert_coords_apply(PBVH &pbvh, blender::Span<blender::float3> vert_positions);

View File

@@ -2309,11 +2309,10 @@ static std::unique_ptr<PBVH> build_pbvh_from_regular_mesh(Object *ob, const Mesh
static std::unique_ptr<PBVH> build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*subdiv_ccg);
Mesh *base_mesh = BKE_mesh_from_object(ob);
BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
return pbvh::build_grids(&key, base_mesh, subdiv_ccg);
return pbvh::build_grids(base_mesh, subdiv_ccg);
}
} // namespace blender::bke
@@ -2330,21 +2329,12 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
* those pointers. */
const PBVHType pbvh_type = BKE_pbvh_type(*ob->sculpt->pbvh);
switch (pbvh_type) {
case PBVH_FACES: {
case PBVH_FACES:
pbvh::update_mesh_pointers(*ob->sculpt->pbvh, BKE_object_get_original_mesh(ob));
break;
}
case PBVH_GRIDS: {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
if (SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get()) {
BKE_sculpt_bvh_update_from_ccg(*ob->sculpt->pbvh, subdiv_ccg);
}
case PBVH_GRIDS:
case PBVH_BMESH:
break;
}
case PBVH_BMESH: {
break;
}
}
return ob->sculpt->pbvh.get();
@@ -2385,12 +2375,6 @@ bool BKE_object_sculpt_use_dyntopo(const Object *object)
return object->sculpt && object->sculpt->bm;
}
void BKE_sculpt_bvh_update_from_ccg(PBVH &pbvh, SubdivCCG *subdiv_ccg)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*subdiv_ccg);
BKE_pbvh_grids_update(pbvh, &key);
}
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
{
SculptSession *ss = ob->sculpt;

View File

@@ -299,8 +299,8 @@ static void build_grid_leaf_node(PBVH &pbvh, PBVHNode *node)
{
int totquads = count_grid_quads(pbvh.subdiv_ccg->grid_hidden,
node->prim_indices,
pbvh.gridkey.grid_size,
pbvh.gridkey.grid_size);
pbvh.subdiv_ccg->grid_size,
pbvh.subdiv_ccg->grid_size);
BKE_pbvh_node_fully_hidden_set(node, (totquads == 0));
BKE_pbvh_node_mark_rebuild_draw(node);
}
@@ -726,12 +726,11 @@ std::unique_ptr<PBVH> build_mesh(Mesh *mesh)
return pbvh;
}
std::unique_ptr<PBVH> build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subdiv_ccg)
std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
std::unique_ptr<PBVH> pbvh = std::make_unique<PBVH>();
pbvh->header.type = PBVH_GRIDS;
pbvh->gridkey = *key;
pbvh->subdiv_ccg = subdiv_ccg;
/* Find maximum number of grids per face. */
@@ -741,13 +740,14 @@ std::unique_ptr<PBVH> build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subd
max_grids = max_ii(max_grids, faces[i].size());
}
const CCGKey key = BKE_subdiv_ccg_key_top_level(*subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg->grids;
/* Ensure leaf limit is at least 4 so there's room
* to split at original face boundaries.
* Fixes #102209.
*/
const int leaf_limit = max_ii(LEAF_LIMIT / (key->grid_area), max_grids);
const int leaf_limit = max_ii(LEAF_LIMIT / (key.grid_area), max_grids);
/* We also need the base mesh for PBVH draw. */
pbvh->mesh = mesh;
@@ -763,8 +763,8 @@ std::unique_ptr<PBVH> build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subd
for (const int i : range) {
CCGElem *grid = grids[i];
prim_bounds[i] = negative_bounds();
for (const int j : IndexRange(key->grid_area)) {
const float3 &position = CCG_elem_offset_co(*key, grid, j);
for (const int j : IndexRange(key.grid_area)) {
const float3 &position = CCG_elem_offset_co(key, grid, j);
math::min_max(position, prim_bounds[i].min, prim_bounds[i].max);
}
const float3 center = math::midpoint(prim_bounds[i].min, prim_bounds[i].max);
@@ -1290,7 +1290,8 @@ static bool update_leaf_node_bounds(PBVH &pbvh)
update_node_bounds_mesh(pbvh.vert_positions, *node);
break;
case PBVH_GRIDS:
update_node_bounds_grids(pbvh.gridkey, pbvh.subdiv_ccg->grids, *node);
update_node_bounds_grids(
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg), pbvh.subdiv_ccg->grids, *node);
break;
case PBVH_BMESH:
update_node_bounds_bmesh(*node);
@@ -1625,23 +1626,18 @@ Bounds<float3> bounds_get(const PBVH &pbvh)
} // namespace blender::bke::pbvh
const CCGKey *BKE_pbvh_get_grid_key(const PBVH &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_GRIDS);
return &pbvh.gridkey;
}
int BKE_pbvh_get_grid_num_verts(const PBVH &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_GRIDS);
return pbvh.subdiv_ccg->grids.size() * pbvh.gridkey.grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
return pbvh.subdiv_ccg->grids.size() * key.grid_area;
}
int BKE_pbvh_get_grid_num_faces(const PBVH &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_GRIDS);
return pbvh.subdiv_ccg->grids.size() * (pbvh.gridkey.grid_size - 1) *
(pbvh.gridkey.grid_size - 1);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
return pbvh.subdiv_ccg->grids.size() * square_i(key.grid_size - 1);
}
/***************************** Node Access ***********************************/
@@ -2068,11 +2064,11 @@ static bool pbvh_grids_node_raycast(PBVH &pbvh,
int *r_active_grid_index,
float *r_face_normal)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
const int totgrid = node->prim_indices.size();
const int gridsize = pbvh.gridkey.grid_size;
const int gridsize = key.grid_size;
bool hit = false;
float nearest_vertex_co[3] = {0.0};
const CCGKey &gridkey = pbvh.gridkey;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg->grids;
@@ -2100,10 +2096,10 @@ static bool pbvh_grids_node_raycast(PBVH &pbvh,
co[3] = origco[y * gridsize + x];
}
else {
co[0] = CCG_grid_elem_co(gridkey, grid, x, y + 1);
co[1] = CCG_grid_elem_co(gridkey, grid, x + 1, y + 1);
co[2] = CCG_grid_elem_co(gridkey, grid, x + 1, y);
co[3] = CCG_grid_elem_co(gridkey, grid, x, y);
co[0] = CCG_grid_elem_co(key, grid, x, y + 1);
co[1] = CCG_grid_elem_co(key, grid, x + 1, y + 1);
co[2] = CCG_grid_elem_co(key, grid, x + 1, y);
co[3] = CCG_grid_elem_co(key, grid, x, y);
}
if (ray_face_intersection_quad(
@@ -2131,8 +2127,8 @@ static bool pbvh_grids_node_raycast(PBVH &pbvh,
{
copy_v3_v3(nearest_vertex_co, co[j]);
r_active_vertex->i = gridkey.grid_area * grid_index +
(y + y_it[j]) * gridkey.grid_size + (x + x_it[j]);
r_active_vertex->i = key.grid_area * grid_index + (y + y_it[j]) * key.grid_size +
(x + x_it[j]);
}
}
}
@@ -2405,8 +2401,9 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH &pbvh,
float *depth,
float *dist_sq)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
const int totgrid = node->prim_indices.size();
const int gridsize = pbvh.gridkey.grid_size;
const int gridsize = key.grid_size;
bool hit = false;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg->grids;
@@ -2439,10 +2436,10 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH &pbvh,
else {
hit |= ray_face_nearest_quad(ray_start,
ray_normal,
CCG_grid_elem_co(pbvh.gridkey, grid, x, y),
CCG_grid_elem_co(pbvh.gridkey, grid, x + 1, y),
CCG_grid_elem_co(pbvh.gridkey, grid, x + 1, y + 1),
CCG_grid_elem_co(pbvh.gridkey, grid, x, y + 1),
CCG_grid_elem_co(key, grid, x, y),
CCG_grid_elem_co(key, grid, x + 1, y),
CCG_grid_elem_co(key, grid, x + 1, y + 1),
CCG_grid_elem_co(key, grid, x, y + 1),
depth,
dist_sq);
}
@@ -2601,7 +2598,7 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
args.vert_data = &pbvh.mesh->vert_data;
args.corner_data = &pbvh.mesh->corner_data;
args.face_data = &pbvh.mesh->face_data;
args.ccg_key = pbvh.gridkey;
args.ccg_key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
args.mesh = pbvh.mesh;
args.grid_indices = node.prim_indices;
args.subdiv_ccg = pbvh.subdiv_ccg;
@@ -2770,11 +2767,6 @@ void BKE_pbvh_draw_debug_cb(PBVH &pbvh,
}
}
void BKE_pbvh_grids_update(PBVH &pbvh, const CCGKey *key)
{
pbvh.gridkey = *key;
}
void BKE_pbvh_vert_coords_apply(PBVH &pbvh, const Span<float3> vert_positions)
{
using namespace blender::bke::pbvh;
@@ -2831,9 +2823,11 @@ PBVHProxyNode &BKE_pbvh_node_add_proxy(PBVH &pbvh, PBVHNode &node)
int num_unique_verts = 0;
switch (pbvh.header.type) {
case PBVH_GRIDS:
num_unique_verts = node.prim_indices.size() * pbvh.gridkey.grid_area;
case PBVH_GRIDS: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
num_unique_verts = node.prim_indices.size() * key.grid_area;
break;
}
case PBVH_FACES:
num_unique_verts = node.uniq_verts;
break;
@@ -2885,7 +2879,8 @@ void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
int totvert;
switch (pbvh.header.type) {
case PBVH_GRIDS:
totvert = node->prim_indices.size() * pbvh.gridkey.grid_area;
totvert = node->prim_indices.size() *
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg).grid_area;
uniq_verts = totvert;
break;
case PBVH_FACES:
@@ -2899,11 +2894,11 @@ void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
}
if (pbvh.header.type == PBVH_GRIDS) {
vi->key = pbvh.gridkey;
vi->key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
vi->grids = pbvh.subdiv_ccg->grids.data();
vi->grid_indices = node->prim_indices.data();
vi->totgrid = node->prim_indices.size();
vi->gridsize = pbvh.gridkey.grid_size;
vi->gridsize = vi->key.grid_size;
}
else {
vi->key = {};
@@ -2953,7 +2948,7 @@ bool pbvh_has_mask(const PBVH &pbvh)
{
switch (pbvh.header.type) {
case PBVH_GRIDS:
return (pbvh.gridkey.has_mask != 0);
return BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg).has_mask;
case PBVH_FACES:
return pbvh.mesh->attributes().contains(".sculpt_mask");
case PBVH_BMESH:
@@ -3117,7 +3112,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH &pbvh, Mesh *mesh)
case PBVH_GRIDS: {
const OffsetIndices faces = mesh->faces();
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
CCGKey key = pbvh.gridkey;
CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
IndexMaskMemory memory;
const IndexMask hidden_faces =

View File

@@ -145,7 +145,6 @@ struct PBVH {
blender::Span<blender::float3> face_normals;
/* Grid Data */
CCGKey gridkey;
SubdivCCG *subdiv_ccg;
#ifdef PERFCNTRS

View File

@@ -574,11 +574,10 @@ static void partialvis_masked_update_grids(Depsgraph &depsgraph,
const VisAction action,
const Span<PBVHNode *> nodes)
{
PBVH &pbvh = *object.sculpt->pbvh;
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
const bool value = action_to_hide(action);
const CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
if (!key.has_mask) {
grid_hide_update(depsgraph,
@@ -1005,7 +1004,7 @@ static void grow_shrink_visibility_grid(Depsgraph &depsgraph,
BitGroupVector<> &grid_hidden = BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg);
const bool desired_state = action_to_hide(action);
const CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
DualBitBuffer buffers;
buffers.front = grid_hidden;
@@ -1245,12 +1244,11 @@ static void partialvis_gesture_update_grids(Depsgraph &depsgraph,
const VisAction action = operation->action;
const Span<PBVHNode *> nodes = gesture_data.nodes;
PBVH &pbvh = *object->sculpt->pbvh;
SubdivCCG *subdiv_ccg = object->sculpt->subdiv_ccg;
SubdivCCG &subdiv_ccg = *object->sculpt->subdiv_ccg;
const bool value = action_to_hide(action);
const CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
const Span<CCGElem *> grids = subdiv_ccg->grids;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
grid_hide_update(
depsgraph, *object, nodes, [&](const int grid_index, MutableBoundedBitSpan hide) {
CCGElem *grid = grids[grid_index];

View File

@@ -767,7 +767,7 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
SubdivCCG &subdiv_ccg = *gesture_data.ss->subdiv_ccg;
const Span<CCGElem *> grids = subdiv_ccg.grids;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
bool any_changed = false;

View File

@@ -194,11 +194,11 @@ const float *SCULPT_vertex_co_get(const SculptSession &ss, PBVHVertRef vertex)
case PBVH_BMESH:
return ((BMVert *)vertex.i)->co;
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
CCGElem *elem = ss.subdiv_ccg->grids[grid_index];
return CCG_elem_co(*key, CCG_elem_offset(*key, elem, index_in_grid));
return CCG_elem_co(key, CCG_elem_offset(key, elem, index_in_grid));
}
}
return nullptr;
@@ -216,11 +216,11 @@ const blender::float3 SCULPT_vertex_normal_get(const SculptSession &ss, PBVHVert
return v->no;
}
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
CCGElem *elem = ss.subdiv_ccg->grids[grid_index];
return CCG_elem_no(*key, CCG_elem_offset(*key, elem, index_in_grid));
return CCG_elem_no(key, CCG_elem_offset(key, elem, index_in_grid));
}
}
BLI_assert_unreachable();
@@ -260,14 +260,14 @@ float3 SCULPT_vertex_limit_surface_get(const SculptSession &ss, PBVHVertRef vert
case PBVH_BMESH:
return SCULPT_vertex_co_get(ss, vertex);
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
SubdivCCGCoord coord{};
coord.grid_index = grid_index;
coord.x = index_in_grid % key->grid_size;
coord.y = index_in_grid / key->grid_size;
coord.x = index_in_grid % key.grid_size;
coord.y = index_in_grid / key.grid_size;
float3 tmp;
BKE_subdiv_ccg_eval_limit_point(*ss.subdiv_ccg, coord, tmp);
return tmp;
@@ -391,9 +391,9 @@ bool vert_visible_get(const SculptSession &ss, PBVHVertRef vertex)
case PBVH_BMESH:
return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN);
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
if (!ss.subdiv_ccg->grid_hidden.is_empty()) {
return !ss.subdiv_ccg->grid_hidden[grid_index][index_in_grid];
}
@@ -466,8 +466,8 @@ bool vert_all_faces_visible_get(const SculptSession &ss, PBVHVertRef vertex)
if (!ss.hide_poly) {
return true;
}
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg, grid_index);
return !ss.hide_poly[face_index];
}
@@ -500,8 +500,8 @@ int vert_face_set_get(const SculptSession &ss, PBVHVertRef vertex)
if (!ss.face_sets) {
return SCULPT_FACE_SET_NONE;
}
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg, grid_index);
return ss.face_sets[face_index];
}
@@ -529,8 +529,8 @@ bool vert_has_face_set(const SculptSession &ss, PBVHVertRef vertex, int face_set
if (!ss.face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg, grid_index);
return ss.face_sets[face_index] == face_set;
}
@@ -602,13 +602,13 @@ bool vert_has_unique_face_set(const SculptSession &ss, PBVHVertRef vertex)
if (!ss.face_sets) {
return true;
}
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
SubdivCCGCoord coord{};
coord.grid_index = grid_index;
coord.x = index_in_grid % key->grid_size;
coord.y = index_in_grid / key->grid_size;
coord.x = index_in_grid % key.grid_size;
coord.y = index_in_grid / key.grid_size;
int v1, v2;
const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
*ss.subdiv_ccg, coord, ss.corner_verts, ss.faces, v1, v2);
@@ -745,14 +745,14 @@ static void sculpt_vertex_neighbors_get_grids(const SculptSession &ss,
/* TODO: optimize this. We could fill #SculptVertexNeighborIter directly,
* maybe provide coordinate and mask pointers directly rather than converting
* back and forth between #CCGElem and global index. */
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
SubdivCCGCoord coord{};
coord.grid_index = grid_index;
coord.x = index_in_grid % key->grid_size;
coord.y = index_in_grid / key->grid_size;
coord.x = index_in_grid % key.grid_size;
coord.y = index_in_grid / key.grid_size;
SubdivCCGNeighbors neighbors;
BKE_subdiv_ccg_neighbor_coords_get(*ss.subdiv_ccg, coord, include_duplicates, neighbors);
@@ -762,8 +762,8 @@ static void sculpt_vertex_neighbors_get_grids(const SculptSession &ss,
iter->neighbor_indices.clear();
for (const int i : neighbors.coords.index_range()) {
int v = neighbors.coords[i].grid_index * key->grid_area +
neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x;
int v = neighbors.coords[i].grid_index * key.grid_area +
neighbors.coords[i].y * key.grid_size + neighbors.coords[i].x;
sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v);
}
@@ -818,13 +818,13 @@ bool SCULPT_vertex_is_boundary(const SculptSession &ss, const PBVHVertRef vertex
return BM_vert_is_boundary(v);
}
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const int grid_index = vertex.i / key->grid_area;
const int index_in_grid = vertex.i - grid_index * key->grid_area;
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
SubdivCCGCoord coord{};
coord.grid_index = grid_index;
coord.x = index_in_grid % key->grid_size;
coord.y = index_in_grid / key->grid_size;
coord.x = index_in_grid % key.grid_size;
coord.y = index_in_grid / key.grid_size;
int v1, v2;
const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
*ss.subdiv_ccg, coord, ss.corner_verts, ss.faces, v1, v2);
@@ -2067,7 +2067,7 @@ static void calc_area_normal_and_center_node_grids(const SculptSession &ss,
AreaNormalCenterData &anctd)
{
const float3 &view_normal = ss.cache ? ss.cache->view_normal : ss.cursor_view_normal;
const CCGKey key = *BKE_pbvh_get_grid_key(*ss.pbvh);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const Span<CCGElem *> grids = subdiv_ccg.grids;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;

View File

@@ -32,6 +32,7 @@
#include "BKE_modifier.hh"
#include "BKE_paint.hh"
#include "BKE_pbvh_api.hh"
#include "BKE_subdiv_ccg.hh"
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_query.hh"
@@ -1067,7 +1068,7 @@ SimulationData *brush_simulation_create(Object &ob,
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
break;
case PBVH_GRIDS:
cloth_sim->grid_key = *BKE_pbvh_get_grid_key(*ss.pbvh);
cloth_sim->grid_key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
break;
}

View File

@@ -155,8 +155,7 @@ static bool is_face_in_active_component(const SculptSession &ss,
vertex.i = corner_verts[faces[f].start()];
break;
case PBVH_GRIDS: {
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
vertex.i = faces[f].start() * key->grid_area;
vertex.i = faces[f].start() * BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg).grid_area;
break;
}
case PBVH_BMESH: {
@@ -800,17 +799,17 @@ static void update_max_face_falloff_factor(SculptSession &ss, Mesh &mesh, Cache
static void vert_to_face_falloff_grids(SculptSession &ss, Mesh *mesh, Cache *expand_cache)
{
const OffsetIndices faces = mesh->faces();
const CCGKey *key = BKE_pbvh_get_grid_key(*ss.pbvh);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
for (const int i : faces.index_range()) {
float accum = 0.0f;
for (const int corner : faces[i]) {
const int grid_loop_index = corner * key->grid_area;
for (int g = 0; g < key->grid_area; g++) {
const int grid_loop_index = corner * key.grid_area;
for (int g = 0; g < key.grid_area; g++) {
accum += expand_cache->vert_falloff[grid_loop_index + g];
}
}
expand_cache->face_falloff[i] = accum / (faces[i].size() * key->grid_area);
expand_cache->face_falloff[i] = accum / (faces[i].size() * key.grid_area);
}
}

View File

@@ -160,7 +160,8 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
case PBVH_GRIDS: {
Main &bmain = *CTX_data_main(C);
Scene &scene = *CTX_data_scene(C);
const CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
switch (mode) {
case InitMode::Random: {
init_mask_grids(
@@ -183,7 +184,6 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan face_sets = *attributes.lookup_or_default<int>(
".sculpt_face_set", bke::AttrDomain::Face, 1);
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const Span<int> grid_to_face = subdiv_ccg.grid_to_face_map;
init_mask_grids(
bmain,

View File

@@ -297,7 +297,7 @@ float neighbor_mask_average(SculptSession &ss,
case PBVH_GRIDS: {
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
avg += SCULPT_mask_get_at_grids_vert_index(
*ss.subdiv_ccg, *BKE_pbvh_get_grid_key(*ss.pbvh), ni.vertex.i);
*ss.subdiv_ccg, BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg), ni.vertex.i);
total++;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);