00001
00002
00003
00004 #ifndef Face_H
00005 #define Face_H
00006
00007
00008 #include "point3d.h"
00009
00010 #include "node.h"
00011
00012 #include "nodearray.h"
00013 #include "edgearray.h"
00014 #include "facearray.h"
00015 #include "tetraarray.h"
00016
00017 class Node;
00018 class Edge;
00019 class Tetra;
00020 class NodeArray;
00021 class EdgeArray;
00022 class FaceArray;
00023 class TetraArray;
00024 class BoundingSphereLeaf;
00025
00026 class Face {
00027 private:
00028 Node *node[3];
00029 Edge *edge[3];
00030
00031 FaceArray* facearray_p;
00032
00033 ReallocableArray<Tetra*> tetra;
00034
00035 Point3D normal;
00036
00037 Point3D isobary;
00038 int marker;
00039
00040 Node* splitNode[2];
00041 Edge* splitEdge[2];
00042 int num_split_edges;
00043 Node* fakeSplitNode[2];
00044
00045
00046 BoundingSphereLeaf* boundingsphere;
00047
00048 public:
00049 Face();
00050 ~Face();
00051 static const char* rcsid;
00052 static int debug;
00053
00054 void init(NodeArray* nodearray_p, EdgeArray* edgearray_p,
00055 FaceArray* facearray_p, int i1, int i2, int i3);
00056 void init(NodeArray* nodearray_p, EdgeArray* edgearray_p,
00057 FaceArray* facearray_p, Node* n1, Node* n2, Node* n3);
00058 void init(NodeArray* nodearray_p, EdgeArray* edgearray_p,
00059 FaceArray* facearray_p, Node* n1, Node* n2, Node* n3,
00060 Edge* e1, Edge* e2, Edge* e3);
00061
00062 int getIndex(void);
00063 FaceArray* getFaceArray();
00064
00065 BoundingSphereLeaf* getBoundingSphere();
00066 void setBoundingSphere(BoundingSphereLeaf* sphere);
00067
00068
00069 int hasNodeLink(Node* node);
00070 Node* getNodeLink(int which);
00071 Node* getOppositeNode(Edge *e);
00072 Node* getOtherNode(Node* n0, Node* n1);
00073 int getNodeIndex(Node* n);
00074
00075
00076 void replaceNodeLink(Node* old_node, Node* new_node);
00077 void replaceNodeLink(int which, Node* new_node);
00078
00079 void replaceEdgeLink(Edge* old_edge, Edge* new_edge);
00080 int hasEdgeLink(Edge* edge);
00081 Edge* getEdgeLink(int which);
00082 int getEdgeLinkIndex(Edge* edge);
00083 Edge* getEdge(int n0, int n1);
00084
00085 Tetra* getTetraLink(int which);
00086
00087 int numTetraLinks();
00088 void addTetraLink(Tetra* t);
00089 void deleteTetraLink(Tetra* t);
00090 int hasTetraLink(Tetra* t);
00091
00092 int stepOffVerts(Point3D intPt);
00093 int stepOffEdges(Point3D intPt);
00094 void interpolateTextureCoords(Node* n);
00095
00096 Node* getSplitNode(int which);
00097 void setSplitNodes(Node* node0, Node* node1);
00098
00099 Node* getFakeSplitNode(int which);
00100 void setFakeSplitNodes(Node* node0, Node* node1);
00101
00102 Edge* getSplitEdge(int which);
00103 void setSplitEdge(Edge* e);
00104 int getNumSplitEdges();
00105
00106 int getCase(int (&v)[9]);
00107
00108 void unlink();
00109
00110 void getAdjacentFaces(Face** f1_p, Face** f2_p, Face** f3_p);
00111 int isAdjacent(Face *f);
00112 Edge* isEdgeAdjacent(Face *f);
00113 Point3D getSatelite(Face *f, Node *p);
00114
00115
00116
00117 void SaveAsMesh(ostream& os);
00118
00119 void setNormal(Point3D normal_in);
00120 void computenormal();
00121 Point3D getNormal();
00122
00123 void draw(int do_texture);
00124 void drawnormal();
00125 void drawlabel(float offset);
00126 void drawmarker();
00127 void setMarker(int value);
00128
00129 int getMarker(void);
00130
00131 Point3D getCenter();
00132 double getRadius();
00133 void computeisobary();
00134 Point3D getIsobary();
00135
00136 int intersectsPlaneSweptByCuttingEdge(Edge* e_in, Point3D* intersection_p);
00137 int vectorCrossesMe(Point3D P1, Point3D P2, Point3D* intPt);
00138
00139 double ZVolume();
00140 double TetraVol(Point3D a, Point3D b, Point3D c, Point3D d);
00141 Point3D Projection(Point3D pt);
00142 int getMinZNode();
00143
00144 double getArea();
00145 double getShadowArea();
00146 double getZShadowArea();
00147
00148 Node *getThirdNode(Node *n1, Node *n2);
00149
00150 double PlaneDistanceToPoint(Point3D pt);
00151 double FaceDistanceToPoint(Point3D pt, int early_exit = 0,
00152 Point3D *nearpt = NULL);
00153
00154 int IsColliding(Point3D pt);
00155
00156 Node* getClosestNodeInFace(Point3D pt);
00157 Node* getClosestNodeInFace(Point3D pt, Node *notme);
00158
00159 void determinePlaneEq(double *a_p, double *b_p, double *c_p, double *d_p);
00160
00161 int intersectsEdge(Edge *e_in, Point3D *intersection_p);
00162 int intersectsFace(Face *f_in, Point3D *intersection_p);
00163
00164 bool intersectsEdge(Edge *edge);
00165 bool intersectsFace(Face *otherFace);
00166 bool intersectsBox(Point3D *min, Point3D *max);
00167
00168 int ResolveMyself(Face *f_in);
00169
00170 int SanityCheck(FaceArray* real_fa_p);
00171 friend ostream& operator<<(ostream& os, const Face& f);
00172 };
00173
00174 inline BoundingSphereLeaf* Face::getBoundingSphere()
00175 { return(boundingsphere); }
00176
00177 inline void Face::setBoundingSphere(BoundingSphereLeaf* sphere)
00178 { boundingsphere = sphere; }
00179
00180 inline Point3D Face::getCenter()
00181 { return ((node[0]->p + node[1]->p + node[2]->p)/3.0); }
00182
00183 inline double Face::getRadius()
00184 { double radius = 0;
00185 Point3D cent = getCenter();
00186 for (int i=0; i<3; i++) {
00187 double currad = node[i]->p.Dist(cent);
00188 if (currad > radius)
00189 radius = currad;
00190 }
00191 return radius;
00192 }
00193
00194 inline Point3D Face::getNormal()
00195 { return(normal); }
00196
00197 inline Point3D Face::getIsobary()
00198 { return(isobary); }
00199
00200 inline Node* Face::getNodeLink(int which)
00201 { if ((which < 0) || (which > 3)) return(NULL);
00202 return(node[which]);
00203 }
00204
00205 inline Edge* Face::getEdgeLink(int which)
00206 { if ((which < 0) || (which > 3)) return(NULL);
00207 return(edge[which]);
00208 }
00209 inline Tetra* Face::getTetraLink(int which)
00210 { if ((which < 0) || (which >= tetra.NumElements()))
00211 return(NULL);
00212 else return(tetra[which]);
00213 }
00214
00215 inline int Face::numTetraLinks()
00216 { return(tetra.NumElements());
00217 }
00218
00219 inline int Face::hasTetraLink(Tetra* t)
00220 { for (int i=0; i<tetra.NumElements(); i++)
00221 if (tetra[i] == t) return(1);
00222 return(0);
00223 }
00224
00225
00226 inline int Face::isAdjacent(Face *f)
00227 {
00228 if (node[0]->hasFaceLink(f) || node[1]->hasFaceLink(f) ||
00229 node[2]->hasFaceLink(f))
00230 return(1);
00231 return(0);
00232 }
00233
00234 inline FaceArray* Face::getFaceArray()
00235 { return(facearray_p); }
00236
00237 inline void Face::setMarker(int value)
00238 { marker = value; }
00239
00240 inline int Face::getMarker()
00241 { return(marker); }
00242
00243 inline void Face::computenormal()
00244 {
00245 Point3D a = node[0]->p;
00246 Point3D b = node[1]->p;
00247 Point3D c = node[2]->p;
00248
00249 Point3D u = b - a, v = c - a;
00250
00251 Point3D n(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x);
00252 double nw = sqrt(n.Squared());
00253 normal = n/nw;
00254 };
00255
00256
00257 inline void Face::computeisobary()
00258 {
00259 Point3D a = node[0]->p;
00260 Point3D b = node[1]->p;
00261 Point3D c = node[2]->p;
00262
00263 Point3D g((1.0/3.0)*(a.x+b.x+c.x), (1.0/3.0)*(a.y+b.y+c.y),
00264 (1.0/3.0)*(a.z+b.z+c.z));
00265 isobary = g;
00266 };
00267
00268 inline int Face::getNodeIndex(Node* n)
00269 {for (int i=0; i<3; i++) if (node[i] == n) return i; return -1;}
00270 inline Node* Face::getSplitNode(int which)
00271 {return splitNode[which];}
00272
00273 inline void Face::setSplitNodes(Node* node0, Node* node1)
00274 {splitNode[0] = node0; splitNode[1] = node1;}
00275
00276 inline Node* Face::getFakeSplitNode(int which)
00277 {return fakeSplitNode[which];}
00278
00279 inline void Face::setFakeSplitNodes(Node* node0, Node* node1)
00280 {fakeSplitNode[0] = node0; fakeSplitNode[1] = node1;node0->setMass(0.01); node1->setMass(0.01);}
00281
00282 inline Edge* Face::getSplitEdge(int which)
00283 {return splitEdge[which];}
00284
00285 inline void Face::setSplitEdge(Edge* e)
00286 {splitEdge[num_split_edges] = e;num_split_edges++;}
00287
00288 inline int Face::getNumSplitEdges()
00289 { return num_split_edges;}
00290
00291 #endif