Merged changes in the trunk up to revision 54802.
[blender.git] / source / blender / blenloader / intern / writefile.c
index 7c022c6f45a2adc50e92f8f631fc52e129a147a7..50e1e229ebac89449eafb47f9e1ab5542be33568 100644 (file)
@@ -89,6 +89,8 @@
 #  include "BLI_winstuff.h"
 #endif
 
+#include "BLI_utildefines.h"
+
 /* allow writefile to use deprecated functionality (for forward compatibility code) */
 #define DNA_DEPRECATED_ALLOW
 
 #include "DNA_key_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_lamp_types.h"
-#include "DNA_linestyle_types.h"
+#ifdef WITH_FREESTYLE
+#  include "DNA_linestyle_types.h"
+#endif
 #include "DNA_meta_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_sdna_types.h"
 #include "DNA_sequence_types.h"
 #include "BLI_bitmap.h"
 #include "BLI_blenlib.h"
 #include "BLI_linklist.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
@@ -198,7 +203,7 @@ static WriteData *writedata_new(int file)
 
        if (wd == NULL) return NULL;
 
-       wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, 0);
+       wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false);
 
        wd->file= file;
 
@@ -851,8 +856,12 @@ static void write_userdef(WriteData *wd)
                        write_keymapitem(wd, kmi);
        }
 
-       for (bext= U.addons.first; bext; bext=bext->next)
+       for (bext= U.addons.first; bext; bext=bext->next) {
                writestruct(wd, DATA, "bAddon", 1, bext);
+               if (bext->prop) {
+                       IDP_WriteProperty(bext->prop, wd);
+               }
+       }
        
        for (style= U.uistyles.first; style; style= style->next) {
                writestruct(wd, DATA, "uiStyle", 1, style);
@@ -1229,7 +1238,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
        bConstraint *con;
 
        for (con=conlist->first; con; con=con->next) {
-               bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+               bConstraintTypeInfo *cti= BKE_constraint_get_typeinfo(con);
                
                /* Write the specific data */
                if (cti && con->data) {
@@ -1417,8 +1426,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                        int size = mmd->dyngridsize;
 
                        writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences);
-                       writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets);
-                       writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
+                       writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets);
+                       writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert,
                                mmd->bindcagecos);
                        writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
                        writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
@@ -1484,6 +1493,14 @@ static void write_objects(WriteData *wd, ListBase *idbase)
                        }
                        writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
                        
+                       if (ob->rigidbody_object) {
+                               // TODO: if any extra data is added to handle duplis, will need separate function then
+                               writestruct(wd, DATA, "RigidBodyOb", 1, ob->rigidbody_object);
+                       }
+                       if (ob->rigidbody_constraint) {
+                               writestruct(wd, DATA, "RigidBodyCon", 1, ob->rigidbody_constraint);
+                       }
+
                        write_particlesystems(wd, &ob->particlesystem);
                        write_modifiers(wd, &ob->modifiers);
                }
@@ -1675,7 +1692,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
                        MDisps *md = &mdlist[i];
                        if (md->disps) {
                                if (!external)
-                                       writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps);
+                                       writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps);
                        }
                        
                        if (md->hidden)
@@ -2160,8 +2177,6 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
        TimeMarker *marker;
        TransformOrientation *ts;
        SceneRenderLayer *srl;
-       FreestyleModuleConfig *fmc;
-       FreestyleLineSet *fls;
        ToolSettings *tos;
        
        sce= scebase->first;
@@ -2286,17 +2301,24 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                for (ts = sce->transform_spaces.first; ts; ts = ts->next)
                        writestruct(wd, DATA, "TransformOrientation", 1, ts);
                
-               for (srl= sce->r.layers.first; srl; srl= srl->next) {
+               for (srl = sce->r.layers.first; srl; srl = srl->next) {
                        writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
                        
-                       for(fmc= srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
-                               writestruct(wd, DATA, "FreestyleModuleConfig", 1, fmc);
-                       }
+#ifdef WITH_FREESTYLE
+                       {
+                               FreestyleModuleConfig *fmc;
+                               FreestyleLineSet *fls;
+
+                               for(fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
+                                       writestruct(wd, DATA, "FreestyleModuleConfig", 1, fmc);
+                               }
                        
-                       for(fls= srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
-                               writestruct(wd, DATA, "FreestyleLineSet", 1, fls);
-                       }
+                               for(fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
+                                       writestruct(wd, DATA, "FreestyleLineSet", 1, fls);
+                               }
 
+                       }
+#endif
                }
                
                if (sce->nodetree) {
@@ -2305,7 +2327,14 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                }
 
                write_view_settings(wd, &sce->view_settings);
-
+               
+               /* writing RigidBodyWorld data to the blend file */
+               if (sce->rigidbody_world) {
+                       writestruct(wd, DATA, "RigidBodyWorld", 1, sce->rigidbody_world);
+                       writestruct(wd, DATA, "EffectorWeights", 1, sce->rigidbody_world->effector_weights);
+                       write_pointcaches(wd, &(sce->rigidbody_world->ptcaches));
+               }
+               
                sce= sce->id.next;
        }
        /* flush helps the compression for undo-save */
@@ -2408,6 +2437,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                for (sa= sc->areabase.first; sa; sa= sa->next) {
                        SpaceLink *sl;
                        Panel *pa;
+                       uiList *ui_list;
                        ARegion *ar;
                        
                        writestruct(wd, DATA, "ScrArea", 1, sa);
@@ -2417,6 +2447,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                
                                for (pa= ar->panels.first; pa; pa= pa->next)
                                        writestruct(wd, DATA, "Panel", 1, pa);
+                               
+                               for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next)
+                                       writestruct(wd, DATA, "uiList", 1, ui_list);
                        }
                        
                        sl= sa->spacedata.first;
@@ -2528,6 +2561,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
 
                sc= sc->id.next;
        }
+       
+       /* flush helps the compression for undo-save */
+       mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
 static void write_libraries(WriteData *wd, Main *main)
@@ -2541,20 +2577,35 @@ static void write_libraries(WriteData *wd, Main *main)
                a=tot= set_listbasepointers(main, lbarray);
 
                /* test: is lib being used */
-               foundone = FALSE;
-               while (tot--) {
-                       for (id= lbarray[tot]->first; id; id= id->next) {
-                               if (id->us>0 && (id->flag & LIB_EXTERN)) {
-                                       foundone = TRUE;
-                                       break;
+               if (main->curlib && main->curlib->packedfile)
+                       foundone = TRUE;
+               else {
+                       foundone = FALSE;
+                       while (tot--) {
+                               for (id= lbarray[tot]->first; id; id= id->next) {
+                                       if (id->us>0 && (id->flag & LIB_EXTERN)) {
+                                               foundone = TRUE;
+                                               break;
+                                       }
                                }
+                               if (foundone) break;
                        }
-                       if (foundone) break;
                }
-
+               
+               /* 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]
+                  quit.blend and temp saves */
                if (foundone) {
                        writestruct(wd, ID_LI, "Library", 1, main->curlib);
 
+                       if (main->curlib->packedfile) {
+                               PackedFile *pf = main->curlib->packedfile;
+                               writestruct(wd, DATA, "PackedFile", 1, pf);
+                               writedata(wd, DATA, pf->size, pf->data);
+                               if (wd->current == NULL)
+                                       printf("write packed .blend: %s\n", main->curlib->name);
+                       }
+                       
                        while (a--) {
                                for (id= lbarray[a]->first; id; id= id->next) {
                                        if (id->us>0 && (id->flag & LIB_EXTERN)) {
@@ -2620,7 +2671,6 @@ static void write_texts(WriteData *wd, ListBase *idbase)
 {
        Text *text;
        TextLine *tmp;
-       TextMarker *mrk;
 
        text= idbase->first;
        while (text) {
@@ -2644,13 +2694,6 @@ static void write_texts(WriteData *wd, ListBase *idbase)
                                writedata(wd, DATA, tmp->len+1, tmp->line);
                                tmp= tmp->next;
                        }
-
-                       /* write markers */
-                       mrk= text->markers.first;
-                       while (mrk) {
-                               writestruct(wd, DATA, "TextMarker", 1, mrk);
-                               mrk= mrk->next;
-                       }
                }
 
 
@@ -2881,10 +2924,11 @@ static void write_masks(WriteData *wd, ListBase *idbase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
+#ifdef WITH_FREESTYLE
 static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers)
 {
        LineStyleModifier *m;
-       char *struct_name;
+       const char *struct_name;
 
        for (m = modifiers->first; m; m = m->next) {
                switch (m->type) {
@@ -2901,7 +2945,7 @@ static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers)
                        struct_name = "LineStyleColorModifier_Material";
                        break;
                default:
-                       struct_name = "LineStyleColorModifier"; // this should not happen
+                       struct_name = "LineStyleColorModifier"; /* this should not happen */
                }
                writestruct(wd, DATA, struct_name, 1, m);
        }
@@ -2926,7 +2970,7 @@ static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers)
 static void write_linestyle_alpha_modifiers(WriteData *wd, ListBase *modifiers)
 {
        LineStyleModifier *m;
-       char *struct_name;
+       const char *struct_name;
 
        for (m = modifiers->first; m; m = m->next) {
                switch (m->type) {
@@ -2943,7 +2987,7 @@ static void write_linestyle_alpha_modifiers(WriteData *wd, ListBase *modifiers)
                        struct_name = "LineStyleAlphaModifier_Material";
                        break;
                default:
-                       struct_name = "LineStyleAlphaModifier"; // this should not happen
+                       struct_name = "LineStyleAlphaModifier"; /* this should not happen */
                }
                writestruct(wd, DATA, struct_name, 1, m);
        }
@@ -2968,7 +3012,7 @@ static void write_linestyle_alpha_modifiers(WriteData *wd, ListBase *modifiers)
 static void write_linestyle_thickness_modifiers(WriteData *wd, ListBase *modifiers)
 {
        LineStyleModifier *m;
-       char *struct_name;
+       const char *struct_name;
 
        for (m = modifiers->first; m; m = m->next) {
                switch (m->type) {
@@ -2988,7 +3032,7 @@ static void write_linestyle_thickness_modifiers(WriteData *wd, ListBase *modifie
                        struct_name = "LineStyleThicknessModifier_Calligraphy";
                        break;
                default:
-                       struct_name = "LineStyleThicknessModifier"; // this should not happen
+                       struct_name = "LineStyleThicknessModifier"; /* this should not happen */
                }
                writestruct(wd, DATA, struct_name, 1, m);
        }
@@ -3013,7 +3057,7 @@ static void write_linestyle_thickness_modifiers(WriteData *wd, ListBase *modifie
 static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifiers)
 {
        LineStyleModifier *m;
-       char *struct_name;
+       const char *struct_name;
 
        for (m = modifiers->first; m; m = m->next) {
                switch (m->type) {
@@ -3057,7 +3101,7 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier
                        struct_name = "LineStyleGeometryModifier_2DTransform";
                        break;
                default:
-                       struct_name = "LineStyleGeometryModifier"; // this should not happen
+                       struct_name = "LineStyleGeometryModifier"; /* this should not happen */
                }
                writestruct(wd, DATA, struct_name, 1, m);
        }
@@ -3067,11 +3111,13 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
 {
        FreestyleLineStyle *linestyle;
 
-       for(linestyle=idbase->first; linestyle; linestyle= linestyle->id.next) {
-               if(linestyle->id.us>0 || wd->current) {
+       for (linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) {
+               if (linestyle->id.us>0 || wd->current) {
                        writestruct(wd, ID_LS, "FreestyleLineStyle", 1, linestyle);
-                       if (linestyle->id.properties) IDP_WriteProperty(linestyle->id.properties, wd);
-                       if (linestyle->adt) write_animdata(wd, linestyle->adt);
+                       if (linestyle->id.properties)
+                               IDP_WriteProperty(linestyle->id.properties, wd);
+                       if (linestyle->adt)
+                               write_animdata(wd, linestyle->adt);
                        write_linestyle_color_modifiers(wd, &linestyle->color_modifiers);
                        write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers);
                        write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers);
@@ -3079,6 +3125,7 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
                }
        }
 }
+#endif
 
 /* context is usually defined by WM, two cases where no WM is available:
  * - for forward compatibility, curscreen has to be saved
@@ -3097,7 +3144,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
 
        /* XXX still remap G */
        fg.curscreen= screen;
-       fg.curscene= screen->scene;
+       fg.curscene= screen? screen->scene : NULL;
        fg.displaymode= G.displaymode;
        fg.winpos= G.winpos;
 
@@ -3106,7 +3153,6 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
 
        fg.globalf= G.f;
        BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
-
        sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
        memcpy(fg.subvstr, subvstr, 4);
        
@@ -3158,11 +3204,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
        write_thumb(wd, thumb);
        write_global(wd, write_flags, mainvar);
 
-       /* no UI save in undo */
-       if (current==NULL) {
-               write_windowmanagers(wd, &mainvar->wm);
-               write_screens  (wd, &mainvar->screen);
-       }
+       write_windowmanagers(wd, &mainvar->wm);
+       write_screens  (wd, &mainvar->screen);
        write_movieclips (wd, &mainvar->movieclip);
        write_masks    (wd, &mainvar->mask);
        write_scenes   (wd, &mainvar->scene);
@@ -3190,7 +3233,9 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
        write_brushes  (wd, &mainvar->brush);
        write_scripts  (wd, &mainvar->script);
        write_gpencils (wd, &mainvar->gpencil);
+#ifdef WITH_FREESTYLE
        write_linestyles(wd, &mainvar->linestyle);
+#endif
        write_libraries(wd,  mainvar->next);
 
        if (write_user_block) {
@@ -3248,13 +3293,12 @@ static int do_history(const char *name, ReportList *reports)
 /* return: success (1) */
 int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb)
 {
-       char userfilename[FILE_MAX];
        char tempname[FILE_MAX+1];
        int file, err, write_user_block;
 
        /* path backup/restore */
        void     *path_list_backup = NULL;
-       const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE);
+       const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);
 
        /* open temporary file, so we preserve the original in case we crash */
        BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
@@ -3267,7 +3311,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
 
        /* check if we need to backup and restore paths */
        if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) {
-               path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag);
+               path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag);
        }
 
        /* remapping of relative paths to new file location */
@@ -3290,24 +3334,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
                                 * we should not have any relative paths, but if there
                                 * is somehow, an invalid or empty G.main->name it will
                                 * print an error, don't try make the absolute in this case. */
-                               BLI_bpath_absolute_convert(mainvar, G.main->name, NULL);
+                               BKE_bpath_absolute_convert(mainvar, G.main->name, NULL);
                        }
                }
        }
 
-       BLI_make_file_string(G.main->name, userfilename, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
-       write_user_block= (BLI_path_cmp(filepath, userfilename) == 0);
+       write_user_block= write_flags & G_FILE_USERPREFS;
 
        if (write_flags & G_FILE_RELATIVE_REMAP)
-               BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
+               BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
 
        /* actual file writing */
        err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb);
        close(file);
 
        if (UNLIKELY(path_list_backup)) {
-               BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
-               BLI_bpath_list_free(path_list_backup);
+               BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
+               BKE_bpath_list_free(path_list_backup);
        }
 
        if (err) {
@@ -3372,3 +3415,4 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr
        if (err==0) return 1;
        return 0;
 }
+