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