Salome HOME
PR: merged from V5_1_4rc1
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index ed42389f991d1d1b56ac0cc794843789a693ade6..bb53cb6b6b2902169f99d0dd8e8d1afba96b9751 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -19,8 +19,9 @@
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMDS : implementaion of Salome mesh data structure
 
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
 #ifdef _MSC_VER
 #pragma warning(disable:4786)
 #endif
@@ -1084,11 +1085,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
 /// Add a polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
                                                   const int        ID)
 {
   int nbNodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
     if (!nodes[i]) return NULL;
@@ -1101,7 +1102,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
-                          (std::vector<const SMDS_MeshNode*> nodes,
+                          (vector<const SMDS_MeshNode*> nodes,
                            const int                         ID)
 {
   SMDS_MeshFace * face;
@@ -1134,7 +1135,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
 /// An ID is automatically affected to the created face.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
 {
   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
 }
@@ -1147,12 +1148,12 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> no
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
-                             (std::vector<int> nodes_ids,
-                              std::vector<int> quantities,
+                             (vector<int> nodes_ids,
+                              vector<int> quantities,
                               const int        ID)
 {
   int nbNodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
     if (!nodes[i]) return NULL;
@@ -1167,8 +1168,8 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
-                            (std::vector<const SMDS_MeshNode*> nodes,
-                             std::vector<int>                  quantities,
+                            (vector<const SMDS_MeshNode*> nodes,
+                             vector<int>                  quantities,
                              const int                         ID)
 {
   SMDS_MeshVolume* volume;
@@ -1201,8 +1202,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
-                            (std::vector<const SMDS_MeshNode*> nodes,
-                             std::vector<int>                  quantities)
+                            (vector<const SMDS_MeshNode*> nodes,
+                             vector<int>                  quantities)
 {
   int ID = myElementIDFactory->GetFreeID();
   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
@@ -1990,10 +1991,10 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 //purpose  : find polygon
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
+const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
 {
   int nbnodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
+  vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
   for (int inode = 0; inode < nbnodes; inode++) {
     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
     if (node == NULL) return NULL;
@@ -2002,22 +2003,43 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
   return FindFace(poly_nodes);
 }
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
+const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
 {
-  if ( nodes.size() > 2 && nodes[0] ) {
-    SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
-    while (itF->more()) {
-      const SMDS_MeshElement* f = itF->next();
-      if ( f->NbNodes() == nodes.size() ) {
-        SMDS_ElemIteratorPtr it2 = f->nodesIterator();
-        while(it2->more()) {
-          if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
-            f = 0;
-            break;
-          }
+  return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
+}
+
+
+//================================================================================
+/*!
+ * \brief Return element based on all given nodes
+ *  \param nodes - node of element
+ *  \param type - type of element
+ *  \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
+ *  \retval const SMDS_MeshElement* - found element or NULL
+ */
+//================================================================================
+
+const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
+                                                const SMDSAbs_ElementType            type,
+                                                const bool                           noMedium)
+{
+  if ( nodes.size() > 0 && nodes[0] )
+  {
+    SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
+    while (itF->more())
+    {
+      const SMDS_MeshElement* e = itF->next();
+      int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
+      if ( nbNodesToCheck == nodes.size() )
+      {
+        for ( int i = 1; e && i < nodes.size(); ++ i )
+        {
+          int nodeIndex = e->GetNodeIndex( nodes[ i ]);
+          if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
+            e = 0;
         }
-        if ( f )
-          return static_cast<const SMDS_MeshFace *> (f);
+        if ( e )
+          return static_cast<const SMDS_MeshFace *> (e);
       }
     }
   }
@@ -2373,10 +2395,12 @@ void SMDS_Mesh::setConstructionFaces(bool b)
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setInverseElements(bool b)
 {
-        if(!b) MESSAGE("Error : inverseElement=false not implemented");
-        myHasInverseElements=b;
+  if(!b) MESSAGE("Error : inverseElement=false not implemented");
+  myHasInverseElements=b;
 }
 
+namespace {
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Iterator on NCollection_Map
 ///////////////////////////////////////////////////////////////////////////////
@@ -2421,7 +2445,7 @@ struct MYElem_Map_Iterator: public FATHER
       _type = typ;
   }
 
-  bool more()
+bool more()
   {
       while (_ctr < _map.size())
       {
@@ -2441,17 +2465,52 @@ struct MYElem_Map_Iterator: public FATHER
   }
 };
 
+//================================================================================
+  /*!
+   * \brief Iterator on elements in id increasing order
+   */
+  //================================================================================
+
+  template <typename ELEM=const SMDS_MeshElement*>
+  class IdSortedIterator : public SMDS_Iterator<ELEM>
+  {
+    const SMDS_MeshElementIDFactory& myIDFact;
+    int                              myID, myMaxID;
+    ELEM                             myElem;
+
+  public:
+    IdSortedIterator(const SMDS_MeshElementIDFactory& fact)
+      :myIDFact( fact ), myID(1), myMaxID( myIDFact.GetMaxID() ), myElem(0)
+    {
+      next();
+    }
+    bool more()
+    {
+      return myElem;
+    }
+    ELEM next()
+    {
+      ELEM current = myElem;
+      for ( myElem = 0; myID <= myMaxID && !myElem; ++myID )
+        myElem = (ELEM) myIDFact.MeshElement( myID );
+      return current;
+    }
+  };
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Return an iterator on nodes of the current mesh factory
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
 {
-  //return SMDS_NodeIteratorPtr
-  //  (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
   typedef MYNode_Map_Iterator
     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
-  return SMDS_NodeIteratorPtr(new TIterator(myNodes));
+  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
+/*  return ( idInceasingOrder ?
+           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory )) :
+           SMDS_NodeIteratorPtr( new TIterator(myNodes)));*/
+  return ( SMDS_NodeIteratorPtr( new TIterator(myNodes)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////