static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress) { IconPreview *ip = (IconPreview *)customdata; IconPreviewSize *cur_size = ip->sizes.first; const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); while (cur_size) { ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); /* construct shader preview from image size and previewcustomdata */ sp->scene = ip->scene; sp->owner = ip->owner; sp->sizex = cur_size->sizex; sp->sizey = cur_size->sizey; sp->pr_method = PR_ICON_RENDER; sp->pr_rect = cur_size->rect; sp->id = ip->id; if (use_new_shading) { /* texture icon rendering is hardcoded to use BI, * so don't even think of using cycle's bmain for * texture icons */ if (GS(ip->id->name) != ID_TE) sp->pr_main = G_pr_main_cycles; else sp->pr_main = G_pr_main; } else { sp->pr_main = G_pr_main; } common_preview_startjob(sp, stop, do_update, progress); shader_preview_free(sp); cur_size = cur_size->next; } }
static void unpack_generate_paths( const char *name, ID *id, char *abspath_r, char *relpath_r, size_t abspathlen, size_t relpathlen) { char tempname[FILE_MAX]; char tempdir[FILE_MAXDIR]; BLI_split_dirfile(name, tempdir, tempname, sizeof(tempdir), sizeof(tempname)); if (tempname[0] == '\0') { /* Note: we do not have any real way to re-create extension out of data... */ BLI_strncpy(tempname, id->name + 2, sizeof(tempname)); printf("%s\n", tempname); BLI_filename_make_safe(tempname); printf("%s\n", tempname); } if (tempdir[0] == '\0') { /* Fallback to relative dir. */ BLI_strncpy(tempdir, "//", sizeof(tempdir)); } switch (GS(id->name)) { case ID_VF: BLI_snprintf(relpath_r, relpathlen, "//fonts/%s", tempname); break; case ID_SO: BLI_snprintf(relpath_r, relpathlen, "//sounds/%s", tempname); break; case ID_IM: BLI_snprintf(relpath_r, relpathlen, "//textures/%s", tempname); break; } { size_t len = BLI_strncpy_rlen(abspath_r, tempdir, abspathlen); BLI_strncpy(abspath_r + len, tempname, abspathlen - len); } }
void BKE_libblock_free_us(Main *bmain, void *idv) /* test users */ { ID *id = idv; id_us_min(id); /* XXX This is a temp (2.77) hack so that we keep same behavior as in 2.76 regarding groups when deleting an object. * Since only 'user_one' usage of objects is groups, and only 'real user' usage of objects is scenes, * removing that 'user_one' tag when there is no more real (scene) users of an object ensures it gets * fully unlinked. * But only for local objects, not linked ones! * Otherwise, there is no real way to get rid of an object anymore - better handling of this is TODO. */ if ((GS(id->name) == ID_OB) && (id->us == 1) && (id->lib == NULL)) { id_us_clear_real(id); } if (id->us == 0) { BKE_libblock_unlink(bmain, id, false, false); BKE_libblock_free(bmain, id); } }
static int copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, int *use_path) { *use_path = FALSE; if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) *lb = CTX_data_collection_get(C, "selected_editable_bones"); else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) *lb = CTX_data_collection_get(C, "selected_pose_bones"); else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) *lb = CTX_data_collection_get(C, "selected_editable_sequences"); else { ID *id = ptr->id.data; if (id && GS(id->name) == ID_OB) { *lb = CTX_data_collection_get(C, "selected_editable_objects"); *use_path = TRUE; } else return 0; } return 1; }
void SDIR(astr A_S,aint K1,aint K2) { // Procedure SDIR[A$,K1,K2] aint I; astr PAT_S="", NAME_S=""; OKNO(100,60,140,160); // OKNO[100,60,140,160] GADGET(OKX+10,OKY+8,120,15,A_S,K1,0,K2,31,-1);// GADGET[OKX+10,OKY+8,120,15,A$,K1,0,K2,31,-1] // If Exist(KAT$+"archiwum") PAT_S=KAT_S+"archiwum/"; // PAT$=KAT$+"archiwum/" if( ! DirExists(PAT_S) ) { PAT_S="./"; } // Else // REQUEST["archiwum:","Archiwum"] // PAT$="archiwum:" // End If // for( I=0; I<=4; ++I ) { // For I=0 To 4 NAME_S = _sdir_get_file_name(I); GADGET(OKX+10,OKY+28+(I*20),120,15,NAME_S,8,1,6,31,I+1);// GADGET[OKX+10,OKY+28+(I*20),120,15,NAME$,8,1,6,31,I+1] } // Next GADGET(OKX+10,OKY+128,120,15,GS("226"),8,1,6,31,6);// GADGET[OKX+10,OKY+128,120,15,"Exit",8,1,6,31,6] Param_S=PAT_S; // End Proc[PAT$] }
bool CSettingConfig::UpdateAdvanced ( bool AdvancedMode, HTREEITEM hItem ) { while (hItem) { CSettingsPage * Page = (CSettingsPage * )m_PagesTreeList.GetItemData(hItem); if (!AdvancedMode && Page == m_AdvancedPage) { m_PagesTreeList.DeleteItem(hItem); return true; } if (AdvancedMode && Page == m_GeneralOptionsPage) { m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM,GS(m_AdvancedPage->PageTitle()),0,0,0,0,(ULONG)m_AdvancedPage,hItem,TVI_FIRST); return true; } if (UpdateAdvanced(AdvancedMode,m_PagesTreeList.GetChildItem(hItem))) { return true; } hItem = m_PagesTreeList.GetNextSiblingItem(hItem); } return false; }
void COptionsShortCutsPage::OnShortCutChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { //Get the virtual key info int index = m_VirtualKeyList.GetCurSel(); if (index < 0) { return; } WORD key = (WORD)m_VirtualKeyList.GetItemData(index); bool bCtrl = (SendDlgItemMessage(IDC_CTL, BM_GETCHECK, 0, 0) == BST_CHECKED); bool bAlt = (SendDlgItemMessage(IDC_ALT, BM_GETCHECK, 0, 0) == BST_CHECKED); bool bShift = (SendDlgItemMessage(IDC_SHIFT, BM_GETCHECK, 0, 0) == BST_CHECKED); ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); stdstr str = GS(m_ShortCuts.GetMenuItemName(key, bCtrl, bAlt, bShift, AccessLevel)); if (str.length() > 0) { str.resize(std::remove(str.begin(), str.end(), '&') - str.begin()); } else { str = "None"; } SetDlgItemText(IDC_ASSIGNED_MENU_ITEM, str.c_str()); }
static char *rna_ColorRamp_path(PointerRNA *ptr) { /* handle the cases where a single datablock may have 2 ramp types */ if (ptr->id.data) { ID *id= ptr->id.data; switch (GS(id->name)) { case ID_MA: /* material has 2 cases - diffuse and specular */ { Material *ma= (Material*)id; if (ptr->data == ma->ramp_col) return BLI_strdup("diffuse_ramp"); else if (ptr->data == ma->ramp_spec) return BLI_strdup("specular_ramp"); } break; } } /* everything else just uses 'color_ramp' */ return BLI_strdup("color_ramp"); }
void set_active_mtex(ID *id, short act) { if (act < 0) act = 0; else if (act >= MAX_MTEX) act = MAX_MTEX - 1; switch (GS(id->name)) { case ID_MA: ((Material *)id)->texact = act; break; case ID_WO: ((World *)id)->texact = act; break; case ID_LA: ((Lamp *)id)->texact = act; break; case ID_LS: ((FreestyleLineStyle *)id)->texact = act; break; case ID_PA: ((ParticleSettings *)id)->texact = act; break; } }
int new_id(ListBase *lb, ID *id, const char *tname) { int result; char name[22]; /* if library, don't rename */ if(id->lib) return 0; /* if no libdata given, look up based on ID */ if(lb==NULL) lb= wich_libbase(G.main, GS(id->name)); if(tname==0) { /* if no name given, use name of current ID */ strncpy(name, id->name+2, 21); result= strlen(id->name+2); } else { /* else make a copy (tname args can be const) */ strncpy(name, tname, 21); result= strlen(tname); } /* if result > 21, strncpy don't put the final '\0' to name. */ if( result >= 21 ) name[21]= 0; result = check_for_dupid( lb, id, name ); strcpy( id->name+2, name ); /* This was in 2.43 and previous releases * however all data in blender should be sorted, not just duplicate names * sorting should not hurt, but noting just incause it alters the way other * functions work, so sort every time */ /* if( result ) sort_alpha_id(lb, id);*/ sort_alpha_id(lb, id); return result; }
/* ID should be not NULL */ void BKE_unpack_id(Main *bmain, ID *id, ReportList *reports, int how) { switch (GS(id->name)) { case ID_IM: { Image *ima = (Image *)id; if (BKE_image_has_packedfile(ima)) { unpackImage(bmain, reports, ima, how); } break; } case ID_VF: { VFont *vf = (VFont *)id; if (vf->packedfile) { unpackVFont(bmain, reports, vf, how); } break; } case ID_SO: { bSound *snd = (bSound *)id; if (snd->packedfile) { unpackSound(bmain, reports, snd, how); } break; } case ID_LI: { Library *li = (Library *)id; BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name); break; } default: break; } }
/* Create new action */ static bAction *action_create_new(bContext *C, bAction *oldact) { ScrArea *sa = CTX_wm_area(C); bAction *action; /* create action - the way to do this depends on whether we've got an * existing one there already, in which case we make a copy of it * (which is useful for "versioning" actions within the same file) */ if (oldact && GS(oldact->id.name) == ID_AC) { /* make a copy of the existing action */ action = BKE_action_copy(CTX_data_main(C), oldact); } else { /* just make a new (empty) action */ action = add_empty_action(CTX_data_main(C), "Action"); } /* when creating new ID blocks, there is already 1 user (as for all new datablocks), * but the RNA pointer code will assign all the proper users instead, so we compensate * for that here */ BLI_assert(action->id.us == 1); id_us_min(&action->id); /* set ID-Root type */ if (sa->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sa->spacedata.first; if (saction->mode == SACTCONT_SHAPEKEY) action->idroot = ID_KE; else action->idroot = ID_OB; } return action; }
static bool ED_object_shape_key_remove_all(Main *bmain, Object *ob) { Key *key; key = BKE_key_from_object(ob); if (key == NULL) return false; switch (GS(key->from->name)) { case ID_ME: ((Mesh *)key->from)->key = NULL; break; case ID_CU: ((Curve *)key->from)->key = NULL; break; case ID_LT: ((Lattice *)key->from)->key = NULL; break; } BKE_libblock_free_us(bmain, key); return true; }
/* used everywhere in blenkernel */ void *BKE_libblock_copy_ex(Main *bmain, ID *id) { ID *idn; size_t idn_len; idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2); assert(idn != NULL); idn_len = MEM_allocN_len(idn); if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ const char *cp = (const char *)id; char *cpn = (char *)idn; memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); } id->newid = idn; idn->flag |= LIB_NEW; BKE_libblock_copy_data(idn, id, false); return idn; }
static void rna_ID_update_tag(ID *id, ReportList *reports, int flag) { /* XXX, new function for this! */ /*if (ob->type == OB_FONT) { Curve *cu = ob->data; freedisplist(&cu->disp); BKE_text_to_curve(sce, ob, CU_LEFT); }*/ if(flag == 0) { /* pass */ } else { /* ensure flag us correct for the type */ switch(GS(id->name)) { case ID_OB: if(flag & ~(OB_RECALC_ALL)) { BKE_report(reports, RPT_ERROR, "'refresh' incompatible with Object ID type"); return; } break; /* Could add particle updates later */ /* case ID_PA: if(flag & ~(OB_RECALC_ALL|PSYS_RECALC)) { BKE_report(reports, RPT_ERROR, "'refresh' incompatible with ParticleSettings ID type"); return; } break; */ default: BKE_report(reports, RPT_ERROR, "This ID type is not compatible with any 'refresh' options"); return; } } DAG_id_tag_update(id, flag); }
bool CFlashram::LoadFlashram() { CPath FileName; FileName.SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str()); FileName.SetName(g_Settings->LoadStringVal(Game_GameName).c_str()); FileName.SetExtension("fla"); if (!FileName.DirectoryExists()) { FileName.DirectoryCreate(); } m_hFile = CreateFile(FileName, m_ReadOnly ? GENERIC_READ : GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if (m_hFile == INVALID_HANDLE_VALUE) { WriteTrace(TraceN64System, TraceError, "Failed to open (%s), ReadOnly = %d, LastError = %X", (LPCTSTR)FileName, m_ReadOnly, GetLastError()); g_Notify->DisplayError(GS(MSG_FAIL_OPEN_FLASH)); return false; } SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); return true; }
int ui_id_icon_get(const bContext *C, ID *id, const bool big) { int iconid = 0; /* icon */ switch (GS(id->name)) { case ID_BR: iconid = ui_id_brush_get_icon(C, id); break; case ID_MA: /* fall through */ case ID_TE: /* fall through */ case ID_IM: /* fall through */ case ID_WO: /* fall through */ case ID_LA: /* fall through */ iconid = BKE_icon_id_ensure(id); /* checks if not exists, or changed */ UI_id_icon_render(C, NULL, id, big, true); break; default: break; } return iconid; }
void SetHeroesInTown::applyCl(CClient *cl) { CGTownInstance *t = GS(cl)->getTown(tid); CGHeroInstance *hGarr = GS(cl)->getHero(this->garrison); CGHeroInstance *hVisit = GS(cl)->getHero(this->visiting); //inform all players that see this object for(auto i = cl->playerint.cbegin(); i != cl->playerint.cend(); ++i) { if(i->first >= PlayerColor::PLAYER_LIMIT) continue; if(GS(cl)->isVisible(t, i->first) || (hGarr && GS(cl)->isVisible(hGarr, i->first)) || (hVisit && GS(cl)->isVisible(hVisit, i->first))) { cl->playerint[i->first]->heroInGarrisonChange(t); } } }
void BKE_previewimg_free_id(ID *id) { if (GS(id->name) == ID_MA) { Material *mat = (Material*)id; BKE_previewimg_free(&mat->preview); } else if (GS(id->name) == ID_TE) { Tex *tex = (Tex*)id; BKE_previewimg_free(&tex->preview); } else if (GS(id->name) == ID_WO) { World *wo = (World*)id; BKE_previewimg_free(&wo->preview); } else if (GS(id->name) == ID_LA) { Lamp *la = (Lamp*)id; BKE_previewimg_free(&la->preview); } else if (GS(id->name) == ID_IM) { Image *img = (Image*)id; BKE_previewimg_free(&img->preview); } else if (GS(id->name) == ID_BR) { Brush *br = (Brush*)id; BKE_previewimg_free(&br->preview); } }
PreviewImage *BKE_previewimg_get(ID *id) { PreviewImage *prv_img = NULL; if (GS(id->name) == ID_MA) { Material *mat = (Material *)id; if (!mat->preview) mat->preview = BKE_previewimg_create(); prv_img = mat->preview; } else if (GS(id->name) == ID_TE) { Tex *tex = (Tex *)id; if (!tex->preview) tex->preview = BKE_previewimg_create(); prv_img = tex->preview; } else if (GS(id->name) == ID_WO) { World *wo = (World *)id; if (!wo->preview) wo->preview = BKE_previewimg_create(); prv_img = wo->preview; } else if (GS(id->name) == ID_LA) { Lamp *la = (Lamp *)id; if (!la->preview) la->preview = BKE_previewimg_create(); prv_img = la->preview; } else if (GS(id->name) == ID_IM) { Image *img = (Image *)id; if (!img->preview) img->preview = BKE_previewimg_create(); prv_img = img->preview; } else if (GS(id->name) == ID_BR) { Brush *br = (Brush *)id; if (!br->preview) br->preview = BKE_previewimg_create(); prv_img = br->preview; } return prv_img; }
/** * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c * * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv. */ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user) { ID *id = idv; short type = GS(id->name); ListBase *lb = which_libbase(bmain, type); DAG_id_type_tag(bmain, type); #ifdef WITH_PYTHON BPY_id_release(id); #endif if (do_id_user) { BKE_libblock_relink_ex(bmain, id, NULL, NULL, true); } switch (type) { case ID_SCE: BKE_scene_free((Scene *)id); break; case ID_LI: BKE_library_free((Library *)id); break; case ID_OB: BKE_object_free((Object *)id); break; case ID_ME: BKE_mesh_free((Mesh *)id); break; case ID_CU: BKE_curve_free((Curve *)id); break; case ID_MB: BKE_mball_free((MetaBall *)id); break; case ID_MA: BKE_material_free((Material *)id); break; case ID_TE: BKE_texture_free((Tex *)id); break; case ID_IM: BKE_image_free((Image *)id); break; case ID_LT: BKE_lattice_free((Lattice *)id); break; case ID_LA: BKE_lamp_free((Lamp *)id); break; case ID_CA: BKE_camera_free((Camera *) id); break; case ID_IP: /* Deprecated. */ BKE_ipo_free((Ipo *)id); break; case ID_KE: BKE_key_free((Key *)id); break; case ID_WO: BKE_world_free((World *)id); break; case ID_SCR: BKE_screen_free((bScreen *)id); break; case ID_VF: BKE_vfont_free((VFont *)id); break; case ID_TXT: BKE_text_free((Text *)id); break; case ID_SPK: BKE_speaker_free((Speaker *)id); break; case ID_SO: BKE_sound_free((bSound *)id); break; case ID_GR: BKE_group_free((Group *)id); break; case ID_AR: BKE_armature_free((bArmature *)id); break; case ID_AC: BKE_action_free((bAction *)id); break; case ID_NT: ntreeFreeTree((bNodeTree *)id); break; case ID_BR: BKE_brush_free((Brush *)id); break; case ID_PA: BKE_particlesettings_free((ParticleSettings *)id); break; case ID_WM: if (free_windowmanager_cb) free_windowmanager_cb(NULL, (wmWindowManager *)id); break; case ID_GD: BKE_gpencil_free((bGPdata *)id, true); break; case ID_MC: BKE_movieclip_free((MovieClip *)id); break; case ID_MSK: BKE_mask_free((Mask *)id); break; case ID_LS: BKE_linestyle_free((FreestyleLineStyle *)id); break; case ID_PAL: BKE_palette_free((Palette *)id); break; case ID_PC: BKE_paint_curve_free((PaintCurve *)id); break; case ID_CF: BKE_cachefile_free((CacheFile *)id); break; } /* avoid notifying on removed data */ BKE_main_lock(bmain); if (free_notifier_reference_cb) { free_notifier_reference_cb(id); } if (remap_editor_id_reference_cb) { remap_editor_id_reference_cb(id, NULL); } BLI_remlink(lb, id); BKE_libblock_free_data(bmain, id); BKE_main_unlock(bmain); MEM_freeN(id); }
/** * Replace all references in given Main to \a old_id by \a new_id * (if \a new_id is NULL, it unlinks \a old_id). */ void BKE_libblock_remap_locked( Main *bmain, void *old_idv, void *new_idv, const short remap_flags) { IDRemap id_remap_data; ID *old_id = old_idv; ID *new_id = new_idv; int skipped_direct, skipped_refcounted; BLI_assert(old_id != NULL); BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name)); BLI_assert(old_id != new_id); libblock_remap_data(bmain, NULL, old_id, new_id, remap_flags, &id_remap_data); if (free_notifier_reference_cb) { free_notifier_reference_cb(old_id); } /* We assume editors do not hold references to their IDs... This is false in some cases * (Image is especially tricky here), editors' code is to handle refcount (id->us) itself then. */ if (remap_editor_id_reference_cb) { remap_editor_id_reference_cb(old_id, new_id); } skipped_direct = id_remap_data.skipped_direct; skipped_refcounted = id_remap_data.skipped_refcounted; /* If old_id was used by some ugly 'user_one' stuff (like Image or Clip editors...), and user count has actually * been incremented for that, we have to decrease once more its user count... unless we had to skip * some 'user_one' cases. */ if ((old_id->tag & LIB_TAG_EXTRAUSER_SET) && !(id_remap_data.status & ID_REMAP_IS_USER_ONE_SKIPPED)) { id_us_min(old_id); old_id->tag &= ~LIB_TAG_EXTRAUSER_SET; } BLI_assert(old_id->us - skipped_refcounted >= 0); UNUSED_VARS_NDEBUG(skipped_refcounted); if (skipped_direct == 0) { /* old_id is assumed to not be used directly anymore... */ if (old_id->lib && (old_id->tag & LIB_TAG_EXTERN)) { old_id->tag &= ~LIB_TAG_EXTERN; old_id->tag |= LIB_TAG_INDIRECT; } } /* Some after-process updates. * This is a bit ugly, but cannot see a way to avoid it. Maybe we should do a per-ID callback for this instead? */ switch (GS(old_id->name)) { case ID_OB: libblock_remap_data_postprocess_object_fromgroup_update(bmain, (Object *)old_id, (Object *)new_id); break; case ID_GR: if (!new_id) { /* Only affects us in case group was unlinked. */ for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) { libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, old_id); } } break; case ID_ME: case ID_CU: case ID_MB: if (new_id) { /* Only affects us in case obdata was relinked (changed). */ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { libblock_remap_data_postprocess_obdata_relink(bmain, ob, new_id); } } break; default: break; } /* Full rebuild of DAG! */ DAG_relations_tag_update(bmain); }
/* XXX Arg! Naming... :( * _relink? avoids confusion with _remap, but is confusing with _unlink * _remap_used_ids? * _remap_datablocks? * BKE_id_remap maybe? * ... sigh */ void BKE_libblock_relink_ex( Main *bmain, void *idv, void *old_idv, void *new_idv, const bool us_min_never_null) { ID *id = idv; ID *old_id = old_idv; ID *new_id = new_idv; int remap_flags = us_min_never_null ? 0 : ID_REMAP_SKIP_NEVER_NULL_USAGE; /* No need to lock here, we are only affecting given ID, not bmain database. */ BLI_assert(id); if (old_id) { BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name)); BLI_assert(old_id != new_id); } else { BLI_assert(new_id == NULL); } libblock_remap_data(bmain, id, old_id, new_id, remap_flags, NULL); /* Some after-process updates. * This is a bit ugly, but cannot see a way to avoid it. Maybe we should do a per-ID callback for this instead? */ switch (GS(id->name)) { case ID_SCE: { Scene *sce = (Scene *)id; if (old_id) { switch (GS(old_id->name)) { case ID_OB: { libblock_remap_data_postprocess_object_fromgroup_update( bmain, (Object *)old_id, (Object *)new_id); break; } case ID_GR: if (!new_id) { /* Only affects us in case group was unlinked. */ libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, old_id); } break; default: break; } } else { /* No choice but to check whole objects/groups. */ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { libblock_remap_data_postprocess_object_fromgroup_update(bmain, ob, NULL); } for (Group *grp = bmain->group.first; grp; grp = grp->id.next) { libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, NULL); } } break; } case ID_OB: if (new_id) { /* Only affects us in case obdata was relinked (changed). */ libblock_remap_data_postprocess_obdata_relink(bmain, (Object *)id, new_id); } break; default: break; } }
static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id_p, int cb_flag) { IDRemap *id_remap_data = user_data; ID *old_id = id_remap_data->old_id; ID *new_id = id_remap_data->new_id; ID *id = id_remap_data->id; if (!old_id) { /* Used to cleanup all IDs used by a specific one. */ BLI_assert(!new_id); old_id = *id_p; } if (*id_p && (*id_p == old_id)) { const bool is_indirect = (cb_flag & IDWALK_INDIRECT_USAGE) != 0; const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0; /* Note: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct, * on the other hand since they get reset to lib data on file open/reload it is indirect too... * Edit Mode is also a 'skip direct' case. */ const bool is_obj = (GS(id->name) == ID_OB); const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id)); const bool is_never_null = ((cb_flag & IDWALK_NEVER_NULL) && (new_id == NULL) && (id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0); const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0; #ifdef DEBUG_PRINT printf("In %s: Remapping %s (%p) to %s (%p) (skip_indirect: %d)\n", id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, skip_indirect); #endif if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_NEVER_NULL)) { id->tag |= LIB_TAG_DOIT; } /* Special hack in case it's Object->data and we are in edit mode (skipped_direct too). */ if ((is_never_null && skip_never_null) || (is_obj_editmode && (((Object *)id)->data == *id_p)) || (skip_indirect && is_indirect)) { if (is_indirect) { id_remap_data->skipped_indirect++; } else if (is_never_null || is_obj_editmode) { id_remap_data->skipped_direct++; } else { BLI_assert(0); } if (cb_flag & IDWALK_USER) { id_remap_data->skipped_refcounted++; } else if (cb_flag & IDWALK_USER_ONE) { /* No need to count number of times this happens, just a flag is enough. */ id_remap_data->status |= ID_REMAP_IS_USER_ONE_SKIPPED; } } else { if (!is_never_null) { *id_p = new_id; DAG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } if (cb_flag & IDWALK_USER) { id_us_min(old_id); /* We do not want to handle LIB_TAG_INDIRECT/LIB_TAG_EXTERN here. */ if (new_id) new_id->us++; } else if (cb_flag & IDWALK_USER_ONE) { id_us_ensure_real(new_id); /* We cannot affect old_id->us directly, LIB_TAG_EXTRAUSER(_SET) are assumed to be set as needed, * that extra user is processed in final handling... */ } if (!is_indirect) { id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT; } } } return IDWALK_RET_NOP; }
/** * Execute the 'data' part of the remapping (that is, all ID pointers from other ID datablocks). * * Behavior differs depending on whether given \a id is NULL or not: * - \a id NULL: \a old_id must be non-NULL, \a new_id may be NULL (unlinking \a old_id) or not * (remapping \a old_id to \a new_id). The whole \a bmain database is checked, and all pointers to \a old_id * are remapped to \a new_id. * - \a id is non-NULL: * + If \a old_id is NULL, \a new_id must also be NULL, and all ID pointers from \a id are cleared (i.e. \a id * does not references any other datablock anymore). * + If \a old_id is non-NULL, behavior is as with a NULL \a id, but only within given \a id. * * \param bmain: the Main data storage to operate on (must never be NULL). * \param id: the datablock to operate on (can be NULL, in which case we operate over all IDs from given bmain). * \param old_id: the datablock to dereference (may be NULL if \a id is non-NULL). * \param new_id: the new datablock to replace \a old_id references with (may be NULL). * \param r_id_remap_data: if non-NULL, the IDRemap struct to use (uselful to retrieve info about remapping process). */ ATTR_NONNULL(1) static void libblock_remap_data( Main *bmain, ID *id, ID *old_id, ID *new_id, const short remap_flags, IDRemap *r_id_remap_data) { IDRemap id_remap_data; ListBase *lb_array[MAX_LIBARRAY]; int i; if (r_id_remap_data == NULL) { r_id_remap_data = &id_remap_data; } r_id_remap_data->bmain = bmain; r_id_remap_data->old_id = old_id; r_id_remap_data->new_id = new_id; r_id_remap_data->id = NULL; r_id_remap_data->flag = remap_flags; r_id_remap_data->status = 0; r_id_remap_data->skipped_direct = 0; r_id_remap_data->skipped_indirect = 0; r_id_remap_data->skipped_refcounted = 0; if (id) { #ifdef DEBUG_PRINT printf("\tchecking id %s (%p, %p)\n", id->name, id, id->lib); #endif r_id_remap_data->id = id; libblock_remap_data_preprocess(r_id_remap_data); BKE_library_foreach_ID_link(id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); } else { i = set_listbasepointers(bmain, lb_array); /* Note that this is a very 'bruteforce' approach, maybe we could use some depsgraph to only process * objects actually using given old_id... sounds rather unlikely currently, though, so this will do for now. */ while (i--) { ID *id_curr = lb_array[i]->first; if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(old_id->name))) { continue; } for (; id_curr; id_curr = id_curr->next) { /* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for * the user count handling... * XXX No more true (except for debug usage of those skipping counters). */ r_id_remap_data->id = id_curr; libblock_remap_data_preprocess(r_id_remap_data); BKE_library_foreach_ID_link( id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP); } } } if (old_id && GS(old_id->name) == ID_OB) { BKE_sca_logic_links_remap(bmain, (Object *)old_id, (Object *)new_id); } /* XXX We may not want to always 'transfer' fakeuser from old to new id... Think for now it's desired behavior * though, we can always add an option (flag) to control this later if needed. */ if (old_id && (old_id->flag & LIB_FAKEUSER)) { id_fake_user_clear(old_id); id_fake_user_set(new_id); } id_us_clear_real(old_id); if (new_id && (new_id->tag & LIB_TAG_INDIRECT) && (r_id_remap_data->status & ID_REMAP_IS_LINKED_DIRECT)) { new_id->tag &= ~LIB_TAG_INDIRECT; new_id->tag |= LIB_TAG_EXTERN; } #ifdef DEBUG_PRINT printf("%s: %d occurences skipped (%d direct and %d indirect ones)\n", __func__, r_id_remap_data->skipped_direct + r_id_remap_data->skipped_indirect, r_id_remap_data->skipped_direct, r_id_remap_data->skipped_indirect); #endif }
ID *find_id(const char *type, const char *name) /* type: "OB" or "MA" etc */ { ListBase *lb= which_libbase(G.main, GS(type)); return BLI_findstring(lb, name, offsetof(ID, name) + 2); }
/* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */ void free_libblock(ListBase *lb, void *idv) { ID *id= idv; #ifdef WITH_PYTHON BPY_id_release(id); #endif switch( GS(id->name) ) { /* GetShort from util.h */ case ID_SCE: free_scene((Scene *)id); break; case ID_LI: free_library((Library *)id); break; case ID_OB: free_object((Object *)id); break; case ID_ME: free_mesh((Mesh *)id); break; case ID_CU: free_curve((Curve *)id); break; case ID_MB: free_mball((MetaBall *)id); break; case ID_MA: free_material((Material *)id); break; case ID_TE: free_texture((Tex *)id); break; case ID_IM: free_image((Image *)id); break; case ID_LT: free_lattice((Lattice *)id); break; case ID_LA: free_lamp((Lamp *)id); break; case ID_CA: free_camera((Camera*) id); break; case ID_IP: free_ipo((Ipo *)id); break; case ID_KE: free_key((Key *)id); break; case ID_WO: free_world((World *)id); break; case ID_SCR: free_screen((bScreen *)id); break; case ID_VF: free_vfont((VFont *)id); break; case ID_TXT: free_text((Text *)id); break; case ID_SCRIPT: //XXX free_script((Script *)id); break; case ID_SPK: free_speaker((Speaker *)id); break; case ID_SO: sound_free((bSound*)id); break; case ID_GR: free_group_objects((Group *)id); break; case ID_AR: free_armature((bArmature *)id); break; case ID_AC: free_action((bAction *)id); break; case ID_NT: ntreeFreeTree((bNodeTree *)id); break; case ID_BR: free_brush((Brush *)id); break; case ID_PA: psys_free_settings((ParticleSettings *)id); break; case ID_WM: if(free_windowmanager_cb) free_windowmanager_cb(NULL, (wmWindowManager *)id); break; case ID_GD: free_gpencil_data((bGPdata *)id); break; } if (id->properties) { IDP_FreeProperty(id->properties); MEM_freeN(id->properties); } BLI_remlink(lb, id); /* this ID may be a driver target! */ BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id); MEM_freeN(id); }
int id_copy(ID *id, ID **newid, int test) { if(!test) *newid= NULL; /* conventions: * - make shallow copy, only this ID block * - id.us of the new ID is set to 1 */ switch(GS(id->name)) { case ID_SCE: return 0; /* can't be copied from here */ case ID_LI: return 0; /* can't be copied from here */ case ID_OB: if(!test) *newid= (ID*)copy_object((Object*)id); return 1; case ID_ME: if(!test) *newid= (ID*)copy_mesh((Mesh*)id); return 1; case ID_CU: if(!test) *newid= (ID*)copy_curve((Curve*)id); return 1; case ID_MB: if(!test) *newid= (ID*)copy_mball((MetaBall*)id); return 1; case ID_MA: if(!test) *newid= (ID*)copy_material((Material*)id); return 1; case ID_TE: if(!test) *newid= (ID*)copy_texture((Tex*)id); return 1; case ID_IM: if(!test) *newid= (ID*)copy_image((Image*)id); return 1; case ID_LT: if(!test) *newid= (ID*)copy_lattice((Lattice*)id); return 1; case ID_LA: if(!test) *newid= (ID*)copy_lamp((Lamp*)id); return 1; case ID_SPK: if(!test) *newid= (ID*)copy_speaker((Speaker*)id); return 1; case ID_CA: if(!test) *newid= (ID*)copy_camera((Camera*)id); return 1; case ID_IP: return 0; /* deprecated */ case ID_KE: if(!test) *newid= (ID*)copy_key((Key*)id); return 1; case ID_WO: if(!test) *newid= (ID*)copy_world((World*)id); return 1; case ID_SCR: return 0; /* can't be copied from here */ case ID_VF: return 0; /* not implemented */ case ID_TXT: if(!test) *newid= (ID*)copy_text((Text*)id); return 1; case ID_SCRIPT: return 0; /* deprecated */ case ID_SO: return 0; /* not implemented */ case ID_GR: if(!test) *newid= (ID*)copy_group((Group*)id); return 1; case ID_AR: if(!test) *newid= (ID*)copy_armature((bArmature*)id); return 1; case ID_AC: if(!test) *newid= (ID*)copy_action((bAction*)id); return 1; case ID_NT: if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id); return 1; case ID_BR: if(!test) *newid= (ID*)copy_brush((Brush*)id); return 1; case ID_PA: if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id); return 1; case ID_WM: return 0; /* can't be copied from here */ case ID_GD: return 0; /* not implemented */ } return 0; }
int id_make_local(ID *id, int test) { if(id->flag & LIB_INDIRECT) return 0; switch(GS(id->name)) { case ID_SCE: return 0; /* not implemented */ case ID_LI: return 0; /* can't be linked */ case ID_OB: if(!test) make_local_object((Object*)id); return 1; case ID_ME: if(!test) { make_local_mesh((Mesh*)id); make_local_key(((Mesh*)id)->key); } return 1; case ID_CU: if(!test) { make_local_curve((Curve*)id); make_local_key(((Curve*)id)->key); } return 1; case ID_MB: if(!test) make_local_mball((MetaBall*)id); return 1; case ID_MA: if(!test) make_local_material((Material*)id); return 1; case ID_TE: if(!test) make_local_texture((Tex*)id); return 1; case ID_IM: return 0; /* not implemented */ case ID_LT: if(!test) { make_local_lattice((Lattice*)id); make_local_key(((Lattice*)id)->key); } return 1; case ID_LA: if(!test) make_local_lamp((Lamp*)id); return 1; case ID_CA: if(!test) make_local_camera((Camera*)id); return 1; case ID_SPK: if(!test) make_local_speaker((Speaker*)id); return 1; case ID_IP: return 0; /* deprecated */ case ID_KE: if(!test) make_local_key((Key*)id); return 1; case ID_WO: if(!test) make_local_world((World*)id); return 1; case ID_SCR: return 0; /* can't be linked */ case ID_VF: return 0; /* not implemented */ case ID_TXT: return 0; /* not implemented */ case ID_SCRIPT: return 0; /* deprecated */ case ID_SO: return 0; /* not implemented */ case ID_GR: return 0; /* not implemented */ case ID_AR: if(!test) make_local_armature((bArmature*)id); return 1; case ID_AC: if(!test) make_local_action((bAction*)id); return 1; case ID_NT: return 0; /* not implemented */ case ID_BR: if(!test) make_local_brush((Brush*)id); return 1; case ID_PA: if(!test) make_local_particlesettings((ParticleSettings*)id); return 1; case ID_WM: return 0; /* can't be linked */ case ID_GD: return 0; /* not implemented */ } return 0; }
static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { ID *id = ptr->id.data; if (GS(id->name) == ID_IM) { Image *ima = (Image *) id; DAG_id_tag_update(&ima->id, 0); BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE); WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id); } else if (GS(id->name) == ID_MC) { MovieClip *clip = (MovieClip *) id; BKE_movieclip_reload(clip); /* all sequencers for now, we don't know which scenes are using this clip as a strip */ BKE_sequencer_cache_cleanup(); BKE_sequencer_preprocessed_cache_cleanup(); WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, &clip->id); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, &clip->id); } else if (GS(id->name) == ID_SCE) { Scene *scene = (Scene *) id; if (scene->ed) { ColorManagedColorspaceSettings *colorspace_settings = (ColorManagedColorspaceSettings *) ptr->data; Sequence *seq; bool seq_found = false; if (&scene->sequencer_colorspace_settings != colorspace_settings) { SEQ_BEGIN(scene->ed, seq); { if (seq->strip && &seq->strip->colorspace_settings == colorspace_settings) { seq_found = true; break; } } SEQ_END; } if (seq_found) { BKE_sequence_free_anim(seq); if (seq->strip->proxy && seq->strip->proxy->anim) { IMB_free_anim(seq->strip->proxy->anim); seq->strip->proxy->anim = NULL; } BKE_sequence_invalidate_cache(scene, seq); BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); } else { SEQ_BEGIN(scene->ed, seq); { BKE_sequence_free_anim(seq); } SEQ_END; BKE_sequencer_cache_cleanup(); BKE_sequencer_preprocessed_cache_cleanup(); } WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); } } }