/*                                                                       */
/* genobj.c by Gerhard.Hippmann@dlr.de                                   */
/* genobj.b <filename>  generates ./<filename>.obj from ./<filename>.txt */
/*                                                                       */
/* gcc -o genobj.b genobj.c                                              */
/*                                                                       */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>


int main( int argc, char *argv[] );


int main( int narg, char *arg[] )
{
   int  found;
   int  ix;
   int  idv;
   int  nivert;
   int  novert;
   int  nface;
   char  ch;
   char  infile[128];
   char  outfile[128];
   char  line[128];
   float  x, y, z;
   float  dis;
   FILE  *file;
   struct  tvert
   {
      float  x;
      float  y;
      float  z;
      struct tvert  *next;
   };
   struct  tface
   {
      struct tidv  *idv;
      struct tface  *next;
   };
   struct  tidv
   {
      int  id;
      struct tidv  *next;
   };
   struct tvert  *pvert;
   struct tvert  *pv;
   struct tvert  *pvn;
   struct tface  *pface;
   struct tface  *pf;
   struct tface  *pfn;
   struct tidv   *pidv;
   struct tidv   *pi;
   struct tidv   *pin;

   const float  eps = 1.0e-6;

   if ( narg != 2 )
   {
      printf( "ERROR: Wrong Number of Arguments narg = %d\n", narg );
      return 1;
   }

   strcpy( infile, arg[1] );
   strcat( infile, ".txt" );

   strcpy( outfile, arg[1] );
   strcat( outfile, ".obj" );

   file = fopen( infile, "rt" );

   if ( file == NULL )
   {
      printf( "** ERROR: Cannot open Input File: %s\n", infile );
      return 1;
   }

   printf( "\n" );
   printf( " * Read Input File: %s\n", infile );

   nivert = 0;
   novert = 0;
   nface = 0;

   pvert = NULL;
   pface = NULL;
   pidv = NULL;
   ix = 0;
   do
   {
      /* Read next Character */
      ch = getc( file );

      if ( ch == '\n' || ch == EOF || ix > 128 )
      {
         /* Process Line */
         line[ix] = '\0';
         narg = sscanf( line, "%e %e %e", &x, &y, &z );
         if ( narg == 3 )
         {
/*
printf( "%e %e %e\n", x,y,z );
*/
            /* Get Vertex-ID */
            idv = 0;
            found = 0;
/*
printf( "\nnew: %e %e %e\n", x,y,z );
*/
            /* Check if Vertex is already in List */
            for ( pvn=pvert; pvn!=NULL; pvn=pvn->next )
            {
               idv++;
               dis = (x - pvn->x) * (x - pvn->x);
               dis = (y - pvn->y) * (y - pvn->y) + dis;
               dis = (z - pvn->z) * (z - pvn->z) + dis;
/*
printf( "vert(%d): %e %e %e\n", idv, pvn->x, pvn->y, pvn->z );
*/
               if ( dis < eps )
               {
                 found = 1;
                 break;
               }
            }
            /* Vertex not found in List -> create and apend new Vertex Element */
            if ( ! found )
            {
               pvn = malloc( sizeof( struct tvert ) );
               pvn->x = x;
               pvn->y = y;
               pvn->z = z;
               pvn->next = NULL;
               if ( pvert == NULL )
                  pvert = pvn;
               else
                  pv->next = pvn;
               pv = pvn;
               idv++;
               novert++;
            }
            /* Apend Vertex-ID */
            pin = malloc( sizeof( struct tidv ) );
            pin->id = idv;
            pin->next = NULL;
            if ( pidv == NULL )
               pidv = pin;
            else
               pi->next = pin;
            pi = pin;
            nivert++;
         }
         else if ( pidv != NULL )
         {
            /* End of Face -> create and apend new Face Element */
/*
printf("========\n");
*/
            pfn = malloc( sizeof( struct tface ) );
            pfn->idv = pidv;
            pfn->next = NULL;
            if ( pface == NULL )
               pface = pfn;
            else
               pf->next = pfn;
            pf = pfn;
            pidv = NULL;
            nface++;
         }
         /* Reset Characters per Line Counter */
         ix = 0;
      }
      else
         /* Apend next Character to line */
         line[ix++] = ch;
   }
   while ( ch != EOF );

   fclose( file );

   printf( "\n" );
   printf( " - Number of Faces           = %d\n", nface );
   printf( " - Number of Input  Vertices = %d\n", nivert );
   printf( " - Number of Output Vertices = %d\n", novert );

   file = fopen( outfile, "wt" );

   if ( file == NULL )
   {
      printf( "** ERROR: Cannot open Output File: %s\n", outfile );
      return 1;
   }

   printf( "\n" );
   printf( " * Write Output File: %s\n", outfile );

   /* Write Header */
   fprintf( file, "# Number of Vertices = %d\n", novert );
   fprintf( file, "# Number of Faces    = %d\n", nface );
   /* Write Vertices */
   for ( pv=pvert; pv!=NULL; pv=pv->next )
      fprintf( file, "v %13e %13e %13e\n", pv->x, pv->y, pv->z );
   /* Write Faces */
   for ( pf=pface; pf!=NULL; pf=pf->next )
   {
      fprintf( file, "f" );
      for ( pi=pf->idv; pi!=NULL; pi=pi->next )
         fprintf( file, " %d", pi->id );
      fprintf( file, "\n" );
   }

   fclose( file );

   printf( "\n" );

   return 0;
}
