Example #1
0
/**
 * Pull an ID out of a library (make it local). Only call this for IDs that
 * don't have other library users.
 */
void id_clear_lib_data(Main *bmain, ID *id)
{
	bNodeTree *ntree = NULL;

	BKE_id_lib_local_paths(bmain, id->lib, id);

	if (id->flag & LIB_FAKEUSER) {
		id->us--;
		id->flag &= ~LIB_FAKEUSER;
	}

	id->lib = NULL;
	id->flag = LIB_LOCAL;
	new_id(which_libbase(bmain, GS(id->name)), id, NULL);

	/* internal bNodeTree blocks inside ID types below
	 * also stores id->lib, make sure this stays in sync.
	 */
	switch (GS(id->name)) {
		case ID_SCE:	ntree = ((Scene *)id)->nodetree;		break;
		case ID_MA:		ntree = ((Material *)id)->nodetree;		break;
		case ID_LA:		ntree = ((Lamp *)id)->nodetree;			break;
		case ID_WO:		ntree = ((World *)id)->nodetree;		break;
		case ID_TE:		ntree = ((Tex *)id)->nodetree;			break;
	}
	if (ntree)
		ntree->id.lib = NULL;
}
Example #2
0
int id_unlink(ID *id, int test)
{
	Main *mainlib= G.main;
	ListBase *lb;

	switch(GS(id->name)) {
		case ID_TXT:
			if(test) return 1;
			unlink_text(mainlib, (Text*)id);
			break;
		case ID_GR:
			if(test) return 1;
			unlink_group((Group*)id);
			break;
		case ID_OB:
			if(test) return 1;
			unlink_object((Object*)id);
			break;
	}

	if(id->us == 0) {
		if(test) return 1;

		lb= which_libbase(mainlib, GS(id->name));
		free_libblock(lb, id);

		return 1;
	}

	return 0;
}
Example #3
0
/**
 * Rename if the ID doesn't exist.
 */
static ID *rename_id_for_versioning(Main *bmain,
                                    const short id_type,
                                    const char *name_src,
                                    const char *name_dst)
{
  /* We can ignore libraries */
  ListBase *lb = which_libbase(bmain, id_type);
  ID *id = NULL;
  for (ID *idtest = lb->first; idtest; idtest = idtest->next) {
    if (idtest->lib == NULL) {
      if (STREQ(idtest->name + 2, name_src)) {
        id = idtest;
      }
      if (STREQ(idtest->name + 2, name_dst)) {
        return NULL;
      }
    }
  }
  if (id != NULL) {
    BLI_strncpy(id->name + 2, name_dst, sizeof(id->name) - 2);
    /* We know it's unique, this just sorts. */
    BLI_libblock_ensure_unique_name(bmain, id->name);
  }
  return id;
}
Example #4
0
/* used everywhere in blenkernel */
void *BKE_libblock_copy_ex(Main *bmain, ID *id)
{
	ID *idn;
	ListBase *lb;
	size_t idn_len;

	lb = which_libbase(bmain, GS(id->name));
	idn = BKE_libblock_alloc(lb, 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;
}
Example #5
0
bool id_unlink(ID *id, int test)
{
	Main *mainlib = G.main;
	ListBase *lb;

	switch (GS(id->name)) {
		case ID_TXT:
			if (test) return true;
			BKE_text_unlink(mainlib, (Text *)id);
			break;
		case ID_GR:
			if (test) return true;
			BKE_group_unlink((Group *)id);
			break;
		case ID_OB:
			if (test) return true;
			BKE_object_unlink((Object *)id);
			break;
	}

	if (id->us == 0) {
		if (test) return true;

		lb = which_libbase(mainlib, GS(id->name));
		BKE_libblock_free(lb, id);

		return true;
	}

	return false;
}
Example #6
0
/* used everywhere in blenkernel */
void *copy_libblock(void *rt)
{
	ID *idn, *id;
	ListBase *lb;
	char *cp, *cpn;
	size_t idn_len;
	
	id= rt;

	lb= which_libbase(G.main, GS(id->name));
	idn= alloc_libblock(lb, 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 */
		cp= (char *)id;
		cpn= (char *)idn;
		memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
	}
	
	id->newid= idn;
	idn->flag |= LIB_NEW;

	copy_libblock_data(idn, id, FALSE);
	
	return idn;
}
Example #7
0
/* Pull an ID out of a library (make it local). Only call this for IDs that
 * don't have other library users. */
void id_clear_lib_data(Main *bmain, ID *id)
{
    BKE_id_lib_local_paths(bmain, id->lib, id);

    id->lib = NULL;
    id->flag = LIB_LOCAL;
    new_id(which_libbase(bmain, GS(id->name)), id, NULL);
}
Example #8
0
void rename_id(ID *id, const char *name)
{
	ListBase *lb;

	BLI_strncpy(id->name+2, name, sizeof(id->name)-2);
	lb= which_libbase(G.main, GS(id->name) );
	
	new_id(lb, id, name);				
}
Example #9
0
void test_idbutton(char *name)
{
	/* called from buttons: when name already exists: call new_id */
	ListBase *lb;
	ID *idtest;
	

	lb= which_libbase(G.main, GS(name-2) );
	if(lb==NULL) return;
	
	/* search for id */
	idtest= BLI_findstring(lb, name, offsetof(ID, name) + 2);

	if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
}
Example #10
0
int new_id(ListBase *lb, ID *id, const char *tname)
{
    int result;
    char name[MAX_ID_NAME - 2];

    /* if library, don't rename */
    if (id->lib) return 0;

    /* if no libdata given, look up based on ID */
    if (lb == NULL) lb = which_libbase(G.main, GS(id->name));

    /* if no name given, use name of current ID
     * else make a copy (tname args can be const) */
    if (tname == NULL)
        tname = id->name + 2;

    strncpy(name, tname, sizeof(name) - 1);

    /* if result > MAX_ID_NAME-3, strncpy don't put the final '\0' to name.
     * easier to assign each time then to check if its needed */
    name[sizeof(name) - 1] = 0;

    if (name[0] == '\0') {
        /* disallow empty names */
        strcpy(name, ID_FALLBACK_NAME);
    }
    else {
        /* disallow non utf8 chars,
         * the interface checks for this but new ID's based on file names don't */
        BLI_utf8_invalid_strip(name, strlen(name));
    }

    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 0
    if (result)
        id_sort_by_name(lb, id);
#endif

    id_sort_by_name(lb, id);

    return result;
}
Example #11
0
/**
 * Allocates and returns a block of the specified type, with the specified name
 * (adjusted as necessary to ensure uniqueness), and appended to the specified list.
 * The user count is set to 1, all other content (apart from name and links) being
 * initialized to zero.
 */
void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
{
	ID *id = NULL;
	ListBase *lb = which_libbase(bmain, type);
	
	id = alloc_libblock_notest(type);
	if (id) {
		BLI_addtail(lb, id);
		id->us = 1;
		id->icon_id = 0;
		*( (short *)id->name) = type;
		new_id(lb, id, name);
		/* alphabetic insertion: is in new_id */
	}
	DAG_id_type_tag(bmain, type);
	return id;
}
Example #12
0
/* medium match strictness: path match only (i.e. ignore ID) */
static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
{
	tAnimCopybufItem *aci;

	for (aci= animcopybuf.first; aci; aci= aci->next) {
		/* check that paths exist */
		if (aci->rna_path && fcu->rna_path) {
			/* find the property of the fcurve and compare against the end of the tAnimCopybufItem
			 * more involved since it needs to to path lookups.
			 * This is not 100% reliable since the user could be editing the curves on a path that wont
			 * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
			 * this should work out ok. 
			 */
			if (BLI_findindex(which_libbase(G.main, aci->id_type), aci->id) == -1) {
				/* pedantic but the ID could have been removed, and beats crashing! */
				printf("paste_animedit_keys: error ID has been removed!\n");
			}
			else {
				PointerRNA id_ptr, rptr;
				PropertyRNA *prop;
				
				RNA_id_pointer_create(aci->id, &id_ptr);
				RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop);
				
				if (prop) {
					const char *identifier= RNA_property_identifier(prop);
					int len_id = strlen(identifier);
					int len_path = strlen(fcu->rna_path);
					if (len_id <= len_path) {
						/* note, paths which end with "] will fail with this test - Animated ID Props */
						if (strcmp(identifier, fcu->rna_path + (len_path-len_id))==0) {
							if ((from_single) || (aci->array_index == fcu->array_index))
								break;
						}
					}
				}
				else {
					printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n", aci->id->name, aci->rna_path);
				}
			}
		}
	}

	return aci;
}
Example #13
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.
 *                    (only applies to main database)
 * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
 *                    \a id.
 */
void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_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);
	}

	BKE_libblock_free_datablock(id, 0);

	/* avoid notifying on removed data */
	BKE_main_lock(bmain);

	if (do_ui_user) {
		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(id, do_id_user);
	BKE_main_unlock(bmain);

	MEM_freeN(id);
}
Example #14
0
void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const bool tag)
{
	ListBase *lb = which_libbase(mainvar, type);

	BKE_main_id_tag_listbase(lb, tag);
}
Example #15
0
void tag_main_idcode(struct Main *mainvar, const short type, const short tag)
{
	ListBase *lb= which_libbase(mainvar, type);

	tag_main_lb(lb, tag);
}
Example #16
0
void filelist_from_main(struct FileList *filelist)
{
	ID *id;
	struct direntry *files, *firstlib = NULL;
	ListBase *lb;
	int a, fake, idcode, ok, totlib, totbl;
	
	// filelist->type = FILE_MAIN; // XXXXX TODO: add modes to filebrowser

	if (filelist->dir[0]=='/') filelist->dir[0]= 0;
	
	if (filelist->dir[0]) {
		idcode= groupname_to_code(filelist->dir);
		if (idcode==0) filelist->dir[0]= 0;
	}
	
	if ( filelist->dir[0]==0) {
		
		/* make directories */
		filelist->numfiles= 24;
		filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
		
		for (a=0; a<filelist->numfiles; a++) {
			memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry));
			filelist->filelist[a].type |= S_IFDIR;
		}
		
		filelist->filelist[0].relname= BLI_strdup("..");
		filelist->filelist[2].relname= BLI_strdup("Scene");
		filelist->filelist[3].relname= BLI_strdup("Object");
		filelist->filelist[4].relname= BLI_strdup("Mesh");
		filelist->filelist[5].relname= BLI_strdup("Curve");
		filelist->filelist[6].relname= BLI_strdup("Metaball");
		filelist->filelist[7].relname= BLI_strdup("Material");
		filelist->filelist[8].relname= BLI_strdup("Texture");
		filelist->filelist[9].relname= BLI_strdup("Image");
		filelist->filelist[10].relname= BLI_strdup("Ika");
		filelist->filelist[11].relname= BLI_strdup("Wave");
		filelist->filelist[12].relname= BLI_strdup("Lattice");
		filelist->filelist[13].relname= BLI_strdup("Lamp");
		filelist->filelist[14].relname= BLI_strdup("Camera");
		filelist->filelist[15].relname= BLI_strdup("Ipo");
		filelist->filelist[16].relname= BLI_strdup("World");
		filelist->filelist[17].relname= BLI_strdup("Screen");
		filelist->filelist[18].relname= BLI_strdup("VFont");
		filelist->filelist[19].relname= BLI_strdup("Text");
		filelist->filelist[20].relname= BLI_strdup("Armature");
		filelist->filelist[21].relname= BLI_strdup("Action");
		filelist->filelist[22].relname= BLI_strdup("NodeTree");
		filelist->filelist[23].relname= BLI_strdup("Speaker");
		filelist_sort(filelist, FILE_SORT_ALPHA);
	}
	else {

		/* make files */
		idcode= groupname_to_code(filelist->dir);
		
		lb= which_libbase(G.main, idcode );
		if (lb == NULL) return;
		
		id= lb->first;
		filelist->numfiles= 0;
		while (id) {
			if (!filelist->hide_dot || id->name[2] != '.') {
				filelist->numfiles++;
			}
			
			id= id->next;
		}
		
		/* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */
		if (!filelist->hide_parent) filelist->numfiles+= 1;
		filelist->filelist= filelist->numfiles > 0 ? (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)) : NULL;

		files = filelist->filelist;
		
		if (!filelist->hide_parent) {
			memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry));
			filelist->filelist[0].relname= BLI_strdup("..");
			filelist->filelist[0].type |= S_IFDIR;
		
			files++;
		}
		
		id= lb->first;
		totlib= totbl= 0;
		
		while (id) {
			ok = 1;
			if (ok) {
				if (!filelist->hide_dot || id->name[2] != '.') {
					memset( files, 0 , sizeof(struct direntry));
					if (id->lib==NULL)
						files->relname= BLI_strdup(id->name+2);
					else {
						files->relname= MEM_mallocN(FILE_MAX+32, "filename for lib");
						sprintf(files->relname, "%s | %s", id->lib->name, id->name+2);
					}
					files->type |= S_IFREG;
#if 0				// XXXXX TODO show the selection status of the objects
					if (!filelist->has_func) { /* F4 DATA BROWSE */
						if (idcode==ID_OB) {
							if ( ((Object *)id)->flag & SELECT) files->selflag |= SELECTED_FILE;
						}
						else if (idcode==ID_SCE) {
							if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE;
						}					
					}
#endif
					files->nr= totbl+1;
					files->poin= id;
					fake= id->flag & LIB_FAKEUSER;
					if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
						files->flags |= IMAGEFILE;
					}
					if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us);
					else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L    %d", id->us);
					else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F    %d", id->us);
					else BLI_snprintf(files->extra, sizeof(files->extra), "      %d", id->us);
					
					if (id->lib) {
						if (totlib==0) firstlib= files;
						totlib++;
					}
					
					files++;
				}
				totbl++;
			}
			
			id= id->next;
		}
		
		/* only qsort of library blocks */
		if (totlib>1) {
			qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
		}
	}
	filelist->filter = 0;
	filelist_filter(filelist);
}
Example #17
0
ID *BKE_libblock_find_name(const short type, const char *name)      /* type: "OB" or "MA" etc */
{
    ListBase *lb = which_libbase(G.main, type);
    BLI_assert(lb != NULL);
    return BLI_findstring(lb, name, offsetof(ID, name) + 2);
}
Example #18
0
void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
{
	ID *id = idv;

	if (use_flag_from_idtag) {
		if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
			flag |= LIB_ID_FREE_NO_MAIN;
		}
		else {
			flag &= ~LIB_ID_FREE_NO_MAIN;
		}

		if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
			flag |= LIB_ID_FREE_NO_USER_REFCOUNT;
		}
		else {
			flag &= ~LIB_ID_FREE_NO_USER_REFCOUNT;
		}

		if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
			flag |= LIB_ID_FREE_NOT_ALLOCATED;
		}
		else {
			flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
		}
	}

	BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
	BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
	BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);

	const short type = GS(id->name);

	if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
		DAG_id_type_tag(bmain, type);
	}

#ifdef WITH_PYTHON
	BPY_id_release(id);
#endif

	if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
		BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
	}

	BKE_libblock_free_datablock(id, flag);

	/* avoid notifying on removed data */
	if (bmain) {
		BKE_main_lock(bmain);
	}

	if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
		if (free_notifier_reference_cb) {
			free_notifier_reference_cb(id);
		}

		if (remap_editor_id_reference_cb) {
			remap_editor_id_reference_cb(id, NULL);
		}
	}

	if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
		ListBase *lb = which_libbase(bmain, type);
		BLI_remlink(lb, id);
	}

	BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);

	if (bmain) {
		BKE_main_unlock(bmain);
	}

	if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
		MEM_freeN(id);
	}
}
Example #19
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);
}
Example #20
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);
}
Example #21
0
/* ***************** ID ************************ */
ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const char *name)
{
	ListBase *lb = which_libbase(bmain, type);
	BLI_assert(lb != NULL);
	return BLI_findstring(lb, name, offsetof(ID, name) + 2);
}