#ifndef TXS_MESH_GUARD #define TXS_MESH_GUARD #include "txs_globals.h" #include "../mathlib/mathlib.h" #include #include "TxsFace.h" namespace TXS { /* * helper classes */ /* * Mesh visitors visit the vertex and face lists. */ class TxsMeshVisitor { public: /* return true to STOP traversing */ virtual bool visitVertex(TxsVertex *v) { return false; } /* return true to STOP traversing */ virtual bool visitFace(TxsFace *f) { return false; } }; class TxsMesh { private: /* * These two lists constitute the connectivity graph. */ list faces; list verts; TXS_REAL getUnitsPerPixel() { return UNITS_PER_PIXEL; } /* min/maxs */ Point mins; Point maxs; void stretchMinsMaxs(const Point &p) { for(int i = 0; i < 3; i++ ) { if(p(i) < mins(i)) mins[i] = p(i); if(p(i) > maxs(i)) maxs[i] = p(i); } } public: TxsMesh() { } ~TxsMesh() { // kill the lists completely! this->faces.clear(); this->verts.clear(); // TODO - delete objs! // TEMP DEBUG TODO memory leak here } list &getFaces() { return this->faces; } list getVerts() { return this->verts; } Point getMins() { return this->mins; } Point getMaxs() { return this->maxs; } /* * Adds a face to this mesh's list. * This will make a copy of the verts list and use that copy. * So faceVerts can be modified or freed after being passed here. */ void addFace(list &faceVerts); /* * Returns the vertex object with the given Point p * as its position. */ TxsVertex *findVertexAt(const Point &p) { TxsVertex *found = NULL; __DBd("looking for vert at " << p); list::iterator it; for(it = this->verts.begin(); it != this->verts.end(); ++it) { TxsVertex* v = *it; __DBd(" - comparing to vert at " << v->getPoint()); if(v->getPoint() == p) { found = v; __DBd("found!"); break; } } return found; } void printVertStats() { list::iterator vit; for(vit = this->verts.begin(); vit != this->verts.end(); ++vit) { TxsVertex* v = *vit; cout << "vertex at " << v->getPoint() << " has " << v->getNumIncidentFaces() << " faces" << endl; } list::iterator fit; for(fit = this->faces.begin(); fit != this->faces.end(); ++fit) { TxsFace* f = *fit; cout << "face normal: " << f->getNormal() << endl; } } /* * visitor accept * visit vertices, then faces */ void accept(TxsMeshVisitor *vtor) { list::iterator vit; for(vit = this->verts.begin(); vit != this->verts.end(); ++vit) { TxsVertex* v = *vit; bool stop = vtor->visitVertex(v); if(stop) break; } list::iterator fit; for(fit = this->faces.begin(); fit != this->faces.end(); ++fit) { TxsFace* f = *fit; bool stop = vtor->visitFace(f); if(stop) break; } } /* * Call this when all triangles have been fed */ void doneFeedingTris() { // calc all vertex normals __LOG__("calc'ing vert avg normals"); list::iterator vit; for(vit = this->verts.begin(); vit != this->verts.end(); ++vit) { TxsVertex* v = *vit; v->calcAvgNormal(); } __LOG__("DONE calc'ing vert avg normals"); __LOG__("building face nbor lists"); list::iterator fit; for(fit = this->faces.begin(); fit != this->faces.end(); ++fit) { TxsFace* f = *fit; f->calcImmediateNbors(); } __LOG__("DONE building face nbor lists"); } // graph stuff private: void detachVertex(TxsVertex *v); void detachFace(TxsFace *f); void attachFace(TxsFace *f); void collapse_valence4_vert_tris_into_quad(TxsVertex *vert); public: void collapse_tris_into_quads_around_valence_4_verts(); void phongShadeAllFaces(); }; } #endif /* TXS_MESH_GUARD */