Salome HOME
Introduced check functions in MEDFileUMesh:
[tools/medcoupling.git] / src / MEDLoader / SauvMedConvertor.cxx
index f487e058822ea6227ed79a2ca17295ab7fe9c9ae..f1542f90cfdc51b2cd94096297575db31bc4b5e1 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
 //
 // 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
 #endif
 
 #ifdef HAS_XDR
+#include <rpc/types.h>
 #include <rpc/xdr.h>
 #endif
 
 using namespace SauvUtilities;
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
 namespace
 {
@@ -209,7 +210,7 @@ namespace
    */
   struct TCellByIDCompare
   {
-    bool operator () (const Cell* i1, const Cell* i2)
+    bool operator () (const Cell* i1, const Cell* i2) const
     {
       return i1->_number < i2->_number;
     }
@@ -2045,7 +2046,11 @@ bool XDRReader::open()
 {
   bool xdr_ok = false;
 #ifdef HAS_XDR
+#ifdef WIN32
+  if ((_xdrs_file = ::fopen(_fileName.c_str(), "rb")))
+#else 
   if ((_xdrs_file = ::fopen(_fileName.c_str(), "r")))
+#endif
     {
       _xdrs = (XDR *)malloc(sizeof(XDR));
       xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE);
@@ -2300,17 +2305,85 @@ void IntermediateMED::checkDataAvailability() const
 
 //================================================================================
 /*!
- * \brief Makes ParaMEDMEM::MEDFileData from self
+ * \brief Safely adds a new Group
+ */
+//================================================================================
+
+Group* IntermediateMED::addNewGroup(std::vector<SauvUtilities::Group*>* groupsToFix)
+{
+  if ( _groups.size() == _groups.capacity() ) // re-allocation would occure
+    {
+      std::vector<Group> newGroups( _groups.size() );
+      newGroups.push_back( Group() );
+
+      for ( size_t i = 0; i < _groups.size(); ++i )
+        {
+          // avoid copying _cells
+          std::vector<const Cell*> cells;
+          cells.swap( _groups[i]._cells );
+          newGroups[i] = _groups[i];
+          newGroups[i]._cells.swap( cells );
+
+          // correct pointers to sub-groups
+          for ( size_t j = 0; j < _groups[i]._groups.size(); ++j )
+            {
+              int iG = _groups[i]._groups[j] - &_groups[0];
+              newGroups[i]._groups[j] = & newGroups[ iG ];
+            }
+        }
+
+      // fix given groups
+      if ( groupsToFix )
+        for ( size_t i = 0; i < groupsToFix->size(); ++i )
+          if ( (*groupsToFix)[i] )
+            {
+              int iG = (*groupsToFix)[i] - &_groups[0];
+              (*groupsToFix)[i] = & newGroups[ iG ];
+            }
+
+      // fix field supports
+      for ( int isNode = 0; isNode < 2; ++isNode )
+        {
+          std::vector<DoubleField* >& fields = isNode ? _nodeFields : _cellFields;
+          for ( size_t i = 0; i < fields.size(); ++i )
+            {
+              if ( !fields[i] ) continue;
+              for ( size_t j = 0; j < fields[i]->_sub.size(); ++j )
+                if ( fields[i]->_sub[j]._support )
+                  {
+                    int iG = fields[i]->_sub[j]._support - &_groups[0];
+                    fields[i]->_sub[j]._support = & newGroups[ iG ];
+                  }
+              if ( fields[i]->_group )
+                {
+                  int iG = fields[i]->_group - &_groups[0];
+                  fields[i]->_group = & newGroups[ iG ];
+                }
+            }
+        }
+
+      _groups.swap( newGroups );
+    }
+  else
+    {
+      _groups.push_back( Group() );
+    }
+  return &_groups.back();
+}
+
+//================================================================================
+/*!
+ * \brief Makes MEDCoupling::MEDFileData from self
  */
 //================================================================================
 
-ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS()
+MEDCoupling::MEDFileData* IntermediateMED::convertInMEDFileDS()
 {
-  MEDCouplingAutoRefCountObjectPtr< MEDFileUMesh >  mesh   = makeMEDFileMesh();
-  MEDCouplingAutoRefCountObjectPtr< MEDFileFields > fields = makeMEDFileFields(mesh);
+  MCAuto< MEDFileUMesh >  mesh   = makeMEDFileMesh();
+  MCAuto< MEDFileFields > fields = makeMEDFileFields(mesh);
 
-  MEDCouplingAutoRefCountObjectPtr< MEDFileMeshes > meshes = MEDFileMeshes::New();
-  MEDCouplingAutoRefCountObjectPtr< MEDFileData >  medData = MEDFileData::New();
+  MCAuto< MEDFileMeshes > meshes = MEDFileMeshes::New();
+  MCAuto< MEDFileData >  medData = MEDFileData::New();
   meshes->pushMesh( mesh );
   medData->setMeshes( meshes );
   if ( fields ) medData->setFields( fields );
@@ -2320,11 +2393,11 @@ ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS()
 
 //================================================================================
 /*!
- * \brief Creates ParaMEDMEM::MEDFileUMesh from its data
+ * \brief Creates MEDCoupling::MEDFileUMesh from its data
  */
 //================================================================================
 
-ParaMEDMEM::MEDFileUMesh* IntermediateMED::makeMEDFileMesh()
+MEDCoupling::MEDFileUMesh* IntermediateMED::makeMEDFileMesh()
 {
   // check if all needed piles are present
   checkDataAvailability();
@@ -2611,42 +2684,43 @@ void IntermediateMED::orientElements2D()
       // --------------------------
       // orient faces clockwise
       // --------------------------
-      int iQuad = isQuadratic ? 2 : 1;
-      for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ )
-        {
-          // look for index of the most left node
-          int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad;
-          double x, minX = nodeCoords( elemIt->_nodes[0] )[0];
-          for ( iNode = 1; iNode < nbNodes; ++iNode )
-            if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX )
-              minX = x, iLeft = iNode;
-
-          // indeces of the nodes neighboring the most left one
-          int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1;
-          int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1;
-          // find components of prev-left and left-next vectors
-          double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ];
-          double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ];
-          double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ];
-          double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ];
-          double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ];
-          double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ];
-          double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector
-          double xLN = xN - xL, yLN = yN - yL; // components of left-next vector
-          // normalise y of the vectors
-          double modPL = sqrt ( xPL * xPL + yPL * yPL );
-          double modLN = sqrt ( xLN * xLN + yLN * yLN );
-          if ( modLN > std::numeric_limits<double>::min() &&
-               modPL > std::numeric_limits<double>::min() )
-            {
-              yPL /= modPL;
-              yLN /= modLN;
-              // summary direction of neighboring links must be positive
-              bool clockwise = ( yPL + yLN > 0 );
-              if ( !clockwise )
-                reverse( *elemIt, swapVec );
-            }
-        }
+      // COMMENTED for issue 0022612 note 17739
+      // int iQuad = isQuadratic ? 2 : 1;
+      // for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ )
+      //   {
+      //     // look for index of the most left node
+      //     int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad;
+      //     double x, minX = nodeCoords( elemIt->_nodes[0] )[0];
+      //     for ( iNode = 1; iNode < nbNodes; ++iNode )
+      //       if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX )
+      //         minX = x, iLeft = iNode;
+
+      //     // indeces of the nodes neighboring the most left one
+      //     int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1;
+      //     int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1;
+      //     // find components of prev-left and left-next vectors
+      //     double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ];
+      //     double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ];
+      //     double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ];
+      //     double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ];
+      //     double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ];
+      //     double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ];
+      //     double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector
+      //     double xLN = xN - xL, yLN = yN - yL; // components of left-next vector
+      //     // normalise y of the vectors
+      //     double modPL = sqrt ( xPL * xPL + yPL * yPL );
+      //     double modLN = sqrt ( xLN * xLN + yLN * yLN );
+      //     if ( modLN > std::numeric_limits<double>::min() &&
+      //          modPL > std::numeric_limits<double>::min() )
+      //       {
+      //         yPL /= modPL;
+      //         yLN /= modLN;
+      //         // summary direction of neighboring links must be positive
+      //         bool clockwise = ( yPL + yLN > 0 );
+      //         if ( !clockwise )
+      //           reverse( *elemIt, swapVec );
+      //       }
+      //   }
     }
 }
 
@@ -2659,7 +2733,8 @@ void IntermediateMED::orientElements2D()
 void IntermediateMED::orientElements3D()
 {
   // set _reverse flags of faces
-  orientFaces3D();
+  // COMMENTED for issue 0022612 note 17739
+  //orientFaces3D();
 
   // -----------------
   // fix connectivity
@@ -2691,7 +2766,8 @@ void IntermediateMED::orientElements3D()
     }
   }
 
-  orientVolumes();
+  // COMMENTED for issue 0022612 note 17739
+  //orientVolumes();
 }
 
 //================================================================================
@@ -3016,7 +3092,7 @@ void IntermediateMED::numberElements()
  */
 //================================================================================
 
-ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords()
+MEDCoupling::DataArrayDouble * IntermediateMED::getCoords()
 {
   DataArrayDouble* coordArray = DataArrayDouble::New();
   coordArray->alloc( _nbNodes, _spaceDim );
@@ -3042,8 +3118,8 @@ ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords()
  */
 //================================================================================
 
-void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh*    mesh,
-                                       ParaMEDMEM::DataArrayDouble* coords )
+void IntermediateMED::setConnectivity( MEDCoupling::MEDFileUMesh*    mesh,
+                                       MEDCoupling::DataArrayDouble* coords )
 {
   int meshDim = 0;
 
@@ -3108,7 +3184,7 @@ void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh*    mesh,
  */
 //================================================================================
 
-void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh )
+void IntermediateMED::setGroups( MEDCoupling::MEDFileUMesh* mesh )
 {
   bool isMeshNameSet = false;
   const int meshDim = mesh->getMeshDimension();
@@ -3117,7 +3193,7 @@ void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh )
       const int meshDimRelToMaxExt = ( dim == 0 ? 1 : dim - meshDim );
 
       std::vector<const DataArrayInt *> medGroups;
-      std::vector<MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > refGroups;
+      std::vector<MCAuto<DataArrayInt> > refGroups;
       for ( size_t i = 0; i < _groups.size(); ++i )
         {
           Group& grp = _groups[i];
@@ -3166,10 +3242,10 @@ void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh )
           grp._medGroup = DataArrayInt::New();
           grp._medGroup->setName( grp._name.c_str() );
           grp._medGroup->alloc( cell2order.size(), /*nbOfCompo=*/1 );
-          int * idsPrt = grp._medGroup->getPointer();
+          int * idsPtr = grp._medGroup->getPointer();
           TCellToOrderMap::iterator cell2orderIt, cell2orderEnd = cell2order.end();
           for ( cell2orderIt = cell2order.begin(); cell2orderIt != cell2orderEnd; ++cell2orderIt )
-            *idsPrt++ = (*cell2orderIt).first->_number - 1;
+            *idsPtr++ = (*cell2orderIt).first->_number - 1;
 
           // try to set the mesh name
           if ( !isMeshNameSet &&
@@ -3190,10 +3266,13 @@ void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh )
           // Issue 0021311. Use case: a gibi group has references (recorded in pile 1)
           // and several names (pile 27) refer (pile 10) to this group.
           // We create a copy of this group per each named reference
+          std::set<std::string> uniqueNames;
+          uniqueNames.insert( grp._name );
           for ( unsigned iRef = 0 ; iRef < grp._refNames.size(); ++iRef )
-            if ( !grp._refNames[ iRef ].empty() )
+            if ( !grp._refNames[ iRef ].empty() &&
+                 uniqueNames.insert( grp._refNames[ iRef ]).second ) // for name uniqueness (23155)
               {
-                refGroups.push_back( grp._medGroup->deepCpy() );
+                refGroups.push_back( grp._medGroup->deepCopy() );
                 refGroups.back()->setName( grp._refNames[ iRef ].c_str() );
                 medGroups.push_back( refGroups.back() );
               }
@@ -3213,16 +3292,17 @@ bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const
   int dim = getDim( grp );
 
   int nbElems = 0;
-  CellsByDimIterator dimCells( *this, dim );
-  while ( const std::set<Cell > * cells = dimCells.nextType() )
-    nbElems += cells->size();
-
-  const bool onAll = ( nbElems == grp->size() );
-
   if ( dim == 0 )
-    dimRel = 0;
+    {
+      nbElems = _nbNodes;
+      dimRel  = 0;
+    }
   else
     {
+      CellsByDimIterator dimCells( *this, dim );
+      while ( const std::set<Cell > * cells = dimCells.nextType() )
+        nbElems += cells->size();
+
       int meshDim = 3;
       for ( ; meshDim > 0; --meshDim )
         {
@@ -3232,6 +3312,8 @@ bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const
         }
       dimRel = dim - meshDim;
     }
+
+  bool onAll = ( nbElems == grp->size() );
   return onAll;
 }
 
@@ -3241,7 +3323,7 @@ bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const
  */
 //================================================================================
 
-ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh)
+MEDCoupling::MEDFileFields * IntermediateMED::makeMEDFileFields(MEDCoupling::MEDFileUMesh* mesh)
 {
   if ( _nodeFields.empty() && _cellFields.empty() ) return 0;
 
@@ -3267,10 +3349,10 @@ ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFi
 //================================================================================
 
 void IntermediateMED::setFields( SauvUtilities::DoubleField* fld,
-                                 ParaMEDMEM::MEDFileFields*  medFields,
-                                 ParaMEDMEM::MEDFileUMesh*   mesh,
+                                 MEDCoupling::MEDFileFields*  medFields,
+                                 MEDCoupling::MEDFileUMesh*   mesh,
                                  const TID                   castemID,
-                                 std::set< std::string >&              usedFieldNames)
+                                 std::set< std::string >&    usedFieldNames)
 {
   bool sameNbGauss = true;
   if ( !fld || !fld->isMedCompatible( sameNbGauss )) return;
@@ -3327,9 +3409,9 @@ void IntermediateMED::setFields( SauvUtilities::DoubleField* fld,
 //================================================================================
 
 void IntermediateMED::setTS( SauvUtilities::DoubleField*  fld,
-                             ParaMEDMEM::DataArrayDouble* values,
-                             ParaMEDMEM::MEDFileFields*   medFields,
-                             ParaMEDMEM::MEDFileUMesh*    mesh,
+                             MEDCoupling::DataArrayDouble* values,
+                             MEDCoupling::MEDFileFields*   medFields,
+                             MEDCoupling::MEDFileUMesh*    mesh,
                              const int                    iSub)
 {
   // treat a field support
@@ -3351,25 +3433,25 @@ void IntermediateMED::setTS( SauvUtilities::DoubleField*  fld,
   // set the mesh
   if ( onAll )
     {
-      MEDCouplingAutoRefCountObjectPtr
+      MCAuto
         < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel );
       timeStamp->setMesh( dimMesh );
     }
-  else if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_NODES )
+  else if ( timeStamp->getTypeOfField() == MEDCoupling::ON_NODES )
     {
       DataArrayDouble * coo = mesh->getCoords();
-      MEDCouplingAutoRefCountObjectPtr
+      MCAuto
         <DataArrayDouble> subCoo = coo->selectByTupleId(support->_medGroup->begin(),
-                                                        support->_medGroup->end()); 
-      MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > nodeSubMesh =
+                                                        support->_medGroup->end());
+      MCAuto< MEDCouplingUMesh > nodeSubMesh =
         MEDCouplingUMesh::Build0DMeshFromCoords( subCoo );
       timeStamp->setMesh( nodeSubMesh );
     }
   else
     {
-      MEDCouplingAutoRefCountObjectPtr
+      MCAuto
         < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel );
-      MEDCouplingAutoRefCountObjectPtr
+      MCAuto
         <MEDCouplingMesh> subMesh = dimMesh->buildPart(support->_medGroup->begin(),
                                                        support->_medGroup->end());
       timeStamp->setMesh( subMesh);
@@ -3380,10 +3462,11 @@ void IntermediateMED::setTS( SauvUtilities::DoubleField*  fld,
   timeStamp->setArray( values );
   values->decrRef();
   // set gauss points
-  if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_GAUSS_PT )
+  if ( timeStamp->getTypeOfField() == MEDCoupling::ON_GAUSS_PT )
     {
-      TGaussDef gaussDef( support->_cellType, fld->_sub[iSub].nbGauss() );
-      timeStamp->setGaussLocalizationOnType( support->_cellType,
+      TGaussDef gaussDef( fld->_sub[iSub]._support->_cellType,
+                          fld->_sub[iSub].nbGauss() );
+      timeStamp->setGaussLocalizationOnType( fld->_sub[iSub]._support->_cellType,
                                              gaussDef.myRefCoords,
                                              gaussDef.myCoords,
                                              gaussDef.myWeights );
@@ -3402,7 +3485,7 @@ void IntermediateMED::setTS( SauvUtilities::DoubleField*  fld,
     timeStamp->setOrder( nbTS );
 
   // add the time-stamp
-  timeStamp->checkCoherency();
+  timeStamp->checkConsistencyLight();
   if ( onAll )
     fld->_curMedField->appendFieldNoProfileSBT( timeStamp );
   else
@@ -3517,9 +3600,9 @@ bool DoubleField::isMultiTimeStamps() const
   if ( _sub.size() < 2 )
     return false;
   bool sameSupports = true;
-  Group* grp1 = _sub[0]._support;
+  Group* grpp1 = _sub[0]._support;// grpp NOT grp because XDR under Windows defines grp...
   for ( size_t i = 1; i < _sub.size() && sameSupports; ++i )
-    sameSupports = ( grp1 == _sub[i]._support );
+    sameSupports = ( grpp1 == _sub[i]._support );
 
   return sameSupports;
 }
@@ -3576,7 +3659,7 @@ bool DoubleField::hasSameComponentsBySupport() const
  */
 //================================================================================
 
-ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const
+MEDCoupling::TypeOfField DoubleField::getMedType( const int iSub ) const
 {
   using namespace INTERP_KERNEL;
 
@@ -3598,7 +3681,7 @@ ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const
  */
 //================================================================================
 
-ParaMEDMEM::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const
+MEDCoupling::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const
 {
   return ONE_TIME;
   // NO_TIME = 4,