/*                                            */
/* cylinder.c by Gerhard.Hippmann@dlr.de      */
/* cylinder.b <filename> <l> <r> <nl> <nr>    */
/* Generates a polygonal surface file         */
/* <filename>.obj                             */
/* representing a cylinder                    */
/* of length l, radius r                      */
/* and discretisation nl, nr                  */
/*                                            */
/* gcc -lm -o cylinder.b cylinder.c           */
/*                                            */
/* 09-05-15 corrected face orientation        */
/* 09-05-15 fixed longitudinal discretisation */
/* 09-05-15 added caps                        */
/*                                            */


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


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


int main( int narg, char *arg[] )
{
   int  nl;
   int  nr;
   int  il;
   int  ir;
   int  ivert;
   int  nvert;
   int  nface;
   int  f1, f2, f3;

   float  l;
   float  r;
   float  x, y, z;

   double  pi;
   double  dl, dphi;
   double  phi;

   char  filename[128];
   char  line[128];
   FILE  *objfile;

   nvert = 0;
   nface = 0;
   pi = 4.0 * atan(1.0e0);

   if ( narg == 6 )
   {
      strcpy( filename, arg[1] );
      strcat( filename, ".obj" );
      narg = sscanf( arg[2], "%e", &l );
      narg = sscanf( arg[3], "%e", &r );
      narg = sscanf( arg[4], "%d", &nl );
      narg = sscanf( arg[5], "%d", &nr );

      printf( " * Filename = %s\n", filename );
      printf( " * Length   = %e\n", l );
      printf( " * Radius   = %e\n", r );
      printf( " * Longitudinal Discretisation = %d\n", nl );
      printf( " * Azimuthal Discretisation    = %d\n", nr );
   }
   else
   {
      printf( "** ERROR: Wrong Number of Arguments narg = %d\n", narg-1 );
      return 1;
   }

   objfile = fopen( filename, "wt" );

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

   fprintf( objfile, "#\n" );
   fprintf( objfile, "# Cylinder in Wavefront format\n" );
   fprintf( objfile, "# Length = %e\n", l );
   fprintf( objfile, "# Radius = %e\n", r );
   fprintf( objfile, "# Longitudinal Discretisation = %d\n", nl );
   fprintf( objfile, "# Azimuthal Discretisation    = %d\n", nr );
   fprintf( objfile, "#\n" );

   dl = l / nl;
   dphi = 2.0*pi / nr;

   fprintf( objfile, "\n" );
   fprintf( objfile, "# Vertex List\n" );

   for ( il=0 ; il<=nl ; il++ )
   {
      z = il * dl - 0.5 * l;

      for ( ir=0; ir<nr ; ir++ )
      {
         phi = ir * dphi;

         x = r * cos(phi);
         y = r * sin(phi);

         fprintf( objfile, "v %13e %13e %13e\n", x, y, z );
         nvert++;
      }
   }

   x = 0.0;
   y = 0.0;
   z = -0.5 * l;
   fprintf( objfile, "v %13e %13e %13e\n", x, y, z );
   nvert++;

   z = 0.5 * l;
   fprintf( objfile, "v %13e %13e %13e\n", x, y, z );
   nvert++;

   fprintf( objfile, "\n" );
   fprintf( objfile, "# Face List\n" );

   ivert = 0;
   for ( il=0 ; il<nl ; il++ )
   {
      for ( ir=0; ir<nr ; ir++ )
      {
         ivert++;

         f1 = ivert;
         f3 = ivert + nr;
         if ( ir == nr-1 )
            f2 = ivert + 1 - nr;
         else
            f2 = ivert + 1;

         fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
         nface++;

         f1 = f3;
         if ( ir == nr-1 )
            f3 = ivert + 1;
         else
            f3 = ivert + nr + 1;

         fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
         nface++;

      }
   }

   ivert = 0;
   f1 = nvert - 1;
   for ( ir=0; ir<nr-1; ir++ )
   {
      ivert++;

      f2 = ivert + 1;
      f3 = ivert;

      fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
      nface++;
   }
   ivert++;
   f2 = 1;
   f3 = ivert;
   fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
   nface++;

   ivert = nvert - nr - 2;
   f1 = nvert;
   for ( ir=0; ir<nr-1; ir++ )
   {
      ivert++;

      f2 = ivert;
      f3 = ivert + 1;

      fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
      nface++;
   }
   ivert++;
   f2 = ivert;
   f3 = nvert - nr - 1;
   fprintf( objfile, "f %d %d %d\n", f1, f2, f3 );
   nface++;


   fprintf( objfile, "\n" );
   fprintf( objfile, "# Number of Vertices: %d\n", nvert );
   fprintf( objfile, "# Number of Faces:    %d\n", nface );
   fprintf( objfile, "\n" );
   fprintf( objfile, "# End of File\n" );

   printf( "done\n" );
   printf( " * Number of Vertices: %d\n", nvert );
   printf( " * Number of Faces:    %d\n", nface );

   fclose( objfile );

   return 0;

}
