/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 1997 by Ton Roosendaal, Frank van Beek and Joeri Kassenaar. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include #include #include #include #include "/usr/people/include/Trace.h" #include "/usr/people/include/Button.h" #include #include #include #include #include #include extern void VecMulf(float *v1, float f); /* ********* DXF tempstructen en globals */ struct DxfLayer { struct DxfLayer *next, *prev; char name[32]; int nr; }; struct DxfBlock { struct DxfBlock *next, *prev; char name[32]; struct ListBase disp; }; struct ListBase DxfLaybase = {0, 0}; struct ListBase DxfBlockbase = {0, 0}; /* ********** DXF hulproutines ********* */ struct ListBase *addDxfBlock(char *name) { struct DxfBlock *dxfblock; dxfblock= callocN(sizeof(struct DxfBlock), "addDxfBlock"); strncpy(dxfblock->name, name, 31); addtail(&DxfBlockbase, dxfblock); return &(dxfblock->disp); } struct ListBase *findDxfBlock(char *name) { struct DxfBlock *dxfblock; dxfblock= DxfBlockbase.first; while(dxfblock) { if( strncmp(dxfblock->name, name, 31)==0) break; dxfblock= dxfblock->next; } if(dxfblock) return &(dxfblock->disp); else return 0; } void addDxfLayer(char *name) { struct DxfLayer *dxflay; int nr=1; /* eerste layer is nummer 1, nummer nul zijn de naamloze layers */ if(name[0]=='0' && name[1]==0) return; dxflay= DxfLaybase.last; if(dxflay) nr= dxflay->nr+1; dxflay= callocN(sizeof(struct DxfLayer), "addDxfLayer"); dxflay->nr= nr; strncpy(dxflay->name, name, 31); addtail(&DxfLaybase, dxflay); } int findDxfLayer(char *name) { struct DxfLayer *dxflay; int nr=0; dxflay= DxfLaybase.first; while(dxflay) { if(strncmp(dxflay->name, name, 31)==0) return dxflay->nr; dxflay= dxflay->next; } return 0; } void strange_DXF_transform(dl, trans) struct DispList *dl; float *trans; { float *data; float q1[4], q2[4], mat[3][3], vec[3]; float co,si,n[3],x2,y2,z2,x1,y1,z1,len1,len,b1; float fac; int totvert; /* dominante as */ if( fabs(trans[0])>fabs(trans[1]) ) fac= 1.0; else fac= -1.0; x2 = trans[0] ; y2 = trans[1] ; z2 = trans[2]; /* vector roteren naar negatieve y-as */ len1=fsqrt(x2*x2+y2*y2+z2*z2); if(len1 == 0.0) return; len= fsqrt(x2*x2+y2*y2); if(len>0.0) { b1= fatan2(x2, -y2); co= fcos(b1/2); si= fsin(b1/2); } else { co= 1.0; si= 0.0; } q1[0]= co; q1[1]= 0.0; q1[2]= 0.0; q1[3]= si; QuatToMat3(q1, mat); VECCOPY(vec, trans); Mat3MulVecfl(mat, vec); /* vector roteren naar positieve z-as */ y2= vec[1]; z2= vec[2]; len= fsqrt(y2*y2+z2*z2); if(len>0.0) { b1= fatan2(fac*y2, z2); co= fcos(b1/2); si= fsin(b1/2); } else { co= 1.0; si= 0.0; } q2[0]= co; q2[1]= si; q2[2]= 0.0; q2[3]= 0.0; QuatMul(q1, q1, q2); QuatToMat3(q1, mat); /* data roteren */ totvert= dl->nr*dl->parts; data= (float *)(dl+1); while(totvert) { Mat3MulVecfl(mat, data); totvert--; data+= 3; } } void makeDxfInsert(listb, lb, transfound, vec) /* lb wordt gekopieerd en toegevoegd aan listb */ struct ListBase *listb, *lb; int transfound; float *vec; { struct DispList *dl, *dlnew; float *data, *datanew; float mat[3][3], rmat[3][3], hoek; int len; Mat3One(mat); hoek= PI*vec[6]/180.0; mat[0][0]= fcos(hoek)*vec[3]; mat[0][1]= fsin(hoek)*vec[3]; mat[1][0]= -fsin(hoek)*vec[4]; mat[1][1]= fcos(hoek)*vec[4]; mat[2][2]= vec[5]; dl= lb->first; while(dl) { len= dl->nr*dl->parts; dlnew= callocN(sizeof(struct DispList)+4*3*len, "makeDxfInsert"); *dlnew= *dl; addtail(listb, dlnew); data= (float *)(dl+1); datanew= (float *)(dlnew+1); while(len--) { VECCOPY(datanew, data); Mat3MulVecfl(mat, datanew); VecAddf(datanew, datanew, vec); data+= 3; datanew+= 3; } if(transfound) strange_DXF_transform(dlnew, vec+7); dl= dl->next; } } void disp_poly_to_cubes(lb, dl, width, extrude, transfound, trans) struct ListBase *lb; struct DispList *dl; float width, extrude; int transfound; float *trans; { struct DispList *dln; float *data, *data3, *datan, axis[3], widthvec[3], extrudevec[3], vec[3], cent[3], cube[8][3]; int a; /* neem setjes van 2 vertices, width==loodrecht op axis en lijn,, extrude==axis */ if(dl->type!=DL_POLY) return; axis[0]= axis[1]= 0.0; axis[2]= 1.0; a= dl->nr; data= (float *)(dl+1); data3= data+3; while(a>0) { VecSubf(vec, data, data3); VecMulf(vec, 0.5); Crossf(widthvec, axis, vec); Normalise(widthvec); VecMulf(widthvec, 0.5*width); VECCOPY(extrudevec, axis); VecMulf(extrudevec, extrude); cent[0]= (data[0]+data3[0])/2.0; cent[1]= (data[1]+data3[1])/2.0; cent[2]= (data[2]+data3[2])/2.0; dln= callocN(sizeof(struct DispList)+6*4*3*4, "disppolytocube"); addtail(lb, dln); dln->type= DL_POLY; dln->nr= 4; dln->parts= 6; datan= (float *)(dln+1); /* cube */ cube[0][0]= cent[0]-vec[0]-widthvec[0]; cube[0][1]= cent[1]-vec[1]-widthvec[1]; cube[0][2]= cent[2]-vec[2]-widthvec[2]; cube[1][0]= cent[0]+vec[0]-widthvec[0]; cube[1][1]= cent[1]+vec[1]-widthvec[1]; cube[1][2]= cent[2]+vec[2]-widthvec[2]; cube[2][0]= cent[0]+vec[0]+widthvec[0]; cube[2][1]= cent[1]+vec[1]+widthvec[1]; cube[2][2]= cent[2]+vec[2]+widthvec[2]; cube[3][0]= cent[0]-vec[0]+widthvec[0]; cube[3][1]= cent[1]-vec[1]+widthvec[1]; cube[3][2]= cent[2]-vec[2]+widthvec[2]; cube[4][0]= cube[0][0]+extrudevec[0]; cube[4][1]= cube[0][1]+extrudevec[1]; cube[4][2]= cube[0][2]+extrudevec[2]; cube[5][0]= cube[1][0]+extrudevec[0]; cube[5][1]= cube[1][1]+extrudevec[1]; cube[5][2]= cube[1][2]+extrudevec[2]; cube[6][0]= cube[2][0]+extrudevec[0]; cube[6][1]= cube[2][1]+extrudevec[1]; cube[6][2]= cube[2][2]+extrudevec[2]; cube[7][0]= cube[3][0]+extrudevec[0]; cube[7][1]= cube[3][1]+extrudevec[1]; cube[7][2]= cube[3][2]+extrudevec[2]; /* onder */ VECCOPY(datan, cube[0]); datan+=3; VECCOPY(datan, cube[1]); datan+=3; VECCOPY(datan, cube[2]); datan+=3; VECCOPY(datan, cube[3]); datan+=3; /* boven */ VECCOPY(datan, cube[4]); datan+=3; VECCOPY(datan, cube[5]); datan+=3; VECCOPY(datan, cube[6]); datan+=3; VECCOPY(datan, cube[7]); datan+=3; /* voor */ VECCOPY(datan, cube[0]); datan+=3; VECCOPY(datan, cube[1]); datan+=3; VECCOPY(datan, cube[5]); datan+=3; VECCOPY(datan, cube[4]); datan+=3; /* achter */ VECCOPY(datan, cube[3]); datan+=3; VECCOPY(datan, cube[2]); datan+=3; VECCOPY(datan, cube[6]); datan+=3; VECCOPY(datan, cube[7]); datan+=3; /* links */ VECCOPY(datan, cube[0]); datan+=3; VECCOPY(datan, cube[3]); datan+=3; VECCOPY(datan, cube[7]); datan+=3; VECCOPY(datan, cube[4]); datan+=3; /* rechts */ VECCOPY(datan, cube[1]); datan+=3; VECCOPY(datan, cube[2]); datan+=3; VECCOPY(datan, cube[6]); datan+=3; VECCOPY(datan, cube[5]); datan+=3; if(transfound) strange_DXF_transform(dln, trans); a--; if(a==1) { if(dl->nr==2) break; data+= 3; data3= (float *)(dl+1); } else { data+= 3; data3+= 3; } } remlink(lb, dl); freeN(dl); } void disp_poly_to_faces(lb, dl, width, transfound, trans) struct ListBase *lb; struct DispList *dl; float width; int transfound; float *trans; { /* printf("Het komt voor \n"); */ } /* ******************* */ void leesDXF(char *str, struct ListBase *listb) { FILE *fp; struct DispList *dl, *dln; struct ListBase *lb, *lbinsert; struct DxfBlock *dxfblock; float vec[12], *data, *hulpdata, *hd, *hd2; int code, readcode=0, a, s, tot, afmx, afmy, ok=0, unknownsize, flag, p1, p2, p3, p4; int curlayer=0, totvlak, extrude, width, transfound; char astr[100]; /* test dl= callocN(sizeof(struct DispList)+3*4, "test"); dl->type= DL_POLY; dl->nr= 1; dl->parts= 1; data= (float *)(dl+1); vec[0]= 1.0; vec[1]= 0.0; vec[2]= 0.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf(" 1 0 0 %f %f %f\n", data[0], data[1], data[2]); vec[0]= -1.0; vec[1]= 0.0; vec[2]= 0.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf("-1 0 0 %f %f %f\n", data[0], data[1], data[2]); vec[0]= 0.0; vec[1]= 1.0; vec[2]= 0.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf(" 0 1 0 %f %f %f\n", data[0], data[1], data[2]); vec[0]= 0.0; vec[1]= -1.0; vec[2]= 0.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf(" 0-1 0 %f %f %f\n", data[0], data[1], data[2]); vec[0]= 0.0; vec[1]= 0.0; vec[2]= 1.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf(" 0 0 1 %f %f %f\n", data[0], data[1], data[2]); vec[0]= 0.0; vec[1]= 0.0; vec[2]= -1.0; data[0]= 1; data[1]= 10; data[2]= 100; strange_DXF_transform(dl, vec); printf(" 0 0-1 %f %f %f\n", data[0], data[1], data[2]); freeN(dl); */ lb= listb; /* variabele wordt gebruikt om BLOCKS te kunnen maken */ fp= fopen(str, "r"); while(TRUE) { if( fscanf(fp, "%d", &code)==EOF ) break; if( fscanf(fp, "%99s", astr)==EOF ) break; if(code==0) { if(strcmp(astr, "SECTION")==0) { if( fscanf(fp, "%d", &code)==EOF ) break; if( fscanf(fp, "%99s", astr)==EOF ) break; if(code==2) { if(strcmp(astr, "ENTITIES")==0) { ok= 1; break; } else if(strcmp(astr, "BLOCKS")==0) { ok= 1; break; } } } else if(strcmp(astr, "LAYER")==0) { /* kleurinformatie */ if( fscanf(fp, "%d", &code)==EOF ) break; if( fscanf(fp, "%99s", astr)==EOF ) break; if(code==2) { addDxfLayer(astr); } } } } while(ok) { if(readcode==0) { /* readcode==1 als een van de delen hieronder te ver doorleest */ if( fscanf(fp, "%d", &code)==EOF ) break; if( fscanf(fp, "%99s", astr)==EOF ) break; } readcode= 0; if(strcmp(astr, "EOF")==0) { ok= 0; } if(strcmp(astr, "BLOCK")==0) { fscanf(fp, "%d", &code); fscanf(fp, "%99s", astr); fscanf(fp, "%d", &code); fscanf(fp, "%99s", astr); fscanf(fp, "%d", &code); fscanf(fp, "%99s", astr); if(code==2) { lb= addDxfBlock(astr); } } else if(strcmp(astr, "ENDBLK")==0) { /* hoofd listbase weer terug */ lb= listb; } else if(strcmp(astr, "INSERT")==0) { code= 1; transfound= 0; vec[0]= vec[1]= vec[2]= 0.0; vec[3]= vec[4]= vec[5]= 1.0; vec[6]= 0.0; lbinsert= 0; while(code!=0) { if( fscanf(fp, "%d", &code)==EOF ) break; switch(code) { case 2: fscanf(fp, "%99s", astr); lbinsert= findDxfBlock(astr); break; case 10: fscanf(fp, "%f", vec); break; /* translatie */ case 20: fscanf(fp, "%f", vec+1); break; case 30: fscanf(fp, "%f", vec+2); break; case 41: fscanf(fp, "%f", vec+3); break; /* scaling */ case 42: fscanf(fp, "%f", vec+4); break; case 43: fscanf(fp, "%f", vec+5); break; case 50: fscanf(fp, "%f", vec+6); break; /* xy vlak rotatie */ case 210: fscanf(fp, "%f", vec+7); transfound= 1; break; case 220: fscanf(fp, "%f", vec+8); break; case 230: fscanf(fp, "%f", vec+9); break; default: fscanf(fp, "%99s", astr); break; } } readcode= 1; /* te ver doorgelezen */ if(lbinsert) { makeDxfInsert(lb, lbinsert, transfound, vec); } } else if(strcmp(astr, "LINE")==0) { /* doet alleen 3D lijnen */ code= 1; while(code!=0) { if( fscanf(fp, "%d", &code)==EOF ) break; switch(code) { case 8: fscanf(fp, "%99s", astr); curlayer= findDxfLayer(astr); break; case 10: fscanf(fp, "%f", vec); break; case 20: fscanf(fp, "%f", vec+1); break; case 30: fscanf(fp, "%f", vec+2); break; case 11: fscanf(fp, "%f", vec+3); break; case 21: fscanf(fp, "%f", vec+4); break; case 31: fscanf(fp, "%f", vec+5); break; default: fscanf(fp, "%99s", astr); break; } if(code==31) break; } if(code==31) { dl= callocN(sizeof(struct DispList)+4*3*2, "leesDXF2"); addtail(lb, dl); dl->nr= 2; dl->parts= 1; dl->type= DL_SEGM; dl->col= curlayer; data= (float *)(dl+1); VECCOPY(data, vec); VECCOPY(data+3, vec+3); } } else if(strcmp(astr, "3DFACE")==0) { /* 4 vertices */ code= 1; while(code!=0) { if( fscanf(fp, "%d", &code)==EOF ) break; switch(code) { case 8: fscanf(fp, "%99s", astr); curlayer= findDxfLayer(astr); break; case 10: fscanf(fp, "%f", vec); break; case 20: fscanf(fp, "%f", vec+1); break; case 30: fscanf(fp, "%f", vec+2); break; case 11: fscanf(fp, "%f", vec+3); break; case 21: fscanf(fp, "%f", vec+4); break; case 31: fscanf(fp, "%f", vec+5); break; case 12: fscanf(fp, "%f", vec+6); break; case 22: fscanf(fp, "%f", vec+7); break; case 32: fscanf(fp, "%f", vec+8); break; case 13: fscanf(fp, "%f", vec+9); break; case 23: fscanf(fp, "%f", vec+10); break; case 33: fscanf(fp, "%f", vec+11); break; default: fscanf(fp, "%99s", astr); break; } if(code==33) break; } if(code==33) { dl= callocN(sizeof(struct DispList)+4*3*4, "leesDXF2"); addtail(lb, dl); dl->nr= 4; dl->parts= 1; dl->type= DL_POLY; dl->col= curlayer; data= (float *)(dl+1); VECCOPY(data, vec); VECCOPY(data+3, vec+3); VECCOPY(data+6, vec+6); VECCOPY(data+9, vec+9); } } else if(strcmp(astr, "POLYLINE")==0) { afmx= afmy= unknownsize= flag= totvlak= extrude= width= transfound= 0; vec[3]= 0.0; /* width */ vec[4]= 0.0; /* extrude */ vec[6]= vec[7]= 0.0; vec[8]= 1.0; /* extrude richting */ code= 1; while(code!=0) { /* wachten op VERTEX */ if( fscanf(fp, "%d", &code)==EOF ) break; if(code==8) {fscanf(fp, "%99s", astr); curlayer= findDxfLayer(astr); } else if(code==39) { fscanf(fp, "%f", vec+3); extrude= 1; } else if(code==40) { fscanf(fp, "%f", vec+4); width= 1; } else if(code==70) fscanf(fp, "%d", &flag); else if(code==71) fscanf(fp, "%d", &afmy); else if(code==72) fscanf(fp, "%d", &afmx); else if(code==210) { fscanf(fp, "%f", vec+6); transfound=1;} else if(code==220) fscanf(fp, "%f", vec+7); else if(code==230) fscanf(fp, "%f", vec+8); else if( fscanf(fp, "%99s", astr)==EOF ) break; } if(flag & 64) { /* nieuw type: beetje videoscape-achtig */ /* afmy= aantal vertices */ /* afmx= aantal vlakken (vierhoeken) */ if(afmx>0 && afmy>0) { hulpdata= callocN(4*3*(afmy+afmx), "leesDXF6"); tot= 4*afmx; dl= callocN(sizeof(struct DispList)+4*3*tot, "leesDXF7"); addtail(lb, dl); dl->nr= 4; dl->parts= afmx; dl->col= curlayer; dl->type= DL_POLY; hd= hulpdata; data= (float *)(dl+1); tot= afmx+afmy; /* hoogstwaarschijnlijk zit in astr nu VERTEX */ if(code==0 && strcmp(astr, "VERTEX")==0 ) { tot--; hd+= 3; } /* alle vertexen inlezen tot SEQUEND */ while(tot>=0) { if( fscanf(fp, "%d", &code)==EOF ) break; switch(code) { case 10: fscanf(fp, "%f", hd-3); break; case 20: fscanf(fp, "%f", hd-2); break; case 30: fscanf(fp, "%f", hd-1); break; case 71: fscanf(fp, "%d", &p1); break; case 72: fscanf(fp, "%d", &p2); break; case 73: fscanf(fp, "%d", &p3); break; case 74: fscanf(fp, "%d", &p4); break; default: fscanf(fp, "%99s", astr); break; } if(code==0 && strcmp(astr, "SEQEND")==0 ) break; if(code==0 && strcmp(astr, "VERTEX")==0 ) { tot--; hd+= 3; } if(code==74) { /* nieuw vlak */ p1= 3*(p1-1); p2= 3*(p2-1); p3= 3*(p3-1); p4= 3*(p4-1); data[0]= hulpdata[p1]; data[1]= hulpdata[p1+1]; data[2]= hulpdata[p1+2]; data+= 3; data[0]= hulpdata[p2]; data[1]= hulpdata[p2+1]; data[2]= hulpdata[p2+2]; data+= 3; data[0]= hulpdata[p3]; data[1]= hulpdata[p3+1]; data[2]= hulpdata[p3+2]; data+= 3; data[0]= hulpdata[p4]; data[1]= hulpdata[p4+1]; data[2]= hulpdata[p4+2]; data+= 3; totvlak++; if(totvlak>afmx) break; } } freeN(hulpdata); if(transfound) strange_DXF_transform(dl, vec+6); } } else { if(afmx==0 && afmy==0) { /* zelf tellen */ unknownsize= 1; afmx= 256; afmy= 1; } tot= afmx*afmy; dl= callocN(sizeof(struct DispList)+4*3*tot, "leesDXF1"); addtail(lb, dl); dl->nr= afmx; dl->parts= afmy; dl->col= curlayer; dl->type= DL_SURF; if(flag & 1) dl->flag= 2; if(flag & 32) dl->flag+= 1; if(afmy<2) dl->type= DL_POLY; data= (float *)(dl+1); /* hoogstwaarschijnlijk zit in astr nu VERTEX */ if(code==0 && strcmp(astr, "VERTEX")==0 ) { tot--; data+= 3; } /* alle vertexen inlezen tot SEQUEND */ while(tot>=0) { if( fscanf(fp, "%d", &code)==EOF ) break; if(code==10) { fscanf(fp, "%f", data-3); } else if(code==20) { fscanf(fp, "%f", data-2); } else if(code==30) { fscanf(fp, "%f", data-1); } else if( fscanf(fp, "%99s", astr)==EOF ) break; if(code==0 && strcmp(astr, "SEQEND")==0 ) break; if(code==0 && strcmp(astr, "VERTEX")==0 ) { tot--; data+= 3; } } if(unknownsize) { dl->nr= 256-tot; if(dl->nr==0) { remlink(lb, dl); } if(dl->nr<250) { /* realloc */ tot= sizeof(struct DispList)+4*3*dl->nr; dln= mallocN(tot, "leesDXF12"); memcpy(dln, dl, tot); remlink(lb, dl); freeN(dl); addtail(lb, dln); dl= dln; } } if(width && dl->type==DL_POLY) { if(extrude) { /* kubussen */ disp_poly_to_cubes(lb, dl, vec[4], vec[3], transfound, vec+6); } else { /* vlakken */ disp_poly_to_faces(lb, dl, vec[4], transfound, vec+6); } } else if(extrude && dl->type==DL_POLY) { tot= 2*dl->nr; dln= callocN(sizeof(struct DispList)+4*3*tot, "leesDXF1"); addtail(lb, dln); dln->nr= dl->nr; dln->parts= 2; dln->col= curlayer; dln->type= DL_SURF; dln->flag= dl->flag; data= (float *)(dl+1); hd= (float *)(dln+1); hd2= hd+ 3*dl->nr; while(tot) { hd[0]= data[0]; hd[1]= data[1]; hd[2]= data[2]; hd2[0]= data[0]; hd2[1]= data[1]; hd2[2]= data[2]+vec[3]; tot-= 2; data+= 3; hd+=3; hd2+= 3; } remlink(lb, dl); freeN(dl); if(transfound) strange_DXF_transform(dln, vec+6); } else if(transfound) strange_DXF_transform(dl, vec+6); } } } fclose(fp); freelistN(&DxfLaybase); dxfblock= DxfBlockbase.first; while(dxfblock) { freelistN(&(dxfblock->disp)); dxfblock= dxfblock->next; } freelistN(&DxfBlockbase); } /* ***************** INVENTOR ******************* */ #define IV_MAXSTACK 100000 #define IV_MAXFIELD 10 #define IV_MAXCOL 16 float *iv_data_stack; struct ListBase ivbase; struct IvNode { struct IvNode *next, *prev; char *nodename; char *fieldname[IV_MAXFIELD]; int datalen[IV_MAXFIELD]; float *data[IV_MAXFIELD]; }; int iv_curcol=0; int iv_colornumber(struct IvNode *iv) { static float colors[IV_MAXCOL][3]; float *fp; int a; /* terugzoeken naar laatste materiaal */ while(iv && strcmp(iv->nodename, "Material ")!=0) iv= iv->prev; if(iv==0) return 0; if(iv->datalen[0]<3) return 0; fp= iv->data[0]; for(a=0; a=IV_MAXCOL) a= IV_MAXCOL-1; iv_curcol= a+1; fp= iv->data[0]; colors[a][0]= fp[0]; colors[a][1]= fp[1]; colors[a][2]= fp[2]; return a; } void iv_finddata(struct IvNode *iv, char *field, int fieldnr) { /* zoek naar "field", tel lengte data en maak datablok */ float *fp; int len, stackcount; char *cpa, terminator; len= strlen(field); cpa= iv->nodename+1; while( *cpa != '}' ) { if( *cpa == *field ) { if( strncmp(cpa, field, len)==0 ) { iv->fieldname[fieldnr]= cpa; /* lezen tot aan eerste karakter */ cpa+= len; *cpa= 0; cpa++; while( *cpa==' ') cpa++; if( *cpa=='[' ) { terminator= ']'; cpa++; } else terminator= 13; stackcount= 0; fp= iv_data_stack; while( *cpa!=terminator && *cpa != '}' ) { if( isspace(*cpa)==0 && (isspace(cpa[-1]) || cpa[-1]==0) ) { /* sscanf(cpa, "%f", fp); */ *fp= atof(cpa); stackcount++; if(stackcount>=IV_MAXSTACK) { printf("stackoverflow in IV read\n"); break; } fp++; } cpa++; } iv->datalen[fieldnr]= stackcount; iv->data[fieldnr]= mallocN(4*stackcount, "iv_finddata"); memcpy(iv->data[fieldnr], iv_data_stack, 4*stackcount); return; } } cpa++; } } void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype) { /* in data schrijven: baseadr met offset index (aantal nr)*/ float *fp; int ofs; while(nr--) { ofs= *index; fp= baseadr+coordtype*ofs; VECCOPY(data, fp); data+= 3; index++; } } ListBase *nurbsbase=0; struct Base *nubase; void new_nubase() { static int count= 0; struct ObData *ob; struct CurveData *cu; count++; if(nurbsbase) { if(count<10) return; count= 0; makeDispList(nubase); } nubase= addbase(0); nubase->f= 9; nubase->f1= 2+8+16+64; /* was 42: 2+8+32 */ nubase->lay= 1<<(G.layact-1); nubase->sf=1; nubase->len= 80; nubase->q[0]=1.0; Mat3One(nubase->m); strcpy(nubase->str, "nurbs"); newbasename(nubase); nubase->soort= 5; G.totobj++; nubase->d= callocN(sizeof(struct ObData) + sizeof(struct ColBlck),"autocad"); ob= (struct ObData *)nubase->d; ob->dt=2; ob->c= 1; initcolblocks( (ob+1), 1); ob->cu= callocstructN(struct CurveData, 1, "addbase10"); cu= ob->cu; cu->ws= 100.0; cu->us= 1; cu->width= 100; cu->flag= 255; nurbsbase= &cu->curve; } void leesInventor(char *str, struct ListBase *listb) { struct IvNode *iv, *ivp; char *maindata, *md, *cpa; float *index, *data, *fp, tempindex[3]; long file, filelen, count; int asnurbs=0, ok, a, b, tot, first, colnr, coordtype; struct DispList *dl, *dln; ivbase.first= ivbase.last= 0; iv_curcol= 0; file= open(str, O_RDONLY); if(file== -1) { error("Can't read file\n"); return; } filelen= lseek(file, 0, 2); /* seek end */ lseek(file, 0, 0); /* en weer terug */ maindata= mallocN(filelen, "leesInventor"); read(file, maindata, filelen); close(file); iv_data_stack= mallocN(4*IV_MAXSTACK, "ivstack"); /* we gaan alles ordenen: welke zijn de nodes en de fields? */ md= maindata; count= 0; while(count32 && *cpa<128) cpa--; cpa++; *md= 0; ok= 0; iv= callocN(sizeof(struct IvNode), "leesInventor"); iv->nodename= cpa; if(strcmp(cpa, "Coordinate3 ")==0 || strcmp(cpa, "Coordinate4 ")==0) { iv_finddata(iv, "point", 0); ok= 1; } else if(strcmp(cpa, "IndexedLineSet ")==0) { iv_finddata(iv, "coordIndex", 0); ok= 1; } else if(strcmp(cpa, "IndexedTriangleMesh ")==0) { iv_finddata(iv, "coordIndex", 0); ok= 1; } else if(strcmp(cpa, "IndexedFaceSet ")==0) { iv_finddata(iv, "coordIndex", 0); ok= 1; } else if(strcmp(cpa, "FaceSet ")==0) { iv_finddata(iv, "numVertices", 0); ok= 1; } else if(strcmp(cpa, "Material ")==0) { iv_finddata(iv, "diffuseColor", 0); ok= 1; } else if(strcmp(cpa, "QuadMesh ")==0) { iv_finddata(iv, "verticesPerColumn", 0); iv_finddata(iv, "verticesPerRow", 1); ok= 1; } else if(strcmp(cpa, "IndexedTriangleStripSet ")==0) { iv_finddata(iv, "coordIndex", 0); ok= 1; } else if(strcmp(cpa, "IndexedNurbsSurface ")==0) { iv_finddata(iv, "numUControlPoints", 0); iv_finddata(iv, "numVControlPoints", 1); iv_finddata(iv, "uKnotVector", 2); iv_finddata(iv, "vKnotVector", 3); ok= 1; } if(ok) { addtail(&ivbase, iv); } else freeN(iv); } md++; count++; } /* Nodes omzetten naar DispLists */ iv= ivbase.first; while(iv) { /* printf(" Node: %s\n", iv->nodename); */ /* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */ coordtype= 3; if( strcmp(iv->nodename, "IndexedLineSet ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { /* tel het aantal lijnen */ tot= 0; index= iv->data[0]; for(a=0; adatalen[0]-1; a++) { if(index[0]!= -1 && index[1]!= -1) tot++; index++; } tot*= 2; /* aantal vertices */ dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor1"); addtail(listb, dl); dl->type= DL_SEGM; dl->nr= 2; dl->parts= tot/2; dl->col= colnr; data= (float *)(dl+1); index= iv->data[0]; for(a=0; adatalen[0]-1; a++) { if(index[0]!= -1 && index[1]!= -1) { read_iv_index(data, ivp->data[0], index, 2, coordtype); data+= 6; } index++; } } } else if( strcmp(iv->nodename, "FaceSet ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { /* tel het aantal driehoeken */ tot= 0; index= iv->data[0]; for(a=0; adatalen[0]; a++) { if(index[0]== 3) tot++; index++; } tot*= 3; /* aantal vertices */ dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_POLY; dl->nr= 3; dl->parts= tot/3; dl->col= colnr; data= (float *)(dl+1); index= ivp->data[0]; first= 1; for(a=0; adatalen[0]; a++) { VECCOPY(data, index); data+= 3; index+= 3; VECCOPY(data, index); data+= 3; index+= 3; VECCOPY(data, index); data+= 3; index+= 3; } } } else if( strcmp(iv->nodename, "IndexedFaceSet ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { /* tel het aantal driehoeken */ tot= 0; index= iv->data[0]; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) tot++; index++; } tot*= 3; /* aantal vertices */ dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_POLY; dl->nr= 3; dl->parts= tot/3; dl->col= colnr; data= (float *)(dl+1); index= iv->data[0]; first= 1; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) { /* deze truuk is om poly's met meer dan 3 vertices correct te vullen */ if(first) { VECCOPY(tempindex, index); first= 0; } else { tempindex[1]= index[1]; tempindex[2]= index[2]; } read_iv_index(data, ivp->data[0], tempindex, 3, coordtype); data+= 9; } else first= 1; index++; } } } else if( strcmp(iv->nodename, "IndexedTriangleMesh ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { /* tel het aantal driehoeken */ tot= 0; index= iv->data[0]; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) tot++; index++; } tot*= 3; /* aantal vertices */ dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_POLY; dl->nr= 3; dl->parts= tot/3; dl->col= colnr; data= (float *)(dl+1); index= iv->data[0]; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) { read_iv_index(data, ivp->data[0], index, 3, coordtype); data+= 9; } index++; } } } else if( strcmp(iv->nodename, "IndexedTriangleStripSet ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { /* tel het aantal driehoeken */ tot= 0; index= iv->data[0]; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) tot++; index++; } tot*= 3; /* aantal vertices */ dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_POLY; dl->nr= 3; dl->parts= tot/3; dl->col= colnr; data= (float *)(dl+1); index= iv->data[0]; for(a=0; adatalen[0]-2; a++) { if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) { read_iv_index(data, ivp->data[0], index, 3, coordtype); data+= 9; } index++; } } } else if( strcmp(iv->nodename, "QuadMesh ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { tot= *(iv->data[0]) * *(iv->data[1]); if(tot>0) { dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_SURF; dl->nr= *(iv->data[0]); dl->parts= *(iv->data[1]); dl->col= colnr; data= (float *)(dl+1); memcpy(data, ivp->data[0], tot*3*4); } } } else if( strcmp(iv->nodename, "IndexedNurbsSurface ")==0 ) { colnr= iv_colornumber(iv); /* terugzoeken naar data */ ivp= iv; while(ivp->prev) { ivp= ivp->prev; if( strcmp(ivp->nodename, "Coordinate3 ")==0 ) { coordtype= 3; break; } if( strcmp(ivp->nodename, "Coordinate4 ")==0 ) { coordtype= 4; break; } } if(ivp) { a= *(iv->data[0]); b= *(iv->data[1]); tot= a*b; if(asnurbs==0) { if(okee("Read as Nurbs")) asnurbs= 1; else asnurbs= 2; } if( (a>4 || b>4) && tot>6 && asnurbs==1) { struct Nurb *nu; struct BPoint *bp; new_nubase(); nu= callocstructN(struct Nurb, 1, "addNurbprim"); addtail(nurbsbase, nu); nu->type= 4; nu->resolu=nu->pntsu= a; nu->resolv=nu->pntsv= b; nu->flagu= 0; nu->flagv= 0; nu->bp=bp= callocstructN(struct BPoint, tot, "addNurbprim3"); a= tot; data= ivp->data[0]; while(a--) { VECCOPY(bp->vec, data); bp->vec[3]= 1.0; data+= coordtype; bp++; } nu->orderu= iv->datalen[2] - nu->pntsu; nu->orderv= iv->datalen[3] - nu->pntsv; nu->knotsu= mallocN( 4*(iv->datalen[2])); memcpy(nu->knotsu, iv->data[2], 4*(iv->datalen[2])); nu->knotsv= mallocN( 4*(iv->datalen[3])); memcpy(nu->knotsv, iv->data[3], 4*(iv->datalen[3])); } else { dl= callocN(sizeof(struct DispList)+tot*3*4, "leesInventor2"); addtail(listb, dl); dl->type= DL_SURF; dl->nr= *(iv->data[0]); dl->parts= *(iv->data[1]); dl->col= colnr; data= (float *)(dl+1); a= tot; fp= ivp->data[0]; while(a--) { VECCOPY(data, fp); fp+= coordtype; data+= 3; } } } } iv= iv->next; } /* vrijgeven */ iv= ivbase.first; while(iv) { for(a=0; adata[a]) freeN(iv->data[a]); } iv= iv->next; } freelistN(&ivbase); freeN(maindata); freeN(iv_data_stack); if(nurbsbase) { nurbsbase= 0; makeDispList(nubase); } } char byteswap(char byte) { char i; i= 0; if(byte & 1) i |= 128; if(byte & 2) i |= 64; if(byte & 4) i |= 32; if(byte & 8) i |= 16; if(byte & 16) i |= 8; if(byte & 32) i |= 4; if(byte & 64) i |= 2; if(byte & 128) i |= 1; return i; } /* ********************************************** */ int finddoublevert(struct VertOb *adrve, int totvert) { struct VertOb *testve; int a, tot; tot= totvert-128; if(tot<0) tot= 0; testve= adrve-1; for(a=totvert-1; a>tot; a--, testve--) { if( adrve->c[0]==testve->c[0]) { if( adrve->c[1]==testve->c[1]) { if( adrve->c[2]==testve->c[2]) { return a; } } } } return -1; } void leesCurry(char *name) { struct Base *base; struct ObData *ob; struct VV *vv; struct ColBlck *col; struct VlakOb *adrvl, *adrvlo; struct VertOb *adrve, *adrveo, *adrve1, *adrve2, *adrve3; float n[3]; int v1, v2, v3; int len, a, file, filelen, totvlak, totvert, vcount=0; char *filedata, *fd, *end; if(G.ebase) { leesCurryEdit(); return; } file= open(name, O_RDONLY); if(file<=0) { error("Can't open file"); return; } filelen= lseek(file, 0, 2); /* seek end */ lseek(file, 0, 0); /* en weer terug */ if(filelen<20) { close(file); return; } filedata= mallocN(filelen, "curry"); read(file, filedata, filelen); close(file); end= filedata+filelen; fd= filedata+20; totvert= (filelen-20)/6; totvlak= totvert/3; if(totvert>65535) totvert= 65535; if(totvlak>65535) totvlak= 65535; base= addbase(0); base->f= 9; base->f1= 2+8+16+64; /* was 42: 2+8+32 */ base->lay= 1<<(G.layact-1); base->sf=1; base->len= 80; base->q[0]=1.0; Mat3One(base->m); strcpy(base->str, "curry"); newbasename(base); base->soort= 1; G.totobj++; base->d= callocN(sizeof(struct ObData)+sizeof(struct ColBlck),"curry"); ob= (struct ObData *)base->d; vv= callocN(sizeof(struct VV)+ totvert*sizeof(struct VertOb)+ totvlak*sizeof(struct VlakOb)); col= (struct ColBlck *)(ob+1); col->r= col->g= col->b= 240; col->mode= 12; initcolblocks(col, 1); ob->vv= vv; ob->c= 1; ob->dt= 1; vv->vert= totvert; vv->vlak= totvlak; vv->us= 1; vv->afm[0]= 32767; vv->afm[1]= 32767; vv->afm[2]= 32767; vv->ws= 1.0; adrve= (struct VertOb *)(vv+1); adrvl= (struct VlakOb *)(adrve+totvert); totvert=0; totvlak=0; while(fdc[0]= 2*((fd[0]<<7)-16384); adrve->c[1]= 2*((fd[1]<<7)-16384); adrve->c[2]= 2*((fd[2]<<7)-16384); adrve->n[0]= -2*((fd[3]<<7)-16384); adrve->n[1]= -2*((fd[4]<<7)-16384); adrve->n[2]= -2*((fd[5]<<7)-16384); v1= finddoublevert(adrve, totvert); if(v1== -1) { v1= totvert; adrve++; totvert++; } fd+= 6; adrve->c[0]= 2*((fd[0]<<7)-16384); adrve->c[1]= 2*((fd[1]<<7)-16384); adrve->c[2]= 2*((fd[2]<<7)-16384); adrve->n[0]= -2*((fd[3]<<7)-16384); adrve->n[1]= -2*((fd[4]<<7)-16384); adrve->n[2]= -2*((fd[5]<<7)-16384); v2= finddoublevert(adrve, totvert); if(v2== -1) { v2= totvert; adrve++; totvert++; } fd+= 6; adrve->c[0]= 2*((fd[0]<<7)-16384); adrve->c[1]= 2*((fd[1]<<7)-16384); adrve->c[2]= 2*((fd[2]<<7)-16384); adrve->n[0]= -2*((fd[3]<<7)-16384); adrve->n[1]= -2*((fd[4]<<7)-16384); adrve->n[2]= -2*((fd[5]<<7)-16384); v3= finddoublevert(adrve, totvert); if(v3== -1) { v3= totvert; adrve++; totvert++; } fd+= 6; adrvl->v1= v1; adrvl->v2= v2; adrvl->v3= v3; totvlak++; adrvl++; if(totvert>65535 || totvlak>65535) { error("warning: file too big"); break; } } freeN(filedata); vv= callocN(sizeof(struct VV)+ totvert*sizeof(struct VertOb)+ totvlak*sizeof(struct VlakOb)); adrve= (struct VertOb *)(vv+1); adrvl= (struct VlakOb *)(adrve+totvert); adrveo= (struct VertOb *)(ob->vv+1); adrvlo= (struct VlakOb *)(adrveo+ob->vv->vert); memcpy(adrve, adrveo, totvert*sizeof(struct VertOb)); memcpy(adrvl, adrvlo, totvlak*sizeof(struct VlakOb)); *vv= *(ob->vv); vv->vert= totvert; vv->vlak= totvlak; freeN(ob->vv); ob->vv= vv; /* puno omklapvlaggen */ adrvl= (struct VlakOb *)(adrve+totvert); for(a=0; av1; adrve2= adrve+adrvl->v2; adrve3= adrve+adrvl->v3; CalcNormShort(adrve1->c, adrve2->c, adrve3->c, n); adrvl->n[0]= ffloor(n[0]*32767.0); adrvl->n[1]= ffloor(n[1]*32767.0); adrvl->n[2]= ffloor(n[2]*32767.0); adrvl->f= 0; len= adrvl->n[0]*adrve1->n[0]+adrvl->n[1]*adrve1->n[1]+adrvl->n[2]*adrve1->n[2]; if(len<0) adrvl->f= 1; len= adrvl->n[0]*adrve2->n[0]+adrvl->n[1]*adrve2->n[1]+adrvl->n[2]*adrve2->n[2]; if(len<0) adrvl->f+= 2; len= adrvl->n[0]*adrve3->n[0]+adrvl->n[1]*adrve3->n[1]+adrvl->n[2]*adrve3->n[2]; if(len<0) adrvl->f+= 4; adrvl++; } } /* ************************** BLENDER ************************ */ void saveblender() { } /* *********************************************************** */ void schr_inventor() { struct Base *base; struct ObData *ob; struct VV *vv; struct VlakOb *adrvl; struct VertOb *adrve; FILE *fp; float fac, len, mat4[4][4], vec[3], omat[3][3]; float *n1, *n2, inp, VecLenf(); int a, tot, file, ok, lasttime, *edgedata, *edda; short *v, val; char *cp, str[128]; strcpy(str, G.sce); val= ffileselect("WRITE INVENTOR", str); if(val==0) return; if(saveover(str)==0) return; fp= fopen(str, "w"); if(fp==NULL) return; fprintf(fp,"#Inventor V2.0 ascii\n"); base= G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort==1) { fprintf(fp,"Separator {\n"); ob= (struct ObData *)base->d; vv= ob->vv; adrve= (struct VertOb *)(vv+1); adrvl= (struct VlakOb *)(adrve+vv->vert); parentbase(base, mat4, omat); fac= vv->ws; Mat4MulFloat3(mat4, fac); fac= 1.0/5000.0; Mat4MulFloat(mat4, fac); if(vv->vert) { fprintf(fp, "Coordinate3 {\n"); fprintf(fp, "point [ \n"); for(a=0; avert; a++, adrve++) { VECCOPY(vec, adrve->c); Mat4MulVecfl(mat4, vec); fprintf(fp, "%f %f %f, \n", vec[0], vec[1], vec[2]); } fprintf(fp, "]\n}\n"); } if(vv->vlak) { fprintf(fp, "IndexedTriangleStripSet {\n"); fprintf(fp, "coordIndex [ \n"); /* driehoeken schrijven */ for(a=0; avlak; a++, adrvl++) { fprintf(fp, "%d, %d, %d, -1,\n", adrvl->v1, adrvl->v2, adrvl->v3); } fprintf(fp, "]\n}\n"); } fprintf(fp, "}\n"); } } base= base->next; } fclose(fp); }