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