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