QEM_Edge.cpp

00001 // QEM_Edge.cpp : Implementation for the Edge class
00002 //
00003 // Author: Matt Loper
00004 // $Revision: 1.4 $
00005 // $Date: 2002/05/15 08:28:12 $
00006 
00007 #include "../common/standard.h"
00008 #include "QEM_Edge.h"   
00009 #include "QEM_Face.h"
00010 
00011 using namespace QEM;
00012 
00013 Edge::Edge (int FaceIndex1, int whichEdge, int VertexIndex1, int VertexIndex2)
00014 {
00015         assert (FaceIndex1 >= 0);
00016         assert (whichEdge >=0 && whichEdge <= 3);
00017         cachedCost = -1.;
00018         face1 = FaceIndex1*3 + whichEdge;
00019         face2 = -1;
00020         v1 = VertexIndex1;
00021         v2 = VertexIndex2;
00022 }
00023 
00024 
00025 
00032 VertexArray *Edge::varray;
00033 
00038 bool Edge::operator<(const Edge &e) const
00039 {
00040     if (getCachedCost() != e.getCachedCost())
00041                 return (getCachedCost() < e.getCachedCost());
00042 
00043     // if we get here, then our quadric-based costs are the same.
00044     // compare by edge length (a shorter edge == a better collapse)
00045     VertexArray &vertices = *varray;
00046 
00047         ColVector3 us   = vertices[v1] - vertices[v2];
00048         ColVector3 them = vertices[e.v1] - vertices[e.v2];
00049 
00050         return (us.getLengthSquared() < them.getLengthSquared());
00051 }
00052 
00053 
00061 bool Edge::swapVertexIndex(int from1, int from2, int to)
00062 {
00063     if (v1 == v2) // we've been given a degenerate edge
00064     {
00065         assert(!"Edge::swapVertexIndex(): called on a degenerate edge.");
00066         throw ("Edge::swapVertexIndex(): called on a degenerate edge.");
00067     }
00068 
00069     if (v1 != from1 && v2 != from1 && 
00070         v1 != from2 && v2 != from2)
00071             return false; // didn't have to swap anything
00072 
00073     if (v1 == from1 || v1 == from2) v1 = to;
00074         if (v2 == from1 || v2 == from2) v2 = to;
00075 
00076     if (v1 == v2) // we've become a degenerate edge
00077     {
00078         assert(!"Edge::swapVertexIndex(): we've created a degenerate edge.");
00079         throw ("Edge::swapVertexIndex(): we've created a degenerate edge.");
00080     }
00081 
00082     // our vertex has been swapped, so we have to update our cached cost.
00083     // if it crashes here, it means that you have probably forgotten 
00084     // to call "recalculateCosts()" before doing your first collapse
00085     VertexQuadric &vertex1 = varray->operator[](v1);
00086     VertexQuadric &vertex2 = varray->operator[](v2);
00087 
00088     // ...sum up the quadrics of our neighboring vertices...
00089     Quadric sum = vertex1.quadric + vertex2.quadric;
00090 
00091     // and try to get an optimum point. If the quadric doesn't specify an
00092     // optimum, then take an average of the two points
00093     Vertex v;
00094     if (!sum.getOptimumPoint (v))
00095     {
00096         v = (vertex1 + vertex2) / 2;
00097     }
00098 
00099     setCachedCost(sum.getCost(v));
00100 
00101     return true;
00102 }
00103 
00104 
00105 
00106 int Edge::faceIndexFirst() const
00107 { 
00108         return edgeIndexFirst()/3;
00109 }
00110 
00111 
00112 
00113 int Edge::faceIndexSecond() const
00114 { 
00115         return edgeIndexSecond()/3;
00116 }
00117 
00118 
00119 
00132 int Edge::edgeIndexFirst() const
00133 { 
00134         if (face1 == -1)
00135                 throw "Edge::edgeIndexFirst(): This edge has no first face.";
00136         
00137         return face1; 
00138 }
00139 
00140 
00141 
00145 int Edge::edgeIndexSecond() const
00146 { 
00147         if (face2 == -1)
00148                 throw "Edge::edgeIndexSecond(): This edge has no second face.";
00149         
00150         return face2; 
00151 }
00152 
00153  
00154 
00155 void Edge::setFace2(int faceIndex, int whichEdge) 
00156 { 
00157         assert (faceIndex >= 0 && whichEdge >= 0);
00158         face2 = faceIndex*3 + whichEdge; 
00159         assert (face1 != face2 && "Edge::setFace1: you're setting this edge to have two identical faces!");
00160         assert (face1/3 != face2/3 && "Edge::setFace1: you're setting this edge to have two identical faces!");
00161 }
00162 
00163 
00164 
00165 void Edge::setFace1(int faceIndex, int whichEdge) 
00166 { 
00167         assert (faceIndex >= 0 && whichEdge >= 0);
00168         face1 = faceIndex*3 + whichEdge; 
00169         assert (face1 != face2 && "Edge::setFace1: you're setting this edge to have two identical faces!");
00170         assert ((face1/3) != (face2/3) && "Edge::setFace1: you're setting this edge to have two identical faces!");
00171 }
00172 
00173 
00174 
00175 void Edge::removeFace1()
00176 {
00177         face1 = -1;
00178 }
00179 
00180 
00181 
00182 void Edge::removeFace2()
00183 {
00184         face2 = -1;
00185 }
00186 
00187 
00188 
00189 void Edge::assertValid()
00190 {
00191         assert (face1 != face2 && "Edge::assertValid(): this edge has two identical faces)");
00192         assert (v1 >= 0 && v2 >= 0 && "Edge::assertValid(): this edge has vertex indices < 0)");
00193         assert (v1 != v2 && "Edge::assertValid(): this edge is degenerate (two identical vertices)");
00194 }
00195  
00196 
00197 
00198 void Edge::printDebugString()
00199 {
00200         MTRACE("EDGE PRINTING -------------\n");
00201         MTRACE("face1 = %d.%d, ", face1/3, face1%3);
00202         MTRACE("face2 = %d.%d\n", face2/3, face2%3);
00203         MTRACE("v1    = %d, v2    = %d\n", v1, v2);
00204 }
00205 
00206 
00207 
00208 bool Edge::operator==(const Edge &e) const
00209 {
00210         if (e.v1 == v1 && e.v2 == v2)
00211                 return true;
00212         if (e.v2 == v1 && e.v1 == v2)
00213                 return true;
00214         return false;
00215 }
00216 
00217 
00218 
00219 bool Edge::operator!=(const Edge &e) const
00220 {
00221         return (!(operator==(e)));
00222 }
00223 
00224 

Generated on Tue May 21 03:34:51 2002 for Archimedes by doxygen1.2.15