bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot) { bDeformGroup *dg; ModifierData *md; bool *vgroup_validmap; GHash *gh; int i, step1 = 1; //int defbase_tot = BLI_countlist(&ob->defbase); if (ob->defbase.first == NULL) { return NULL; } gh = BLI_ghash_str_new("BKE_objdef_validmap_get gh"); /* add all names to a hash table */ for (dg = ob->defbase.first; dg; dg = dg->next) { BLI_ghash_insert(gh, dg->name, NULL); } BLI_assert(BLI_ghash_size(gh) == defbase_tot); /* now loop through the armature modifiers and identify deform bones */ for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob) : md->next) { if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual))) continue; if (md->type == eModifierType_Armature) { ArmatureModifierData *amd = (ArmatureModifierData *) md; if (amd->object && amd->object->pose) { bPose *pose = amd->object->pose; bPoseChannel *chan; for (chan = pose->chanbase.first; chan; chan = chan->next) { if (chan->bone->flag & BONE_NO_DEFORM) continue; if (BLI_ghash_remove(gh, chan->name, NULL, NULL)) { BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1)); } } } } } vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map"); /* add all names to a hash table */ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); } BLI_assert(i == BLI_ghash_size(gh)); BLI_ghash_free(gh, NULL, NULL); return vgroup_validmap; }
void BKE_sim_debug_data_free(void) { if (_sim_debug_data) { if (_sim_debug_data->gh) BLI_ghash_free(_sim_debug_data->gh, NULL, debug_element_free); MEM_freeN(_sim_debug_data); } }
/*does not free the BMEditMesh struct itself*/ void BKE_editmesh_free(BMEditMesh *em) { BKE_editmesh_free_derivedmesh(em); BKE_editmesh_color_free(em); if (em->looptris) MEM_freeN(em->looptris); /* free preselection item lists */ if (em->presel_verts) BLI_ghash_free(em->presel_verts, NULL, NULL); if (em->presel_edges) BLI_ghash_free(em->presel_edges, NULL, NULL); if (em->presel_faces) BLI_ghash_free(em->presel_faces, NULL, NULL); if (em->prop3d_faces) BLI_ghash_free(em->prop3d_faces, NULL, NULL); if (em->prop2d_faces) BLI_ghash_free(em->prop2d_faces, NULL, NULL); if (em->bm) BM_mesh_free(em->bm); }
void seq_stripelem_cache_destruct(void) { if (!entrypool) { return; } BLI_ghash_free(hash, HashKeyFree, HashValFree); delete_MEM_CacheLimiter(limitor); BLI_mempool_destroy(entrypool); BLI_mempool_destroy(keypool); }
DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select, int int_op_type) { struct CarveMeshDescr *left, *right, *output = NULL; DerivedMesh *output_dm = NULL; int operation; bool result; DMArrays dm_left_arrays, dm_right_arrays; if (dm == NULL || dm_select == NULL) { return NULL; } operation = operation_from_optype(int_op_type); if (operation == -1) { return NULL; } dm_arrays_get(dm_select, &dm_left_arrays); dm_arrays_get(dm, &dm_right_arrays); left = carve_mesh_from_dm(ob_select, dm_select, &dm_left_arrays); right = carve_mesh_from_dm(ob, dm, &dm_right_arrays); result = carve_performBooleanOperation(left, right, operation, &output); carve_deleteMesh(left); carve_deleteMesh(right); if (result) { ExportMeshData export_data; prepare_export_data(ob_select, dm_select, &dm_left_arrays, ob, dm, &dm_right_arrays, &export_data); carve_exportMesh(output, &MeshExporter, &export_data); output_dm = export_data.dm; /* Free memory used by export mesh. */ BLI_ghash_free(export_data.material_hash, NULL, NULL); output_dm->cd_flag |= dm->cd_flag | dm_select->cd_flag; output_dm->dirty |= DM_DIRTY_NORMALS; carve_deleteMesh(output); } dm_arrays_free(&dm_left_arrays); dm_arrays_free(&dm_right_arrays); return output_dm; }
void free_sss(Render *re) { if (re->sss_hash) { GHashIterator *it= BLI_ghashIterator_new(re->sss_hash); while (!BLI_ghashIterator_done(it)) { sss_free_tree(BLI_ghashIterator_getValue(it)); BLI_ghashIterator_step(it); } BLI_ghashIterator_free(it); BLI_ghash_free(re->sss_hash, NULL, NULL); re->sss_hash= NULL; } }
void WM_uilisttype_free(void) { GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash); for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) { uiListType *ult = BLI_ghashIterator_getValue(iter); if (ult->ext.free) { ult->ext.free(ult->ext.data); } } BLI_ghashIterator_free(iter); BLI_ghash_free(uilisttypes_hash, NULL, MEM_freeN); uilisttypes_hash = NULL; }
static void text_autocomplete_free(bContext *C, wmOperator *op) { GHash *gh = op->customdata; if (gh) { BLI_ghash_free(gh, NULL, MEM_freeN); op->customdata = NULL; } /* other stuff */ { SpaceText *st = CTX_wm_space_text(C); st->doplugins = false; texttool_text_clear(); } }
void WM_menutype_free(void) { GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash); for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { MenuType *mt= BLI_ghashIterator_getValue(iter); if(mt->ext.free) { mt->ext.free(mt->ext.data); } } BLI_ghashIterator_free(iter); BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN); menutypes_hash= NULL; }
void seq_stripelem_cache_cleanup(void) { if (!entrypool) { seq_stripelem_cache_init(); } /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n", ibufs_in, ibufs_rem); */ BLI_ghash_free(hash, HashKeyFree, HashValFree); hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash"); /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n", ibufs_in, ibufs_rem); */ }
void DNA_sdna_free(SDNA *sdna) { if (sdna->data_alloc) { MEM_freeN((void *)sdna->data); } MEM_freeN((void *)sdna->names); MEM_freeN(sdna->types); MEM_freeN(sdna->structs); #ifdef WITH_DNA_GHASH BLI_ghash_free(sdna->structs_map, NULL, NULL); #endif MEM_freeN(sdna); }
void IMB_moviecache_free(MovieCache *cache) { PRINT("%s: cache '%s' free\n", __func__, cache->name); BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree); BLI_mempool_destroy(cache->keys_pool); BLI_mempool_destroy(cache->items_pool); BLI_mempool_destroy(cache->userkeys_pool); if (cache->points) MEM_freeN(cache->points); if (cache->last_userkey) MEM_freeN(cache->last_userkey); MEM_freeN(cache); }
void postEditBoneDuplicate(struct ListBase *editbones, Object *ob) { if (ob->pose == NULL) { return; } BKE_pose_channels_hash_free(ob->pose); BKE_pose_channels_hash_make(ob->pose); GHash *name_map = BLI_ghash_str_new(__func__); for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) { EditBone *ebone_dst = ebone_src->temp.ebone; if (!ebone_dst) { ebone_dst = ED_armature_bone_get_mirrored(editbones, ebone_src); } if (ebone_dst) { BLI_ghash_insert(name_map, ebone_src->name, ebone_dst->name); } } for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) { EditBone *ebone_dst = ebone_src->temp.ebone; if (ebone_dst) { bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name); if (pchan_src) { bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name); if (pchan_dst) { if (pchan_src->custom_tx) { pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx); } if (pchan_src->bbone_prev) { pchan_dst->bbone_prev = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_prev); } if (pchan_src->bbone_next) { pchan_dst->bbone_next = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_next); } } } } } BLI_ghash_free(name_map, NULL, NULL); }
void GPU_extensions_exit(void) { extern Material defmaterial; // render module abuse... if(defmaterial.gpumaterial.first) GPU_material_free(&defmaterial); if(FUNCTION_HASH) { BLI_ghash_free(FUNCTION_HASH, NULL, (GHashValFreeFP)MEM_freeN); FUNCTION_HASH = NULL; } /*if(FUNCTION_PROTOTYPES) { MEM_freeN(FUNCTION_PROTOTYPES); FUNCTION_PROTOTYPES = NULL; }*/ /*if(FUNCTION_LIB) { GPU_shader_free(FUNCTION_LIB); FUNCTION_LIB = NULL; }*/ }
void tracks_map_free(TracksMap *map, void (*customdata_free)(void *customdata)) { int i = 0; BLI_ghash_free(map->hash, NULL, NULL); for (i = 0; i < map->num_tracks; i++) { if (map->customdata && customdata_free) customdata_free(&map->customdata[i * map->customdata_size]); BKE_tracking_track_free(&map->tracks[i]); } if (map->customdata) MEM_freeN(map->customdata); MEM_freeN(map->tracks); BLI_spin_end(&map->spin_lock); MEM_freeN(map); }
void imb_tile_cache_exit(void) { ImGlobalTile *gtile; int a; if(GLOBAL_CACHE.initialized) { for(gtile=GLOBAL_CACHE.tiles.first; gtile; gtile=gtile->next) imb_global_cache_tile_unload(gtile); for(a=0; a<GLOBAL_CACHE.totthread; a++) imb_thread_cache_exit(&GLOBAL_CACHE.thread_cache[a]); if(GLOBAL_CACHE.memarena) BLI_memarena_free(GLOBAL_CACHE.memarena); if(GLOBAL_CACHE.tilehash) BLI_ghash_free(GLOBAL_CACHE.tilehash, NULL, NULL); BLI_mutex_end(&GLOBAL_CACHE.mutex); memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache)); } }
/** * Free (or release) any data used by this ViewLayer. */ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user) { view_layer->basact = NULL; BLI_freelistN(&view_layer->object_bases); if (view_layer->object_bases_hash) { BLI_ghash_free(view_layer->object_bases_hash, NULL, NULL); } for (LayerCollection *lc = view_layer->layer_collections.first; lc; lc = lc->next) { layer_collection_free(view_layer, lc); } BLI_freelistN(&view_layer->layer_collections); for (ViewLayerEngineData *sled = view_layer->drawdata.first; sled; sled = sled->next) { if (sled->storage) { if (sled->free) { sled->free(sled->storage); } MEM_freeN(sled->storage); } } BLI_freelistN(&view_layer->drawdata); MEM_SAFE_FREE(view_layer->stats); BKE_freestyle_config_free(&view_layer->freestyle_config, do_id_user); if (view_layer->id_properties) { IDP_FreeProperty(view_layer->id_properties); } MEM_SAFE_FREE(view_layer->object_bases_array); MEM_freeN(view_layer); }
/** * Move here pose function for game engine so that we can mix with GE objects * Principle is as follow: * Use Blender structures so that BKE_pose_where_is can be used unchanged * Copy the constraint so that they can be enabled/disabled/added/removed at runtime * Don't copy the constraints for the pose used by the Action actuator, it does not need them. * Scan the constraint structures so that the KX equivalent of target objects are identified and * stored in separate list. * When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding * Blender objects and restore after the evaluation. */ static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) { bPose *out; bPoseChannel *pchan, *outpchan; GHash *ghash; /* the game engine copies the current armature pose and then swaps * the object pose pointer. this makes it possible to change poses * without affecting the original blender data. */ if (!src) { *dst=NULL; return; } else if (*dst==src) { printf("game_copy_pose source and target are the same\n"); *dst=NULL; return; } out= (bPose*)MEM_dupallocN(src); out->chanhash = NULL; out->agroups.first= out->agroups.last= NULL; out->ikdata = NULL; out->ikparam = MEM_dupallocN(src->ikparam); out->flag |= POSE_GAME_ENGINE; BLI_duplicatelist(&out->chanbase, &src->chanbase); /* remap pointers */ ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "game_copy_pose gh"); pchan= (bPoseChannel *)src->chanbase.first; outpchan= (bPoseChannel *)out->chanbase.first; for (; pchan; pchan=pchan->next, outpchan=outpchan->next) BLI_ghash_insert(ghash, pchan, outpchan); for (pchan = (bPoseChannel *)out->chanbase.first; pchan; pchan = pchan->next) { pchan->parent= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->parent); pchan->child= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->child); if (copy_constraint) { ListBase listb; // copy all constraint for backward compatibility // BKE_constraints_copy NULLs listb, no need to make extern for this operation. BKE_constraints_copy(&listb, &pchan->constraints, false); pchan->constraints= listb; } else { BLI_listbase_clear(&pchan->constraints); } if (pchan->custom) { id_us_plus(&pchan->custom->id); } // fails to link, props are not used in the BGE yet. #if 0 if (pchan->prop) pchan->prop= IDP_CopyProperty(pchan->prop); #endif pchan->prop= NULL; } BLI_ghash_free(ghash, NULL, NULL); // set acceleration structure for channel lookup BKE_pose_channels_hash_make(out); *dst=out; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { MaskModifierData *mmd= (MaskModifierData *)md; DerivedMesh *dm= derivedData, *result= NULL; GHash *vertHash=NULL, *edgeHash, *faceHash; GHashIterator *hashIter; MDeformVert *dvert= NULL, *dv; int numFaces=0, numEdges=0, numVerts=0; int maxVerts, maxEdges, maxFaces; int i; /* Overview of Method: * 1. Get the vertices that are in the vertexgroup of interest * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices * 3. Make a new mesh containing only the mapping data */ /* get original number of verts, edges, and faces */ maxVerts= dm->getNumVerts(dm); maxEdges= dm->getNumEdges(dm); maxFaces= dm->getNumFaces(dm); /* check if we can just return the original mesh * - must have verts and therefore verts assigned to vgroups to do anything useful */ if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (maxVerts == 0) || (ob->defbase.first == NULL) ) { return derivedData; } /* if mode is to use selected armature bones, aggregate the bone groups */ if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */ { GHash *vgroupHash; Object *oba= mmd->ob_arm; bPoseChannel *pchan; bDeformGroup *def; char *bone_select_array; int bone_select_tot= 0; /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first)) return derivedData; bone_select_array= MEM_mallocN(BLI_countlist(&ob->defbase) * sizeof(char), "mask array"); for (i = 0, def = ob->defbase.first; def; def = def->next, i++) { if (((pchan= get_pose_channel(oba->pose, def->name)) && pchan->bone && (pchan->bone->flag & BONE_SELECTED))) { bone_select_array[i]= TRUE; bone_select_tot++; } else { bone_select_array[i]= FALSE; } } /* hashes for finding mapping of: * - vgroups to indices -> vgroupHash (string, int) * - bones to vgroup indices -> boneHash (index of vgroup, dummy) */ vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "mask vgroup gh"); /* build mapping of names of vertex groups to indices */ for (i = 0, def = ob->defbase.first; def; def = def->next, i++) BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i)); /* if no bones selected, free hashes and return original mesh */ if (bone_select_tot == 0) { BLI_ghash_free(vgroupHash, NULL, NULL); MEM_freeN(bone_select_array); return derivedData; } /* repeat the previous check, but for dverts */ dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT); if (dvert == NULL) { BLI_ghash_free(vgroupHash, NULL, NULL); MEM_freeN(bone_select_array); return derivedData; } /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert gh"); /* add vertices which exist in vertexgroups into vertHash for filtering */ for (i= 0, dv= dvert; i < maxVerts; i++, dv++) { MDeformWeight *dw= dv->dw; int j; for (j= dv->totweight; j > 0; j--, dw++) { if (bone_select_array[dw->def_nr]) { if(dw->weight != 0.0f) { break; } } } /* check if include vert in vertHash */ if (mmd->flag & MOD_MASK_INV) { /* if this vert is in the vgroup, don't include it in vertHash */ if (dw) continue; } else { /* if this vert isn't in the vgroup, don't include it in vertHash */ if (!dw) continue; } /* add to ghash for verts (numVerts acts as counter for mapping) */ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts)); numVerts++; } /* free temp hashes */ BLI_ghash_free(vgroupHash, NULL, NULL); MEM_freeN(bone_select_array); } else /* --- Using Nominated VertexGroup only --- */ { int defgrp_index = defgroup_name_index(ob, mmd->vgroup); /* get dverts */ if (defgrp_index >= 0) dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); /* if no vgroup (i.e. dverts) found, return the initial mesh */ if ((defgrp_index < 0) || (dvert == NULL)) return dm; /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert2 bh"); /* add vertices which exist in vertexgroup into ghash for filtering */ for (i= 0, dv= dvert; i < maxVerts; i++, dv++) { const int weight_set= defvert_find_weight(dv, defgrp_index) != 0.0f; /* check if include vert in vertHash */ if (mmd->flag & MOD_MASK_INV) { /* if this vert is in the vgroup, don't include it in vertHash */ if (weight_set) continue; } else { /* if this vert isn't in the vgroup, don't include it in vertHash */ if (!weight_set) continue; } /* add to ghash for verts (numVerts acts as counter for mapping) */ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts)); numVerts++; } } /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask ed2 gh"); faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh"); /* loop over edges and faces, and do the same thing to * ensure that they only reference existing verts */ for (i = 0; i < maxEdges; i++) { MEdge me; dm->getEdge(dm, i, &me); /* only add if both verts will be in new mesh */ 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, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges)); numEdges++; } } for (i = 0; i < maxFaces; i++) { MFace mf; dm->getFace(dm, i, &mf); /* all verts must be available */ if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) && (mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) ) { BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces)); numFaces++; } } /* now we know the number of verts, edges and faces, * we can create the new (reduced) mesh */ result = CDDM_from_template(dm, numVerts, numEdges, numFaces); /* using ghash-iterators, map data into new mesh */ /* vertices */ for ( hashIter = BLI_ghashIterator_new(vertHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getVert(dm, oldIndex, &source); dest = CDDM_get_vert(result, newIndex); DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* edges */ for ( hashIter = BLI_ghashIterator_new(edgeHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getEdge(dm, oldIndex, &source); dest = CDDM_get_edge(result, newIndex); source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); DM_copy_edge_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* faces */ for ( hashIter = BLI_ghashIterator_new(faceHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { MFace source; MFace *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); int orig_v4; dm->getFace(dm, oldIndex, &source); dest = CDDM_get_face(result, newIndex); orig_v4 = source.v4; source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); if (source.v4) source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); DM_copy_face_data(dm, result, oldIndex, newIndex, 1); *dest = source; test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3)); } BLI_ghashIterator_free(hashIter); /* recalculate normals */ CDDM_calc_normals(result); /* free hashes */ BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); BLI_ghash_free(faceHash, NULL, NULL); /* return the new mesh */ return result; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { MaskModifierData *mmd = (MaskModifierData *)md; DerivedMesh *dm = derivedData, *result = NULL; GHash *vertHash = NULL, *edgeHash, *polyHash; GHashIterator *hashIter; MDeformVert *dvert = NULL, *dv; int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0; int maxVerts, maxEdges, maxPolys; int i; MPoly *mpoly; MLoop *mloop; MPoly *mpoly_new; MLoop *mloop_new; MEdge *medge_new; MVert *mvert_new; int *loop_mapping; /* Overview of Method: * 1. Get the vertices that are in the vertexgroup of interest * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices * 3. Make a new mesh containing only the mapping data */ /* get original number of verts, edges, and faces */ maxVerts = dm->getNumVerts(dm); maxEdges = dm->getNumEdges(dm); maxPolys = dm->getNumPolys(dm); /* check if we can just return the original mesh * - must have verts and therefore verts assigned to vgroups to do anything useful */ if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (maxVerts == 0) || (ob->defbase.first == NULL) ) { return derivedData; } /* if mode is to use selected armature bones, aggregate the bone groups */ if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */ Object *oba = mmd->ob_arm; bPoseChannel *pchan; bDeformGroup *def; char *bone_select_array; int bone_select_tot = 0; const int defbase_tot = BLI_countlist(&ob->defbase); /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM3(NULL, oba, oba->pose, ob->defbase.first)) return derivedData; /* determine whether each vertexgroup is associated with a selected bone or not * - each cell is a boolean saying whether bone corresponding to the ith group is selected * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts) */ bone_select_array = MEM_mallocN(defbase_tot * sizeof(char), "mask array"); for (i = 0, def = ob->defbase.first; def; def = def->next, i++) { pchan = BKE_pose_channel_find_name(oba->pose, def->name); if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { bone_select_array[i] = TRUE; bone_select_tot++; } else { bone_select_array[i] = FALSE; } } /* if no dverts (i.e. no data for vertex groups exists), we've got an * inconsistent situation, so free hashes and return oirginal mesh */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); if (dvert == NULL) { MEM_freeN(bone_select_array); return derivedData; } /* verthash gives mapping from original vertex indices to the new indices (including selected matches only) * key = oldindex, value = newindex */ vertHash = BLI_ghash_int_new("mask vert gh"); /* add vertices which exist in vertexgroups into vertHash for filtering * - dv = for each vertex, what vertexgroups does it belong to * - dw = weight that vertex was assigned to a vertexgroup it belongs to */ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { MDeformWeight *dw = dv->dw; short found = 0; int j; /* check the groups that vertex is assigned to, and see if it was any use */ for (j = 0; j < dv->totweight; j++, dw++) { if (dw->def_nr < defbase_tot) { if (bone_select_array[dw->def_nr]) { if (dw->weight != 0.0f) { found = TRUE; break; } } } } /* check if include vert in vertHash */ if (mmd->flag & MOD_MASK_INV) { /* if this vert is in the vgroup, don't include it in vertHash */ if (found) continue; } else { /* if this vert isn't in the vgroup, don't include it in vertHash */ if (!found) continue; } /* add to ghash for verts (numVerts acts as counter for mapping) */ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts)); numVerts++; } /* free temp hashes */ MEM_freeN(bone_select_array); } else { /* --- Using Nominated VertexGroup only --- */ int defgrp_index = defgroup_name_index(ob, mmd->vgroup); /* get dverts */ if (defgrp_index != -1) dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); /* if no vgroup (i.e. dverts) found, return the initial mesh */ if ((defgrp_index == -1) || (dvert == NULL)) return dm; /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ vertHash = BLI_ghash_int_new("mask vert2 bh"); /* add vertices which exist in vertexgroup into ghash for filtering */ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { const int weight_set = defvert_find_weight(dv, defgrp_index) != 0.0f; /* check if include vert in vertHash */ if (mmd->flag & MOD_MASK_INV) { /* if this vert is in the vgroup, don't include it in vertHash */ if (weight_set) continue; } else { /* if this vert isn't in the vgroup, don't include it in vertHash */ if (!weight_set) continue; } /* add to ghash for verts (numVerts acts as counter for mapping) */ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts)); numVerts++; } } /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ edgeHash = BLI_ghash_int_new("mask ed2 gh"); polyHash = BLI_ghash_int_new("mask fa2 gh"); mpoly = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */ /* loop over edges and faces, and do the same thing to * ensure that they only reference existing verts */ for (i = 0; i < maxEdges; i++) { MEdge me; dm->getEdge(dm, i, &me); /* only add if both verts will be in new mesh */ 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, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges)); numEdges++; } } for (i = 0; i < maxPolys; i++) { MPoly *mp = &mpoly[i]; MLoop *ml = mloop + mp->loopstart; int ok = TRUE; int j; for (j = 0; j < mp->totloop; j++, ml++) { if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) { ok = FALSE; break; } } /* all verts must be available */ if (ok) { BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys)); loop_mapping[numPolys] = numLoops; numPolys++; numLoops += mp->totloop; } } /* now we know the number of verts, edges and faces, * we can create the new (reduced) mesh */ result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys); mpoly_new = CDDM_get_polys(result); mloop_new = CDDM_get_loops(result); medge_new = CDDM_get_edges(result); mvert_new = CDDM_get_verts(result); /* using ghash-iterators, map data into new mesh */ /* vertices */ for (hashIter = BLI_ghashIterator_new(vertHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getVert(dm, oldIndex, &source); dest = &mvert_new[newIndex]; DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* edges */ for (hashIter = BLI_ghashIterator_new(edgeHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter)) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getEdge(dm, oldIndex, &source); dest = &medge_new[newIndex]; source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); DM_copy_edge_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* faces */ for (hashIter = BLI_ghashIterator_new(polyHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); MPoly *source = &mpoly[oldIndex]; MPoly *dest = &mpoly_new[newIndex]; int oldLoopIndex = source->loopstart; int newLoopIndex = loop_mapping[newIndex]; MLoop *source_loop = &mloop[oldLoopIndex]; MLoop *dest_loop = &mloop_new[newLoopIndex]; DM_copy_poly_data(dm, result, oldIndex, newIndex, 1); DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop); *dest = *source; dest->loopstart = newLoopIndex; for (i = 0; i < source->totloop; i++) { dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v))); dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e))); } } BLI_ghashIterator_free(hashIter); MEM_freeN(loop_mapping); /* why is this needed? - campbell */ /* recalculate normals */ CDDM_calc_normals(result); /* free hashes */ BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); BLI_ghash_free(polyHash, NULL, NULL); /* return the new mesh */ return result; }
static void make_duplis_font(const DupliContext *ctx) { Object *par = ctx->object; GHash *family_gh; Object *ob; Curve *cu; struct CharTrans *ct, *chartransdata = NULL; float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; int text_len, a; size_t family_len; const wchar_t *text = NULL; bool text_free = false; /* font dupliverts not supported inside groups */ if (ctx->group) return; copy_m4_m4(pmat, par->obmat); /* in par the family name is stored, use this to find the other objects */ BKE_vfont_to_curve_ex(G.main, par, FO_DUPLI, NULL, &text, &text_len, &text_free, &chartransdata); if (text == NULL || chartransdata == NULL) { return; } cu = par->data; fsize = cu->fsize; xof = cu->xof; yof = cu->yof; ct = chartransdata; /* cache result */ family_len = strlen(cu->family); family_gh = BLI_ghash_int_new_ex(__func__, 256); /* advance matching BLI_strncpy_wchar_from_utf8 */ for (a = 0; a < text_len; a++, ct++) { ob = find_family_object(cu->family, family_len, (unsigned int)text[a], family_gh); if (ob) { vec[0] = fsize * (ct->xof - xof); vec[1] = fsize * (ct->yof - yof); vec[2] = 0.0; mul_m4_v3(pmat, vec); copy_m4_m4(obmat, par->obmat); if (UNLIKELY(ct->rot != 0.0f)) { float rmat[4][4]; zero_v3(obmat[3]); unit_m4(rmat); rotate_m4(rmat, 'Z', -ct->rot); mul_m4_m4m4(obmat, obmat, rmat); } copy_v3_v3(obmat[3], vec); make_dupli(ctx, ob, obmat, a, false, false); } } if (text_free) { MEM_freeN((void *)text); } BLI_ghash_free(family_gh, NULL, NULL); MEM_freeN(chartransdata); }
/* XXX Logick bricks... I don't have words to say what I think about this behavior. * They have silent hidden ugly inter-objects dependencies (a sensor can link into any other * object's controllers, and same between controllers and actuators, without *any* explicit reference * to data-block involved). * This is bad, bad, bad!!! * ...and forces us to add yet another very ugly hack to get remapping with logic bricks working. */ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new) { if (ob_new == NULL || (ob_old->controllers.first == NULL && ob_old->actuators.first == NULL)) { /* Nothing to do here... */ return; } GHash *controllers_map = ob_old->controllers.first ? BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->controllers)) : NULL; GHash *actuators_map = ob_old->actuators.first ? BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->actuators)) : NULL; /* We try to remap old controllers/actuators to new ones - in a very basic way. */ for (bController *cont_old = ob_old->controllers.first, *cont_new = ob_new->controllers.first; cont_old; cont_old = cont_old->next) { bController *cont_new2 = cont_new; if (cont_old->mynew != NULL) { cont_new2 = cont_old->mynew; if (!(cont_new2 == cont_new || BLI_findindex(&ob_new->controllers, cont_new2) >= 0)) { cont_new2 = NULL; } } else if (cont_new && cont_old->type != cont_new->type) { cont_new2 = NULL; } BLI_ghash_insert(controllers_map, cont_old, cont_new2); if (cont_new) { cont_new = cont_new->next; } } for (bActuator *act_old = ob_old->actuators.first, *act_new = ob_new->actuators.first; act_old; act_old = act_old->next) { bActuator *act_new2 = act_new; if (act_old->mynew != NULL) { act_new2 = act_old->mynew; if (!(act_new2 == act_new || BLI_findindex(&ob_new->actuators, act_new2) >= 0)) { act_new2 = NULL; } } else if (act_new && act_old->type != act_new->type) { act_new2 = NULL; } BLI_ghash_insert(actuators_map, act_old, act_new2); if (act_new) { act_new = act_new->next; } } for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { if (controllers_map != NULL) { for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) { for (int a = 0; a < sens->totlinks; a++) { if (sens->links[a]) { bController *old_link = sens->links[a]; bController **new_link_p = (bController **)BLI_ghash_lookup_p(controllers_map, old_link); if (new_link_p == NULL) { /* old_link is *not* in map's keys (i.e. not to any ob_old->controllers), * which means we ignore it totally here. */ } else if (*new_link_p == NULL) { unlink_logicbricks((void **)&old_link, (void ***)&(sens->links), &sens->totlinks); a--; } else { sens->links[a] = *new_link_p; } } } } } if (actuators_map != NULL) { for (bController *cont = ob->controllers.first; cont; cont = cont->next) { for (int a = 0; a < cont->totlinks; a++) { if (cont->links[a]) { bActuator *old_link = cont->links[a]; bActuator **new_link_p = (bActuator **)BLI_ghash_lookup_p(actuators_map, old_link); if (new_link_p == NULL) { /* old_link is *not* in map's keys (i.e. not to any ob_old->actuators), * which means we ignore it totally here. */ } else if (*new_link_p == NULL) { unlink_logicbricks((void **)&old_link, (void ***)&(cont->links), &cont->totlinks); a--; } else { cont->links[a] = *new_link_p; } } } } } } if (controllers_map) { BLI_ghash_free(controllers_map, NULL, NULL); } if (actuators_map) { BLI_ghash_free(actuators_map, NULL, NULL); } }
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 *hashIter; /* 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_mallocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap"); edgeMap = MEM_mallocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap"); faceMap = MEM_mallocN(sizeof(*faceMap) * numPoly_src, "build modifier faceMap"); #pragma omp parallel sections if (numVert_src + numEdge_src + numPoly_src >= DM_OMP_LIMIT) { #pragma omp section { range_vn_i(vertMap, numVert_src, 0); } #pragma omp section { range_vn_i(edgeMap, numEdge_src, 0); } #pragma omp section { range_vn_i(faceMap, numPoly_src, 0); } } frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); 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; if (bmd->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; for (i = 0; i < numFaces_dst; i++) { mp = mpoly + faceMap[i]; ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(ml->v), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } numLoops_dst += mp->totloop; } /* 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; for (i = 0; i < numEdge_src; i++) { 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))) { j = BLI_ghash_size(edgeHash); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j), SET_INT_IN_POINTER(i)); BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(j)); } } } else if (numEdges_dst) { MEdge *medge, *me; if (bmd->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; for (i = 0; i < numEdges_dst; i++) { me = medge + edgeMap[i]; if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v1), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) { BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } } /* get the set of edges that will be in the new mesh */ for (i = 0; i < numEdges_dst; i++) { j = BLI_ghash_size(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->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_size(vertHash), BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst); /* copy the vertices across */ for (hashIter = BLI_ghashIterator_new(vertHash); BLI_ghashIterator_done(hashIter) == false; BLI_ghashIterator_step(hashIter) ) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); source = mvert_src[oldIndex]; dest = CDDM_get_vert(result, newIndex); DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* copy the edges across, remapping indices */ for (i = 0; i < BLI_ghash_size(edgeHash); i++) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); source = medge_src[oldIndex]; dest = CDDM_get_edge(result, i); source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); DM_copy_edge_data(dm, result, oldIndex, i, 1); *dest = source; } mpoly_dst = CDDM_get_polys(result); /* mloop_dst = */ ml_dst = CDDM_get_loops(result); /* copy the faces across, remapping indices */ k = 0; for (i = 0; i < numFaces_dst; i++) { MPoly *source; MPoly *dest; source = mpoly_src + faceMap[i]; dest = mpoly_dst + i; DM_copy_poly_data(dm, result, faceMap[i], i, 1); *dest = *source; dest->loopstart = k; DM_copy_loop_data(dm, result, source->loopstart, dest->loopstart, dest->totloop); ml_src = mloop_src + source->loopstart; for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) { ml_dst->v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(ml_src->v))); ml_dst->e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash2, SET_INT_IN_POINTER(ml_src->e))); } } BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); BLI_ghash_free(edgeHash2, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); MEM_freeN(faceMap); if (dm->dirty & DM_DIRTY_NORMALS) { result->dirty |= DM_DIRTY_NORMALS; } return result; }
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { DerivedMesh *dm = derivedData; DerivedMesh *result; BuildModifierData *bmd = (BuildModifierData*) md; int i; int numFaces, numEdges; int *vertMap, *edgeMap, *faceMap; float frac; GHashIterator *hashIter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build ve apply gh"); /* maps edge indices in new mesh to indices in old mesh */ GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build ed apply gh"); const int maxVerts= dm->getNumVerts(dm); const int maxEdges= dm->getNumEdges(dm); const int maxFaces= dm->getNumFaces(dm); vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap"); for(i = 0; i < maxVerts; ++i) vertMap[i] = i; edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap"); for(i = 0; i < maxEdges; ++i) edgeMap[i] = i; faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); for(i = 0; i < maxFaces; ++i) faceMap[i] = i; frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); numFaces = dm->getNumFaces(dm) * frac; numEdges = dm->getNumEdges(dm) * frac; /* if there's at least one face, build based on faces */ if(numFaces) { if(bmd->randomize) BLI_array_randomize(faceMap, sizeof(*faceMap), maxFaces, 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 < numFaces; ++i) { MFace mf; dm->getFace(dm, faceMap[i], &mf); if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4), SET_INT_IN_POINTER(BLI_ghash_size(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) */ for(i = 0; i < maxEdges; ++i) { MEdge me; dm->getEdge(dm, i, &me); 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, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i)); } } else if(numEdges) { if(bmd->randomize) BLI_array_randomize(edgeMap, sizeof(*edgeMap), maxEdges, 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 < numEdges; ++i) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash))); } /* get the set of edges that will be in the new mesh */ for(i = 0; i < numEdges; ++i) { MEdge me; dm->getEdge(dm, edgeMap[i], &me); BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(edgeMap[i])); } } else { int numVerts = dm->getNumVerts(dm) * frac; if(bmd->randomize) BLI_array_randomize(vertMap, sizeof(*vertMap), maxVerts, 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_size(vertHash), BLI_ghash_size(edgeHash), numFaces); /* copy the vertices across */ for( hashIter = BLI_ghashIterator_new(vertHash); !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { MVert source; MVert *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); dm->getVert(dm, oldIndex, &source); dest = CDDM_get_vert(result, newIndex); DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); *dest = source; } BLI_ghashIterator_free(hashIter); /* copy the edges across, remapping indices */ for(i = 0; i < BLI_ghash_size(edgeHash); ++i) { MEdge source; MEdge *dest; int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i))); dm->getEdge(dm, oldIndex, &source); dest = CDDM_get_edge(result, i); source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); DM_copy_edge_data(dm, result, oldIndex, i, 1); *dest = source; } /* copy the faces across, remapping indices */ for(i = 0; i < numFaces; ++i) { MFace source; MFace *dest; int orig_v4; dm->getFace(dm, faceMap[i], &source); dest = CDDM_get_face(result, i); orig_v4 = source.v4; source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3))); if(source.v4) source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4))); DM_copy_face_data(dm, result, faceMap[i], i, 1); *dest = source; test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3)); } CDDM_calc_normals(result); BLI_ghash_free(vertHash, NULL, NULL); BLI_ghash_free(edgeHash, NULL, NULL); MEM_freeN(vertMap); MEM_freeN(edgeMap); MEM_freeN(faceMap); return result; }
void BKE_outliner_treehash_free(void *treehash) { BLI_assert(treehash); BLI_ghash_free(treehash, NULL, free_treehash_group); }
/* Iterate over the CSG Output Descriptors and create a new DerivedMesh from them */ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( CSG_FaceIteratorDescriptor *face_it, CSG_VertexIteratorDescriptor *vertex_it, float parinv[][4], float mapmat[][4], Material **mat, int *totmat, DerivedMesh *dm1, Object *ob1, DerivedMesh *dm2, Object *ob2) { DerivedMesh *result, *orig_dm; GHash *material_hash = NULL; Mesh *me1= (Mesh*)ob1->data; Mesh *me2= (Mesh*)ob2->data; int i; // create a new DerivedMesh result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements); CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH, CD_DEFAULT, face_it->num_elements); CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH, CD_DEFAULT, face_it->num_elements); // step through the vertex iterators: for (i = 0; !vertex_it->Done(vertex_it->it); i++) { CSG_IVertex csgvert; MVert *mvert = CDDM_get_vert(result, i); // retrieve a csg vertex from the boolean module vertex_it->Fill(vertex_it->it, &csgvert); vertex_it->Step(vertex_it->it); // we have to map the vertex coordinates back in the coordinate frame // of the resulting object, since it was computed in world space mul_v3_m4v3(mvert->co, parinv, csgvert.position); } // a hash table to remap materials to indices if (mat) { material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "CSG_mat gh"); *totmat = 0; } // step through the face iterators for(i = 0; !face_it->Done(face_it->it); i++) { Mesh *orig_me; Object *orig_ob; Material *orig_mat; CSG_IFace csgface; MFace *mface; int orig_index, mat_nr; // retrieve a csg face from the boolean module face_it->Fill(face_it->it, &csgface); face_it->Step(face_it->it); // find the original mesh and data orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2; orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2; orig_me = (orig_ob == ob1)? me1: me2; orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1); // copy all face layers, including mface CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1); // set mface mface = CDDM_get_face(result, i); mface->v1 = csgface.vertex_index[0]; mface->v2 = csgface.vertex_index[1]; mface->v3 = csgface.vertex_index[2]; mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0; // set material, based on lookup in hash table orig_mat= give_current_material(orig_ob, mface->mat_nr+1); if (mat && orig_mat) { if (!BLI_ghash_haskey(material_hash, orig_mat)) { mat[*totmat] = orig_mat; mat_nr = mface->mat_nr = (*totmat)++; BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr)); } else mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat)); } else mface->mat_nr = 0; InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number, (orig_me == me2)? mapmat: NULL); test_index_face(mface, &result->faceData, i, csgface.vertex_number); } if (material_hash) BLI_ghash_free(material_hash, NULL, NULL); CDDM_calc_edges(result); CDDM_calc_normals(result); return result; }
void evaluate_fmodifiers_storage_free(FModifierStackStorage *storage) { if (storage != NULL) { BLI_ghash_free((GHash *) storage, NULL, NULL); } }
static void imb_thread_cache_exit(ImThreadTileCache *cache) { BLI_ghash_free(cache->tilehash, NULL, NULL); }
static void ui_editsource_active_but_clear(void) { BLI_ghash_free(ui_editsource_info->hash, NULL, (GHashValFreeFP)MEM_freeN); MEM_freeN(ui_editsource_info); ui_editsource_info= NULL; }
static void codegen_set_unique_ids(ListBase *nodes) { GHash *bindhash, *definehash; GPUNode *node; GPUInput *input; GPUOutput *output; int id = 1, texid = 0; bindhash= BLI_ghash_ptr_new("codegen_set_unique_ids1 gh"); definehash= BLI_ghash_ptr_new("codegen_set_unique_ids2 gh"); for (node=nodes->first; node; node=node->next) { for (input=node->inputs.first; input; input=input->next) { /* set id for unique names of uniform variables */ input->id = id++; input->bindtex = 0; input->definetex = 0; /* set texid used for settings texture slot with multitexture */ if (codegen_input_has_texture(input) && ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL))) { if (input->link) { /* input is texture from buffer, assign only one texid per * buffer to avoid sampling the same texture twice */ if (!BLI_ghash_haskey(bindhash, input->link)) { input->texid = texid++; input->bindtex = 1; BLI_ghash_insert(bindhash, input->link, SET_INT_IN_POINTER(input->texid)); } else input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->link)); } else if (input->ima) { /* input is texture from image, assign only one texid per * buffer to avoid sampling the same texture twice */ if (!BLI_ghash_haskey(bindhash, input->ima)) { input->texid = texid++; input->bindtex = 1; BLI_ghash_insert(bindhash, input->ima, SET_INT_IN_POINTER(input->texid)); } else input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima)); } else if (input->prv) { /* input is texture from preview render, assign only one texid per * buffer to avoid sampling the same texture twice */ if (!BLI_ghash_haskey(bindhash, input->prv)) { input->texid = texid++; input->bindtex = 1; BLI_ghash_insert(bindhash, input->prv, SET_INT_IN_POINTER(input->texid)); } else input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->prv)); } else { if (!BLI_ghash_haskey(bindhash, input->tex)) { /* input is user created texture, check tex pointer */ input->texid = texid++; input->bindtex = 1; BLI_ghash_insert(bindhash, input->tex, SET_INT_IN_POINTER(input->texid)); } else input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->tex)); } /* make sure this pixel is defined exactly once */ if (input->source == GPU_SOURCE_TEX_PIXEL) { if (input->ima) { if (!BLI_ghash_haskey(definehash, input->ima)) { input->definetex = 1; BLI_ghash_insert(definehash, input->ima, SET_INT_IN_POINTER(input->texid)); } } else { if (!BLI_ghash_haskey(definehash, input->link)) { input->definetex = 1; BLI_ghash_insert(definehash, input->link, SET_INT_IN_POINTER(input->texid)); } } } } } for (output=node->outputs.first; output; output=output->next) /* set id for unique names of tmp variables storing output */ output->id = id++; } BLI_ghash_free(bindhash, NULL, NULL); BLI_ghash_free(definehash, NULL, NULL); }