42 const bool keep_existing_edges,
47 edge_maps, [&](
EdgeMap &edge_map) { edge_map.
reserve(totedge_guess / edge_maps.
size()); });
57 const int task_index = &edge_map - edge_maps.
data();
58 for (
const int2 edge : edges) {
61 if (task_index == (parallel_mask &
edge_hash_2(ordered_edge))) {
62 edge_map.
add(ordered_edge);
75 const int task_index = &edge_map - edge_maps.
data();
76 for (
const int face_i :
faces.index_range()) {
78 for (
const int corner : face) {
79 const int vert = corner_verts[corner];
82 if (
LIKELY(vert_prev != vert)) {
85 if (task_index == (parallel_mask &
edge_hash_2(ordered_edge))) {
86 edge_map.
add(ordered_edge);
99 const int task_index = &edge_map - edge_maps.
data();
100 if (edge_offsets[task_index].is_empty()) {
117 for (const int face_index : range) {
118 const IndexRange face = faces[face_index];
119 for (const int corner : face) {
120 const int vert = corner_verts[corner];
121 const int vert_prev = corner_verts[bke::mesh::face_corner_next(face, corner)];
122 if (UNLIKELY(vert == vert_prev)) {
126 corner_edges[corner] = 0;
130 const OrderedEdge ordered_edge(vert_prev, vert);
131 const int task_index = parallel_mask & edge_hash_2(ordered_edge);
132 const EdgeMap &edge_map = edge_maps[task_index];
133 const int edge_i = edge_map.index_of(ordered_edge);
134 const int edge_index = edge_offsets[task_index][edge_i];
135 corner_edges[corner] = edge_index;
165 for (const int2 original_edge : known_edges.slice(range)) {
166 const OrderedEdge ordered_edge(original_edge);
167 const int task_index = parallel_mask & edge_hash_2(ordered_edge);
168 const EdgeMap &edge_map = edge_maps[task_index];
169 const int edge_i = edge_map.index_of(ordered_edge);
170 const int edge_index = edge_offsets[task_index][edge_i];
171 selection[edge_index] = false;
182 const int parallel_maps = calc_edges::get_parallel_maps_count(
mesh);
186 calc_edges::reserve_hash_maps(
mesh, keep_existing_edges, edge_maps);
189 if (keep_existing_edges) {
190 calc_edges::add_existing_edges_to_hash_maps(
mesh, parallel_mask, edge_maps);
192 calc_edges::add_face_edges_to_hash_maps(
mesh, parallel_mask, edge_maps);
196 edge_sizes[i] = edge_maps[i].
size();
198 const OffsetIndices<int> edge_offsets = offset_indices::accumulate_counts_to_offsets(edge_sizes);
205 calc_edges::serialize_and_initialize_deduplicated_edges(edge_maps, edge_offsets, new_edges);
206 calc_edges::update_edge_indices_in_face_loops(
mesh.faces(),
211 mesh.corner_edges_for_write());
214 if (keep_existing_edges && select_new_edges) {
225 if (select_new_edges) {
228 ".select_edge", AttrDomain::Edge);
230 select_edge.
span.fill(
true);
232 calc_edges::deselect_known_edges(
233 edge_offsets, edge_maps, parallel_mask, original_edges, select_edge.
span);
239 if (!keep_existing_edges) {
241 mesh.tag_loose_edges_none();
245 calc_edges::clear_hash_tables(edge_maps);
CustomData interface, see also DNA_customdata_types.h.
void CustomData_reset(CustomData *data)
void CustomData_free(CustomData *data)
MINLINE int power_of_2_min_i(int n)
MINLINE int is_power_of_2_i(int n)
int BLI_system_thread_count(void)
MutableSpan< T > as_mutable_span()
IndexRange index_range() const
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr T * data() const
constexpr void copy_from(Span< T > values) const
constexpr IndexRange index_range() const
void reserve(const int64_t n)
Span< Key > as_span() const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
static void add_existing_edges_to_hash_maps(const Mesh &mesh, const uint32_t parallel_mask, MutableSpan< EdgeMap > edge_maps)
static uint64_t edge_hash_2(const OrderedEdge &edge)
static void update_edge_indices_in_face_loops(const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< EdgeMap > edge_maps, const uint32_t parallel_mask, const OffsetIndices< int > edge_offsets, MutableSpan< int > corner_edges)
static void serialize_and_initialize_deduplicated_edges(MutableSpan< EdgeMap > edge_maps, const OffsetIndices< int > edge_offsets, MutableSpan< int2 > new_edges)
static int get_parallel_maps_count(const Mesh &mesh)
static void deselect_known_edges(const OffsetIndices< int > edge_offsets, const Span< EdgeMap > edge_maps, const uint32_t parallel_mask, const Span< int2 > known_edges, MutableSpan< bool > selection)
static void clear_hash_tables(MutableSpan< EdgeMap > edge_maps)
static void reserve_hash_maps(const Mesh &mesh, const bool keep_existing_edges, MutableSpan< EdgeMap > edge_maps)
static void add_face_edges_to_hash_maps(const Mesh &mesh, const uint32_t parallel_mask, MutableSpan< EdgeMap > edge_maps)
int face_corner_prev(const IndexRange face, const int corner)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
void parallel_for_each(Range &&range, const Function &function)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
PythonProbingStrategy<> DefaultProbingStrategy
unsigned __int64 uint64_t
MutableVArraySpan< T > span