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 #ifndef DISABLE_PYTHON
121 #include "BPY_extern.h"
128 static int is_dxf(char *str);
129 static void dxf_read(char *filename);
130 static int is_stl(char *str);
132 static int is_stl_ascii(char *str)
138 fpSTL = fopen(str, "rb");
139 if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
140 { fclose(fpSTL); return 0; }
142 for (i=0; i < numread; ++i) {
143 /* if bit 8 is set we assume binary */
144 if (buffer[i] & 0x80)
145 { fclose(fpSTL); return 0; }
149 if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) )
150 { fclose(fpSTL); return 0; }
157 static int is_stl(char *str)
161 if ( (str[i] !='s') && (str[i] !='S'))
164 if ( (str[i] !='t') && (str[i] !='T'))
167 if ( (str[i] !='l') && (str[i] !='L'))
173 #define READSTLVERT { \
174 if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
175 char error_msg[255]; \
176 MEM_freeN(vertdata); \
177 MEM_freeN(facedata); \
179 sprintf(error_msg, "Problems reading face %d!", i); \
184 if (G.order==B_ENDIAN) { \
185 SWITCH_INT(mvert->co[0]); \
186 SWITCH_INT(mvert->co[1]); \
187 SWITCH_INT(mvert->co[2]); \
192 static void simple_vertex_normal_blend(short *no, short *ble)
194 if(no[0]==0 && no[1]==0 && no[2]==0) {
198 no[0]= (2*no[0] + ble[0])/3;
199 no[1]= (2*no[1] + ble[1])/3;
200 no[2]= (2*no[2] + ble[2])/3;
204 static void mesh_add_normals_flags(Mesh *me)
206 MVert *v1, *v2, *v3, *v4;
213 for(a=0; a<me->totface; a++, mface++) {
214 v1= me->mvert+mface->v1;
215 v2= me->mvert+mface->v2;
216 v3= me->mvert+mface->v3;
217 v4= me->mvert+mface->v4;
219 CalcNormFloat(v1->co, v2->co, v3->co, nor);
220 sno[0]= 32767.0*nor[0];
221 sno[1]= 32767.0*nor[1];
222 sno[2]= 32767.0*nor[2];
224 simple_vertex_normal_blend(v1->no, sno);
225 simple_vertex_normal_blend(v2->no, sno);
226 simple_vertex_normal_blend(v3->no, sno);
228 simple_vertex_normal_blend(v4->no, sno);
230 mface->edcode= ME_V1V2|ME_V2V3;
234 static void read_stl_mesh_binary(char *str)
239 MVert *mvert, *vertdata;
240 MFace *mface, *facedata;
241 unsigned int numfacets = 0, i, j, vertnum;
242 unsigned int maxmeshsize, nummesh, lastmeshsize;
243 unsigned int totvert, totface;
245 fpSTL= fopen(str, "rb");
247 error("Can't read file");
251 fseek(fpSTL, 80, SEEK_SET);
252 fread(&numfacets, 4*sizeof(char), 1, fpSTL);
253 if (G.order==B_ENDIAN) {
254 SWITCH_INT(numfacets);
257 maxmeshsize = MESH_MAX_VERTS/3;
259 nummesh = (numfacets / maxmeshsize) + 1;
260 lastmeshsize = numfacets % maxmeshsize;
263 for (j=0; j < nummesh; ++j) {
265 if (j == nummesh-1) {
266 totface = lastmeshsize;
269 totface = maxmeshsize;
271 totvert = 3 * totface;
273 vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
274 facedata = MEM_callocN(totface*sizeof(MFace), "mface");
279 for (i=0; i < totface; i++) {
280 fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
288 mface->v1 = vertnum++;
289 mface->v2 = vertnum++;
290 mface->v3 = vertnum++;
293 fseek(fpSTL, 2, SEEK_CUR);
296 ob= add_object(OB_MESH);
298 me->totvert = totvert;
299 me->totface = totface;
300 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
302 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
305 mesh_add_normals_flags(me);
315 #define STLALLOCERROR { \
316 char error_msg[255]; \
318 sprintf(error_msg, "Can't allocate storage for %d faces!", \
319 numtenthousand * 10000); \
324 #define STLBAILOUT(message) { \
325 char error_msg[255]; \
328 sprintf(error_msg, "Line %d: %s", linenum, message); \
333 #define STLREADLINE { \
334 if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
338 #define STLREADVERT { \
340 if ( !(cp = strstr(buffer, "vertex")) && \
341 !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
342 vp = vertdata + 3 * totvert; \
343 if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
344 STLBAILOUT("Bad vertex!"); \
347 static void read_stl_mesh_ascii(char *str)
350 char buffer[2048], *cp;
355 float *vertdata, *vp;
356 unsigned int numtenthousand, linenum;
357 unsigned int i, vertnum;
358 unsigned int totvert, totface;
360 /* ASCII stl sucks ... we don't really know how many faces there
361 are until the file is done, so lets allocate faces 10000 at a time */
363 fpSTL= fopen(str, "r");
365 error("Can't read file");
369 /* we'll use the standard malloc/realloc for now ...
370 * lets allocate enough storage to hold 10000 triangles,
371 * i.e. 30000 verts, i.e., 90000 floats.
374 vertdata = malloc(numtenthousand*3*30000*sizeof(float)); // uses realloc!
375 if (!vertdata) STLALLOCERROR;
378 /* Get rid of the first line */
384 /* Read in the next line */
387 /* lets check if this is the end of the file */
388 if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") )
391 /* Well, guess that wasn't the end, so lets make
392 * sure we have enough storage for some more faces
394 if ( (totface) && ( (totface % 10000) == 0 ) ) {
396 vertdata = realloc(vertdata,
397 numtenthousand*3*30000*sizeof(float));
398 if (!vertdata) STLALLOCERROR;
401 /* Don't read normal, but check line for proper syntax anyway
403 if ( !(cp = strstr(buffer, "facet")) &&
404 !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
405 if ( !(strstr(cp+5, "normal")) &&
406 !(strstr(cp+5, "NORMAL")) ) STLBAILOUT("Bad normal line!");
408 /* Read in what should be the outer loop line
411 if ( !(cp = strstr(buffer, "outer")) &&
412 !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
413 if ( !(strstr(cp+5, "loop")) &&
414 !(strstr(cp+5, "LOOP")) ) STLBAILOUT("Bad outer loop!");
416 /* Read in the face */
421 /* Read in what should be the endloop line
424 if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") )
425 STLBAILOUT("Bad endloop!");
427 /* Read in what should be the endfacet line
430 if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") )
431 STLBAILOUT("Bad endfacet!");
433 /* Made it this far? Increment face count */
438 /* OK, lets create our mesh */
439 ob = add_object(OB_MESH);
442 me->totface = totface;
443 me->totvert = totvert;
444 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
446 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
449 /* Copy vert coords and create topology */
453 for (i=0; i < totface; ++i) {
454 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
459 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
464 memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
473 mesh_add_normals_flags(me);
484 static void read_videoscape_mesh(char *str)
492 float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
493 unsigned int color[32], col;
494 int totcol, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
498 fp= fopen(str, "rb");
500 error("Can't read file");
504 fscanf(fp, "%40s", s);
506 fscanf(fp, "%d\n", &verts);
513 if(verts>MESH_MAX_VERTS) {
514 error("too many vertices");
519 INIT_MINMAX(min, max);
520 vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
522 for(a=0; a<verts; a++) {
523 fscanf(fp, "%f %f %f", vd, vd+1, vd+2);
524 DO_MINMAX(vd, min, max);
528 /* count faces and colors */
529 for(a=0; a<32; a++) color[a]= 0;
533 end= fscanf(fp,"%d", &poly);
536 if(poly==3) tottria++;
537 else if(poly==4) totquad++;
540 for(a=0;a<poly;a++) {
541 end= fscanf(fp,"%d", &nr);
546 end= fscanf(fp,"%i\n", &col);
548 for(a=0; a<totcol; a++) {
549 if(color[a]==col) break;
551 if(a>=totcol && totcol<32) {
558 ob= add_object(OB_MESH);
561 me->totface= totedge+tottria+totquad;
563 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
565 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
570 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
571 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
573 ob->totcol= (unsigned char) me->totcol;
578 for(a=0; a<totcol; a++) {
579 ma= G.main->mat.first;
582 col= rgb_to_cpack(ma->r, ma->g, ma->b);
592 ma= add_material("ext");
594 cpack_to_rgb(color[a], cent, cent+1, cent+2);
604 cent[0]= (min[0]+max[0])/2.0f;
605 cent[1]= (min[1]+max[1])/2.0f;
606 cent[2]= (min[2]+max[2])/2.0f;
607 VECCOPY(ob->loc, cent);
613 VecSubf(mvert->co, vd, cent);
622 fscanf(fp, "%40s", s);
623 fscanf(fp, "%d\n", &verts);
625 for(a=0;a<verts;a++) {
626 fscanf(fp, "%f %f %f", &ftemp, &ftemp, &ftemp);
632 end= fscanf(fp,"%d", &poly);
635 if(poly==3 || poly==4) {
636 fscanf(fp,"%d", &nr);
637 mface->v1= MIN2(nr, me->totvert-1);
638 fscanf(fp,"%d", &nr);
639 mface->v2= MIN2(nr, me->totvert-1);
640 fscanf(fp,"%d", &nr);
641 mface->v3= MIN2(nr, me->totvert-1);
643 if( fscanf(fp,"%d", &nr) <=0 ) break;
644 mface->v4= MIN2(nr, me->totvert-1);
647 test_index_face(mface, NULL, 0, poly);
652 if( fscanf(fp,"%d", &nr0) <=0) break;
654 for(b=1; b<poly; b++) {
655 end= fscanf(fp,"%d", &nr);
657 nr= MIN2(nr, me->totvert-1);
669 end= fscanf(fp,"%i", &col);
673 for(b=0; b<totcol; b++) {
675 (mface-1)->mat_nr= b;
685 mesh_add_normals_flags(me);
691 static void read_radiogour(char *str)
698 float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
699 unsigned int *colv, *colf, *colvertdata;
700 int itemp, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
704 fp= fopen(str, "rb");
706 error("Can't read file");
710 fscanf(fp, "%40s", s);
712 fscanf(fp, "%d\n", &verts);
719 if(verts>MESH_MAX_VERTS) {
720 error("too many vertices");
725 INIT_MINMAX(min, max);
726 vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
727 colv= colvertdata= MEM_mallocN(verts*sizeof(float), "coldata");
729 for(a=0; a<verts; a++) {
730 fscanf(fp, "%f %f %f %i", vd, vd+1, vd+2, colv);
731 DO_MINMAX(vd, min, max);
739 end= fscanf(fp,"%d", &poly);
742 if(poly==3) tottria++;
743 else if(poly==4) totquad++;
746 for(a=0;a<poly;a++) {
747 end= fscanf(fp,"%d", &nr);
754 if(totedge+tottria+totquad>MESH_MAX_VERTS) {
755 printf(" var1: %d, var2: %d, var3: %d \n", totedge, tottria, totquad);
756 error("too many faces");
758 MEM_freeN(colvertdata);
764 ob= add_object(OB_MESH);
767 me->totface= totedge+tottria+totquad;
770 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
772 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
777 cent[0]= (min[0]+max[0])/2.0f;
778 cent[1]= (min[1]+max[1])/2.0f;
779 cent[2]= (min[2]+max[2])/2.0f;
780 VECCOPY(ob->loc, cent);
786 VecSubf(mvert->co, vd, cent);
795 fscanf(fp, "%40s", s);
796 fscanf(fp, "%d\n", &verts);
797 for(a=0;a<verts;a++) {
798 fscanf(fp, "%f %f %f %i", &ftemp, &ftemp, &ftemp, &itemp);
804 end= fscanf(fp,"%d", &poly);
807 if(poly==3 || poly==4) {
808 fscanf(fp,"%d", &nr);
809 mface->v1= MIN2(nr, me->totvert-1);
810 fscanf(fp,"%d", &nr);
811 mface->v2= MIN2(nr, me->totvert-1);
812 fscanf(fp,"%d", &nr);
813 mface->v3= MIN2(nr, me->totvert-1);
815 if( fscanf(fp,"%d", &nr) <=0 ) break;
816 mface->v4= MIN2(nr, me->totvert-1);
819 test_index_face(mface, NULL, 0, poly);
824 if( fscanf(fp,"%d", &nr0) <=0) break;
826 for(b=1; b<poly; b++) {
827 end= fscanf(fp,"%d", &nr);
829 nr= MIN2(nr, me->totvert-1);
838 mface->flag= ME_SMOOTH;
845 /* mcol is 4 colors per face */
846 me->mcol= MEM_mallocN(4*sizeof(int)*me->totface, "mcol");
847 colf= (unsigned int *)me->mcol;
853 colf[0]= colvertdata[mface->v1];
854 colf[1]= colvertdata[mface->v2];
855 colf[2]= colvertdata[mface->v3];
856 colf[3]= colvertdata[mface->v4];
862 MEM_freeN(colvertdata);
868 mesh_add_normals_flags(me);
875 static void read_videoscape_lamp(char *str)
884 fp= fopen(str, "rb");
886 error("Can't read file");
890 fscanf(fp, "%40s", s);
891 fscanf(fp, "%d\n", &tot);
894 ob= add_object(OB_LAMP);
897 fscanf(fp, "%d\n", &val);
899 if(la->type==1) la->type= LA_SPOT;
900 else if(la->type==2) la->type= LA_SUN;
902 fscanf(fp, "%f %f\n", &la->spotsize, &la->spotblend);
904 fscanf(fp, "%f %f %f %f\n", &la->r, &la->g, &la->b, &la->energy);
906 fscanf(fp, "%f %f %f\n", ob->loc, ob->loc+1, ob->loc+2);
907 val= fscanf(fp, "%f %f %f\n", vec, vec+1, vec+2);
908 vectoquat(vec, 5, 2, q1);
909 QuatToEul(q1, ob->rot);
917 static void read_videoscape_nurbs(char *str)
925 float tmat[4][4], omat[3][3], imat[3][3], mat[3][3];
926 int a, tot, type, val;
929 fp= fopen(str, "rb");
931 error("Can't read file");
935 fscanf(fp, "%40s", s);
936 fscanf(fp, "%d\n", &type);
938 if(type==5) ob= add_object(OB_SURF);
939 else ob= add_object(OB_CURVE);
942 fscanf(fp, "%d\n", &tot);
943 fscanf(fp, "%d %d\n", &type, &val);
945 cu->ext1= 0.002f*type;
946 cu->ext2= 0.002f*val;
948 for(a=0; a<4; a++) fscanf(fp, "%e %e %e %e\n", tmat[a], tmat[a]+1, tmat[a]+2, tmat[a]+3);
950 VECCOPY(ob->loc, tmat[3]);
952 Mat3CpyMat4(omat, tmat);
953 Mat3ToEul(omat, ob->rot);
954 EulToMat3(ob->rot, mat);
956 Mat3MulMat3((float ( * )[3])tmat, imat, omat);
959 nu= (Nurb*)MEM_callocN(sizeof(Nurb),"nu from exotic");
960 BLI_addtail(&cu->nurb, nu);
962 fscanf(fp, "%d\n", &type);
965 fscanf(fp, "%d %d\n", &type, &val);
966 nu->pntsu= type; nu->pntsv= val;
967 fscanf(fp, "%d %d\n", &type, &val);
968 nu->resolu= type; nu->resolv= val;
969 fscanf(fp, "%d %d\n", &type, &val);
970 nu->orderu= type; nu->orderv= val;
971 fscanf(fp, "%d %d\n", &type, &val);
972 nu->flagu= type; nu->flagv= val;
974 if( (nu->type & 7)==CU_BEZIER) {
976 nu->bezt= bezt= MEM_callocN(a*sizeof(BezTriple), "bezt from exotic");
978 fscanf(fp, "%f %f %f ", bezt->vec[0], bezt->vec[0]+1, bezt->vec[0]+2);
979 Mat4MulVecfl(tmat, bezt->vec[0]);
980 fscanf(fp, "%f %f %f ", bezt->vec[1], bezt->vec[1]+1, bezt->vec[1]+2);
981 Mat4MulVecfl(tmat, bezt->vec[1]);
982 fscanf(fp, "%f %f %f ", bezt->vec[2], bezt->vec[2]+1, bezt->vec[2]+2);
983 Mat4MulVecfl(tmat, bezt->vec[2]);
984 fscanf(fp, "%d %d\n", &type, &val);
991 a= nu->pntsu*nu->pntsv;
993 nu->bp= bp= MEM_callocN(a*sizeof(BPoint), "bp from exotic");
995 fscanf(fp, "%f %f %f %f\n", bp->vec, bp->vec+1, bp->vec+2, bp->vec+3);
996 Mat4MulVecfl(tmat, bp->vec);
1001 nu->knotsu= MEM_mallocN(sizeof(float)*val, "knots");
1002 for(a=0; a<val; a++) fscanf(fp, "%f\n", nu->knotsu+a);
1006 nu->knotsv= MEM_mallocN(sizeof(float)*val, "knots");
1007 for(a=0; a<val; a++) fscanf(fp, "%f\n", nu->knotsv+a);
1011 BLI_remlink(&cu->nurb, nu);
1019 static void read_videoscape(char *str)
1023 unsigned short numlen;
1024 char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXFILE];
1029 file= open(name, O_BINARY|O_RDONLY);
1032 read(file, &type, 4);
1035 if(type==DDG1) read_videoscape_mesh(name);
1036 else if(type==DDG2) read_videoscape_lamp(name);
1037 else if(type==DDG3) read_videoscape_nurbs(name);
1040 val = BLI_stringdec(name, head, tail, &numlen);
1041 BLI_stringenc(name, head, tail, numlen, val + 1);
1047 /* ***************** INVENTOR ******************* */
1050 #define IV_MAXSTACK 3000000
1051 #define IV_MAXFIELD 10
1052 #define IV_MAXCOL 16
1054 static float *iv_data_stack;
1055 static float ivcolors[IV_MAXCOL][3];
1056 static Object *ivsurf;
1057 static ListBase ivbase;
1060 struct IvNode *next, *prev;
1062 char *fieldname[IV_MAXFIELD];
1063 int datalen[IV_MAXFIELD];
1064 float *data[IV_MAXFIELD];
1067 static int iv_curcol=0;
1069 static int iv_colornumber(struct IvNode *iv)
1071 float *fp, fr = 0.0, fg = 0.0, fb = 0.0;
1075 /* search back to last material */
1077 if( strcmp(iv->nodename, "Material")==0) {
1079 if(fp==0) fp= iv->data[1];
1087 else if( strcmp(iv->nodename, "BaseColor")==0) {
1094 else if( strcmp(iv->nodename, "PackedColor")==0) {
1095 cp= (char *)iv->data[0];
1105 if(iv->datalen[0]<3) return 0;
1107 for(a=0; a<iv_curcol; a++) {
1109 if(ivcolors[a][0]== fr)
1110 if(ivcolors[a][1]== fg)
1111 if(ivcolors[a][2]== fb) return a+1
1115 if(a>=IV_MAXCOL) a= IV_MAXCOL-1;
1124 static int iv_finddata(struct IvNode *iv, char *field, int fieldnr)
1126 /* search for "field", count data size and make datablock. return skipdata */
1128 int len, stackcount, skipdata=0;
1129 char *cpa, terminator, str[64];
1134 cpa= iv->nodename+1;
1135 while( *cpa != '}' ) {
1137 if( *cpa == *field ) {
1138 if( strncmp(cpa, field, len)==0 ) {
1139 iv->fieldname[fieldnr]= cpa;
1141 /* read until first character */
1148 while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) cpa++;
1154 else terminator= 13;
1159 while( *cpa!=terminator && *cpa != '}' ) {
1161 /* in fact, isdigit should include the dot and minus */
1162 if( (isdigit(*cpa) || *cpa=='.' || *cpa=='-') && (isspace(cpa[-1]) || cpa[-1]==0 || cpa[-1]==',') ) {
1164 memcpy(str, cpa, 16);
1167 sscanf(str, "%x", (int *)fp);
1170 /* atof doesn't stop after the first float
1171 * in a long string at Windows... so we copy
1172 * the float to a new string then atof... */
1173 char *cpa_temp = strpbrk(cpa, ", \n");
1178 memcpy(str, cpa, i);
1181 *fp= (float) atof(str);
1186 if(stackcount>=IV_MAXSTACK) {
1187 printf("stackoverflow in IV read\n");
1196 iv->datalen[fieldnr]= stackcount;
1198 iv->data[fieldnr]= MEM_mallocN(sizeof(float)*stackcount, "iv_finddata");
1199 memcpy(iv->data[fieldnr], iv_data_stack, sizeof(float)*stackcount);
1201 else iv->data[fieldnr]= 0;
1213 static void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype)
1215 /* write in data: baseadr with offset index (and number nr) */
1221 fp= baseadr+coordtype*ofs;
1230 static void read_inventor(char *str, struct ListBase *listb)
1232 struct IvNode *iv, *ivp, *ivn;
1233 char *maindata, *md, *cpa;
1234 float *index, *data, *fp;
1235 int file, filelen, count, lll, face, nr = 0;
1236 int skipdata, ok, a, b, tot, first, colnr, coordtype, polytype, *idata;
1237 struct DispList *dl;
1239 ivbase.first= ivbase.last= 0;
1243 file= open(str, O_BINARY|O_RDONLY);
1245 error("Can't read file\n");
1249 filelen= BLI_filesize(file);
1255 maindata= MEM_mallocN(filelen, "leesInventor");
1256 read(file, maindata, filelen);
1259 iv_data_stack= MEM_mallocN(sizeof(float)*IV_MAXSTACK, "ivstack");
1261 /* preprocess: remove comments */
1264 while(count<filelen) {
1265 if( *md=='#' ) { /* comment */
1266 while( *md!=13 && *md!=10) { /* enters */
1270 if(count>=filelen) break;
1278 /* now time to collect: which are the nodes and fields? */
1281 while(count<filelen) {
1282 if( *md=='{' ) { /* read back */
1285 while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) { /* remove spaces/enters/tab */
1290 while( *cpa>32 && *cpa<128) cpa--;
1296 iv= MEM_callocN(sizeof(struct IvNode), "leesInventor");
1299 if(strcmp(cpa, "Coordinate3")==0 || strcmp(cpa, "Coordinate4")==0) {
1300 skipdata= iv_finddata(iv, "point", 0);
1303 else if(strcmp(cpa, "VertexProperty")==0) {
1304 skipdata= iv_finddata(iv, "vertex", 0);
1307 else if(strcmp(cpa, "IndexedLineSet")==0) {
1308 skipdata= iv_finddata(iv, "coordIndex", 0);
1311 else if(strcmp(cpa, "IndexedTriangleMesh")==0) {
1312 skipdata= iv_finddata(iv, "coordIndex", 0);
1315 else if(strcmp(cpa, "IndexedFaceSet")==0) {
1316 skipdata= iv_finddata(iv, "coordIndex", 0);
1319 else if(strcmp(cpa, "FaceSet")==0) {
1320 skipdata= iv_finddata(iv, "numVertices", 0);
1323 else if(strcmp(cpa, "Material")==0) {
1324 iv_finddata(iv, "diffuseColor", 0);
1325 iv_finddata(iv, "ambientColor", 1);
1328 else if(strcmp(cpa, "BaseColor")==0) {
1329 iv_finddata(iv, "rgb", 0);
1332 else if(strcmp(cpa, "PackedColor")==0) {
1333 iv_finddata(iv, "rgba", 0);
1336 else if(strcmp(cpa, "QuadMesh")==0) {
1337 iv_finddata(iv, "verticesPerColumn", 0);
1338 iv_finddata(iv, "verticesPerRow", 1);
1342 else if(strcmp(cpa, "IndexedTriangleStripSet")==0) {
1343 skipdata= iv_finddata(iv, "coordIndex", 0);
1346 else if(strcmp(cpa, "TriangleStripSet")==0) {
1347 skipdata= iv_finddata(iv, "numVertices", 0);
1350 else if(strcmp(cpa, "IndexedNurbsSurface")==0 || strcmp(cpa, "NurbsSurface")==0) {
1351 iv_finddata(iv, "numUControlPoints", 0);
1352 iv_finddata(iv, "numVControlPoints", 1);
1353 iv_finddata(iv, "uKnotVector", 2);
1354 iv_finddata(iv, "vKnotVector", 3);
1359 while( *md != '}') {
1362 if(count<filelen) break;
1368 BLI_addtail(&ivbase, iv);
1385 if( strncmp(iv->nodename, "Indexed", 7)==0) {
1386 /* seek back: same name? */
1390 if(strcmp(iv->nodename, ivp->nodename)==0) break;
1392 if(strcmp(ivp->nodename, "Coordinate3")==0 ||
1393 strcmp(ivp->nodename, "Coordinate4")==0 ||
1394 strcmp(ivp->nodename, "VertexProperty")==0) {
1404 tot= iv->datalen[0] + ivp->datalen[0];
1406 data= MEM_mallocN(tot*sizeof(float), "samenvoeg iv");
1407 memcpy(data, ivp->data[0], sizeof(float)*ivp->datalen[0]);
1408 memcpy(data+ivp->datalen[0], iv->data[0], sizeof(float)*iv->datalen[0]);
1410 ivp->datalen[0]+= iv->datalen[0];
1411 MEM_freeN(ivp->data[0]);
1414 BLI_remlink(&ivbase, iv);
1415 MEM_freeN(iv->data[0]);
1425 /* convert Nodes to DispLists */
1429 /* printf(" Node: %s\n", iv->nodename); */
1430 /* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */
1433 if( strcmp(iv->nodename, "IndexedLineSet")==0 ) {
1435 colnr= iv_colornumber(iv);
1437 /* seek back to data */
1441 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1445 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1452 /* count the nr of lines */
1455 lll = iv->datalen[0]-1;
1456 for(a=0; a<lll; a++) {
1457 if(index[0]!= -1 && index[1]!= -1) tot++;
1461 tot*= 2; /* nr of vertices */
1462 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor1");
1463 BLI_addtail(listb, dl);
1468 data= (float *)(dl+1);
1471 for(a=0; a<lll; a++) {
1472 if(index[0]!= -1 && index[1]!= -1) {
1473 read_iv_index(data, ivp->data[0], index, 2, coordtype);
1480 else if( strcmp(iv->nodename, "FaceSet")==0 ) {
1482 colnr= iv_colornumber(iv);
1484 /* seek back to data */
1488 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1492 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1499 /* count triangles */
1503 polytype= (int) index[0];
1505 for(a=0; a<iv->datalen[0]; a++) {
1506 if(index[0]== polytype) tot++; /* one kind? */
1511 tot*= polytype; /* nr of vertices */
1512 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor4");
1513 BLI_addtail(listb, dl);
1516 dl->parts= tot/polytype;
1518 data= (float *)(dl+1);
1520 index= ivp->data[0];
1522 for(a=0; a<iv->datalen[0]; a++) {
1524 VECCOPY(data, index);
1528 VECCOPY(data, index);
1532 VECCOPY(data, index);
1537 VECCOPY(data, index);
1544 else if( strcmp(iv->nodename, "TriangleStripSet")==0 ) {
1546 colnr= iv_colornumber(iv);
1548 /* seek back to data */
1552 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1556 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1563 /* count triangles */
1567 index= iv->data[0]; /* strip size */
1569 for(a=0; a<iv->datalen[0]; a++) {
1570 tot+= (int) index[0];
1571 face+= ((int) index[0]) - 2;
1575 dl= MEM_callocN(sizeof(struct DispList), "leesInventor4");
1576 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1577 dl->index= MEM_callocN( face*3*sizeof(int), "dl index");
1579 dl->type= DL_INDEX3;
1583 BLI_addtail(listb, dl);
1586 index= iv->data[0]; /* strip size */
1587 fp= ivp->data[0]; /* vertices */
1592 for(a=0; a<iv->datalen[0]; a++) {
1595 for(b=0; b<index[0]; b++) {
1603 for(b=0; b<lll; b++) {
1616 else if( strcmp(iv->nodename, "IndexedFaceSet")==0 ) {
1618 colnr= iv_colornumber(iv);
1620 /* seek back to data */
1624 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1628 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1635 /* count triangles */
1638 lll = iv->datalen[0]-2;
1639 for(a=0; a<lll; a++) {
1640 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1644 /*number of vertices */
1645 tot= ivp->datalen[0]/coordtype;
1648 dl= MEM_callocN(sizeof(struct DispList), "leesInventor5");
1649 BLI_addtail(listb, dl);
1650 dl->type= DL_INDEX3;
1655 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1656 dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1661 for(b=tot; b>0; b--) {
1671 lll=iv->datalen[0]-2;
1672 for(a=0; a<lll; a++) {
1674 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1676 /* this trick is to fill poly's with more than 3 vertices correctly */
1682 idata[1]= (int) index[1];
1683 idata[2]= (int) index[2];
1693 else if( strcmp(iv->nodename, "IndexedTriangleMesh")==0 ||
1694 strcmp(iv->nodename, "IndexedTriangleStripSet")==0 ) {
1696 colnr= iv_colornumber(iv);
1698 /* seek back to data */
1702 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1706 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1713 /* count triangles */
1716 lll=iv->datalen[0]-2;
1717 for(a=0; a<lll; a++) {
1718 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1722 /* nr of vertices */
1723 tot= ivp->datalen[0]/coordtype;
1725 dl= MEM_callocN(sizeof(struct DispList), "leesInventor6");
1726 BLI_addtail(listb, dl);
1727 dl->type= DL_INDEX3;
1732 dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1733 dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1738 for(b=tot; b>0; b--) {
1748 lll=iv->datalen[0]-2;
1749 for(a=lll; a>0; a--) {
1751 if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1752 idata[0]= (int) index[0];
1753 idata[1]= (int) index[1];
1754 idata[2]= (int) index[2];
1761 else if( strcmp(iv->nodename, "QuadMesh")==0 ) {
1763 colnr= iv_colornumber(iv);
1765 /* seek back to data */
1769 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1773 if( strcmp(ivp->nodename, "VertexProperty")==0 ) {
1777 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1784 tot= (int) (floor(*(iv->data[0])+0.5) * floor(*(iv->data[1])+0.5));
1787 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor8");
1788 BLI_addtail(listb, dl);
1790 dl->parts= (int) floor(*(iv->data[0])+0.5);
1791 dl->nr= (int) floor(*(iv->data[1])+0.5);
1793 data= (float *)(dl+1);
1794 memcpy(data, ivp->data[0], tot*3*sizeof(float));
1798 else if(strcmp(iv->nodename, "IndexedNurbsSurface")==0 || strcmp(iv->nodename, "NurbsSurface")==0) {
1800 colnr= iv_colornumber(iv);
1802 /* sek back to data */
1806 if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1810 if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1816 a= (int) *(iv->data[0]);
1817 b= (int) *(iv->data[1]);
1821 if( (a>=4 || b>=4) && tot>6) {
1828 ob= add_object(OB_SURF);
1833 nu = (Nurb*) MEM_callocN(sizeof(Nurb),"addNurbprim") ;
1834 BLI_addtail(&cu->nurb, nu);
1846 (BPoint*)MEM_callocN(tot * sizeof(BPoint), "addNurbprim3");
1850 VECCOPY(bp->vec, data);
1852 bp->vec[3]= data[3];
1853 VecMulf(bp->vec, 1.0f/data[3]);
1855 else bp->vec[3]= 1.0;
1860 /* iv->datalen[2] / [3] is number of knots */
1861 nu->orderu= iv->datalen[2] - nu->pntsu;
1862 nu->orderv= iv->datalen[3] - nu->pntsv;
1864 nu->knotsu= MEM_mallocN( sizeof(float)*(iv->datalen[2]), "knots");
1865 memcpy(nu->knotsu, iv->data[2], sizeof(float)*(iv->datalen[2]));
1866 nu->knotsv= MEM_mallocN( sizeof(float)*(iv->datalen[3]), "knots");
1867 memcpy(nu->knotsv, iv->data[3], sizeof(float)*(iv->datalen[3]));
1869 switchdirectionNurb(nu);
1873 dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor3");
1874 BLI_addtail(listb, dl);
1876 dl->nr= (int) *(iv->data[0]);
1877 dl->parts= (int) *(iv->data[1]);
1879 data= (float *)(dl+1);
1897 for(a=0; a<IV_MAXFIELD; a++) {
1898 if(iv->data[a]) MEM_freeN(iv->data[a]);
1903 BLI_freelistN(&ivbase);
1904 MEM_freeN(maindata);
1905 MEM_freeN(iv_data_stack);
1909 /* ************************************************************ */
1911 static void displist_to_mesh(DispList *dlfirst)
1919 float *data, vec[3], min[3], max[3];
1920 int a, b, startve, *idata, totedge=0, tottria=0, totquad=0, totvert=0, totface, totcol=0, colnr;
1922 unsigned int maxvertidx;
1925 INIT_MINMAX(min, max);
1930 /* PATCH 1 (polyfill) can't be done, there's no listbase here. do that first! */
1932 if(dl->type==DL_SEGM && dl->nr>2) {
1933 data= (float *)(dl+1);
1934 if(data[0]==data[3*(dl->nr-1)]) {
1935 if(data[1]==data[3*(dl->nr-1)+1]) {
1936 if(data[2]==data[3*(dl->nr-1)+2]) {
1945 if(dl->col > totcol) totcol= dl->col;
1947 /* size and count */
1948 if(dl->type==DL_SURF) {
1951 if(dl->flag & DL_CYCL_U) a++;
1952 if(dl->flag & DL_CYCL_V) b++;
1956 totvert+= dl->nr*dl->parts;
1958 data= (float *)(dl+1);
1959 for(a= dl->nr*dl->parts; a>0; a--) {
1960 DO_MINMAX(data, min, max);
1964 else if(dl->type==DL_POLY) {
1965 if(dl->nr==3 || dl->nr==4) {
1966 if(dl->nr==3) tottria+= dl->parts;
1967 else totquad+= dl->parts;
1969 totvert+= dl->nr*dl->parts;
1971 data= (float *)(dl+1);
1972 for(a= dl->nr*dl->parts; a>0; a--) {
1973 DO_MINMAX(data, min, max);
1979 tottria+= dl->nr*dl->parts;
1980 totvert+= dl->nr*dl->parts;
1982 data= (float *)(dl+1);
1983 for(a= dl->nr*dl->parts; a>0; a--) {
1984 DO_MINMAX(data, min, max);
1990 else if(dl->type==DL_INDEX3) {
1991 tottria+= dl->parts;
1995 for(a= dl->nr; a>0; a--) {
1996 DO_MINMAX(data, min, max);
2000 else if(dl->type==DL_SEGM) {
2002 tottria+= (dl->nr-1)*dl->parts;
2003 totvert+= dl->nr*dl->parts;
2005 data= (float *)(dl+1);
2006 for(a= dl->nr*dl->parts; a>0; a--) {
2007 DO_MINMAX(data, min, max);
2020 error("Found more than 16 different colors");
2024 vec[0]= (min[0]+max[0])/2;
2025 vec[1]= (min[1]+max[1])/2;
2026 vec[2]= (min[2]+max[2])/2;
2028 ob= add_object(OB_MESH);
2029 VECCOPY(ob->loc, vec);
2030 where_is_object(ob);
2036 ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
2037 me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
2039 ob->totcol= (unsigned char) me->totcol;
2044 for(a=0; a<totcol; a++) {
2045 ma= G.main->mat.first;
2047 if(ma->mtex[0]==0) {
2048 if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
2057 ma= add_material("ext");
2059 ma->r= ivcolors[a][0];
2060 ma->g= ivcolors[a][1];
2061 ma->b= ivcolors[a][2];
2066 totface= totquad+tottria+totedge;
2068 printf("Import: %d vertices %d faces\n", totvert, totface);
2070 me->totvert= totvert;
2071 me->totface= totface;
2072 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
2074 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
2076 maxvertidx= totvert-1;
2086 colnr= (dl->col>15 ? 15: dl->col);
2089 if(dl->type==DL_SURF) {
2090 data= (float *)(dl+1);
2092 for(a=dl->parts*dl->nr; a>0; a--) {
2093 mvert->co[0]= data[0] -vec[0];
2094 mvert->co[1]= data[1] -vec[1];
2095 mvert->co[2]= data[2] -vec[2];
2101 for(a=0; a<dl->parts; a++) {
2103 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
2111 for(; b<dl->nr; b++) {
2118 mface->mat_nr= colnr;
2119 test_index_face(mface, NULL, 0, 4);
2130 startve += dl->parts*dl->nr;
2133 else if(dl->type==DL_POLY) {
2135 if(dl->nr==3 || dl->nr==4) {
2136 data= (float *)(dl+1);
2138 for(a=dl->parts*dl->nr; a>0; a--) {
2139 mvert->co[0]= data[0] -vec[0];
2140 mvert->co[1]= data[1] -vec[1];
2141 mvert->co[2]= data[2] -vec[2];
2146 for(a=0; a<dl->parts; a++) {
2148 mface->v1= startve+a*dl->nr;
2149 mface->v2= startve+a*dl->nr+1;
2150 mface->v3= startve+a*dl->nr+2;
2151 mface->mat_nr= colnr;
2152 test_index_face(mface, NULL, 0, 3);
2156 mface->v1= startve+a*dl->nr;
2157 mface->v2= startve+a*dl->nr+1;
2158 mface->v3= startve+a*dl->nr+2;
2159 mface->v4= startve+a*dl->nr+3;
2160 mface->mat_nr= colnr;
2161 test_index_face(mface, NULL, 0, 4);
2165 startve += dl->parts*dl->nr;
2168 data= (float *)(dl+1);
2170 for(a=dl->parts*dl->nr; a>0; a--) {
2171 mvert->co[0]= data[0] -vec[0];
2172 mvert->co[1]= data[1] -vec[1];
2173 mvert->co[2]= data[2] -vec[2];
2179 for(b=0; b<dl->parts; b++) {
2180 for(a=0; a<dl->nr; a++) {
2181 mface->v1= startve+a;
2183 if(a==dl->nr-1) mface->v2= startve;
2184 else mface->v2= startve+a+1;
2186 mface->mat_nr= colnr;
2194 else if(dl->type==DL_INDEX3) {
2197 for(a=dl->nr; a>0; a--) {
2198 mvert->co[0]= data[0] -vec[0];
2199 mvert->co[1]= data[1] -vec[1];
2200 mvert->co[2]= data[2] -vec[2];
2206 for(b=dl->parts; b>0; b--) {
2207 mface->v1= startve+idata[0];
2208 mface->v2= startve+idata[1];
2209 mface->v3= startve+idata[2];
2210 mface->mat_nr= colnr;
2212 if (mface->v1>maxvertidx) mface->v1= maxvertidx;
2213 if (mface->v2>maxvertidx) mface->v2= maxvertidx;
2214 if (mface->v3>maxvertidx) mface->v3= maxvertidx;
2216 test_index_face(mface, NULL, 0, 3);
2222 else if(dl->type==DL_SEGM) {
2223 data= (float *)(dl+1);
2225 for(a=dl->parts*dl->nr; a>0; a--) {
2226 mvert->co[0]= data[0] -vec[0];
2227 mvert->co[1]= data[1] -vec[1];
2228 mvert->co[2]= data[2] -vec[2];
2233 for(b=0; b<dl->parts; b++) {
2234 for(a=0; a<dl->nr-1; a++) {
2235 mface->v1= startve+a;
2236 mface->v2= startve+a+1;
2237 mface->mat_nr= colnr;
2246 mesh_add_normals_flags(me);
2250 static void displist_to_objects(ListBase *lbase)
2252 DispList *dl, *first, *prev, *next;
2254 int maxaantal, curcol, totvert=0, vert;
2256 /* irst this: is still active */
2258 where_is_object(ivsurf);
2266 /* PATCH 1: polyfill */
2267 if(dl->type==DL_POLY && dl->nr>4) {
2268 /* solution: put them together in separate listbase */
2271 /* PATCH 2: poly's of 2 points */
2272 if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
2277 /* count vertices */
2282 if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
2283 else if(dl->type==DL_POLY) {
2284 if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
2285 else if(dl->nr>4) totvert+= dl->nr*dl->parts;
2287 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
2288 else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
2295 if(ivsurf==0) error("Found no data");
2296 if(lbase->first) BLI_freelistN(lbase);
2303 if(totvert>maxaantal) {
2305 /* try to put colors together */
2307 tempbase.first= tempbase.last= 0;
2309 while(lbase->first) {
2313 if(dl->col==curcol) {
2314 BLI_remlink(lbase, dl);
2315 BLI_addtail(&tempbase, dl);
2322 /* in tempbase are all 'curcol' */
2324 dl= first= tempbase.first;
2328 if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
2329 else if(dl->type==DL_POLY) {
2330 if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
2331 else if(dl->nr>4) vert= dl->nr*dl->parts;
2333 else if(dl->type==DL_INDEX3) totvert+= dl->nr;
2334 else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
2337 if(totvert > maxaantal || dl->next==0) {
2339 displist_to_mesh(first);
2344 displist_to_mesh(first);
2354 freedisplist(&tempbase);
2359 else displist_to_mesh(lbase->first);
2361 freedisplist(lbase);
2365 int BKE_read_exotic(char *name)
2367 ListBase lbase={0, 0};
2371 int *s0 = (int*) str;
2374 // make sure we're not trying to read a directory....
2377 if (name[len-1] !='/' && name[len-1] != '\\') {
2378 gzfile = gzopen(name,"rb");
2380 if (NULL == gzfile ) {
2381 error("Can't open file: %s", name);
2384 gzread(gzfile, str, 31);
2387 if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
2393 error("Unable to perform function in EditMode");
2395 read_radiogour(name);
2399 else if ELEM4(*s0, DDG1, DDG2, DDG3, DDG4) {
2401 error("Unable to perform function in EditMode");
2403 read_videoscape(name);
2407 else if(strncmp(str, "#Inventor V1.0", 14)==0) {
2408 if( strncmp(str+15, "ascii", 5)==0) {
2409 read_inventor(name, &lbase);
2410 displist_to_objects(&lbase);
2413 error("Can only read Inventor 1.0 ascii");
2416 else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
2417 read_inventor(name, &lbase);
2418 displist_to_objects(&lbase);
2421 else if(is_dxf(name)) {
2425 else if(is_stl(name)) {
2426 if (is_stl_ascii(name))
2427 read_stl_mesh_ascii(name);
2429 read_stl_mesh_binary(name);
2432 #ifndef DISABLE_PYTHON
2433 // TODO: this should not be in the kernel...
2434 else { // unknown format, call Python importloader
2435 if (BPY_call_importloader(name)) {
2438 error("Unknown file type or error, check console");
2442 #endif /* DISABLE_PYTHON */
2452 /* ************************ WRITE ************************** */
2455 char temp_dir[160]= {0, 0};
2457 static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
2461 VECCOPY(vert, verts[(index)].co);
2462 Mat4MulVecfl(ob->obmat, vert);
2464 if (G.order==B_ENDIAN) {
2465 SWITCH_INT(vert[0]);
2466 SWITCH_INT(vert[1]);
2467 SWITCH_INT(vert[2]);
2470 fwrite(vert, sizeof(float), 3, fpSTL);
2473 static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
2475 MVert *mvert = dm->getVertArray(dm);
2476 MFace *mface = dm->getFaceArray(dm);
2477 int i, numfacets = 0, totface = dm->getNumFaces(dm);
2478 float zero[3] = {0.0f, 0.0f, 0.0f};
2480 for (i=0; i<totface; i++, mface++) {
2481 fwrite(zero, sizeof(float), 3, fpSTL);
2482 write_vert_stl(ob, mvert, mface->v1, fpSTL);
2483 write_vert_stl(ob, mvert, mface->v2, fpSTL);
2484 write_vert_stl(ob, mvert, mface->v3, fpSTL);
2485 fprintf(fpSTL, " ");
2488 if(mface->v4) { /* quad = 2 tri's */
2489 fwrite(zero, sizeof(float), 3, fpSTL);
2490 write_vert_stl(ob, mvert, mface->v1, fpSTL);
2491 write_vert_stl(ob, mvert, mface->v3, fpSTL);
2492 write_vert_stl(ob, mvert, mface->v4, fpSTL);
2493 fprintf(fpSTL, " ");
2501 static int write_object_stl(FILE *fpSTL, Object *ob, Mesh *me)
2504 DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
2506 numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
2513 void write_stl(char *str)
2521 if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2522 if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2523 if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
2525 if (!during_script()) {
2526 if (BLI_exists(str))
2527 if(saveover(str)==0)
2531 fpSTL= fopen(str, "wb");
2534 if (!during_script()) error("Can't write file");
2537 strcpy(temp_dir, str);
2541 /* The header part of the STL */
2542 /* First 80 characters are a title or whatever you want.
2543 Lets make the first 32 of those spam and the rest the filename.
2544 Those first 80 characters will be followed by 4 bytes
2545 which will be overwritten later with an integer holding
2546 how many facets are written (we set them to ' ' for now).
2548 fprintf(fpSTL, "Binary STL output from Blender: %-48.48s ", str);
2550 /* Write all selected mesh objects */
2551 base= G.scene->base.first;
2553 if (base->flag & SELECT) {
2555 if (ob->type == OB_MESH) {
2558 numfacets += write_object_stl(fpSTL, ob, me);
2564 /* time to write the number of facets in the 4 bytes
2567 fseek(fpSTL, 80, SEEK_SET);
2569 if (G.order==B_ENDIAN) {
2570 SWITCH_INT(numfacets);
2572 fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
2579 static void write_videoscape_mesh(Object *ob, char *str)
2581 EditMesh *em = G.editMesh;
2588 unsigned int kleur[32];
2594 if(ob && ob->type==OB_MESH);
2599 kleur[0]= 0x00C0C0C0;
2602 for(a=0; a<ob->totcol; a++, cp+=4) {
2604 ma= give_current_material(ob, a+1);
2606 cp[0]= (unsigned char) (255.0*ma->emit);
2607 cp[1]= (unsigned char) (255.0*ma->b);
2608 cp[2]= (unsigned char) (255.0*ma->g);
2609 cp[3]= (unsigned char) (255.0*ma->r);
2610 if(G.order==L_ENDIAN) SWITCH_INT(kleur[a]);
2612 else kleur[a]= 0x00C0C0C0;
2617 fp= fopen(str, "wb");
2618 if(fp==NULL) return;
2620 fprintf(fp,"3DG1\n");
2624 fprintf(fp, "%d\n", G.totvert);
2627 eve= em->verts.first;
2629 VECCOPY(co, eve->co);
2630 Mat4MulVecfl(ob->obmat, co);
2631 fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
2636 evl= em->faces.first;
2640 fprintf(fp, "3 %ld %ld %ld 0x%x\n",
2641 (long int) evl->v1->tmp.l,
2642 (long int) evl->v2->tmp.l,
2643 (long int) evl->v3->tmp.l,
2644 kleur[evl->mat_nr]);
2647 fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n",
2648 (long int) evl->v1->tmp.l,
2649 (long int) evl->v2->tmp.l,
2650 (long int) evl->v3->tmp.l,
2651 (long int) evl->v4->tmp.l,
2652 kleur[evl->mat_nr]);
2658 DerivedMesh *dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
2662 fprintf(fp, "%d\n", me->totvert);
2665 for(a=0; a<me->totvert; a++) {
2666 dm->getVertCo(dm, a, co);
2667 Mat4MulVecfl(ob->obmat, co);
2668 fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
2670 for(a=0; a<me->totface; a++, mface++) {
2672 fprintf(fp, "3 %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, kleur[mface->mat_nr]);
2675 fprintf(fp, "4 %d %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, mface->v4, kleur[mface->mat_nr]);
2687 void write_videoscape(char *str)
2690 int file, val, lampdone=0;
2691 unsigned short numlen;
2692 char head[FILE_MAXFILE], tail[FILE_MAXFILE];
2694 if(BLI_testextensie(str,".trace")) str[ strlen(str)-6]= 0;
2695 if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2696 if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2697 if(BLI_testextensie(str,".obj")==0) strcat(str, ".obj");
2699 file= open(str,O_BINARY|O_RDONLY);
2701 if(file>-1) if(!during_script() && saveover(str)==0) return;
2703 strcpy(temp_dir, str);
2705 base= G.scene->base.first;
2707 if((base->flag & SELECT) && (base->lay & G.scene->lay)) {
2708 if(base->object->type==OB_MESH) {
2709 write_videoscape_mesh(base->object, str);
2710 val = BLI_stringdec(str, head, tail, &numlen);
2711 BLI_stringenc(str, head, tail, numlen, val + 1);
2713 else if(base->object->type==OB_CURVE || base->object->type==OB_SURF) {
2714 /* write_videoscape_nurbs(base->object, str); */
2715 /* val = stringdec(str, head, tail, &numlen); */
2716 /* stringenc(str, head, tail, numlen, val + 1); */
2718 else if(lampdone==0 && base->object->type==OB_LAMP) {
2720 /* write_videoscape_lamps(str); */
2721 /* val = stringdec(str, head, tail, &numlen); */
2722 /* stringenc(str, head, tail, numlen, val + 1); */
2729 /* remove when higher numbers exist */
2730 while(remove(str)==0) {
2732 val = BLI_stringdec(str, head, tail, &numlen);
2733 BLI_stringenc(str, head, tail, numlen, val + 1);
2737 /* ******************************* WRITE VRML ***************************** */
2739 static void replace_chars(char *str1, char *str2)
2741 int a= strlen(str2);
2745 if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
2746 else str1[a]= str2[a];
2751 static void write_material_vrml(FILE *fp, Material *ma)
2755 replace_chars(str, ma->id.name+2);
2757 fprintf(fp, "\tDEF %s\n", str);
2758 fprintf(fp, "\tMaterial {\n");
2760 fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
2761 fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
2762 fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
2763 fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
2765 fprintf(fp, "\t}\n");
2769 unsigned int *mcol_to_vcol(Mesh *me)
2772 unsigned int *mcol, *mcoln, *mcolmain;
2775 if(me->totface==0 || me->mcol==0) return 0;
2777 mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
2778 mcol = (unsigned int *)me->mcol;
2781 for(a=me->totface; a>0; a--, mface++) {
2782 mcoln[mface->v1]= mcol[0];
2783 mcoln[mface->v2]= mcol[1];
2784 mcoln[mface->v3]= mcol[2];
2785 if(mface->v4) mcoln[mface->v4]= mcol[3];
2793 void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)