Refactor: Move mesh face dot tag out of MVert
Continuing the refactors described in T93602, this commit moves the face dot tag set by the subdivision surface modifier out of `MVert` to `MeshRuntime`. This clarifies its status as runtime data and allows further refactoring of mesh positions in the future. Before, `BKE_modifiers_uses_subsurf_facedots` was used to check whether subsurf face dots should be drawn, but now we can just check if the tags exist on the mesh. Modifiers that create new new geometry or modify topology will already remove the array by clearing mesh runtime data. Differential Revision: https://developer.blender.org/D14680
This commit is contained in:
parent
775f0d76d5
commit
8c25889bb6
Notes:
blender-bot
2023-02-14 00:10:08 +01:00
Referenced by issue #99253, 3.2 regression: deforming modifiers have stopped displaying original faces with on cage option enabled. Referenced by issue #97853, Crash upon entering Edit Mode and toggling X-Ray Referenced by issue #93602, Struct of Arrays Refactor for Mesh Vertices
|
@ -491,7 +491,6 @@ struct Object *BKE_modifiers_is_deformed_by_lattice(struct Object *ob);
|
|||
struct Object *BKE_modifiers_is_deformed_by_curve(struct Object *ob);
|
||||
bool BKE_modifiers_uses_multires(struct Object *ob);
|
||||
bool BKE_modifiers_uses_armature(struct Object *ob, struct bArmature *arm);
|
||||
bool BKE_modifiers_uses_subsurf_facedots(const struct Scene *scene, struct Object *ob);
|
||||
bool BKE_modifiers_is_correctable_deformed(const struct Scene *scene, struct Object *ob);
|
||||
void BKE_modifier_free_temporary_data(struct ModifierData *md);
|
||||
|
||||
|
|
|
@ -310,6 +310,8 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
|
|||
BKE_mesh_vertex_normals_ensure(mesh) :
|
||||
NULL;
|
||||
const int *index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
|
||||
const BLI_bitmap *facedot_tags = mesh->runtime.subsurf_face_dot_tags;
|
||||
BLI_assert(facedot_tags != NULL);
|
||||
|
||||
if (index) {
|
||||
for (int i = 0; i < mesh->totpoly; i++, mp++) {
|
||||
|
@ -320,8 +322,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
|
|||
ml = &mesh->mloop[mp->loopstart];
|
||||
for (int j = 0; j < mp->totloop; j++, ml++) {
|
||||
mv = &mesh->mvert[ml->v];
|
||||
if (mv->flag & ME_VERT_FACEDOT) {
|
||||
|
||||
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
|
||||
func(userData,
|
||||
orig,
|
||||
mv->co,
|
||||
|
@ -335,7 +336,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
|
|||
ml = &mesh->mloop[mp->loopstart];
|
||||
for (int j = 0; j < mp->totloop; j++, ml++) {
|
||||
mv = &mesh->mvert[ml->v];
|
||||
if (mv->flag & ME_VERT_FACEDOT) {
|
||||
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
|
||||
func(userData, i, mv->co, (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag))
|
|||
runtime->looptris = blender::dna::shallow_zero_initialize();
|
||||
runtime->bvh_cache = nullptr;
|
||||
runtime->shrinkwrap_data = nullptr;
|
||||
runtime->subsurf_face_dot_tags = nullptr;
|
||||
|
||||
runtime->vert_normals_dirty = true;
|
||||
runtime->poly_normals_dirty = true;
|
||||
|
@ -254,6 +255,8 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
|||
mesh->runtime.subdiv_ccg = nullptr;
|
||||
}
|
||||
BKE_shrinkwrap_discard_boundary_data(mesh);
|
||||
|
||||
MEM_SAFE_FREE(mesh->runtime.subsurf_face_dot_tags);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -845,41 +845,6 @@ bool BKE_modifiers_uses_armature(Object *ob, bArmature *arm)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool BKE_modifiers_uses_subsurf_facedots(const struct Scene *scene, Object *ob)
|
||||
{
|
||||
/* Search (backward) in the modifier stack to find if we have a subsurf modifier (enabled) before
|
||||
* the last modifier displayed on cage (or if the subsurf is the last). */
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
|
||||
int cage_index = BKE_modifiers_get_cage_index(scene, ob, NULL, 1);
|
||||
if (cage_index == -1) {
|
||||
return false;
|
||||
}
|
||||
/* Find first modifier enabled on cage. */
|
||||
for (int i = 0; md && i < cage_index; i++) {
|
||||
md = md->next;
|
||||
}
|
||||
/* Now from this point, search for subsurf modifier. */
|
||||
for (; md; md = md->prev) {
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
|
||||
if (md->type == eModifierType_Subsurf) {
|
||||
ModifierMode mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||
if (BKE_modifier_is_enabled(scene, md, mode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mti->type == eModifierTypeType_OnlyDeform) {
|
||||
/* These modifiers do not reset the subdiv flag nor change the topology.
|
||||
* We can still search for a subsurf modifier. */
|
||||
}
|
||||
else {
|
||||
/* Other modifiers may reset the subdiv facedot flag or create. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BKE_modifier_is_correctable_deformed(ModifierData *md)
|
||||
{
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
@ -464,6 +465,9 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
|
|||
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
|
||||
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
|
||||
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
|
||||
MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags);
|
||||
subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
|
||||
__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -527,7 +531,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
|
|||
/* Apply displacement. */
|
||||
add_v3_v3(subdiv_vert->co, D);
|
||||
/* Remove facedot flag. This can happen if there is more than one subsurf modifier. */
|
||||
subdiv_vert->flag &= ~ME_VERT_FACEDOT;
|
||||
BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
}
|
||||
|
||||
static void evaluate_vertex_and_apply_displacement_interpolate(
|
||||
|
@ -687,12 +691,13 @@ static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u
|
|||
}
|
||||
|
||||
static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly,
|
||||
MVert *subdiv_vert,
|
||||
const int subdiv_vertex_index,
|
||||
const float u,
|
||||
const float v)
|
||||
const float v,
|
||||
Mesh *subdiv_mesh)
|
||||
{
|
||||
if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) {
|
||||
subdiv_vert->flag |= ME_VERT_FACEDOT;
|
||||
BLI_BITMAP_ENABLE(subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,7 +722,7 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
|
|||
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
|
||||
subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
|
||||
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
|
||||
subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vert, u, v);
|
||||
subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -2121,7 +2121,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
|
|||
|
||||
MDEPS_ASSERT_MAP_INDEX(TRIS_PER_MAT_INDEX);
|
||||
|
||||
const bool use_subsurf_fdots = scene ? BKE_modifiers_uses_subsurf_facedots(scene, ob) : false;
|
||||
const bool use_subsurf_fdots = me->runtime.subsurf_face_dot_tags != NULL;
|
||||
|
||||
if (do_uvcage) {
|
||||
mesh_buffer_cache_create_requested(task_graph,
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_bitmap.h"
|
||||
|
||||
#include "extract_mesh.h"
|
||||
|
||||
|
@ -538,7 +536,8 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
|
|||
{
|
||||
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
|
||||
if (mr->use_subsurf_fdots) {
|
||||
/* Check #ME_VERT_FACEDOT. */
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
|
||||
|
@ -546,8 +545,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
|
|||
|
||||
const bool real_fdot = (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex &&
|
||||
mr->p_origindex[mp_index] != ORIGINDEX_NONE);
|
||||
const bool subd_fdot = (!mr->use_subsurf_fdots ||
|
||||
(mr->mvert[ml->v].flag & ME_VERT_FACEDOT) != 0);
|
||||
const bool subd_fdot = BLI_BITMAP_TEST(facedot_tags, ml->v);
|
||||
edituv_facedot_add(data,
|
||||
((mp->flag & ME_HIDE) != 0) || !real_fdot || !subd_fdot,
|
||||
(mp->flag & ME_FACE_SEL) != 0,
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BLI_bitmap.h"
|
||||
|
||||
#include "extract_mesh.h"
|
||||
|
||||
|
@ -46,13 +44,13 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
|
|||
{
|
||||
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
|
||||
if (mr->use_subsurf_fdots) {
|
||||
/* Check #ME_VERT_FACEDOT. */
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
|
||||
const MLoop *ml = &mloop[ml_index];
|
||||
const MVert *mv = &mr->mvert[ml->v];
|
||||
if ((mv->flag & ME_VERT_FACEDOT) && !(mr->use_hide && (mp->flag & ME_HIDE))) {
|
||||
if (BLI_BITMAP_TEST(facedot_tags, ml->v) && !(mr->use_hide && (mp->flag & ME_HIDE))) {
|
||||
GPU_indexbuf_set_point_vert(elb, mp_index, mp_index);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
|
||||
#include "extract_mesh.h"
|
||||
|
||||
#include "draw_subdivision.h"
|
||||
|
@ -75,14 +77,14 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
|
|||
|
||||
const MVert *mvert = mr->mvert;
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
|
||||
const MLoop *ml = &mloop[ml_index];
|
||||
if (mr->use_subsurf_fdots) {
|
||||
const MVert *mv = &mr->mvert[ml->v];
|
||||
if (mv->flag & ME_VERT_FACEDOT) {
|
||||
copy_v3_v3(center[mp_index], mv->co);
|
||||
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
|
||||
copy_v3_v3(center[mp_index], mvert[ml->v].co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
|
||||
#include "extract_mesh.h"
|
||||
|
||||
namespace blender::draw {
|
||||
|
@ -72,13 +74,14 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
|
|||
void *_data)
|
||||
{
|
||||
MeshExtract_FdotUV_Data *data = static_cast<MeshExtract_FdotUV_Data *>(_data);
|
||||
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
|
||||
|
||||
const MLoop *mloop = mr->mloop;
|
||||
const int ml_index_end = mp->loopstart + mp->totloop;
|
||||
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
|
||||
const MLoop *ml = &mloop[ml_index];
|
||||
if (mr->use_subsurf_fdots) {
|
||||
const MVert *mv = &mr->mvert[ml->v];
|
||||
if (mv->flag & ME_VERT_FACEDOT) {
|
||||
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
|
||||
copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index].uv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -568,7 +568,7 @@ void mesh_foreachScreenFace(
|
|||
|
||||
BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE);
|
||||
|
||||
if (BKE_modifiers_uses_subsurf_facedots(vc->scene, vc->obedit)) {
|
||||
if (me->runtime.subsurf_face_dot_tags != NULL) {
|
||||
BKE_mesh_foreach_mapped_subdiv_face_center(
|
||||
me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,11 @@ typedef struct Mesh_Runtime {
|
|||
float (*vert_normals)[3];
|
||||
float (*poly_normals)[3];
|
||||
|
||||
void *_pad2;
|
||||
/**
|
||||
* A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
|
||||
* subdivision surface modifier and used by drawing code instead of polygon center face dots.
|
||||
*/
|
||||
uint32_t *subsurf_face_dot_tags;
|
||||
} Mesh_Runtime;
|
||||
|
||||
typedef struct Mesh {
|
||||
|
|
|
@ -33,7 +33,6 @@ typedef struct MVert {
|
|||
enum {
|
||||
/* SELECT = (1 << 0), */
|
||||
ME_HIDE = (1 << 4),
|
||||
ME_VERT_FACEDOT = (1 << 5),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue