Exemple #1
0
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;
	}
}
Exemple #2
0
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);
	}
}
Exemple #3
0
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;
}
Exemple #5
0
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$]
}
Exemple #6
0
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());
}
Exemple #8
0
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");
}
Exemple #9
0
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;
	}
}
Exemple #10
0
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;
}
Exemple #11
0
/* 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;
	}
}
Exemple #12
0
/* 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;
}
Exemple #13
0
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;
}
Exemple #14
0
/* 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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #18
0
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);
		}
	}
}
Exemple #19
0
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);
	}
}
Exemple #20
0
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;
}
Exemple #21
0
/**
 * 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);
}
Exemple #22
0
/**
 * 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);
}
Exemple #23
0
/* 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;
	}
}
Exemple #24
0
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;
}
Exemple #25
0
/**
 * 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
}
Exemple #26
0
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);
}
Exemple #27
0
/* 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);
}
Exemple #28
0
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;
}
Exemple #29
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;
}
Exemple #30
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);
		}
	}
}