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