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