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