c7a8b150d3a065ca3e69b73edc25a550ff9d28bd
[blender-staging.git] / source / blender / blenkernel / intern / exotic.c
1 /*  exotic.c   
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  *
23  * Contributor(s): 
24  * - Martin DeMello
25  *   Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline
26  *   Copyright (C) 2004 by Etheract Software Labs
27  *
28  * - Blender Foundation
29  *
30  * ***** END GPL LICENSE BLOCK *****/
31
32 #include "BLI_storage.h"
33
34 #include <ctype.h> /* isdigit, isspace */
35 #include <math.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <fcntl.h>
39 #include <string.h>
40
41 #ifndef _WIN32 
42 #include <unistd.h>
43 #else
44 #include <io.h>
45 #define open _open
46 #define read _read
47 #define close _close
48 #define write _write
49 #endif
50
51 #include "MEM_guardedalloc.h"
52
53 #include "DNA_object_types.h"
54 #include "DNA_mesh_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_material_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_curve_types.h"
59 #include "DNA_image_types.h"
60 #include "DNA_camera_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_view3d_types.h"
63 #include "DNA_userdef_types.h"
64
65 #include "BKE_utildefines.h"
66 #include "BLI_blenlib.h"
67 #include "BLI_arithb.h"
68 #include "BLI_editVert.h"
69
70 #include "BKE_blender.h"
71 #include "BKE_global.h"
72 #include "BKE_main.h"
73 #include "BKE_mesh.h"
74 #include "BKE_library.h"
75 #include "BKE_global.h"
76 #include "BKE_object.h"
77 #include "BKE_material.h"
78 #include "BKE_exotic.h"
79
80 /*  #include "BKE_error.h" */
81 #include "BKE_screen.h"
82 #include "BKE_displist.h"
83 #include "BKE_DerivedMesh.h"
84 #include "BKE_curve.h"
85 #include "BKE_customdata.h"
86
87 #ifndef DISABLE_PYTHON
88 #include "BPY_extern.h"
89 #endif
90
91 #include "zlib.h"
92
93 static int is_dxf(char *str);
94 static void dxf_read(Scene *scene, char *filename);
95 static int is_stl(char *str);
96
97 static int is_stl_ascii(char *str)
98 {       
99         FILE *fpSTL;
100         char buffer[1000];
101         int  numread, i;
102
103         fpSTL = fopen(str, "rb");
104         if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
105           { fclose(fpSTL); return 0; }
106
107         for (i=0; i < numread; ++i) {
108           /* if bit 8 is set we assume binary */
109           if (buffer[i] & 0x80)
110                 { fclose(fpSTL); return 0; }
111         }
112
113         buffer[5] = '\0';
114         if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) ) 
115           { fclose(fpSTL); return 0; }
116
117         fclose(fpSTL);
118         
119         return 1;
120 }
121
122 static int is_stl(char *str)
123 {
124         int i;
125         i = strlen(str) - 3;
126         if ( (str[i] !='s') && (str[i] !='S'))
127                 return 0;
128         i++;
129         if ( (str[i] !='t') && (str[i] !='T'))
130                 return 0;
131         i++;
132         if ( (str[i] !='l') && (str[i] !='L'))
133                 return 0;
134
135         return 1;
136 }
137
138 #define READSTLVERT {                                   \
139   if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
140     char error_msg[255];                                \
141     MEM_freeN(vertdata);                                \
142     MEM_freeN(facedata);                                \
143     fclose(fpSTL);                                      \
144     sprintf(error_msg, "Problems reading face %d!", i); \
145     return;                                             \
146   }                                                     \
147   else {                                                \
148     if (ENDIAN_ORDER==B_ENDIAN) {                       \
149       SWITCH_INT(mvert->co[0]);                         \
150       SWITCH_INT(mvert->co[1]);                         \
151       SWITCH_INT(mvert->co[2]);                         \
152     }                                                   \
153   }                                                     \
154 }
155
156 static void simple_vertex_normal_blend(short *no, short *ble)
157 {
158         if(no[0]==0 && no[1]==0 && no[2]==0) {
159                 VECCOPY(no, ble);
160         }
161         else {
162                 no[0]= (2*no[0] + ble[0])/3;
163                 no[1]= (2*no[1] + ble[1])/3;
164                 no[2]= (2*no[2] + ble[2])/3;
165         }
166 }
167
168 static void mesh_add_normals_flags(Mesh *me)
169 {
170         MVert *v1, *v2, *v3, *v4;
171         MFace *mface;
172         float nor[3];
173         int a;
174         short sno[3];
175         
176         mface= me->mface;
177         for(a=0; a<me->totface; a++, mface++) {
178                 v1= me->mvert+mface->v1;
179                 v2= me->mvert+mface->v2;
180                 v3= me->mvert+mface->v3;
181                 v4= me->mvert+mface->v4;
182                 
183                 CalcNormFloat(v1->co, v2->co, v3->co, nor);
184                 sno[0]= 32767.0*nor[0];
185                 sno[1]= 32767.0*nor[1];
186                 sno[2]= 32767.0*nor[2];
187                 
188                 simple_vertex_normal_blend(v1->no, sno);
189                 simple_vertex_normal_blend(v2->no, sno);
190                 simple_vertex_normal_blend(v3->no, sno);
191                 if(mface->v4) {
192                         simple_vertex_normal_blend(v4->no, sno);
193                 }
194                 mface->edcode= ME_V1V2|ME_V2V3;
195         }       
196 }
197
198 static void read_stl_mesh_binary(Scene *scene, char *str)
199 {
200         FILE   *fpSTL;
201         Object *ob;
202         Mesh   *me;
203         MVert  *mvert, *vertdata;
204         MFace  *mface, *facedata;
205         unsigned int numfacets = 0, i, j, vertnum;
206         unsigned int maxmeshsize, nummesh, lastmeshsize;
207         unsigned int totvert, totface;
208
209         fpSTL= fopen(str, "rb");
210         if(fpSTL==NULL) {
211                 //XXX error("Can't read file");
212                 return;
213         }
214
215         fseek(fpSTL, 80, SEEK_SET);
216         fread(&numfacets, 4*sizeof(char), 1, fpSTL);
217         if (ENDIAN_ORDER==B_ENDIAN) {
218                 SWITCH_INT(numfacets);
219         }
220
221         maxmeshsize = MESH_MAX_VERTS/3;
222
223         nummesh      = (numfacets / maxmeshsize) + 1;
224         lastmeshsize = numfacets % maxmeshsize;
225
226         if (numfacets) {
227                 for (j=0; j < nummesh; ++j) {
228                         /* new object */
229                         if (j == nummesh-1) {
230                                 totface = lastmeshsize;
231                         }
232                         else {
233                                 totface = maxmeshsize;
234                         }
235                         totvert = 3 * totface;
236         
237                         vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
238                         facedata = MEM_callocN(totface*sizeof(MFace), "mface");
239
240                         vertnum = 0;
241                         mvert= vertdata;
242                         mface = facedata;
243                         for (i=0; i < totface; i++) {
244                                 fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
245                                 READSTLVERT;
246                                 mvert++;
247                                 READSTLVERT;
248                                 mvert++;
249                                 READSTLVERT;
250                                 mvert++;
251
252                                 mface->v1 = vertnum++;
253                                 mface->v2 = vertnum++;
254                                 mface->v3 = vertnum++;
255                                 mface++;
256
257                                 fseek(fpSTL, 2, SEEK_CUR);
258                         }
259
260                         ob= add_object(scene, OB_MESH);
261                         me= ob->data;
262                         me->totvert = totvert;
263                         me->totface = totface;
264                         me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
265                                                          vertdata, totvert);
266                         me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
267                                                          facedata, totface);
268
269                         mesh_add_normals_flags(me);
270                         make_edges(me, 0);
271                 }
272                 //XXX waitcursor(1);
273         }
274         fclose(fpSTL);
275
276 }
277 #undef READSTLVERT
278
279 #define STLALLOCERROR { \
280         char error_msg[255]; \
281         fclose(fpSTL); \
282         sprintf(error_msg, "Can't allocate storage for %d faces!", \
283                         numtenthousand * 10000); \
284         return; \
285 }
286
287 #define STLBAILOUT(message) { \
288         char error_msg[255]; \
289         fclose(fpSTL); \
290         free(vertdata); \
291         sprintf(error_msg, "Line %d: %s", linenum, message); \
292         return; \
293 }
294
295 #define STLREADLINE { \
296         if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
297         linenum++; \
298 }
299
300 #define STLREADVERT { \
301         STLREADLINE; \
302         if ( !(cp = strstr(buffer, "vertex")) && \
303                  !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
304         vp = vertdata + 3 * totvert; \
305         if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
306                 STLBAILOUT("Bad vertex!"); \
307         ++totvert; \
308 }
309 static void read_stl_mesh_ascii(Scene *scene, char *str)
310 {
311         FILE   *fpSTL;
312         char   buffer[2048], *cp;
313         Object *ob;
314         Mesh   *me;
315         MVert  *mvert;
316         MFace  *mface;
317         float  *vertdata, *vp;
318         unsigned int numtenthousand, linenum;
319         unsigned int i, vertnum;
320         unsigned int totvert, totface;
321
322         /* ASCII stl sucks ... we don't really know how many faces there
323            are until the file is done, so lets allocate faces 10000 at a time */
324
325         fpSTL= fopen(str, "r");
326         if(fpSTL==NULL) {
327                 //XXX error("Can't read file");
328                 return;
329         }
330         
331         /* we'll use the standard malloc/realloc for now ... 
332          * lets allocate enough storage to hold 10000 triangles,
333          * i.e. 30000 verts, i.e., 90000 floats.
334          */
335         numtenthousand = 1;
336         vertdata = malloc(numtenthousand*3*30000*sizeof(float));        // uses realloc!
337         if (!vertdata); STLALLOCERROR;
338
339         linenum = 1;
340         /* Get rid of the first line */
341         STLREADLINE;
342
343         totvert = 0;
344         totface = 0;
345         while(1) {
346                 /* Read in the next line */
347                 STLREADLINE;
348
349                 /* lets check if this is the end of the file */
350                 if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") ) 
351                         break;
352
353                 /* Well, guess that wasn't the end, so lets make
354                  * sure we have enough storage for some more faces
355                  */
356                 if ( (totface) && ( (totface % 10000) == 0 ) ) {
357                         ++numtenthousand;
358                         vertdata = realloc(vertdata, 
359                                                            numtenthousand*3*30000*sizeof(float));
360                         if (!vertdata); STLALLOCERROR;
361                 }
362                 
363                 /* Don't read normal, but check line for proper syntax anyway
364                  */
365                 if ( !(cp = strstr(buffer, "facet")) && 
366                          !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
367                 if ( !(strstr(cp+5, "normal")) && 
368                          !(strstr(cp+5, "NORMAL")) )       STLBAILOUT("Bad normal line!");
369
370                 /* Read in what should be the outer loop line 
371                  */
372                 STLREADLINE;
373                 if ( !(cp = strstr(buffer, "outer")) &&
374                          !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
375                 if ( !(strstr(cp+5, "loop")) &&
376                          !(strstr(cp+5, "LOOP")) )         STLBAILOUT("Bad outer loop!");
377
378                 /* Read in the face */
379                 STLREADVERT;
380                 STLREADVERT;
381                 STLREADVERT;
382
383                 /* Read in what should be the endloop line 
384                  */
385                 STLREADLINE;
386                 if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") ) 
387                         STLBAILOUT("Bad endloop!");
388
389                 /* Read in what should be the endfacet line 
390                  */
391                 STLREADLINE;
392                 if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") ) 
393                         STLBAILOUT("Bad endfacet!");
394
395                 /* Made it this far? Increment face count */
396                 ++totface;
397         }
398         fclose(fpSTL);
399
400         /* OK, lets create our mesh */
401         ob = add_object(scene, OB_MESH);
402         me = ob->data;
403
404         me->totface = totface;
405         me->totvert = totvert;
406         me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
407                                          NULL, totvert);
408         me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
409                                          NULL, totface);
410
411         /* Copy vert coords and create topology */
412         mvert = me->mvert;
413         mface = me->mface;
414         vertnum = 0;
415         for (i=0; i < totface; ++i) {
416                 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
417                 mface->v1 = vertnum;
418                 mvert++;
419                 vertnum++;
420
421                 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
422                 mface->v2 = vertnum;
423                 mvert++;
424                 vertnum++;
425
426                 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
427                 mface->v3 = vertnum;
428                 mvert++;
429                 vertnum++;
430
431                 mface++;
432         }
433         free(vertdata);
434
435         mesh_add_normals_flags(me);
436         make_edges(me, 0);
437
438         //XXX waitcursor(1);
439 }
440
441 #undef STLALLOCERROR
442 #undef STLBAILOUT
443 #undef STLREADLINE
444 #undef STLREADVERT
445
446 /* ***************** INVENTOR ******************* */
447
448
449 #define IV_MAXSTACK 3000000
450 #define IV_MAXFIELD 10
451 #define IV_MAXCOL 16
452
453 static float *iv_data_stack;
454 static float ivcolors[IV_MAXCOL][3];
455 static Object *ivsurf;
456 static ListBase ivbase;
457
458 struct IvNode {
459         struct IvNode *next, *prev;
460         char *nodename;
461         char *fieldname[IV_MAXFIELD];
462         int datalen[IV_MAXFIELD];
463         float *data[IV_MAXFIELD];
464 };
465
466 static int iv_curcol=0;
467
468 static int iv_colornumber(struct IvNode *iv)
469 {
470         float *fp, fr = 0.0, fg = 0.0, fb = 0.0;
471         int a;
472         char *cp;
473         
474         /* search back to last material */
475         while(iv) {
476                 if( strcmp(iv->nodename, "Material")==0) {
477                         fp= iv->data[0];
478                         if(fp==0) fp= iv->data[1];
479                         if(fp) {
480                                 fr= fp[0];
481                                 fg= fp[1];
482                                 fb= fp[2];
483                         }
484                         break;
485                 }
486                 else if( strcmp(iv->nodename, "BaseColor")==0) {
487                         fp= iv->data[0];
488                         fr= fp[0];
489                         fg= fp[1];
490                         fb= fp[2];
491                         break;
492                 }
493                 else if( strcmp(iv->nodename, "PackedColor")==0) {
494                         cp= (char *)iv->data[0];
495                         fr= cp[3]/255.0f;
496                         fg= cp[2]/255.0f;
497                         fb= cp[1]/255.0f;
498                         break;
499                 }
500                 iv= iv->prev;
501                 
502         }
503         if(iv==0) return 0;
504         if(iv->datalen[0]<3) return 0;
505         
506         for(a=0; a<iv_curcol; a++) {
507         
508                 if(ivcolors[a][0]== fr)
509                         if(ivcolors[a][1]== fg)
510                                 if(ivcolors[a][2]== fb) return a+1
511                                 ;
512         }
513         
514         if(a>=IV_MAXCOL) a= IV_MAXCOL-1;
515         iv_curcol= a+1;
516         ivcolors[a][0]= fr;
517         ivcolors[a][1]= fg;
518         ivcolors[a][2]= fb;
519         
520         return iv_curcol;
521 }
522
523 static int iv_finddata(struct IvNode *iv, char *field, int fieldnr)
524 {
525         /* search for "field", count data size and make datablock. return skipdata */
526         float *fp;
527         int len, stackcount, skipdata=0;
528         char *cpa, terminator, str[64];
529         intptr_t i;
530         
531         len= strlen(field);
532
533         cpa= iv->nodename+1;
534         while( *cpa != '}' ) {
535                 
536                 if( *cpa == *field ) {
537                         if( strncmp(cpa, field, len)==0 ) {
538                                 iv->fieldname[fieldnr]= cpa;
539                                 
540                                 /* read until first character */
541                                 cpa+= len;
542                                 skipdata+= len;
543                                 *cpa= 0;
544                                 cpa++;
545                                 skipdata++;
546                                 
547                                 while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) cpa++;
548                                 if( *cpa=='[' ) {
549                                         terminator= ']';
550                                         cpa++;
551                                         skipdata++;
552                                 }
553                                 else terminator= 13;
554                                 
555                                 stackcount= 0;
556                                 fp= iv_data_stack;
557                                 
558                                 while( *cpa!=terminator && *cpa != '}' ) {
559                                         
560                                         /* in fact, isdigit should include the dot and minus */
561                                         if( (isdigit(*cpa) || *cpa=='.' || *cpa=='-') && (isspace(cpa[-1]) || cpa[-1]==0 || cpa[-1]==',') ) {
562                                                 if(cpa[1]=='x') {
563                                                         memcpy(str, cpa, 16);
564                                                         str[16]= 0;
565                                                         
566                                                         sscanf(str, "%x", (int *)fp);
567                                                 }
568                                                 else {
569                                                         /* atof doesn't stop after the first float
570                                                          * in a long string at Windows... so we copy 
571                                                          * the float to a new string then atof... */
572                                                         char *cpa_temp = strpbrk(cpa, ", \n");
573                                                         i = cpa_temp - cpa;
574                                                         
575                                                         if (i>63) *fp= 0.0;
576                                                         else {
577                                                                 memcpy(str, cpa, i);
578                                                                 str[i]=0;
579                                                         
580                                                                 *fp= (float) atof(str);
581                                                         }
582                                                 }
583                                                                                                 
584                                                 stackcount++;
585                                                 if(stackcount>=IV_MAXSTACK) {
586                                                         printf("stackoverflow in IV read\n");
587                                                         break;
588                                                 }
589                                                 fp++;
590                                         }
591                                         cpa++;
592                                         skipdata++;
593                                 }
594                                 
595                                 iv->datalen[fieldnr]= stackcount;
596                                 if(stackcount) {
597                                         iv->data[fieldnr]= MEM_mallocN(sizeof(float)*stackcount, "iv_finddata");
598                                         memcpy(iv->data[fieldnr], iv_data_stack, sizeof(float)*stackcount);
599                                 }
600                                 else iv->data[fieldnr]= 0;
601                                 
602                                 return skipdata;
603                         }
604                 }
605                 cpa++;
606                 skipdata++;
607         }
608         
609         return skipdata;
610 }
611
612 static void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype)
613 {
614         /* write in data: baseadr with offset index (and number nr) */
615         float *fp;
616         int ofs;
617         
618         while(nr--) {
619                 ofs= (int) *index;
620                 fp= baseadr+coordtype*ofs;
621                 VECCOPY(data, fp);
622                 data+= 3;
623                 index++;
624         }
625 }
626
627
628
629 static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
630 {
631         struct IvNode *iv, *ivp, *ivn;
632         char *maindata, *md, *cpa;
633         float *index, *data, *fp;
634         int file, filelen, count, lll, face, nr = 0;
635         int skipdata, ok, a, b, tot, first, colnr, coordtype, polytype, *idata;
636         struct DispList *dl;
637         
638         ivbase.first= ivbase.last= 0;
639         iv_curcol= 0;
640         ivsurf= 0;
641         
642         file= open(str, O_BINARY|O_RDONLY);
643         if(file== -1) {
644                 //XXX error("Can't read file\n");
645                 return;
646         }
647
648         filelen= BLI_filesize(file);
649         if(filelen < 1) {
650                 close(file);
651                 return;
652         }
653         
654         maindata= MEM_mallocN(filelen, "leesInventor");
655         read(file, maindata, filelen);
656         close(file);
657
658         iv_data_stack= MEM_mallocN(sizeof(float)*IV_MAXSTACK, "ivstack");
659
660         /* preprocess: remove comments */
661         md= maindata+20;
662         count= 20;
663         while(count<filelen) {
664                 if( *md=='#' ) {        /* comment */
665                         while( *md!=13 && *md!=10) {    /* enters */
666                                 *md= 32;
667                                 md++;
668                                 count++;
669                                 if(count>=filelen) break;
670                         }
671                 }
672                 md++;
673                 count++;        
674         }
675         
676
677         /* now time to collect: which are the nodes and fields? */
678         md= maindata;
679         count= 0;
680         while(count<filelen) {
681                 if( *md=='{' ) {        /* read back */
682                 
683                         cpa= md-1;
684                         while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) {   /* remove spaces/enters/tab  */
685                                 *cpa= 0;
686                                 cpa--;
687                         }               
688                                 
689                         while( *cpa>32 && *cpa<128) cpa--;
690                         cpa++;
691                         *md= 0;
692                         
693                         ok= 0;
694                         skipdata= 0;
695                         iv= MEM_callocN(sizeof(struct IvNode), "leesInventor");
696                         iv->nodename= cpa;
697
698                         if(strcmp(cpa, "Coordinate3")==0 || strcmp(cpa, "Coordinate4")==0) {
699                                 skipdata= iv_finddata(iv, "point", 0);
700                                 ok= 1;
701                         }
702                         else if(strcmp(cpa, "VertexProperty")==0) {
703                                 skipdata= iv_finddata(iv, "vertex", 0);
704                                 ok= 1;
705                         }
706                         else if(strcmp(cpa, "IndexedLineSet")==0) {
707                                 skipdata= iv_finddata(iv, "coordIndex", 0);
708                                 ok= 1;
709                         }
710                         else if(strcmp(cpa, "IndexedTriangleMesh")==0) {
711                                 skipdata= iv_finddata(iv, "coordIndex", 0);
712                                 ok= 1;
713                         }
714                         else if(strcmp(cpa, "IndexedFaceSet")==0) {
715                                 skipdata= iv_finddata(iv, "coordIndex", 0);
716                                 ok= 1;
717                         }
718                         else if(strcmp(cpa, "FaceSet")==0) {
719                                 skipdata= iv_finddata(iv, "numVertices", 0);
720                                 ok= 1;
721                         }
722                         else if(strcmp(cpa, "Material")==0) {
723                                 iv_finddata(iv, "diffuseColor", 0);
724                                 iv_finddata(iv, "ambientColor", 1);
725                                 ok= 1;
726                         }
727                         else if(strcmp(cpa, "BaseColor")==0) {
728                                 iv_finddata(iv, "rgb", 0);
729                                 ok= 1;
730                         }
731                         else if(strcmp(cpa, "PackedColor")==0) {
732                                 iv_finddata(iv, "rgba", 0);
733                                 ok= 1;
734                         }
735                         else if(strcmp(cpa, "QuadMesh")==0) {
736                                 iv_finddata(iv, "verticesPerColumn", 0);
737                                 iv_finddata(iv, "verticesPerRow", 1);
738                                 
739                                 ok= 1;
740                         }
741                         else if(strcmp(cpa, "IndexedTriangleStripSet")==0) {
742                                 skipdata= iv_finddata(iv, "coordIndex", 0);
743                                 ok= 1;
744                         }
745                         else if(strcmp(cpa, "TriangleStripSet")==0) {
746                                 skipdata= iv_finddata(iv, "numVertices", 0);
747                                 ok= 1;
748                         }
749                         else if(strcmp(cpa, "IndexedNurbsSurface")==0 || strcmp(cpa, "NurbsSurface")==0) {
750                                 iv_finddata(iv, "numUControlPoints", 0);
751                                 iv_finddata(iv, "numVControlPoints", 1);
752                                 iv_finddata(iv, "uKnotVector", 2);
753                                 iv_finddata(iv, "vKnotVector", 3);
754                                 ok= 1;
755                         }
756                         else {
757                                 /* to the end */
758                                 while( *md != '}') {
759                                         md++;
760                                         count++;
761                                         if(count<filelen) break;
762                                 }
763                         }
764                         
765                         
766                         if(ok) {
767                                 BLI_addtail(&ivbase, iv);
768                                 md+= skipdata;
769                                 count+= skipdata;
770                         }
771                         else MEM_freeN(iv);
772                         
773                 }
774                 md++;
775                 count++;
776         }
777         
778         /* join nodes */
779         iv= ivbase.first;
780         
781         while(iv) {
782                 ivn= iv->next;
783                 
784                 if( strncmp(iv->nodename, "Indexed", 7)==0) {
785                         /* seek back: same name? */
786                         
787                         ivp= iv->prev;
788                         while(ivp) {
789                                 if(strcmp(iv->nodename, ivp->nodename)==0) break;
790
791                                 if(strcmp(ivp->nodename, "Coordinate3")==0 || 
792                                    strcmp(ivp->nodename, "Coordinate4")==0 ||
793                                    strcmp(ivp->nodename, "VertexProperty")==0) {
794                                         ivp= 0;
795                                         break;
796                                 }
797                                 ivp= ivp->prev;
798                         }
799                         
800                         if(ivp) {
801                                 /* add iv to ivp */
802                                 
803                                 tot= iv->datalen[0] + ivp->datalen[0];
804                                 if(tot) {
805                                         data= MEM_mallocN(tot*sizeof(float), "samenvoeg iv");
806                                         memcpy(data, ivp->data[0], sizeof(float)*ivp->datalen[0]);
807                                         memcpy(data+ivp->datalen[0], iv->data[0], sizeof(float)*iv->datalen[0]);
808                                         
809                                         ivp->datalen[0]+= iv->datalen[0];
810                                         MEM_freeN(ivp->data[0]);
811                                         ivp->data[0]= data;
812                                         
813                                         BLI_remlink(&ivbase, iv);
814                                         MEM_freeN(iv->data[0]);
815                                         MEM_freeN(iv);
816                                 }
817                         }
818                 }
819                 
820                 iv= ivn;
821         }
822
823         
824         /* convert Nodes to DispLists */
825         iv= ivbase.first;
826         while(iv) {
827                 
828                 /* printf(" Node: %s\n", iv->nodename); */
829                 /* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */
830                 coordtype= 3;
831                 
832                 if( strcmp(iv->nodename, "IndexedLineSet")==0 ) {
833                         
834                         colnr= iv_colornumber(iv);
835
836                         /* seek back to data */
837                         ivp= iv;
838                         while(ivp->prev) {
839                                 ivp= ivp->prev;
840                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
841                                         coordtype= 3;
842                                         break;
843                                 }
844                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
845                                         coordtype= 4;
846                                         break;
847                                 }
848                         }
849                         if(ivp) {
850                         
851                                 /* count the nr of lines */
852                                 tot= 0;
853                                 index= iv->data[0];
854                                 lll = iv->datalen[0]-1;
855                                 for(a=0; a<lll; a++) {
856                                         if(index[0]!= -1 && index[1]!= -1) tot++;
857                                         index++;
858                                 }
859                                 
860                                 tot*= 2;        /* nr of vertices */
861                                 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor1");
862                                 BLI_addtail(listb, dl);
863                                 dl->type= DL_SEGM;
864                                 dl->nr= 2;
865                                 dl->parts= tot/2;
866                                 dl->col= colnr;
867                                 data= (float *)(dl+1);
868                                 
869                                 index= iv->data[0];
870                                 for(a=0; a<lll; a++) {
871                                         if(index[0]!= -1 && index[1]!= -1) {
872                                                 read_iv_index(data, ivp->data[0], index, 2, coordtype);
873                                                 data+= 6;
874                                         }
875                                         index++;
876                                 }
877                         }
878                 }
879                 else if( strcmp(iv->nodename, "FaceSet")==0 ) {
880                         
881                         colnr= iv_colornumber(iv);
882                 
883                         /* seek back to data */
884                         ivp= iv;
885                         while(ivp->prev) {
886                                 ivp= ivp->prev;
887                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
888                                         coordtype= 3;
889                                         break;
890                                 }
891                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
892                                         coordtype= 4;
893                                         break;
894                                 }
895                         }
896                         
897                         if(ivp) {
898                                 /* count triangles */
899                                 tot= 0;
900                                 
901                                 index= iv->data[0];
902                                 polytype= (int) index[0];
903                                 
904                                 for(a=0; a<iv->datalen[0]; a++) {
905                                         if(index[0]== polytype) tot++;  /* one kind? */
906                                         index++;
907                                 }
908                                 
909                                 
910                                 tot*= polytype;         /* nr of vertices */
911                                 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor4");
912                                 BLI_addtail(listb, dl);
913                                 dl->type= DL_POLY;
914                                 dl->nr= polytype;
915                                 dl->parts= tot/polytype;
916                                 dl->col= colnr;
917                                 data= (float *)(dl+1);
918
919                                 index= ivp->data[0];
920                                 first= 1;
921                                 for(a=0; a<iv->datalen[0]; a++) {
922                                         
923                                         VECCOPY(data, index);
924                                         data+= 3;
925                                         index+= 3;
926
927                                         VECCOPY(data, index);
928                                         data+= 3;
929                                         index+= 3;
930
931                                         VECCOPY(data, index);
932                                         data+= 3;
933                                         index+= 3;
934
935                                         if(polytype==4) {
936                                                 VECCOPY(data, index);
937                                                 data+= 3;
938                                                 index+= 3;
939                                         }
940                                 }
941                         }
942                 }
943                 else if( strcmp(iv->nodename, "TriangleStripSet")==0 ) {
944                         
945                         colnr= iv_colornumber(iv);
946                 
947                         /* seek back to data */
948                         ivp= iv;
949                         while(ivp->prev) {
950                                 ivp= ivp->prev;
951                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
952                                         coordtype= 3;
953                                         break;
954                                 }
955                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
956                                         coordtype= 4;
957                                         break;
958                                 }
959                         }
960                         
961                         if(ivp) {
962                                 /* count triangles */
963                                 tot= 0;
964                                 face= 0;
965                                 
966                                 index= iv->data[0];             /* strip size */ 
967                                 
968                                 for(a=0; a<iv->datalen[0]; a++) {
969                                         tot+= (int) index[0];
970                                         face+= ((int) index[0]) - 2;
971                                         index++;
972                                 }
973                                 
974                                 dl= MEM_callocN(sizeof(struct DispList), "leesInventor4");
975                                 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
976                                 dl->index= MEM_callocN( face*3*sizeof(int), "dl index");
977                                 
978                                 dl->type= DL_INDEX3;
979                                 dl->nr= tot;
980                                 dl->parts= face;
981
982                                 BLI_addtail(listb, dl);
983                                 dl->col= colnr;
984
985                                 index= iv->data[0];             /* strip size */ 
986                                 fp= ivp->data[0];               /* vertices */
987                                 data= dl->verts;
988                                 idata= dl->index;
989                                 first= 0;
990                                 
991                                 for(a=0; a<iv->datalen[0]; a++) {
992                                         
993                                         /* vertices */
994                                         for(b=0; b<index[0]; b++) {
995                                                 VECCOPY(data, fp);
996                                                 data+= 3; 
997                                                 fp+= coordtype;
998                                         }
999                                                 
1000                                         /* indices */
1001                                         lll = index[0] - 2;
1002                                         for(b=0; b<lll; b++) {
1003                                                 idata[0]= first;
1004                                                 idata[1]= first+1;
1005                                                 idata[2]= first+2;
1006                                                 first++;
1007                                                 idata+= 3;
1008                                         }
1009                                         first+= 2;
1010                                         
1011                                         index++;
1012                                 }
1013                         }
1014                 }
1015                 else if( strcmp(iv->nodename, "IndexedFaceSet")==0 ) {
1016                         
1017                         colnr= iv_colornumber(iv);
1018                 
1019                         /* seek back to data */
1020                         ivp= iv;
1021                         while(ivp->prev) {
1022                                 ivp= ivp->prev;
1023                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1024                                         coordtype= 3;
1025                                         break;
1026                                 }
1027                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1028                                         coordtype= 4;
1029                                         break;
1030                                 }
1031                         }
1032                         if(ivp) {
1033                         
1034                                 /* count triangles */
1035                                 face= 0;
1036                                 index= iv->data[0];
1037                 lll = iv->datalen[0]-2;
1038                                 for(a=0; a<lll; a++) {
1039                                         if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1040                                         index++;
1041                                 }
1042
1043                                 /*number of vertices */
1044                                 tot= ivp->datalen[0]/coordtype;
1045
1046                                 if(tot) {
1047                                         dl= MEM_callocN(sizeof(struct DispList), "leesInventor5");
1048                                         BLI_addtail(listb, dl);
1049                                         dl->type= DL_INDEX3;
1050                                         dl->nr= tot;
1051                                         dl->parts= face;
1052                                         dl->col= colnr;
1053         
1054                                         dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1055                                         dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1056         
1057                                         /* vertices */
1058                                         fp= ivp->data[0];
1059                                         data= dl->verts;
1060                                         for(b=tot; b>0; b--) {
1061                                                 VECCOPY(data, fp);
1062                                                 data+= 3; 
1063                                                 fp+= coordtype;
1064                                         }
1065                                         
1066                                         /* indices */
1067                                         index= iv->data[0];
1068                                         idata= dl->index;
1069                                         first= 1;
1070                                         lll=iv->datalen[0]-2;
1071                                         for(a=0; a<lll; a++) {
1072                                                 
1073                                                 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1074         
1075                                                         /* this trick is to fill poly's with more than 3 vertices correctly */
1076                                                         if(first) {
1077                                                                 nr= (int) index[0];
1078                                                                 first= 0;
1079                                                         }
1080                                                         idata[0]= nr;
1081                                                         idata[1]= (int) index[1];
1082                                                         idata[2]= (int) index[2];
1083                                                         idata+= 3;
1084                                                 }
1085                                                 else first= 1;
1086                                                 
1087                                                 index++;
1088                                         }
1089                                 }
1090                         }
1091                 }
1092                 else if( strcmp(iv->nodename, "IndexedTriangleMesh")==0 || 
1093                                  strcmp(iv->nodename, "IndexedTriangleStripSet")==0 ) {
1094                         
1095                         colnr= iv_colornumber(iv);
1096                 
1097                         /* seek back to data */
1098                         ivp= iv;
1099                         while(ivp->prev) {
1100                                 ivp= ivp->prev;
1101                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1102                                         coordtype= 3;
1103                                         break;
1104                                 }
1105                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1106                                         coordtype= 4;
1107                                         break;
1108                                 }
1109                         }
1110                         if(ivp) {
1111                         
1112                                 /* count triangles */
1113                                 face= 0;
1114                                 index= iv->data[0];
1115                                 lll=iv->datalen[0]-2;
1116                                 for(a=0; a<lll; a++) {
1117                                         if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1118                                         index++;
1119                                 }
1120                                 
1121                                 /* nr of vertices */
1122                                 tot= ivp->datalen[0]/coordtype;
1123                                 
1124                                 dl= MEM_callocN(sizeof(struct DispList), "leesInventor6");
1125                                 BLI_addtail(listb, dl);
1126                                 dl->type= DL_INDEX3;
1127                                 dl->nr= tot;
1128                                 dl->parts= face;
1129                                 dl->col= colnr;
1130                                 
1131                                 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1132                                 dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1133
1134                                 /* vertices */
1135                                 fp= ivp->data[0];
1136                                 data= dl->verts;
1137                                 for(b=tot; b>0; b--) {
1138                                         VECCOPY(data, fp);
1139                                         data+= 3; 
1140                                         fp+= coordtype;
1141                                 }
1142                                 
1143                                 /* indices */
1144                                 index= iv->data[0];
1145                                 idata= dl->index;
1146                                 
1147                                 lll=iv->datalen[0]-2;
1148                                 for(a=lll; a>0; a--) {
1149                                 
1150                                         if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1151                                                 idata[0]= (int) index[0];
1152                                                 idata[1]= (int) index[1];
1153                                                 idata[2]= (int) index[2];
1154                                                 idata+= 3;
1155                                         }
1156                                         index++;
1157                                 }
1158                         }
1159                 }
1160                 else if( strcmp(iv->nodename, "QuadMesh")==0 ) {
1161                         
1162                         colnr= iv_colornumber(iv);
1163                 
1164                         /* seek back to data */
1165                         ivp= iv;
1166                         while(ivp->prev) {
1167                                 ivp= ivp->prev;
1168                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1169                                         coordtype= 3;
1170                                         break;
1171                                 }
1172                                 if( strcmp(ivp->nodename, "VertexProperty")==0 ) {
1173                                         coordtype= 3;
1174                                         break;
1175                                 }
1176                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1177                                         coordtype= 4;
1178                                         break;
1179                                 }
1180                         }
1181                         
1182                         if(ivp) {
1183                                 tot= (int) (floor(*(iv->data[0])+0.5) * floor(*(iv->data[1])+0.5));
1184
1185                                 if(tot>0) {
1186                                         dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor8");
1187                                         BLI_addtail(listb, dl);
1188                                         dl->type= DL_SURF;
1189                                         dl->parts= (int) floor(*(iv->data[0])+0.5);
1190                                         dl->nr= (int) floor(*(iv->data[1])+0.5);
1191                                         dl->col= colnr;
1192                                         data= (float *)(dl+1);
1193                                         memcpy(data, ivp->data[0], tot*3*sizeof(float));
1194                                 }
1195                         }
1196                 }
1197                 else if(strcmp(iv->nodename, "IndexedNurbsSurface")==0 || strcmp(iv->nodename, "NurbsSurface")==0) {
1198                         
1199                         colnr= iv_colornumber(iv);
1200                 
1201                         /* sek back to data */
1202                         ivp= iv;
1203                         while(ivp->prev) {
1204                                 ivp= ivp->prev;
1205                                 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1206                                         coordtype= 3;
1207                                         break;
1208                                 }
1209                                 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1210                                         coordtype= 4;
1211                                         break;
1212                                 }
1213                         }
1214                         if(ivp) {
1215                                 a= (int) *(iv->data[0]);
1216                                 b= (int) *(iv->data[1]);
1217                                 
1218                                 tot= a*b;
1219
1220                                 if( (a>=4 || b>=4) && tot>6) {
1221                                         Object *ob;
1222                                         Curve *cu;
1223                                         Nurb *nu;
1224                                         BPoint *bp;
1225                                         
1226                                         if(ivsurf==0) {
1227                                                 ob= add_object(scene, OB_SURF);
1228                                                 ivsurf= ob;
1229                                         }
1230                                         else ob= ivsurf;
1231                                         cu= ob->data;
1232                                         nu = (Nurb*) MEM_callocN(sizeof(Nurb),"addNurbprim") ;
1233                                         BLI_addtail(&cu->nurb, nu);
1234                                         nu->type= CU_NURBS;
1235
1236                                         nu->pntsu= a;
1237                                         nu->pntsv= b;
1238                                         nu->resolu= 2*a;
1239                                         nu->resolv= 2*b;
1240
1241                                         nu->flagu= 0;
1242                                         nu->flagv= 0;
1243                                         
1244                                         nu->bp = bp =
1245                                                 (BPoint*)MEM_callocN(tot * sizeof(BPoint), "addNurbprim3");
1246                                         a= tot;
1247                                         data= ivp->data[0];
1248                                         while(a--) {
1249                                                 VECCOPY(bp->vec, data);
1250                                                 if(coordtype==4) {
1251                                                         bp->vec[3]= data[3];
1252                                                         VecMulf(bp->vec, 1.0f/data[3]);
1253                                                 }
1254                                                 else bp->vec[3]= 1.0;
1255                                                 data+= coordtype;
1256                                                 bp++;
1257                                         }
1258                                         
1259                                         /* iv->datalen[2] / [3] is number of knots */
1260                                         nu->orderu= iv->datalen[2] - nu->pntsu;
1261                                         nu->orderv= iv->datalen[3] - nu->pntsv;
1262                                         
1263                                         nu->knotsu= MEM_mallocN( sizeof(float)*(iv->datalen[2]), "knots");
1264                                         memcpy(nu->knotsu, iv->data[2], sizeof(float)*(iv->datalen[2]));
1265                                         nu->knotsv= MEM_mallocN( sizeof(float)*(iv->datalen[3]), "knots");
1266                                         memcpy(nu->knotsv, iv->data[3], sizeof(float)*(iv->datalen[3]));                                        
1267
1268                                         switchdirectionNurb(nu);
1269
1270                                 }
1271                                 else {
1272                                         dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor3");
1273                                         BLI_addtail(listb, dl);
1274                                         dl->type= DL_SURF;
1275                                         dl->nr= (int) *(iv->data[0]);
1276                                         dl->parts= (int) *(iv->data[1]);
1277                                         dl->col= colnr;
1278                                         data= (float *)(dl+1);
1279                                         
1280                                         a= tot;
1281                                         fp= ivp->data[0];
1282                                         while(a--) {
1283                                                 VECCOPY(data, fp);
1284                                                 fp+= coordtype;
1285                                                 data+= 3;
1286                                         }
1287                                 }
1288                         }
1289                 }
1290                 iv= iv->next;
1291         }
1292
1293         /* free */
1294         iv= ivbase.first;
1295         while(iv) {
1296                 for(a=0; a<IV_MAXFIELD; a++) {
1297                         if(iv->data[a]) MEM_freeN(iv->data[a]);
1298                 }
1299                 iv= iv->next;
1300         }
1301
1302         BLI_freelistN(&ivbase);
1303         MEM_freeN(maindata);
1304         MEM_freeN(iv_data_stack);
1305         
1306 }
1307
1308 /* ************************************************************ */
1309
1310 static void displist_to_mesh(Scene *scene, DispList *dlfirst)
1311 {
1312         Object *ob;
1313         Mesh *me;
1314         Material *ma;
1315         DispList *dl;
1316         MVert *mvert;
1317         MFace *mface;
1318         float *data, vec[3], min[3], max[3];
1319         int a, b, startve, *idata, totedge=0, tottria=0, totquad=0, totvert=0, totface, totcol=0, colnr;
1320         int p1, p2, p3, p4;
1321         unsigned int maxvertidx;
1322
1323         /* count first */
1324         INIT_MINMAX(min, max);
1325
1326         dl= dlfirst;
1327         while(dl) {
1328         
1329                 /* PATCH 1 (polyfill) can't be done, there's no listbase here. do that first! */
1330                 /* PATCH 2 */
1331                 if(dl->type==DL_SEGM && dl->nr>2) {
1332                         data= (float *)(dl+1);
1333                         if(data[0]==data[3*(dl->nr-1)]) {
1334                                 if(data[1]==data[3*(dl->nr-1)+1]) {
1335                                         if(data[2]==data[3*(dl->nr-1)+2]) {
1336                                                 dl->type= DL_POLY;
1337                                                 dl->nr--;
1338                                         }
1339                                 }
1340                         }
1341                 }
1342                 
1343                 /* colors */
1344                 if(dl->col > totcol) totcol= dl->col;
1345                 
1346                 /* size and count */
1347                 if(dl->type==DL_SURF) {
1348                         a= dl->nr;
1349                         b= dl->parts;
1350                         if(dl->flag & DL_CYCL_U) a++;
1351                         if(dl->flag & DL_CYCL_V) b++;
1352                         
1353                         totquad+= a*b;
1354
1355                         totvert+= dl->nr*dl->parts;
1356
1357                         data= (float *)(dl+1);
1358                         for(a= dl->nr*dl->parts; a>0; a--) {
1359                                 DO_MINMAX(data, min, max);
1360                                 data+= 3;
1361                         }
1362                 }
1363                 else if(dl->type==DL_POLY) {
1364                         if(dl->nr==3 || dl->nr==4) {
1365                                 if(dl->nr==3) tottria+= dl->parts;
1366                                 else totquad+= dl->parts;
1367                                 
1368                                 totvert+= dl->nr*dl->parts;
1369
1370                                 data= (float *)(dl+1);
1371                                 for(a= dl->nr*dl->parts; a>0; a--) {
1372                                         DO_MINMAX(data, min, max);
1373                                         data+= 3;
1374                                 }
1375                         }
1376                         else if(dl->nr>4) {
1377                                 
1378                                 tottria+= dl->nr*dl->parts;
1379                                 totvert+= dl->nr*dl->parts;
1380                                 
1381                                 data= (float *)(dl+1);
1382                                 for(a= dl->nr*dl->parts; a>0; a--) {
1383                                         DO_MINMAX(data, min, max);
1384                                         data+= 3;
1385                                 }
1386                                 
1387                         }
1388                 }
1389                 else if(dl->type==DL_INDEX3) {
1390                         tottria+= dl->parts;
1391                         totvert+= dl->nr;
1392                         
1393                         data= dl->verts;
1394                         for(a= dl->nr; a>0; a--) {
1395                                 DO_MINMAX(data, min, max);
1396                                 data+= 3;
1397                         }
1398                 }
1399                 else if(dl->type==DL_SEGM) {
1400                         
1401                         tottria+= (dl->nr-1)*dl->parts;
1402                         totvert+= dl->nr*dl->parts;
1403                         
1404                         data= (float *)(dl+1);
1405                         for(a= dl->nr*dl->parts; a>0; a--) {
1406                                 DO_MINMAX(data, min, max);
1407                                 data+= 3;
1408                         }
1409                 }
1410
1411                 dl= dl->next;
1412         }
1413
1414         if(totvert==0) {
1415                 return;
1416         }
1417         
1418         vec[0]= (min[0]+max[0])/2;
1419         vec[1]= (min[1]+max[1])/2;
1420         vec[2]= (min[2]+max[2])/2;
1421
1422         ob= add_object(scene, OB_MESH);
1423         VECCOPY(ob->loc, vec);
1424         where_is_object(scene, ob);
1425
1426         me= ob->data;
1427         
1428         /* colors */
1429         if(totcol) {
1430                 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
1431                 ob->matbits= MEM_callocN(sizeof(char)*totcol, "ob->matbits");
1432                 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
1433                 me->totcol= totcol;
1434                 ob->totcol= (unsigned char) me->totcol;
1435                 ob->actcol= 1;
1436         }
1437         
1438         /* materials */
1439         for(a=0; a<totcol; a++) {
1440                 ma= G.main->mat.first;
1441                 while(ma) {
1442                         if(ma->mtex[0]==0) {
1443                                 if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
1444                                         me->mat[a]= ma;
1445                                         ma->id.us++;
1446                                         break;
1447                                 }
1448                         }
1449                         ma= ma->id.next;
1450                 }
1451                 if(ma==0) {
1452                         ma= add_material("ext");
1453                         me->mat[a]= ma;
1454                         ma->r= ivcolors[a][0];
1455                         ma->g= ivcolors[a][1];
1456                         ma->b= ivcolors[a][2];
1457                         automatname(ma);
1458                 }
1459         }
1460         
1461         totface= totquad+tottria+totedge;
1462
1463         printf("Import: %d vertices %d faces\n", totvert, totface);
1464         
1465         me->totvert= totvert;
1466         me->totface= totface;
1467         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
1468                                         NULL, me->totvert);
1469         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
1470                                         NULL, me->totface);
1471         maxvertidx= totvert-1;
1472         
1473         mvert= me->mvert;
1474         mface= me->mface;
1475
1476         startve= 0;
1477
1478         dl= dlfirst;
1479         while(dl) {
1480                 
1481                 colnr= dl->col;
1482                 if(colnr) colnr--;
1483                 
1484                 if(dl->type==DL_SURF) {
1485                         data= (float *)(dl+1);
1486
1487                         for(a=dl->parts*dl->nr; a>0; a--) {
1488                                 mvert->co[0]= data[0] -vec[0];
1489                                 mvert->co[1]= data[1] -vec[1];
1490                                 mvert->co[2]= data[2] -vec[2];
1491                                 
1492                                 data+=3;
1493                                 mvert++;
1494                         }
1495
1496                         for(a=0; a<dl->parts; a++) {
1497                                 
1498                                 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
1499                                         break;
1500                                 
1501                                 p1+= startve; 
1502                                 p2+= startve; 
1503                                 p3+= startve; 
1504                                 p4+= startve;
1505
1506                                 for(; b<dl->nr; b++) {
1507                                 
1508                                         mface->v1= p1;
1509                                         mface->v2= p2;
1510                                         mface->v3= p4;
1511                                         mface->v4= p3;
1512                                         
1513                                         mface->mat_nr= colnr;
1514                                         test_index_face(mface, NULL, 0, 4);
1515                                         
1516                                         mface++;
1517                                         
1518                                         p4= p3; 
1519                                         p3++;
1520                                         p2= p1; 
1521                                         p1++;
1522                                 }
1523                         }
1524                         
1525                         startve += dl->parts*dl->nr;
1526
1527                 }
1528                 else if(dl->type==DL_POLY) {
1529                 
1530                         if(dl->nr==3 || dl->nr==4) {
1531                                 data= (float *)(dl+1);
1532
1533                                 for(a=dl->parts*dl->nr; a>0; a--) {
1534                                         mvert->co[0]= data[0] -vec[0];
1535                                         mvert->co[1]= data[1] -vec[1];
1536                                         mvert->co[2]= data[2] -vec[2];
1537                                         data+=3;
1538                                         mvert++;
1539                                 }
1540
1541                                 for(a=0; a<dl->parts; a++) {
1542                                         if(dl->nr==3) {
1543                                                 mface->v1= startve+a*dl->nr;
1544                                                 mface->v2= startve+a*dl->nr+1;
1545                                                 mface->v3= startve+a*dl->nr+2;
1546                                                 mface->mat_nr= colnr;
1547                                                 test_index_face(mface, NULL, 0, 3);
1548                                                 mface++;
1549                                         }
1550                                         else {
1551                                                 mface->v1= startve+a*dl->nr;
1552                                                 mface->v2= startve+a*dl->nr+1;
1553                                                 mface->v3= startve+a*dl->nr+2;
1554                                                 mface->v4= startve+a*dl->nr+3;
1555                                                 mface->mat_nr= colnr;
1556                                                 test_index_face(mface, NULL, 0, 4);
1557                                                 mface++;
1558                                         }
1559                                 }
1560                                 startve += dl->parts*dl->nr;
1561                         }
1562                         else if(dl->nr>4) {
1563                                 data= (float *)(dl+1);
1564
1565                                 for(a=dl->parts*dl->nr; a>0; a--) {
1566                                         mvert->co[0]= data[0] -vec[0];
1567                                         mvert->co[1]= data[1] -vec[1];
1568                                         mvert->co[2]= data[2] -vec[2];
1569                                         
1570                                         data+=3;
1571                                         mvert++;
1572                                 }
1573
1574                                 for(b=0; b<dl->parts; b++) {
1575                                         for(a=0; a<dl->nr; a++) {
1576                                                 mface->v1= startve+a;
1577                                                 
1578                                                 if(a==dl->nr-1) mface->v2= startve;
1579                                                 else mface->v2= startve+a+1;
1580                                                 
1581                                                 mface->mat_nr= colnr;
1582
1583                                                 mface++;
1584                                         }
1585                                         startve += dl->nr;
1586                                 }
1587                         }
1588                 }
1589                 else if(dl->type==DL_INDEX3) {
1590                         data= dl->verts;
1591                         
1592                         for(a=dl->nr; a>0; a--) {
1593                                 mvert->co[0]= data[0] -vec[0];
1594                                 mvert->co[1]= data[1] -vec[1];
1595                                 mvert->co[2]= data[2] -vec[2];
1596                                 data+=3;
1597                                 mvert++;
1598                         }
1599
1600                         idata= dl->index;
1601                         for(b=dl->parts; b>0; b--) {
1602                                 mface->v1= startve+idata[0];
1603                                 mface->v2= startve+idata[1];
1604                                 mface->v3= startve+idata[2];
1605                                 mface->mat_nr= colnr;
1606                                 
1607                                 if (mface->v1>maxvertidx) mface->v1= maxvertidx;
1608                                 if (mface->v2>maxvertidx) mface->v2= maxvertidx;
1609                                 if (mface->v3>maxvertidx) mface->v3= maxvertidx;
1610
1611                                 test_index_face(mface, NULL, 0, 3);
1612                                 mface++;
1613                                 idata+= 3;
1614                         }
1615                         startve += dl->nr;
1616                 }
1617                 else if(dl->type==DL_SEGM) {
1618                         data= (float *)(dl+1);
1619
1620                         for(a=dl->parts*dl->nr; a>0; a--) {
1621                                 mvert->co[0]= data[0] -vec[0];
1622                                 mvert->co[1]= data[1] -vec[1];
1623                                 mvert->co[2]= data[2] -vec[2];
1624                                 data+=3;
1625                                 mvert++;
1626                         }
1627
1628                         for(b=0; b<dl->parts; b++) {
1629                                 for(a=0; a<dl->nr-1; a++) {
1630                                         mface->v1= startve+a;
1631                                         mface->v2= startve+a+1;
1632                                         mface->mat_nr= colnr;
1633                                         mface++;
1634                                 }
1635                                 startve += dl->nr;
1636                         }
1637                 }
1638                 dl= dl->next;
1639         }
1640
1641         mesh_add_normals_flags(me);
1642         make_edges(me, 0);
1643 }
1644
1645 static void displist_to_objects(Scene *scene, ListBase *lbase)
1646 {
1647         DispList *dl, *first, *prev, *next;
1648         ListBase tempbase;
1649         int maxaantal, curcol, totvert=0, vert;
1650         
1651         /* irst this: is still active */
1652         if(ivsurf) {
1653                 where_is_object(scene, ivsurf);
1654 // XXX          docenter_new();
1655         }
1656
1657         dl= lbase->first;
1658         while(dl) {
1659                 next= dl->next;
1660                 
1661                 /* PATCH 1: polyfill */
1662                 if(dl->type==DL_POLY && dl->nr>4) {
1663                         /* solution: put them together in separate listbase */
1664                         ;
1665                 }
1666                 /* PATCH 2: poly's of 2 points */
1667                 if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
1668                 
1669                 dl= next;
1670         }
1671
1672         /* count vertices */
1673
1674         dl= lbase->first;
1675         while(dl) {
1676
1677                 if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
1678                 else if(dl->type==DL_POLY) {
1679                         if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
1680                         else if(dl->nr>4) totvert+= dl->nr*dl->parts;
1681                 }
1682                 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1683                 else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
1684
1685                 dl= dl->next;
1686         }
1687
1688         if(totvert==0) {
1689                 
1690                 if(ivsurf==0) ; //XXX error("Found no data");
1691                 if(lbase->first) BLI_freelistN(lbase);
1692                 
1693                 return;
1694         }
1695
1696         maxaantal= 32000;
1697         
1698         if(totvert>maxaantal) {
1699         
1700                 /* try to put colors together */
1701                 curcol= 0;
1702                 tempbase.first= tempbase.last= 0;
1703
1704                 while(lbase->first) {
1705                         dl= lbase->first;
1706                         while(dl) {
1707                                 next= dl->next;
1708                                 if(dl->col==curcol) {
1709                                         BLI_remlink(lbase, dl);
1710                                         BLI_addtail(&tempbase, dl);
1711                                         dl->col= 0;
1712                                 }
1713                                 
1714                                 dl= next;
1715                         }
1716                         
1717                         /* in tempbase are all 'curcol' */
1718                         totvert= 0;
1719                         dl= first= tempbase.first;
1720                         while(dl) {
1721                                 vert= 0;
1722                                 
1723                                 if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
1724                                 else if(dl->type==DL_POLY) {
1725                                         if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
1726                                         else if(dl->nr>4) vert= dl->nr*dl->parts;
1727                                 }
1728                                 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1729                                 else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
1730                                 
1731                                 totvert+= vert;
1732                                 if(totvert > maxaantal || dl->next==0) {
1733                                         if(dl->next==0) {
1734                                                 displist_to_mesh(scene, first);
1735                                         }
1736                                         else if(dl->prev) {
1737                                                 prev= dl->prev;
1738                                                 prev->next= 0;
1739                                                 displist_to_mesh(scene, first);
1740                                                 prev->next= dl;
1741                                                 first= dl;
1742                                                 totvert= 0;
1743                                         }
1744                                 }
1745                                 
1746                                 dl= dl->next;
1747                         }
1748                         
1749                         freedisplist(&tempbase);
1750                         
1751                         curcol++;
1752                 }
1753         }
1754         else displist_to_mesh(scene, lbase->first);
1755
1756         freedisplist(lbase);
1757
1758 }
1759
1760 int BKE_read_exotic(Scene *scene, char *name)
1761 {
1762         ListBase lbase={0, 0};
1763         int len;
1764         gzFile gzfile;
1765         char str[32];
1766         int *s0 = (int*) str;
1767         int retval = 0;
1768
1769         // make sure we're not trying to read a directory....
1770
1771         len= strlen(name);
1772         if (name[len-1] !='/' && name[len-1] != '\\') {
1773                 gzfile = gzopen(name,"rb");
1774
1775                 if (NULL == gzfile ) {
1776                         //XXX error("Can't open file: %s", name);
1777                         retval= -1;
1778                 } else {
1779                         gzread(gzfile, str, 31);
1780                         gzclose(gzfile);
1781
1782                         if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
1783
1784                                 //XXX waitcursor(1);
1785                                 if(strncmp(str, "#Inventor V1.0", 14)==0) {
1786                                         if( strncmp(str+15, "ascii", 5)==0) {
1787                                                 read_inventor(scene, name, &lbase);
1788                                                 displist_to_objects(scene, &lbase);                             
1789                                                 retval = 1;
1790                                         } else {
1791                                                 //XXX error("Can only read Inventor 1.0 ascii");
1792                                         }
1793                                 }
1794                                 else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
1795                                         read_inventor(scene, name, &lbase);
1796                                         displist_to_objects(scene, &lbase);                             
1797                                         retval = 1;
1798                                 }
1799                                 else if(is_dxf(name)) {
1800                                         dxf_read(scene, name);
1801                                         retval = 1;
1802                                 }
1803                                 else if(is_stl(name)) {
1804                                         if (is_stl_ascii(name))
1805                                                 read_stl_mesh_ascii(scene, name);
1806                                         else
1807                                                 read_stl_mesh_binary(scene, name);
1808                                         retval = 1;
1809                                 }
1810 #ifndef DISABLE_PYTHON
1811                                 // TODO: this should not be in the kernel...
1812                                 else { // unknown format, call Python importloader 
1813                                         if (BPY_call_importloader(name)) {
1814                                                 retval = 1;
1815                                         } else {        
1816                                                 //XXX error("Unknown file type or error, check console");
1817                                         }       
1818                                 
1819                                 }
1820 #endif /* DISABLE_PYTHON */
1821                                 //XXX waitcursor(0);
1822                         }
1823                 }
1824         }
1825         
1826         return (retval);
1827 }
1828
1829
1830 /* ************************ WRITE ************************** */
1831
1832
1833 char temp_dir[160]= {0, 0};
1834
1835 static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
1836 {
1837         float vert[3];
1838
1839         VECCOPY(vert, verts[(index)].co);
1840         Mat4MulVecfl(ob->obmat, vert);
1841
1842         if (ENDIAN_ORDER==B_ENDIAN) {
1843                 SWITCH_INT(vert[0]);
1844                 SWITCH_INT(vert[1]);
1845                 SWITCH_INT(vert[2]);
1846         }
1847
1848         fwrite(vert, sizeof(float), 3, fpSTL);
1849 }
1850
1851 static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
1852 {
1853         MVert *mvert = dm->getVertArray(dm);
1854         MFace *mface = dm->getFaceArray(dm);
1855         int i, numfacets = 0, totface = dm->getNumFaces(dm);
1856         float zero[3] = {0.0f, 0.0f, 0.0f};
1857
1858         for (i=0; i<totface; i++, mface++) {
1859                 fwrite(zero, sizeof(float), 3, fpSTL);
1860                 write_vert_stl(ob, mvert, mface->v1, fpSTL);
1861                 write_vert_stl(ob, mvert, mface->v2, fpSTL);
1862                 write_vert_stl(ob, mvert, mface->v3, fpSTL);
1863                 fprintf(fpSTL, "  ");
1864                 numfacets++;
1865
1866                 if(mface->v4) { /* quad = 2 tri's */
1867                         fwrite(zero, sizeof(float), 3, fpSTL);
1868                         write_vert_stl(ob, mvert, mface->v1, fpSTL);
1869                         write_vert_stl(ob, mvert, mface->v3, fpSTL);
1870                         write_vert_stl(ob, mvert, mface->v4, fpSTL);
1871                         fprintf(fpSTL, "  ");
1872                         numfacets++;
1873                 }
1874         }
1875
1876         return numfacets;
1877 }
1878
1879 static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob, Mesh *me)
1880 {
1881         int  numfacets = 0;
1882         DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
1883
1884         numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
1885
1886         dm->release(dm);
1887
1888         return numfacets;
1889 }
1890
1891 void write_stl(Scene *scene, char *str)
1892 {
1893         Object *ob;
1894         Mesh   *me;
1895         Base   *base;
1896         FILE   *fpSTL;
1897         int    numfacets = 0;
1898         
1899         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
1900         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
1901         if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
1902
1903         if (!during_script()) {
1904                 if (BLI_exists(str))
1905                         ; //XXX if(saveover(str)==0)
1906                         //XXX   return;
1907         }
1908
1909         fpSTL= fopen(str, "wb");
1910         
1911         if(fpSTL==NULL) {
1912                 if (!during_script()) ; //XXX error("Can't write file");
1913                 return;
1914         }
1915         strcpy(temp_dir, str);
1916         
1917         //XXX waitcursor(1);
1918         
1919         /* The header part of the STL */
1920         /* First 80 characters are a title or whatever you want.
1921            Lets make the first 32 of those spam and the rest the filename.
1922            Those first 80 characters will be followed by 4 bytes
1923            which will be overwritten later with an integer holding
1924            how many facets are written (we set them to ' ' for now).
1925         */
1926         fprintf(fpSTL, "Binary STL output from Blender: %-48.48s    ", str);
1927
1928         /* Write all selected mesh objects */
1929         base= scene->base.first;
1930         while(base) {
1931                 if (base->flag & SELECT) {
1932                         ob = base->object;
1933                         if (ob->type == OB_MESH) {
1934                                 me = ob->data;
1935                                 if (me)
1936                                         numfacets += write_object_stl(fpSTL, scene, ob, me);
1937                         }
1938                 }
1939                 base= base->next;
1940         }
1941
1942         /* time to write the number of facets in the 4 bytes
1943            starting at byte 81
1944         */
1945         fseek(fpSTL, 80, SEEK_SET);
1946
1947         if (ENDIAN_ORDER==B_ENDIAN) {
1948                 SWITCH_INT(numfacets);
1949         }
1950         fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
1951
1952         fclose(fpSTL);
1953         
1954         //XXX waitcursor(0);
1955 }
1956
1957 /* ******************************* WRITE VRML ***************************** */
1958
1959 static void replace_chars(char *str1, char *str2)
1960 {
1961         int a= strlen(str2);
1962         
1963         str1[a]= 0;
1964         while(a--) {
1965                 if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
1966                 else str1[a]= str2[a];
1967         }
1968 }
1969
1970
1971 static void write_material_vrml(FILE *fp, Material *ma)
1972 {
1973         char str[32];
1974         
1975         replace_chars(str, ma->id.name+2);
1976         
1977         fprintf(fp, "\tDEF %s\n", str);
1978         fprintf(fp, "\tMaterial {\n");
1979         
1980         fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
1981         fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
1982         fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
1983         fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
1984         
1985         fprintf(fp, "\t}\n");
1986         
1987 }
1988
1989 unsigned int *mcol_to_vcol(Mesh *me)
1990 {
1991         MFace *mface;
1992         unsigned int *mcol, *mcoln, *mcolmain;
1993         int a;
1994
1995         if(me->totface==0 || me->mcol==0) return 0;
1996         
1997         mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
1998         mcol = (unsigned int *)me->mcol;
1999         mface= me->mface;
2000         
2001         for(a=me->totface; a>0; a--, mface++) {
2002                 mcoln[mface->v1]= mcol[0];
2003                 mcoln[mface->v2]= mcol[1];
2004                 mcoln[mface->v3]= mcol[2];
2005                 if(mface->v4) mcoln[mface->v4]= mcol[3];
2006
2007                 mcol+= 4;
2008         }
2009         
2010         return mcolmain;
2011 }
2012
2013 void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)
2014 {
2015         char *cp;
2016         
2017         cp = (char *)&col;
2018         
2019         *r= cp[3];
2020         *r /= 255.0;
2021
2022         *g= cp[2];
2023         *g /= 255.0;
2024
2025         *b= cp[1];
2026         *b /= 255.0;
2027
2028         *a= cp[0];
2029         *a /= 255.0;
2030 }
2031
2032 static void write_mesh_vrml(FILE *fp, Mesh *me)
2033 {
2034         Material *ma;
2035         MVert *mvert;
2036         MFace *mface;
2037         MTFace *tface;
2038         Image *ima;
2039         int a, b, totcol, texind;
2040         char str[32];
2041         
2042         replace_chars(str, me->id.name+2);
2043
2044         fprintf(fp, "\tDEF %s\n", str);
2045         fprintf(fp, "\tSeparator {\n");
2046         
2047         if(me->mtface) {
2048                 ima= ((MTFace *)me->mtface)->tpage;
2049                 if(ima) {
2050                         fprintf(fp, "\t\tTexture2 {\n");
2051                         fprintf(fp, "\t\t\tfilename %s\n", ima->name);
2052                         fprintf(fp, "\t\t\twrapS REPEAT \n");
2053                         fprintf(fp, "\t\t\twrapT REPEAT \n");
2054                         fprintf(fp, "\t\t}\n");
2055                 }
2056         }
2057         
2058         if(me->mcol) {
2059                 unsigned int *mcol, *mcolmain;
2060                 float r, g, b, cola;
2061                 
2062                 fprintf(fp, "\t\tMaterial {\n");
2063                 fprintf(fp, "\t\t\tdiffuseColor [\n");
2064                 
2065                 a= me->totvert;
2066                 mcol= mcolmain= mcol_to_vcol(me);
2067                 if(mcol) {
2068                         while(a--) {
2069                                 mcol_to_rgba(*mcol, &r, &g, &b, &cola);
2070                                 fprintf(fp, "\t\t\t\t %f %f %f,\n", r, g, b);
2071                                 mcol++;
2072                         }
2073                         MEM_freeN(mcolmain);
2074                 }
2075                 fprintf(fp, "\t\t\t]\n");
2076                 fprintf(fp, "\t\t}\n");
2077
2078                 fprintf(fp, "\t\tMaterialBinding { value PER_VERTEX_INDEXED }\n");
2079         }
2080
2081
2082         fprintf(fp, "\t\tCoordinate3 {\n");
2083         fprintf(fp, "\t\t\tpoint [\n");
2084         
2085         a= me->totvert;
2086         mvert= me->mvert;
2087         while(a--) {
2088                 fprintf(fp, "\t\t\t\t %f %f %f,\n", mvert->co[0], mvert->co[1], mvert->co[2]);
2089                 mvert++;
2090         }
2091         fprintf(fp, "\t\t\t]\n");
2092         fprintf(fp, "\t\t}\n");
2093         
2094         
2095         totcol= me->totcol;
2096         if(totcol==0) totcol= 1;
2097         texind= 0; // index for uv coords
2098         
2099         for(b=0; b<totcol; b++) {
2100                 
2101                 if(me->mcol==0) {
2102                         if(me->mat) {
2103                                 ma= me->mat[b];
2104                                 if(ma) {
2105                                         replace_chars(str, ma->id.name+2);
2106
2107                                         fprintf(fp, "\t\tUSE %s\n\n", str);
2108                                 }
2109                         }
2110                 }
2111                 
2112                 if(me->mtface) {
2113                         fprintf(fp, "\t\tTextureCoordinate2 {\n");
2114                         fprintf(fp, "\t\t\tpoint [\n");
2115         
2116                         a= me->totface;
2117                         mface= me->mface;
2118                         tface= me->mtface;
2119                         while(a--) {
2120                                 if(mface->mat_nr==b) {
2121                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[0][0], tface->uv[0][1]); 
2122                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[1][0], tface->uv[1][1]); 
2123                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[2][0], tface->uv[2][1]); 
2124                                         if(mface->v4) fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[3][0], tface->uv[3][1]); 
2125                                 }
2126                                 mface++;
2127                                 tface++;
2128                         }
2129                         fprintf(fp, "\t\t\t]\n");
2130                         fprintf(fp, "\t\t}\n");
2131                 }
2132
2133                 fprintf(fp, "\t\tIndexedFaceSet {\n");
2134                 fprintf(fp, "\t\t\tcoordIndex [\n");
2135
2136                 a= me->totface;
2137                 mface= me->mface;
2138                 while(a--) {
2139                         if(mface->mat_nr==b) {
2140                                 if(mface->v4) fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3, mface->v4); 
2141                                 else fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3); 
2142                         }
2143                         mface++;
2144                 }
2145                 fprintf(fp, "\t\t\t]\n");
2146
2147                 if(me->mtface) {
2148                         fprintf(fp, "\t\t\ttextureCoordIndex [\n");
2149         
2150                         a= me->totface;
2151                         mface= me->mface;
2152                         while(a--) {
2153                                 if(mface->mat_nr==b) {
2154                                         if(mface->v4) {
2155                                                 fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", texind, texind+1, texind+2, texind+3); 
2156                                                 texind+= 4;
2157                                         }
2158                                         else {
2159                                                 fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", texind, texind+1, texind+2); 
2160                                                 texind+= 3;
2161                                         }
2162                                 }
2163                                 mface++;
2164                         }
2165                         fprintf(fp, "\t\t\t]\n");
2166                 }
2167                 fprintf(fp, "\t\t}\n");
2168         }
2169         
2170         fprintf(fp, "\t}\n");
2171 }
2172
2173 static void write_camera_vrml(FILE *fp, Object *ob)
2174 {
2175         Camera *cam;
2176         
2177         if(ob==0) return;
2178         Mat4Invert(ob->imat, ob->obmat);
2179
2180         fprintf(fp, "\tMatrixTransform {\n");
2181
2182         fprintf(fp, "\tmatrix \n");
2183
2184         fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[0][0], ob->imat[0][1], ob->imat[0][2], ob->imat[0][3]);
2185         fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[1][0], ob->imat[1][1], ob->imat[1][2], ob->imat[1][3]);
2186         fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[2][0], ob->imat[2][1], ob->imat[2][2], ob->imat[2][3]);
2187         fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[3][0], ob->imat[3][1], ob->imat[3][2], ob->imat[3][3]);
2188
2189         fprintf(fp, "\t}\n");
2190
2191         cam= ob->data;
2192
2193         fprintf(fp, "\tPerspectiveCamera {\n");
2194         fprintf(fp, "\t\tfocalDistance %f\n", cam->lens/10.0);
2195         
2196         fprintf(fp, "\t}\n");
2197
2198 }
2199
2200 static void write_object_vrml(FILE *fp, Object *ob)
2201 {
2202         ID *id;
2203         char str[32];
2204         
2205         fprintf(fp, "\tSeparator {\n");
2206         fprintf(fp, "\t\tMatrixTransform {\n");
2207
2208         fprintf(fp, "\t\tmatrix \n");
2209
2210         fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[0][0], ob->obmat[0][1], ob->obmat[0][2], ob->obmat[0][3]);
2211         fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[1][0], ob->obmat[1][1], ob->obmat[1][2], ob->obmat[1][3]);
2212         fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[2][0], ob->obmat[2][1], ob->obmat[2][2], ob->obmat[2][3]);
2213         fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2], ob->obmat[3][3]);
2214
2215         fprintf(fp, "\t\t}\n");
2216
2217         id= ob->data;
2218
2219         replace_chars(str, id->name+2);
2220
2221         fprintf(fp, "\t\tUSE %s\n", str);
2222         fprintf(fp, "\t}\n");
2223 }
2224
2225
2226 void write_vrml(Scene *scene, char *str)
2227 {
2228         Mesh *me;
2229         Material *ma;
2230         Base *base;
2231         FILE *fp;
2232         
2233         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2234         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2235         if(BLI_testextensie(str,".wrl")==0) strcat(str, ".wrl");
2236         //XXX saveover()       if(!during_script() && saveover(str)==0) return;
2237         
2238         fp= fopen(str, "w");
2239         
2240         if(fp==NULL && !during_script()) {
2241                 //XXX error("Can't write file");
2242                 return;
2243         }
2244         strcpy(temp_dir, str);
2245
2246         //XXX waitcursor(1);
2247         
2248         /* FIRST: write all the datablocks */
2249         
2250         fprintf(fp, "#VRML V1.0 ascii\n\n# Blender V%d\n\n# 'Switch' is used as a hack, to ensure it is not part of the drawing\n\n", BLENDER_VERSION);
2251         fprintf(fp, "Separator {\n");
2252         fprintf(fp, "Switch {\n");
2253
2254         ma= G.main->mat.first;
2255         while(ma) {
2256                 if(ma->id.us) {
2257                         write_material_vrml(fp, ma);
2258                 }
2259                 ma= ma->id.next;
2260         }
2261
2262         /* only write meshes we're using in this scene */
2263         flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2264         
2265         for(base= scene->base.first; base; base= base->next)
2266                 if(base->object->type== OB_MESH)
2267                         ((ID *)base->object->data)->flag |= LIB_DOIT;   
2268         
2269         me= G.main->mesh.first;
2270         while(me) {
2271                 if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2272                         write_mesh_vrml(fp, me);
2273                 }
2274                 me= me->id.next;
2275         }
2276         
2277         /* THEN:Hidden Objects */
2278         fprintf(fp, "\n\t# Hidden Objects, in invisible layers\n\n");
2279         base= scene->base.first;
2280         while(base) {
2281                 if(base->object->type== OB_MESH) {
2282                         if( (base->lay & scene->lay)==0 ) {
2283                                 write_object_vrml(fp, base->object);
2284                         }
2285                 }
2286                 base= base->next;
2287         }
2288
2289         fprintf(fp, "}\n");
2290         fprintf(fp, "\n# Visible Objects\n\n");
2291         fprintf(fp, "Separator {\n");
2292         
2293         /* The camera */
2294
2295         write_camera_vrml(fp, scene->camera);
2296         
2297         /* THEN:The Objects */
2298         
2299         base= scene->base.first;
2300         while(base) {
2301                 if(base->object->type== OB_MESH) {
2302                         if(base->lay & scene->lay) {
2303                                 write_object_vrml(fp, base->object);
2304                         }
2305                 }
2306                 base= base->next;
2307         }
2308         
2309         fprintf(fp, "}\n");
2310         fprintf(fp, "}\n");
2311         
2312         fclose(fp);
2313         
2314         //XXX waitcursor(0);
2315 }
2316
2317
2318 /* ******************************* WRITE DXF ***************************** */
2319
2320 #define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
2321
2322 /* A completely wacky function to try and make good
2323 indexed (AutoCAD index) values out of straight rgb 
2324 ones... crazy */
2325
2326 static int rgb_to_dxf_col (float rf, float gf, float bf) 
2327 {
2328         int r= (int) (rf*255.0f);
2329         int g= (int) (gf*255.0f);
2330         int b= (int) (bf*255.0f);
2331         float h,s,v;
2332         int ret;
2333         
2334         /* Grayscale value */
2335         if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51);
2336         /* A nice chroma value */
2337         else {
2338                 rgb_to_hsv (rf,gf,bf,&h,&s,&v);
2339                 
2340                 ret= (int) (10.0f + (h*239.0f));
2341                 CLAMP(ret,10,249);
2342                 
2343                 /* If its whitish make the index odd */
2344                 if (s<.5 || v>.5) if(ret%2) ret++;
2345         }
2346         
2347         return ret;
2348 }
2349
2350 /* And its completely wacky complement */
2351
2352 static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf)
2353 {
2354         float h, s, v;
2355         
2356         /* Grayscale values */
2357         if (cid>=250 && cid <= 255) {
2358                 *rf= *gf= *bf= (float) ((cid-250)*51)/255;
2359                 CLAMP(*rf, 0.0, 1.0);
2360                 CLAMP(*gf, 0.0, 1.0);
2361                 CLAMP(*bf, 0.0, 1.0);
2362                 
2363         /* Pure values */
2364         } else if (cid<10) {
2365                 switch (cid) {
2366                 case 1:
2367                         *rf=1.0;
2368                         *gf=0.0;
2369                         *bf=0.0;
2370                         break;
2371                 case 2:
2372                         *rf=1.0;
2373                         *gf=1.0;
2374                         *bf=0.0;
2375                         break;
2376                 case 3:
2377                         *gf=1.0;
2378                         *rf=0.0;
2379                         *bf=0.0;
2380                         break;
2381                 case 4:
2382                         *rf=0.0;
2383                         *gf=1.0;
2384                         *bf=1.0;
2385                         break;
2386                 case 5:
2387                         *rf=0.0;
2388                         *gf=0.0;
2389                         *bf=1.0;
2390                         break;
2391                 case 6:
2392                         *rf=1.0;
2393                         *gf=0.0;
2394                         *bf=1.0;
2395                         break;
2396                 case 7:
2397                 default:
2398                         *rf= *gf= *bf= 1.0;
2399                         break;
2400                 }
2401         } else {
2402                 /* Get chroma values */
2403                         
2404                 h= (float) (cid-10)/239;
2405                 CLAMP(h, 0.0, 1.0);
2406                 
2407                 /* If its odd make it a bit whitish */
2408                 if (cid%2) { s=.75; v= 0.25; 
2409                 } else {  s= 0.25; v= 0.75;}
2410                 
2411                 hsv_to_rgb (h, s, v, rf, gf, bf);
2412         }
2413 }
2414
2415 static void write_mesh_dxf(FILE *fp, Mesh *me)
2416 {
2417         Material *ma;
2418         MVert *mvert;
2419         MFace *mface;
2420         int a;
2421         char str[32];
2422         
2423         replace_chars(str, me->id.name+2);
2424
2425         write_group(0, "BLOCK");
2426         
2427         write_group(2, str); /* The name */
2428                 
2429         write_group(8, "Meshes"); /* DXF Layer */
2430         write_group(70, "64"); /* DXF block flags */
2431         
2432         write_group(10, "0.0"); /* X of base */
2433         write_group(20, "0.0"); /* Y of base */
2434         write_group(30, "0.0"); /* Z of base */
2435
2436         write_group(3, str); /* The name (again) */
2437         
2438         write_group(0, "POLYLINE"); /* Start the mesh */
2439         write_group(66, "1"); /* Vertices follow flag */
2440         write_group(8,"Meshes"); /* DXF Layer */
2441
2442         if (me->totcol) {
2443                 ma= me->mat[0];
2444                 if(ma) {
2445                         sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2446                         write_group(62, str); /* Color index */
2447                 }
2448         }
2449
2450         write_group(70, "64"); /* Polymesh mesh flag */
2451         
2452         fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */
2453         fprintf(fp, "72\n%d\n", me->totface); /* Total faces */
2454         
2455         /* Write the vertices */
2456         a= me->totvert;
2457         mvert= me->mvert;
2458         while(a--) {
2459                 write_group(0, "VERTEX"); /* Start a new vertex */
2460                 write_group(8, "Meshes"); /* DXF Layer */
2461                 fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */
2462                 fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */
2463                 fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */
2464                 write_group(70, "192"); /* Polymesh vertex flag */
2465                                 
2466                 mvert++;
2467         }
2468
2469         /* Write the face entries */
2470         a= me->totface;
2471         mface= me->mface;
2472         while(a--) {
2473                 write_group(0, "VERTEX"); /* Start a new face */
2474                 write_group(8, "Meshes");
2475         
2476                 /* Write a face color */
2477                 if (me->totcol) {
2478                         ma= me->mat[(int)mface->mat_nr];
2479                         if(ma) {
2480                                 sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2481                                 write_group(62, str); /* Color index */
2482                         }
2483                 }
2484                 else write_group(62, "254"); /* Color Index */
2485
2486                 /* Not sure what this really corresponds too */
2487                 write_group(10, "0.0"); /* X of base */
2488                 write_group(20, "0.0"); /* Y of base */
2489                 write_group(30, "0.0"); /* Z of base */
2490         
2491                 write_group(70, "128"); /* Polymesh face flag */
2492         
2493                 if(mface->v4) {
2494                         fprintf (fp, "71\n%d\n", mface->v1+1);
2495                         fprintf (fp, "72\n%d\n", mface->v2+1);
2496                         fprintf (fp, "73\n%d\n", mface->v3+1);
2497                         fprintf (fp, "74\n%d\n", mface->v4+1);
2498                 } else {
2499                         fprintf (fp, "71\n%d\n", mface->v1+1);
2500                         fprintf (fp, "72\n%d\n", mface->v2+1);
2501                         fprintf (fp, "73\n%d\n", mface->v3+1);
2502                 }
2503                 mface++;
2504         }
2505
2506         write_group(0, "SEQEND");       
2507         
2508         write_group(0, "ENDBLK");
2509 }
2510
2511 static void write_object_dxf(FILE *fp, Object *ob, int layer)
2512 {
2513         ID *id;
2514         char str[32];
2515
2516         id= ob->data;
2517
2518         write_group(0, "INSERT"); /* Start an insert group */
2519         
2520         sprintf(str, "%d", layer);
2521         write_group(8, str);
2522
2523         replace_chars(str, id->name+2);
2524         write_group(2, str);
2525
2526         fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */
2527         fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */
2528         fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */
2529         
2530         fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */
2531         fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */
2532         fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */
2533         
2534         fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */
2535 }
2536
2537 void write_dxf(struct Scene *scene, char *str)
2538 {
2539         Mesh *me;
2540         Base *base;
2541         FILE *fp;
2542         
2543         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2544         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2545         if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
2546
2547         if (!during_script()) {
2548                 if (BLI_exists(str))
2549                         ; //XXX if(saveover(str)==0)
2550                         //      return;
2551         }
2552
2553         fp= fopen(str, "w");
2554         
2555         if(fp==NULL && !during_script()) {
2556                 //XXX error("Can't write file");
2557                 return;
2558         }
2559         strcpy(temp_dir, str);
2560         
2561         //XXX waitcursor(1);
2562         
2563         /* The header part of the DXF */
2564         
2565         write_group(0, "SECTION");
2566     write_group(2, "HEADER");
2567         write_group(0, "ENDSEC");
2568
2569         /* The blocks part of the DXF */
2570         
2571         write_group(0, "SECTION");
2572     write_group(2, "BLOCKS");
2573
2574     
2575         /* only write meshes we're using in this scene */
2576         flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2577         
2578         for(base= scene->base.first; base; base= base->next)
2579                 if(base->object->type== OB_MESH)
2580                         ((ID *)base->object->data)->flag |= LIB_DOIT;   
2581         
2582         /* Write all the meshes */
2583         me= G.main->mesh.first;
2584         while(me) {
2585                 if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2586                         write_mesh_dxf(fp, me);
2587                 }
2588                 me= me->id.next;
2589         }
2590
2591         write_group(0, "ENDSEC");
2592
2593         /* The entities part of the DXF */
2594         
2595         write_group(0, "SECTION");
2596     write_group(2, "ENTITIES");
2597
2598         /* Write all the mesh objects */
2599         base= scene->base.first;
2600         while(base) {
2601                 if(base->object->type== OB_MESH) {
2602                         write_object_dxf(fp, base->object, base->lay);
2603                 }
2604                 base= base->next;
2605         }
2606
2607         write_group(0, "ENDSEC");
2608         
2609         /* Thats all */
2610         
2611         write_group(0, "EOF");
2612         fclose(fp);
2613         
2614         //XXX waitcursor(0);
2615 }
2616
2617
2618 static int dxf_line= 0;
2619 static FILE *dxf_fp= NULL;
2620
2621 /* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual
2622  * Studio/VC98/include\ctype.h(268) : see previous definition of
2623  * 'iswspace' */
2624 #define ton_iswspace(c) (c==' '||c=='\n'||c=='\t')
2625
2626 static void clean_wspace (char *str) 
2627 {
2628         char *from, *to;
2629         char t;
2630         
2631         from= str;
2632         to=str;
2633         
2634         while (*from!=0) {
2635                 t= *from;
2636                 *to= t;
2637                 
2638                 if(!ton_iswspace(*from)) to++;
2639                 from++;
2640         }
2641         *to=0;
2642 }
2643
2644 static int all_wspace(char *str)
2645 {
2646         while(*str != 0) {
2647                 if (!ton_iswspace(*str)) return 0;
2648                 str++;
2649         }
2650
2651         return 1;
2652 }
2653
2654 static int all_digits(char *str)
2655 {
2656         while(*str != 0) {
2657                 if (!isdigit(*str)) return 0;
2658                 str++;
2659         }
2660
2661         return 1;
2662 }
2663
2664 static int dxf_get_layer_col(char *layer) 
2665 {
2666         return 1;
2667 }
2668
2669 static int dxf_get_layer_num(Scene *scene, char *layer)
2670 {
2671         int ret = 0;
2672
2673         if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer);
2674         if (ret == 0) ret = scene->lay;
2675
2676         return ret;
2677 }
2678
2679 static void dos_clean(char *str)
2680 {
2681         while (*str) {
2682                 if (*str == 0x0d) {
2683                         *str='\n';
2684                         *(++str)= 0;
2685                         break;
2686                 }
2687                 str++;
2688         }       
2689 }
2690
2691 static void myfgets(char *str, int len, FILE *fp)
2692 {
2693         char c;
2694         
2695         while(len>0 && (c=getc(dxf_fp)) ) {
2696                 *str= c;
2697                 str++;
2698                 len--;
2699                 /* three types of enters, \n \r and \r\n  */
2700                 if(c == '\n') break;
2701                 if(c=='\r') {
2702                         c= getc(dxf_fp);                                // read the linefeed from stream
2703                         if(c != 10) ungetc(c, dxf_fp);  // put back, if it's not one...
2704                         break;
2705                 }
2706         }
2707 }
2708
2709 static int read_groupf(char *str) 
2710 {
2711         short c;
2712         int ret=-1;
2713         char tmp[256];
2714         
2715         strcpy(str, " ");
2716
2717         while ((c=getc(dxf_fp)) && ton_iswspace(c));
2718         ungetc(c, dxf_fp);
2719         if (c==EOF) return -1;
2720         
2721         myfgets(tmp, 255, dxf_fp);
2722         
2723         dos_clean(tmp);
2724
2725         if(sscanf(tmp, "%d\n", &ret)!=1) return -2;
2726                 
2727         myfgets(tmp, 255, dxf_fp);
2728
2729         dos_clean(tmp);
2730
2731         if (!all_wspace(tmp)) {
2732                 if (sscanf(tmp, "%s\n", str)!=1) return -2;
2733         }
2734         
2735         clean_wspace(str);
2736         dxf_line+=2;
2737         
2738         return ret;
2739 }
2740
2741 //XXX error() is now printf until we have a callback error
2742 #define id_test(id) if(id<0) {char errmsg[128];fclose(dxf_fp); if(id==-1) sprintf(errmsg, "Error inputting dxf, near line %d", dxf_line); else if(id==-2) sprintf(errmsg, "Error reading dxf, near line %d", dxf_line);printf("%s", errmsg); return;}
2743
2744 #define read_group(id,str) {id= read_groupf(str); id_test(id);}
2745
2746 #define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0)
2747 #define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0)
2748 #define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;}
2749
2750 static int id;
2751 static char val[256];
2752
2753 static short error_exit=0;
2754 static short hasbumped=0;
2755
2756 static int is_dxf(char *str)
2757 {       
2758         dxf_line=0;
2759         
2760         dxf_fp= fopen(str, "r");
2761         if (dxf_fp==NULL) return 0;
2762
2763         id= read_groupf(val);
2764         if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1;
2765         
2766         fclose(dxf_fp);
2767         
2768         return 0;
2769 }
2770
2771 /* NOTES ON THE READER */ 
2772 /*
2773         --
2774         It turns out that most DXF writers like (LOVE) to
2775         write meshes as a long string of 3DFACE entities.
2776         This means the natural way to read a DXF file
2777         (every entity corresponds to an object) is completely
2778         unusable, reading in 10,000 faces each as an
2779         object just doesn't cut it. Thus the 3DFACE
2780         entry reader holds state, and only finalizes to
2781         an object when a) the layer name changes, b) the
2782         entry type changes, c) we are done reading.
2783
2784         PS... I decided to do the same thing with LINES, 
2785         apparently the same thing happens sometimes as
2786         well.
2787
2788         PPS... I decided to do the same thing with everything.
2789         Now it is all really nasty and should be rewritten. 
2790         --
2791         
2792         Added circular and elliptical arcs and lwpolylines.
2793         These are all self-contained and have the size known
2794         in advance, and so I haven't used the held state. -- martin
2795 */
2796
2797 static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer) 
2798 {
2799         Material *ma;
2800         
2801         if (!me) return;
2802         
2803         if(ob) {
2804                 ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
2805                 ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
2806                 ob->actcol= 1;
2807         }
2808
2809         me->totcol= 1;
2810         me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
2811         
2812         if (color[0]<0) {
2813                 if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]);
2814                 color[0]= color[1]= color[2]= 0.8f;
2815         }                                                                                               
2816                                                 
2817         ma= G.main->mat.first;
2818         while(ma) {
2819                 if(ma->mtex[0]==0) {
2820                         if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) {
2821                                 me->mat[0]= ma;
2822                                 ma->id.us++;
2823                                 break;
2824                         }
2825                 }
2826                 ma= ma->id.next;
2827         }
2828         if(ma==0) {
2829                 ma= add_material("ext");
2830                 me->mat[0]= ma;
2831                 ma->r= color[0];
2832                 ma->g= color[1];
2833                 ma->b= color[2];
2834                 automatname(ma);
2835         }
2836 }
2837
2838         /* General DXF vars */
2839 static float cent[3]={0.0, 0.0, 0.0};
2840 static char layname[32]="";
2841 static char entname[32]="";
2842 static float color[3]={-1.0, -1.0, -1.0};
2843 static float *vcenter;
2844 static float zerovec[3]= {0.0, 0.0, 0.0};
2845
2846 #define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0
2847
2848
2849 static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob)
2850 {
2851         Mesh *me = NULL;
2852         Object *ob;
2853         
2854         if (!noob) {
2855                 *o = add_object(scene, OB_MESH);
2856                 ob = *o;
2857                 
2858                 if (strlen(entname)) new_id(&G.main->object, (ID *)ob, entname);
2859                 else if (strlen(layname)) new_id(&G.main->object, (ID *)ob,  layname);
2860
2861                 if (strlen(layname)) ob->lay= dxf_get_layer_num(scene, layname);
2862                 else ob->lay= scene->lay;
2863                 // not nice i know... but add_object() sets active base, which needs layer setting too (ton)
2864                 scene->basact->lay= ob->lay;
2865
2866                 *m = ob->data;
2867                 me= *m;
2868
2869                 vcenter= ob->loc;
2870         } 
2871         else {
2872                 *o = NULL;
2873                 *m = add_mesh("Mesh");
2874
2875                 me = *m;
2876                 ob = *o;
2877                 
2878   &nb