28#include <fmt/format.h>
33#define DNA_DEPRECATED_ALLOW
121#define U (*((const UserDef *)&U))
180#define USE_BHEAD_READ_ON_DEMAND
185#if ENDIAN_ORDER == B_ENDIAN
186# warning "Support for Big Endian endianness is deprecated and will be removed in Blender 5.0"
196#ifdef USE_BHEAD_READ_ON_DEMAND
206#define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -int(offsetof(BHeadN, bhead))))
212#define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == BLO_CODE_DATA)
223 char fixed_buf[1024];
228 vsnprintf(fixed_buf,
sizeof(fixed_buf),
format, args);
231 fixed_buf[
sizeof(fixed_buf) - 1] =
'\0';
235 if (
G.background == 0) {
243 return lib->runtime->parent ?
lib->runtime->parent->runtime->filepath_abs :
"<direct>";
265 return MEM_new<OldNewMap>(__func__);
274 if (oldaddr ==
nullptr || newaddr ==
nullptr) {
297 if (entry ==
nullptr) {
300 if (increase_users) {
309 if (addr ==
nullptr) {
327 if (new_addr.nr == 0) {
353 int a = fromarray.size();
370 if (bmain->
id_map !=
nullptr) {
379 if (tojoin == bmain) {
395 const bool do_split_packed_ids)
397 for (
ID *
id =
static_cast<ID *
>(lb_src->
first), *idnext;
id;
id = idnext) {
398 idnext =
static_cast<ID *
>(
id->next);
401 if (
uint(id->lib->runtime->temp_index) < lib_main_array.
size()) {
402 Main *mainvar = lib_main_array[
id->lib->runtime->temp_index];
418 bmain->
split_mains = std::make_shared<blender::VectorSet<Main *>>();
425 if (bmain->
id_map !=
nullptr) {
455 lib->runtime->temp_index = lib_index;
456 lib_main_array.
append(libmain);
463 ID *
id =
static_cast<ID *
>(lbarray[
i]->first);
504 main->curlib->runtime->versionfile =
main->versionfile;
505 main->curlib->runtime->subversionfile =
main->subversionfile;
508 main->curlib->runtime->colorspace =
main->colorspace;
516 return bhead->
code <= 0xFFFF;
525 const short id_type_code = bhead->
code & 0xFFFF;
532 bool is_link =
false;
537 if (code_prev != bhead->code) {
538 code_prev = bhead->code;
567 "A critical error happened (the blend file is likely corrupted): %s",
594 BHeadN *new_bhead =
nullptr;
600 BHead *bhead =
nullptr;
601 if (!bhead_opt.has_value()) {
604 else if (bhead_opt->len < 0) {
609 bhead = &bhead_opt.value();
618#ifdef USE_BHEAD_READ_ON_DEMAND
623 new_bhead->
next = new_bhead->
prev =
nullptr;
627 new_bhead->
bhead = *bhead;
628 const off64_t seek_new = fd->
file->
seek(fd->
file, bhead->
len, SEEK_CUR);
644 new_bhead =
static_cast<BHeadN *
>(
647 new_bhead->
next = new_bhead->
prev =
nullptr;
648#ifdef USE_BHEAD_READ_ON_DEMAND
653 new_bhead->
bhead = *bhead;
688 BHead *bhead =
nullptr;
694 if (new_bhead ==
nullptr) {
699 bhead = &new_bhead->
bhead;
710 return (prev) ? &prev->bhead :
nullptr;
715 BHeadN *new_bhead =
nullptr;
716 BHead *bhead =
nullptr;
724 new_bhead = new_bhead->
next;
725 if (new_bhead ==
nullptr) {
733 bhead = &new_bhead->
bhead;
739#ifdef USE_BHEAD_READ_ON_DEMAND
761 if (fd->
file->
seek(fd->
file, offset_backup, SEEK_SET) == -1) {
780 return &new_bhead_data->
bhead;
787 const char *id_name =
reinterpret_cast<const char *
>(
804 return *
reinterpret_cast<const short *
>(
826 return reinterpret_cast<const IDHash *
>(
833 if (std::holds_alternative<BlenderHeaderInvalid>(header_variant)) {
836 if (std::holds_alternative<BlenderHeaderUnknown>(header_variant)) {
840 const BlenderHeader &header = std::get<BlenderHeader>(header_variant);
877 subversion = atoi(
num);
881 const bool do_alias =
false;
893 fd->
filesdna,
"ID",
"char",
"name[]");
896 fd->
filesdna,
"ID",
"AssetMetaData",
"*asset_data");
898 fd->
filesdna,
"ID",
"short",
"flag");
900 fd->
filesdna,
"ID",
"IDHash",
"deep_hash");
914 *r_error_message =
"Missing DNA block";
921 int *blend_thumb =
nullptr;
926 int *
data = (
int *)(bhead + 1);
928 if (bhead->
len <
sizeof(
int[2])) {
932 const int width =
data[0];
933 const int height =
data[1];
975 if (processed_ids.
contains(id_iter)) {
978 processed_ids.
add_new(id_iter);
983 if (!used_names.
contains(id_iter->name)) {
984 used_names.
add_new(id_iter->name);
991 used_names.
add_new(id_iter->name);
992 CLOG_DEBUG(&
LOG,
"ID name has been de-duplicated to '%s'", id_iter->name);
1017 switch (
GS(id_iter->
name)) {
1019 bool has_truncated_slot_identifer =
false;
1024 "Truncated too long action slot name to '%s'",
1026 has_truncated_slot_identifer =
true;
1029 if (!has_truncated_slot_identifer) {
1057 auto visit_constraint = [](
const bConstraint &constraint) ->
bool {
1064 "Truncated too long bActionConstraint.last_slot_identifier to '%s'",
1072 visit_constraint(*con);
1077 visit_constraint(*con);
1088 "Truncated too long AnimData.last_slot_identifier to '%s'",
1093 "Truncated too long AnimData.tmp_last_slot_identifier to '%s'",
1100 "Truncated too long NlaStrip.last_slot_identifier to '%s'",
1123 FileData *fd = MEM_new<FileData>(__func__);
1155 char writer_ver_str[16];
1156 char min_reader_ver_str[16];
1165 writer_ver_str,
sizeof(writer_ver_str),
short(fd->
fileversion), -1);
1167 min_reader_ver_str,
sizeof(min_reader_ver_str), fg->
minversion, -1);
1171 "The file was saved by a newer version, open it with Blender %s or later",
1172 min_reader_ver_str);
1174 "%s: File saved by a newer version of Blender (%s), Blender %s or later is "
1175 "needed to open it.",
1178 min_reader_ver_str);
1196 "Blend file '%s' created by a Big Endian version of Blender, support for "
1197 "these files has been removed in Blender 5.0, use an older version of Blender "
1198 "to open and convert it.",
1204 const char *error_message =
nullptr;
1207 reports,
RPT_ERROR,
"Failed to read blend file '%s': %s", fd->
relabase, error_message);
1220 "Cannot read blend file '%s', incomplete header, may be from a newer version of Blender",
1244 if (rawfile ==
nullptr || rawfile->
read(rawfile, header,
sizeof(header)) !=
sizeof(header)) {
1247 "Unable to read '%s': %s",
1249 errno ? strerror(errno) :
RPT_(
"insufficient content"));
1251 rawfile->
close(rawfile);
1260 rawfile->
seek(rawfile, 0, SEEK_SET);
1263 if (memcmp(header,
"BLENDER",
sizeof(header)) == 0) {
1266 if (file ==
nullptr) {
1274 if (file !=
nullptr) {
1280 if (file !=
nullptr) {
1286 if (rawfile !=
nullptr) {
1287 rawfile->
close(rawfile);
1289 if (file ==
nullptr) {
1298 if (
BLI_stat(filepath, &stat) != -1) {
1312 "Unable to open '%s': %s",
1314 errno ? strerror(errno) :
RPT_(
"unknown error reading file"));
1323 if (fd !=
nullptr) {
1340 if (fd !=
nullptr) {
1370 if (file ==
nullptr) {
1372 mem_file->
close(mem_file);
1407# ifdef USE_BHEAD_READ_ON_DEMAND
1463 const int width = fd_data[0];
1464 const int height = fd_data[1];
1471 data->width = width;
1472 data->height = height;
1473 memcpy(
data->rect, &fd_data[2], data_size -
sizeof(*
data));
1525 const bool is_linked_only,
1528 return newlibadr(fd, self_id, is_linked_only, adr);
1553 if (old == entry.newp) {
1613 ID *
id,
const IDCacheKey *key,
void **cache_p,
uint ,
void *cache_storage_v)
1623 *storage_key = *key;
1626 storage_value->
cache_v = *cache_p;
1633 ID *
id,
const IDCacheKey *key,
void **cache_p,
const uint flags,
void *cache_storage_v)
1637 if (cache_storage ==
nullptr) {
1658 if (storage_value ==
nullptr) {
1663 *cache_p = storage_value->
cache_v;
1671 void *cache_storage_v)
1677 if (storage_value ==
nullptr) {
1703 if (
id ==
nullptr) {
1733 if (
id ==
nullptr) {
1778 const char *blockname,
1785 using keyT =
const std::pair<const std::string, const int>;
1790 constexpr std::string_view STORAGE_ID =
"readfile";
1796 std::string(STORAGE_ID));
1802 const bool is_id_data = !blockname && (id_type_index >= 0 && id_type_index <
INDEX_ID_MAX);
1806 static const std::array<std::string, INDEX_ID_MAX> id_alloc_names = [] {
1807 auto n =
decltype(id_alloc_names)();
1808 for (
int idtype_index = 0; idtype_index <
INDEX_ID_MAX; idtype_index++) {
1814 n[size_t(idtype_index)] =
"UNKNWOWN";
1817 n[size_t(idtype_index)] = idtype_info->
name;
1823 const std::string block_alloc_name = is_id_data ? id_alloc_names[id_type_index] : blockname;
1825 keyT key{block_alloc_name + struct_name, bh->
nr};
1827 const std::string alloc_string = fmt::format(
1828 fmt::runtime(is_id_data ?
"{}{} (for ID type '{}')" :
"{}{} (for block '{}')"),
1830 bh->
nr > 1 ? fmt::format(
"[{}]", bh->
nr) :
"",
1832 return storage.
insert(key, alloc_string);
1834 return storage.
find(key);
1841 return storage.
insert(id_type_index,
"Data from UNKNOWN");
1844 const std::string alloc_string = fmt::format(
"Data from '{}' ID type", id_type->
name);
1845 return storage.
insert(id_type_index, alloc_string);
1847 return storage.
find(id_type_index);
1855 void *temp =
nullptr;
1858#ifdef USE_BHEAD_READ_ON_DEMAND
1859 BHead *bh_orig = bh;
1869#ifdef USE_BHEAD_READ_ON_DEMAND
1881 const char *alloc_name =
get_alloc_name(fd, bh, blockname, id_type_index);
1883#ifdef USE_BHEAD_READ_ON_DEMAND
1899#ifdef USE_BHEAD_READ_ON_DEMAND
1901 memcpy(temp, (bh + 1), bh->
len);
1913 memcpy(temp, (bh + 1), bh->
len);
1918#ifdef USE_BHEAD_READ_ON_DEMAND
1919 if (bh_orig != bh) {
1930 ID *
id =
static_cast<ID *
>(
read_struct(fd, bh, blockname, id_type_index));
1954 return (bhead->
len) ? (
const void *)(bhead + 1) :
nullptr;
1978 ln->
next =
static_cast<Link *
>(poin);
1999 if (nodetree !=
nullptr) {
2002 if (nodetree->
owner_id ==
nullptr) {
2004 "NULL owner_id pointer for embedded NodeTree of %s, should never happen",
2008 else if (nodetree->
owner_id !=
id) {
2010 "Inconsistent owner_id pointer for embedded NodeTree of %s, should never happen",
2023 "NULL owner_id pointer for embedded Scene Collection of %s, should never happen",
2029 "Inconsistent owner_id pointer for embedded Scene Collection of %s, should "
2087 scene->nodetree =
nullptr;
2091 if (nodetree !=
nullptr && *nodetree !=
nullptr) {
2097 RPT_(
"Data-block '%s' had an invalid embedded node group, which has not been read"),
2123 RPT_(
"Scene '%s' had an invalid root collection, which has not been read"),
2131 id_old !=
nullptr ? &((
Scene *)id_old)->master_collection->id :
2153 const ID *id_target,
2154 const ID *id_current,
2155 const bool is_identical)
2160 int recalc = id_target->
recalc;
2162 if (id_current ==
nullptr) {
2171 if (!is_identical) {
2180 recalc |= id_current->
recalc;
2200 if (
id.runtime->readfile_data) {
2208 if (!
id.runtime->readfile_data) {
2211 return id.runtime->readfile_data->tags;
2217 return id.runtime->readfile_data->tags;
2234 Collection *collection =
reinterpret_cast<Scene *
>(id)->master_collection;
2258 "Unknown or invalid ID type, this should never happen");
2270 if (!current_library) {
2272 "Data-block '%s' flagged as packed, but without a valid library, fixing by "
2273 "making fully local...",
2279 "Data-block '%s' flagged as packed, but using a regular library, fixing by "
2280 "making fully linked...",
2285 id->lib = current_library;
2292 id->newid =
nullptr;
2293 id->orig_id =
nullptr;
2294 id->py_instance =
nullptr;
2305 id->runtime->readfile_data->tags = id_read_tags;
2312 id->library_weak_reference =
nullptr;
2358 id->recalc_after_undo_push = 0;
2362 id->recalc_after_undo_push = 0;
2374 id->override_library->runtime =
nullptr;
2398 block->uid = key->
uidgen++;
2408#ifdef USE_SETSCENE_CHECK
2412static bool scene_validate_setscene__liblink(
Scene *sce,
const int totscene)
2417 if (sce->
set ==
nullptr) {
2421 for (a = 0, sce_iter = sce; sce_iter->
set; sce_iter = sce_iter->
set, a++) {
2446#ifdef USE_SETSCENE_CHECK
2451 if (!scene_validate_setscene__liblink(sce, totscene)) {
2461#undef USE_SETSCENE_CHECK
2472 if (
lib->runtime->filedata) {
2475 "Packed Archive libraries should never own their filedata");
2476 if (
lib->runtime->is_filedata_owner) {
2480 lib->runtime->filedata =
nullptr;
2482 lib->runtime->is_filedata_owner =
false;
2510 RPT_(
"Library '%s', '%s' had multiple instances, save and reload!"),
2512 lib->runtime->filepath_abs);
2555 lib->runtime->filedata = fd;
2556 lib->runtime->is_filedata_owner =
false;
2559 lib->runtime->parent =
nullptr;
2564 lib->id.lib =
nullptr;
2572 if (basepath ==
nullptr || basepath[0] ==
'\0') {
2607 const bool was_liboverride)
2613 *((
short *)ph_id->
name) = idcode;
2621 if (was_liboverride) {
2632 if (mainvar->
id_map !=
nullptr) {
2648 ID *obdata =
static_cast<ID *
>(ob->data);
2683 bool success =
true;
2709 const char *allocname,
2710 const int id_type_index)
2720 "Blendfile corruption: Invalid, or multiple `bhead` with same old address "
2721 "value (%p) for a given ID.",
2741 const char *lib_filepath,
2743 const bool is_packed_library)
2763 STRNCPY(
lib->runtime->filepath_abs, filepath_abs);
2765 if (is_packed_library) {
2768 lib->archive_parent_library = reference_lib;
2772 lib->runtime->parent = reference_lib->
runtime->parent;
2778 lib->runtime->tag = reference_lib->
runtime->tag & copy_tag;
2782 lib->runtime->filedata = fd;
2783 lib->runtime->is_filedata_owner =
false;
2785 reference_lib->
runtime->archived_libraries.append(
lib);
2789 if (is_packed_library) {
2799 reference_lib->
runtime->archived_libraries.append(
lib);
2802 lib->runtime->filedata = fd;
2803 lib->runtime->is_filedata_owner =
false;
2853 int i = lbarray.size();
2860 ID *
id =
static_cast<ID *
>(lbarray[
i]->first);
2895 curlib->
runtime->archived_libraries = {};
2899 if (bhead !=
nullptr) {
2929 if (id_old ==
nullptr) {
2939 if (&libmain->curlib->id == id_old) {
2943 " compare with %s -> match (existing libpath: %s)",
2944 libmain->curlib->id.name,
2945 libmain->curlib->runtime->filepath_abs);
2975 if (*r_id_old ==
nullptr) {
2980 if (*r_id_old ==
nullptr) {
2982 " from %s (%s): NOT found",
2989 " from %s (%s): found by name",
2999 " from %s (%s): found by session_uid",
3034 id_old->
newid =
nullptr;
3037 const short idcode =
GS(id_old->
name);
3069 lib->archive_parent_library->id.session_uid) ==
3070 &
lib->archive_parent_library->id);
3075 fd,
lib,
lib->archive_parent_library,
lib->filepath,
lib->runtime->filepath_abs,
true);
3094 const short idcode =
GS(id->
name);
3138 Library *lib_old = blender::id_cast<Library *>(id_old);
3139 Library *
lib = blender::id_cast<Library *>(
id);
3145 bmain_iter->
curlib = lib_old;
3195 &
LOG_UNDO,
"UNDO: skip restore datablock %s, 'NO_MEMFILE_UNDO' type of ID", id->
name);
3212 if (!do_partial_undo) {
3214 "UNDO: read %s (uid %u) -> no partial undo, always read at new address",
3224 "UNDO: read %s (uid %u) -> keep identical data-block",
3233 if (id_old !=
nullptr) {
3236 "UNDO: read %s (uid %u) -> read to old existing address",
3261 const bool placeholder_set_indirect_extern,
3269 ID *id_old =
nullptr;
3275 if (
main->id_map !=
nullptr && id_old !=
nullptr) {
3286 const char *blockname =
nullptr;
3290 const char *blockname =
get_alloc_name(fd, bhead,
nullptr, id_type_index);
3293 if (
id ==
nullptr) {
3301 const short idcode =
GS(id->
name);
3303 if (lb ==
nullptr) {
3305 CLOG_WARN(&
LOG,
"Unknown id code '%c%c'", (idcode & 0xff), (idcode >> 8));
3320 ID *id_target = (do_partial_undo && id_old !=
nullptr) ? id_old : id;
3336 if (placeholder_set_indirect_extern) {
3347 if (
main->id_map !=
nullptr) {
3366 if (r_id !=
nullptr) {
3371 if (do_partial_undo && id_old !=
nullptr) {
3378 if (
main->id_map !=
nullptr) {
3387 id->runtime->src_blend_modifification_time = fd->
file_stat->st_mtime;
3504 if (user ==
nullptr) {
3516 main->is_locked_for_linking =
true;
3538 char build_commit_datetime[32];
3539 time_t temp_time =
main->build_commit_timestamp;
3540 tm *tm = (temp_time) ? gmtime(&temp_time) :
nullptr;
3542 strftime(build_commit_datetime,
sizeof(build_commit_datetime),
"%Y-%m-%d %H:%M", tm);
3545 STRNCPY(build_commit_datetime,
"unknown");
3550 " Version %d sub %d date %s hash %s",
3552 main->subversionfile,
3553 build_commit_datetime,
3557 if (!
main->is_read_invalid) {
3560 if (!
main->is_read_invalid) {
3563 if (!
main->is_read_invalid) {
3566 if (!
main->is_read_invalid) {
3569 if (!
main->is_read_invalid) {
3572 if (!
main->is_read_invalid) {
3575 if (!
main->is_read_invalid) {
3578 if (!
main->is_read_invalid) {
3581 if (!
main->is_read_invalid) {
3584 if (!
main->is_read_invalid) {
3587 if (!
main->is_read_invalid) {
3590 if (!
main->is_read_invalid) {
3593 if (!
main->is_read_invalid) {
3596 if (!
main->is_read_invalid) {
3605 main->is_locked_for_linking =
false;
3613 "Processing %s (%s), %d.%d",
3614 main->curlib ?
main->curlib->filepath :
main->filepath,
3615 main->curlib ?
"LIB" :
"MAIN",
3617 main->subversionfile);
3620 main->is_locked_for_linking =
true;
3622 if (!
main->is_read_invalid) {
3625 if (!
main->is_read_invalid) {
3628 if (!
main->is_read_invalid) {
3631 if (!
main->is_read_invalid) {
3634 if (!
main->is_read_invalid) {
3637 if (!
main->is_read_invalid) {
3640 if (!
main->is_read_invalid) {
3643 if (!
main->is_read_invalid) {
3646 if (!
main->is_read_invalid) {
3649 if (!
main->is_read_invalid) {
3652 if (!
main->is_read_invalid) {
3655 if (!
main->is_read_invalid) {
3658 if (!
main->is_read_invalid) {
3662 main->is_locked_for_linking =
false;
3752 id->orig_id =
nullptr;
3778 reports ? reports->
reports :
nullptr,
3780 "Critical blend-file corruption: Conflicts and/or otherwise invalid data-blocks names "
3781 "(see console for details)");
3841 keymap->modal_items =
nullptr;
3842 keymap->poll =
nullptr;
3852 if (kmdi->remove_item) {
3855 if (kmdi->add_item) {
3926 if (*id_pointer !=
nullptr) {
3995 bfd = MEM_new<BlendFileData>(__func__);
4018 const int width =
data[0];
4019 const int height =
data[1];
4044 Main *bmain_to_read_into =
nullptr;
4045 bool placeholder_set_indirect_extern =
false;
4047 switch (bhead->
code) {
4080 placeholder_set_indirect_extern =
true;
4089 bmain_to_read_into = fd->
bmain;
4117 "Local IDs should always be put in the first Main split data-base, not in "
4118 "a 'linked data' one");
4121 if (bmain_to_read_into) {
4123 fd, bmain_to_read_into, bhead, 0, {}, placeholder_set_indirect_extern,
nullptr);
4150 for (
Main *libmain : old_main_split_mains.
as_span().drop_front(1)) {
4170 "Blendfile '%s' was created by a future version of Blender and contains ID "
4171 "names longer than currently supported. These have been truncated.",
4177 "Blendfile '%s' appears corrupted, it contains invalid ID names. These have "
4209 const bool contains_link_placeholder = (bmain->
curlib !=
nullptr &&
4214 for (
ListBase *lb_array : lbarray) {
4216 BLI_assert_msg((id->runtime->readfile_data->tags.is_link_placeholder ==
4217 contains_link_placeholder),
4218 contains_link_placeholder ?
4219 "Real Library split Main contains non-placeholder IDs" :
4220 (bmain->
curlib ==
nullptr ?
4221 "Local data split Main contains placeholder IDs" :
4222 "Archive Library split Main contains placeholder IDs"));
4226 if (contains_link_placeholder) {
4317 if (
lib->runtime->versionfile == 0 &&
lib->runtime->archived_libraries.is_empty()) {
4352 std::string cur_view_layer_name = bfd->
cur_view_layer !=
nullptr ?
4416 if (x1->
old > x2->old) {
4419 if (x1->
old < x2->old) {
4491 if (bhead->
old == old) {
4503 *((
short *)idname_full) = idcode;
4528 if (
ID *existing_id = fd->
id_by_deep_hash->lookup_default(*deep_hash,
nullptr)) {
4537 if (mainvar->
id_map ==
nullptr) {
4564 const bool has_forward_compatibility_issues,
4565 const char *filepath)
4570 if (has_forward_compatibility_issues) {
4573 "Library '%s' was created by a future version of Blender and contains ID names "
4574 "longer than currently supported. This may cause missing linked data, consider "
4575 "opening and re-saving that library with the current Blender version.",
4581 "Library '%s' appears corrupted, it contains invalid ID names. This may cause "
4582 "missing linked data.",
4594 std::queue<ID *> &ids_to_expand,
4612 const char *lib_filepath,
4613 const char *relabase,
4614 const BHead *id_bhead,
4615 const char *id_name,
4616 const bool is_packed_id)
4618 Library *parent_lib =
nullptr;
4621 STRNCPY(filepath_abs, lib_filepath);
4631 "Found library '%s' for file path '%s'",
4637 if (!is_packed_id) {
4643 parent_lib = main_it->
curlib;
4671 "Found archive library '%s' for the packed ID '%s'",
4681 fd,
nullptr,
nullptr, lib_filepath, filepath_abs,
false);
4682 parent_lib = reference_bmain->
curlib;
4684 "Added new parent library '%s' for file path '%s'",
4692 fd,
nullptr, parent_lib, lib_filepath, filepath_abs, is_packed_id);
4698 "Added new archive library '%s' for the packed ID '%s'",
4704 &
LOG,
"Added new library '%s' for file path '%s'", bmain->
curlib->
id.
name, lib_filepath);
4718 std::queue<ID *> &ids_to_expand,
4725 ID *
id = existing_id;
4727 if (
id ==
nullptr) {
4731 if (
id ==
nullptr) {
4750 ids_to_expand.push(
id);
4779 printf(
"expand_doit: already linked: %s lib: %s\n", id->
name,
lib->filepath);
4786 std::queue<ID *> &ids_to_expand,
4797 if (bhead ==
nullptr) {
4816 "A link placeholder ID (aka reference to some ID linked from another library) "
4817 "should never be packed.");
4822 if (bheadlib ==
nullptr) {
4825 RPT_(
"LIB: .blend file %s seems corrupted, no owner 'Library' data found "
4826 "for the linked data-block '%s'. Try saving the file again."),
4828 id_name ? id_name :
"<InvalidIDName>");
4835 fd,
lib->filepath, fd->
relabase,
nullptr,
nullptr,
false);
4838 if (libmain->
curlib ==
nullptr) {
4841 RPT_(
"LIB: Data refers to main .blend file: '%s' from %s"),
4842 id_name ? id_name :
"<InvalidIDName>",
4851 else if (is_packed_id) {
4858 read_id_in_lib(fd, ids_to_expand,
nullptr,
nullptr, bhead, existing_id, {});
4863 if (bheadlib ==
nullptr) {
4866 RPT_(
"LIB: .blend file %s seems corrupted, no owner 'Library' data found "
4867 "for the packed linked data-block %s. Try saving the file again."),
4869 id_name ? id_name :
"<InvalidIDName>");
4876 fd,
lib->filepath, fd->
relabase, bhead, id_name, is_packed_id);
4879 if (libmain->
curlib ==
nullptr) {
4882 RPT_(
"LIB: Data refers to main .blend file: '%s' from %s"),
4883 id_name ? id_name :
"<InvalidIDName>",
4890 read_id_in_lib(fd, ids_to_expand, libmain,
nullptr, bhead,
nullptr, id_read_tags);
4896 read_id_in_lib(fd, ids_to_expand, mainvar,
nullptr, bhead,
nullptr, id_read_tags);
4999 if (
id ==
nullptr) {
5004 read_libblock(fd, mainl, bhead, tag, id_read_tags,
false, &
id);
5023 else if (use_placeholders) {
5045 ID *ret_id =
nullptr;
5060 const char *filepath,
5061 const int id_tag_extra)
5072 fd->
bmain = mainvar;
5108 const int id_tag_extra)
5113 params->id_tag_extra = id_tag_extra;
5119 const int id_tag_extra,
5126 if (scene !=
nullptr) {
5127 params->context.scene = scene;
5128 params->context.view_layer = view_layer;
5129 params->context.v3d = v3d;
5134 const char *filepath,
5152 int i = lbarray.size();
5167 Main *mainvar = (*fd)->bmain;
5170 if (mainl->
id_map ==
nullptr) {
5237 if (mainlib->is_read_invalid) {
5312 *bh =
reinterpret_cast<BlendHandle *
>(fd);
5329 int a = lbarray.size();
5346 BHead *bhead =
nullptr;
5361 RPT_(
"LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
5362 "non-linkable data type"),
5379 "LIB: %s: '%s' missing from '%s', parent '%s'",
5403 int a = lbarray.size();
5405 ID *
id =
static_cast<ID *
>(lbarray[a]->first);
5408 ID *id_next =
static_cast<ID *
>(
id->next);
5413 if (mainvar->
id_map !=
nullptr) {
5439 if (realid && !realid->
runtime->readfile_data) {
5440 realid->
runtime->readfile_data =
id->runtime->readfile_data;
5441 id->runtime->readfile_data =
nullptr;
5472 int a = lbarray.size();
5474 ID *
id =
static_cast<ID *
>(lbarray[a]->first);
5477 ID *id_next =
static_cast<ID *
>(
id->next);
5497 if (fd !=
nullptr) {
5508 RPT_(
"Read packed library: '%s', parent '%s'"),
5520 RPT_(
"Read library: '%s', '%s', parent '%s'"),
5561 if (fd ==
nullptr) {
5564 RPT_(
"Cannot find lib '%s'"),
5602 "Reading linked data-blocks from %s (%s)",
5612 if (libmain->
id_map ==
nullptr) {
5640 if (libmain->versionfile) {
5651 if (libmain->curlib->runtime->filedata) {
5652 do_versions(libmain->curlib->runtime->filedata, libmain->curlib, main_newid);
5659 if (libmain->curlib->runtime->filedata) {
5660 lib_link_all(libmain->curlib->runtime->filedata, libmain);
5677 const size_t expected_size)
5679 if (new_address !=
nullptr) {
5685 "Corrupt .blend file, unexpected data size.");
5704 const void *old_address,
5705 const size_t expected_size)
5712 const void *old_address,
5713 const size_t expected_size)
5715 void *new_address =
newdataadr(reader->
fd, old_address);
5720 const char *struct_name,
5722 const void *old_address)
5733 const bool is_linked_only,
5736 return static_cast<ID *
>(
newlibadr(reader->
fd, self_id, is_linked_only,
id));
5750 const size_t expected_elem_size,
5759 Link *prev =
nullptr;
5772 *ptr_p =
reinterpret_cast<char *
>(
5778 *ptr_p =
reinterpret_cast<uint8_t *
>(
5784 *ptr_p =
reinterpret_cast<int8_t *
>(
5790 *ptr_p =
reinterpret_cast<int16_t *
>(
5797 *ptr_p =
reinterpret_cast<int32_t *
>(
5804 *ptr_p =
reinterpret_cast<uint32_t *
>(
5811 *ptr_p =
reinterpret_cast<float *
>(
5823 *ptr_p =
reinterpret_cast<double *
>(
5833 const char *
str = *ptr_p;
5837 if (
str[
len - 1] ==
'\0') {
5842 BLI_assert_msg(0,
"Corrupt .blend file, expected string to be null terminated.");
5864 for (
int i = 0;
i < array_size;
i++) {
5871 const uint32_t *src,
5875 for (
int i = 0;
i < array_size;
i++) {
5885 if (orig_array ==
nullptr) {
5893 void *final_array =
nullptr;
5895 if (file_pointer_size == current_pointer_size) {
5897 final_array = orig_array;
5899 else if (file_pointer_size == 8 && current_pointer_size == 4) {
5903 reader, array_size, (
uint64_t *)orig_array, (uint32_t *)final_array);
5906 else if (file_pointer_size == 4 && current_pointer_size == 8) {
5910 reader, array_size, (uint32_t *)orig_array, (
uint64_t *)final_array);
5917 *ptr_p = final_array;
5936 sharing_info_data->sharing_info->add_user();
5937 return *sharing_info_data;
5948 if (shared_data->sharing_info) {
5949 shared_data->sharing_info->add_user();
5951 return *shared_data;
5957 const void *new_address = *ptr_p;
5990 return reader->
main;
AnimData * BKE_animdata_from_id(const ID *id)
void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id)
void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
void BKE_asset_catalog_path_list_blend_read_data(BlendDataReader *reader, ListBase &catalog_path_list)
#define BLENDER_FILE_SUBVERSION
void BKE_blender_version_blendfile_string_from_values(char *str_buff, const size_t str_buff_maxncpy, const short file_version, const short file_subversion)
#define BLENDER_FILE_VERSION
void BKE_collections_after_lib_link(Main *bmain)
void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection, ID *owner_id)
void BKE_main_collections_parent_relations_rebuild(Main *bmain)
#define IDP_BlendDataRead(reader, prop)
const IDTypeInfo * BKE_idtype_get_info_from_idtype_index(const int idtype_index)
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
@ IDTYPE_FLAGS_NO_MEMFILE_UNDO
const char * BKE_idtype_idcode_to_name(short idcode)
bool BKE_idtype_idcode_is_linkable(short idcode)
void BKE_idtype_id_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
int BKE_idtype_idcode_to_index(short idcode)
uint BKE_idtype_cache_key_hash(const void *key_v)
bool BKE_idtype_idcode_is_valid(short idcode)
@ IDTYPE_CACHE_CB_FLAGS_PERSISTENT
void BKE_layer_collection_resync_forbid()
void BKE_layer_collection_resync_allow()
ViewLayer * BKE_view_layer_find(const Scene *scene, const char *layer_name)
void BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
IDNewNameResult BKE_id_new_name_validate(Main &bmain, ListBase &lb, ID &id, const char *newname, IDNewNameMode mode, bool do_linked_data)
void BKE_libblock_free_runtime_data(ID *id)
void BKE_id_free(Main *bmain, void *idv)
void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
#define MAIN_ID_SESSION_UID_UNSET
void BKE_libblock_init_empty(ID *id) ATTR_NONNULL(1)
void BKE_lib_libblock_session_uid_ensure(ID *id)
void id_us_ensure_real(ID *id)
void BKE_lib_id_swap_full(Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
void * BKE_id_new(Main *bmain, short type, const char *name)
const char * BKE_id_name(const ID &id)
void BKE_libblock_runtime_ensure(ID &id)
void BKE_main_id_refcount_recompute(Main *bmain, bool do_linked_only)
ID * BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT
void BKE_main_id_tag_all(Main *mainvar, int tag, bool value)
void BKE_lib_override_library_main_validate(Main *bmain, ReportList *reports)
void BKE_lib_override_library_main_update(Main *bmain)
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_DIRECT_WEAK_LINK
@ IDWALK_CB_READFILE_IGNORE
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
@ IDWALK_DO_DEPRECATED_POINTERS
@ IDWALK_NO_ORIG_POINTERS_ACCESS
@ ID_REMAP_SKIP_USER_CLEAR
@ ID_REMAP_SKIP_USER_REFCOUNT
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
@ ID_REMAP_SKIP_UPDATE_TAGGING
@ ID_REMAP_NO_ORIG_POINTERS_ACCESS
@ LIBRARY_IS_ASSET_EDIT_FILE
@ LIBRARY_TAG_RESYNC_REQUIRED
#define FOREACH_MAIN_ID_END
MainListsArray BKE_main_lists_get(Main &bmain)
ListBase * which_libbase(Main *bmain, short type)
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
#define FOREACH_MAIN_LISTBASE_ID_END
std::array< ListBase *, INDEX_ID_MAX - 1 > MainListsArray
#define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id)
#define FOREACH_MAIN_LISTBASE_END
#define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb)
void BKE_main_free(Main *bmain)
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
#define MAIN_VERSION_FILE_OLDER_OR_EQUAL(main, ver, subver)
#define BLEN_THUMB_MEMSIZE(_x, _y)
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
#define BLEN_THUMB_MEMSIZE_IS_VALID(_x, _y)
bool BKE_main_is_empty(Main *bmain)
const char * BKE_main_blendfile_path_from_global()
ID ID ID * BKE_main_idmap_lookup_uid(IDNameLib_Map *id_map, uint session_uid) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Main * BKE_main_idmap_main_get(IDNameLib_Map *id_map) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
IDNameLib_Map * BKE_main_idmap_create(Main *bmain, bool create_valid_ids_set, Main *old_bmain, int idmap_types) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BKE_main_idmap_remove_id(IDNameLib_Map *id_map, const ID *id) ATTR_NONNULL()
void BKE_main_idmap_destroy(IDNameLib_Map *id_map) ATTR_NONNULL()
void BKE_main_idmap_insert_id(IDNameLib_Map *id_map, ID *id) ATTR_NONNULL()
ID * BKE_main_idmap_lookup_name(IDNameLib_Map *id_map, short id_type, const char *name, const Library *lib) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
bool BKE_main_namemap_validate_and_fix(Main &bmain)
void BKE_main_namemap_clear(Main &bmain)
General operations, lookup, etc. for materials.
void BKE_object_materials_sync_length(Main *bmain, Object *ob, ID *id)
General operations, lookup, etc. for blender objects.
void BKE_packedfile_blend_read(BlendDataReader *reader, PackedFile **pf_p, blender::StringRefNull filepath)
void BKE_preferences_extension_repo_read_data(struct BlendDataReader *reader, bUserExtensionRepo *repo)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
void BKE_report_log(eReportType type, const char *message, CLG_LogRef *log)
bool BKE_screen_blend_read_data(BlendDataReader *reader, bScreen *screen)
#define BLI_assert_unreachable()
#define BLI_STATIC_ASSERT(a, msg)
#define BLI_assert_msg(a, msg)
File and directory operations.
bool BLI_file_magic_is_gzip(const char header[4])
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_file_magic_is_zstd(const char header[4])
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FileReader * BLI_filereader_new_mmap(int filedes) ATTR_WARN_UNUSED_RESULT
FileReader * BLI_filereader_new_zstd(FileReader *base) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FileReader * BLI_filereader_new_file(int filedes) ATTR_WARN_UNUSED_RESULT
FileReader * BLI_filereader_new_gzip(FileReader *base) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FileReader * BLI_filereader_new_memory(const void *data, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
bool BLI_remlink_safe(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
ATTR_WARN_UNUSED_RESULT const size_t num
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
size_t size_t size_t bool BLI_str_utf8_truncate_at_size(char *str, const size_t str_size)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
Platform independent time functions.
double BLI_time_now_seconds(void)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define POINTER_OFFSET(v, ofs)
Compatibility-like things for windows.
Utilities ensuring .blend file (i.e. Main) is in valid state during write and/or read process.
void BLO_main_validate_embedded_flag(Main *bmain, ReportList *reports)
bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports)
void BLO_main_validate_embedded_liboverrides(Main *bmain, ReportList *reports)
uint32_t uint32_from_uint64_ptr(uint64_t ptr)
std::optional< BHead > BLO_readfile_read_bhead(FileReader *file, BHeadType type)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct(reader, struct_name, ptr_p)
external readfile function prototypes.
@ BLO_LIBLINK_USE_PLACEHOLDERS
@ BLO_LIBLINK_COLLECTION_NO_HIERARCHY_REBUILD
@ BLO_LIBLINK_FORCE_INDIRECT
@ BLO_READ_SKIP_UNDO_OLD_MAIN
ID_Readfile_Data::Tags BLO_readfile_id_runtime_tags(ID &id)
#define BLEN_THUMB_MEMSIZE_FILE(_x, _y)
FileReader * BLO_memfile_new_filereader(MemFile *memfile, int undo_direction)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_DEBUG(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref,...)
#define ID_IS_PACKED(_id)
@ ID_TAG_UNDO_OLD_ID_REUSED_UNCHANGED
@ ID_TAG_UNDO_OLD_ID_REUSED_NOUNDO
@ ID_TAG_UNDO_OLD_ID_REREAD_IN_PLACE
@ ID_TAG_LIBOVERRIDE_NEED_RESYNC
#define ID_FAKE_USERS(id)
#define ID_IS_LINKED(_id)
#define ID_TAG_KEEP_ON_UNDO
@ ID_FLAG_INDIRECT_WEAK_LINK
@ ID_FLAG_LINKED_AND_PACKED
@ LIBRARY_FLAG_IS_ARCHIVE
#define ID_LINK_PLACEHOLDER
Object groups, one object can be in many groups at once.
blenloader genfile private function prototypes
const char * DNA_struct_get_compareflags(const struct SDNA *oldsdna, const struct SDNA *newsdna)
void DNA_sdna_free(struct SDNA *sdna)
const struct SDNA * DNA_sdna_current_get(void)
int DNA_struct_find_with_alias(const struct SDNA *sdna, const char *str)
int DNA_struct_member_offset_by_name_with_alias(const struct SDNA *sdna, const char *stype, const char *vartype, const char *name)
int DNA_struct_size(const struct SDNA *sdna, int struct_index)
const char * DNA_struct_identifier(struct SDNA *sdna, int struct_index)
void * DNA_struct_reconstruct(const struct DNA_ReconstructInfo *reconstruct_info, int old_struct_index, int blocks, const void *old_blocks, const char *alloc_name)
struct SDNA * DNA_sdna_from_data(const void *data, int data_len, bool data_alloc, bool do_alias, const char **r_error_message)
struct DNA_ReconstructInfo * DNA_reconstruct_info_create(const struct SDNA *oldsdna, const struct SDNA *newsdna, const char *compare_flags)
void DNA_reconstruct_info_free(struct DNA_ReconstructInfo *reconstruct_info)
int DNA_struct_alignment(const struct SDNA *sdna, int struct_index)
void DNA_sdna_alias_data_ensure_structs_map(struct SDNA *sdna)
@ SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK
#define SDNA_RAW_DATA_STRUCT_INDEX
@ USER_MENU_TYPE_OPERATOR
void IMB_colormanagement_working_space_convert(Main *bmain, const blender::float3x3 ¤t_scene_linear_to_xyz, const blender::float3x3 &new_xyz_to_scene_linear, const bool depsgraph_tag=false, const bool linked_only=false, const bool editable_assets_only=false)
Read Guarded memory(de)allocation.
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
unsigned long long int uint64_t
const Value * lookup_ptr(const Key &key) const
bool add_overwrite(const Key &key, const Value &value)
ValueIterator values() const &
bool add(const Key &key, const Value &value)
bool add_overwrite(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
bool contains(const Key &key) const
void add_new(const Key &key)
void append(const T &value)
Span< T > as_span() const
const char * insert(const keyT &key, std::string alloc_string)
bool contains(const keyT &key)
const char * find(const keyT &key)
#define pf(_x, _i)
Prefetch 64.
void * MEM_mallocN(size_t len, const char *str)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
bool foreach_strip_adt(const AnimData &adt, blender::FunctionRef< bool(NlaStrip *)> callback)
void node_tree_blend_read_data(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
void node_tree_update_all_new(Main &main)
bNodeTree ** node_tree_ptr_from_id(ID *id)
bNodeTree * node_tree_from_id(ID *id)
MatBase< float, 3, 3 > float3x3
AllocStringStorage< keyT, hashT > & alloc_string_storage_get(const std::string &storage_identifier)
static int lib_link_cb(LibraryIDLinkCallbackData *cb_data)
static BHead * find_bhead(FileData *fd, void *old)
static void * newdataadr_no_us(FileData *fd, const void *adr)
static void long_id_names_ensure_unique_id_names(Main *bmain)
void * blo_do_versions_newlibadr(FileData *fd, ID *self_id, const bool is_linked_only, const void *adr)
static void lib_link_scenes_check_set(Main *bmain)
static void read_file_version_and_colorspace(FileData *fd, Main *main)
void BLO_read_struct_list_with_size(BlendDataReader *reader, const size_t expected_elem_size, ListBase *list)
static void link_glob_list(FileData *fd, ListBase *lb)
static ID * read_id_struct(FileData *fd, BHead *bh, const char *blockname, const int id_type_index)
static ID * create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag, const bool was_liboverride)
static void lib_link_all(FileData *fd, Main *bmain)
void blo_cache_storage_end(FileData *fd)
void blo_join_main(Main *bmain)
static void long_id_names_process_action_slots_identifiers(Main *bmain)
static FileData * filedata_new(BlendFileReadReport *reports)
void BLO_read_int32_array(BlendDataReader *reader, const int64_t array_size, int32_t **ptr_p)
BlendThumbnail * BLO_thumbnail_from_file(const char *filepath)
static void expand_main(void *fdhandle, Main *mainvar, BLOExpandDoitCallback callback)
static void direct_link_library(FileData *fd, Library *lib, Main *main)
static void read_file_bhead_idname_map_create(FileData *fd)
static int direct_link_id_restore_recalc_exceptions(const ID *id_current)
void BLO_read_uint8_array(BlendDataReader *reader, const int64_t array_size, uint8_t **ptr_p)
static void convert_pointer_array_32_to_64(BlendDataReader *, const int64_t array_size, const uint32_t *src, uint64_t *dst)
static void split_libdata(ListBase *lb_src, blender::Vector< Main * > &lib_main_array, const bool do_split_packed_ids)
const char * blo_bhead_id_name(FileData *fd, const BHead *bhead)
void BLO_library_link_params_init(LibraryLink_Params *params, Main *bmain, const int flag, const int id_tag_extra)
static void split_main_newid(Main *mainptr, Main *main_newid)
void BLO_read_float_array(BlendDataReader *reader, const int64_t array_size, float **ptr_p)
static void link_global(FileData *fd, BlendFileData *bfd)
static BHead * read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
int BLO_read_fileversion_get(BlendDataReader *reader)
BHead * blo_bhead_next(FileData *fd, BHead *thisblock)
void BLO_read_uint32_array(BlendDataReader *reader, const int64_t array_size, uint32_t **ptr_p)
blender::ImplicitSharingInfoAndData blo_read_shared_impl(BlendDataReader *reader, const void **ptr_p, const blender::FunctionRef< const blender::ImplicitSharingInfo *()> read_fn)
static void read_undo_reuse_noundo_local_ids(FileData *fd)
BlendFileReadReport * BLO_read_data_reports(BlendDataReader *reader)
static const IDHash * blo_bhead_id_deep_hash(const FileData *fd, const BHead *bhead)
BHead * blo_bhead_first(FileData *fd)
static bool read_libblock_is_identical(FileData *fd, BHead *bhead)
static void change_ID_pointer_to_real_ID_pointer_fd(FileData *fd, const void *old, void *newp)
Main * BLO_read_lib_get_main(BlendLibReader *reader)
static int direct_link_id_restore_recalc(const FileData *fd, const ID *id_target, const ID *id_current, const bool is_identical)
static bool blo_bhead_is_id(const BHead *bhead)
static void direct_link_id_override_property(BlendDataReader *reader, IDOverrideLibraryProperty *op)
static const char * library_parent_filepath(Library *lib)
static void direct_link_id_common(BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, int id_tag, ID_Readfile_Data::Tags id_read_tags)
static void direct_link_id_embedded_id(BlendDataReader *reader, Library *current_library, ID *id, ID *id_old)
static bool oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, const int nr)
void BLO_read_glob_list(BlendDataReader *reader, ListBase *list)
static int has_linked_ids_to_read(Main *mainvar)
static BHead * blo_bhead_read_full(FileData *fd, BHead *thisblock)
static void do_versions_userdef(FileData *, BlendFileData *bfd)
static void library_link_end(Main *mainl, FileData **fd, const int flag, ReportList *reports)
void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, const int nr)
static void add_main_to_main(Main *mainvar, Main *from)
static OldNewMap * oldnewmap_new()
static Main * blo_add_main_for_library(FileData *fd, Library *lib, Library *reference_lib, const char *lib_filepath, char(&filepath_abs)[FILE_MAX], const bool is_packed_library)
static void after_liblink_id_process(BlendLibReader *reader, ID *id)
bool BLO_read_data_is_undo(BlendDataReader *reader)
static bool read_libblock_undo_restore_linked(FileData *fd, Main *libmain, const ID *id, ID **r_id_old, BHead *bhead)
static void * newdataadr(FileData *fd, const void *adr)
void * BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address, const size_t expected_size)
static void do_versions_after_linking(FileData *fd, Main *main)
static void read_library_clear_weak_links(FileData *basefd, Main *mainvar)
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params, ReportList *reports)
static BHead * read_data_into_datamap(FileData *fd, BHead *bhead, const char *allocname, const int id_type_index)
static void change_link_placeholder_to_real_ID_pointer(FileData *basefd, void *old, void *newp)
ID * BLO_read_get_new_id_address(BlendLibReader *reader, ID *self_id, const bool is_linked_only, ID *id)
static void readfile_id_runtime_data_ensure(ID &id)
static void read_libraries_report_invalid_id_names(FileData *fd, ReportList *reports, const bool has_forward_compatibility_issues, const char *filepath)
static BHead * find_bhead_from_idname(FileData *fd, const char *idname)
static void blo_cache_storage_entry_restore_in_new(ID *id, const IDCacheKey *key, void **cache_p, const uint flags, void *cache_storage_v)
BlendFileReadReport * BLO_read_lib_reports(BlendLibReader *reader)
AssetMetaData * blo_bhead_id_asset_data_address(const FileData *fd, const BHead *bhead)
BlendFileData * blo_read_file_internal(FileData *fd, const char *filepath)
void BLO_readfile_id_runtime_data_free(ID &id)
static BHead * read_libblock(FileData *fd, Main *main, BHead *bhead, int id_tag, ID_Readfile_Data::Tags id_read_tags, const bool placeholder_set_indirect_extern, ID **r_id)
static void read_libraries(FileData *basefd)
static void sort_bhead_old_map(FileData *fd)
static Main * blo_find_main_for_library_and_idname(FileData *fd, const char *lib_filepath, const char *relabase, const BHead *id_bhead, const char *id_name, const bool is_packed_id)
FileData * blo_filedata_from_memfile(MemFile *memfile, const BlendFileReadParams *params, BlendFileReadReport *reports)
void BLO_read_double_array(BlendDataReader *reader, const int64_t array_size, double **ptr_p)
static void fix_relpaths_library(const char *basepath, Main *main)
static bool read_libblock_undo_restore(FileData *fd, Main *main, BHead *bhead, const int id_tag, ID **r_id_old)
static void convert_pointer_array_64_to_32(BlendDataReader *reader, const int64_t array_size, const uint64_t *src, uint32_t *dst)
void BLO_read_int16_array(BlendDataReader *reader, const int64_t array_size, int16_t **ptr_p)
bool BLO_read_lib_is_undo(BlendLibReader *reader)
void * BLO_read_struct_array_with_size(BlendDataReader *reader, const void *old_address, const size_t expected_size)
static const void * peek_struct_undo(FileData *fd, BHead *bhead)
static FileData * read_library_file_data(FileData *basefd, Main *bmain, Main *lib_bmain)
static void * oldnewmap_liblookup(OldNewMap *onm, const void *addr, const bool is_linked_only)
static void oldnewmap_free(OldNewMap *onm)
static void oldnewmap_lib_insert(FileData *fd, const void *oldaddr, ID *newaddr, const int id_code)
void * BLO_read_struct_by_name_array(BlendDataReader *reader, const char *struct_name, const int64_t items_num, const void *old_address)
static void read_id_in_lib(FileData *fd, std::queue< ID * > &ids_to_expand, Main *libmain, Library *parent_lib, BHead *bhead, ID *existing_id, ID_Readfile_Data::Tags id_read_tags)
static void blo_cache_storage_entry_clear_in_old(ID *, const IDCacheKey *key, void **cache_p, const uint, void *cache_storage_v)
static BHeadN * get_bhead(FileData *fd)
static ID * link_named_part(Main *mainl, FileData *fd, const short idcode, const char *name, const int flag)
static void after_liblink_merged_bmain_process(Main *bmain, BlendFileReadReport *reports)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_read_data_globmap_add(BlendDataReader *reader, void *oldaddr, void *newaddr)
static void read_library_linked_ids(FileData *basefd, FileData *fd, Main *mainvar)
ID_Readfile_Data::Tags BLO_readfile_id_runtime_tags(ID &id)
static int expand_cb(LibraryIDLinkCallbackData *cb_data)
static void read_undo_remap_noundo_data(FileData *fd)
FileData * blo_filedata_from_file(const char *filepath, BlendFileReadReport *reports)
void BLO_read_int8_array(BlendDataReader *reader, const int64_t array_size, int8_t **ptr_p)
static void read_library_linked_id(FileData *basefd, FileData *fd, Main *mainvar, ID *id, ID **r_id)
static void do_versions(FileData *fd, Library *lib, Main *main)
static const char * get_alloc_name(FileData *fd, BHead *bh, const char *blockname, const int id_type_index=INDEX_ID_NULL)
FileData * blo_filedata_from_memory(const void *mem, const int memsize, BlendFileReadReport *reports)
#define BHEADN_FROM_BHEAD(bh)
static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *newp)
Main * BLO_library_link_begin(BlendHandle **bh, const char *filepath, const LibraryLink_Params *params)
static ID * library_id_is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
static FileData * blo_filedata_from_file_descriptor(const char *filepath, BlendFileReadReport *reports, const int filedes)
static ID * library_id_is_yet_read_main(Main *mainvar, const char *idname)
static void direct_link_keymapitem(BlendDataReader *reader, wmKeyMapItem *kmi)
static void blo_cache_storage_entry_register(ID *id, const IDCacheKey *key, void **cache_p, uint, void *cache_storage_v)
static void * newlibadr(FileData *fd, ID *, const bool is_linked_only, const void *adr)
static int verg_bheadsort(const void *v1, const void *v2)
void BLO_library_link_params_init_with_context(LibraryLink_Params *params, Main *bmain, const int flag, const int id_tag_extra, Scene *scene, ViewLayer *view_layer, const View3D *v3d)
static bool read_file_dna(FileData *fd, const char **r_error_message)
void blo_do_versions_key_uidgen(Key *key)
static void placeholders_ensure_valid(Main *bmain)
static BHead * find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
void blo_cache_storage_init(FileData *fd, Main *bmain)
void blo_make_old_idmap_from_main(FileData *fd, Main *bmain)
short BLO_version_from_file(const char *filepath)
BHead * blo_read_asset_data_block(FileData *fd, BHead *bhead, AssetMetaData **r_asset_data)
static void read_libblock_undo_restore_identical(FileData *fd, Main *main, const ID *, ID *id_old, BHead *bhead, const int id_tag)
static FileData * blo_filedata_from_file_minimal(const char *filepath)
static ID * library_id_is_yet_read_deep_hash(FileData *fd, BHead *bhead)
static void oldnewmap_clear(OldNewMap *onm)
static void expand_doit_library(void *fdhandle, std::queue< ID * > &ids_to_expand, Main *mainvar, void *old)
void BLO_readfile_id_runtime_data_free_all(Main &bmain)
static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, ID *id, ID *id_old)
void blo_split_main(Main *bmain, const bool do_split_packed_ids)
static bool direct_link_id(FileData *fd, Main *main, const int tag, const ID_Readfile_Data::Tags id_read_tags, ID *id, ID *id_old)
static BHead * find_previous_lib(FileData *fd, BHead *bhead)
#define BHEAD_USE_READ_ON_DEMAND(bhead)
void BLO_read_char_array(BlendDataReader *reader, const int64_t array_size, char **ptr_p)
void * BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
void BLO_read_float3_array(BlendDataReader *reader, const int64_t array_size, float **ptr_p)
short blo_bhead_id_flag(const FileData *fd, const BHead *bhead)
static bool is_minversion_older_than_blender(FileData *fd, ReportList *reports)
static void change_ID_pointer_to_real_ID_pointer(FileData *basefd, void *old, void *newp)
ID * BLO_read_get_new_id_address_from_session_uid(BlendLibReader *reader, const uint session_uid)
void * BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address)
ID_Readfile_Data::Tags & BLO_readfile_id_runtime_tags_for_write(ID &id)
static bool read_libblock_undo_restore_library(FileData *fd, const ID *id, ID *id_old, BHead *bhead)
static void library_filedata_release(Library *lib)
static Main * library_link_begin(Main *mainvar, FileData *fd, const char *filepath, const int id_tag_extra)
static void blo_read_file_checks(Main *bmain)
ID * BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcode, const char *name, const LibraryLink_Params *params)
static bool blo_bhead_read_data(FileData *fd, BHead *thisblock, void *buf)
static BHead * read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
void blo_filedata_free(FileData *fd)
static int * read_file_thumbnail(FileData *fd)
static bool blo_bhead_is_id_valid_type(const BHead *bhead)
static void * blo_verify_data_address(FileData *fd, void *new_address, const void *, const size_t expected_size)
static void after_liblink_id_embedded_id_process(BlendLibReader *reader, ID *id)
static FileData * change_ID_link_filedata_get(Main *bmain, FileData *basefd)
BHead * blo_bhead_prev(FileData *, BHead *thisblock)
void BLO_read_pointer_array(BlendDataReader *reader, const int64_t array_size, void **ptr_p)
void blo_readfile_invalidate(FileData *fd, Main *bmain, const char *message)
static void read_blender_header(FileData *fd)
static void * oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, const bool increase_users)
void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old)
static CLG_LogRef LOG_UNDO
static FileData * blo_filedata_from_file_open(const char *filepath, BlendFileReadReport *reports)
static int read_undo_remap_noundo_data_cb(LibraryIDLinkCallbackData *cb_data)
static void * read_struct(FileData *fd, BHead *bh, const char *blockname, const int id_type_index)
static FileData * blo_decode_and_check(FileData *fd, ReportList *reports)
void BLO_reportf_wrap(BlendFileReadReport *reports, const eReportType type, const char *format,...)
void * blo_read_get_new_globaldata_address(FileData *fd, const void *adr)
static void read_undo_move_libmain_data(FileData *fd, Main *libmain, BHead *bhead)
void(*)(void *fdhandle, std::queue< ID * > &ids_to_expand, Main *mainvar, void *idv) BLOExpandDoitCallback
void blo_do_versions_400(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_300(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_450(FileData *fd, Main *bmain)
void do_versions_after_linking_300(FileData *fd, Main *bmain)
void blo_do_versions_dna(SDNA *sdna, int versionfile, int subversionfile)
void blo_do_versions_450(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_500(FileData *fd, Main *bmain)
void do_versions_after_linking_410(FileData *fd, Main *bmain)
void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_410(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_400(FileData *fd, Main *bmain)
void do_versions_after_linking_430(FileData *fd, Main *bmain)
void do_versions_after_linking_250(Main *bmain)
void do_versions_after_linking_290(FileData *fd, Main *bmain)
@ FD_FLAGS_FILE_POINTSIZE_IS_4
@ FD_FLAGS_POINTSIZE_DIFFERS
@ FD_FLAGS_HAS_INVALID_ID_NAMES
void do_versions_after_linking_440(FileData *fd, Main *bmain)
void do_versions_after_linking_420(FileData *fd, Main *bmain)
void blo_do_versions_userdef(UserDef *userdef)
void blo_do_versions_500(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_420(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_280(FileData *fd, Main *bmain)
void blo_do_versions_290(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_270(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_270(Main *bmain)
void blo_do_versions_440(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_430(FileData *fd, Library *lib, Main *bmain)
void do_versions_after_linking_260(Main *bmain)
void blo_do_versions_260(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
void blo_do_versions_280(FileData *fd, Library *lib, Main *bmain)
char tmp_last_slot_identifier[258]
char last_slot_identifier[258]
bool is_memchunk_identical
blender::Map< uint64_t, blender::ImplicitSharingInfoAndData > shared_data_by_stored_address
BLOExpandDoitCallback callback
std::queue< ID * > ids_to_expand
ViewLayer * cur_view_layer
struct BlendFileReadReport::@077003321007012203371307366200326111253233132273 duration
struct BlendFileReadReport::@124362246150331065306145367225174223236260272332 count
BlenderHeader blender_header
DNA_ReconstructInfo * reconstruct_info
std::optional< blender::Map< blender::StringRefNull, BHead * > > bhead_idname_map
IDNameLib_Map * new_idmap_uid
BLOCacheStorage * cache_storage
std::shared_ptr< blender::Map< IDHash, ID * > > id_by_deep_hash
BlendFileReadReport * reports
IDNameLib_Map * old_idmap_uid
std::optional< BLI_stat_t > file_stat
struct ViewLayer * cur_view_layer
float colorspace_scene_linear_to_xyz[3][3]
uint64_t build_commit_timestamp
char colorspace_scene_linear_name[64]
struct bScreen * curscreen
unsigned int id_session_uid
IDTypeBlendReadUndoPreserve blend_read_undo_preserve
IDTypeForeachCacheFunction foreach_cache
IDTypeBlendReadDataFunction blend_read_data
AssetTypeInfo * asset_type_info
IDTypeBlendReadAfterLiblinkFunction blend_read_after_liblink
unsigned int recalc_after_undo_push
ID_RuntimeHandle * runtime
struct AssetMetaData * asset_data
IDProperty * system_properties
IDOverrideLibrary * override_library
unsigned int recalc_up_to_undo_push
struct LibraryWeakReference * library_weak_reference
LibraryForeachIDCallbackFlag cb_flag
struct PackedFile * packedfile
LibraryRuntimeHandle * runtime
struct Library * archive_parent_library
char scene_linear_name[64]
blender::float3x3 scene_linear_to_xyz
bool has_forward_compatibility_issues
BlendThumbnail * blen_thumb
uint64_t build_commit_timestamp
std::shared_ptr< blender::VectorSet< Main * > > split_mains
MainColorspace colorspace
blender::Map< uint64_t, blender::ImplicitSharingInfoAndData > sharing_info_by_address_id
MemFileSharedStorage * shared_storage
char last_slot_identifier[258]
blender::Map< const void *, NewAddress > map
struct Collection * master_collection
struct bNodeTree * compositing_node_group
ListBase script_directories
struct ListBase asset_shelves_settings
struct ListBase user_keymaps
struct ListBase autoexec_paths
struct ListBase user_keyconfig_prefs
struct ListBase extension_repos
struct ListBase user_menus
struct ListBase asset_libraries
char last_slot_identifier[258]
struct ActionSlot ** slot_array
void version_system_idprops_generate(Main *bmain)
void version_system_idprops_nodes_generate(Main *bmain)
void version_system_idprops_children_bones_generate(Main *bmain)
short do_versions_new_to_old_idcode_get(const short id_code_new)
static DynamicLibrary lib