diff options
Diffstat (limited to 'source/blender/blenloader/intern/writefile.c')
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1506 |
1 files changed, 48 insertions, 1458 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 8bbdee78381..11fe240620a 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -93,96 +93,27 @@ /* allow writefile to use deprecated functionality (for forward compatibility code) */ #define DNA_DEPRECATED_ALLOW -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_brush_types.h" -#include "DNA_cachefile_types.h" -#include "DNA_camera_types.h" -#include "DNA_cloth_types.h" -#include "DNA_collection_types.h" -#include "DNA_constraint_types.h" -#include "DNA_curveprofile_types.h" -#include "DNA_dynamicpaint_types.h" #include "DNA_fileglobal_types.h" -#include "DNA_fluid_types.h" #include "DNA_genfile.h" -#include "DNA_gpencil_modifier_types.h" -#include "DNA_gpencil_types.h" -#include "DNA_hair_types.h" -#include "DNA_key_types.h" -#include "DNA_lattice_types.h" -#include "DNA_layer_types.h" -#include "DNA_light_types.h" -#include "DNA_lightprobe_types.h" -#include "DNA_linestyle_types.h" -#include "DNA_mask_types.h" -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_meta_types.h" -#include "DNA_movieclip_types.h" -#include "DNA_node_types.h" -#include "DNA_object_force_types.h" -#include "DNA_object_types.h" -#include "DNA_packedFile_types.h" -#include "DNA_particle_types.h" -#include "DNA_pointcache_types.h" -#include "DNA_pointcloud_types.h" -#include "DNA_rigidbody_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" #include "DNA_sdna_types.h" -#include "DNA_sequence_types.h" -#include "DNA_shader_fx_types.h" -#include "DNA_simulation_types.h" -#include "DNA_sound_types.h" -#include "DNA_space_types.h" -#include "DNA_speaker_types.h" -#include "DNA_text_types.h" -#include "DNA_vfont_types.h" -#include "DNA_view3d_types.h" -#include "DNA_volume_types.h" -#include "DNA_windowmanager_types.h" -#include "DNA_workspace_types.h" -#include "DNA_world_types.h" #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_mempool.h" -#include "MEM_guardedalloc.h" // MEM_freeN +#include "MEM_guardedalloc.h" /* MEM_freeN */ -#include "BKE_action.h" -#include "BKE_anim_data.h" -#include "BKE_animsys.h" -#include "BKE_armature.h" #include "BKE_blender_version.h" #include "BKE_bpath.h" -#include "BKE_collection.h" -#include "BKE_colortools.h" -#include "BKE_constraint.h" -#include "BKE_curve.h" -#include "BKE_curveprofile.h" -#include "BKE_deform.h" -#include "BKE_fcurve.h" -#include "BKE_fcurve_driver.h" -#include "BKE_global.h" // for G -#include "BKE_gpencil_modifier.h" -#include "BKE_icons.h" +#include "BKE_global.h" /* for G */ #include "BKE_idprop.h" #include "BKE_idtype.h" #include "BKE_layer.h" #include "BKE_lib_id.h" #include "BKE_lib_override.h" #include "BKE_main.h" -#include "BKE_modifier.h" #include "BKE_node.h" -#include "BKE_object.h" #include "BKE_packedFile.h" -#include "BKE_pointcache.h" #include "BKE_report.h" -#include "BKE_sequencer.h" -#include "BKE_shader_fx.h" -#include "BKE_subsurf.h" #include "BKE_workspace.h" #include "BLO_blend_defs.h" @@ -322,7 +253,7 @@ typedef struct { /** Use for file and memory writing (fixed size of #MYWRITE_BUFFER_SIZE). */ uchar *buf; /** Number of bytes used in #WriteData.buf (flushed when exceeded). */ - int buf_used_len; + size_t buf_used_len; #ifdef USE_WRITE_DATA_LEN /** Total number of bytes written. */ @@ -364,12 +295,17 @@ static WriteData *writedata_new(WriteWrap *ww) return wd; } -static void writedata_do_write(WriteData *wd, const void *mem, int memlen) +static void writedata_do_write(WriteData *wd, const void *mem, size_t memlen) { if ((wd == NULL) || wd->error || (mem == NULL) || memlen < 1) { return; } + if (memlen > INT_MAX) { + BLI_assert(!"Cannot write chunks bigger than INT_MAX."); + return; + } + if (UNLIKELY(wd->error)) { return; } @@ -405,7 +341,7 @@ static void writedata_free(WriteData *wd) */ static void mywrite_flush(WriteData *wd) { - if (wd->buf_used_len) { + if (wd->buf_used_len != 0) { writedata_do_write(wd, wd->buf, wd->buf_used_len); wd->buf_used_len = 0; } @@ -416,7 +352,7 @@ static void mywrite_flush(WriteData *wd) * \param adr: Pointer to new chunk of data * \param len: Length of new chunk of data */ -static void mywrite(WriteData *wd, const void *adr, int len) +static void mywrite(WriteData *wd, const void *adr, size_t len) { if (UNLIKELY(wd->error)) { return; @@ -438,13 +374,13 @@ static void mywrite(WriteData *wd, const void *adr, int len) /* if we have a single big chunk, write existing data in * buffer and write out big chunk in smaller pieces */ if (len > MYWRITE_MAX_CHUNK) { - if (wd->buf_used_len) { + if (wd->buf_used_len != 0) { writedata_do_write(wd, wd->buf, wd->buf_used_len); wd->buf_used_len = 0; } do { - int writelen = MIN2(len, MYWRITE_MAX_CHUNK); + size_t writelen = MIN2(len, MYWRITE_MAX_CHUNK); writedata_do_write(wd, adr, writelen); adr = (const char *)adr + writelen; len -= writelen; @@ -492,7 +428,7 @@ static WriteData *mywrite_begin(WriteWrap *ww, MemFile *compare, MemFile *curren */ static bool mywrite_end(WriteData *wd) { - if (wd->buf_used_len) { + if (wd->buf_used_len != 0) { writedata_do_write(wd, wd->buf, wd->buf_used_len); wd->buf_used_len = 0; } @@ -559,7 +495,6 @@ static void writestruct_at_address_nr( WriteData *wd, int filecode, const int struct_nr, int nr, const void *adr, const void *data) { BHead bh; - const short *sp; BLI_assert(struct_nr > 0 && struct_nr < SDNA_TYPE_MAX); @@ -573,16 +508,16 @@ static void writestruct_at_address_nr( bh.nr = nr; bh.SDNAnr = struct_nr; - sp = wd->sdna->structs[bh.SDNAnr]; + const SDNA_Struct *struct_info = wd->sdna->structs[bh.SDNAnr]; - bh.len = nr * wd->sdna->types_size[sp[0]]; + bh.len = nr * wd->sdna->types_size[struct_info->type]; if (bh.len == 0) { return; } mywrite(wd, &bh, sizeof(BHead)); - mywrite(wd, data, bh.len); + mywrite(wd, data, (size_t)bh.len); } static void writestruct_nr( @@ -592,7 +527,7 @@ static void writestruct_nr( } /* do not use for structs */ -static void writedata(WriteData *wd, int filecode, int len, const void *adr) +static void writedata(WriteData *wd, int filecode, size_t len, const void *adr) { BHead bh; @@ -600,15 +535,20 @@ static void writedata(WriteData *wd, int filecode, int len, const void *adr) return; } + if (len > INT_MAX) { + BLI_assert(!"Cannot write chunks bigger than INT_MAX."); + return; + } + /* align to 4 (writes uninitialized bytes in some cases) */ - len = (len + 3) & ~3; + len = (len + 3) & ~((size_t)3); /* init BHead */ bh.code = filecode; bh.old = adr; bh.nr = 1; bh.SDNAnr = 0; - bh.len = len; + bh.len = (int)len; mywrite(wd, &bh, sizeof(BHead)); mywrite(wd, adr, len); @@ -820,1290 +760,6 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef) } } -static void write_boid_state(BlendWriter *writer, BoidState *state) -{ - BLO_write_struct(writer, BoidState, state); - - LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { - switch (rule->type) { - case eBoidRuleType_Goal: - case eBoidRuleType_Avoid: - BLO_write_struct(writer, BoidRuleGoalAvoid, rule); - break; - case eBoidRuleType_AvoidCollision: - BLO_write_struct(writer, BoidRuleAvoidCollision, rule); - break; - case eBoidRuleType_FollowLeader: - BLO_write_struct(writer, BoidRuleFollowLeader, rule); - break; - case eBoidRuleType_AverageSpeed: - BLO_write_struct(writer, BoidRuleAverageSpeed, rule); - break; - case eBoidRuleType_Fight: - BLO_write_struct(writer, BoidRuleFight, rule); - break; - default: - BLO_write_struct(writer, BoidRule, rule); - break; - } - } -#if 0 - BoidCondition *cond = state->conditions.first; - for (; cond; cond = cond->next) { - BLO_write_struct(writer, BoidCondition, cond); - } -#endif -} - -/* update this also to readfile.c */ -static const char *ptcache_data_struct[] = { - "", // BPHYS_DATA_INDEX - "", // BPHYS_DATA_LOCATION - "", // BPHYS_DATA_VELOCITY - "", // BPHYS_DATA_ROTATION - "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */ - "", // BPHYS_DATA_SIZE: - "", // BPHYS_DATA_TIMES: - "BoidData", // case BPHYS_DATA_BOIDS: -}; -static const char *ptcache_extra_struct[] = { - "", - "ParticleSpring", - "vec3f", -}; -static void write_pointcaches(BlendWriter *writer, ListBase *ptcaches) -{ - LISTBASE_FOREACH (PointCache *, cache, ptcaches) { - BLO_write_struct(writer, PointCache, cache); - - if ((cache->flag & PTCACHE_DISK_CACHE) == 0) { - LISTBASE_FOREACH (PTCacheMem *, pm, &cache->mem_cache) { - BLO_write_struct(writer, PTCacheMem, pm); - - for (int i = 0; i < BPHYS_TOT_DATA; i++) { - if (pm->data[i] && pm->data_types & (1 << i)) { - if (ptcache_data_struct[i][0] == '\0') { - BLO_write_raw(writer, MEM_allocN_len(pm->data[i]), pm->data[i]); - } - else { - BLO_write_struct_array_by_name( - writer, ptcache_data_struct[i], pm->totpoint, pm->data[i]); - } - } - } - - LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) { - if (ptcache_extra_struct[extra->type][0] == '\0') { - continue; - } - BLO_write_struct(writer, PTCacheExtra, extra); - BLO_write_struct_array_by_name( - writer, ptcache_extra_struct[extra->type], extra->totdata, extra->data); - } - } - } - } -} - -static void write_particlesettings(BlendWriter *writer, - ParticleSettings *part, - const void *id_address) -{ - if (part->id.us > 0 || BLO_write_is_undo(writer)) { - /* write LibData */ - BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id); - BKE_id_blend_write(writer, &part->id); - - if (part->adt) { - BKE_animdata_blend_write(writer, part->adt); - } - BLO_write_struct(writer, PartDeflect, part->pd); - BLO_write_struct(writer, PartDeflect, part->pd2); - BLO_write_struct(writer, EffectorWeights, part->effector_weights); - - if (part->clumpcurve) { - BKE_curvemapping_blend_write(writer, part->clumpcurve); - } - if (part->roughcurve) { - BKE_curvemapping_blend_write(writer, part->roughcurve); - } - if (part->twistcurve) { - BKE_curvemapping_blend_write(writer, part->twistcurve); - } - - LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ - if (dw->ob != NULL) { - dw->index = 0; - if (part->instance_collection) { /* can be NULL if lining fails or set to None */ - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) { - if (object == dw->ob) { - break; - } - dw->index++; - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - } - } - BLO_write_struct(writer, ParticleDupliWeight, dw); - } - - if (part->boids && part->phystype == PART_PHYS_BOIDS) { - BLO_write_struct(writer, BoidSettings, part->boids); - - LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - write_boid_state(writer, state); - } - } - if (part->fluid && part->phystype == PART_PHYS_FLUID) { - BLO_write_struct(writer, SPHFluidSettings, part->fluid); - } - - for (int a = 0; a < MAX_MTEX; a++) { - if (part->mtex[a]) { - BLO_write_struct(writer, MTex, part->mtex[a]); - } - } - } -} - -static void write_particlesystems(BlendWriter *writer, ListBase *particles) -{ - LISTBASE_FOREACH (ParticleSystem *, psys, particles) { - BLO_write_struct(writer, ParticleSystem, psys); - - if (psys->particles) { - BLO_write_struct_array(writer, ParticleData, psys->totpart, psys->particles); - - if (psys->particles->hair) { - ParticleData *pa = psys->particles; - - for (int a = 0; a < psys->totpart; a++, pa++) { - BLO_write_struct_array(writer, HairKey, pa->totkey, pa->hair); - } - } - - if (psys->particles->boid && (psys->part->phystype == PART_PHYS_BOIDS)) { - BLO_write_struct_array(writer, BoidParticle, psys->totpart, psys->particles->boid); - } - - if (psys->part->fluid && (psys->part->phystype == PART_PHYS_FLUID) && - (psys->part->fluid->flag & SPH_VISCOELASTIC_SPRINGS)) { - BLO_write_struct_array( - writer, ParticleSpring, psys->tot_fluidsprings, psys->fluid_springs); - } - } - LISTBASE_FOREACH (ParticleTarget *, pt, &psys->targets) { - BLO_write_struct(writer, ParticleTarget, pt); - } - - if (psys->child) { - BLO_write_struct_array(writer, ChildParticle, psys->totchild, psys->child); - } - - if (psys->clmd) { - BLO_write_struct(writer, ClothModifierData, psys->clmd); - BLO_write_struct(writer, ClothSimSettings, psys->clmd->sim_parms); - BLO_write_struct(writer, ClothCollSettings, psys->clmd->coll_parms); - } - - write_pointcaches(writer, &psys->ptcaches); - } -} - -static void write_motionpath(BlendWriter *writer, bMotionPath *mpath) -{ - /* sanity checks */ - if (mpath == NULL) { - return; - } - - /* firstly, just write the motionpath struct */ - BLO_write_struct(writer, bMotionPath, mpath); - - /* now write the array of data */ - BLO_write_struct_array(writer, bMotionPathVert, mpath->length, mpath->points); -} - -static void write_constraints(BlendWriter *writer, ListBase *conlist) -{ - LISTBASE_FOREACH (bConstraint *, con, conlist) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - - /* Write the specific data */ - if (cti && con->data) { - /* firstly, just write the plain con->data struct */ - BLO_write_struct_by_name(writer, cti->structName, con->data); - - /* do any constraint specific stuff */ - switch (con->type) { - case CONSTRAINT_TYPE_PYTHON: { - bPythonConstraint *data = con->data; - - /* write targets */ - LISTBASE_FOREACH (bConstraintTarget *, ct, &data->targets) { - BLO_write_struct(writer, bConstraintTarget, ct); - } - - /* Write ID Properties -- and copy this comment EXACTLY for easy finding - * of library blocks that implement this.*/ - IDP_BlendWrite(writer, data->prop); - - break; - } - case CONSTRAINT_TYPE_ARMATURE: { - bArmatureConstraint *data = con->data; - - /* write targets */ - LISTBASE_FOREACH (bConstraintTarget *, ct, &data->targets) { - BLO_write_struct(writer, bConstraintTarget, ct); - } - - break; - } - case CONSTRAINT_TYPE_SPLINEIK: { - bSplineIKConstraint *data = con->data; - - /* write points array */ - BLO_write_float_array(writer, data->numpoints, data->points); - - break; - } - } - } - - /* Write the constraint */ - BLO_write_struct(writer, bConstraint, con); - } -} - -static void write_pose(BlendWriter *writer, bPose *pose, bArmature *arm) -{ - /* Write each channel */ - if (pose == NULL) { - return; - } - - BLI_assert(arm != NULL); - - /* Write channels */ - LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) { - /* Write ID Properties -- and copy this comment EXACTLY for easy finding - * of library blocks that implement this.*/ - if (chan->prop) { - IDP_BlendWrite(writer, chan->prop); - } - - write_constraints(writer, &chan->constraints); - - write_motionpath(writer, chan->mpath); - - /* Prevent crashes with autosave, - * when a bone duplicated in editmode has not yet been assigned to its posechannel. - * Also needed with memundo, in some cases we can store a step before pose has been - * properly rebuilt from previous undo step. */ - Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) : - chan->bone; - if (bone != NULL) { - /* gets restored on read, for library armatures */ - chan->selectflag = bone->flag & BONE_SELECTED; - } - - BLO_write_struct(writer, bPoseChannel, chan); - } - - /* Write groups */ - LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) { - BLO_write_struct(writer, bActionGroup, grp); - } - - /* write IK param */ - if (pose->ikparam) { - const char *structname = BKE_pose_ikparam_get_name(pose); - if (structname) { - BLO_write_struct_by_name(writer, structname, pose->ikparam); - } - } - - /* Write this pose */ - BLO_write_struct(writer, bPose, pose); -} - -static void write_defgroups(BlendWriter *writer, ListBase *defbase) -{ - LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) { - BLO_write_struct(writer, bDeformGroup, defgroup); - } -} - -static void write_fmaps(BlendWriter *writer, ListBase *fbase) -{ - LISTBASE_FOREACH (bFaceMap *, fmap, fbase) { - BLO_write_struct(writer, bFaceMap, fmap); - } -} - -static void write_modifiers(BlendWriter *writer, ListBase *modbase) -{ - if (modbase == NULL) { - return; - } - - LISTBASE_FOREACH (ModifierData *, md, modbase) { - const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); - if (mti == NULL) { - return; - } - - BLO_write_struct_by_name(writer, mti->structName, md); - - if (md->type == eModifierType_Cloth) { - ClothModifierData *clmd = (ClothModifierData *)md; - - BLO_write_struct(writer, ClothSimSettings, clmd->sim_parms); - BLO_write_struct(writer, ClothCollSettings, clmd->coll_parms); - BLO_write_struct(writer, EffectorWeights, clmd->sim_parms->effector_weights); - write_pointcaches(writer, &clmd->ptcaches); - } - else if (md->type == eModifierType_Fluid) { - FluidModifierData *fmd = (FluidModifierData *)md; - - if (fmd->type & MOD_FLUID_TYPE_DOMAIN) { - BLO_write_struct(writer, FluidDomainSettings, fmd->domain); - - if (fmd->domain) { - write_pointcaches(writer, &(fmd->domain->ptcaches[0])); - - /* create fake pointcache so that old blender versions can read it */ - fmd->domain->point_cache[1] = BKE_ptcache_add(&fmd->domain->ptcaches[1]); - fmd->domain->point_cache[1]->flag |= PTCACHE_DISK_CACHE | PTCACHE_FAKE_SMOKE; - fmd->domain->point_cache[1]->step = 1; - - write_pointcaches(writer, &(fmd->domain->ptcaches[1])); - - if (fmd->domain->coba) { - BLO_write_struct(writer, ColorBand, fmd->domain->coba); - } - - /* cleanup the fake pointcache */ - BKE_ptcache_free_list(&fmd->domain->ptcaches[1]); - fmd->domain->point_cache[1] = NULL; - - BLO_write_struct(writer, EffectorWeights, fmd->domain->effector_weights); - } - } - else if (fmd->type & MOD_FLUID_TYPE_FLOW) { - BLO_write_struct(writer, FluidFlowSettings, fmd->flow); - } - else if (fmd->type & MOD_FLUID_TYPE_EFFEC) { - BLO_write_struct(writer, FluidEffectorSettings, fmd->effector); - } - } - else if (md->type == eModifierType_Fluidsim) { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)md; - - BLO_write_struct(writer, FluidsimSettings, fluidmd->fss); - } - else if (md->type == eModifierType_DynamicPaint) { - DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; - - if (pmd->canvas) { - BLO_write_struct(writer, DynamicPaintCanvasSettings, pmd->canvas); - - /* write surfaces */ - LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) { - BLO_write_struct(writer, DynamicPaintSurface, surface); - } - /* write caches and effector weights */ - LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) { - write_pointcaches(writer, &(surface->ptcaches)); - - BLO_write_struct(writer, EffectorWeights, surface->effector_weights); - } - } - if (pmd->brush) { - BLO_write_struct(writer, DynamicPaintBrushSettings, pmd->brush); - BLO_write_struct(writer, ColorBand, pmd->brush->paint_ramp); - BLO_write_struct(writer, ColorBand, pmd->brush->vel_ramp); - } - } - else if (md->type == eModifierType_Collision) { - -#if 0 - CollisionModifierData *collmd = (CollisionModifierData *)md; - // TODO: CollisionModifier should use pointcache - // + have proper reset events before enabling this - writestruct(wd, DATA, MVert, collmd->numverts, collmd->x); - writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew); - writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces); -#endif - } - - if (mti->blendWrite != NULL) { - mti->blendWrite(writer, md); - } - } -} - -static void write_gpencil_modifiers(BlendWriter *writer, ListBase *modbase) -{ - if (modbase == NULL) { - return; - } - - LISTBASE_FOREACH (GpencilModifierData *, md, modbase) { - const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type); - if (mti == NULL) { - return; - } - - BLO_write_struct_by_name(writer, mti->struct_name, md); - - if (md->type == eGpencilModifierType_Thick) { - ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; - - if (gpmd->curve_thickness) { - BKE_curvemapping_blend_write(writer, gpmd->curve_thickness); - } - } - else if (md->type == eGpencilModifierType_Noise) { - NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md; - - if (gpmd->curve_intensity) { - BKE_curvemapping_blend_write(writer, gpmd->curve_intensity); - } - } - else if (md->type == eGpencilModifierType_Hook) { - HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md; - - if (gpmd->curfalloff) { - BKE_curvemapping_blend_write(writer, gpmd->curfalloff); - } - } - else if (md->type == eGpencilModifierType_Tint) { - TintGpencilModifierData *gpmd = (TintGpencilModifierData *)md; - if (gpmd->colorband) { - BLO_write_struct(writer, ColorBand, gpmd->colorband); - } - if (gpmd->curve_intensity) { - BKE_curvemapping_blend_write(writer, gpmd->curve_intensity); - } - } - else if (md->type == eGpencilModifierType_Smooth) { - SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; - if (gpmd->curve_intensity) { - BKE_curvemapping_blend_write(writer, gpmd->curve_intensity); - } - } - else if (md->type == eGpencilModifierType_Color) { - ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md; - if (gpmd->curve_intensity) { - BKE_curvemapping_blend_write(writer, gpmd->curve_intensity); - } - } - else if (md->type == eGpencilModifierType_Opacity) { - OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md; - if (gpmd->curve_intensity) { - BKE_curvemapping_blend_write(writer, gpmd->curve_intensity); - } - } - } -} - -static void write_shaderfxs(BlendWriter *writer, ListBase *fxbase) -{ - if (fxbase == NULL) { - return; - } - - LISTBASE_FOREACH (ShaderFxData *, fx, fxbase) { - const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type); - if (fxi == NULL) { - return; - } - - BLO_write_struct_by_name(writer, fxi->struct_name, fx); - } -} - -static void write_object(BlendWriter *writer, Object *ob, const void *id_address) -{ - if (ob->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - BKE_object_runtime_reset(ob); - - /* write LibData */ - BLO_write_id_struct(writer, Object, id_address, &ob->id); - BKE_id_blend_write(writer, &ob->id); - - if (ob->adt) { - BKE_animdata_blend_write(writer, ob->adt); - } - - /* direct data */ - BLO_write_pointer_array(writer, ob->totcol, ob->mat); - BLO_write_raw(writer, sizeof(char) * ob->totcol, ob->matbits); - - bArmature *arm = NULL; - if (ob->type == OB_ARMATURE) { - arm = ob->data; - if (arm && ob->pose && arm->act_bone) { - BLI_strncpy( - ob->pose->proxy_act_bone, arm->act_bone->name, sizeof(ob->pose->proxy_act_bone)); - } - } - - write_pose(writer, ob->pose, arm); - write_defgroups(writer, &ob->defbase); - write_fmaps(writer, &ob->fmaps); - write_constraints(writer, &ob->constraints); - write_motionpath(writer, ob->mpath); - - BLO_write_struct(writer, PartDeflect, ob->pd); - if (ob->soft) { - /* Set deprecated pointers to prevent crashes of older Blenders */ - ob->soft->pointcache = ob->soft->shared->pointcache; - ob->soft->ptcaches = ob->soft->shared->ptcaches; - BLO_write_struct(writer, SoftBody, ob->soft); - BLO_write_struct(writer, SoftBody_Shared, ob->soft->shared); - write_pointcaches(writer, &(ob->soft->shared->ptcaches)); - BLO_write_struct(writer, EffectorWeights, ob->soft->effector_weights); - } - - if (ob->rigidbody_object) { - /* TODO: if any extra data is added to handle duplis, will need separate function then */ - BLO_write_struct(writer, RigidBodyOb, ob->rigidbody_object); - } - if (ob->rigidbody_constraint) { - BLO_write_struct(writer, RigidBodyCon, ob->rigidbody_constraint); - } - - if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { - BLO_write_struct(writer, ImageUser, ob->iuser); - } - - write_particlesystems(writer, &ob->particlesystem); - write_modifiers(writer, &ob->modifiers); - write_gpencil_modifiers(writer, &ob->greasepencil_modifiers); - write_shaderfxs(writer, &ob->shader_fx); - - BLO_write_struct_list(writer, LinkData, &ob->pc_ids); - - BKE_previewimg_blend_write(writer, ob->preview); - } -} - -static void write_collection_nolib(BlendWriter *writer, Collection *collection) -{ - /* Shared function for collection data-blocks and scene master collection. */ - BKE_previewimg_blend_write(writer, collection->preview); - - LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { - BLO_write_struct(writer, CollectionObject, cob); - } - - LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - BLO_write_struct(writer, CollectionChild, child); - } -} - -static void write_collection(BlendWriter *writer, Collection *collection, const void *id_address) -{ - if (collection->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->tag = 0; - BLI_listbase_clear(&collection->object_cache); - BLI_listbase_clear(&collection->parents); - - /* write LibData */ - BLO_write_id_struct(writer, Collection, id_address, &collection->id); - BKE_id_blend_write(writer, &collection->id); - - write_collection_nolib(writer, collection); - } -} - -static void write_sequence_modifiers(BlendWriter *writer, ListBase *modbase) -{ - LISTBASE_FOREACH (SequenceModifierData *, smd, modbase) { - const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); - - if (smti) { - BLO_write_struct_by_name(writer, smti->struct_name, smd); - - if (smd->type == seqModifierType_Curves) { - CurvesModifierData *cmd = (CurvesModifierData *)smd; - - BKE_curvemapping_blend_write(writer, &cmd->curve_mapping); - } - else if (smd->type == seqModifierType_HueCorrect) { - HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd; - - BKE_curvemapping_blend_write(writer, &hcmd->curve_mapping); - } - } - else { - BLO_write_struct(writer, SequenceModifierData, smd); - } - } -} - -static void write_view_settings(BlendWriter *writer, ColorManagedViewSettings *view_settings) -{ - if (view_settings->curve_mapping) { - BKE_curvemapping_blend_write(writer, view_settings->curve_mapping); - } -} - -static void write_view3dshading(BlendWriter *writer, View3DShading *shading) -{ - if (shading->prop) { - IDP_BlendWrite(writer, shading->prop); - } -} - -static void write_paint(BlendWriter *writer, Paint *p) -{ - if (p->cavity_curve) { - BKE_curvemapping_blend_write(writer, p->cavity_curve); - } - BLO_write_struct_array(writer, PaintToolSlot, p->tool_slots_len, p->tool_slots); -} - -static void write_layer_collections(BlendWriter *writer, ListBase *lb) -{ - LISTBASE_FOREACH (LayerCollection *, lc, lb) { - BLO_write_struct(writer, LayerCollection, lc); - - write_layer_collections(writer, &lc->layer_collections); - } -} - -static void write_view_layer(BlendWriter *writer, ViewLayer *view_layer) -{ - BLO_write_struct(writer, ViewLayer, view_layer); - BLO_write_struct_list(writer, Base, &view_layer->object_bases); - - if (view_layer->id_properties) { - IDP_BlendWrite(writer, view_layer->id_properties); - } - - LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) { - BLO_write_struct(writer, FreestyleModuleConfig, fmc); - } - - LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { - BLO_write_struct(writer, FreestyleLineSet, fls); - } - write_layer_collections(writer, &view_layer->layer_collections); -} - -static void write_lightcache_texture(BlendWriter *writer, LightCacheTexture *tex) -{ - if (tex->data) { - size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2]; - if (tex->data_type == LIGHTCACHETEX_FLOAT) { - data_size *= sizeof(float); - } - else if (tex->data_type == LIGHTCACHETEX_UINT) { - data_size *= sizeof(uint); - } - - /* FIXME: We can't save more than what 32bit systems can handle. - * The solution would be to split the texture but it is too late for 2.90. (see T78529) */ - if (data_size < INT_MAX) { - BLO_write_raw(writer, data_size, tex->data); - } - } -} - -static void write_lightcache(BlendWriter *writer, LightCache *cache) -{ - write_lightcache_texture(writer, &cache->grid_tx); - write_lightcache_texture(writer, &cache->cube_tx); - - if (cache->cube_mips) { - BLO_write_struct_array(writer, LightCacheTexture, cache->mips_len, cache->cube_mips); - for (int i = 0; i < cache->mips_len; i++) { - write_lightcache_texture(writer, &cache->cube_mips[i]); - } - } - - BLO_write_struct_array(writer, LightGridCache, cache->grid_len, cache->grid_data); - BLO_write_struct_array(writer, LightProbeCache, cache->cube_len, cache->cube_data); -} - -static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address) -{ - if (BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - /* XXX This UI data should not be stored in Scene at all... */ - memset(&sce->cursor, 0, sizeof(sce->cursor)); - } - - /* write LibData */ - BLO_write_id_struct(writer, Scene, id_address, &sce->id); - BKE_id_blend_write(writer, &sce->id); - - if (sce->adt) { - BKE_animdata_blend_write(writer, sce->adt); - } - BKE_keyingsets_blend_write(writer, &sce->keyingsets); - - /* direct data */ - ToolSettings *tos = sce->toolsettings; - BLO_write_struct(writer, ToolSettings, tos); - if (tos->vpaint) { - BLO_write_struct(writer, VPaint, tos->vpaint); - write_paint(writer, &tos->vpaint->paint); - } - if (tos->wpaint) { - BLO_write_struct(writer, VPaint, tos->wpaint); - write_paint(writer, &tos->wpaint->paint); - } - if (tos->sculpt) { - BLO_write_struct(writer, Sculpt, tos->sculpt); - write_paint(writer, &tos->sculpt->paint); - } - if (tos->uvsculpt) { - BLO_write_struct(writer, UvSculpt, tos->uvsculpt); - write_paint(writer, &tos->uvsculpt->paint); - } - if (tos->gp_paint) { - BLO_write_struct(writer, GpPaint, tos->gp_paint); - write_paint(writer, &tos->gp_paint->paint); - } - if (tos->gp_vertexpaint) { - BLO_write_struct(writer, GpVertexPaint, tos->gp_vertexpaint); - write_paint(writer, &tos->gp_vertexpaint->paint); - } - if (tos->gp_sculptpaint) { - BLO_write_struct(writer, GpSculptPaint, tos->gp_sculptpaint); - write_paint(writer, &tos->gp_sculptpaint->paint); - } - if (tos->gp_weightpaint) { - BLO_write_struct(writer, GpWeightPaint, tos->gp_weightpaint); - write_paint(writer, &tos->gp_weightpaint->paint); - } - /* write grease-pencil custom ipo curve to file */ - if (tos->gp_interpolate.custom_ipo) { - BKE_curvemapping_blend_write(writer, tos->gp_interpolate.custom_ipo); - } - /* write grease-pencil multiframe falloff curve to file */ - if (tos->gp_sculpt.cur_falloff) { - BKE_curvemapping_blend_write(writer, tos->gp_sculpt.cur_falloff); - } - /* write grease-pencil primitive curve to file */ - if (tos->gp_sculpt.cur_primitive) { - BKE_curvemapping_blend_write(writer, tos->gp_sculpt.cur_primitive); - } - /* Write the curve profile to the file. */ - if (tos->custom_bevel_profile_preset) { - BKE_curveprofile_blend_write(writer, tos->custom_bevel_profile_preset); - } - - write_paint(writer, &tos->imapaint.paint); - - Editing *ed = sce->ed; - if (ed) { - Sequence *seq; - - BLO_write_struct(writer, Editing, ed); - - /* reset write flags too */ - - SEQ_ALL_BEGIN (ed, seq) { - if (seq->strip) { - seq->strip->done = false; - } - BLO_write_struct(writer, Sequence, seq); - } - SEQ_ALL_END; - - SEQ_ALL_BEGIN (ed, seq) { - if (seq->strip && seq->strip->done == 0) { - /* write strip with 'done' at 0 because readfile */ - - if (seq->effectdata) { - switch (seq->type) { - case SEQ_TYPE_COLOR: - BLO_write_struct(writer, SolidColorVars, seq->effectdata); - break; - case SEQ_TYPE_SPEED: - BLO_write_struct(writer, SpeedControlVars, seq->effectdata); - break; - case SEQ_TYPE_WIPE: - BLO_write_struct(writer, WipeVars, seq->effectdata); - break; - case SEQ_TYPE_GLOW: - BLO_write_struct(writer, GlowVars, seq->effectdata); - break; - case SEQ_TYPE_TRANSFORM: - BLO_write_struct(writer, TransformVars, seq->effectdata); - break; - case SEQ_TYPE_GAUSSIAN_BLUR: - BLO_write_struct(writer, GaussianBlurVars, seq->effectdata); - break; - case SEQ_TYPE_TEXT: - BLO_write_struct(writer, TextVars, seq->effectdata); - break; - case SEQ_TYPE_COLORMIX: - BLO_write_struct(writer, ColorMixVars, seq->effectdata); - break; - } - } - - BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format); - - Strip *strip = seq->strip; - BLO_write_struct(writer, Strip, strip); - if (strip->crop) { - BLO_write_struct(writer, StripCrop, strip->crop); - } - if (strip->transform) { - BLO_write_struct(writer, StripTransform, strip->transform); - } - if (strip->proxy) { - BLO_write_struct(writer, StripProxy, strip->proxy); - } - if (seq->type == SEQ_TYPE_IMAGE) { - BLO_write_struct_array(writer, - StripElem, - MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), - strip->stripdata); - } - else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { - BLO_write_struct(writer, StripElem, strip->stripdata); - } - - strip->done = true; - } - - if (seq->prop) { - IDP_BlendWrite(writer, seq->prop); - } - - write_sequence_modifiers(writer, &seq->modifiers); - } - SEQ_ALL_END; - - /* new; meta stack too, even when its nasty restore code */ - LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) { - BLO_write_struct(writer, MetaStack, ms); - } - } - - if (sce->r.avicodecdata) { - BLO_write_struct(writer, AviCodecData, sce->r.avicodecdata); - if (sce->r.avicodecdata->lpFormat) { - BLO_write_raw(writer, sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat); - } - if (sce->r.avicodecdata->lpParms) { - BLO_write_raw(writer, sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms); - } - } - if (sce->r.ffcodecdata.properties) { - IDP_BlendWrite(writer, sce->r.ffcodecdata.properties); - } - - /* writing dynamic list of TimeMarkers to the blend file */ - LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) { - BLO_write_struct(writer, TimeMarker, marker); - } - - /* writing dynamic list of TransformOrientations to the blend file */ - LISTBASE_FOREACH (TransformOrientation *, ts, &sce->transform_spaces) { - BLO_write_struct(writer, TransformOrientation, ts); - } - - /* writing MultiView to the blend file */ - LISTBASE_FOREACH (SceneRenderView *, srv, &sce->r.views) { - BLO_write_struct(writer, SceneRenderView, srv); - } - - if (sce->nodetree) { - BLO_write_struct(writer, bNodeTree, sce->nodetree); - ntreeBlendWrite(writer, sce->nodetree); - } - - write_view_settings(writer, &sce->view_settings); - - /* writing RigidBodyWorld data to the blend file */ - if (sce->rigidbody_world) { - /* Set deprecated pointers to prevent crashes of older Blenders */ - sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache; - sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches; - BLO_write_struct(writer, RigidBodyWorld, sce->rigidbody_world); - - BLO_write_struct(writer, RigidBodyWorld_Shared, sce->rigidbody_world->shared); - BLO_write_struct(writer, EffectorWeights, sce->rigidbody_world->effector_weights); - write_pointcaches(writer, &(sce->rigidbody_world->shared->ptcaches)); - } - - BKE_previewimg_blend_write(writer, sce->preview); - BKE_curvemapping_curves_blend_write(writer, &sce->r.mblur_shutter_curve); - - LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { - write_view_layer(writer, view_layer); - } - - if (sce->master_collection) { - BLO_write_struct(writer, Collection, sce->master_collection); - write_collection_nolib(writer, sce->master_collection); - } - - /* Eevee Lightcache */ - if (sce->eevee.light_cache_data && !BLO_write_is_undo(writer)) { - BLO_write_struct(writer, LightCache, sce->eevee.light_cache_data); - write_lightcache(writer, sce->eevee.light_cache_data); - } - - write_view3dshading(writer, &sce->display.shading); - - /* Freed on doversion. */ - BLI_assert(sce->layer_properties == NULL); -} - -static void write_wm_xr_data(BlendWriter *writer, wmXrData *xr_data) -{ - write_view3dshading(writer, &xr_data->session_settings.shading); -} - -static void write_region(BlendWriter *writer, ARegion *region, int spacetype) -{ - BLO_write_struct(writer, ARegion, region); - - if (region->regiondata) { - if (region->flag & RGN_FLAG_TEMP_REGIONDATA) { - return; - } - - switch (spacetype) { - case SPACE_VIEW3D: - if (region->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = region->regiondata; - BLO_write_struct(writer, RegionView3D, rv3d); - - if (rv3d->localvd) { - BLO_write_struct(writer, RegionView3D, rv3d->localvd); - } - if (rv3d->clipbb) { - BLO_write_struct(writer, BoundBox, rv3d->clipbb); - } - } - else { - printf("regiondata write missing!\n"); - } - break; - default: - printf("regiondata write missing!\n"); - } - } -} - -static void write_uilist(BlendWriter *writer, uiList *ui_list) -{ - BLO_write_struct(writer, uiList, ui_list); - - if (ui_list->properties) { - IDP_BlendWrite(writer, ui_list->properties); - } -} - -static void write_space_outliner(BlendWriter *writer, SpaceOutliner *space_outliner) -{ - BLI_mempool *ts = space_outliner->treestore; - - if (ts) { - SpaceOutliner space_outliner_flat = *space_outliner; - - int elems = BLI_mempool_len(ts); - /* linearize mempool to array */ - TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; - - if (data) { - /* In this block we use the memory location of the treestore - * but _not_ its data, the addresses in this case are UUID's, - * since we can't rely on malloc giving us different values each time. - */ - TreeStore ts_flat = {0}; - - /* we know the treestore is at least as big as a pointer, - * so offsetting works to give us a UUID. */ - void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *)); - - ts_flat.usedelem = elems; - ts_flat.totelem = elems; - ts_flat.data = data_addr; - - BLO_write_struct(writer, SpaceOutliner, space_outliner); - - BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat); - BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data); - - MEM_freeN(data); - } - else { - space_outliner_flat.treestore = NULL; - BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat); - } - } - else { - BLO_write_struct(writer, SpaceOutliner, space_outliner); - } -} - -static void write_panel_list(BlendWriter *writer, ListBase *lb) -{ - LISTBASE_FOREACH (Panel *, panel, lb) { - BLO_write_struct(writer, Panel, panel); - write_panel_list(writer, &panel->children); - } -} - -static void write_area_regions(BlendWriter *writer, ScrArea *area) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - write_region(writer, region, area->spacetype); - write_panel_list(writer, ®ion->panels); - - LISTBASE_FOREACH (PanelCategoryStack *, pc_act, ®ion->panels_category_active) { - BLO_write_struct(writer, PanelCategoryStack, pc_act); - } - - LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { - write_uilist(writer, ui_list); - } - - LISTBASE_FOREACH (uiPreview *, ui_preview, ®ion->ui_previews) { - BLO_write_struct(writer, uiPreview, ui_preview); - } - } - - LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { - write_region(writer, region, sl->spacetype); - } - - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - BLO_write_struct(writer, View3D, v3d); - - if (v3d->localvd) { - BLO_write_struct(writer, View3D, v3d->localvd); - } - - write_view3dshading(writer, &v3d->shading); - } - else if (sl->spacetype == SPACE_GRAPH) { - SpaceGraph *sipo = (SpaceGraph *)sl; - ListBase tmpGhosts = sipo->runtime.ghost_curves; - - /* temporarily disable ghost curves when saving */ - BLI_listbase_clear(&sipo->runtime.ghost_curves); - - BLO_write_struct(writer, SpaceGraph, sl); - if (sipo->ads) { - BLO_write_struct(writer, bDopeSheet, sipo->ads); - } - - /* reenable ghost curves */ - sipo->runtime.ghost_curves = tmpGhosts; - } - else if (sl->spacetype == SPACE_PROPERTIES) { - BLO_write_struct(writer, SpaceProperties, sl); - } - else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - - BLO_write_struct(writer, SpaceFile, sl); - if (sfile->params) { - BLO_write_struct(writer, FileSelectParams, sfile->params); - } - } - else if (sl->spacetype == SPACE_SEQ) { - BLO_write_struct(writer, SpaceSeq, sl); - } - else if (sl->spacetype == SPACE_OUTLINER) { - SpaceOutliner *space_outliner = (SpaceOutliner *)sl; - write_space_outliner(writer, space_outliner); - } - else if (sl->spacetype == SPACE_IMAGE) { - BLO_write_struct(writer, SpaceImage, sl); - } - else if (sl->spacetype == SPACE_TEXT) { - BLO_write_struct(writer, SpaceText, sl); - } - else if (sl->spacetype == SPACE_SCRIPT) { - SpaceScript *scr = (SpaceScript *)sl; - scr->but_refs = NULL; - BLO_write_struct(writer, SpaceScript, sl); - } - else if (sl->spacetype == SPACE_ACTION) { - BLO_write_struct(writer, SpaceAction, sl); - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla = (SpaceNla *)sl; - - BLO_write_struct(writer, SpaceNla, snla); - if (snla->ads) { - BLO_write_struct(writer, bDopeSheet, snla->ads); - } - } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - BLO_write_struct(writer, SpaceNode, snode); - - LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) { - BLO_write_struct(writer, bNodeTreePath, path); - } - } - else if (sl->spacetype == SPACE_CONSOLE) { - SpaceConsole *con = (SpaceConsole *)sl; - - LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) { - /* 'len_alloc' is invalid on write, set from 'len' on read */ - BLO_write_struct(writer, ConsoleLine, cl); - BLO_write_raw(writer, cl->len + 1, cl->line); - } - BLO_write_struct(writer, SpaceConsole, sl); - } -#ifdef WITH_GLOBAL_AREA_WRITING - else if (sl->spacetype == SPACE_TOPBAR) { - BLO_write_struct(writer, SpaceTopBar, sl); - } - else if (sl->spacetype == SPACE_STATUSBAR) { - BLO_write_struct(writer, SpaceStatusBar, sl); - } -#endif - else if (sl->spacetype == SPACE_USERPREF) { - BLO_write_struct(writer, SpaceUserPref, sl); - } - else if (sl->spacetype == SPACE_CLIP) { - BLO_write_struct(writer, SpaceClip, sl); - } - else if (sl->spacetype == SPACE_INFO) { - BLO_write_struct(writer, SpaceInfo, sl); - } - } -} - -static void write_area_map(BlendWriter *writer, ScrAreaMap *area_map) -{ - BLO_write_struct_list(writer, ScrVert, &area_map->vertbase); - BLO_write_struct_list(writer, ScrEdge, &area_map->edgebase); - LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { - area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */ - - BLO_write_struct(writer, ScrArea, area); - -#ifdef WITH_GLOBAL_AREA_WRITING - BLO_write_struct(writer, ScrGlobalAreaData, area->global); -#endif - - write_area_regions(writer, area); - - area->butspacetype = SPACE_EMPTY; /* Unset again, was changed above. */ - } -} - -static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const void *id_address) -{ - BLO_write_id_struct(writer, wmWindowManager, id_address, &wm->id); - BKE_id_blend_write(writer, &wm->id); - write_wm_xr_data(writer, &wm->xr); - - LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { -#ifndef WITH_GLOBAL_AREA_WRITING - /* Don't write global areas yet, while we make changes to them. */ - ScrAreaMap global_areas = win->global_areas; - memset(&win->global_areas, 0, sizeof(win->global_areas)); -#endif - - /* update deprecated screen member (for so loading in 2.7x uses the correct screen) */ - win->screen = BKE_workspace_active_screen_get(win->workspace_hook); - - BLO_write_struct(writer, wmWindow, win); - BLO_write_struct(writer, WorkSpaceInstanceHook, win->workspace_hook); - BLO_write_struct(writer, Stereo3dFormat, win->stereo3d_format); - -#ifdef WITH_GLOBAL_AREA_WRITING - write_area_map(writer, &win->global_areas); -#else - win->global_areas = global_areas; -#endif - - /* data is written, clear deprecated data again */ - win->screen = NULL; - } -} - -static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_address) -{ - /* Screens are reference counted, only saved if used by a workspace. */ - if (screen->id.us > 0 || BLO_write_is_undo(writer)) { - /* write LibData */ - /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ - writestruct_at_address(writer->wd, ID_SCRN, bScreen, 1, id_address, screen); - BKE_id_blend_write(writer, &screen->id); - - BKE_previewimg_blend_write(writer, screen->preview); - - /* direct data */ - write_area_map(writer, AREAMAP_FROM_SCREEN(screen)); - } -} - -static void write_sound(BlendWriter *writer, bSound *sound, const void *id_address) -{ - if (sound->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - sound->tags = 0; - sound->handle = NULL; - sound->playback_handle = NULL; - sound->spinlock = NULL; - - /* write LibData */ - BLO_write_id_struct(writer, bSound, id_address, &sound->id); - BKE_id_blend_write(writer, &sound->id); - - BKE_packedfile_blend_write(writer, sound->packedfile); - } -} - -static void write_cachefile(BlendWriter *writer, CacheFile *cache_file, const void *id_address) -{ - if (cache_file->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - BLI_listbase_clear(&cache_file->object_paths); - cache_file->handle = NULL; - memset(cache_file->handle_filepath, 0, sizeof(cache_file->handle_filepath)); - cache_file->handle_readers = NULL; - - BLO_write_id_struct(writer, CacheFile, id_address, &cache_file->id); - - if (cache_file->adt) { - BKE_animdata_blend_write(writer, cache_file->adt); - } - } -} - -static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address) -{ - BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id); - BKE_id_blend_write(writer, &workspace->id); - BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts); - BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations); - BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids); - BLO_write_struct_list(writer, bToolRef, &workspace->tools); - LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { - if (tref->properties) { - IDP_BlendWrite(writer, tref->properties); - } - } -} - /* Keep it last of write_foodata functions. */ static void write_libraries(WriteData *wd, Main *main) { @@ -2279,7 +935,7 @@ static bool write_file_handle(Main *mainvar, write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); - /* The windowmanager and screen often change, + /* The window-manager and screen often change, * avoid thumbnail detecting changes because of this. */ mywrite_flush(wd); @@ -2361,78 +1017,6 @@ static bool write_file_handle(Main *mainvar, id_type->blend_write(&writer, (ID *)id_buffer, id); } - switch ((ID_Type)GS(id->name)) { - case ID_WM: - write_windowmanager(&writer, (wmWindowManager *)id_buffer, id); - break; - case ID_WS: - write_workspace(&writer, (WorkSpace *)id_buffer, id); - break; - case ID_SCR: - write_screen(&writer, (bScreen *)id_buffer, id); - break; - case ID_SCE: - write_scene(&writer, (Scene *)id_buffer, id); - break; - case ID_SO: - write_sound(&writer, (bSound *)id_buffer, id); - break; - case ID_GR: - write_collection(&writer, (Collection *)id_buffer, id); - break; - case ID_OB: - write_object(&writer, (Object *)id_buffer, id); - break; - case ID_PA: - write_particlesettings(&writer, (ParticleSettings *)id_buffer, id); - break; - case ID_CF: - write_cachefile(&writer, (CacheFile *)id_buffer, id); - break; - case ID_ME: - case ID_LT: - case ID_AC: - case ID_NT: - case ID_LS: - case ID_TXT: - case ID_VF: - case ID_MC: - case ID_PC: - case ID_PAL: - case ID_BR: - case ID_IM: - case ID_LA: - case ID_MA: - case ID_MB: - case ID_CU: - case ID_CA: - case ID_WO: - case ID_MSK: - case ID_SPK: - case ID_AR: - case ID_LP: - case ID_KE: - case ID_TE: - case ID_GD: - case ID_HA: - case ID_PT: - case ID_VO: - case ID_SIM: - /* Do nothing, handled in IDTypeInfo callback. */ - break; - case ID_LI: - /* Do nothing, handled below - and should never be reached. */ - BLI_assert(0); - break; - case ID_IP: - /* Do nothing, deprecated. */ - break; - default: - /* Should never be reached. */ - BLI_assert(0); - break; - } - if (do_override) { BKE_lib_override_library_operations_store_end(override_storage, id); } @@ -2467,7 +1051,7 @@ static bool write_file_handle(Main *mainvar, * * Note that we *borrow* the pointer to 'DNAstr', * so writing each time uses the same address and doesn't cause unnecessary undo overhead. */ - writedata(wd, DNA1, wd->sdna->data_len, wd->sdna->data); + writedata(wd, DNA1, (size_t)wd->sdna->data_len, wd->sdna->data); /* end of file */ memset(&bhead, 0, sizeof(BHead)); @@ -2688,7 +1272,7 @@ bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int w return (err == 0); } -void BLO_write_raw(BlendWriter *writer, int size_in_bytes, const void *data_ptr) +void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr) { writedata(writer->wd, DATA, size_in_bytes, data_ptr); } @@ -2721,7 +1305,13 @@ void BLO_write_struct_at_address_by_id(BlendWriter *writer, const void *address, const void *data_ptr) { - writestruct_at_address_nr(writer->wd, DATA, struct_id, 1, address, data_ptr); + BLO_write_struct_at_address_by_id_with_filecode(writer, DATA, struct_id, address, data_ptr); +} + +void BLO_write_struct_at_address_by_id_with_filecode( + BlendWriter *writer, int filecode, int struct_id, const void *address, const void *data_ptr) +{ + writestruct_at_address_nr(writer->wd, filecode, struct_id, 1, address, data_ptr); } void BLO_write_struct_array_by_id(BlendWriter *writer, @@ -2764,38 +1354,38 @@ int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name) return struct_id; } -void BLO_write_int32_array(BlendWriter *writer, int size, const int32_t *data_ptr) +void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr) { - BLO_write_raw(writer, sizeof(int32_t) * size, data_ptr); + BLO_write_raw(writer, sizeof(int32_t) * (size_t)num, data_ptr); } -void BLO_write_uint32_array(BlendWriter *writer, int size, const uint32_t *data_ptr) +void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr) { - BLO_write_raw(writer, sizeof(uint32_t) * size, data_ptr); + BLO_write_raw(writer, sizeof(uint32_t) * (size_t)num, data_ptr); } -void BLO_write_float_array(BlendWriter *writer, int size, const float *data_ptr) +void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr) { - BLO_write_raw(writer, sizeof(float) * size, data_ptr); + BLO_write_raw(writer, sizeof(float) * (size_t)num, data_ptr); } -void BLO_write_pointer_array(BlendWriter *writer, int size, const void *data_ptr) +void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr) { - BLO_write_raw(writer, sizeof(void *) * size, data_ptr); + BLO_write_raw(writer, sizeof(void *) * (size_t)num, data_ptr); } -void BLO_write_float3_array(BlendWriter *writer, int size, const float *data_ptr) +void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr) { - BLO_write_raw(writer, sizeof(float[3]) * size, data_ptr); + BLO_write_raw(writer, sizeof(float[3]) * (size_t)num, data_ptr); } /** * Write a null terminated string. */ -void BLO_write_string(BlendWriter *writer, const char *str) +void BLO_write_string(BlendWriter *writer, const char *data_ptr) { - if (str != NULL) { - BLO_write_raw(writer, strlen(str) + 1, str); + if (data_ptr != NULL) { + BLO_write_raw(writer, strlen(data_ptr) + 1, data_ptr); } } |