Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

MeshJoin.cc

Go to the documentation of this file.
00001 /*
00002     File:       MeshJoin.cc
00003 
00004     Notes:      Requires triangles to share a single vertex array
00005                 
00006                 Calling conventions: 
00007                     Call Init() with the number of vertices in the model
00008                     Call StartGroup() for each surface group
00009                     Call AddTriangle for all faces in that group
00010                     Call EndGroup() when done.
00011                     Repeat the last 3 calls as necessary.
00012 
00013     Author:     Andrew Willmott
00014 
00015     Notes:      
00016 */
00017 
00018 #include "MeshJoin.h"
00019 
00020 #define MJ_DBG if (0) cerr
00021 
00022 static Int tNextEdge3[3] = { 1, 2, 0 };
00023 static Int tNextEdge4[4] = { 1, 2, 3, 0 };
00024 
00025 Void MeshJoin::Init(Int numVertices)
00026 {
00027     vertexFaces = new FacePtr[numVertices];
00028     vertexEdges = new Edge[numVertices];
00029     SELF.numVertices = numVertices;
00030     surfaceVertices = numVertices;
00031 }
00032 
00033 Void MeshJoin::StartGroup()
00034 {
00035     Int     i;
00036 
00037     for (i = 0; i < numVertices; i++)
00038         vertexFaces[i] = 0;
00039     for (i = 0; i < numVertices; i++)
00040         vertexEdges[i] = 0;
00041 }
00042 
00043 Bool MeshJoin::EdgesMatch(
00044         FacePtr face1,
00045         Edge    edge1,
00046         FacePtr face2,
00047         Edge    edge2
00048     )
00049 {
00050     return(
00051         // shared vertex?
00052         (face1->index[edge1] == face2->index[edge2])
00053         // same normal?
00054         && (dot(face1->Normal(), face2->Normal()) > 0.1)
00055         // same material?
00056         && (face1->Reflectance() == face2->Reflectance())
00057     );
00058 }
00059 
00060 
00061 Void MeshJoin::AddTriangle(Face *addFace)
00062 {
00063     Int     i, j, k;
00064     Int     n = addFace->Sides();
00065     Int     *nextEdge;
00066     FacePtr curFace, *curFacePtr;
00067     Edge    curEdge, *curEdgePtr;
00068     Int     vIndex;
00069     Bool    match[4];
00070     
00071     if (addFace->IsTri())
00072         nextEdge = tNextEdge3;
00073     else
00074         nextEdge = tNextEdge4;
00075 
00076     /*
00077         Each vertex has a list of unmatched incident edges
00078         (where unmatched means that we haven't found a neighbouring
00079         triangle along that edge.)
00080         When we add a triangle, we first check to see whether
00081         an edge is present in this list. If it is, we remove it,
00082         and connect the two faces along that edge. If it is not,
00083         we add it to the list.
00084     */
00085     
00086     // for all vertices...
00087 
00088     for (i = 0; i < n; i++)
00089     {
00090         j = nextEdge[i];    // next vertex
00091         k = nextEdge[j];
00092 
00093         addFace->clrIdx[i] = addFace->index[i];
00094         
00095         MJ_DBG << "vertex " << j << " = " << addFace->index[j] << endl;
00096 
00097         // Check outgoing edge against the vertex's 
00098         // edge list.
00099         
00100         // we will be looking at vertex j
00101         // incident edge is (i)->(j), outgoing edge is (j)->(k)
00102 
00103         vIndex = addFace->index[j];
00104         
00105         // we first check the edge list at vertex (j) and try
00106         // to locate an edge which starts from vertex (i).
00107         
00108         curFacePtr = &vertexFaces[vIndex];
00109         curEdgePtr = &vertexEdges[vIndex];
00110         curFace = *curFacePtr;
00111         curEdge = *curEdgePtr;
00112                 
00113         match[j] = false;
00114 
00115         while (curFace)
00116         {
00117             // Do we have an edge match?
00118             MJ_DBG << "checking edge to vertex " << curFace->index[curEdge]
00119                     << endl;
00120             
00121             if (EdgesMatch(curFace, curEdge, addFace, k))
00122             {
00123                 MJ_DBG << "matched." << endl;
00124 
00125                 // Yes! remove curEdge from the list
00126                 *curFacePtr = curFace->nbFace[curEdge];
00127                 *curEdgePtr = curFace->nbEdge[curEdge];
00128                 
00129                 // connect the two triangles that share this edge
00130                 addFace->nbFace[j] = curFace;
00131                 addFace->nbEdge[j] = curEdge;
00132                 curFace->nbFace[curEdge] = addFace;
00133                 curFace->nbEdge[curEdge] = j;
00134                 
00135                 Assert(addFace->index[j] == curFace->index[nextEdge[curEdge]], 
00136                        "1st vertices");
00137                 Assert(addFace->index[k] == curFace->index[curEdge], 
00138                        "2nd vertices");
00139                 
00140                 // and quit.
00141                 match[j] = true;
00142                 break;
00143             }
00144 
00145             MJ_DBG << "didn't match." << endl;
00146 
00147             // If not, move on to next edge...
00148             curFacePtr = &curFace->nbFace[curEdge];
00149             curEdgePtr = &curFace->nbEdge[curEdge];
00150             curFace = *curFacePtr;
00151             curEdge = *curEdgePtr;
00152         }
00153         
00154         // If there was no match, we add the incoming edge to the vertex's
00155         // edge list.
00156     }
00157     
00158     for (i = 0; i < n; i++)
00159     {
00160         j = nextEdge[i];    // next vertex
00161 
00162         if (!match[i])
00163         {
00164             vIndex = addFace->index[j];
00165 
00166             MJ_DBG << "adding unmatched edge " << i << " to list." << endl;
00167             // set this edge to point to first member of the list...
00168             addFace->nbFace[i] = vertexFaces[vIndex];
00169             addFace->nbEdge[i] = vertexEdges[vIndex];
00170 
00171             // then set the start of the list to point to this edge
00172             vertexFaces[vIndex] = addFace;
00173             vertexEdges[vIndex] = i;
00174         }
00175     }
00176 }
00177 
00178 Void MeshJoin::SetFaceChainVertices(Face *f, Int edge, Int i)
00179 // Sets the colour index to i of all faces connected to f around
00180 // the point at the end of 'edge'.
00181 {
00182     if (!f)
00183         return;
00184         
00185     Int ccwEdge;
00186 
00187     // find the next face around the point
00188     if (f->IsTri())
00189         ccwEdge = tNextEdge3[edge];
00190     else
00191         ccwEdge = tNextEdge4[edge];
00192     
00193     f->clrIdx[ccwEdge] = i;
00194     
00195     SetFaceChainVertices(f->nbFace[ccwEdge], f->nbEdge[ccwEdge], i);
00196 }
00197 
00198 Void MeshJoin::EndGroup()
00199 {
00200     Int     i, n;
00201     FacePtr curFace, nextFace;
00202     Edge    curEdge, nextEdge;
00203     
00204     // Finally, we pass through the vertex face lists again, and
00205     // set the neighbour fields of all unmatched edges to 0,
00206     // to mark that they're not connected to anything.
00207     // (We have to do this because we've been using these fields
00208     // to help store the unconnected edge list.)
00209 
00210     // For vertices that share several disconnected faces (i.e., there
00211     // is a surface discontinuity adjacent to the edge), we must make
00212     // sure that each disconnected segment has its own colour/normal
00213     // corresponding to that vertex. Otherwise we end up using the
00214     // same colour for two faces that share a vertex but are not
00215     // continuous.
00216 
00217     for (i = 0; i < numVertices; i++)
00218     // Cycle through the remaining unmatched edges.
00219     {
00220         // head of the edge list for this vertex
00221         curFace = vertexFaces[i];
00222         curEdge = vertexEdges[i];
00223                 
00224         while (curFace)
00225         {
00226             // Store next edge...
00227             nextFace = curFace->nbFace[curEdge];
00228             nextEdge = curFace->nbEdge[curEdge];
00229 
00230             // clear nbFace pointer
00231             curFace->nbFace[curEdge] = 0;
00232 
00233             // move on to next edge in the list
00234             curFace = nextFace;
00235             curEdge = nextEdge;
00236 
00237             // Fill in a new colour index for all faces connected to this edge
00238             // around this vertex.
00239             // (Need to do this for all unmatched edges but the first one,
00240             // which retains its original setting.)
00241             if (curFace)
00242                 SetFaceChainVertices(curFace, curEdge, surfaceVertices++);
00243         }
00244     }
00245 }
00246 
00247 Int MeshJoin::Finished()
00248 {
00249     delete[] vertexFaces;
00250     delete[] vertexEdges;
00251     return(surfaceVertices);
00252 }

Generated at Sat Aug 5 00:26:52 2000 for Radiator by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000