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