home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / crend5 / plgframe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-13  |  17.0 KB  |  750 lines

  1. /*  PLG file processing package
  2. /*  by Dave Stampe 13/5/93
  3. /*
  4. /*  PLGX.EXE
  5. /*  type PLG /? for instructions
  6. /*
  7. /*  center, size, scale, rotate, translate
  8. /*  merge duplicate vertices (IRIT and NorthCad)
  9. /*  renumber vertex comments in file
  10. /*  attempts to preserve original comments in new file
  11. /*
  12. */
  13.  
  14.  
  15.  
  16. #include <stdio.h>
  17. #include <math.h>
  18. #include <dos.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. #define MAXVERTS 2000
  24. #define MAXPOLYS 2000
  25.                           /* vertex, poly storage */
  26. typedef struct { float x, y, z;         } VERT;
  27. typedef struct { char color[20];
  28.          unsigned nverts;
  29.          unsigned vtx[20];       } POLY;
  30.  
  31. #define DEL 1e10    /* flags deleted vertex */
  32.  
  33. VERT v[MAXVERTS];       /* array of vertices */
  34. int vmap[MAXVERTS];     /* maps vertices for combination */
  35. POLY *p[MAXPOLYS];      /* pointers to polygons */
  36. int nlines;             /* total lines in PLG file */
  37. int nameline;           /* original file line numbers of PLG */
  38. int vtxline;            /* sections: so comments will be in  */
  39. int polyline;           /* the right places */
  40.  
  41. char fin[80] = "";      /* in, out filennames */
  42. char fout[80] = "";
  43.  
  44. FILE *in, *out;
  45.  
  46. char plgname[100];      /* PLG object name */
  47.  
  48. int hasverts = 0;    /* when reading the #MULTI tag is valid */
  49.  
  50. int nverts, npolys;     /* old, new vertex counts to/from processing */
  51. int overts, opolys;
  52.  
  53. char line[300];        /* line from PLG file */
  54.  
  55. float sx = 1.0, sy = 1.0, sz = 1.0; /* scale   */
  56. float tx = 0.0, ty = 0.0, tz = 0.0; /* xlat    */
  57. float rx = 0.0, ry = 0.0, rz = 0.0; /* rotate  */
  58. float bx = 0.0, by = 0.0, bz = 0.0; /* box fit */
  59. float clim = -1.0;                  /* combine delta */
  60.  
  61. int centerxz = 0;    /* action flags */
  62. int centery = 0;
  63. int gcenter = 0;
  64. int ground = 0;
  65. int info = 0;
  66. int multi = 0;
  67. int renverts = 0;
  68. int reverse = 0;
  69. int whole = 0;
  70. int integrated = 0;
  71.  
  72. float maxx, maxy, maxz;        /* box size/center statistics */
  73. float minx, miny, minz;
  74. float sumx, sumy, sumz;
  75.  
  76. long plgpos;
  77. int abssumverts;
  78.  
  79. read_plg()        /* reads data from PLG file, checks */
  80. {
  81.  int i,j,k;
  82.  char *c;
  83.  float x, y, z;
  84.  POLY p1;
  85.  POLY *pp;
  86.  
  87.  plgpos = ftell(in);        /* record for file rewind */
  88.  
  89.  if(!integrated)
  90.   {
  91.    maxx = maxy = maxz = -1e9;    /* initialize for object-by-object data */
  92.    minx = miny = minz =  1e9;
  93.    sumx = sumy = sumz =  0.0;
  94.    abssumverts = 0;
  95.   }
  96.  nlines = 0;
  97.  nameline = vtxline = polyline = -1;
  98.  
  99.  while(!feof(in))        /* read till name */
  100.   {
  101.    nameline = nlines++;
  102.    fgets(line, 300, in);
  103.    c=strchr(line,'#');
  104.    if(c)
  105.     {
  106.      if(strstr(c,"#MULTI")) multi++;    /* detect multi-res type */
  107.      *c = 0;
  108.     }
  109.  
  110.    if(sscanf(line, "%s %d %d", plgname, &nverts, &npolys)==3) break;
  111.   }
  112.  if(feof(in))
  113.   {
  114.    nameline = -1;    /* EOF before new object */
  115.    return 0;
  116.   }
  117.  
  118.  overts = nverts;        /* process vertex count */
  119.  opolys = npolys;
  120.  if(integrated>=0) abssumverts += nverts;
  121.  
  122.  for(i=0;i<nverts;i++)      /* read vertices */
  123.   {
  124.    while(1)
  125.     {
  126.      if(feof(in))
  127.       {
  128.        fprintf(stderr, "Early EOF in input file\n");
  129.        fcloseall();
  130.        exit(-1);
  131.       }
  132.  
  133.      fgets(line, 300, in);    /* delete comments */
  134.      nlines++;
  135.      c=strchr(line,'#');
  136.      if(c)
  137.       {
  138.        *c = 0;
  139.       }
  140.  
  141.      j=sscanf(line, "%f %f %f", &x, &y, &z);    /* get vertex */
  142.      if(j==0 || j==EOF) continue;
  143.      if(j<3)
  144.       {
  145.        fprintf(stderr, "Syntax error on line %d of input file\n", nlines);
  146.        fcloseall();
  147.        exit(-1);
  148.       }
  149.      if(j==3) break;
  150.     }
  151.    if(vtxline<0) vtxline = nlines;
  152.    v[i].x = x;  v[i].y = y; v[i].z = z;
  153.    sumx += x;  sumy += y;  sumz += z;
  154.    if(x>maxx) maxx = x;            /* box statistics */
  155.    if(y>maxy) maxy = y;
  156.    if(z>maxz) maxz = z;
  157.    if(x<minx) minx = x;
  158.    if(y<miny) miny = y;
  159.    if(z<minz) minz = z;
  160.   }
  161.  
  162.  for(i=0;i<npolys;i++)        /* read polygons */
  163.   {
  164.    while(1)
  165.     {
  166.      if(feof(in))
  167.       {
  168.        fprintf(stderr, "Early EOF in input file\n");
  169.        fcloseall();
  170.        exit(-1);
  171.       }
  172.  
  173.      fgets(line, 300, in);
  174.      nlines++;
  175.      c=strchr(line,'#');    /* skip comments */
  176.      if(c)
  177.       {
  178.        *c = 0;
  179.       }
  180.  
  181.      c = strtok(line," \t");
  182.      if(c==NULL || c[0]==0 || c[0]=='\n') continue;
  183.      else break;
  184.     }
  185.  
  186.    if(vtxline<0) vtxline = nlines;
  187.    strcpy(p1.color, line);        /* color as string */
  188.    c = strtok(NULL," \t");
  189.    p1.nverts = atoi(c);
  190.    if(p1.nverts<1)
  191.     {
  192.      fprintf(stderr, "Syntax error on line %d of input file\n", nlines);
  193.      fcloseall();
  194.      exit(-1);
  195.     }
  196.    if(p1.nverts>20)    /* max. 20 vertices for REND386 */
  197.     {
  198.      fprintf(stderr, "Too many vertices in poly on line %d of input file\n", nlines);
  199.      fcloseall();
  200.      exit(-1);
  201.     }
  202.    for (j = 0; j < p1.nverts; ++j)    /* read vertex indices */
  203.     {
  204.      c = strtok(NULL," \t");
  205.      k = atoi(c);
  206.      if(k<0 || k>nverts)
  207.       {
  208.        fprintf(stderr, "Bad vertex number on line %d of input file\n", nlines);
  209.        fcloseall();
  210.        exit(-1);
  211.       }
  212.      p1.vtx[j] = k;
  213.      pp = (POLY *) calloc(sizeof(POLY), 1);
  214.      if(!pp)
  215.       {
  216.        fprintf(stderr, "Out of memory at line %d of input file\n", nlines);
  217.        fcloseall();
  218.        exit(-1);
  219.       }
  220.      memcpy(pp, &p1, sizeof(POLY));    /* store new poly */
  221.      p[i] = pp;
  222.     }
  223.   }
  224.  return 1;
  225. }
  226.  
  227.  
  228. char *trcomments(char * line)    /* extract comments from line */
  229. {
  230.  char *c;        /* c == line if nothing but comments or blank */
  231.  
  232.  c=strchr(line,'#');
  233.  if (!c) c = line+strlen(line);
  234.  while(c>line && isspace(*(c-1))) c--;    /* include leading space */
  235.  return c;
  236. }
  237.  
  238.  
  239. write_plg()     /* writes PLG file, tries to preserve comments */
  240. {
  241.  int i,j,k, ln;
  242.  int vtxn, plyn;
  243.  char *c;
  244.  char lbuff[300];
  245.  
  246.  fseek(in, plgpos, SEEK_SET);    /* rewind to get PLG comments */
  247.  
  248.  for(ln=0;ln<nameline;ln++)    /* copy leading comments */
  249.   {
  250.    fgets(line, 300, in);
  251.    fputs(trcomments(line), out);
  252.   }
  253.  
  254.  k = sprintf(lbuff,"%s %d %d",     /* name line with comments */
  255.        plgname, nverts, npolys);
  256.  fgets(line, 300, in);
  257.  ln++;
  258.  c=strchr(line,'#');
  259.  strcpy(lbuff+k, trcomments(line));
  260.  fputs(lbuff, out);
  261.  
  262.  for(;ln<vtxline-1;ln++)    /* lines to start of vertices */
  263.   {
  264.    fgets(line, 300, in);
  265.    fputs(trcomments(line), out);
  266.   }
  267.  
  268.  vtxn = 0;
  269.  for(i=0;i<overts;i++)     /* lines containing vertices */
  270.   {
  271.    while(1)
  272.     {
  273.      fgets(line, 300, in);
  274.      ln++;
  275.      if(trcomments(line) == line)
  276.       {
  277.        fputs(trcomments(line), out);
  278.        continue;    /* blank/comment line */
  279.       }
  280.      else break;
  281.     }
  282.    if(v[i].x == DEL)    /* maark vertices deleted by combining */
  283.     {
  284.      if(!renverts) k = 0;
  285.      else k = sprintf(lbuff, "# DELETED\t ");
  286.     }
  287.    else
  288.     {
  289.      if(maxx-minx>1 || maxy-miny>1 || maxz-minz>1)
  290.       {
  291.        if(fabs(v[i].x)<0.01) v[i].x = 0.0;   /* delete tiny numbers */
  292.        if(fabs(v[i].y)<0.01) v[i].y = 0.0;   /* for better formatting */
  293.        if(fabs(v[i].z)<0.01) v[i].z = 0.0;
  294.       }
  295.      if(!renverts)
  296.        k = sprintf(lbuff,"% 6g % 6g % 6g ", v[i].x, v[i].y, v[i].z);
  297.      else
  298.        k = sprintf(lbuff,"% 6g % 6g % 6g\t #VTX %d\t ", v[i].x, v[i].y, v[i].z, vtxn);
  299.  
  300.      if(vtxn != i)    /* renumber poly vertices too */
  301.       {                 /* after recombination */
  302.        int j,k;
  303.        for(j=0;j<opolys;j++)
  304.     {
  305.      if(p[j]==NULL) continue;
  306.      for(k=0;k<p[j]->nverts;k++)
  307.        if(p[j]->vtx[k]==i) p[j]->vtx[k] = vtxn;
  308.     }
  309.       }
  310.      vtxn++;
  311.     }
  312.    strcpy(lbuff+k, trcomments(line));    /* add comments to vertex line */
  313.    fputs(lbuff, out);
  314.   }
  315.  
  316.  for(;ln<polyline-1;ln++)    /* lines to start of polyss */
  317.   {
  318.    fgets(line, 300, in);
  319.    fputs(trcomments(line), out);
  320.   }
  321.  
  322.  for(i=0;i<opolys;i++)     /* lines containing polys */
  323.   {
  324.    while(1)
  325.     {
  326.      fgets(line, 300, in);
  327.      ln++;
  328.      if(trcomments(line) == line)
  329.       {
  330.        fputs(trcomments(line), out);
  331.        continue;    /* blank/comment line */
  332.       }
  333.      else break;
  334.     }
  335.    if(p[i] == NULL)
  336.     {
  337.      k = sprintf(lbuff, "# DELETED ");    /* mark deleted polys */
  338.     }
  339.    else
  340.     {
  341.      k = sprintf(lbuff,"%s % 3d", p[i]->color, p[i]->nverts);
  342.      for(j=0;j<p[i]->nverts;j++)
  343.        k += sprintf(lbuff+k, "% 3d", p[i]->vtx[j]);
  344.      free(p[i]);
  345.     }
  346.    strcpy(lbuff+k, trcomments(line));
  347.    fputs(lbuff, out);
  348.   }
  349. }
  350.          /* ascii to color number for information */
  351.  
  352. unsigned convert_color(char *s, char **ptr)
  353. {
  354.  int hue, value;
  355.  if (isdigit(*s)) return (unsigned) strtoul(s, ptr, 0);
  356.  if (ptr) for (*ptr = s; isalnum(**ptr) || **ptr == '_'; ++*ptr);
  357.  if (!strnicmp(s, "shaded", 6))
  358.   {
  359.    sscanf(s, "shaded_%d_%d", &hue, &value);
  360.    return 0x1000 | ((hue & 0x0F) << 8) | (value & 0xFF);
  361.   }
  362.  else if (!strnicmp(s, "metal", 5))
  363.   {
  364.    sscanf(s, "metal_%d_%d", &hue, &value);
  365.    return 0x2000 | ((hue & 0x0F) << 8) | ((value & 0x1F) << 3);
  366.   }
  367.  else if (!strnicmp(s, "glass", 5))
  368.   {
  369.    sscanf(s, "glass_%d_%d", &hue, &value);
  370.    return 0x3000 | ((hue & 0x0F) << 8) | ((value & 0x1F) << 3);
  371.   }
  372.  return 0;
  373. }
  374.  
  375.  
  376. print_info()    /* info on poly object */
  377. {
  378.  int i;
  379.  unsigned c;
  380.  int hasabs = 0;
  381.  int hasstd = 0;
  382.  int hasmap = 0;
  383.  
  384.  if(multi) printf("PLG file type: MULTI resolution\n");
  385.  printf("PLG file name: \t%s\n", fin);
  386.  printf("PLG object name: \t%s\n", plgname);
  387.  printf("Vertices: \t%d\n", nverts);
  388.  printf("Polygons: \t%d\n", npolys);
  389.  
  390.  for(i=0;i<npolys;i++)
  391.   {
  392.    c = convert_color(p[i]->color, NULL);
  393.    if(c & 0x8000)
  394.     {
  395.      if((c&0x0FFF)>hasmap) hasmap = c & 0x0FFF;
  396.     }
  397.    else if ((c&0xFF00)==0) hasabs++;
  398.    else hasstd++;
  399.   }
  400.  
  401.  printf("Color types: \n");
  402.  if(hasabs) printf("\tDirect palette mapped colors\n");
  403.  if(hasstd) printf("\tCosine lit, glass, metal types\n");
  404.  if(hasmap) printf("\tSurface mapped, 1 to %d\n", hasmap);
  405.  
  406.  printf("Bounding box: (%g, %g, %g) - (%g, %g, %g)\n",
  407.    minx, miny, minz, maxx, maxy, maxz);
  408.  printf("Centered at: (%g, %g, %g)\n", (maxx+minx)/2.0,
  409.               (maxy+miny)/2.0,(maxz+minz)/2.0  );
  410.  printf("Size: (%g, %g, %g)\n", maxx-minx, maxy-miny,maxz-minz );
  411.  printf("\n");
  412. }
  413.  
  414.  
  415. reverse_order()   /* reverse order of all poly vertex lists */
  416. {
  417.  int i, j, k, n;
  418.  
  419.  for(i=0;i<npolys;i++)
  420.   {
  421.    n =p[i]->nverts;
  422.    for(j=0;j<n/2;j++)
  423.     {
  424.      k = p[i]->vtx[j];
  425.      k = p[i]->vtx[j] = p[i]->vtx[n-j-1];
  426.      p[i]->vtx[n-j-1] = k;
  427.     }
  428.   }
  429. }
  430.  
  431.  
  432. mmult(float A, float B, float C,    /* matrix to vertex apply */
  433.       float D, float E, float F,
  434.       float G, float H, float I,
  435.       float *x, float *y, float *z)
  436. {
  437.  float xx = *x, yy= *y, zz = *z;
  438.  
  439.  *x = A*xx + B*yy + C*zz;
  440.  *y = D*xx + E*yy + F*zz;
  441.  *z = G*xx + H*yy + I*zz;
  442. }
  443.  
  444.  
  445. process_plg()        /* pocess all polys in object */
  446. {
  447.  int i, j, k;
  448.  
  449.  float ox, oy, oz;
  450.  float snx, csx, sny, csy, snz, csz;
  451.  float cx, cy, cz;
  452.  
  453.  if (reverse) reverse_order();    /* reverse visibility */
  454.  
  455.  if(gcenter)    /* center of gravity */
  456.   {
  457.    cx = sumx/abssumverts;
  458.    cy = sumy/abssumverts;
  459.    cz = sumz/abssumverts;
  460.   }
  461.  else
  462.   {
  463.    cx = (maxx+minx)/2.0;    /* box center */
  464.    cy = (maxy+miny)/2.0;
  465.    cz = (maxz+minz)/2.0;
  466.   }
  467.  
  468.  if(centerxz || centery || ground)   /* precenter or shift vertices */
  469.    for(i=0;i<nverts;i++)
  470.     {
  471.      v[i].x -= cx;
  472.      v[i].z -= cz;
  473.      if(centery) v[i].y -= cy;
  474.      if(ground)  v[i].y -= miny;
  475.     }
  476.  
  477.  if(rx+ry+rz > 0.0001)        /* rotation */
  478.   {
  479.    float x,y,z;
  480.  
  481.    snx = sin(rx/57.296);    /* precompute for speed */
  482.    csx = cos(rx/57.296);
  483.    sny = sin(ry/57.296);
  484.    csy = cos(ry/57.296);
  485.    snz = sin(rz/57.296);
  486.    csz = cos(rz/57.296);
  487.  
  488.    for(i=0;i<nverts;i++)
  489.     {
  490.      x = v[i].x;
  491.      y = v[i].y;               /* rotate in Y, X, Z order */
  492.      z = v[i].z;
  493.      mmult(csy, 0, sny, 0, 1, 0, -sny, 0, csy, &x, &y, &z);
  494.      mmult(1, 0, 0, 0, csx, -snx, 0, snx, csx, &x, &y, &z);
  495.      mmult(csz, -snz, 0, snz, csz, 0, 0, 0, 1, &x, &y, &z);
  496.      v[i].x = x;
  497.      v[i].y = y;
  498.      v[i].z = z;
  499.     }
  500.   }
  501.  
  502.  if(bx)     /* compute box scaling */
  503.   {
  504.    if(maxx-minx>0.0001) sx = bx/(maxx-minx); else sx = 1.0;
  505.    if(maxy-miny>0.0001) sy = by/(maxy-miny); else sy = 1.0;
  506.    if(maxz-minz>0.0001) sz = bz/(maxz-minz); else sz = 1.0;
  507.   }
  508.  
  509.  if(sx!=1.0 || sy!=1.0 || sz!=1.0)   /* scale object */
  510.    for(i=0;i<nverts;i++)
  511.     {
  512.      v[i].x *= sx;
  513.      v[i].y *= sy;
  514.      v[i].z *= sz;
  515.     }
  516.  
  517.  if(tx || ty || tz)   /* translate object */
  518.    for(i=0;i<nverts;i++)
  519.     {
  520.      v[i].x += tx;
  521.      v[i].y += ty;
  522.      v[i].z += tz;
  523.     }
  524.  
  525.  if(whole)   /* integerize object */
  526.    for(i=0;i<nverts;i++)
  527.     {
  528.      v[i].x = floor(v[i].x);
  529.      v[i].y = floor(v[i].y);
  530.      v[i].z = floor(v[i].z);
  531.     }
  532.  
  533.  if(clim>0.0)               /* delete duplicte vertices */
  534.   {
  535.    int nvtx = nverts;
  536.    float x,y,z;
  537.  
  538.    for(i=0;i<nverts;i++) vmap[i] = -1;
  539.  
  540.    for(i=0;i<nverts;i++)
  541.     {
  542.      if(v[i].x == DEL) continue;
  543.      x = v[i].x;
  544.      y = v[i].y;
  545.      z = v[i].z;
  546.  
  547.      for(j=i+1;j<nverts;j++)   /* duplicate test */
  548.       {
  549.        if ( v[j].x == DEL) continue;
  550.        if ( fabs(x-v[j].x)<clim &&
  551.         fabs(y-v[j].y)<clim &&
  552.         fabs(z-v[j].z)<clim   )
  553.          {
  554.           v[j].x = DEL;
  555.           vmap[j] = i;
  556.           nvtx--;
  557.          }
  558.       }
  559.     }
  560.    nverts = nvtx;
  561.  
  562.    if(nverts != overts)
  563.      for(i=0;i<npolys;i++)    /* update polygons */
  564.       {
  565.        if(p[i]==NULL) continue;
  566.        for(j=0;j<p[i]->nverts;j++)
  567.      if((k=vmap[p[i]->vtx[j]])>=0) p[i]->vtx[j] = k;
  568.       }
  569.   }
  570. }
  571.  
  572.  
  573. syntax()
  574. {
  575.  fprintf(stderr,"\n");
  576.  fprintf(stderr,"\n");
  577.  fprintf(stderr,"\n");
  578.  fprintf(stderr,"\n");
  579.  fprintf(stderr,"\n");
  580.  fprintf(stderr,"\n");
  581.  fprintf(stderr,"\n");
  582.  fprintf(stderr,"\n");
  583.  fprintf(stderr,"\n");
  584. }
  585.  
  586.  
  587. int add_extension(char *fname, char *ext)
  588. {
  589.  int i,j;
  590.  
  591.  if(fname[0] == 0) return(-1);         /* error: no string */
  592.  for(i=0;i<70;i++)
  593.   {
  594.    if(fname[i] == '.') return(1);    /* already has valid extension */
  595.    if(fname[i] == 0)
  596.     {
  597.      fname[i] = '.';                 /* add default extension */
  598.      fname[i+1] = ext[0];
  599.      fname[i+2] = ext[1];
  600.      fname[i+3] = ext[2];
  601.      fname[i+4] = 0;
  602.      return(0);
  603.     }
  604.   }
  605.  return(-1);            /* error: string too long */
  606. }
  607.  
  608.  
  609. int obj = 0;
  610.  
  611. void main(int argc, char *argv[])
  612. {
  613.  int i,c;
  614.  
  615.  if(argc<2) syntax();
  616.  
  617.  for (i = 1; i < argc; ++i)
  618.   {
  619.    if (argv[i][0] == '/' || argv[i][0] == '-')
  620.     {
  621.      switch(toupper(argv[i][1]))
  622.       {
  623.        case 'C':/* center overall */
  624.         centerxz = 1;
  625.         centery = 1;
  626.         break;
  627.        case 'G':/* ground and center */
  628.         ground  = 1;
  629.         centerxz = 1;
  630.         centery  = 0;
  631.         break;
  632.        case 'I':/* information on object */
  633.         info = 1;
  634.         break;
  635.        case 'F':/* reverse vertex order */
  636.         reverse = 1;
  637.         break;
  638.        case 'N':/* renumber vertices in comments */
  639.         renverts = 1;
  640.         break;
  641.        case 'W':/* integer (whole) numbers only */
  642.         whole = 1;
  643.         break;
  644.        case 'Y':/* all objects in file are one for size/center */
  645.         integrated = 1;
  646.         break;
  647.        case 'Z':/* avg. center */
  648.         gcenter = 1;
  649.         break;
  650.        case '?':/* syntax */
  651.         syntax();
  652.         exit(0);
  653.         break;
  654.  
  655.        case 'S':/* scale PLG */
  656.         c=sscanf(argv[++i],"%f,%f,%f",&sx,&sy,&sz);
  657.         if (c<3) sy = sz = sx;
  658. /*        if(sx<0 || sy<0 || sz<0)
  659.          {
  660.           fprintf(stderr, "Negative scaling not allowed: will cause visibility errors\n");
  661.           fprintf(stderr, "Please use rotation instead\n");
  662.           exit(-1);
  663.          } */
  664.         break;
  665.        case 'T':/* translate PLG */
  666.         c=sscanf(argv[++i],"%f,%f,%f",&tx,&ty,&tz);
  667.         break;
  668.        case 'R':/* rotate PLG */
  669.         c=sscanf(argv[++i],"%f,%f,%f",&rx,&ry,&rz);
  670.         break;
  671.        case 'B':/* abs box size PLG */
  672.         c=sscanf(argv[++i],"%f,%f,%f",&bx,&by,&bz);
  673.         if (c<3) by = bz = bx;
  674.         break;
  675.  
  676.        case 'O':/* object in file to process */
  677.         obj = 1;
  678.         if(isdigit(argv[i+1][0]))
  679.            c=sscanf(argv[++i],"%d",&obj);
  680.         break;
  681.        case 'V':/* vertex recombine */
  682.         clim = 0.0001;
  683.         if(isdigit(argv[i+1][0]))
  684.            c=sscanf(argv[++i],"%f",&clim);
  685.         break;
  686.        case 'D':/* default size box */
  687.         {
  688.          float ds = 1000.0;
  689.          if(isdigit(argv[i+1][0]))
  690.              c=sscanf(argv[++i],"%f",&ds);
  691.          bx = by = bz = ds;
  692.         }
  693.         break;
  694.       }
  695.     }
  696.    else
  697.     {
  698.      if(!fin[0]) strcpy(fin,argv[i]);      /* copy in, out filename */
  699.      else        strcpy(fout,argv[i]);
  700.     }
  701.   }
  702.  if(fin[0]==0 || fout[0]==0) syntax();
  703.  add_extension(fin, "plg");
  704.  add_extension(fout, "plg");
  705.  if((in=fopen(fin,"r"))==NULL)
  706.   {
  707.    fprintf(stderr, "Can't open %s for input.\n", fin);
  708.    exit(-1);
  709.   }
  710.  if(fout[0])
  711.   if((out=fopen(fout,"w"))==NULL)
  712.     {
  713.      fprintf(stderr, "Can't open %s for output.\n", fout);
  714.      exit(-1);
  715.     }
  716.  
  717.  maxx = maxy = maxz = -1e9;
  718.  minx = miny = minz =  1e9;
  719.  sumx = sumy = sumz =  0.0;
  720.  abssumverts = 0;
  721.  
  722.  i = 0;
  723.  
  724.  if(integrated)
  725.   {
  726.    while(!feof(in))
  727.     {
  728.      read_plg();
  729.      if(nameline<0) break;
  730.     }
  731.    fseek(in,0,0);
  732.    integrated = -1;
  733.   }
  734.  
  735.  while(!feof(in))
  736.   {
  737.    i++;
  738.    read_plg();
  739.    if(nameline<0) break;
  740.    if(info) print_info();
  741.    if(obj==0 || obj == i) process_plg();
  742.    if(fout[0]) write_plg();
  743.   }
  744.  fcloseall();
  745.  fprintf(stderr, "Sucessful completion.\n");
  746.  exit(0);
  747.  
  748.  
  749. }
  750.