Mesh Simplification / MeshSimplification / HEdge.h

	Program to load and display files in OFF format

	Uses half-edge data structure instead of vertex/face lists for rendering the model

	Keys:  LEFT, RIGHT: rotate about y-axis
			 UP, DOWN:  zoom in/out
			 PAGEUP, PAGEDOWN: rotate about x-axis

			 'b': Enable/disable backface culling

	 Input model file:

#pragma once

#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <map>
#include <vector>
#include <utility>
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#include <GL/glut.h>

#include "Vector3.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846


#define INVALID_STATE -100
#define INFINITE_LOOP -10
#define ERROR -1

using namespace std;

extern float normal_threshold;
extern float threshold_curvature;
extern int nv, np, ne;

extern string last_file;

enum UntieType {
	UVRT = 0x01,
	UEDG = 0x02,
	UFCE = 0x04,
	UPAR = 0x08,
	UALL = 0x0F

struct HE_vert;
struct HE_face;

struct HE_edge {
	HE_edge() { vert = NULL; vert2 = NULL; face = NULL; next = NULL; pair = NULL; index = -1; }
	HE_vert* vert;
	HE_vert* vert2;
	HE_face* face; 
	HE_edge* next; 
	HE_edge* pair;
	int index;

struct HE_vert {
	HE_vert() { edge = NULL; index = -1; }
	HE_vert(const HE_vert& v) { x = v.x; y = v.y; z = v.z; index = v.index; edge = v.edge; }
	HE_vert(const HE_vert* v) { x = v->x; y = v->y; z = v->z; index = v->index; edge = v->edge; } 
	float x; 
	float y;
	float z;
	HE_edge* edge;
	int index;

struct HE_face {
	HE_face() { edge = NULL; index = -1; }
	HE_edge* edge;
	int index;

extern map<int, HE_edge*> edges;
extern vector<int> eiAvail;
extern int ei;

extern map<int, HE_vert*> verts;
extern vector<int> viAvail;
extern int vi;

extern map<int, HE_face*> faces;
extern vector<int> fiAvail;
extern int fi;

extern map<pair<int, int>, HE_edge*> pair_map;

extern vector<HE_vert> last_decimated;
extern vector<HE_vert> last_boundary;

// Mesh operations
Vector3 getVector(HE_vert* vert);
HE_face* create_face(int k1, int k2, int k3);
int test_face(HE_face* face, int k1, int k2, int k3);
void load_mesh(string filename);

// Half Edge data structure operations

// Edge container operations
HE_edge* update_pair(HE_edge* e);
int adde(HE_edge* e);
HE_edge* newe();
int untie_from_edges(HE_edge* e);
int untie_from_pair(HE_edge* e);
int untie_from_face(HE_edge* e);
int untie_from_vert(HE_edge* e);
int untie_edge(HE_edge* e, int t = UALL);
int reme(HE_edge* e);
int dele(HE_edge* e);
HE_edge* gete(int i);
void cleare();
// Vertex container operations
int addv(HE_vert* v);
HE_vert* newv();
int remv(HE_vert* v);
int delv(HE_vert* v);
HE_vert* getv(int i);
void clearv();
// Face container operations
int addf(HE_face* f);
HE_face* newf();
int remf(HE_face* f);
int delf(HE_face* f);
HE_face* getf(int i);
void clearf();