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