MeshTopology.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <iostream>
00026 #include <sofa/component/topology/MeshTopology.h>
00027 #include <sofa/core/ObjectFactory.h>
00028 #include <sofa/helper/fixed_array.h>
00029 #include <sofa/component/MeshLoader.h>
00030 #include <sofa/helper/system/gl.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <set>
00033 #include <string.h>
00034 
00035 #include <sofa/component/MeshLoader.h>
00036 
00037 namespace sofa
00038 {
00039 
00040 namespace component
00041 {
00042 
00043 namespace topology
00044 {
00045 
00046 using namespace sofa::defaulttype;
00047 using core::componentmodel::topology::BaseMeshTopology;
00048 
00049 SOFA_DECL_CLASS(MeshTopology)
00050 
00051 int MeshTopologyClass = core::RegisterObject("Generic mesh topology")
00052 .addAlias("Mesh")
00053 .add< MeshTopology >()
00054 ;
00055 
00056 MeshTopology::MeshTopology()
00057 : nbPoints(0)
00058 , seqEdges(initData(&seqEdges,"lines","List of line indices")), validEdges(false)
00059 , seqTriangles(initData(&seqTriangles,"triangles","List of triangle indices")), validTriangles(false)
00060 , seqQuads(initData(&seqQuads,"quads","List of quad indices")), validQuads(false)
00061 , seqTetras(initData(&seqTetras,"tetras","List of tetra indices")), validTetras(false)
00062 , seqHexas(initData(&seqHexas,"hexas","List of hexa indices")), validHexas(false)
00063 , revision(0)
00064 , _draw(initData(&_draw, false, "drawHexas","if true, draw the topology hexahedra"))
00065 {
00066 }
00067 
00068 void MeshTopology::init()
00069 {
00070     sofa::component::MeshLoader* loader;
00071     this->getContext()->get(loader);
00072     
00073     if(loader)
00074     {
00075         loadFromMeshLoader(loader);
00076     }
00077 
00078     // compute the number of points, if the topology is charged from the scene or if it was loaded from a MeshLoader without any points data.
00079     if (nbPoints==0)
00080     {
00081         unsigned int n = 0;
00082         for (unsigned int i=0; i<seqEdges.getValue().size();i++)
00083         {
00084             for (unsigned int j=0; j<seqEdges.getValue()[i].size();j++)
00085             {
00086                 if (n <= seqEdges.getValue()[i][j])
00087                     n = 1 + seqEdges.getValue()[i][j];
00088             }
00089         }
00090         for (unsigned int i=0; i<seqTriangles.getValue().size();i++)
00091         {
00092             for (unsigned int j=0; j<seqTriangles.getValue()[i].size();j++)
00093             {
00094                 if (n <= seqTriangles.getValue()[i][j])
00095                     n = 1 + seqTriangles.getValue()[i][j];
00096             }
00097         }
00098         for (unsigned int i=0; i<seqQuads.getValue().size();i++)
00099         {
00100             for (unsigned int j=0; j<seqQuads.getValue()[i].size();j++)
00101             {
00102                 if (n <= seqQuads.getValue()[i][j])
00103                     n = 1 + seqQuads.getValue()[i][j];
00104             }
00105         }
00106         for (unsigned int i=0; i<seqTetras.getValue().size();i++)
00107         {
00108             for (unsigned int j=0; j<seqTetras.getValue()[i].size();j++)
00109             {
00110                 if (n <= seqTetras.getValue()[i][j])
00111                     n = 1 + seqTetras.getValue()[i][j];
00112             }
00113         }
00114         for (unsigned int i=0; i<seqHexas.getValue().size();i++)
00115         {
00116             for (unsigned int j=0; j<seqHexas.getValue()[i].size();j++)
00117             {
00118                 if (n <= seqHexas.getValue()[i][j])
00119                     n = 1 + seqHexas.getValue()[i][j];
00120             }
00121         }
00122         nbPoints = n;
00123     }
00124 }
00125 
00126 void MeshTopology::loadFromMeshLoader(sofa::component::MeshLoader* loader)
00127 {
00128     nbPoints = loader->getNbPoints();
00129     seqPoints = loader->getPoints();
00130     seqEdges = loader->getEdges();
00131     seqTriangles = loader->getTriangles();
00132     seqQuads = loader->getQuads();
00133     seqTetras = loader->getTetras();         
00134     seqHexas = loader->getHexas();        
00135 }
00136 
00137 void MeshTopology::clear()
00138 {
00139     nbPoints = 0;
00140     seqEdges.beginEdit()->clear(); seqEdges.endEdit();
00141     seqTriangles.beginEdit()->clear(); seqTriangles.endEdit();
00142     seqQuads.beginEdit()->clear();seqQuads.endEdit();
00143     seqTetras.beginEdit()->clear();seqTetras.endEdit();
00144     seqHexas.beginEdit()->clear();seqHexas.endEdit();
00145     invalidate();
00146 }
00147 
00148 
00149 void MeshTopology::addPoint(double px, double py, double pz)
00150 {
00151   seqPoints.push_back(helper::make_array((SReal)px, (SReal)py, (SReal)pz));
00152     if (seqPoints.size() > (unsigned)nbPoints)
00153         nbPoints = seqPoints.size();
00154 
00155 }
00156 
00157 void MeshTopology::addEdge( int a, int b )
00158 {
00159     seqEdges.beginEdit()->push_back(Edge(a,b));
00160     seqEdges.endEdit();
00161     if (a >= (int)nbPoints) nbPoints = a+1;
00162     if (b >= (int)nbPoints) nbPoints = b+1;
00163 }
00164 
00165 void MeshTopology::addTriangle( int a, int b, int c )
00166 {
00167     seqTriangles.beginEdit()->push_back( Triangle(a,b,c) );
00168     seqTriangles.endEdit();
00169     if (a >= (int)nbPoints) nbPoints = a+1;
00170     if (b >= (int)nbPoints) nbPoints = b+1;
00171     if (c >= (int)nbPoints) nbPoints = c+1;
00172 }
00173 
00174 void MeshTopology::addQuad(int a, int b, int c, int d)
00175 {
00176     seqQuads.beginEdit()->push_back(Quad(a,b,c,d));
00177     seqQuads.endEdit();
00178     if (a >= (int)nbPoints) nbPoints = a+1;
00179     if (b >= (int)nbPoints) nbPoints = b+1;
00180     if (c >= (int)nbPoints) nbPoints = c+1;
00181     if (d >= (int)nbPoints) nbPoints = d+1;
00182 }
00183 
00184 void MeshTopology::addTetra( int a, int b, int c, int d )
00185 {
00186     seqTetras.beginEdit()->push_back( Tetra(a,b,c,d) );
00187     seqTetras.endEdit();
00188     if (a >= (int)nbPoints) nbPoints = a+1;
00189     if (b >= (int)nbPoints) nbPoints = b+1;
00190     if (c >= (int)nbPoints) nbPoints = c+1;
00191     if (d >= (int)nbPoints) nbPoints = d+1;
00192 }
00193 
00194 void MeshTopology::addHexa(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8)
00195 {
00196 #ifdef SOFA_NEW_HEXA
00197     seqHexas.beginEdit()->push_back(Hexa(p1,p2,p3,p4,p5,p6,p7,p8));
00198 #else
00199     seqHexas.beginEdit()->push_back(Hexa(p1,p2,p4,p3,p5,p6,p8,p7));
00200 #endif
00201     seqHexas.endEdit();
00202     if (p1 >= (int)nbPoints) nbPoints = p1+1;
00203     if (p2 >= (int)nbPoints) nbPoints = p2+1;
00204     if (p3 >= (int)nbPoints) nbPoints = p3+1;
00205     if (p4 >= (int)nbPoints) nbPoints = p4+1;
00206     if (p5 >= (int)nbPoints) nbPoints = p5+1;
00207     if (p6 >= (int)nbPoints) nbPoints = p6+1;
00208     if (p7 >= (int)nbPoints) nbPoints = p7+1;
00209     if (p8 >= (int)nbPoints) nbPoints = p8+1;
00210 }
00211 
00212 const MeshTopology::SeqEdges& MeshTopology::getEdges() 
00213 {
00214     if (!validEdges)
00215     {
00216         updateEdges();
00217         validEdges = true;
00218     }
00219     return seqEdges.getValue();
00220 }
00221 
00222 const MeshTopology::SeqTriangles& MeshTopology::getTriangles()
00223 {
00224     if (!validTriangles)
00225     {
00226         updateTriangles();
00227         validTriangles = true;
00228     }
00229         return seqTriangles.getValue();
00230 }
00231 
00232 const MeshTopology::SeqQuads& MeshTopology::getQuads()
00233 {
00234     if (!validQuads)
00235     {
00236         updateQuads();
00237         validQuads = true;
00238     }
00239     return seqQuads.getValue();
00240 }
00241 
00242 const MeshTopology::SeqTetras& MeshTopology::getTetras()
00243 {
00244     if (!validTetras)
00245     {
00246         updateTetras();
00247         validTetras = true;
00248     }
00249     return seqTetras.getValue();
00250 }
00251 
00252 const MeshTopology::SeqHexas& MeshTopology::getHexas()
00253 {  
00254     if (!validHexas)
00255     {
00256         updateHexas();
00257         validHexas = true;
00258     }
00259     return seqHexas.getValue();
00260 }
00261 
00262 int MeshTopology::getNbPoints() const
00263 {
00264     return nbPoints;
00265 }
00266 
00267 void MeshTopology::setNbPoints(int n)
00268 {
00269     nbPoints = n;
00270 }
00271 
00272 int MeshTopology::getNbEdges()
00273 {
00274     return getEdges().size();
00275 }
00276 
00277 int MeshTopology::getNbTriangles()
00278 {
00279     return getTriangles().size();
00280 }
00281 
00282 int MeshTopology::getNbQuads()
00283 {
00284     return getQuads().size();
00285 }
00286 
00287 int MeshTopology::getNbTetras()
00288 {
00289     return getTetras().size();
00290 }
00291 
00292 int MeshTopology::getNbHexas()
00293 {
00294     return getHexas().size();
00295 }
00296 
00297 MeshTopology::Edge MeshTopology::getEdge(index_type i)
00298 {
00299     return getEdges()[i];
00300 }
00301 
00302 MeshTopology::Triangle MeshTopology::getTriangle(index_type i)
00303 {
00304     return getTriangles()[i];
00305 }
00306 
00307 MeshTopology::Quad MeshTopology::getQuad(index_type i)
00308 {
00309     return getQuads()[i];
00310 }
00311 
00312 MeshTopology::Tetra MeshTopology::getTetra(index_type i)
00313 {
00314     return getTetras()[i];
00315 }
00316 
00317 MeshTopology::Hexa MeshTopology::getHexa(index_type i)
00318 {  
00319     return getHexas()[i];
00320 }
00321 
00322 void MeshTopology::createEdgeVertexShellArray ()
00323 {
00324     m_edgeVertexShell.resize( nbPoints );
00325 
00326     for (unsigned int i = 0; i < seqEdges.getValue().size(); ++i)
00327     {
00328         // adding edge i in the edge shell of both points
00329         m_edgeVertexShell[ seqEdges.getValue()[i][0] ].push_back( i );
00330         m_edgeVertexShell[ seqEdges.getValue()[i][1] ].push_back( i );
00331     }
00332 }
00333 
00334 void MeshTopology::createEdgeTriangleShellArray ()
00335 {
00336     m_edgeTriangleShell.resize( getNbTriangles());
00337     unsigned int j;
00338     int edgeIndex;
00339 
00340     if (seqEdges.getValue().size()>0) {
00341 
00342         for (unsigned int i = 0; i < seqTriangles.getValue().size(); ++i)
00343         {
00344             const Triangle &t=seqTriangles.getValue()[i];
00345             // adding edge i in the edge shell of both points
00346             for (j=0;j<3;++j) { 
00347                 edgeIndex=getEdgeIndex(t[(j+1)%3],t[(j+2)%3]);
00348                 assert(edgeIndex!= -1);
00349                 m_edgeTriangleShell[i][j]=edgeIndex; 
00350             }
00351         }
00352     } else {
00353         // create a temporary map to find redundant edges
00354         std::map<Edge,unsigned int> edgeMap;
00355         std::map<Edge,unsigned int>::iterator ite;
00356         Edge e;
00357         unsigned int v1,v2;
00359         for (unsigned int i = 0; i < seqTriangles.getValue().size(); ++i)
00360         {
00361             const Triangle &t=seqTriangles.getValue()[i];
00362             for (j=0;j<3;++j) { 
00363                 v1=t[(j+1)%3];
00364                 v2=t[(j+2)%3];
00365                 // sort vertices in lexicographics order
00366                 if (v1<v2) {
00367                     e=Edge(v1,v2);
00368                 } else {
00369                     e=Edge(v2,v1);
00370                 }
00371                 ite=edgeMap.find(e);
00372                 if (ite==edgeMap.end()) {
00373                 // edge not in edgeMap so create a new one
00374                     edgeIndex=edgeMap.size();
00375                     edgeMap[e]=edgeIndex;
00376                     vector<Edge> ea=seqEdges.getValue();
00377                     ea.push_back(e);
00378                     seqEdges.setValue(ea);
00379                 } else {
00380                     edgeIndex=(*ite).second;
00381                 }
00382                 m_edgeTriangleShell[i][j]=edgeIndex; 
00383             }
00384         }
00385     }
00386 }
00387 
00388 void MeshTopology::createEdgeQuadShellArray ()
00389 {
00390     m_edgeQuadShell.resize( getNbQuads());
00391     unsigned int j;
00392     int edgeIndex;
00393 
00394     if (seqEdges.getValue().size()>0) {
00395 
00396         for (unsigned int i = 0; i < seqQuads.getValue().size(); ++i)
00397         {
00398             const Quad &t=seqQuads.getValue()[i];
00399             for (j=0;j<4;++j) { 
00400                 edgeIndex=getEdgeIndex(t[(j+1)%4],t[(j+2)%4]);
00401                 assert(edgeIndex!= -1);
00402                 m_edgeQuadShell[i][j]=edgeIndex; 
00403             }
00404         }
00405     } else {
00406         // create a temporary map to find redundant edges
00407         std::map<Edge,unsigned int> edgeMap;
00408         std::map<Edge,unsigned int>::iterator ite;
00409         Edge e;
00410         unsigned int v1,v2;
00412         for (unsigned int i = 0; i < seqQuads.getValue().size(); ++i)
00413         {
00414             const Quad &t=seqQuads.getValue()[i];
00415             for (j=0;j<4;++j) { 
00416                 v1=t[(j+1)%4];
00417                 v2=t[(j+2)%4];
00418                 // sort vertices in lexicographics order
00419                 if (v1<v2) {
00420                     e=Edge(v1,v2);
00421                 } else {
00422                     e=Edge(v2,v1);
00423                 }
00424                 ite=edgeMap.find(e);
00425                 if (ite==edgeMap.end()) {
00426                 // edge not in edgeMap so create a new one
00427                     edgeIndex=edgeMap.size();
00428                     edgeMap[e]=edgeIndex;
00429                     vector<Edge> ea=seqEdges.getValue();
00430                     ea.push_back(e);
00431                     seqEdges.setValue(ea);
00432                 } else {
00433                     edgeIndex=(*ite).second;
00434                 }
00435                 m_edgeQuadShell[i][j]=edgeIndex; 
00436             }
00437         }
00438     }
00439 }
00440 
00441 void MeshTopology::createEdgeTetraShellArray ()
00442 {
00443     m_edgeTetraShell.resize( getNbTetras());
00444     unsigned int j;
00445     int edgeIndex;
00446     const unsigned int tetrahedronEdgeArray[6][2]={{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
00447 
00448     if (seqEdges.getValue().size()>0) {
00449         for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00450         {
00451             const Tetra &t=seqTetras.getValue()[i];
00452             // adding edge i in the edge shell of both points
00453             for (j=0;j<6;++j) { 
00454                 edgeIndex=getEdgeIndex(t[tetrahedronEdgeArray[j][0]],
00455                     t[tetrahedronEdgeArray[j][1]]);
00456                 assert(edgeIndex!= -1);
00457                 m_edgeTetraShell[i][j]=edgeIndex; 
00458             }
00459         }
00460     } else {
00461         // create a temporary map to find redundant edges
00462         std::map<Edge,unsigned int> edgeMap;
00463         std::map<Edge,unsigned int>::iterator ite;
00464         Edge e;
00465         unsigned int v1,v2;
00467         for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00468         {
00469             const Tetra &t=seqTetras.getValue()[i];
00470             for (j=0;j<6;++j) { 
00471                 v1=t[tetrahedronEdgeArray[j][0]];
00472                 v2=t[tetrahedronEdgeArray[j][1]];
00473                 // sort vertices in lexicographics order
00474                 if (v1<v2) {
00475                     e=Edge(v1,v2);
00476                 } else {
00477                     e=Edge(v2,v1);
00478                 }
00479                 ite=edgeMap.find(e);
00480                 if (ite==edgeMap.end()) {
00481                 // edge not in edgeMap so create a new one
00482                     edgeIndex=edgeMap.size();
00483                     edgeMap[e]=edgeIndex;
00484                     vector<Edge> ea=seqEdges.getValue();
00485                     ea.push_back(e);
00486                     seqEdges.setValue(ea);
00487                 } else {
00488                     edgeIndex=(*ite).second;
00489                 }
00490                 m_edgeTetraShell[i][j]=edgeIndex; 
00491             }
00492         }
00493     }
00494 }
00495 
00496 void MeshTopology::createEdgeHexaShellArray ()
00497 {
00498     m_edgeHexaShell.resize( getNbHexas());
00499     unsigned int j;
00500     int edgeIndex;
00501     unsigned int edgeHexahedronDescriptionArray[12][2]={{0,1},{0,3},{0,4},{1,2},{1,5},{2,3},{2,6},{3,7},{4,5},{4,7},{5,6},{6,7}};
00502 
00503     if (seqEdges.getValue().size()>0) {
00504         for (unsigned int i = 0; i < m_edgeHexaShell.size(); ++i)
00505         {
00506             const Hexa &h=seqHexas.getValue()[i];
00507             // adding edge i in the edge shell of both points
00508             for (j=0;j<12;++j) { 
00509                 edgeIndex=getEdgeIndex(h[edgeHexahedronDescriptionArray[j][0]],
00510                     h[edgeHexahedronDescriptionArray[j][1]]);
00511                 assert(edgeIndex!= -1);
00512                 m_edgeHexaShell[i][j]=edgeIndex; 
00513             }
00514         }
00515     } else {
00516         // create a temporary map to find redundant edges
00517         std::map<Edge,unsigned int> edgeMap;
00518         std::map<Edge,unsigned int>::iterator ite;
00519         Edge e;
00520         unsigned int v1,v2;
00522         for (unsigned int i = 0; i < m_edgeHexaShell.size(); ++i)
00523         {
00524             const Hexa &h=seqHexas.getValue()[i];
00525             for (j=0;j<12;++j) { 
00526                 v1=h[edgeHexahedronDescriptionArray[j][0]];
00527                 v2=h[edgeHexahedronDescriptionArray[j][1]];
00528                 // sort vertices in lexicographics order
00529                 if (v1<v2) {
00530                     e=Edge(v1,v2);
00531                 } else {
00532                     e=Edge(v2,v1);
00533                 }
00534                 ite=edgeMap.find(e);
00535                 if (ite==edgeMap.end()) {
00536                 // edge not in edgeMap so create a new one
00537                     edgeIndex=edgeMap.size();
00538                     edgeMap[e]=edgeIndex;
00539                     vector<Edge> ea=seqEdges.getValue();
00540                     ea.push_back(e);
00541                     seqEdges.setValue(ea);
00542                 } else {
00543                     edgeIndex=(*ite).second;
00544                 }
00545                 m_edgeHexaShell[i][j]=edgeIndex; 
00546             }
00547         }
00548     }
00549 }
00550 
00551 void MeshTopology::createTriangleVertexShellArray ()
00552 {
00553     m_triangleVertexShell.resize( nbPoints );
00554     unsigned int j;
00555 
00556     for (unsigned int i = 0; i < seqTriangles.getValue().size(); ++i)
00557     {
00558         // adding triangle i in the triangle shell of all points
00559         for (j=0;j<3;++j) 
00560             m_triangleVertexShell[ seqTriangles.getValue()[i][j]  ].push_back( i );
00561     }
00562 }
00563 
00564 void MeshTopology::createTriangleEdgeShellArray ()
00565 {
00566     if (m_edgeTriangleShell.empty())
00567         createEdgeTriangleShellArray();
00568     m_triangleEdgeShell.resize( getNbEdges());
00569     const vector< TriangleEdges > &tea=m_edgeTriangleShell;
00570     unsigned int j;
00571 
00572     for (unsigned int i = 0; i < seqTriangles.getValue().size(); ++i)
00573     {
00574         const Triangle &t=seqTriangles.getValue()[i];
00575         // adding triangle i in the triangle shell of all edges
00576         for (j=0;j<3;++j) {
00577                 if (seqEdges.getValue()[tea[i][j]][0] == t[(j+1)%3])
00578                     m_triangleEdgeShell[ tea[i][j] ].insert(m_triangleEdgeShell[ tea[i][j] ].begin(), i); // triangle is on the left of the edge
00579                 else
00580                     m_triangleEdgeShell[ tea[i][j] ].push_back( i ); // triangle is on the right of the edge
00581         }
00582     }
00583 }
00584 
00585 void MeshTopology::createTriangleTetraShellArray ()
00586 {
00587     m_triangleTetraShell.resize( getNbTetras());
00588     unsigned int j;
00589     int triangleIndex;
00590 
00591     if (seqTriangles.getValue().size()>0) {
00592         for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00593         {
00594             const Tetra &t=seqTetras.getValue()[i];
00595             // adding triangles in the triangle list of the ith tetrahedron  i
00596             for (j=0;j<4;++j) {
00597                 triangleIndex=getTriangleIndex(t[(j+1)%4],t[(j+2)%4],t[(j+3)%4]);
00598                 assert(triangleIndex!= -1);
00599                 m_triangleTetraShell[i][j]=triangleIndex; 
00600             }
00601         }
00602     } else {
00603         // create a temporary map to find redundant triangles
00604         std::map<Triangle,unsigned int> triangleMap;
00605         std::map<Triangle,unsigned int>::iterator itt;
00606         Triangle tr;
00607         unsigned int v[3],val;
00609         for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00610         {
00611             const Tetra &t=seqTetras.getValue()[i];
00612             for (j=0;j<4;++j) { 
00613                 if (j%2) {
00614                 v[0]=t[(j+1)%4]; v[1]=t[(j+2)%4]; v[2]=t[(j+3)%4];
00615                 } else {
00616                 v[0]=t[(j+1)%4]; v[2]=t[(j+2)%4]; v[1]=t[(j+3)%4];
00617                 }
00618         //      std::sort(v,v+2);
00619                 // sort v such that v[0] is the smallest one 
00620                 while ((v[0]>v[1]) || (v[0]>v[2])) {
00621                     val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=val;
00622                 }
00623                 // check if a triangle with an opposite orientation already exists
00624                 tr=helper::make_array<unsigned int>(v[0],v[2],v[1]);
00625                 itt=triangleMap.find(tr);
00626                 if (itt==triangleMap.end()) {
00627                 // edge not in edgeMap so create a new one
00628                     triangleIndex=triangleMap.size();
00629                     tr=helper::make_array<unsigned int>(v[0],v[1],v[2]);
00630                     triangleMap[tr]=triangleIndex;
00631                     vector<Triangle> ta=seqTriangles.getValue();
00632                     ta.push_back(tr);
00633                     seqTriangles.setValue(ta);
00634                 } else {
00635                     triangleIndex=(*itt).second;
00636                 }
00637                 m_triangleTetraShell[i][j]=triangleIndex; 
00638             }
00639         }
00640     }
00641 }
00642 
00643 
00644 void MeshTopology::createQuadVertexShellArray ()
00645 {
00646     m_quadVertexShell.resize( nbPoints );
00647     unsigned int j;
00648 
00649     for (unsigned int i = 0; i < seqQuads.getValue().size(); ++i)
00650     {
00651         // adding quad i in the quad shell of all points
00652         for (j=0;j<4;++j) 
00653             m_quadVertexShell[ seqQuads.getValue()[i][j]  ].push_back( i );
00654     }
00655 }
00656 
00657 void MeshTopology::createQuadEdgeShellArray ()
00658 {
00659     if (m_edgeQuadShell.empty())
00660         createEdgeQuadShellArray();
00661     m_quadEdgeShell.resize( getNbEdges() );
00662     unsigned int j;
00663     for (unsigned int i = 0; i < seqQuads.getValue().size(); ++i)
00664     {
00665         // adding edge i in the edge shell of both points
00666         for (j=0;j<4;++j) { 
00667             m_quadEdgeShell[ m_edgeQuadShell[i][j] ].push_back( i );
00668         }
00669     }
00670 }
00671 
00672 void MeshTopology::createQuadHexaShellArray ()
00673 {
00674     m_quadHexaShell.resize(getNbHexas());
00675     int quadIndex;
00676 
00677     if (seqQuads.getValue().size()>0) {
00678         for (unsigned int i = 0; i < seqHexas.getValue().size(); ++i)
00679         {
00680             const Hexa &h=seqHexas.getValue()[i];
00681             // adding the 6 quads in the quad list of the ith hexahedron  i
00682             // Quad 0 :
00683             quadIndex=getQuadIndex(h[0],h[3],h[2],h[1]);
00684             assert(quadIndex!= -1);
00685             m_quadHexaShell[i][0]=quadIndex; 
00686             // Quad 1 :
00687             quadIndex=getQuadIndex(h[4],h[5],h[6],h[7]);
00688             assert(quadIndex!= -1);
00689             m_quadHexaShell[i][1]=quadIndex; 
00690             // Quad 2 :
00691             quadIndex=getQuadIndex(h[0],h[1],h[5],h[4]);
00692             assert(quadIndex!= -1);
00693             m_quadHexaShell[i][2]=quadIndex; 
00694             // Quad 3 :
00695             quadIndex=getQuadIndex(h[1],h[2],h[6],h[5]);
00696             assert(quadIndex!= -1);
00697             m_quadHexaShell[i][3]=quadIndex; 
00698             // Quad 4 :
00699             quadIndex=getQuadIndex(h[2],h[3],h[7],h[6]);
00700             assert(quadIndex!= -1);
00701             m_quadHexaShell[i][4]=quadIndex; 
00702             // Quad 5 :
00703             quadIndex=getQuadIndex(h[3],h[0],h[4],h[7]);
00704             assert(quadIndex!= -1);
00705             m_quadHexaShell[i][5]=quadIndex; 
00706         }
00707     } else {
00708         // create a temporary map to find redundant quads
00709         std::map<Quad,unsigned int> quadMap;
00710         std::map<Quad,unsigned int>::iterator itt;
00711         Quad qu;
00712         unsigned int v[4],val;
00714         for (unsigned int i = 0; i < seqHexas.getValue().size(); ++i)
00715         {
00716             const Hexa &h=seqHexas.getValue()[i];
00717 
00718             // Quad 0 :
00719             v[0]=h[0]; v[1]=h[3]; v[2]=h[2]; v[3]=h[1];
00720             // sort v such that v[0] is the smallest one 
00721             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00722                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00723             }
00724             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00725             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00726             //std::sort(v+2,v+3);
00727             // sort vertices in lexicographics order
00728             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00729             itt=quadMap.find(qu);
00730             if (itt==quadMap.end()) {
00731             // quad not in edgeMap so create a new one
00732                 quadIndex=seqQuads.getValue().size();
00733                 quadMap[qu]=quadIndex;
00734                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00735                 quadMap[qu]=quadIndex;
00736                 
00737                 seqQuads.beginEdit()->push_back(qu);
00738                 seqQuads.endEdit();
00739                 
00740             } else {
00741                 quadIndex=(*itt).second;
00742             }
00743             m_quadHexaShell[i][0]=quadIndex; 
00744 
00745             // Quad 1 :
00746             v[0]=h[4]; v[1]=h[5]; v[2]=h[6]; v[3]=h[7];
00747             // sort v such that v[0] is the smallest one 
00748             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00749                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00750             }
00751             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00752             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00753             //std::sort(v+2,v+3);
00754             // sort vertices in lexicographics order
00755             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00756             itt=quadMap.find(qu);
00757             if (itt==quadMap.end()) {
00758             // quad not in edgeMap so create a new one
00759                 quadIndex=seqQuads.getValue().size();
00760                 quadMap[qu]=quadIndex;
00761                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00762                 quadMap[qu]=quadIndex;
00763                 seqQuads.beginEdit()->push_back(qu);
00764                 seqQuads.endEdit();
00765             } else {
00766                 quadIndex=(*itt).second;
00767             }
00768             m_quadHexaShell[i][1]=quadIndex; 
00769 
00770             // Quad 2 :
00771             v[0]=h[0]; v[1]=h[1]; v[2]=h[5]; v[3]=h[4];
00772             // sort v such that v[0] is the smallest one 
00773             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00774                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00775             }
00776             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00777             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00778             //std::sort(v+2,v+3);
00779             // sort vertices in lexicographics order
00780             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00781             itt=quadMap.find(qu);
00782             if (itt==quadMap.end()) {
00783             // quad not in edgeMap so create a new one
00784                 quadIndex=seqQuads.getValue().size();
00785                 quadMap[qu]=quadIndex;
00786                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00787                 quadMap[qu]=quadIndex;
00788                 seqQuads.beginEdit()->push_back(qu);
00789                 seqQuads.endEdit();
00790             } else {
00791                 quadIndex=(*itt).second;
00792             }
00793             m_quadHexaShell[i][2]=quadIndex; 
00794 
00795             // Quad 3 :
00796             v[0]=h[1]; v[1]=h[2]; v[2]=h[6]; v[3]=h[5];
00797             // sort v such that v[0] is the smallest one 
00798             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00799                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00800             }
00801             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00802             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00803             //std::sort(v+2,v+3);
00804             // sort vertices in lexicographics order
00805             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00806             itt=quadMap.find(qu);
00807             if (itt==quadMap.end()) {
00808             // quad not in edgeMap so create a new one
00809                 quadIndex=seqQuads.getValue().size();
00810                 quadMap[qu]=quadIndex;
00811                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00812                 quadMap[qu]=quadIndex;
00813                 seqQuads.beginEdit()->push_back(qu);
00814                 seqQuads.endEdit();
00815             } else {
00816                 quadIndex=(*itt).second;
00817             }
00818             m_quadHexaShell[i][3]=quadIndex; 
00819 
00820             // Quad 4 :
00821             v[0]=h[2]; v[1]=h[3]; v[2]=h[7]; v[3]=h[6];
00822             // sort v such that v[0] is the smallest one 
00823             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00824                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00825             }
00826             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00827             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00828             //std::sort(v+2,v+3);
00829             // sort vertices in lexicographics order
00830             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00831             itt=quadMap.find(qu);
00832             if (itt==quadMap.end()) {
00833             // quad not in edgeMap so create a new one
00834                 quadIndex=seqQuads.getValue().size();
00835                 quadMap[qu]=quadIndex;
00836                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00837                 quadMap[qu]=quadIndex;
00838                 seqQuads.beginEdit()->push_back(qu);
00839                 seqQuads.endEdit();
00840             } else {
00841                 quadIndex=(*itt).second;
00842             }
00843             m_quadHexaShell[i][4]=quadIndex; 
00844 
00845             // Quad 5 :
00846             v[0]=h[3]; v[1]=h[0]; v[2]=h[4]; v[3]=h[7];
00847             // sort v such that v[0] is the smallest one 
00848             while ((v[0]>v[1]) || (v[0]>v[2]) || (v[0]>v[3])) {
00849                 val=v[0]; v[0]=v[1];v[1]=v[2];v[2]=v[3];v[3]=val;
00850             }
00851             //std::sort(v,v+1); std::sort(v,v+2); std::sort(v,v+3);
00852             //std::sort(v+1,v+2); std::sort(v+1,v+3);
00853             //std::sort(v+2,v+3);
00854             // sort vertices in lexicographics order
00855             qu=helper::make_array<unsigned int>(v[0],v[3],v[2],v[1]);
00856             itt=quadMap.find(qu);
00857             if (itt==quadMap.end()) {
00858             // quad not in edgeMap so create a new one
00859                 quadIndex=seqQuads.getValue().size();
00860                 quadMap[qu]=quadIndex;
00861                 qu=helper::make_array<unsigned int>(v[0],v[1],v[2],v[3]);
00862                 quadMap[qu]=quadIndex;
00863                 seqQuads.beginEdit()->push_back(qu);
00864                 seqQuads.endEdit();
00865             } else {
00866                 quadIndex=(*itt).second;
00867             }
00868             m_quadHexaShell[i][5]=quadIndex; 
00869         }
00870     }
00871 }
00872 
00873 void MeshTopology::createTetraVertexShellArray ()
00874 {
00875     m_tetraVertexShell.resize( nbPoints );
00876     unsigned int j;
00877 
00878     for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00879     {
00880         // adding edge i in the edge shell of both points
00881         for (j=0;j<4;++j) 
00882             m_tetraVertexShell[ seqTetras.getValue()[i][j]  ].push_back( i );
00883     }
00884 }
00885 
00886 void MeshTopology::createTetraEdgeShellArray ()
00887 {
00888     if (!m_edgeTetraShell.size())
00889         createEdgeTetraShellArray();
00890     m_tetraEdgeShell.resize( getNbEdges() );
00891     const vector< TetraEdges > &tea = m_edgeTetraShell;
00892     unsigned int j;
00893 
00894     for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00895     {
00896         // adding edge i in the edge shell of both points
00897         for (j=0;j<6;++j) { 
00898             m_tetraEdgeShell[ tea[i][j] ].push_back( i );
00899         }
00900     }
00901 }
00902 
00903 void MeshTopology::createTetraTriangleShellArray ()
00904 {
00905     if (!m_triangleTetraShell.size())
00906         createTriangleTetraShellArray();
00907     m_tetraTriangleShell.resize( getNbTriangles());
00908     unsigned int j;
00909     const vector< TetraTriangles > &tta=m_triangleTetraShell;
00910 
00911 
00912     for (unsigned int i = 0; i < seqTetras.getValue().size(); ++i)
00913     {
00914         // adding edge i in the edge shell of both points
00915         for (j=0;j<4;++j) { 
00916             m_tetraTriangleShell[ tta[i][j] ].push_back( i );
00917         }
00918     }
00919 }
00920 
00921 void MeshTopology::createHexaVertexShellArray ()
00922 {
00923     m_hexaVertexShell.resize( nbPoints );
00924     unsigned int j;
00925 
00926     for (unsigned int i = 0; i < seqHexas.getValue().size(); ++i)
00927     {
00928         // adding vertex i in the vertex shell
00929         for (j=0;j<8;++j) 
00930             m_hexaVertexShell[ seqHexas.getValue()[i][j]  ].push_back( i );
00931     }
00932 }
00933 
00934 void MeshTopology::createHexaEdgeShellArray ()
00935 {
00936     if (!m_edgeHexaShell.size())
00937         createEdgeHexaShellArray();
00938     m_hexaEdgeShell.resize(getNbEdges());
00939     unsigned int j;
00940     const vector< HexaEdges > &hea=m_edgeHexaShell;
00941 
00942 
00943     for (unsigned int i = 0; i < seqHexas.getValue().size(); ++i)
00944     {
00945         // adding edge i in the edge shell
00946         for (j=0;j<12;++j) { 
00947             m_hexaEdgeShell[ hea[i][j] ].push_back( i );
00948         }
00949     }
00950 }
00951 
00952 void MeshTopology::createHexaQuadShellArray ()
00953 {
00954     if (!m_quadHexaShell.size())
00955         createQuadHexaShellArray();
00956     m_hexaQuadShell.resize( getNbQuads());
00957     unsigned int j;
00958     const vector< HexaQuads > &qha=m_quadHexaShell;
00959 
00960 
00961     for (unsigned int i = 0; i < seqHexas.getValue().size(); ++i)
00962     {
00963         // adding quad i in the edge shell of both points
00964         for (j=0;j<6;++j) { 
00965             m_hexaQuadShell[ qha[i][j] ].push_back( i );
00966         }
00967     }
00968 }
00969 
00970 const MeshTopology::VertexEdges& MeshTopology::getEdgeVertexShell(PointID i) 
00971 {
00972     if (!m_edgeVertexShell.size() || i > m_edgeVertexShell.size()-1)
00973         createEdgeVertexShellArray();
00974     return m_edgeVertexShell[i];
00975 }
00976 
00977 const MeshTopology::TriangleEdges& MeshTopology::getEdgeTriangleShell(TriangleID i)
00978 {
00979     if (m_edgeTriangleShell.empty() || i > m_edgeTriangleShell.size()-1)
00980         createEdgeTriangleShellArray();
00981     return m_edgeTriangleShell[i];
00982 }
00983 
00984 const MeshTopology::QuadEdges& MeshTopology::getEdgeQuadShell(QuadID i)
00985 {
00986     if (m_edgeQuadShell.empty() || i > m_edgeQuadShell.size()-1)
00987         createEdgeQuadShellArray();
00988     return m_edgeQuadShell[i];
00989 }
00990 
00991 const MeshTopology::TetraEdges& MeshTopology::getEdgeTetraShell(TetraID i)
00992 {
00993     if (!m_edgeTetraShell.empty() || i > m_edgeTetraShell.size()-1)
00994         createEdgeTetraShellArray();
00995     return m_edgeTetraShell[i];
00996 }
00997 
00998 const MeshTopology::HexaEdges& MeshTopology::getEdgeHexaShell(HexaID i)
00999 {
01000     if (!m_edgeHexaShell.size() || i > m_edgeHexaShell.size()-1)
01001         createEdgeHexaShellArray();
01002     return m_edgeHexaShell[i];
01003 }
01004 
01005 const MeshTopology::VertexTriangles& MeshTopology::getTriangleVertexShell(PointID i) 
01006 {
01007     if (!m_triangleVertexShell.size() || i > m_triangleVertexShell.size()-1)
01008         createTriangleVertexShellArray();
01009     return m_triangleVertexShell[i];
01010 }
01011 
01012 const MeshTopology::EdgeTriangles& MeshTopology::getTriangleEdgeShell(EdgeID i) 
01013 {
01014     if (m_triangleEdgeShell.empty() || i > m_triangleEdgeShell.size()-1)
01015         createTriangleEdgeShellArray();
01016     return m_triangleEdgeShell[i];
01017 }
01018 
01019 const MeshTopology::TetraTriangles& MeshTopology::getTriangleTetraShell(TetraID i)
01020 {
01021     if (!m_triangleTetraShell.size() || i > m_triangleTetraShell.size()-1)
01022         createTriangleTetraShellArray();
01023     return m_triangleTetraShell[i];
01024 }
01025 
01026 const MeshTopology::VertexQuads& MeshTopology::getQuadVertexShell(PointID i) 
01027 {
01028     if (m_quadVertexShell.empty() || i > m_quadVertexShell.size()-1)
01029         createQuadVertexShellArray();
01030     return m_quadVertexShell[i];
01031 }
01032 
01033 const vector< MeshTopology::QuadID >& MeshTopology::getQuadEdgeShell(EdgeID i) 
01034 {
01035     if (!m_quadEdgeShell.size() || i > m_quadEdgeShell.size()-1)
01036         createQuadEdgeShellArray();
01037     return m_quadEdgeShell[i];
01038 }
01039 
01040 const MeshTopology::HexaQuads& MeshTopology::getQuadHexaShell(HexaID i) 
01041 {
01042     if (!m_quadHexaShell.size() || i > m_quadHexaShell.size()-1)
01043         createQuadHexaShellArray();
01044     return m_quadHexaShell[i];
01045 }
01046 
01047 const MeshTopology::VertexTetras& MeshTopology::getTetraVertexShell(PointID i) 
01048 {
01049     if (!m_tetraVertexShell.size() || i > m_tetraVertexShell.size()-1)
01050         createTetraVertexShellArray();
01051     return m_tetraVertexShell[i];
01052 }
01053 
01054 const MeshTopology::EdgeTetras& MeshTopology::getTetraEdgeShell(EdgeID i) 
01055 {
01056     if (!m_tetraEdgeShell.size() || i > m_tetraEdgeShell.size()-1)
01057         createTetraEdgeShellArray();
01058     return m_tetraEdgeShell[i];
01059 }
01060 
01061 const MeshTopology::TriangleTetras& MeshTopology::getTetraTriangleShell(TriangleID i) 
01062 {
01063     if (!m_tetraTriangleShell.size() || i > m_tetraTriangleShell.size()-1)
01064         createTetraTriangleShellArray();
01065     return m_tetraTriangleShell[i];
01066 }
01067 
01068 const MeshTopology::VertexHexas& MeshTopology::getHexaVertexShell(PointID i) 
01069 {
01070     if (!m_hexaVertexShell.size() || i > m_hexaVertexShell.size()-1)
01071         createHexaVertexShellArray();
01072     return m_hexaVertexShell[i];
01073 }
01074 
01075 const MeshTopology::EdgeHexas& MeshTopology::getHexaEdgeShell(EdgeID i) 
01076 {
01077     if (!m_hexaEdgeShell.size() || i > m_hexaEdgeShell.size()-1)
01078         createHexaEdgeShellArray();
01079     return m_hexaEdgeShell[i];
01080 }
01081 
01082 const MeshTopology::QuadHexas& MeshTopology::getHexaQuadShell(QuadID i) 
01083 {
01084     if (!m_hexaQuadShell.size() || i > m_hexaQuadShell.size()-1)
01085         createHexaQuadShellArray();
01086     return m_hexaQuadShell[i];
01087 }
01088 
01089 const vector< MeshTopology::VertexTriangles >& MeshTopology::getTriangleVertexShellArray() 
01090 {
01091     if (!m_triangleVertexShell.size())
01092         createTriangleVertexShellArray();
01093     return m_triangleVertexShell;
01094 }
01095 
01096 const vector< MeshTopology::VertexQuads >& MeshTopology::getQuadVertexShellArray() 
01097 {
01098     if (!m_quadVertexShell.size())
01099         createQuadVertexShellArray();
01100     return m_quadVertexShell;
01101 }
01102 
01103 int MeshTopology::getEdgeIndex(PointID v1, PointID v2){
01104      const VertexEdges &es1 = getEdgeVertexShell(v1) ;
01105      const SeqEdges &ea = getEdges();
01106      unsigned int i=0;
01107      int result= -1;
01108      while ((i<es1.size()) && (result== -1)) {
01109          const MeshTopology::Edge &e=ea[es1[i]];
01110          if ((e[0]==v2)|| (e[1]==v2))
01111              result=(int) es1[i];
01112 
01113          i++;
01114      }
01115      return result;
01116 }
01117 
01118 int MeshTopology::getTriangleIndex(PointID v1, PointID v2, PointID v3)
01119 {
01120     //const vector< VertexTriangles > &tvs=getTriangleVertexShellArray();
01121 
01122     const vector<TriangleID> &set1=getTriangleVertexShell(v1);
01123     const vector<TriangleID> &set2=getTriangleVertexShell(v2);
01124     const vector<TriangleID> &set3=getTriangleVertexShell(v3);
01125 
01126     // The destination vector must be large enough to contain the result.
01127     vector<TriangleID> out1(set1.size()+set2.size());
01128     vector<TriangleID>::iterator result1;
01129     result1 = std::set_intersection(set1.begin(),set1.end(),set2.begin(),set2.end(),out1.begin());
01130     out1.erase(result1,out1.end());
01131 
01132     vector<TriangleID> out2(set3.size()+out1.size());
01133     vector<TriangleID>::iterator result2;
01134     result2 = std::set_intersection(set3.begin(),set3.end(),out1.begin(),out1.end(),out2.begin());
01135     out2.erase(result2,out2.end());
01136 
01137     assert(out2.size()==0 || out2.size()==1);
01138 
01139     if (out2.size()==1)
01140         return (int) (out2[0]);
01141     else
01142         return -1;
01143 }
01144 
01145 int MeshTopology::getQuadIndex(PointID v1, PointID v2, PointID v3,  PointID v4){
01146     //const vector< VertexQuads > &qvs=getQuadVertexShellArray();
01147 
01148     const vector<QuadID> &set1=getQuadVertexShell(v1);
01149     const vector<QuadID> &set2=getQuadVertexShell(v2);
01150     const vector<QuadID> &set3=getQuadVertexShell(v3);
01151     const vector<QuadID> &set4=getQuadVertexShell(v4);
01152 
01153     // The destination vector must be large enough to contain the result.
01154     vector<QuadID> out1(set1.size()+set2.size());
01155     vector<QuadID>::iterator result1;
01156     result1 = std::set_intersection(set1.begin(),set1.end(),set2.begin(),set2.end(),out1.begin());
01157     out1.erase(result1,out1.end());
01158 
01159     vector<QuadID> out2(set3.size()+out1.size());
01160     vector<QuadID>::iterator result2;
01161     result2 = std::set_intersection(set3.begin(),set3.end(),out1.begin(),out1.end(),out2.begin());
01162     out2.erase(result2,out2.end());
01163 
01164     vector<QuadID> out3(set4.size()+out2.size());
01165     vector<QuadID>::iterator result3;
01166     result3 = std::set_intersection(set4.begin(),set4.end(),out2.begin(),out2.end(),out3.begin());
01167     out3.erase(result3,out3.end());
01168 
01169     assert(out3.size()==0 || out3.size()==1);
01170 
01171     if (out3.size()==1)
01172         return (int) (out3[0]);
01173     else
01174         return -1;
01175 }
01176 
01177 int MeshTopology::getTetrahedronIndex(PointID v1, PointID v2, PointID v3,  PointID v4){ 
01178 
01179     const vector<TetraID> &set1=getTetraVertexShell(v1);
01180     const vector<TetraID> &set2=getTetraVertexShell(v2);
01181     const vector<TetraID> &set3=getTetraVertexShell(v3);
01182     const vector<TetraID> &set4=getTetraVertexShell(v4);
01183 
01184     // The destination vector must be large enough to contain the result.
01185     vector<TetraID> out1(set1.size()+set2.size());
01186     vector<TetraID>::iterator result1;
01187     result1 = std::set_intersection(set1.begin(),set1.end(),set2.begin(),set2.end(),out1.begin());
01188     out1.erase(result1,out1.end());
01189 
01190     vector<TetraID> out2(set3.size()+out1.size());
01191     vector<TetraID>::iterator result2;
01192     result2 = std::set_intersection(set3.begin(),set3.end(),out1.begin(),out1.end(),out2.begin());
01193     out2.erase(result2,out2.end());
01194 
01195     vector<TetraID> out3(set4.size()+out2.size());
01196     vector<TetraID>::iterator result3;
01197     result3 = std::set_intersection(set4.begin(),set4.end(),out2.begin(),out2.end(),out3.begin());
01198     out3.erase(result3,out3.end());
01199 
01200     assert(out3.size()==0 || out3.size()==1);
01201 
01202     if (out3.size()==1)
01203         return (int) (out3[0]);
01204     else
01205         return -1;
01206 }
01207 
01208 int MeshTopology::getHexahedronIndex(PointID v1, PointID v2, PointID v3, PointID v4, PointID v5, PointID v6, PointID v7, PointID v8){   
01209 
01210     const vector<HexaID> &set1=getTetraVertexShell(v1);
01211     const vector<HexaID> &set2=getTetraVertexShell(v2);
01212     const vector<HexaID> &set3=getTetraVertexShell(v3);
01213     const vector<HexaID> &set4=getTetraVertexShell(v4);
01214     const vector<HexaID> &set5=getTetraVertexShell(v5);
01215     const vector<HexaID> &set6=getTetraVertexShell(v6);
01216     const vector<HexaID> &set7=getTetraVertexShell(v7);
01217     const vector<HexaID> &set8=getTetraVertexShell(v8);
01218 
01219     // The destination vector must be large enough to contain the result.
01220     vector<HexaID> out1(set1.size()+set2.size());
01221     vector<HexaID>::iterator result1;
01222     result1 = std::set_intersection(set1.begin(),set1.end(),set2.begin(),set2.end(),out1.begin());
01223     out1.erase(result1,out1.end());
01224 
01225     vector<HexaID> out2(set3.size()+out1.size());
01226     vector<HexaID>::iterator result2;
01227     result2 = std::set_intersection(set3.begin(),set3.end(),out1.begin(),out1.end(),out2.begin());
01228     out2.erase(result2,out2.end());
01229 
01230     vector<HexaID> out3(set4.size()+out2.size());
01231     vector<HexaID>::iterator result3;
01232     result3 = std::set_intersection(set4.begin(),set4.end(),out2.begin(),out2.end(),out3.begin());
01233     out3.erase(result3,out3.end());
01234 
01235     vector<HexaID> out4(set5.size()+set3.size());
01236     vector<HexaID>::iterator result4;
01237     result4 = std::set_intersection(set5.begin(),set5.end(),set3.begin(),set3.end(),out4.begin());
01238     out4.erase(result4,out4.end());
01239 
01240     vector<HexaID> out5(set6.size()+out4.size());
01241     vector<HexaID>::iterator result5;
01242     result5 = std::set_intersection(set6.begin(),set6.end(),out4.begin(),out4.end(),out5.begin());
01243     out5.erase(result5,out5.end());
01244 
01245     vector<HexaID> out6(set7.size()+out5.size());
01246     vector<HexaID>::iterator result6;
01247     result6 = std::set_intersection(set7.begin(),set7.end(),out5.begin(),out5.end(),out6.begin());
01248     out6.erase(result6,out6.end());
01249 
01250     vector<HexaID> out7(set8.size()+out6.size());
01251     vector<HexaID>::iterator result7;
01252     result7 = std::set_intersection(set8.begin(),set8.end(),out6.begin(),out6.end(),out7.begin());
01253     out7.erase(result6,out7.end());
01254 
01255     assert(out7.size()==0 || out7.size()==1);
01256 
01257     if (out7.size()==1)
01258         return (int) (out7[0]);
01259     else
01260         return -1;
01261 }
01262 
01263 int MeshTopology::getVertexIndexInTriangle(const Triangle &t, PointID vertexIndex) const
01264 {
01265     if (t[0]==vertexIndex)
01266         return 0;
01267     else if (t[1]==vertexIndex)
01268         return 1;
01269     else if (t[2]==vertexIndex)
01270         return 2;
01271     else 
01272         return -1;
01273 }
01274 
01275 int MeshTopology::getEdgeIndexInTriangle(const TriangleEdges &t, EdgeID edgeIndex) const
01276 {
01277     if (t[0]==edgeIndex)
01278         return 0;
01279     else if (t[1]==edgeIndex)
01280         return 1;
01281     else if (t[2]==edgeIndex)
01282         return 2;
01283     else 
01284         return -1;
01285 }
01286 
01287 int MeshTopology::getVertexIndexInQuad(Quad &t, PointID vertexIndex) const
01288 {
01289     if(t[0]==vertexIndex)
01290         return 0;
01291     else if(t[1]==vertexIndex)
01292         return 1;
01293     else if(t[2]==vertexIndex)
01294         return 2;
01295     else if(t[3]==vertexIndex)
01296         return 3;
01297     else 
01298         return -1;
01299 }
01300 
01301 int MeshTopology::getEdgeIndexInQuad(QuadEdges &t, EdgeID edgeIndex) const
01302 {
01303     if(t[0]==edgeIndex)
01304         return 0;
01305     else if(t[1]==edgeIndex)
01306         return 1;
01307     else if(t[2]==edgeIndex)
01308         return 2;
01309     else if(t[3]==edgeIndex)
01310         return 3;
01311     else 
01312         return -1;
01313 }
01314 
01315 int MeshTopology::getVertexIndexInTetrahedron(const Tetra &t, PointID vertexIndex) const
01316 {
01317     if (t[0]==vertexIndex)
01318         return 0;
01319     else if (t[1]==vertexIndex)
01320         return 1;
01321     else if (t[2]==vertexIndex)
01322         return 2;
01323     else if (t[3]==vertexIndex)
01324         return 3;
01325     else 
01326         return -1;
01327 }
01328 
01329 int MeshTopology::getEdgeIndexInTetrahedron(const TetraEdges &t, EdgeID edgeIndex) const
01330 {
01331     if (t[0]==edgeIndex)
01332         return 0;
01333     else if (t[1]==edgeIndex)
01334         return 1;
01335     else if (t[2]==edgeIndex)
01336         return 2;
01337     else if (t[3]==edgeIndex)
01338         return 3;
01339     else if (t[4]==edgeIndex)
01340         return 4;
01341     else if (t[5]==edgeIndex)
01342         return 5;
01343     else 
01344         return -1;
01345 }
01346 
01347 int MeshTopology::getTriangleIndexInTetrahedron(const TetraTriangles &t, TriangleID triangleIndex) const
01348 {
01349     if (t[0]==triangleIndex)
01350         return 0;
01351     else if (t[1]==triangleIndex)
01352         return 1;
01353     else if (t[2]==triangleIndex)
01354         return 2;
01355     else if (t[3]==triangleIndex)
01356         return 3;
01357     else 
01358         return -1;
01359 }
01360 
01361 int MeshTopology::getVertexIndexInHexahedron(Hexa &t, PointID vertexIndex) const
01362 {
01363     if(t[0]==vertexIndex)
01364         return 0;
01365     else if(t[1]==vertexIndex)
01366         return 1;
01367     else if(t[2]==vertexIndex)
01368         return 2;
01369     else if(t[3]==vertexIndex)
01370         return 3;
01371     else if(t[4]==vertexIndex)
01372         return 4;
01373     else if(t[5]==vertexIndex)
01374         return 5;
01375     else if(t[6]==vertexIndex)
01376         return 6;
01377     else if(t[7]==vertexIndex)
01378         return 7;
01379     else 
01380         return -1;
01381 }
01382 
01383 int MeshTopology::getEdgeIndexInHexahedron(const HexaEdges &t, EdgeID edgeIndex) const
01384 {
01385     if(t[0]==edgeIndex)
01386         return 0;
01387     else if(t[1]==edgeIndex)
01388         return 1;
01389     else if(t[2]==edgeIndex)
01390         return 2;
01391     else if(t[3]==edgeIndex)
01392         return 3;
01393     else if(t[4]==edgeIndex)
01394         return 4;
01395     else if(t[5]==edgeIndex)
01396         return 5;
01397     else if(t[6]==edgeIndex)
01398         return 6;
01399     else if(t[7]==edgeIndex)
01400         return 7;
01401     else if(t[8]==edgeIndex)
01402         return 8;
01403     else if(t[9]==edgeIndex)
01404         return 9;
01405     else if(t[10]==edgeIndex)
01406         return 10;
01407     else if(t[11]==edgeIndex)
01408         return 11;
01409     else 
01410         return -1;
01411 }
01412 
01413 int MeshTopology::getQuadIndexInHexahedron(const HexaQuads &t, QuadID quadIndex) const
01414 {
01415     if(t[0]==quadIndex)
01416         return 0;
01417     else if(t[1]==quadIndex)
01418         return 1;
01419     else if(t[2]==quadIndex)
01420         return 2;
01421     else if(t[3]==quadIndex)
01422         return 3;
01423     else if(t[4]==quadIndex)
01424         return 4;
01425     else if(t[5]==quadIndex)
01426         return 5;
01427     else 
01428         return -1;
01429 }
01430 
01431 MeshTopology::Edge MeshTopology::getLocalTetrahedronEdges (const unsigned int i) const
01432 {
01433     assert(i<6);
01434     const unsigned int tetrahedronEdgeArray[6][2]={{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
01435     return MeshTopology::Edge (tetrahedronEdgeArray[i][0], tetrahedronEdgeArray[i][1]);
01436 }
01437 
01438 bool MeshTopology::hasPos() const
01439 {
01440     return !seqPoints.empty();
01441 }
01442 
01443 double MeshTopology::getPX(int i) const
01444 {
01445     return ((unsigned)i<seqPoints.size()?seqPoints[i][0]:0.0);
01446 }
01447 
01448 double MeshTopology::getPY(int i) const
01449 {
01450     return ((unsigned)i<seqPoints.size()?seqPoints[i][1]:0.0);
01451 }
01452 
01453 double MeshTopology::getPZ(int i) const
01454 {
01455     return ((unsigned)i<seqPoints.size()?seqPoints[i][2]:0.0);
01456 }
01457 
01458 void MeshTopology::invalidate()
01459 {
01460     validEdges = false;
01461     validTriangles = false;
01462     validQuads = false;
01463     validTetras = false;
01464     validHexas = false;
01465     ++revision;
01466     //std::cout << "MeshTopology::invalidate()"<<std::endl;
01467 }
01468 
01469 void MeshTopology::draw()
01470 {
01471     if (_draw.getValue())
01472     {
01473         glDisable(GL_LIGHTING);
01474 
01475         
01476         glColor3f(1,0,0);
01477         for (int i=0; i<getNbHexas(); i++)
01478         {
01479             const Hexa& c = getHexa(i);
01480             glBegin(GL_LINE_STRIP);
01481             glVertex3d(getPX(c[0]), getPY(c[0]), getPZ(c[0]));
01482             glVertex3d(getPX(c[1]), getPY(c[1]), getPZ(c[1]));
01483             glVertex3d(getPX(c[2]), getPY(c[2]), getPZ(c[2]));
01484             glVertex3d(getPX(c[3]), getPY(c[3]), getPZ(c[3]));
01485             glVertex3d(getPX(c[0]), getPY(c[0]), getPZ(c[0]));
01486             glEnd();
01487             glBegin(GL_LINE_STRIP);
01488             glVertex3d(getPX(c[4]), getPY(c[4]), getPZ(c[4]));
01489             glVertex3d(getPX(c[5]), getPY(c[5]), getPZ(c[5]));
01490             glVertex3d(getPX(c[6]), getPY(c[6]), getPZ(c[6]));
01491             glVertex3d(getPX(c[7]), getPY(c[7]), getPZ(c[7]));
01492             glVertex3d(getPX(c[4]), getPY(c[4]), getPZ(c[4]));
01493             glEnd();
01494             glBegin(GL_LINES);
01495             glVertex3d(getPX(c[3]), getPY(c[3]), getPZ(c[3]));
01496             glVertex3d(getPX(c[7]), getPY(c[7]), getPZ(c[7]));
01497             //glEnd();
01498             //glBegin(GL_LINES);
01499             glVertex3d(getPX(c[2]), getPY(c[2]), getPZ(c[2]));
01500             glVertex3d(getPX(c[6]), getPY(c[6]), getPZ(c[6]));
01501             //glEnd();
01502             //glBegin(GL_LINES);
01503             glVertex3d(getPX(c[0]), getPY(c[0]), getPZ(c[0]));
01504             glVertex3d(getPX(c[4]), getPY(c[4]), getPZ(c[4]));
01505             //glEnd();
01506             //glBegin(GL_LINES);
01507             glVertex3d(getPX(c[1]), getPY(c[1]), getPZ(c[1]));
01508             glVertex3d(getPX(c[5]), getPY(c[5]), getPZ(c[5]));
01509             glEnd();
01510         }
01511     }
01512 }
01513 
01514 } // namespace topology
01515 
01516 } // namespace component
01517 
01518 } // namespace sofa
01519 

Generated on Sun Nov 23 03:44:45 2008 for Sofa by  doxygen 1.5.7.1