Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/BLO_readfile.h30
-rw-r--r--source/blender/blenloader/BLO_runtime.h53
-rw-r--r--source/blender/blenloader/BLO_writefile.h2
-rw-r--r--source/blender/blenloader/CMakeLists.txt10
-rw-r--r--source/blender/blenloader/SConscript2
-rw-r--r--source/blender/blenloader/intern/readblenentry.c61
-rw-r--r--source/blender/blenloader/intern/readfile.c407
-rw-r--r--source/blender/blenloader/intern/readfile.h4
-rw-r--r--source/blender/blenloader/intern/runtime.c145
-rw-r--r--source/blender/blenloader/intern/writefile.c154
10 files changed, 612 insertions, 256 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 22083eda1c8..85d4b936c51 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -49,6 +49,8 @@ struct SpaceFile;
struct SpaceImaSel;
struct UserDef;
struct bContext;
+struct BHead;
+struct FileData;
typedef struct BlendHandle BlendHandle;
@@ -79,12 +81,12 @@ typedef struct BlendFileData {
* returns NULL and sets a report in the list if
* it cannot open the file.
*
- * @param file The path of the file to open.
+ * @param filepath The path of the file to open.
* @param reports If the return value is NULL, errors
* indicating the cause of the failure.
* @return The data of the file.
*/
-BlendFileData* BLO_read_from_file(const char *file, struct ReportList *reports);
+BlendFileData* BLO_read_from_file(const char *filepath, struct ReportList *reports);
/**
* Open a blender file from memory. The function
@@ -209,22 +211,38 @@ int BLO_has_bfile_extension(char *str);
*/
int BLO_is_a_library(const char *path, char *dir, char *group);
-struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir);
+struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, const char *filepath);
+
/**
* Link/Append a named datablock from an external blend file.
*
+ * @param mainl The main database to link from (not the active one).
+ * @param bh The blender file handle.
+ * @param idname The name of the datablock (without the 2 char ID prefix)
+ * @param idcode The kind of datablock to link.
+ * @return the appended ID when found.
+ */
+struct ID *BLO_library_append_named_part(struct Main *mainl, BlendHandle** bh, const char *idname, const int idcode);
+
+/**
+ * Link/Append a named datablock from an external blend file.
+ * optionally instance the object in the scene when the flags are set.
+ *
* @param C The context, when NULL instancing object in the scene isnt done.
* @param mainl The main database to link from (not the active one).
* @param bh The blender file handle.
- * @param name The name of the datablock (without the 2 char ID prefix)
+ * @param idname The name of the datablock (without the 2 char ID prefix)
* @param idcode The kind of datablock to link.
* @param flag Options for linking, used for instancing.
- * @return Boolean, 0 when the datablock could not be found.
+ * @return the appended ID when found.
*/
-int BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag);
+struct ID *BLO_library_append_named_part_ex(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *idname, const int idcode, const short flag);
+
void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
+void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
+
/* deprecated */
#if 1
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
diff --git a/source/blender/blenloader/BLO_runtime.h b/source/blender/blenloader/BLO_runtime.h
new file mode 100644
index 00000000000..920b14e92fa
--- /dev/null
+++ b/source/blender/blenloader/BLO_runtime.h
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+#ifndef BLO_RUNTIME_H
+#define BLO_RUNTIME_H
+
+/** \file BLO_runtime.h
+ * \ingroup blenloader
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct BlendFileData;
+struct ReportList;
+
+int BLO_is_a_runtime(char *file);
+struct BlendFileData *BLO_read_runtime(char *file, struct ReportList *reports);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLO_RUNTIME_H */
+
diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h
index 651928aa6a1..5c41350a463 100644
--- a/source/blender/blenloader/BLO_writefile.h
+++ b/source/blender/blenloader/BLO_writefile.h
@@ -39,7 +39,7 @@ struct MemFile;
struct Main;
struct ReportList;
-extern int BLO_write_file(struct Main *mainvar, char *dir, int write_flags, struct ReportList *reports, int *thumb);
+extern int BLO_write_file(struct Main *mainvar, const char *filepath, int write_flags, struct ReportList *reports, int *thumb);
extern int BLO_write_file_mem(struct Main *mainvar, struct MemFile *compare, struct MemFile *current, int write_flags);
extern int BLO_write_runtime(struct Main *mainvar, const char *file, char *exename, struct ReportList *reports);
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 4d8ac9bc4b6..be15b191c8a 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -26,23 +26,27 @@
set(INC
.
- ../blenlib
../blenkernel
+ ../blenlib
../makesdna
- ../readblenfile
../makesrna
../render/extern/include
../../../intern/guardedalloc
+)
+
+set(INC_SYS
${ZLIB_INCLUDE_DIRS}
)
set(SRC
intern/readblenentry.c
intern/readfile.c
+ intern/runtime.c
intern/undofile.c
intern/writefile.c
BLO_readfile.h
+ BLO_runtime.h
BLO_soundfile.h
BLO_sys_types.h
BLO_undofile.h
@@ -54,4 +58,4 @@ if(WITH_BUILDINFO)
add_definitions(-DNAN_BUILDINFO)
endif()
-blender_add_lib(bf_blenloader "${SRC}" "${INC}")
+blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript
index 695d17f0638..be9908d84e6 100644
--- a/source/blender/blenloader/SConscript
+++ b/source/blender/blenloader/SConscript
@@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
incs = '. #/intern/guardedalloc ../blenlib ../blenkernel'
-incs += ' ../makesdna ../readblenfile ../editors/include'
+incs += ' ../makesdna ../editors/include'
incs += ' ../render/extern/include ../makesrna'
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 39fab1929da..4ce5685ff18 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -62,8 +62,6 @@
#include "readfile.h"
-#include "BLO_readblenfile.h"
-
#include "BLO_sys_types.h" // needed for intptr_t
#ifdef _WIN32
@@ -150,15 +148,14 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
LinkNode *previews= NULL;
BHead *bhead;
int looking=0;
- int npreviews = 0;
PreviewImage* prv = NULL;
PreviewImage* new_prv = NULL;
int tot= 0;
for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
if (bhead->code==ofblocktype) {
- ID *id= (ID*) (bhead+1);
- switch(GS(id->name))
+ char *idname= bhead_id_name(fd, bhead);
+ switch(GS(idname))
{
case ID_MA: /* fall through */
case ID_TE: /* fall through */
@@ -176,31 +173,29 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
} else if (bhead->code==DATA) {
if (looking) {
if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage") ) {
- prv = (PreviewImage*) (bhead+1);
- npreviews = 0;
- memcpy(new_prv, prv, sizeof(PreviewImage));
- if (prv->rect[0]) {
- unsigned int *rect = NULL;
- // int rectlen = 0;
- new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
- bhead= blo_nextbhead(fd, bhead);
- rect = (unsigned int*)(bhead+1);
- // rectlen = new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int);
- memcpy(new_prv->rect[0], rect, bhead->len);
- } else {
- new_prv->rect[0] = NULL;
- }
-
- if (prv->rect[1]) {
- unsigned int *rect = NULL;
- // int rectlen = 0;
- new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
- bhead= blo_nextbhead(fd, bhead);
- rect = (unsigned int*)(bhead+1);
- // rectlen = new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int);
- memcpy(new_prv->rect[1], rect, bhead->len);
- } else {
- new_prv->rect[1] = NULL;
+ prv = BLO_library_read_struct(fd, bhead, "PreviewImage");
+ if (prv) {
+ memcpy(new_prv, prv, sizeof(PreviewImage));
+ if (prv->rect[0]) {
+ unsigned int *rect = NULL;
+ new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
+ bhead= blo_nextbhead(fd, bhead);
+ rect = (unsigned int*)(bhead+1);
+ memcpy(new_prv->rect[0], rect, bhead->len);
+ } else {
+ new_prv->rect[0] = NULL;
+ }
+
+ if (prv->rect[1]) {
+ unsigned int *rect = NULL;
+ new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
+ bhead= blo_nextbhead(fd, bhead);
+ rect = (unsigned int*)(bhead+1);
+ memcpy(new_prv->rect[1], rect, bhead->len);
+ } else {
+ new_prv->rect[1] = NULL;
+ }
+ MEM_freeN(prv);
}
}
}
@@ -253,15 +248,15 @@ void BLO_blendhandle_close(BlendHandle *bh) {
/**********/
-BlendFileData *BLO_read_from_file(const char *file, ReportList *reports)
+BlendFileData *BLO_read_from_file(const char *filepath, ReportList *reports)
{
BlendFileData *bfd = NULL;
FileData *fd;
- fd = blo_openblenderfile(file, reports);
+ fd = blo_openblenderfile(filepath, reports);
if (fd) {
fd->reports= reports;
- bfd= blo_read_file_internal(fd, file);
+ bfd= blo_read_file_internal(fd, filepath);
blo_freefiledata(fd);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9ff30916eff..1099823a8b1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -76,6 +76,7 @@
#include "DNA_node_types.h"
#include "DNA_object_fluidsim.h" // NT
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
@@ -138,7 +139,6 @@
//XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
#include "BLO_readfile.h"
#include "BLO_undofile.h"
-#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
#include "readfile.h"
@@ -489,13 +489,13 @@ static void read_file_version(FileData *fd, Main *main)
}
-static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, const char *relabase)
+static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *filepath, const char *relabase)
{
Main *m;
Library *lib;
char name1[FILE_MAXDIR+FILE_MAXFILE];
- strncpy(name1, name, sizeof(name1)-1);
+ BLI_strncpy(name1, filepath, sizeof(name1));
cleanup_path(relabase, name1);
// printf("blo_find_main: original in %s\n", name);
// printf("blo_find_main: converted to %s\n", name1);
@@ -513,14 +513,14 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, c
BLI_addtail(mainlist, m);
lib= alloc_libblock(&m->library, ID_LI, "lib");
- strncpy(lib->name, name, sizeof(lib->name)-1);
+ strncpy(lib->name, filepath, sizeof(lib->name)-1);
BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
m->curlib= lib;
read_file_version(fd, m);
- if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", name);
+ if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", filepath);
return m;
}
@@ -946,14 +946,14 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
/* cannot be called with relative paths anymore! */
/* on each new library added, it now checks for the current FileData and expands relativeness */
-FileData *blo_openblenderfile(const char *name, ReportList *reports)
+FileData *blo_openblenderfile(const char *filepath, ReportList *reports)
{
gzFile gzfile;
errno= 0;
- gzfile= gzopen(name, "rb");
+ gzfile= gzopen(filepath, "rb");
if (gzfile == (gzFile)Z_NULL) {
- BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", name, errno ? strerror(errno) : "Unknown error reading file");
+ BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file");
return NULL;
} else {
FileData *fd = filedata_new();
@@ -961,7 +961,7 @@ FileData *blo_openblenderfile(const char *name, ReportList *reports)
fd->read = fd_read_gzip_from_file;
/* needed for library_append and read_libraries */
- BLI_strncpy(fd->relabase, name, sizeof(fd->relabase));
+ BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
return blo_decode_and_check(fd, reports);
}
@@ -1084,7 +1084,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
/* now we know that we are in a blend file and it is safe to
assume that gp actually points to a group */
- if (BLI_streq("Screen", gp)==0)
+ if (strcmp("Screen", gp)!=0)
BLI_strncpy(group, gp, GROUP_MAX);
}
return 1;
@@ -1585,7 +1585,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
if (prv) {
int i;
- for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+ for (i=0; i < NUM_ICON_SIZES; ++i) {
if (prv->rect[i]) {
prv->rect[i] = newdataadr(fd, prv->rect[i]);
}
@@ -1738,6 +1738,12 @@ static void direct_link_fmodifiers(FileData *fd, ListBase *list)
FMod_Generator *data= (FMod_Generator *)fcm->data;
data->coefficients= newdataadr(fd, data->coefficients);
+
+ if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ unsigned int a;
+ for(a = 0; a < data->arraysize; a++)
+ SWITCH_INT(data->coefficients[a]);
+ }
}
break;
case FMODIFIER_TYPE_ENVELOPE:
@@ -2089,7 +2095,7 @@ static void lib_nodetree_do_versions_group(bNodeTree *ntree)
for (node=ntree->nodes.first; node; node=node->next) {
if (node->type==NODE_GROUP) {
bNodeTree *ngroup= (bNodeTree*)node->id;
- if (ngroup->flag & NTREE_DO_VERSIONS)
+ if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS))
lib_node_do_versions_group(node);
}
}
@@ -2117,7 +2123,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
}
{
- int has_old_groups=0;
+ /*int has_old_groups=0;*/ /*UNUSED*/
/* XXX this should actually be part of do_versions, but since we need
* finished library linking, it is not possible there. Instead in do_versions
* we have set the NTREE_DO_VERSIONS flag, so at this point we can do the
@@ -2127,7 +2133,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
if (ntree->flag & NTREE_DO_VERSIONS) {
/* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
nodeGroupExposeAllSockets(ntree);
- has_old_groups = 1;
+ /*has_old_groups = 1;*/ /*UNUSED*/
}
}
/* now verify all types in material trees, groups are set OK now */
@@ -3157,9 +3163,37 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
if(part->effector_weights)
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
- dw = part->dupliweights.first;
- for(; dw; dw=dw->next)
- dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+ if(part->dupliweights.first) {
+ int index_ok = 0;
+ /* check for old files without indices (all indexes 0) */
+ dw = part->dupliweights.first;
+ if(part->dupliweights.first == part->dupliweights.last) {
+ /* special case for only one object in the group */
+ index_ok = 1;
+ }
+ else {
+ for(; dw; dw=dw->next) {
+ if(dw->index > 0) {
+ index_ok = 1;
+ break;
+ }
+ }
+ }
+
+ if(index_ok) {
+ /* if we have indexes, let's use them */
+ dw = part->dupliweights.first;
+ for(; dw; dw=dw->next) {
+ GroupObject *go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index);
+ dw->ob = go ? go->ob : NULL;
+ }
+ }
+ else {
+ /* otherwise try to get objects from own library (won't work on library linked groups) */
+ for(; dw; dw=dw->next)
+ dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+ }
+ }
if(part->boids) {
BoidState *state = part->boids->states.first;
@@ -3534,6 +3568,18 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
+
+ /* If mesh has the same number of vertices as the
+ highest multires level, load the current mesh verts
+ into multires and discard the old data. Needed
+ because some saved files either do not have a verts
+ array, or the verts array contains out-of-date
+ data. */
+ if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert) {
+ if(mesh->mr->verts)
+ MEM_freeN(mesh->mr->verts);
+ mesh->mr->verts = MEM_dupallocN(mesh->mvert);
+ }
for(; lvl; lvl= lvl->next) {
lvl->verts= newdataadr(fd, lvl->verts);
@@ -3543,16 +3589,11 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
}
}
- /* Gracefully handle corrupted mesh */
+ /* if multires is present but has no valid vertex data,
+ there's no way to recover it; silently remove multires */
if(mesh->mr && !mesh->mr->verts) {
- /* If totals match, simply load the current mesh verts into multires */
- if(mesh->totvert == ((MultiresLevel*)mesh->mr->levels.last)->totvert)
- mesh->mr->verts = MEM_dupallocN(mesh->mvert);
- else {
- /* Otherwise, we can't recover the data, silently remove multires */
- multires_free(mesh->mr);
- mesh->mr = NULL;
- }
+ multires_free(mesh->mr);
+ mesh->mr = NULL;
}
if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) {
@@ -3839,26 +3880,10 @@ static void lib_link_object(FileData *fd, Main *main)
if(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain)
{
- smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
- smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
- smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
-
- smd->domain->effector_weights->group = newlibadr(fd, ob->id.lib, smd->domain->effector_weights->group);
-
smd->domain->flags |= MOD_SMOKE_FILE_LOAD; /* flag for refreshing the simulation after loading */
}
}
- {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-
- if(clmd)
- {
- clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
- clmd->coll_parms->group= newlibadr(fd, ob->id.lib, clmd->coll_parms->group);
- }
- }
-
/* texture field */
if(ob->pd)
lib_link_partdeflect(fd, &ob->id, ob->pd);
@@ -3969,7 +3994,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
fluidmd->fss= newdataadr(fd, fluidmd->fss);
fluidmd->fss->fmd= fluidmd;
- fluidmd->fss->meshSurfNormals = NULL;
+ fluidmd->fss->meshVelocities = NULL;
}
else if (md->type==eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData*) md;
@@ -4142,9 +4167,8 @@ static void direct_link_object(FileData *fd, Object *ob)
bActuator *act;
PythonComponent *pc;
ComponentProperty *cprop;
- int a;
- /* weak weak... this was only meant as draw flag, now is used in give_base too */
+ /* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
ob->flag &= ~OB_FROMGROUP;
/* loading saved files with editmode enabled works, but for undo we like
@@ -4242,6 +4266,7 @@ static void direct_link_object(FileData *fd, Object *ob)
sb->keys= newdataadr(fd, sb->keys);
test_pointer_array(fd, (void **)&sb->keys);
if(sb->keys) {
+ int a;
for(a=0; a<sb->totkey; a++) {
sb->keys[a]= newdataadr(fd, sb->keys[a]);
}
@@ -4349,6 +4374,7 @@ static void direct_link_object(FileData *fd, Object *ob)
MEM_freeN(hook);
}
+ ob->customdata_mask= 0;
ob->bb= NULL;
ob->derivedDeform= NULL;
ob->derivedFinal= NULL;
@@ -4856,7 +4882,6 @@ static void lib_link_screen(FileData *fd, Main *main)
else if(sl->spacetype==SPACE_FILE) {
SpaceFile *sfile= (SpaceFile *)sl;
sfile->files= NULL;
- sfile->params= NULL;
sfile->op= NULL;
sfile->layout= NULL;
sfile->folders_prev= NULL;
@@ -5469,7 +5494,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sfile->files= NULL;
sfile->layout= NULL;
sfile->op= NULL;
- sfile->params= NULL;
+ sfile->params= newdataadr(fd, sfile->params);
}
}
@@ -5529,20 +5554,31 @@ static void lib_link_library(FileData *UNUSED(fd), Main *main)
}
}
-/* Always call this once you havbe loaded new library data to set the relative paths correctly in relation to the blend file */
+/* Always call this once you have loaded new library data to set the relative paths correctly in relation to the blend file */
static void fix_relpaths_library(const char *basepath, Main *main)
{
Library *lib;
/* BLO_read_from_memory uses a blank filename */
- if (basepath==NULL || basepath[0] == '\0')
- return;
-
- for(lib= main->library.first; lib; lib= lib->id.next) {
- /* Libraries store both relative and abs paths, recreate relative paths,
- * relative to the blend file since indirectly linked libs will be relative to their direct linked library */
- if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */
- strncpy(lib->name, lib->filepath, sizeof(lib->name));
- BLI_path_rel(lib->name, basepath);
+ if (basepath==NULL || basepath[0] == '\0') {
+ for(lib= main->library.first; lib; lib= lib->id.next) {
+ /* when loading a linked lib into a file which has not been saved,
+ * there is nothing we can be relative to, so instead we need to make
+ * it absolute. This can happen when appending an object with a relative
+ * link into an unsaved blend file. See [#27405].
+ * The remap relative option will make it relative again on save - campbell */
+ if (strncmp(lib->name, "//", 2)==0) {
+ strncpy(lib->name, lib->filepath, sizeof(lib->name));
+ }
+ }
+ }
+ else {
+ for(lib= main->library.first; lib; lib= lib->id.next) {
+ /* Libraries store both relative and abs paths, recreate relative paths,
+ * relative to the blend file since indirectly linked libs will be relative to their direct linked library */
+ if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */
+ strncpy(lib->name, lib->filepath, sizeof(lib->name));
+ BLI_path_rel(lib->name, basepath);
+ }
}
}
}
@@ -5659,11 +5695,10 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a
while(bhead && bhead->code==DATA) {
void *data;
#if 0
- /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
+ /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
short *sp= fd->filesdna->structs[bhead->SDNAnr];
- char *allocname = fd->filesdna->types[ sp[0] ];
char *tmp= malloc(100);
-
+ allocname = fd->filesdna->types[ sp[0] ];
strcpy(tmp, allocname);
data= read_struct(fd, bhead, tmp);
#else
@@ -6281,7 +6316,7 @@ static void area_add_header_region(ScrArea *sa, ListBase *lb)
BLI_addtail(lb, ar);
ar->regiontype= RGN_TYPE_HEADER;
- if(sa->headertype==1)
+ if(sa->headertype==HEADERDOWN)
ar->alignment= RGN_ALIGN_BOTTOM;
else
ar->alignment= RGN_ALIGN_TOP;
@@ -8385,7 +8420,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ArmatureModifierData *amd = (ArmatureModifierData*) md;
if(amd->object && amd->deformflag==0) {
Object *oba= newlibadr(fd, lib, amd->object);
- bArmature *arm= newlibadr(fd, lib, oba->data);
+ arm= newlibadr(fd, lib, oba->data);
amd->deformflag= arm->deformflag;
}
}
@@ -8532,7 +8567,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
int a;
for(a=0; a<MAX_MTEX; a++) {
if(ma->mtex[a] && ma->mtex[a]->tex) {
- Tex *tex= newlibadr(fd, lib, ma->mtex[a]->tex);
+ tex= newlibadr(fd, lib, ma->mtex[a]->tex);
if(tex && tex->type==TEX_STUCCI)
ma->mtex[a]->mapto &= ~(MAP_COL|MAP_SPEC|MAP_REF);
}
@@ -8724,7 +8759,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* now, subversion control! */
if(main->subversionfile < 3) {
- bScreen *sc;
Image *ima;
Tex *tex;
@@ -9641,7 +9675,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
fluidmd->fss->lastgoodframe = INT_MAX;
fluidmd->fss->flag = 0;
- fluidmd->fss->meshSurfNormals = NULL;
+ fluidmd->fss->meshVelocities = NULL;
}
}
}
@@ -9700,7 +9734,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
nu->radius_interp = 3;
/* resolu and resolv are now used differently for surfaces
- * rather then using the resolution to define the entire number of divisions,
+ * rather than using the resolution to define the entire number of divisions,
* use it for the number of divisions per segment
*/
if (nu->pntsv > 1) {
@@ -10140,7 +10174,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ToolSettings *ts;
//PTCacheID *pid;
//ListBase pidlist;
- int a;
for(ob = main->object.first; ob; ob = ob->id.next) {
//BKE_ptcache_ids_from_object(&pidlist, ob);
@@ -10179,6 +10212,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
for(ma = main->mat.first; ma; ma = ma->id.next) {
+ int a;
if(ma->mode & MA_WIRE) {
ma->material_type= MA_TYPE_WIRE;
ma->mode &= ~MA_WIRE;
@@ -10264,8 +10298,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sce->gm.attrib = sce->r.attrib;
//Stereo
- sce->gm.xsch = sce->r.xsch;
- sce->gm.ysch = sce->r.ysch;
sce->gm.stereomode = sce->r.stereomode;
/* reassigning stereomode NO_STEREO and DOME to a separeted flag*/
if (sce->gm.stereomode == 1){ //1 = STEREO_NOSTEREO
@@ -11505,7 +11537,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
do_version_bone_roll_256(bone);
/* fix for objects which have zero dquat's
- * since this is multiplied with the quat rather then added */
+ * since this is multiplied with the quat rather than added */
for(ob= main->object.first; ob; ob= ob->id.next) {
if(is_zero_v4(ob->dquat)) {
unit_qt(ob->dquat);
@@ -11612,9 +11644,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- /* put compatibility code here until next subversion bump */
-
- {
+ if (main->versionfile < 258 || (main->versionfile == 258 && main->subversionfile < 1)){
/* screen view2d settings were not properly initialized [#27164]
* v2d->scroll caused the bug but best reset other values too which are in old blend files only.
* need to make less ugly - possibly an iterator? */
@@ -11666,6 +11696,35 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ {
+ /* add default value for behind strength of camera actuator */
+ Object *ob;
+ bActuator *act;
+ for(ob = main->object.first; ob; ob= ob->id.next) {
+ for(act= ob->actuators.first; act; act= act->next) {
+ if (act->type == ACT_CAMERA) {
+ bCameraActuator *ba= act->data;
+
+ ba->damping = 1.0/32.0;
+ }
+ }
+ }
+ }
+
+ {
+ ParticleSettings *part;
+ for(part = main->particle.first; part; part = part->id.next) {
+ /* Initialize particle billboard scale */
+ part->bb_size[0] = part->bb_size[1] = 1.0f;
+ }
+ }
+ }
+
+ /* put compatibility code here until next subversion bump */
+
+ {
+
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -11748,7 +11807,8 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
// XXX
user->uifonts.first= user->uifonts.last= NULL;
- user->uistyles.first= user->uistyles.last= NULL;
+
+ link_list(fd, &user->uistyles);
/* free fd->datamap again */
oldnewmap_free_unused(fd->datamap);
@@ -11757,7 +11817,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
return bhead;
}
-BlendFileData *blo_read_file_internal(FileData *fd, const char *filename)
+BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
{
BHead *bhead= blo_firstbhead(fd);
BlendFileData *bfd;
@@ -11769,7 +11829,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filename)
bfd->main->versionfile= fd->fileversion;
bfd->type= BLENFILETYPE_BLEND;
- strncpy(bfd->main->name, filename, sizeof(bfd->main->name)-1);
+ strncpy(bfd->main->name, filepath, sizeof(bfd->main->name)-1);
while(bhead) {
switch(bhead->code) {
@@ -12208,6 +12268,9 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
if(ma->nodetree)
expand_nodetree(fd, mainvar, ma->nodetree);
+
+ if(ma->group)
+ expand_doit(fd, mainvar, ma->group);
}
static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
@@ -12722,11 +12785,11 @@ static int object_in_any_scene(Main *mainvar, Object *ob)
return 0;
}
-/* when *lib set, it also does objects that were in the appended group */
-static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is_group_append)
+static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const short is_link)
{
Object *ob;
Base *base;
+ const short is_group_append= (is_link==FALSE && idcode==ID_GR);
/* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */
for(ob= mainvar->object.first; ob; ob= ob->id.next) {
@@ -12742,12 +12805,32 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
int do_it= 0;
- if(ob->id.us==0)
+ if(ob->id.us==0) {
do_it= 1;
- else if(ob->id.us==1 && lib)
- if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0)
- do_it= 1;
-
+ }
+ else if(idcode==ID_GR) {
+ if(ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) {
+ if((ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) {
+ do_it= 1;
+ }
+ }
+ }
+ else {
+ /* when appending, make sure any indirectly loaded objects
+ * get a base else they cant be accessed at all [#27437] */
+ if(ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) {
+
+ /* we may be appending from a scene where we already
+ * have a linked object which is not in any scene [#27616] */
+ if((ob->id.flag & LIB_PRE_EXISTING)==0) {
+
+ if(object_in_any_scene(mainvar, ob)==0) {
+ do_it= 1;
+ }
+ }
+ }
+ }
+
if(do_it) {
base= MEM_callocN( sizeof(Base), "add_ext_base");
BLI_addtail(&(sce->base), base);
@@ -12764,7 +12847,6 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
}
}
-/* when *lib set, it also does objects that were in the appended group */
static void give_base_to_groups(Main *mainvar, Scene *scene)
{
Group *group;
@@ -12796,29 +12878,22 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
}
/* returns true if the item was found
- * but it may already have already been appended/linked */
-static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
+* but it may already have already been appended/linked */
+static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, const short idcode)
{
- Scene *scene= CTX_data_scene(C);
- Object *ob;
- Base *base;
BHead *bhead;
- ID *id;
- int endloop=0;
+ ID *id= NULL;
int found=0;
- bhead = blo_firstbhead(fd);
- while(bhead && endloop==0) {
+ for(bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
+ if(bhead->code==idcode) {
+ const char *idname_test= bhead_id_name(fd, bhead);
- if(bhead->code==ENDB) endloop= 1;
- else if(bhead->code==idcode) {
- char *idname= bhead_id_name(fd, bhead);
-
- if(strcmp(idname+2, name)==0) {
+ if(strcmp(idname_test + 2, idname)==0) {
found= 1;
id= is_yet_read(fd, mainl, bhead);
if(id==NULL) {
- read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
+ read_libblock(fd, mainl, bhead, LIB_TESTEXT, &id);
}
else {
printf("append: already linked\n");
@@ -12829,47 +12904,67 @@ static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const
}
}
- if(idcode==ID_OB && scene) { /* loose object: give a base */
- base= MEM_callocN( sizeof(Base), "app_nam_part");
- BLI_addtail(&scene->base, base);
-
- if(id==NULL) ob= mainl->object.last;
- else ob= (Object *)id;
-
- /* link at active layer (view3d->lay if in context, else scene->lay */
- if((flag & FILE_ACTIVELAY)) {
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d) {
- ob->lay = v3d->layact;
- } else {
- ob->lay = scene->lay;
- }
- }
- ob->mode= 0;
- base->lay= ob->lay;
- base->object= ob;
- ob->id.us++;
-
- if(flag & FILE_AUTOSELECT) {
- base->flag |= SELECT;
- base->object->flag = base->flag;
- /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
- }
- }
- endloop= 1;
+ break;
}
}
+ else if(bhead->code==ENDB) {
+ break;
+ }
+ }
- bhead = blo_nextbhead(fd, bhead);
+ /* if we found the id but the id is NULL, this is really bad */
+ BLI_assert((found != 0) == (id != NULL));
+
+ return found ? id : NULL;
+}
+
+static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag)
+{
+ ID *id= append_named_part(mainl, fd, idname, idcode);
+
+ if(id && (GS(id->name) == ID_OB)) { /* loose object: give a base */
+ Scene *scene= CTX_data_scene(C); /* can be NULL */
+ if(scene) {
+ Base *base;
+ Object *ob;
+
+ base= MEM_callocN( sizeof(Base), "app_nam_part");
+ BLI_addtail(&scene->base, base);
+
+ ob= (Object *)id;
+
+ /* link at active layer (view3d->lay if in context, else scene->lay */
+ if((flag & FILE_ACTIVELAY)) {
+ View3D *v3d = CTX_wm_view3d(C);
+ ob->lay = v3d ? v3d->layact : scene->lay;
+ }
+
+ ob->mode= 0;
+ base->lay= ob->lay;
+ base->object= ob;
+ ob->id.us++;
+
+ if(flag & FILE_AUTOSELECT) {
+ base->flag |= SELECT;
+ base->object->flag = base->flag;
+ /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
+ }
+ }
}
- return found;
+ return id;
+}
+
+ID *BLO_library_append_named_part(Main *mainl, BlendHandle** bh, const char *idname, const int idcode)
+{
+ FileData *fd= (FileData*)(*bh);
+ return append_named_part(mainl, fd, idname, idcode);
}
-int BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
+ID *BLO_library_append_named_part_ex(const bContext *C, Main *mainl, BlendHandle** bh, const char *idname, const int idcode, const short flag)
{
FileData *fd= (FileData*)(*bh);
- return append_named_part(C, mainl, fd, name, idcode, flag);
+ return append_named_part_ex(C, mainl, fd, idname, idcode, flag);
}
static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
@@ -12878,8 +12973,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
if (bhead->code == GS(id->name)) {
-
- if (BLI_streq(id->name, bhead_id_name(fd, bhead))) {
+
+ if (strcmp(id->name, bhead_id_name(fd, bhead))==0) {
id->flag &= ~LIB_READ;
id->flag |= LIB_TEST;
// printf("read lib block %s\n", id->name);
@@ -12894,7 +12989,7 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
/* common routine to append/link something from a library */
-static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
+static Main* library_append_begin(const bContext *C, FileData **fd, const char *filepath)
{
Main *mainvar= CTX_data_main(C);
Main *mainl;
@@ -12903,7 +12998,7 @@ static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
blo_split_main(&(*fd)->mainlist, mainvar);
/* which one do we need? */
- mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.main->name);
+ mainl = blo_find_main(*fd, &(*fd)->mainlist, filepath, G.main->name);
/* needed for do_version */
mainl->versionfile= (*fd)->fileversion;
@@ -12912,10 +13007,10 @@ static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
return mainl;
}
-Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir)
+Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, const char *filepath)
{
FileData *fd= (FileData*)(*bh);
- return library_append_begin(C, &fd, dir);
+ return library_append_begin(C, &fd, filepath);
}
static void append_do_cursor(Scene *scene, Library *curlib, short flag)
@@ -13000,23 +13095,21 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
/* give a base to loose objects. If group append, do it for objects too */
if(scene) {
+ const short is_link= (flag & FILE_LINK) != 0;
if(idcode==ID_SCE) {
/* dont instance anything when linking in scenes, assume the scene its self instances the data */
}
- else if(idcode==ID_GR) {
- if (flag & FILE_LINK) {
- give_base_to_objects(mainvar, scene, NULL, 0);
- } else {
- give_base_to_objects(mainvar, scene, curlib, 1);
- }
+ else {
+ give_base_to_objects(mainvar, scene, curlib, idcode, is_link);
if (flag & FILE_GROUP_INSTANCE) {
give_base_to_groups(mainvar, scene);
}
- } else {
- give_base_to_objects(mainvar, scene, NULL, 0);
}
}
+ else {
+ printf("library_append_end, scene is NULL (objects wont get bases)\n");
+ }
/* has been removed... erm, why? s..ton) */
/* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
/* 20041208: put back. It only linked direct, not indirect objects (ton) */
@@ -13037,30 +13130,10 @@ void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle**
*bh= (BlendHandle*)fd;
}
-/* this is a version of BLO_library_append needed by the BPython API, so
- * scripts can load data from .blend files -- see Blender.Library module.*/
-/* append to scene */
-/* this should probably be moved into the Python code anyway */
-/* tentatively removed, Python should be able to use the split functions too: */
-/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */
-#if 0
-void BLO_script_library_append(BlendHandle **bh, char *dir, const char *name,
- int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
+void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
{
- FileData *fd= (FileData*)(*bh);
-
- /* try to append the requested object */
- fd->reports= reports;
- library_append(mainvar, scene, name, dir, idcode, 0, &fd, NULL, 0, flag );
- if(fd) fd->reports= NULL;
-
- /* do we need to do this? */
- if(scene)
- DAG_scene_sort(bmain, scene);
-
- *bh= (BlendHandle*)fd;
+ return read_struct(fd, bh, blockname);
}
-#endif
/* ************* READ LIBRARY ************** */
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index b409e456fe6..d4e42ccde16 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -113,9 +113,9 @@ struct Main;
void blo_join_main(ListBase *mainlist);
void blo_split_main(ListBase *mainlist, struct Main *main);
-BlendFileData *blo_read_file_internal(FileData *fd, const char *filename);
+BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath);
-FileData *blo_openblenderfile(const char *name, struct ReportList *reports);
+FileData *blo_openblenderfile(const char *filepath, struct ReportList *reports);
FileData *blo_openblendermemory(void *buffer, int buffersize, struct ReportList *reports);
FileData *blo_openblendermemfile(struct MemFile *memfile, struct ReportList *reports);
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
new file mode 100644
index 00000000000..f5308b5ea5c
--- /dev/null
+++ b/source/blender/blenloader/intern/runtime.c
@@ -0,0 +1,145 @@
+/*
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/**
+ * \file runtime.c
+ * \brief This file handles the loading of .blend files embedded in runtimes
+ * \ingroup blenloader
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#ifdef WIN32
+#include <io.h> // read, open
+#include "BLI_winstuff.h"
+#else // ! WIN32
+#include <unistd.h> // read
+#endif
+
+#include "BLO_readfile.h"
+#include "BLO_runtime.h"
+
+#include "BKE_blender.h"
+#include "BKE_report.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_blenlib.h"
+
+/* Runtime reading */
+
+static int handle_read_msb_int(int handle)
+{
+ unsigned char buf[4];
+
+ if(read(handle, buf, 4) != 4)
+ return -1;
+
+ return (buf[0]<<24) + (buf[1]<<16) + (buf[2]<<8) + (buf[3]<<0);
+}
+
+int BLO_is_a_runtime(char *path)
+{
+ int res= 0, fd= open(path, O_BINARY|O_RDONLY, 0);
+ int datastart;
+ char buf[8];
+
+ if(fd==-1)
+ goto cleanup;
+
+ lseek(fd, -12, SEEK_END);
+
+ datastart= handle_read_msb_int(fd);
+
+ if(datastart==-1)
+ goto cleanup;
+ else if(read(fd, buf, 8)!=8)
+ goto cleanup;
+ else if(memcmp(buf, "BRUNTIME", 8)!=0)
+ goto cleanup;
+ else
+ res= 1;
+
+cleanup:
+ if(fd!=-1)
+ close(fd);
+
+ return res;
+}
+
+BlendFileData *BLO_read_runtime(char *path, ReportList *reports)
+{
+ BlendFileData *bfd= NULL;
+ size_t actualsize;
+ int fd, datastart;
+ char buf[8];
+
+ fd= open(path, O_BINARY|O_RDONLY, 0);
+
+ if(fd==-1) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", path, strerror(errno));
+ goto cleanup;
+ }
+
+ actualsize= BLI_filesize(fd);
+
+ lseek(fd, -12, SEEK_END);
+
+ datastart= handle_read_msb_int(fd);
+
+ if(datastart==-1) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (problem seeking)", path);
+ goto cleanup;
+ }
+ else if(read(fd, buf, 8)!=8) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (truncated header)", path);
+ goto cleanup;
+ }
+ else if(memcmp(buf, "BRUNTIME", 8)!=0) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (not a blend file)", path);
+ goto cleanup;
+ }
+ else {
+ //printf("starting to read runtime from %s at datastart %d\n", path, datastart);
+ lseek(fd, datastart, SEEK_SET);
+ bfd = blo_read_blendafterruntime(fd, path, actualsize-datastart, reports);
+ fd= -1; // file was closed in blo_read_blendafterruntime()
+ }
+
+cleanup:
+ if(fd!=-1)
+ close(fd);
+
+ return bfd;
+}
+
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 28074b52322..3f2abd8355c 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -724,7 +724,8 @@ static void write_userdef(WriteData *wd)
wmKeyMap *keymap;
wmKeyMapItem *kmi;
bAddon *bext;
-
+ uiStyle *style;
+
writestruct(wd, USER, "UserDef", 1, &U);
for(btheme= U.themes.first; btheme; btheme=btheme->next)
@@ -743,6 +744,10 @@ static void write_userdef(WriteData *wd)
for(bext= U.addons.first; bext; bext=bext->next)
writestruct(wd, DATA, "bAddon", 1, bext);
+
+ for(style= U.uistyles.first; style; style= style->next) {
+ writestruct(wd, DATA, "uiStyle", 1, style);
+ }
}
static void write_boid_state(WriteData *wd, BoidState *state)
@@ -833,6 +838,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
{
ParticleSettings *part;
ParticleDupliWeight *dw;
+ GroupObject *go;
int a;
part= idbase->first;
@@ -847,8 +853,16 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
dw = part->dupliweights.first;
- for(; dw; dw=dw->next)
+ for(; dw; dw=dw->next) {
+ /* update indices */
+ dw->index = 0;
+ go = part->dup_group->gobject.first;
+ while(go && go->ob != dw->ob) {
+ go=go->next;
+ dw->index++;
+ }
writestruct(wd, DATA, "ParticleDupliWeight", 1, dw);
+ }
if(part->boids && part->phystype == PART_PHYS_BOIDS) {
BoidState *state = part->boids->states.first;
@@ -2130,7 +2144,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceButs", 1, sl);
}
else if(sl->spacetype==SPACE_FILE) {
+ SpaceFile *sfile= (SpaceFile *)sl;
+
writestruct(wd, DATA, "SpaceFile", 1, sl);
+ if(sfile->params)
+ writestruct(wd, DATA, "FileSelectParams", 1, sfile->params);
}
else if(sl->spacetype==SPACE_SEQ) {
writestruct(wd, DATA, "SpaceSeq", 1, sl);
@@ -2162,8 +2180,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceText", 1, sl);
}
else if(sl->spacetype==SPACE_SCRIPT) {
- SpaceScript *sc = (SpaceScript*)sl;
- sc->but_refs = NULL;
+ SpaceScript *scr = (SpaceScript*)sl;
+ scr->but_refs = NULL;
writestruct(wd, DATA, "SpaceScript", 1, sl);
}
else if(sl->spacetype==SPACE_ACTION) {
@@ -2552,15 +2570,50 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
return endwrite(wd);
}
+/* do reverse file history: .blend1 -> .blend2, .blend -> .blend1 */
+/* return: success(0), failure(1) */
+static int do_history(const char *name, ReportList *reports)
+{
+ char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
+ int hisnr= U.versions;
+
+ if(U.versions==0) return 0;
+ if(strlen(name)<2) {
+ BKE_report(reports, RPT_ERROR, "Unable to make version backup: filename too short");
+ return 1;
+ }
+
+ while(hisnr > 1) {
+ BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr-1);
+ BLI_snprintf(tempname2, sizeof(tempname2), "%s%d", name, hisnr);
+
+ if(BLI_rename(tempname1, tempname2)) {
+ BKE_report(reports, RPT_ERROR, "Unable to make version backup");
+ return 1;
+ }
+ hisnr--;
+ }
+
+ /* is needed when hisnr==1 */
+ BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr);
+
+ if(BLI_rename(name, tempname1)) {
+ BKE_report(reports, RPT_ERROR, "Unable to make version backup");
+ return 1;
+ }
+
+ return 0;
+}
+
/* return: success (1) */
-int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *reports, int *thumb)
+int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, int *thumb)
{
char userfilename[FILE_MAXDIR+FILE_MAXFILE];
char tempname[FILE_MAXDIR+FILE_MAXFILE+1];
int file, err, write_user_block;
/* open temporary file, so we preserve the original in case we crash */
- BLI_snprintf(tempname, sizeof(tempname), "%s@", dir);
+ BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
file = open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
if(file == -1) {
@@ -2572,68 +2625,83 @@ int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *report
if(write_flags & G_FILE_RELATIVE_REMAP) {
char dir1[FILE_MAXDIR+FILE_MAXFILE];
char dir2[FILE_MAXDIR+FILE_MAXFILE];
- BLI_split_dirfile(dir, dir1, NULL);
+ BLI_split_dirfile(filepath, dir1, NULL);
BLI_split_dirfile(mainvar->name, dir2, NULL);
/* just incase there is some subtle difference */
BLI_cleanup_dir(mainvar->name, dir1);
BLI_cleanup_dir(mainvar->name, dir2);
- if(strcmp(dir1, dir2)==0)
+ if(BLI_path_cmp(dir1, dir2)==0) {
write_flags &= ~G_FILE_RELATIVE_REMAP;
- else
- makeFilesAbsolute(mainvar, G.main->name, NULL);
+ }
+ else {
+ if(G.relbase_valid) {
+ /* blend may not have been saved before. Tn this case
+ * we should not have any relative paths, but if there
+ * is somehow, an invalid or empty G.main->name it will
+ * print an error, dont try make the absolute in this case. */
+ makeFilesAbsolute(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(dir, userfilename) == 0);
+ write_user_block= (BLI_path_cmp(filepath, userfilename) == 0);
if(write_flags & G_FILE_RELATIVE_REMAP)
- makeFilesRelative(mainvar, dir, NULL); /* note, making relative to something OTHER then G.main->name */
+ makeFilesRelative(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);
- /* rename/compress */
- if(!err) {
- if(write_flags & G_FILE_COMPRESS) {
- /* compressed files have the same ending as regular files... only from 2.4!!! */
- char gzname[FILE_MAXDIR+FILE_MAXFILE+4];
- int ret;
+ if (err) {
+ BKE_report(reports, RPT_ERROR, strerror(errno));
+ remove(tempname);
- /* first write compressed to separate @.gz */
- BLI_snprintf(gzname, sizeof(gzname), "%s@.gz", dir);
- ret = BLI_gzip(tempname, gzname);
-
- if(0==ret) {
- /* now rename to real file name, and delete temp @ file too */
- if(BLI_rename(gzname, dir) != 0) {
- BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @.");
- return 0;
- }
+ return 0;
+ }
- BLI_delete(tempname, 0, 0);
- }
- else if(-1==ret) {
- BKE_report(reports, RPT_ERROR, "Failed opening .gz file.");
- return 0;
- }
- else if(-2==ret) {
- BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression.");
+ /* file save to temporary file was successful */
+ /* now do reverse file history (move .blend1 -> .blend2, .blend -> .blend1) */
+ if (write_flags & G_FILE_HISTORY) {
+ int err_hist = do_history(filepath, reports);
+ if (err_hist) {
+ BKE_report(reports, RPT_ERROR, "Version backup failed. File saved with @");
+ return 0;
+ }
+ }
+
+ if(write_flags & G_FILE_COMPRESS) {
+ /* compressed files have the same ending as regular files... only from 2.4!!! */
+ char gzname[FILE_MAXDIR+FILE_MAXFILE+4];
+ int ret;
+
+ /* first write compressed to separate @.gz */
+ BLI_snprintf(gzname, sizeof(gzname), "%s@.gz", filepath);
+ ret = BLI_gzip(tempname, gzname);
+
+ if(0==ret) {
+ /* now rename to real file name, and delete temp @ file too */
+ if(BLI_rename(gzname, filepath) != 0) {
+ BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @.");
return 0;
}
+
+ BLI_delete(tempname, 0, 0);
}
- else if(BLI_rename(tempname, dir) != 0) {
- BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @");
+ else if(-1==ret) {
+ BKE_report(reports, RPT_ERROR, "Failed opening .gz file.");
+ return 0;
+ }
+ else if(-2==ret) {
+ BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression.");
return 0;
}
-
}
- else {
- BKE_report(reports, RPT_ERROR, strerror(errno));
- remove(tempname);
-
+ else if(BLI_rename(tempname, filepath) != 0) {
+ BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @");
return 0;
}