Refactor: Sculpt: Remove SculptSession face sets pointer

Part of #118145.
This commit is contained in:
Hans Goudey
2024-09-13 09:43:58 -04:00
parent 8ba5c50f5c
commit 1f7d594aca
14 changed files with 139 additions and 99 deletions

View File

@@ -361,11 +361,6 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
/* Total number of faces of the base mesh. */
int totfaces = 0;
/* The 0 ID is not used by the tools or the visibility system, it is just used when creating new
* geometry (the trim tool, for example) to detect which geometry was just added, so it can be
* assigned a valid Face Set after creation. Tools are not intended to run with Face Sets IDs set
* to 0. */
const int *face_sets = nullptr;
/**
* A reference to the ".hide_poly" attribute, to store whether (base) faces are hidden.
* May be null.

View File

@@ -1964,7 +1964,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
* evaluated yet. */
Mesh *mesh_eval = BKE_object_get_evaluated_mesh_unchecked(ob_eval);
MultiresModifierData *mmd = sculpt_multires_modifier_get(scene, ob, true);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
BLI_assert(mesh_eval != nullptr);
@@ -2001,15 +2000,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss.multires.level = 0;
}
/* Sculpt Face Sets. */
if (use_face_sets) {
ss.face_sets = static_cast<const int *>(
CustomData_get_layer_named(&mesh_orig->face_data, CD_PROP_INT32, ".sculpt_face_set"));
}
else {
ss.face_sets = nullptr;
}
ss.hide_poly = (bool *)CustomData_get_layer_named(
&mesh_orig->face_data, CD_PROP_BOOL, ".hide_poly");

View File

@@ -176,7 +176,8 @@ static void do_draw_face_sets_brush_mesh(const Depsgraph &depsgraph,
undo::push_nodes(depsgraph, object, node_mask, undo::Type::FaceSet);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
threading::EnumerableThreadSpecific<MeshLocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -276,7 +277,8 @@ static void do_draw_face_sets_brush_grids(const Depsgraph &depsgraph,
undo::push_nodes(depsgraph, object, node_mask, undo::Type::FaceSet);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
threading::EnumerableThreadSpecific<GridLocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();

View File

@@ -104,6 +104,7 @@ BLI_NOINLINE static void calc_factors_faces(const Depsgraph &depsgraph,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const GroupedSpan<int> vert_to_face_map,
const Span<int> face_sets,
const float strength,
const bool relax_face_sets,
const Object &object,
@@ -138,7 +139,7 @@ BLI_NOINLINE static void calc_factors_faces(const Depsgraph &depsgraph,
calc_brush_texture_factors(ss, brush, positions_eval, verts, factors);
face_set::filter_verts_with_unique_face_sets_mesh(
vert_to_face_map, ss.face_sets, relax_face_sets, verts, factors);
vert_to_face_map, face_sets, relax_face_sets, verts, factors);
}
static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph,
@@ -158,6 +159,7 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
@@ -178,6 +180,7 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph,
positions_eval,
vert_normals,
vert_to_face_map,
face_sets,
strength,
relax_face_sets,
object,
@@ -195,7 +198,7 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
ss.face_sets,
face_sets,
hide_poly,
relax_face_sets,
nodes[i].verts(),
@@ -220,6 +223,7 @@ BLI_NOINLINE static void calc_factors_grids(const Depsgraph &depsgraph,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const GroupedSpan<int> vert_to_face_map,
const Span<int> face_sets,
const bke::pbvh::GridsNode &node,
const float strength,
const bool relax_face_sets,
@@ -261,7 +265,7 @@ BLI_NOINLINE static void calc_factors_grids(const Depsgraph &depsgraph,
corner_verts,
faces,
subdiv_ccg,
ss.face_sets,
face_sets,
relax_face_sets,
grids,
factors);
@@ -287,6 +291,7 @@ static void do_relax_face_sets_brush_grids(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
Array<int> node_offset_data;
const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
@@ -304,6 +309,7 @@ static void do_relax_face_sets_brush_grids(const Depsgraph &depsgraph,
faces,
corner_verts,
vert_to_face_map,
face_sets,
nodes[i],
strength,
relax_face_sets,
@@ -319,7 +325,7 @@ static void do_relax_face_sets_brush_grids(const Depsgraph &depsgraph,
subdiv_ccg,
faces,
corner_verts,
ss.face_sets,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
nodes[i].grids(),
@@ -485,6 +491,7 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
@@ -518,7 +525,7 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
ss.face_sets,
face_sets,
hide_poly,
false,
nodes[i].verts(),
@@ -602,6 +609,7 @@ static void do_topology_relax_brush_grids(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
Array<int> node_offset_data;
const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
@@ -631,7 +639,7 @@ static void do_topology_relax_brush_grids(const Depsgraph &depsgraph,
subdiv_ccg,
faces,
corner_verts,
ss.face_sets,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
nodes[i].grids(),

View File

@@ -239,18 +239,25 @@ int active_face_set_get(const Object &object)
{
const SculptSession &ss = *object.sculpt;
switch (bke::object::pbvh_get(object)->type()) {
case bke::pbvh::Type::Mesh:
if (!ss.face_sets) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return SCULPT_FACE_SET_NONE;
}
return ss.face_sets[ss.active_face_index];
return face_sets[ss.active_face_index];
}
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return SCULPT_FACE_SET_NONE;
}
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg,
ss.active_grid_index);
return ss.face_sets[face_index];
return face_sets[face_index];
}
case bke::pbvh::Type::BMesh:
return SCULPT_FACE_SET_NONE;
@@ -267,15 +274,17 @@ int vert_face_set_get(const Object &object, PBVHVertRef vertex)
const SculptSession &ss = *object.sculpt;
switch (bke::object::pbvh_get(object)->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.face_sets) {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return SCULPT_FACE_SET_NONE;
}
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
int face_set = 0;
for (const int face_index : vert_to_face_map[vertex.i]) {
if (ss.face_sets[face_index] > face_set) {
face_set = ss.face_sets[face_index];
if (face_sets[face_index] > face_set) {
face_set = face_sets[face_index];
}
}
return face_set;
@@ -283,13 +292,16 @@ int vert_face_set_get(const Object &object, PBVHVertRef vertex)
case bke::pbvh::Type::BMesh:
return 0;
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return SCULPT_FACE_SET_NONE;
}
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];
return face_sets[face_index];
}
}
return 0;
@@ -307,11 +319,11 @@ int vert_face_set_get(const GroupedSpan<int> vert_to_face_map,
}
bool vert_has_face_set(const GroupedSpan<int> vert_to_face_map,
const int *face_sets,
const Span<int> face_sets,
const int vert,
const int face_set)
{
if (!face_sets) {
if (face_sets.is_empty()) {
return face_set == SCULPT_FACE_SET_NONE;
}
const Span<int> faces = vert_to_face_map[vert];
@@ -320,11 +332,11 @@ bool vert_has_face_set(const GroupedSpan<int> vert_to_face_map,
}
bool vert_has_face_set(const SubdivCCG &subdiv_ccg,
const int *face_sets,
const Span<int> face_sets,
const int grid,
const int face_set)
{
if (!face_sets) {
if (face_sets.is_empty()) {
return face_set == SCULPT_FACE_SET_NONE;
}
const int face = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, grid);
@@ -351,13 +363,15 @@ bool vert_has_face_set(const Object &object, PBVHVertRef vertex, int face_set)
const SculptSession &ss = *object.sculpt;
switch (bke::object::pbvh_get(object)->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.face_sets) {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
for (const int face_index : vert_to_face_map[vertex.i]) {
if (ss.face_sets[face_index] == face_set) {
if (face_sets[face_index] == face_set) {
return true;
}
}
@@ -366,13 +380,16 @@ bool vert_has_face_set(const Object &object, PBVHVertRef vertex, int face_set)
case bke::pbvh::Type::BMesh:
return true;
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
if (!face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
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;
return face_sets[face_index] == face_set;
}
}
return true;
@@ -385,7 +402,10 @@ bool vert_has_unique_face_set(const Object &object, PBVHVertRef vertex)
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
return vert_has_unique_face_set(vert_to_face_map, ss.face_sets, vertex.i);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
return vert_has_unique_face_set(vert_to_face_map, face_sets, vertex.i);
}
case bke::pbvh::Type::BMesh: {
BMVert *v = (BMVert *)vertex.i;
@@ -396,23 +416,24 @@ bool vert_has_unique_face_set(const Object &object, PBVHVertRef vertex)
const OffsetIndices<int> faces = base_mesh.faces();
const Span<int> corner_verts = base_mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = base_mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = base_mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
SubdivCCGCoord coord = SubdivCCGCoord::from_index(key, vertex.i);
return vert_has_unique_face_set(
vert_to_face_map, corner_verts, faces, ss.face_sets, *ss.subdiv_ccg, coord);
vert_to_face_map, corner_verts, faces, face_sets, *ss.subdiv_ccg, coord);
}
}
return false;
}
bool vert_has_unique_face_set(const GroupedSpan<int> vert_to_face_map,
const int *face_sets,
const Span<int> face_sets,
int vert)
{
/* TODO: Move this check higher out of this function & make this function take empty span instead
* of a raw pointer. */
if (!face_sets) {
/* TODO: Move this check higher out of this function. */
if (face_sets.is_empty()) {
return true;
}
int face_set = -1;
@@ -435,7 +456,7 @@ bool vert_has_unique_face_set(const GroupedSpan<int> vert_to_face_map,
*/
static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(
const GroupedSpan<int> vert_to_face_map,
const int *face_sets,
const Span<int> face_sets,
const Span<int> corner_verts,
const OffsetIndices<int> faces,
int v1,
@@ -469,13 +490,12 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(
bool vert_has_unique_face_set(const GroupedSpan<int> vert_to_face_map,
const Span<int> corner_verts,
const OffsetIndices<int> faces,
const int *face_sets,
const Span<int> face_sets,
const SubdivCCG &subdiv_ccg,
SubdivCCGCoord coord)
{
/* TODO: Move this check higher out of this function & make this function take empty span instead
* of a raw pointer. */
if (!face_sets) {
/* TODO: Move this check higher out of this function. */
if (face_sets.is_empty()) {
return true;
}
int v1, v2;
@@ -1296,7 +1316,8 @@ static void restore_face_set_from_undo_step(Object &object)
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
node_mask.foreach_index(GrainSize(1), [&](const int i) {
if (const std::optional<Span<int>> orig_data = orig_face_set_data_lookup_mesh(object,
nodes[i]))
@@ -1311,7 +1332,8 @@ static void restore_face_set_from_undo_step(Object &object)
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
threading::EnumerableThreadSpecific<Vector<int>> all_tls;
node_mask.foreach_index(GrainSize(1), [&](const int i) {
Vector<int> &tls = all_tls.local();

View File

@@ -1031,9 +1031,7 @@ static void init_face_sets_masking(const Sculpt &sd, Object &ob, MutableSpan<flo
}
threading::parallel_for(IndexRange(mesh.verts_num), 1024, [&](const IndexRange range) {
for (const int vert : range) {
if (!face_set::vert_has_face_set(
vert_to_face_map, face_sets.data(), vert, active_face_set))
{
if (!face_set::vert_has_face_set(vert_to_face_map, face_sets, vert, active_face_set)) {
factors[vert] = 0.0f;
}
}
@@ -1104,6 +1102,7 @@ static void init_boundary_masking_mesh(Object &object,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
const int num_verts = bke::pbvh::vert_positions_eval(depsgraph, object).size();
Array<int> edge_distance(num_verts, EDGE_DISTANCE_INF);
@@ -1116,7 +1115,7 @@ static void init_boundary_masking_mesh(Object &object,
}
break;
case BoundaryAutomaskMode::FaceSets:
if (!face_set::vert_has_unique_face_set(vert_to_face_map, ss.face_sets, i)) {
if (!face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, i)) {
edge_distance[i] = 0;
}
break;
@@ -1167,6 +1166,8 @@ static void init_boundary_masking_grids(Object &object,
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
Array<int> edge_distance(positions.size(), EDGE_DISTANCE_INF);
for (const int i : positions.index_range()) {
@@ -1181,7 +1182,7 @@ static void init_boundary_masking_grids(Object &object,
break;
case BoundaryAutomaskMode::FaceSets:
if (!face_set::vert_has_unique_face_set(
vert_to_face_map, corner_verts, faces, ss.face_sets, subdiv_ccg, coord))
vert_to_face_map, corner_verts, faces, face_sets, subdiv_ccg, coord))
{
edge_distance[i] = 0;
}

View File

@@ -2078,6 +2078,7 @@ static void apply_filter_forces_mesh(const Depsgraph &depsgraph,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const GroupedSpan<int> vert_to_face_map,
const Span<int> face_sets,
const bke::pbvh::MeshNode &node,
Object &object,
FilterLocalData &tls)
@@ -2098,7 +2099,7 @@ static void apply_filter_forces_mesh(const Depsgraph &depsgraph,
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (!face_set::vert_has_face_set(
vert_to_face_map, ss.face_sets, vert, ss.filter_cache->active_face_set))
vert_to_face_map, face_sets, vert, ss.filter_cache->active_face_set))
{
factors[i] = 0.0f;
}
@@ -2143,6 +2144,7 @@ static void apply_filter_forces_mesh(const Depsgraph &depsgraph,
}
static void apply_filter_forces_grids(const Depsgraph &depsgraph,
const Span<int> face_sets,
const ClothFilterType filter_type,
const float filter_strength,
const float3 &gravity,
@@ -2167,7 +2169,7 @@ static void apply_filter_forces_grids(const Depsgraph &depsgraph,
if (ss.filter_cache->active_face_set != SCULPT_FACE_SET_NONE) {
for (const int i : grids.index_range()) {
if (!face_set::vert_has_face_set(
subdiv_ccg, ss.face_sets, grids[i], ss.filter_cache->active_face_set))
subdiv_ccg, face_sets, grids[i], ss.filter_cache->active_face_set))
{
factors.slice(i * key.grid_area, key.grid_area).fill(0.0f);
}
@@ -2334,6 +2336,9 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(*depsgraph, object);
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
FilterLocalData &tls = all_tls.local();
@@ -2345,6 +2350,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
positions_eval,
vert_normals,
vert_to_face_map,
face_sets,
nodes[i],
object,
tls);
@@ -2355,6 +2361,10 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
break;
}
case bke::pbvh::Type::Grids: {
const Mesh &base_mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = base_mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
@@ -2362,7 +2372,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_filter_forces_grids(
*depsgraph, filter_type, filter_strength, gravity, nodes[i], object, tls);
*depsgraph, face_sets, filter_type, filter_strength, gravity, nodes[i], object, tls);
BKE_pbvh_node_mark_positions_update(nodes[i]);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});

View File

@@ -1417,7 +1417,8 @@ static void expand_cache_free(SculptSession &ss)
static void restore_face_set_data(Object &object, Cache &expand_cache)
{
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
face_sets.span.copy_from(expand_cache.original_face_sets);
face_sets.finish();
@@ -1686,8 +1687,8 @@ static void update_mask_bmesh(SculptSession &ss,
*/
static void face_sets_update(Object &object, Cache &expand_cache)
{
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(mesh);
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const bke::AttributeAccessor attributes = mesh.attributes();
@@ -1823,10 +1824,10 @@ static void original_state_store(Object &ob, Cache &expand_cache)
static void face_sets_restore(Object &object, Cache &expand_cache)
{
SculptSession &ss = *object.sculpt;
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
Mesh &mesh = *static_cast<Mesh *>(object.data);
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(mesh);
const int totfaces = ss.totfaces;
for (int i = 0; i < totfaces; i++) {
if (expand_cache.original_face_sets[i] <= 0) {

View File

@@ -161,9 +161,8 @@ bool create_face_sets_mesh(Object &object)
return true;
}
bke::SpanAttributeWriter<int> ensure_face_sets_mesh(Object &object)
bke::SpanAttributeWriter<int> ensure_face_sets_mesh(Mesh &mesh)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
if (!attributes.contains(".sculpt_face_set")) {
attributes.add<int>(".sculpt_face_set",
@@ -171,8 +170,6 @@ bke::SpanAttributeWriter<int> ensure_face_sets_mesh(Object &object)
bke::AttributeInitVArray(VArray<int>::ForSingle(1, mesh.faces_num)));
mesh.face_sets_color_default = 1;
}
object.sculpt->face_sets = static_cast<const int *>(
CustomData_get_layer_named(&mesh.face_data, CD_PROP_INT32, ".sculpt_face_set"));
return attributes.lookup_or_add_for_write_span<int>(".sculpt_face_set", bke::AttrDomain::Face);
}
@@ -209,7 +206,7 @@ Array<int> duplicate_face_sets(const Mesh &mesh)
}
void filter_verts_with_unique_face_sets_mesh(const GroupedSpan<int> vert_to_face_map,
const int *face_sets,
const Span<int> face_sets,
const bool unique,
const Span<int> verts,
const MutableSpan<float> factors)
@@ -227,7 +224,7 @@ void filter_verts_with_unique_face_sets_grids(const GroupedSpan<int> vert_to_fac
const Span<int> corner_verts,
const OffsetIndices<int> faces,
const SubdivCCG &subdiv_ccg,
const int *face_sets,
const Span<int> face_sets,
const bool unique,
const Span<int> grids,
const MutableSpan<float> factors)
@@ -289,7 +286,8 @@ static void face_sets_update(const Depsgraph &depsgraph,
SculptSession &ss = *object.sculpt;
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
struct TLS {
Vector<int> face_indices;
@@ -578,7 +576,7 @@ static void init_flood_fill(Object &ob, const FaceSetsFloodFillFn &test_fn)
BitVector<> visited_faces(mesh->faces_num, false);
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(ob);
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(*mesh);
const Span<int2> edges = mesh->edges();
const OffsetIndices faces = mesh->faces();
@@ -704,7 +702,7 @@ static int init_op_exec(bContext *C, wmOperator *op)
break;
}
case InitMode::Materials: {
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(ob);
bke::SpanAttributeWriter<int> face_sets = ensure_face_sets_mesh(*mesh);
const VArraySpan<int> material_indices = *attributes.lookup_or_default<int>(
"material_index", bke::AttrDomain::Face, 0);
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
@@ -1333,16 +1331,17 @@ static void edit_fairing(const Depsgraph &depsgraph,
const BitSpan boundary_verts = ss.vertex_info.boundary;
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
Array<bool> fair_verts(positions.size(), false);
for (const int vert : positions.index_range()) {
if (boundary::vert_is_boundary(hide_poly, vert_to_face_map, boundary_verts, vert)) {
continue;
}
if (!vert_has_face_set(vert_to_face_map, ss.face_sets, vert, active_face_set_id)) {
if (!vert_has_face_set(vert_to_face_map, face_sets, vert, active_face_set_id)) {
continue;
}
if (!vert_has_unique_face_set(vert_to_face_map, ss.face_sets, vert)) {
if (!vert_has_unique_face_set(vert_to_face_map, face_sets, vert)) {
continue;
}
fair_verts[vert] = true;
@@ -1641,7 +1640,7 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const IndexMa
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(mesh);
struct TLS {
Vector<int> face_indices;

View File

@@ -30,17 +30,17 @@ int vert_face_set_get(GroupedSpan<int> vert_to_face_map, Span<int> face_sets, in
bool vert_has_face_set(const Object &object, PBVHVertRef vertex, int face_set);
bool vert_has_face_set(GroupedSpan<int> vert_to_face_map,
const int *face_sets,
Span<int> face_sets,
int vert,
int face_set);
bool vert_has_face_set(const SubdivCCG &subdiv_ccg, const int *face_sets, int grid, int face_set);
bool vert_has_face_set(const SubdivCCG &subdiv_ccg, Span<int> face_sets, int grid, int face_set);
bool vert_has_face_set(int face_set_offset, const BMVert &vert, int face_set);
bool vert_has_unique_face_set(const Object &object, PBVHVertRef vertex);
bool vert_has_unique_face_set(GroupedSpan<int> vert_to_face_map, const int *face_sets, int vert);
bool vert_has_unique_face_set(GroupedSpan<int> vert_to_face_map, Span<int> face_sets, int vert);
bool vert_has_unique_face_set(GroupedSpan<int> vert_to_face_map,
Span<int> corner_verts,
OffsetIndices<int> faces,
const int *face_sets,
Span<int> face_sets,
const SubdivCCG &subdiv_ccg,
SubdivCCGCoord coord);
bool vert_has_unique_face_set(const BMVert *vert);
@@ -57,13 +57,13 @@ bool create_face_sets_mesh(Object &object);
*
* \see face_set::create_face_sets_mesh to avoid having to remember to call .finish()
*/
bke::SpanAttributeWriter<int> ensure_face_sets_mesh(Object &object);
bke::SpanAttributeWriter<int> ensure_face_sets_mesh(Mesh &mesh);
int ensure_face_sets_bmesh(Object &object);
Array<int> duplicate_face_sets(const Mesh &mesh);
Set<int> gather_hidden_face_sets(Span<bool> hide_poly, Span<int> face_sets);
void filter_verts_with_unique_face_sets_mesh(GroupedSpan<int> vert_to_face_map,
const int *face_sets,
Span<int> face_sets,
bool unique,
Span<int> verts,
MutableSpan<float> factors);
@@ -71,7 +71,7 @@ void filter_verts_with_unique_face_sets_grids(GroupedSpan<int> vert_to_face_map,
Span<int> corner_verts,
OffsetIndices<int> faces,
const SubdivCCG &subdiv_ccg,
const int *face_sets,
Span<int> face_sets,
bool unique,
Span<int> grids,
MutableSpan<float> factors);

View File

@@ -1019,6 +1019,8 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
@@ -1042,7 +1044,7 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
ss.face_sets,
face_sets,
hide_poly,
false,
verts,
@@ -1070,6 +1072,9 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
const OffsetIndices faces = base_mesh.faces();
const Span<int> corner_verts = base_mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = base_mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = base_mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
@@ -1092,7 +1097,7 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
ss.face_sets,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,
@@ -1183,6 +1188,8 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
@@ -1199,7 +1206,7 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
clamp_factors(factors, 0.0f, 1.0f);
face_set::filter_verts_with_unique_face_sets_mesh(
vert_to_face_map, ss.face_sets, relax_face_sets, verts, factors);
vert_to_face_map, face_sets, relax_face_sets, verts, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
@@ -1209,7 +1216,7 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
ss.face_sets,
face_sets,
hide_poly,
relax_face_sets,
verts,
@@ -1237,6 +1244,10 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
const OffsetIndices faces = base_mesh.faces();
const Span<int> corner_verts = base_mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = base_mesh.vert_to_face_map();
const bke::AttributeAccessor attributes = base_mesh.attributes();
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
@@ -1258,7 +1269,7 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
corner_verts,
faces,
subdiv_ccg,
ss.face_sets,
face_sets,
relax_face_sets,
grids,
factors);
@@ -1268,7 +1279,7 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
ss.face_sets,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,

View File

@@ -443,7 +443,7 @@ void calc_relaxed_translations_faces(const Span<float3> vert_positions,
const Span<int> corner_verts,
const GroupedSpan<int> vert_to_face_map,
const BitSpan boundary_verts,
const int *face_sets,
const Span<int> face_sets,
const Span<bool> hide_poly,
const bool filter_boundary_face_sets,
const Span<int> verts,
@@ -511,7 +511,7 @@ void calc_relaxed_translations_faces(const Span<float3> vert_positions,
void calc_relaxed_translations_grids(const SubdivCCG &subdiv_ccg,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const int *face_sets,
const Span<int> face_sets,
const GroupedSpan<int> vert_to_face_map,
const BitSpan boundary_verts,
const Span<int> grids,

View File

@@ -90,7 +90,7 @@ void calc_relaxed_translations_faces(Span<float3> vert_positions,
Span<int> corner_verts,
GroupedSpan<int> vert_to_face_map,
BitSpan boundary_verts,
const int *face_sets,
Span<int> face_sets,
Span<bool> hide_poly,
bool filter_boundary_face_sets,
Span<int> verts,
@@ -100,7 +100,7 @@ void calc_relaxed_translations_faces(Span<float3> vert_positions,
void calc_relaxed_translations_grids(const SubdivCCG &subdiv_ccg,
OffsetIndices<int> faces,
Span<int> corner_verts,
const int *face_sets,
Span<int> face_sets,
GroupedSpan<int> vert_to_face_map,
BitSpan boundary_verts,
Span<int> grids,

View File

@@ -705,7 +705,8 @@ static bool restore_face_sets(Object &object,
{
const Span<int> face_indices = unode.face_indices;
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(object);
bke::SpanAttributeWriter<int> face_sets = face_set::ensure_face_sets_mesh(
*static_cast<Mesh *>(object.data));
bool modified = false;
for (const int i : face_indices.index_range()) {
const int face = face_indices[i];