Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenloader/intern/writefile.c
| Show First 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_action.h" | #include "BKE_action.h" | ||||
| #include "BKE_blender_version.h" | #include "BKE_blender_version.h" | ||||
| #include "BKE_bpath.h" | #include "BKE_bpath.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_constraint.h" | #include "BKE_constraint.h" | ||||
| #include "BKE_global.h" // for G | #include "BKE_global.h" // for G | ||||
| #include "BKE_idcode.h" | #include "BKE_idcode.h" | ||||
| #include "BKE_library.h" // for set_listbasepointers | #include "BKE_library.h" // for set_listbasepointers | ||||
| #include "BKE_library_override.h" | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_sequencer.h" | #include "BKE_sequencer.h" | ||||
| #include "BKE_subsurf.h" | #include "BKE_subsurf.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_pointcache.h" | #include "BKE_pointcache.h" | ||||
| ▲ Show 20 Lines • Show All 497 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void write_iddata(void *wd, const ID *id) | static void write_iddata(void *wd, const ID *id) | ||||
| { | { | ||||
| /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ | /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ | ||||
| if (id->properties && !ELEM(GS(id->name), ID_WM)) { | if (id->properties && !ELEM(GS(id->name), ID_WM)) { | ||||
| IDP_WriteProperty(id->properties, wd); | IDP_WriteProperty(id->properties, wd); | ||||
| } | } | ||||
| if (id->override_static) { | |||||
| writestruct(wd, DATA, IDOverrideStatic, 1, id->override_static); | |||||
| writelist(wd, DATA, IDOverrideStaticProperty, &id->override_static->properties); | |||||
| for (IDOverrideStaticProperty *op = id->override_static->properties.first; op; op = op->next) { | |||||
| writedata(wd, DATA, strlen(op->rna_path) + 1, op->rna_path); | |||||
| writelist(wd, DATA, IDOverrideStaticPropertyOperation, &op->operations); | |||||
| for (IDOverrideStaticPropertyOperation *opop = op->operations.first; opop; opop = opop->next) { | |||||
| if (opop->subitem_reference_name) { | |||||
| writedata(wd, DATA, strlen(opop->subitem_reference_name) + 1, opop->subitem_reference_name); | |||||
| } | |||||
| if (opop->subitem_local_name) { | |||||
| writedata(wd, DATA, strlen(opop->subitem_local_name) + 1, opop->subitem_local_name); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| static void write_previews(WriteData *wd, const PreviewImage *prv_orig) | static void write_previews(WriteData *wd, const PreviewImage *prv_orig) | ||||
| { | { | ||||
| /* Never write previews when doing memsave (i.e. undo/redo)! */ | /* Never write previews when doing memsave (i.e. undo/redo)! */ | ||||
| if (prv_orig && !wd->current) { | if (prv_orig && !wd->current) { | ||||
| PreviewImage prv = *prv_orig; | PreviewImage prv = *prv_orig; | ||||
| ▲ Show 20 Lines • Show All 3,090 Lines • ▼ Show 20 Lines | else { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */ | /* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */ | ||||
| /* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the] | /* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the] | ||||
| * quit.blend and temp saves */ | * quit.blend and temp saves */ | ||||
| if (found_one) { | if (found_one) { | ||||
| /* Not overridable. */ | |||||
| writestruct(wd, ID_LI, Library, 1, main->curlib); | writestruct(wd, ID_LI, Library, 1, main->curlib); | ||||
| write_iddata(wd, &main->curlib->id); | write_iddata(wd, &main->curlib->id); | ||||
| if (main->curlib->packedfile) { | if (main->curlib->packedfile) { | ||||
| PackedFile *pf = main->curlib->packedfile; | PackedFile *pf = main->curlib->packedfile; | ||||
| writestruct(wd, DATA, PackedFile, 1, pf); | writestruct(wd, DATA, PackedFile, 1, pf); | ||||
| writedata(wd, DATA, pf->size, pf->data); | writedata(wd, DATA, pf->size, pf->data); | ||||
| if (wd->current == NULL) { | if (wd->current == NULL) { | ||||
| ▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | #endif | ||||
| write_renderinfo(wd, mainvar); | write_renderinfo(wd, mainvar); | ||||
| write_thumb(wd, thumb); | write_thumb(wd, thumb); | ||||
| write_global(wd, write_flags, mainvar); | write_global(wd, write_flags, mainvar); | ||||
| /* The windowmanager and screen often change, | /* The windowmanager and screen often change, | ||||
| * avoid thumbnail detecting changes because of this. */ | * avoid thumbnail detecting changes because of this. */ | ||||
| mywrite_flush(wd); | mywrite_flush(wd); | ||||
| OverrideStaticStorage *override_storage = !wd->current ? BKE_override_static_operations_store_initialize() : NULL; | |||||
| /* This outer loop allows to save first datablocks from real mainvar, then the temp ones from override process, | |||||
| * if needed, without duplicating whole code. */ | |||||
| Main *bmain = mainvar; | |||||
| do { | |||||
| ListBase *lbarray[MAX_LIBARRAY]; | ListBase *lbarray[MAX_LIBARRAY]; | ||||
| int a = set_listbasepointers(mainvar, lbarray); | int a = set_listbasepointers(bmain, lbarray); | ||||
| while (a--) { | while (a--) { | ||||
| ID *id = lbarray[a]->first; | ID *id = lbarray[a]->first; | ||||
| if (id && GS(id->name) == ID_LI) { | if (id && GS(id->name) == ID_LI) { | ||||
| continue; /* Libraries are handled separately below. */ | continue; /* Libraries are handled separately below. */ | ||||
| } | } | ||||
| for (; id; id = id->next) { | for (; id; id = id->next) { | ||||
| /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */ | /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */ | ||||
| BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0); | BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0); | ||||
| const bool do_override = !ELEM(override_storage, NULL, bmain) && id->override_static; | |||||
| if (do_override) { | |||||
| BKE_override_static_operations_store_start(override_storage, id); | |||||
| } | |||||
| switch ((ID_Type)GS(id->name)) { | switch ((ID_Type)GS(id->name)) { | ||||
| case ID_WM: | case ID_WM: | ||||
| write_windowmanager(wd, (wmWindowManager *)id); | write_windowmanager(wd, (wmWindowManager *)id); | ||||
| break; | break; | ||||
| case ID_WS: | case ID_WS: | ||||
| write_workspace(wd, (WorkSpace *)id); | write_workspace(wd, (WorkSpace *)id); | ||||
| break; | break; | ||||
| case ID_SCR: | case ID_SCR: | ||||
| write_screen(wd, (bScreen *)id); | write_screen(wd, (bScreen *)id); | ||||
| break; | break; | ||||
| case ID_MC: | case ID_MC: | ||||
| write_movieclip(wd, (MovieClip *)id); | write_movieclip(wd, (MovieClip *)id); | ||||
| break; | break; | ||||
| case ID_MSK: | case ID_MSK: | ||||
| write_mask(wd, (Mask *)id); | write_mask(wd, (Mask *)id); | ||||
| break; | break; | ||||
| case ID_SCE: | case ID_SCE: | ||||
| write_scene(wd, (Scene *)id); | write_scene(wd, (Scene *)id); | ||||
| break; | break; | ||||
| case ID_CU: | case ID_CU: | ||||
| write_curve(wd, (Curve *)id); | write_curve(wd,(Curve *)id); | ||||
| break; | break; | ||||
| case ID_MB: | case ID_MB: | ||||
| write_mball(wd, (MetaBall *)id); | write_mball(wd, (MetaBall *)id); | ||||
| break; | break; | ||||
| case ID_IM: | case ID_IM: | ||||
| write_image(wd, (Image *)id); | write_image(wd, (Image *)id); | ||||
| break; | break; | ||||
| case ID_CA: | case ID_CA: | ||||
| write_camera(wd, (Camera *)id); | write_camera(wd, (Camera *)id); | ||||
| break; | break; | ||||
| case ID_LA: | case ID_LA: | ||||
| write_lamp(wd, (Lamp *)id); | write_lamp(wd, (Lamp *)id); | ||||
| break; | break; | ||||
| case ID_LT: | case ID_LT: | ||||
| write_lattice(wd, (Lattice *)id); | write_lattice(wd, (Lattice *)id); | ||||
| break; | break; | ||||
| case ID_VF: | case ID_VF: | ||||
| write_vfont(wd, (VFont *)id); | write_vfont(wd, (VFont *)id); | ||||
| break; | break; | ||||
| case ID_KE: | case ID_KE: | ||||
| write_key(wd, (Key *)id); | write_key(wd, (Key *)id); | ||||
| break; | break; | ||||
| case ID_WO: | case ID_WO: | ||||
| write_world(wd, (World *)id); | write_world(wd, (World *)id); | ||||
| break; | break; | ||||
| case ID_TXT: | case ID_TXT: | ||||
| write_text(wd, (Text *)id); | write_text(wd, (Text *)id); | ||||
| break; | break; | ||||
| case ID_SPK: | case ID_SPK: | ||||
| write_speaker(wd, (Speaker *)id); | write_speaker(wd, (Speaker *)id); | ||||
| break; | break; | ||||
| case ID_LP: | case ID_LP: | ||||
| write_probe(wd, (LightProbe *)id); | write_probe(wd, (LightProbe *)id); | ||||
| break; | break; | ||||
| case ID_SO: | case ID_SO: | ||||
| write_sound(wd, (bSound *)id); | write_sound(wd, (bSound *)id); | ||||
| break; | break; | ||||
| case ID_GR: | case ID_GR: | ||||
| write_group(wd, (Group *)id); | write_group(wd, (Group *)id); | ||||
| break; | break; | ||||
| case ID_AR: | case ID_AR: | ||||
| write_armature(wd, (bArmature *)id); | write_armature(wd, (bArmature *)id); | ||||
| break; | break; | ||||
| case ID_AC: | case ID_AC: | ||||
| write_action(wd, (bAction *)id); | write_action(wd, (bAction *)id); | ||||
| break; | break; | ||||
| case ID_OB: | case ID_OB: | ||||
| write_object(wd, (Object *)id); | write_object(wd, (Object *)id); | ||||
| break; | break; | ||||
| case ID_MA: | case ID_MA: | ||||
| write_material(wd, (Material *)id); | write_material(wd, (Material *)id); | ||||
| break; | break; | ||||
| case ID_TE: | case ID_TE: | ||||
| write_texture(wd, (Tex *)id); | write_texture(wd, (Tex *)id); | ||||
| break; | break; | ||||
| case ID_ME: | case ID_ME: | ||||
| write_mesh(wd, (Mesh *)id); | write_mesh(wd, (Mesh *)id); | ||||
| break; | break; | ||||
| case ID_PA: | case ID_PA: | ||||
| write_particlesettings(wd, (ParticleSettings *)id); | write_particlesettings(wd, (ParticleSettings *)id); | ||||
| break; | break; | ||||
| case ID_NT: | case ID_NT: | ||||
| write_nodetree(wd, (bNodeTree *)id); | write_nodetree(wd, (bNodeTree *)id); | ||||
| break; | break; | ||||
| case ID_BR: | case ID_BR: | ||||
| write_brush(wd, (Brush *)id); | write_brush(wd, (Brush *)id); | ||||
| break; | break; | ||||
| case ID_PAL: | case ID_PAL: | ||||
| write_palette(wd, (Palette *)id); | write_palette(wd, (Palette *)id); | ||||
| break; | break; | ||||
| case ID_PC: | case ID_PC: | ||||
| write_paintcurve(wd, (PaintCurve *)id); | write_paintcurve(wd, (PaintCurve *)id); | ||||
| break; | break; | ||||
| case ID_GD: | case ID_GD: | ||||
| write_gpencil(wd, (bGPdata *)id); | write_gpencil(wd, (bGPdata *)id); | ||||
| break; | break; | ||||
| case ID_LS: | case ID_LS: | ||||
| write_linestyle(wd, (FreestyleLineStyle *)id); | write_linestyle(wd, (FreestyleLineStyle *)id); | ||||
| break; | break; | ||||
| case ID_CF: | case ID_CF: | ||||
| write_cachefile(wd, (CacheFile *)id); | write_cachefile(wd, (CacheFile *)id); | ||||
| break; | break; | ||||
| case ID_LI: | case ID_LI: | ||||
| /* Do nothing, handled below - and should never be reached. */ | /* Do nothing, handled below - and should never be reached. */ | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| break; | break; | ||||
| case ID_IP: | case ID_IP: | ||||
| /* Do nothing, deprecated. */ | /* Do nothing, deprecated. */ | ||||
| break; | break; | ||||
| default: | default: | ||||
| /* Should never be reached. */ | /* Should never be reached. */ | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| break; | break; | ||||
| } | } | ||||
| if (do_override) { | |||||
| BKE_override_static_operations_store_end(override_storage, id); | |||||
| } | |||||
| } | } | ||||
| mywrite_flush(wd); | mywrite_flush(wd); | ||||
| } | } | ||||
| } while ((bmain != override_storage) && (bmain = override_storage)); | |||||
| if (override_storage) { | |||||
| BKE_override_static_operations_store_finalize(override_storage); | |||||
| override_storage = NULL; | |||||
| } | |||||
| /* Special handling, operating over split Mains... */ | /* Special handling, operating over split Mains... */ | ||||
| write_libraries(wd, mainvar->next); | write_libraries(wd, mainvar->next); | ||||
| /* So changes above don't cause a 'DNA1' to be detected as changed on undo. */ | /* So changes above don't cause a 'DNA1' to be detected as changed on undo. */ | ||||
| mywrite_flush(wd); | mywrite_flush(wd); | ||||
| if (write_flags & G_FILE_USERPREFS) { | if (write_flags & G_FILE_USERPREFS) { | ||||
| ▲ Show 20 Lines • Show All 185 Lines • Show Last 20 Lines | |||||