Wm4VEManifoldMesh.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 "Wm4VEManifoldMesh.h"
00019 using namespace Wm4;
00020 
00021 //----------------------------------------------------------------------------
00022 VEManifoldMesh::VEManifoldMesh (VCreator oVCreator, ECreator oECreator)
00023 {
00024     m_oVCreator = (oVCreator ? oVCreator : CreateVertex);
00025     m_oECreator = (oECreator ? oECreator : CreateEdge);
00026 }
00027 //----------------------------------------------------------------------------
00028 VEManifoldMesh::~VEManifoldMesh ()
00029 {
00030     VMap::iterator pkVIter;
00031     for (pkVIter = m_kVMap.begin(); pkVIter != m_kVMap.end(); pkVIter++)
00032     {
00033         WM4_DELETE pkVIter->second;
00034     }
00035 
00036     EMap::iterator pkEIter;
00037     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00038     {
00039         WM4_DELETE pkEIter->second;
00040     }
00041 }
00042 //----------------------------------------------------------------------------
00043 VEManifoldMesh::VPtr VEManifoldMesh::CreateVertex (int iV)
00044 {
00045     return WM4_NEW Vertex(iV);
00046 }
00047 //----------------------------------------------------------------------------
00048 VEManifoldMesh::EPtr VEManifoldMesh::CreateEdge (int iV0, int iV1)
00049 {
00050     return WM4_NEW Edge(iV0,iV1);
00051 }
00052 //----------------------------------------------------------------------------
00053 VEManifoldMesh::EPtr VEManifoldMesh::InsertEdge (int iV0, int iV1)
00054 {
00055     std::pair<int,int> kEKey(iV0,iV1);
00056     EMapIterator pkEIter = m_kEMap.find(kEKey);
00057     if (pkEIter != m_kEMap.end())
00058     {
00059         // edge already exists
00060         return 0;
00061     }
00062 
00063     // add new edge
00064     EPtr pkEdge = m_oECreator(iV0,iV1);
00065     m_kEMap[kEKey] = pkEdge;
00066 
00067     // add vertices to mesh
00068     for (int i = 0; i < 2; i++)
00069     {
00070         int iV = pkEdge->V[i];
00071         VPtr pkVertex;
00072         VMapIterator pkVIter = m_kVMap.find(iV);
00073         if (pkVIter == m_kVMap.end())
00074         {
00075             // first time vertex encountered
00076             pkVertex = m_oVCreator(iV);
00077             m_kVMap[iV] = pkVertex;
00078 
00079             // update vertex
00080             pkVertex->E[0] = pkEdge;
00081         }
00082         else
00083         {
00084             // second time vertex encountered
00085             pkVertex = pkVIter->second;
00086             assert(pkVertex);
00087 
00088             // update vertex
00089             if (pkVertex->E[1])
00090             {
00091                 assert(false);  // mesh must be manifold
00092                 return 0;
00093             }
00094             pkVertex->E[1] = pkEdge;
00095 
00096             // update adjacent edge
00097             EPtr pkAdjacent = pkVertex->E[0];
00098             assert(pkAdjacent);
00099             for (int j = 0; j < 2; j++)
00100             {
00101                 if (pkAdjacent->V[j] == iV)
00102                 {
00103                     pkAdjacent->E[j] = pkEdge;
00104                     break;
00105                 }
00106             }
00107 
00108             // update edge
00109             pkEdge->E[i] = pkAdjacent;
00110         }
00111     }
00112 
00113     return pkEdge;
00114 }
00115 //----------------------------------------------------------------------------
00116 bool VEManifoldMesh::RemoveEdge (int iV0, int iV1)
00117 {
00118     std::pair<int,int> kEKey(iV0,iV1);
00119     EMapIterator pkEIter = m_kEMap.find(kEKey);
00120     if (pkEIter == m_kEMap.end())
00121     {
00122         // edge does not exist
00123         return false;
00124     }
00125 
00126     EPtr pkEdge = pkEIter->second;
00127     for (int i = 0; i < 2; i++)
00128     {
00129         // inform vertices you are going away
00130         VMapIterator pkVIter = m_kVMap.find(pkEdge->V[i]);
00131         assert(pkVIter != m_kVMap.end());
00132         Vertex* pkVertex = pkVIter->second;
00133         assert(pkVertex);
00134         if (pkVertex->E[0] == pkEdge)
00135         {
00136             // one-edge vertices always have pointer in slot zero
00137             pkVertex->E[0] = pkVertex->E[1];
00138             pkVertex->E[1] = 0;
00139         }
00140         else if (pkVertex->E[1] == pkEdge)
00141         {
00142             pkVertex->E[1] = 0;
00143         }
00144         else
00145         {
00146             assert(false);
00147             return false;
00148         }
00149 
00150         // remove vertex if you had the last reference to it
00151         if (!pkVertex->E[0] && !pkVertex->E[1])
00152         {
00153             m_kVMap.erase(pkVertex->V);
00154             WM4_DELETE pkVertex;
00155         }
00156 
00157         // inform adjacent edges you are going away
00158         EPtr pkAdjacent = pkEdge->E[i];
00159         if (pkAdjacent)
00160         {
00161             for (int j = 0; j < 2; j++)
00162             {
00163                 if (pkAdjacent->E[j] == pkEdge)
00164                 {
00165                     pkAdjacent->E[j] = 0;
00166                     break;
00167                 }
00168             }
00169         }
00170     }
00171 
00172     m_kEMap.erase(kEKey);
00173     WM4_DELETE pkEdge;
00174     return true;
00175 }
00176 //----------------------------------------------------------------------------
00177 bool VEManifoldMesh::IsClosed () const
00178 {
00179     VMapCIterator pkVIter;
00180     for (pkVIter = m_kVMap.begin(); pkVIter != m_kVMap.end(); pkVIter++)
00181     {
00182         const Vertex* pkVertex = pkVIter->second;
00183         if (!pkVertex->E[0] || !pkVertex->E[1])
00184         {
00185             return false;
00186         }
00187     }
00188     return true;
00189 }
00190 //----------------------------------------------------------------------------
00191 void VEManifoldMesh::Print (const char* acFilename)
00192 {
00193     std::ofstream kOStr(acFilename);
00194     if (!kOStr)
00195     {
00196         return;
00197     }
00198 
00199     // assign unique indices to the edges
00200     std::map<EPtr,int> kEIndex;
00201     kEIndex[0] = 0;
00202     int i = 1;
00203     EMapIterator pkEIter;
00204     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00205     {
00206         if (pkEIter->second)
00207         {
00208             kEIndex[pkEIter->second] = i++;
00209         }
00210     }
00211 
00212     // print vertices
00213     kOStr << "vertex quantity = " << (int)m_kVMap.size() << std::endl;
00214     VMapIterator pkVIter;
00215     for (pkVIter = m_kVMap.begin(); pkVIter != m_kVMap.end(); pkVIter++)
00216     {
00217         const Vertex& rkVertex = *pkVIter->second;
00218         kOStr << 'v' << rkVertex.V << " <";
00219         if (rkVertex.E[0])
00220         {
00221             kOStr << 'e' << kEIndex[rkVertex.E[0]];
00222         }
00223         else
00224         {
00225             kOStr << '*';
00226         }
00227         kOStr << ',';
00228         if (rkVertex.E[1])
00229         {
00230             kOStr << 'e'  << kEIndex[rkVertex.E[1]];
00231         }
00232         else
00233         {
00234             kOStr << '*';
00235         }
00236         kOStr << '>' << std::endl;
00237     }
00238 
00239     // print edges
00240     kOStr << "edge quantity = " << (int)m_kEMap.size() << std::endl;
00241     for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
00242     {
00243         const Edge& rkEdge = *pkEIter->second;
00244         kOStr << 'e' << kEIndex[pkEIter->second] << " <"
00245               << 'v' << rkEdge.V[0] << ",v" << rkEdge.V[1] << "; ";
00246         if (rkEdge.E[0])
00247         {
00248             kOStr << 'e' << kEIndex[rkEdge.E[0]];
00249         }
00250         else
00251         {
00252             kOStr << '*';
00253         }
00254         kOStr << ',';
00255         if (rkEdge.E[1])
00256         {
00257             kOStr << 'e' << kEIndex[rkEdge.E[1]];
00258         }
00259         else
00260         {
00261             kOStr << '*';
00262         }
00263         kOStr << '>' << std::endl;
00264     }
00265     kOStr << std::endl;
00266 }
00267 //----------------------------------------------------------------------------
00268 
00269 //----------------------------------------------------------------------------
00270 // VEManifoldMesh::Vertex
00271 //----------------------------------------------------------------------------
00272 VEManifoldMesh::Vertex::Vertex (int iV)
00273 {
00274     V = iV;
00275     E[0] = 0;
00276     E[1] = 0;
00277 }
00278 //----------------------------------------------------------------------------
00279 VEManifoldMesh::Vertex::~Vertex ()
00280 {
00281 }
00282 //----------------------------------------------------------------------------
00283 
00284 //----------------------------------------------------------------------------
00285 // VEManifoldMesh::Edge
00286 //----------------------------------------------------------------------------
00287 VEManifoldMesh::Edge::Edge (int iV0, int iV1)
00288 {
00289     V[0] = iV0;
00290     V[1] = iV1;
00291     E[0] = 0;
00292     E[1] = 0;
00293 }
00294 //----------------------------------------------------------------------------
00295 VEManifoldMesh::Edge::~Edge ()
00296 {
00297 }
00298 //----------------------------------------------------------------------------

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