/*                                        */
/* torus.c by Gerhard.Hippmann@dlr.de     */
/* torus.b <filename> <r1> <r2> <n1> <n2> */
/* Generates a polygonal surface file     */
/* <filename>.obj                         */
/* representing a torus                   */
/* of radii r1, r2                        */
/* and discretisation n1, n2              */
/*                                        */
/* gcc -lm -o torus.b torus.c             */
/*                                        */


#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  n1;
   int  n2;
   int  i1;
   int  i2;
   int  nvert;
   int  nface;
   int  f1, f2, f3;

   float  r1;
   float  r2;
   float  x1, y1, z1;
   float  x2, y2, z2;

   double  pi;
   double  dphi1, dphi2;
   double  phi1, phi2;
   double  s1, c1;
   double  s2, c2;

   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", &r1 );
      narg = sscanf( arg[3], "%e", &r2 );
      narg = sscanf( arg[4], "%d", &n1 );
      narg = sscanf( arg[5], "%d", &n2 );

      printf( " * Filename = %s\n", filename );
      printf( " * Centre Line Radius = %e\n", r1 );
      printf( " * Tube Radius        = %e\n", r2 );
      printf( " * Centre Line Discretisation = %d\n", n1 );
      printf( " * Tube Discretisation        = %d\n", n2 );
   }
   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, "# Torus in Wavefront format\n" );
   fprintf( objfile, "# Centre Line Radius = %e\n", r1 );
   fprintf( objfile, "# Tube Radius        = %e\n", r2 );
   fprintf( objfile, "# Centre Line Discretisation = %d\n", n1 );
   fprintf( objfile, "# Tube Discretisation        = %d\n", n2 );
   fprintf( objfile, "#\n" );

   dphi1 = 2.0*pi / n1;
   dphi2 = 2.0*pi / n2;

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

   for ( i1=0 ; i1<n1 ; i1++ )
   {
      phi1 = i1 * dphi1;

      c1 = cos( phi1 );
      s1 = sin( phi1 );

      x1 = r1 * c1;
      y1 = r1 * s1;
      z1 = 0.0;

      for ( i2=0; i2<n2 ; i2++ )
      {
         phi2 = i2 * dphi2;

         c2 = cos( phi2 );
         s2 = sin( phi2 );

         x2 = r2 * c2;
         y2 = 0.0;
         z2 = r2 * s2;

         y2 = x2 * s1;
         x2 = x2 * c1;

         fprintf( objfile, "v %13e %13e %13e\n", x1+x2, y1+y2, z1+z2 );
      }
   }

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

   for ( i1=0 ; i1<n1 ; i1++ )
   {
      for ( i2=0; i2<n2 ; i2++ )
      {
         nvert++;

         nface ++;

         f1 = nvert;
         if ( i1 == n1-1 )
            f2 = i2 + 1;
         else
            f2 = nvert + n2;
         if ( i2 == n2-1 )
            f3 = nvert + 1 - n2;
         else
            f3 = nvert + 1;

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

         nface ++;

         f1 = f2;
         if ( i1 == n1-1 && i2 == n2-1 )
            f2 = 1;
         else if ( i1 == n1-1 )
            f2 = i2 + 2;
         else if ( i2 == n2-1 )
            f2 = nvert + 1;
         else
            f2 = nvert + n2 + 1;

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

      }
   }

   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;

}
