NLA SoC: Start of 'Meta' Strips
[blender.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         if(totcol>16) {
1419                 //XXX error("Found more than 16 different colors");
1420                 totcol= 16;
1421         }
1422
1423         vec[0]= (min[0]+max[0])/2;
1424         vec[1]= (min[1]+max[1])/2;
1425         vec[2]= (min[2]+max[2])/2;
1426
1427         ob= add_object(scene, OB_MESH);
1428         VECCOPY(ob->loc, vec);
1429         where_is_object(scene, ob);
1430
1431         me= ob->data;
1432         
1433         /* colors */
1434         if(totcol) {
1435                 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
1436                 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
1437                 me->totcol= totcol;
1438                 ob->totcol= (unsigned char) me->totcol;
1439                 ob->actcol= 1;
1440         }
1441         
1442         /* materials */
1443         for(a=0; a<totcol; a++) {
1444                 ma= G.main->mat.first;
1445                 while(ma) {
1446                         if(ma->mtex[0]==0) {
1447                                 if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
1448                                         me->mat[a]= ma;
1449                                         ma->id.us++;
1450                                         break;
1451                                 }
1452                         }
1453                         ma= ma->id.next;
1454                 }
1455                 if(ma==0) {
1456                         ma= add_material("ext");
1457                         me->mat[a]= ma;
1458                         ma->r= ivcolors[a][0];
1459                         ma->g= ivcolors[a][1];
1460                         ma->b= ivcolors[a][2];
1461                         automatname(ma);
1462                 }
1463         }
1464         
1465         totface= totquad+tottria+totedge;
1466
1467         printf("Import: %d vertices %d faces\n", totvert, totface);
1468         
1469         me->totvert= totvert;
1470         me->totface= totface;
1471         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
1472                                         NULL, me->totvert);
1473         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
1474                                         NULL, me->totface);
1475         maxvertidx= totvert-1;
1476         
1477         mvert= me->mvert;
1478         mface= me->mface;
1479
1480         startve= 0;
1481
1482         dl= dlfirst;
1483         while(dl) {
1484                 
1485                 colnr= (dl->col>15 ? 15: dl->col);
1486                 if(colnr) colnr--;
1487                 
1488                 if(dl->type==DL_SURF) {
1489                         data= (float *)(dl+1);
1490
1491                         for(a=dl->parts*dl->nr; a>0; a--) {
1492                                 mvert->co[0]= data[0] -vec[0];
1493                                 mvert->co[1]= data[1] -vec[1];
1494                                 mvert->co[2]= data[2] -vec[2];
1495                                 
1496                                 data+=3;
1497                                 mvert++;
1498                         }
1499
1500                         for(a=0; a<dl->parts; a++) {
1501                                 
1502                                 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
1503                                         break;
1504                                 
1505                                 p1+= startve; 
1506                                 p2+= startve; 
1507                                 p3+= startve; 
1508                                 p4+= startve;
1509
1510                                 for(; b<dl->nr; b++) {
1511                                 
1512                                         mface->v1= p1;
1513                                         mface->v2= p2;
1514                                         mface->v3= p4;
1515                                         mface->v4= p3;
1516                                         
1517                                         mface->mat_nr= colnr;
1518                                         test_index_face(mface, NULL, 0, 4);
1519                                         
1520                                         mface++;
1521                                         
1522                                         p4= p3; 
1523                                         p3++;
1524                                         p2= p1; 
1525                                         p1++;
1526                                 }
1527                         }
1528                         
1529                         startve += dl->parts*dl->nr;
1530
1531                 }
1532                 else if(dl->type==DL_POLY) {
1533                 
1534                         if(dl->nr==3 || dl->nr==4) {
1535                                 data= (float *)(dl+1);
1536
1537                                 for(a=dl->parts*dl->nr; a>0; a--) {
1538                                         mvert->co[0]= data[0] -vec[0];
1539                                         mvert->co[1]= data[1] -vec[1];
1540                                         mvert->co[2]= data[2] -vec[2];
1541                                         data+=3;
1542                                         mvert++;
1543                                 }
1544
1545                                 for(a=0; a<dl->parts; a++) {
1546                                         if(dl->nr==3) {
1547                                                 mface->v1= startve+a*dl->nr;
1548                                                 mface->v2= startve+a*dl->nr+1;
1549                                                 mface->v3= startve+a*dl->nr+2;
1550                                                 mface->mat_nr= colnr;
1551                                                 test_index_face(mface, NULL, 0, 3);
1552                                                 mface++;
1553                                         }
1554                                         else {
1555                                                 mface->v1= startve+a*dl->nr;
1556                                                 mface->v2= startve+a*dl->nr+1;
1557                                                 mface->v3= startve+a*dl->nr+2;
1558                                                 mface->v4= startve+a*dl->nr+3;
1559                                                 mface->mat_nr= colnr;
1560                                                 test_index_face(mface, NULL, 0, 4);
1561                                                 mface++;
1562                                         }
1563                                 }
1564                                 startve += dl->parts*dl->nr;
1565                         }
1566                         else if(dl->nr>4) {
1567                                 data= (float *)(dl+1);
1568
1569                                 for(a=dl->parts*dl->nr; a>0; a--) {
1570                                         mvert->co[0]= data[0] -vec[0];
1571                                         mvert->co[1]= data[1] -vec[1];
1572                                         mvert->co[2]= data[2] -vec[2];
1573                                         
1574                                         data+=3;
1575                                         mvert++;
1576                                 }
1577
1578                                 for(b=0; b<dl->parts; b++) {
1579                                         for(a=0; a<dl->nr; a++) {
1580                                                 mface->v1= startve+a;
1581                                                 
1582                                                 if(a==dl->nr-1) mface->v2= startve;
1583                                                 else mface->v2= startve+a+1;
1584                                                 
1585                                                 mface->mat_nr= colnr;
1586
1587                                                 mface++;
1588                                         }
1589                                         startve += dl->nr;
1590                                 }
1591                         }
1592                 }
1593                 else if(dl->type==DL_INDEX3) {
1594                         data= dl->verts;
1595                         
1596                         for(a=dl->nr; a>0; a--) {
1597                                 mvert->co[0]= data[0] -vec[0];
1598                                 mvert->co[1]= data[1] -vec[1];
1599                                 mvert->co[2]= data[2] -vec[2];
1600                                 data+=3;
1601                                 mvert++;
1602                         }
1603
1604                         idata= dl->index;
1605                         for(b=dl->parts; b>0; b--) {
1606                                 mface->v1= startve+idata[0];
1607                                 mface->v2= startve+idata[1];
1608                                 mface->v3= startve+idata[2];
1609                                 mface->mat_nr= colnr;
1610                                 
1611                                 if (mface->v1>maxvertidx) mface->v1= maxvertidx;
1612                                 if (mface->v2>maxvertidx) mface->v2= maxvertidx;
1613                                 if (mface->v3>maxvertidx) mface->v3= maxvertidx;
1614
1615                                 test_index_face(mface, NULL, 0, 3);
1616                                 mface++;
1617                                 idata+= 3;
1618                         }
1619                         startve += dl->nr;
1620                 }
1621                 else if(dl->type==DL_SEGM) {
1622                         data= (float *)(dl+1);
1623
1624                         for(a=dl->parts*dl->nr; a>0; a--) {
1625                                 mvert->co[0]= data[0] -vec[0];
1626                                 mvert->co[1]= data[1] -vec[1];
1627                                 mvert->co[2]= data[2] -vec[2];
1628                                 data+=3;
1629                                 mvert++;
1630                         }
1631
1632                         for(b=0; b<dl->parts; b++) {
1633                                 for(a=0; a<dl->nr-1; a++) {
1634                                         mface->v1= startve+a;
1635                                         mface->v2= startve+a+1;
1636                                         mface->mat_nr= colnr;
1637                                         mface++;
1638                                 }
1639                                 startve += dl->nr;
1640                         }
1641                 }
1642                 dl= dl->next;
1643         }
1644
1645         mesh_add_normals_flags(me);
1646         make_edges(me, 0);
1647 }
1648
1649 static void displist_to_objects(Scene *scene, ListBase *lbase)
1650 {
1651         DispList *dl, *first, *prev, *next;
1652         ListBase tempbase;
1653         int maxaantal, curcol, totvert=0, vert;
1654         
1655         /* irst this: is still active */
1656         if(ivsurf) {
1657                 where_is_object(scene, ivsurf);
1658 // XXX          docenter_new();
1659         }
1660
1661         dl= lbase->first;
1662         while(dl) {
1663                 next= dl->next;
1664                 
1665                 /* PATCH 1: polyfill */
1666                 if(dl->type==DL_POLY && dl->nr>4) {
1667                         /* solution: put them together in separate listbase */
1668                         ;
1669                 }
1670                 /* PATCH 2: poly's of 2 points */
1671                 if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
1672                 
1673                 dl= next;
1674         }
1675
1676         /* count vertices */
1677
1678         dl= lbase->first;
1679         while(dl) {
1680
1681                 if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
1682                 else if(dl->type==DL_POLY) {
1683                         if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
1684                         else if(dl->nr>4) totvert+= dl->nr*dl->parts;
1685                 }
1686                 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1687                 else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
1688
1689                 dl= dl->next;
1690         }
1691
1692         if(totvert==0) {
1693                 
1694                 if(ivsurf==0) ; //XXX error("Found no data");
1695                 if(lbase->first) BLI_freelistN(lbase);
1696                 
1697                 return;
1698         }
1699
1700         maxaantal= 32000;
1701         
1702         if(totvert>maxaantal) {
1703         
1704                 /* try to put colors together */
1705                 curcol= 0;
1706                 tempbase.first= tempbase.last= 0;
1707
1708                 while(lbase->first) {
1709                         dl= lbase->first;
1710                         while(dl) {
1711                                 next= dl->next;
1712                                 if(dl->col==curcol) {
1713                                         BLI_remlink(lbase, dl);
1714                                         BLI_addtail(&tempbase, dl);
1715                                         dl->col= 0;
1716                                 }
1717                                 
1718                                 dl= next;
1719                         }
1720                         
1721                         /* in tempbase are all 'curcol' */
1722                         totvert= 0;
1723                         dl= first= tempbase.first;
1724                         while(dl) {
1725                                 vert= 0;
1726                                 
1727                                 if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
1728                                 else if(dl->type==DL_POLY) {
1729                                         if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
1730                                         else if(dl->nr>4) vert= dl->nr*dl->parts;
1731                                 }
1732                                 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1733                                 else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
1734                                 
1735                                 totvert+= vert;
1736                                 if(totvert > maxaantal || dl->next==0) {
1737                                         if(dl->next==0) {
1738                                                 displist_to_mesh(scene, first);
1739                                         }
1740                                         else if(dl->prev) {
1741                                                 prev= dl->prev;
1742                                                 prev->next= 0;
1743                                                 displist_to_mesh(scene, first);
1744                                                 prev->next= dl;
1745                                                 first= dl;
1746                                                 totvert= 0;
1747                                         }
1748                                 }
1749                                 
1750                                 dl= dl->next;
1751                         }
1752                         
1753                         freedisplist(&tempbase);
1754                         
1755                         curcol++;
1756                 }
1757         }
1758         else displist_to_mesh(scene, lbase->first);
1759
1760         freedisplist(lbase);
1761
1762 }
1763
1764 int BKE_read_exotic(Scene *scene, char *name)
1765 {
1766         ListBase lbase={0, 0};
1767         int len;
1768         gzFile gzfile;
1769         char str[32];
1770         int *s0 = (int*) str;
1771         int retval = 0;
1772
1773         // make sure we're not trying to read a directory....
1774
1775         len= strlen(name);
1776         if (name[len-1] !='/' && name[len-1] != '\\') {
1777                 gzfile = gzopen(name,"rb");
1778
1779                 if (NULL == gzfile ) {
1780                         //XXX error("Can't open file: %s", name);
1781                         retval= -1;
1782                 } else {
1783                         gzread(gzfile, str, 31);
1784                         gzclose(gzfile);
1785
1786                         if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
1787
1788                                 //XXX waitcursor(1);
1789                                 if(strncmp(str, "#Inventor V1.0", 14)==0) {
1790                                         if( strncmp(str+15, "ascii", 5)==0) {
1791                                                 read_inventor(scene, name, &lbase);
1792                                                 displist_to_objects(scene, &lbase);                             
1793                                                 retval = 1;
1794                                         } else {
1795                                                 //XXX error("Can only read Inventor 1.0 ascii");
1796                                         }
1797                                 }
1798                                 else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
1799                                         read_inventor(scene, name, &lbase);
1800                                         displist_to_objects(scene, &lbase);                             
1801                                         retval = 1;
1802                                 }
1803                                 else if(is_dxf(name)) {
1804                                         dxf_read(scene, name);
1805                                         retval = 1;
1806                                 }
1807                                 else if(is_stl(name)) {
1808                                         if (is_stl_ascii(name))
1809                                                 read_stl_mesh_ascii(scene, name);
1810                                         else
1811                                                 read_stl_mesh_binary(scene, name);
1812                                         retval = 1;
1813                                 }
1814 #ifndef DISABLE_PYTHON
1815                                 // TODO: this should not be in the kernel...
1816                                 else { // unknown format, call Python importloader 
1817                                         if (BPY_call_importloader(name)) {
1818                                                 retval = 1;
1819                                         } else {        
1820                                                 //XXX error("Unknown file type or error, check console");
1821                                         }       
1822                                 
1823                                 }
1824 #endif /* DISABLE_PYTHON */
1825                                 //XXX waitcursor(0);
1826                         }
1827                 }
1828         }
1829         
1830         return (retval);
1831 }
1832
1833
1834 /* ************************ WRITE ************************** */
1835
1836
1837 char temp_dir[160]= {0, 0};
1838
1839 static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
1840 {
1841         float vert[3];
1842
1843         VECCOPY(vert, verts[(index)].co);
1844         Mat4MulVecfl(ob->obmat, vert);
1845
1846         if (ENDIAN_ORDER==B_ENDIAN) {
1847                 SWITCH_INT(vert[0]);
1848                 SWITCH_INT(vert[1]);
1849                 SWITCH_INT(vert[2]);
1850         }
1851
1852         fwrite(vert, sizeof(float), 3, fpSTL);
1853 }
1854
1855 static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
1856 {
1857         MVert *mvert = dm->getVertArray(dm);
1858         MFace *mface = dm->getFaceArray(dm);
1859         int i, numfacets = 0, totface = dm->getNumFaces(dm);
1860         float zero[3] = {0.0f, 0.0f, 0.0f};
1861
1862         for (i=0; i<totface; i++, mface++) {
1863                 fwrite(zero, sizeof(float), 3, fpSTL);
1864                 write_vert_stl(ob, mvert, mface->v1, fpSTL);
1865                 write_vert_stl(ob, mvert, mface->v2, fpSTL);
1866                 write_vert_stl(ob, mvert, mface->v3, fpSTL);
1867                 fprintf(fpSTL, "  ");
1868                 numfacets++;
1869
1870                 if(mface->v4) { /* quad = 2 tri's */
1871                         fwrite(zero, sizeof(float), 3, fpSTL);
1872                         write_vert_stl(ob, mvert, mface->v1, fpSTL);
1873                         write_vert_stl(ob, mvert, mface->v3, fpSTL);
1874                         write_vert_stl(ob, mvert, mface->v4, fpSTL);
1875                         fprintf(fpSTL, "  ");
1876                         numfacets++;
1877                 }
1878         }
1879
1880         return numfacets;
1881 }
1882
1883 static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob, Mesh *me)
1884 {
1885         int  numfacets = 0;
1886         DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
1887
1888         numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
1889
1890         dm->release(dm);
1891
1892         return numfacets;
1893 }
1894
1895 void write_stl(Scene *scene, char *str)
1896 {
1897         Object *ob;
1898         Mesh   *me;
1899         Base   *base;
1900         FILE   *fpSTL;
1901         int    numfacets = 0;
1902         
1903         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
1904         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
1905         if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
1906
1907         if (!during_script()) {
1908                 if (BLI_exists(str))
1909                         ; //XXX if(saveover(str)==0)
1910                         //XXX   return;
1911         }
1912
1913         fpSTL= fopen(str, "wb");
1914         
1915         if(fpSTL==NULL) {
1916                 if (!during_script()) ; //XXX error("Can't write file");
1917                 return;
1918         }
1919         strcpy(temp_dir, str);
1920         
1921         //XXX waitcursor(1);
1922         
1923         /* The header part of the STL */
1924         /* First 80 characters are a title or whatever you want.
1925            Lets make the first 32 of those spam and the rest the filename.
1926            Those first 80 characters will be followed by 4 bytes
1927            which will be overwritten later with an integer holding
1928            how many facets are written (we set them to ' ' for now).
1929         */
1930         fprintf(fpSTL, "Binary STL output from Blender: %-48.48s    ", str);
1931
1932         /* Write all selected mesh objects */
1933         base= scene->base.first;
1934         while(base) {
1935                 if (base->flag & SELECT) {
1936                         ob = base->object;
1937                         if (ob->type == OB_MESH) {
1938                                 me = ob->data;
1939                                 if (me)
1940                                         numfacets += write_object_stl(fpSTL, scene, ob, me);
1941                         }
1942                 }
1943                 base= base->next;
1944         }
1945
1946         /* time to write the number of facets in the 4 bytes
1947            starting at byte 81
1948         */
1949         fseek(fpSTL, 80, SEEK_SET);
1950
1951         if (ENDIAN_ORDER==B_ENDIAN) {
1952                 SWITCH_INT(numfacets);
1953         }
1954         fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
1955
1956         fclose(fpSTL);
1957         
1958         //XXX waitcursor(0);
1959 }
1960
1961 /* ******************************* WRITE VRML ***************************** */
1962
1963 static void replace_chars(char *str1, char *str2)
1964 {
1965         int a= strlen(str2);
1966         
1967         str1[a]= 0;
1968         while(a--) {
1969                 if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
1970                 else str1[a]= str2[a];
1971         }
1972 }
1973
1974
1975 static void write_material_vrml(FILE *fp, Material *ma)
1976 {
1977         char str[32];
1978         
1979         replace_chars(str, ma->id.name+2);
1980         
1981         fprintf(fp, "\tDEF %s\n", str);
1982         fprintf(fp, "\tMaterial {\n");
1983         
1984         fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
1985         fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
1986         fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
1987         fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
1988         
1989         fprintf(fp, "\t}\n");
1990         
1991 }
1992
1993 unsigned int *mcol_to_vcol(Mesh *me)
1994 {
1995         MFace *mface;
1996         unsigned int *mcol, *mcoln, *mcolmain;
1997         int a;
1998
1999         if(me->totface==0 || me->mcol==0) return 0;
2000         
2001         mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
2002         mcol = (unsigned int *)me->mcol;
2003         mface= me->mface;
2004         
2005         for(a=me->totface; a>0; a--, mface++) {
2006                 mcoln[mface->v1]= mcol[0];
2007                 mcoln[mface->v2]= mcol[1];
2008                 mcoln[mface->v3]= mcol[2];
2009                 if(mface->v4) mcoln[mface->v4]= mcol[3];
2010
2011                 mcol+= 4;
2012         }
2013         
2014         return mcolmain;
2015 }
2016
2017 void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)
2018 {
2019         char *cp;
2020         
2021         cp = (char *)&col;
2022         
2023         *r= cp[3];
2024         *r /= 255.0;
2025
2026         *g= cp[2];
2027         *g /= 255.0;
2028
2029         *b= cp[1];
2030         *b /= 255.0;
2031
2032         *a= cp[0];
2033         *a /= 255.0;
2034 }
2035
2036 static void write_mesh_vrml(FILE *fp, Mesh *me)
2037 {
2038         Material *ma;
2039         MVert *mvert;
2040         MFace *mface;
2041         MTFace *tface;
2042         Image *ima;
2043         int a, b, totcol, texind;
2044         char str[32];
2045         
2046         replace_chars(str, me->id.name+2);
2047
2048         fprintf(fp, "\tDEF %s\n", str);
2049         fprintf(fp, "\tSeparator {\n");
2050         
2051         if(me->mtface) {
2052                 ima= ((MTFace *)me->mtface)->tpage;
2053                 if(ima) {
2054                         fprintf(fp, "\t\tTexture2 {\n");
2055                         fprintf(fp, "\t\t\tfilename %s\n", ima->name);
2056                         fprintf(fp, "\t\t\twrapS REPEAT \n");
2057                         fprintf(fp, "\t\t\twrapT REPEAT \n");
2058                         fprintf(fp, "\t\t}\n");
2059                 }
2060         }
2061         
2062         if(me->mcol) {
2063                 unsigned int *mcol, *mcolmain;
2064                 float r, g, b, cola;
2065                 
2066                 fprintf(fp, "\t\tMaterial {\n");
2067                 fprintf(fp, "\t\t\tdiffuseColor [\n");
2068                 
2069                 a= me->totvert;
2070                 mcol= mcolmain= mcol_to_vcol(me);
2071                 if(mcol) {
2072                         while(a--) {
2073                                 mcol_to_rgba(*mcol, &r, &g, &b, &cola);
2074                                 fprintf(fp, "\t\t\t\t %f %f %f,\n", r, g, b);
2075                                 mcol++;
2076                         }
2077                         MEM_freeN(mcolmain);
2078                 }
2079                 fprintf(fp, "\t\t\t]\n");
2080                 fprintf(fp, "\t\t}\n");
2081
2082                 fprintf(fp, "\t\tMaterialBinding { value PER_VERTEX_INDEXED }\n");
2083         }
2084
2085
2086         fprintf(fp, "\t\tCoordinate3 {\n");
2087         fprintf(fp, "\t\t\tpoint [\n");
2088         
2089         a= me->totvert;
2090         mvert= me->mvert;
2091         while(a--) {
2092                 fprintf(fp, "\t\t\t\t %f %f %f,\n", mvert->co[0], mvert->co[1], mvert->co[2]);
2093                 mvert++;
2094         }
2095         fprintf(fp, "\t\t\t]\n");
2096         fprintf(fp, "\t\t}\n");
2097         
2098         
2099         totcol= me->totcol;
2100         if(totcol==0) totcol= 1;
2101         texind= 0; // index for uv coords
2102         
2103         for(b=0; b<totcol; b++) {
2104                 
2105                 if(me->mcol==0) {
2106                         if(me->mat) {
2107                                 ma= me->mat[b];
2108                                 if(ma) {
2109                                         replace_chars(str, ma->id.name+2);
2110
2111                                         fprintf(fp, "\t\tUSE %s\n\n", str);
2112                                 }
2113                         }
2114                 }
2115                 
2116                 if(me->mtface) {
2117                         fprintf(fp, "\t\tTextureCoordinate2 {\n");
2118                         fprintf(fp, "\t\t\tpoint [\n");
2119         
2120                         a= me->totface;
2121                         mface= me->mface;
2122                         tface= me->mtface;
2123                         while(a--) {
2124                                 if(mface->mat_nr==b) {
2125                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[0][0], tface->uv[0][1]); 
2126                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[1][0], tface->uv[1][1]); 
2127                                         fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[2][0], tface->uv[2][1]); 
2128                                         if(mface->v4) fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[3][0], tface->uv[3][1]); 
2129                                 }
2130                                 mface++;
2131                                 tface++;
2132                         }
2133                         fprintf(fp, "\t\t\t]\n");
2134                         fprintf(fp, "\t\t}\n");
2135                 }
2136
2137                 fprintf(fp, "\t\tIndexedFaceSet {\n");
2138                 fprintf(fp, "\t\t\tcoordIndex [\n");
2139
2140                 a= me->totface;
2141                 mface= me->mface;
2142                 while(a--) {
2143                         if(mface->mat_nr==b) {
2144                                 if(mface->v4) fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3, mface->v4); 
2145                                 else fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3); 
2146                         }
2147                         mface++;
2148                 }
2149                 fprintf(fp, "\t\t\t]\n");
2150
2151                 if(me->mtface) {
2152                         fprintf(fp, "\t\t\ttextureCoordIndex [\n");
2153         
2154                         a= me->totface;
2155                         mface= me->mface;
2156                         while(a--) {
2157                                 if(mface->mat_nr==b) {
2158                                         if(mface->v4) {
2159                                                 fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", texind, texind+1, texind+2, texind+3); 
2160                                                 texind+= 4;
2161                                         }
2162                                         else {
2163                                                 fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", texind, texind+1, texind+2); 
2164                                                 texind+= 3;
2165                                         }
2166                                 }
2167                                 mface++;
2168                         }
2169                         fprintf(fp, "\t\t\t]\n");
2170                 }
2171                 fprintf(fp, "\t\t}\n");
2172         }
2173         
2174         fprintf(fp, "\t}\n");
2175 }
2176
2177 static void write_camera_vrml(FILE *fp, Object *ob)
2178 {
2179         Camera *cam;
2180         
2181         if(ob==0) return;
2182         Mat4Invert(ob->imat, ob->obmat);
2183
2184         fprintf(fp, "\tMatrixTransform {\n");
2185
2186         fprintf(fp, "\tmatrix \n");
2187
2188         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]);
2189         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]);
2190         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]);
2191         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]);
2192
2193         fprintf(fp, "\t}\n");
2194
2195         cam= ob->data;
2196
2197         fprintf(fp, "\tPerspectiveCamera {\n");
2198         fprintf(fp, "\t\tfocalDistance %f\n", cam->lens/10.0);
2199         
2200         fprintf(fp, "\t}\n");
2201
2202 }
2203
2204 static void write_object_vrml(FILE *fp, Object *ob)
2205 {
2206         ID *id;
2207         char str[32];
2208         
2209         fprintf(fp, "\tSeparator {\n");
2210         fprintf(fp, "\t\tMatrixTransform {\n");
2211
2212         fprintf(fp, "\t\tmatrix \n");
2213
2214         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]);
2215         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]);
2216         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]);
2217         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]);
2218
2219         fprintf(fp, "\t\t}\n");
2220
2221         id= ob->data;
2222
2223         replace_chars(str, id->name+2);
2224
2225         fprintf(fp, "\t\tUSE %s\n", str);
2226         fprintf(fp, "\t}\n");
2227 }
2228
2229
2230 void write_vrml(Scene *scene, char *str)
2231 {
2232         Mesh *me;
2233         Material *ma;
2234         Base *base;
2235         FILE *fp;
2236         
2237         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2238         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2239         if(BLI_testextensie(str,".wrl")==0) strcat(str, ".wrl");
2240         //XXX saveover()       if(!during_script() && saveover(str)==0) return;
2241         
2242         fp= fopen(str, "w");
2243         
2244         if(fp==NULL && !during_script()) {
2245                 //XXX error("Can't write file");
2246                 return;
2247         }
2248         strcpy(temp_dir, str);
2249
2250         //XXX waitcursor(1);
2251         
2252         /* FIRST: write all the datablocks */
2253         
2254         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);
2255         fprintf(fp, "Separator {\n");
2256         fprintf(fp, "Switch {\n");
2257
2258         ma= G.main->mat.first;
2259         while(ma) {
2260                 if(ma->id.us) {
2261                         write_material_vrml(fp, ma);
2262                 }
2263                 ma= ma->id.next;
2264         }
2265
2266         /* only write meshes we're using in this scene */
2267         flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2268         
2269         for(base= scene->base.first; base; base= base->next)
2270                 if(base->object->type== OB_MESH)
2271                         ((ID *)base->object->data)->flag |= LIB_DOIT;   
2272         
2273         me= G.main->mesh.first;
2274         while(me) {
2275                 if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2276                         write_mesh_vrml(fp, me);
2277                 }
2278                 me= me->id.next;
2279         }
2280         
2281         /* THEN:Hidden Objects */
2282         fprintf(fp, "\n\t# Hidden Objects, in invisible layers\n\n");
2283         base= scene->base.first;
2284         while(base) {
2285                 if(base->object->type== OB_MESH) {
2286                         if( (base->lay & scene->lay)==0 ) {
2287                                 write_object_vrml(fp, base->object);
2288                         }
2289                 }
2290                 base= base->next;
2291         }
2292
2293         fprintf(fp, "}\n");
2294         fprintf(fp, "\n# Visible Objects\n\n");
2295         fprintf(fp, "Separator {\n");
2296         
2297         /* The camera */
2298
2299         write_camera_vrml(fp, scene->camera);
2300         
2301         /* THEN:The Objects */
2302         
2303         base= scene->base.first;
2304         while(base) {
2305                 if(base->object->type== OB_MESH) {
2306                         if(base->lay & scene->lay) {
2307                                 write_object_vrml(fp, base->object);
2308                         }
2309                 }
2310                 base= base->next;
2311         }
2312         
2313         fprintf(fp, "}\n");
2314         fprintf(fp, "}\n");
2315         
2316         fclose(fp);
2317         
2318         //XXX waitcursor(0);
2319 }
2320
2321
2322 /* ******************************* WRITE DXF ***************************** */
2323
2324 #define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
2325
2326 /* A completely wacky function to try and make good
2327 indexed (AutoCAD index) values out of straight rgb 
2328 ones... crazy */
2329
2330 static int rgb_to_dxf_col (float rf, float gf, float bf) 
2331 {
2332         int r= (int) (rf*255.0f);
2333         int g= (int) (gf*255.0f);
2334         int b= (int) (bf*255.0f);
2335         float h,s,v;
2336         int ret;
2337         
2338         /* Grayscale value */
2339         if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51);
2340         /* A nice chroma value */
2341         else {
2342                 rgb_to_hsv (rf,gf,bf,&h,&s,&v);
2343                 
2344                 ret= (int) (10.0f + (h*239.0f));
2345                 CLAMP(ret,10,249);
2346                 
2347                 /* If its whitish make the index odd */
2348                 if (s<.5 || v>.5) if(ret%2) ret++;
2349         }
2350         
2351         return ret;
2352 }
2353
2354 /* And its completely wacky complement */
2355
2356 static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf)
2357 {
2358         float h, s, v;
2359         
2360         /* Grayscale values */
2361         if (cid>=250 && cid <= 255) {
2362                 *rf= *gf= *bf= (float) ((cid-250)*51)/255;
2363                 CLAMP(*rf, 0.0, 1.0);
2364                 CLAMP(*gf, 0.0, 1.0);
2365                 CLAMP(*bf, 0.0, 1.0);
2366                 
2367         /* Pure values */
2368         } else if (cid<10) {
2369                 switch (cid) {
2370                 case 1:
2371                         *rf=1.0;
2372                         *gf=0.0;
2373                         *bf=0.0;
2374                         break;
2375                 case 2:
2376                         *rf=1.0;
2377                         *gf=1.0;
2378                         *bf=0.0;
2379                         break;
2380                 case 3:
2381                         *gf=1.0;
2382                         *rf=0.0;
2383                         *bf=0.0;
2384                         break;
2385                 case 4:
2386                         *rf=0.0;
2387                         *gf=1.0;
2388                         *bf=1.0;
2389                         break;
2390                 case 5:
2391                         *rf=0.0;
2392                         *gf=0.0;
2393                         *bf=1.0;
2394                         break;
2395                 case 6:
2396                         *rf=1.0;
2397                         *gf=0.0;
2398                         *bf=1.0;
2399                         break;
2400                 case 7:
2401                 default:
2402                         *rf= *gf= *bf= 1.0;
2403                         break;
2404                 }
2405         } else {
2406                 /* Get chroma values */
2407                         
2408                 h= (float) (cid-10)/239;
2409                 CLAMP(h, 0.0, 1.0);
2410                 
2411                 /* If its odd make it a bit whitish */
2412                 if (cid%2) { s=.75; v= 0.25; 
2413                 } else {  s= 0.25; v= 0.75;}
2414                 
2415                 hsv_to_rgb (h, s, v, rf, gf, bf);
2416         }
2417 }
2418
2419 static void write_mesh_dxf(FILE *fp, Mesh *me)
2420 {
2421         Material *ma;
2422         MVert *mvert;
2423         MFace *mface;
2424         int a;
2425         char str[32];
2426         
2427         replace_chars(str, me->id.name+2);
2428
2429         write_group(0, "BLOCK");
2430         
2431         write_group(2, str); /* The name */
2432                 
2433         write_group(8, "Meshes"); /* DXF Layer */
2434         write_group(70, "64"); /* DXF block flags */
2435         
2436         write_group(10, "0.0"); /* X of base */
2437         write_group(20, "0.0"); /* Y of base */
2438         write_group(30, "0.0"); /* Z of base */
2439
2440         write_group(3, str); /* The name (again) */
2441         
2442         write_group(0, "POLYLINE"); /* Start the mesh */
2443         write_group(66, "1"); /* Vertices follow flag */
2444         write_group(8,"Meshes"); /* DXF Layer */
2445
2446         if (me->totcol) {
2447                 ma= me->mat[0];
2448                 if(ma) {
2449                         sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2450                         write_group(62, str); /* Color index */
2451                 }
2452         }
2453
2454         write_group(70, "64"); /* Polymesh mesh flag */
2455         
2456         fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */
2457         fprintf(fp, "72\n%d\n", me->totface); /* Total faces */
2458         
2459         /* Write the vertices */
2460         a= me->totvert;
2461         mvert= me->mvert;
2462         while(a--) {
2463                 write_group(0, "VERTEX"); /* Start a new vertex */
2464                 write_group(8, "Meshes"); /* DXF Layer */
2465                 fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */
2466                 fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */
2467                 fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */
2468                 write_group(70, "192"); /* Polymesh vertex flag */
2469                                 
2470                 mvert++;
2471         }
2472
2473         /* Write the face entries */
2474         a= me->totface;
2475         mface= me->mface;
2476         while(a--) {
2477                 write_group(0, "VERTEX"); /* Start a new face */
2478                 write_group(8, "Meshes");
2479         
2480                 /* Write a face color */
2481                 if (me->totcol) {
2482                         ma= me->mat[(int)mface->mat_nr];
2483                         if(ma) {
2484                                 sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2485                                 write_group(62, str); /* Color index */
2486                         }
2487                 }
2488                 else write_group(62, "254"); /* Color Index */
2489
2490                 /* Not sure what this really corresponds too */
2491                 write_group(10, "0.0"); /* X of base */
2492                 write_group(20, "0.0"); /* Y of base */
2493                 write_group(30, "0.0"); /* Z of base */
2494         
2495                 write_group(70, "128"); /* Polymesh face flag */
2496         
2497                 if(mface->v4) {
2498                         fprintf (fp, "71\n%d\n", mface->v1+1);
2499                         fprintf (fp, "72\n%d\n", mface->v2+1);
2500                         fprintf (fp, "73\n%d\n", mface->v3+1);
2501                         fprintf (fp, "74\n%d\n", mface->v4+1);
2502                 } else {
2503                         fprintf (fp, "71\n%d\n", mface->v1+1);
2504                         fprintf (fp, "72\n%d\n", mface->v2+1);
2505                         fprintf (fp, "73\n%d\n", mface->v3+1);
2506                 }
2507                 mface++;
2508         }
2509
2510         write_group(0, "SEQEND");       
2511         
2512         write_group(0, "ENDBLK");
2513 }
2514
2515 static void write_object_dxf(FILE *fp, Object *ob, int layer)
2516 {
2517         ID *id;
2518         char str[32];
2519
2520         id= ob->data;
2521
2522         write_group(0, "INSERT"); /* Start an insert group */
2523         
2524         sprintf(str, "%d", layer);
2525         write_group(8, str);
2526
2527         replace_chars(str, id->name+2);
2528         write_group(2, str);
2529
2530         fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */
2531         fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */
2532         fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */
2533         
2534         fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */
2535         fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */
2536         fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */
2537         
2538         fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */
2539 }
2540
2541 void write_dxf(struct Scene *scene, char *str)
2542 {
2543         Mesh *me;
2544         Base *base;
2545         FILE *fp;
2546         
2547         if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2548         if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2549         if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
2550
2551         if (!during_script()) {
2552                 if (BLI_exists(str))
2553                         ; //XXX if(saveover(str)==0)
2554                         //      return;
2555         }
2556
2557         fp= fopen(str, "w");
2558         
2559         if(fp==NULL && !during_script()) {
2560                 //XXX error("Can't write file");
2561                 return;
2562         }
2563         strcpy(temp_dir, str);
2564         
2565         //XXX waitcursor(1);
2566         
2567         /* The header part of the DXF */
2568         
2569         write_group(0, "SECTION");
2570     write_group(2, "HEADER");
2571         write_group(0, "ENDSEC");
2572
2573         /* The blocks part of the DXF */
2574         
2575         write_group(0, "SECTION");
2576     write_group(2, "BLOCKS");
2577
2578     
2579         /* only write meshes we're using in this scene */
2580         flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2581         
2582         for(base= scene->base.first; base; base= base->next)
2583                 if(base->object->type== OB_MESH)
2584                         ((ID *)base->object->data)->flag |= LIB_DOIT;   
2585         
2586         /* Write all the meshes */
2587         me= G.main->mesh.first;
2588         while(me) {
2589                 if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2590                         write_mesh_dxf(fp, me);
2591                 }
2592                 me= me->id.next;
2593         }
2594
2595         write_group(0, "ENDSEC");
2596
2597         /* The entities part of the DXF */
2598         
2599         write_group(0, "SECTION");
2600     write_group(2, "ENTITIES");
2601
2602         /* Write all the mesh objects */
2603         base= scene->base.first;
2604         while(base) {
2605                 if(base->object->type== OB_MESH) {
2606                         write_object_dxf(fp, base->object, base->lay);
2607                 }
2608                 base= base->next;
2609         }
2610
2611         write_group(0, "ENDSEC");
2612         
2613         /* Thats all */
2614         
2615         write_group(0, "EOF");
2616         fclose(fp);
2617         
2618         //XXX waitcursor(0);
2619 }
2620
2621
2622 static int dxf_line= 0;
2623 static FILE *dxf_fp= NULL;
2624
2625 /* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual
2626  * Studio/VC98/include\ctype.h(268) : see previous definition of
2627  * 'iswspace' */
2628 #define ton_iswspace(c) (c==' '||c=='\n'||c=='\t')
2629
2630 static void clean_wspace (char *str) 
2631 {
2632         char *from, *to;
2633         char t;
2634         
2635         from= str;
2636         to=str;
2637         
2638         while (*from!=0) {
2639                 t= *from;
2640                 *to= t;
2641                 
2642                 if(!ton_iswspace(*from)) to++;
2643                 from++;
2644         }
2645         *to=0;
2646 }
2647
2648 static int all_wspace(char *str)
2649 {
2650         while(*str != 0) {
2651                 if (!ton_iswspace(*str)) return 0;
2652                 str++;
2653         }
2654
2655         return 1;
2656 }
2657
2658 static int all_digits(char *str)
2659 {
2660         while(*str != 0) {
2661                 if (!isdigit(*str)) return 0;
2662                 str++;
2663         }
2664
2665         return 1;
2666 }
2667
2668 static int dxf_get_layer_col(char *layer) 
2669 {
2670         return 1;
2671 }
2672
2673 static int dxf_get_layer_num(Scene *scene, char *layer)
2674 {
2675         int ret = 0;
2676
2677         if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer);
2678         if (ret == 0) ret = scene->lay;
2679
2680         return ret;
2681 }
2682
2683 static void dos_clean(char *str)
2684 {
2685         while (*str) {
2686                 if (*str == 0x0d) {
2687                         *str='\n';
2688                         *(++str)= 0;
2689                         break;
2690                 }
2691                 str++;
2692         }       
2693 }
2694
2695 static void myfgets(char *str, int len, FILE *fp)
2696 {
2697         char c;
2698         
2699         while(len>0 && (c=getc(dxf_fp)) ) {
2700                 *str= c;
2701                 str++;
2702                 len--;
2703                 /* three types of enters, \n \r and \r\n  */
2704                 if(c == '\n') break;
2705                 if(c=='\r') {
2706                         c= getc(dxf_fp);                                // read the linefeed from stream
2707                         if(c != 10) ungetc(c, dxf_fp);  // put back, if it's not one...
2708                         break;
2709                 }
2710         }
2711 }
2712
2713 static int read_groupf(char *str) 
2714 {
2715         short c;
2716         int ret=-1;
2717         char tmp[256];
2718         
2719         strcpy(str, " ");
2720
2721         while ((c=getc(dxf_fp)) && ton_iswspace(c));
2722         ungetc(c, dxf_fp);
2723         if (c==EOF) return -1;
2724         
2725         myfgets(tmp, 255, dxf_fp);
2726         
2727         dos_clean(tmp);
2728
2729         if(sscanf(tmp, "%d\n", &ret)!=1) return -2;
2730                 
2731         myfgets(tmp, 255, dxf_fp);
2732
2733         dos_clean(tmp);
2734
2735         if (!all_wspace(tmp)) {
2736                 if (sscanf(tmp, "%s\n", str)!=1) return -2;
2737         }
2738         
2739         clean_wspace(str);
2740         dxf_line+=2;
2741         
2742         return ret;
2743 }
2744
2745 //XXX error() is now printf until we have a callback error
2746 #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;}
2747
2748 #define read_group(id,str) {id= read_groupf(str); id_test(id);}
2749
2750 #define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0)
2751 #define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0)
2752 #define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;}
2753
2754 static int id;
2755 static char val[256];
2756
2757 static short error_exit=0;
2758 static short hasbumped=0;
2759
2760 static int is_dxf(char *str)
2761 {       
2762         dxf_line=0;
2763         
2764         dxf_fp= fopen(str, "r");
2765         if (dxf_fp==NULL) return 0;
2766
2767         id= read_groupf(val);
2768         if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1;
2769         
2770         fclose(dxf_fp);
2771         
2772         return 0;
2773 }
2774
2775 /* NOTES ON THE READER */ 
2776 /*
2777         --
2778         It turns out that most DXF writers like (LOVE) to
2779         write meshes as a long string of 3DFACE entities.
2780         This means the natural way to read a DXF file
2781         (every entity corresponds to an object) is completely
2782         unusable, reading in 10,000 faces each as an
2783         object just doesn't cut it. Thus the 3DFACE
2784         entry reader holds state, and only finalizes to
2785         an object when a) the layer name changes, b) the
2786         entry type changes, c) we are done reading.
2787
2788         PS... I decided to do the same thing with LINES, 
2789         apparently the same thing happens sometimes as
2790         well.
2791
2792         PPS... I decided to do the same thing with everything.
2793         Now it is all really nasty and should be rewritten. 
2794         --
2795         
2796         Added circular and elliptical arcs and lwpolylines.
2797         These are all self-contained and have the size known
2798         in advance, and so I haven't used the held state. -- martin
2799 */
2800
2801 static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer) 
2802 {
2803         Material *ma;
2804         
2805         if (!me) return;
2806         
2807         if(ob) ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
2808         if(ob) ob->actcol= 1;
2809
2810         me->totcol= 1;
2811         me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
2812         
2813         if (color[0]<0) {
2814                 if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]);
2815                 color[0]= color[1]= color[2]= 0.8f;
2816         }                                                                                               
2817                                                 
2818         ma= G.main->mat.first;
2819         while(ma) {
2820                 if(ma->mtex[0]==0) {
2821                         if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) {
2822                                 me->mat[0]= ma;
2823                                 ma->id.us++;
2824                                 break;
2825                         }
2826                 }
2827                 ma= ma->id.next;
2828         }
2829         if(ma==0) {
2830                 ma= add_material("ext");
2831                 me->mat[0]= ma;
2832                 ma->r= color[0];
2833                 ma->g= color[1];
2834                 ma->b= color[2];
2835                 automatname(ma);
2836         }
2837 }
2838
2839         /* General DXF vars */
2840 static float cent[3]={0.0, 0.0, 0.0};
2841 static char layname[32]="";
2842 static char entname[32]="";
2843 static float color[3]={-1.0, -1.0, -1.0};
2844 static float *vcenter;
2845 static float zerovec[3]= {0.0, 0.0, 0.0};
2846
2847 #define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0
2848
2849
2850 static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob)
2851 {
2852         Mesh *me = NULL;
2853         Object *ob;
2854         
2855         if (!noob) {
2856                 *o = add_object(scene, OB_MESH);
2857                 ob = *o;
2858                 
2859                 if (strlen(entname)) new_id(&G.main->object, (ID *)ob, entname);
2860                 else if (strlen(layname)) new_id(&G.main->object, (ID *)ob,  layname);
2861
2862                 if (strlen(layname)) ob->lay= dxf_get_layer_num(scene, layname);
2863                 else ob->lay= scene->lay;
2864                 // not nice i know... but add_object() sets active base, which needs layer setting too (ton)
2865                 scene->basact->lay= ob->lay;
2866
2867                 *m = ob->data;
2868                 me= *m;
2869
2870                 vcenter= ob->loc;
2871         } 
2872         else {
2873                 *o = NULL;
2874                 *m = add_mesh("Mesh");
2875
2876                 me = *m;
2877                 ob = *o;
2878                 
2879                 ((ID *)me)->us=0;
2880
2881                 if (strlen(entname)) new_id(&G.main->mesh, (ID *)me, entname);
2882                 else if (strlen(layname)) new_id(&G.main->mesh, (ID *)me, layname);
2883
2884                 vcenter = zerovec;
2885         }
2886         me->totvert=0;
2887         me->totface=0;
2888         me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 0);
2889         me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
2890 }
2891
2892 static void dxf_read_point(Scene *scene, int noob) {    
2893         /* Blender vars */
2894         Object *ob;
2895         Mesh *me;
2896         MVert *mvert;
2897         
2898         reset_vars;
2899
2900         read_group(id, val);                                                            
2901         while(id!=0) {
2902                 if (id==8) {
2903                         BLI_strncpy(layname, val, sizeof(layname));
2904                 } else if (id==10) {
2905                         cent[0]= (float) atof(val);
2906                 } else if (id==20) {
2907                         cent[1]= (float) atof(val);
2908                 } else if (id==30) {
2909                         cent[2]= (float) atof(val);
2910                 } else if (id==60) {
2911                         /* short invisible= atoi(val); */
2912                 } else if (id==62) {
2913                         int colorid= atoi(val);
2914                                                         
2915                         CLAMP(colorid, 1, 255);
2916                         dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
2917                 }
2918                 read_group(id, val);                                                            
2919         }
2920
2921         dxf_get_mesh(scene, &me, &ob, noob);
2922         me->totvert= 1;
2923         me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
2924         CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
2925         
2926         dxf_add_mat (ob, me, color, layname);                                   
2927
2928         mvert= me->mvert;
2929         mvert->co[0]= mvert->co[1]= mvert->co[2]= 0;
2930                 
2931         if (ob) VECCOPY(ob->loc, cent);
2932
2933         hasbumped=1;
2934 }
2935
2936         /* Line state vars */
2937 static Object *linehold=NULL;
2938 static Mesh *linemhold=NULL;
2939
2940 static char oldllay[32];
2941 static short lwasline=0; /* last was face 3d? */
2942
2943 static void dxf_close_line(void)
2944 {
2945         linemhold=NULL;
2946         if (linehold==NULL) return;
2947         
2948         linehold=NULL;
2949 }
2950
2951 static void dxf_read_line(Scene *scene, int noob) {     
2952         /* Entity specific vars */
2953         float epoint[3]={0.0, 0.0, 0.0};
2954         short vspace=0; /* Whether or not coords are relative */
2955