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