diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_legacy_convert.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_mapping.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/attribute_access.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.cc | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mball_tessellate.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.cc | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_boolean_convert.cc | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_calc_edges.cc | 27 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.cc | 127 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_legacy_convert.cc | 98 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_mapping.cc | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_deform.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_converter_mesh.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_mesh.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 3 |
16 files changed, 228 insertions, 119 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index ef57c9a2e0e..c1f4d9733aa 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -870,16 +870,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me); */ void BKE_mesh_flush_hidden_from_verts(struct Mesh *me); void BKE_mesh_flush_hidden_from_polys(struct Mesh *me); -/** - * simple poly -> vert/edge selection. - */ -void BKE_mesh_flush_select_from_polys_ex(struct MVert *mvert, - int totvert, - const struct MLoop *mloop, - struct MEdge *medge, - int totedge, - const struct MPoly *mpoly, - int totpoly); + void BKE_mesh_flush_select_from_polys(struct Mesh *me); void BKE_mesh_flush_select_from_verts(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index f45dfd8bc8d..d3e582ff197 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -55,6 +55,16 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh); void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh); /** + * Convert the selected element attributes to the old flag format for writing. + */ +void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh); +/** + * Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for + * reading. Only add the attributes when there are any elements in each domain selected. + */ +void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh); + +/** * Move material indices from a generic attribute to #MPoly. */ void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index cf9763d50a4..2ee50fbaaee 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -93,6 +93,7 @@ typedef struct MeshElemMap { /* mapping */ UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly, const bool *hide_poly, + const bool *select_poly, const struct MLoop *mloop, const struct MLoopUV *mloopuv, unsigned int totpoly, diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index df7787986db..b86353bdb74 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -58,7 +58,7 @@ const char *no_procedural_access_message = bool allow_procedural_attribute_access(StringRef attribute_name) { - return !attribute_name.startswith(".sculpt") && !attribute_name.startswith(".selection") && + return !attribute_name.startswith(".sculpt") && !attribute_name.startswith(".select") && !attribute_name.startswith(".hide"); } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 084fe76cd10..51c3b405ebc 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2372,7 +2372,14 @@ bool CustomData_merge(const CustomData *source, static bool attribute_stored_in_bmesh_flag(const StringRef name) { - return ELEM(name, ".hide_vert", ".hide_edge", ".hide_poly", "material_index"); + return ELEM(name, + ".hide_vert", + ".hide_edge", + ".hide_poly", + ".select_vert", + ".select_edge", + ".select_poly", + "material_index"); } static CustomData shallow_copy_remove_non_bmesh_attributes(const CustomData &src) diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c index 49963c333ec..48fadd2e9b8 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.c +++ b/source/blender/blenkernel/intern/mball_tessellate.c @@ -1447,7 +1447,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, NULL, mesh->totvert); for (int i = 0; i < mesh->totvert; i++) { copy_v3_v3(mvert[i].co, process.co[i]); - mvert->flag = 0; } MEM_freeN(process.co); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 34cebeaa5d4..6df6cd31cf4 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -68,6 +68,7 @@ using blender::BitVector; using blender::float3; using blender::MutableSpan; using blender::Span; +using blender::StringRef; using blender::VArray; using blender::Vector; @@ -248,12 +249,19 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address Set<std::string> names_to_skip; if (!BLO_write_is_undo(writer)) { BKE_mesh_legacy_convert_hide_layers_to_flags(mesh); + BKE_mesh_legacy_convert_selection_layers_to_flags(mesh); BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh); BKE_mesh_legacy_bevel_weight_from_layers(mesh); BKE_mesh_legacy_face_set_from_generic(mesh); BKE_mesh_legacy_edge_crease_from_layers(mesh); /* When converting to the old mesh format, don't save redundant attributes. */ - names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly", "material_index"}); + names_to_skip.add_multiple_new({".hide_vert", + ".hide_edge", + ".hide_poly", + "material_index", + ".select_vert", + ".select_edge", + ".select_poly"}); /* Set deprecated mesh data pointers for forward compatibility. */ mesh->mvert = const_cast<MVert *>(mesh->verts().data()); @@ -689,7 +697,6 @@ static int customdata_compare( case CD_PROP_BOOL: { const bool *l1_data = (bool *)l1->data; const bool *l2_data = (bool *)l2->data; - for (int i = 0; i < total_length; i++) { if (l1_data[i] != l2_data[i]) { return MESHCMP_ATTRIBUTE_VALUE_MISMATCH; @@ -1638,39 +1645,46 @@ void BKE_mesh_mselect_clear(Mesh *me) void BKE_mesh_mselect_validate(Mesh *me) { + using namespace blender; + using namespace blender::bke; MSelect *mselect_src, *mselect_dst; int i_src, i_dst; if (me->totselect == 0) { return; } - const Span<MVert> verts = me->verts(); - const Span<MEdge> edges = me->edges(); - const Span<MPoly> polys = me->polys(); mselect_src = me->mselect; mselect_dst = (MSelect *)MEM_malloc_arrayN( (me->totselect), sizeof(MSelect), "Mesh selection history"); + const AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + const VArray<bool> select_edge = attributes.lookup_or_default<bool>( + ".select_edge", ATTR_DOMAIN_EDGE, false); + const VArray<bool> select_poly = attributes.lookup_or_default<bool>( + ".select_poly", ATTR_DOMAIN_FACE, false); + for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) { int index = mselect_src[i_src].index; switch (mselect_src[i_src].type) { case ME_VSEL: { - if (verts[index].flag & SELECT) { + if (select_vert[index]) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } break; } case ME_ESEL: { - if (edges[index].flag & SELECT) { + if (select_edge[index]) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } break; } case ME_FSEL: { - if (polys[index].flag & SELECT) { + if (select_poly[index]) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 3d6ecec44e1..be6c27ee6f9 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -375,14 +375,10 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, * `mv` is in `dest_mesh` with index `mv_index`. * The `orig_mv` vertex came from Mesh `orig_me` and had index `index_in_orig_me` there. */ static void copy_vert_attributes(Mesh *dest_mesh, - MVert *mv, - const MVert *orig_mv, const Mesh *orig_me, int mv_index, int index_in_orig_me) { - mv->flag = orig_mv->flag; - /* For all layers in the orig mesh, copy the layer information. */ CustomData *target_cd = &dest_mesh->vdata; const CustomData *source_cd = &orig_me->vdata; @@ -723,14 +719,14 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) MutableSpan<MVert> verts = result->verts_for_write(); for (int vi : im->vert_index_range()) { const Vert *v = im->vert(vi); - MVert *mv = &verts[vi]; - copy_v3fl_v3db(mv->co, v->co); if (v->orig != NO_INDEX) { const Mesh *orig_me; int index_in_orig_me; - const MVert *orig_mv = mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me); - copy_vert_attributes(result, mv, orig_mv, orig_me, vi, index_in_orig_me); + mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me); + copy_vert_attributes(result, orig_me, vi, index_in_orig_me); } + MVert *mv = &verts[vi]; + copy_v3fl_v3db(mv->co, v->co); } /* Set the loopstart and totloop for each output poly, diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index cc315130ad1..038133c33ae 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -13,6 +13,7 @@ #include "BLI_threads.h" #include "BLI_timeit.hh" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_mesh.h" @@ -120,8 +121,7 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh, } static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edge_maps, - MutableSpan<MEdge> new_edges, - short new_edge_flag) + MutableSpan<MEdge> new_edges) { /* All edges are distributed in the hash tables now. They have to be serialized into a single * array below. To be able to parallelize this, we have to compute edge index offsets for each @@ -147,7 +147,7 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edg /* Initialize new edge. */ new_edge.v1 = item.key.v_low; new_edge.v2 = item.key.v_high; - new_edge.flag = new_edge_flag; + new_edge.flag = ME_EDGEDRAW | ME_EDGERENDER; } item.value.index = new_edge_index; new_edge_index++; @@ -236,8 +236,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select /* Create new edges. */ MutableSpan<MEdge> new_edges{ static_cast<MEdge *>(MEM_calloc_arrayN(new_totedge, sizeof(MEdge), __func__)), new_totedge}; - const short new_edge_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select_new_edges ? SELECT : 0); - calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges, new_edge_flag); + calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, new_edges); calc_edges::update_edge_indices_in_poly_loops(mesh, edge_maps, parallel_mask); /* Free old CustomData and assign new one. */ @@ -246,6 +245,24 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge); mesh->totedge = new_totedge; + if (select_new_edges) { + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_span<bool>( + ".select_edge", ATTR_DOMAIN_EDGE); + if (select_edge) { + int new_edge_index = 0; + for (const EdgeMap &edge_map : edge_maps) { + for (EdgeMap::Item item : edge_map.items()) { + if (item.value.original_edge == nullptr) { + select_edge.span[new_edge_index] = true; + } + new_edge_index++; + } + } + select_edge.finish(); + } + } + /* Explicitly clear edge maps, because that way it can be parallelized. */ clear_hash_tables(edge_maps); } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 938d7e42aa3..4f8391263a1 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -818,103 +818,88 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) hide_edge.finish(); } -void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, - const int totvert, - const MLoop *mloop, - MEdge *medge, - const int totedge, - const MPoly *mpoly, - const int totpoly) +void BKE_mesh_flush_select_from_polys(Mesh *me) { - MVert *mv; - MEdge *med; - const MPoly *mp; - - int i = totvert; - for (mv = mvert; i--; mv++) { - mv->flag &= (char)~SELECT; + using namespace blender::bke; + MutableAttributeAccessor attributes = me->attributes_for_write(); + const VArray<bool> select_poly = attributes.lookup_or_default<bool>( + ".select_poly", ATTR_DOMAIN_FACE, false); + if (select_poly.is_single() && !select_poly.get_internal_single()) { + attributes.remove(".select_vert"); + attributes.remove(".select_edge"); + return; } + SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_edge", ATTR_DOMAIN_EDGE); - i = totedge; - for (med = medge; i--; med++) { - med->flag &= ~SELECT; - } + /* Use generic domain interpolation to read the polygon attribute on the other domains. + * Assume selected faces are not hidden and none of their vertices/edges are hidden. */ + attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_POINT, false) + .materialize(select_vert.span); + attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_EDGE, false) + .materialize(select_edge.span); - i = totpoly; - for (mp = mpoly; i--; mp++) { - /* Assume if its selected its not hidden and none of its verts/edges are hidden - * (a common assumption). */ - if (mp->flag & ME_FACE_SEL) { - const MLoop *ml; - int j; - j = mp->totloop; - for (ml = &mloop[mp->loopstart]; j--; ml++) { - mvert[ml->v].flag |= SELECT; - medge[ml->e].flag |= SELECT; - } - } - } -} -void BKE_mesh_flush_select_from_polys(Mesh *me) -{ - BKE_mesh_flush_select_from_polys_ex(me->verts_for_write().data(), - me->totvert, - me->loops().data(), - me->edges_for_write().data(), - me->totedge, - me->polys().data(), - me->totpoly); + select_vert.finish(); + select_edge.finish(); } -static void mesh_flush_select_from_verts(const Span<MVert> verts, +static void mesh_flush_select_from_verts(const Span<MEdge> edges, + const Span<MPoly> polys, const Span<MLoop> loops, const VArray<bool> &hide_edge, const VArray<bool> &hide_poly, - MutableSpan<MEdge> edges, - MutableSpan<MPoly> polys) + const VArray<bool> &select_vert, + MutableSpan<bool> select_edge, + MutableSpan<bool> select_poly) { + /* Select visible edges that have both of their vertices selected. */ for (const int i : edges.index_range()) { if (!hide_edge[i]) { - MEdge &edge = edges[i]; - if ((verts[edge.v1].flag & SELECT) && (verts[edge.v2].flag & SELECT)) { - edge.flag |= SELECT; - } - else { - edge.flag &= ~SELECT; - } + const MEdge &edge = edges[i]; + select_edge[i] = select_vert[edge.v1] && select_vert[edge.v2]; } } + /* Select visible faces that have all of their vertices selected. */ for (const int i : polys.index_range()) { - if (hide_poly[i]) { - continue; - } - MPoly &poly = polys[i]; - bool all_verts_selected = true; - for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - if (!(verts[loop.v].flag & SELECT)) { - all_verts_selected = false; - } - } - if (all_verts_selected) { - poly.flag |= ME_FACE_SEL; - } - else { - poly.flag &= (char)~ME_FACE_SEL; + if (!hide_poly[i]) { + const MPoly &poly = polys[i]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + select_poly[i] = std::all_of(poly_loops.begin(), poly_loops.end(), [&](const MLoop &loop) { + return select_vert[loop.v]; + }); } } } void BKE_mesh_flush_select_from_verts(Mesh *me) { - const blender::bke::AttributeAccessor attributes = me->attributes(); + using namespace blender::bke; + MutableAttributeAccessor attributes = me->attributes_for_write(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + if (select_vert.is_single() && !select_vert.get_internal_single()) { + attributes.remove(".select_edge"); + attributes.remove(".select_poly"); + return; + } + SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_edge", ATTR_DOMAIN_EDGE); + SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_poly", ATTR_DOMAIN_FACE); mesh_flush_select_from_verts( - me->verts(), + me->edges(), + me->polys(), me->loops(), attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false), attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false), - me->edges_for_write(), - me->polys_for_write()); + select_vert, + select_edge.span, + select_poly.span); + select_edge.finish(); + select_poly.finish(); } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 09982f15afa..506501ead2a 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -13,6 +13,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" #include "BLI_edgehash.h" #include "BLI_math.h" @@ -1058,7 +1059,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) ".hide_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - SET_FLAG_FROM_TEST(verts[i].flag, hide_vert[i], ME_HIDE); + SET_FLAG_FROM_TEST(verts[i].flag_legacy, hide_vert[i], ME_HIDE); } }); @@ -1088,13 +1089,14 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) MutableAttributeAccessor attributes = mesh->attributes_for_write(); const Span<MVert> verts = mesh->verts(); - if (std::any_of( - verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) { + if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { + return vert.flag_legacy & ME_HIDE; + })) { SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>( ".hide_vert", ATTR_DOMAIN_POINT); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - hide_vert.span[i] = verts[i].flag & ME_HIDE; + hide_vert.span[i] = verts[i].flag_legacy & ME_HIDE; } }); hide_vert.finish(); @@ -1128,6 +1130,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) } /** \} */ + /* -------------------------------------------------------------------- */ /** \name Material Index Conversion * \{ */ @@ -1167,3 +1170,90 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Selection Attribute and Legacy Flag Conversion + * \{ */ + +void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + const AttributeAccessor attributes = mesh->attributes(); + + MutableSpan<MVert> verts = mesh->verts_for_write(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + SET_FLAG_FROM_TEST(verts[i].flag_legacy, select_vert[i], SELECT); + } + }); + + MutableSpan<MEdge> edges = mesh->edges_for_write(); + const VArray<bool> select_edge = attributes.lookup_or_default<bool>( + ".select_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, select_edge[i], SELECT); + } + }); + + MutableSpan<MPoly> polys = mesh->polys_for_write(); + const VArray<bool> select_poly = attributes.lookup_or_default<bool>( + ".select_poly", ATTR_DOMAIN_FACE, false); + threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + SET_FLAG_FROM_TEST(polys[i].flag, select_poly[i], ME_FACE_SEL); + } + }); +} + +void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + + const Span<MVert> verts = mesh->verts(); + if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { + return vert.flag_legacy & SELECT; + })) { + SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + select_vert.span[i] = (verts[i].flag_legacy & SELECT) != 0; + } + }); + select_vert.finish(); + } + + const Span<MEdge> edges = mesh->edges(); + if (std::any_of( + edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & SELECT; })) { + SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_edge", ATTR_DOMAIN_EDGE); + threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + select_edge.span[i] = (edges[i].flag & SELECT) != 0; + } + }); + select_edge.finish(); + } + + const Span<MPoly> polys = mesh->polys(); + if (std::any_of( + polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_FACE_SEL; })) { + SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_only_span<bool>( + ".select_poly", ATTR_DOMAIN_FACE); + threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + select_poly.span[i] = (polys[i].flag & ME_FACE_SEL) != 0; + } + }); + select_poly.finish(); + } +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index db091361223..b612564ef09 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -31,6 +31,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 bool *select_poly, const MLoop *mloop, const MLoopUV *mloopuv, uint totpoly, @@ -53,7 +54,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 || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) { + if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) { totuv += mp->totloop; } } @@ -76,7 +77,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, mp = mpoly; for (a = 0; a < totpoly; a++, mp++) { - if (!selected || (!(hide_poly && hide_poly[a]) && (mp->flag & ME_FACE_SEL))) { + if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) { float(*tf_uv)[2] = NULL; if (use_winding) { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 1fe5d7aa0e7..a72d68710ed 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -163,14 +163,14 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele } else { if (BKE_mesh_deform_verts(me)) { - const MVert *mv; + const bool *select_vert = (const bool *)CustomData_get_layer_named( + &me->vdata, CD_PROP_BOOL, ".select_vert"); int i; - mv = BKE_mesh_verts(me); dv = BKE_mesh_deform_verts_for_write(me); - for (i = 0; i < me->totvert; i++, mv++, dv++) { - if (dv->dw && (!use_selection || (mv->flag & SELECT))) { + for (i = 0; i < me->totvert; i++, dv++) { + if (dv->dw && (!use_selection || (select_vert && select_vert[i]))) { MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr); BKE_defvert_remove_group(dv, dw); /* dw can be NULL */ changed = true; diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 369e7f7060a..aabed2cea28 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -212,6 +212,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( storage->polys, (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"), + (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".select_poly"), storage->loops, mloopuv, num_poly, diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index 04389b43fd9..6bc188fd1fc 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -1137,8 +1137,6 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach is_simple, u, subdiv_vertex->co); - /* Reset flags and such. */ - subdiv_vertex->flag = 0; } /** \} */ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 98d4ee6e8c2..c95c43a8099 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -285,7 +285,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, * 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, NULL, mloop, mloopuv, totface, totvert, limit, false, true); + mpoly, NULL, NULL, mloop, mloopuv, totface, totvert, limit, false, true); if (!vmap) { return 0; } @@ -880,7 +880,6 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3]) BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem) { copy_v3_v3(mv->co, CCG_elem_co(key, elem)); - mv->flag = 0; } static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) |