static int main_relations_create_idlink_cb(void *user_data, ID *id_self, ID **id_pointer, int cb_flag) { MainIDRelations *rel = user_data; if (*id_pointer) { MainIDRelationsEntry *entry, **entry_p; entry = BLI_mempool_alloc(rel->entry_pool); if (BLI_ghash_ensure_p(rel->id_user_to_used, id_self, (void ***)&entry_p)) { entry->next = *entry_p; } else { entry->next = NULL; } entry->id_pointer = id_pointer; entry->usage_flag = cb_flag; *entry_p = entry; entry = BLI_mempool_alloc(rel->entry_pool); if (BLI_ghash_ensure_p(rel->id_used_to_user, *id_pointer, (void ***)&entry_p)) { entry->next = *entry_p; } else { entry->next = NULL; } entry->id_pointer = (ID **)id_self; entry->usage_flag = cb_flag; *entry_p = entry; } return IDWALK_RET_NOP; }
static bool ghash_insert_link( GHash *gh, void *key, void *val, bool use_test, MemArena *mem_arena) { void **ls_base_p; struct LinkBase *ls_base; LinkNode *ls; if (!BLI_ghash_ensure_p(gh, key, &ls_base_p)) { ls_base = *ls_base_p = BLI_memarena_alloc(mem_arena, sizeof(*ls_base)); ls_base->list = NULL; ls_base->list_len = 0; } else { ls_base = *ls_base_p; if (use_test && (BLI_linklist_index(ls_base->list, val) != -1)) { return false; } } ls = BLI_memarena_alloc(mem_arena, sizeof(*ls)); ls->next = ls_base->list; ls->link = val; ls_base->list = ls; ls_base->list_len += 1; return true; }
void BKE_outliner_treehash_add_element(void *treehash, TreeStoreElem *elem) { TseGroup *group; void **val_p; if (!BLI_ghash_ensure_p(treehash, elem, &val_p)) { *val_p = tse_group_create(); } group = *val_p; tse_group_add(group, elem); }
void BKE_icon_set(int icon_id, struct Icon *icon) { void **val_p; if (BLI_ghash_ensure_p(gIcons, SET_INT_IN_POINTER(icon_id), &val_p)) { printf("%s: Internal error, icon already set: %d\n", __func__, icon_id); return; } *val_p = icon; }
static short layer_collection_sync(ViewLayer *view_layer, const ListBase *lb_scene, ListBase *lb_layer, ListBase *new_object_bases, short parent_exclude, short parent_restrict, short parent_layer_restrict) { /* TODO: support recovery after removal of intermediate collections, reordering, .. * For local edits we can make editing operating do the appropriate thing, but for * linking we can only sync after the fact. */ /* Remove layer collections that no longer have a corresponding scene collection. */ for (LayerCollection *lc = lb_layer->first; lc;) { /* Note ID remap can set lc->collection to NULL when deleting collections. */ LayerCollection *lc_next = lc->next; Collection *collection = (lc->collection) ? BLI_findptr(lb_scene, lc->collection, offsetof(CollectionChild, collection)) : NULL; if (!collection) { if (lc == view_layer->active_collection) { view_layer->active_collection = NULL; } /* Free recursively. */ layer_collection_free(view_layer, lc); BLI_freelinkN(lb_layer, lc); } lc = lc_next; } /* Add layer collections for any new scene collections, and ensure order is the same. */ ListBase new_lb_layer = {NULL, NULL}; short runtime_flag = 0; for (const CollectionChild *child = lb_scene->first; child; child = child->next) { Collection *collection = child->collection; LayerCollection *lc = BLI_findptr(lb_layer, collection, offsetof(LayerCollection, collection)); if (lc) { BLI_remlink(lb_layer, lc); BLI_addtail(&new_lb_layer, lc); } else { lc = layer_collection_add(&new_lb_layer, collection); lc->flag = parent_exclude; } /* Collection restrict is inherited. */ short child_restrict = parent_restrict; short child_layer_restrict = parent_layer_restrict; if (!(collection->flag & COLLECTION_IS_MASTER)) { child_restrict |= collection->flag; child_layer_restrict |= lc->flag; } /* Sync child collections. */ short child_runtime_flag = layer_collection_sync(view_layer, &collection->children, &lc->layer_collections, new_object_bases, lc->flag, child_restrict, child_layer_restrict); /* Layer collection exclude is not inherited. */ if (lc->flag & LAYER_COLLECTION_EXCLUDE) { lc->runtime_flag = 0; continue; } else { lc->runtime_flag = child_runtime_flag; } if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) && ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) { lc->runtime_flag |= LAYER_COLLECTION_VISIBLE; } /* Sync objects, except if collection was excluded. */ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { if (cob->ob == NULL) { continue; } void **base_p; Base *base; if (BLI_ghash_ensure_p(view_layer->object_bases_hash, cob->ob, &base_p)) { /* Move from old base list to new base list. Base might have already * been moved to the new base list and the first/last test ensure that * case also works. */ base = *base_p; if (!ELEM(base, new_object_bases->first, new_object_bases->last)) { BLI_remlink(&view_layer->object_bases, base); BLI_addtail(new_object_bases, base); } } else { /* Create new base. */ base = object_base_new(cob->ob); *base_p = base; BLI_addtail(new_object_bases, base); } if ((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) { base->flag_from_collection |= BASE_ENABLED_VIEWPORT; if ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0) { base->flag_from_collection |= BASE_VISIBLE; if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) { base->flag_from_collection |= BASE_SELECTABLE; } } } if ((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) { base->flag_from_collection |= BASE_ENABLED_RENDER; } /* Holdout and indirect only */ if (lc->flag & LAYER_COLLECTION_HOLDOUT) { base->flag_from_collection |= BASE_HOLDOUT; } if (lc->flag & LAYER_COLLECTION_INDIRECT_ONLY) { base->flag_from_collection |= BASE_INDIRECT_ONLY; } lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS; /* Make sure flags on base are usable right away. */ BKE_base_eval_flags(base); } runtime_flag |= lc->runtime_flag; } /* Replace layer collection list with new one. */ *lb_layer = new_lb_layer; BLI_assert(BLI_listbase_count(lb_scene) == BLI_listbase_count(lb_layer)); return runtime_flag; }
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData *) md; int i, j, k; int numFaces_dst, numEdges_dst, numLoops_dst = 0; int *vertMap, *edgeMap, *faceMap; float frac; MPoly *mpoly_dst; MLoop *ml_dst, *ml_src /*, *mloop_dst */; GHashIterator gh_iter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_int_new("build ve apply gh"); /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_int_new("build ed apply gh"); GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh"); const int numVert_src = dm->getNumVerts(dm); const int numEdge_src = dm->getNumEdges(dm); const int numPoly_src = dm->getNumPolys(dm); MPoly *mpoly_src = dm->getPolyArray(dm); MLoop *mloop_src = dm->getLoopArray(dm); MEdge *medge_src = dm->getEdgeArray(dm); MVert *mvert_src = dm->getVertArray(dm); vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap"); edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap"); faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap"); range_vn_i(vertMap, numVert_src, 0); range_vn_i(edgeMap, numEdge_src, 0); range_vn_i(faceMap, numPoly_src, 0); frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); if (bmd->flag & MOD_BUILD_FLAG_REVERSE) { frac = 1.0f - frac; } numFaces_dst = numPoly_src * frac; numEdges_dst = numEdge_src * frac; /* if there's at least one face, build based on faces */ if (numFaces_dst) { MPoly *mpoly, *mp; MLoop *ml, *mloop; MEdge *medge; uintptr_t hash_num, hash_num_alt; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { BLI_array_randomize(faceMap, sizeof(*faceMap), numPoly_src, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ mpoly = mpoly_src; mloop = mloop_src; hash_num = 0; for (i = 0; i < numFaces_dst; i++) { mp = mpoly + faceMap[i]; ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { void **val_p; if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(ml->v), &val_p)) { *val_p = (void *)hash_num; hash_num++; } } numLoops_dst += mp->totloop; } BLI_assert(hash_num == BLI_ghash_len(vertHash)); /* get the set of edges that will be in the new mesh (i.e. all edges * that have both verts in the new mesh) */ medge = medge_src; hash_num = 0; hash_num_alt = 0; for (i = 0; i < numEdge_src; i++, hash_num_alt++) { MEdge *me = medge + i; if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) { BLI_ghash_insert(edgeHash, (void *)hash_num, (void *)hash_num_alt); BLI_ghash_insert(edgeHash2, (void *)hash_num_alt, (void *)hash_num); hash_num++; } } } else if (numEdges_dst) { MEdge *medge, *me; uintptr_t hash_num; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) BLI_array_randomize(edgeMap, sizeof(*edgeMap), numEdge_src, bmd->seed); /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ medge = medge_src; hash_num = 0; BLI_assert(hash_num == BLI_ghash_len(vertHash)); for (i = 0; i < numEdges_dst; i++) { void **val_p; me = medge + edgeMap[i]; if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(me->v1), &val_p)) { *val_p = (void *)hash_num; hash_num++; } if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(me->v2), &val_p)) { *val_p = (void *)hash_num; hash_num++; } } BLI_assert(hash_num == BLI_ghash_len(vertHash)); /* get the set of edges that will be in the new mesh */ for (i = 0; i < numEdges_dst; i++) { j = BLI_ghash_len(edgeHash); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(edgeMap[i])); BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(edgeMap[i]), SET_INT_IN_POINTER(j)); } } else { int numVerts = numVert_src * frac; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { BLI_array_randomize(vertMap, sizeof(*vertMap), numVert_src, bmd->seed); } /* get the set of all vert indices that will be in the final mesh, * mapped to the new indices */ for (i = 0; i < numVerts; i++) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i)); } } /* now we know the number of verts, edges and faces, we can create * the mesh */ result = CDDM_from_template(dm, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); source = mvert_src[oldIndex]; dest = CDDM_get_vert(result, newIndex); DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; }