diff options
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_calc_edges.cc')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_calc_edges.cc | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index 31e20750cf2..5e6babdf7b4 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" @@ -34,8 +35,7 @@ struct OrderedEdge { } } - OrderedEdge(const uint v1, const uint v2) - : OrderedEdge(static_cast<int>(v1), static_cast<int>(v2)) + OrderedEdge(const uint v1, const uint v2) : OrderedEdge(int(v1), int(v2)) { } @@ -80,9 +80,10 @@ static void add_existing_edges_to_hash_maps(Mesh *mesh, uint32_t parallel_mask) { /* Assume existing edges are valid. */ + const Span<MEdge> edges = mesh->edges(); threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) { const int task_index = &edge_map - edge_maps.data(); - for (const MEdge &edge : Span(mesh->medge, mesh->totedge)) { + for (const MEdge &edge : edges) { OrderedEdge ordered_edge{edge.v1, edge.v2}; /* Only add the edge when it belongs into this map. */ if (task_index == (parallel_mask & ordered_edge.hash2())) { @@ -96,10 +97,11 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh, MutableSpan<EdgeMap> edge_maps, uint32_t parallel_mask) { - const Span<MLoop> loops{mesh->mloop, mesh->totloop}; + const Span<MPoly> polys = mesh->polys(); + const Span<MLoop> loops = mesh->loops(); threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) { const int task_index = &edge_map - edge_maps.data(); - for (const MPoly &poly : Span(mesh->mpoly, mesh->totpoly)) { + for (const MPoly &poly : polys) { Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); const MLoop *prev_loop = &poly_loops.last(); for (const MLoop &next_loop : poly_loops) { @@ -118,8 +120,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 @@ -145,7 +146,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++; @@ -157,10 +158,11 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh, Span<EdgeMap> edge_maps, uint32_t parallel_mask) { - const MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; + const Span<MPoly> polys = mesh->polys(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) { for (const int poly_index : range) { - MPoly &poly = mesh->mpoly[poly_index]; + const MPoly &poly = polys[poly_index]; MutableSpan<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); MLoop *prev_loop = &poly_loops.last(); @@ -214,7 +216,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select * Each edge is assigned to one of the hash maps based on the lower bits of a hash value. */ const int parallel_maps = get_parallel_maps_count(mesh); BLI_assert(is_power_of_2_i(parallel_maps)); - const uint32_t parallel_mask = static_cast<uint32_t>(parallel_maps) - 1; + const uint32_t parallel_mask = uint32_t(parallel_maps) - 1; Array<EdgeMap> edge_maps(parallel_maps); reserve_hash_maps(mesh, keep_existing_edges, edge_maps); @@ -233,8 +235,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. */ @@ -242,7 +243,24 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select CustomData_reset(&mesh->edata); CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge); mesh->totedge = new_totedge; - mesh->medge = new_edges.data(); + + 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); |