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