Cleanup: Move mesh visibility and selection flushing to C++ namespace

Also rename the functions and move a sculpt function that depended on
the mesh functions to a more proper place. And also use references and
nicer variable names for meshes.
This commit is contained in:
Hans Goudey
2023-12-06 18:16:43 -05:00
parent 9f5878b628
commit 466dca07d5
15 changed files with 111 additions and 110 deletions

View File

@@ -473,16 +473,6 @@ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
/* Flush flags. */
/**
* Update the hide flag for edges and faces from the corresponding flag in verts.
*/
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me);
void BKE_mesh_flush_hidden_from_faces(struct Mesh *me);
void BKE_mesh_flush_select_from_faces(struct Mesh *me);
void BKE_mesh_flush_select_from_verts(struct Mesh *me);
void BKE_mesh_flush_select_from_edges(struct Mesh *me);
/* spatial evaluation */
/**
* This function takes the difference between 2 vertex-coord-arrays

View File

@@ -297,6 +297,18 @@ void mesh_vert_normals_assign(Mesh &mesh, Span<float3> vert_normals);
/** Set mesh vertex normals to known-correct values, avoiding future lazy computation. */
void mesh_vert_normals_assign(Mesh &mesh, Vector<float3> vert_normals);
/** Make edge and face visibility consistent with vertices. */
void mesh_hide_vert_flush(Mesh &mesh);
/** Make vertex and edge visibility consistent with faces. */
void mesh_hide_face_flush(Mesh &mesh);
/** Make edge and face visibility consistent with vertices. */
void mesh_select_vert_flush(Mesh &mesh);
/** Make vertex and face visibility consistent with edges. */
void mesh_select_edge_flush(Mesh &mesh);
/** Make vertex and edge visibility consistent with faces. */
void mesh_select_face_flush(Mesh &mesh);
} // namespace blender::bke
/* -------------------------------------------------------------------- */

View File

@@ -846,7 +846,7 @@ int *BKE_sculpt_face_sets_ensure(Object *ob);
/**
* 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).
* (see #ed::sculpt_paint::hide::sync_all_from_faces).
*/
bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh);

View File

@@ -510,6 +510,8 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
/** \name Visibility Interpolation
* \{ */
namespace blender::bke {
/* Hide edges when either of their vertices are hidden. */
static void edge_hide_from_vert(const Span<int2> edges,
const Span<bool> hide_vert,
@@ -539,11 +541,9 @@ static void face_hide_from_vert(const OffsetIndices<int> faces,
});
}
void BKE_mesh_flush_hidden_from_verts(Mesh *me)
void mesh_hide_vert_flush(Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = me->attributes_for_write();
MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
@@ -559,18 +559,16 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_poly", ATTR_DOMAIN_FACE);
edge_hide_from_vert(me->edges(), hide_vert_span, hide_edge.span);
face_hide_from_vert(me->faces(), me->corner_verts(), hide_vert_span, hide_poly.span);
edge_hide_from_vert(mesh.edges(), hide_vert_span, hide_edge.span);
face_hide_from_vert(mesh.faces(), mesh.corner_verts(), hide_vert_span, hide_poly.span);
hide_edge.finish();
hide_poly.finish();
}
void BKE_mesh_flush_hidden_from_faces(Mesh *me)
void mesh_hide_face_flush(Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = me->attributes_for_write();
MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
@@ -580,9 +578,9 @@ void BKE_mesh_flush_hidden_from_faces(Mesh *me)
return;
}
const VArraySpan<bool> hide_poly_span{hide_poly};
const OffsetIndices faces = me->faces();
const Span<int> corner_verts = me->corner_verts();
const Span<int> corner_edges = me->corner_edges();
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const Span<int> corner_edges = mesh.corner_edges();
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -617,11 +615,9 @@ void BKE_mesh_flush_hidden_from_faces(Mesh *me)
/** \name Selection Interpolation
* \{ */
void BKE_mesh_flush_select_from_faces(Mesh *me)
void mesh_select_face_flush(Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = me->attributes_for_write();
MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
".select_poly", ATTR_DOMAIN_FACE, false);
if (select_poly.is_single() && !select_poly.get_internal_single()) {
@@ -645,11 +641,9 @@ void BKE_mesh_flush_select_from_faces(Mesh *me)
select_edge.finish();
}
void BKE_mesh_flush_select_from_verts(Mesh *me)
void mesh_select_vert_flush(Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = me->attributes_for_write();
MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
".select_vert", ATTR_DOMAIN_POINT, false);
if (select_vert.is_single() && !select_vert.get_internal_single()) {
@@ -683,11 +677,9 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
select_poly.finish();
}
void BKE_mesh_flush_select_from_edges(Mesh *me)
void mesh_select_edge_flush(Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = me->attributes_for_write();
MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
".select_edge", ATTR_DOMAIN_POINT, false);
if (select_edge.is_single() && !select_edge.get_internal_single()) {
@@ -721,6 +713,8 @@ void BKE_mesh_flush_select_from_edges(Mesh *me)
select_poly.finish();
}
} // namespace blender::bke
/** \} */
/* -------------------------------------------------------------------- */

View File

@@ -3210,7 +3210,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
using namespace blender::bke;
switch (pbvh->header.type) {
case PBVH_FACES: {
BKE_mesh_flush_hidden_from_verts(mesh);
mesh_hide_vert_flush(*mesh);
break;
}
case PBVH_BMESH: {
@@ -3273,7 +3273,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
hide_poly.finish();
}
BKE_mesh_flush_hidden_from_faces(mesh);
mesh_hide_face_flush(*mesh);
break;
}
}

View File

@@ -66,7 +66,7 @@ void paintface_flush_flags(bContext *C,
/* we could call this directly in all areas that change selection,
* since this could become slow for realtime updates (circle-select for eg) */
if (flush_selection) {
BKE_mesh_flush_select_from_faces(me);
bke::mesh_select_face_flush(*me);
}
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -184,7 +184,7 @@ void paintface_hide(bContext *C, Object *ob, const bool unselected)
hide_poly.finish();
select_poly.finish();
BKE_mesh_flush_hidden_from_faces(me);
bke::mesh_hide_face_flush(*me);
paintface_flush_flags(C, ob, true, true);
}
@@ -214,7 +214,7 @@ void paintface_reveal(bContext *C, Object *ob, const bool select)
attributes.remove(".hide_poly");
BKE_mesh_flush_hidden_from_faces(me);
bke::mesh_hide_face_flush(*me);
paintface_flush_flags(C, ob, true, true);
}
@@ -819,7 +819,6 @@ bool paintface_mouse_select(bContext *C,
void paintvert_flush_flags(Object *ob)
{
using namespace blender;
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
@@ -829,7 +828,7 @@ void paintvert_flush_flags(Object *ob)
/* we could call this directly in all areas that change selection,
* since this could become slow for realtime updates (circle-select for eg) */
BKE_mesh_flush_select_from_verts(me);
bke::mesh_select_vert_flush(*me);
if (me_eval == nullptr) {
return;
@@ -1214,7 +1213,7 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected)
hide_vert.finish();
select_vert.finish();
BKE_mesh_flush_hidden_from_verts(me);
bke::mesh_hide_vert_flush(*me);
paintvert_flush_flags(ob);
paintvert_tag_select_update(C, ob);
@@ -1245,7 +1244,7 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select)
/* Remove the hide attribute to reveal all vertices. */
attributes.remove(".hide_vert");
BKE_mesh_flush_hidden_from_verts(me);
bke::mesh_hide_vert_flush(*me);
paintvert_flush_flags(ob);
paintvert_tag_select_update(C, ob);

View File

@@ -53,6 +53,58 @@
namespace blender::ed::sculpt_paint::hide {
void sync_all_from_faces(Object &object)
{
SculptSession &ss = *object.sculpt;
Mesh &mesh = *static_cast<Mesh *>(object.data);
SCULPT_topology_islands_invalidate(&ss);
switch (BKE_pbvh_type(ss.pbvh)) {
case PBVH_FACES: {
/* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for
* vertices and edges consistent. */
bke::mesh_hide_face_flush(mesh);
break;
}
case PBVH_GRIDS: {
/* 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_hide_face_flush(mesh);
BKE_sculpt_sync_face_visibility_to_grids(&mesh, ss.subdiv_ccg);
break;
}
case PBVH_BMESH: {
BMesh &bm = *ss.bm;
BMIter iter;
BMFace *f;
/* Hide all verts and edges attached to faces. */
BM_ITER_MESH (f, &iter, &bm, BM_FACES_OF_MESH) {
BMLoop *l = f->l_first;
do {
BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN);
BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN);
} while ((l = l->next) != f->l_first);
}
/* Unhide verts and edges attached to visible faces. */
BM_ITER_MESH (f, &iter, &bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
BMLoop *l = f->l_first;
do {
BM_elem_flag_disable(l->v, BM_ELEM_HIDDEN);
BM_elem_flag_disable(l->e, BM_ELEM_HIDDEN);
} while ((l = l->next) != f->l_first);
}
break;
}
}
}
void tag_update_visibility(const bContext &C)
{
ARegion *region = CTX_wm_region(&C);
@@ -122,7 +174,7 @@ void mesh_show_all(Object &object, const Span<PBVHNode *> nodes)
BKE_pbvh_node_fully_hidden_set(node, false);
}
attributes.remove(".hide_vert");
BKE_mesh_flush_hidden_from_verts(&mesh);
bke::mesh_hide_vert_flush(mesh);
}
bool hide_is_changed(const Span<int> verts, const Span<bool> orig_hide, const Span<bool> new_hide)
@@ -169,7 +221,7 @@ static void vert_hide_update(Object &object,
hide_vert.finish();
if (any_changed) {
BKE_mesh_flush_hidden_from_verts(&mesh);
bke::mesh_hide_vert_flush(mesh);
}
}
@@ -643,7 +695,7 @@ static void invert_visibility_mesh(Object &object, const Span<PBVHNode *> nodes)
});
hide_vert.finish();
BKE_mesh_flush_hidden_from_verts(&mesh);
bke::mesh_hide_vert_flush(mesh);
}
static void invert_visibility_grids(Depsgraph &depsgraph,

View File

@@ -455,6 +455,7 @@ enum BrushStrokeMode {
/* paint_hide.cc */
namespace blender::ed::sculpt_paint::hide {
void sync_all_from_faces(Object &object);
bool hide_is_changed(Span<int> verts, Span<bool> orig_hide, Span<bool> new_hide);
void mesh_show_all(Object &object, const Span<PBVHNode *> nodes);
void grids_show_all(Depsgraph &depsgraph, Object &object, Span<PBVHNode *> nodes);

View File

@@ -374,23 +374,24 @@ void mode_enter_generic(
void mode_exit_generic(Object *ob, const eObjectMode mode_flag)
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
ob->mode &= ~mode_flag;
if (mode_flag == OB_MODE_VERTEX_PAINT) {
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_faces(me);
bke::mesh_select_face_flush(*me);
}
else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
BKE_mesh_flush_select_from_verts(me);
bke::mesh_select_vert_flush(*me);
}
}
else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
BKE_mesh_flush_select_from_verts(me);
bke::mesh_select_vert_flush(*me);
}
else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_faces(me);
bke::mesh_select_face_flush(*me);
}
}
else {

View File

@@ -741,6 +741,7 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven
static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
{
using namespace blender;
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
WPGradient_vertStoreBase *vert_cache;
ARegion *region = CTX_wm_region(C);
@@ -773,7 +774,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
/* On initialization only, convert face -> vert sel. */
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_faces(me);
bke::mesh_select_face_flush(*me);
}
}

View File

@@ -583,56 +583,6 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_
return true;
}
void SCULPT_visibility_sync_all_from_faces(Object *ob)
{
SculptSession *ss = ob->sculpt;
Mesh *mesh = BKE_object_get_original_mesh(ob);
SCULPT_topology_islands_invalidate(ss);
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
/* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for
* vertices and edges consistent. */
BKE_mesh_flush_hidden_from_faces(mesh);
break;
}
case PBVH_GRIDS: {
/* 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_faces(mesh);
BKE_sculpt_sync_face_visibility_to_grids(mesh, ss->subdiv_ccg);
break;
}
case PBVH_BMESH: {
BMIter iter;
BMFace *f;
/* Hide all verts and edges attached to faces. */
BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
BMLoop *l = f->l_first;
do {
BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN);
BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN);
} while ((l = l->next) != f->l_first);
}
/* Unhide verts and edges attached to visible faces. */
BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
BMLoop *l = f->l_first;
do {
BM_elem_flag_disable(l->v, BM_ELEM_HIDDEN);
BM_elem_flag_disable(l->e, BM_ELEM_HIDDEN);
} while ((l = l->next) != f->l_first);
}
break;
}
}
}
static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int index)
{

View File

@@ -874,7 +874,7 @@ static void face_hide_update(Object &object,
hide_poly.finish();
if (any_changed) {
SCULPT_visibility_sync_all_from_faces(&object);
hide::sync_all_from_faces(object);
}
}
@@ -1352,7 +1352,7 @@ static void face_set_edit_do_post_visibility_updates(Object *ob, Span<PBVHNode *
SculptSession *ss = ob->sculpt;
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
SCULPT_visibility_sync_all_from_faces(ob);
hide::sync_all_from_faces(*ob);
for (PBVHNode *node : nodes) {
BKE_pbvh_node_mark_update_visibility(node);

View File

@@ -981,7 +981,6 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, PBVHVertRef vertex);
bool SCULPT_vertex_visible_get(const 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_from_faces(Object *ob);
/** \} */

View File

@@ -78,6 +78,7 @@
#include "ED_undo.hh"
#include "bmesh.hh"
#include "paint_intern.hh"
#include "sculpt_intern.hh"
using blender::MutableSpan;
@@ -914,6 +915,7 @@ static void sculpt_undo_refine_subdiv(Depsgraph *depsgraph,
static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase *lb)
{
using namespace blender::ed::sculpt_paint;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1090,7 +1092,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
BKE_pbvh_update_mask(ss->pbvh);
}
if (changed_hide_face) {
SCULPT_visibility_sync_all_from_faces(ob);
hide::sync_all_from_faces(*ob);
BKE_pbvh_update_visibility(ss->pbvh);
}
if (changed_hide_vert) {

View File

@@ -58,14 +58,14 @@ static void node_geo_exec(GeoNodeExecParams params)
".select_vert",
ATTR_DOMAIN_POINT,
selection);
BKE_mesh_flush_select_from_verts(mesh);
bke::mesh_select_vert_flush(*mesh);
break;
case ATTR_DOMAIN_EDGE:
bke::try_capture_field_on_geometry(geometry.get_component_for_write<MeshComponent>(),
".select_edge",
ATTR_DOMAIN_EDGE,
selection);
BKE_mesh_flush_select_from_edges(mesh);
bke::mesh_select_edge_flush(*mesh);
break;
case ATTR_DOMAIN_FACE:
/* Remove attributes in case they are on the wrong domain, which can happen after
@@ -76,7 +76,7 @@ static void node_geo_exec(GeoNodeExecParams params)
".select_poly",
ATTR_DOMAIN_FACE,
selection);
BKE_mesh_flush_select_from_faces(mesh);
bke::mesh_select_face_flush(*mesh);
break;
default:
break;