Hopefully a working merge with trunk (could be one error left in raytrace.c - will...
[blender.git] / source / blender / blenloader / intern / writefile.c
index 4d8544ec09d542d6661a59f9c09210b8f09c4c33..739b0f11e7eb1084da030d6fa0766b64b83ef5a5 100644 (file)
@@ -4,15 +4,12 @@
  *
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,7 +27,7 @@
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 /*
@@ -115,6 +112,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
 #include "DNA_customdata_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_image_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_fileglobal_types.h"
@@ -176,8 +174,6 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
 #include "BIF_verse.h"
 #endif
 
-#include "GEN_messaging.h"
-
 #include "BLO_writefile.h"
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
@@ -401,7 +397,7 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr)      /* do not
 void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
 void IDP_WriteProperty(IDProperty *prop, void *wd);
 
-void IDP_WriteArray(IDProperty *prop, void *wd)
+static void IDP_WriteArray(IDProperty *prop, void *wd)
 {
        /*REMEMBER to set totalen to len in the linking code!!*/
        if (prop->data.pointer) {
@@ -409,13 +405,13 @@ void IDP_WriteArray(IDProperty *prop, void *wd)
        }
 }
 
-void IDP_WriteString(IDProperty *prop, void *wd)
+static void IDP_WriteString(IDProperty *prop, void *wd)
 {
        /*REMEMBER to set totalen to len in the linking code!!*/
        writedata(wd, DATA, prop->len+1, prop->data.pointer);
 }
 
-void IDP_WriteGroup(IDProperty *prop, void *wd)
+static void IDP_WriteGroup(IDProperty *prop, void *wd)
 {
        IDProperty *loop;
 
@@ -474,6 +470,8 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
                                write_curvemapping(wd, node->storage);
                        else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
                                write_curvemapping(wd, node->storage);
+                       else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) )
+                               write_curvemapping(wd, node->storage);
                        else 
                                writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
                }
@@ -526,25 +524,6 @@ static void write_userdef(WriteData *wd)
        }
 }
 
-static void write_effects(WriteData *wd, ListBase *lb)
-{
-       Effect *eff;
-
-       eff= lb->first;
-       while(eff) {
-
-               switch(eff->type) {
-               case EFF_PARTICLE:
-                       writestruct(wd, DATA, "PartEff", 1, eff);
-                       break;
-               default:
-                       writedata(wd, DATA, MEM_allocN_len(eff), eff);
-               }
-
-               eff= eff->next;
-       }
-}
-
 static void write_particlesettings(WriteData *wd, ListBase *idbase)
 {
        ParticleSettings *part;
@@ -554,7 +533,9 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
                if(part->id.us>0 || wd->current) {
                        /* write LibData */
                        writestruct(wd, ID_PA, "ParticleSettings", 1, part);
+                       if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd);
+                       writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
                }
                part= part->id.next;
        }
@@ -576,16 +557,11 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
                                for(a=0; a<psys->totpart; a++, pa++)
                                        writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair);
                        }
-                       
-                       if(psys->particles->keys) {
-                               ParticleData *pa = psys->particles;
-
-                               for(a=0; a<psys->totpart; a++, pa++)
-                                       writestruct(wd, DATA, "ParticleKey", pa->totkey, pa->keys);
-                       }
                }
                if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
                writestruct(wd, DATA, "SoftBody", 1, psys->soft);
+               if(psys->soft) writestruct(wd, DATA, "PointCache", 1, psys->soft->pointcache);
+               writestruct(wd, DATA, "PointCache", 1, psys->pointcache);
        }
 }
 
@@ -630,6 +606,12 @@ static void write_sensors(WriteData *wd, ListBase *lb)
                case SENS_PROPERTY:
                        writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
                        break;
+               case SENS_ACTUATOR:
+                       writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
+                       break;
+               case SENS_DELAY:
+                       writestruct(wd, DATA, "bDelaySensor", 1, sens->data);
+                       break;
                case SENS_COLLISION:
                        writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
                        break;
@@ -691,6 +673,7 @@ static void write_actuators(WriteData *wd, ListBase *lb)
 
                switch(act->type) {
                case ACT_ACTION:
+               case ACT_SHAPEACTION:
                        writestruct(wd, DATA, "bActionActuator", 1, act->data);
                        break;
                case ACT_SOUND:
@@ -738,6 +721,12 @@ static void write_actuators(WriteData *wd, ListBase *lb)
                case ACT_2DFILTER:
                        writestruct(wd, DATA, "bTwoDFilterActuator", 1, act->data);
                        break;
+               case ACT_PARENT:
+                       writestruct(wd, DATA, "bParentActuator", 1, act->data);
+                       break;
+               case ACT_STATE:
+                       writestruct(wd, DATA, "bStateActuator", 1, act->data);
+                       break;
                default:
                        ; /* error: don't know how to write this file */
                }
@@ -861,7 +850,12 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                        
                        writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
                        writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
+                       writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
+               } 
+               else if(md->type==eModifierType_Fluidsim) {
+                       FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
                        
+                       writestruct(wd, DATA, "FluidsimSettings", 1, fluidmd->fss);
                } 
                else if (md->type==eModifierType_Collision) {
                        
@@ -913,7 +907,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
 
                        /* direct data */
                        writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat);
-                       write_effects(wd, &ob->effect);
+                       /* write_effects(wd, &ob->effect); */ /* not used anymore */
                        write_properties(wd, &ob->prop);
                        write_sensors(wd, &ob->sensors);
                        write_controllers(wd, &ob->controllers);
@@ -927,7 +921,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
                        
                        writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
                        writestruct(wd, DATA, "SoftBody", 1, ob->soft);
-                       writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT
+                       if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache);
+                       writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
                        
                        write_particlesystems(wd, &ob->particlesystem);
                        write_modifiers(wd, &ob->modifiers);
@@ -1071,7 +1066,7 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
        }
 }
 
-int amount_of_chars(char *str)
+static int amount_of_chars(char *str)
 {
        // Since the data is saved as UTF-8 to the cu->str
        // The cu->len is not same as the strlen(cu->str)
@@ -1337,9 +1332,20 @@ static void write_textures(WriteData *wd, ListBase *idbase)
                        if (tex->id.properties) IDP_WriteProperty(tex->id.properties, wd);
 
                        /* direct data */
-                       if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
+                       if(tex->type == TEX_PLUGIN && tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
                        if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
-                       if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+                       if(tex->type == TEX_ENVMAP && tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+                       if(tex->pd) {
+                               writestruct(wd, DATA, "PointDensity", 1, tex->pd);
+                               if(tex->pd->coba) writestruct(wd, DATA, "ColorBand", 1, tex->pd->coba);
+                       }
+                       if(tex->vd) writestruct(wd, DATA, "VoxelData", 1, tex->vd);
+                       
+                       /* nodetree is integral part of texture, no libdata */
+                       if(tex->nodetree) {
+                               writestruct(wd, DATA, "bNodeTree", 1, tex->nodetree);
+                               write_nodetree(wd, tex->nodetree);
+                       }
                        
                        write_previews(wd, tex->preview);
                }
@@ -1528,7 +1534,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                                                writestruct(wd, DATA, "StripColorBalance", 1, strip->color_balance);
                                        }
                                        if(seq->type==SEQ_IMAGE)
-                                               writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata);
+                                               writestruct(wd, DATA, "StripElem", MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), strip->stripdata);
                                        else if(seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND)
                                                writestruct(wd, DATA, "StripElem", 1, strip->stripdata);
 
@@ -1555,6 +1561,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                        writestruct(wd, DATA, "QuicktimeCodecData", 1, sce->r.qtcodecdata);
                        if (sce->r.qtcodecdata->cdParms) writedata(wd, DATA, sce->r.qtcodecdata->cdSize, sce->r.qtcodecdata->cdParms);
                }
+               if (sce->r.ffcodecdata.properties) {
+                       IDP_WriteProperty(sce->r.ffcodecdata.properties, wd);
+               }
 
                /* writing dynamic list of TimeMarkers to the blend file */
                for(marker= sce->markers.first; marker; marker= marker->next)
@@ -1578,6 +1587,32 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
+static void write_gpencil(WriteData *wd, bGPdata *gpd)
+{
+       bGPDlayer *gpl;
+       bGPDframe *gpf;
+       bGPDstroke *gps;
+       
+       /* write gpd data block to file */
+       writestruct(wd, DATA, "bGPdata", 1, gpd);
+       
+       /* write grease-pencil layers to file */
+       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+               writestruct(wd, DATA, "bGPDlayer", 1, gpl);
+               
+               /* write this layer's frames to file */
+               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                       writestruct(wd, DATA, "bGPDframe", 1, gpf);
+                       
+                       /* write strokes */
+                       for (gps= gpf->strokes.first; gps; gps= gps->next) {
+                               writestruct(wd, DATA, "bGPDstroke", 1, gps);
+                               writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);                               
+                       }
+               }
+       }
+}
+
 static void write_screens(WriteData *wd, ListBase *scrbase)
 {
        bScreen *sc;
@@ -1623,11 +1658,12 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                        sl= sa->spacedata.first;
                        while(sl) {
                                if(sl->spacetype==SPACE_VIEW3D) {
-                                       View3D *v3d= (View3D*) sl;
+                                       View3D *v3d= (View3D *) sl;
                                        writestruct(wd, DATA, "View3D", 1, v3d);
                                        if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
                                        if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
                                        if(v3d->clipbb) writestruct(wd, DATA, "BoundBox", 1, v3d->clipbb);
+                                       if(v3d->gpd) write_gpencil(wd, v3d->gpd);
                                }
                                else if(sl->spacetype==SPACE_IPO) {
                                        writestruct(wd, DATA, "SpaceIpo", 1, sl);
@@ -1639,7 +1675,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceFile", 1, sl);
                                }
                                else if(sl->spacetype==SPACE_SEQ) {
+                                       SpaceSeq *sseq= (SpaceSeq *)sl;
                                        writestruct(wd, DATA, "SpaceSeq", 1, sl);
+                                       if(sseq->gpd) write_gpencil(wd, sseq->gpd);
                                }
                                else if(sl->spacetype==SPACE_OOPS) {
                                        SpaceOops *so= (SpaceOops *)sl;
@@ -1676,7 +1714,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        
                                        writestruct(wd, DATA, "SpaceImage", 1, sl);
                                        if(sima->cumap)
-                                               write_curvemapping(wd, sima->cumap);                                    
+                                               write_curvemapping(wd, sima->cumap);
+                                       if(sima->gpd) 
+                                               write_gpencil(wd, sima->gpd);
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
                                        writestruct(wd, DATA, "SpaceImaSel", 1, sl);
@@ -1702,7 +1742,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceTime", 1, sl);
                                }
                                else if(sl->spacetype==SPACE_NODE){
+                                       SpaceNode *snode= (SpaceNode *)sl;
                                        writestruct(wd, DATA, "SpaceNode", 1, sl);
+                                       if(snode->gpd) write_gpencil(wd, snode->gpd);
                                }
                                sl= sl->next;
                        }
@@ -1825,6 +1867,7 @@ static void write_texts(WriteData *wd, ListBase *idbase)
 {
        Text *text;
        TextLine *tmp;
+       TextMarker *mrk;
 
        text= idbase->first;
        while(text) {
@@ -1848,7 +1891,16 @@ 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;
+                       }
                }
+
+
                text= text->id.next;
        }
 
@@ -1985,7 +2037,7 @@ static void write_global(WriteData *wd)
        fg.subversion= BLENDER_SUBVERSION;
        fg.minversion= BLENDER_MINVERSION;
        fg.minsubversion= BLENDER_MINSUBVERSION;
-       
+       fg.pads= 0; /* prevent mem checkers from complaining */
        writestruct(wd, GLOB, "FileGlobal", 1, &fg);
 }
 
@@ -2093,7 +2145,7 @@ int BLO_write_file(char *dir, int write_flags, char **error_r)
                        }
                }
                else
-               if(BLI_rename(tempname, dir) < 0) {
+               if(BLI_rename(tempname, dir) != 0) {
                        *error_r= "Can't change old file. File saved with @";
                        return 0;
                }
@@ -2255,7 +2307,7 @@ static int handle_append_runtime(int handle, char *exename, char **cause_r) {
        unsigned char buf[1024];
        int count, progfd= -1;
 
-       if (!runtime) {
+       if (!BLI_exists(runtime)) {
                cause= "Unable to find runtime";
                goto cleanup;
        }