Beispiel #1
0
static void rna_ID_user_remap(ID *id, Main *bmain, ID *new_id)
{
	if (GS(id->name) == GS(new_id->name)) {
		/* For now, do not allow remapping data in linked data from here... */
		BKE_libblock_remap(bmain, id, new_id, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
	}
}
Beispiel #2
0
void BKE_libblock_delete(Main *bmain, void *idv)
{
	ListBase *lbarray[MAX_LIBARRAY];
	int base_count, i;

	base_count = set_listbasepointers(bmain, lbarray);
	BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);

	/* First tag all datablocks directly from target lib.
	 * Note that we go forward here, since we want to check dependencies before users (e.g. meshes before objects).
	 * Avoids to have to loop twice. */
	for (i = 0; i < base_count; i++) {
		ListBase *lb = lbarray[i];
		ID *id;

		for (id = lb->first; id; id = id->next) {
			/* Note: in case we delete a library, we also delete all its datablocks! */
			if ((id == (ID *)idv) || (id->lib == (Library *)idv) || (id->tag & LIB_TAG_DOIT)) {
				id->tag |= LIB_TAG_DOIT;
				/* Will tag 'never NULL' users of this ID too.
				 * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect (and proxy!)
				 * links, this can lead to nasty crashing here in second, actual deleting loop.
				 * Also, this will also flag users of deleted data that cannot be unlinked
				 * (object using deleted obdata, etc.), so that they also get deleted. */
				BKE_libblock_remap(bmain, id, NULL, ID_REMAP_FLAG_NEVER_NULL_USAGE | ID_REMAP_FORCE_NEVER_NULL_USAGE);
			}
		}
	}

	/* In usual reversed order, such that all usage of a given ID, even 'never NULL' ones, have been already cleared
	 * when we reach it (e.g. Objects being processed before meshes, they'll have already released their 'reference'
	 * over meshes when we come to freeing obdata). */
	for (i = base_count; i--; ) {
		ListBase *lb = lbarray[i];
		ID *id, *id_next;

		for (id = lb->first; id; id = id_next) {
			id_next = id->next;
			if (id->tag & LIB_TAG_DOIT) {
				if (id->us != 0) {
#ifdef DEBUG_PRINT
					printf("%s: deleting %s (%d)\n", __func__, id->name, id->us);
#endif
					BLI_assert(id->us == 0);
				}
				BKE_libblock_free(bmain, id);
			}
		}
	}
}
Beispiel #3
0
void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
{
	bool is_local = false, is_lib = false;

	/* - only lib users: do nothing (unless force_local is set)
	 * - only local users: set flag
	 * - mixed: make copy
	 */

	if (!ID_IS_LINKED_DATABLOCK(brush)) {
		return;
	}

	if (brush->clone.image) {
		/* Special case: ima always local immediately. Clone image should only have one user anyway. */
		id_make_local(bmain, &brush->clone.image->id, false, false);
	}

	BKE_library_ID_test_usages(bmain, brush, &is_local, &is_lib);

	if (lib_local || is_local) {
		if (!is_lib) {
			id_clear_lib_data(bmain, &brush->id);
			BKE_id_expand_local(&brush->id);

			/* enable fake user by default */
			id_fake_user_set(&brush->id);
		}
		else {
			Brush *brush_new = BKE_brush_copy(bmain, brush);  /* Ensures FAKE_USER is set */

			brush_new->id.us = 0;

			/* setting newid is mandatory for complex make_lib_local logic... */
			ID_NEW_SET(brush, brush_new);

			if (!lib_local) {
				BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
			}
		}
	}
}