DXFCON2.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 /* file DXFLOAD in utilities */
00025 
00026 typedef struct DXFCOLOUR {
00027   unsigned char r,g,b;
00028 } DXFcolour;
00029 
00030 static DXFcolour DXFc[256];
00031 
00032 typedef struct DXFBLOCK {
00033   char   name[32];
00034   long   offset,x,y,z,frozen;
00035   vertex *vs;
00036   edge   *es;
00037 } DXFblock;
00038 
00039 typedef struct DXFLAYER {
00040   long colour,frozen,nought;
00041   char name[32];
00042   skel *sp;
00043 } DXFlayer;
00044 
00045 typedef struct AUTOVERTEX {
00046   vertex *vp;
00047   long n;
00048   struct AUTOVERTEX **adj;
00049 } autovertex;
00050 
00051 static DXFlayer *DXFlayers=NULL;
00052 static DXFblock *DXFblocks=NULL;
00053 static long nDXFblocks,nDXFlayers,skel_type,l_freeze,b_freeze,verbose,
00054             current_colour,current_layer,current_nought,no_weld,inc2d,
00055             current_freeze,inc3d,circle_step;
00056 static double weld_threshold=0.0001,weld_mult;
00057 static char CurrentLayer[32];
00058 static skel *current_sp;
00059 static long file_size=1;
00060 
00061 static short InsertDXFblock(FILE *, skel *);
00062 
00063 static void UpdateProgress(FILE *dxfp){
00064  long p;
00065  if(hwndProgress == NULL)return;
00066  p=ftell(dxfp);
00067  p=(p*100)/file_size;
00068  SendMessage(hwndProgress,PBM_SETPOS,(WPARAM)p,0);
00069  Sleep(0);
00070 // MSG msg;
00071 // while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)){
00072 //   TranslateMessage(&msg);
00073 //   DispatchMessage(&msg);
00074 // }
00075  return;
00076 }
00077 
00078 static void AddDXFface(vertex *v1, vertex *v2, vertex *v3, short check){
00079  CreateFace(v1,v2,v3,check);
00080  MainFp->color[0]=DXFc[current_colour].r;
00081  MainFp->color[1]=DXFc[current_colour].g;
00082  MainFp->color[2]=DXFc[current_colour].b;
00083 }
00084 
00085 void veccross(double *o, double *a, double *b){
00086   double r[3];
00087   r[0] = a[1] * b[2] - a[2] * b[1];
00088   r[1] = a[2] * b[0] - a[0] * b[2];
00089   r[2] = a[0] * b[1] - a[1] * b[0];
00090   o[0]=r[0];
00091   o[1]=r[1];
00092   o[2]=r[2];
00093 }
00094 
00095 vecnorm(double *o, double *a){
00096   double mag;
00097   mag = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
00098   mag = 1.0/mag;
00099   o[0]=a[0]*mag;
00100   o[1]=a[1]*mag;
00101   o[2]=a[2]*mag;
00102 }
00103 
00104 void arbaxis(double *newaxis, double *oldaxis){
00105  double yaxis[3] = {0.0, 1.0, 0.0};
00106  double zaxis[3] = {0.0, 0.0, 1.0};
00107  if (fabs(oldaxis[0]) < 0.015625 && fabs(oldaxis[1]) < 0.015625)
00108     veccross(newaxis, yaxis, oldaxis);
00109  else
00110     veccross(newaxis, zaxis, oldaxis);
00111  vecnorm(newaxis, newaxis);
00112 }
00113 
00114 void gettrans(double *zdir, double m[3][3]){
00115  double xdir[3], ydir[3];
00116  vecnorm(zdir,zdir);
00117  arbaxis(xdir, zdir);
00118  veccross(ydir, zdir, xdir);
00119  vecnorm(ydir, ydir);
00120  m[0][0]=xdir[0];
00121  m[1][0]=xdir[1];
00122  m[2][0]=xdir[2];
00123  m[0][1]=ydir[0];
00124  m[1][1]=ydir[1];
00125  m[2][1]=ydir[2];
00126  m[0][2]=zdir[0];
00127  m[1][2]=zdir[1];
00128  m[2][2]=zdir[2];
00129 }
00130 
00131 #if 0
00132 // the old way this appears to be wrong
00133 static void ReOrientate(double Nx,double Ny,double Nz,vertex *vl,vertex *vs){
00134  vertex *vp;                  /* apply the AUTOCAD arbitrary axis rotation */
00135  double x,y,z,dx,dy,dz;
00136  long axis=0;
00137  /* X__pri("Not normal direction %lf %lf %lf",Nx,Ny,Nz); */
00138  if(fabs(Nx) < 0.015625 && fabs(Ny) < 0.015625)axis=1;
00139  vp=vl; while(vp != vs){
00140    dx=(double)vp->xyz[0]; dy=(double)vp->xyz[1]; dz=(double)vp->xyz[2];
00141    if(axis){
00142      x =  Nz*dx - Nx*Ny*dy + Nx*dz;
00143      y =  (Nx*Nx+Nz*Nz)*dy + Ny*dz;
00144      z = -Nx*dx + Nz*Ny*dy + Nz*dz;
00145    }
00146    else{
00147      x = -Ny*dx - Nx*Nz*dy + Nx*dz;
00148      y =  Nx*dx + Ny*Nz*dy + Ny*dz;
00149      z =  (Nx*Nx+Ny*Ny)*dy + Nz*dz;
00150    }
00151    vp->xyz[0]=(long)x; vp->xyz[1]=(long)y; vp->xyz[2]=(long)z;
00152    vp=vp->last;
00153  }
00154 }
00155 #endif
00156 
00157 static void ReOrientate(double Nx,double Ny,double Nz,vertex *vl,vertex *vs){
00158  vertex *vp;
00159  long i;
00160  double z[3],m[3][3],dx,dy,dz;
00161  z[0]=Nx; z[1]=Ny; z[2]=Nz;
00162  gettrans(z,m);
00163  vp=vl; while(vp != vs){
00164    dx=(double)(vp->xyz[0]);
00165    dy=(double)(vp->xyz[1]);
00166    dz=(double)(vp->xyz[2]);
00167    for (i=0; i<3; i++){
00168      vp->xyz[i] = (long)(m[i][0] * dx + m[i][1] * dy + m[i][2] * dz);
00169    }
00170    vp=vp->last;
00171  }
00172 }
00173 
00174 static void DXFhsv2rgb(double hh, double ss, double vv,
00175              unsigned char *r, unsigned char *g, unsigned char *b){
00176  double rr,gg,bb,maxcol,mincol;
00177  mincol=vv*(1.0-ss);
00178  if(hh <= 120.0){bb=mincol;
00179    if(hh <=  60){rr=vv; gg=mincol+hh*(vv-mincol)/(120.0-hh);}
00180    else         {gg=vv; rr=mincol+(120.0-hh)*(vv-mincol)/hh;}
00181  }
00182  else if( hh <= 240){rr=mincol;
00183    if(hh <= 180){gg=vv; bb=mincol+(hh-120.0)*(vv-mincol)/(240.0-hh);}
00184    else         {bb=vv; gg=mincol+(240.0-hh)*(vv-mincol)/(hh-120.0);}
00185  }
00186  else {gg=mincol;
00187    if(hh <= 300){bb=vv; rr=mincol+(hh-240.0)*(vv-mincol)/(360.0-hh);}
00188    else         {rr=vv; bb=mincol+(360.0-hh)*(vv-mincol)/(hh-240.0);}
00189  }
00190  rr = rr*255.0; *r=(unsigned char)rr;
00191  gg = gg*255.0; *g=(unsigned char)gg;
00192  bb = bb*255.0; *b=(unsigned char)bb;
00193 }
00194 
00195 static void SetupDXFcolours(void){
00196   double hue;
00197   long i,j,k,l;
00198   DXFc[  0].r=  0; DXFc[  0].g=  0; DXFc[  0].b=  0;
00199   DXFc[  1].r=255; DXFc[  1].g=  0; DXFc[  1].b=  0;
00200   DXFc[  2].r=255; DXFc[  2].g=255; DXFc[  2].b=  0;
00201   DXFc[  3].r=  0; DXFc[  3].g=255; DXFc[  3].b=  0;
00202   DXFc[  4].r=  0; DXFc[  4].g=255; DXFc[  4].b=255;
00203   DXFc[  5].r=  0; DXFc[  5].g=  0; DXFc[  5].b=255;
00204   DXFc[  6].r=255; DXFc[  6].g=  0; DXFc[  6].b=255;
00205   DXFc[  7].r=255; DXFc[  7].g=255; DXFc[  7].b=255;
00206   DXFc[  8].r= 64; DXFc[  8].g= 64; DXFc[  8].b= 64;
00207   DXFc[  9].r=128; DXFc[  9].g=128; DXFc[  9].b=128;
00208   for(i=10;i<=240;i+=10){
00209     for(j=0;j<=8;j+=2){
00210       for(k=0;k<2;k++){
00211         l=i+j+k; hue=((double)i/240.0)*360.0;
00212         DXFhsv2rgb(hue,(double)(k+1)/2.0,0.1+(double)(8-j)/10.0,
00213           &(DXFc[l].r),&(DXFc[l].g),&(DXFc[l].b));
00214       }
00215     }
00216   }
00217   DXFc[250].r= 42; DXFc[250].g= 42; DXFc[250].b= 42;
00218   DXFc[251].r= 84; DXFc[251].g= 84; DXFc[251].b= 84;
00219   DXFc[252].r=126; DXFc[252].g=126; DXFc[252].b=126;
00220   DXFc[252].r=169; DXFc[253].g=169; DXFc[253].b=169;
00221   DXFc[254].r=210; DXFc[254].g=210; DXFc[254].b=210;
00222   DXFc[255].r=252; DXFc[255].g=252; DXFc[255].b=252;
00223 }
00224 
00225 /* changed to accomodate MAC style as well  see also file open */
00226 
00227 static long getDXFcode(FILE *dxfp, long *vi, double *di, char *dstr){
00228  long gc,i,j;
00229  strnset(dstr,0,256);
00230 // j=0; while(((i=fgetc(dxfp)) != 13) && i >= 0 && j < 256)
00231  //     if(i != 10) *(dstr+(j++))=i;
00232  j=0;
00233  while(1){
00234    i=fgetc(dxfp);
00235    if(i < 0 || j > 255)return -1;
00236    else if(i == 13 || i == 10){
00237      if((i=fgetc(dxfp)) < 0)break; /* end of file */
00238      if( !(i == 13 || i == 10))ungetc(i,dxfp);
00239      break;
00240    }
00241    *(dstr+(j++))=i;
00242  }
00243  *(dstr+j)=0;
00244 //X__pri("[%s] j=%ld lenght=%ld",dstr,j,(long)strlen(dstr));
00245  if(sscanf(dstr,"%ld",&gc) != 1)return -1;
00246  strnset(dstr,0,256);
00247 // j=0; while(((i=fgetc(dxfp)) != 13) && i >= 0 && j < 256)
00248 //      if(i != 10) *(dstr+(j++))=i;
00249  j=0;
00250  while(1){
00251    i=fgetc(dxfp);
00252    if(i < 0 || j > 255)return -1;
00253    else if(i == 13 || i == 10){
00254      if((i=fgetc(dxfp)) < 0)break;
00255      if( !(i == 13 || i == 10))ungetc(i,dxfp);
00256      break;
00257    }
00258    *(dstr+(j++))=i;
00259  }
00260  *(dstr+j)=0;
00261 //X__pri("[%s] j=%ld lenght=%ld",dstr,j,(long)strlen(dstr));
00262  if(gc < 10 || gc == 999){
00263    return gc;
00264  }
00265  else if(gc < 60){
00266    if(sscanf(dstr,"%lf",di) != 1)return -1;
00267    return gc;
00268  }
00269  else if(gc > 60 && gc < 80){
00270    if(sscanf(dstr,"%ld",vi) != 1)return -1;
00271    return gc;
00272  }
00273  else if(gc > 80 && gc < 210){ /* not in autocad manual !!!!!!! */
00274    return gc;
00275  }
00276  else if(gc >= 210 && gc < 240){
00277    if(sscanf(dstr,"%lf",di) != 1)return -1;
00278    return gc;
00279  }
00280  else if(gc >= 1000 && gc < 1010){
00281    return gc;
00282  }
00283  else if(gc >= 1010 && gc < 1060){
00284    if(sscanf(dstr,"%lf",di) != 1)return -1;
00285    return gc;
00286  }
00287  else if(gc >= 1060 && gc < 1080){
00288    if(sscanf(dstr,"%ld",vi) != 1)return -1;
00289    return gc;
00290  }
00291  return -1;
00292 }
00293 
00294 static void CreateEdgeWithCheck(vertex *v1, vertex *v2, edge *le){
00295  edge *ep;
00296  ep=MainEp;
00297  while(ep != le){
00298    if(   ((ep->V[0] == v1) && (ep->V[1] == v2))
00299       || ((ep->V[0] == v2) && (ep->V[1] == v1)) )return;
00300    ep=ep->last;
00301  }
00302  CreateEdge(v1,v2,0);
00303 }
00304 
00305 static short ReadDXFheader(FILE *dxfp){
00306  char dstr[260]; double di; long vi,gc;
00307  if(verbose > 1)X__pri("Header");
00308  for(;;){
00309    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00310    if(gc == 0 && strncmp(dstr,"ENDSEC",6) == 0)break;
00311  }
00312  UpdateProgress(dxfp);
00313  return 0;
00314 }
00315 
00316 static short AddLayerToTable(char *name, long colour, long frozen){
00317  DXFlayer *db;
00318  long i,j;
00319  char confirm;
00320  if(nDXFlayers > 0){
00321    for(i=0;i<nDXFlayers;i++){
00322      if(strcmp(name,DXFlayers[i].name) == 0){
00323        return 0;
00324      }
00325    }
00326  }
00327  db=DXFlayers;
00328  if(db == NULL)db=(DXFlayer *)malloc(sizeof(DXFlayer));
00329  else db=(DXFlayer *)realloc(db,(nDXFlayers+1)*sizeof(DXFlayer));
00330  if(db == NULL){
00331    if(DXFlayers != NULL)free(DXFlayers); DXFlayers=NULL; nDXFlayers=0;
00332    return -1;
00333  }
00334  DXFlayers=db;
00335  if(l_freeze){
00336 //   frozen ^= 1;
00337    frozen = 0;
00338  }
00339  DXFlayers[nDXFlayers].colour=colour;
00340  DXFlayers[nDXFlayers].frozen=frozen;
00341  if(strcmp("0",name) == 0)DXFlayers[nDXFlayers].nought=1;
00342  else                     DXFlayers[nDXFlayers].nought=0;
00343  strcpy(DXFlayers[nDXFlayers].name,name);
00344  if(skel_type == 1){
00345    CreateSkeleton(FirstSp);
00346    j=min(12,strlen(name)); strncpy(MainSp->name,name,j); *(MainSp->name+j)=0;
00347    DXFlayers[nDXFlayers].sp=MainSp;
00348    MainSp->xyz[2]=MINUNIT*2*Nskel;
00349  }
00350  else DXFlayers[nDXFlayers].sp=NULL;
00351  nDXFlayers++;
00352  return 0;
00353 }
00354 
00355 static void SetLayerCurrents(char *name){
00356 /* If the layer is layer 0 then if the entity is in a block the Layer + */
00357 /* colour used is the colour of the block that is being        inserted */
00358  long i;
00359  if(nDXFlayers > 0){
00360    for(i=0;i<nDXFlayers;i++){
00361      if(strcmp(name,DXFlayers[i].name) == 0)goto GOTIT;
00362    }
00363  }
00364  if(AddLayerToTable(name,7,0) < 0)return;   /* colour 7 not frozen */
00365  i=nDXFlayers-1;
00366  GOTIT:
00367  current_nought = DXFlayers[i].nought;
00368  if(!current_nought){
00369    current_freeze=DXFlayers[i].frozen;
00370    current_colour=DXFlayers[i].colour;
00371    current_layer  = i;
00372    strcpy(CurrentLayer,DXFlayers[i].name);
00373    if(skel_type == 1)current_sp=DXFlayers[i].sp;
00374  }
00375 }
00376 
00377 static short ReadDXFtables(FILE *dxfp){
00378  char name[32],dstr[260]; double di; long vi,gc;
00379  short layer_table=0;
00380  long freeze=0;
00381  if(verbose > 0)X__pri("Tables");
00382  for(;;){
00383    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00384    if(gc == 0 && strncmp(dstr,"ENDSEC",6) == 0)break;
00385    if(gc == 0 && strncmp(dstr,"TABLE",5) == 0){
00386      if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00387      if(gc == 2){
00388        if(verbose > 1)X__pri("Table [%s]",dstr);
00389        if(strncmp(dstr,"LAYER",5) == 0){
00390           layer_table=1;
00391           if(l_freeze)X__pri("Confirm the Freeze/Thaw status of layers");
00392        }
00393        else layer_table=0;
00394        for(;;){
00395          if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00396          if(gc == 0 && strncmp(dstr,"ENDTAB",6) == 0)break;
00397          if(layer_table){
00398            if(gc == 2)strcpy(name,dstr);
00399            else if(gc == 70){
00400              if((vi & 1) == 1)freeze=1;
00401              else             freeze=0;
00402            }
00403            else if(gc == 62){
00404              if(AddLayerToTable(name,vi,freeze) < 0)return -1;
00405              freeze=0;
00406            }
00407          }
00408        }
00409        if(verbose > 1)X__pri("End Table");
00410      }
00411    }
00412  }
00413  UpdateProgress(dxfp);
00414  return 0;
00415 }
00416 
00417 static short CreateSimplePolyline(FILE *dxfp, vertex *lastvertex,
00418              edge *lastedge, long closed, long height, long line3d,
00419              double dx, double dy, double dz){
00420  char dstr[260]; double di; long vi,gc;
00421  long x=0,y=0,z=0,flag=0;
00422  vertex *vp,*tv,*f1=NULL,*f2=NULL,*l1=NULL,*l2=NULL,*l0=NULL;
00423 //X__pri("Standard polyline c=%ld h=%ld 3d=%ld",closed,height,line3d);
00424  tv=MainVp;
00425  for(;;){
00426    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00427    else if(gc == 0 && strncmp(dstr,"SEQEND",6) == 0)flag=1;
00428    if     (gc == 10)x=(long)(di*weld_mult);
00429    else if(gc == 20)y=(long)(di*weld_mult);
00430    else if(gc == 30)z=(long)(di*weld_mult);
00431    else if(gc == 62)current_colour=vi;
00432    else if(gc ==  8)SetLayerCurrents(dstr);
00433    if(flag || (gc == 0 && strncmp(dstr,"VERTEX",5) == 0)){
00434    /* next vertex or end of sequence so create the vertex */
00435      CreateVertex();
00436      MainVp->xyz[0]=x; MainVp->xyz[1]=y; MainVp->xyz[2]=z;
00437      l0=l1;
00438      if(l1 != NULL)CreateEdge(MainVp,l1,0); else f1=MainVp;
00439      l1=MainVp;
00440      if(height > 0){
00441        CreateVertex();
00442        MainVp->xyz[0]=x; MainVp->xyz[1]=y; MainVp->xyz[2]=z+height;
00443        CreateEdge(MainVp,l1,0);
00444        if(l2 != NULL){ /* l0 will also be non null */
00445          CreateEdge(MainVp,l2,0); CreateEdge(MainVp,l0,0);
00446          AddDXFface(MainVp,l2,l0,0);
00447          AddDXFface(MainVp,l0,l1,0);
00448        }
00449        else f2=MainVp;
00450        l2=MainVp;
00451      }
00452    }
00453    if(flag){ /* end of sequence so quit */
00454      if(closed && tv != NULL && f1 != NULL){ /* cloes off the line */
00455        CreateEdge(l1,f1,0);
00456        if(height > 0){
00457          CreateEdge(l2,f2,0); CreateEdge(f1,l1,0);
00458          AddDXFface(f2,l2,l1,0);
00459          AddDXFface(f2,l1,f1,0);
00460        }
00461      }
00462      if(current_sp != NULL){ /* assign to current_skeleton       */
00463         vp=MainVp; while(vp != tv){ vp->sp=current_sp; vp=vp->last; }
00464      }
00465      if(!line3d && (dx != 0.0 || dy != 0.0 || dz != 1.0)){
00466        ReOrientate(dx,dy,dz,MainVp,tv);
00467      }
00468      return 0;
00469    }
00470  }
00471 }
00472 
00473 void BuildEdges(long n, autovertex *av){
00474  long i,j,nn;
00475  for(j=0;j<n;j++){
00476   nn=(av+j)->n;
00477   if(nn > 0)for(i=0;i<nn;i++)
00478     CreateEdge((av+j)->vp,((av+j)->adj[i])->vp,0);
00479  }
00480 }
00481 
00482 static void InsertInVertexList(autovertex *vj, autovertex *vi){
00483  long i,j;
00484  if(vi->n > 0)for(i=0;i<vi->n;i++)if(vi->adj[i] == vj)return;
00485  if(vj->n > 0)for(j=0;j<vj->n;j++)if(vj->adj[j] == vi)return;
00486  if((vi->adj = (autovertex **)realloc(vi->adj,(vi->n + 1)
00487        * sizeof(autovertex *))) == NULL){
00488    if(verbose > 0)X__pri("out of memory");  exit(0);
00489  }
00490  vi->adj[vi->n] = vj;
00491  (vi->n)++;
00492 }
00493 
00494 static autovertex *NewDXFvertex(vertex *lastvertex, long x, long y, long z,
00495                                 autovertex *av, long *nav){
00496   vertex *vp,*vf;
00497   autovertex *tav;
00498   vf=NULL; tav=av;
00499   if(tav == NULL)tav=(autovertex *)malloc(sizeof(autovertex));
00500   else tav=(autovertex *)realloc(av,sizeof(autovertex)*( *nav + 1));
00501   if(tav == NULL){
00502     if(av != NULL){
00503       long i;
00504       for(i=0;i < *nav;i++)if((av+i)->adj != NULL)free((av+i)->adj);
00505       free(av);
00506       return NULL;
00507     }
00508   }
00509   av=tav;
00510   (av + *nav)->n=0; (av + *nav)->adj=NULL;
00511   if(!no_weld){
00512     vp=MainVp; while(vp != lastvertex){
00513       if(x == vp->xyz[0] && y == vp->xyz[1] && z == vp->xyz[2]){
00514         vf=vp; break;
00515       }
00516       vp=vp->last;
00517     }
00518   }
00519   if(vf != NULL){
00520     av[*nav].vp=vf;
00521   }
00522   else{
00523     CreateVertex();
00524     MainVp->xyz[0]=x;
00525     MainVp->xyz[1]=y;
00526     MainVp->xyz[2]=z;
00527     av[*nav].vp=MainVp;
00528   }
00529   (*nav)++;
00530   return av;
00531 }
00532 
00533 static short CreateDXFpolyline(FILE *dxfp,DXFblock *blk){
00534  char dstr[260]; double di; long vi,gc;
00535  long line3d=0,polygon_mesh=0,polyface_mesh=0,polyn=0,polym=0,
00536       x=0,y=0,z=0,fid[4],nfid=0,facespec=0,nav=0,i,j,k,
00537       closed=0,height=0;
00538  short in1=1,in2=1,in3=1,make_vertex;
00539  double lastx=0,lasty=0,lastz=0,dx=0,dy=0,dz=1;
00540  vertex *lastvertex,*vp,*tv;
00541  edge   *lastedge;
00542  autovertex *av=NULL; tv=MainVp;
00543  if(blk == NULL || no_weld){ lastvertex=MainVp; lastedge=MainEp;   }
00544  else                      { lastvertex=blk->vs; lastedge=blk->es; }
00545  for(;;){ /* do the POLYLINE stuff */
00546    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00547    if(gc == 0 && strncmp(dstr,"VERTEX",5) == 0)break;   /* vertices must follow */
00548    else if(gc == 0 && strncmp(dstr,"SEQEND",6) == 0)return -1;
00549    else if(gc == 62)current_colour=vi;
00550    else if(gc ==  8)SetLayerCurrents(dstr);
00551    else if(gc == 70){
00552      if ((vi &  8) ==  8)line3d=1;
00553      if ((vi & 16) == 16)polygon_mesh=1;
00554      if ((vi & 64) == 64)polyface_mesh=1;
00555      if ((vi &  1) ==  1)closed=1;
00556    }
00557    else if(gc == 71)polyn=vi;
00558    else if(gc == 72)polym=vi;
00559    else if(gc == 39)height=(long)(di*weld_mult);
00560    else if(gc == 210)dx=di;
00561    else if(gc == 220)dy=di;
00562    else if(gc == 230)dz=di;
00563  }
00564  if(current_freeze){  /* this POLYLINE entity is on a frozen layer */
00565    for(;;){
00566      if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00567      else if(gc == 0 && strncmp(dstr,"SEQEND",6) == 0)return 0;
00568    }
00569  }
00570  if(!polyface_mesh && !polygon_mesh){ /* a simple polyline */
00571    if(height == 0 && !inc2d){ /* skip the poly line */
00572      for(;;){
00573        if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00574        if(gc == 0 && strncmp(dstr,"SEQEND",6) == 0)return 0;
00575      }
00576    }
00577    if(CreateSimplePolyline(dxfp,lastvertex,lastedge,closed,height,
00578                            line3d,dx,dy,dz) < 0)return -1;
00579    return  0;
00580  }
00581  LOOP1:
00582  make_vertex=0;
00583  LOOP:  /* something else 3d etc */
00584  if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00585  if(polyface_mesh || polygon_mesh){
00586    if     (gc == 10){lastx=di; x=(long)(lastx*weld_mult); in1=0;}
00587    else if(gc == 20){lasty=di; y=(long)(lasty*weld_mult); in2=0;}
00588    else if(gc == 30){lastz=di; z=(long)(lastz*weld_mult); in3=0;}
00589    else if(gc == 62)current_colour=vi;
00590    else if(gc ==  8)SetLayerCurrents(dstr);
00591    else if(gc == 70){
00592      if((polyface_mesh && vi == 192) || (polygon_mesh && vi == 64)){
00593        make_vertex=1;
00594      }
00595      else if(polyface_mesh && vi == 128){ /* 128 bit -> code */
00596        facespec=1,nfid=0;        /* face -> vertex entity   */
00597      }
00598    }
00599    else if(polyface_mesh && gc > 70 && gc < 75){ /* face spec    */
00600      if(nfid > 3)return -1;     /*  more than 4 vertices per face */
00601      fid[nfid++]=abs(vi);       /*  gather all the face indices   */
00602      /* NB: the first index is 1 */
00603    }
00604  }
00605  if(gc != 0)goto LOOP;   /* wait until next entity */
00606  if(make_vertex){
00607    if((in1 || in2 || in3) && verbose > 0){
00608 //ToDo     X__pri("Warning x y or z not initialised"); getch();
00609    }
00610    if((av=NewDXFvertex(lastvertex,x,y,z,av,&nav)) == NULL)return -1;
00611  }
00612  if(facespec > 0){ /* a face has been found build it */
00613    /* X__pri("%ld vertices around face",nfid); */
00614 //   CreateEdgeWithCheck(av[fid[0]-1].vp,av[fid[1]-1].vp,lastedge);
00615 //   CreateEdgeWithCheck(av[fid[1]-1].vp,av[fid[2]-1].vp,lastedge);
00616 //   CreateEdgeWithCheck(av[fid[2]-1].vp,av[fid[0]-1].vp,lastedge);
00617      InsertInVertexList(&av[fid[0]-1],&av[fid[1]-1]);
00618      InsertInVertexList(&av[fid[1]-1],&av[fid[2]-1]);
00619      InsertInVertexList(&av[fid[2]-1],&av[fid[0]-1]);
00620    AddDXFface(av[fid[0]-1].vp,av[fid[1]-1].vp,av[fid[2]-1].vp,0);
00621    if(nfid > 3){ /* create 2nd face since 4 edges */
00622 //     CreateEdgeWithCheck(av[fid[2]-1].vp,av[fid[3]-1].vp,lastedge);
00623 //     CreateEdgeWithCheck(av[fid[3]-1].vp,av[fid[0]-1].vp,lastedge);
00624      InsertInVertexList(&av[fid[2]-1],&av[fid[3]-1]);
00625      InsertInVertexList(&av[fid[3]-1],&av[fid[0]-1]);
00626      AddDXFface(av[fid[0]-1].vp,av[fid[2]-1].vp,av[fid[3]-1].vp,0);
00627    }
00628    nfid=0; facespec=0;
00629  }
00630  if(gc == 0 && strncmp(dstr,"SEQEND",6) == 0){
00631    /* build polygon meshes if any */
00632    if(polygon_mesh == 1 && polyn > 1 && polym > 1 &&
00633      nav == polyn*polym){ /* build mesh ! ensure correct No.V's*/
00634      for(j=0;j<polyn;j++){
00635        for(k=0;k<polym;k++){
00636          i=j*polym+k;
00637          if(k < polym-1)CreateEdge(av[i].vp,av[i+1].vp,0);
00638          if(j > 0){
00639            CreateEdge(av[i].vp,av[i-polym].vp,0);
00640            if(k > 0){
00641              CreateEdge(av[i].vp,av[i-polym-1].vp,0);
00642              AddDXFface(av[i-1].vp,av[i].vp,av[i-polym-1].vp,0);
00643              MainFp->texture |= 0x80;
00644              AddDXFface(av[i].vp,av[i-polym].vp,av[i-polym-1].vp,0);
00645              MainFp->texture |= 0x80;
00646            }
00647          }
00648        }
00649      }
00650    }
00651    if(av != NULL){
00652      if(polyface_mesh)BuildEdges(nav,av);
00653      for(i=0;i<nav;i++)if((av+i)->adj != NULL)free((av+i)->adj);
00654      free(av); /* free any autovertices */
00655    }
00656    if(current_sp != NULL){ /* assign to current_skeleton       */
00657       vp=MainVp; while(vp != tv){ vp->sp=current_sp; vp=vp->last; }
00658    }
00659    return 0;
00660  }
00661  goto LOOP1;
00662 }
00663 
00664 static short CreateDXF3dface(FILE *dxfp, DXFblock *blk){
00665  char dstr[260]; double di; long vi,gc;
00666  vertex *LastUsedVertex,*vp,*vpi[4],*tv;
00667  edge   *LastUsedEdge;
00668  long j,Nf,Face_X[4],Face_Y[4],Face_Z[4];
00669  tv=MainVp;
00670  if(blk == NULL){ LastUsedVertex=MainVp;  LastUsedEdge=MainEp;  }
00671  else           { LastUsedVertex=blk->vs; LastUsedEdge=blk->es; }
00672  for(;;){
00673    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00674    if(gc==33){ /* last vertex so now build the face/faces */
00675      if(!current_freeze){
00676        Face_Z[3]=(long)(di*weld_mult);
00677        if(Face_X[3] == Face_X[2] &&
00678           Face_Y[3] == Face_Y[2] &&
00679           Face_Z[3] == Face_Z[2] )Nf=3;/* a single triangle */
00680        else Nf=4;
00681        for(j=0;j<Nf;j++){
00682          vpi[j]=NULL;
00683          vp=MainVp; while(vp != LastUsedVertex){
00684            if(Face_X[j] == vp->xyz[0] &&
00685               Face_Y[j] == vp->xyz[1] &&
00686               Face_Z[j] == vp->xyz[2]){vpi[j]=vp; break;}
00687            vp=vp->last;
00688          }
00689        }
00690        for(j=0;j<Nf;j++){
00691          if(vpi[j] == NULL){
00692            CreateVertex();
00693            vpi[j]=MainVp;
00694            MainVp->xyz[0]=Face_X[j];
00695            MainVp->xyz[1]=Face_Y[j];
00696            MainVp->xyz[2]=Face_Z[j];
00697          }
00698        }
00699        CreateEdgeWithCheck(vpi[0],vpi[1],LastUsedEdge);
00700        CreateEdgeWithCheck(vpi[1],vpi[2],LastUsedEdge);
00701        AddDXFface(vpi[0],vpi[1],vpi[2],0);
00702        if(Nf > 3){
00703          AddDXFface(vpi[0],vpi[2],vpi[3],0);
00704          CreateEdgeWithCheck(vpi[2],vpi[3],LastUsedEdge);
00705          CreateEdgeWithCheck(vpi[3],vpi[0],LastUsedEdge);
00706          CreateEdge(vpi[0],vpi[2],0);
00707        }
00708        else{
00709          CreateEdgeWithCheck(vpi[2],vpi[0],LastUsedEdge);
00710        }
00711        if(current_sp != NULL){
00712          vp=MainVp; while(vp != tv){ vp->sp=current_sp; vp=vp->last; }
00713        }
00714      }
00715      break;  /* got all this entity go to next */
00716    }
00717    else if(gc==10){Face_X[0]=(long)(di*weld_mult);}
00718    else if(gc==20){Face_Y[0]=(long)(di*weld_mult);}
00719    else if(gc==30){Face_Z[0]=(long)(di*weld_mult);}
00720    else if(gc==11){Face_X[1]=(long)(di*weld_mult);}
00721    else if(gc==21){Face_Y[1]=(long)(di*weld_mult);}
00722    else if(gc==31){Face_Z[1]=(long)(di*weld_mult);}
00723    else if(gc==12){Face_X[2]=(long)(di*weld_mult);}
00724    else if(gc==22){Face_Y[2]=(long)(di*weld_mult);}
00725    else if(gc==32){Face_Z[2]=(long)(di*weld_mult);}
00726    else if(gc==13){Face_X[3]=(long)(di*weld_mult);}
00727    else if(gc==23){Face_Y[3]=(long)(di*weld_mult);}
00728    else if(gc == 8){
00729      if(strcmp(dstr,CurrentLayer) != 0){ /* if the 3dFace is not on the  */
00730        if(blk != NULL){                  /* same layer, then change the  */
00731          blk->vs=MainVp;                 /* the Weld origin, this speeds */
00732          blk->es=MainEp;                 /* up welding a lot !!!         */
00733        }
00734        LastUsedVertex=MainVp;
00735        LastUsedEdge=MainEp;
00736      }
00737      SetLayerCurrents(dstr);
00738    }
00739    else if(gc == 62)current_colour=vi;
00740  }
00741  return 0;
00742 }
00743 
00744 short CreateDXFsolid(FILE *dxfp, DXFblock *blk){
00745  char dstr[260]; double di; long vi,gc;
00746  long i,offset,x[4],y[4],z[4],height=0;
00747  double dx=0,dy=0,dz=1;
00748  vertex *v1,*v2,*v3,*v4,*v5,*v6,*v7,*v8,*vl;
00749  for(i=0;i<4;i++)x[i]=y[i]=z[i]=0;
00750  for(;;){
00751    offset=ftell(dxfp);
00752    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00753    if(gc == 0)break;  /* next entity */
00754    else if(gc ==  8)SetLayerCurrents(dstr);
00755    else if(gc == 62)current_colour=vi;
00756    else if(gc > 9 && gc < 14)x[gc-10]=(long)(di*weld_mult);
00757    else if(gc >19 && gc < 24)y[gc-20]=(long)(di*weld_mult);
00758    else if(gc >29 && gc < 34)z[gc-30]=(long)(di*weld_mult);
00759    else if(gc == 39)height=(long)(di*weld_mult);
00760    else if(gc == 210)dx=di;
00761    else if(gc == 220)dy=di;
00762    else if(gc == 230)dz=di;
00763  }
00764  vl=MainVp;
00765  if(height != 0){ /* make a solid */
00766    if(!current_freeze){
00767      CreateVertex(); v1=MainVp; CreateVertex(); v2=MainVp;
00768      CreateVertex(); v3=MainVp; CreateVertex(); v4=MainVp;
00769      CreateVertex(); v5=MainVp; CreateVertex(); v6=MainVp;
00770      CreateVertex(); v7=MainVp; CreateVertex(); v8=MainVp;
00771      if(current_sp != NULL){
00772        v1->sp=v2->sp=v3->sp=v4->sp=current_sp;
00773        v5->sp=v6->sp=v7->sp=v8->sp=current_sp;
00774      }
00775      CreateEdge(v1,v2,0); CreateEdge(v2,v3,0);   /* top */
00776      CreateEdge(v3,v4,0); CreateEdge(v4,v1,0);
00777      CreateEdge(v5,v6,0); CreateEdge(v6,v7,0);   /* bottom */
00778      CreateEdge(v7,v8,0); CreateEdge(v8,v5,0);
00779      CreateEdge(v1,v5,0); CreateEdge(v2,v6,0);   /* sides */
00780      CreateEdge(v3,v7,0); CreateEdge(v4,v8,0);
00781      CreateEdge(v1,v6,0); CreateEdge(v2,v7,0);   /* side diagonal */
00782      CreateEdge(v3,v8,0); CreateEdge(v4,v5,0);
00783      AddDXFface(v1,v2,v6,0); AddDXFface(v1,v6,v5,0); /* sides */
00784      AddDXFface(v2,v3,v7,0); AddDXFface(v2,v7,v6,0);
00785      AddDXFface(v3,v4,v8,0); AddDXFface(v3,v8,v7,0);
00786      AddDXFface(v4,v1,v5,0); AddDXFface(v4,v5,v8,0);
00787      CreateEdge(v1,v3,0); /* top diagonal */
00788      AddDXFface(v1,v2,v3,0); AddDXFface(v1,v3,v4,0); /* top */
00789      AddDXFface(v5,v6,v7,0); AddDXFface(v5,v7,v8,0); /* bottom */
00790      CreateEdge(v5,v7,0); /* bottom diagonal */
00791      v1->xyz[0]=x[0]; v1->xyz[1]=y[0]; v1->xyz[2]=z[0]+height;
00792      v2->xyz[0]=x[1]; v2->xyz[1]=y[1]; v2->xyz[2]=z[1]+height;
00793      v3->xyz[0]=x[3]; v3->xyz[1]=y[3]; v3->xyz[2]=z[3]+height;
00794      v4->xyz[0]=x[2]; v4->xyz[1]=y[2]; v4->xyz[2]=z[2]+height;
00795      v5->xyz[0]=x[0]; v5->xyz[1]=y[0]; v5->xyz[2]=z[0];
00796      v6->xyz[0]=x[1]; v6->xyz[1]=y[1]; v6->xyz[2]=z[1];
00797      v7->xyz[0]=x[3]; v7->xyz[1]=y[3]; v7->xyz[2]=z[3];
00798      v8->xyz[0]=x[2]; v8->xyz[1]=y[2]; v8->xyz[2]=z[2];
00799    }
00800  }
00801  else {
00802    CreateVertex(); v1=MainVp; CreateVertex(); v2=MainVp;
00803    CreateVertex(); v3=MainVp; CreateVertex(); v4=MainVp;
00804    if(current_sp != NULL){
00805      v1->sp=v2->sp=v3->sp=v4->sp=current_sp;
00806    }
00807    CreateEdge(v1,v2,0); CreateEdge(v2,v3,0);   /* top */
00808    CreateEdge(v3,v4,0); CreateEdge(v4,v1,0); CreateEdge(v1,v3,0);
00809    v1->xyz[0]=x[0]; v1->xyz[1]=y[0]; v1->xyz[2]=z[0];
00810    v2->xyz[0]=x[1]; v2->xyz[1]=y[1]; v2->xyz[2]=z[1];
00811    v3->xyz[0]=x[3]; v3->xyz[1]=y[3]; v3->xyz[2]=z[3];
00812    v4->xyz[0]=x[2]; v4->xyz[1]=y[2]; v4->xyz[2]=z[2];
00813    AddDXFface(v1,v2,v3,0);
00814    AddDXFface(v1,v3,v4,0);
00815  }
00816  if(dx != 0.0 || dy != 0.0 || dz != 1.0){
00817    ReOrientate(dx,dy,dz,MainVp,vl);
00818  }
00819  fseek(dxfp,offset,SEEK_SET); /* go back to get the next entity */
00820  return 0;
00821 }
00822 
00823 short CreateDXFline(FILE *dxfp, DXFblock *blk){
00824  char dstr[260]; double di; long vi,gc;
00825  long offset,x[2],y[2],z[2],height=0;
00826  double dx=0,dy=0,dz=1;
00827  vertex *v1,*v2,*v3,*v4,*vp,*vl;
00828  x[0]=x[1]=y[0]=y[1]=z[0]=z[1]=0;
00829  for(;;){
00830    offset=ftell(dxfp);
00831    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00832    if(gc == 0)break;  /* next entity */
00833    else if(gc ==  8)SetLayerCurrents(dstr);
00834    else if(gc == 62)current_colour=vi;
00835    else if(gc > 9 && gc < 12)x[gc-10]=(long)(di*weld_mult);
00836    else if(gc >19 && gc < 22)y[gc-20]=(long)(di*weld_mult);
00837    else if(gc >29 && gc < 32)z[gc-30]=(long)(di*weld_mult);
00838    else if(gc == 39)height=(long)(di*weld_mult);
00839    else if(gc == 210)dx=di;
00840    else if(gc == 220)dy=di;
00841    else if(gc == 230)dz=di;
00842  }
00843  vl=MainVp;
00844  if(height != 0){ /* make an extruded line */
00845    if(!current_freeze){
00846      CreateVertex(); v1=MainVp; CreateVertex(); v2=MainVp;
00847      CreateVertex(); v3=MainVp; CreateVertex(); v4=MainVp;
00848      if(current_sp != NULL){
00849        v1->sp=v2->sp=v3->sp=v4->sp=current_sp;
00850      }
00851      CreateEdge(v1,v2,0); CreateEdge(v2,v3,0);
00852      CreateEdge(v3,v4,0); CreateEdge(v4,v1,0);
00853      CreateEdge(v1,v3,0); /* top diagonal */
00854      AddDXFface(v1,v2,v3,0); AddDXFface(v1,v3,v4,0);
00855      v1->xyz[0]=x[0]; v1->xyz[1]=y[0]; v1->xyz[2]=z[0];
00856      v2->xyz[0]=x[1]; v2->xyz[1]=y[1]; v2->xyz[2]=z[1];
00857      v3->xyz[0]=x[1]; v3->xyz[1]=y[1]; v3->xyz[2]=z[1]+height;
00858      v4->xyz[0]=x[0]; v4->xyz[1]=y[0]; v4->xyz[2]=z[0]+height;
00859    }
00860  }
00861  else if(inc2d && !current_freeze){ /* 2D line if required */
00862 //X__pri("2D line on layer [%s] %ld",CurrentLayer,current_freeze);
00863    v1=NULL; v2=NULL;
00864    if(blk != NULL && !no_weld){
00865      vp=MainVp; while(vp != blk->vs){
00866        if(vp->xyz[0] == x[0] && vp->xyz[1] == y[0] && vp->xyz[2] == z[0])v1=vp;
00867        if(vp->xyz[0] == x[1] && vp->xyz[1] == y[1] && vp->xyz[2] == z[1])v2=vp;
00868        vp=vp->last;
00869      }
00870    }
00871    if(v1 == NULL){
00872      CreateVertex(); v1=MainVp; if(current_sp != NULL)v1->sp=current_sp;
00873      v1->xyz[0]=x[0]; v1->xyz[1]=y[0]; v1->xyz[2]=z[0];
00874    }
00875    if(v2 == NULL){
00876      CreateVertex(); v2=MainVp; if(current_sp != NULL)v2->sp=current_sp;
00877      v2->xyz[0]=x[1]; v2->xyz[1]=y[1]; v2->xyz[2]=z[1];
00878    }
00879    CreateEdge(v1,v2,0);
00880  }
00881 // lines should not need orientation
00882 // if(dx != 0.0 || dy != 0.0 || dz != 1.0){
00883 //   ReOrientate(dx,dy,dz,MainVp,vl);
00884 // }
00885  fseek(dxfp,offset,SEEK_SET); /* go back to get the next entity */
00886  return 0;
00887 }
00888 
00889 short CreateDXFcircle(FILE *dxfp, DXFblock *blk, long fill){/* ARC fill=0 */
00890  char dstr[260]; double di; long vi,gc;
00891  long offset,x=0,y=0,z=0,height=0,i,sa,ea;
00892  double dx=0,dy=0,dz=1,d=0,z2=0,x2=0,y2=0;
00893  vertex *v1,*v2,*v1s,*v2s,*v1l,*v2l,*vc1,*vc2,*vl,*vp;
00894  skel *sp=NULL;
00895  for(;;){
00896    offset=ftell(dxfp);
00897    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
00898    if(gc == 0)break;  /* next entity */
00899    else if(gc ==  8)SetLayerCurrents(dstr);
00900    else if(gc == 62)current_colour=vi;
00901    else if(gc == 10)x=(long)(di*weld_mult);
00902    else if(gc == 20)y=(long)(di*weld_mult);
00903    else if(gc == 30)z=(long)(di*weld_mult);
00904    else if(gc == 40)d=(double)(di*weld_mult);
00905    else if(gc == 39)height=(long)(di*weld_mult);
00906    else if(gc == 50)sa=(long)di;
00907    else if(gc == 51)ea=(long)di;
00908    else if(gc == 210)dx=di;
00909    else if(gc == 220)dy=di;
00910    else if(gc == 230)dz=di;
00911  }
00912  vl=MainVp;
00913  if(height != 0){ /* make an extruded circle or arc */
00914    if(!current_freeze){
00915      if(fill){  /* circle */
00916        CreateVertex(); vc1=MainVp; CreateVertex(); vc2=MainVp; /* Bottom */
00917        vc1->xyz[0]=x; vc1->xyz[1]=y; vc1->xyz[2]=z;
00918        vc2->xyz[0]=x; vc2->xyz[1]=y; vc2->xyz[2]=z+height;     /* Top    */
00919        for(i=0;i<360;i+=circle_step){
00920          z2=PI*(double)i/180; x2=x+(long)(d*cos(z2)); y2=y+(long)(d*sin(z2));
00921          CreateVertex(); v1=MainVp;
00922          CreateVertex(); v2=MainVp;
00923          v1->xyz[0]=x2; v1->xyz[1]=y2; v1->xyz[2]=z;
00924          v2->xyz[0]=x2; v2->xyz[1]=y2; v2->xyz[2]=z+height;
00925          CreateEdge(v1,v2,0);
00926          CreateEdge(v1,vc1,0); CreateEdge(v2,vc2,0);   /* bottom top */
00927          if(i == 0){v1s=v1; v2s=v2;}
00928          else{
00929           CreateEdge(v1,v1l,0); CreateEdge(v2,v2l,0); CreateEdge(v1l,v2,0);
00930           AddDXFface(v1l,v1,v2,0); AddDXFface(v2,v2l,v1l,0);
00931           AddDXFface(v1,vc1,v1l,0); AddDXFface(v2,vc2,v2l,0); /* B/T */
00932          }
00933          v1l=v1; v2l=v2;
00934        }
00935        if(v1s != NULL && v2s != NULL){
00936          CreateEdge(v1,v1s,0); CreateEdge(v2,v2s,0); CreateEdge(v1,v2s,0);
00937          AddDXFface(v1,v1s,v2s,0); AddDXFface(v2s,v2,v1l,0);
00938          AddDXFface(v1s,vc1,v1,0); AddDXFface(v2s,vc2,v2,0);   /* B/T */
00939        }
00940      }
00941      else { /* arc */
00942        if(ea < sa)ea += 360;
00943        i=sa; for(;;){
00944          LOOPARC1:
00945          z2=PI*(double)i/180; x2=x+(long)(d*cos(z2)); y2=y+(long)(d*sin(z2));
00946          CreateVertex(); v1=MainVp;
00947          CreateVertex(); v2=MainVp;
00948          v1->xyz[0]=x2; v1->xyz[1]=y2; v1->xyz[2]=z;
00949          v2->xyz[0]=x2; v2->xyz[1]=y2; v2->xyz[2]=z+height;
00950          CreateEdge(v1,v2,0);
00951          if(i != sa){
00952           CreateEdge(v1,v1l,0); CreateEdge(v2,v2l,0); CreateEdge(v1l,v2,0);
00953           AddDXFface(v1l,v1,v2,0); AddDXFface(v2,v2l,v1l,0);
00954          }
00955          v1l=v1; v2l=v2;
00956          i += circle_step; if(i > ea)break;
00957        }
00958        if(i < ea+circle_step){i=ea; goto LOOPARC1;}
00959      }
00960      if(current_sp != NULL){
00961         vp=MainVp; while(vp != vl){
00962           vp->sp=current_sp;
00963           vp=vp->last;
00964         }
00965      }
00966    }
00967  }
00968  else if(inc2d && !current_freeze){ /* 2d circle or arc */
00969 //X__pri("circle or arc on layer [%s] %ld",CurrentLayer,current_freeze);
00970    if(fill == 0){ /* arc */
00971      if(ea < sa)ea += 360;
00972      i=sa; for(;;){
00973        LOOPARC:
00974        z2=PI*(double)i/180; x2=x+(long)(d*cos(z2)); y2=y+(long)(d*sin(z2));
00975        CreateVertex();
00976        MainVp->xyz[0]=x2; MainVp->xyz[1]=y2; MainVp->xyz[2]=z;
00977        if(i != sa)CreateEdge(MainVp,v1,0);
00978        v1=MainVp;
00979        i += circle_step; if(i > ea)break;
00980      }
00981      if(i < ea+circle_step){i=ea; goto LOOPARC;} /* make sure arc ends EA */
00982    }
00983    else{  /* full circle */
00984      for(i=0;i<360;i+=circle_step){
00985        z2=PI*(double)i/180; x2=x+(long)(d*cos(z2)); y2=y+(long)(d*sin(z2));
00986        CreateVertex(); v1=MainVp;
00987        v1->xyz[0]=x2; v1->xyz[1]=y2; v1->xyz[2]=z;
00988        if(i == 0)v1s=v1;
00989        else CreateEdge(v1,v1l,0);
00990        v1l=v1;
00991      }
00992      if(v1s != NULL)CreateEdge(v1,v1s,0);
00993    }
00994    if(current_sp != NULL){
00995      vp=MainVp; while(vp != vl){
00996        vp->sp=current_sp;
00997        vp=vp->last;
00998      }
00999    }
01000  }
01001  if(dx != 0.0 || dy != 0.0 || dz != 1.0){
01002    ReOrientate(dx,dy,dz,MainVp,vl);
01003 //   ReOrientate2(dx,dy,dz,x,y,z,MainVp,vl);
01004  }
01005  fseek(dxfp,offset,SEEK_SET); /* go back to get the next entity */
01006  return 0;
01007 }
01008 
01009 static DXFblock *WhatBlock(char *name){
01010  long i;
01011  if(nDXFblocks > 0 && DXFblocks != NULL){
01012    for(i=0;i<nDXFblocks;i++){
01013      if(strcmp(DXFblocks[i].name,name) == 0)return &DXFblocks[i];
01014    }
01015  }
01016  return NULL;
01017 }
01018 
01019 static short CreateEntity(FILE *dxfp,DXFblock *blk,char *entity,skel *sp){
01020  if     (strncmp(entity,"POLYLINE",8) == 0 &&
01021          CreateDXFpolyline(dxfp,blk) < 0)return -1;
01022  else if(strncmp(entity,"LINE",4) == 0 &&
01023          CreateDXFline(dxfp,blk) < 0)return -1;
01024  else if(strncmp(entity,"CIRCLE",6) == 0 &&
01025          CreateDXFcircle(dxfp,blk,1) < 0)return -1;
01026  else if(strncmp(entity,"ARC",3) == 0 &&       /*  arc is like circle    */
01027          CreateDXFcircle(dxfp,blk,0) < 0)return -1;
01028  else if(strncmp(entity,"TRACE",5) == 0 &&      /* trace is same as solid */
01029          CreateDXFsolid(dxfp,blk) < 0)return -1;
01030  else if(strncmp(entity,"SOLID",5) == 0 &&
01031          CreateDXFsolid(dxfp,blk) < 0)return -1;
01032  else if(strncmp(entity,"3DFACE",6) == 0 &&
01033          CreateDXF3dface(dxfp,blk) < 0)return -1;
01034  else if(strncmp(entity,"INSERT",6) == 0 &&
01035          InsertDXFblock(dxfp,sp) < 0)return -1;
01036  return 0;
01037 }
01038 
01039 static short InsertDXFblock(FILE *dxfp,skel *parent){
01040  char dstr[260]; double di; long vi,gc;
01041  char block[32],layer[32];
01042  long offset,x=0,y=0,z=0,j;
01043  double theta,ctheta,stheta,rot=0.0,sx=1.0,sy=1.0,sz=1.0,
01044         dx,dy,dz,tx,ty,edx=0.0,edy=0.0,edz=1.0;
01045  DXFblock *blk;
01046  vertex *vp,*ibs;
01047  skel *sp;
01048  for(;;){
01049    offset=ftell(dxfp);
01050    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01051    if(gc == 0)break;  /* next entity */
01052    else if(gc == 2)strcpy(block,dstr);
01053    else if(gc == 8)SetLayerCurrents(dstr);
01054    else if(gc == 10)x=(long)(di*weld_mult);
01055    else if(gc == 20)y=(long)(di*weld_mult);
01056    else if(gc == 30)z=(long)(di*weld_mult);
01057    else if(gc == 50)rot=di;
01058    else if(gc == 41)sx=di;
01059    else if(gc == 42)sy=di;
01060    else if(gc == 43)sz=di;
01061    else if(gc == 210)edx=di;
01062    else if(gc == 220)edy=di;
01063    else if(gc == 230)edz=di;
01064  }
01065  /* insert the BLOCK */
01066  if(!current_freeze && (blk=WhatBlock(block)) != NULL && !blk->frozen){
01067    if(skel_type == 2){ /* create a child */
01068      sp=parent;
01069      CreateSkeleton(parent);
01070      j=min(12,strlen(block));
01071      strncpy(MainSp->name,block,j); *(MainSp->name+j)=0;
01072      MainSp->xyz[2]=MINUNIT*2*Nskel;
01073      current_sp=MainSp;
01074    }
01075    if(verbose > 1){
01076      X__pri("Inserting [%s] at %lf %lf %lf  @ %lf",blk->name,
01077       (double)x*weld_threshold,(double)y*weld_threshold,(double)z*weld_threshold,rot);
01078      X__pri("Scaling %lf %lf %lf",sx,sy,sz);
01079      X__pri("Block origin %lf %lf %lf",(double)blk->x*weld_threshold,
01080         (double)blk->y*weld_threshold,(double)blk->z*weld_threshold);
01081    }
01082    fseek(dxfp,blk->offset,SEEK_SET); /* go to start of block */
01083    blk->vs=MainVp; blk->es=MainEp; ibs=MainVp;
01084    theta=rot*0.017453292; ctheta=cos(theta); stheta=sin(theta);
01085    for(;;){
01086      if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01087      if(gc == 0 && strncmp(dstr,"ENDBLK",6) == 0)break;
01088      else if(gc == 0){
01089        if(CreateEntity(dxfp,blk,dstr,current_sp) < 0)return -1;
01090      }
01091    }
01092    /* move block into place */
01093    vp=MainVp; while(vp != ibs){
01094      dx = (double)(vp->xyz[0] - blk->x);  dx = dx*sx;
01095      dy = (double)(vp->xyz[1] - blk->y);  dy = dy*sy;
01096      dz = (double)(vp->xyz[2] - blk->z);  dz = dz*sz;
01097      if(rot != 0.0){
01098        tx=(ctheta*dx-stheta*dy);
01099        ty=(stheta*dx+ctheta*dy);
01100        dx=tx; dy=ty;
01101      }
01102      vp->xyz[0] = x + (long)dx;
01103      vp->xyz[1] = y + (long)dy;
01104      vp->xyz[2] = z + (long)dz;
01105      vp=vp->last;
01106    }
01107    if(edx != 0.0 || edy != 0.0 || edz != 1.0){
01108      ReOrientate(edx,edy,edz,MainVp,ibs);
01109    }
01110    /* block now in place */
01111    if(skel_type == 2)current_sp=sp;
01112  }
01113  /* XXXX */
01114  fseek(dxfp,offset,SEEK_SET); /* go back to get the next entity */
01115  return 0;
01116 }
01117 
01118 static short CreateBlockHeader(FILE *dxfp, char *name,
01119                             double *bx, double *by, double *bz){
01120  char dstr[260]; double di; long vi,gc;
01121  DXFblock *db;
01122  long j,offset;
01123  skel *sp=NULL;
01124  *bx = *by = *bz = 0.0;
01125  for(;;){
01126    offset=ftell(dxfp);
01127    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01128    if(gc == 0){ /* next entity so break out */
01129      fseek(dxfp,offset,SEEK_SET); /* go back so that next entity is ready */
01130      break;
01131    }
01132    else if(gc ==  2)strcpy(name,dstr);
01133    else if(gc == 10) *bx=di;
01134    else if(gc == 20) *by=di;
01135    else if(gc == 30) *bz=di;
01136  }
01137  db=DXFblocks;
01138  if(db == NULL)db=(DXFblock *)malloc(sizeof(DXFblock));
01139  else db=(DXFblock *)realloc(db,(nDXFblocks+1)*sizeof(DXFblock));
01140  if(db == NULL){
01141    if(DXFblocks != NULL)free(DXFblocks);
01142    DXFblocks=NULL; nDXFblocks=0;
01143    return -1;
01144  }
01145  DXFblocks=db;
01146  DXFblocks[nDXFblocks].x = (long)((*bx)*weld_mult);
01147  DXFblocks[nDXFblocks].y = (long)((*by)*weld_mult);
01148  DXFblocks[nDXFblocks].z = (long)((*bz)*weld_mult);
01149  DXFblocks[nDXFblocks].vs=NULL;
01150  DXFblocks[nDXFblocks].es=NULL;
01151  DXFblocks[nDXFblocks].frozen=0;
01152  strcpy(DXFblocks[nDXFblocks].name,name);
01153  DXFblocks[nDXFblocks].offset=ftell(dxfp);
01154  nDXFblocks++;
01155  return 0;
01156 }
01157 
01158 static short ReadDXFblocks(FILE *dxfp){
01159  char dstr[260]; double di; long vi,gc,confirm;
01160  char block_name[32];
01161  double bx=0,by=0,bz=0;
01162  for(;;){
01163    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01164    if(gc == 0 && strncmp(dstr,"ENDSEC",6) == 0)break;
01165    if(gc == 0 && strncmp(dstr,"BLOCK",5) == 0){
01166      UpdateProgress(dxfp);
01167      if(CreateBlockHeader(dxfp,block_name,&bx,&by,&bz) < 0)return -1;
01168      if(verbose > 0 || b_freeze)X__pri("Block [%s]",block_name);
01169      for(;;){
01170        if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01171        if(gc == 0 && strncmp(dstr,"ENDBLK",6) == 0)break;
01172      }
01173      if(verbose > 0)X__pri(" at %lf %lf %lf",
01174               (double)DXFblocks[nDXFblocks-1].x * weld_threshold,
01175               (double)DXFblocks[nDXFblocks-1].y * weld_threshold,
01176               (double)DXFblocks[nDXFblocks-1].z * weld_threshold);
01177 //     if(b_freeze){
01178 //       if(confirm == 'Y' || confirm == 'y')DXFblocks[nDXFblocks-1].frozen=1;
01179 //       if(DXFblocks[nDXFblocks-1].frozen)X__pri("  now FROZEN ");
01180 //     }
01181    }
01182  }
01183  return 0;
01184 }
01185 
01186 static short ReadDXFentities(FILE *dxfp){
01187  char dstr[260]; double di; long vi,gc;
01188  vertex *vp,*EntityStart;
01189  long i,dmax,dmin;
01190  double scale,scan;
01191  DXFblock EntityBlock;
01192  if(verbose > 0)X__pri("Entities");
01193  EntityBlock.offset=ftell(dxfp);   /* this is needed for welding */
01194  EntityBlock.x = 0;                /* entities in the Entities   */
01195  EntityBlock.y = 0;                /* section only               */
01196  EntityBlock.z = 0;
01197  EntityBlock.vs=MainVp;
01198  EntityBlock.es=MainEp;
01199  strcpy(EntityBlock.name,"NULL");
01200  strcpy(CurrentLayer,"Dummy-RSF"); current_layer = -1; current_nought = 0;
01201  EntityStart=MainVp; /* vertices after this are DXF */
01202  current_freeze=0;
01203  if(skel_type == 2)current_sp=FirstSp; else current_sp=NULL;
01204  for(;;){
01205    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)return -1;
01206    if(gc == 0 && strncmp(dstr,"ENDSEC",6) == 0)break;
01207    else if(gc == 0){
01208      UpdateProgress(dxfp);
01209      if(CreateEntity(dxfp,&EntityBlock,dstr,FirstSp) < 0)return -1;
01210    }
01211  }
01212  /* scale the model */
01213  dmin = MAXUNIT; dmax = -MAXUNIT;
01214  dmin *= 256; dmax *= 256;
01215  vp=MainVp; while(vp != EntityStart){
01216    if(vp->xyz[0] < dmin)dmin=vp->xyz[0];
01217    if(vp->xyz[1] < dmin)dmin=vp->xyz[1];
01218    if(vp->xyz[2] < dmin)dmin=vp->xyz[2];
01219    if(vp->xyz[0] > dmax)dmax=vp->xyz[0];
01220    if(vp->xyz[1] > dmax)dmax=vp->xyz[1];
01221    if(vp->xyz[2] > dmax)dmax=vp->xyz[2];
01222    vp=vp->last;
01223  }
01224  scale=(double)(dmax-dmin);
01225  scale=(double)(UNIT2*2)/(double)scale*100.0;
01226 
01227  if(dlg != NULL)DestroyWindow(dlg); dlg=NULL;
01228  scan=scale;
01229  if(DialogBoxParam(hInstance,MAKEINTRESOURCE(DLG_SCALE),hWndParent,
01230               (DLGPROC)DlgProcScale,(LPARAM)&scan)){
01231    scale=scan;
01232  }
01233  dlg=CreateDialog(hInstance,MAKEINTRESOURCE(DLGWRIT),hWndParent,(DLGPROC)DlgProc);
01234  scale /= 100.0;
01235  vp=MainVp; while(vp != EntityStart){
01236    for(i=0;i<3;i++)vp->xyz[i] = (long)((double)vp->xyz[i] * scale);
01237    vp=vp->last;
01238  }
01239  if(verbose > 0)X__pri("End Entities");
01240  return 0;
01241 }
01242 
01243 short DxfLoad(char *filename,short skl,short l_fr,short b_fr, short report,
01244               double w_t,short nw,short d2,short d3, short cs){
01245  short error=0;
01246  char dstr[260]; double di; long vi,gc;
01247  FILE *dxfp;
01248  int fhandle;
01249  skel_type=skl; l_freeze=l_fr; b_freeze=b_fr; verbose=report; circle_step=cs;
01250  if(w_t > 0.0)weld_threshold=w_t; no_weld=nw; inc2d=d2; inc3d=1;
01251  nDXFblocks=0; nDXFlayers=0;
01252  current_colour=7; current_layer = -1; current_nought = 0;
01253  current_freeze=0; current_sp=NULL;
01254  if((fhandle=open(filename,O_RDONLY)) >= 0){
01255    struct stat buffer;
01256    if(fstat(fhandle,&buffer) == 0){
01257      file_size=buffer.st_size;
01258    }
01259    else MessageBox(NULL,"File size",NULL,MB_OK);
01260    close(fhandle);
01261  }
01262  else MessageBox(NULL,"Open for size",NULL,MB_OK);
01263  if((dxfp=fopen(filename,"rb")) != NULL){
01264    weld_mult=1.0/weld_threshold;
01265    SetupDXFcolours();
01266    LOOP:
01267    UpdateProgress(dxfp);
01268    if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)goto NOTOK;
01269    if(gc == 0 && strncmp(dstr,"EOF",3) == 0)goto CLOSE;
01270    if(gc == 0 && strncmp(dstr,"SECTION",7) == 0){
01271      UpdateProgress(dxfp);
01272      if((gc=getDXFcode(dxfp,&vi,&di,dstr)) < 0)goto NOTOK;
01273      if     (gc == 2 && strncmp(dstr,"HEADER",6) == 0 &&
01274         ReadDXFheader(dxfp) < 0)goto NOTOK;
01275      else if(gc == 2 && strncmp(dstr,"TABLES",6) == 0  &&
01276         ReadDXFtables(dxfp) < 0)goto NOTOK;
01277      else if(gc == 2 && strncmp(dstr,"BLOCKS",6) == 0  &&
01278         ReadDXFblocks(dxfp) < 0)goto NOTOK;
01279      else if(gc == 2 && strncmp(dstr,"ENTITIES",8) == 0  &&
01280         ReadDXFentities(dxfp) < 0)goto NOTOK;
01281    }
01282    goto LOOP;
01283    NOTOK:
01284    error=2;
01285    CLOSE:
01286    UpdateProgress(dxfp);
01287    fclose(dxfp);
01288  }
01289  else{
01290    error=1;
01291  }
01292  return error;
01293 }

Generated on Sun Apr 27 14:20:10 2014 for OpenFX by  doxygen 1.5.6