/** * Adds the key to the set (no checks for unique keys!). * Matching #BLI_edgehash_insert */ void BLI_edgeset_insert(EdgeSet *es, unsigned int v0, unsigned int v1) { unsigned int hash; EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash((EdgeHash *)es, v0, v1); edgehash_insert_ex_keyonly((EdgeHash *)es, v0, v1, hash); }
BLI_INLINE void edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val) { unsigned int hash; EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash(eh, v0, v1); edgehash_insert_ex(eh, v0, v1, val, hash); }
/** * Internal lookup function. Only wraps #edgehash_lookup_entry_ex */ BLI_INLINE EdgeEntry *edgehash_lookup_entry(EdgeHash *eh, unsigned int v0, unsigned int v1) { unsigned int hash; EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash(eh, v0, v1); return edgehash_lookup_entry_ex(eh, v0, v1, hash); }
static void erot_state_ex(const BMEdge *e, int v_index[2], int f_index[2]) { BLI_assert(BM_edge_is_manifold(e)); BLI_assert(BM_vert_in_edge(e, e->l->prev->v) == false); BLI_assert(BM_vert_in_edge(e, e->l->radial_next->prev->v) == false); /* verts of the edge */ v_index[0] = BM_elem_index_get(e->v1); v_index[1] = BM_elem_index_get(e->v2); EDGE_ORD(v_index[0], v_index[1]); /* verts of each of the 2 faces attached to this edge * (that are not apart of this edge) */ f_index[0] = BM_elem_index_get(e->l->prev->v); f_index[1] = BM_elem_index_get(e->l->radial_next->prev->v); EDGE_ORD(f_index[0], f_index[1]); }
/** * Remove \a key (v0, v1) from \a eh, or return false if the key wasn't found. * * \param v0, v1: The key to remove. * \param valfreefp: Optional callback to free the value. * \return true if \a key was removed from \a eh. */ bool BLI_edgehash_remove(EdgeHash *eh, uint v0, uint v1, EdgeHashFreeFP valfreefp) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_remove_ex(eh, v0, v1, valfreefp, bucket_index); if (e) { BLI_mempool_free(eh->epool, e); return true; } else { return false; } }
/** * A version of BLI_edgeset_insert which checks first if the key is in the set. * \returns true if a new key has been added. * * \note EdgeHash has no equivalent to this because typically the value would be different. */ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index((EdgeHash *)es, v0, v1); EdgeEntry *e = edgehash_lookup_entry_ex((EdgeHash *)es, v0, v1, bucket_index); if (e) { return false; } else { edgehash_insert_ex_keyonly((EdgeHash *)es, v0, v1, bucket_index); return true; } }
/** * Remove \a key (v0, v1) from \a eh, returning the value or NULL if the key wasn't found. * * \param v0, v1: The key to remove. * \return the value of \a key int \a eh or NULL. */ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_remove_ex(eh, v0, v1, NULL, bucket_index); IS_EDGEHASH_ASSERT(eh); if (e) { void *val = e->val; BLI_mempool_free(eh->epool, e); return val; } else { return NULL; } }
/** * Ensure \a (v0, v1) is exists in \a eh. * * This handles the common situation where the caller needs ensure a key is added to \a eh, * constructing a new value in the case the key isn't found. * Otherwise use the existing value. * * Such situations typically incur multiple lookups, however this function * avoids them by ensuring the key is added, * returning a pointer to the value so it can be used or initialized by the caller. * * \returns true when the value didn't need to be added. * (when false, the caller _must_ initialize the value). */ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_val) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_lookup_entry_ex(eh, v0, v1, bucket_index); const bool haskey = (e != NULL); if (!haskey) { e = BLI_mempool_alloc(eh->epool); edgehash_insert_ex_keyonly_entry(eh, v0, v1, bucket_index, e); } *r_val = &e->val; return haskey; }
/** * Assign a new value to a key that may already be in edgehash. */ bool BLI_edgeset_reinsert(EdgeSet *es, unsigned int v0, unsigned int v1) { unsigned int hash; EdgeEntry *e; EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash((EdgeHash *)es, v0, v1); e = edgehash_lookup_entry_ex((EdgeHash *)es, v0, v1, hash); if (e) { return false; } else { edgehash_insert_ex_keyonly((EdgeHash *)es, v0, v1, hash); return true; } }
/** * Assign a new value to a key that may already be in edgehash. */ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *val) { IS_EDGEHASH_ASSERT(eh); EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_lookup_entry_ex(eh, v0, v1, bucket_index); if (e) { e->val = val; return false; } else { edgehash_insert_ex(eh, v0, v1, val, bucket_index); return true; } }
/** * Assign a new value to a key that may already be in edgehash. */ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val) { unsigned int hash; EdgeEntry *e; IS_EDGEHASH_ASSERT(eh); EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash(eh, v0, v1); e = edgehash_lookup_entry_ex(eh, v0, v1, hash); if (e) { e->val = val; return false; } else { edgehash_insert_ex(eh, v0, v1, val, hash); return true; } }
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val) { unsigned int hash; EdgeEntry *e = BLI_mempool_alloc(eh->epool); /* this helps to track down errors with bad edge data */ BLI_assert(v0 != v1); EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = EDGE_HASH(v0, v1) % eh->nbuckets; e->v0 = v0; e->v1 = v1; e->val = val; e->next = eh->buckets[hash]; eh->buckets[hash] = e; if (++eh->nentries > eh->nbuckets * 3) { EdgeEntry **old = eh->buckets; int i, nold = eh->nbuckets; eh->nbuckets = _ehash_hashsizes[++eh->cursize]; eh->buckets = MEM_mallocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets"); memset(eh->buckets, 0, eh->nbuckets * sizeof(*eh->buckets)); for (i = 0; i < nold; i++) { for (e = old[i]; e; ) { EdgeEntry *n = e->next; hash = EDGE_HASH(e->v0, e->v1) % eh->nbuckets; e->next = eh->buckets[hash]; eh->buckets[hash] = e; e = n; } } MEM_freeN(old); } }
/** * Adds the key to the set (no checks for unique keys!). * Matching #BLI_edgehash_insert */ void BLI_edgeset_insert(EdgeSet *es, uint v0, uint v1) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index((EdgeHash *)es, v0, v1); edgehash_insert_ex_keyonly((EdgeHash *)es, v0, v1, bucket_index); }
BLI_INLINE void edgehash_insert(EdgeHash *eh, uint v0, uint v1, void *val) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); edgehash_insert_ex(eh, v0, v1, val, bucket_index); }
/** * Internal lookup function. Only wraps #edgehash_lookup_entry_ex */ BLI_INLINE EdgeEntry *edgehash_lookup_entry(EdgeHash *eh, uint v0, uint v1) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); return edgehash_lookup_entry_ex(eh, v0, v1, bucket_index); }