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:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh_convert.cc')
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.cc74
1 files changed, 54 insertions, 20 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
index d5581584f41..aa8972f9d14 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
@@ -908,6 +908,16 @@ static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attribu
}
}
+static void assert_bmesh_has_no_mesh_only_attributes(BMesh &bm)
+{
+ (void)bm; /* Unused in the release builds. */
+
+ /* 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);
+}
+
static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
const bool need_hide_vert,
const bool need_hide_edge,
@@ -916,9 +926,7 @@ static void convert_bmesh_hide_flags_to_mesh_attributes(BMesh &bm,
{
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);
+ assert_bmesh_has_no_mesh_only_attributes(bm);
if (!(need_hide_vert || need_hide_edge || need_hide_poly)) {
return;
@@ -1206,8 +1214,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BKE_mesh_runtime_clear_geometry(me);
}
+/* NOTE: The function is called from multiple threads with the same input BMesh and different
+ * mesh objects. */
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
{
+ using namespace blender;
+
/* Must be an empty mesh. */
BLI_assert(me->totvert == 0);
BLI_assert(cd_mask_extra == nullptr || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
@@ -1248,17 +1260,15 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
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_poly = false;
- bool need_material_index = 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);
me->runtime.deformed_only = true;
+ bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write();
+
+ bke::SpanAttributeWriter<bool> hide_vert_attribute;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
MVert *mv = &mvert[i];
@@ -1268,13 +1278,18 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
mv->flag = BM_vert_flag_to_mflag(eve);
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- need_hide_vert = true;
+ if (!hide_vert_attribute) {
+ hide_vert_attribute = mesh_attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_vert", ATTR_DOMAIN_POINT);
+ }
+ hide_vert_attribute.span[i] = true;
}
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
}
bm->elem_index_dirty &= ~BM_VERT;
+ bke::SpanAttributeWriter<bool> hide_edge_attribute;
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
MEdge *med = &medge[i];
@@ -1285,7 +1300,11 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
med->flag = BM_edge_flag_to_mflag(eed);
if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- need_hide_edge = true;
+ if (!hide_edge_attribute) {
+ hide_edge_attribute = mesh_attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_edge", ATTR_DOMAIN_EDGE);
+ }
+ hide_edge_attribute.span[i] = true;
}
/* Handle this differently to editmode switching,
@@ -1305,6 +1324,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
bm->elem_index_dirty &= ~BM_EDGE;
j = 0;
+ bke::SpanAttributeWriter<int> material_index_attribute;
+ bke::SpanAttributeWriter<bool> hide_poly_attribute;
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
BMLoop *l_iter;
BMLoop *l_first;
@@ -1315,12 +1336,20 @@ 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_poly = true;
+ if (!hide_poly_attribute) {
+ hide_poly_attribute = mesh_attributes.lookup_or_add_for_write_only_span<bool>(
+ ".hide_poly", ATTR_DOMAIN_FACE);
+ }
+ hide_poly_attribute.span[i] = true;
}
mp->loopstart = j;
if (efa->mat_nr != 0) {
- need_material_index = true;
+ if (!material_index_attribute) {
+ material_index_attribute = mesh_attributes.lookup_or_add_for_write_only_span<int>(
+ "material_index", ATTR_DOMAIN_FACE);
+ }
+ material_index_attribute.span[i] = efa->mat_nr;
}
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
@@ -1339,16 +1368,21 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
}
bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
- if (need_material_index) {
- BM_mesh_elem_table_ensure(bm, BM_FACE);
- write_fn_to_attribute<int>(
- me->attributes_for_write(), "material_index", ATTR_DOMAIN_FACE, true, [&](const int i) {
- return static_cast<int>(BM_face_at_index(bm, i)->mat_nr);
- });
+ if (material_index_attribute) {
+ material_index_attribute.finish();
}
- convert_bmesh_hide_flags_to_mesh_attributes(
- *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me);
+ assert_bmesh_has_no_mesh_only_attributes(*bm);
+
+ if (hide_vert_attribute) {
+ hide_vert_attribute.finish();
+ }
+ if (hide_edge_attribute) {
+ hide_edge_attribute.finish();
+ }
+ if (hide_poly_attribute) {
+ hide_poly_attribute.finish();
+ }
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
}