Blender  V2.59
readblenentry.c
Go to the documentation of this file.
00001 /*
00002  * $Id: readblenentry.c 36757 2011-05-18 19:42:30Z elubie $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * .blend file reading entry point
00029  */
00030 
00036 #include <stddef.h>
00037 #include "BLI_storage.h" /* _LARGEFILE_SOURCE */
00038 
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <stdio.h>
00042 #include <math.h>
00043 
00044 #include "MEM_guardedalloc.h"
00045 
00046 #include "BLI_utildefines.h"
00047 #include "BLI_ghash.h"
00048 #include "BLI_linklist.h"
00049 
00050 #include "DNA_genfile.h"
00051 #include "DNA_sdna_types.h"
00052 
00053 
00054 #include "BKE_main.h"
00055 #include "BKE_library.h" // for free_main
00056 #include "BKE_idcode.h"
00057 #include "BKE_report.h"
00058 #include "BKE_utildefines.h"
00059 
00060 #include "BLO_readfile.h"
00061 #include "BLO_undofile.h"
00062 
00063 #include "readfile.h"
00064 
00065 #include "BLO_sys_types.h" // needed for intptr_t
00066 
00067 #ifdef _WIN32
00068 #include "BLI_winstuff.h"
00069 #endif
00070 
00071 /* local prototypes --------------------- */
00072 void BLO_blendhandle_print_sizes(BlendHandle *, void *); 
00073 
00074         /* Access routines used by filesel. */
00075          
00076 BlendHandle *BLO_blendhandle_from_file(char *file, ReportList *reports)
00077 {
00078         BlendHandle *bh;
00079 
00080         bh= (BlendHandle*)blo_openblenderfile(file, reports);
00081 
00082         return bh;
00083 }
00084 
00085 BlendHandle *BLO_blendhandle_from_memory(void *mem, int memsize)
00086 {
00087         BlendHandle *bh;
00088 
00089         bh= (BlendHandle*)blo_openblendermemory(mem, memsize, NULL);
00090 
00091         return bh;
00092 }
00093 
00094 void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) 
00095 {
00096         FileData *fd= (FileData*) bh;
00097         BHead *bhead;
00098 
00099         fprintf(fp, "[\n");
00100         for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
00101                 if (bhead->code==ENDB)
00102                         break;
00103                 else {
00104                         short *sp= fd->filesdna->structs[bhead->SDNAnr];
00105                         char *name= fd->filesdna->types[ sp[0] ];
00106                         char buf[4];
00107                         
00108                         buf[0]= (bhead->code>>24)&0xFF;
00109                         buf[1]= (bhead->code>>16)&0xFF;
00110                         buf[2]= (bhead->code>>8)&0xFF;
00111                         buf[3]= (bhead->code>>0)&0xFF;
00112                         
00113                         buf[0]= buf[0]?buf[0]:' ';
00114                         buf[1]= buf[1]?buf[1]:' ';
00115                         buf[2]= buf[2]?buf[2]:' ';
00116                         buf[3]= buf[3]?buf[3]:' ';
00117                         
00118                         fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (long int)bhead->len+sizeof(BHead));
00119                 }
00120         }
00121         fprintf(fp, "]\n");
00122 }
00123 
00124 LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, int *tot_names)
00125 {
00126         FileData *fd= (FileData*) bh;
00127         LinkNode *names= NULL;
00128         BHead *bhead;
00129         int tot= 0;
00130 
00131         for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
00132                 if (bhead->code==ofblocktype) {
00133                         char *idname= bhead_id_name(fd, bhead);
00134 
00135                         BLI_linklist_prepend(&names, strdup(idname+2));
00136                         tot++;
00137                 } else if (bhead->code==ENDB)
00138                         break;
00139         }
00140 
00141         *tot_names= tot;
00142         return names;
00143 }
00144 
00145 LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *tot_prev)
00146 {
00147         FileData *fd= (FileData*) bh;
00148         LinkNode *previews= NULL;
00149         BHead *bhead;
00150         int looking=0;
00151         PreviewImage* prv = NULL;
00152         PreviewImage* new_prv = NULL;
00153         int tot= 0;
00154         
00155         for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
00156                 if (bhead->code==ofblocktype) {
00157                         char *idname= bhead_id_name(fd, bhead);
00158                         switch(GS(idname))
00159                         {
00160                                 case ID_MA: /* fall through */
00161                                 case ID_TE: /* fall through */
00162                                 case ID_IM: /* fall through */
00163                                 case ID_WO: /* fall through */
00164                                 case ID_LA: /* fall through */
00165                                         new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
00166                                         BLI_linklist_prepend(&previews, new_prv);
00167                                         tot++;
00168                                         looking = 1;
00169                                         break;
00170                                 default:
00171                                         break;
00172                         }
00173                 } else if (bhead->code==DATA) {
00174                         if (looking) {
00175                                 if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage") ) {
00176                                         prv = BLO_library_read_struct(fd, bhead, "PreviewImage");       
00177                                         if (prv) {
00178                                                 memcpy(new_prv, prv, sizeof(PreviewImage));
00179                                                 if (prv->rect[0]) {
00180                                                         unsigned int *rect = NULL;
00181                                                         new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
00182                                                         bhead= blo_nextbhead(fd, bhead);
00183                                                         rect = (unsigned int*)(bhead+1);
00184                                                         memcpy(new_prv->rect[0], rect, bhead->len);                                     
00185                                                 } else {
00186                                                         new_prv->rect[0] = NULL;
00187                                                 }
00188                                                 
00189                                                 if (prv->rect[1]) {
00190                                                         unsigned int *rect = NULL;
00191                                                         new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
00192                                                         bhead= blo_nextbhead(fd, bhead);
00193                                                         rect = (unsigned int*)(bhead+1);
00194                                                         memcpy(new_prv->rect[1], rect, bhead->len);                                                     
00195                                                 } else {
00196                                                         new_prv->rect[1] = NULL;
00197                                                 }
00198                                                 MEM_freeN(prv);
00199                                         }
00200                                 }
00201                         }
00202                 } else if (bhead->code==ENDB) {
00203                         break;
00204                 } else {
00205                         looking = 0;
00206                         new_prv = NULL;
00207                         prv = NULL;
00208                 }
00209                 
00210         }
00211 
00212         *tot_prev= tot;
00213         return previews;
00214 }
00215 
00216 LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) 
00217 {
00218         FileData *fd= (FileData*) bh;
00219         GHash *gathered= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "linkable_groups gh");
00220         LinkNode *names= NULL;
00221         BHead *bhead;
00222         
00223         for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
00224                 if (bhead->code==ENDB) {
00225                         break;
00226                 } else if (BKE_idcode_is_valid(bhead->code)) {
00227                         if (BKE_idcode_is_linkable(bhead->code)) {
00228                                 const char *str= BKE_idcode_to_name(bhead->code);
00229                                 
00230                                 if (!BLI_ghash_haskey(gathered, (void *)str)) {
00231                                         BLI_linklist_prepend(&names, strdup(str));
00232                                         BLI_ghash_insert(gathered, (void *)str, NULL);
00233                                 }
00234                         }
00235                 }
00236         }
00237         
00238         BLI_ghash_free(gathered, NULL, NULL);
00239         
00240         return names;
00241 }               
00242 
00243 void BLO_blendhandle_close(BlendHandle *bh) {
00244         FileData *fd= (FileData*) bh;
00245         
00246         blo_freefiledata(fd);
00247 }
00248 
00249         /**********/
00250 
00251 BlendFileData *BLO_read_from_file(const char *filepath, ReportList *reports)
00252 {
00253         BlendFileData *bfd = NULL;
00254         FileData *fd;
00255                 
00256         fd = blo_openblenderfile(filepath, reports);
00257         if (fd) {
00258                 fd->reports= reports;
00259                 bfd= blo_read_file_internal(fd, filepath);
00260                 blo_freefiledata(fd);                   
00261         }
00262 
00263         return bfd;     
00264 }
00265 
00266 BlendFileData *BLO_read_from_memory(void *mem, int memsize, ReportList *reports)
00267 {
00268         BlendFileData *bfd = NULL;
00269         FileData *fd;
00270                 
00271         fd = blo_openblendermemory(mem, memsize,  reports);
00272         if (fd) {
00273                 fd->reports= reports;
00274                 bfd= blo_read_file_internal(fd, "");
00275                 blo_freefiledata(fd);                   
00276         }
00277 
00278         return bfd;     
00279 }
00280 
00281 BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFile *memfile, ReportList *reports)
00282 {
00283         BlendFileData *bfd = NULL;
00284         FileData *fd;
00285         ListBase mainlist;
00286         
00287         fd = blo_openblendermemfile(memfile, reports);
00288         if (fd) {
00289                 fd->reports= reports;
00290                 strcpy(fd->relabase, filename);
00291                 
00292                 /* clear ob->proxy_from pointers in old main */
00293                 blo_clear_proxy_pointers_from_lib(oldmain);
00294 
00295                 /* separate libraries from old main */
00296                 blo_split_main(&mainlist, oldmain);
00297                 /* add the library pointers in oldmap lookup */
00298                 blo_add_library_pointer_map(&mainlist, fd);
00299                 
00300                 /* makes lookup of existing images in old main */
00301                 blo_make_image_pointer_map(fd, oldmain);
00302                 
00303                 bfd= blo_read_file_internal(fd, filename);
00304                 
00305                 /* ensures relinked images are not freed */
00306                 blo_end_image_pointer_map(fd, oldmain);
00307                 
00308                 /* move libraries from old main to new main */
00309                 if(bfd && mainlist.first!=mainlist.last) {
00310                         
00311                         /* Library structs themselves */
00312                         bfd->main->library= oldmain->library;
00313                         oldmain->library.first= oldmain->library.last= NULL;
00314                         
00315                         /* add the Library mainlist to the new main */
00316                         BLI_remlink(&mainlist, oldmain);
00317                         BLI_addhead(&mainlist, bfd->main);
00318                 }
00319                 blo_join_main(&mainlist);
00320                 
00321                 blo_freefiledata(fd);                   
00322         }
00323 
00324         return bfd;     
00325 }
00326 
00327 void BLO_blendfiledata_free(BlendFileData *bfd)
00328 {
00329         if (bfd->main) {
00330                 free_main(bfd->main);
00331         }
00332         
00333         if (bfd->user) {
00334                 MEM_freeN(bfd->user);
00335         }
00336 
00337         MEM_freeN(bfd);
00338 }
00339