/*****************************************************/
/* ShellyV1.2: The ShellShapeGenerator by:           */
/*         RANDi                                     */
/*              (rschultz@informatik.uni-rostock.de) */
/*****************************************************/

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

#include "shelly.h"

int countw=0, counth=0, countp=0;
double camx=0,camy=500,camz=500;


/********************************************/
/*cot:                                      */
/********************************************/
double cot(double in)
{
 if (sin(in) == 0) 
  return(0);
 else 
  return(cos(in)/sin(in));
}


/********************************************/
/*round:                                    */
/********************************************/
double round(double in)
{
 if((floor(in)-in) < 0)
  return(floor(in));
 else
  return(floor(in)+1);
}


/********************************************/
/*myfree:                                   */
/********************************************/
int myfree(struct punkt *anker1)
{
 struct punkt *hp, *hpnew;
 if (anker1 == NULL)
  return(0);

 hp = anker1;
 hpnew = hp;
 do
 {
  hp = hpnew;
  hpnew = (*hp).next;

  cfree(hp);
 }
 while(hpnew);

return(0);
}


/********************************************/
/*mycopystr:                                */
/********************************************/
char *mycopystr(char *source,char *destination,char endchar)
{
 int ende = 1;
 char *merk;

 merk = destination;        /* merk points now on destination */
 while (ende)
 {
  if ((*source == '\0') || (*source == endchar)) 
  {
  ende = 0;
  }
  else
  {
   *destination = *source; 
   destination++;
   source++;
  } /* if */
 } /* while */
 *destination = '\0';
return(merk);
}


/********************************************/
/*ReadInfile:                               */
/********************************************/

void ReadInfile(struct ShellyArguments *ShellyArgs,char *fin)
{
 char readline[laenge], hilf[laenge], *hp;
 FILE *fp;

 (*ShellyArgs).output = POV;

 fp = fopen(fin,"r");
 if (fp != NULL) 
 {
  fprintf(stderr,"Parsing:");
  while (fgets(readline,laenge,fp))
  {
   fprintf(stderr,".");

   hp = strstr(readline,"alpha:");
   if (hp != NULL)
   {
    mycopystr(hp+6,hilf,'\0');
    (*ShellyArgs).alpha = atof(hilf);
   } /* if */

   hp = strstr(readline,"beta:");
   if (hp != NULL)
   {
    mycopystr(hp+5,hilf,'\0');
    (*ShellyArgs).beta = atof(hilf);
   } /* if */
   hp = strstr(readline,"phi:");
   if (hp != NULL)
   {
    mycopystr(hp+4,hilf,'\0');
    (*ShellyArgs).phi = atof(hilf);
   } /* if */

   hp = strstr(readline,"my:");
   if (hp != NULL)
   {
    mycopystr(hp+3,hilf,'\0');
    (*ShellyArgs).my = atof(hilf);
   } /* if */

   hp = strstr(readline,"omega:");
   if (hp != NULL)
   {
    mycopystr(hp+6,hilf,'\0');
    (*ShellyArgs).omega = atof(hilf);
   } /* if */

   hp = strstr(readline,"smin:");
   if (hp != NULL)
   {
    mycopystr(hp+5,hilf,'\0');
    (*ShellyArgs).smin = atof(hilf);
   } /* if */
  
   hp = strstr(readline,"smax:");
   if (hp != NULL)
   {
    mycopystr(hp+5,hilf,'\0');
    (*ShellyArgs).smax = atof(hilf);
   } /* if */

   hp = strstr(readline,"sd:");
   if (hp != NULL)
   {
    mycopystr(hp+3,hilf,'\0');
    (*ShellyArgs).sd = atof(hilf);
   } /* if */

   hp = strstr(readline,"A:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).A = atof(hilf);
   } /* if */

   hp = strstr(readline,"a:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).a = atof(hilf);
   } /* if */


   hp = strstr(readline,"b:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).b = atof(hilf);
   } /* if */

   hp = strstr(readline,"P:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).P = atof(hilf);
   } /* if */

   hp = strstr(readline,"W1:");
   if (hp != NULL)
   {
    mycopystr(hp+3,hilf,'\0');
    (*ShellyArgs).W1 = atof(hilf);
   } /* if */

   hp = strstr(readline,"W2:");
   if (hp != NULL)
   {
    mycopystr(hp+3,hilf,'\0');
    (*ShellyArgs).W2 = atof(hilf);
   } /* if */

   hp = strstr(readline,"N:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).N = atof(hilf);
   } /* if */

   hp = strstr(readline,"L:");
   if (hp != NULL)
   {
    mycopystr(hp+2,hilf,'\0');
    (*ShellyArgs).L = atof(hilf);
   } /* if */

   hp = strstr(readline,"omin:");
   if (hp != NULL)
   {
    mycopystr(hp+5,hilf,'\0');
    (*ShellyArgs).omin = atof(hilf);
   } /* if */

   hp = strstr(readline,"omax:");
   if (hp != NULL)
   {
    mycopystr(hp+5,hilf,'\0');
    (*ShellyArgs).omax = atof(hilf);
   } /* if */

   hp = strstr(readline,"od:");
   if (hp != NULL)
   {
    mycopystr(hp+3,hilf,'\0');
    (*ShellyArgs).od = atof(hilf);
   } /* if */

   hp = strstr(readline,"POV");
   if (hp != NULL)
   {
    (*ShellyArgs).output = POV;
   } /* if */

   hp = strstr(readline,"RPL");
   if (hp != NULL)
   {
    (*ShellyArgs).output = RPL;
   } /* if */

   hp = strstr(readline,"T3D");
   if (hp != NULL)
   {
    (*ShellyArgs).output = T3D;
   } /* if */
   
  } /* while */

  fprintf(stderr,"\n");
  if (fclose(fp) != 0) 
  fprintf(stderr,"Error while closing file: %s!\n",fin);
 }
 else
 {
  fprintf(stderr,"Could not open datafile: %s!\n",fin);
  exit(5);
 }
} /* ReadInfile */


/********************************************/
/* writepovheader: reads in camera/light's  */
/*                                          */
/********************************************/

void writepovheader(FILE *fp)
{

 fprintf(fp,"/* POV-Scenefile generated by Shelly1.2           */\n");
 fprintf(fp,"/* by RANDi: (rschultz@informatik.uni-rostock.de) */\n");

 fprintf(fp,"#declare te = pigment { color red 1 green 0 blue 0 }\n");

 fprintf(fp,"camera\n{\n location  <%.1f,%.1f,%.1f>\n",camx,camy,camz);
 fprintf(fp," look_at <0, 0, 0>\n}\n");
 
 fprintf(fp,"object\n{\n light_source {\n");
 fprintf(fp,"  <250, 500, 500> color red 1 green 1 blue 1\n }\n");
 fprintf(fp,"}\n");
 fprintf(fp,"object\n{\n light_source {\n");
 fprintf(fp,"  <-250, 500, 500> color red 1 green 1 blue 1\n }\n");
 fprintf(fp,"}\n");

} /* writepovheader */


/********************************************/
/* writepovtriangles:                       */
/********************************************/
int writepovtriangles(FILE *fp,struct punkt *anker1,struct punkt *anker2)
{
 struct punkt *p11, *p12, *p21, *p22;

 if ((anker1 == NULL) || (anker2 == NULL))
  return(0);

 p11 = anker1;
 p21 = anker2;
 p12 = p11;
 p22 = p21;

 do
 {
  p11 = p12;
  p21 = p22;
  p12 = (*p11).next;
  p22 = (*p21).next;

  if ((p12 != NULL) && (p22 != NULL))
  {
   fprintf(fp,"triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n",(*p11).x,(*p11).y,(*p11).z,(*p12).x,(*p12).y,(*p12).z,(*p21).x,(*p21).y,(*p21).z);
   fprintf(fp,"pigment{te}}\n");

   fprintf(fp,"triangle{<%.2f,%.2f,%.2f><%.2f,%.2f,%.2f><%.2f,%.2f,%.2f>\n",(*p21).x,(*p21).y,(*p21).z,(*p12).x,(*p12).y,(*p12).z,(*p22).x,(*p22).y,(*p22).z);
   fprintf(fp,"pigment{te}}\n");
  }
 }
 while((p12 != NULL) && (p22 != NULL));

 return(0);
} /* writepovtriangles */


/********************************************/
/* writerplline:                            */
/********************************************/
int writerplline(FILE *fp,struct punkt *anker1)
{
 struct punkt *p11, *p12;

 if (anker1 == NULL)
  return(0);

 p11 = anker1;
 p12 = p11;

 countw++;                                /* calc number of lines created */

 fprintf(fp,"%.3f  %.3f  %.3f\n",(*p11).x/100.0,(*p11).y/100.0,(*p11).z/100.0);

 do
 {
  p11 = p12;
  p12 = (*p11).next;

  if (p12 != NULL)
  {
   fprintf(fp,"%.3f  %.3f  %.3f\n",(*p12).x/100.0,(*p12).y/100.0,(*p12).z/100.0);   
  }
 }
 while(p12 != NULL);

 return(0);
} /* writerplline */


/********************************************/
/* writerplfinish:                          */
/*                                          */
/********************************************/

void writerplfinish(FILE *fp)
{
  fprintf(fp,"%d\n",counth);           /* height width of the mesh */
  fprintf(fp,"%d\n",countw);
  
  fprintf(fp,"3\n0\n255 255 255 0\n"); /* RGBA */
  fprintf(fp,"\"Shell\"\n0\n");        /* Name */
  fprintf(fp,"\"CEND\"\n");
  fprintf(fp,"C_MESH DROP\n");

} /* writerplfinish */


/********************************************/
/* writet3dheader:                          */
/*                                          */
/********************************************/

void writet3dheader(FILE *fp)
{
 char percent = '%';

 fprintf(fp," %c T3Dlib-data-file generated by Shelly1.2\n",percent);
 fprintf(fp," %c the ShellShapeGenerator by RANDi :    \n",percent);
 fprintf(fp," %c (rschultz@informatik.uni-rostock.de)\n",percent);

 fprintf(fp,"OBJ Begin \"Hierarchy 1\"\n");
 fprintf(fp," DESC Begin \"Object 1 at level 1 of hierarchy 1\"\n");
 fprintf(fp,"  NAME \"SHELL\"\n");
 fprintf(fp,"  SHAP Shape = 2\n");
 fprintf(fp,"  SHAP Lamp  = 0\n");
 fprintf(fp,"  POSI X=0 Y=0 Z=0\n");
 fprintf(fp,"  AXIS XAxis X=1 Y=0 Z=0\n");
 fprintf(fp,"  AXIS YAxis X=0 Y=1 Z=0\n");
 fprintf(fp,"  AXIS ZAxis X=0 Y=0 Z=1\n");
 fprintf(fp,"  SIZE X=32 Y=32 Z=32\n");

} /* writet3dheader */


/********************************************/
/* writet3dline:                            */
/********************************************/
int writet3dline(FILE *fp,struct punkt *anker1)
{
 struct punkt *p11, *p12;

 static int called = 0, count = 0;
 if (anker1 == NULL)
  return(0);

 if(called == 0)
 {
  fprintf(fp,"  PNTS PCount %d\n",countp);
  called = 1;
  count =-1;
  countw = 0;
 }

 countw++;
 
 p11 = anker1;
 p12 = p11;
  
 fprintf(fp,"  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n",++count,(*p11).x,(*p11).y,(*p11).z);

 do
 {
  p11 = p12;
  p12 = (*p11).next;

  if (p12 != NULL)
  {
   fprintf(fp,"  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n",++count,(*p12).x,(*p12).y,(*p12).z);
  }
 }
 while(p12 != NULL);

 return(0);
} /* writet3dline */


/********************************************/
/* writet3dfinish:                          */
/*                                          */
/********************************************/

void writet3dfinish(FILE *fp)
{
 int edges=0, faces=0, edgecount=0, facecount=0, a=0, b=0, r=0, r2=0, r3=0;
 int point1=0, point2=0, edge1=0, edge2=0, edge3=0;
 
 fprintf(stderr,"Writing additional T3Dlib-Data ...\n");
 
 edges = (counth*(countw-1)+countw*(counth-1)+(counth-1)*(countw-1));
                                           /* number of edges! */ 
 fprintf(fp,"  EDGE ECount %d\n",edges);


                              /* write horizontal edges */
 for (a=0; a<counth;a++)
 {
  r = a;
  for (b=0;b<(countw-1);b++)
  {
   point1=r; 
   point2=r+counth;
   fprintf(fp,"  EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
   r=r+counth;
  }  
 }
                              /* write vertical edges */
 for (a=0; a<countw;a++)
 {
  r = a*counth;
  for(b=0; b<(counth-1);b++)
  {
   point1=r+b; 
   point2=r+b+1;
   fprintf(fp,"  EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
  }
 }
                                /* write diagonal edges */
 for (a=0; a<counth-1;a++)
 {
  r = a;
  for (b=0;b<(countw-1);b++)
  {
   point1=r; 
   point2=r+counth+1;
   fprintf(fp,"  EDGE Edge[%d] %d %d\n",edgecount++,point1,point2);
   r=r+counth;
  }  
 }
     /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */

                                         /* write faces */

 faces = 2*(countw-1)*(counth-1); 
 
 fprintf(fp,"  FACE TCount %d\n",faces);

 r = 0;
 r3 = countw*(counth-1)+counth*(countw-1);

 for(a=0; a<counth-1; a++)
 {
  r2=counth*(countw-1)+a;
  for(b=0; b<countw-1; b++)
  {
   edge1 = r+countw-1;
   edge2 = r2;
   edge3 = r3;
   fprintf(fp,"  FACE Connect[%d] %d %d %d\n",facecount++,edge1,edge2,edge3);

   edge1 = r;
   edge2 = r2+counth-1;
   edge3 = r3;
   fprintf(fp,"  FACE Connect[%d] %d %d %d\n",facecount++,edge1,edge2,edge3);

   r++;
   r2=r2+counth-1;
   r3++;
  }
 } 

 fprintf(fp,"  COLR R=98 G=68 B=58\n");
 fprintf(fp,"  REFL R=0 G=0 B=0\n");
 fprintf(fp,"  TRAN R=0 G=0 B=0\n");
 fprintf(fp,"  SPC1 R=0 G=0 B=0\n");
 fprintf(fp,"  End DESC   \"Object 1 at level 1 of hierarchy 1\"\n");
 fprintf(fp," TOBJ       \"Object 0 at level 1 of hierarchy 1\"\n");
 fprintf(fp,"End OBJ  \"Hierarchy 1\"\n");



} /* writet3dfinish */


/**********************************************/
/* CalcCameraposition:                        */
/*                                            */
/**********************************************/

void CalcCameraposition(struct ShellyArguments *ShellyArgs)

{
 double x,y,z,R,S,O;
 double my, Re, P, W1, W2, N, L, g, k;
 double smin, smax, sd, a, b, A, beta, phi, omega, alpha, omin, omax, od;   
 double max = 0.0;

 smin = (*ShellyArgs).smin*pi/180;
 smax = (*ShellyArgs).smax*pi/180;
 omin = (*ShellyArgs).omin*pi/180;
 omax = (*ShellyArgs).omax*pi/180;
 sd = (*ShellyArgs).sd*pi/180;
 od = (*ShellyArgs).od*pi/180;

 alpha = (*ShellyArgs).alpha*pi/180;
 beta = (*ShellyArgs).beta*pi/180;
 phi = (*ShellyArgs).phi*pi/180;
 omega = (*ShellyArgs).omega*pi/180;
 my = (*ShellyArgs).my*pi/180;

 a = (*ShellyArgs).a;
 b = (*ShellyArgs).b;
 A = (*ShellyArgs).A;

 N = (*ShellyArgs).N;
 W1 = (*ShellyArgs).W1*pi/180;
 W2 = (*ShellyArgs).W2*pi/180;
 P = (*ShellyArgs).P*pi/180;
 L = (*ShellyArgs).L;


  fprintf(stderr,"Calculating Cameraposition ...");
  fflush(stderr);

  for(O = omin; (O+od)<omax; O=O+od)
  {
   for(S = smin; (S+sd)<smax; S=S+sd)
   {

    if (N == 0) 
     g = 0;
    else
     g  = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi)));

    Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5); 
    if (N == 0)
     k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
    else
     k  = L*exp(-1*(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-1*(2*g/W2)*(2*g/W2));


    R = Re + k;
    
    x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));   
    y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
    z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));

    countp++;

    if (fabs(y)>fabs(z))
    {
     if (fabs(x)>fabs(y))
     {
      if(max<fabs(x)) 
       max = fabs(x);
     }  
     else
     {
      if(max<fabs(y))
       max = fabs(y);
     }
    }  
    else
     if (fabs(x)>fabs(z))
     {
      if(max<fabs(x)) 
       max = fabs(x);
     }  
     else
     {
      if(max<fabs(z))
       max = fabs(z);
     }
      
   } /* for */
  } /* for */


  camy = 1.5*max;
  camz = camy;

  fprintf(stderr,"\n");      /* rrrrready :) */

} /* CalcCameraposition */


/**********************************************/
/* RenderShell:                               */
/*             SSIA :)                        */
/**********************************************/

void RenderShell(struct ShellyArguments *ShellyArgs,char *fout)

{
 struct punkt *List1anker, *List2anker, *L1p1, *L2p1, *L1p2, *L2p2;

 double x,y,z,R,S,O;
 double my, Re, P, W1, W2, N, L, g, k;
 double smin, smax, sd, a, b, A, beta, phi, omega, alpha, omin, omax, od;   
 FILE *fp;

 smin = (*ShellyArgs).smin*pi/180;
 smax = (*ShellyArgs).smax*pi/180;
 omin = (*ShellyArgs).omin*pi/180;
 omax = (*ShellyArgs).omax*pi/180;
 sd = (*ShellyArgs).sd*pi/180;
 od = (*ShellyArgs).od*pi/180;

 alpha = (*ShellyArgs).alpha*pi/180;
 beta = (*ShellyArgs).beta*pi/180;
 phi = (*ShellyArgs).phi*pi/180;
 omega = (*ShellyArgs).omega*pi/180;
 my = (*ShellyArgs).my*pi/180;

 a = (*ShellyArgs).a;
 b = (*ShellyArgs).b;
 A = (*ShellyArgs).A;

 N = (*ShellyArgs).N;
 W1 = (*ShellyArgs).W1*pi/180;
 W2 = (*ShellyArgs).W2*pi/180;
 P = (*ShellyArgs).P*pi/180;
 L = (*ShellyArgs).L;


 if ((*ShellyArgs).output != RPL)
  CalcCameraposition(ShellyArgs);

 fp = fopen(fout,"w");
 if (fp != NULL) 
 {
  if ((*ShellyArgs).output == POV)
   writepovheader(fp);
  if ((*ShellyArgs).output == T3D)
   writet3dheader(fp);
   
  fprintf(stderr,"Calculating the Shell ...\n");

  for(S = smin;(S+sd)<smax;S=S+sd)
  {
   if (N == 0) 
    g = 0;
   else
    g  = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi))); 

   Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5); 

   if (N == 0)
    k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
   else
    k  = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-(2*g/W2)*(2*g/W2));

   R = Re + k;

  /* alternatively: */
  /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */

   x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));   
   y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
   z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));

   if ((L1p1 = calloc(1,sizeof(struct punkt))) == NULL)
   {
    fprintf(stderr,"Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
    fclose(fp);
    myfree(List2anker);
    myfree(List1anker);
    exit(5);
   } /* if */

   if (S == smin) 
    List1anker = L1p1;
   else
    (*L1p2).next = L1p1;
   L1p2 = L1p1;

   (*L1p1).x = x;
   (*L1p1).y = y;
   (*L1p1).z = z;

  } /* for */

  if ((*ShellyArgs).output == RPL)
   writerplline(fp,List1anker);
  if ((*ShellyArgs).output == T3D)
   writet3dline(fp,List1anker);
 
  for(O = omin+od;(O+od)<omax;O=O+od)
  {

   counth = 0;

   for(S = smin;(S+sd)<smax;S=S+sd)
   {

    counth++;                           /* calc number of points per line */
  
    if (N == 0) 
     g = 0;
    else
     g  = (2*pi)/N*(O*N/(2*pi)-round(O*N/(2*pi)));

    Re = pow((pow(a,-2.0)*(cos(S)*cos(S))+pow(b,-2.0)*(sin(S)*sin(S))),-0.5); 
    if (N == 0)
     k = L*exp(-(2*(S-P)/W1)*(2*(S-P)/W1));
    else
     k  = L*exp(-1*(2*(S-P)/W1)*(2*(S-P)/W1))*exp(-1*(2*g/W2)*(2*g/W2));


    R = Re + k;

    /* alternatively: */
    /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */

    x = (A*sin(beta)*cos(O)+R*cos(S+phi)*cos(O+omega)-R*sin(my)*sin(S+phi)*sin(O))*exp(O*cot(alpha));   
    y = (-1*A*sin(beta)*sin(O)-R*cos(S+phi)*sin(O+omega)-R*sin(my)*sin(S+phi)*cos(O))*exp(O*cot(alpha));
    z = (-1*A*cos(beta)+R*sin(S+phi)*cos(my))*exp(O*cot(alpha));

    if ((L2p1 = calloc(1,sizeof(struct punkt))) == NULL)
    {
     fprintf(stderr,"Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
     fclose(fp);
     myfree(List1anker);
     myfree(List1anker);
     exit(5);
    } /* if */

    if (S == smin)
     List2anker = L2p1;
    else
     (*L2p2).next = L2p1;
    L2p2 = L2p1;

    (*L2p1).x = x;
    (*L2p1).y = y;
    (*L2p1).z = z;


   } /* for */

   if ((*ShellyArgs).output == POV)
    writepovtriangles(fp,List1anker,List2anker);    
   if ((*ShellyArgs).output == T3D)
    writet3dline(fp,List2anker);
   if ((*ShellyArgs).output == RPL)
    writerplline(fp,List2anker);

   myfree(List1anker);
   List1anker = List2anker;


  } /* for */

  if ((*ShellyArgs).output == RPL)
   writerplfinish(fp);
  if ((*ShellyArgs).output == T3D)
   writet3dfinish(fp);
   
  

  fprintf(stderr,"Ready!\n");

  myfree(List1anker);

  if (fclose(fp) != 0) 
  fprintf(stderr,"Error while closing file: %s!\n",fout);
 }
 else
fprintf(stderr,"Could not open outfile: %s!\n",fout);

} /* RenderShell */




/********************************************/
/*main:                                     */
/********************************************/
int main(int ac,char **av)

{
 
 struct ShellyArguments ShellyArgs;

 fprintf(stderr,"ShellyV1.2, the ShellShapeGenerator by RANDi\n");
 
 if (ac < 3)
 {
  fprintf(stderr,"wrong arguments!\nUSAGE:\n\n");
  fprintf(stderr,"   'shelly infilename outfilename'\n\n");
  exit(0);
 } /* if */

 ReadInfile(&ShellyArgs,av[1]); 

 RenderShell(&ShellyArgs,av[2]); 

 exit(0);
}
