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