Salome HOME
IPAL54452: Compact mesh after merge operations
authoreap <eap@opencascade.com>
Thu, 29 Aug 2019 13:19:25 +0000 (16:19 +0300)
committereap <eap@opencascade.com>
Thu, 29 Aug 2019 13:19:25 +0000 (16:19 +0300)
  Don't use elem IDs at UNV and DAT export to avoid gaps in numeration

src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/UNV2417_Structure.hxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshPartDS.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_SWIG/smeshBuilder.py

index 1cf4667b5283a65fb30f04778b1df0872d6f963c..8157374954176867f4a0093b794a0b3420cc9b2a 100644 (file)
@@ -76,11 +76,19 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
    *                       ECRITURE DES NOEUDS                                 *
    ****************************************************************************/
 
+  std::vector< size_t > nodeNumByID;
+  if ( myMesh->HasNumerationHoles() )
+    nodeNumByID.resize( myMesh->MaxNodeID() + 1 );
+
+  int num;
   SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
-  while(itNodes->more())
+  for ( num = 1; itNodes->more(); ++num )
   {
     const SMDS_MeshNode * node = itNodes->next();
-    fprintf(aFileId, "%d %.14e %.14e %.14e\n", node->GetID(), node->X(), node->Y(), node->Z());
+    fprintf(aFileId, "%d %.14e %.14e %.14e\n", num, node->X(), node->Y(), node->Z());
+
+    if ( !nodeNumByID.empty() )
+      nodeNumByID[ node->GetID() ] = num;
   }
 
   /****************************************************************************
@@ -88,47 +96,46 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
    ****************************************************************************/
   /* Ecriture des connectivites, noms, numeros des mailles */
 
-  SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator();
-  while(itEdges->more())
+  num = 1;
+  for ( SMDS_EdgeIteratorPtr itEdges = myMesh->edgesIterator(); itEdges->more(); ++num )
   {
     const SMDS_MeshElement * elem = itEdges->next();
-    switch (elem->NbNodes())
+    fprintf(aFileId, "%d %d ", num, 100 + elem->NbNodes());
+
+    for ( SMDS_ElemIteratorPtr it = elem->nodesIterator(); it->more(); )
     {
-    case 2:
-      fprintf(aFileId, "%d %d ", elem->GetID(), 102);
-      break;
-    case 3:
-      fprintf(aFileId, "%d %d ", elem->GetID(), 103);
-      break;
+      int nodeID = it->next()->GetID();
+      if ( !nodeNumByID.empty() )
+        nodeID = nodeNumByID[ nodeID ];
+      fprintf(aFileId, "%d ", nodeID );
     }
-    SMDS_ElemIteratorPtr it=elem->nodesIterator();
-    while(it->more())
-      fprintf(aFileId, "%d ", it->next()->GetID());
     fprintf(aFileId, "\n");
   }
 
-  SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator();
-  while(itFaces->more())
+  for ( SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator(); itFaces->more(); ++num )
   {
     const SMDS_MeshElement * elem = itFaces->next();
-    if ( elem->IsPoly() )
-      fprintf(aFileId, "%d %d ", elem->GetID(), 400+elem->NbNodes());
-    else
-      fprintf(aFileId, "%d %d ", elem->GetID(), 200+elem->NbNodes());
-    SMDS_ElemIteratorPtr it=elem->nodesIterator();
-    while(it->more())
-      fprintf(aFileId, "%d ", it->next()->GetID());
+
+    fprintf(aFileId, "%d %d ", num, (elem->IsPoly() ? 400 : 200 ) + elem->NbNodes() );
+
+    for( SMDS_ElemIteratorPtr it = elem->nodesIterator(); it->more(); )
+    {
+      int nodeID = it->next()->GetID();
+      if ( !nodeNumByID.empty() )
+        nodeID = nodeNumByID[ nodeID ];
+      fprintf(aFileId, "%d ", nodeID );
+    }
     fprintf(aFileId, "\n");
   }
 
-  SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
+
   const SMDS_MeshVolume* v;
-  while(itVolumes->more())
+  for ( SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); itVolumes->more(); ++num )
   {
     const SMDS_MeshElement * elem = itVolumes->next();
     if ( elem->IsPoly() )
     {
-      fprintf(aFileId, "%d %d ", elem->GetID(), 500+elem->NbNodes());
+      fprintf(aFileId, "%d %d ", num, 500 + elem->NbNodes());
 
       if (( v = myMesh->DownCast< SMDS_MeshVolume >( elem )))
       {
@@ -143,11 +150,16 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
     }
     else
     {
-      fprintf(aFileId, "%d %d ", elem->GetID(), 300+elem->NbNodes());
+      fprintf(aFileId, "%d %d ", num, 300 + elem->NbNodes());
+    }
+
+    for( SMDS_ElemIteratorPtr it = elem->nodesIterator(); it->more(); )
+    {
+      int nodeID = it->next()->GetID();
+      if ( !nodeNumByID.empty() )
+        nodeID = nodeNumByID[ nodeID ];
+      fprintf(aFileId, "%d ", nodeID );
     }
-    SMDS_ElemIteratorPtr it=elem->nodesIterator();
-    while(it->more())
-      fprintf(aFileId, "%d ", it->next()->GetID());
 
     fprintf(aFileId, "\n");
   }
index 639cedf9cab78629ae8c5c4ec552fccd9dada8f0..e579bfaabc979e7451b6c0fa7498bd09b315daec 100644 (file)
@@ -56,17 +56,24 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
     UNV164::Write( out_stream ); // unit system
     UNV2420::Write( out_stream, myMeshName ); // Coordinate system
 
+    std::vector< size_t > nodeLabelByID;
+    if ( myMesh->HasNumerationHoles() )
+      nodeLabelByID.resize( myMesh->MaxNodeID() + 1 );
+
     {
       using namespace UNV2411;
       TDataSet aDataSet2411;
+      // -----------------------------------
       // Storing SMDS nodes to the UNV file
-      //-----------------------------------
+      // -----------------------------------
       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
       TRecord aRec;
-      while ( aNodesIter->more() )
+      for ( aRec.label = 1; aNodesIter->more(); ++aRec.label )
       {
         const SMDS_MeshNode* aNode = aNodesIter->next();
-        aRec.label    = aNode->GetID();
+        // aRec.label    = aNode->GetID(); -- IPAL54452
+        if ( !nodeLabelByID.empty() )
+          nodeLabelByID[ aNode->GetID() ] = aRec.label;
         aRec.coord[0] = aNode->X();
         aRec.coord[1] = aNode->Y();
         aRec.coord[2] = aNode->Z();
@@ -74,52 +81,67 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
       }
       UNV2411::Write(out_stream,aDataSet2411);
     }
+
+    std::vector< size_t > elemLabelByID;
+    if ( !myGroups.empty() )
+      elemLabelByID.resize( myMesh->MaxElementID() + 1 );
+
     {
       using namespace UNV2412;
       TDataSet aDataSet2412;
+      TRecord aRec;
+      aRec.label = 0;
 
+      // -------------------
       // Storing SMDS Edges
-      if(myMesh->NbEdges()){
+      // -------------------
+      if ( myMesh->NbEdges() )
+      {
         SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
-        while( anIter->more() )
+        while ( anIter->more() )
         {
           const SMDS_MeshEdge* anElem = anIter->next();
-          int aNbNodes = anElem->NbNodes();
-          TRecord aRec;
-          aRec.label = anElem->GetID();
-          aRec.node_labels.reserve(aNbNodes);
-          if( anElem->IsQuadratic() ) {
-            aRec.fe_descriptor_id = 22;
-          } else {
-            aRec.fe_descriptor_id = 11;
-          }
+          // aRec.label = anElem->GetID();  -- IPAL54452
+          ++aRec.label;
+          if ( !elemLabelByID.empty() )
+            elemLabelByID[ anElem->GetID() ] = aRec.label;
+
+          aRec.fe_descriptor_id = anElem->IsQuadratic() ? 22 : 11;
+
           SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
-          while( aNodesIter->more())
+          for ( aRec.node_labels.clear(); aNodesIter->more(); )
           {
             const SMDS_MeshNode* aNode = aNodesIter->next();
-            aRec.node_labels.push_back( aNode->GetID() );
+            if ( nodeLabelByID.empty() )
+              aRec.node_labels.push_back( aNode->GetID() );
+            else
+              aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
           }
+
           aDataSet2412.push_back(aRec);
         }
       }
 
+      // -------------------
+      // Storing SMDS Faces
+      // -------------------
       if ( myMesh->NbFaces() )
       {
         SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-        while ( anIter->more())
+        while ( anIter->more() )
         {
           const SMDS_MeshFace* anElem = anIter->next();
           if ( anElem->IsPoly() ) continue;
-          int aNbNodes = anElem->NbNodes();
-          TRecord aRec;
-          aRec.label = anElem->GetID();
-          aRec.node_labels.reserve(aNbNodes);
+
           SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
-          while( aNodesIter->more() ) {
+          for ( aRec.node_labels.clear(); aNodesIter->more();  ) {
             const SMDS_MeshNode* aNode = aNodesIter->next();
-            aRec.node_labels.push_back( aNode->GetID() );
+            if ( nodeLabelByID.empty() )
+              aRec.node_labels.push_back( aNode->GetID() );
+            else
+              aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
           }
-          switch ( aNbNodes ) {
+          switch ( anElem->NbNodes() ) {
           case 3: aRec.fe_descriptor_id = 41; break;
           case 4: aRec.fe_descriptor_id = 44; break;
           case 6: aRec.fe_descriptor_id = 42; break;
@@ -129,76 +151,94 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
           default:
             continue;
           }
+          // aRec.label = anElem->GetID(); -- IPAL54452
+          ++aRec.label;
+          if ( !elemLabelByID.empty() )
+            elemLabelByID[ anElem->GetID() ] = aRec.label;
+
           aDataSet2412.push_back(aRec);
         }
       }
 
+      // ---------------------
+      // Storing SMDS Volumes
+      // ---------------------
       if ( myMesh->NbVolumes() )
       {
         SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
-        while ( anIter->more())
+        while ( anIter->more() )
         {
           const SMDS_MeshVolume* anElem = anIter->next();
           if ( anElem->IsPoly() )
             continue;
-          int aNbNodes = anElem->NbNodes();
-          int anId = -1;
-          switch(aNbNodes) {
-          case 4:  anId = 111; break;
-          case 6:  anId = 112; break;
-          case 8:  anId = 115; break;
-          case 10: anId = 118; break;
-          case 13: anId = 114; break;
-          case 15: anId = 113; break;
+          size_t aNbNodes = anElem->NbNodes();
+          switch( aNbNodes ) {
+          case 4:  aRec.fe_descriptor_id = 111; break;
+          case 6:  aRec.fe_descriptor_id = 112; break;
+          case 8:  aRec.fe_descriptor_id = 115; break;
+          case 10: aRec.fe_descriptor_id = 118; break;
+          case 13: aRec.fe_descriptor_id = 114; break;
+          case 15: aRec.fe_descriptor_id = 113; break;
           case 20:
-          case 27: anId = 116; aNbNodes = 20; break;
+          case 27: aRec.fe_descriptor_id = 116; aNbNodes = 20; break;
           default:
             continue;
           }
-          if(anId>0){
-            TRecord aRec;
-            aRec.label = anElem->GetID();
-            aRec.fe_descriptor_id = anId;
-            aRec.node_labels.reserve(aNbNodes);
-            SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
-            while ( aNodesIter->more() && (int)aRec.node_labels.size() < aNbNodes )
-            {
-              const SMDS_MeshElement* aNode = aNodesIter->next();
-              aRec.node_labels.push_back(aNode->GetID());
-            }
-            aDataSet2412.push_back(aRec);
+          // aRec.label = anElem->GetID(); -- IPAL54452
+          ++aRec.label;
+          if ( !elemLabelByID.empty() )
+            elemLabelByID[  anElem->GetID() ] = aRec.label;
+
+          aRec.node_labels.clear();
+          SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
+          while ( aNodesIter->more() && aRec.node_labels.size() < aNbNodes )
+          {
+            const SMDS_MeshElement* aNode = aNodesIter->next();
+            if ( nodeLabelByID.empty() )
+              aRec.node_labels.push_back( aNode->GetID() );
+            else
+              aRec.node_labels.push_back( nodeLabelByID[ aNode->GetID() ]);
           }
+          aDataSet2412.push_back(aRec);
         }
       }
       UNV2412::Write(out_stream,aDataSet2412);
     }
+
+    // --------------------
+    // Storing SMDS Groups
+    // --------------------
     {
       using namespace UNV2417;
-      if (myGroups.size() > 0) {
+      if ( myGroups.size() > 0 ) {
+        TRecord aRec;
         TDataSet aDataSet2417;
         TGroupList::const_iterator aIter = myGroups.begin();
-        for (; aIter != myGroups.end(); aIter++) {
+        for ( ; aIter != myGroups.end(); aIter++ )
+        {
           SMESHDS_GroupBase* aGroupDS = *aIter;
-          TRecord aRec;
           aRec.GroupName = aGroupDS->GetStoreName();
+          aRec.NodeList.clear();
+          aRec.ElementList.clear();
 
-          int i;
           SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
-          if (aGroupDS->GetType() == SMDSAbs_Node) {
-            aRec.NodeList.resize(aGroupDS->Extent());
-            i = 0;
-            while (aIter->more()) {
-              const SMDS_MeshElement* aElem = aIter->next();
-              aRec.NodeList[i] = aElem->GetID(); 
-              i++;
+          if ( aGroupDS->GetType() == SMDSAbs_Node ) {
+            while ( aIter->more() ) {
+              const SMDS_MeshElement* aNode = aIter->next();
+              if ( nodeLabelByID.empty() )
+                aRec.NodeList.push_back( aNode->GetID() );
+              else
+                aRec.NodeList.push_back( nodeLabelByID[ aNode->GetID() ]);
             }
-          } else {
-            aRec.ElementList.resize(aGroupDS->Extent());
-            i = 0;
-            while (aIter->more()) {
+          }
+          else
+          {
+            while ( aIter->more() ) {
               const SMDS_MeshElement* aElem = aIter->next();
-              aRec.ElementList[i] = aElem->GetID(); 
-              i++;
+              if ( elemLabelByID.empty() )
+                aRec.ElementList.push_back( aElem->GetID() );
+              else
+                aRec.ElementList.push_back( elemLabelByID[ aElem->GetID() ]);
             }
           }
           // 0019936: EDF 794 SMESH : Export UNV : Node color and group id
@@ -209,39 +249,6 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
         myGroups.clear();
       }
     }
-    /*    {
-      using namespace UNV2417;
-      TDataSet aDataSet2417;
-      for ( TGroupsMap::iterator it = myGroupsMap.begin(); it != myGroupsMap.end(); it++ ) {
-        SMESH_Group*       aGroup   = it->second;
-        SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
-        if ( aGroupDS ) {
-          TRecord aRec;
-          aRec.GroupName = aGroup->GetName();
-          int i;
-          SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
-          if (aGroupDS->GetType() == SMDSAbs_Node) {
-            aRec.NodeList.resize(aGroupDS->Extent());
-            i = 0;
-            while (aIter->more()) {
-              const SMDS_MeshElement* aElem = aIter->next();
-              aRec.NodeList[i] = aElem->GetID(); 
-              i++;
-            }
-          } else {
-            aRec.ElementList.resize(aGroupDS->Extent());
-            i = 0;
-            while (aIter->more()) {
-              const SMDS_MeshElement* aElem = aIter->next();
-              aRec.ElementList[i] = aElem->GetID(); 
-              i++;
-            }
-          }
-          aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
-        }
-      }
-      UNV2417::Write(out_stream,aDataSet2417);
-      }*/
 
     out_stream.flush();
     out_stream.close();
index 2101a9261333c703525c6de8781d9b7b1d2a6eef..1c89a7e572d47920fcf511d926f7e6cefb77b36d 100644 (file)
@@ -31,7 +31,7 @@
 
 namespace UNV2417{
 
-  typedef std::vector<int> TListOfId; // Nodal connectivitiesList of Id
+  typedef std::vector<int> TListOfId; // Nodal connectivity / List of Ids
 
   struct TRecord{
     std::string GroupName;
index 25742c55bd3f31e4f94527665bccabecbfe109f0..d6a40165c1ec7fb99e9ce13bd7d3454afcc47de8 100644 (file)
@@ -2919,8 +2919,7 @@ void SMDS_Mesh::CompactMesh()
 {
   this->myCompactTime = this->myModifTime;
 
-  bool idsChange = ( myNodeFactory->CompactChangePointers() ||
-                     myCellFactory->CompactChangePointers() );
+  bool idsChange = HasNumerationHoles();
   if ( idsChange )
   {
     std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
@@ -2997,6 +2996,13 @@ bool SMDS_Mesh::IsCompacted()
   return ( this->myCompactTime == this->myModifTime );
 }
 
+//! are there holes in elements or nodes numeration
+bool SMDS_Mesh::HasNumerationHoles()
+{
+  return ( myNodeFactory->CompactChangePointers() ||
+           myCellFactory->CompactChangePointers() );
+}
+
 void SMDS_Mesh::setNbShapes( size_t nbShapes )
 {
   myNodeFactory->SetNbShapes( nbShapes );
index b42f22dbb43988fe74bf95cf1e1bf5ddac7d8762..3da801f598891de96fcb6ec2b957ef86a5421904 100644 (file)
@@ -618,7 +618,8 @@ public:
   // Renumber all nodes or elements.
 
   virtual void CompactMesh();
-  bool IsCompacted();
+  virtual bool IsCompacted();
+  virtual bool HasNumerationHoles();
 
   template<class ELEMTYPE>
     static const ELEMTYPE* DownCast( const SMDS_MeshElement* e )
@@ -677,10 +678,10 @@ public:
    */
   static int CheckMemory(const bool doNotRaise=false) throw (std::bad_alloc);
 
-  int MaxNodeID() const;
-  int MinNodeID() const;
-  int MaxElementID() const;
-  int MinElementID() const;
+  virtual int MaxNodeID() const;
+  virtual int MinNodeID() const;
+  virtual int MaxElementID() const;
+  virtual int MinElementID() const;
 
   const SMDS_MeshInfo& GetMeshInfo() const { return myInfo; }
 
index c32453a9dbc4cd61651e439f4c6b726dee890fda..1589d11b4d01aced16dc2256fb6d485aa545826e 100644 (file)
@@ -5617,23 +5617,20 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
   initData();
 
   const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
-  if(!elem) return false;
+  if ( !elem ) return false;
 
   int nbn = newIDs.length();
-  int i=0;
   vector<const SMDS_MeshNode*> aNodes(nbn);
-  int nbn1=-1;
-  for(; i<nbn; i++) {
-    const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
-    if(aNode) {
-      nbn1++;
-      aNodes[nbn1] = aNode;
-    }
+  for ( int i = 0; i < nbn; i++ ) {
+    const SMDS_MeshNode* aNode = getMeshDS()->FindNode( newIDs[ i ]);
+    if ( !aNode )
+      return false;
+    aNodes[ i ] = aNode;
   }
   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
                 << ide << ", " << newIDs << " )";
 
-  bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
+  bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], aNodes.size() );
 
   declareMeshModified( /*isReComputeSafe=*/ !res );
 
index 3e9fe82b56c7533d4b6c117aa2dd7e04715a4d80..31a3ec0d2fbe40660dc7aa7c21b6ca0af2c23419 100644 (file)
@@ -58,6 +58,12 @@ public:
 
   virtual const SMDS_MeshElement *FindElement(int IDelem) const;
 
+  virtual bool HasNumerationHoles();
+  virtual int MaxNodeID() const;
+  virtual int MinNodeID() const;
+  virtual int MaxElementID() const;
+  virtual int MinElementID() const;
+
 private:
   TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
   SMESHDS_Mesh*    _meshDS;
index 082f2914ad400880c7910dc29c7e6c5c973fd6de..f0dfcda690a590f92042954d89e247b103faf3c4 100644 (file)
@@ -6631,6 +6631,48 @@ const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
   return 0;
 }
 // -------------------------------------------------------------------------------------
+bool SMESH_MeshPartDS::HasNumerationHoles()
+{
+  if ( _meshDS ) return _meshDS->HasNumerationHoles();
+
+  return ( MinNodeID() != 1 ||
+           MaxNodeID() != NbNodes() ||
+           MinElementID() != 1 ||
+           MaxElementID() != NbElements() );
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MaxNodeID() const
+{
+  if ( _meshDS ) return _meshDS->MaxNodeID();
+  return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MinNodeID() const
+{
+  if ( _meshDS ) return _meshDS->MinNodeID();
+  return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
+}  
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MaxElementID() const
+{
+  if ( _meshDS ) return _meshDS->MaxElementID();
+  int maxID = 0;
+  for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
+    if ( !_elements[ iType ].empty() )
+      maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
+  return maxID;
+}
+// -------------------------------------------------------------------------------------
+int SMESH_MeshPartDS::MinElementID() const
+{
+  if ( _meshDS ) return _meshDS->MinElementID();
+  int minID = 0;
+  for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
+    if ( !_elements[ iType ].empty() )
+      minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
+  return minID;
+}
+// -------------------------------------------------------------------------------------
 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
 {
   if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
index 52d2451574f7651daa11cea0c9fb85fa4a6f7d57..35f4ddfd0d1f09be3ee4abb772bb6ad47bb01438 100644 (file)
@@ -2773,6 +2773,10 @@ class Mesh(metaclass = MeshMeta):
 
         Parameters:
                 group (SMESH.SMESH_GroupBase): group to remove
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         self.mesh.RemoveGroupWithContents(group)
@@ -3971,6 +3975,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True or False
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveElements(IDsOfElements)
@@ -3984,6 +3992,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True or False
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveNodes(IDsOfNodes)
@@ -3994,6 +4006,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             number of the removed nodes
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveOrphanNodes()
@@ -4469,6 +4485,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             False if proper faces were not found
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.DeleteDiag(NodeID1, NodeID2)
@@ -4599,6 +4619,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
@@ -4623,6 +4647,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
@@ -4646,6 +4674,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
@@ -4669,6 +4701,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
@@ -4686,6 +4722,10 @@ class Mesh(metaclass = MeshMeta):
                 theElements: the faces to be splitted. This can be either 
                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
                         or a list of face IDs. By default all quadrangles are split
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if isinstance( theElements, Mesh ):
@@ -4707,6 +4747,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
@@ -4723,6 +4767,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
@@ -4743,6 +4791,10 @@ class Mesh(metaclass = MeshMeta):
             * 1 if 1-3 diagonal is better, 
             * 2 if 2-4 diagonal is better, 
             * 0 if error occurs.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
 
@@ -4755,6 +4807,10 @@ class Mesh(metaclass = MeshMeta):
                 method:  flags passing splitting method:
                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if isinstance( elems, Mesh ):
@@ -4779,6 +4835,10 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
                 if None (default), all bi-quadratic elements will be split
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
@@ -4810,6 +4870,10 @@ class Mesh(metaclass = MeshMeta):
                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
                         to *startHexPoint* are split, else *startHexPoint*
                         is used to find the facet to split in all domains present in *elems*.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         # IDSource
         unRegister = genObjUnRegister()
@@ -4839,6 +4903,10 @@ class Mesh(metaclass = MeshMeta):
     def SplitQuadsNearTriangularFacets(self):
         """
         Split quadrangle faces near triangular facets of volumes
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         faces_array = self.GetElementsByType(SMESH.FACE)
         for face_id in faces_array:
@@ -4883,6 +4951,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 #    Pattern:
 #                     5.---------.6
@@ -4947,6 +5019,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 #        Pattern:     5.---------.6
 #                     /|#       /|
@@ -5104,6 +5180,10 @@ class Mesh(metaclass = MeshMeta):
 
         Warning:
             If *theSubMesh* is provided, the mesh can become non-conformal
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if isinstance( theSubMesh, Mesh ):
@@ -5131,6 +5211,10 @@ class Mesh(metaclass = MeshMeta):
 
         Warning:
             If *theSubMesh* is provided, the mesh can become non-conformal
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if theSubMesh:
@@ -6341,6 +6425,10 @@ class Mesh(metaclass = MeshMeta):
                 then the first node in the group is kept.
             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
                 invalid
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
@@ -6390,6 +6478,10 @@ class Mesh(metaclass = MeshMeta):
             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
                 If *ElementsToKeep* does not include an element to keep for some group to merge,
                 then the first element in the group is kept.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         unRegister = genObjUnRegister()
@@ -6405,6 +6497,10 @@ class Mesh(metaclass = MeshMeta):
     def MergeEqualElements(self):
         """
         Leave one element and remove all other elements built on the same nodes.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         self.editor.MergeEqualElements()
@@ -6474,6 +6570,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             a number of successfully sewed groups
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if freeBorders and isinstance( freeBorders, list ):
@@ -6505,6 +6605,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
@@ -6518,6 +6622,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
@@ -6530,6 +6638,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
@@ -6548,6 +6660,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
@@ -6556,7 +6672,7 @@ class Mesh(metaclass = MeshMeta):
 
     def ChangeElemNodes(self, ide, newIDs):
         """
-        Set new nodes for the given element.
+        Set new nodes for the given element. Number of nodes should be kept.
 
         Parameters:
             ide: the element ID