#include <stdarg.h>
#include <stdlib.h>
#include <math.h>

typedef struct Polyhedron {
    int vertexCount;
    int faceCount;
    double maxVertexLength;
    double* vertices;
    int* faces;
    double* faceColors;
    double* normals;
} Polyhedron;

Polyhedron cube = {0};

static void doubleArray(double* array, int count, ... ) {
    int i;
    va_list args;
    va_start (args, count);
    for (i = 0; i < count; i++) {
        array[i] = va_arg(args,double);
    }
}

static void intArray(int* array, int count, ... ) {
    int i;
    va_list args;
    va_start (args, count);
    for (i = 0; i < count; i++) {
        array[i] = va_arg(args,int);
    }
}

static double findMax(double* array, int vertexCount) {
    double max = 0;
    int i;
    for (i = 0; i < vertexCount; i++) {
        double x = array[3*i];
        double y = array[3*i+1];
        double z = array[3*i+2];
        double len2 = x*x + y*y + z*z;
        if (len2 > max) {
            max = len2;
        }
    }
    return sqrt(max);
}

Polyhedron house;

static Polyhedron create_houseIFS() {
   Polyhedron poly;
   poly.vertexCount = 10;
   poly.faceCount = 9;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = malloc( poly.faceCount*3*sizeof(double) );
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 43*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      2.000, -1.000, 2.000,
      2.000, -1.000, -2.000,
      2.000, 1.000, -2.000,
      2.000, 1.000, 2.000,
      1.500, 1.500, 0.000,
      -1.500, 1.500, 0.000,
      -2.000, -1.000, 2.000,
      -2.000, 1.000, 2.000,
      -2.000, 1.000, -2.000,
      -2.000, -1.000, -2.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      1.000, 0.000, 0.000,
      0.707, 0.707, 0.000,
      0.000, 0.970, 0.243,
      0.000, 0.970, -0.243,
      -0.707, 0.707, 0.000,
      0.000, 0.000, 1.000,
      0.000, -1.000, 0.000,
      0.000, 0.000, -1.000,
      -1.000, 0.000, 0.000
   );
   intArray(poly.faces, 43,
      0,1,2,3,-1,
      3,2,4,-1,
      7,3,4,5,-1,
      2,8,5,4,-1,
      5,8,7,-1,
      0,3,7,6,-1,
      0,6,9,1,-1,
      2,1,9,8,-1,
      6,7,8,9,-1
   );
   doubleArray(poly.faceColors, 3*poly.faceCount,
      1.000, 0.800, 0.800,
      0.700, 0.700, 1.000,
      0.000, 0.000, 1.000,
      0.000, 0.000, 0.700,
      0.700, 0.700, 1.000,
      1.000, 0.000, 0.000,
      0.400, 0.400, 0.400,
      1.000, 0.000, 0.000,
      1.000, 0.800, 0.800
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron cube;

static Polyhedron create_cubeIFS() {
   Polyhedron poly;
   poly.vertexCount = 8;
   poly.faceCount = 6;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = malloc( poly.faceCount*3*sizeof(double) );
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 30*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      1.000, 1.000, 1.000,
      1.000, 1.000, -1.000,
      1.000, -1.000, -1.000,
      1.000, -1.000, 1.000,
      -1.000, 1.000, 1.000,
      -1.000, 1.000, -1.000,
      -1.000, -1.000, -1.000,
      -1.000, -1.000, 1.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -1.000, 0.000, 0.000,
      0.000, 0.000, -1.000,
      0.000, -1.000, 0.000,
      0.000, -0.000, 1.000,
      1.000, 0.000, -0.000,
      -0.000, 1.000, 0.000
   );
   intArray(poly.faces, 30,
      0,1,2,3,-1,
      0,3,7,4,-1,
      0,4,5,1,-1,
      6,2,1,5,-1,
      6,5,4,7,-1,
      6,7,3,2,-1
   );
   doubleArray(poly.faceColors, 3*poly.faceCount,
      1.000, 0.000, 0.000,
      0.000, 1.000, 0.000,
      0.000, 0.000, 1.000,
      0.000, 1.000, 1.000,
      1.000, 0.000, 1.000,
      1.000, 1.000, 0.000
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron dodecahedron;

static Polyhedron create_dodecahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 20;
   poly.faceCount = 12;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 72*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -1.000, 0.000, -0.382,
      0.618, 0.618, 0.618,
      1.000, 0.000, 0.382,
      0.618, -0.618, 0.618,
      0.000, -0.382, 1.000,
      0.000, 0.382, 1.000,
      1.000, 0.000, -0.382,
      0.618, 0.618, -0.618,
      0.382, 1.000, 0.000,
      -0.382, 1.000, 0.000,
      -0.618, 0.618, -0.618,
      0.000, 0.382, -1.000,
      0.618, -0.618, -0.618,
      0.382, -1.000, 0.000,
      -0.382, -1.000, 0.000,
      -1.000, 0.000, 0.382,
      -0.618, 0.618, 0.618,
      -0.618, -0.618, -0.618,
      0.000, -0.382, -1.000,
      -0.618, -0.618, 0.618
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.000, -0.851, -0.526,
      0.000, -0.851, 0.526,
      -0.851, -0.526, 0.000,
      -0.851, 0.526, 0.000,
      0.000, 0.851, 0.526,
      0.000, 0.851, -0.526,
      -0.526, -0.000, -0.851,
      0.526, 0.000, -0.851,
      -0.526, 0.000, 0.851,
      0.526, 0.000, 0.851,
      0.851, -0.526, 0.000,
      0.851, 0.526, -0.000
   );
   intArray(poly.faces, 72,
      16,9,8,1,5,-1,
      9,10,11,7,8,-1,
      8,7,6,2,1,-1,
      6,12,13,3,2,-1,
      18,17,14,13,12,-1,
      14,19,4,3,13,-1,
      4,5,1,2,3,-1,
      15,16,5,4,19,-1,
      7,11,18,12,6,-1,
      10,0,17,18,11,-1,
      0,10,9,16,15,-1,
      17,0,15,19,14,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron icosahedron;

static Polyhedron create_icosahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 12;
   poly.faceCount = 20;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 80*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -1.000, -0.618, 0.000,
      0.000, 1.000, 0.618,
      0.000, 1.000, -0.618,
      1.000, 0.618, 0.000,
      1.000, -0.618, 0.000,
      0.000, -1.000, -0.618,
      0.000, -1.000, 0.618,
      0.618, 0.000, 1.000,
      -0.618, 0.000, 1.000,
      0.618, 0.000, -1.000,
      -0.618, 0.000, -1.000,
      -1.000, 0.618, 0.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -0.577, -0.577, -0.577,
      -0.934, 0.000, -0.357,
      -0.577, 0.577, -0.577,
      0.000, 0.357, -0.934,
      0.000, -0.357, -0.934,
      -0.934, 0.000, 0.357,
      -0.577, -0.577, 0.577,
      -0.357, -0.934, 0.000,
      0.357, -0.934, 0.000,
      0.577, -0.577, 0.577,
      0.000, -0.357, 0.934,
      -0.577, 0.577, 0.577,
      -0.357, 0.934, 0.000,
      0.357, 0.934, 0.000,
      0.934, 0.000, -0.357,
      0.577, -0.577, -0.577,
      0.577, 0.577, 0.577,
      0.000, 0.357, 0.934,
      0.577, 0.577, -0.577,
      0.934, 0.000, 0.357
   );
   intArray(poly.faces, 80,
      3,7,1,-1,
      4,7,3,-1,
      6,7,4,-1,
      8,7,6,-1,
      7,8,1,-1,
      9,4,3,-1,
      2,9,3,-1,
      2,3,1,-1,
      11,2,1,-1,
      10,2,11,-1,
      10,9,2,-1,
      9,5,4,-1,
      6,4,5,-1,
      0,6,5,-1,
      0,11,8,-1,
      11,1,8,-1,
      10,0,5,-1,
      10,5,9,-1,
      0,8,6,-1,
      0,10,11,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron octahedron;

static Polyhedron create_octahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 6;
   poly.faceCount = 8;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = malloc( poly.faceCount*3*sizeof(double) );
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 32*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -1.000, 0.000, 0.000,
      0.000, 0.000, -1.000,
      0.000, 0.000, 1.000,
      0.000, -1.000, 0.000,
      0.000, 1.000, 0.000,
      1.000, 0.000, 0.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -0.577, -0.577, -0.577,
      0.577, -0.577, -0.577,
      0.577, 0.577, -0.577,
      -0.577, 0.577, -0.577,
      -0.577, -0.577, 0.577,
      0.577, -0.577, 0.577,
      0.577, 0.577, 0.577,
      -0.577, 0.577, 0.577
   );
   intArray(poly.faces, 32,
      4,5,2,-1,
      0,4,2,-1,
      0,2,3,-1,
      5,3,2,-1,
      5,4,1,-1,
      4,0,1,-1,
      0,3,1,-1,
      3,5,1,-1
   );
   doubleArray(poly.faceColors, 3*poly.faceCount,
      0.000, 1.000, 1.000,
      1.000, 0.000, 0.000,
      0.500, 0.500, 0.500,
      1.000, 1.000, 0.000,
      1.000, 1.000, 1.000,
      0.000, 1.000, 0.000,
      1.000, 0.000, 1.000,
      0.000, 0.000, 1.000
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron rhombicDodecahedron;

static Polyhedron create_rhombicDodecahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 14;
   poly.faceCount = 12;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 60*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      0.000, 2.000, 0.000,
      -1.000, -1.000, -1.000,
      1.000, -1.000, -1.000,
      1.000, 1.000, -1.000,
      -1.000, 1.000, -1.000,
      -1.000, -1.000, 1.000,
      1.000, -1.000, 1.000,
      1.000, 1.000, 1.000,
      -1.000, 1.000, 1.000,
      0.000, 0.000, 2.000,
      0.000, 0.000, -2.000,
      -2.000, 0.000, 0.000,
      2.000, 0.000, 0.000,
      0.000, -2.000, 0.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.000, 0.707, 0.707,
      -0.707, 0.000, 0.707,
      0.000, -0.707, 0.707,
      0.707, 0.000, 0.707,
      -0.707, 0.707, 0.000,
      -0.707, -0.707, 0.000,
      0.707, -0.707, 0.000,
      0.707, 0.707, 0.000,
      0.000, 0.707, -0.707,
      -0.707, 0.000, -0.707,
      0.000, -0.707, -0.707,
      0.707, 0.000, -0.707
   );
   intArray(poly.faces, 60,
      1,13,2,10,-1,
      2,12,3,10,-1,
      3,0,4,10,-1,
      4,11,1,10,-1,
      2,13,6,12,-1,
      3,12,7,0,-1,
      4,0,8,11,-1,
      1,11,5,13,-1,
      5,9,6,13,-1,
      6,9,7,12,-1,
      7,9,8,0,-1,
      8,9,5,11,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron socerBall;

static Polyhedron create_socerBallIFS() {
   Polyhedron poly;
   poly.vertexCount = 60;
   poly.faceCount = 32;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 212*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.667, -0.745, 0.206,
      -0.667, -0.745, -0.206,
      -0.873, -0.412, -0.333,
      -1.000, -0.206, 0.000,
      -0.873, -0.412, 0.333,
      0.333, 0.873, 0.412,
      0.206, 0.667, 0.745,
      -0.206, 0.667, 0.745,
      -0.333, 0.873, 0.412,
      0.000, 1.000, 0.206,
      0.206, 0.667, -0.745,
      0.333, 0.873, -0.412,
      0.000, 1.000, -0.206,
      -0.333, 0.873, -0.412,
      -0.206, 0.667, -0.745,
      0.873, 0.412, 0.333,
      0.667, 0.745, 0.206,
      0.667, 0.745, -0.206,
      0.873, 0.412, -0.333,
      1.000, 0.206, 0.000,
      0.873, -0.412, 0.333,
      1.000, -0.206, 0.000,
      0.873, -0.412, -0.333,
      0.667, -0.745, -0.206,
      0.667, -0.745, 0.206,
      0.333, -0.873, -0.412,
      0.206, -0.667, -0.745,
      -0.206, -0.667, -0.745,
      -0.333, -0.873, -0.412,
      0.000, -1.000, -0.206,
      0.206, -0.667, 0.745,
      0.333, -0.873, 0.412,
      0.000, -1.000, 0.206,
      -0.333, -0.873, 0.412,
      -0.206, -0.667, 0.745,
      0.412, 0.333, 0.873,
      0.745, 0.206, 0.667,
      0.745, -0.206, 0.667,
      0.412, -0.333, 0.873,
      0.206, 0.000, 1.000,
      -0.206, 0.000, 1.000,
      -0.412, -0.333, 0.873,
      -0.745, -0.206, 0.667,
      -0.745, 0.206, 0.667,
      -0.412, 0.333, 0.873,
      0.745, -0.206, -0.667,
      0.745, 0.206, -0.667,
      0.412, 0.333, -0.873,
      0.206, 0.000, -1.000,
      0.412, -0.333, -0.873,
      -0.412, 0.333, -0.873,
      -0.745, 0.206, -0.667,
      -0.745, -0.206, -0.667,
      -0.412, -0.333, -0.873,
      -0.206, 0.000, -1.000,
      -0.667, 0.745, -0.206,
      -0.667, 0.745, 0.206,
      -0.873, 0.412, 0.333,
      -1.000, 0.206, 0.000,
      -0.873, 0.412, -0.333
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.851, 0.526, -0.000,
      -0.000, -0.851, -0.526,
      -0.000, -0.851, 0.526,
      -0.851, -0.526, -0.000,
      -0.851, 0.526, 0.000,
      0.000, 0.851, 0.526,
      -0.000, 0.851, -0.526,
      -0.526, -0.000, -0.851,
      0.526, 0.000, -0.851,
      -0.526, 0.000, 0.851,
      0.526, 0.000, 0.851,
      0.851, -0.526, 0.000,
      -0.577, -0.577, -0.577,
      -0.934, 0.000, -0.357,
      -0.577, 0.577, -0.577,
      0.000, 0.357, -0.934,
      0.000, -0.357, -0.934,
      -0.934, 0.000, 0.357,
      -0.577, -0.577, 0.577,
      -0.357, -0.934, 0.000,
      0.357, -0.934, 0.000,
      0.577, -0.577, 0.577,
      0.000, -0.357, 0.934,
      -0.577, 0.577, 0.577,
      -0.357, 0.934, 0.000,
      0.357, 0.934, -0.000,
      0.934, 0.000, -0.357,
      0.577, -0.577, -0.577,
      0.577, 0.577, 0.577,
      -0.000, 0.357, 0.934,
      0.577, 0.577, -0.577,
      0.934, -0.000, 0.357
   );
   intArray(poly.faces, 212,
      0,1,2,3,4,-1,
      5,6,7,8,9,-1,
      10,11,12,13,14,-1,
      15,16,17,18,19,-1,
      20,21,22,23,24,-1,
      25,26,27,28,29,-1,
      30,31,32,33,34,-1,
      35,36,37,38,39,-1,
      40,41,42,43,44,-1,
      45,46,47,48,49,-1,
      50,51,52,53,54,-1,
      55,56,57,58,59,-1,
      15,36,35,6,5,16,-1,
      20,37,36,15,19,21,-1,
      30,38,37,20,24,31,-1,
      40,39,38,30,34,41,-1,
      39,40,44,7,6,35,-1,
      45,22,21,19,18,46,-1,
      10,47,46,18,17,11,-1,
      11,17,16,5,9,12,-1,
      55,13,12,9,8,56,-1,
      50,14,13,55,59,51,-1,
      54,48,47,10,14,50,-1,
      49,26,25,23,22,45,-1,
      31,24,23,25,29,32,-1,
      0,33,32,29,28,1,-1,
      3,58,57,43,42,4,-1,
      56,8,7,44,43,57,-1,
      52,2,1,28,27,53,-1,
      53,27,26,49,48,54,-1,
      4,42,41,34,33,0,-1,
      2,52,51,59,58,3,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron stellatedDodecahedron;

static Polyhedron create_stellatedDodecahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 32;
   poly.faceCount = 60;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 240*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.650, 0.000, -0.248,
      0.402, 0.402, 0.402,
      0.650, 0.000, 0.248,
      0.402, -0.402, 0.402,
      0.000, -0.248, 0.650,
      0.000, 0.248, 0.650,
      0.650, 0.000, -0.248,
      0.402, 0.402, -0.402,
      0.248, 0.650, 0.000,
      -0.248, 0.650, 0.000,
      -0.402, 0.402, -0.402,
      0.000, 0.248, -0.650,
      0.402, -0.402, -0.402,
      0.248, -0.650, 0.000,
      -0.248, -0.650, 0.000,
      -0.650, 0.000, 0.248,
      -0.402, 0.402, 0.402,
      -0.402, -0.402, -0.402,
      0.000, -0.248, -0.650,
      -0.402, -0.402, 0.402,
      0.000, 1.052, 0.650,
      -0.000, 1.052, -0.650,
      1.052, 0.650, -0.000,
      1.052, -0.650, -0.000,
      -0.000, -1.052, -0.650,
      -0.000, -1.052, 0.650,
      0.650, 0.000, 1.052,
      -0.650, 0.000, 1.052,
      0.650, -0.000, -1.052,
      -0.650, 0.000, -1.052,
      -1.052, 0.650, -0.000,
      -1.052, -0.650, 0.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.851, -0.526, -0.000,
      0.000, -0.851, 0.526,
      -0.851, -0.526, -0.000,
      -0.526, -0.000, -0.851,
      0.526, -0.000, -0.851,
      0.851, -0.526, 0.000,
      0.526, -0.000, 0.851,
      -0.526, -0.000, 0.851,
      -0.851, -0.526, 0.000,
      0.000, -0.851, -0.526,
      -0.000, -0.851, 0.526,
      -0.526, -0.000, 0.851,
      -0.851, 0.526, 0.000,
      -0.526, -0.000, -0.851,
      -0.000, -0.851, -0.526,
      -0.526, 0.000, 0.851,
      -0.000, 0.851, 0.526,
      -0.000, 0.851, -0.526,
      -0.526, 0.000, -0.851,
      -0.851, -0.526, 0.000,
      0.526, 0.000, 0.851,
      0.851, 0.526, 0.000,
      0.000, 0.851, -0.526,
      -0.851, 0.526, 0.000,
      -0.526, 0.000, 0.851,
      0.851, 0.526, -0.000,
      0.526, 0.000, -0.851,
      -0.526, 0.000, -0.851,
      -0.851, 0.526, -0.000,
      -0.000, 0.851, 0.526,
      0.526, 0.000, -0.851,
      -0.000, -0.851, -0.526,
      -0.851, -0.526, -0.000,
      -0.851, 0.526, -0.000,
      -0.000, 0.851, -0.526,
      0.851, -0.526, -0.000,
      0.000, -0.851, -0.526,
      -0.526, 0.000, -0.851,
      0.000, 0.851, -0.526,
      0.851, 0.526, -0.000,
      -0.000, -0.851, 0.526,
      0.526, -0.000, 0.851,
      -0.000, 0.851, 0.526,
      -0.851, 0.526, 0.000,
      -0.851, -0.526, 0.000,
      0.851, -0.526, 0.000,
      0.851, 0.526, 0.000,
      0.000, 0.851, 0.526,
      -0.526, 0.000, 0.851,
      0.000, -0.851, 0.526,
      0.526, -0.000, 0.851,
      0.000, -0.851, 0.526,
      0.000, -0.851, -0.526,
      0.526, -0.000, -0.851,
      0.851, 0.526, -0.000,
      0.526, 0.000, 0.851,
      0.851, -0.526, 0.000,
      0.526, 0.000, -0.851,
      0.000, 0.851, -0.526,
      0.000, 0.851, 0.526
   );
   intArray(poly.faces, 240,
      16,9,20,-1,
      9,8,20,-1,
      8,1,20,-1,
      1,5,20,-1,
      5,16,20,-1,
      9,10,21,-1,
      10,11,21,-1,
      11,7,21,-1,
      7,8,21,-1,
      8,9,21,-1,
      8,7,22,-1,
      7,6,22,-1,
      6,2,22,-1,
      2,1,22,-1,
      1,8,22,-1,
      6,12,23,-1,
      12,13,23,-1,
      13,3,23,-1,
      3,2,23,-1,
      2,6,23,-1,
      18,17,24,-1,
      17,14,24,-1,
      14,13,24,-1,
      13,12,24,-1,
      12,18,24,-1,
      14,19,25,-1,
      19,4,25,-1,
      4,3,25,-1,
      3,13,25,-1,
      13,14,25,-1,
      4,5,26,-1,
      5,1,26,-1,
      1,2,26,-1,
      2,3,26,-1,
      3,4,26,-1,
      15,16,27,-1,
      16,5,27,-1,
      5,4,27,-1,
      4,19,27,-1,
      19,15,27,-1,
      7,11,28,-1,
      11,18,28,-1,
      18,12,28,-1,
      12,6,28,-1,
      6,7,28,-1,
      10,0,29,-1,
      0,17,29,-1,
      17,18,29,-1,
      18,11,29,-1,
      11,10,29,-1,
      0,10,30,-1,
      10,9,30,-1,
      9,16,30,-1,
      16,15,30,-1,
      15,0,30,-1,
      17,0,31,-1,
      0,15,31,-1,
      15,19,31,-1,
      19,14,31,-1,
      14,17,31,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron stellatedIcosahedron;

static Polyhedron create_stellatedIcosahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 32;
   poly.faceCount = 60;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 240*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.450, -0.278, 0.000,
      0.000, 0.450, 0.278,
      0.000, 0.450, -0.278,
      0.450, 0.278, 0.000,
      0.450, -0.278, 0.000,
      0.000, -0.450, -0.278,
      0.000, -0.450, 0.278,
      0.278, 0.000, 0.450,
      -0.278, 0.000, 0.450,
      0.278, 0.000, -0.450,
      -0.278, 0.000, -0.450,
      -0.450, 0.278, 0.000,
      0.728, 0.728, 0.728,
      1.178, 0.000, 0.450,
      0.728, -0.728, 0.728,
      0.000, -0.450, 1.178,
      0.000, 0.450, 1.178,
      1.178, 0.000, -0.450,
      0.728, 0.728, -0.728,
      0.450, 1.178, 0.000,
      -0.450, 1.178, 0.000,
      -0.728, 0.728, -0.728,
      0.000, 0.450, -1.178,
      0.728, -0.728, -0.728,
      0.450, -1.178, 0.000,
      -0.450, -1.178, 0.000,
      -1.178, 0.000, 0.450,
      -0.728, 0.728, 0.728,
      -0.728, -0.728, -0.728,
      0.000, -0.450, -1.178,
      -0.728, -0.728, 0.728,
      -1.178, 0.000, -0.450
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -0.851, 0.526, 0.000,
      0.526, 0.000, -0.851,
      0.000, -0.851, 0.526,
      -0.000, 0.851, -0.526,
      -0.000, -0.851, -0.526,
      -0.526, 0.000, 0.851,
      0.526, -0.000, -0.851,
      -0.851, -0.526, 0.000,
      0.000, 0.851, 0.526,
      -0.000, -0.851, -0.526,
      -0.851, 0.526, -0.000,
      0.851, 0.526, -0.000,
      0.000, 0.851, -0.526,
      0.851, -0.526, -0.000,
      -0.851, -0.526, -0.000,
      -0.000, 0.851, 0.526,
      -0.526, -0.000, -0.851,
      -0.000, -0.851, 0.526,
      0.526, 0.000, 0.851,
      -0.851, 0.526, -0.000,
      0.000, -0.851, -0.526,
      -0.526, -0.000, 0.851,
      -0.526, -0.000, -0.851,
      0.851, -0.526, 0.000,
      0.526, -0.000, 0.851,
      -0.851, -0.526, -0.000,
      0.526, -0.000, -0.851,
      -0.526, 0.000, 0.851,
      -0.000, -0.851, -0.526,
      0.851, 0.526, -0.000,
      0.000, 0.851, 0.526,
      -0.851, -0.526, 0.000,
      0.851, -0.526, 0.000,
      0.526, -0.000, 0.851,
      0.000, 0.851, -0.526,
      -0.851, -0.526, -0.000,
      -0.526, 0.000, -0.851,
      -0.526, 0.000, 0.851,
      0.851, 0.526, 0.000,
      0.526, 0.000, -0.851,
      -0.851, 0.526, 0.000,
      0.526, 0.000, 0.851,
      0.526, 0.000, 0.851,
      0.000, -0.851, -0.526,
      0.000, 0.851, -0.526,
      -0.000, -0.851, 0.526,
      -0.526, 0.000, -0.851,
      0.851, 0.526, 0.000,
      0.851, -0.526, -0.000,
      -0.000, 0.851, -0.526,
      -0.526, -0.000, 0.851,
      0.851, 0.526, 0.000,
      -0.851, 0.526, 0.000,
      0.000, -0.851, 0.526,
      0.851, -0.526, 0.000,
      -0.526, -0.000, -0.851,
      -0.000, 0.851, 0.526,
      0.000, 0.851, 0.526,
      0.000, -0.851, 0.526,
      0.526, 0.000, -0.851
   );
   intArray(poly.faces, 240,
      3,7,12,-1,
      7,1,12,-1,
      1,3,12,-1,
      4,7,13,-1,
      7,3,13,-1,
      3,4,13,-1,
      6,7,14,-1,
      7,4,14,-1,
      4,6,14,-1,
      8,7,15,-1,
      7,6,15,-1,
      6,8,15,-1,
      7,8,16,-1,
      8,1,16,-1,
      1,7,16,-1,
      9,4,17,-1,
      4,3,17,-1,
      3,9,17,-1,
      2,9,18,-1,
      9,3,18,-1,
      3,2,18,-1,
      2,3,19,-1,
      3,1,19,-1,
      1,2,19,-1,
      11,2,20,-1,
      2,1,20,-1,
      1,11,20,-1,
      10,2,21,-1,
      2,11,21,-1,
      11,10,21,-1,
      10,9,22,-1,
      9,2,22,-1,
      2,10,22,-1,
      9,5,23,-1,
      5,4,23,-1,
      4,9,23,-1,
      6,4,24,-1,
      4,5,24,-1,
      5,6,24,-1,
      0,6,25,-1,
      6,5,25,-1,
      5,0,25,-1,
      0,11,26,-1,
      11,8,26,-1,
      8,0,26,-1,
      11,1,27,-1,
      1,8,27,-1,
      8,11,27,-1,
      10,0,28,-1,
      0,5,28,-1,
      5,10,28,-1,
      10,5,29,-1,
      5,9,29,-1,
      9,10,29,-1,
      0,8,30,-1,
      8,6,30,-1,
      6,0,30,-1,
      0,10,31,-1,
      10,11,31,-1,
      11,0,31,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron stellatedOctahedron;

static Polyhedron create_stellatedOctahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 14;
   poly.faceCount = 24;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 96*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.600, 0.000, 0.000,
      0.000, 0.000, -0.600,
      0.000, 0.000, 0.600,
      0.000, -0.600, 0.000,
      0.000, 0.600, 0.000,
      0.600, 0.000, 0.000,
      0.600, 0.600, 0.600,
      -0.600, 0.600, 0.600,
      -0.600, -0.600, 0.600,
      0.600, -0.600, 0.600,
      0.600, 0.600, -0.600,
      -0.600, 0.600, -0.600,
      -0.600, -0.600, -0.600,
      0.600, -0.600, -0.600
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -0.577, -0.577, 0.577,
      -0.577, 0.577, -0.577,
      0.577, -0.577, -0.577,
      0.577, -0.577, 0.577,
      -0.577, -0.577, -0.577,
      0.577, 0.577, -0.577,
      0.577, -0.577, -0.577,
      -0.577, 0.577, -0.577,
      0.577, 0.577, 0.577,
      -0.577, 0.577, 0.577,
      0.577, 0.577, -0.577,
      -0.577, -0.577, -0.577,
      -0.577, -0.577, -0.577,
      0.577, -0.577, 0.577,
      -0.577, 0.577, 0.577,
      0.577, -0.577, -0.577,
      0.577, 0.577, 0.577,
      -0.577, -0.577, 0.577,
      0.577, 0.577, -0.577,
      -0.577, 0.577, 0.577,
      0.577, -0.577, 0.577,
      -0.577, 0.577, -0.577,
      -0.577, -0.577, 0.577,
      0.577, 0.577, 0.577
   );
   intArray(poly.faces, 96,
      4,5,6,-1,
      5,2,6,-1,
      2,4,6,-1,
      0,4,7,-1,
      4,2,7,-1,
      2,0,7,-1,
      0,2,8,-1,
      2,3,8,-1,
      3,0,8,-1,
      5,3,9,-1,
      3,2,9,-1,
      2,5,9,-1,
      5,4,10,-1,
      4,1,10,-1,
      1,5,10,-1,
      4,0,11,-1,
      0,1,11,-1,
      1,4,11,-1,
      0,3,12,-1,
      3,1,12,-1,
      1,0,12,-1,
      3,5,13,-1,
      5,1,13,-1,
      1,3,13,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron tetrahedron;

static Polyhedron create_tetrahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 4;
   poly.faceCount = 4;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = malloc( poly.faceCount*3*sizeof(double) );
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 16*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      1.000, -1.000, -1.000,
      -1.000, -1.000, 1.000,
      -1.000, 1.000, -1.000,
      1.000, 1.000, 1.000
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      -0.577, -0.577, 0.577,
      -0.577, 0.577, -0.577,
      0.577, 0.577, 0.577,
      0.577, -0.577, -0.577
   );
   intArray(poly.faces, 16,
      0,3,2,-1,
      3,0,1,-1,
      0,2,1,-1,
      2,3,1,-1
   );
   doubleArray(poly.faceColors, 3*poly.faceCount,
      1.000, 0.000, 0.000,
      0.000, 1.000, 0.000,
      0.000, 0.000, 1.000,
      1.000, 1.000, 0.000
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron truncatedIcosahedron;

static Polyhedron create_truncatedIcosahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 60;
   poly.faceCount = 32;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 152*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.500, -0.809, 0.309,
      -0.500, -0.809, -0.309,
      -0.809, -0.309, -0.500,
      -1.000, 0.000, 0.000,
      -0.809, -0.309, 0.500,
      0.500, 0.809, 0.309,
      0.309, 0.500, 0.809,
      -0.309, 0.500, 0.809,
      -0.500, 0.809, 0.309,
      0.000, 1.000, 0.000,
      0.309, 0.500, -0.809,
      0.500, 0.809, -0.309,
      0.000, 1.000, 0.000,
      -0.500, 0.809, -0.309,
      -0.309, 0.500, -0.809,
      0.809, 0.309, 0.500,
      0.500, 0.809, 0.309,
      0.500, 0.809, -0.309,
      0.809, 0.309, -0.500,
      1.000, 0.000, 0.000,
      0.809, -0.309, 0.500,
      1.000, 0.000, 0.000,
      0.809, -0.309, -0.500,
      0.500, -0.809, -0.309,
      0.500, -0.809, 0.309,
      0.500, -0.809, -0.309,
      0.309, -0.500, -0.809,
      -0.309, -0.500, -0.809,
      -0.500, -0.809, -0.309,
      0.000, -1.000, 0.000,
      0.309, -0.500, 0.809,
      0.500, -0.809, 0.309,
      0.000, -1.000, 0.000,
      -0.500, -0.809, 0.309,
      -0.309, -0.500, 0.809,
      0.309, 0.500, 0.809,
      0.809, 0.309, 0.500,
      0.809, -0.309, 0.500,
      0.309, -0.500, 0.809,
      0.000, 0.000, 1.000,
      0.000, 0.000, 1.000,
      -0.309, -0.500, 0.809,
      -0.809, -0.309, 0.500,
      -0.809, 0.309, 0.500,
      -0.309, 0.500, 0.809,
      0.809, -0.309, -0.500,
      0.809, 0.309, -0.500,
      0.309, 0.500, -0.809,
      0.000, 0.000, -1.000,
      0.309, -0.500, -0.809,
      -0.309, 0.500, -0.809,
      -0.809, 0.309, -0.500,
      -0.809, -0.309, -0.500,
      -0.309, -0.500, -0.809,
      0.000, 0.000, -1.000,
      -0.500, 0.809, -0.309,
      -0.500, 0.809, 0.309,
      -0.809, 0.309, 0.500,
      -1.000, 0.000, 0.000,
      -0.809, 0.309, -0.500
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.851, 0.526, -0.000,
      -0.000, -0.851, -0.526,
      0.000, -0.851, 0.526,
      -0.851, -0.526, -0.000,
      -0.851, 0.526, 0.000,
      0.000, 0.851, 0.526,
      0.000, 0.851, -0.526,
      -0.526, -0.000, -0.851,
      0.526, -0.000, -0.851,
      -0.526, 0.000, 0.851,
      0.526, 0.000, 0.851,
      0.851, -0.526, 0.000,
      -0.577, -0.577, -0.577,
      -0.934, -0.000, -0.357,
      -0.577, 0.577, -0.577,
      0.000, 0.357, -0.934,
      0.000, -0.357, -0.934,
      -0.934, 0.000, 0.357,
      -0.577, -0.577, 0.577,
      -0.357, -0.934, -0.000,
      0.357, -0.934, 0.000,
      0.577, -0.577, 0.577,
      0.000, -0.357, 0.934,
      -0.577, 0.577, 0.577,
      -0.357, 0.934, 0.000,
      0.357, 0.934, 0.000,
      0.934, 0.000, -0.357,
      0.577, -0.577, -0.577,
      0.577, 0.577, 0.577,
      0.000, 0.357, 0.934,
      0.577, 0.577, -0.577,
      0.934, 0.000, 0.357
   );
   intArray(poly.faces, 152,
      0,1,2,3,4,-1,
      5,6,7,8,9,-1,
      10,11,12,13,14,-1,
      15,16,17,18,19,-1,
      20,21,22,23,24,-1,
      25,26,27,28,29,-1,
      30,31,32,33,34,-1,
      35,36,37,38,39,-1,
      40,41,42,43,44,-1,
      45,46,47,48,49,-1,
      50,51,52,53,54,-1,
      55,56,57,58,59,-1,
      15,35,5,-1,
      20,36,19,-1,
      30,37,24,-1,
      40,38,34,-1,
      39,44,6,-1,
      45,21,18,-1,
      10,46,17,-1,
      11,16,9,-1,
      55,12,8,-1,
      50,13,59,-1,
      54,47,14,-1,
      49,25,22,-1,
      31,23,29,-1,
      0,32,28,-1,
      3,57,42,-1,
      56,7,43,-1,
      52,1,27,-1,
      53,26,48,-1,
      4,41,33,-1,
      2,51,58,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

Polyhedron truncatedRhombicDodecahedron;

static Polyhedron create_truncatedRhombicDodecahedronIFS() {
   Polyhedron poly;
   poly.vertexCount = 48;
   poly.faceCount = 26;
   poly.vertices = malloc( poly.vertexCount*3*sizeof(double) );
   poly.faceColors = NULL;
   poly.normals = malloc( poly.faceCount*3*sizeof(double) );
   poly.faces = malloc( 170*sizeof(int) );
   doubleArray(poly.vertices, 3*poly.vertexCount,
      -0.333, 1.667, -0.333,
      0.333, 1.667, -0.333,
      0.333, 1.667, 0.333,
      -0.333, 1.667, 0.333,
      -0.667, -1.333, -0.667,
      -0.667, -0.667, -1.333,
      -1.333, -0.667, -0.667,
      0.667, -0.667, -1.333,
      0.667, -1.333, -0.667,
      1.333, -0.667, -0.667,
      0.667, 0.667, -1.333,
      1.333, 0.667, -0.667,
      0.667, 1.333, -0.667,
      -0.667, 0.667, -1.333,
      -0.667, 1.333, -0.667,
      -1.333, 0.667, -0.667,
      -0.667, -1.333, 0.667,
      -1.333, -0.667, 0.667,
      -0.667, -0.667, 1.333,
      1.333, -0.667, 0.667,
      0.667, -1.333, 0.667,
      0.667, -0.667, 1.333,
      0.667, 1.333, 0.667,
      1.333, 0.667, 0.667,
      0.667, 0.667, 1.333,
      -1.333, 0.667, 0.667,
      -0.667, 1.333, 0.667,
      -0.667, 0.667, 1.333,
      0.333, -0.333, 1.667,
      -0.333, -0.333, 1.667,
      -0.333, 0.333, 1.667,
      0.333, 0.333, 1.667,
      -0.333, -0.333, -1.667,
      0.333, -0.333, -1.667,
      0.333, 0.333, -1.667,
      -0.333, 0.333, -1.667,
      -1.667, -0.333, -0.333,
      -1.667, 0.333, -0.333,
      -1.667, 0.333, 0.333,
      -1.667, -0.333, 0.333,
      1.667, 0.333, -0.333,
      1.667, -0.333, -0.333,
      1.667, -0.333, 0.333,
      1.667, 0.333, 0.333,
      0.333, -1.667, -0.333,
      -0.333, -1.667, -0.333,
      -0.333, -1.667, 0.333,
      0.333, -1.667, 0.333
   );
   doubleArray(poly.normals, 3*poly.faceCount,
      0.000, -1.000, 0.000,
      0.577, 0.577, 0.577,
      -0.577, 0.577, 0.577,
      -0.577, -0.577, 0.577,
      0.577, -0.577, 0.577,
      0.577, 0.577, -0.577,
      -0.577, 0.577, -0.577,
      -0.577, -0.577, -0.577,
      0.577, -0.577, -0.577,
      0.000, 0.000, -1.000,
      0.000, -0.000, 1.000,
      1.000, 0.000, -0.000,
      -1.000, 0.000, 0.000,
      0.000, 1.000, 0.000,
      -0.000, 0.707, 0.707,
      -0.707, 0.000, 0.707,
      0.000, -0.707, 0.707,
      0.707, 0.000, 0.707,
      -0.707, 0.707, 0.000,
      -0.707, -0.707, 0.000,
      0.707, -0.707, 0.000,
      0.707, 0.707, -0.000,
      0.000, 0.707, -0.707,
      -0.707, 0.000, -0.707,
      -0.000, -0.707, -0.707,
      0.707, 0.000, -0.707
   );
   intArray(poly.faces, 170,
      0,1,2,3,-1,
      4,5,6,-1,
      7,8,9,-1,
      10,11,12,-1,
      13,14,15,-1,
      16,17,18,-1,
      19,20,21,-1,
      22,23,24,-1,
      25,26,27,-1,
      28,29,30,31,-1,
      32,33,34,35,-1,
      36,37,38,39,-1,
      40,41,42,43,-1,
      44,45,46,47,-1,
      4,45,44,8,7,33,32,5,-1,
      9,41,40,11,10,34,33,7,-1,
      12,1,0,14,13,35,34,10,-1,
      15,37,36,6,5,32,35,13,-1,
      8,44,47,20,19,42,41,9,-1,
      11,40,43,23,22,2,1,12,-1,
      14,0,3,26,25,38,37,15,-1,
      6,36,39,17,16,46,45,4,-1,
      18,29,28,21,20,47,46,16,-1,
      21,28,31,24,23,43,42,19,-1,
      24,31,30,27,26,3,2,22,-1,
      27,30,29,18,17,39,38,25,-1
   );
   poly.maxVertexLength = findMax(poly.vertices,poly.vertexCount);
   return poly;
}

void createPolyhedra() {
   house = create_houseIFS();
   cube = create_cubeIFS();
   dodecahedron = create_dodecahedronIFS();
   icosahedron = create_icosahedronIFS();
   octahedron = create_octahedronIFS();
   rhombicDodecahedron = create_rhombicDodecahedronIFS();
   socerBall = create_socerBallIFS();
   stellatedDodecahedron = create_stellatedDodecahedronIFS();
   stellatedIcosahedron = create_stellatedIcosahedronIFS();
   stellatedOctahedron = create_stellatedOctahedronIFS();
   tetrahedron = create_tetrahedronIFS();
   truncatedIcosahedron = create_truncatedIcosahedronIFS();
   truncatedRhombicDodecahedron = create_truncatedRhombicDodecahedronIFS();
}
