//-*-c++-*- #ifndef FLEXFACE_H #define FLEXFACE_H /* James R. Diebel Stanford University Started: 29 November 2005 General templated triangular mesh face class, part of FlexMesh class structure Template parameters: - floating point type T */ #include "vec3.h" #include #include #include #include #define FF_CHECK_BOUNDS 1 #define FF_PO 2 // Forward Declarations template class FlexVertex; template class FlexFace; template class FlexEdge; template class FlexMesh; //////////////////// // FlexFace Class // //////////////////// template class FlexFace { public: // Public Data sla::Vec3 n; // normal vector of face sla::Vec3 n0; // reference normal vector sla::Vec3 x; // center of face int flag; // general purpose integer face flag // Public Methods FlexFace(); FlexVertex& v(const int i); FlexVertex& v(const int i) const; FlexFace& f(const int i); FlexFace& f(const int i) const; int numf() const; void writeTo(std::ostream& os, FlexVertex* v0); void readFrom(std::istream& is, FlexVertex* v0); void print(std::ostream& os, FlexVertex* v0) const; // Find Derived Data void findCenter(); protected: // Protected Data int nf; FlexVertex* vd[3]; // pointers to vertices that make up this face FlexFace* fd[3]; // pointers to neighboring faces FlexEdge* ed[3]; // pointers to neightboring edges // Protected members void setVertexIndices(const sla::Vec3& ind, FlexVertex* v0); sla::Vec3 getVertexIndices(FlexVertex* v0) const; friend class FlexMesh; }; // Instantiate a few instances template class FlexFace; template class FlexFace; //////////////////////////// // FlexFace Methods // //////////////////////////// // Constructor template inline FlexFace::FlexFace() { nf = 0; } // Returns reference to vertex i of this face template inline FlexVertex& FlexFace::v(const int i) { #if FF_CHECK_BOUNDS if (i < 0 || i >= 3) { printf("Vertex index %i out of range [0,%i], exiting.\n", i, 3); std::exit(1); } #endif return *(vd[i]); } // Returns const reference to vertex i of this face template inline FlexVertex& FlexFace::v(const int i) const { #if FF_CHECK_BOUNDS if (i < 0 || i >= 3) { printf("Vertex index %i out of range [0,%i], exiting.\n", i, 3); std::exit(1); } #endif return *(vd[i]); } // Returns reference to neighboring face i of this face template inline FlexFace& FlexFace::f(const int i) { #if FF_CHECK_BOUNDS if (i < 0 || i >= nf) { printf("Face: Face index %i out of range [0,%i], exiting.\n", i, nf); std::exit(1); } #endif return *(fd[i]); } // Returns const reference to neighboring face i of this face template inline FlexFace& FlexFace::f(const int i) const { #if FF_CHECK_BOUNDS if (i < 0 || i >= nf) { printf("Face: Face index %i out of range [0,%i], exiting.\n", i, nf); std::exit(1); } #endif return *(fd[i]); } // Returns the number of neighboring faces template inline int FlexFace::numf() const { return nf; } // Sets vertex i of this face to point to the given vertex template inline void FlexFace::setVertexIndices(const sla::Vec3& ind, FlexVertex* v) { for (int i=0;i<3;i++) vd[i] = &(v[ind(i)]); } // Returns the indices of the vertices of this face relative to given ref template inline sla::Vec3 FlexFace::getVertexIndices(FlexVertex* v0) const { return sla::Vec3(int(vd[0] - v0),int(vd[1] - v0),int(vd[2] - v0)); } // Writes state to stream (binary) template inline void FlexFace::writeTo(std::ostream& os, FlexVertex* v0) { sla::Vec3i ind(getVertexIndices(v0)); ind.writeTo(os); n.writeTo(os); } // Restores state from stream (binary) template inline void FlexFace::readFrom(std::istream& is, FlexVertex* v0) { sla::Vec3i ind; ind.readFrom(is); setVertexIndices(ind, v0); n.readFrom(is); } // Writes state as formated ascii to given stream template inline void FlexFace::print(std::ostream& os, FlexVertex* v0) const { sla::Vec3i ind(getVertexIndices(v0)); os << "indices: " << ind; os << "normal: " << n; } // Find Face center as average of vertex positions template inline void FlexFace::findCenter() { x.set(T(0)); for (int i=0;i<3;i++) { x += v(i).x; } x /= T(3); } #endif