Refactor: Sculpt: Remove SubdivCCG pointer from BVH tree

Part of #118145.
This commit is contained in:
Hans Goudey
2024-08-22 16:07:16 -04:00
parent 24809baf2b
commit c7b4e3e71a
20 changed files with 144 additions and 121 deletions

View File

@@ -183,9 +183,6 @@ class Tree {
/* Memory backing for Node.prim_indices. */
Array<int> prim_indices_;
/* Grid Data */
SubdivCCG *subdiv_ccg_ = nullptr;
float planes_[6][4];
int num_planes_;
@@ -279,6 +276,7 @@ bool raycast_node(Tree &pbvh,
Span<int3> corner_tris,
Span<int> corner_tri_faces,
Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@@ -321,6 +319,7 @@ bool find_nearest_to_ray_node(Tree &pbvh,
Span<int3> corner_tris,
Span<int> corner_tri_faces,
Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@@ -358,8 +357,8 @@ int count_grid_quads(const BitGroupVector<> &grid_visibility,
} // namespace blender::bke::pbvh
int BKE_pbvh_get_grid_num_verts(const blender::bke::pbvh::Tree &pbvh);
int BKE_pbvh_get_grid_num_faces(const blender::bke::pbvh::Tree &pbvh);
int BKE_pbvh_get_grid_num_verts(const Object &object);
int BKE_pbvh_get_grid_num_faces(const Object &object);
enum PBVHTopologyUpdateMode {
PBVH_Subdivide = 1,
@@ -425,7 +424,9 @@ Span<int> node_face_indices_calc_mesh(Span<int> corner_tri_faces,
* Gather the indices of all base mesh faces in the node.
* For convenience, pass a reference to the data in the result.
*/
Span<int> node_face_indices_calc_grids(const Tree &pbvh, const Node &node, Vector<int> &faces);
Span<int> node_face_indices_calc_grids(const SubdivCCG &subdiv_ccg,
const Node &node,
Vector<int> &faces);
Bounds<float3> node_bounds(const Node &node);
@@ -496,7 +497,6 @@ IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
Span<const Node *> nodes,
IndexMaskMemory &memory);
}
void BKE_pbvh_subdiv_cgg_set(blender::bke::pbvh::Tree &pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh,
blender::Span<blender::float3> vert_positions);

View File

@@ -1997,8 +1997,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
BLI_assert(pbvh == ss.pbvh.get());
UNUSED_VARS_NDEBUG(pbvh);
BKE_pbvh_subdiv_cgg_set(*ss.pbvh, ss.subdiv_ccg);
sculpt_attribute_update_refs(ob, ss.pbvh->type());
if (ob->type == OB_MESH) {

View File

@@ -523,8 +523,6 @@ std::unique_ptr<Tree> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
std::unique_ptr<Tree> pbvh = std::make_unique<Tree>(Type::Grids);
pbvh->subdiv_ccg_ = subdiv_ccg;
/* Find maximum number of grids per face. */
int max_grids = 1;
const OffsetIndices faces = mesh->faces();
@@ -1572,18 +1570,20 @@ Bounds<float3> bounds_get(const Tree &pbvh)
} // namespace blender::bke::pbvh
int BKE_pbvh_get_grid_num_verts(const blender::bke::pbvh::Tree &pbvh)
int BKE_pbvh_get_grid_num_verts(const Object &object)
{
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
return pbvh.subdiv_ccg_->grids.size() * key.grid_area;
const SculptSession &ss = *object.sculpt;
BLI_assert(ss.pbvh->type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
return ss.subdiv_ccg->grids.size() * key.grid_area;
}
int BKE_pbvh_get_grid_num_faces(const blender::bke::pbvh::Tree &pbvh)
int BKE_pbvh_get_grid_num_faces(const Object &object)
{
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
return pbvh.subdiv_ccg_->grids.size() * square_i(key.grid_size - 1);
const SculptSession &ss = *object.sculpt;
BLI_assert(ss.pbvh->type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
return ss.subdiv_ccg->grids.size() * square_i(key.grid_size - 1);
}
/***************************** Node Access ***********************************/
@@ -1723,10 +1723,12 @@ Span<int> node_face_indices_calc_mesh(const Span<int> corner_tri_faces,
return faces.as_span();
}
Span<int> node_face_indices_calc_grids(const Tree &pbvh, const Node &node, Vector<int> &faces)
Span<int> node_face_indices_calc_grids(const SubdivCCG &subdiv_ccg,
const Node &node,
Vector<int> &faces)
{
faces.clear();
const Span<int> grid_to_face_map = pbvh.subdiv_ccg_->grid_to_face_map;
const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
int prev_face = -1;
for (const int prim : node.prim_indices_) {
const int face = grid_to_face_map[prim];
@@ -1994,7 +1996,7 @@ static bool pbvh_faces_node_raycast(const Node &node,
return hit;
}
static bool pbvh_grids_node_raycast(Tree &pbvh,
static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg,
Node &node,
const float (*origco)[3],
const float ray_start[3],
@@ -2005,13 +2007,13 @@ static bool pbvh_grids_node_raycast(Tree &pbvh,
int *r_active_grid_index,
float *r_face_normal)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const int totgrid = node.prim_indices_.size();
const int gridsize = key.grid_size;
bool hit = false;
float nearest_vertex_co[3] = {0.0};
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg_->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg_->grids;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const Span<CCGElem *> grids = subdiv_ccg.grids;
for (int i = 0; i < totgrid; i++) {
const int grid_index = node.prim_indices_[i];
@@ -2097,6 +2099,7 @@ bool raycast_node(Tree &pbvh,
const Span<int3> corner_tris,
const Span<int> corner_tri_faces,
const Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@@ -2129,7 +2132,7 @@ bool raycast_node(Tree &pbvh,
face_normal);
break;
case Type::Grids:
hit |= pbvh_grids_node_raycast(pbvh,
hit |= pbvh_grids_node_raycast(*subdiv_ccg,
node,
origco,
ray_start,
@@ -2141,7 +2144,6 @@ bool raycast_node(Tree &pbvh,
face_normal);
break;
case Type::BMesh:
BM_mesh_elem_index_ensure(pbvh.bm_, BM_VERT);
hit = bmesh_node_raycast(node,
ray_start,
ray_normal,
@@ -2331,7 +2333,7 @@ static bool pbvh_faces_node_nearest_to_ray(const Node &node,
return hit;
}
static bool pbvh_grids_node_nearest_to_ray(Tree &pbvh,
static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
Node &node,
const float (*origco)[3],
const float ray_start[3],
@@ -2339,12 +2341,12 @@ static bool pbvh_grids_node_nearest_to_ray(Tree &pbvh,
float *depth,
float *dist_sq)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const int totgrid = node.prim_indices_.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;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const Span<CCGElem *> grids = subdiv_ccg.grids;
for (int i = 0; i < totgrid; i++) {
CCGElem *grid = grids[node.prim_indices_[i]];
@@ -2401,6 +2403,7 @@ bool find_nearest_to_ray_node(Tree &pbvh,
const Span<int3> corner_tris,
const Span<int> corner_tri_faces,
const Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@@ -2428,7 +2431,7 @@ bool find_nearest_to_ray_node(Tree &pbvh,
break;
case Type::Grids:
hit |= pbvh_grids_node_nearest_to_ray(
pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
*subdiv_ccg, node, origco, ray_start, ray_normal, depth, dist_sq);
break;
case Type::BMesh:
hit = bmesh_node_nearest_to_ray(node, ray_start, ray_normal, depth, dist_sq, use_origco);
@@ -2532,16 +2535,18 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Object &obje
args.prim_indices = node.prim_indices_;
args.tri_faces = mesh_eval.corner_tri_faces();
break;
case blender::bke::pbvh::Type::Grids:
case blender::bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *mesh_eval.runtime->subdiv_ccg;
args.vert_data = &mesh_orig.vert_data;
args.corner_data = &mesh_orig.corner_data;
args.face_data = &mesh_orig.face_data;
args.ccg_key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
args.ccg_key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
args.mesh = &mesh_orig;
args.grid_indices = node.prim_indices_;
args.subdiv_ccg = pbvh.subdiv_ccg_;
args.grids = pbvh.subdiv_ccg_->grids;
args.subdiv_ccg = &const_cast<SubdivCCG &>(subdiv_ccg);
args.grids = subdiv_ccg.grids;
break;
}
case blender::bke::pbvh::Type::BMesh:
args.bm = pbvh.bm_;
args.vert_data = &args.bm->vdata;
@@ -2830,11 +2835,6 @@ Span<float3> vert_normals_eval_from_eval(const Object &object_eval)
} // namespace blender::bke::pbvh
void BKE_pbvh_subdiv_cgg_set(blender::bke::pbvh::Tree &pbvh, SubdivCCG *subdiv_ccg)
{
pbvh.subdiv_ccg_ = subdiv_ccg;
}
void BKE_pbvh_ensure_node_face_corners(blender::bke::pbvh::Tree &pbvh,
const blender::Span<blender::int3> corner_tris)
{

View File

@@ -301,7 +301,7 @@ void do_enhance_details_brush(const Depsgraph &depsgraph,
bke::pbvh::Tree &pbvh = *ss.pbvh;
if (SCULPT_stroke_is_first_brush_step(*ss.cache)) {
ss.cache->detail_directions.reinitialize(SCULPT_vertex_count_get(ss));
ss.cache->detail_directions.reinitialize(SCULPT_vertex_count_get(object));
Vector<bke::pbvh::Node *> effective_nodes = bke::pbvh::search_gather(
pbvh, [&](bke::pbvh::Node &node) { return !node_fully_masked_or_hidden(node); });
calc_smooth_translations(depsgraph, object, effective_nodes, ss.cache->detail_directions);

View File

@@ -384,7 +384,8 @@ void do_layer_brush(const Depsgraph &depsgraph,
if (displacement.is_empty()) {
if (ss.cache->layer_displacement_factor.is_empty()) {
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(ss), 0.0f);
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(object),
0.0f);
}
displacement = ss.cache->layer_displacement_factor;
}
@@ -413,7 +414,7 @@ void do_layer_brush(const Depsgraph &depsgraph,
}
case bke::pbvh::Type::Grids: {
if (ss.cache->layer_displacement_factor.is_empty()) {
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(ss), 0.0f);
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(object), 0.0f);
}
const MutableSpan<float> displacement = ss.cache->layer_displacement_factor;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -426,7 +427,7 @@ void do_layer_brush(const Depsgraph &depsgraph,
}
case bke::pbvh::Type::BMesh: {
if (ss.cache->layer_displacement_factor.is_empty()) {
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(ss), 0.0f);
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(object), 0.0f);
}
const MutableSpan<float> displacement = ss.cache->layer_displacement_factor;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {

View File

@@ -1130,8 +1130,7 @@ static int visibility_filter_exec(bContext *C, wmOperator *op)
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
const SculptSession &ss = *object.sculpt;
int num_verts = SCULPT_vertex_count_get(ss);
int num_verts = SCULPT_vertex_count_get(object);
int iterations = RNA_int_get(op->ptr, "iterations");

View File

@@ -147,15 +147,17 @@ void SCULPT_vertex_random_access_ensure(SculptSession &ss)
}
}
int SCULPT_vertex_count_get(const SculptSession &ss)
int SCULPT_vertex_count_get(const Object &object)
{
const SculptSession &ss = *object.sculpt;
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
return ss.totvert;
BLI_assert(object.type == OB_MESH);
return static_cast<const Mesh *>(object.data)->verts_num;
case blender::bke::pbvh::Type::BMesh:
return BM_mesh_elem_count(ss.bm, BM_VERT);
case blender::bke::pbvh::Type::Grids:
return BKE_pbvh_get_grid_num_verts(*ss.pbvh);
return BKE_pbvh_get_grid_num_verts(object);
}
return 0;
@@ -2948,6 +2950,8 @@ struct SculptRaycastData {
Span<int> corner_tri_faces;
blender::VArraySpan<bool> hide_poly;
const SubdivCCG *subdiv_ccg;
PBVHVertRef active_vertex;
float *face_normal;
@@ -2968,6 +2972,8 @@ struct SculptFindNearestToRayData {
Span<blender::int3> corner_tris;
Span<int> corner_tri_faces;
blender::VArraySpan<bool> hide_poly;
const SubdivCCG *subdiv_ccg;
};
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
@@ -3458,7 +3464,7 @@ static void do_brush_action(const Depsgraph &depsgraph,
(brush.smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE))
{
BLI_assert(ss.cache->surface_smooth_laplacian_disp.is_empty());
ss.cache->surface_smooth_laplacian_disp = Array<float3>(SCULPT_vertex_count_get(ss),
ss.cache->surface_smooth_laplacian_disp = Array<float3>(SCULPT_vertex_count_get(ob),
float3(0));
}
}
@@ -4759,6 +4765,7 @@ static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData
srd.corner_tris,
srd.corner_tri_faces,
srd.hide_poly,
srd.subdiv_ccg,
srd.ray_start,
srd.ray_normal,
&srd.isect_precalc,
@@ -4805,6 +4812,7 @@ static void sculpt_find_nearest_to_ray_cb(blender::bke::pbvh::Node &node,
srd.corner_tris,
srd.corner_tri_faces,
srd.hide_poly,
srd.subdiv_ccg,
srd.ray_start,
srd.ray_normal,
&srd.depth,
@@ -4904,6 +4912,10 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
}
else if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
srd.subdiv_ccg = ss.subdiv_ccg;
}
SCULPT_vertex_random_access_ensure(ss);
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
srd.depth = depth;
@@ -4929,7 +4941,6 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
/* Update the active vertex of the SculptSession. */
const PBVHVertRef active_vertex = srd.active_vertex;
ss.set_active_vert(active_vertex);
SCULPT_vertex_random_access_ensure(ss);
copy_v3_v3(out->active_vertex_co, SCULPT_vertex_co_get(*depsgraph, ob, active_vertex));
switch (ss.pbvh->type()) {
@@ -5059,6 +5070,10 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
}
else if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
srd.subdiv_ccg = ss.subdiv_ccg;
}
SCULPT_vertex_random_access_ensure(ss);
srd.depth = depth;
srd.original = original;
srd.face_normal = face_normal;
@@ -5095,6 +5110,9 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
const bke::AttributeAccessor attributes = mesh.attributes();
srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
}
else if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
srd.subdiv_ccg = ss.subdiv_ccg;
}
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
srd.depth = FLT_MAX;
@@ -5788,9 +5806,10 @@ enum {
SCULPT_TOPOLOGY_ID_DEFAULT,
};
static void fake_neighbor_init(SculptSession &ss, const float max_dist)
static void fake_neighbor_init(Object &object, const float max_dist)
{
const int totvert = SCULPT_vertex_count_get(ss);
SculptSession &ss = *object.sculpt;
const int totvert = SCULPT_vertex_count_get(object);
ss.fake_neighbors.fake_neighbor_index = Array<int>(totvert, FAKE_NEIGHBOR_NONE);
ss.fake_neighbors.current_max_distance = max_dist;
}
@@ -6043,7 +6062,7 @@ void SCULPT_fake_neighbors_ensure(const Depsgraph &depsgraph, Object &ob, const
{
using namespace blender::ed::sculpt_paint;
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
/* Fake neighbors were already initialized with the same distance, so no need to be
* recalculated.
@@ -6055,7 +6074,7 @@ void SCULPT_fake_neighbors_ensure(const Depsgraph &depsgraph, Object &ob, const
}
islands::ensure_cache(ob);
fake_neighbor_init(ss, max_dist);
fake_neighbor_init(ob, max_dist);
const float max_distance_sq = max_dist * max_dist;
/* NOTE: This algorithm is extremely slow, it has O(n^2) runtime for the entire mesh. This looks
@@ -6127,6 +6146,10 @@ bool SCULPT_vertex_is_occluded(const Object &object, const float3 &position, boo
srd.corner_tris = mesh.corner_tris();
srd.corner_tri_faces = mesh.corner_tri_faces();
}
else if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
srd.subdiv_ccg = ss.subdiv_ccg;
}
SCULPT_vertex_random_access_ensure(ss);
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
bke::pbvh::raycast(

View File

@@ -456,10 +456,8 @@ static void calc_blurred_cavity(const Depsgraph &depsgraph,
int settings_hash(const Object &ob, const Cache &automasking)
{
const SculptSession &ss = *ob.sculpt;
int hash;
int totvert = SCULPT_vertex_count_get(ss);
int totvert = SCULPT_vertex_count_get(ob);
hash = BLI_hash_int(automasking.settings.flags);
hash = BLI_hash_int_2d(hash, totvert);
@@ -838,7 +836,7 @@ static void init_face_sets_masking(const Sculpt &sd, Object &ob)
return;
}
int tot_vert = SCULPT_vertex_count_get(ss);
int tot_vert = SCULPT_vertex_count_get(ob);
int active_face_set = face_set::active_face_set_get(ss);
for (int i : IndexRange(tot_vert)) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(*ss.pbvh, i);
@@ -860,7 +858,7 @@ static void init_boundary_masking(Object &ob, BoundaryAutomaskMode mode, int pro
{
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
Array<int> edge_distance(totvert, 0);
for (int i : IndexRange(totvert)) {
@@ -957,7 +955,7 @@ static void normal_occlusion_automasking_fill(const Depsgraph &depsgraph,
eAutomasking_flag mode)
{
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
/* No need to build original data since this is only called at the beginning of strokes. */
for (int i = 0; i < totvert; i++) {
@@ -1100,7 +1098,7 @@ std::unique_ptr<Cache> cache_init(const Depsgraph &depsgraph,
* If it isn't enabled, initialize to 1. */
const float initial_value = !(mode & BRUSH_AUTOMASKING_TOPOLOGY) ? 1.0f : 0.0f;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
for (int i : IndexRange(totvert)) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(*ss.pbvh, i);

View File

@@ -1301,7 +1301,7 @@ static void cloth_brush_satisfy_constraints(const Depsgraph &depsgraph,
const float3 sim_location = cloth_brush_simulation_location_get(ss, brush);
/* Precalculate factors into an array since we need random access to specific vertex values. */
Array<float> factors(SCULPT_vertex_count_get(ss));
Array<float> factors(SCULPT_vertex_count_get(object));
calc_constraint_factors(depsgraph, object, brush, sim_location, cloth_sim.init_pos, factors);
for (int constraint_it = 0; constraint_it < CLOTH_SIMULATION_ITERATIONS; constraint_it++) {
@@ -1687,7 +1687,7 @@ std::unique_ptr<SimulationData> brush_simulation_create(const Depsgraph &depsgra
const bool needs_deform_coords)
{
SculptSession &ss = *ob.sculpt;
const int totverts = SCULPT_vertex_count_get(ss);
const int totverts = SCULPT_vertex_count_get(ob);
std::unique_ptr<SimulationData> cloth_sim = std::make_unique<SimulationData>();
cloth_sim->length_constraints.reserve(CLOTH_LENGTH_CONSTRAINTS_BLOCK);

View File

@@ -344,7 +344,7 @@ static BitVector<> enabled_state_to_bitmap(const Depsgraph &depsgraph,
const Cache &expand_cache)
{
const SculptSession &ss = *object.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(object);
BitVector<> enabled_verts(totvert);
if (expand_cache.all_enabled) {
if (!expand_cache.invert) {
@@ -447,7 +447,7 @@ static IndexMask boundary_from_enabled(Object &object,
IndexMaskMemory &memory)
{
SculptSession &ss = *object.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(object);
const IndexMask enabled_mask = IndexMask::from_bits(enabled_verts, memory);
@@ -646,7 +646,7 @@ static void calc_topology_falloff_from_verts(Object &ob,
MutableSpan<float> distances)
{
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
@@ -713,7 +713,7 @@ static Array<float> topology_falloff_create(const Depsgraph &depsgraph,
IndexMaskMemory memory;
const IndexMask mask = IndexMask::from_indices(symm_verts.as_span(), memory);
Array<float> dists(SCULPT_vertex_count_get(ss), 0.0f);
Array<float> dists(SCULPT_vertex_count_get(ob), 0.0f);
calc_topology_falloff_from_verts(ob, mask, dists);
return dists;
}
@@ -730,7 +730,7 @@ static Array<float> normals_falloff_create(const Depsgraph &depsgraph,
const int blur_steps)
{
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
Array<float> dists(totvert, 0.0f);
Array<float> edge_factors(totvert, 1.0f);
@@ -826,7 +826,7 @@ static Array<float> spherical_falloff_create(const Depsgraph &depsgraph,
const PBVHVertRef v)
{
SculptSession &ss = *object.sculpt;
Array<float> dists(SCULPT_vertex_count_get(ss));
Array<float> dists(SCULPT_vertex_count_get(object));
const Vector<int> symm_verts = calc_symmetry_vert_indices(depsgraph,
object,
@@ -913,12 +913,10 @@ static Array<float> boundary_topology_falloff_create(const Depsgraph &depsgraph,
Object &ob,
const int inititial_vert)
{
SculptSession &ss = *ob.sculpt;
const Vector<int> symm_verts = calc_symmetry_vert_indices(
depsgraph, ob, SCULPT_mesh_symmetry_xyz_get(ob), inititial_vert);
BitVector<> boundary_verts(SCULPT_vertex_count_get(ss));
BitVector<> boundary_verts(SCULPT_vertex_count_get(ob));
for (const int vert : symm_verts) {
if (std::unique_ptr<boundary::SculptBoundary> boundary = boundary::data_init(
depsgraph, ob, nullptr, vert, FLT_MAX))
@@ -932,7 +930,7 @@ static Array<float> boundary_topology_falloff_create(const Depsgraph &depsgraph,
IndexMaskMemory memory;
const IndexMask boundary_mask = IndexMask::from_bits(boundary_verts, memory);
Array<float> dists(SCULPT_vertex_count_get(ss), 0.0f);
Array<float> dists(SCULPT_vertex_count_get(ob), 0.0f);
calc_topology_falloff_from_verts(ob, boundary_mask, dists);
return dists;
}
@@ -950,7 +948,7 @@ static Array<float> diagonals_falloff_create(const Depsgraph &depsgraph,
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
Array<float> dists(totvert, 0.0f);
/* This algorithm uses mesh data (faces and loops), so this falloff type can't be initialized for
@@ -999,10 +997,11 @@ static Array<float> diagonals_falloff_create(const Depsgraph &depsgraph,
* Updates the max_falloff value for vertices in a #Cache based on the current values of
* the falloff, skipping any invalid values initialized to FLT_MAX and not initialized components.
*/
static void update_max_vert_falloff_value(SculptSession &ss, Cache &expand_cache)
static void update_max_vert_falloff_value(const Object &object, Cache &expand_cache)
{
SculptSession &ss = *object.sculpt;
expand_cache.max_vert_falloff = threading::parallel_reduce(
IndexRange(SCULPT_vertex_count_get(ss)),
IndexRange(SCULPT_vertex_count_get(object)),
4096,
std::numeric_limits<float>::lowest(),
[&](const IndexRange range, float max) {
@@ -1143,10 +1142,7 @@ static void topology_from_state_boundary(Object &ob,
{
expand_cache.face_falloff = {};
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
expand_cache.vert_falloff.reinitialize(totvert);
expand_cache.vert_falloff.reinitialize(SCULPT_vertex_count_get(ob));
expand_cache.vert_falloff.fill(0);
IndexMaskMemory memory;
@@ -1184,7 +1180,7 @@ static void resursion_step_add(const Depsgraph &depsgraph,
break;
}
update_max_vert_falloff_value(ss, expand_cache);
update_max_vert_falloff_value(ob, expand_cache);
if (expand_cache.target == TargetType::FaceSets) {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
vert_to_face_falloff(ss, &mesh, expand_cache);
@@ -1205,7 +1201,7 @@ static void init_from_face_set_boundary(const Depsgraph &depsgraph,
const bool internal_falloff)
{
SculptSession &ss = *ob.sculpt;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
BitVector<> enabled_verts(totvert);
for (int i = 0; i < totvert; i++) {
@@ -1314,7 +1310,7 @@ static void calc_falloff_from_vert_and_symmetry(const Depsgraph &depsgraph,
}
/* Update max falloff values and propagate to base mesh faces if needed. */
update_max_vert_falloff_value(ss, expand_cache);
update_max_vert_falloff_value(ob, expand_cache);
if (expand_cache.target == TargetType::FaceSets) {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
vert_to_face_falloff(ss, &mesh, expand_cache);
@@ -1747,7 +1743,7 @@ static void original_state_store(Object &ob, Cache &expand_cache)
{
SculptSession &ss = *ob.sculpt;
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
face_set::create_face_sets_mesh(ob);
@@ -2206,7 +2202,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event
copy_v2_v2(expand_cache.initial_mouse_move, mval_fl);
copy_v2_v2(expand_cache.original_mouse_move, expand_cache.initial_mouse);
if (expand_cache.falloff_type == FalloffType::Geodesic &&
SCULPT_vertex_count_get(ss) > expand_cache.max_geodesic_move_preview)
SCULPT_vertex_count_get(ob) > expand_cache.max_geodesic_move_preview)
{
/* Set to spherical falloff for preview in high poly meshes as it is the fastest one.
* In most cases it should match closely the preview from geodesic. */
@@ -2545,7 +2541,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (RNA_boolean_get(op->ptr, "use_auto_mask")) {
if (any_nonzero_mask(ob)) {
write_mask_data(ob, Array<float>(SCULPT_vertex_count_get(ss), 1.0f));
write_mask_data(ob, Array<float>(SCULPT_vertex_count_get(ob), 1.0f));
}
}
}
@@ -2553,7 +2549,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
BKE_sculpt_update_object_for_edit(depsgraph, &ob, needs_colors);
/* Do nothing when the mesh has 0 vertices. */
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
if (totvert == 0) {
expand_cache_free(ss);
return OPERATOR_CANCELLED;

View File

@@ -287,7 +287,8 @@ static void face_sets_update(const Depsgraph &depsgraph,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(Span<int>, MutableSpan<int>)> calc_face_sets)
{
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SculptSession &ss = *object.sculpt;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> tri_faces = mesh.corner_tri_faces();
@@ -305,7 +306,7 @@ static void face_sets_update(const Depsgraph &depsgraph,
const Span<int> faces =
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
bke::pbvh::node_face_indices_calc_grids(*ss.subdiv_ccg, *node, tls.face_indices);
tls.new_face_sets.resize(faces.size());
MutableSpan<int> new_face_sets = tls.new_face_sets;
@@ -340,7 +341,8 @@ static void clear_face_sets(const Depsgraph &depsgraph,
if (!attributes.contains(".sculpt_face_set")) {
return;
}
const bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SculptSession &ss = *object.sculpt;
bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<int> tri_faces = mesh.corner_tri_faces();
const int default_face_set = mesh.face_sets_color_default;
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
@@ -351,7 +353,7 @@ static void clear_face_sets(const Depsgraph &depsgraph,
const Span<int> faces =
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, face_indices);
bke::pbvh::node_face_indices_calc_grids(*ss.subdiv_ccg, *node, face_indices);
if (std::any_of(faces.begin(), faces.end(), [&](const int face) {
return face_sets[face] != default_face_set;
}))
@@ -825,7 +827,8 @@ static void face_hide_update(const Depsgraph &depsgraph,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(Span<int>, MutableSpan<bool>)> calc_hide)
{
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SculptSession &ss = *object.sculpt;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> tri_faces = mesh.corner_tri_faces();
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -845,7 +848,7 @@ static void face_hide_update(const Depsgraph &depsgraph,
const Span<int> faces =
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
bke::pbvh::node_face_indices_calc_grids(*ss.subdiv_ccg, *node, tls.face_indices);
tls.new_hide.resize(faces.size());
MutableSpan<bool> new_hide = tls.new_hide;
@@ -1583,7 +1586,7 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data,
const Span<int> node_faces =
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
bke::pbvh::node_face_indices_calc_grids(*ss.subdiv_ccg, *node, tls.face_indices);
bool any_updated = false;
for (const int face : node_faces) {

View File

@@ -319,7 +319,7 @@ static void sculpt_color_presmooth_init(const Mesh &mesh, SculptSession &ss)
const GVArraySpan colors = *color_attribute;
if (ss.filter_cache->pre_smoothed_color.is_empty()) {
ss.filter_cache->pre_smoothed_color = Array<float4>(SCULPT_vertex_count_get(ss));
ss.filter_cache->pre_smoothed_color = Array<float4>(mesh.verts_num);
}
const MutableSpan<float4> pre_smoothed_color = ss.filter_cache->pre_smoothed_color;

View File

@@ -669,7 +669,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
* One iteration per 50000 vertices in the mesh should be fine in most cases.
* Maybe we want this to be configurable. */
if (RNA_boolean_get(op->ptr, "auto_iteration_count")) {
iterations = int(SCULPT_vertex_count_get(ss) / 50000.0f) + 1;
iterations = int(SCULPT_vertex_count_get(ob) / 50000.0f) + 1;
}
threading::EnumerableThreadSpecific<FilterLocalData> all_tls;

View File

@@ -2029,11 +2029,12 @@ static void calc_erase_displacement_filter(const Depsgraph &depsgraph,
});
}
static void mesh_filter_surface_smooth_init(SculptSession &ss,
static void mesh_filter_surface_smooth_init(Object &object,
const float shape_preservation,
const float current_vertex_displacement)
{
const int totvert = SCULPT_vertex_count_get(ss);
SculptSession &ss = *object.sculpt;
const int totvert = SCULPT_vertex_count_get(object);
filter::Cache *filter_cache = ss.filter_cache;
filter_cache->surface_smooth_laplacian_disp.reinitialize(totvert);
@@ -2067,7 +2068,7 @@ static void mesh_filter_sharpen_init(const Depsgraph &depsgraph,
const SculptSession &ss = *object.sculpt;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<bke::pbvh::Node *> nodes = filter_cache.nodes;
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(object);
filter_cache.sharpen_smooth_ratio = smooth_ratio;
filter_cache.sharpen_intensify_detail_strength = intensify_detail_strength;
@@ -2427,7 +2428,7 @@ static void sculpt_filter_specific_init(const Depsgraph &depsgraph,
SculptSession &ss = *object.sculpt;
switch (filter_type) {
case MeshFilterType::SurfaceSmooth: {
mesh_filter_surface_smooth_init(ss,
mesh_filter_surface_smooth_init(object,
RNA_float_get(op->ptr, "surface_smooth_shape_preservation"),
RNA_float_get(op->ptr, "surface_smooth_current_vertex"));
break;
@@ -2442,13 +2443,13 @@ static void sculpt_filter_specific_init(const Depsgraph &depsgraph,
break;
}
case MeshFilterType::EnhanceDetails: {
ss.filter_cache->detail_directions.reinitialize(SCULPT_vertex_count_get(ss));
ss.filter_cache->detail_directions.reinitialize(SCULPT_vertex_count_get(object));
calc_smooth_translations(
depsgraph, object, ss.filter_cache->nodes, ss.filter_cache->detail_directions);
break;
}
case MeshFilterType::EraseDispacement: {
ss.filter_cache->limit_surface_co.reinitialize(SCULPT_vertex_count_get(ss));
ss.filter_cache->limit_surface_co.reinitialize(SCULPT_vertex_count_get(object));
calc_limit_surface_positions(object, ss.filter_cache->limit_surface_co);
break;
}

View File

@@ -19,11 +19,12 @@
namespace blender::ed::sculpt_paint::flood_fill {
FillData init_fill(SculptSession &ss)
FillData init_fill(Object &object)
{
SculptSession &ss = *object.sculpt;
SCULPT_vertex_random_access_ensure(ss);
FillData data;
data.visited_verts.resize(SCULPT_vertex_count_get(ss));
data.visited_verts.resize(SCULPT_vertex_count_get(object));
return data;
}

View File

@@ -83,7 +83,7 @@ struct FillDataBMesh {
/**
* \deprecated See the individual FillData constructors instead of this method.
*/
FillData init_fill(SculptSession &ss);
FillData init_fill(Object &object);
void add_initial(FillData &flood, PBVHVertRef vertex);
void add_and_skip_initial(FillData &flood, PBVHVertRef vertex);

View File

@@ -482,7 +482,7 @@ void sculpt_project_v3_normal_align(const SculptSession &ss,
/** Ensure random access; required for blender::bke::pbvh::Type::BMesh */
void SCULPT_vertex_random_access_ensure(SculptSession &ss);
int SCULPT_vertex_count_get(const SculptSession &ss);
int SCULPT_vertex_count_get(const Object &object);
const float *SCULPT_vertex_co_get(const Depsgraph &depsgraph,
const Object &object,
PBVHVertRef vertex);

View File

@@ -495,7 +495,7 @@ static void sculpt_pose_grow_pose_factor(const Depsgraph &depsgraph,
bool grow_next_iteration = true;
float prev_len = FLT_MAX;
Array<float> prev_mask(SCULPT_vertex_count_get(ss));
Array<float> prev_mask(SCULPT_vertex_count_get(ob));
while (grow_next_iteration) {
prev_mask.as_mutable_span().copy_from(pose_factor);
@@ -809,7 +809,7 @@ void calc_pose_data(const Depsgraph &depsgraph,
SCULPT_vertex_random_access_ensure(ss);
/* Calculate the pose rotation point based on the boundaries of the brush factor. */
flood_fill::FillData flood = flood_fill::init_fill(ss);
flood_fill::FillData flood = flood_fill::init_fill(ob);
flood_fill::add_initial_with_symmetry(
depsgraph, ob, flood, ss.active_vert_ref(), !r_pose_factor.is_empty() ? radius : 0.0f);
@@ -911,7 +911,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_topology(const Depsgraph &dep
const float chain_segment_len = radius * (1.0f + brush.pose_offset);
float3 next_chain_segment_target;
int totvert = SCULPT_vertex_count_get(ss);
int totvert = SCULPT_vertex_count_get(ob);
PBVHVertRef nearest_vertex = nearest_vert_calc(depsgraph, ob, initial_location, FLT_MAX, true);
int nearest_vertex_index = BKE_pbvh_vertex_to_index(*ss.pbvh, nearest_vertex);
@@ -984,7 +984,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_face_sets(const Depsgraph &de
const float radius)
{
int totvert = SCULPT_vertex_count_get(ss);
int totvert = SCULPT_vertex_count_get(ob);
const int tot_segments = pose_brush_num_effective_segments(brush);
const int symm = SCULPT_mesh_symmetry_xyz_get(ob);
@@ -1003,7 +1003,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_face_sets(const Depsgraph &de
for (const int i : ik_chain->segments.index_range()) {
const bool is_first_iteration = i == 0;
flood_fill::FillData flood = flood_fill::init_fill(ss);
flood_fill::FillData flood = flood_fill::init_fill(ob);
flood_fill::add_initial_with_symmetry(depsgraph, ob, flood, current_vertex, FLT_MAX);
visited_face_sets.add(current_face_set);
@@ -1122,7 +1122,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_face_sets_fk(const Depsgraph
const float radius,
const float3 &initial_location)
{
const int totvert = SCULPT_vertex_count_get(ss);
const int totvert = SCULPT_vertex_count_get(ob);
std::unique_ptr<IKChain> ik_chain = pose_ik_chain_new(1, totvert);
@@ -1139,7 +1139,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_face_sets_fk(const Depsgraph
int target_face_set = SCULPT_FACE_SET_NONE;
{
int masked_face_set_it = 0;
flood_fill::FillData flood = flood_fill::init_fill(ss);
flood_fill::FillData flood = flood_fill::init_fill(ob);
flood_fill::add_initial(flood, active_vertex);
flood_fill::execute(ob, flood, [&](PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate) {
return pose_face_sets_fk_find_masked_floodfill(ss,
@@ -1199,7 +1199,7 @@ static std::unique_ptr<IKChain> pose_ik_chain_init_face_sets_fk(const Depsgraph
}
{
flood_fill::FillData flood = flood_fill::init_fill(ss);
flood_fill::FillData flood = flood_fill::init_fill(ob);
flood_fill::add_initial_with_symmetry(depsgraph, ob, flood, ss.active_vert_ref(), radius);
MutableSpan<float> fk_weights = ik_chain->segments[0].weights;
flood_fill::execute(

View File

@@ -955,11 +955,12 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
}
if (use_multires_undo(step_data, ss)) {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
Vector<int> faces_vector;
for (bke::pbvh::Node *node : nodes) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.pbvh, *node, faces_vector);
subdiv_ccg, *node, faces_vector);
if (indices_contain_true(modified_faces, faces)) {
BKE_pbvh_node_mark_update_visibility(*node);
}
@@ -1029,11 +1030,12 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
restore_face_sets(object, *unode, modified_faces);
}
if (use_multires_undo(step_data, ss)) {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
Vector<int> faces_vector;
for (bke::pbvh::Node *node : nodes) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.pbvh, *node, faces_vector);
subdiv_ccg, *node, faces_vector);
if (indices_contain_true(modified_faces, faces)) {
BKE_pbvh_node_mark_update_face_sets(*node);
}
@@ -1346,7 +1348,8 @@ static void fill_node_data(const Depsgraph &depsgraph,
bke::pbvh::node_face_indices_calc_mesh(mesh.corner_tri_faces(), *node, unode.face_indices);
}
else {
bke::pbvh::node_face_indices_calc_grids(*ss.pbvh, *node, unode.face_indices);
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
bke::pbvh::node_face_indices_calc_grids(subdiv_ccg, *node, unode.face_indices);
}
}

View File

@@ -377,8 +377,8 @@ static void stats_object_sculpt(const Object *ob, SceneStats *stats)
stats->tottri = ob->sculpt->bm->totface;
break;
case blender::bke::pbvh::Type::Grids:
stats->totvertsculpt = BKE_pbvh_get_grid_num_verts(*ss->pbvh);
stats->totfacesculpt = BKE_pbvh_get_grid_num_faces(*ss->pbvh);
stats->totvertsculpt = BKE_pbvh_get_grid_num_verts(*ob);
stats->totfacesculpt = BKE_pbvh_get_grid_num_faces(*ob);
break;
}
}