3 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20 * All rights reserved.
22 * The Original Code is: all of this file.
26 * Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline
27 * Copyright (C) 2004 by Etheract Software Labs
29 * ***** END GPL LICENSE BLOCK *****
31 * eigen videoscape formaat:
47 5 of 11 (curve of surf)
51 mat[0][0] mat[0][1] mat[0][2] mat[0][3]
52 mat[1][0] mat[1][1] mat[1][2] mat[1][3]
61 (als type==nurb) x y z w
64 (als type==bez) xyz xyz xyz h1 h2 h3
72 #include <ctype.h> /* isdigit, isspace */
85 #include "MEM_guardedalloc.h"
87 #include "DNA_object_types.h"
88 #include "DNA_mesh_types.h"
89 #include "DNA_meshdata_types.h"
90 #include "DNA_material_types.h"
91 #include "DNA_lamp_types.h"
92 #include "DNA_curve_types.h"
93 #include "DNA_image_types.h"
94 #include "DNA_camera_types.h"
95 #include "DNA_scene_types.h"
96 #include "DNA_view3d_types.h"
97 #include "DNA_userdef_types.h"
99 #include "BKE_bad_level_calls.h"
100 #include "BKE_utildefines.h"
101 #include "BLI_blenlib.h"
102 #include "BLI_arithb.h"
103 #include "BLI_editVert.h"
105 #include "BKE_global.h"
106 #include "BKE_main.h"
107 #include "BKE_mesh.h"
108 #include "BKE_library.h"
109 #include "BKE_global.h"
110 #include "BKE_object.h"
111 #include "BKE_material.h"
112 #include "BKE_exotic.h"
113 /* #include "BKE_error.h" */
114 #include "BKE_screen.h"
115 #include "BKE_displist.h"
116 #include "BKE_DerivedMesh.h"
117 #include "BKE_curve.h"
118 #include "BKE_customdata.h"
120 #include "BPY_extern.h"
126 static int is_dxf(char *str);
127 static void dxf_read(char *filename);
128 static int is_stl(char *str);
130 static int is_stl_ascii(char *str)
136 fpSTL = fopen(str, "rb");
137 if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
138 { fclose(fpSTL); return 0; }
140 for (i=0; i < numread; ++i) {
141 /* if bit 8 is set we assume binary */
142 if (buffer[i] & 0x80)
143 { fclose(fpSTL); return 0; }
147 if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) )
148 { fclose(fpSTL); return 0; }
155 static int is_stl(char *str)
159 if ( (str[i] !='s') && (str[i] !='S'))
162 if ( (str[i] !='t') && (str[i] !='T'))
165 if ( (str[i] !='l') && (str[i] !='L'))
171 #define READSTLVERT { \
172 if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
173 char error_msg[255]; \
174 MEM_freeN(vertdata); \
175 MEM_freeN(facedata); \
177 sprintf(error_msg, "Problems reading face %d!", i); \
182 if (G.order==B_ENDIAN) { \
183 SWITCH_INT(mvert->co[0]); \
184 SWITCH_INT(mvert->co[1]); \
185 SWITCH_INT(mvert->co[2]); \
190 static void simple_vertex_normal_blend(short *no, short *ble)
192 if(no[0]==0 && no[1]==0 && no[2]==0) {
196 no[0]= (2*no[0] + ble[0])/3;
197 no[1]= (2*no[1] + ble[1])/3;
198 no[2]= (2*no[2] + ble[2])/3;
202 static void mesh_add_normals_flags(Mesh *me)
204 MVert *v1, *v2, *v3, *v4;
211 for(a=0; a<me->totface; a++, mface++) {
212 v1= me->mvert+mface->v1;
213 v2= me->mvert+mface->v2;
214 v3= me->mvert+mface->v3;
215 v4= me->mvert+mface->v4;
217 CalcNormFloat(v1->co, v2->co, v3->co, nor);
218 sno[0]= 32767.0*nor[0];
219 sno[1]= 32767.0*nor[1];
220 sno[2]= 32767.0*nor[2];
222 simple_vertex_normal_blend(v1->no, sno);
223 simple_vertex_normal_blend(v2->no, sno);
224 simple_vertex_normal_blend(v3->no, sno);
226 simple_vertex_normal_blend(v4->no, sno);
228 mface->edcode= ME_V1V2|ME_V2V3;
232 static void read_stl_mesh_binary(char *str)
237 MVert *mvert, *vertdata;
238 MFace *mface, *facedata;
239 unsigned int numfacets = 0, i, j, vertnum;
240 unsigned int maxmeshsize, nummesh, lastmeshsize;
241 unsigned int totvert, totface;
243 fpSTL= fopen(str, "rb");
245 error("Can't read file");
249 fseek(fpSTL, 80, SEEK_SET);
250 fread(&numfacets, 4*sizeof(char), 1, fpSTL);
251 if (G.order==B_ENDIAN) {
252 SWITCH_INT(numfacets);
255 maxmeshsize = MESH_MAX_VERTS/3;
257 nummesh = (numfacets / maxmeshsize) + 1;
258 lastmeshsize = numfacets % maxmeshsize;
261 for (j=0; j < nummesh; ++j) {
263 if (j == nummesh-1) {
264 totface = lastmeshsize;
267 totface = maxmeshsize;
269 totvert = 3 * totface;
271 vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
272 facedata = MEM_callocN(totface*sizeof(MFace), "mface");
277 for (i=0; i < totface; i++) {
278 fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
286 mface->v1 = vertnum++;
287 mface->v2 = vertnum++;
288 mface->v3 = vertnum++;
291 fseek(fpSTL, 2, SEEK_CUR);
294 ob= add_object(OB_MESH);
296 me->totvert = totvert;
297 me->totface = totface;
298 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
300 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
303 mesh_add_normals_flags(me);
313 #define STLALLOCERROR { \
314 char error_msg[255]; \
316 sprintf(error_msg, "Can't allocate storage for %d faces!", \
317 numtenthousand * 10000); \
322 #define STLBAILOUT(message) { \
323 char error_msg[255]; \
326 sprintf(error_msg, "Line %d: %s", linenum, message); \
331 #define STLREADLINE { \
332 if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
336 #define STLREADVERT { \
338 if ( !(cp = strstr(buffer, "vertex")) && \
339 !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
340 vp = vertdata + 3 * totvert; \
341 if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
342 STLBAILOUT("Bad vertex!"); \
345 static void read_stl_mesh_ascii(char *str)
348 char buffer[2048], *cp;
353 float *vertdata, *vp;
354 unsigned int numtenthousand, linenum;
355 unsigned int i, vertnum;
356 unsigned int totvert, totface;
358 /* ASCII stl sucks ... we don't really know how many faces there
359 are until the file is done, so lets allocate faces 10000 at a time */
361 fpSTL= fopen(str, "r");
363 error("Can't read file");
367 /* we'll use the standard malloc/realloc for now ...
368 * lets allocate enough storage to hold 10000 triangles,
369 * i.e. 30000 verts, i.e., 90000 floats.
372 vertdata = malloc(numtenthousand*3*30000*sizeof(float)); // uses realloc!
373 if (!vertdata) STLALLOCERROR;
376 /* Get rid of the first line */
382 /* Read in the next line */
385 /* lets check if this is the end of the file */
386 if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") )
389 /* Well, guess that wasn't the end, so lets make
390 * sure we have enough storage for some more faces
392 if ( (totface) && ( (totface % 10000) == 0 ) ) {
394 vertdata = realloc(vertdata,
395 numtenthousand*3*30000*sizeof(float));
396 if (!vertdata) STLALLOCERROR;
399 /* Don't read normal, but check line for proper syntax anyway
401 if ( !(cp = strstr(buffer, "facet")) &&
402 !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
403 if ( !(strstr(cp+5, "normal")) &&
404 !(strstr(cp+5, "NORMAL")) ) STLBAILOUT("Bad normal line!");
406 /* Read in what should be the outer loop line
409 if ( !(cp = strstr(buffer, "outer")) &&
410 !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
411 if ( !(strstr(cp+5, "loop")) &&
412 !(strstr(cp+5, "LOOP")) ) STLBAILOUT("Bad outer loop!");
414 /* Read in the face */
419 /* Read in what should be the endloop line
422 if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") )
423 STLBAILOUT("Bad endloop!");
425 /* Read in what should be the endfacet line
428 if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") )
429 STLBAILOUT("Bad endfacet!");
431 /* Made it this far? Increment face count */
436 /* OK, lets create our mesh */
437 ob = add_object(OB_MESH);
440 me->totface = totface;
441 me->totvert = totvert;
442 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
444 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
447 /* Copy vert coords and create topology */
451 for (i=0; i < totface; ++i) {
452 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
457 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
462 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
471 mesh_add_normals_flags(me);
482 static void read_videoscape_mesh(char *str)
490 float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
491 unsigned int color[32], col;
492 int totcol, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
496 fp= fopen(str, "rb");
498 error("Can't read file");
502 fscanf(fp, "%40s", s);
504 fscanf(fp, "%d\n", &verts);
511 if(verts>MESH_MAX_VERTS) {
512 error("too many vertices");
517 INIT_MINMAX(min, max);
518 vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
520 for(a=0; a<verts; a++) {
521 fscanf(fp, "%f %f %f", vd, vd+1, vd+2);
522 DO_MINMAX(vd, min, max);
526 /* count faces and colors */
527 for(a=0; a<32; a++) color[a]= 0;
531 end= fscanf(fp,"%d", &poly);
534 if(poly==3) tottria++;
535 else if(poly==4) totquad++;
538 for(a=0;a<poly;a++) {
539 end= fscanf(fp,"%d", &nr);
544 end= fscanf(fp,"%i\n", &col);
546 for(a=0; a<totcol; a++) {
547 if(color[a]==col) break;
549 if(a>=totcol && totcol<32) {
556 ob= add_object(OB_MESH);
559 me->totface= totedge+tottria+totquad;
561 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
563 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
568 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
569 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
571 ob->totcol= (unsigned char) me->totcol;
576 for(a=0; a<totcol; a++) {
577 ma= G.main->mat.first;
580 col= rgb_to_cpack(ma->r, ma->g, ma->b);
590 ma= add_material("ext");
592 cpack_to_rgb(color[a], cent, cent+1, cent+2);
602 cent[0]= (min[0]+max[0])/2.0f;
603 cent[1]= (min[1]+max[1])/2.0f;
604 cent[2]= (min[2]+max[2])/2.0f;
605 VECCOPY(ob->loc, cent);
611 VecSubf(mvert->co, vd, cent);
620 fscanf(fp, "%40s", s);
621 fscanf(fp, "%d\n", &verts);
623 for(a=0;a<verts;a++) {
624 fscanf(fp, "%f %f %f", &ftemp, &ftemp, &ftemp);
630 end= fscanf(fp,"%d", &poly);
633 if(poly==3 || poly==4) {
634 fscanf(fp,"%d", &nr);
635 mface->v1= MIN2(nr, me->totvert-1);
636 fscanf(fp,"%d", &nr);
637 mface->v2= MIN2(nr, me->totvert-1);
638 fscanf(fp,"%d", &nr);
639 mface->v3= MIN2(nr, me->totvert-1);
641 if( fscanf(fp,"%d", &nr) <=0 ) break;
642 mface->v4= MIN2(nr, me->totvert-1);
645 test_index_face(mface, NULL, 0, poly);
650 if( fscanf(fp,"%d", &nr0) <=0) break;
652 for(b=1; b<poly; b++) {
653 end= fscanf(fp,"%d", &nr);
655 nr= MIN2(nr, me->totvert-1);
667 end= fscanf(fp,"%i", &col);
671 for(b=0; b<totcol; b++) {
673 (mface-1)->mat_nr= b;
683 mesh_add_normals_flags(me);
689 static void read_radiogour(char *str)
696 float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
697 unsigned int *colv, *colf, *colvertdata;
698 int itemp, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
702 fp= fopen(str, "rb");
704 error("Can't read file");
708 fscanf(fp, "%40s", s);
710 fscanf(fp, "%d\n", &verts);
717 if(verts>MESH_MAX_VERTS) {
718 error("too many vertices");
723 INIT_MINMAX(min, max);
724 vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
725 colv= colvertdata= MEM_mallocN(verts*sizeof(float), "coldata");
727 for(a=0; a<verts; a++) {
728 fscanf(fp, "%f %f %f %i", vd, vd+1, vd+2, colv);
729 DO_MINMAX(vd, min, max);
737 end= fscanf(fp,"%d", &poly);
740 if(poly==3) tottria++;
741 else if(poly==4) totquad++;
744 for(a=0;a<poly;a++) {
745 end= fscanf(fp,"%d", &nr);
752 if(totedge+tottria+totquad>MESH_MAX_VERTS) {
753 printf(" var1: %d, var2: %d, var3: %d \n", totedge, tottria, totquad);
754 error("too many faces");
756 MEM_freeN(colvertdata);
762 ob= add_object(OB_MESH);
765 me->totface= totedge+tottria+totquad;
768 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
770 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
775 cent[0]= (min[0]+max[0])/2.0f;
776 cent[1]= (min[1]+max[1])/2.0f;
777 cent[2]= (min[2]+max[2])/2.0f;
778 VECCOPY(ob->loc, cent);
784 VecSubf(mvert->co, vd, cent);
793 fscanf(fp, "%40s", s);
794 fscanf(fp, "%d\n", &verts);
795 for(a=0;a<verts;a++) {
796 fscanf(fp, "%f %f %f %i", &ftemp, &ftemp, &ftemp, &itemp);
802 end= fscanf(fp,"%d", &poly);
805 if(poly==3 || poly==4) {
806 fscanf(fp,"%d", &nr);
807 mface->v1= MIN2(nr, me->totvert-1);
808 fscanf(fp,"%d", &nr);
809 mface->v2= MIN2(nr, me->totvert-1);
810 fscanf(fp,"%d", &nr);
811 mface->v3= MIN2(nr, me->totvert-1);
813 if( fscanf(fp,"%d", &nr) <=0 ) break;
814 mface->v4= MIN2(nr, me->totvert-1);
817 test_index_face(mface, NULL, 0, poly);
822 if( fscanf(fp,"%d", &nr0) <=0) break;
824 for(b=1; b<poly; b++) {
825 end= fscanf(fp,"%d", &nr);
827 nr= MIN2(nr, me->totvert-1);
836 mface->flag= ME_SMOOTH;
843 /* mcol is 4 colors per face */
844 me->mcol= MEM_mallocN(4*sizeof(int)*me->totface, "mcol");
845 colf= (unsigned int *)me->mcol;
851 colf[0]= colvertdata[mface->v1];
852 colf[1]= colvertdata[mface->v2];
853 colf[2]= colvertdata[mface->v3];
854 colf[3]= colvertdata[mface->v4];
860 MEM_freeN(colvertdata);
866 mesh_add_normals_flags(me);
873 static void read_videoscape_lamp(char *str)
882 fp= fopen(str, "rb");
884 error("Can't read file");
888 fscanf(fp, "%40s", s);
889 fscanf(fp, "%d\n", &tot);
892 ob= add_object(OB_LAMP);
895 fscanf(fp, "%d\n", &val);
897 if(la->type==1) la->type= LA_SPOT;
898 else if(la->type==2) la->type= LA_SUN;
900 fscanf(fp, "%f %f\n", &la->spotsize, &la->spotblend);
902 fscanf(fp, "%f %f %f %f\n", &la->r, &la->g, &la->b, &la->energy);
904 fscanf(fp, "%f %f %f\n", ob->loc, ob->loc+1, ob->loc+2);
905 val= fscanf(fp, "%f %f %f\n", vec, vec+1, vec+2);
906 vectoquat(vec, 5, 2, q1);
907 QuatToEul(q1, ob->rot);
915 static void read_videoscape_nurbs(char *str)
923 float tmat[4][4], omat[3][3], imat[3][3], mat[3][3];
924 int a, tot, type, val;
927 fp= fopen(str, "rb");
929 error("Can't read file");
933 fscanf(fp, "%40s", s);
934 fscanf(fp, "%d\n", &type);
936 if(type==5) ob= add_object(OB_SURF);
937 else ob= add_object(OB_CURVE);
940 fscanf(fp, "%d\n", &tot);
941 fscanf(fp, "%d %d\n", &type, &val);
943 cu->ext1= 0.002f*type;
944 cu->ext2= 0.002f*val;
946 for(a=0; a<4; a++) fscanf(fp, "%e %e %e %e\n", tmat[a], tmat[a]+1, tmat[a]+2, tmat[a]+3);
948 VECCOPY(ob->loc, tmat[3]);
950 Mat3CpyMat4(omat, tmat);
951 Mat3ToEul(omat, ob->rot);
952 EulToMat3(ob->rot, mat);
954 Mat3MulMat3((float ( * )[3])tmat, imat, omat);
957 nu= (Nurb*)MEM_callocN(sizeof(Nurb),"nu from exotic");
958 BLI_addtail(&cu->nurb, nu);
960 fscanf(fp, "%d\n", &type);
963 fscanf(fp, "%d %d\n", &type, &val);
964 nu->pntsu= type; nu->pntsv= val;
965 fscanf(fp, "%d %d\n", &type, &val);
966 nu->resolu= type; nu->resolv= val;
967 fscanf(fp, "%d %d\n", &type, &val);
968 nu->orderu= type; nu->orderv= val;
969 fscanf(fp, "%d %d\n", &type, &val);
970 nu->flagu= type; nu->flagv= val;
972 if( (nu->type & 7)==CU_BEZIER) {
974 nu->bezt= bezt= MEM_callocN(a*sizeof(BezTriple), "bezt from exotic");
976 fscanf(fp, "%f %f %f ", bezt->vec[0], bezt->vec[0]+1, bezt->vec[0]+2);
977 Mat4MulVecfl(tmat, bezt->vec[0]);
978 fscanf(fp, "%f %f %f ", bezt->vec[1], bezt->vec[1]+1, bezt->vec[1]+2);
979 Mat4MulVecfl(tmat, bezt->vec[1]);
980 fscanf(fp, "%f %f %f ", bezt->vec[2], bezt->vec[2]+1, bezt->vec[2]+2);
981 Mat4MulVecfl(tmat, bezt->vec[2]);
982 fscanf(fp, "%d %d\n", &type, &val);
989 a= nu->pntsu*nu->pntsv;
991 nu->bp= bp= MEM_callocN(a*sizeof(BPoint), "bp from exotic");
993 fscanf(fp, "%f %f %f %f\n", bp->vec, bp->vec+1, bp->vec+2, bp->vec+3);
994 Mat4MulVecfl(tmat, bp->vec);
999 nu->knotsu= MEM_mallocN(sizeof(float)*val, "knots");
1000 for(a=0; a<val; a++) fscanf(fp, "%f\n", nu->knotsu+a);
1004 nu->knotsv= MEM_mallocN(sizeof(float)*val, "knots");
1005 for(a=0; a<val; a++) fscanf(fp, "%f\n", nu->knotsv+a);
1009 BLI_remlink(&cu->nurb, nu);
1017 static void read_videoscape(char *str)
1021 unsigned short numlen;
1022 char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXFILE];
1027 file= open(name, O_BINARY|O_RDONLY);
1030 read(file, &type, 4);
1033 if(type==DDG1) read_videoscape_mesh(name);
1034 else if(type==DDG2) read_videoscape_lamp(name);
1035 else if(type==DDG3) read_videoscape_nurbs(name);
1038 val = BLI_stringdec(name, head, tail, &numlen);
1039 BLI_stringenc(name, head, tail, numlen, val + 1);
1045 /* ***************** INVENTOR ******************* */
1048 #define IV_MAXSTACK 3000000
1049 #define IV_MAXFIELD 10
1050 #define IV_MAXCOL 16
1052 static float *iv_data_stack;
1053 static float ivcolors[IV_MAXCOL][3];
1054 static Object *ivsurf;
1055 static ListBase ivbase;
1058 struct IvNode *next, *prev;
1060 char *fieldname[IV_MAXFIELD];
1061 int datalen[IV_MAXFIELD];
1062 float *data[IV_MAXFIELD];
1065 static int iv_curcol=0;
1067 static int iv_colornumber(struct IvNode *iv)
1069 float *fp, fr = 0.0, fg = 0.0, fb = 0.0;
1073 /* search back to last material */
1075 if( strcmp(iv->nodename, "Material")==0) {
1077 if(fp==0) fp= iv->data[1];
1085 else if( strcmp(iv->nodename, "BaseColor")==0) {
1092 else if( strcmp(iv->nodename, "PackedColor")==0) {
1093 cp= (char *)iv->data[0];
1103 if(iv->datalen[0]<3) return 0;
1105 for(a=0; a<iv_curcol; a++) {
1107 if(ivcolors[a][0]== fr)
1108 if(ivcolors[a][1]== fg)
1109 if(ivcolors[a][2]== fb) return a+1
1113 if(a>=IV_MAXCOL) a= IV_MAXCOL-1;
1122 static int iv_finddata(struct IvNode *iv, char *field, int fieldnr)
1124 /* search for "field", count data size and make datablock. return skipdata */
1126 int len, stackcount, skipdata=0;
1127 char *cpa, terminator, str[64];
1132 cpa= iv->nodename+1;
1133 while( *cpa != '}' ) {
1135 if( *cpa == *field ) {
1136 if( strncmp(cpa, field, len)==0 ) {
1137 iv->fieldname[fieldnr]= cpa;
1139 /* read until first character */
1146 while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) cpa++;
1152 else terminator= 13;
1157 while( *cpa!=terminator && *cpa != '}' ) {
1159 /* in fact, isdigit should include the dot and minus */
1160 if( (isdigit(*cpa) || *cpa=='.' || *cpa=='-') && (isspace(cpa[-1]) || cpa[-1]==0 || cpa[-1]==',') ) {
1162 memcpy(str, cpa, 16);
1165 sscanf(str, "%x", (int *)fp);
1168 /* atof doesn't stop after the first float
1169 * in a long string at Windows... so we copy
1170 * the float to a new string then atof... */
1171 char *cpa_temp = strpbrk(cpa, ", \n");
1176 memcpy(str, cpa, i);
1179 *fp= (float) atof(str);
1184 if(stackcount>=IV_MAXSTACK) {
1185 printf("stackoverflow in IV read\n");
1194 iv->datalen[fieldnr]= stackcount;
1196 iv->data[fieldnr]= MEM_mallocN(sizeof(float)*stackcount, "iv_finddata");
1197 memcpy(iv->data[fieldnr], iv_data_stack, sizeof(float)*stackcount);
1199 else iv->data[fieldnr]= 0;
1211 static void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype)
1213 /* write in data: baseadr with offset index (and number nr) */
1219 fp= baseadr+coordtype*ofs;
1228 static void read_inventor(char *str, struct ListBase *listb)
1230 struct IvNode *iv, *ivp, *ivn;
1231 char *maindata, *md, *cpa;
1232 float *index, *data, *fp;
1233 int file, filelen, count, lll, face, nr = 0;
1234 int skipdata, ok, a, b, tot, first, colnr, coordtype, polytype, *idata;
1235 struct DispList *dl;
1237 ivbase.first= ivbase.last= 0;
1241 file= open(str, O_BINARY|O_RDONLY);
1243 error("Can't read file\n");
1247 filelen= BLI_filesize(file);
1253 maindata= MEM_mallocN(filelen, "leesInventor");
1254 read(file, maindata, filelen);
1257 iv_data_stack= MEM_mallocN(sizeof(float)*IV_MAXSTACK, "ivstack");
1259 /* preprocess: remove comments */
1262 while(count<filelen) {
1263 if( *md=='#' ) { /* comment */
1264 while( *md!=13 && *md!=10) { /* enters */
1268 if(count>=filelen) break;
1276 /* now time to collect: which are the nodes and fields? */
1279 while(count<filelen) {
1280 if( *md=='{' ) { /* read back */
1283 while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) { /* remove spaces/enters/tab */
1288 while( *cpa>32 && *cpa<128) cpa--;
1294 iv= MEM_callocN(sizeof(struct IvNode), "leesInventor");
1297 if(strcmp(cpa, "Coordinate3")==0 || strcmp(cpa, "Coordinate4")==0) {
1298 skipdata= iv_finddata(iv, "point", 0);
1301 else if(strcmp(cpa, "VertexProperty")==0) {
1302 skipdata= iv_finddata(iv, "vertex", 0);
1305 else if(strcmp(cpa, "IndexedLineSet")==0) {
1306 skipdata= iv_finddata(iv, "coordIndex", 0);
1309 else if(strcmp(cpa, "IndexedTriangleMesh")==0) {
1310 skipdata= iv_finddata(iv, "coordIndex", 0);
1313 else if(strcmp(cpa, "IndexedFaceSet")==0) {
1314 skipdata= iv_finddata(iv, "coordIndex", 0);
1317 else if(strcmp(cpa, "FaceSet")==0) {
1318 skipdata= iv_finddata(iv, "numVertices", 0);
1321 else if(strcmp(cpa, "Material")==0) {
1322 iv_finddata(iv, "diffuseColor", 0);
1323 iv_finddata(iv, "ambientColor", 1);
1326 else if(strcmp(cpa, "BaseColor")==0) {
1327 iv_finddata(iv, "rgb", 0);
1330 else if(strcmp(cpa, "PackedColor")==0) {
1331 iv_finddata(iv, "rgba", 0);
1334 else if(strcmp(cpa, "QuadMesh")==0) {
1335 iv_finddata(iv, "verticesPerColumn", 0);
1336 iv_finddata(iv, "verticesPerRow", 1);
1340 else if(strcmp(cpa, "IndexedTriangleStripSet")==0) {
1341 skipdata= iv_finddata(iv, "coordIndex", 0);
1344 else if(strcmp(cpa, "TriangleStripSet")==0) {
1345 skipdata= iv_finddata(iv, "numVertices", 0);
1348 else if(strcmp(cpa, "IndexedNurbsSurface")==0 || strcmp(cpa, "NurbsSurface")==0) {
1349 iv_finddata(iv, "numUControlPoints", 0);
1350 iv_finddata(iv, "numVControlPoints", 1);
1351 iv_finddata(iv, "uKnotVector", 2);
1352 iv_finddata(iv, "vKnotVector", 3);
1357 while( *md != '}') {
1360 if(count<filelen) break;
1366 BLI_addtail(&ivbase, iv);
1383 if( strncmp(iv->nodename, "Indexed", 7)==0) {
1384 /* seek back: same name? */
1388 if(strcmp(iv->nodename, ivp->nodename)==0) break;
1390 if(strcmp(ivp->nodename, "Coordinate3")==0 ||
1391 strcmp(ivp->nodename, "Coordinate4")==0 ||
1392 strcmp(ivp->nodename, "VertexProperty")==0) {
1402 tot= iv->datalen[0] + ivp->datalen[0];
1404 data= MEM_mallocN(tot*sizeof(float), "samenvoeg iv");
1405 memcpy(data, ivp->data[0], sizeof(float)*ivp->datalen[0]);
1406 memcpy(data+ivp->datalen[0], iv->data[0], sizeof(float)*iv->datalen[0]);
1408 ivp->datalen[0]+= iv->datalen[0];
1409 MEM_freeN(ivp->data[0]);
1412 BLI_remlink(&ivbase, iv);
1413 MEM_freeN(iv->data[0]);
1423 /* convert Nodes to DispLists */
1427 /* printf(" Node: %s\n", iv->nodename); */
1428 /* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */
1431 if( strcmp(iv->nodename, "IndexedLineSet")==0 ) {
1433 colnr= iv_colornumber(iv);
1435 /* seek back to data */
1439 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1443 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1450 /* count the nr of lines */
1453 lll = iv->datalen[0]-1;
1454 for(a=0; a<lll; a++) {
1455 if(index[0]!= -1 && index[1]!= -1) tot++;
1459 tot*= 2; /* nr of vertices */
1460 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor1");
1461 BLI_addtail(listb, dl);
1466 data= (float *)(dl+1);
1469 for(a=0; a<lll; a++) {
1470 if(index[0]!= -1 && index[1]!= -1) {
1471 read_iv_index(data, ivp->data[0], index, 2, coordtype);
1478 else if( strcmp(iv->nodename, "FaceSet")==0 ) {
1480 colnr= iv_colornumber(iv);
1482 /* seek back to data */
1486 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1490 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1497 /* count triangles */
1501 polytype= (int) index[0];
1503 for(a=0; a<iv->datalen[0]; a++) {
1504 if(index[0]== polytype) tot++; /* one kind? */
1509 tot*= polytype; /* nr of vertices */
1510 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor4");
1511 BLI_addtail(listb, dl);
1514 dl->parts= tot/polytype;
1516 data= (float *)(dl+1);
1518 index= ivp->data[0];
1520 for(a=0; a<iv->datalen[0]; a++) {
1522 VECCOPY(data, index);
1526 VECCOPY(data, index);
1530 VECCOPY(data, index);
1535 VECCOPY(data, index);
1542 else if( strcmp(iv->nodename, "TriangleStripSet")==0 ) {
1544 colnr= iv_colornumber(iv);
1546 /* seek back to data */
1550 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1554 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1561 /* count triangles */
1565 index= iv->data[0]; /* strip size */
1567 for(a=0; a<iv->datalen[0]; a++) {
1568 tot+= (int) index[0];
1569 face+= ((int) index[0]) - 2;
1573 dl= MEM_callocN(sizeof(struct DispList), "leesInventor4");
1574 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1575 dl->index= MEM_callocN( face*3*sizeof(int), "dl index");
1577 dl->type= DL_INDEX3;
1581 BLI_addtail(listb, dl);
1584 index= iv->data[0]; /* strip size */
1585 fp= ivp->data[0]; /* vertices */
1590 for(a=0; a<iv->datalen[0]; a++) {
1593 for(b=0; b<index[0]; b++) {
1601 for(b=0; b<lll; b++) {
1614 else if( strcmp(iv->nodename, "IndexedFaceSet")==0 ) {
1616 colnr= iv_colornumber(iv);
1618 /* seek back to data */
1622 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1626 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1633 /* count triangles */
1636 lll = iv->datalen[0]-2;
1637 for(a=0; a<lll; a++) {
1638 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1642 /*number of vertices */
1643 tot= ivp->datalen[0]/coordtype;
1646 dl= MEM_callocN(sizeof(struct DispList), "leesInventor5");
1647 BLI_addtail(listb, dl);
1648 dl->type= DL_INDEX3;
1653 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1654 dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1659 for(b=tot; b>0; b--) {
1669 lll=iv->datalen[0]-2;
1670 for(a=0; a<lll; a++) {
1672 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1674 /* this trick is to fill poly's with more than 3 vertices correctly */
1680 idata[1]= (int) index[1];
1681 idata[2]= (int) index[2];
1691 else if( strcmp(iv->nodename, "IndexedTriangleMesh")==0 ||
1692 strcmp(iv->nodename, "IndexedTriangleStripSet")==0 ) {
1694 colnr= iv_colornumber(iv);
1696 /* seek back to data */
1700 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1704 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1711 /* count triangles */
1714 lll=iv->datalen[0]-2;
1715 for(a=0; a<lll; a++) {
1716 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1720 /* nr of vertices */
1721 tot= ivp->datalen[0]/coordtype;
1723 dl= MEM_callocN(sizeof(struct DispList), "leesInventor6");
1724 BLI_addtail(listb, dl);
1725 dl->type= DL_INDEX3;
1730 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1731 dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1736 for(b=tot; b>0; b--) {
1746 lll=iv->datalen[0]-2;
1747 for(a=lll; a>0; a--) {
1749 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1750 idata[0]= (int) index[0];
1751 idata[1]= (int) index[1];
1752 idata[2]= (int) index[2];
1759 else if( strcmp(iv->nodename, "QuadMesh")==0 ) {
1761 colnr= iv_colornumber(iv);
1763 /* seek back to data */
1767 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1771 if( strcmp(ivp->nodename, "VertexProperty")==0 ) {
1775 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1782 tot= (int) (floor(*(iv->data[0])+0.5) * floor(*(iv->data[1])+0.5));
1785 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor8");
1786 BLI_addtail(listb, dl);
1788 dl->parts= (int) floor(*(iv->data[0])+0.5);
1789 dl->nr= (int) floor(*(iv->data[1])+0.5);
1791 data= (float *)(dl+1);
1792 memcpy(data, ivp->data[0], tot*3*sizeof(float));
1796 else if(strcmp(iv->nodename, "IndexedNurbsSurface")==0 || strcmp(iv->nodename, "NurbsSurface")==0) {
1798 colnr= iv_colornumber(iv);
1800 /* sek back to data */
1804 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1808 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1814 a= (int) *(iv->data[0]);
1815 b= (int) *(iv->data[1]);
1819 if( (a>=4 || b>=4) && tot>6) {
1826 ob= add_object(OB_SURF);
1831 nu = (Nurb*) MEM_callocN(sizeof(Nurb),"addNurbprim") ;
1832 BLI_addtail(&cu->nurb, nu);
1844 (BPoint*)MEM_callocN(tot * sizeof(BPoint), "addNurbprim3");
1848 VECCOPY(bp->vec, data);
1850 bp->vec[3]= data[3];
1851 VecMulf(bp->vec, 1.0f/data[3]);
1853 else bp->vec[3]= 1.0;
1858 /* iv->datalen[2] / [3] is number of knots */
1859 nu->orderu= iv->datalen[2] - nu->pntsu;
1860 nu->orderv= iv->datalen[3] - nu->pntsv;
1862 nu->knotsu= MEM_mallocN( sizeof(float)*(iv->datalen[2]), "knots");
1863 memcpy(nu->knotsu, iv->data[2], sizeof(float)*(iv->datalen[2]));
1864 nu->knotsv= MEM_mallocN( sizeof(float)*(iv->datalen[3]), "knots");
1865 memcpy(nu->knotsv, iv->data[3], sizeof(float)*(iv->datalen[3]));
1867 switchdirectionNurb(nu);
1871 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor3");
1872 BLI_addtail(listb, dl);
1874 dl->nr= (int) *(iv->data[0]);
1875 dl->parts= (int) *(iv->data[1]);
1877 data= (float *)(dl+1);
1895 for(a=0; a<IV_MAXFIELD; a++) {
1896 if(iv->data[a]) MEM_freeN(iv->data[a]);
1901 BLI_freelistN(&ivbase);
1902 MEM_freeN(maindata);
1903 MEM_freeN(iv_data_stack);
1907 /* ************************************************************ */
1909 static void displist_to_mesh(DispList *dlfirst)
1917 float *data, vec[3], min[3], max[3];
1918 int a, b, startve, *idata, totedge=0, tottria=0, totquad=0, totvert=0, totface, totcol=0, colnr;
1920 unsigned int maxvertidx;
1923 INIT_MINMAX(min, max);
1928 /* PATCH 1 (polyfill) can't be done, there's no listbase here. do that first! */
1930 if(dl->type==DL_SEGM && dl->nr>2) {
1931 data= (float *)(dl+1);
1932 if(data[0]==data[3*(dl->nr-1)]) {
1933 if(data[1]==data[3*(dl->nr-1)+1]) {
1934 if(data[2]==data[3*(dl->nr-1)+2]) {
1943 if(dl->col > totcol) totcol= dl->col;
1945 /* size and count */
1946 if(dl->type==DL_SURF) {
1949 if(dl->flag & DL_CYCL_U) a++;
1950 if(dl->flag & DL_CYCL_V) b++;
1954 totvert+= dl->nr*dl->parts;
1956 data= (float *)(dl+1);
1957 for(a= dl->nr*dl->parts; a>0; a--) {
1958 DO_MINMAX(data, min, max);
1962 else if(dl->type==DL_POLY) {
1963 if(dl->nr==3 || dl->nr==4) {
1964 if(dl->nr==3) tottria+= dl->parts;
1965 else totquad+= dl->parts;
1967 totvert+= dl->nr*dl->parts;
1969 data= (float *)(dl+1);
1970 for(a= dl->nr*dl->parts; a>0; a--) {
1971 DO_MINMAX(data, min, max);
1977 tottria+= dl->nr*dl->parts;
1978 totvert+= dl->nr*dl->parts;
1980 data= (float *)(dl+1);
1981 for(a= dl->nr*dl->parts; a>0; a--) {
1982 DO_MINMAX(data, min, max);
1988 else if(dl->type==DL_INDEX3) {
1989 tottria+= dl->parts;
1993 for(a= dl->nr; a>0; a--) {
1994 DO_MINMAX(data, min, max);
1998 else if(dl->type==DL_SEGM) {
2000 tottria+= (dl->nr-1)*dl->parts;
2001 totvert+= dl->nr*dl->parts;
2003 data= (float *)(dl+1);
2004 for(a= dl->nr*dl->parts; a>0; a--) {
2005 DO_MINMAX(data, min, max);
2018 error("Found more than 16 different colors");
2022 vec[0]= (min[0]+max[0])/2;
2023 vec[1]= (min[1]+max[1])/2;
2024 vec[2]= (min[2]+max[2])/2;
2026 ob= add_object(OB_MESH);
2027 VECCOPY(ob->loc, vec);
2028 where_is_object(ob);
2034 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
2035 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
2037 ob->totcol= (unsigned char) me->totcol;
2042 for(a=0; a<totcol; a++) {
2043 ma= G.main->mat.first;
2045 if(ma->mtex[0]==0) {
2046 if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
2055 ma= add_material("ext");
2057 ma->r= ivcolors[a][0];
2058 ma->g= ivcolors[a][1];
2059 ma->b= ivcolors[a][2];
2064 totface= totquad+tottria+totedge;
2066 printf("Import: %d vertices %d faces\n", totvert, totface);
2068 me->totvert= totvert;
2069 me->totface= totface;
2070 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
2072 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
2074 maxvertidx= totvert-1;
2084 colnr= (dl->col>15 ? 15: dl->col);
2087 if(dl->type==DL_SURF) {
2088 data= (float *)(dl+1);
2090 for(a=dl->parts*dl->nr; a>0; a--) {
2091 mvert->co[0]= data[0] -vec[0];
2092 mvert->co[1]= data[1] -vec[1];
2093 mvert->co[2]= data[2] -vec[2];
2099 for(a=0; a<dl->parts; a++) {
2101 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
2109 for(; b<dl->nr; b++) {
2116 mface->mat_nr= colnr;
2117 test_index_face(mface, NULL, 0, 4);
2128 startve += dl->parts*dl->nr;
2131 else if(dl->type==DL_POLY) {
2133 if(dl->nr==3 || dl->nr==4) {
2134 data= (float *)(dl+1);
2136 for(a=dl->parts*dl->nr; a>0; a--) {
2137 mvert->co[0]= data[0] -vec[0];
2138 mvert->co[1]= data[1] -vec[1];
2139 mvert->co[2]= data[2] -vec[2];
2144 for(a=0; a<dl->parts; a++) {
2146 mface->v1= startve+a*dl->nr;
2147 mface->v2= startve+a*dl->nr+1;
2148 mface->v3= startve+a*dl->nr+2;
2149 mface->mat_nr= colnr;
2150 test_index_face(mface, NULL, 0, 3);
2154 mface->v1= startve+a*dl->nr;
2155 mface->v2= startve+a*dl->nr+1;
2156 mface->v3= startve+a*dl->nr+2;
2157 mface->v4= startve+a*dl->nr+3;
2158 mface->mat_nr= colnr;
2159 test_index_face(mface, NULL, 0, 4);
2163 startve += dl->parts*dl->nr;
2166 data= (float *)(dl+1);
2168 for(a=dl->parts*dl->nr; a>0; a--) {
2169 mvert->co[0]= data[0] -vec[0];
2170 mvert->co[1]= data[1] -vec[1];
2171 mvert->co[2]= data[2] -vec[2];
2177 for(b=0; b<dl->parts; b++) {
2178 for(a=0; a<dl->nr; a++) {
2179 mface->v1= startve+a;
2181 if(a==dl->nr-1) mface->v2= startve;
2182 else mface->v2= startve+a+1;
2184 mface->mat_nr= colnr;
2192 else if(dl->type==DL_INDEX3) {
2195 for(a=dl->nr; a>0; a--) {
2196 mvert->co[0]= data[0] -vec[0];
2197 mvert->co[1]= data[1] -vec[1];
2198 mvert->co[2]= data[2] -vec[2];
2204 for(b=dl->parts; b>0; b--) {
2205 mface->v1= startve+idata[0];
2206 mface->v2= startve+idata[1];
2207 mface->v3= startve+idata[2];
2208 mface->mat_nr= colnr;
2210 if (mface->v1>maxvertidx) mface->v1= maxvertidx;
2211 if (mface->v2>maxvertidx) mface->v2= maxvertidx;
2212 if (mface->v3>maxvertidx) mface->v3= maxvertidx;
2214 test_index_face(mface, NULL, 0, 3);
2220 else if(dl->type==DL_SEGM) {
2221 data= (float *)(dl+1);
2223 for(a=dl->parts*dl->nr; a>0; a--) {
2224 mvert->co[0]= data[0] -vec[0];
2225 mvert->co[1]= data[1] -vec[1];
2226 mvert->co[2]= data[2] -vec[2];
2231 for(b=0; b<dl->parts; b++) {
2232 for(a=0; a<dl->nr-1; a++) {
2233 mface->v1= startve+a;
2234 mface->v2= startve+a+1;
2235 mface->mat_nr= colnr;
2244 mesh_add_normals_flags(me);
2248 static void displist_to_objects(ListBase *lbase)
2250 DispList *dl, *first, *prev, *next;
2252 int maxaantal, curcol, totvert=0, vert;
2254 /* irst this: is still active */
2256 where_is_object(ivsurf);
2264 /* PATCH 1: polyfill */
2265 if(dl->type==DL_POLY && dl->nr>4) {
2266 /* solution: put them together in separate listbase */
2269 /* PATCH 2: poly's of 2 points */
2270 if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
2275 /* count vertices */
2280 if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
2281 else if(dl->type==DL_POLY) {
2282 if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
2283 else if(dl->nr>4) totvert+= dl->nr*dl->parts;
2285 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
2286 else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
2293 if(ivsurf==0) error("Found no data");
2294 if(lbase->first) BLI_freelistN(lbase);
2301 if(totvert>maxaantal) {
2303 /* try to put colors together */
2305 tempbase.first= tempbase.last= 0;
2307 while(lbase->first) {
2311 if(dl->col==curcol) {
2312 BLI_remlink(lbase, dl);
2313 BLI_addtail(&tempbase, dl);
2320 /* in tempbase are all 'curcol' */
2322 dl= first= tempbase.first;
2326 if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
2327 else if(dl->type==DL_POLY) {
2328 if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
2329 else if(dl->nr>4) vert= dl->nr*dl->parts;
2331 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
2332 else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
2335 if(totvert > maxaantal || dl->next==0) {
2337 displist_to_mesh(first);
2342 displist_to_mesh(first);
2352 freedisplist(&tempbase);
2357 else displist_to_mesh(lbase->first);
2359 freedisplist(lbase);
2363 int BKE_read_exotic(char *name)
2365 ListBase lbase={0, 0};
2369 int *s0 = (int*) str;
2372 // make sure we're not trying to read a directory....
2375 if (name[len-1] !='/' && name[len-1] != '\\') {
2376 gzfile = gzopen(name,"rb");
2378 if (NULL == gzfile ) {
2379 error("Can't open file: %s", name);
2382 gzread(gzfile, str, 31);
2385 if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
2391 error("Unable to perform function in EditMode");
2393 read_radiogour(name);
2397 else if ELEM4(*s0, DDG1, DDG2, DDG3, DDG4) {
2399 error("Unable to perform function in EditMode");
2401 read_videoscape(name);
2405 else if(strncmp(str, "#Inventor V1.0", 14)==0) {
2406 if( strncmp(str+15, "ascii", 5)==0) {
2407 read_inventor(name, &lbase);
2408 displist_to_objects(&lbase);
2411 error("Can only read Inventor 1.0 ascii");
2414 else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
2415 read_inventor(name, &lbase);
2416 displist_to_objects(&lbase);
2419 else if(is_dxf(name)) {
2423 else if(is_stl(name)) {
2424 if (is_stl_ascii(name))
2425 read_stl_mesh_ascii(name);
2427 read_stl_mesh_binary(name);
2430 // TODO: this should not be in the kernel...
2431 else { // unknown format, call Python importloader
2432 if (BPY_call_importloader(name)) {
2435 error("Unknown file type or error, check console");
2448 /* ************************ WRITE ************************** */
2451 char temp_dir[160]= {0, 0};
2453 static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
2457 VECCOPY(vert, verts[(index)].co);
2458 Mat4MulVecfl(ob->obmat, vert);
2460 if (G.order==B_ENDIAN) {
2461 SWITCH_INT(vert[0]);
2462 SWITCH_INT(vert[1]);
2463 SWITCH_INT(vert[2]);
2466 fwrite(vert, sizeof(float), 3, fpSTL);
2469 static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
2471 MVert *mvert = dm->getVertArray(dm);
2472 MFace *mface = dm->getFaceArray(dm);
2473 int i, numfacets = 0, totface = dm->getNumFaces(dm);
2474 float zero[3] = {0.0f, 0.0f, 0.0f};
2476 for (i=0; i<totface; i++, mface++) {
2477 fwrite(zero, sizeof(float), 3, fpSTL);
2478 write_vert_stl(ob, mvert, mface->v1, fpSTL);
2479 write_vert_stl(ob, mvert, mface->v2, fpSTL);
2480 write_vert_stl(ob, mvert, mface->v3, fpSTL);
2481 fprintf(fpSTL, " ");
2484 if(mface->v4) { /* quad = 2 tri's */
2485 fwrite(zero, sizeof(float), 3, fpSTL);
2486 write_vert_stl(ob, mvert, mface->v1, fpSTL);
2487 write_vert_stl(ob, mvert, mface->v3, fpSTL);
2488 write_vert_stl(ob, mvert, mface->v4, fpSTL);
2489 fprintf(fpSTL, " ");
2497 static int write_object_stl(FILE *fpSTL, Object *ob, Mesh *me)
2500 DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
2502 numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
2509 void write_stl(char *str)
2517 if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2518 if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2519 if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
2521 if (!during_script()) {
2522 if (BLI_exists(str))
2523 if(saveover(str)==0)
2527 fpSTL= fopen(str, "wb");
2530 if (!during_script()) error("Can't write file");
2533 strcpy(temp_dir, str);
2537 /* The header part of the STL */
2538 /* First 80 characters are a title or whatever you want.
2539 Lets make the first 32 of those spam and the rest the filename.
2540 Those first 80 characters will be followed by 4 bytes
2541 which will be overwritten later with an integer holding
2542 how many facets are written (we set them to ' ' for now).
2544 fprintf(fpSTL, "Binary STL output from Blender: %-48.48s ", str);
2546 /* Write all selected mesh objects */
2547 base= G.scene->base.first;
2549 if (base->flag & SELECT) {
2551 if (ob->type == OB_MESH) {
2554 numfacets += write_object_stl(fpSTL, ob, me);
2560 /* time to write the number of facets in the 4 bytes
2563 fseek(fpSTL, 80, SEEK_SET);
2565 if (G.order==B_ENDIAN) {
2566 SWITCH_INT(numfacets);
2568 fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
2575 static void write_videoscape_mesh(Object *ob, char *str)
2577 EditMesh *em = G.editMesh;
2584 unsigned int kleur[32];
2590 if(ob && ob->type==OB_MESH);
2595 kleur[0]= 0x00C0C0C0;
2598 for(a=0; a<ob->totcol; a++, cp+=4) {
2600 ma= give_current_material(ob, a+1);
2602 cp[0]= (unsigned char) (255.0*ma->emit);
2603 cp[1]= (unsigned char) (255.0*ma->b);
2604 cp[2]= (unsigned char) (255.0*ma->g);
2605 cp[3]= (unsigned char) (255.0*ma->r);
2606 if(G.order==L_ENDIAN) SWITCH_INT(kleur[a]);
2608 else kleur[a]= 0x00C0C0C0;
2613 fp= fopen(str, "wb");
2614 if(fp==NULL) return;
2616 fprintf(fp,"3DG1\n");
2620 fprintf(fp, "%d\n", G.totvert);
2623 eve= em->verts.first;
2625 VECCOPY(co, eve->co);
2626 Mat4MulVecfl(ob->obmat, co);
2627 fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
2632 evl= em->faces.first;
2636 fprintf(fp, "3 %ld %ld %ld 0x%x\n",
2637 (long int) evl->v1->tmp.l,
2638 (long int) evl->v2->tmp.l,
2639 (long int) evl->v3->tmp.l,
2640 kleur[evl->mat_nr]);
2643 fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n",
2644 (long int) evl->v1->tmp.l,
2645 (long int) evl->v2->tmp.l,
2646 (long int) evl->v3->tmp.l,
2647 (long int) evl->v4->tmp.l,
2648 kleur[evl->mat_nr]);
2654 DerivedMesh *dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
2658 fprintf(fp, "%d\n", me->totvert);
2661 for(a=0; a<me->totvert; a++) {
2662 dm->getVertCo(dm, a, co);
2663 Mat4MulVecfl(ob->obmat, co);
2664 fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
2666 for(a=0; a<me->totface; a++, mface++) {
2668 fprintf(fp, "3 %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, kleur[mface->mat_nr]);
2671 fprintf(fp, "4 %d %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, mface->v4, kleur[mface->mat_nr]);
2683 void write_videoscape(char *str)
2686 int file, val, lampdone=0;
2687 unsigned short numlen;
2688 char head[FILE_MAXFILE], tail[FILE_MAXFILE];
2690 if(BLI_testextensie(str,".trace")) str[ strlen(str)-6]= 0;
2691 if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2692 if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2693 if(BLI_testextensie(str,".obj")==0) strcat(str, ".obj");
2695 file= open(str,O_BINARY|O_RDONLY);
2697 if(file>-1) if(!during_script() && saveover(str)==0) return;
2699 strcpy(temp_dir, str);
2701 base= G.scene->base.first;
2703 if((base->flag & SELECT) && (base->lay & G.scene->lay)) {
2704 if(base->object->type==OB_MESH) {
2705 write_videoscape_mesh(base->object, str);
2706 val = BLI_stringdec(str, head, tail, &numlen);
2707 BLI_stringenc(str, head, tail, numlen, val + 1);
2709 else if(base->object->type==OB_CURVE || base->object->type==OB_SURF) {
2710 /* write_videoscape_nurbs(base->object, str); */
2711 /* val = stringdec(str, head, tail, &numlen); */
2712 /* stringenc(str, head, tail, numlen, val + 1); */
2714 else if(lampdone==0 && base->object->type==OB_LAMP) {
2716 /* write_videoscape_lamps(str); */
2717 /* val = stringdec(str, head, tail, &numlen); */
2718 /* stringenc(str, head, tail, numlen, val + 1); */
2725 /* remove when higher numbers exist */
2726 while(remove(str)==0) {
2728 val = BLI_stringdec(str, head, tail, &numlen);
2729 BLI_stringenc(str, head, tail, numlen, val + 1);
2733 /* ******************************* WRITE VRML ***************************** */
2735 static void replace_chars(char *str1, char *str2)
2737 int a= strlen(str2);
2741 if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
2742 else str1[a]= str2[a];
2747 static void write_material_vrml(FILE *fp, Material *ma)
2751 replace_chars(str, ma->id.name+2);
2753 fprintf(fp, "\tDEF %s\n", str);
2754 fprintf(fp, "\tMaterial {\n");
2756 fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
2757 fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
2758 fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
2759 fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
2761 fprintf(fp, "\t}\n");
2765 unsigned int *mcol_to_vcol(Mesh *me)
2768 unsigned int *mcol, *mcoln, *mcolmain;
2771 if(me->totface==0 || me->mcol==0) return 0;
2773 mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
2774 mcol = (unsigned int *)me->mcol;
2777 for(a=me->totface; a>0; a--, mface++) {
2778 mcoln[mface->v1]= mcol[0];
2779 mcoln[mface->v2]= mcol[1];
2780 mcoln[mface->v3]= mcol[2];
2781 if(mface->v4) mcoln[mface->v4]= mcol[3];
2789 void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)