Readme File


/*
    This program uses 3 structures, one for each modelling method.
    When the keyboard event 'b' occurs, the program will give you
    options to choose from. When the option is chosen it will ask
    for the name of an input file. Then given the option it will
    invoke the designated parser to get the information from the
    file. Then the coorect function(s) are called to produce output
    for the given file in point mode. The mode can be changed with
    the right-click menu. 

*/

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include "glut.h"

using namespace std; //introduces namespace std

#define POINTS 1
#define WIREFRAME 2

/********************************************/
// structures used to hold points for the different types of modelling
struct surface
    {
    int number;
    double xpoints[40];
    double ypoints[40];
    double xsurface_points[40][36];
    double zsurface_points[40][36];
    };
   
struct ext
    {
    int objects;
    double distance[3];
    int vertices[3];
    double xpoints[3][12];
    double ypoints[3][12];
   
    };
   
struct loft
    {
    int vertices;
    int num_polygons;
    double xpoints[10][12];
    double ypoints[10][12];
    double zpoints[10][12];
    };

/*******************************************/
// global variables used
surface surfaces;   
loft lofting;
ext extrusion;

ifstream open_file;

const double pi = 3.14158265;

int method = 0;// used to show the methods
bool pt_or_wire = 0;// lets the user change between points and a wireframe

char file[60];

/*******************************************/
// function names
void myInit(void);
void myDisplay(void);
void createGLUTMenus();// callback to create a menu
void processMenuEvents(int option);
void myKeyboard(unsigned char theKey, int x, int y);
    // callback function for keyboard input

// getting input from files
void read_surfaces(istream &infile);
void read_extrusion(istream &infile);
void read_lofting(istream &infile);

// surfaces of revolution
void rotate_points(); // saves values for rotated points
void surface_points();// prints points to the screen
void connect_points();// prints wireframe to the screen

//extrusion
void extrude();
void show_extrude();

//lofting
void lofting_points();
void do_lofting();
void print_lofting();

/*******************************************/
// main, myInit, myDisplay
int main (int argc, char **argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
   
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100,100);
    glutCreateWindow("Final Project: 3D Modeller");
   
    // callback functions
    glutDisplayFunc(myDisplay);
    createGLUTMenus();
    glutKeyboardFunc(myKeyboard);
   
    myInit();
   
    glutMainLoop();
    }

void myInit(void)
    {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glColor3f(0.0, 0.0, 0.0);
    glPointSize(2.0);
   
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glOrtho(-15.0, 15.0, -2.0, 15.0, -15.0, 200.0);
    gluLookAt(0.0, 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glRotated(15, 1, 1, 0);
       
    glClear(GL_COLOR_BUFFER_BIT);
    }

void myDisplay(void)
    {
    glClear(GL_COLOR_BUFFER_BIT);
   
    if(method == 1 && pt_or_wire == 0)
        surface_points();
    else if(method == 1 && pt_or_wire == 1)
        connect_points();
    else if(method == 2 && pt_or_wire == 0)
        extrude();
    else if(method == 2 && pt_or_wire == 1)
        show_extrude();
    else if(method == 3 && pt_or_wire == 0)
        lofting_points();
    else if(method ==3 && pt_or_wire == 1)
        do_lofting();   

    glFlush();
    }
   
/**********************************************/
// these read the input files
void read_surfaces(istream &infile)
    {
    infile >> surfaces.number;
    for(int i = 0; i < surfaces.number; i++)
        {
        infile >> surfaces.xpoints[i];
        infile >> surfaces.ypoints[i];
        }
    }
   
void read_extrusion(istream &infile)
    {
    infile >> extrusion.objects;
    for(int i = 0; i < extrusion.objects; i++)
        {
        infile >> extrusion.distance[i];
        infile >> extrusion.vertices[i];
        for(int j = 0; j < extrusion.vertices[i]; j++)
            {
            infile >> extrusion.xpoints[i][j];
            infile >> extrusion.ypoints[i][j];
            }
        }
    }
   
void read_lofting(istream &infile)
    {
    infile >> lofting.num_polygons;
    infile >> lofting.vertices;
    for(int i = 0; i < lofting.num_polygons; i++)
        {
        for(int j = 0; j < lofting.vertices; j++)
            {
            infile >> lofting.xpoints[i][j];
            infile >> lofting.ypoints[i][j];
            infile >> lofting.zpoints[i][j];
            }
        }
    }
   
/********************************************/
// surfaces of revolution
void rotate_points()
    // determines the x and z values for the points being rotated
    {
    double degree;
    double change = (10 * pi / 180);
    for(int i = 0; i < surfaces.number; i++)
        {
        degree = 0;
        for(int j = 0; j < 36; j++)
            {
            if(j == 0)
                {
                surfaces.xsurface_points[i][j] = surfaces.xpoints[i];
                surfaces.zsurface_points[i][j] = 0;
                degree += change;
                }
            else if(j == 9)
                {
                surfaces.xsurface_points[i][j] = 0;
                surfaces.zsurface_points[i][j] = surfaces.xpoints[i];
                degree += change;
                }
            else if(j == 18)
                {
                surfaces.xsurface_points[i][j] = - surfaces.xpoints[i];
                surfaces.zsurface_points[i][j] = 0;
                degree += change;
                }
            else if(j == 27)
                {
                surfaces.xsurface_points[i][j] = 0;
                surfaces.zsurface_points[i][j] = - surfaces.xpoints[i];
                degree += change;
                }
            else
                {
                surfaces.xsurface_points[i][j] = surfaces.xpoints[i] * cos(degree);
                surfaces.zsurface_points[i][j] = surfaces.xpoints[i] * sin(degree);
                degree += change;
                }   
            }
        }
    }
   
void surface_points()
    {
    glBegin(GL_POINTS);
    for(int i = 0; i < surfaces.number; i++)
        {
        for(int j = 0; j < 36; j ++)
            {
            glVertex3d(surfaces.xsurface_points[i][j],
                        surfaces.ypoints[i],
                        surfaces.zsurface_points[i][j]);
            }
        }
    glEnd();
    }
   
void connect_points()
    {
    glBegin(GL_LINE_STRIP);
    for(int i = 0; i < surfaces.number; i++)
        {
        for(int j = 0; j < 36; j ++)
            {
            if(j == 35)
                {
                /*glVertex3d(surfaces.xsurface_points[i][j],
                            surfaces.ypoints[i],
                            surfaces.zsurface_points[i][j]);
                glVertex3d(surfaces.xsurface_points[i][0],
                            surfaces.ypoints[0],
                            surfaces.zsurface_points[i][0]);
                glVertex3d(surfaces.xsurface_points[0][0],
                            surfaces.ypoints[0],
                            surfaces.zsurface_points[0][0]);
                */
                }
            else
                {
                glVertex3d(surfaces.xsurface_points[i][j],
                            surfaces.ypoints[i],
                            surfaces.zsurface_points[i][j]);
                glVertex3d(surfaces.xsurface_points[i + 1][j],
                            surfaces.ypoints[i + 1],
                            surfaces.zsurface_points[i + 1][j]);
                glVertex3d(surfaces.xsurface_points[i + 1][j + 1],
                            surfaces.ypoints[i + 1],
                            surfaces.zsurface_points[i + 1][j + 1]);
                }
            }
        }
    glEnd();
    }
   
/***************************************/
//extrusion
void extrude()
    {
    glBegin(GL_POINTS);
    for(int j = 0; j < extrusion.objects; j++)
        for(int i = 0; i < extrusion.vertices[j]; i++)
            {
            glVertex3d(extrusion.xpoints[j][i],
                        extrusion.ypoints[j][i],
                        0);
            glVertex3d(extrusion.xpoints[j][i],
                        extrusion.ypoints[j][i],
                        extrusion.distance[j]);
            }
    glEnd();
    }
   
void show_extrude()
    {
    // front
    for(int i = 0; i < extrusion.objects; i++)
        {
        glBegin(GL_LINE_LOOP);
        for(int j = 0; j < extrusion.vertices[i]; j++)
            {
            glVertex3d(extrusion.xpoints[i][j],
                        extrusion.ypoints[i][j],
                        0);
            }
        glEnd();
        }
   
    //back
    for(int j = 0; j < extrusion.objects; j++)
        {
        glBegin(GL_LINE_LOOP);
        for(int i = 0; i < extrusion.vertices[j]; i++)
            {
            glVertex3d(extrusion.xpoints[j][i],
                        extrusion.ypoints[j][i],
                        extrusion.distance[j]);
            }
        glEnd();
    }
   
    // connect fronts to backs
    glBegin(GL_LINES);
    for(int j = 0; j < extrusion.objects; j++)
        for(int i = 0; i < extrusion.vertices[j]; i++)
            {
            glVertex3d(extrusion.xpoints[j][i],
                        extrusion.ypoints[j][i],
                        0);
            glVertex3d(extrusion.xpoints[j][i],
                        extrusion.ypoints[j][i],
                        extrusion.distance[j]);
            }
    glEnd();
    }
   
/***********************************/   
// lofting
void lofting_points()
    {
    glBegin(GL_POINTS);
    for(int i = 0; i < lofting.num_polygons; i++)
        {
        for(int j = 0; j < lofting.vertices; j ++)
            {
            glVertex3d(lofting.xpoints[i][j],
                        lofting.ypoints[i][j],
                        lofting.zpoints[i][j]);
            }
        }
    glEnd();
    }

void do_lofting()
    {
    for(int i = 0; i < lofting.num_polygons; i++)
        {
        glBegin(GL_LINE_LOOP);
        for(int j = 0; j < lofting.vertices; j++)
            {
            //this connects the vertices of the polygons to eachother
            glVertex3d(lofting.xpoints[i][j],
                        lofting.ypoints[i][j],
                        lofting.zpoints[i][j]);
            }
        glEnd();
        }
   
   
        for(int i = 0; i < lofting.vertices; i++)
            {
            glBegin(GL_LINE_STRIP);
            for(int j = 0; j < lofting.num_polygons; j++)
                {
                //this connects points from one polygon to the other
                glVertex3d(lofting.xpoints[j][i],
                            lofting.ypoints[j][i],
                            lofting.zpoints[j][i]);
                }
            glEnd();
            }
   
    }
   


/********************************************/
// definitions for user events   
void createGLUTMenus()
    {
    int menu;
   
    menu = glutCreateMenu(processMenuEvents);
   
    glutAddMenuEntry("Points", POINTS);
    glutAddMenuEntry("Wireframe", WIREFRAME);
   
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    }
   
void processMenuEvents(int option)
    {
    switch(option)
        {
        case POINTS:
            pt_or_wire = 0;
            break;
        case WIREFRAME:
            pt_or_wire = 1;
            break;
        }
    glutPostRedisplay();
    }
   
void myKeyboard(unsigned char theKey, int x, int y)
    {
    x = 1;
    y = 2;
    switch(theKey)
        {
        case 'b': // begin the program
            cout << "Here are the methods that you can choose from:\n";
            cout << "1 - Surfaces of Revolution\n";
            cout << "2 - Extrusion\n";
            cout << "3 - Lofting\n";
            cout << "Enter the one you would like to use. ";
            cin >> method;
             
            cout << "Enter the name of the file you would like to open? ";
            cin >> file;

            open_file.open(file);
            if (!open_file.is_open()) // This exits the program if the file doesn't open correctly
                {
                cout << "The file failed to open successfully\n";
                exit(EXIT_FAILURE);
                }
           
            if(method == 1)
                {
                read_surfaces(open_file);
                rotate_points();
                }
            else if(method == 2)
                {
                read_extrusion(open_file);
                }
            else if(method == 3)   
                {
                read_lofting(open_file);
                }
            break;
        }
    }