- replaced G.{edve,eded,edvl} with G.editMesh, atm just a structure to
[blender.git] / source / blender / blenkernel / intern / blender.c
1
2 /*  blender.c   jan 94     MIXED MODEL
3  * 
4  * common help functions and data
5  * 
6  * $Id$
7  *
8  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version. The Blender
14  * Foundation also sells licenses for use in proprietary software under
15  * the Blender License.  See http://www.blender.org/BL/ for information
16  * about this.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  *
27  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
28  * All rights reserved.
29  *
30  * The Original Code is: all of this file.
31  *
32  * Contributor(s): none yet.
33  *
34  * ***** END GPL/BL DUAL LICENSE BLOCK *****
35  */
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #ifndef WIN32 
42     #include <unistd.h> // for read close
43     #include <sys/param.h> // for MAXPATHLEN
44 #else
45     #include <io.h> // for open close read
46 #endif
47
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 #include <fcntl.h> // for open
52
53 #include "MEM_guardedalloc.h"
54 #include "DNA_listBase.h"
55 #include "DNA_sdna_types.h"
56 #include "DNA_userdef_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_curve_types.h"
59
60 #include "BLI_blenlib.h"
61 #include "IMB_imbuf_types.h"
62 #include "IMB_imbuf.h"
63
64 #ifdef WIN32
65 #include "BLI_winstuff.h"
66 #endif
67
68 #include "DNA_mesh_types.h"
69 #include "DNA_screen_types.h"
70
71 #include "BKE_library.h"
72 #include "BKE_blender.h"
73 #include "BKE_displist.h"
74 #include "BKE_global.h"
75 #include "BKE_main.h"
76 #include "BKE_object.h"
77 #include "BKE_scene.h"
78 #include "BKE_effect.h"
79 #include "BKE_curve.h"
80 #include "BKE_font.h"
81
82 #include "BLI_editVert.h"
83 #include "BKE_bad_level_calls.h" /* for BPY_do_pyscript */
84
85 #include "BLO_readfile.h" /* for BLO_read_file */
86
87 #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
88 #include "BKE_utildefines.h" // O_BINARY FALSE
89
90 #include "nla.h"
91
92 Global G;
93 UserDef U;
94
95 char versionstr[48]= "";
96
97 /* ************************************************ */
98 /* pushpop facility: to store data temporally, FIFO! */
99
100 ListBase ppmain={0, 0};
101
102 typedef struct PushPop {
103         struct PushPop *next, *prev;
104         void *data;
105         int len;
106 } PushPop;
107
108 void pushdata(void *data, int len)
109 {
110         PushPop *pp;
111         
112         pp= MEM_mallocN(sizeof(PushPop), "pushpop");
113         BLI_addtail(&ppmain, pp);
114         pp->data= MEM_mallocN(len, "pushpop");
115         pp->len= len;
116         memcpy(pp->data, data, len);
117 }
118
119 void popfirst(void *data)
120 {
121         PushPop *pp;
122         
123         pp= ppmain.first;
124         if(pp) {
125                 memcpy(data, pp->data, pp->len);
126                 BLI_remlink(&ppmain, pp);
127                 MEM_freeN(pp->data);
128                 MEM_freeN(pp);
129         }
130         else printf("error in popfirst\n");
131 }
132
133 void poplast(void *data)
134 {
135         PushPop *pp;
136         
137         pp= ppmain.last;
138         if(pp) {
139                 memcpy(data, pp->data, pp->len);
140                 BLI_remlink(&ppmain, pp);
141                 MEM_freeN(pp->data);
142                 MEM_freeN(pp);
143         }
144         else printf("error in poplast\n");
145 }
146
147 void free_pushpop()
148 {
149         PushPop *pp;
150
151         pp= ppmain.first;
152         while(pp) {
153                 BLI_remlink(&ppmain, pp);
154                 MEM_freeN(pp->data);
155                 MEM_freeN(pp);
156         }       
157 }
158
159 void pushpop_test()
160 {
161         if(ppmain.first) printf("pushpop not empty\n");
162         free_pushpop();
163 }
164
165
166
167 /* ********** free ********** */
168
169 void free_blender(void)
170 {
171         free_main(G.main);
172         G.main= NULL;
173
174         IMB_freeImBufdata();            /* imbuf lib */
175 }
176
177 void duplicatelist(ListBase *list1, ListBase *list2)  /* copy from 2 to 1 */
178 {
179         struct Link *link1, *link2;
180         
181         list1->first= list1->last= 0;
182         
183         link2= list2->first;
184         while(link2) {
185
186                 link1= MEM_dupallocN(link2);
187                 BLI_addtail(list1, link1);
188                 
189                 link2= link2->next;
190         }       
191 }
192
193 static EditMesh theEditMesh;
194
195 void initglobals(void)
196 {
197         memset(&G, 0, sizeof(Global));
198         
199         G.editMesh = &theEditMesh;
200         memset(G.editMesh, 0, sizeof(G.editMesh));
201
202         U.savetime= 1;
203
204         G.animspeed= 4;
205
206         G.main= MEM_callocN(sizeof(Main), "initglobals");
207
208         strcpy(G.ima, "//");
209
210         G.version= BLENDER_VERSION;
211
212         G.order= 1;
213         G.order= (((char*)&G.order)[0])?L_ENDIAN:B_ENDIAN;
214
215         sprintf(versionstr, "www.blender.org %d", G.version);
216
217 #ifdef _WIN32   // FULLSCREEN
218         G.windowstate = G_WINDOWSTATE_USERDEF;
219 #endif
220
221         clear_workob(); /* object.c */
222 }
223
224 /***/
225
226 static void clear_global(void) {
227         extern short winqueue_break;    /* screen.c */
228
229         freeAllRad();
230         free_main(G.main); /* free all lib data */
231         freefastshade();        /* othwerwise old lamp settings stay active */
232
233
234         /* prevent hanging vars */      
235         R.backbuf= 0;
236         
237         /* force all queues to be left */
238         winqueue_break= 1;
239         
240         if (G.obedit) {
241                 freeNurblist(&editNurb);
242                 free_editMesh();
243                 free_editText();
244                 free_editArmature();
245         }
246
247         G.curscreen= NULL;
248         G.scene= NULL;
249         G.main= NULL;
250         
251         G.obedit= NULL;
252         G.obpose= NULL;
253         G.saction= NULL;
254         G.buts= NULL;
255         G.v2d= NULL;
256         G.vd= NULL;
257         G.soops= NULL;
258         G.sima= NULL;
259         G.sipo= NULL;
260         
261         G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT);
262 }
263
264 static void setup_app_data(BlendFileData *bfd, char *filename) {
265         Object *ob;
266         
267         clear_global();
268         
269         G.save_over = 1;
270         
271         G.main= bfd->main;
272         if (bfd->user) {
273                 U= *bfd->user;
274                 MEM_freeN(bfd->user);
275                 
276                 /* the UserDef struct is not corrected with do_versions() .... ugh! */
277                 if(U.wheellinescroll == 0) U.wheellinescroll = 3;
278                 if(U.menuthreshold1==0) {
279                         U.menuthreshold1= 5;
280                         U.menuthreshold2= 2;
281                 }
282                 if(U.tb_leftmouse==0) {
283                         U.tb_leftmouse= 5;
284                         U.tb_rightmouse= 5;
285                 }
286                 if(U.mixbufsize==0) U.mixbufsize= 2048;
287         }
288         
289         R.winpos= bfd->winpos;
290         R.displaymode= bfd->displaymode;
291         G.curscreen= bfd->curscreen;
292         G.fileflags= bfd->fileflags;
293         if (G.f & G_DEBUG) bfd->globalf |=G_DEBUG;
294         G.f= bfd->globalf;
295         G.scene= G.curscreen->scene;
296         
297                 /* few DispLists, but do text_to_curve */
298         // this should be removed!!! But first a better displist system (ton)
299         for (ob= G.main->object.first; ob; ob= ob->id.next) {
300                 if(ob->type==OB_FONT) {
301                         Curve *cu= ob->data;
302                         if(cu->nurb.first==0) text_to_curve(ob, 0);
303                 }
304                 else if(ob->type==OB_MESH) {
305                         makeDispList(ob);
306                         if(ob->effect.first) object_wave(ob);
307                 }
308         }
309         
310         if (!G.background) {
311                 setscreen(G.curscreen);
312         }
313                 /* baseflags */
314         set_scene_bg(G.scene);
315         
316         if (G.f & G_SCENESCRIPT) {
317                 BPY_do_pyscript(&G.scene->id, SCRIPT_ONLOAD);
318         }
319         
320         strcpy(G.sce, filename);
321         strcpy(G.main->name, filename); /* is guaranteed current file */
322         
323         MEM_freeN(bfd);
324 }
325
326 int BKE_read_file(char *dir, void *type_r) {
327         BlendReadError bre;
328         BlendFileData *bfd;
329         
330         if (!G.background)
331                 waitcursor(1);
332                 
333         bfd= BLO_read_from_file(dir, &bre);
334         if (bfd) {
335                 if (type_r)
336                         *((BlenFileType*)type_r)= bfd->type;
337                 
338                 setup_app_data(bfd, dir);
339         } else {
340                 error("Loading %s failed: %s", dir, BLO_bre_as_string(bre));
341         }
342         
343         if (!G.background)
344                 waitcursor(0);
345         
346         return (bfd?1:0);
347 }
348
349 int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r)
350 {
351         BlendReadError bre;
352         BlendFileData *bfd;
353         
354         if (!G.background)
355                 waitcursor(1);
356                 
357         bfd= BLO_read_from_memory(filebuf, filelength, &bre);
358         if (bfd) {
359                 if (type_r)
360                         *((BlenFileType*)type_r)= bfd->type;
361                 
362                 setup_app_data(bfd, "<memory>");
363         } else {
364                 error("Loading failed: %s", BLO_bre_as_string(bre));
365         }
366         
367         if (!G.background)
368                 waitcursor(0);
369         
370         return (bfd?1:0);
371 }