#include #include #include "mesh.h" const double PI = 3.14159265358979323; Mesh::Mesh() { numS = 0; numT = 0; numVerts = 0; numNorms = 0; pt = NULL; norm = NULL; return; } Mesh::Mesh(string fname) { numS = 0; numT = 0; numVerts = 0; numNorms = 0; pt = NULL; norm = NULL; readMesh(fname); return; } Mesh::Mesh(const Mesh& m) { copy(m); return; } Mesh::~Mesh() { makeEmpty(); return; } Mesh& Mesh::operator=(const Mesh& m) { if (this != &m) { makeEmpty(); copy(m); } return *this; } bool Mesh::isEmpty() { return numS == 0 && numT == 0; } void Mesh::makeEmpty() { if (pt != NULL) { delete [] pt; delete [] norm; numVerts = 0; numNorms = 0; numS = 0; numT =0; pt = NULL; norm = NULL; } return; } void Mesh::createMesh(Point3D (*f)(double, double), Vector3D (*dfds)(double, double), Vector3D (*dfdt)(double, double), double smin, double smax, double tmin, double tmax, int nS, int nT) { makeEmpty(); numS = nS; numT = nT; numVerts = (numS + 1)*(numT + 1); numNorms = numVerts; pt = new Point3D[numVerts]; norm = new Vector3D[numNorms]; double delS = (smax - smin)/numS; double delT = (tmax - tmin)/numT; double s = smin; int k = 0; for (int i = 0; i <= numS; i++) { double t = tmin; for (int j = 0; j <= numT; j++) { pt[k] = f(s, t); norm[k++] = (dfds(s, t).cross(dfdt(s, t))).normalize(); t += delT; } s += delS; } return; } void Mesh::readMesh(string fname) { /* ifstream fin; fin.open(fname.c_str(), std::ios::in); if (fin.fail() || fin.eof()) { printf("Can't open file or eof: %s", fname.c_str()); makeEmpty(); return; } fin >> numS >> numT >> numVerts >> numNorms; pt = new Point3[numVerts]; norm = new Vector3[numNorms]; for (int i = 0; i < numVerts; i++) fin >> pt[i].x >> pt[i].y >> pt[i].z; for (int i = 0; i < numNorms; i++) fin >> norm[i].x >> norm[i].y >> norm[i].z; fin.close();*/ return; } void Mesh::writeMesh(string fname) { /* ofstream fout; fout.open(fname.c_str(), std::ios::out); if (fout.fail() || fout.eof()) { printf("Can't open file or eof: %s", fname.c_str()); return; } fout << numS << ' ' << numT << ' ' << numVerts << ' ' << numNorms << endl; for (int i = 0; i < numVerts; i++) fout << pt[i].x << ' ' << pt[i].y << ' ' << pt[i].z << endl; for (int i = 0; i < numNorms; i++) fout << norm[i].x << ' ' << norm[i].y << ' ' << norm[i].z << endl; fout.close();*/ return; } void Mesh::drawMesh(int mode, bool normals) { if (isEmpty()) return; int oldMode[1]; glGetIntegerv(GL_POLYGON_MODE, oldMode); glPolygonMode(GL_FRONT_AND_BACK, mode); for (int j = 0; j < numT; j++) { for (int i = 0; i < numS; i++) { int p[4]; p[0] = i*(numS + 1) + j; p[1] = p[0] + 1; p[2] = p[1] + numS + 1; p[3] = p[2] - 1; glBegin(GL_POLYGON); for (int k = 0; k < 4; k++) { int m = p[k]; if (normals) glNormal3f(norm[m].x, norm[m].y, norm[m].z); glVertex3f(pt[m].x, pt[m].y, pt[m].z); } glEnd(); } } glPolygonMode(GL_FRONT_AND_BACK, oldMode[0]); return; } void Mesh::translate(float dx, float dy, float dz) { for (int i = 0; i < numVerts; i++) { pt[i].x += dx; pt[i].y += dy; pt[i].z += dz; } return; } void Mesh::rotate(float angle, float ux, float uy, float uz) { float beta = PI/180.0*angle; float c = cos(beta); float s = sin(beta); float cmp = 1 - c; float len = 1.0/sqrt(ux*ux + uy*uy + uz*uz); ux *= len; uy *= len; uz *= len; float newx, newy, newz; for (int i = 0; i < numVerts; i++) { newx = pt[i].x*(c + cmp*ux*ux) + pt[i].y*(cmp*ux*uy - s*uz) + pt[i].z*(cmp*ux*uz + s*uy); newy = pt[i].x*(cmp*ux*uy + s*uz) + pt[i].y*(c + cmp*uy*uy) + pt[i].z*(cmp*uy*uz - s*ux); newz = pt[i].x*(cmp*ux*uz - s*uy) + pt[i].y*(cmp*uy*uz + s*ux) + pt[i].z*(c + cmp*uz*uz); pt[i].x = newx; pt[i].y = newy; pt[i].z = newz; } for (int i = 0; i < numNorms; i++) { newx = norm[i].x*(c + cmp*ux*ux) + norm[i].y*(cmp*ux*uy - s*uz) + norm[i].z*(cmp*ux*uz + s*uy); newy = norm[i].x*(cmp*ux*uy + s*uz) + norm[i].y*(c + cmp*uy*uy) + norm[i].z*(cmp*uy*uz - s*ux); newz = norm[i].x*(cmp*ux*uz - s*uy) + norm[i].y*(cmp*uy*uz + s*ux) + norm[i].z*(c + cmp*uz*uz); norm[i].x = newx; norm[i].y = newy; norm[i].z = newz; } return; } void Mesh::scale(float sx, float sy, float sz) { for (int i = 0; i < numVerts; i++) { pt[i].x *= sx; pt[i].y *= sy; pt[i].z *= sz; } for (int i = 0; i < numNorms; i++) { norm[i].x /= sx; norm[i].y /= sy; norm[i].z /= sz; norm[i].normalize(); } return; } void Mesh::copy(const Mesh& m) { numS = m.numS; numT = m.numT; numVerts = m.numVerts; numNorms = m.numNorms; pt = new Point3D[numVerts]; norm = new Vector3D[numNorms]; for (int i = 0; i < numVerts; i++) pt[i] = m.pt[i]; for (int i = 0; i < numNorms; i++) norm[i] = m.norm[i]; return; }