27#include <fmt/format.h>
32#define DNA_DEPRECATED_ALLOW
117#define U (*((const UserDef *)&U))
176#define USE_BHEAD_READ_ON_DEMAND
181#if ENDIAN_ORDER == B_ENDIAN
182# warning "Support for Big Endian endianness is deprecated and will be removed in Blender 5.0"
192#ifdef USE_BHEAD_READ_ON_DEMAND
202#define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -int(offsetof(BHeadN, bhead))))
208#define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == BLO_CODE_DATA)
219 char fixed_buf[1024];
224 vsnprintf(fixed_buf,
sizeof(fixed_buf),
format, args);
227 fixed_buf[
sizeof(fixed_buf) - 1] =
'\0';
231 if (
G.background == 0) {
239 return lib->runtime->parent ?
lib->runtime->parent->runtime->filepath_abs :
"<direct>";
261 return MEM_new<OldNewMap>(__func__);
270 if (oldaddr ==
nullptr || newaddr ==
nullptr) {
293 if (entry ==
nullptr) {
296 if (increase_users) {
305 if (addr ==
nullptr) {
323 if (new_addr.nr == 0) {
349 int a = fromarray.size();
357 Main *tojoin, *mainl;
359 mainl =
static_cast<Main *
>(mainlist->
first);
361 if (mainl->
id_map !=
nullptr) {
370 while ((tojoin = mainl->
next)) {
375 tojoin->
next = tojoin->
prev =
nullptr;
382 for (
ID *
id =
static_cast<ID *
>(lb_src->
first), *idnext;
id;
id = idnext) {
383 idnext =
static_cast<ID *
>(
id->next);
386 if ((
uint(id->lib->runtime->temp_index) < lib_main_array_len) &&
388 (lib_main_array[id->lib->runtime->temp_index]->
curlib == id->lib))
390 Main *mainvar = lib_main_array[
id->lib->runtime->temp_index];
405 main->next =
nullptr;
411 if (
main->id_map !=
nullptr) {
414 main->id_map =
nullptr;
436 lib->runtime->temp_index =
i;
437 lib_main_array[
i] = libmain;
443 ID *
id =
static_cast<ID *
>(lbarray[
i]->first);
483 main->curlib->runtime->versionfile =
main->versionfile;
484 main->curlib->runtime->subversionfile =
main->subversionfile;
494 return bhead->
code <= 0xFFFF;
503 const short id_type_code = bhead->
code & 0xFFFF;
510 bool is_link =
false;
515 if (code_prev != bhead->code) {
516 code_prev = bhead->code;
541 STRNCPY(filepath_abs, filepath);
574 STRNCPY(
lib->runtime->filepath_abs, filepath_abs);
591 for (; bmain->
prev !=
nullptr; bmain = bmain->
prev) {
598 "A critical error happened (the blend file is likely corrupted): %s",
625 BHeadN *new_bhead =
nullptr;
632 BHead *bhead =
nullptr;
633 if (!bhead_opt.has_value()) {
636 else if (bhead_opt->len < 0) {
641 bhead = &bhead_opt.value();
650#ifdef USE_BHEAD_READ_ON_DEMAND
655 new_bhead->
next = new_bhead->
prev =
nullptr;
659 new_bhead->
bhead = *bhead;
660 const off64_t seek_new = fd->
file->
seek(fd->
file, bhead->
len, SEEK_CUR);
676 new_bhead =
static_cast<BHeadN *
>(
679 new_bhead->
next = new_bhead->
prev =
nullptr;
680#ifdef USE_BHEAD_READ_ON_DEMAND
685 new_bhead->
bhead = *bhead;
720 BHead *bhead =
nullptr;
726 if (new_bhead ==
nullptr) {
731 bhead = &new_bhead->
bhead;
742 return (prev) ? &prev->bhead :
nullptr;
747 BHeadN *new_bhead =
nullptr;
748 BHead *bhead =
nullptr;
756 new_bhead = new_bhead->
next;
757 if (new_bhead ==
nullptr) {
765 bhead = &new_bhead->
bhead;
771#ifdef USE_BHEAD_READ_ON_DEMAND
793 if (fd->
file->
seek(fd->
file, offset_backup, SEEK_SET) == -1) {
812 return &new_bhead_data->
bhead;
818 const char *
id_name =
reinterpret_cast<const char *
>(
840 if (std::holds_alternative<BlenderHeaderInvalid>(header_variant)) {
843 if (std::holds_alternative<BlenderHeaderUnknown>(header_variant)) {
847 const BlenderHeader &header = std::get<BlenderHeader>(header_variant);
884 subversion = atoi(
num);
888 const bool do_alias =
false;
890 &bhead[1], bhead->
len, do_endian_swap,
true, do_alias, r_error_message);
901 fd->
filesdna,
"ID",
"char",
"name[]");
904 fd->
filesdna,
"ID",
"AssetMetaData",
"*asset_data");
916 *r_error_message =
"Missing DNA block";
923 int *blend_thumb =
nullptr;
928 int *
data = (
int *)(bhead + 1);
930 if (bhead->
len <
sizeof(
int[2])) {
934 if (do_endian_swap) {
939 const int width =
data[0];
940 const int height =
data[1];
982 if (processed_ids.
contains(id_iter)) {
985 processed_ids.
add_new(id_iter);
990 if (!used_names.
contains(id_iter->name)) {
991 used_names.
add_new(id_iter->name);
998 used_names.
add_new(id_iter->name);
999 CLOG_INFO(&
LOG, 3,
"ID name has been de-duplicated to '%s'", id_iter->name);
1024 switch (
GS(id_iter->
name)) {
1026 bool has_truncated_slot_identifer =
false;
1032 "Truncated too long action slot name to '%s'",
1034 has_truncated_slot_identifer =
true;
1037 if (!has_truncated_slot_identifer) {
1065 auto visit_constraint = [](
const bConstraint &constraint) ->
bool {
1073 "Truncated too long bActionConstraint.last_slot_identifier to '%s'",
1081 visit_constraint(*con);
1086 visit_constraint(*con);
1098 "Truncated too long AnimData.last_slot_identifier to '%s'",
1104 "Truncated too long AnimData.tmp_last_slot_identifier to '%s'",
1112 "Truncated too long NlaStrip.last_slot_identifier to '%s'",
1135 FileData *fd = MEM_new<FileData>(__func__);
1166 char writer_ver_str[16];
1167 char min_reader_ver_str[16];
1176 writer_ver_str,
sizeof(writer_ver_str),
short(fd->
fileversion), -1);
1178 min_reader_ver_str,
sizeof(min_reader_ver_str), fg->
minversion, -1);
1182 "The file was saved by a newer version, open it with Blender %s or later",
1183 min_reader_ver_str);
1185 "%s: File saved by a newer version of Blender (%s), Blender %s or later is "
1186 "needed to open it.",
1189 min_reader_ver_str);
1204 const char *error_message =
nullptr;
1220 "Blend file '%s' created by a Big Endian version of Blender, support for these "
1221 "files will be removed in Blender 5.0",
1226 "Blend file '%s' created by a Big Endian version of Blender, support for "
1227 "these files will be removed in Blender 5.0",
1236 "Cannot read blend file '%s', incomplete header, may be from a newer version of Blender",
1260 if (rawfile ==
nullptr || rawfile->
read(rawfile, header,
sizeof(header)) !=
sizeof(header)) {
1263 "Unable to read '%s': %s",
1265 errno ? strerror(errno) :
RPT_(
"insufficient content"));
1267 rawfile->
close(rawfile);
1276 rawfile->
seek(rawfile, 0, SEEK_SET);
1279 if (memcmp(header,
"BLENDER",
sizeof(header)) == 0) {
1282 if (file ==
nullptr) {
1290 if (file !=
nullptr) {
1296 if (file !=
nullptr) {
1302 if (rawfile !=
nullptr) {
1303 rawfile->
close(rawfile);
1305 if (file ==
nullptr) {
1323 "Unable to open '%s': %s",
1325 errno ? strerror(errno) :
RPT_(
"unknown error reading file"));
1334 if (fd !=
nullptr) {
1351 if (fd !=
nullptr) {
1381 if (file ==
nullptr) {
1383 mem_file->
close(mem_file);
1418# ifdef USE_BHEAD_READ_ON_DEMAND
1474 const int width = fd_data[0];
1475 const int height = fd_data[1];
1482 data->width = width;
1483 data->height = height;
1484 memcpy(
data->rect, &fd_data[2], data_size -
sizeof(*
data));
1536 const bool is_linked_only,
1539 return newlibadr(fd, self_id, is_linked_only, adr);
1551 entry.nr =
GS(((
ID *)newp)->name);
1564 if (old == entry.newp) {
1568 entry.nr =
GS(((
ID *)newp)->name);
1630 ID *
id,
const IDCacheKey *key,
void **cache_p,
uint ,
void *cache_storage_v)
1640 *storage_key = *key;
1643 storage_value->
cache_v = *cache_p;
1650 ID *
id,
const IDCacheKey *key,
void **cache_p,
const uint flags,
void *cache_storage_v)
1654 if (cache_storage ==
nullptr) {
1675 if (storage_value ==
nullptr) {
1680 *cache_p = storage_value->
cache_v;
1688 void *cache_storage_v)
1694 if (storage_value ==
nullptr) {
1720 if (
id ==
nullptr) {
1750 if (
id ==
nullptr) {
1789 int blocksize, nblocks;
1792 data = (
char *)(bhead + 1);
1796 nblocks = bhead->
nr;
1812 const char *blockname,
1819 using keyT =
const std::pair<const std::string, const int>;
1824 constexpr std::string_view STORAGE_ID =
"readfile";
1830 std::string(STORAGE_ID));
1836 const bool is_id_data = !blockname && (id_type_index >= 0 && id_type_index <
INDEX_ID_MAX);
1840 static const std::array<std::string, INDEX_ID_MAX> id_alloc_names = [] {
1841 auto n =
decltype(id_alloc_names)();
1842 for (
int idtype_index = 0; idtype_index <
INDEX_ID_MAX; idtype_index++) {
1848 n[size_t(idtype_index)] =
"UNKNWOWN";
1851 n[size_t(idtype_index)] = idtype_info->
name;
1857 const std::string block_alloc_name = is_id_data ? id_alloc_names[id_type_index] : blockname;
1859 keyT key{block_alloc_name + struct_name, bh->
nr};
1861 const std::string alloc_string = fmt::format(
1862 fmt::runtime((is_id_data ?
"{}{} (for ID type '{}')" :
"{}{} (for block '{}')")),
1864 bh->
nr > 1 ? fmt::format(
"[{}]", bh->
nr) :
"",
1866 return storage.
insert(key, alloc_string);
1868 return storage.
find(key);
1875 return storage.
insert(id_type_index,
"Data from UNKNOWN");
1878 const std::string alloc_string = fmt::format(
"Data from '{}' ID type", id_type->
name);
1879 return storage.
insert(id_type_index, alloc_string);
1881 return storage.
find(id_type_index);
1889 void *temp =
nullptr;
1892#ifdef USE_BHEAD_READ_ON_DEMAND
1893 BHead *bh_orig = bh;
1902#ifdef USE_BHEAD_READ_ON_DEMAND
1915 const char *alloc_name =
get_alloc_name(fd, bh, blockname, id_type_index);
1917#ifdef USE_BHEAD_READ_ON_DEMAND
1933#ifdef USE_BHEAD_READ_ON_DEMAND
1935 memcpy(temp, (bh + 1), bh->
len);
1947 memcpy(temp, (bh + 1), bh->
len);
1952#ifdef USE_BHEAD_READ_ON_DEMAND
1953 if (bh_orig != bh) {
1964 ID *
id =
static_cast<ID *
>(
read_struct(fd, bh, blockname, id_type_index));
1988 return (bhead->
len) ? (
const void *)(bhead + 1) :
nullptr;
2012 ln->
next =
static_cast<Link *
>(poin);
2033 if (nodetree !=
nullptr) {
2036 if (nodetree->
owner_id ==
nullptr) {
2038 "NULL owner_id pointer for embedded NodeTree of %s, should never happen",
2042 else if (nodetree->
owner_id !=
id) {
2044 "Inconsistent owner_id pointer for embedded NodeTree of %s, should never happen",
2057 "NULL owner_id pointer for embedded Scene Collection of %s, should never happen",
2063 "Inconsistent owner_id pointer for embedded Scene Collection of %s, should "
2116 if (nodetree !=
nullptr && *nodetree !=
nullptr) {
2122 RPT_(
"Data-block '%s' had an invalid embedded node group, which has not been read"),
2148 RPT_(
"Scene '%s' had an invalid root collection, which has not been read"),
2156 id_old !=
nullptr ? &((
Scene *)id_old)->master_collection->id :
2178 const ID *id_target,
2179 const ID *id_current,
2180 const bool is_identical)
2185 int recalc = id_target->
recalc;
2187 if (id_current ==
nullptr) {
2196 if (!is_identical) {
2205 recalc |= id_current->
recalc;
2225 if (
id.runtime.readfile_data) {
2233 if (!
id.runtime.readfile_data) {
2236 return id.runtime.readfile_data->tags;
2242 return id.runtime.readfile_data->tags;
2259 Collection *collection =
reinterpret_cast<Scene *
>(id)->master_collection;
2283 "Unknown or invalid ID type, this should never happen");
2291 id->lib = current_library;
2298 id->newid =
nullptr;
2299 id->orig_id =
nullptr;
2300 id->py_instance =
nullptr;
2316 id->runtime.readfile_data->tags = id_read_tags;
2323 id->library_weak_reference =
nullptr;
2369 id->recalc_after_undo_push = 0;
2373 id->recalc_after_undo_push = 0;
2385 id->override_library->runtime =
nullptr;
2409 block->uid = key->
uidgen++;
2419#ifdef USE_SETSCENE_CHECK
2423static bool scene_validate_setscene__liblink(
Scene *sce,
const int totscene)
2428 if (sce->
set ==
nullptr) {
2432 for (a = 0, sce_iter = sce; sce_iter->
set; sce_iter = sce_iter->
set, a++) {
2457#ifdef USE_SETSCENE_CHECK
2462 if (!scene_validate_setscene__liblink(sce, totscene)) {
2472#undef USE_SETSCENE_CHECK
2495 if (newmain->curlib) {
2496 if (
BLI_path_cmp(newmain->curlib->runtime->filepath_abs,
lib->runtime->filepath_abs) == 0) {
2499 RPT_(
"Library '%s', '%s' had multiple instances, save and reload!"),
2501 lib->runtime->filepath_abs);
2534 lib->runtime->parent =
nullptr;
2544 if (basepath ==
nullptr || basepath[0] ==
'\0') {
2579 const bool was_liboverride)
2584 *((
short *)ph_id->
name) = idcode;
2592 if (was_liboverride) {
2603 if (mainvar->
id_map !=
nullptr) {
2619 ID *obdata =
static_cast<ID *
>(ob->data);
2654 bool success =
true;
2680 const char *allocname,
2681 const int id_type_index)
2691 "Blendfile corruption: Invalid, or multiple `bhead` with same old address "
2692 "value (%p) for a given ID.",
2740 int i = lbarray.size();
2747 ID *
id =
static_cast<ID *
>(lbarray[
i]->first);
2778 if (bhead !=
nullptr) {
2803 if (id_old ==
nullptr) {
2810 for (libmain = libmain->
next; libmain; libmain = libmain->
next) {
2811 if (&libmain->
curlib->
id == id_old) {
2815 " compare with %s -> match (existing libpath: %s)",
2843 if (*r_id_old ==
nullptr) {
2848 if (*r_id_old ==
nullptr) {
2851 " from %s (%s): NOT found",
2859 " from %s (%s): found by name",
2870 " from %s (%s): found by session_uid",
2905 id_old->
newid =
nullptr;
2908 const short idcode =
GS(id_old->
name);
2945 const short idcode =
GS(id->
name);
3014 &
LOG_UNDO, 2,
"UNDO: skip restore datablock %s, 'NO_MEMFILE_UNDO' type of ID", id->
name);
3031 if (!do_partial_undo) {
3034 "UNDO: read %s (uid %u) -> no partial undo, always read at new address",
3045 "UNDO: read %s (uid %u) -> keep identical datablock",
3054 if (id_old !=
nullptr) {
3058 "UNDO: read %s (uid %u) -> read to old existing address",
3083 const bool placeholder_set_indirect_extern,
3091 ID *id_old =
nullptr;
3097 if (
main->id_map !=
nullptr && id_old !=
nullptr) {
3108 const char *blockname =
nullptr;
3112 const char *blockname =
get_alloc_name(fd, bhead,
nullptr, id_type_index);
3115 if (
id ==
nullptr) {
3123 const short idcode =
GS(id->
name);
3125 if (lb ==
nullptr) {
3127 CLOG_WARN(&
LOG,
"Unknown id code '%c%c'", (idcode & 0xff), (idcode >> 8));
3142 ID *id_target = (do_partial_undo && id_old !=
nullptr) ? id_old : id;
3158 if (placeholder_set_indirect_extern) {
3169 if (
main->id_map !=
nullptr) {
3188 if (r_id !=
nullptr) {
3193 if (do_partial_undo && id_old !=
nullptr) {
3200 if (
main->id_map !=
nullptr) {
3314 if (user ==
nullptr) {
3326 main->is_locked_for_linking =
true;
3335 char build_commit_datetime[32];
3336 time_t temp_time =
main->build_commit_timestamp;
3337 tm *tm = (temp_time) ? gmtime(&temp_time) :
nullptr;
3339 strftime(build_commit_datetime,
sizeof(build_commit_datetime),
"%Y-%m-%d %H:%M", tm);
3342 STRNCPY(build_commit_datetime,
"unknown");
3348 " Version %d sub %d date %s hash %s",
3350 main->subversionfile,
3351 build_commit_datetime,
3355 if (!
main->is_read_invalid) {
3358 if (!
main->is_read_invalid) {
3361 if (!
main->is_read_invalid) {
3364 if (!
main->is_read_invalid) {
3367 if (!
main->is_read_invalid) {
3370 if (!
main->is_read_invalid) {
3373 if (!
main->is_read_invalid) {
3376 if (!
main->is_read_invalid) {
3379 if (!
main->is_read_invalid) {
3382 if (!
main->is_read_invalid) {
3385 if (!
main->is_read_invalid) {
3388 if (!
main->is_read_invalid) {
3391 if (!
main->is_read_invalid) {
3400 main->is_locked_for_linking =
false;
3409 "Processing %s (%s), %d.%d",
3410 main->curlib ?
main->curlib->filepath :
main->filepath,
3411 main->curlib ?
"LIB" :
"MAIN",
3413 main->subversionfile);
3416 main->is_locked_for_linking =
true;
3418 if (!
main->is_read_invalid) {
3421 if (!
main->is_read_invalid) {
3424 if (!
main->is_read_invalid) {
3427 if (!
main->is_read_invalid) {
3430 if (!
main->is_read_invalid) {
3433 if (!
main->is_read_invalid) {
3436 if (!
main->is_read_invalid) {
3439 if (!
main->is_read_invalid) {
3442 if (!
main->is_read_invalid) {
3445 if (!
main->is_read_invalid) {
3448 if (!
main->is_read_invalid) {
3451 if (!
main->is_read_invalid) {
3455 main->is_locked_for_linking =
false;
3545 id->orig_id =
nullptr;
3573 "Critical blend-file corruption: Conflicts and/or otherwise invalid data-blocks names "
3574 "(see console for details)");
3634 keymap->modal_items =
nullptr;
3635 keymap->poll =
nullptr;
3645 if (kmdi->remove_item) {
3648 if (kmdi->add_item) {
3719 if (*id_pointer !=
nullptr) {
3775 ListBase mainlist = {
nullptr,
nullptr};
3789 bfd = MEM_new<BlendFileData>(__func__);
3810 const int width =
data[0];
3811 const int height =
data[1];
3836 switch (bhead->
code) {
3868 bhead =
read_libblock(fd, libmain, bhead, 0, {},
true,
nullptr);
3915 Main *libmain, *libmain_next;
3916 for (libmain = old_main->
next; libmain !=
nullptr; libmain = libmain_next) {
3917 libmain_next = libmain->
next;
3929 "Blendfile '%s' was created by a future version of Blender and contains ID "
3930 "names longer than currently supported. These have been truncated.",
3936 "Blendfile '%s' appears corrupted, it contains invalid ID names. These have "
4009 if (mainvar->versionfile == 0) {
4013 mainvar->curlib->runtime->filedata :
4029 if (
lib->runtime->filedata) {
4032 lib->runtime->filedata =
nullptr;
4044 else if (
lib->runtime->versionfile == 0) {
4079 std::string cur_view_layer_name = bfd->
cur_view_layer !=
nullptr ?
4144 if (x1->
old > x2->old) {
4147 if (x1->
old < x2->old) {
4219 if (bhead->
old == old) {
4231 *((
short *)idname_full) = idcode;
4232 BLI_strncpy(idname_full + 2, name,
sizeof(idname_full) - 2);
4255 if (mainvar->
id_map ==
nullptr) {
4272 const bool has_forward_compatibility_issues,
4273 const char *filepath)
4278 if (has_forward_compatibility_issues) {
4281 "Library '%s' was created by a future version of Blender and contains ID names "
4282 "longer than currently supported. This may cause missing linked data, consider "
4283 "opening and re-saving that library with the current Blender version.",
4289 "Library '%s' appears corrupted, it contains invalid ID names. This may cause "
4290 "missing linked data.",
4316 if (bhead ==
nullptr) {
4335 if (bheadlib ==
nullptr) {
4343 if (libmain->
curlib ==
nullptr) {
4348 RPT_(
"LIB: Data refers to main .blend file: '%s' from %s"),
4349 idname ? idname :
"<InvalidIDName>",
4356 if (
id ==
nullptr) {
4392 printf(
"expand_doit: already linked: %s lib: %s\n", id->
name,
lib->filepath);
4402 if (
id ==
nullptr) {
4463 for (
bool do_it =
true; do_it;) {
4499 Main *mainl,
FileData *fd,
const short idcode,
const char *name,
const int flag)
4511 if (
id ==
nullptr) {
4516 read_libblock(fd, mainl, bhead, tag, id_read_tags,
false, &
id);
4535 else if (use_placeholders) {
4557 ID *ret_id =
nullptr;
4572 const char *filepath,
4573 const int id_tag_extra)
4606 const int id_tag_extra)
4611 params->id_tag_extra = id_tag_extra;
4617 const int id_tag_extra,
4624 if (scene !=
nullptr) {
4625 params->context.scene = scene;
4626 params->context.view_layer = view_layer;
4627 params->context.v3d = v3d;
4632 const char *filepath,
4649 int i = lbarray.size();
4667 if (mainl->
id_map ==
nullptr) {
4692 mainvar =
static_cast<Main *
>((*fd)->mainlist->first);
4718 for (mainvar = ((
Main *)(*fd)->mainlist->first)->
next; mainvar; mainvar = mainvar->
next) {
4737 mainvar =
static_cast<Main *
>((*fd)->mainlist->first);
4800 if (
lib->runtime->filedata ==
reinterpret_cast<FileData *
>(*bh)) {
4802 lib->runtime->filedata =
nullptr;
4804 else if (
lib->runtime->filedata) {
4812 lib->runtime->filedata =
nullptr;
4816 *bh =
reinterpret_cast<BlendHandle *
>(fd);
4833 int a = lbarray.size();
4850 BHead *bhead =
nullptr;
4865 RPT_(
"LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
4866 "non-linkable data type"),
4884 "LIB: %s: '%s' missing from '%s', parent '%s'",
4911 int a = lbarray.size();
4913 ID *
id =
static_cast<ID *
>(lbarray[a]->first);
4916 ID *id_next =
static_cast<ID *
>(
id->next);
4921 if (mainvar->
id_map !=
nullptr) {
4949 id->runtime.readfile_data =
nullptr;
4976 int a = lbarray.size();
4978 ID *
id =
static_cast<ID *
>(lbarray[a]->first);
4981 ID *id_next =
static_cast<ID *
>(
id->next);
5004 if (fd !=
nullptr) {
5015 RPT_(
"Read packed library: '%s', parent '%s'"),
5027 RPT_(
"Read library: '%s', '%s', parent '%s'"),
5064 if (fd ==
nullptr) {
5067 RPT_(
"Cannot find lib '%s'"),
5092 for (
Main *mainptr = mainl->
next; mainptr; mainptr = mainptr->
next) {
5097 "Reading linked data-blocks from %s (%s)",
5098 mainptr->curlib->id.name,
5099 mainptr->curlib->filepath);
5107 if (mainptr->id_map ==
nullptr) {
5123 for (
Main *mainptr = mainl->
next; mainptr; mainptr = mainptr->
next) {
5131 for (
Main *mainptr = mainl->
next; mainptr; mainptr = mainptr->
next) {
5135 if (mainptr->versionfile) {
5146 if (mainptr->curlib->runtime->filedata) {
5147 do_versions(mainptr->curlib->runtime->filedata, mainptr->curlib, main_newid);
5154 if (mainptr->curlib->runtime->filedata) {
5155 lib_link_all(mainptr->curlib->runtime->filedata, mainptr);
5172 const size_t expected_size)
5174 if (new_address !=
nullptr) {
5180 "Corrupt .blend file, unexpected data size.");
5199 const void *old_address,
5200 const size_t expected_size)
5207 const void *old_address,
5208 const size_t expected_size)
5210 void *new_address =
newdataadr(reader->
fd, old_address);
5215 const char *struct_name,
5217 const void *old_address)
5228 const bool is_linked_only,
5231 return static_cast<ID *
>(
newlibadr(reader->
fd, self_id, is_linked_only,
id));
5251 const char *vartype,
5258 const size_t expected_elem_size,
5267 Link *prev =
nullptr;
5280 *ptr_p =
reinterpret_cast<char *
>(
5286 *ptr_p =
reinterpret_cast<uint8_t *
>(
5292 *ptr_p =
reinterpret_cast<int8_t *
>(
5298 *ptr_p =
reinterpret_cast<int16_t *
>(
5308 *ptr_p =
reinterpret_cast<int32_t *
>(
5318 *ptr_p =
reinterpret_cast<uint32_t *
>(
5328 *ptr_p =
reinterpret_cast<float *
>(
5343 *ptr_p =
reinterpret_cast<double *
>(
5356 const char *
str = *ptr_p;
5360 if (
str[
len - 1] ==
'\0') {
5365 BLI_assert_msg(0,
"Corrupt .blend file, expected string to be null terminated.");
5386 for (
int i = 0;
i < array_size;
i++) {
5393 const uint32_t *src,
5397 for (
int i = 0;
i < array_size;
i++) {
5407 if (orig_array ==
nullptr) {
5415 void *final_array =
nullptr;
5417 if (file_pointer_size == current_pointer_size) {
5419 final_array = orig_array;
5421 else if (file_pointer_size == 8 && current_pointer_size == 4) {
5425 reader, array_size, (
uint64_t *)orig_array, (uint32_t *)final_array);
5428 else if (file_pointer_size == 4 && current_pointer_size == 8) {
5432 reader, array_size, (uint32_t *)orig_array, (
uint64_t *)final_array);
5439 *ptr_p = final_array;
5447 const void *old_address = *ptr_p;
5458 sharing_info->add_user();
5459 return {sharing_info, old_address};
5470 if (shared_data->sharing_info) {
5471 shared_data->sharing_info->add_user();
5473 return *shared_data;
5479 const void *new_address = *ptr_p;
5512 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)
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)
@ IDTYPE_FLAGS_NO_MEMFILE_UNDO
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_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_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_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
#define FOREACH_MAIN_ID_END
MainListsArray BKE_main_lists_get(Main &bmain)
ListBase * which_libbase(Main *bmain, short type)
#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)
bool BKE_reports_print_test(const ReportList *reports, eReportType type)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
const char * BKE_report_type_str(eReportType type)
void BKE_report(ReportList *reports, eReportType type, const char *message)
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)
void BLI_endian_switch_float_array(float *val, int size) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_int32(int *val) ATTR_NONNULL(1)
void BLI_endian_switch_int32_array(int *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_uint32_array(unsigned int *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_int16_array(short *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_double_array(double *val, int size) ATTR_NONNULL(1)
File and directory operations.
bool BLI_file_magic_is_gzip(const char header[4])
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)
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
#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, const bool use_endian_swap)
std::optional< BHead > BLO_readfile_read_bhead(FileReader *file, BHeadType type, bool do_endian_swap)
#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.
void(*)(void *fdhandle, Main *mainvar, void *idv) BLOExpandDoitCallback
@ 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_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
@ 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
@ ID_FLAG_INDIRECT_WEAK_LINK
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 DNA_ReconstructInfo * DNA_reconstruct_info_create(const struct SDNA *oldsdna, const struct SDNA *newsdna, const char *compare_flags)
struct SDNA * DNA_sdna_from_data(const void *data, int data_len, bool do_endian_swap, bool data_alloc, bool do_alias, const char **r_error_message)
void DNA_struct_switch_endian(const struct SDNA *sdna, int struct_index, char *data)
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
Read Guarded memory(de)allocation.
BKE_main_namemap_clear * new_bmain
BKE_main_namemap_clear * old_bmain
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)
Value lookup_default(const Key &key, const Value &default_value) const
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)
const char * insert(const keyT &key, std::string alloc_string)
bool contains(const keyT &key)
const char * find(const keyT &key)
std::string id_name(void *id)
#define pf(_x, _i)
Prefetch 64.
#define ID_FAKE_USERS(id)
#define ID_IS_LINKED(_id)
#define ID_LINK_PLACEHOLDER
#define ID_TAG_KEEP_ON_UNDO
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)
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 read_libraries(FileData *basefd, ListBase *mainlist)
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)
void BLO_read_struct_list_with_size(BlendDataReader *reader, const size_t expected_elem_size, ListBase *list)
static bool read_libblock_undo_restore_library(FileData *fd, Main *new_main, const ID *id, ID *id_old, BHead *bhead)
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)
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 direct_link_library(FileData *fd, Library *lib, Main *main)
int BLO_read_struct_member_offset(const BlendDataReader *reader, const char *stype, const char *vartype, const char *name)
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)
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)
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 change_ID_pointer_to_real_ID_pointer(ListBase *mainlist, FileData *basefd, void *old, void *newp)
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 split_libdata(ListBase *lb_src, Main **lib_main_array, const uint lib_main_array_len)
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 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)
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)
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)
static void switch_endian_structs(const SDNA *filesdna, BHead *bhead)
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 sort_bhead_old_map(FileData *fd)
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)
static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
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 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 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)
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 read_library_linked_ids(FileData *basefd, FileData *fd, ListBase *mainlist, Main *mainvar)
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)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
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 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)
void blo_split_main(ListBase *mainlist, Main *main)
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 void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist, FileData *basefd, void *old, void *newp)
static FileData * blo_filedata_from_file_minimal(const char *filepath)
static void oldnewmap_clear(OldNewMap *onm)
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)
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)
static void read_library_clear_weak_links(FileData *basefd, ListBase *mainlist, Main *mainvar)
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)
static bool is_minversion_older_than_blender(FileData *fd, ReportList *reports)
void BLO_expand_main(void *fdhandle, Main *mainvar, BLOExpandDoitCallback callback)
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 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 Main * blo_find_main(FileData *fd, const char *filepath, const char *relabase)
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)
static void read_undo_move_libmain_data(FileData *fd, Main *new_main, Main *old_main, Main *libmain, BHead *bhead)
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 read_file_version(FileData *fd, Main *main)
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)
void blo_join_main(ListBase *mainlist)
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 FileData * read_library_file_data(FileData *basefd, ListBase *mainlist, Main *mainl, Main *mainptr)
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_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_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 last_slot_identifier[66]
char tmp_last_slot_identifier[66]
bool is_memchunk_identical
blender::Map< const void *, blender::ImplicitSharingInfoAndData > shared_data_by_stored_address
BLOExpandDoitCallback callback
ViewLayer * cur_view_layer
struct BlendFileReadReport::@142320212234231245113115306176140270124216310033 duration
struct BlendFileReadReport::@322005145130211163057315230271062050320025262277 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
BlendFileReadReport * reports
IDNameLib_Map * old_idmap_uid
struct ViewLayer * cur_view_layer
uint64_t build_commit_timestamp
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
struct ID_Readfile_Data * readfile_data
unsigned int recalc_after_undo_push
struct AssetMetaData * asset_data
IDProperty * system_properties
IDOverrideLibrary * override_library
unsigned int recalc_up_to_undo_push
struct LibraryWeakReference * library_weak_reference
struct ID_Runtime runtime
LibraryForeachIDCallbackFlag cb_flag
struct PackedFile * packedfile
LibraryRuntimeHandle * runtime
bool has_forward_compatibility_issues
BlendThumbnail * blen_thumb
uint64_t build_commit_timestamp
blender::Map< const void *, const blender::ImplicitSharingInfo * > map
MemFileSharedStorage * shared_storage
char last_slot_identifier[66]
blender::Map< const void *, NewAddress > map
struct Collection * master_collection
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[66]
struct ActionSlot ** slot_array
void version_forward_compat_system_idprops(Main *bmain)
short do_versions_new_to_old_idcode_get(const short id_code_new)
static DynamicLibrary lib