Salome HOME
Merge branch 'master' into pre/penta18
[modules/smesh.git] / src / DriverCGNS / DriverCGNS_Read.cxx
index 492c1eb62a75ca2162673a512d8f5e9c22ed8cf2..c784acc9fa2f598f15b1f79eb8cca26a483025f2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -29,6 +29,7 @@
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Comment.hxx"
+#include "SMESH_TypeDefs.hxx"
 
 #include <gp_XYZ.hxx>
 
@@ -76,7 +77,9 @@ namespace
     }
     bool IsStructured() const { return ( _type == CGNS_ENUMV( Structured )); }
     int IndexSize() const { return IsStructured() ? _meshDim : 1; }
-    string ReadZonesConnection(int file, int base, const map< string, TZoneData >& zonesByName);
+    string ReadZonesConnection(int file, int base,
+                               const map< string, TZoneData >& zonesByName,
+                               SMESHDS_Mesh*                   mesh);
     void ReplaceNodes( cgsize_t* ids, int nbIds, int idShift = 0 ) const;
 
     // Methods for a structured zone
@@ -205,6 +208,37 @@ namespace
     //gp_XYZ End() const { return gp_XYZ( _end[0]-1, _end[1]-1, _end[2]-1 ); }
   };
 
+  //================================================================================
+  /*!
+   * \brief Checks if the two arrays of node IDs describe nodes with equal coordinates
+   */
+  //================================================================================
+
+  bool isEqualNodes( const int* nIds1, const int* nIds2, int nbNodes, SMESHDS_Mesh* mesh )
+  {
+    if ( nbNodes > 0 )
+    {
+      SMESH_TNodeXYZ nn1[2], nn2[2];
+      nn1[0] = mesh->FindNode( nIds1[0] );
+      nn2[0] = mesh->FindNode( nIds2[0] );
+      if ( !nn1[0]._node || !nn2[0]._node )
+        return false;
+      double dist1 = ( nn1[0] - nn2[0] ).Modulus();
+      double dist2 = 0, tol = 1e-7;
+      if ( nbNodes > 1 )
+      {
+        nn1[1] = mesh->FindNode( nIds1[1] );
+        nn2[1] = mesh->FindNode( nIds2[1] );
+        if ( !nn1[1]._node || !nn2[1]._node )
+          return false;
+        dist2 = ( nn1[1] - nn2[1] ).Modulus();
+        tol   = 1e-5 * ( nn1[0] - nn1[1] ).Modulus();
+      }
+      return ( dist1 < tol && dist2 < tol );
+    }
+    return false;
+  }
+
   //================================================================================
   /*!
    * \brief Reads zone interface connectivity
@@ -220,7 +254,8 @@ namespace
 
   string TZoneData::ReadZonesConnection( int                             file,
                                          int                             base,
-                                         const map< string, TZoneData >& zonesByName)
+                                         const map< string, TZoneData >& zonesByName,
+                                         SMESHDS_Mesh*                   mesh)
   {
     string error;
 
@@ -277,6 +312,26 @@ namespace
                   continue; // this interface already read
               }
             }
+            // check if range and donorRange describe the same nodes
+            {
+              int ids1[2], ids2[2], nbN = 0;
+              TPointRangeIterator rangeIt1bis( range, _meshDim );
+              index1 = rangeIt1bis.Next();
+              index2 = T * ( index1 - begin1 ) + begin2;
+              ids1[0] = NodeID( index1 );
+              ids2[0] = zone2.NodeID( index2 );
+              ++nbN;
+              if ( rangeIt1bis.More() )
+              {
+                index1 = rangeIt1bis.Next();
+                index2 = T * ( index1 - begin1 ) + begin2;
+                ids1[1] = NodeID( index1 );
+                ids2[1] = zone2.NodeID( index2 );
+                ++nbN;
+              }
+              if ( !isEqualNodes( &ids1[0], &ids2[0], nbN, mesh ))
+                continue;
+            }
             while ( rangeIt1.More() )
             {
               index1 = rangeIt1.Next();
@@ -338,7 +393,7 @@ namespace
           {
             for ( int isThisZone = 0; isThisZone < 2; ++isThisZone )
             {
-              const TZoneData&            zone = isThisZone ? *this : zone2;
+              const TZoneData&           zone = isThisZone ? *this : zone2;
               CGNS_ENUMT(PointSetType_t) type = isThisZone ? ptype : donorPtype;
               vector< cgsize_t >&      points = isThisZone ? ids : donorIds;
               if ( type == CGNS_ENUMV( PointRange ))
@@ -361,8 +416,10 @@ namespace
                   points[i] += zone._nodeIdShift;
               }
             }
-            for ( size_t i = 0; i < ids.size() && i < donorIds.size(); ++i )
-              _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
+            size_t nbN = std::min( ids.size(), donorIds.size());
+            if ( isEqualNodes( &ids[0], &donorIds[0], nbN, mesh ))
+              for ( size_t i = 0; i < nbN; ++i )
+                _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
           }
           else
           {
@@ -394,7 +451,7 @@ namespace
     if ( !_nodeReplacementMap.empty() )
     {
       map< int, int >::const_iterator it, end = _nodeReplacementMap.end();
-      for ( size_t i = 0; i < nbIds; ++i )
+      for ( int i = 0; i < nbIds; ++i )
         if (( it = _nodeReplacementMap.find( ids[i] + idShift)) != end )
           ids[i] = it->second;
         else
@@ -402,7 +459,7 @@ namespace
     }
     else if ( idShift )
     {
-      for ( size_t i = 0; i < nbIds; ++i )
+      for ( int i = 0; i < nbIds; ++i )
         ids[i] += idShift;
     }
   }
@@ -709,8 +766,8 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
     }
 
     // Read connectivity between zones. Nodes of the zone interface will be
-    // replaced withing the zones read later
-    string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName );
+    // replaced within the zones read later
+    string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName, myMesh );
     if ( !err.empty() )
       addMessage( err );
 
@@ -965,7 +1022,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
           if ( zone.IsStructured() )
           {
             int axis = 0; // axis perpendiculaire to which boundary elements are oriented
-            if ( ids.size() >= meshDim * 2 )
+            if ( (int) ids.size() >= meshDim * 2 )
             {
               for ( ; axis < meshDim; ++axis )
                 if ( ids[axis] - ids[axis+meshDim] == 0 )
@@ -1070,7 +1127,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
 
             if ( psType == CGNS_ENUMV( PointRange ) && ids.size() == 2 )
             {
-              for ( size_t i = ids[0]; i <= ids[1]; ++i )
+              for ( cgsize_t i = ids[0]; i <= ids[1]; ++i )
                 if ( const SMDS_MeshElement* e = myMesh->FindElement( i ))
                   groupDS.Add( e );
             }