Wm4ETManifoldMesh.cpp

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4ETManifoldMesh.h"
00019 using namespace Wm4;
00020 
00021 //----------------------------------------------------------------------------
00022 ETManifoldMesh::ETManifoldMesh (ECreator oECreator, TCreator oTCreator)
00023 {
00024     m_oECreator = (oECreator ? oECreator : CreateEdge);
00025     m_oTCreator = (oTCreator ? oTCreator : CreateTriangle);
00026 }
00027 //----------------------------------------------------------------------------
00028 ETManifoldMesh::~ETManifoldMesh ()
00029 {
00030     EMap::iterator pkEIter;
00031     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00032     {
00033         WM4_DELETE pkEIter->second;
00034     }
00035 
00036     TMap::iterator pkTIter;
00037     for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
00038     {
00039         WM4_DELETE pkTIter->second;
00040     }
00041 }
00042 //----------------------------------------------------------------------------
00043 ETManifoldMesh::EPtr ETManifoldMesh::CreateEdge (int iV0, int iV1)
00044 {
00045     return WM4_NEW Edge(iV0,iV1);
00046 }
00047 //----------------------------------------------------------------------------
00048 ETManifoldMesh::TPtr ETManifoldMesh::CreateTriangle (int iV0, int iV1,
00049     int iV2)
00050 {
00051     return WM4_NEW Triangle(iV0,iV1,iV2);
00052 }
00053 //----------------------------------------------------------------------------
00054 ETManifoldMesh::TPtr ETManifoldMesh::InsertTriangle (int iV0, int iV1,
00055     int iV2)
00056 {
00057     TriangleKey kTKey(iV0,iV1,iV2);
00058     TMapIterator pkTIter = m_kTMap.find(kTKey);
00059     if (pkTIter != m_kTMap.end())
00060     {
00061         // triangle already exists
00062         return 0;
00063     }
00064 
00065     // add new triangle
00066     TPtr pkTriangle = m_oTCreator(iV0,iV1,iV2);
00067     m_kTMap[kTKey] = pkTriangle;
00068 
00069     // add edges to mesh
00070     for (int i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
00071     {
00072         EdgeKey kEKey(pkTriangle->V[i0],pkTriangle->V[i1]);
00073         EPtr pkEdge;
00074         EMapIterator pkEIter = m_kEMap.find(kEKey);
00075         if (pkEIter == m_kEMap.end())
00076         {
00077             // first time edge encountered
00078             pkEdge = m_oECreator(pkTriangle->V[i0],pkTriangle->V[i1]);
00079             m_kEMap[kEKey] = pkEdge;
00080 
00081             // update edge and triangle
00082             pkEdge->T[0] = pkTriangle;
00083             pkTriangle->E[i0] = pkEdge;
00084         }
00085         else
00086         {
00087             // second time edge encountered
00088             pkEdge = pkEIter->second;
00089             assert(pkEdge);
00090 
00091             // update edge
00092             if (pkEdge->T[1])
00093             {
00094                 assert(false);  // mesh must be manifold
00095                 return 0;
00096             }
00097             pkEdge->T[1] = pkTriangle;
00098 
00099             // update adjacent triangles
00100             TPtr pkAdjacent = pkEdge->T[0];
00101             assert(pkAdjacent);
00102             for (int i = 0; i < 3; i++)
00103             {
00104                 if (pkAdjacent->E[i] == pkEdge)
00105                 {
00106                     pkAdjacent->T[i] = pkTriangle;
00107                     break;
00108                 }
00109             }
00110 
00111             // update triangle
00112             pkTriangle->E[i0] = pkEdge;
00113             pkTriangle->T[i0] = pkAdjacent;
00114         }
00115     }
00116 
00117     return pkTriangle;
00118 }
00119 //----------------------------------------------------------------------------
00120 bool ETManifoldMesh::RemoveTriangle (int iV0, int iV1, int iV2)
00121 {
00122     TriangleKey kTKey(iV0,iV1,iV2);
00123     TMapIterator pkTIter = m_kTMap.find(kTKey);
00124     if (pkTIter == m_kTMap.end())
00125     {
00126         // triangle does not exist
00127         return false;
00128     }
00129 
00130     TPtr pkTriangle = pkTIter->second;
00131     for (int i = 0; i < 3; i++)
00132     {
00133         // inform edges you are going away
00134         Edge* pkEdge = pkTriangle->E[i];
00135         assert(pkEdge);
00136         if (pkEdge->T[0] == pkTriangle)
00137         {
00138             // one-triangle edges always have pointer in slot zero
00139             pkEdge->T[0] = pkEdge->T[1];
00140             pkEdge->T[1] = 0;
00141         }
00142         else if (pkEdge->T[1] == pkTriangle)
00143         {
00144             pkEdge->T[1] = 0;
00145         }
00146         else
00147         {
00148             assert(false);
00149             return false;
00150         }
00151 
00152         // remove edge if you had the last reference to it
00153         if (!pkEdge->T[0] && !pkEdge->T[1])
00154         {
00155             EdgeKey kEKey(pkEdge->V[0],pkEdge->V[1]);
00156             m_kEMap.erase(kEKey);
00157             WM4_DELETE pkEdge;
00158         }
00159 
00160         // inform adjacent triangles you are going away
00161         TPtr pkAdjacent = pkTriangle->T[i];
00162         if (pkAdjacent)
00163         {
00164             for (int j = 0; j < 3; j++)
00165             {
00166                 if (pkAdjacent->T[j] == pkTriangle)
00167                 {
00168                     pkAdjacent->T[j] = 0;
00169                     break;
00170                 }
00171             }
00172         }
00173     }
00174 
00175     m_kTMap.erase(kTKey);
00176     WM4_DELETE pkTriangle;
00177     return true;
00178 }
00179 //----------------------------------------------------------------------------
00180 bool ETManifoldMesh::IsClosed () const
00181 {
00182     EMapCIterator pkEIter;
00183     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00184     {
00185         const Edge* pkEdge = pkEIter->second;
00186         if (!pkEdge->T[0] || !pkEdge->T[1])
00187         {
00188             return false;
00189         }
00190     }
00191     return true;
00192 }
00193 //----------------------------------------------------------------------------
00194 void ETManifoldMesh::Print (const char* acFilename)
00195 {
00196     std::ofstream kOStr(acFilename);
00197     if (!kOStr)
00198     {
00199         return;
00200     }
00201 
00202     // assign unique indices to the edges
00203     std::map<EPtr,int> kEIndex;
00204     kEIndex[0] = 0;
00205     int i = 1;
00206     EMapIterator pkEIter;
00207     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00208     {
00209         if (pkEIter->second)
00210         {
00211             kEIndex[pkEIter->second] = i++;
00212         }
00213     }
00214 
00215     // assign unique indices to the triangles
00216     std::map<TPtr,int> kTIndex;
00217     kTIndex[0] = 0;
00218     i = 1;
00219     TMapIterator pkTIter;
00220     for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
00221     {
00222         if (pkTIter->second)
00223         {
00224             kTIndex[pkTIter->second] = i++;
00225         }
00226     }
00227 
00228     // print edges
00229     kOStr << "edge quantity = " << (int)m_kEMap.size() << std::endl;
00230     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00231     {
00232         const Edge& rkEdge = *pkEIter->second;
00233         kOStr << 'e' << kEIndex[pkEIter->second] << " <"
00234               << 'v' << rkEdge.V[0] << ",v" << rkEdge.V[1] << "; ";
00235         if (rkEdge.T[0])
00236         {
00237             kOStr << 't' << kTIndex[rkEdge.T[0]];
00238         }
00239         else
00240         {
00241             kOStr << '*';
00242         }
00243         kOStr << ',';
00244         if (rkEdge.T[1])
00245         {
00246             kOStr << 't' << kTIndex[rkEdge.T[1]];
00247         }
00248         else
00249         {
00250             kOStr << '*';
00251         }
00252         kOStr << '>' << std::endl;
00253     }
00254     kOStr << std::endl;
00255 
00256     // print triangles
00257     kOStr << "triangle quantity = " << (int)m_kTMap.size() << std::endl;
00258     for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
00259     {
00260         const Triangle& rkTriangle = *pkTIter->second;
00261         kOStr << 't' << kTIndex[pkTIter->second] << " <"
00262               << 'v' << rkTriangle.V[0] << ",v" << rkTriangle.V[1] << ",v"
00263               << rkTriangle.V[2] << "; ";
00264         if (rkTriangle.E[0])
00265         {
00266             kOStr << 'e' << kEIndex[rkTriangle.E[0]];
00267         }
00268         else
00269         {
00270             kOStr << '*';
00271         }
00272         kOStr << ',';
00273         if (rkTriangle.E[1])
00274         {
00275             kOStr << 'e' << kEIndex[rkTriangle.E[1]];
00276         }
00277         else
00278         {
00279             kOStr << '*';
00280         }
00281         kOStr << ',';
00282         if (rkTriangle.E[2])
00283         {
00284             kOStr << 'e' << kEIndex[rkTriangle.E[2]];
00285         }
00286         else
00287         {
00288             kOStr << '*';
00289         }
00290         kOStr << "; ";
00291 
00292         if (rkTriangle.T[0])
00293         {
00294             kOStr << 't' << kTIndex[rkTriangle.T[0]];
00295         }
00296         else
00297         {
00298             kOStr << '*';
00299         }
00300         kOStr << ',';
00301         if (rkTriangle.T[1])
00302         {
00303             kOStr << 't' << kTIndex[rkTriangle.T[1]];
00304         }
00305         else
00306         {
00307             kOStr << '*';
00308         }
00309         kOStr << ',';
00310         if (rkTriangle.T[2])
00311         {
00312             kOStr << 't' << kTIndex[rkTriangle.T[2]];
00313         }
00314         else
00315         {
00316             kOStr << '*';
00317         }
00318         kOStr << '>' << std::endl;
00319     }
00320     kOStr << std::endl;
00321 }
00322 //----------------------------------------------------------------------------
00323 
00324 //----------------------------------------------------------------------------
00325 // ETManifoldMesh::Edge
00326 //----------------------------------------------------------------------------
00327 ETManifoldMesh::Edge::Edge (int iV0, int iV1)
00328 {
00329     V[0] = iV0;
00330     V[1] = iV1;
00331     T[0] = 0;
00332     T[1] = 0;
00333 }
00334 //----------------------------------------------------------------------------
00335 ETManifoldMesh::Edge::~Edge ()
00336 {
00337 }
00338 //----------------------------------------------------------------------------
00339 
00340 //----------------------------------------------------------------------------
00341 // ETManifoldMesh::Triangle
00342 //----------------------------------------------------------------------------
00343 ETManifoldMesh::Triangle::Triangle (int iV0, int iV1, int iV2)
00344 {
00345     V[0] = iV0;
00346     V[1] = iV1;
00347     V[2] = iV2;
00348 
00349     for (int i = 0; i < 3; i++)
00350     {
00351         E[i] = 0;
00352         T[i] = 0;
00353     }
00354 }
00355 //----------------------------------------------------------------------------
00356 ETManifoldMesh::Triangle::~Triangle ()
00357 {
00358 }
00359 //----------------------------------------------------------------------------

Generated on Wed Nov 23 19:01:03 2011 for FreeCAD by  doxygen 1.6.1