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-08-11 19:54:24 +0300
committerHans Goudey <h.goudey@me.com>2022-08-11 19:59:06 +0300
commit2480b55f216c31373a84bc5c5d2b0cc158497c44 (patch)
tree3de24d411a604dfa3a6cfe22796b1fbc8f6be9da
parent5cbfdaccd0af7537f2e5c4c777d3edae1ce4645a (diff)
Mesh: Move hide flags to generic attributes
This commit moves the hide status of mesh vertices, edges, and faces from the `ME_FLAG` to optional generic boolean attributes. Storing this data as generic attributes can significantly simplify and improve code, as described in T95965. The attributes are called `.hide_vert`, `.hide_edge`, and `.hide_poly`, using the attribute name semantics discussed in T97452. The `.` prefix means they are "UI attributes", so they still contain original data edited by users, but they aren't meant to be accessed procedurally by the user in arbitrary situations. They are also be hidden in the spreadsheet and the attribute list by default, Until 4.0, the attributes are still written to and read from the mesh in the old way, so neither forward nor backward compatibility are affected. This means memory requirements will be increased by one byte per element when the hide status is used. When the flags are removed completely, requirements will decrease when hiding is unused. Further notes: * Some code can be further simplified to skip some processing when the hide attributes don't exist. * The data is still stored in flags for `BMesh`, necessitating some complexity in the conversion to and from `Mesh`. * Access to the "hide" property of mesh elements in RNA is slower. The separate boolean arrays should be used where possible. Ref T95965 Differential Revision: https://developer.blender.org/D14685
-rw-r--r--source/blender/blenkernel/BKE_customdata.h23
-rw-r--r--source/blender/blenkernel/BKE_mesh.h12
-rw-r--r--source/blender/blenkernel/BKE_mesh_legacy_convert.h10
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h1
-rw-r--r--source/blender/blenkernel/BKE_paint.h2
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h5
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc19
-rw-r--r--source/blender/blenkernel/intern/customdata.cc57
-rw-r--r--source/blender/blenkernel/intern/mesh.cc18
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc148
-rw-r--r--source/blender/blenkernel/intern/mesh_legacy_convert.cc92
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c5
-rw-r--r--source/blender/blenkernel/intern/paint.c22
-rw-r--r--source/blender/blenkernel/intern/pbvh.c37
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h3
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c10
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c3
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c36
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.cc139
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc15
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc10
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.hh3
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc57
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc40
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc19
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc11
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc12
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc11
-rw-r--r--source/blender/editors/include/ED_mesh.h5
-rw-r--r--source/blender/editors/mesh/editface.cc179
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c4
-rw-r--r--source/blender/editors/mesh/meshtools.cc23
-rw-r--r--source/blender/editors/object/object_vgroup.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c22
-rw-r--r--source/blender/gpu/GPU_buffers.h1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c21
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder_stubs.cc2
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c69
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c3
50 files changed, 923 insertions, 340 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 6e27fd2d80f..8bad89a9211 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -11,7 +11,9 @@
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#ifdef __cplusplus
+# include "BLI_set.hh"
# include "BLI_span.hh"
+# include "BLI_string_ref.hh"
# include "BLI_vector.hh"
#endif
@@ -141,6 +143,15 @@ void CustomData_copy(const struct CustomData *source,
eCDAllocType alloctype,
int totelem);
+/**
+ * Like #CustomData_copy but skips copying layers that are stored as flags on #BMesh.
+ */
+void CustomData_copy_mesh_to_bmesh(const struct CustomData *source,
+ struct CustomData *dest,
+ eCustomDataMask mask,
+ eCDAllocType alloctype,
+ int totelem);
+
/* BMESH_TODO, not really a public function but readfile.c needs it */
void CustomData_update_typemap(struct CustomData *data);
@@ -155,6 +166,15 @@ bool CustomData_merge(const struct CustomData *source,
int totelem);
/**
+ * Like #CustomData_copy but skips copying layers that are stored as flags on #BMesh.
+ */
+bool CustomData_merge_mesh_to_bmesh(const struct CustomData *source,
+ struct CustomData *dest,
+ eCustomDataMask mask,
+ eCDAllocType alloctype,
+ int totelem);
+
+/**
* Reallocate custom data to a new element count.
* Only affects on data layers which are owned by the CustomData itself,
* referenced data is kept unchanged,
@@ -697,7 +717,8 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
* the struct.
*/
void CustomData_blend_write_prepare(CustomData &data,
- blender::Vector<CustomDataLayer, 16> &layers_to_write);
+ blender::Vector<CustomDataLayer, 16> &layers_to_write,
+ const blender::Set<blender::StringRef> &skip_names = {});
/**
* \param layers_to_write: Layers created by #CustomData_blend_write_prepare.
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 17f541b362e..b0516e96562 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -865,19 +865,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
/**
* Update the hide flag for edges and faces from the corresponding flag in verts.
*/
-void BKE_mesh_flush_hidden_from_verts_ex(const struct MVert *mvert,
- const struct MLoop *mloop,
- struct MEdge *medge,
- int totedge,
- struct MPoly *mpoly,
- int totpoly);
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me);
-void BKE_mesh_flush_hidden_from_polys_ex(struct MVert *mvert,
- const struct MLoop *mloop,
- struct MEdge *medge,
- int totedge,
- const struct MPoly *mpoly,
- int totpoly);
void BKE_mesh_flush_hidden_from_polys(struct Mesh *me);
/**
* simple poly -> vert/edge selection.
diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
index 909fd0e0dea..bbc61d5af5e 100644
--- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
@@ -18,6 +18,16 @@ struct Mesh;
struct MFace;
/**
+ * Convert the hidden element attributes to the old flag format for writing.
+ */
+void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh);
+/**
+ * Convert the old hide flags (#ME_HIDE) to the hidden element attribute for reading.
+ * Only add the attributes when there are any elements in each domain hidden.
+ */
+void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh);
+
+/**
* Recreate #MFace Tessellation.
*
* \note This doesn't use multi-threading like #BKE_mesh_recalc_looptri since
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 525483bae19..abe590b6806 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -92,6 +92,7 @@ typedef struct MeshElemMap {
/* mapping */
UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly,
+ const bool *hide_poly,
const struct MLoop *mloop,
const struct MLoopUV *mloopuv,
unsigned int totpoly,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 8b9deadc960..fa67ff08383 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -213,7 +213,7 @@ bool BKE_paint_always_hide_test(struct Object *ob);
* Returns non-zero if any of the face's vertices are hidden, zero otherwise.
*/
bool paint_is_face_hidden(const struct MLoopTri *lt,
- const struct MVert *mvert,
+ const bool *hide_vert,
const struct MLoop *mloop);
/**
* Returns non-zero if any of the corners of the grid
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index af7effe806c..2be3f323d07 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -533,6 +533,7 @@ typedef struct PBVHVertexIter {
/* mesh */
struct MVert *mverts;
float (*vert_normals)[3];
+ const bool *hide_vert;
int totvert;
const int *vert_indices;
float *vmask;
@@ -593,7 +594,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
if (vi.respect_hide) { \
- vi.visible = !(vi.mvert->flag & ME_HIDE); \
+ vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \
if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
continue; \
} \
@@ -667,6 +668,8 @@ void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings,
struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3];
+const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh);
+bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh);
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 1af3cde1821..b9995796a21 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -56,7 +56,7 @@ const char *no_procedural_access_message =
bool allow_procedural_attribute_access(StringRef attribute_name)
{
- return !attribute_name.startswith(".selection");
+ return !attribute_name.startswith(".selection") && !attribute_name.startswith(".hide");
}
static int attribute_data_type_complexity(const eCustomDataType data_type)
diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc
index 03dd5c89b70..d0b57b45d35 100644
--- a/source/blender/blenkernel/intern/bvhutils.cc
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -27,6 +27,8 @@
#include "MEM_guardedalloc.h"
+using blender::VArray;
+
/* -------------------------------------------------------------------- */
/** \name BVHCache
* \{ */
@@ -1181,9 +1183,13 @@ static BLI_bitmap *loose_edges_map_get(const MEdge *medge,
}
static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly,
+ const VArray<bool> &hide_poly,
const int looptri_len,
int *r_looptri_active_len)
{
+ if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+ return nullptr;
+ }
BLI_bitmap *looptri_mask = BLI_BITMAP_NEW(looptri_len, __func__);
int looptri_no_hidden_len = 0;
@@ -1191,8 +1197,7 @@ static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly,
int i_poly = 0;
while (looptri_iter != looptri_len) {
int mp_totlooptri = mpoly[i_poly].totloop - 2;
- const MPoly &mp = mpoly[i_poly];
- if (mp.flag & ME_HIDE) {
+ if (hide_poly[i_poly]) {
looptri_iter += mp_totlooptri;
}
else {
@@ -1276,9 +1281,15 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1);
break;
- case BVHTREE_FROM_LOOPTRI_NO_HIDDEN:
- mask = looptri_no_hidden_map_get(mesh->mpoly, looptri_len, &mask_bits_act_len);
+ case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: {
+ blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
+ mask = looptri_no_hidden_map_get(
+ mesh->mpoly,
+ attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
+ looptri_len,
+ &mask_bits_act_len);
ATTR_FALLTHROUGH;
+ }
case BVHTREE_FROM_LOOPTRI:
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
tree_type,
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index acb978642aa..69825031795 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -26,6 +26,7 @@
#include "BLI_math_vector.hh"
#include "BLI_mempool.h"
#include "BLI_path_util.h"
+#include "BLI_set.hh"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
@@ -58,6 +59,7 @@
#include "data_transfer_intern.h"
using blender::IndexRange;
+using blender::Set;
using blender::Span;
using blender::StringRef;
using blender::Vector;
@@ -2342,6 +2344,43 @@ bool CustomData_merge(const CustomData *source,
return changed;
}
+static bool attribute_stored_in_bmesh_flag(const StringRef name)
+{
+ return ELEM(name, ".hide_vert", ".hide_edge", ".hide_poly");
+}
+
+static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src)
+{
+ Vector<CustomDataLayer> dst_layers;
+ for (const CustomDataLayer &layer : Span<CustomDataLayer>{src.layers, src.totlayer}) {
+ if (!attribute_stored_in_bmesh_flag(layer.name)) {
+ dst_layers.append(layer);
+ }
+ }
+
+ CustomData dst = src;
+ dst.layers = static_cast<CustomDataLayer *>(
+ MEM_calloc_arrayN(dst_layers.size(), sizeof(CustomDataLayer), __func__));
+ dst.totlayer = dst_layers.size();
+ memcpy(dst.layers, dst_layers.data(), dst_layers.as_span().size_in_bytes());
+
+ CustomData_update_typemap(&dst);
+
+ return dst;
+}
+
+bool CustomData_merge_mesh_to_bmesh(const CustomData *source,
+ CustomData *dest,
+ const eCustomDataMask mask,
+ const eCDAllocType alloctype,
+ const int totelem)
+{
+ CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
+ const bool result = CustomData_merge(&source_copy, dest, mask, alloctype, totelem);
+ MEM_SAFE_FREE(source_copy.layers);
+ return result;
+}
+
void CustomData_realloc(CustomData *data, const int totelem)
{
BLI_assert(totelem >= 0);
@@ -2373,6 +2412,17 @@ void CustomData_copy(const CustomData *source,
CustomData_merge(source, dest, mask, alloctype, totelem);
}
+void CustomData_copy_mesh_to_bmesh(const CustomData *source,
+ CustomData *dest,
+ const eCustomDataMask mask,
+ const eCDAllocType alloctype,
+ const int totelem)
+{
+ CustomData source_copy = shallow_copy_remove_non_bmesh_attributes(*source);
+ CustomData_copy(&source_copy, dest, mask, alloctype, totelem);
+ MEM_SAFE_FREE(source_copy.layers);
+}
+
static void customData_free_layer__internal(CustomDataLayer *layer, const int totelem)
{
const LayerTypeInfo *typeInfo;
@@ -4303,7 +4353,9 @@ void CustomData_file_write_info(int type, const char **r_struct_name, int *r_str
*r_struct_num = typeInfo->structnum;
}
-void CustomData_blend_write_prepare(CustomData &data, Vector<CustomDataLayer, 16> &layers_to_write)
+void CustomData_blend_write_prepare(CustomData &data,
+ Vector<CustomDataLayer, 16> &layers_to_write,
+ const Set<StringRef> &skip_names)
{
for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) {
if (layer.flag & CD_FLAG_NOCOPY) {
@@ -4312,6 +4364,9 @@ void CustomData_blend_write_prepare(CustomData &data, Vector<CustomDataLayer, 16
if (layer.anonymous_id != nullptr) {
continue;
}
+ if (skip_names.contains(layer.name)) {
+ continue;
+ }
layers_to_write.append(layer);
}
data.totlayer = layers_to_write.size();
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 65f3a82eadf..abf47acd5cc 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -28,6 +28,7 @@
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
+#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
@@ -36,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_anim_data.h"
+#include "BKE_attribute.hh"
#include "BKE_bpath.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
@@ -62,6 +64,8 @@
#include "BLO_read_write.h"
using blender::float3;
+using blender::MutableSpan;
+using blender::VArray;
using blender::Vector;
static void mesh_clear_geometry(Mesh *mesh);
@@ -241,10 +245,14 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
memset(&mesh->pdata, 0, sizeof(mesh->pdata));
}
else {
- CustomData_blend_write_prepare(mesh->vdata, vert_layers);
- CustomData_blend_write_prepare(mesh->edata, edge_layers);
+ if (!BLO_write_is_undo(writer)) {
+ BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
+ }
+
+ CustomData_blend_write_prepare(mesh->vdata, vert_layers, {".hide_vert"});
+ CustomData_blend_write_prepare(mesh->edata, edge_layers, {".hide_edge"});
CustomData_blend_write_prepare(mesh->ldata, loop_layers);
- CustomData_blend_write_prepare(mesh->pdata, poly_layers);
+ CustomData_blend_write_prepare(mesh->pdata, poly_layers, {".hide_poly"});
}
BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
@@ -323,6 +331,10 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
}
}
+ if (!BLO_read_data_is_undo(reader)) {
+ BKE_mesh_legacy_convert_flags_to_hide_layers(mesh);
+ }
+
/* We don't expect to load normals from files, since they are derived data. */
BKE_mesh_normals_tag_dirty(mesh);
BKE_mesh_assert_normals_dirty_or_calculated(mesh);
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index 7d26262a504..ebe1f8852e4 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -22,15 +22,17 @@
#include "BLI_math.h"
#include "BLI_span.hh"
#include "BLI_utildefines.h"
+#include "BLI_virtual_array.hh"
#include "BKE_customdata.h"
+#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "BKE_multires.h"
-using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
+using blender::VArray;
/* -------------------------------------------------------------------- */
/** \name Polygon Calculations
@@ -732,75 +734,89 @@ void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int t
/** \name Mesh Flag Flushing
* \{ */
-void BKE_mesh_flush_hidden_from_verts_ex(const MVert *mvert,
- const MLoop *mloop,
- MEdge *medge,
- const int totedge,
- MPoly *mpoly,
- const int totpoly)
+void BKE_mesh_flush_hidden_from_verts(Mesh *me)
{
- int i, j;
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*me);
- for (i = 0; i < totedge; i++) {
- MEdge *e = &medge[i];
- if (mvert[e->v1].flag & ME_HIDE || mvert[e->v2].flag & ME_HIDE) {
- e->flag |= ME_HIDE;
- }
- else {
- e->flag &= ~ME_HIDE;
- }
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ if (hide_vert.is_single() && !hide_vert.get_internal_single()) {
+ attributes.remove(".hide_edge");
+ attributes.remove(".hide_poly");
+ return;
}
- for (i = 0; i < totpoly; i++) {
- MPoly *p = &mpoly[i];
- p->flag &= (char)~ME_HIDE;
- for (j = 0; j < p->totloop; j++) {
- if (mvert[mloop[p->loopstart + j].v].flag & ME_HIDE) {
- p->flag |= ME_HIDE;
- }
- }
+ const VArraySpan<bool> hide_vert_span{hide_vert};
+ const Span<MEdge> edges(me->medge, me->totedge);
+ const Span<MPoly> polys(me->mpoly, me->totpoly);
+ const Span<MLoop> loops(me->mloop, me->totloop);
+
+ /* Hide edges when either of their vertices are hidden. */
+ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+ for (const int i : edges.index_range()) {
+ const MEdge &edge = edges[i];
+ hide_edge.span[i] = hide_vert_span[edge.v1] || hide_vert_span[edge.v2];
}
-}
-void BKE_mesh_flush_hidden_from_verts(Mesh *me)
-{
- BKE_mesh_flush_hidden_from_verts_ex(
- me->mvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
+ hide_edge.finish();
+
+ /* Hide faces when any of their vertices are hidden. */
+ SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ const Span<MLoop> loops = loops.slice(poly.loopstart, poly.totloop);
+ hide_poly.span[i] = std::any_of(
+ loops.begin(), loops.end(), [&](const MLoop &loop) { return hide_vert_span[loop.v]; });
+ }
+ hide_poly.finish();
}
-void BKE_mesh_flush_hidden_from_polys_ex(MVert *mvert,
- const MLoop *mloop,
- MEdge *medge,
- const int UNUSED(totedge),
- const MPoly *mpoly,
- const int totpoly)
+void BKE_mesh_flush_hidden_from_polys(Mesh *me)
{
- int i = totpoly;
- for (const MPoly *mp = mpoly; i--; mp++) {
- if (mp->flag & ME_HIDE) {
- const MLoop *ml;
- int j = mp->totloop;
- for (ml = &mloop[mp->loopstart]; j--; ml++) {
- mvert[ml->v].flag |= ME_HIDE;
- medge[ml->e].flag |= ME_HIDE;
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*me);
+
+ 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()) {
+ attributes.remove(".hide_vert");
+ attributes.remove(".hide_edge");
+ return;
+ }
+ const VArraySpan<bool> hide_face_span{hide_poly};
+ const Span<MPoly> polys(me->mpoly, me->totpoly);
+ const Span<MLoop> loops(me->mloop, me->totloop);
+ 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>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+
+ /* Hide all edges or vertices connected to hidden faces. */
+ for (const int i : polys.index_range()) {
+ if (hide_face_span[i]) {
+ const MPoly &poly = polys[i];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ hide_vert.span[loop.v] = true;
+ hide_edge.span[loop.e] = true;
}
}
}
-
- i = totpoly;
- for (const MPoly *mp = mpoly; i--; mp++) {
- if ((mp->flag & ME_HIDE) == 0) {
- const MLoop *ml;
- int j = mp->totloop;
- for (ml = &mloop[mp->loopstart]; j--; ml++) {
- mvert[ml->v].flag &= (char)~ME_HIDE;
- medge[ml->e].flag &= (short)~ME_HIDE;
+ /* Unhide vertices and edges connected to visible faces. */
+ for (const int i : polys.index_range()) {
+ if (!hide_face_span[i]) {
+ const MPoly &poly = polys[i];
+ for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+ hide_vert.span[loop.v] = false;
+ hide_edge.span[loop.e] = false;
}
}
}
-}
-void BKE_mesh_flush_hidden_from_polys(Mesh *me)
-{
- BKE_mesh_flush_hidden_from_polys_ex(
- me->mvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
+
+ hide_vert.finish();
+ hide_edge.finish();
}
void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
@@ -848,11 +864,13 @@ void BKE_mesh_flush_select_from_polys(Mesh *me)
static void mesh_flush_select_from_verts(const Span<MVert> verts,
const Span<MLoop> loops,
+ const VArray<bool> &hide_edge,
+ const VArray<bool> &hide_poly,
MutableSpan<MEdge> edges,
MutableSpan<MPoly> polys)
{
for (const int i : edges.index_range()) {
- if ((edges[i].flag & ME_HIDE) == 0) {
+ if (!hide_edge[i]) {
MEdge &edge = edges[i];
if ((verts[edge.v1].flag & SELECT) && (verts[edge.v2].flag & SELECT)) {
edge.flag |= SELECT;
@@ -864,7 +882,7 @@ static void mesh_flush_select_from_verts(const Span<MVert> verts,
}
for (const int i : polys.index_range()) {
- if (polys[i].flag & ME_HIDE) {
+ if (hide_poly[i]) {
continue;
}
MPoly &poly = polys[i];
@@ -885,10 +903,14 @@ static void mesh_flush_select_from_verts(const Span<MVert> verts,
void BKE_mesh_flush_select_from_verts(Mesh *me)
{
- mesh_flush_select_from_verts({me->mvert, me->totvert},
- {me->mloop, me->totloop},
- {me->medge, me->totedge},
- {me->mpoly, me->totpoly});
+ const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me);
+ mesh_flush_select_from_verts(
+ {me->mvert, me->totvert},
+ {me->mloop, me->totloop},
+ attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
+ attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
+ {me->medge, me->totedge},
+ {me->mpoly, me->totpoly});
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index 479dd6a012a..04c1850f4ae 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -7,7 +7,7 @@
* Functions to convert mesh data to and from legacy formats like #MFace.
*/
-// #include <climits>
+#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.h"
@@ -18,8 +18,10 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
+#include "BLI_task.hh"
#include "BLI_utildefines.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
@@ -874,3 +876,91 @@ void BKE_mesh_add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Attribute and Legacy Flag Conversion
+ * \{ */
+
+void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ const AttributeAccessor attributes = mesh_attributes(*mesh);
+
+ MutableSpan<MVert> vertices(mesh->mvert, mesh->totvert);
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ threading::parallel_for(vertices.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(vertices[i].flag, hide_vert[i], ME_HIDE);
+ }
+ });
+
+ MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
+ const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE, false);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(edges[i].flag, hide_edge[i], ME_HIDE);
+ }
+ });
+
+ MutableSpan<MPoly> polygons(mesh->mpoly, mesh->totpoly);
+ const VArray<bool> hide_face = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ threading::parallel_for(polygons.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ SET_FLAG_FROM_TEST(polygons[i].flag, hide_face[i], ME_HIDE);
+ }
+ });
+}
+
+void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
+
+ const Span<MVert> vertices(mesh->mvert, mesh->totvert);
+ if (std::any_of(vertices.begin(), vertices.end(), [](const MVert &vert) {
+ return vert.flag & ME_HIDE;
+ })) {
+ SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ threading::parallel_for(vertices.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_vert.span[i] = vertices[i].flag & ME_HIDE;
+ }
+ });
+ hide_vert.finish();
+ }
+
+ const Span<MEdge> edges(mesh->medge, mesh->totedge);
+ if (std::any_of(
+ edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
+ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+ threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_edge.span[i] = edges[i].flag & ME_HIDE;
+ }
+ });
+ hide_edge.finish();
+ }
+
+ const Span<MPoly> polygons(mesh->mpoly, mesh->totpoly);
+ if (std::any_of(polygons.begin(), polygons.end(), [](const MPoly &poly) {
+ return poly.flag & ME_HIDE;
+ })) {
+ SpanAttributeWriter<bool> hide_face = attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ threading::parallel_for(polygons.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ hide_face.span[i] = polygons[i].flag & ME_HIDE;
+ }
+ });
+ hide_face.finish();
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 9c4098e2db6..798fe087ea8 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -29,6 +29,7 @@
/* ngon version wip, based on BM_uv_vert_map_create */
UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
+ const bool *hide_poly,
const MLoop *mloop,
const MLoopUV *mloopuv,
uint totpoly,
@@ -51,7 +52,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
/* generate UvMapVert array */
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
+ if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
totuv += mp->totloop;
}
}
@@ -74,7 +75,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
mp = mpoly;
for (a = 0; a < totpoly; a++, mp++) {
- if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
+ if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) {
float(*tf_uv)[2] = NULL;
if (use_winding) {
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b540357ce49..922ea45703d 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1243,11 +1243,13 @@ void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
}
}
-bool paint_is_face_hidden(const MLoopTri *lt, const MVert *mvert, const MLoop *mloop)
+bool paint_is_face_hidden(const MLoopTri *lt, const bool *hide_vert, const MLoop *mloop)
{
- return ((mvert[mloop[lt->tri[0]].v].flag & ME_HIDE) ||
- (mvert[mloop[lt->tri[1]].v].flag & ME_HIDE) ||
- (mvert[mloop[lt->tri[2]].v].flag & ME_HIDE));
+ if (!hide_vert) {
+ return false;
+ }
+ return ((hide_vert[mloop[lt->tri[0]].v]) || (hide_vert[mloop[lt->tri[1]].v]) ||
+ (hide_vert[mloop[lt->tri[2]].v]));
}
bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y)
@@ -2068,9 +2070,11 @@ void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(Mesh *mesh)
}
int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ const bool *hide_poly = (const bool *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
for (int i = 0; i < mesh->totpoly; i++) {
- if (!(mesh->mpoly[i].flag & ME_HIDE)) {
+ if (!(hide_poly && hide_poly[i])) {
continue;
}
@@ -2095,9 +2099,13 @@ void BKE_sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
return;
}
+ bool *hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
+ if (!hide_poly) {
+ return;
+ }
+
for (int i = 0; i < mesh->totpoly; i++) {
- const bool is_face_set_visible = face_sets[i] >= 0;
- SET_FLAG_FROM_TEST(mesh->mpoly[i].flag, !is_face_set_visible, ME_HIDE);
+ hide_poly[i] = face_sets[i] < 0;
}
BKE_mesh_flush_hidden_from_polys(mesh);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index dae9788d21c..4e6418942be 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -287,7 +287,7 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
}
if (has_visible == false) {
- if (!paint_is_face_hidden(lt, pbvh->verts, pbvh->mloop)) {
+ if (!paint_is_face_hidden(lt, pbvh->hide_vert, pbvh->mloop)) {
has_visible = true;
}
}
@@ -562,6 +562,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
pbvh->verts = verts;
BKE_mesh_vertex_normals_ensure(mesh);
pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh);
+ pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert");
pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap");
pbvh->totvert = totvert;
pbvh->leaf_limit = LEAF_LIMIT;
@@ -1316,7 +1317,6 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
case PBVH_FACES:
node->draw_buffers = GPU_pbvh_mesh_buffers_build(
pbvh->mesh,
- pbvh->verts,
pbvh->looptri,
CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
node->prim_indices,
@@ -1590,9 +1590,12 @@ static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ if (pbvh->hide_vert == NULL) {
+ BKE_pbvh_node_fully_hidden_set(node, false);
+ return;
+ }
for (i = 0; i < totvert; i++) {
- MVert *v = &mvert[vert_indices[i]];
- if (!(v->flag & ME_HIDE)) {
+ if (!(pbvh->hide_vert[vert_indices[i]])) {
BKE_pbvh_node_fully_hidden_set(node, false);
return;
}
@@ -2291,7 +2294,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
+ if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_vert, mloop)) {
continue;
}
@@ -2600,7 +2603,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (pbvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
+ if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_vert, mloop)) {
continue;
}
@@ -3127,6 +3130,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->mask = NULL;
if (pbvh->header.type == PBVH_FACES) {
vi->vert_normals = pbvh->vert_normals;
+ vi->hide_vert = pbvh->hide_vert;
vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK);
}
@@ -3207,6 +3211,27 @@ const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]
return pbvh->vert_normals;
}
+const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh)
+{
+ BLI_assert(pbvh->header.type == PBVH_FACES);
+ return pbvh->hide_vert;
+}
+
+bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh)
+{
+ BLI_assert(pbvh->header.type == PBVH_FACES);
+ if (pbvh->hide_vert) {
+ return pbvh->hide_vert;
+ }
+ pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+ if (pbvh->hide_vert) {
+ return pbvh->hide_vert;
+ }
+ pbvh->hide_vert = (bool *)CustomData_add_layer_named(
+ &pbvh->mesh->vdata, CD_PROP_BOOL, CD_CALLOC, NULL, pbvh->mesh->totvert, ".hide_vert");
+ return pbvh->hide_vert;
+}
+
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg)
{
pbvh->subdiv_ccg = subdiv_ccg;
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 0edf224e5ff..5babfd3acbe 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -144,10 +144,11 @@ struct PBVH {
int leaf_limit;
/* Mesh data */
- const struct Mesh *mesh;
+ struct Mesh *mesh;
/* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */
float (*vert_normals)[3];
+ bool *hide_vert;
struct MVert *verts;
const struct MPoly *mpoly;
const struct MLoop *mloop;
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index 12a5f00a68b..9c6d507d42c 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -205,7 +205,15 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
mesh->totloop, sizeof(int), "loop uv vertex index");
}
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- mpoly, mloop, mloopuv, num_poly, num_vert, limit, false, true);
+ mpoly,
+ (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"),
+ mloop,
+ mloopuv,
+ num_poly,
+ num_vert,
+ limit,
+ false,
+ true);
/* NOTE: First UV vertex is supposed to be always marked as separate. */
storage->num_uv_coordinates = -1;
for (int vertex_index = 0; vertex_index < num_vert; vertex_index++) {
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index efabb4f039a..f19aac68d35 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -284,7 +284,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
* UV map in really simple cases with mirror + subsurf, see second part of T44530.
* Also, initially intention is to treat merged vertices from mirror modifier as seams.
* This fixes a very old regression (2.49 was correct here) */
- vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
+ vmap = BKE_mesh_uv_vert_map_create(
+ mpoly, NULL, mloop, mloopuv, totface, totvert, limit, false, true);
if (!vmap) {
return 0;
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index a7637d2712c..0ee5545527b 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -512,16 +512,24 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst,
for (int i = 0; i < me_src_array_len; i++) {
const Mesh *me_src = me_src_array[i];
if (i == 0) {
- CustomData_copy(&me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
- CustomData_copy(&me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
- CustomData_copy(&me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
- CustomData_copy(&me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(
+ &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(
+ &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(
+ &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(
+ &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
}
else {
- CustomData_merge(&me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
- CustomData_merge(&me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
- CustomData_merge(&me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
- CustomData_merge(&me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
+ CustomData_merge_mesh_to_bmesh(
+ &me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
+ CustomData_merge_mesh_to_bmesh(
+ &me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
+ CustomData_merge_mesh_to_bmesh(
+ &me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
+ CustomData_merge_mesh_to_bmesh(
+ &me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
}
cd_flag |= me_src->cd_flag;
@@ -714,26 +722,25 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
char BM_vert_flag_from_mflag(const char mflag)
{
- return (((mflag & SELECT) ? BM_ELEM_SELECT : 0) | ((mflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
+ return ((mflag & SELECT) ? BM_ELEM_SELECT : 0);
}
char BM_edge_flag_from_mflag(const short mflag)
{
return (((mflag & SELECT) ? BM_ELEM_SELECT : 0) | ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
- ((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */
- ((mflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
+ ((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0));
}
char BM_face_flag_from_mflag(const char mflag)
{
return (((mflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
- ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) | ((mflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
+ ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0));
}
char BM_vert_flag_to_mflag(BMVert *v)
{
const char hflag = v->head.hflag;
- return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0));
+ return (((hflag & BM_ELEM_SELECT) ? SELECT : 0));
}
short BM_edge_flag_to_mflag(BMEdge *e)
@@ -743,7 +750,6 @@ short BM_edge_flag_to_mflag(BMEdge *e)
return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
- ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
(BM_edge_is_wire(e) ? ME_LOOSEEDGE : 0) | /* not typical */
ME_EDGERENDER);
}
@@ -752,5 +758,5 @@ char BM_face_flag_to_mflag(BMFace *f)
const char hflag = f->head.hflag;
return (((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
- ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0));
+ ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0));
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
index 884f6b5388a..cdaaabd1f05 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
@@ -83,7 +83,10 @@
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
+#include "BLI_string_ref.hh"
+#include "BLI_task.hh"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
@@ -103,7 +106,9 @@ static CLG_LogRef LOG = {"bmesh.mesh.convert"};
using blender::Array;
using blender::IndexRange;
+using blender::MutableSpan;
using blender::Span;
+using blender::StringRef;
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
{
@@ -212,10 +217,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
if (!me || !me->totvert) {
if (me && is_new) { /* No verts? still copy custom-data layout. */
- CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_DEFAULT, 0);
- CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_DEFAULT, 0);
- CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_DEFAULT, 0);
- CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_DEFAULT, 0);
+ CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_DEFAULT, 0);
+ CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_DEFAULT, 0);
+ CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_DEFAULT, 0);
+ CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_DEFAULT, 0);
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
@@ -231,10 +236,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
if (is_new) {
- CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0);
- CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0);
- CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0);
- CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0);
+ CustomData_copy_mesh_to_bmesh(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0);
}
else {
CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, bm, BM_VERT);
@@ -352,6 +357,13 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) :
-1;
+ const bool *hide_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".hide_vert");
+ const bool *hide_edge = (const bool *)CustomData_get_layer_named(
+ &me->edata, CD_PROP_BOOL, ".hide_edge");
+ const bool *hide_poly = (const bool *)CustomData_get_layer_named(
+ &me->pdata, CD_PROP_BOOL, ".hide_poly");
+
Span<MVert> mvert{me->mvert, me->totvert};
Array<BMVert *> vtable(me->totvert);
for (const int i : mvert.index_range()) {
@@ -361,6 +373,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Transfer flag. */
v->head.hflag = BM_vert_flag_from_mflag(mvert[i].flag & ~SELECT);
+ if (hide_vert && hide_vert[i]) {
+ BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
+ }
/* This is necessary for selection counts to work properly. */
if (mvert[i].flag & SELECT) {
@@ -404,6 +419,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Transfer flags. */
e->head.hflag = BM_edge_flag_from_mflag(medge[i].flag & ~SELECT);
+ if (hide_edge && hide_edge[i]) {
+ BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
+ }
/* This is necessary for selection counts to work properly. */
if (medge[i].flag & SELECT) {
@@ -457,6 +475,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Transfer flag. */
f->head.hflag = BM_face_flag_from_mflag(mpoly[i].flag & ~ME_FACE_SEL);
+ if (hide_poly && hide_poly[i]) {
+ BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
+ }
/* This is necessary for selection counts to work properly. */
if (mpoly[i].flag & ME_FACE_SEL) {
@@ -902,6 +923,63 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
}
}
+template<typename GetFn>
+static void write_elem_flag_to_attribute(blender::bke::MutableAttributeAccessor &attributes,
+ const StringRef attribute_name,
+ const eAttrDomain domain,
+ const bool do_write,
+ const GetFn &get_fn)
+{
+ using namespace blender;
+ if (do_write) {
+ bke::SpanAttributeWriter<bool> attribute = attributes.lookup_or_add_for_write_only_span<bool>(
+ attribute_name, domain);
+ threading::parallel_for(attribute.span.index_range(), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ attribute.span[i] = get_fn(i);
+ }
+ });
+ attribute.finish();
+ }
+ else {
+ /* To avoid overhead, remove the hide attribute if possible. */
+ attributes.remove(attribute_name);
+ }
+}
+
+static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
+ const bool need_hide_vert,
+ const bool need_hide_edge,
+ const bool need_hide_face,
+ Mesh &mesh)
+{
+ using namespace blender;
+ /* The "hide" attributes are stored as flags on #BMesh. */
+ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr);
+ BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr);
+
+ if (!(need_hide_vert || need_hide_edge || need_hide_face)) {
+ return;
+ }
+
+ bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(mesh);
+ BM_mesh_elem_table_ensure(&bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ write_elem_flag_to_attribute(
+ attributes, ".hide_vert", ATTR_DOMAIN_POINT, need_hide_vert, [&](const int i) {
+ return BM_elem_flag_test(BM_vert_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+ write_elem_flag_to_attribute(
+ attributes, ".hide_edge", ATTR_DOMAIN_EDGE, need_hide_edge, [&](const int i) {
+ return BM_elem_flag_test(BM_edge_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+ write_elem_flag_to_attribute(
+ attributes, ".hide_poly", ATTR_DOMAIN_FACE, need_hide_face, [&](const int i) {
+ return BM_elem_flag_test(BM_face_at_index(&bm, i), BM_ELEM_HIDDEN);
+ });
+}
+
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
MEdge *med;
@@ -938,10 +1016,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
{
CustomData_MeshMasks mask = CD_MASK_MESH;
CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
- CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
- CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
- CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
- CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
+ CustomData_copy_mesh_to_bmesh(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
+ CustomData_copy_mesh_to_bmesh(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
+ CustomData_copy_mesh_to_bmesh(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
+ CustomData_copy_mesh_to_bmesh(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
}
MVert *mvert = bm->totvert ? (MVert *)MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") :
@@ -958,6 +1036,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
+ bool need_hide_vert = false;
+ bool need_hide_edge = false;
+ bool need_hide_face = false;
+
/* Clear normals on the mesh completely, since the original vertex and polygon count might be
* different than the BMesh's. */
BKE_mesh_clear_derived_normals(me);
@@ -972,6 +1054,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
copy_v3_v3(mvert->co, v->co);
mvert->flag = BM_vert_flag_to_mflag(v);
+ if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ need_hide_vert = true;
+ }
BM_elem_index_set(v, i); /* set_inline */
@@ -996,6 +1081,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
med->v2 = BM_elem_index_get(e->v2);
med->flag = BM_edge_flag_to_mflag(e);
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ need_hide_edge = true;
+ }
BM_elem_index_set(e, i); /* set_inline */
@@ -1025,6 +1113,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
mpoly->totloop = f->len;
mpoly->mat_nr = f->mat_nr;
mpoly->flag = BM_face_flag_to_mflag(f);
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ need_hide_face = true;
+ }
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@@ -1117,6 +1208,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
}
+ convert_bmesh_hide_flags_to_mesh_attributes(
+ *bm, need_hide_vert, need_hide_edge, need_hide_face, *me);
+
BKE_mesh_update_customdata_pointers(me, false);
{
@@ -1210,6 +1304,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+ bool need_hide_vert = false;
+ bool need_hide_edge = false;
+ bool need_hide_face = false;
+
/* Clear normals on the mesh completely, since the original vertex and polygon count might be
* different than the BMesh's. */
BKE_mesh_clear_derived_normals(me);
@@ -1224,6 +1322,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
BM_elem_index_set(eve, i); /* set_inline */
mv->flag = BM_vert_flag_to_mflag(eve);
+ if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ need_hide_vert = true;
+ }
+
+ if (cd_vert_bweight_offset != -1) {
+ mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+ }
if (cd_vert_bweight_offset != -1) {
mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
@@ -1242,6 +1347,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
med->v2 = BM_elem_index_get(eed->v2);
med->flag = BM_edge_flag_to_mflag(eed);
+ if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ need_hide_edge = true;
+ }
/* Handle this differently to editmode switching,
* only enable draw for single user edges rather than calculating angle. */
@@ -1272,6 +1380,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
mp->totloop = efa->len;
mp->flag = BM_face_flag_to_mflag(efa);
+ if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ need_hide_face = true;
+ }
+
mp->loopstart = j;
mp->mat_nr = efa->mat_nr;
@@ -1291,5 +1403,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
}
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
+ convert_bmesh_hide_flags_to_mesh_attributes(
+ *bm, need_hide_vert, need_hide_edge, need_hide_face, *me);
+
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
}
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
index 27f1636cee5..0159c9fc86e 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
@@ -228,9 +228,9 @@ static void mesh_render_data_polys_sorted_build(MeshRenderData *mr, MeshBufferCa
}
}
else {
- const MPoly *mp = &mr->mpoly[0];
- for (int i = 0; i < mr->poly_len; i++, mp++) {
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+ for (int i = 0; i < mr->poly_len; i++) {
+ if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[i])) {
+ const MPoly *mp = &mr->mpoly[i];
const int mat = min_ii(mp->mat_nr, mat_last);
tri_first_index[i] = mat_tri_offs[mat];
mat_tri_offs[mat] += mp->totloop - 2;
@@ -269,7 +269,7 @@ static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata
int *mat_tri_len = static_cast<int *>(tls->userdata_chunk);
const MPoly *mp = &mr->mpoly[iter];
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+ if (!(mr->use_hide && mr->hide_poly && mr->hide_poly[iter])) {
int mat = min_ii(mp->mat_nr, mr->mat_len - 1);
mat_tri_len[mat] += mp->totloop - 2;
}
@@ -578,6 +578,13 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
+
+ mr->hide_vert = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert"));
+ mr->hide_edge = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->edata, CD_PROP_BOOL, ".hide_edge"));
+ mr->hide_poly = static_cast<const bool *>(
+ CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly"));
}
else {
/* #BMesh */
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index 2f8a2540776..075e08eb49f 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -668,7 +668,9 @@ static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
}
}
-static void draw_subdiv_cache_extra_coarse_face_data_mesh(Mesh *mesh, uint32_t *flags_data)
+static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *mr,
+ Mesh *mesh,
+ uint32_t *flags_data)
{
for (int i = 0; i < mesh->totpoly; i++) {
uint32_t flag = 0;
@@ -678,7 +680,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(Mesh *mesh, uint32_t *
if ((mesh->mpoly[i].flag & ME_FACE_SEL) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
- if ((mesh->mpoly[i].flag & ME_HIDE) != 0) {
+ if (mr->hide_poly && mr->hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
flags_data[i] = (uint)(mesh->mpoly[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
@@ -691,7 +693,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
uint32_t *flags_data)
{
if (bm == nullptr) {
- draw_subdiv_cache_extra_coarse_face_data_mesh(mesh, flags_data);
+ draw_subdiv_cache_extra_coarse_face_data_mesh(mr, mesh, flags_data);
return;
}
@@ -726,7 +728,7 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach
draw_subdiv_cache_extra_coarse_face_data_mapped(mesh, cache->bm, mr, flags_data);
}
else {
- draw_subdiv_cache_extra_coarse_face_data_mesh(mesh, flags_data);
+ draw_subdiv_cache_extra_coarse_face_data_mesh(mr, mesh, flags_data);
}
/* Make sure updated data is re-uploaded. */
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
index a4773736f0c..57abf088c16 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
@@ -83,6 +83,9 @@ struct MeshRenderData {
MLoopTri *mlooptri;
const float (*vert_normals)[3];
const float (*poly_normals)[3];
+ const bool *hide_vert;
+ const bool *hide_edge;
+ const bool *hide_poly;
float (*loop_normals)[3];
int *lverts, *ledges;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
index 2ff093d0bd8..9f82cc56941 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
@@ -61,7 +61,7 @@ static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const MPoly *mp = &mr->mpoly[mlt->poly];
edituv_tri_add(data,
- (mp->flag & ME_HIDE) != 0,
+ mr->hide_poly && mr->hide_poly[mlt->poly],
(mp->flag & ME_FACE_SEL) != 0,
mlt->tri[0],
mlt->tri[1],
@@ -117,7 +117,7 @@ static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache *UNUSED(subd
}
static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(subdiv_cache),
- const MeshRenderData *UNUSED(mr),
+ const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
@@ -125,19 +125,13 @@ static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(su
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const uint loop_idx = subdiv_quad_index * 4;
- edituv_tri_add(data,
- (coarse_quad->flag & ME_HIDE) != 0,
- (coarse_quad->flag & ME_FACE_SEL) != 0,
- loop_idx,
- loop_idx + 1,
- loop_idx + 2);
+ const bool hidden = mr->hide_poly && mr->hide_poly[coarse_quad - mr->mpoly];
- edituv_tri_add(data,
- (coarse_quad->flag & ME_HIDE) != 0,
- (coarse_quad->flag & ME_FACE_SEL) != 0,
- loop_idx,
- loop_idx + 2,
- loop_idx + 3);
+ edituv_tri_add(
+ data, hidden, (coarse_quad->flag & ME_FACE_SEL) != 0, loop_idx, loop_idx + 1, loop_idx + 2);
+
+ edituv_tri_add(
+ data, hidden, (coarse_quad->flag & ME_FACE_SEL) != 0, loop_idx, loop_idx + 2, loop_idx + 3);
}
static void extract_edituv_tris_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
@@ -218,6 +212,8 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
+ const bool hidden = mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
+
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) {
@@ -227,11 +223,8 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_next = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1);
const bool real_edge = (mr->e_origindex == nullptr ||
mr->e_origindex[ml->e] != ORIGINDEX_NONE);
- edituv_edge_add(data,
- (mp->flag & ME_HIDE) != 0 || !real_edge,
- (mp->flag & ME_FACE_SEL) != 0,
- ml_index,
- ml_index_next);
+ edituv_edge_add(
+ data, hidden || !real_edge, (mp->flag & ME_FACE_SEL) != 0, ml_index, ml_index_next);
}
}
@@ -288,6 +281,8 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
const MPoly *coarse_poly)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
+ const bool hidden = mr->hide_poly && mr->hide_poly[coarse_poly - mr->mpoly];
+
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
uint start_loop_idx = subdiv_quad_index * 4;
@@ -298,7 +293,7 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
(mr->e_origindex == nullptr ||
mr->e_origindex[edge_origindex] != ORIGINDEX_NONE));
edituv_edge_add(data,
- (coarse_poly->flag & ME_HIDE) != 0 || !real_edge,
+ hidden || !real_edge,
(coarse_poly->flag & ME_FACE_SEL) != 0,
loop_idx,
(loop_idx + 1 == end_loop_idx) ? start_loop_idx : (loop_idx + 1));
@@ -382,14 +377,15 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
+ const bool hidden = mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
+
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 bool real_vert = !mr->v_origindex || mr->v_origindex[ml->v] != ORIGINDEX_NONE;
- edituv_point_add(
- data, ((mp->flag & ME_HIDE) != 0) || !real_vert, (mp->flag & ME_FACE_SEL) != 0, ml_index);
+ edituv_point_add(data, hidden || !real_vert, (mp->flag & ME_FACE_SEL) != 0, ml_index);
}
}
@@ -442,6 +438,7 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
const MPoly *coarse_quad)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
+ const bool hidden = mr->hide_poly && mr->hide_poly[coarse_quad - mr->mpoly];
int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
uint start_loop_idx = subdiv_quad_index * 4;
@@ -450,10 +447,7 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
const int vert_origindex = subdiv_loop_vert_index[i];
const bool real_vert = !mr->v_origindex || (vert_origindex != -1 &&
mr->v_origindex[vert_origindex] != ORIGINDEX_NONE);
- edituv_point_add(data,
- ((coarse_quad->flag & ME_HIDE) != 0) || !real_vert,
- (coarse_quad->flag & ME_FACE_SEL) != 0,
- i);
+ edituv_point_add(data, hidden || !real_vert, (coarse_quad->flag & ME_FACE_SEL) != 0, i);
}
}
@@ -533,6 +527,8 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
+ const bool hidden = mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
+
if (mr->use_subsurf_fdots) {
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
@@ -543,16 +539,13 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
const bool real_fdot = !mr->p_origindex || (mr->p_origindex[mp_index] != ORIGINDEX_NONE);
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,
- mp_index);
+ edituv_facedot_add(
+ data, hidden || !real_fdot || !subd_fdot, (mp->flag & ME_FACE_SEL) != 0, mp_index);
}
}
else {
const bool real_fdot = !mr->p_origindex || (mr->p_origindex[mp_index] != ORIGINDEX_NONE);
- edituv_facedot_add(
- data, ((mp->flag & ME_HIDE) != 0) || !real_fdot, (mp->flag & ME_FACE_SEL) != 0, mp_index);
+ edituv_facedot_add(data, hidden || !real_fdot, (mp->flag & ME_FACE_SEL) != 0, mp_index);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
index cc0b383f12b..8dc00617039 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
@@ -42,6 +42,8 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
const int mp_index,
void *_userdata)
{
+ const bool hidden = mr->use_hide && mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
+
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
if (mr->use_subsurf_fdots) {
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
@@ -50,7 +52,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
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 (BLI_BITMAP_TEST(facedot_tags, ml->v) && !(mr->use_hide && (mp->flag & ME_HIDE))) {
+ if (BLI_BITMAP_TEST(facedot_tags, ml->v) && !hidden) {
GPU_indexbuf_set_point_vert(elb, mp_index, mp_index);
return;
}
@@ -58,7 +60,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
GPU_indexbuf_set_point_restart(elb, mp_index);
}
else {
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+ if (!hidden) {
GPU_indexbuf_set_point_vert(elb, mp_index, mp_index);
}
else {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
index e6c0d815963..fe883fb0c96 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
@@ -58,14 +58,12 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
/* Using poly & loop iterator would complicate accessing the adjacent loop. */
const MLoop *mloop = mr->mloop;
- const MEdge *medge = mr->medge;
if (mr->use_hide || (mr->extract_type == MR_EXTRACT_MAPPED) || (mr->e_origindex != nullptr)) {
const int ml_index_last = mp->loopstart + (mp->totloop - 1);
int ml_index = ml_index_last, ml_index_next = mp->loopstart;
do {
const MLoop *ml = &mloop[ml_index];
- const MEdge *med = &medge[ml->e];
- if (!((mr->use_hide && (med->flag & ME_HIDE)) ||
+ if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[ml->e]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[ml->e] == ORIGINDEX_NONE)))) {
GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next);
@@ -111,7 +109,7 @@ static void extract_lines_iter_ledge_mesh(const MeshRenderData *mr,
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
const int l_index_offset = mr->edge_len + ledge_index;
const int e_index = mr->ledges[ledge_index];
- if (!((mr->use_hide && (med->flag & ME_HIDE)) ||
+ if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[med - mr->medge]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
const int l_index = mr->loop_len + ledge_index * 2;
@@ -185,9 +183,14 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
switch (mr->extract_type) {
case MR_EXTRACT_MESH: {
- const MEdge *medge = mr->medge;
- for (DRWSubdivLooseEdge edge : loose_edges) {
- *flags_data++ = (medge[edge.coarse_edge_index].flag & ME_HIDE) != 0;
+ const bool *hide_vert = mr->hide_vert;
+ if (hide_vert) {
+ for (DRWSubdivLooseEdge edge : loose_edges) {
+ *flags_data++ = hide_vert[edge.coarse_edge_index];
+ }
+ }
+ else {
+ MutableSpan<uint>(flags_data, loose_edges.size()).fill(0);
}
break;
}
@@ -199,18 +202,23 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
}
}
else {
- for (DRWSubdivLooseEdge edge : loose_edges) {
- int e = edge.coarse_edge_index;
-
- if (mr->e_origindex && mr->e_origindex[e] != ORIGINDEX_NONE) {
- *flags_data++ = (mr->medge[mr->e_origindex[e]].flag & ME_HIDE) != 0;
- }
- else {
- *flags_data++ = false;
+ const bool *hide_vert = mr->hide_vert;
+ if (hide_vert) {
+ for (DRWSubdivLooseEdge edge : loose_edges) {
+ int e = edge.coarse_edge_index;
+
+ if (mr->e_origindex && mr->e_origindex[e] != ORIGINDEX_NONE) {
+ *flags_data++ = hide_vert[edge.coarse_edge_index];
+ }
+ else {
+ *flags_data++ = false;
+ }
}
}
+ else {
+ MutableSpan<uint>(flags_data, loose_edges.size()).fill(0);
+ }
}
-
break;
}
case MR_EXTRACT_BMESH: {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
index c2cfb66ec28..d6c246c51a9 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
@@ -119,16 +119,17 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
- const MPoly *mp = &mr->mpoly[mlt->poly];
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
- lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v,
- mr->mloop[mlt->tri[1]].v,
- mr->mloop[mlt->tri[2]].v,
- mlt->tri[0],
- mlt->tri[1],
- mlt->tri[2],
- data);
+ const bool hidden = mr->use_hide && mr->hide_poly && mr->hide_poly[mlt->poly];
+ if (hidden) {
+ return;
}
+ lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v,
+ mr->mloop[mlt->tri[1]].v,
+ mr->mloop[mlt->tri[2]].v,
+ mlt->tri[0],
+ mlt->tri[1],
+ mlt->tri[2],
+ data);
}
static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
index 11c71d61775..d5f31c08eaf 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
@@ -47,8 +47,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
const MLoop *ml = &mloop[ml_index];
const int e_index = ml->e;
- const MEdge *me = &mr->medge[e_index];
- if (!((mr->use_hide && (me->flag & ME_HIDE)) ||
+ if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[e_index]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[e_index] == ORIGINDEX_NONE)))) {
@@ -122,8 +121,7 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
GPU_indexbuf_set_line_restart(&data->elb, subdiv_edge_index);
}
else {
- const MEdge *me = &mr->medge[coarse_edge_index];
- if (!((mr->use_hide && (me->flag & ME_HIDE)) ||
+ if (!((mr->use_hide && mr->hide_edge && mr->hide_edge[coarse_edge_index]) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[coarse_edge_index] == ORIGINDEX_NONE)))) {
const uint ml_index_other = (loop_idx == (end_loop_idx - 1)) ? start_loop_idx :
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
index f7c5505422b..ca46a38823d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
@@ -43,10 +43,10 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
const int v_index,
const int l_index)
{
- const MVert *mv = &mr->mvert[v_index];
- if (!((mr->use_hide && (mv->flag & ME_HIDE)) ||
- ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
- (mr->v_origindex[v_index] == ORIGINDEX_NONE)))) {
+ const bool hidden = mr->use_hide && mr->hide_vert && mr->hide_vert[v_index];
+
+ if (!(hidden || ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
+ (mr->v_origindex[v_index] == ORIGINDEX_NONE)))) {
GPU_indexbuf_set_point_vert(elb, v_index, l_index);
}
else {
@@ -181,8 +181,7 @@ static void extract_points_iter_subdiv_common(GPUIndexBufBuilder *elb,
}
}
else {
- const MVert *mv = &mr->mvert[coarse_vertex_index];
- if (mr->use_hide && (mv->flag & ME_HIDE)) {
+ if (mr->use_hide && mr->hide_vert && mr->hide_vert[coarse_vertex_index]) {
GPU_indexbuf_set_point_restart(elb, coarse_vertex_index);
continue;
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index 9fc18620d11..2e3e6c7b6b1 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -189,12 +189,12 @@ static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr,
void *_data)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
- const MPoly *mp = &mr->mpoly[mlt->poly];
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
- GPU_indexbuf_set_tri_verts(elb, mlt_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
+ const bool hidden = mr->use_hide && mr->hide_poly && mr->hide_poly[mlt->poly];
+ if (hidden) {
+ GPU_indexbuf_set_tri_restart(elb, mlt_index);
}
else {
- GPU_indexbuf_set_tri_restart(elb, mlt_index);
+ GPU_indexbuf_set_tri_verts(elb, mlt_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
index ac517269e7d..ef67e1b540d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
@@ -62,6 +62,8 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
const int mp_index,
void *data)
{
+ const bool hidden = mr->hide_poly && mr->hide_poly[mp_index];
+
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) {
@@ -80,8 +82,8 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
/* Flag for paint mode overlay.
* Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
* In paint mode it will use the un-mapped data to draw the wire-frame. */
- if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED &&
- (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
+ if (hidden || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
+ mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mp->flag & ME_FACE_SEL) {
@@ -185,6 +187,8 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
const int mp_index,
void *data)
{
+ const bool hidden = mr->hide_poly && mr->hide_poly[mp_index];
+
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) {
@@ -203,8 +207,8 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
/* Flag for paint mode overlay.
* Only use #MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals.
* In paint mode it will use the un-mapped data to draw the wire-frame. */
- if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED &&
- (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
+ if (hidden || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
+ mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mp->flag & ME_FACE_SEL) {
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index 9788beabeb5..4d2a10e83ce 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -83,10 +83,11 @@ static void extract_pos_nor_iter_poly_bm(const MeshRenderData *mr,
static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
- const int UNUSED(mp_index),
+ const int mp_index,
void *_data)
{
MeshExtract_PosNor_Data *data = static_cast<MeshExtract_PosNor_Data *>(_data);
+ const bool face_hidden = mr->hide_poly && mr->hide_poly[mp_index];
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
@@ -95,10 +96,11 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
PosNorLoop *vert = &data->vbo_data[ml_index];
const MVert *mv = &mr->mvert[ml->v];
+ const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v];
copy_v3_v3(vert->pos, mv->co);
vert->nor = data->normals[ml->v].low;
/* Flag for paint mode overlay. */
- if (mp->flag & ME_HIDE || mv->flag & ME_HIDE ||
+ if (face_hidden || vert_hidden ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
@@ -432,18 +434,21 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
+ const bool face_hidden = mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
+
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 bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v];
PosNorHQLoop *vert = &data->vbo_data[ml_index];
const MVert *mv = &mr->mvert[ml->v];
copy_v3_v3(vert->pos, mv->co);
copy_v3_v3_short(vert->nor, data->normals[ml->v].high);
/* Flag for paint mode overlay. */
- if (mp->flag & ME_HIDE || mv->flag & ME_HIDE ||
+ if (face_hidden || vert_hidden ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
(mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 9d3fd5af47f..71ddffca8a9 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -390,7 +390,10 @@ void ED_keymap_mesh(struct wmKeyConfig *keyconf);
* Copy the face flags, most importantly selection from the mesh to the final derived mesh,
* use in object mode when selecting faces (while painting).
*/
-void paintface_flush_flags(struct bContext *C, struct Object *ob, short flag);
+void paintface_flush_flags(struct bContext *C,
+ struct Object *ob,
+ bool flush_selection,
+ bool flush_hidden);
/**
* \return True when pick finds an element or the selection changed.
*/
diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc
index 3608e162727..96a493cba49 100644
--- a/source/blender/editors/mesh/editface.cc
+++ b/source/blender/editors/mesh/editface.cc
@@ -17,6 +17,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
@@ -36,14 +37,18 @@
/* own include */
-void paintface_flush_flags(bContext *C, Object *ob, short flag)
+void paintface_flush_flags(bContext *C,
+ Object *ob,
+ const bool flush_selection,
+ const bool flush_hidden)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
MPoly *polys, *mp_orig;
const int *index_array = nullptr;
int totpoly;
- BLI_assert((flag & ~(SELECT | ME_HIDE)) == 0);
+ BLI_assert(flush_selection || flush_hidden);
if (me == nullptr) {
return;
@@ -53,7 +58,7 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag)
/* we could call this directly in all areas that change selection,
* since this could become slow for realtime updates (circle-select for eg) */
- if (flag & SELECT) {
+ if (flush_selection) {
BKE_mesh_flush_select_from_polys(me);
}
@@ -64,8 +69,11 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag)
return;
}
+ bke::AttributeAccessor attributes_me = bke::mesh_attributes(*me);
Mesh *me_orig = (Mesh *)ob_eval->runtime.data_orig;
+ bke::MutableAttributeAccessor attributes_orig = bke::mesh_attributes_for_write(*me_orig);
Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
+ bke::MutableAttributeAccessor attributes_eval = bke::mesh_attributes_for_write(*me_eval);
bool updated = false;
if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) {
@@ -73,13 +81,17 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag)
for (int i = 0; i < me->totpoly; i++) {
me_orig->mpoly[i].flag = me->mpoly[i].flag;
}
-
- /* If the mesh has only deform modifiers, the evaluated mesh shares arrays. */
- if (me_eval->mpoly == me_orig->mpoly) {
- updated = true;
+ if (flush_hidden) {
+ const VArray<bool> hide_face_me = attributes_me.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> hide_face_orig =
+ attributes_orig.lookup_or_add_for_write_only_span<bool>(".hide_poly", ATTR_DOMAIN_FACE);
+ hide_face_me.materialize(hide_face_orig.span);
+ hide_face_orig.finish();
}
+
/* Mesh polys => Final derived polys */
- else if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
+ if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
polys = me_eval->mpoly;
totpoly = me_eval->totpoly;
@@ -91,13 +103,24 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag)
polys[i].flag = mp_orig->flag;
}
}
+ const VArray<bool> hide_face_orig = attributes_orig.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ bke::SpanAttributeWriter<bool> hide_face_eval =
+ attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_poly", ATTR_DOMAIN_FACE);
+ for (const int i : IndexRange(me_eval->totpoly)) {
+ const int orig_face_index = index_array[i];
+ if (orig_face_index != ORIGINDEX_NONE) {
+ hide_face_eval.span[i] = hide_face_orig[orig_face_index];
+ }
+ }
+ hide_face_eval.finish();
updated = true;
}
}
if (updated) {
- if (flag & ME_HIDE) {
+ if (flush_hidden) {
BKE_mesh_batch_cache_dirty_tag(me_eval, BKE_MESH_BATCH_DIRTY_ALL);
}
else {
@@ -115,59 +138,79 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag)
void paintface_hide(bContext *C, Object *ob, const bool unselected)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr || me->totpoly == 0) {
return;
}
+ bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
+ bke::SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
- if ((mpoly->flag & ME_HIDE) == 0) {
+ if (!hide_poly.span[i]) {
if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) {
- mpoly->flag |= ME_HIDE;
+ hide_poly.span[i] = true;
}
}
- if (mpoly->flag & ME_HIDE) {
+ if (hide_poly.span[i]) {
mpoly->flag &= ~ME_FACE_SEL;
}
}
+ hide_poly.finish();
+
BKE_mesh_flush_hidden_from_polys(me);
- paintface_flush_flags(C, ob, SELECT | ME_HIDE);
+ paintface_flush_flags(C, ob, true, true);
}
void paintface_reveal(bContext *C, Object *ob, const bool select)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr || me->totpoly == 0) {
return;
}
- for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &me->mpoly[i];
- if (mpoly->flag & ME_HIDE) {
- SET_FLAG_FROM_TEST(mpoly->flag, select, ME_FACE_SEL);
- mpoly->flag &= ~ME_HIDE;
+ bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
+
+ if (select) {
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+ for (int i = 0; i < me->totpoly; i++) {
+ MPoly *mpoly = &me->mpoly[i];
+ if (hide_poly[i]) {
+ mpoly->flag |= ME_FACE_SEL;
+ }
}
}
+ attributes.remove(".hide_poly");
+
BKE_mesh_flush_hidden_from_polys(me);
- paintface_flush_flags(C, ob, SELECT | ME_HIDE);
+ paintface_flush_flags(C, ob, true, true);
}
/* Set object-mode face selection seams based on edge data, uses hash table to find seam edges. */
static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bool select)
{
+ using namespace blender;
bool do_it = true;
bool mark = false;
BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
if (index != (uint)-1) {
/* only put face under cursor in array */
MPoly *mp = &me->mpoly[index];
@@ -178,7 +221,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
/* fill array by selection */
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
- if (mp->flag & ME_HIDE) {
+ if (hide_poly[i]) {
/* pass */
}
else if (mp->flag & ME_FACE_SEL) {
@@ -194,7 +237,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
/* expand selection */
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
- if (mp->flag & ME_HIDE) {
+ if (hide_poly[i]) {
continue;
}
@@ -249,22 +292,27 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b
select_linked_tfaces_with_seams(me, index, select);
- paintface_flush_flags(C, ob, SELECT);
+ paintface_flush_flags(C, ob, true, false);
}
bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr) {
return false;
}
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
- if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) {
+ if (!hide_poly[i] && mpoly->flag & ME_FACE_SEL) {
action = SEL_DESELECT;
break;
}
@@ -275,7 +323,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
for (int i = 0; i < me->totpoly; i++) {
MPoly *mpoly = &me->mpoly[i];
- if ((mpoly->flag & ME_HIDE) == 0) {
+ if (!hide_poly[i]) {
switch (action) {
case SEL_SELECT:
if ((mpoly->flag & ME_FACE_SEL) == 0) {
@@ -299,7 +347,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
if (changed) {
if (flush_flags) {
- paintface_flush_flags(C, ob, SELECT);
+ paintface_flush_flags(C, ob, true, false);
}
}
return changed;
@@ -307,6 +355,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
{
+ using namespace blender;
bool ok = false;
float vec[3], bmat[3][3];
@@ -318,9 +367,13 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
copy_m3_m4(bmat, ob->obmat);
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
for (int i = 0; i < me->totpoly; i++) {
MPoly *mp = &me->mpoly[i];
- if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL)) {
+ if (hide_poly[i] || !(mp->flag & ME_FACE_SEL)) {
continue;
}
@@ -342,6 +395,7 @@ bool paintface_mouse_select(bContext *C,
const SelectPick_Params *params,
Object *ob)
{
+ using namespace blender;
MPoly *mpoly_sel = nullptr;
uint index;
bool changed = false;
@@ -350,10 +404,14 @@ bool paintface_mouse_select(bContext *C,
/* Get the face under the cursor */
Mesh *me = BKE_mesh_from_object(ob);
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
if (index < me->totpoly) {
mpoly_sel = me->mpoly + index;
- if ((mpoly_sel->flag & ME_HIDE) == 0) {
+ if (!hide_poly[index]) {
found = true;
}
}
@@ -402,7 +460,7 @@ bool paintface_mouse_select(bContext *C,
/* image window redraw */
- paintface_flush_flags(C, ob, SELECT);
+ paintface_flush_flags(C, ob, true, false);
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
changed = true;
}
@@ -463,17 +521,24 @@ void paintvert_tag_select_update(bContext *C, Object *ob)
bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr) {
return false;
}
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
for (int i = 0; i < me->totvert; i++) {
MVert *mvert = &me->mvert[i];
- if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
+ if (!hide_poly[i] && mvert->flag & SELECT) {
action = SEL_DESELECT;
break;
}
@@ -483,7 +548,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool changed = false;
for (int i = 0; i < me->totvert; i++) {
MVert *mvert = &me->mvert[i];
- if ((mvert->flag & ME_HIDE) == 0) {
+ if (!hide_vert[i]) {
switch (action) {
case SEL_SELECT:
if ((mvert->flag & SELECT) == 0) {
@@ -526,6 +591,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
if (me == nullptr || me->dvert == nullptr) {
@@ -536,10 +602,14 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
}
+ bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
+ const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE, false);
+
for (int i = 0; i < me->totvert; i++) {
MVert *mv = &me->mvert[i];
MDeformVert *dv = &me->dvert[i];
- if ((mv->flag & ME_HIDE) == 0) {
+ if (!hide_poly[i]) {
if (dv->dw == nullptr) {
/* if null weight then not grouped */
mv->flag |= SELECT;
@@ -554,25 +624,30 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
void paintvert_hide(bContext *C, Object *ob, const bool unselected)
{
- Mesh *const me = BKE_mesh_from_object(ob);
-
- if (me == nullptr || me->totvert == 0) {
+ using namespace blender;
+ Mesh *me = BKE_mesh_from_object(ob);
+ if (me == NULL || me->totvert == 0) {
return;
}
- for (int i = 0; i < me->totvert; i++) {
- MVert *const mvert = &me->mvert[i];
+ bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
+ bke::SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ MutableSpan<MVert> vertices(me->mvert, me->totvert);
- if ((mvert->flag & ME_HIDE) == 0) {
- if (((mvert->flag & SELECT) == 0) == unselected) {
- mvert->flag |= ME_HIDE;
+ for (const int i : vertices.index_range()) {
+ MVert &vert = vertices[i];
+ if (!hide_vert.span[i]) {
+ if (((vert.flag & SELECT) == 0) == unselected) {
+ hide_vert.span[i] = true;
}
}
- if (mvert->flag & ME_HIDE) {
- mvert->flag &= ~SELECT;
+ if (hide_vert.span[i]) {
+ vert.flag &= ~SELECT;
}
}
+ hide_vert.finish();
BKE_mesh_flush_hidden_from_verts(me);
@@ -582,21 +657,27 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected)
void paintvert_reveal(bContext *C, Object *ob, const bool select)
{
- Mesh *const me = BKE_mesh_from_object(ob);
-
- if (me == nullptr || me->totvert == 0) {
+ using namespace blender;
+ Mesh *me = BKE_mesh_from_object(ob);
+ if (me == NULL || me->totvert == 0) {
return;
}
- for (int i = 0; i < me->totvert; i++) {
- MVert *const mvert = &me->mvert[i];
+ bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
+ const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT, false);
+ MutableSpan<MVert> vertices(me->mvert, me->totvert);
- if (mvert->flag & ME_HIDE) {
- SET_FLAG_FROM_TEST(mvert->flag, select, SELECT);
- mvert->flag &= ~ME_HIDE;
+ for (const int i : vertices.index_range()) {
+ MVert &vert = vertices[i];
+ if (hide_vert[i]) {
+ SET_FLAG_FROM_TEST(vert.flag, select, SELECT);
}
}
+ /* Remove the hide attribute to reveal all vertices. */
+ attributes.remove(".hide_vert");
+
BKE_mesh_flush_hidden_from_verts(me);
paintvert_flush_flags(ob);
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index d75c92f963f..af8084e16c4 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -594,6 +594,10 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
/* Uncomment for troubleshooting. */
// BM_mesh_validate(em->bm);
+ /* Copy the ID name characters to the mesh so code that depends on accessing the ID type can work
+ * on it. Necessary to use the attribute API. */
+ strcpy(um->me.id.name, "MEundomesh_from_editmesh");
+
BM_mesh_bm_to_me(
NULL,
em->bm,
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index 9e28e1bafdd..b1004b23a21 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -1329,6 +1329,7 @@ bool ED_mesh_pick_face_vert(
*/
struct VertPickData {
const MVert *mvert;
+ const bool *hide_vert;
const float *mval_f; /* [2] */
ARegion *region;
@@ -1343,16 +1344,16 @@ static void ed_mesh_pick_vert__mapFunc(void *userData,
const float UNUSED(no[3]))
{
VertPickData *data = static_cast<VertPickData *>(userData);
- if ((data->mvert[index].flag & ME_HIDE) == 0) {
- float sco[2];
-
- if (ED_view3d_project_float_object(data->region, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) ==
- V3D_PROJ_RET_OK) {
- const float len = len_manhattan_v2v2(data->mval_f, sco);
- if (len < data->len_best) {
- data->len_best = len;
- data->v_idx_best = index;
- }
+ if (data->hide_vert && data->hide_vert[index]) {
+ return;
+ }
+ float sco[2];
+ if (ED_view3d_project_float_object(data->region, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) ==
+ V3D_PROJ_RET_OK) {
+ const float len = len_manhattan_v2v2(data->mval_f, sco);
+ if (len < data->len_best) {
+ data->len_best = len;
+ data->v_idx_best = index;
}
}
}
@@ -1416,6 +1417,8 @@ bool ED_mesh_pick_vert(
data.mval_f = mval_f;
data.len_best = FLT_MAX;
data.v_idx_best = -1;
+ data.hide_vert = (const bool *)CustomData_get_layer_named(
+ &me_eval->vdata, CD_PROP_BOOL, ".hide_vert");
BKE_mesh_foreach_mapped_vert(me_eval, ed_mesh_pick_vert__mapFunc, &data, MESH_FOREACH_NOP);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 6369afac632..eb5aaf7ef61 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -1034,6 +1034,7 @@ static void vgroup_select_verts(Object *ob, int select)
}
else {
if (me->dvert) {
+ const bool *hide_vert = CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert");
MVert *mv;
MDeformVert *dv;
int i;
@@ -1042,7 +1043,7 @@ static void vgroup_select_verts(Object *ob, int select)
dv = me->dvert;
for (i = 0; i < me->totvert; i++, mv++, dv++) {
- if (!(mv->flag & ME_HIDE)) {
+ if (hide_vert != NULL && !hide_vert[i]) {
if (BKE_defvert_find_index(dv, def_nr)) {
if (select) {
mv->flag |= SELECT;
@@ -1930,7 +1931,11 @@ static void vgroup_smooth_subset(Object *ob,
#define IS_BM_VERT_READ(v) (use_hide ? (BM_elem_flag_test(v, BM_ELEM_HIDDEN) == 0) : true)
#define IS_BM_VERT_WRITE(v) (use_select ? (BM_elem_flag_test(v, BM_ELEM_SELECT) != 0) : true)
-#define IS_ME_VERT_READ(v) (use_hide ? (((v)->flag & ME_HIDE) == 0) : true)
+ const bool *hide_vert = me ? (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".hide_vert") :
+ NULL;
+
+#define IS_ME_VERT_READ(v) (use_hide ? (hide_vert && hide_vert[v]) : true)
#define IS_ME_VERT_WRITE(v) (use_select ? (((v)->flag & SELECT) != 0) : true)
/* initialize used verts */
@@ -1956,8 +1961,8 @@ static void vgroup_smooth_subset(Object *ob,
if (IS_ME_VERT_WRITE(v)) {
for (int j = 0; j < emap[i].count; j++) {
const MEdge *e = &me->medge[emap[i].indices[j]];
- const MVert *v_other = &me->mvert[(e->v1 == i) ? e->v2 : e->v1];
- if (IS_ME_VERT_READ(v_other)) {
+ const int i_other = (e->v1 == i) ? e->v2 : e->v1;
+ if (IS_ME_VERT_READ(i_other)) {
STACK_PUSH(verts_used, i);
break;
}
@@ -2031,9 +2036,7 @@ static void vgroup_smooth_subset(Object *ob,
for (j = 0; j < emap[i].count; j++) {
MEdge *e = &me->medge[emap[i].indices[j]];
const int i_other = (e->v1 == i ? e->v2 : e->v1);
- MVert *v_other = &me->mvert[i_other];
-
- if (IS_ME_VERT_READ(v_other)) {
+ if (IS_ME_VERT_READ(i_other)) {
WEIGHT_ACCUMULATE;
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 944b3f953a0..c904d533db8 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -78,6 +78,12 @@ static void partialvis_update_mesh(Object *ob,
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+ bool *hide_vert = CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert");
+ if (hide_vert == NULL) {
+ hide_vert = CustomData_add_layer_named(
+ &me->vdata, CD_PROP_BOOL, CD_CALLOC, NULL, me->totvert, ".hide_vert");
+ }
+
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
for (i = 0; i < totvert; i++) {
@@ -86,16 +92,11 @@ static void partialvis_update_mesh(Object *ob,
/* Hide vertex if in the hide volume. */
if (is_effected(area, planes, v->co, vmask)) {
- if (action == PARTIALVIS_HIDE) {
- v->flag |= ME_HIDE;
- }
- else {
- v->flag &= ~ME_HIDE;
- }
+ hide_vert[vert_indices[i]] = (action == PARTIALVIS_HIDE);
any_changed = true;
}
- if (!(v->flag & ME_HIDE)) {
+ if (!hide_vert[vert_indices[i]]) {
any_visible = true;
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 02d21941a25..ffa931268fd 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -344,9 +344,11 @@ int SCULPT_active_face_set_get(SculptSession *ss)
void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visible)
{
switch (BKE_pbvh_type(ss->pbvh)) {
- case PBVH_FACES:
- SET_FLAG_FROM_TEST(ss->mvert[vertex.i].flag, !visible, ME_HIDE);
+ case PBVH_FACES: {
+ bool *hide_vert = BKE_pbvh_get_vert_hide_for_write(ss->pbvh);
+ hide_vert[vertex.i] = visible;
break;
+ }
case PBVH_BMESH: {
BMVert *v = (BMVert *)vertex.i;
BM_elem_flag_set(v, BM_ELEM_HIDDEN, !visible);
@@ -360,8 +362,10 @@ void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visib
bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(ss->pbvh)) {
- case PBVH_FACES:
- return !(ss->mvert[vertex.i].flag & ME_HIDE);
+ case PBVH_FACES: {
+ const bool *hide_vert = BKE_pbvh_get_vert_hide(ss->pbvh);
+ return hide_vert == NULL || !hide_vert[vertex.i];
+ }
case PBVH_BMESH:
return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN);
case PBVH_GRIDS: {
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 4f91d2215fb..40b4b74a441 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -227,8 +227,9 @@ static void SCULPT_dynamic_topology_disable_ex(
me->face_sets_color_default = 1;
/* Sync the visibility to vertices manually as the pmap is still not initialized. */
- for (int i = 0; i < me->totvert; i++) {
- me->mvert[i].flag &= ~ME_HIDE;
+ bool *hide_vert = (bool *)CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert");
+ if (hide_vert != NULL) {
+ memset(hide_vert, 0, sizeof(bool) * me->totvert);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index dc814d6d22f..04b2b2f04bf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -346,14 +346,13 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool
SculptSession *ss = ob->sculpt;
SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
- if (unode->maxvert) {
- MVert *mvert = ss->mvert;
+ bool *hide_vert = BKE_pbvh_get_vert_hide_for_write(ss->pbvh);
+ if (unode->maxvert) {
for (int i = 0; i < unode->totvert; i++) {
- MVert *v = &mvert[unode->index[i]];
- if ((BLI_BITMAP_TEST(unode->vert_hidden, i) != 0) != ((v->flag & ME_HIDE) != 0)) {
+ if ((BLI_BITMAP_TEST(unode->vert_hidden, i) != 0) != hide_vert[i]) {
BLI_BITMAP_FLIP(unode->vert_hidden, i);
- v->flag ^= ME_HIDE;
+ hide_vert[unode->index[i]] = !hide_vert[i];
modified_vertices[unode->index[i]] = true;
}
}
@@ -1247,6 +1246,11 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode *node = unode->node;
+ const bool *hide_vert = BKE_pbvh_get_vert_hide(pbvh);
+ if (hide_vert == NULL) {
+ return;
+ }
+
if (unode->grids) {
/* Already stored during allocation. */
}
@@ -1258,7 +1262,7 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
for (int i = 0; i < allvert; i++) {
- BLI_BITMAP_SET(unode->vert_hidden, i, mvert[vert_indices[i]].flag & ME_HIDE);
+ BLI_BITMAP_SET(unode->vert_hidden, i, hide_vert[vert_indices[i]]);
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 35d4746608b..6256eeb9621 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -205,6 +205,7 @@ typedef struct foreachScreenObjectVert_userData {
void (*func)(void *userData, MVert *mv, const float screen_co[2], int index);
void *userData;
ViewContext vc;
+ const bool *hide_vert;
eV3DProjTest clip_flag;
} foreachScreenObjectVert_userData;
@@ -262,18 +263,19 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData,
const float UNUSED(no[3]))
{
foreachScreenObjectVert_userData *data = userData;
+ if (data->hide_vert && data->hide_vert[index]) {
+ return;
+ }
struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
- if (!(mv->flag & ME_HIDE)) {
- float screen_co[2];
-
- if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
- V3D_PROJ_RET_OK) {
- return;
- }
+ float screen_co[2];
- data->func(data->userData, mv, screen_co, index);
+ if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
+ V3D_PROJ_RET_OK) {
+ return;
}
+
+ data->func(data->userData, mv, screen_co, index);
}
void meshobject_foreachScreenVert(
@@ -297,6 +299,8 @@ void meshobject_foreachScreenVert(
data.func = func;
data.userData = userData;
data.clip_flag = clip_flag;
+ data.hide_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".hide_vert");
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
ED_view3d_clipping_local(vc->rv3d, vc->obact->obmat);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 571c39f30cb..cd609f7e8cf 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -335,14 +335,16 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me,
const eSelectOp sel_op)
{
MVert *mv = me->mvert;
- uint index;
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
if (mv) {
- for (index = 0; index < me->totvert; index++, mv++) {
- if (!(mv->flag & ME_HIDE)) {
+ const bool *hide_vert = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".hide_vert");
+
+ for (int index = 0; index < me->totvert; index++, mv++) {
+ if (!(hide_vert && hide_vert[index])) {
const bool is_select = mv->flag & SELECT;
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
@@ -362,14 +364,16 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me,
const eSelectOp sel_op)
{
MPoly *mpoly = me->mpoly;
- uint index;
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
if (mpoly) {
- for (index = 0; index < me->totpoly; index++, mpoly++) {
- if (!(mpoly->flag & ME_HIDE)) {
+ const bool *hide_poly = (const bool *)CustomData_get_layer_named(
+ &me->vdata, CD_PROP_BOOL, ".hide_poly");
+
+ for (int index = 0; index < me->totpoly; index++, mpoly++) {
+ if (!(hide_poly && hide_poly[index])) {
const bool is_select = mpoly->flag & ME_FACE_SEL;
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
@@ -1260,7 +1264,7 @@ static bool do_lasso_select_paintface(ViewContext *vc,
}
if (changed) {
- paintface_flush_flags(vc->C, ob, SELECT);
+ paintface_flush_flags(vc->C, ob, true, false);
}
return changed;
}
@@ -3192,7 +3196,7 @@ static bool do_paintface_box_select(ViewContext *vc,
}
if (changed) {
- paintface_flush_flags(vc->C, vc->obact, SELECT);
+ paintface_flush_flags(vc->C, vc->obact, true, false);
}
return changed;
}
@@ -4093,7 +4097,7 @@ static bool paint_facesel_circle_select(ViewContext *vc,
}
if (changed) {
- paintface_flush_flags(vc->C, ob, SELECT);
+ paintface_flush_flags(vc->C, ob, true, false);
}
return changed;
}
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 6dc49ff494d..d1d91cb7508 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -48,7 +48,6 @@ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
* Threaded: do not call any functions that use OpenGL calls!
*/
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct Mesh *mesh,
- const struct MVert *vertices,
const struct MLoopTri *looptri,
const int *sculpt_face_sets,
const int *face_indices,
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 2a0f624ac45..d64b8b4118a 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -211,11 +211,11 @@ static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
* \{ */
static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
- const MVert *mvert,
+ const bool *hide_vert,
const MLoop *mloop,
const int *sculpt_face_sets)
{
- return (!paint_is_face_hidden(lt, mvert, mloop) && sculpt_face_sets &&
+ return (!paint_is_face_hidden(lt, hide_vert, mloop) && sculpt_face_sets &&
sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE);
}
@@ -233,6 +233,9 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
GPUAttrRef vcol_refs[MAX_GPU_ATTR];
GPUAttrRef cd_uvs[MAX_GPU_ATTR];
+ const bool *hide_vert = (bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+
const CustomDataLayer *actcol = BKE_id_attributes_active_color_get(&mesh->id);
eAttrDomain actcol_domain = actcol ? BKE_id_attribute_domain(&mesh->id, actcol) :
ATTR_DOMAIN_AUTO;
@@ -310,7 +313,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
for (uint i = 0; i < buffers->face_indices_len; i++) {
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -350,7 +353,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
buffers->mloop[lt->tri[2]].v,
};
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -390,7 +393,7 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
buffers->mloop[lt->tri[2]].v,
};
- if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -454,7 +457,6 @@ void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
}
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
- const MVert *vertices,
const MLoopTri *looptri,
const int *sculpt_face_sets,
const int *face_indices,
@@ -469,6 +471,9 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
+ const bool *hide_vert = (bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+
/* smooth or flat for all */
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
@@ -477,7 +482,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
/* Count the number of visible triangles */
for (i = 0, tottri = 0; i < face_indices_len; i++) {
const MLoopTri *lt = &looptri[face_indices[i]];
- if (gpu_pbvh_is_looptri_visible(lt, vertices, mloop, sculpt_face_sets)) {
+ if (gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) {
int r_edges[3];
BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
for (int j = 0; j < 3; j++) {
@@ -510,7 +515,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
const MLoopTri *lt = &looptri[face_indices[i]];
/* Skip hidden faces */
- if (!gpu_pbvh_is_looptri_visible(lt, vertices, mloop, sculpt_face_sets)) {
+ if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) {
continue;
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
index d8af2fc584d..3a14c060484 100644
--- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
@@ -137,7 +137,7 @@ eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
/** \name Stubs of BKE_paint.h
* \{ */
bool paint_is_face_hidden(const struct MLoopTri *UNUSED(lt),
- const struct MVert *UNUSED(mvert),
+ const bool *UNUSED(hide_vert),
const struct MLoop *UNUSED(mloop))
{
BLI_assert_unreachable();
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index 9460746630d..9b050af0891 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -296,7 +296,7 @@ void OBJMesh::store_uv_coords_and_indices()
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- mpoly, mloop, mloopuv, totpoly, totvert, limit, false, false);
+ mpoly, nullptr, mloop, mloopuv, totpoly, totvert, limit, false, false);
uv_indices_.resize(totpoly);
/* At least total vertices of a mesh will be present in its texture map. So
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 4090c45a753..abef90495c5 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -30,10 +30,13 @@ typedef struct MVert {
} MVert;
/** #MVert.flag */
+
+#ifdef DNA_DEPRECATED_ALLOW
enum {
/* SELECT = (1 << 0), */
ME_HIDE = (1 << 4),
};
+#endif
/**
* Mesh Edges.
@@ -351,7 +354,7 @@ typedef struct MDisps {
/**
* Used for hiding parts of a multires mesh.
- * Essentially the multires equivalent of #MVert.flag's ME_HIDE bit.
+ * Essentially the multires equivalent of the mesh ".hide_vert" boolean layer.
*
* \note This is a bitmap, keep in sync with type used in BLI_bitmap.h
*/
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 9aef19c8230..bdc96f6dec1 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -356,6 +356,27 @@ static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
copy_v3_v3(value, vert_normals[index]);
}
+static bool rna_MeshVertex_hide_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *hide_vert = (const bool *)CustomData_get_layer_named(
+ &mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+ const int index = (const MVert *)ptr->data - mesh->mvert;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totvert);
+ return hide_vert[index];
+}
+
+static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert");
+ const int index = (const MVert *)ptr->data - mesh->mvert;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totvert);
+ hide_vert[index] = value;
+}
+
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
{
MVert *mvert = (MVert *)ptr->data;
@@ -464,6 +485,27 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values)
BKE_mesh_calc_poly_normal(mp, me->mloop + mp->loopstart, me->mvert, values);
}
+static bool rna_MeshPolygon_hide_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *hide_poly = (const bool *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
+ const int index = (const MPoly *)ptr->data - mesh->mpoly;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totpoly);
+ return hide_poly[index];
+}
+
+static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly");
+ const int index = (const MPoly *)ptr->data - mesh->mpoly;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totpoly);
+ hide_poly[index] = value;
+}
+
static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
@@ -1188,6 +1230,27 @@ static int rna_MeshEdge_index_get(PointerRNA *ptr)
return (int)(edge - me->medge);
}
+static bool rna_MeshEdge_hide_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const bool *hide_edge = (const bool *)CustomData_get_layer_named(
+ &mesh->pdata, CD_PROP_BOOL, ".hide_edge");
+ const int index = (const MEdge *)ptr->data - mesh->medge;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totedge);
+ return hide_edge[index];
+}
+
+static void rna_MeshEdge_hide_set(PointerRNA *ptr, bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ bool *hide_edge = (bool *)CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".hide_edge");
+ const int index = (const MEdge *)ptr->data - mesh->medge;
+ BLI_assert(index >= 0);
+ BLI_assert(index < mesh->totedge);
+ hide_edge[index] = value;
+}
+
static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -1830,8 +1893,8 @@ static void rna_def_mvert(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE);
RNA_def_property_ui_text(prop, "Hide", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_hide_get", "rna_MeshVertex_hide_set");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE);
@@ -1906,8 +1969,8 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE);
RNA_def_property_ui_text(prop, "Hide", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_hide_get", "rna_MeshEdge_hide_set");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "use_seam", PROP_BOOLEAN, PROP_NONE);
@@ -2119,8 +2182,8 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE);
RNA_def_property_ui_text(prop, "Hide", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshPolygon_hide_get", "rna_MeshPolygon_hide_set");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 3df4fbcbea8..55d9d148d10 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -201,11 +201,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
updateFaceCount(ctx, dmd, bm->totface);
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
/* make sure we never alloc'd these */
BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL && bm->ftoolflagpool == NULL);
BLI_assert(bm->vtable == NULL && bm->etable == NULL && bm->ftable == NULL);
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+
BM_mesh_free(bm);
#ifdef USE_TIMEIT