// compile as: // cc -o dxfsize dxfsize.c #include #include #include #include double minx,maxx,miny,maxy; long lines=0,polylines=0,lwpolylines=0,crosses=0,dxfitems=0; long lsegments=0; long moves=0; int showentities=0; int listall=0; int listfmt=0; int listfmtsec=0; int stripcomments=0; int stripcrosses=0; int ignoreerrors=0; FILE*fi; int dxferr=0; int isdxf=0; long maxl=100; #define MAXXY 999999999 void initvars(){ lines=0;polylines=0;lwpolylines=0;crosses=0;dxfitems=0; lsegments=0;moves=0; minx=MAXXY;miny=MAXXY;maxx=-MAXXY;maxy=-MAXXY; } /* void scanfile() { char s1[512],s2[512],*sp; int i,t,iscross=0; int seclev=0; double d; // long lines=0; dxferr=0; isdxf=0; lines=0;polylines=0;crosses=0;dxfitems=0; minx=MAXXY;miny=MAXXY;maxx=-MAXXY;maxy=-MAXXY; while(!feof(fi)){ fgets(s1,510,fi); fgets(s2,510,fi);sp=strchr(s2,0x0d);if(sp)sp[0]=0;sp=strchr(s2,0x0a);if(sp)sp[0]=0; if(ferror(fi)){printf("[Error %i at read]",ferror(fi));return;} //printf("%li:",lines); //if(!ignoreerrors)if(i==0)if(strncmp(s1," 0",3)){dxferr=1;return;} dxfitems++; // if(lines>maxl){printf("More lines than %li, aborting.",maxl);return;} i=atoi(s1); if(!strcmp(s2,"ENDSEC")){seclev--;} if(i==999){ if(!strcmp(s2,"----CROSSBEGIN")){iscross=1;crosses++;if(stripcrosses)continue;} if(!strcmp(s2,"----CROSSEND")){iscross=0;if(stripcrosses)continue;} if(!strncmp(s2,"CROSSCOORD",10)){if(stripcrosses)continue;} if(stripcomments)continue; } if(i==0)if(showentities)printf("%s\n",s2); if(i==0){if(!strcmp(s2,"LINE")){isdxf=1;lines++;}else if(!strcmp(s2,"LWPOLYLINE")){polylines++;isdxf=1;} } if(listall){if(listfmt)if(i)printf("\t"); if(listfmtsec){int t;for(t=0;tmaxx)maxx=d;} if((i==20)||(i==21)){d=atof(s2);if(dmaxy)maxy=d;} } } */ #define LTYPE_NONE 0 #define LTYPE_LINE 1 #define LTYPE_POLY 2 void setminmaxx(double d){if(dmaxx)maxx=d;} void setminmaxy(double d){if(dmaxy)maxy=d;} double str2x(char*s) { double d; d=atof(s); // if(x_tozero)d=d-minx; // d=(d+preaddx)*multix; // if(x_fliphorz)d=maxx-d; // d=d+addx; return d; } double str2y(char*s) { double d; d=atof(s); // if(x_tozero)d=d-miny; // d=(d+preaddy)*multiy; // if(x_flipvert)d=maxy-d; // d=d+addy; return d; } void scanfile() { char s1[512],s2[512],*sp; int i,t; double d; double x1,y1,x2,y2,xo=0,yo=0; int ltype=0; int movecheck=0; int seclev=0; int iscross=0; int polylen=0; int isvertex=0; int vertexes=0; int templev=0; minx=MAXXY;maxx=-MAXXY;miny=MAXXY;maxy=-MAXXY; rewind(fi); while(!feof(fi)){ fgets(s1,510,fi);sp=strchr(s1,0x0d);if(sp)sp[0]=0;sp=strchr(s1,0x0a);if(sp)sp[0]=0; fgets(s2,510,fi);sp=strchr(s2,0x0d);if(sp)sp[0]=0;sp=strchr(s2,0x0a);if(sp)sp[0]=0; if(ferror(fi)){fprintf(stderr,"[Error %i at read]",ferror(fi));return;} dxfitems++; i=atoi(s1); // if(showentities)printf("%3i %s\n",i,s2); // if(showentities>1)printf("%3i %i %i %s\n",i,ltype,isvertex,s2); //if(i==0)fprintf(stderr,"\n"); //fprintf(stderr,"#DXF: %i:%s\n",i,s2); templev=0; switch(i){ //10=x1, 11=x2, 20=y1, 21=y2 case 0: if(showentities)printf("%s\n",s2); if(!strncmp(s2,"VERTEX",6)){isdxf=1;isvertex=1;vertexes++;break;} if(!strncmp(s2,"SEQEND",6)){isdxf=1;isvertex=0;if(vertexes)lsegments=lsegments+vertexes-1;vertexes=0;ltype=0;templev=1;break;} ltype=0; if(!strncmp(s2,"SECTION",7)){seclev++;templev=-1;break;} if(!strcmp(s2,"ENDSEC")){if(seclev>0)seclev--;templev=0;break;} if(!strncmp(s2,"TABLE",5)){seclev++;templev=-1;break;} if(!strcmp(s2,"ENDTAB")){if(seclev>0)seclev--;templev=0;break;} // if(!strncmp(s2,"LINE",4)){ltype=LTYPE_LINE;lines++;isdxf=1;} if(!strncmp(s2,"LWPOLYLINE",10)){ltype=LTYPE_POLY;lwpolylines++;isdxf=1;isvertex=0;polylen=0;} if(!strncmp(s2,"POLYLINE",8)){ltype=LTYPE_POLY;polylines++;isdxf=1;vertexes=0;isvertex=0;polylen=0;} movecheck=0; break; case 10:if(ltype==0)break;d=str2x(s2);setminmaxx(d); if(ltype==LTYPE_POLY){ if(polylen)x2=d;else x1=d; if(polylen)xo=d; //polylen++; }else x1=d; break; case 11:if(ltype==0)break;d=str2x(s2);setminmaxx(d);x2=d; break; case 20:if(ltype==0)break;d=str2y(s2);setminmaxy(d); if(ltype==LTYPE_POLY){ if(polylen)y2=d;else y1=d; if(polylen)yo=d; if(!isvertex)if(polylen)lsegments++; //if(isvertex)if(polylen) polylen++; //printf("[%i,%i]\n",vertexes,lsegments); //movecheck=0; if(!movecheck){// check if //fprintf(stderr," %f:%f %f:%f %f:%f\n",xo,yo,x1,y1,x2,y2); if((xo!=x1)||(yo!=y1))moves++; //if((xo!=x1)||(yo!=y1))fprintf(stderr," MOVE\n"); xo=x2;yo=y2; movecheck=1;} }else y1=d; break; case 21:if(ltype==0)break;d=str2y(s2);setminmaxy(d);y2=d;lsegments++; if(!movecheck){ //fprintf(stderr," %f:%f %f:%f %f:%f\n",xo,yo,x1,y1,x2,y2); if((xo!=x1)||(yo!=y1))moves++; //if((xo!=x1)||(yo!=y1))fprintf(stderr," MOVE\n"); xo=x2;yo=y2; movecheck=1;} break; case 999: if(!strcmp(s2,"----CROSSBEGIN")){iscross=1;crosses++;if(stripcrosses)continue;} if(!strcmp(s2,"----CROSSEND")){iscross=0;if(stripcrosses)continue;} if(!strncmp(s2,"CROSSCOORD",10)){if(stripcrosses)continue;} if(stripcomments)continue; break; } // if((i==10)||(i==11)){d=str2x(s2);if(dmaxx)maxx=d;} // if((i==20)||(i==21)){d=str2y(s2);if(dmaxy)maxy=d;} // if(i==21)lsegments++; // if(i==0)ltype=0; // if(!strncmp(s2,"LINE",4)){ltype=LTYPE_LINE;lines++;} // if(!strncmp(s2,"LWPOLYLINE",10)){ltype=LTYPE_POLY;polylines++;} // if(i==999){ // if(!strncmp(s2,"CROSSCOORDMAXX:",15))crosscoordmaxx=atof(s2+15); // if(!strncmp(s2,"CROSSCOORDMAXY:",15))crosscoordmaxy=atof(s2+15); // } // if(listall){if(listfmt)if(i)printf("\t"); if(listall){//if(listfmt)printf("\t"); if(isvertex)if(i)templev++; if(listfmtsec){int t;for(t=0;tmaxx)maxx=crosscoordmaxx; // if(crosscoordmaxy>maxy)maxy=crosscoordmaxy; // pixelsx=mm2pix(maxx)+strokewid; // pixelsy=mm2pix(maxy)+strokewid; // if(tozero){pixelsx-=mm2pix(minx);pixelsy-=mm2pix(miny);} } void entitiestoline() { char s1[512],s2[512],*sp; int i; int firstline=0; int iscross=0; if(!fi)return; rewind(fi); while(!feof(fi)){ fgets(s1,510,fi);if(strlen(s1)==0)break; fgets(s2,510,fi);sp=strchr(s2,0x0d);if(sp)sp[0]=0;sp=strchr(s2,0x0a);if(sp)sp[0]=0; if(ferror(fi)){printf("[Error %i at read]",ferror(fi));return;} i=atoi(s1); if(!ignoreerrors)if(i==0)if(strncmp(s1," 0",3)){dxferr=1;return;} // if(i==0)if(!strcmp(s2,"")){dxferr=1;return;} if(!strcmp(s2,"SECTION"))isdxf=1; //strip comments if(i==999){ if(!strcmp(s2,"----CROSSBEGIN")){iscross=1;if(stripcrosses)continue;} if(!strcmp(s2,"----CROSSEND")){iscross=0;if(stripcrosses)continue;} if(!strncmp(s2,"CROSSCOORD",10)){if(stripcrosses)continue;} if(stripcomments)continue; } if(iscross)if(stripcrosses)continue; if((i==0)||(i==999)) {if(firstline)printf("\n");} else printf("|"); printf("%3i|%s",i,s2); // } // else { // } firstline++; } if(firstline)printf("\n"); } void help() { printf("dxfsize - shows dimensions of OpenSCAD DXF file parts, optionally lists the entities in the file\n" " (does not support entities other than LINE and LWPOLYLINE)\n" "Usage: dxfsize [options] \n" " if no file specified, feed it from stdin\n" " -vc show DXF entities\n" " -f force operation even if it does not look like a DXF file\n" " -nf don't show filename\n" " -fn show filename (if no -fn or -nf, show filename unless -show is used)\n" " -l reformat group codes and data to single lines, replace \"|\" with \"\\n\" to undo\n" " -ll like -l, offsets parameters\n" " -lll like -ll, also offsets by section depth\n" " -le reformat group codes and data to single lines, whole entities per line\n" " -sc strip comments\n" " -scr strip crosses\n" " -var show variable value\n" " variables: minx, maxx, miny, maxy, xsize/width, ysize/height, lines, polys, lwpolys, crosses,\n" " items (dxf line pairs), dims (dimensions), dimscoord (dimensions and starting coordinates),\n" " alllines (lines+poly), linesnocross (lines-2*cross), alllinesnocross (lines+poly-2*cross) \n" " -h, --help this help\n" ); exit(0); } int main(int argc,char*argv[]) { char*fni=""; int showfile=1; int forceshowfile=0; int forcehidefile=0; int listentities=0; int doshow=0; int t,t1,t2; int fnames=0; if(argc<2)help(); for(t=1;t1)if(showfile==0)showfile=1; // if(showfile==2)showfile=0; if(fnames==1)if(listall||listentities||doshow)showfile=0; // don't show filename if -show is, for one name only if(forceshowfile==1)showfile=1; if(forcehidefile==1)showfile=0; for(t1=1;t11) {if(!strcmp(argv[t1],"-var"))t1++; continue; } fni=argv[t1]; if(!strcmp(fni,"-"))fi=stdin; else if(fni[0]){ fi=fopen(fni,"r");if(!fi){fprintf(stderr,"Cannot open file '%s'.\n",fni);continue;} } // else fi=stdin; initvars(); if(showfile) {if(listentities||listall)printf("\n"); printf("%-20s: ",fni); if(listentities||listall)printf("\n");else printf("\t");} if(listentities){entitiestoline();} else scanfile(); if(fi!=stdin)fclose(fi); if(!isdxf){printf("not a DXF file?\n");continue;} if(listentities)continue; if(listall)continue; if(!doshow) { printf("lines:%-5li polylines:%-5li lwpoly:%-5li segm:%-5li moves:%-5li crosses:%-3li items:%-5li",lines,polylines,lwpolylines,lsegments,moves,crosses,dxfitems); printf(" size:%7.2f x%7.2f",maxx-minx,maxy-miny); printf(" viewport:%.2f,%.2f:%.2f,%.2f",minx,miny,maxx,maxy); printf("\n");} if(doshow){ //printf("SHOW:\n"); int ocnt=0; for(t=1;t