Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-14 22:33:55 +0300
committerHans Goudey <h.goudey@me.com>2022-09-14 22:37:18 +0300
commitee23f0f3fb58ce569947171d8f9dff97ec564c27 (patch)
treecb36a82fba12510ac6dcb0fb0ec3b460d02e5566
parent68589a31ebfb79165f99a979357d237e5413e904 (diff)
Sculpt: Separate hide status from face sets, use generic attribute
Whether faces are hidden and face sets are orthogonal concepts, but currently sculpt mode stores them together in the face set array. This means that if anything is hidden, there must be face sets, and if there are face sets, we have to keep track of what is hidden. In other words, it adds a bunch of redundant work and state tracking. On the user level it's nice that face sets and hiding are consistent, but we don't need to store them together to accomplish that. This commit uses the `".hide_poly"` attribute from rB2480b55f216c to read and change hiding in sculpt mode. Face sets don't need to be negative anymore, and a bunch of "face set <-> hide status" conversion can be removed. Plus some other benefits: - We don't need to allocate either array quite as much. - The hide status can be read from 1/4 the memory as face sets. - Updates when entering or exiting sculpt mode can be removed. - More opportunities for early-outs when nothing is hidden. - Separating concerns makes sculpt code more obvious. - It will be easier to convert face sets into a generic int attribute. Differential Revision: https://developer.blender.org/D15950
-rw-r--r--source/blender/blenkernel/BKE_paint.h41
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h1
-rw-r--r--source/blender/blenkernel/intern/paint.cc145
-rw-r--r--source/blender/blenkernel/intern/pbvh.c22
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c5
-rw-r--r--source/blender/blenloader/intern/versioning_300.c10
-rw-r--r--source/blender/editors/mesh/meshtools.cc11
-rw-r--r--source/blender/editors/object/object_remesh.cc2
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c147
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c74
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_geodesic.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c3
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c4
-rw-r--r--source/blender/makesrna/intern/rna_object.c6
18 files changed, 166 insertions, 328 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index eef91bacc2f..774765c3ca1 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -529,13 +529,16 @@ typedef struct SculptSession {
/* Mesh Face Sets */
/* Total number of polys of the base mesh. */
int totfaces;
- /* Face sets store its visibility in the sign of the integer, using the absolute value as the
- * Face Set ID. Positive IDs are visible, negative IDs are hidden.
- * The 0 ID is not used by the tools or the visibility system, it is just used when creating new
+ /* 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. */
int *face_sets;
+ /**
+ * A reference to the ".hide_poly" attribute, to store whether (base) polygons are hidden.
+ * May be null.
+ */
+ bool *hide_poly;
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
@@ -697,6 +700,12 @@ void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Obj
struct MultiresModifierData *BKE_sculpt_multires_active(const struct Scene *scene,
struct Object *ob);
int *BKE_sculpt_face_sets_ensure(struct Mesh *mesh);
+/**
+ * Create the attribute used to store face visibility and retrieve its data.
+ * Note that changes to the face visibility have to be propagated to other domains
+ * (see #SCULPT_visibility_sync_all_from_faces).
+ */
+bool *BKE_sculpt_hide_poly_ensure(struct Mesh *mesh);
int BKE_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd);
void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
@@ -704,31 +713,7 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
-/**
- * This ensure that all elements in the mesh (both vertices and grids) have their visibility
- * updated according to the face sets.
- */
-void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
-
-/**
- * Individual function to sync the Face Set visibility to mesh and grids.
- */
-void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(struct Mesh *mesh);
-void BKE_sculpt_sync_face_sets_visibility_to_grids(struct Mesh *mesh,
- struct SubdivCCG *subdiv_ccg);
-
-/**
- * If a face set layer exists, initialize its visibility (sign) from the mesh's hidden values.
- */
-void BKE_sculpt_face_sets_update_from_base_mesh_visibility(struct Mesh *mesh);
-
-/**
- * Makes sculpt data consistent with other data on the mesh.
- *
- * \note IDs are expected to be original ones here, and calling code should ensure it updates its
- * depsgraph properly after calling this function if it needs up-to-date evaluated data.
- */
-void BKE_sculpt_ensure_orig_mesh_data(struct Object *object);
+void BKE_sculpt_sync_face_visibility_to_grids(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
/**
* Test if PBVH can be used directly for drawing, which is faster than
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 6a194698bd8..c32645e9ce7 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -380,8 +380,6 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
int totgrid,
int gridsize);
-void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh);
-
/**
* Multi-res level, only valid for type == #PBVH_GRIDS.
*/
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index b30b707759c..ced7ff2aa71 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -325,6 +325,7 @@ const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
+void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG *subdiv_ccg, int grid_index);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index 7ad9fd3a7c3..ea1bd3c1cc3 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -1712,6 +1712,8 @@ static void sculpt_update_object(
ss->face_sets = nullptr;
}
+ ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly");
+
ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
@@ -1720,6 +1722,7 @@ static void sculpt_update_object(
BKE_pbvh_subdiv_cgg_set(ss->pbvh, ss->subdiv_ccg);
BKE_pbvh_face_sets_set(ss->pbvh, ss->face_sets);
+ BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh);
BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
@@ -1940,29 +1943,21 @@ int *BKE_sculpt_face_sets_ensure(Mesh *mesh)
&mesh->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, nullptr, mesh->totpoly)),
mesh->totpoly};
- /* Initialize the new face sets with a default valid visible ID and set the default
- * color to render it white. */
- if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
- face_sets.fill(1);
- }
- else {
- const int face_sets_default_visible_id = 1;
- const int face_sets_default_hidden_id = -2;
-
- const VArraySpan<bool> hide_poly_span{hide_poly};
- for (const int i : face_sets.index_range()) {
- /* Assign a new hidden ID to hidden faces. This way we get at initial split in two Face Sets
- * between hidden and visible faces based on the previous mesh visibly from other mode that
- * can be useful in some cases. */
- face_sets[i] = hide_poly_span[i] ? face_sets_default_hidden_id :
- face_sets_default_visible_id;
- }
- }
-
+ face_sets.fill(1);
mesh->face_sets_color_default = 1;
return face_sets.data();
}
+bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh)
+{
+ if (bool *hide_poly = static_cast<bool *>(
+ CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"))) {
+ return hide_poly;
+ }
+ return static_cast<bool *>(CustomData_add_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh->totpoly, ".hide_poly"));
+}
+
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
{
Mesh *me = static_cast<Mesh *>(ob->data);
@@ -2082,11 +2077,11 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
-void BKE_sculpt_face_sets_update_from_base_mesh_visibility(Mesh *mesh)
+void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
using namespace blender;
using namespace blender::bke;
- if (!CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
+ if (!subdiv_ccg) {
return;
}
@@ -2094,70 +2089,19 @@ void BKE_sculpt_face_sets_update_from_base_mesh_visibility(Mesh *mesh)
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+ /* Nothing is hidden, so we can just remove all visibility bitmaps. */
+ for (const int i : hide_poly.index_range()) {
+ BKE_subdiv_ccg_grid_hidden_free(subdiv_ccg, i);
+ }
return;
}
- MutableSpan<int> face_sets{
- static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)), mesh->totpoly};
-
- for (const int i : hide_poly.index_range()) {
- face_sets[i] = hide_poly[i] ? -std::abs(face_sets[i]) : std::abs(face_sets[i]);
- }
-}
-
-static void set_hide_poly_from_face_sets(Mesh &mesh)
-{
- using namespace blender;
- using namespace blender::bke;
- if (!CustomData_has_layer(&mesh.pdata, CD_SCULPT_FACE_SETS)) {
- return;
- }
-
- const Span<int> face_sets{
- static_cast<const int *>(CustomData_get_layer(&mesh.pdata, CD_SCULPT_FACE_SETS)),
- mesh.totpoly};
-
- MutableAttributeAccessor attributes = mesh.attributes_for_write();
- if (std::all_of(
- face_sets.begin(), face_sets.end(), [&](const int value) { return value > 0; })) {
- attributes.remove(".hide_poly");
- return;
- }
-
- SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
- ".hide_poly", ATTR_DOMAIN_FACE);
- if (!hide_poly) {
- return;
- }
- for (const int i : hide_poly.span.index_range()) {
- hide_poly.span[i] = face_sets[i] < 0;
- }
- hide_poly.finish();
-}
-
-void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
-{
- set_hide_poly_from_face_sets(*mesh);
- BKE_mesh_flush_hidden_from_polys(mesh);
-}
-
-void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
-{
- const int *face_sets = static_cast<const int *>(
- CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
- if (!face_sets) {
- return;
- }
-
- if (!subdiv_ccg) {
- return;
- }
-
+ const VArraySpan<bool> hide_poly_span(hide_poly);
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
for (int i = 0; i < mesh->totloop; i++) {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
- const bool is_hidden = (face_sets[face_index] < 0);
+ const bool is_hidden = hide_poly_span[face_index];
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
@@ -2173,41 +2117,6 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv
}
}
-void BKE_sculpt_sync_face_set_visibility(Mesh *mesh, SubdivCCG *subdiv_ccg)
-{
- BKE_sculpt_face_sets_update_from_base_mesh_visibility(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
-}
-
-void BKE_sculpt_ensure_orig_mesh_data(Object *object)
-{
- Mesh *mesh = BKE_mesh_from_object(object);
- BLI_assert(object->mode == OB_MODE_SCULPT);
-
- /* Copy the current mesh visibility to the Face Sets. */
- BKE_sculpt_face_sets_update_from_base_mesh_visibility(mesh);
-
- /* Tessfaces aren't used and will become invalid. */
- BKE_mesh_tessface_clear(mesh);
-
- /* We always need to flush updates from depsgraph here, since at the very least
- * `BKE_sculpt_face_sets_update_from_base_mesh_visibility()` will have updated some data layer of
- * the mesh.
- *
- * All known potential sources of updates:
- * - Addition of, or changes to, the `CD_SCULPT_FACE_SETS` data layer
- * (`BKE_sculpt_face_sets_update_from_base_mesh_visibility`).
- * - Addition of a `CD_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`).
- * - Object has any active modifier (modifier stack can be different in Sculpt mode).
- * - Multires:
- * + Differences of subdiv levels between sculpt and object modes
- * (`mmd->sculptlvl != mmd->lvl`).
- * + Addition of a `CD_GRID_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`).
- */
- DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
-}
-
static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
PBVH *pbvh = BKE_pbvh_new();
@@ -2239,8 +2148,6 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(
loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri);
- BKE_sculpt_sync_face_set_visibility(me, nullptr);
-
BKE_pbvh_build_mesh(pbvh,
me,
polys.data(),
@@ -2275,7 +2182,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
Mesh *base_mesh = BKE_mesh_from_object(ob);
- BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
+ BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
@@ -2369,10 +2276,10 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *UNUSED(v3d)
void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4])
{
float rgba[4];
- float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (abs(face_set) + (seed % 10));
+ float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (face_set + (seed % 10));
random_mod_hue = random_mod_hue - floorf(random_mod_hue);
- const float random_mod_sat = BLI_hash_int_01(abs(face_set) + seed + 1);
- const float random_mod_val = BLI_hash_int_01(abs(face_set) + seed + 2);
+ const float random_mod_sat = BLI_hash_int_01(face_set + seed + 1);
+ const float random_mod_val = BLI_hash_int_01(face_set + seed + 2);
hsv_to_rgb(random_mod_hue,
0.6f + (random_mod_sat * 0.25f),
1.0f - (random_mod_val * 0.35f),
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 2e273e076d5..b3de2b17dd8 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -366,26 +366,6 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
return totquad;
}
-void BKE_pbvh_sync_face_sets_to_grids(PBVH *pbvh)
-{
- const int gridsize = pbvh->gridkey.grid_size;
- for (int i = 0; i < pbvh->totgrid; i++) {
- BLI_bitmap *gh = pbvh->grid_hidden[i];
- const int face_index = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, i);
- if (!gh && pbvh->face_sets[face_index] < 0) {
- gh = pbvh->grid_hidden[i] = BLI_BITMAP_NEW(pbvh->gridkey.grid_area,
- "partialvis_update_grids");
- }
- if (gh) {
- for (int y = 0; y < gridsize; y++) {
- for (int x = 0; x < gridsize; x++) {
- BLI_BITMAP_SET(gh, y * gridsize + x, pbvh->face_sets[face_index] < 0);
- }
- }
- }
- }
-}
-
static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node)
{
int totquads = BKE_pbvh_count_grid_quads(
@@ -3218,7 +3198,7 @@ const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh)
const bool *BKE_pbvh_get_poly_hide(const PBVH *pbvh)
{
- BLI_assert(pbvh->header.type == PBVH_FACES);
+ BLI_assert(ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS));
return pbvh->hide_poly;
}
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index c956ef09af3..03937b270bc 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -2043,6 +2043,11 @@ void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
}
+void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG *subdiv_ccg, int grid_index)
+{
+ MEM_SAFE_FREE(subdiv_ccg->grid_hidden[grid_index]);
+}
+
static void subdiv_ccg_coord_to_ptex_coord(const SubdivCCG *subdiv_ccg,
const SubdivCCGCoord *coord,
int *r_ptex_face_index,
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 1692fd2d747..244f74cfe59 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -3368,5 +3368,15 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
FOREACH_NODETREE_END;
}
+
+ /* Face sets no longer store whether the corresponding face is hidden. */
+ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
+ int *face_sets = (int *)CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (face_sets) {
+ for (int i = 0; i < mesh->totpoly; i++) {
+ face_sets[i] = abs(face_sets[i]);
+ }
+ }
+ }
}
}
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index 108fa210075..831ab858b1c 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -317,15 +317,10 @@ static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset
for (int f = 0; f < mesh->totpoly; f++) {
/* As face sets encode the visibility in the integer sign, the offset needs to be added or
* subtracted depending on the initial sign of the integer to get the new ID. */
- if (abs(face_sets[f]) <= *face_set_offset) {
- if (face_sets[f] > 0) {
- face_sets[f] += *face_set_offset;
- }
- else {
- face_sets[f] -= *face_set_offset;
- }
+ if (face_sets[f] <= *face_set_offset) {
+ face_sets[f] += *face_set_offset;
}
- max_face_set = max_ii(max_face_set, abs(face_sets[f]));
+ max_face_set = max_ii(max_face_set, face_sets[f]);
}
*face_set_offset = max_face_set;
}
diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc
index aa8dc4debd9..adc07d0b411 100644
--- a/source/blender/editors/object/object_remesh.cc
+++ b/source/blender/editors/object/object_remesh.cc
@@ -186,7 +186,6 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
}
if (ob->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(ob);
ED_sculpt_undo_geometry_end(ob);
}
@@ -912,7 +911,6 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update
}
if (ob->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(ob);
ED_sculpt_undo_geometry_end(ob);
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 2b80c62a0ba..9e435ee0748 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -386,8 +386,6 @@ static int hide_show_exec(bContext *C, wmOperator *op)
BKE_pbvh_update_hide_attributes_from_mesh(pbvh);
}
- SCULPT_visibility_sync_all_vertex_to_face_sets(ob->sculpt);
-
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 089a8a4cb54..3ead299a447 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -390,19 +390,15 @@ bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex)
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible)
{
BLI_assert(ss->face_sets != NULL);
+ BLI_assert(ss->hide_poly != NULL);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) != face_set) {
+ if (ss->face_sets[i] != face_set) {
continue;
}
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ ss->hide_poly[i] = !visible;
}
break;
case PBVH_BMESH:
@@ -410,14 +406,15 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
}
}
-void SCULPT_face_sets_visibility_invert(SculptSession *ss)
+void SCULPT_face_visibility_all_invert(SculptSession *ss)
{
BLI_assert(ss->face_sets != NULL);
+ BLI_assert(ss->hide_poly != NULL);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- ss->face_sets[i] *= -1;
+ ss->hide_poly[i] = !ss->hide_poly[i];
}
break;
case PBVH_BMESH:
@@ -425,47 +422,29 @@ void SCULPT_face_sets_visibility_invert(SculptSession *ss)
}
}
-void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
+void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
- if (!ss->face_sets) {
- return;
- }
- for (int i = 0; i < ss->totfaces; i++) {
-
- /* This can run on geometry without a face set assigned, so its ID sign can't be changed to
- * modify the visibility. Force that geometry to the ID 1 to enable changing the visibility
- * here. */
- if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
- ss->face_sets[i] = 1;
- }
-
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
- }
+ BLI_assert(ss->hide_poly != NULL);
+ memset(ss->hide_poly, !visible, sizeof(bool) * ss->totfaces);
break;
case PBVH_BMESH:
break;
}
}
-bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex)
+bool SCULPT_vertex_any_face_visible_get(SculptSession *ss, PBVHVertRef vertex)
{
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
- if (!hide_poly) {
- return true;
- }
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
+ if (!ss->hide_poly) {
+ return true;
+ }
MeshElemMap *vert_map = &ss->pmap[vertex.i];
for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (!hide_poly[vert_map->indices[j]]) {
+ if (!ss->hide_poly[vert_map->indices[j]]) {
return true;
}
}
@@ -479,17 +458,16 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef verte
return true;
}
-bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex)
+bool SCULPT_vertex_all_faces_visible_get(const SculptSession *ss, PBVHVertRef vertex)
{
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
- if (!hide_poly) {
- return true;
- }
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
+ if (!ss->hide_poly) {
+ return true;
+ }
MeshElemMap *vert_map = &ss->pmap[vertex.i];
for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (hide_poly[vert_map->indices[j]]) {
+ if (ss->hide_poly[vert_map->indices[j]]) {
return false;
}
}
@@ -498,10 +476,13 @@ bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRe
case PBVH_BMESH:
return true;
case PBVH_GRIDS: {
+ 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 int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
- return !hide_poly[face_index];
+ return !ss->hide_poly[face_index];
}
}
return true;
@@ -514,11 +495,15 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_
BLI_assert(ss->face_sets != NULL);
MeshElemMap *vert_map = &ss->pmap[vertex.i];
for (int j = 0; j < ss->pmap[vertex.i].count; j++) {
- if (ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(face_set);
+ const int poly_index = vert_map->indices[j];
+ if (ss->hide_poly && ss->hide_poly[poly_index]) {
+ /* Skip hidden faces conntected to the vertex. */
+ continue;
}
+ ss->face_sets[poly_index] = face_set;
}
- } break;
+ break;
+ }
case PBVH_BMESH:
break;
case PBVH_GRIDS: {
@@ -526,11 +511,13 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
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);
- if (ss->face_sets[face_index] > 0) {
- ss->face_sets[face_index] = abs(face_set);
+ if (ss->hide_poly && ss->hide_poly[face_index]) {
+ /* Skip the vertex if it's in a hidden face. */
+ return;
}
-
- } break;
+ ss->face_sets[face_index] = face_set;
+ break;
+ }
}
}
@@ -595,19 +582,23 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_
return true;
}
-void SCULPT_visibility_sync_all_face_sets_to_verts(Object *ob)
+void SCULPT_visibility_sync_all_from_faces(Object *ob)
{
SculptSession *ss = ob->sculpt;
Mesh *mesh = BKE_object_get_original_mesh(ob);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
+ /* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for
+ * vertices and edges consistent. */
+ BKE_mesh_flush_hidden_from_polys(mesh);
BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh);
break;
}
case PBVH_GRIDS: {
- BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
- BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, ss->subdiv_ccg);
+ /* In addition to making the hide status of the base mesh consistent, we also have to
+ * propagate the status to the Multires grids. */
+ BKE_mesh_flush_hidden_from_polys(mesh);
+ BKE_sculpt_sync_face_visibility_to_grids(mesh, ss->subdiv_ccg);
break;
}
case PBVH_BMESH:
@@ -615,46 +606,6 @@ void SCULPT_visibility_sync_all_face_sets_to_verts(Object *ob)
}
}
-static void UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)(SculptSession *ss,
- PBVHVertRef vertex)
-{
- MeshElemMap *vert_map = &ss->pmap[vertex.i];
- const bool visible = SCULPT_vertex_visible_get(ss, vertex);
- for (int i = 0; i < ss->pmap[vertex.i].count; i++) {
- if (visible) {
- ss->face_sets[vert_map->indices[i]] = abs(ss->face_sets[vert_map->indices[i]]);
- }
- else {
- ss->face_sets[vert_map->indices[i]] = -abs(ss->face_sets[vert_map->indices[i]]);
- }
- }
-}
-
-void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
-{
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- if (ss->face_sets == NULL) {
- return;
- }
- for (int i = 0; i < ss->totfaces; i++) {
- const MPoly *poly = &ss->mpoly[i];
- bool poly_visible = true;
- for (int l = 0; l < poly->totloop; l++) {
- const MLoop *loop = &ss->mloop[poly->loopstart + l];
- if (!SCULPT_vertex_visible_get(ss, BKE_pbvh_make_vref(loop->v))) {
- poly_visible = false;
- }
- }
- if (poly_visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
- }
- }
-}
-
static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int index)
{
if (!ss->face_sets) {
@@ -664,10 +615,10 @@ static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int ind
int face_set = -1;
for (int i = 0; i < ss->pmap[index].count; i++) {
if (face_set == -1) {
- face_set = abs(ss->face_sets[vert_map->indices[i]]);
+ face_set = ss->face_sets[vert_map->indices[i]];
}
else {
- if (abs(ss->face_sets[vert_map->indices[i]]) != face_set) {
+ if (ss->face_sets[vert_map->indices[i]] != face_set) {
return false;
}
}
@@ -751,8 +702,8 @@ int SCULPT_face_set_next_available_get(SculptSession *ss)
}
int next_face_set = 0;
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) > next_face_set) {
- next_face_set = abs(ss->face_sets[i]);
+ if (ss->face_sets[i] > next_face_set) {
+ next_face_set = ss->face_sets[i];
}
}
next_face_set++;
@@ -940,7 +891,7 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- if (!SCULPT_vertex_all_face_sets_visible_get(ss, vertex)) {
+ if (!SCULPT_vertex_all_faces_visible_get(ss, vertex)) {
return true;
}
return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex.i);
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 8aa645c6af5..90b92845b09 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -67,7 +67,7 @@ int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
int next_face_set_id = 0;
for (int i = 0; i < mesh->totpoly; i++) {
- next_face_set_id = max_ii(next_face_set_id, abs(face_sets[i]));
+ next_face_set_id = max_ii(next_face_set_id, face_sets[i]);
}
next_face_set_id++;
@@ -135,6 +135,10 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
continue;
}
+ const bool face_hidden = ss->hide_poly && ss->hide_poly[vert_map->indices[j]];
+ if (face_hidden) {
+ continue;
+ }
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -145,8 +149,8 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
vd.vertex,
thread_id);
- if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
+ if (fade > 0.05f) {
+ ss->face_sets[vert_map->indices[j]] = ss->cache->paint_face_set;
}
}
}
@@ -750,7 +754,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
SCULPT_undo_push_end(ob);
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
@@ -854,10 +858,12 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (!pbvh_has_face_sets(ss->pbvh)) {
+ if (!ss->face_sets) {
return OPERATOR_CANCELLED;
}
+ Mesh *mesh = BKE_object_get_original_mesh(ob);
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const int tot_vert = SCULPT_vertex_count_get(ss);
@@ -895,37 +901,49 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
}
}
- for (int i = 0; i < ss->totfaces; i++) {
- if (ss->face_sets[i] <= 0) {
- hidden_vertex = true;
- break;
+ if (ss->hide_poly) {
+ for (int i = 0; i < ss->totfaces; i++) {
+ if (ss->hide_poly[i]) {
+ hidden_vertex = true;
+ break;
+ }
}
}
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
+
if (hidden_vertex) {
- SCULPT_face_sets_visibility_all_set(ss, true);
+ SCULPT_face_visibility_all_set(ss, true);
}
else {
- SCULPT_face_sets_visibility_all_set(ss, false);
+ SCULPT_face_visibility_all_set(ss, false);
SCULPT_face_set_visibility_set(ss, active_face_set, true);
}
}
if (mode == SCULPT_FACE_SET_VISIBILITY_SHOW_ALL) {
- SCULPT_face_sets_visibility_all_set(ss, true);
+ /* As an optimization, free the hide attribute when making all geometry visible. This allows
+ * reduced memory usage without manually clearing it later, and allows sculpt operations to
+ * avoid checking element's hide status. */
+ CustomData_free_layer_named(&mesh->pdata, ".hide_poly", mesh->totpoly);
+ ss->hide_poly = NULL;
+ BKE_pbvh_update_hide_attributes_from_mesh(pbvh);
}
if (mode == SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE) {
- SCULPT_face_sets_visibility_all_set(ss, false);
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
+ SCULPT_face_visibility_all_set(ss, false);
SCULPT_face_set_visibility_set(ss, active_face_set, true);
}
if (mode == SCULPT_FACE_SET_VISIBILITY_HIDE_ACTIVE) {
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
SCULPT_face_set_visibility_set(ss, active_face_set, false);
}
if (mode == SCULPT_FACE_SET_VISIBILITY_INVERT) {
- SCULPT_face_sets_visibility_invert(ss);
+ ss->hide_poly = BKE_sculpt_hide_poly_ensure(mesh);
+ SCULPT_face_visibility_all_invert(ss);
}
/* For modes that use the cursor active vertex, update the rotation origin for viewport
@@ -941,7 +959,7 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
}
/* Sync face sets visibility and vertex visibility. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
SCULPT_undo_push_end(ob);
@@ -1008,7 +1026,7 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator *UNUSE
return OPERATOR_CANCELLED;
}
- if (!pbvh_has_face_sets(ss->pbvh)) {
+ if (!ss->face_sets) {
return OPERATOR_CANCELLED;
}
@@ -1172,14 +1190,15 @@ static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool
int first_face_set = SCULPT_FACE_SET_NONE;
if (check_visible_only) {
for (int f = 0; f < ss->totfaces; f++) {
- if (face_sets[f] > 0) {
- first_face_set = face_sets[f];
- break;
+ if (ss->hide_poly && ss->hide_poly[f]) {
+ continue;
}
+ first_face_set = face_sets[f];
+ break;
}
}
else {
- first_face_set = abs(face_sets[0]);
+ first_face_set = face_sets[0];
}
if (first_face_set == SCULPT_FACE_SET_NONE) {
@@ -1187,8 +1206,10 @@ static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool
}
for (int f = 0; f < ss->totfaces; f++) {
- const int face_set_id = check_visible_only ? face_sets[f] : abs(face_sets[f]);
- if (face_set_id != first_face_set) {
+ if (check_visible_only && ss->hide_poly && ss->hide_poly[f]) {
+ continue;
+ }
+ if (face_sets[f] != first_face_set) {
return false;
}
}
@@ -1222,9 +1243,10 @@ static void sculpt_face_set_delete_geometry(Object *ob,
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
const int face_index = BM_elem_index_get(f);
- const int face_set_id = modify_hidden ? abs(ss->face_sets[face_index]) :
- ss->face_sets[face_index];
- BM_elem_flag_set(f, BM_ELEM_TAG, face_set_id == active_face_set_id);
+ if (!modify_hidden && ss->hide_poly && ss->hide_poly[face_index]) {
+ continue;
+ }
+ BM_elem_flag_set(f, BM_ELEM_TAG, ss->face_sets[face_index] == active_face_set_id);
}
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
@@ -1353,7 +1375,7 @@ static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **node
PBVH *pbvh = ss->pbvh;
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_update_visibility(nodes[i]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
index c0856ab21d2..5dd602bc36d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c
+++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
@@ -170,8 +170,6 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
}
}
- const bool *hide_poly = BKE_pbvh_get_poly_hide(ss->pbvh);
-
/* Add edges adjacent to an initial vertex to the queue. */
for (int i = 0; i < totedge; i++) {
const int v1 = edges[i].v1;
@@ -201,7 +199,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
if (ss->epmap[e].count != 0) {
for (int poly_map_index = 0; poly_map_index < ss->epmap[e].count; poly_map_index++) {
const int poly = ss->epmap[e].indices[poly_map_index];
- if (hide_poly && hide_poly[poly]) {
+ if (ss->hide_poly && ss->hide_poly[poly]) {
continue;
}
const MPoly *mpoly = &polys[poly];
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 7a72e5cc84b..681c90bafb6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1004,9 +1004,13 @@ void SCULPT_connected_components_ensure(Object *ob);
void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visible);
bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex);
+bool SCULPT_vertex_all_faces_visible_get(const SculptSession *ss, PBVHVertRef vertex);
+bool SCULPT_vertex_any_face_visible_get(SculptSession *ss, PBVHVertRef vertex);
-void SCULPT_visibility_sync_all_face_sets_to_verts(struct Object *ob);
-void SCULPT_visibility_sync_all_vertex_to_face_sets(struct SculptSession *ss);
+void SCULPT_face_visibility_all_invert(SculptSession *ss);
+void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible);
+
+void SCULPT_visibility_sync_all_from_faces(struct Object *ob);
/** \} */
@@ -1024,11 +1028,6 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex);
int SCULPT_face_set_next_available_get(SculptSession *ss);
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible);
-bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex);
-bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex);
-
-void SCULPT_face_sets_visibility_invert(SculptSession *ss);
-void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible);
/** \} */
diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c
index f942aac2e18..cfd02438188 100644
--- a/source/blender/editors/sculpt_paint/sculpt_ops.c
+++ b/source/blender/editors/sculpt_paint/sculpt_ops.c
@@ -300,8 +300,6 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene,
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = OB_MODE_SCULPT;
- BKE_sculpt_ensure_orig_mesh_data(ob);
-
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
/* This function expects a fully evaluated depsgraph. */
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 51af8f878e5..9bf63ad1468 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -767,7 +767,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false);
- SCULPT_visibility_sync_all_face_sets_to_verts(ob);
+ SCULPT_visibility_sync_all_from_faces(ob);
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
@@ -923,7 +923,6 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
if (update_visibility) {
- SCULPT_visibility_sync_all_vertex_to_face_sets(ss);
BKE_pbvh_update_visibility(ss->pbvh);
}
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 78f595cbff2..c0527357663 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -406,7 +406,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
if (show_face_sets) {
- const int fset = abs(sculpt_face_sets[lt->poly]);
+ const int fset = sculpt_face_sets[lt->poly];
/* Skip for the default color Face Set to render it white. */
if (fset != face_sets_color_default) {
BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
@@ -766,7 +766,7 @@ void GPU_pbvh_grid_buffers_update(PBVHGPUFormat *vbo_id,
if (show_face_sets && subdiv_ccg && sculpt_face_sets) {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, grid_index);
- const int fset = abs(sculpt_face_sets[face_index]);
+ const int fset = sculpt_face_sets[face_index];
/* Skip for the default color Face Set to render it white. */
if (fset != face_sets_color_default) {
BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index cfc3a832166..467bfa57538 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -497,12 +497,6 @@ static void rna_Object_dependency_update(Main *bmain, Scene *UNUSED(scene), Poin
void rna_Object_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- Object *object = (Object *)ptr->data;
-
- if (object->mode == OB_MODE_SCULPT) {
- BKE_sculpt_ensure_orig_mesh_data(object);
- }
-
rna_Object_internal_update_data_dependency(bmain, scene, ptr);
}