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