home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / q_t / shelly / src / shelly.c next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  69.5 KB  |  2,914 lines

  1. /*****************************************************/
  2. /* ShellyV1.6: The ShellShapeGenerator by:           */
  3. /*         RANDi                                     */
  4. /*              (rschultz@informatik.uni-rostock.de) */
  5. /* 21.11.1994                                        */
  6. /*****************************************************/
  7.  
  8. #include <math.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <memory.h>
  13.  
  14. #include "shelly.h"
  15.  
  16.  
  17. struct glob
  18.   {
  19.     int countw, counth, countp, countl, countt;
  20.     int calledwrtx3dl, count;
  21.     int calledwrtt3dl;
  22.     int calledwrtrpll;
  23.     double N, N2, N3, L, L2, L3, W1, W2, W12, W22, W13, W23, P, P2, P3,
  24.       Off2, Off3;
  25.     double biggest;
  26.     double my, a, b, A, beta, phi, omega, alpha, Scale;
  27.     double Scans, Scano;
  28.     double smin, smax, sd;
  29.     double omin, omax, od;
  30.     struct patch *patchanchor;
  31.     double rnod;
  32.   }
  33. gl;
  34.  
  35. double camx = 0, camy = 500, camz = 500;
  36. int camposspecified = NO;
  37. struct lmerk *bigllist;
  38. struct tmerk *bigtlist;
  39.  
  40. /********************************************/
  41. /*cot:                                      */
  42. /********************************************/
  43. double
  44. cot (double in)
  45. {
  46.   if (sin (in) == 0)
  47.     return (0);
  48.   else
  49.     return (cos (in) / sin (in));
  50. }
  51.  
  52.  
  53. /********************************************/
  54. /*round:                                    */
  55. /********************************************/
  56. double
  57. round (double in)
  58. {
  59.   if (in - floor (in) < 0.5)
  60.     return (floor (in));
  61.   else
  62.     return (floor (in) + 1);
  63. }
  64.  
  65.  
  66. /********************************************/
  67. /*myfree:                                   */
  68. /********************************************/
  69. int
  70. myfree (struct punkt *anker1)
  71. {
  72.   struct punkt *hp, *hpnew;
  73.   if (anker1 == NULL)
  74.     return (0);
  75.  
  76.   hp = anker1;
  77.   hpnew = hp;
  78.   do
  79.     {
  80.       hp = hpnew;
  81.       hpnew = (*hp).next;
  82.  
  83.       free (hp);
  84.     }
  85.   while (hpnew != NULL);
  86.  
  87.   return (0);
  88. }
  89.  
  90.  
  91. /********************************************/
  92. /*mycopystr:                                */
  93. /********************************************/
  94. char *
  95. mycopystr (char *source, char *destination, char endchar)
  96. {
  97.   int ende = 1;
  98.   char *merk;
  99.  
  100.   merk = destination;        /* merk points now on destination */
  101.   if (source != NULL)
  102.     while ((*source != '\0') && (*source != endchar))
  103.       {
  104.     *destination = *source;
  105.     destination++;
  106.     source++;
  107.       }                /* while */
  108.   *destination = '\0';
  109.   return (merk);
  110. }
  111.  
  112.  
  113. /********************************************/
  114. /*filecopy:                                 */
  115. /********************************************/
  116. void
  117. filecopy (FILE * source, FILE * dest)
  118. {
  119.   int a, b;
  120.  
  121.   fseek (source, 0, 0);
  122.   do
  123.     {
  124.       a = fgetc (source);
  125.       if (a != EOF)
  126.     {
  127.       b = fputc (a, dest);
  128.       if (b == EOF)
  129.         {
  130.           fclose (source);
  131.           fclose (dest);
  132.           exit (5);
  133.         };            /* if */
  134.     };            /* if */
  135.     }
  136.   while (a != EOF);
  137. }
  138.  
  139.  
  140. /********************************************/
  141. /*crosspro:                                 */
  142. /********************************************/
  143. void
  144. crosspro (double a[3],double b[3],double *(c[3]))
  145. {
  146.  *(c[0]) = (a[1]*b[2] - a[2]*b[1]); 
  147.  *(c[1]) = (a[2]*b[0] - a[0]*b[2]); 
  148.  *(c[2]) = (a[0]*b[1] - a[1]*b[0]); 
  149. } /* crosspro */ 
  150.  
  151. /********************************************/
  152. /*ReadInfile:                               */
  153. /********************************************/
  154. void
  155. ReadInfile (struct ShellyArguments *ShellyArgs, char *fin)
  156. {
  157.   char readline[laenge], hilf[laenge], *hp;
  158.   FILE *fp;
  159.  
  160.   /* set some defaults */
  161.  
  162.   (*ShellyArgs).output = POV;
  163.   (*ShellyArgs).mode = NORMAL;
  164.   (*ShellyArgs).Scano = 0.05;
  165.   (*ShellyArgs).Scans = 0.05;
  166.   (*ShellyArgs).heightdiffo = 0.1;
  167.   (*ShellyArgs).heightdiffs = 0.1;
  168.  
  169.   (*ShellyArgs).Scale = 1.0;
  170.   (*ShellyArgs).Render = NO;
  171.   (*ShellyArgs).N2 = 0;
  172.   (*ShellyArgs).N3 = 0;
  173.   (*ShellyArgs).N = 0;
  174.   (*ShellyArgs).anim = NO;
  175.   (*ShellyArgs).steps = 10;
  176.  
  177.   mycopystr ("-f +d +w200 +h160", (*ShellyArgs).povargs, '\0');
  178.  
  179.  
  180.   fp = fopen (fin, "r");
  181.   if (fp != NULL)
  182.     {
  183.       fprintf (stdout, "Parsing:");
  184.       while (fgets (readline, laenge, fp) != NULL)
  185.     {
  186.       fprintf (stdout, ".");
  187.  
  188.       hp = strstr (readline, "alpha:");
  189.       if (hp != NULL)
  190.         {
  191.           mycopystr (hp + 6, hilf, '\0');
  192.           (*ShellyArgs).alpha = atof (hilf);
  193.         }            /* if */
  194.       hp = strstr (readline, "beta:");
  195.       if (hp != NULL)
  196.         {
  197.           mycopystr (hp + 5, hilf, '\0');
  198.           (*ShellyArgs).beta = atof (hilf);
  199.         }            /* if */
  200.       hp = strstr (readline, "phi:");
  201.       if (hp != NULL)
  202.         {
  203.           mycopystr (hp + 4, hilf, '\0');
  204.           (*ShellyArgs).phi = atof (hilf);
  205.         }            /* if */
  206.       hp = strstr (readline, "my:");
  207.       if (hp != NULL)
  208.         {
  209.           mycopystr (hp + 3, hilf, '\0');
  210.           (*ShellyArgs).my = atof (hilf);
  211.         }            /* if */
  212.       hp = strstr (readline, "omega:");
  213.       if (hp != NULL)
  214.         {
  215.           mycopystr (hp + 6, hilf, '\0');
  216.           (*ShellyArgs).omega = atof (hilf);
  217.         }            /* if */
  218.       hp = strstr (readline, "smin:");
  219.       if (hp != NULL)
  220.         {
  221.           mycopystr (hp + 5, hilf, '\0');
  222.           (*ShellyArgs).smin = atof (hilf);
  223.         }            /* if */
  224.       hp = strstr (readline, "smax:");
  225.       if (hp != NULL)
  226.         {
  227.           mycopystr (hp + 5, hilf, '\0');
  228.           (*ShellyArgs).smax = atof (hilf);
  229.         }            /* if */
  230.       hp = strstr (readline, "sd:");
  231.       if (hp != NULL)
  232.         {
  233.           mycopystr (hp + 3, hilf, '\0');
  234.           (*ShellyArgs).sd = atof (hilf);
  235.         }            /* if */
  236.       hp = strstr (readline, "A:");
  237.       if (hp != NULL)
  238.         {
  239.           mycopystr (hp + 2, hilf, '\0');
  240.           (*ShellyArgs).A = atof (hilf);
  241.         }            /* if */
  242.       hp = strstr (readline, "a:");
  243.       if (hp != NULL)
  244.         {
  245.           mycopystr (hp + 2, hilf, '\0');
  246.           (*ShellyArgs).a = atof (hilf);
  247.         }            /* if */
  248.       hp = strstr (readline, "b:");
  249.       if (hp != NULL)
  250.         {
  251.           mycopystr (hp + 2, hilf, '\0');
  252.           (*ShellyArgs).b = atof (hilf);
  253.         }            /* if */
  254.       hp = strstr (readline, "P:");
  255.       if (hp != NULL)
  256.         {
  257.           mycopystr (hp + 2, hilf, '\0');
  258.           (*ShellyArgs).P = atof (hilf);
  259.         }            /* if */
  260.       hp = strstr (readline, "W1:");
  261.       if (hp != NULL)
  262.         {
  263.           mycopystr (hp + 3, hilf, '\0');
  264.           (*ShellyArgs).W1 = atof (hilf);
  265.         }            /* if */
  266.       hp = strstr (readline, "W2:");
  267.       if (hp != NULL)
  268.         {
  269.           mycopystr (hp + 3, hilf, '\0');
  270.           (*ShellyArgs).W2 = atof (hilf);
  271.         }            /* if */
  272.       hp = strstr (readline, "N:");
  273.       if (hp != NULL)
  274.         {
  275.           mycopystr (hp + 2, hilf, '\0');
  276.           (*ShellyArgs).N = atof (hilf);
  277.         }            /* if */
  278.       hp = strstr (readline, "L:");
  279.       if (hp != NULL)
  280.         {
  281.           mycopystr (hp + 2, hilf, '\0');
  282.           (*ShellyArgs).L = atof (hilf);
  283.         }            /* if */
  284.       hp = strstr (readline, "omin:");
  285.       if (hp != NULL)
  286.         {
  287.           mycopystr (hp + 5, hilf, '\0');
  288.           (*ShellyArgs).omin = atof (hilf);
  289.         }            /* if */
  290.       hp = strstr (readline, "omax:");
  291.       if (hp != NULL)
  292.         {
  293.           mycopystr (hp + 5, hilf, '\0');
  294.           (*ShellyArgs).omax = atof (hilf);
  295.         }            /* if */
  296.       hp = strstr (readline, "od:");
  297.       if (hp != NULL)
  298.         {
  299.           mycopystr (hp + 3, hilf, '\0');
  300.           (*ShellyArgs).od = atof (hilf);
  301.         }            /* if */
  302.       hp = strstr (readline, "Hdo:");
  303.       if (hp != NULL)
  304.         {
  305.           mycopystr (hp + 4, hilf, '\0');
  306.           (*ShellyArgs).heightdiffo = atof (hilf);
  307.         }            /* if */
  308.       hp = strstr (readline, "Hds:");
  309.       if (hp != NULL)
  310.         {
  311.           mycopystr (hp + 4, hilf, '\0');
  312.           (*ShellyArgs).heightdiffs = atof (hilf);
  313.         }            /* if */
  314.       hp = strstr (readline, "Scans:");
  315.       if (hp != NULL)
  316.         {
  317.           mycopystr (hp + 6, hilf, '\0');
  318.           (*ShellyArgs).Scans = atof (hilf);
  319.         }            /* if */
  320.       hp = strstr (readline, "Scano:");
  321.       if (hp != NULL)
  322.         {
  323.           mycopystr (hp + 6, hilf, '\0');
  324.           (*ShellyArgs).Scano = atof (hilf);
  325.         }            /* if */
  326.  
  327.       hp = strstr (readline, "Scale:");
  328.       if (hp != NULL)
  329.         {
  330.           mycopystr (hp + 6, hilf, '\0');
  331.           (*ShellyArgs).Scale = atof (hilf);
  332.         }            /* if */
  333.  
  334.       hp = strstr (readline, "POV");
  335.       if (hp != NULL)
  336.         {
  337.           (*ShellyArgs).output = POV;
  338.         }            /* if */
  339.       hp = strstr (readline, "BEZ");
  340.       if (hp != NULL)
  341.         {
  342.           (*ShellyArgs).output = BEZ;
  343.         }            /* if */
  344.       hp = strstr (readline, "RPL");
  345.       if (hp != NULL)
  346.         {
  347.           (*ShellyArgs).output = RPL;
  348.         }            /* if */
  349.       hp = strstr (readline, "T3D");
  350.       if (hp != NULL)
  351.         {
  352.           (*ShellyArgs).output = T3D;
  353.         }            /* if */
  354.       hp = strstr (readline, "RAW");
  355.       if (hp != NULL)
  356.         {
  357.           (*ShellyArgs).output = RAW;
  358.         }            /* if */
  359.       hp = strstr (readline, "X3D");
  360.       if (hp != NULL)
  361.         {
  362.           (*ShellyArgs).output = X3D;
  363.         }            /* if */
  364.  
  365.       hp = strstr (readline, "NORMAL");
  366.       if (hp != NULL)
  367.         {
  368.           (*ShellyArgs).mode = NORMAL;
  369.         }            /* if */
  370.       hp = strstr (readline, "NODULE");
  371.       if (hp != NULL)
  372.         {
  373.           (*ShellyArgs).mode = NODULE;
  374.         }            /* if */
  375.       hp = strstr (readline, "NEWNOD");
  376.       if (hp != NULL)
  377.         {
  378.           (*ShellyArgs).mode = NEWNOD;
  379.         }            /* if */
  380.       hp = strstr (readline, "RENDER");
  381.       if (hp != NULL)
  382.         {
  383.           (*ShellyArgs).Render = YES;
  384.         }            /* if */
  385.  
  386.       hp = strstr (readline, "POVARGS:");
  387.       if (hp != NULL)
  388.         mycopystr (hp + 8, (*ShellyArgs).povargs, '\n');
  389.  
  390.       hp = strstr (readline, "P2:");
  391.       if (hp != NULL)
  392.         {
  393.           mycopystr (hp + 3, hilf, '\0');
  394.           (*ShellyArgs).P2 = atof (hilf);
  395.         }            /* if */
  396.       hp = strstr (readline, "W12:");
  397.       if (hp != NULL)
  398.         {
  399.           mycopystr (hp + 4, hilf, '\0');
  400.           (*ShellyArgs).W12 = atof (hilf);
  401.         }            /* if */
  402.       hp = strstr (readline, "W22:");
  403.       if (hp != NULL)
  404.         {
  405.           mycopystr (hp + 4, hilf, '\0');
  406.           (*ShellyArgs).W22 = atof (hilf);
  407.         }            /* if */
  408.       hp = strstr (readline, "N2:");
  409.       if (hp != NULL)
  410.         {
  411.           mycopystr (hp + 3, hilf, '\0');
  412.           (*ShellyArgs).N2 = atof (hilf);
  413.         }            /* if */
  414.       hp = strstr (readline, "L2:");
  415.       if (hp != NULL)
  416.         {
  417.           mycopystr (hp + 3, hilf, '\0');
  418.           (*ShellyArgs).L2 = atof (hilf);
  419.         }            /* if */
  420.       hp = strstr (readline, "P3:");
  421.       if (hp != NULL)
  422.         {
  423.           mycopystr (hp + 3, hilf, '\0');
  424.           (*ShellyArgs).P3 = atof (hilf);
  425.         }            /* if */
  426.       hp = strstr (readline, "W13:");
  427.       if (hp != NULL)
  428.         {
  429.           mycopystr (hp + 4, hilf, '\0');
  430.           (*ShellyArgs).W13 = atof (hilf);
  431.         }            /* if */
  432.       hp = strstr (readline, "W23:");
  433.       if (hp != NULL)
  434.         {
  435.           mycopystr (hp + 4, hilf, '\0');
  436.           (*ShellyArgs).W23 = atof (hilf);
  437.         }            /* if */
  438.       hp = strstr (readline, "N3:");
  439.       if (hp != NULL)
  440.         {
  441.           mycopystr (hp + 3, hilf, '\0');
  442.           (*ShellyArgs).N3 = atof (hilf);
  443.         }            /* if */
  444.       hp = strstr (readline, "L3:");
  445.       if (hp != NULL)
  446.         {
  447.           mycopystr (hp + 3, hilf, '\0');
  448.           (*ShellyArgs).L3 = atof (hilf);
  449.         }            /* if */
  450.       hp = strstr (readline, "Off2:");
  451.       if (hp != NULL)
  452.         {
  453.           mycopystr (hp + 5, hilf, '\0');
  454.           (*ShellyArgs).Off2 = atof (hilf);
  455.         }            /* if */
  456.       hp = strstr (readline, "Off3:");
  457.       if (hp != NULL)
  458.         {
  459.           mycopystr (hp + 5, hilf, '\0');
  460.           (*ShellyArgs).Off3 = atof (hilf);
  461.         }            /* if */
  462.       hp = strstr (readline, "camx:");
  463.       if (hp != NULL)
  464.         {
  465.           mycopystr (hp + 5, hilf, '\0');
  466.           camx = atof (hilf);
  467.           camposspecified = YES;
  468.         }            /* if */
  469.       hp = strstr (readline, "camy:");
  470.       if (hp != NULL)
  471.         {
  472.           mycopystr (hp + 5, hilf, '\0');
  473.           camy = atof (hilf);
  474.           camposspecified = YES;
  475.         }            /* if */
  476.       hp = strstr (readline, "camz:");
  477.       if (hp != NULL)
  478.         {
  479.           mycopystr (hp + 5, hilf, '\0');
  480.           camz = atof (hilf);
  481.           camposspecified = YES;
  482.         }            /* if */
  483.       hp = strstr (readline, "Animate:");
  484.       if (hp != NULL)
  485.         {
  486.           mycopystr (hp + 8, (*ShellyArgs).animto, '\n');
  487.           (*ShellyArgs).anim = YES;
  488.         }            /* if */
  489.       hp = strstr (readline, "Steps:");
  490.       if (hp != NULL)
  491.         {
  492.           mycopystr (hp + 6, hilf, '\0');
  493.           (*ShellyArgs).steps = atoi (hilf);
  494.         }            /* if */
  495. /*      hp = strstr (readline, "Rand:");
  496.       if (hp != NULL)
  497.         {
  498.           mycopystr (hp + 5, hilf, '\0');
  499.           (*ShellyArgs).rnod = atof (hilf);
  500.         }*/            /* if */
  501.  
  502.     }            /* while */
  503.  
  504.       fprintf (stdout, "\n");
  505.       if (fclose (fp) != 0)
  506.     fprintf (stdout, "Error while closing file: %s!\n", fin);
  507.     }
  508.   else
  509.     {
  510.       fprintf (stdout, "Could not open datafile: %s!\n", fin);
  511.       exit (5);
  512.     }
  513. }                /* ReadInfile */
  514.  
  515.  
  516. /********************************************/
  517. /* triangulate:                             */
  518. /*                                          */
  519. /********************************************/
  520. int
  521. triangulate (struct punkt *list1, struct punkt *list2, struct triangle **result)
  522. {
  523.   struct punkt *p11, *p12, *p21, *p22;
  524.   struct triangle *tp, *tp2, *anker = NULL;
  525.   int ende = 1;
  526.  
  527.   if ((list1 == NULL) || (list2 == NULL))
  528.     return (5);
  529.  
  530.   p11 = list1;
  531.   p21 = list2;
  532.  
  533.   while (ende)
  534.     {
  535.       p12 = p11->next;
  536.       p22 = p21->next;
  537.  
  538.  
  539.       if ((p11->next == NULL) && (p21->next == NULL))
  540.     ende = 0;
  541.       else if (p11->next == NULL)
  542.     {
  543.       tp = calloc (1, sizeof (struct triangle));
  544.       if (tp != NULL)
  545.         {
  546.           tp->p1 = p21;
  547.           tp->p2 = p22;
  548.           tp->p3 = p11;
  549.           if (anker == NULL)
  550.         anker = tp;
  551.           else
  552.         tp2->next = tp;
  553.           tp2 = tp;
  554.         }
  555.       p21 = p22;
  556.     }
  557.       else if (p21->next == NULL)
  558.     {
  559.       tp = calloc (1, sizeof (struct triangle));
  560.       if (tp != NULL)
  561.         {
  562.           tp->p1 = p11;
  563.           tp->p2 = p21;
  564.           tp->p3 = p12;
  565.           if (anker == NULL)
  566.         anker = tp;
  567.           else
  568.         tp2->next = tp;
  569.           tp2 = tp;
  570.         }
  571.       p11 = p12;
  572.     }
  573.       else if (p11->s == p21->s)
  574.     {
  575.       if (fabs (p11->s - p12->s) < fabs (p21->s - p22->s))
  576.         {
  577.           tp = calloc (1, sizeof (struct triangle));
  578.           if (tp != NULL)
  579.         {
  580.           tp->p1 = p11;
  581.           tp->p2 = p21;
  582.           tp->p3 = p12;
  583.           if (anker == NULL)
  584.             anker = tp;
  585.           else
  586.             tp2->next = tp;
  587.           tp2 = tp;
  588.         }
  589.           p11 = p12;
  590.         }
  591.       else
  592.         {
  593.           tp = calloc (1, sizeof (struct triangle));
  594.           if (tp != NULL)
  595.         {
  596.           tp->p1 = p21;
  597.           tp->p2 = p22;
  598.           tp->p3 = p11;
  599.           if (anker == NULL)
  600.             anker = tp;
  601.           else
  602.             tp2->next = tp;
  603.           tp2 = tp;
  604.         }
  605.           p21 = p22;
  606.         }
  607.     }
  608.       else if (p11->s < p21->s)
  609.     {
  610.       tp = calloc (1, sizeof (struct triangle));
  611.       if (tp != NULL)
  612.         {
  613.           tp->p1 = p11;
  614.           tp->p2 = p21;
  615.           tp->p3 = p12;
  616.           if (anker == NULL)
  617.         anker = tp;
  618.           else
  619.         tp2->next = tp;
  620.           tp2 = tp;
  621.         }
  622.       p11 = p12;
  623.  
  624.     }
  625.       else if (p11->s > p21->s)
  626.     {
  627.       tp = calloc (1, sizeof (struct triangle));
  628.       if (tp != NULL)
  629.         {
  630.           tp->p1 = p21;
  631.           tp->p2 = p22;
  632.           tp->p3 = p11;
  633.           if (anker == NULL)
  634.         anker = tp;
  635.           else
  636.         tp2->next = tp;
  637.           tp2 = tp;
  638.         }
  639.       p21 = p22;
  640.  
  641.     }            /* big if-cascade ;) */
  642.  
  643.     }                /* while */
  644.  
  645.   *result = anker;
  646.   return (0);
  647.  
  648. }                /* triangulate */
  649.  
  650.  
  651. /********************************************/
  652. /* writepovheader:                          */
  653. /*                                          */
  654. /********************************************/
  655. void
  656. writepovheader (FILE * fp)
  657. {
  658.  
  659.   fprintf (fp, "/* POV-Scenefile generated by Shelly1.6           */\n");
  660.   fprintf (fp, "/* by RANDi: (rschultz@informatik.uni-rostock.de) */\n");
  661.  
  662.   fprintf (fp, "#declare te = pigment { color red 1 green 0 blue 0 }\n");
  663.  
  664.   fprintf (fp, "camera\n{\n location  <%.1f,%.1f,%.1f>\n", camx, camy, camz);
  665.   fprintf (fp, " look_at <0, 0, 0>\n}\n");
  666.  
  667.   fprintf (fp, "object\n{\n light_source {\n");
  668.   fprintf (fp, "  <250, 500, 500> color red 1 green 1 blue 1\n }\n");
  669.   fprintf (fp, "}\n");
  670.   fprintf (fp, "object\n{\n light_source {\n");
  671.   fprintf (fp, "  <-250, 500, 500> color red 1 green 1 blue 1\n }\n");
  672.   fprintf (fp, "}\n");
  673.  
  674. }                /* writepovheader */
  675.  
  676.  
  677. /********************************************/
  678. /* writepovtriangles:                       */
  679. /********************************************/
  680. int
  681. writepovtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  682. {
  683.   struct punkt *p11, *p12, *p21, *p22;
  684.   struct triangle *tp, *tp1, *tp2;
  685.  
  686.   if ((anker1 == NULL) || (anker2 == NULL))
  687.     return (0);
  688.  
  689.   if (mode == 1)
  690.     {
  691.       triangulate (anker1, anker2, &tp);
  692.  
  693.       tp1 = tp;
  694.       while (tp1 != NULL)
  695.     {
  696.  
  697.       fprintf (fp, "triangle{<%.2f,%.2f,%.2f>,<%.2f,%.2f,%.2f>,<%.2f,%.2f,%.2f>\n", tp1->p1->x, tp1->p1->y, tp1->p1->z, tp1->p2->x, tp1->p2->y, tp1->p2->z, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  698.       fprintf (fp, "pigment{te}}\n");
  699.  
  700.       tp2 = tp1->next;
  701.  
  702.       free (tp1);
  703.  
  704.       tp1 = tp2;
  705.     }            /* while */
  706.  
  707.       return (0);
  708.     };
  709.  
  710.  
  711.   p11 = anker1;
  712.   p12 = p11;
  713.   p21 = anker2;
  714.   p22 = p21;
  715.  
  716.   do
  717.     {
  718.       p11 = p12;
  719.       p21 = p22;
  720.       p12 = (*p11).next;
  721.       p22 = (*p21).next;
  722.  
  723.       if ((p12 != NULL) && (p22 != NULL))
  724.     {
  725.       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);
  726.       fprintf (fp, "pigment{te}}\n");
  727.  
  728.       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);
  729.       fprintf (fp, "pigment{te}}\n");
  730.     }
  731.     }
  732.   while ((p12 != NULL) && (p22 != NULL));
  733.  
  734.   return (0);
  735. }                /* writepovtriangles */
  736.  
  737. /********************************************/
  738. /* writepovpatches:                         */
  739. /* or: How to walk with 16 Pointer through  */
  740. /*     4 Lists ;)                           */
  741. /********************************************/
  742. int
  743. writepovpatches (FILE * fp, struct punkt *anker1, struct punkt *anker2, struct punkt *anker3, struct punkt *anker4)
  744. {
  745.   struct punkt *p[16];
  746.   int i = 0;
  747.  
  748.  
  749.   if ((anker1 == NULL) || (anker2 == NULL) || (anker3 == NULL) || (anker4 == NULL))
  750.     return (0);
  751.  
  752.   p[0] = anker1;
  753.   p[1] = anker2;
  754.   p[2] = anker3;
  755.   p[3] = anker4;
  756.  
  757.   do
  758.     {
  759.       if (p[0] && p[1] && p[2] && p[3])
  760.     for (i = 0; i < 4; i++)
  761.       p[i + 4] = p[i]->next;
  762.  
  763.       if (p[4] && p[5] && p[6] && p[7])
  764.     for (i = 0; i < 4; i++)
  765.       p[i + 8] = p[i + 4]->next;
  766.  
  767.       if (p[8] && p[9] && p[10] && p[11])
  768.     for (i = 0; i < 4; i++)
  769.       p[i + 12] = p[i + 8]->next;
  770.  
  771.      if(p[0] && p[1] && p[2] && p[3] && p[4] && p[5] && p[6] && p[7] && p[8]&& p[9] && p[10] && p[11] && p[12] && p[13] && p[14] && p[15])
  772.      {
  773.       fprintf (fp, "bicubic_patch{type 1 flatness 0 u_steps 3 v_steps 3\n");
  774.       fprintf (fp, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>\n", p[0]->x, p[0]->y, p[0]->z, p[1]->x, p[1]->y, p[1]->z, p[2]->x, p[2]->y, p[2]->z, p[3]->x, p[3]->y,p[3]->z);
  775.       fprintf (fp, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,\n", p[4]->x, p[4]->y, p[4]->z, p[5]->x, p[5]->y, p[5]->z, p[6]->x, p[6]->y, p[6]->z, p[7]->x, p[7]->y, p[7]->z);
  776.       fprintf (fp, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,\n", p[8]->x, p[8]->y, p[8]->z, p[9]->x, p[9]->y, p[9]->z, p[10]->x, p[10]->y, p[10]->z, p[11]->x, p[11]->y, p[11]->z);
  777.       fprintf (fp, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>\n", p[12]->x, p[12]->y, p[12]->z, p[13]->x, p[13]->y, p[13]->z, p[14]->x, p[14]->y, p[14]->z, p[15]->x, p[15]->y, p[15]->z);
  778.       fprintf (fp, "pigment{te}}\n");
  779.      } /* if */
  780.       if (p[12] && p[13] && p[14] && p[15])
  781.     for (i = 0; i < 4; i++)
  782.       p[i] = p[i + 12];
  783.  
  784.     }
  785.   while (p[0] && p[1] && p[2] && p[3] && p[4] && p[5] && p[6] && p[7] && p[8] && p[9] && p[10] && p[11] && p[12] && p[13] && p[14] && p[15]);
  786.  
  787.   return (0);
  788. }                /* writepovpatches */
  789.  
  790.  
  791. /********************************************/
  792. /* writepovfinish:                          */
  793. /********************************************/
  794. void
  795. writepovfinish (FILE * fptemp, FILE * fp)
  796. {
  797.  
  798.   filecopy (fptemp, fp);
  799.  
  800. }
  801.  
  802.  
  803. /********************************************/
  804. /* new_pnode:                               */
  805. /*                                          */
  806. /********************************************/
  807. void
  808. new_pnode (struct pmerk **anker, struct punkt *p1)
  809. {
  810.   struct pmerk *mp;
  811.  
  812.   if ((mp = calloc (1, sizeof (struct pmerk))) != NULL)
  813.     {
  814.       mp->x = p1->x;
  815.       mp->y = p1->y;
  816.       mp->z = p1->z;
  817.       mp->id = gl.countp;
  818.       mp->next = *anker;
  819.       *anker = mp;
  820.     }
  821.   else
  822.     return;
  823.  
  824. }                /* new_pnode */
  825.  
  826. /********************************************/
  827. /* free_pmerk_list:                         */
  828. /*                                          */
  829. /********************************************/
  830. void
  831. free_pmerk_list (struct pmerk *anker)
  832. {
  833.   struct pmerk *mp1 = anker, *mp2;
  834.  
  835.   while (mp1 != NULL)
  836.     {
  837.       mp2 = mp1->next;
  838.       free (mp1);
  839.       mp1 = mp2;
  840.     }                /* while */
  841.  
  842. }                /* free_pmerk_list */
  843.  
  844. /********************************************/
  845. /* is_p_in:                                 */
  846. /*                                          */
  847. /********************************************/
  848. int
  849. is_p_in (struct pmerk *anker, struct punkt *p)
  850. {
  851.   struct pmerk *mp1 = anker, *mp2;
  852.  
  853.   while (mp1 != NULL)
  854.     {
  855.       if (mp1->x == p->x)
  856.     if (mp1->y == p->y)
  857.       if (mp1->z == p->z)
  858.         return (mp1->id);
  859.  
  860.       mp2 = mp1->next;
  861.       mp1 = mp2;
  862.     }
  863.   return (0);
  864. }                /* is_p_in */
  865.  
  866. /********************************************/
  867. /* new_lnode:                               */
  868. /*                                          */
  869. /********************************************/
  870. void
  871. new_lnode (struct lmerk **anker, int id1, int id2)
  872. {
  873.   struct lmerk *lp, *lp1 = *anker, *lp2;
  874.  
  875.   if (lp1 == NULL)
  876.     {
  877.       if ((lp = calloc (1, sizeof (struct lmerk))) != NULL)
  878.     {
  879.       lp->id1 = id1;
  880.       lp->id2 = id2;
  881.       lp->id = gl.countl;
  882.       *anker = lp;
  883.     }
  884.       else
  885.     return;
  886.     }
  887.  
  888.   while (lp1 != NULL)
  889.     {
  890.       lp2 = lp1->next;
  891.       if (lp2 == NULL)
  892.     if ((lp = calloc (1, sizeof (struct lmerk))) != NULL)
  893.       {
  894.         lp->id1 = id1;
  895.         lp->id2 = id2;
  896.         lp->id = gl.countl;
  897.         lp1->next = lp;
  898.       }
  899.     else
  900.       return;
  901.  
  902.       lp1 = lp2;
  903.     }
  904.  
  905. }                /* new_lnode */
  906.  
  907. /********************************************/
  908. /* app_llist:                               */
  909. /*                                          */
  910. /********************************************/
  911. void
  912. app_llist (struct lmerk *anker, struct lmerk *list)
  913. {
  914.   struct lmerk *lp1 = anker, *lp2;
  915.  
  916.   while (lp1 != NULL)
  917.     {
  918.       lp2 = lp1->next;
  919.       if (lp2 == NULL)
  920.     lp1->next = list;
  921.       lp1 = lp2;
  922.     }
  923.   return;
  924. }                /* app_llist */
  925.  
  926. /********************************************/
  927. /* free_lmerk_list:                         */
  928. /*                                          */
  929. /********************************************/
  930. void
  931. free_lmerk_list (struct lmerk *anker)
  932. {
  933.   struct lmerk *mp1 = anker, *mp2;
  934.  
  935.   while (mp1 != NULL)
  936.     {
  937.       mp2 = mp1->next;
  938.       free (mp1);
  939.       mp1 = mp2;
  940.     }                /* while */
  941.  
  942. }                /* free_lmerk_list */
  943.  
  944. /********************************************/
  945. /* is_l_in:                                 */
  946. /*                                          */
  947. /********************************************/
  948. int
  949. is_l_in (struct lmerk *anker, int id1, int id2)
  950. {
  951.   struct lmerk *mp1 = anker, *mp2;
  952.  
  953.   while (mp1 != NULL)
  954.     {
  955.       if (mp1->id1 == id1)
  956.     if (mp1->id2 == id2)
  957.       return (mp1->id);
  958.  
  959.       if (mp1->id2 == id1)
  960.     if (mp1->id1 == id2)
  961.       return (mp1->id);
  962.  
  963.       mp2 = mp1->next;
  964.       mp1 = mp2;
  965.     }
  966.   return (0);
  967. }                /* is_l_in */
  968.  
  969. /********************************************/
  970. /* new_tnode:                               */
  971. /*                                          */
  972. /********************************************/
  973. void
  974. new_tnode (struct tmerk **anker, int id1, int id2, int id3, int pid1, int pid2, int pid3)
  975. {
  976.   struct tmerk *tp, *tp1 = *anker, *tp2;
  977.   if (tp1 == NULL)
  978.     if ((tp = calloc (1, sizeof (struct tmerk))) != NULL)
  979.       {
  980.     tp->lid1 = id1;
  981.     tp->lid2 = id2;
  982.     tp->lid3 = id3;
  983.     tp->pid1 = pid1;
  984.     tp->pid2 = pid2;
  985.     tp->pid3 = pid3;
  986.     
  987.     *anker = tp;
  988.       }
  989.     else
  990.       return;
  991.   while (tp1 != NULL)
  992.     {
  993.       tp2 = tp1->next;
  994.       if (tp2 == NULL)
  995.     if ((tp = calloc (1, sizeof (struct tmerk))) != NULL)
  996.       {
  997.         tp->lid1 = id1;
  998.         tp->lid2 = id2;
  999.         tp->lid3 = id3;
  1000.         tp->pid1 = pid1;
  1001.         tp->pid2 = pid2;
  1002.         tp->pid3 = pid3;
  1003.             tp1->next = tp;
  1004.       }
  1005.     else
  1006.       return;
  1007.       tp1 = tp2;
  1008.     }
  1009.  
  1010. }                /* new_tnode */
  1011.  
  1012. /********************************************/
  1013. /* free_tmerk_list:                         */
  1014. /*                                          */
  1015. /********************************************/
  1016. void
  1017. free_tmerk_list (struct tmerk *anker)
  1018. {
  1019.   struct tmerk *tp1 = anker, *tp2;
  1020.  
  1021.   while (tp1 != NULL)
  1022.     {
  1023.       tp2 = tp1->next;
  1024.       free (tp1);
  1025.       tp1 = tp2;
  1026.     }                /* while */
  1027.  
  1028. }                /* free_tmerk_list */
  1029.  
  1030.  
  1031.  
  1032. /********************************************/
  1033. /* writerplline:                            */
  1034. /********************************************/
  1035. int
  1036. writerplline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1037. {
  1038.   struct punkt *p11, *p12;
  1039.   struct triangle *tp1, *tp2, *tp;
  1040.  
  1041.   static struct pmerk *plist1 = NULL;
  1042.   struct pmerk *plist2 = NULL;
  1043.  
  1044.   int pid1, pid2, pid3;
  1045.  
  1046.  
  1047.   if (mode == 2)
  1048.     {
  1049.       free_pmerk_list (plist1);
  1050.       return (0);
  1051.     };
  1052.  
  1053.   if (mode == 1)
  1054.     {
  1055.       triangulate (anker1, anker2, &tp);
  1056.  
  1057.       tp1 = tp;
  1058.       while (tp1 != NULL)
  1059.     {
  1060.       if (((pid1 = is_p_in (plist2, tp1->p1)) == 0) && ((pid1 = is_p_in (plist1, tp1->p1)) == 0))
  1061.         {
  1062.           fprintf (fp, "%.3f %.3f %.3f\n", tp1->p1->x/10.0, tp1->p1->y/10.0, tp1->p1->z/10.0);
  1063.           new_pnode (&plist2, tp1->p1);
  1064.           pid1 = gl.countp;
  1065.           gl.countp++;
  1066.         }
  1067.  
  1068.       if (((pid2 = is_p_in (plist2, tp1->p2)) == 0) && ((pid2 = is_p_in (plist1, tp1->p2)) == 0))
  1069.         {
  1070.           fprintf (fp, "%.3f %.3f %.3f\n", tp1->p2->x/10.0, tp1->p2->y/10.0, tp1->p2->z/10.0);
  1071.           new_pnode (&plist2, tp1->p2);
  1072.           pid2 = gl.countp;
  1073.           gl.countp++;
  1074.         }
  1075.  
  1076.       if (((pid3 = is_p_in (plist2, tp1->p3)) == 0) && ((pid3 = is_p_in (plist1, tp1->p3)) == 0))
  1077.         {
  1078.           fprintf (fp, "%.3f %.3f %.3f\n", tp1->p3->x/10.0, tp1->p3->y/10.0, tp1->p3->z/10.0);
  1079.           new_pnode (&plist2, tp1->p3);
  1080.           pid3 = gl.countp;
  1081.           gl.countp++;
  1082.         }
  1083.  
  1084.  
  1085.       new_tnode (&bigtlist, 0, 0, 0, pid1, pid2, pid3);
  1086.       gl.countt++;
  1087.  
  1088.       tp2 = tp1->next;
  1089.       free (tp1);
  1090.       tp1 = tp2;
  1091.     }            /* while */
  1092.  
  1093.  
  1094.       free_pmerk_list (plist1);
  1095.       plist1 = plist2;
  1096.  
  1097.       return (0);
  1098.     };
  1099.  
  1100.   if (anker1 == NULL)
  1101.     return (0);
  1102.  
  1103.   p11 = anker1;
  1104.   p12 = p11;
  1105.  
  1106.   gl.countw++;            /* calc number of lines created */
  1107.  
  1108.   fprintf (fp, "%.3f  %.3f  %.3f\n", (*p11).x / 100.0, (*p11).y / 100.0, (*p11).z / 100.0);
  1109.  
  1110.   do
  1111.     {
  1112.       p11 = p12;
  1113.       p12 = (*p11).next;
  1114.  
  1115.       if (p12 != NULL)
  1116.     {
  1117.       fprintf (fp, "%.3f  %.3f  %.3f\n", (*p12).x / 100.0, (*p12).y / 100.0, (*p12).z / 100.0);
  1118.     }
  1119.     }
  1120.   while (p12 != NULL);
  1121.  
  1122.   return (0);
  1123. }                /* writerplline */
  1124.  
  1125.  
  1126. /********************************************/
  1127. /* writerplfinish:                          */
  1128. /*                                          */
  1129. /********************************************/
  1130. void
  1131. writerplfinish (FILE * fptemp, FILE * fp, int mode)
  1132. {
  1133.   int faces = 0;
  1134.   struct tmerk *tp1 = bigtlist, *tp2;
  1135.  
  1136.   filecopy (fptemp, fp);
  1137.  
  1138.   if (mode == 1)
  1139.    {
  1140.     fprintf (fp, "%d ( Points\n", gl.countp);    /* Number of points */
  1141.  
  1142.     while (tp1 != NULL)
  1143.     {
  1144.      fprintf (fp, "%d %d %d\n", tp1->pid1, tp1->pid2, tp1->pid3);
  1145.      tp2 = tp1->next;
  1146.      free (tp1);
  1147.      tp1 = tp2;
  1148.     }
  1149.  
  1150.     faces = gl.countt;
  1151.     fprintf (fp, "%d ( Faces\n", faces);
  1152.  
  1153.     fprintf (fp, "wFT_PHONG\n255 255 255 0\n");    /* type RGBA */
  1154.     fprintf (fp, "\"Shell\"\n0\n");    /* Name */
  1155.     fprintf (fp, "\"CEND\"\n");
  1156.     fprintf (fp, "C_TRISET DROP\n");
  1157.  
  1158.  
  1159.     return;
  1160.    }
  1161.    
  1162.   if (mode == 0)
  1163.     {
  1164.       fprintf (fp, "%d\n", gl.counth);    /* height width of the mesh */
  1165.       fprintf (fp, "%d\n", gl.countw);
  1166.  
  1167.       fprintf (fp, "3\n0\n255 255 255 0\n");    /* RGBA */
  1168.       fprintf (fp, "\"Shell\"\n0\n");    /* Name */
  1169.       fprintf (fp, "\"CEND\"\n");
  1170.       fprintf (fp, "C_MESH DROP\n");
  1171.     }                /* if */
  1172. }                /* writerplfinish */
  1173.  
  1174. /********************************************/
  1175. /* writex3dheader:                          */
  1176. /*                                          */
  1177. /********************************************/
  1178. void
  1179. writex3dheader (FILE * fp)
  1180. {
  1181.  
  1182.   fprintf (fp, "2\n");        /* Number of Colors */
  1183.   fprintf (fp, "0  0 0 0\n");    /* Color 0 Black */
  1184.   fprintf (fp, "1  255 0 0\n");    /* Color 1 Red */
  1185.  
  1186. }                /* writex3dheader */
  1187.  
  1188.  
  1189. /********************************************/
  1190. /* writex3dline:                            */
  1191. /********************************************/
  1192. int
  1193. writex3dline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1194. {
  1195.   struct punkt *p11, *p12;
  1196.   struct triangle *tp, *tp1, *tp2;
  1197.  
  1198.   static struct pmerk *plist1 = NULL;
  1199.   struct pmerk *plist2 = NULL;
  1200.   static struct lmerk *llist1 = NULL;
  1201.   struct lmerk *llist2 = NULL;
  1202.  
  1203.   int pid1, pid2, pid3;
  1204.   int lid1, lid2, lid3;
  1205.  
  1206.   if (mode == 2)
  1207.     {
  1208.       free_pmerk_list (plist1);
  1209.       return (0);
  1210.     };
  1211.  
  1212.   if (mode == 1)
  1213.     {
  1214.       triangulate (anker1, anker2, &tp);
  1215.  
  1216.       tp1 = tp;
  1217.       while (tp1 != NULL)
  1218.     {
  1219.       if (((pid1 = is_p_in (plist2, tp1->p1)) == 0) && ((pid1 = is_p_in (plist1, tp1->p1)) == 0))
  1220.         {
  1221.           fprintf (fp, "%d %.3f %.3f %.3f\n", gl.countp, tp1->p1->x, tp1->p1->y, tp1->p1->z);
  1222.           new_pnode (&plist2, tp1->p1);
  1223.           pid1 = gl.countp;
  1224.           gl.countp++;
  1225.         }
  1226.  
  1227.       if (((pid2 = is_p_in (plist2, tp1->p2)) == 0) && ((pid2 = is_p_in (plist1, tp1->p2)) == 0))
  1228.         {
  1229.           fprintf (fp, "%d %.3f %.3f %.3f\n", gl.countp, tp1->p2->x, tp1->p2->y, tp1->p2->z);
  1230.           new_pnode (&plist2, tp1->p2);
  1231.           pid2 = gl.countp;
  1232.           gl.countp++;
  1233.         }
  1234.  
  1235.       if (((pid3 = is_p_in (plist2, tp1->p3)) == 0) && ((pid3 = is_p_in (plist1, tp1->p3)) == 0))
  1236.         {
  1237.           fprintf (fp, "%d %.3f %.3f %.3f\n", gl.countp, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1238.           new_pnode (&plist2, tp1->p3);
  1239.           pid3 = gl.countp;
  1240.           gl.countp++;
  1241.         }
  1242.  
  1243.       if (((lid1 = is_l_in (llist2, pid1, pid2)) == 0) && ((lid1 = is_l_in (llist1, pid1, pid2)) == 0))
  1244.         {
  1245.           new_lnode (&llist2, pid1, pid2);
  1246.           lid1 = gl.countl;
  1247.           gl.countl++;
  1248.         }
  1249.  
  1250.       if (((lid2 = is_l_in (llist2, pid2, pid3)) == 0) && ((lid2 = is_l_in (llist1, pid2, pid3)) == 0))
  1251.         {
  1252.           new_lnode (&llist2, pid2, pid3);
  1253.           lid2 = gl.countl;
  1254.           gl.countl++;
  1255.         }
  1256.  
  1257.       if (((lid3 = is_l_in (llist2, pid3, pid1)) == 0) && ((lid3 = is_l_in (llist1, pid3, pid1)) == 0))
  1258.         {
  1259.           new_lnode (&llist2, pid3, pid1);
  1260.           lid3 = gl.countl;
  1261.           gl.countl++;
  1262.         }
  1263.  
  1264.       new_tnode (&bigtlist, lid1, lid2, lid3, 0, 0, 0);
  1265.       gl.countt++;
  1266.  
  1267.       tp2 = tp1->next;
  1268.       free (tp1);
  1269.       tp1 = tp2;
  1270.     }            /* while */
  1271.  
  1272.  
  1273.       free_pmerk_list (plist1);
  1274.       plist1 = plist2;
  1275.       if (gl.calledwrtx3dl == 0)
  1276.     bigllist = llist2;
  1277.       else
  1278.     app_llist (llist1, llist2);
  1279.       llist1 = llist2;
  1280.  
  1281.       gl.calledwrtx3dl = 1;
  1282.       return (0);
  1283.     };
  1284.  
  1285.  
  1286.  
  1287.   if (anker1 == NULL)
  1288.     return (0);
  1289.  
  1290.   if (gl.calledwrtx3dl == 0)
  1291.     {
  1292.       gl.calledwrtx3dl = 1;
  1293.       gl.count = -1;
  1294.       gl.countw = 0;
  1295.     }
  1296.   gl.countw++;
  1297.  
  1298.   p11 = anker1;
  1299.   p12 = p11;
  1300.  
  1301.   fprintf (fp, "%d  %.3f %.3f %.3f\n", ++gl.count, (*p11).x, (*p11).y, (*p11).z);
  1302.  
  1303.   do
  1304.     {
  1305.       p11 = p12;
  1306.       p12 = (*p11).next;
  1307.  
  1308.       if (p12 != NULL)
  1309.     {
  1310.       fprintf (fp, "%d  %.3f %.3f %.3f\n", ++gl.count, (*p12).x, (*p12).y, (*p12).z);
  1311.     }
  1312.     }
  1313.   while (p12 != NULL);
  1314.  
  1315.   return (0);
  1316. }                /* writex3dline */
  1317.  
  1318. /********************************************/
  1319. /* writex3dfinish:                          */
  1320. /*                                          */
  1321. /********************************************/
  1322. void
  1323. writex3dfinish (FILE * fptemp, FILE * fp, int mode)
  1324. {
  1325.   int edges = 0, faces = 0, edgecount = 0, facecount = 0, a = 0, b = 0,
  1326.     r = 0, r2 = 0, r3 = 0;
  1327.   int point1 = 0, point2 = 0, edge1 = 0, edge2 = 0, edge3 = 0;
  1328.   struct tmerk *tp1 = bigtlist, *tp2;
  1329.   struct lmerk *lp1 = bigllist, *lp2;
  1330.  
  1331.   fprintf (stdout, "\nWriting additional X3D-Data ...");
  1332.  
  1333.   fprintf (fp, "%d\n", gl.countp);    /* Number of points */
  1334.  
  1335.   filecopy (fptemp, fp);
  1336.  
  1337.   if (mode == 1)
  1338.     {
  1339.       edges = gl.countl;
  1340.       fprintf (fp, "%d\n", edges);
  1341.  
  1342.       while (lp1 != NULL)
  1343.     {
  1344.       fprintf (fp, "%d 1 %d %d\n", edgecount++, lp1->id1, lp1->id2);
  1345.       lp2 = lp1->next;
  1346.       free (lp1);
  1347.       lp1 = lp2;
  1348.     }
  1349.  
  1350.       faces = gl.countt;
  1351.       fprintf (fp, "%d\n", faces);
  1352.  
  1353.       while (tp1 != NULL)
  1354.     {
  1355.       fprintf (fp, "%d 1 3 %d %d %d\n", facecount++, tp1->lid1, tp1->lid2, tp1->lid3);
  1356.       tp2 = tp1->next;
  1357.       free (tp1);
  1358.       tp1 = tp2;
  1359.     }
  1360.  
  1361.       return;
  1362.     }
  1363.  
  1364.   edges = (gl.counth * (gl.countw - 1) + gl.countw * (gl.counth - 1) + (gl.counth - 1) * (gl.countw - 1));
  1365.   /* number of edges! */
  1366.   fprintf (fp, "%d\n", edges);
  1367.  
  1368.  
  1369.   /* write horizontal edges */
  1370.   for (a = 0; a < gl.counth; a++)
  1371.     {
  1372.       r = a;
  1373.       for (b = 0; b < (gl.countw - 1); b++)
  1374.     {
  1375.       point1 = r;
  1376.       point2 = r + gl.counth;
  1377.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1378.       r = r + gl.counth;
  1379.     }
  1380.     }
  1381.   /* write vertical edges */
  1382.   for (a = 0; a < gl.countw; a++)
  1383.     {
  1384.       r = a * gl.counth;
  1385.       for (b = 0; b < (gl.counth - 1); b++)
  1386.     {
  1387.       point1 = r + b;
  1388.       point2 = r + b + 1;
  1389.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1390.     }
  1391.     }
  1392.   /* write diagonal edges */
  1393.   for (a = 0; a < gl.counth - 1; a++)
  1394.     {
  1395.       r = a;
  1396.       for (b = 0; b < (gl.countw - 1); b++)
  1397.     {
  1398.       point1 = r;
  1399.       point2 = r + gl.counth + 1;
  1400.       fprintf (fp, "%d  1   %d %d\n", edgecount++, point1, point2);
  1401.       r = r + gl.counth;
  1402.     }
  1403.     }
  1404.   /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
  1405.  
  1406.   /* write faces */
  1407.  
  1408.   faces = 2 * (gl.countw - 1) * (gl.counth - 1);
  1409.  
  1410.   fprintf (fp, "%d\n", faces);    /* number of faces/polygons */
  1411.  
  1412.   r = 0;
  1413.   r3 = gl.countw * (gl.counth - 1) + gl.counth * (gl.countw - 1);
  1414.  
  1415.   for (a = 0; a < gl.counth - 1; a++)
  1416.     {
  1417.       r2 = gl.counth * (gl.countw - 1) + a;
  1418.       for (b = 0; b < gl.countw - 1; b++)
  1419.     {
  1420.       edge1 = r + gl.countw - 1;
  1421.       edge2 = r2;
  1422.       edge3 = r3;
  1423.       fprintf (fp, "%d  1  3  %d %d %d\n", facecount++, edge1, edge2, edge3);
  1424.  
  1425.       edge1 = r;
  1426.       edge2 = r2 + gl.counth - 1;
  1427.       edge3 = r3;
  1428.       fprintf (fp, "%d  1  3  %d %d %d\n", facecount++, edge1, edge2, edge3);
  1429.  
  1430.       r++;
  1431.       r2 = r2 + gl.counth - 1;
  1432.       r3++;
  1433.     }
  1434.     }
  1435.  
  1436.  
  1437. }                /* writex3dfinish */
  1438.  
  1439.  
  1440. /********************************************/
  1441. /* writet3dheader:                          */
  1442. /*                                          */
  1443. /********************************************/
  1444. void
  1445. writet3dheader (FILE * fp)
  1446. {
  1447.   char percent = '%';
  1448.  
  1449.   fprintf (fp, " %c T3Dlib-data-file generated by Shelly1.6\n", percent);
  1450.   fprintf (fp, " %c the ShellShapeGenerator by RANDi :    \n", percent);
  1451.   fprintf (fp, " %c (rschultz@informatik.uni-rostock.de)\n", percent);
  1452.  
  1453.   fprintf (fp, "OBJ Begin \"Hierarchy 1\"\n");
  1454.   fprintf (fp, " DESC Begin \"Object 1 at level 1 of hierarchy 1\"\n");
  1455.   fprintf (fp, "  NAME \"SHELL\"\n");
  1456.   fprintf (fp, "  SHAP Shape = 2\n");
  1457.   fprintf (fp, "  SHAP Lamp  = 0\n");
  1458.   fprintf (fp, "  POSI X=0 Y=0 Z=0\n");
  1459.   fprintf (fp, "  AXIS XAxis X=1 Y=0 Z=0\n");
  1460.   fprintf (fp, "  AXIS YAxis X=0 Y=1 Z=0\n");
  1461.   fprintf (fp, "  AXIS ZAxis X=0 Y=0 Z=1\n");
  1462.   fprintf (fp, "  SIZE X=32 Y=32 Z=32\n");
  1463.  
  1464. }                /* writet3dheader */
  1465.  
  1466.  
  1467. /********************************************/
  1468. /* writet3dline:                            */
  1469. /********************************************/
  1470. int
  1471. writet3dline (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1472. {
  1473.   struct punkt *p11, *p12;
  1474.   struct triangle *tp, *tp1, *tp2;
  1475.  
  1476.   static struct pmerk *plist1 = NULL;
  1477.   struct pmerk *plist2 = NULL;
  1478.   static struct lmerk *llist1 = NULL;
  1479.   struct lmerk *llist2 = NULL;
  1480.  
  1481.  
  1482.   int pid1, pid2, pid3;
  1483.   int lid1, lid2, lid3;
  1484.  
  1485.   if ((anker1 == NULL) && (anker2 == NULL))
  1486.     return (5);
  1487.  
  1488.   if (mode == 2)
  1489.     {
  1490.       free_pmerk_list (plist1);
  1491.       return (0);
  1492.     };
  1493.  
  1494.   if (mode == 1)
  1495.     {
  1496.       triangulate (anker1, anker2, &tp);
  1497.  
  1498.       tp1 = tp;
  1499.       while (tp1 != NULL)
  1500.     {
  1501.       if (((pid1 = is_p_in (plist2, tp1->p1)) == 0) && ((pid1 = is_p_in (plist1, tp1->p1)) == 0))
  1502.         {
  1503.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", gl.countp, tp1->p1->x, tp1->p1->y, tp1->p1->z);
  1504.           new_pnode (&plist2, tp1->p1);
  1505.           pid1 = gl.countp;
  1506.           gl.countp++;
  1507.         }
  1508.  
  1509.       if (((pid2 = is_p_in (plist2, tp1->p2)) == 0) && ((pid2 = is_p_in (plist1, tp1->p2)) == 0))
  1510.         {
  1511.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", gl.countp, tp1->p2->x, tp1->p2->y, tp1->p2->z);
  1512.           new_pnode (&plist2, tp1->p2);
  1513.           pid2 = gl.countp;
  1514.           gl.countp++;
  1515.         }
  1516.  
  1517.       if (((pid3 = is_p_in (plist2, tp1->p3)) == 0) && ((pid3 = is_p_in (plist1, tp1->p3)) == 0))
  1518.         {
  1519.           fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", gl.countp, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1520.           new_pnode (&plist2, tp1->p3);
  1521.           pid3 = gl.countp;
  1522.           gl.countp++;
  1523.         }
  1524.  
  1525.       if (((lid1 = is_l_in (llist2, pid1, pid2)) == 0) && ((lid1 = is_l_in (llist1, pid1, pid2)) == 0))
  1526.         {
  1527.           new_lnode (&llist2, pid1, pid2);
  1528.           lid1 = gl.countl;
  1529.           gl.countl++;
  1530.         }
  1531.  
  1532.       if (((lid2 = is_l_in (llist2, pid2, pid3)) == 0) && ((lid2 = is_l_in (llist1, pid2, pid3)) == 0))
  1533.         {
  1534.           new_lnode (&llist2, pid2, pid3);
  1535.           lid2 = gl.countl;
  1536.           gl.countl++;
  1537.         }
  1538.  
  1539.       if (((lid3 = is_l_in (llist2, pid3, pid1)) == 0) && ((lid3 = is_l_in (llist1, pid3, pid1)) == 0))
  1540.         {
  1541.           new_lnode (&llist2, pid3, pid1);
  1542.           lid3 = gl.countl;
  1543.           gl.countl++;
  1544.         }
  1545.  
  1546.       new_tnode (&bigtlist, lid1, lid2, lid3,0,0,0);
  1547.       gl.countt++;
  1548.  
  1549.       tp2 = tp1->next;
  1550.       free (tp1);
  1551.       tp1 = tp2;
  1552.     }            /* while */
  1553.  
  1554.  
  1555.       free_pmerk_list (plist1);
  1556.       plist1 = plist2;
  1557.  
  1558.       if (gl.calledwrtt3dl == 0)
  1559.     bigllist = llist2;
  1560.       else
  1561.     app_llist (llist1, llist2);
  1562.       llist1 = llist2;
  1563.  
  1564.       gl.calledwrtt3dl = 1;
  1565.       return (0);
  1566.     };
  1567.  
  1568.  
  1569.   if (anker1 == NULL)
  1570.     return (0);
  1571.  
  1572.   if (gl.calledwrtt3dl == 0)
  1573.     {
  1574.       gl.calledwrtt3dl = 1;
  1575.       gl.count = -1;
  1576.       gl.countw = 0;
  1577.     }
  1578.   gl.countw++;
  1579.  
  1580.   p11 = anker1;
  1581.   p12 = p11;
  1582.  
  1583.   fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++gl.count, (*p11).x, (*p11).y, (*p11).z);
  1584.  
  1585.   do
  1586.     {
  1587.       p11 = p12;
  1588.       p12 = (*p11).next;
  1589.  
  1590.       if (p12 != NULL)
  1591.     {
  1592.       fprintf (fp, "  PNTS Point[%d] X=%.3f Y=%.3f Z=%.3f\n", ++gl.count, (*p12).x, (*p12).y, (*p12).z);
  1593.     }
  1594.     }
  1595.   while (p12 != NULL);
  1596.  
  1597.   return (0);
  1598. }                /* writet3dline */
  1599.  
  1600.  
  1601. /********************************************/
  1602. /* writet3dfinish:                          */
  1603. /*                                          */
  1604. /********************************************/
  1605. void
  1606. writet3dfinish (FILE * fptemp, FILE * fp, int mode)
  1607. {
  1608.   int edges = 0, faces = 0, edgecount = 0, facecount = 0, a = 0, b = 0,
  1609.     r = 0, r2 = 0, r3 = 0;
  1610.   int point1 = 0, point2 = 0, edge1 = 0, edge2 = 0, edge3 = 0;
  1611.   struct tmerk *tp1 = bigtlist, *tp2;
  1612.   struct lmerk *lp1 = bigllist, *lp2;
  1613.  
  1614.  
  1615.   fprintf (stdout, "\nWriting additional T3Dlib-Data ...");
  1616.  
  1617.   fprintf (fp, "  PNTS PCount %d\n", gl.countp);
  1618.  
  1619.   filecopy (fptemp, fp);
  1620.  
  1621.   if (mode == 1)
  1622.     {
  1623.       edges = gl.countl;
  1624.       fprintf (fp, "  EDGE ECount %d\n", edges);
  1625.  
  1626.       while (lp1 != NULL)
  1627.     {
  1628.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, lp1->id1, lp1->id2);
  1629.       lp2 = lp1->next;
  1630.       free (lp1);
  1631.       lp1 = lp2;
  1632.     }
  1633.  
  1634.       faces = gl.countt;
  1635.       fprintf (fp, "  FACE TCount %d\n", faces);
  1636.  
  1637.       while (tp1 != NULL)
  1638.     {
  1639.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, tp1->lid1, tp1->lid2, tp1->lid3);
  1640.       tp2 = tp1->next;
  1641.       free (tp1);
  1642.       tp1 = tp2;
  1643.     }
  1644.  
  1645.       return;
  1646.     }
  1647.  
  1648.   edges = (gl.counth * (gl.countw - 1) + gl.countw * (gl.counth - 1) + (gl.counth - 1) * (gl.countw - 1));
  1649.   /* number of edges! */
  1650.   fprintf (fp, "  EDGE ECount %d\n", edges);
  1651.  
  1652.  
  1653.   /* write horizontal edges */
  1654.   for (a = 0; a < gl.counth; a++)
  1655.     {
  1656.       r = a;
  1657.       for (b = 0; b < (gl.countw - 1); b++)
  1658.     {
  1659.       point1 = r;
  1660.       point2 = r + gl.counth;
  1661.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1662.       r = r + gl.counth;
  1663.     }
  1664.     }
  1665.   /* write vertical edges */
  1666.   for (a = 0; a < gl.countw; a++)
  1667.     {
  1668.       r = a * gl.counth;
  1669.       for (b = 0; b < (gl.counth - 1); b++)
  1670.     {
  1671.       point1 = r + b;
  1672.       point2 = r + b + 1;
  1673.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1674.     }
  1675.     }
  1676.   /* write diagonal edges */
  1677.   for (a = 0; a < gl.counth - 1; a++)
  1678.     {
  1679.       r = a;
  1680.       for (b = 0; b < (gl.countw - 1); b++)
  1681.     {
  1682.       point1 = r;
  1683.       point2 = r + gl.counth + 1;
  1684.       fprintf (fp, "  EDGE Edge[%d] %d %d\n", edgecount++, point1, point2);
  1685.       r = r + gl.counth;
  1686.     }
  1687.     }
  1688.   /* ohhh boy, THIS (^^^) took me time ! :), now to that faces! */
  1689.  
  1690.   /* write faces */
  1691.  
  1692.   faces = 2 * (gl.countw - 1) * (gl.counth - 1);
  1693.  
  1694.   fprintf (fp, "  FACE TCount %d\n", faces);
  1695.  
  1696.   r = 0;
  1697.   r3 = gl.countw * (gl.counth - 1) + gl.counth * (gl.countw - 1);
  1698.  
  1699.   for (a = 0; a < gl.counth - 1; a++)
  1700.     {
  1701.       r2 = gl.counth * (gl.countw - 1) + a;
  1702.       for (b = 0; b < gl.countw - 1; b++)
  1703.     {
  1704.       edge1 = r + gl.countw - 1;
  1705.       edge2 = r2;
  1706.       edge3 = r3;
  1707.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  1708.  
  1709.       edge1 = r;
  1710.       edge2 = r2 + gl.counth - 1;
  1711.       edge3 = r3;
  1712.       fprintf (fp, "  FACE Connect[%d] %d %d %d\n", facecount++, edge1, edge2, edge3);
  1713.  
  1714.       r++;
  1715.       r2 = r2 + gl.counth - 1;
  1716.       r3++;
  1717.     }
  1718.     }
  1719.  
  1720.   fprintf (fp, "  COLR R=98 G=68 B=58\n");
  1721.   fprintf (fp, "  REFL R=0 G=0 B=0\n");
  1722.   fprintf (fp, "  TRAN R=0 G=0 B=0\n");
  1723.   fprintf (fp, "  SPC1 R=0 G=0 B=0\n");
  1724.   fprintf (fp, "  End DESC   \"Object 1 at level 1 of hierarchy 1\"\n");
  1725.   fprintf (fp, " TOBJ       \"Object 0 at level 1 of hierarchy 1\"\n");
  1726.   fprintf (fp, "End OBJ  \"Hierarchy 1\"\n");
  1727.  
  1728. }                /* writet3dfinish */
  1729.  
  1730.  
  1731. /********************************************/
  1732. /* writerawtriangles:                       */
  1733. /********************************************/
  1734. int
  1735. writerawtriangles (FILE * fp, struct punkt *anker1, struct punkt *anker2, int mode)
  1736. {
  1737.   struct punkt *p11, *p12, *p21, *p22;
  1738.   struct triangle *tp, *tp1, *tp2;
  1739.  
  1740.   if ((anker1 == NULL) || (anker2 == NULL))
  1741.     return (0);
  1742.  
  1743.   if (mode == 1)
  1744.     {
  1745.       triangulate (anker1, anker2, &tp);
  1746.  
  1747.       tp1 = tp;
  1748.       while (tp1 != NULL)
  1749.     {
  1750.       fprintf (fp, "%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", tp1->p1->x, tp1->p1->y, tp1->p1->z, tp1->p2->x, tp1->p2->y, tp1->p2->z, tp1->p3->x, tp1->p3->y, tp1->p3->z);
  1751.       tp2 = tp1->next;
  1752.  
  1753.       free (tp1);
  1754.  
  1755.       tp1 = tp2;
  1756.     }            /* while */
  1757.  
  1758.       return (0);
  1759.     };
  1760.  
  1761.   p11 = anker1;
  1762.   p12 = p11;
  1763.   p21 = anker2;
  1764.   p22 = p21;
  1765.  
  1766.   do
  1767.     {
  1768.       p11 = p12;
  1769.       p21 = p22;
  1770.       p12 = (*p11).next;
  1771.       p22 = (*p21).next;
  1772.  
  1773.       if ((p12 != NULL) && (p22 != NULL))
  1774.     {
  1775.       fprintf (fp, "%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", (*p11).x, (*p11).y, (*p11).z, (*p12).x, (*p12).y, (*p12).z, (*p21).x, (*p21).y, (*p21).z);
  1776.  
  1777.       fprintf (fp, "%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", (*p21).x, (*p21).y, (*p21).z, (*p12).x, (*p12).y, (*p12).z, (*p22).x, (*p22).y, (*p22).z);
  1778.     }
  1779.     }
  1780.   while ((p12 != NULL) && (p22 != NULL));
  1781.  
  1782.   return (0);
  1783. }                /* writerawtriangles */
  1784.  
  1785.  
  1786. /********************************************/
  1787. /*init: fills global structure              */
  1788. /********************************************/
  1789. void
  1790. init (struct ShellyArguments *ShellyArgs)
  1791. {
  1792.   gl.countw = 0, gl.counth = 0, gl.countp = 0, gl.countl = 0, gl.countt = 0;
  1793.   gl.calledwrtx3dl = 0;
  1794.   gl.count = 0;
  1795.   gl.calledwrtt3dl = 0;
  1796.   gl.N = (*ShellyArgs).N;
  1797.   gl.N2 = (*ShellyArgs).N2;
  1798.   gl.N3 = (*ShellyArgs).N3;
  1799.   gl.L = (*ShellyArgs).L;
  1800.   gl.L2 = (*ShellyArgs).L2;
  1801.   gl.L3 = (*ShellyArgs).L3;
  1802.   gl.W1 = (*ShellyArgs).W1 * pi / 180;
  1803.   gl.W2 = (*ShellyArgs).W2 * pi / 180;
  1804.   gl.W12 = (*ShellyArgs).W12 * pi / 180;
  1805.   gl.W22 = (*ShellyArgs).W22 * pi / 180;
  1806.   gl.W13 = (*ShellyArgs).W13 * pi / 180;
  1807.   gl.W23 = (*ShellyArgs).W23 * pi / 180;
  1808.   gl.P = (*ShellyArgs).P * pi / 180;
  1809.   gl.P2 = (*ShellyArgs).P2 * pi / 180;
  1810.   gl.P3 = (*ShellyArgs).P3 * pi / 180;
  1811.   gl.Off2 = (*ShellyArgs).Off2 * pi / 180;
  1812.   gl.Off3 = (*ShellyArgs).Off3 * pi / 180;
  1813.   gl.biggest = 0;
  1814.   gl.alpha = (*ShellyArgs).alpha * pi / 180;
  1815.   gl.beta = (*ShellyArgs).beta * pi / 180;
  1816.   gl.phi = (*ShellyArgs).phi * pi / 180;
  1817.   gl.omega = (*ShellyArgs).omega * pi / 180;
  1818.   gl.my = (*ShellyArgs).my * pi / 180;
  1819.  
  1820.   gl.a = (*ShellyArgs).a;
  1821.   gl.b = (*ShellyArgs).b;
  1822.   gl.A = (*ShellyArgs).A;
  1823.  
  1824.   gl.Scale = (*ShellyArgs).Scale;
  1825.  
  1826.   gl.smin = (*ShellyArgs).smin * pi / 180;
  1827.   gl.smax = (*ShellyArgs).smax * pi / 180;
  1828.   gl.sd = (*ShellyArgs).sd * pi / 180;
  1829.   gl.Scans = (*ShellyArgs).Scans;
  1830.   gl.omin = (*ShellyArgs).omin * pi / 180;
  1831.   gl.omax = (*ShellyArgs).omax * pi / 180;
  1832.   gl.od = (*ShellyArgs).od * pi / 180;
  1833.   gl.Scano = (*ShellyArgs).Scano;
  1834.  
  1835. }                /* init */
  1836.  
  1837.  
  1838. /********************************************/
  1839. /*calcg:                                    */
  1840. /********************************************/
  1841. double
  1842. calcg (double O, double N)
  1843. {
  1844.   if (N == 0)
  1845.     return (0);
  1846.   else
  1847.     return ((2 * pi) / N * (O * N / (2 * pi) - round (O * N / (2 * pi))));
  1848.  
  1849. }                /* calcg */
  1850.  
  1851.  
  1852. /********************************************/
  1853. /*calck:                                    */
  1854. /********************************************/
  1855. double
  1856. calck (double S, double O)
  1857. {
  1858.   double N, N2, N3, L, L2, L3, W1, W2, W12, W13, W22, W23, P, P2, P3, Off2,
  1859.     Off3;
  1860.   double k = 0, g;
  1861.  
  1862.  
  1863.   N = gl.N;
  1864.   W1 = gl.W1;
  1865.   W2 = gl.W2;
  1866.   P = gl.P;
  1867.   L = gl.L;
  1868.   N2 = gl.N2;
  1869.   W12 = gl.W12;
  1870.   W22 = gl.W22;
  1871.   P2 = gl.P2;
  1872.   L2 = gl.L2;
  1873.  
  1874.   N3 = gl.N3;
  1875.   W13 = gl.W13;
  1876.   W23 = gl.W23;
  1877.   P3 = gl.P3;
  1878.   L3 = gl.L3;
  1879.  
  1880.   Off2 = gl.Off2;
  1881.   Off3 = gl.Off3;
  1882.  
  1883.  
  1884.  
  1885.  
  1886.   g = calcg (O, N);
  1887.   if (N != 0)
  1888.     k = L * exp (-(2 * (S - P) / W1) * (2 * (S - P) / W1)) * exp (-(2 * g / W2) * (2 * g / W2));
  1889.  
  1890.   g = calcg (O + Off2, N2);
  1891.   if (N2 != 0)
  1892.     k = k + (L2 * exp (-(2 * (S - P2) / W12) * (2 * (S - P2) / W12)) * exp (-(2 * g / W22) * (2 * g / W22)));
  1893.  
  1894.   g = calcg (O + Off3, N3);
  1895.   if (N3 != 0)
  1896.     k = k + (L3 * exp (-(2 * (S - P3) / W13) * (2 * (S - P3) / W13)) * exp (-(2 * g / W23) * (2 * g / W23)));
  1897.  
  1898. /*  if(gl.rnod!=0.0)
  1899.   {
  1900.   
  1901.   
  1902.    k = k + ((double) RAND_MAX/rand())*gl.rnod;
  1903.    printf("k= %f %f\n",k,gl.rnod);
  1904.   }*/
  1905.  
  1906.   return (k);
  1907. }                /* calck */
  1908.  
  1909.  
  1910. /********************************************/
  1911. /*innodule2:                                */
  1912. /********************************************/
  1913. double
  1914. innodule2 (double sc, double O, double S)
  1915. {
  1916.   double k1 = 0, k2 = 0;
  1917.  
  1918.   k1 = calck (S, O);
  1919.  
  1920.   k2 = calck (S + sc, O);
  1921.  
  1922.   return (fabs (k1) - fabs (k2));
  1923.  
  1924. }                /* innodule */
  1925.  
  1926.  
  1927. /********************************************/
  1928. /*innodule:                                 */
  1929. /********************************************/
  1930. double
  1931. innodule (double sc, double O)
  1932. {
  1933.   double N, N2, N3, L, L2, L3, W2, W22, W23, Off2, Off3;
  1934.  
  1935.   double k1 = 0, k2 = 0, g;
  1936.  
  1937.   N = gl.N;
  1938.   W2 = gl.W2;
  1939.   L = gl.L;
  1940.   N2 = gl.N2;
  1941.   W22 = gl.W22;
  1942.   L2 = gl.L2;
  1943.   N3 = gl.N3;
  1944.   W23 = gl.W23;
  1945.   L3 = gl.L3;
  1946.   Off2 = gl.Off2;
  1947.   Off3 = gl.Off3;
  1948.  
  1949.  
  1950.   g = calcg (O, N);
  1951.   if (N != 0)
  1952.     k1 = L * exp (-(2 * g / W2) * (2 * g / W2));
  1953.   g = calcg (O + Off2, N2);
  1954.   if (N2 != 0)
  1955.     k1 = k1 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  1956.   g = calcg (O + Off3, N3);
  1957.   if (N3 != 0)
  1958.     k1 = k1 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  1959.  
  1960.   g = calcg (O + sc, N);
  1961.   if (N != 0)
  1962.     k2 = L * exp (-(2 * g / W2) * (2 * g / W2));
  1963.   g = calcg (O + Off2 + sc, N2);
  1964.   if (N2 != 0)
  1965.     k2 = k2 + (L2 * exp (-(2 * g / W22) * (2 * g / W22)));
  1966.   g = calcg (O + Off3 + sc, N3);
  1967.   if (N3 != 0)
  1968.     k2 = k2 + (L3 * exp (-(2 * g / W23) * (2 * g / W23)));
  1969.  
  1970.  
  1971.   return (fabs (k1) - fabs (k2));
  1972.  
  1973. }                /* innodule */
  1974.  
  1975.  
  1976. /********************************************/
  1977. /*calccamera:                               */
  1978. /********************************************/
  1979. void
  1980. calccamera (double x, double y, double z)
  1981. {
  1982.  
  1983.   if ((fabs (x) > fabs (y)) && (fabs (x) > fabs (z)))
  1984.     if (fabs (x) > gl.biggest)
  1985.       {
  1986.     gl.biggest = fabs (x);
  1987.     camy = gl.biggest * 1.5;
  1988.     camz = gl.biggest * 1.5;
  1989.       }
  1990.   if ((fabs (y) > fabs (x)) && (fabs (y) > fabs (z)))
  1991.     if (fabs (y) > gl.biggest)
  1992.       {
  1993.     gl.biggest = fabs (y);
  1994.     camy = gl.biggest * 1.5;
  1995.     camz = gl.biggest * 1.5;
  1996.       }
  1997.  
  1998.   if ((fabs (z) > fabs (y)) && (fabs (z) > fabs (x)))
  1999.     if (fabs (z) > gl.biggest)
  2000.       {
  2001.     gl.biggest = fabs (z);
  2002.     camy = gl.biggest * 1.5;
  2003.     camz = gl.biggest * 1.5;
  2004.       }
  2005.  
  2006. }                /* calccamera */
  2007.  
  2008.  
  2009. /**********************************************/
  2010. /* CalcPoint:                                 */
  2011. /*                                            */
  2012. /**********************************************/
  2013. int
  2014. calcpoint (double O, double S, struct punkt **point)
  2015. {
  2016.   struct punkt *point1 = NULL;
  2017.   double x, y, z, R, Re, k;
  2018.   double a, b, A, beta, phi, omega, alpha, Scale, my;
  2019.  
  2020.   alpha = gl.alpha;
  2021.   beta = gl.beta;
  2022.   phi = gl.phi;
  2023.   omega = gl.omega;
  2024.   my = gl.my;
  2025.  
  2026.   a = gl.a;
  2027.   b = gl.b;
  2028.   A = gl.A;
  2029.  
  2030.   Scale = gl.Scale;
  2031.  
  2032.   gl.counth = 0;
  2033.  
  2034.   Re = pow ((pow (a, -2.0) * (cos (S) * cos (S)) + pow (b, -2.0) * (sin (S) * sin (S))), -0.5);
  2035.  
  2036.   k = calck (S, O);
  2037.  
  2038.   R = Re + k;
  2039.  
  2040.   /* alternatively: */
  2041.   /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
  2042.  
  2043.   x = Scale * (A * sin (beta) * cos (O) + R * cos (S + phi) * cos (O + omega) - R * sin (my) * sin (S + phi) * sin (O)) * exp (O * cot (alpha));
  2044.   y = Scale * (-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));
  2045.   z = Scale * (-1 * A * cos (beta) + R * sin (S + phi) * cos (my)) * exp (O * cot (alpha));
  2046.   if (camposspecified == NO)
  2047.     calccamera (x, y, z);
  2048.   if ((point1 = calloc (1, sizeof (struct punkt))) == NULL)
  2049.     {
  2050.       fprintf (stdout, "Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
  2051.       return (5);
  2052.     }                /* if */
  2053.  
  2054.   (*point1).x = x;
  2055.   (*point1).y = y;
  2056.   (*point1).z = z;
  2057.   (*point1).s = S;
  2058.  
  2059.   *point = point1;
  2060.  
  2061.   return (0);
  2062.  
  2063. }                /* calcpoint */
  2064.  
  2065.  
  2066. /**********************************************/
  2067. /* calcnews:                                  */
  2068. /*             SSIA :)                        */
  2069. /**********************************************/
  2070. void
  2071. calcnews (struct ShellyArguments *SA, double O, double Sold, double *newS)
  2072. {
  2073.   double S = Sold, sd;
  2074.   int mittenodul = NO;
  2075.   sd = SA->sd * pi / 180;
  2076.  
  2077.   S += SA->Scans;
  2078.  
  2079.  
  2080.   while ((fabs (innodule2 (S - Sold, O, Sold)) < SA->heightdiffs) && (S - Sold < sd) && (mittenodul == NO))
  2081.     {
  2082.       S += SA->Scans;
  2083.       if ((innodule2 (SA->Scans, O, Sold) < 0) && (innodule2 (SA->Scans, O, S) > 0))
  2084.     {
  2085.       mittenodul = YES;
  2086.     }
  2087.     }
  2088.  
  2089.   *newS = S;
  2090.  
  2091.   return;
  2092.  
  2093. }                /* calcnews */
  2094.  
  2095.  
  2096. /**********************************************/
  2097. /* CalcnodLine:                               */
  2098. /*                                            */
  2099. /**********************************************/
  2100. int
  2101. calcnodline (double O, struct ShellyArguments *ShellyArgs, struct punkt **list)
  2102. {
  2103.   struct punkt *list1 = NULL, *L1p1, *L1p2;
  2104.   double S, newS;
  2105.   double sc;
  2106.   double smin, smax, sd;
  2107.  
  2108.   smin = gl.smin;
  2109.   smax = gl.smax;
  2110.   sd = gl.sd;
  2111.  
  2112.   sc = gl.Scans;
  2113.  
  2114.  
  2115.   S = smin;
  2116.  
  2117.   calcpoint (O, smin, &list1);
  2118.   L1p1 = list1;
  2119.   L1p2 = list1;
  2120.  
  2121.   while (S <= smax)
  2122.     {
  2123.       calcnews (ShellyArgs, O, S, &newS);
  2124.       S = newS;
  2125.  
  2126.       calcpoint (O, S, &L1p1);
  2127.       L1p2->next = L1p1;
  2128.       L1p2 = L1p1;
  2129.  
  2130.  
  2131.     }                /* while */
  2132.  
  2133.   *list = list1;
  2134.  
  2135.   return (0);
  2136.  
  2137. }                /* calcnodline */
  2138.  
  2139.  
  2140. /**********************************************/
  2141. /* CalcLine:                                  */
  2142. /*                                            */
  2143. /**********************************************/
  2144. int
  2145. calcline (double O, struct ShellyArguments *ShellyArgs, struct punkt **list)
  2146. {
  2147.   struct punkt *list1 = NULL, *L1p1, *L1p2;
  2148.   double x, y, z, R, S, Re, k;
  2149.   double my;
  2150.   double smin, smax, sd, a, b, A, beta, phi, omega, alpha, Scale;
  2151.  
  2152.   smin = gl.smin;
  2153.   smax = gl.smax;
  2154.   sd = gl.sd;
  2155.  
  2156.   alpha = gl.alpha;
  2157.   beta = gl.beta;
  2158.   phi = gl.phi;
  2159.   omega = gl.omega;
  2160.   my = gl.my;
  2161.  
  2162.   a = gl.a;
  2163.   b = gl.b;
  2164.   A = gl.A;
  2165.  
  2166.   Scale = gl.Scale;
  2167.  
  2168.   gl.counth = 0;
  2169.  
  2170.   for (S = smin; (S + sd) < smax; S = S + sd)
  2171.     {
  2172.       gl.counth++;
  2173.       gl.countp++;
  2174.  
  2175.       Re = pow ((pow (a, -2.0) * (cos (S) * cos (S)) + pow (b, -2.0) * (sin (S) * sin (S))), -0.5);
  2176.  
  2177.       k = calck (S, O);
  2178.  
  2179.       R = Re + k;
  2180.  
  2181.       /* alternatively: */
  2182.       /* R = pow((pow(a,2.0)*pow(cos(S),2.0)+pow(b,2.0)*pow(sin(S),2.0)),0.5); */
  2183.  
  2184.       x = Scale * (A * sin (beta) * cos (O) + R * cos (S + phi) * cos (O + omega) - R * sin (my) * sin (S + phi) * sin (O)) * exp (O * cot (alpha));
  2185.       y = Scale * (-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));
  2186.       z = Scale * (-1 * A * cos (beta) + R * sin (S + phi) * cos (my)) * exp (O * cot (alpha));
  2187.       if (camposspecified == NO)
  2188.     calccamera (x, y, z);
  2189.  
  2190.       if ((L1p1 = calloc (1, sizeof (struct punkt))) == NULL)
  2191.     {
  2192.       fprintf (stdout, "Shelly: NOT ENOUGH MEMORY!!! ... exiting ... !\n");
  2193.       if (S != smin)
  2194.         myfree (list1);
  2195.       return (5);
  2196.     }            /* if */
  2197.       if (S == smin)
  2198.     list1 = L1p1;
  2199.       else
  2200.     (*L1p2).next = L1p1;
  2201.       L1p2 = L1p1;
  2202.  
  2203.       (*L1p1).x = x;
  2204.       (*L1p1).y = y;
  2205.       (*L1p1).z = z;
  2206.       (*L1p1).s = S;
  2207.  
  2208.     }                /* for */
  2209.  
  2210.   *list = list1;
  2211.  
  2212.   return (0);
  2213.  
  2214. }                /* calcline */
  2215.  
  2216.  
  2217. /**********************************************/
  2218. /* calcnewo:                                  */
  2219. /*             SSIA :)                        */
  2220. /**********************************************/
  2221. void
  2222. calcnewo (struct ShellyArguments *SA, double Oold, double *newO)
  2223. {
  2224.   double O = Oold, od;
  2225.   int mittenodul = NO;
  2226.   od = SA->od * pi / 180;
  2227.  
  2228.   O += SA->Scano;
  2229.  
  2230.   while ((fabs (innodule (O - Oold, Oold)) < SA->heightdiffo) && (O - Oold < od) && (mittenodul == NO))
  2231.     {
  2232.       O += SA->Scano;
  2233.       if ((innodule (SA->Scano, Oold) < 0) && (innodule (SA->Scano, O) > 0))
  2234.     {
  2235.       mittenodul = YES;
  2236.     }
  2237.     }
  2238.  
  2239.   *newO = O;
  2240.  
  2241.   return;
  2242.  
  2243. }                /* calcnewo */
  2244.  
  2245.  
  2246. /**********************************************/
  2247. /* CalcNewNod:                                */
  2248. /*             SSIA :)                        */
  2249. /**********************************************/
  2250. void
  2251. CalcNewNod (struct ShellyArguments *ShellyArgs, char *fout)
  2252. {
  2253.   struct punkt *list1 = NULL, *list2;
  2254.  
  2255.   double O, newO, omin, omax;
  2256.   FILE *fptemp, *fp;
  2257.   char *hilf, temp[laenge];
  2258.  
  2259.   omin = gl.omin;
  2260.   omax = gl.omax;
  2261.   O = omin;
  2262.  
  2263.   mycopystr (fout, temp, '\0');
  2264.   hilf = strchr (temp, '\0');
  2265.   if (hilf != NULL)
  2266.     mycopystr (".tmp", hilf, '\0');
  2267.  
  2268.  
  2269.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2270.     {
  2271.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2272.       exit (5);
  2273.     }
  2274.  
  2275.   if ((fp = fopen (fout, "w")) == NULL)
  2276.     {
  2277.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2278.       exit (5);
  2279.     }
  2280.   if ((*ShellyArgs).output == X3D)
  2281.     writex3dheader (fp);
  2282.   if ((*ShellyArgs).output == T3D)
  2283.     writet3dheader (fp);
  2284.  
  2285.  
  2286.   fprintf (stdout, "Calculating the Shell:");
  2287.  
  2288.   if (calcnodline (omin, ShellyArgs, &list1) != 0)
  2289.     exit (5);
  2290.  
  2291.   while (O <= omax)
  2292.     {
  2293.       calcnewo (ShellyArgs, O, &newO);
  2294.       O = newO;
  2295.  
  2296.       if (calcnodline (O, ShellyArgs, &list2) != 0)
  2297.     exit (5);
  2298.  
  2299.       fprintf (stdout, ".");
  2300.       fflush (stdout);
  2301.  
  2302.       if ((*ShellyArgs).output == RPL)
  2303.     writerplline (fptemp, list1, list2, 1);
  2304.       if ((*ShellyArgs).output == POV)
  2305.     writepovtriangles (fptemp, list1, list2, 1);
  2306.       if ((*ShellyArgs).output == X3D)
  2307.     writex3dline (fptemp, list1, list2, 1);
  2308.       if ((*ShellyArgs).output == T3D)
  2309.     writet3dline (fptemp, list1, list2, 1);
  2310.  
  2311.       if ((*ShellyArgs).output == RAW)
  2312.     writerawtriangles (fp, list1, list2, 1);
  2313.  
  2314.       myfree (list1);
  2315.       list1 = list2;
  2316.  
  2317.     }
  2318.  
  2319.  
  2320.   if ((*ShellyArgs).output == POV)
  2321.     writepovheader (fp);
  2322.  
  2323.  
  2324.   if ((*ShellyArgs).output == RPL)
  2325.     writerplfinish (fptemp, fp, 1);
  2326.   if ((*ShellyArgs).output == POV)
  2327.     writepovfinish (fptemp, fp);
  2328.   if ((*ShellyArgs).output == X3D)
  2329.     writex3dfinish (fptemp, fp, 1);
  2330.   if ((*ShellyArgs).output == T3D)
  2331.     writet3dfinish (fptemp, fp, 1);
  2332.  
  2333.   fprintf (stdout, "\n");
  2334.  
  2335.   myfree (list1);
  2336.   if ((*ShellyArgs).output == X3D)
  2337.     writex3dline (fptemp, NULL, NULL, 2);    /* free temporary pointlist in writex3dline */
  2338.   if ((*ShellyArgs).output == T3D)
  2339.     writet3dline (fptemp, NULL, NULL, 2);    /* free temporary pointlist in writet3dline */
  2340.   if ((*ShellyArgs).output == RPL)
  2341.     writerplline (fptemp, NULL, NULL, 2);    /* free temporary pointlist in writet3dline */
  2342.  
  2343.   if (fclose (fptemp) != 0)
  2344.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2345.  
  2346.   if (fclose (fp) != 0)
  2347.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2348.   remove (temp);
  2349. }                /* CalcNewNod */
  2350.  
  2351.  
  2352. /**********************************************/
  2353. /* CalcNodule:                                */
  2354. /*             SSIA :)                        */
  2355. /**********************************************/
  2356. void
  2357. CalcNodule (struct ShellyArguments *ShellyArgs, char *fout)
  2358. {
  2359.   struct punkt *list1 = NULL, *list2;
  2360.  
  2361.   double O, newO, omin, omax;
  2362.   FILE *fptemp, *fp;
  2363.   char *hilf, temp[laenge];
  2364.  
  2365.   omin = gl.omin;
  2366.   omax = gl.omax;
  2367.  
  2368.   O = omin;
  2369.  
  2370.   mycopystr (fout, temp, '\0');
  2371.   hilf = strchr (temp, '\0');
  2372.   if (hilf != NULL)
  2373.     mycopystr (".tmp", hilf, '\0');
  2374.  
  2375.  
  2376.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2377.     {
  2378.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2379.       exit (5);
  2380.     }
  2381.  
  2382.   if ((fp = fopen (fout, "w")) == NULL)
  2383.     {
  2384.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2385.       exit (5);
  2386.     }
  2387.  
  2388.  
  2389.   fprintf (stdout, "Calculating the Shell:");
  2390.  
  2391.   if (calcline (omin, ShellyArgs, &list1) != 0)
  2392.     exit (5);
  2393.  
  2394.   if ((*ShellyArgs).output == RPL)
  2395.     writerplline (fptemp, list1, NULL, 0);
  2396.   if ((*ShellyArgs).output == T3D)
  2397.     writet3dline (fptemp, list1, NULL, 0);
  2398.   if ((*ShellyArgs).output == X3D)
  2399.     writex3dline (fptemp, list1, NULL, 0);
  2400.  
  2401.  
  2402.   while (O <= omax)
  2403.     {
  2404.  
  2405.       calcnewo (ShellyArgs, O, &newO);
  2406.       O = newO;
  2407.  
  2408.       if (calcline (O, ShellyArgs, &list2) != 0)
  2409.     exit (5);
  2410.  
  2411.       fprintf (stdout, ".");
  2412.       fflush (stdout);
  2413.  
  2414.       if ((*ShellyArgs).output == RPL)
  2415.     writerplline (fptemp, list1, NULL, 0);
  2416.       if ((*ShellyArgs).output == POV)
  2417.     writepovtriangles (fptemp, list1, list2, 0);
  2418.       if ((*ShellyArgs).output == T3D)
  2419.     writet3dline (fptemp, list1, NULL, 0);
  2420.       if ((*ShellyArgs).output == X3D)
  2421.     writex3dline (fptemp, list1, NULL, 0);
  2422.       if ((*ShellyArgs).output == RAW)
  2423.     writerawtriangles (fp, list1, list2, 0);
  2424.  
  2425.       myfree (list1);
  2426.       list1 = list2;
  2427.     }
  2428.  
  2429.   if ((*ShellyArgs).output == POV)
  2430.     writepovheader (fp);
  2431.   if ((*ShellyArgs).output == T3D)
  2432.     writet3dheader (fp);
  2433.   if ((*ShellyArgs).output == X3D)
  2434.     writex3dheader (fp);
  2435.  
  2436.  
  2437.   if ((*ShellyArgs).output == RPL)
  2438.     writerplfinish (fptemp, fp, 0);
  2439.   if ((*ShellyArgs).output == T3D)
  2440.     writet3dfinish (fptemp, fp, 0);
  2441.   if ((*ShellyArgs).output == POV)
  2442.     writepovfinish (fptemp, fp);
  2443.   if ((*ShellyArgs).output == X3D)
  2444.     writex3dfinish (fptemp, fp, 0);
  2445.  
  2446.   fprintf (stdout, "\n");
  2447.  
  2448.   myfree (list1);
  2449.  
  2450.  
  2451.   if (fclose (fptemp) != 0)
  2452.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2453.  
  2454.   if (fclose (fp) != 0)
  2455.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2456.   remove (temp);
  2457. }                /* CalcNodule */
  2458.  
  2459.  
  2460. /**********************************************/
  2461. /* CalcShell:                                 */
  2462. /*             SSIA :)                        */
  2463. /**********************************************/
  2464. void
  2465. CalcShell (struct ShellyArguments *ShellyArgs, char *fout)
  2466. {
  2467.   struct punkt *list1 = NULL, *list2;
  2468.  
  2469.   double O, omin, omax, od;
  2470.   FILE *fptemp, *fp;
  2471.   char temp[laenge], *hilf;
  2472.  
  2473.   omin = gl.omin;
  2474.   omax = gl.omax;
  2475.   od = gl.od;
  2476.  
  2477.  
  2478.   mycopystr (fout, temp, '\0');
  2479.   hilf = strchr (temp, '\0');
  2480.   if (hilf != NULL)
  2481.     mycopystr (".tmp", hilf, '\0');
  2482.  
  2483.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2484.     {
  2485.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2486.       exit (5);
  2487.     }
  2488.  
  2489.   if ((fp = fopen (fout, "w")) == NULL)
  2490.     {
  2491.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2492.       exit (5);
  2493.     }
  2494.  
  2495.  
  2496.  
  2497.  
  2498.   fprintf (stdout, "Calculating the Shell:");
  2499.  
  2500.   if (calcline (omin, ShellyArgs, &list1) != 0)
  2501.     exit (5);
  2502.  
  2503.  
  2504.   if ((*ShellyArgs).output == RPL)
  2505.     writerplline (fptemp, list1, NULL, 0);
  2506.   if ((*ShellyArgs).output == T3D)
  2507.     writet3dline (fptemp, list1, NULL, 0);
  2508.   if ((*ShellyArgs).output == X3D)
  2509.     writex3dline (fptemp, list1, NULL, 0);
  2510.  
  2511.   for (O = omin + od; (O + od) < omax; O = O + od)
  2512.     {
  2513.  
  2514.       gl.counth = 0;
  2515.  
  2516.       if (calcline (O, ShellyArgs, &list2) != 0)
  2517.     exit (5);
  2518.  
  2519.       fprintf (stdout, ".");
  2520.       fflush (stdout);
  2521.  
  2522.  
  2523.       if ((*ShellyArgs).output == RPL)
  2524.     writerplline (fptemp, list1, NULL, 0);
  2525.       if ((*ShellyArgs).output == POV)
  2526.     writepovtriangles (fptemp, list1, list2, 0);
  2527.       if ((*ShellyArgs).output == T3D)
  2528.     writet3dline (fptemp, list1, NULL, 0);
  2529.       if ((*ShellyArgs).output == RAW)
  2530.     writerawtriangles (fp, list1, list2, 0);
  2531.       if ((*ShellyArgs).output == X3D)
  2532.     writex3dline (fptemp, list1, NULL, 0);
  2533.  
  2534.  
  2535.       myfree (list1);
  2536.       list1 = list2;
  2537.  
  2538.     }                /* for */
  2539.  
  2540.   if ((*ShellyArgs).output == POV)
  2541.     writepovheader (fp);
  2542.   if ((*ShellyArgs).output == T3D)
  2543.     writet3dheader (fp);
  2544.   if ((*ShellyArgs).output == X3D)
  2545.     writex3dheader (fp);
  2546.  
  2547.  
  2548.   if ((*ShellyArgs).output == RPL)
  2549.     writerplfinish (fptemp, fp, 0);
  2550.   if ((*ShellyArgs).output == T3D)
  2551.     writet3dfinish (fptemp, fp, 0);
  2552.   if ((*ShellyArgs).output == POV)
  2553.     writepovfinish (fptemp, fp);
  2554.   if ((*ShellyArgs).output == X3D)
  2555.     writex3dfinish (fptemp, fp, 0);
  2556.  
  2557.   fprintf (stdout, "\n");
  2558.  
  2559.   myfree (list1);
  2560.  
  2561.  
  2562.   if (fclose (fptemp) != 0)
  2563.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2564.  
  2565.   if (fclose (fp) != 0)
  2566.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2567.   remove (temp);
  2568. }                /* CalcShell */
  2569.  
  2570.  
  2571. /**********************************************/
  2572. /* CalcShell2:                                */
  2573. /* It allows use of the BezierPatch capa-     */
  2574. /* bilities in POV2.x                         */
  2575. /**********************************************/
  2576. void
  2577. CalcShell2 (struct ShellyArguments *ShellyArgs, char *fout)
  2578. {
  2579.   struct punkt *list1, *list2, *list3, *list4;
  2580.  
  2581.   double O, omin, omax, od;
  2582.   FILE *fptemp, *fp;
  2583.   char temp[laenge], *hilf;
  2584.  
  2585.   omin = gl.omin;
  2586.   omax = gl.omax;
  2587.   od = gl.od;
  2588.  
  2589.  
  2590.   mycopystr (fout, temp, '\0');
  2591.   strcat (temp, ".tmp");
  2592.  
  2593.   if ((fptemp = fopen (temp, "w+")) == NULL)
  2594.     {
  2595.       fprintf (stdout, "Could not open outfile: %s!\n", temp);
  2596.       exit (5);
  2597.     }
  2598.  
  2599.   if ((fp = fopen (fout, "w")) == NULL)
  2600.     {
  2601.       fprintf (stdout, "Could not open outfile: %s!\n", fout);
  2602.       exit (5);
  2603.     }
  2604.  
  2605.   fprintf (stdout, "Calculating the Shell:");
  2606.  
  2607.  
  2608.   O = omin;
  2609.  
  2610.   if (calcline (O, ShellyArgs, &list1) != 0)
  2611.    exit (5);
  2612.   O += od;
  2613.  
  2614.   while ((O + od) < omax)
  2615.     {
  2616.  
  2617.       if (calcline (O, ShellyArgs, &list2) != 0)
  2618.     exit (5);
  2619.       O += od;
  2620.       if (calcline (O, ShellyArgs, &list3) != 0)
  2621.     exit (5);
  2622.       O += od;
  2623.       if (calcline (O, ShellyArgs, &list4) != 0)
  2624.     exit (5);
  2625.       O += od;
  2626.  
  2627.       fprintf (stdout, ".");
  2628.       fflush (stdout);
  2629.  
  2630.       writepovpatches (fptemp, list1, list2, list3, list4);
  2631.  
  2632.       myfree (list1);
  2633.       myfree (list2);
  2634.       myfree (list3);
  2635.       list1 = list4;
  2636.  
  2637.     }                /* for */
  2638.  
  2639.   writepovheader (fp);
  2640.  
  2641.  
  2642.   writepovfinish (fptemp, fp);
  2643.  
  2644.   fprintf (stdout, "\n");
  2645.  
  2646.  
  2647.   if (fclose (fptemp) != 0)
  2648.     fprintf (stdout, "Error while closing file: %s!\n", temp);
  2649.  
  2650.   if (fclose (fp) != 0)
  2651.     fprintf (stdout, "Error while closing file: %s!\n", fout);
  2652.   remove (temp);
  2653. }                /* CalcShell2 */
  2654.  
  2655.  
  2656. /**********************************************/
  2657. /* RenderPov:                                 */
  2658. /*           invoke pov for rendering         */
  2659. /**********************************************/
  2660. void
  2661. RenderPov (struct ShellyArguments *ShellyArgs, char *fout)
  2662. {
  2663.   char call[laenge];
  2664.  
  2665.   printf ("Rendering...\n");
  2666.  
  2667.   mycopystr ("pov ", call, '\0');
  2668.   mycopystr ((*ShellyArgs).povargs, &call[4], '\0');
  2669.   strcat (call, " +i");
  2670.   strcat (call, fout);
  2671.   system (call);
  2672.  
  2673.  
  2674. }                /* RenderPov */
  2675.  
  2676.  
  2677. /********************************************/
  2678. /*calcnewparams:                            */
  2679. /********************************************/
  2680. void
  2681. calcnewparams (struct ShellyArguments *SAstart, struct ShellyArguments *SAend, struct ShellyArguments *SAi)
  2682. {
  2683.   static int called = NO;
  2684.   static double dalpha = 0, dbeta = 0, dphi = 0, dmy = 0, domega = 0, dA = 0,
  2685.     da = 0, db = 0;
  2686.   static double domin = 0, domax = 0, dsmin = 0, dsmax = 0, dod = 0, dsd = 0,
  2687.     dScale = 0;
  2688.   static double dP = 0, dW1 = 0, dW2 = 0, dN = 0, dL = 0;
  2689.   static double dP2 = 0, dW12 = 0, dW22 = 0, dN2 = 0, dL2 = 0, dOff2 = 0;
  2690.   static double dP3 = 0, dW13 = 0, dW23 = 0, dN3 = 0, dL3 = 0, dOff3 = 0;
  2691.   static double dcamx = 0, dcamy = 0, dcamz = 0;
  2692.  
  2693.  
  2694.   if (called == NO)
  2695.     {
  2696.       if (SAstart->alpha != SAend->alpha)
  2697.     dalpha = ((SAend->alpha - SAstart->alpha) / SAstart->steps);
  2698.       if (SAstart->beta != SAend->beta)
  2699.     dbeta = ((SAend->beta - SAstart->beta) / SAstart->steps);
  2700.       if (SAstart->phi != SAend->phi)
  2701.     dphi = ((SAend->phi - SAstart->phi) / SAstart->steps);
  2702.       if (SAstart->my != SAend->my)
  2703.     dmy = ((SAend->my - SAstart->my) / SAstart->steps);
  2704.       if (SAstart->omega != SAend->omega)
  2705.     domega = ((SAend->omega - SAstart->omega) / SAstart->steps);
  2706.       if (SAstart->A != SAend->A)
  2707.     dA = ((SAend->A - SAstart->A) / SAstart->steps);
  2708.       if (SAstart->a != SAend->a)
  2709.     da = ((SAend->a - SAstart->a) / SAstart->steps);
  2710.       if (SAstart->b != SAend->b)
  2711.     db = ((SAend->b - SAstart->b) / SAstart->steps);
  2712.       if (SAstart->omin != SAend->omin)
  2713.     domin = ((SAend->omin - SAstart->omin) / SAstart->steps);
  2714.       if (SAstart->omax != SAend->omax)
  2715.     domax = ((SAend->omax - SAstart->omax) / SAstart->steps);
  2716.       if (SAstart->smin != SAend->smin)
  2717.     dsmin = ((SAend->smin - SAstart->smin) / SAstart->steps);
  2718.       if (SAstart->smax != SAend->smax)
  2719.     dsmax = ((SAend->smax - SAstart->smax) / SAstart->steps);
  2720.       if (SAstart->od != SAend->od)
  2721.     dod = ((SAend->od - SAstart->od) / SAstart->steps);
  2722.       if (SAstart->sd != SAend->sd)
  2723.     dsd = ((SAend->sd - SAstart->sd) / SAstart->steps);
  2724.       if (SAstart->Scale != SAend->Scale)
  2725.     dScale = ((SAend->Scale - SAstart->Scale) / SAstart->steps);
  2726.       if (SAstart->P != SAend->P)
  2727.     dP = ((SAend->P - SAstart->P) / SAstart->steps);
  2728.       if (SAstart->L != SAend->L)
  2729.     dL = ((SAend->L - SAstart->L) / SAstart->steps);
  2730.       if (SAstart->N != SAend->N)
  2731.     dN = ((SAend->N - SAstart->N) / SAstart->steps);
  2732.       if (SAstart->W1 != SAend->W1)
  2733.     dW1 = ((SAend->W1 - SAstart->W1) / SAstart->steps);
  2734.       if (SAstart->W2 != SAend->W2)
  2735.     dW2 = ((SAend->W2 - SAstart->W2) / SAstart->steps);
  2736.       if (SAstart->P2 != SAend->P2)
  2737.     dP2 = ((SAend->P2 - SAstart->P2) / SAstart->steps);
  2738.       if (SAstart->L2 != SAend->L2)
  2739.     dL2 = ((SAend->L2 - SAstart->L2) / SAstart->steps);
  2740.       if (SAstart->N2 != SAend->N2)
  2741.     dN2 = ((SAend->N2 - SAstart->N2) / SAstart->steps);
  2742.       if (SAstart->Off2 != SAend->Off2)
  2743.     dOff2 = ((SAend->Off2 - SAstart->Off2) / SAstart->steps);
  2744.       if (SAstart->W12 != SAend->W12)
  2745.     dW12 = ((SAend->W12 - SAstart->W12) / SAstart->steps);
  2746.       if (SAstart->W22 != SAend->W22)
  2747.     dW22 = ((SAend->W22 - SAstart->W22) / SAstart->steps);
  2748.       if (SAstart->P3 != SAend->P3)
  2749.     dP3 = ((SAend->P3 - SAstart->P3) / SAstart->steps);
  2750.       if (SAstart->L3 != SAend->L3)
  2751.     dL3 = ((SAend->L3 - SAstart->L3) / SAstart->steps);
  2752.       if (SAstart->N3 != SAend->N3)
  2753.     dN3 = ((SAend->N3 - SAstart->N3) / SAstart->steps);
  2754.       if (SAstart->Off3 != SAend->Off3)
  2755.     dOff3 = ((SAend->Off3 - SAstart->Off3) / SAstart->steps);
  2756.       if (SAstart->W13 != SAend->W13)
  2757.     dW13 = ((SAend->W13 - SAstart->W13) / SAstart->steps);
  2758.       if (SAstart->W23 != SAend->W23)
  2759.     dW23 = ((SAend->W23 - SAstart->W23) / SAstart->steps);
  2760.       if (SAstart->camx != SAend->camx)
  2761.     dcamx = ((SAend->camx - SAstart->camx) / SAstart->steps);
  2762.       if (SAstart->camy != SAend->camy)
  2763.     dcamy = ((SAend->camy - SAstart->camy) / SAstart->steps);
  2764.       if (SAstart->camz != SAend->camz)
  2765.     dcamz = ((SAend->camz - SAstart->camz) / SAstart->steps);
  2766.  
  2767.       called = YES;
  2768.     }
  2769.  
  2770.   SAi->alpha = SAi->alpha + dalpha;
  2771.   SAi->phi = SAi->phi + dphi;
  2772.   SAi->my = SAi->my + dmy;
  2773.   SAi->omega = SAi->omega + domega;
  2774.   SAi->omin = SAi->omin + domin;
  2775.   SAi->omax = SAi->omax + domax;
  2776.   SAi->smin = SAi->smin + dsmin;
  2777.   SAi->smax = SAi->smax + dsmax;
  2778.   SAi->od = SAi->od + dod;
  2779.   SAi->sd = SAi->sd + dsd;
  2780.   SAi->Scale = SAi->Scale + dScale;
  2781.   SAi->A = SAi->A + dA;
  2782.   SAi->a = SAi->a + da;
  2783.   SAi->b = SAi->b + db;
  2784.   SAi->P = SAi->P + dP;
  2785.   SAi->W1 = SAi->W1 + dW1;
  2786.   SAi->W2 = SAi->W2 + dW2;
  2787.   SAi->N = SAi->N + dN;
  2788.   SAi->L = SAi->L + dL;
  2789.   SAi->P2 = SAi->P2 + dP2;
  2790.   SAi->W12 = SAi->W12 + dW12;
  2791.   SAi->W22 = SAi->W22 + dW22;
  2792.   SAi->N2 = SAi->N2 + dN2;
  2793.   SAi->L2 = SAi->L2 + dL2;
  2794.   SAi->Off2 = SAi->Off2 + dOff2;
  2795.   SAi->P3 = SAi->P3 + dP3;
  2796.   SAi->W13 = SAi->W13 + dW13;
  2797.   SAi->W23 = SAi->W23 + dW23;
  2798.   SAi->N3 = SAi->N3 + dN3;
  2799.   SAi->L3 = SAi->L3 + dL3;
  2800.   SAi->Off3 = SAi->Off3 + dOff3;
  2801.   SAi->camx = SAi->camx + dcamx;
  2802.   SAi->camy = SAi->camy + dcamy;
  2803.   SAi->camz = SAi->camz + dcamz;
  2804.  
  2805.  
  2806. }                /* calcnewparams */
  2807.  
  2808.  
  2809. /********************************************/
  2810. /*animate:                                  */
  2811. /********************************************/
  2812. void
  2813. animate (struct ShellyArguments *SAstart, int ac, char **av)
  2814. {
  2815.   int i;
  2816.   char fn[laenge];
  2817.   struct ShellyArguments *SAend, SAi;
  2818.  
  2819.  
  2820.  
  2821.   if (SAstart == NULL)
  2822.     return;
  2823.  
  2824.   mycopystr (av[2], fn, '\0');
  2825.  
  2826.   if ((SAend = calloc (1, sizeof (struct ShellyArguments))) != NULL);
  2827.   {
  2828.     ReadInfile (SAend, SAstart->animto);
  2829.     printf ("Doing Animation, %d steps.\n", SAstart->steps);
  2830.  
  2831.     SAstart->steps--;
  2832.     SAi = *SAstart;
  2833.  
  2834.     for (i = 0; i <= SAstart->steps; i++)
  2835.       {
  2836.     mycopystr (av[2], fn, '\0');
  2837.     sprintf (fn, "%s%d", fn, i);
  2838.  
  2839.     init (&SAi);
  2840.  
  2841.         if (SAstart->output == BEZ)
  2842.          CalcShell2(&SAi, fn); 
  2843.  
  2844.     if (SAi.mode == NORMAL)
  2845.       CalcShell (&SAi, fn);
  2846.     if (SAi.mode == NODULE)
  2847.       CalcNodule (&SAi, fn);
  2848.     if (SAi.mode == NEWNOD)
  2849.       CalcNewNod (&SAi, fn);
  2850.  
  2851.     if (SAi.Render == YES)
  2852.       if (SAi.output != POV)
  2853.         fprintf (stdout, "Rendering is only available for POV-output!\n(Ever tried to feed a RPL-Macro into POV? ;))\n");
  2854.       else
  2855.         RenderPov (&SAi, fn);
  2856.  
  2857.     calcnewparams (SAstart, SAend, &SAi);
  2858.  
  2859.       }                /* for */
  2860.  
  2861.   }
  2862.   exit (0);
  2863. }
  2864.  
  2865. /********************************************/
  2866. /*main:                                     */
  2867. /********************************************/
  2868. int
  2869. main (int ac, char **av)
  2870. {
  2871.   struct ShellyArguments *ShellyArgs;
  2872.  
  2873.   fprintf (stdout, "ShellyV1.6, the ShellShapeGenerator by RANDi\n");
  2874.  
  2875.   if (ac != 3)
  2876.     {
  2877.       fprintf (stdout, "USAGE:\n\n");
  2878.       fprintf (stdout, "   'shelly infilename outfilename'\n\n");
  2879.       exit (1);
  2880.     }                /* if */
  2881.  
  2882.  
  2883.   if ((ShellyArgs = calloc (1, sizeof (struct ShellyArguments))) != NULL);
  2884.   {
  2885.     ReadInfile (ShellyArgs, av[1]);
  2886.  
  2887.     init (ShellyArgs);
  2888.  
  2889.     if (ShellyArgs->anim == YES)
  2890.       animate (ShellyArgs, ac, av);
  2891.  
  2892.     if (ShellyArgs->output == BEZ)
  2893.       CalcShell2(ShellyArgs, av[2]); 
  2894.     else
  2895.     {
  2896.      if (ShellyArgs->mode == NORMAL)
  2897.        CalcShell (ShellyArgs, av[2]);
  2898.      if (ShellyArgs->mode == NODULE)
  2899.        CalcNodule (ShellyArgs, av[2]);
  2900.      if (ShellyArgs->mode == NEWNOD)
  2901.        CalcNewNod (ShellyArgs, av[2]);
  2902.     }
  2903.     
  2904.     if (ShellyArgs->Render == YES)
  2905.       if (ShellyArgs->output != POV || ShellyArgs->output != BEZ)
  2906.     fprintf (stdout, "Rendering is only available for POV-output!\n(Ever tried to feed a RPL-Macro into POV? ;))\n");
  2907.       else
  2908.     RenderPov (ShellyArgs, av[2]);
  2909.  
  2910.     free (ShellyArgs);
  2911.   }
  2912.   exit (0);
  2913. }
  2914.