Back to index

salome-med  6.5.0
SauvReader.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 // File      : SauvReader.cxx
00020 // Created   : Tue Aug 16 13:57:42 2011
00021 // Author    : Edward AGAPOV (eap)
00022 //
00023 
00024 #include "SauvReader.hxx"
00025 
00026 #include "SauvMedConvertor.hxx"
00027 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
00028 #include "NormalizedUnstructuredMesh.hxx"
00029 #include "MEDCouplingRefCountObject.hxx"
00030 
00031 #include <cstring>
00032 #include <sstream>
00033 #include <iostream>
00034 
00035 using namespace ParaMEDMEM;
00036 using namespace SauvUtilities;
00037 using namespace std;
00038 
00039 #define GIBI_EQUAL(var_str, stat_str) (strncmp (var_str, stat_str, strlen(stat_str)) == 0)
00040 
00041 //================================================================================
00045 //================================================================================
00046 
00047 SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception)
00048 {
00049   if ( !fileName || strlen(fileName) < 1 ) THROW_IK_EXCEPTION("Invalid file name");
00050 
00051   ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr< SauvUtilities::FileReader> parser;
00052 
00053   // try to open as XRD
00054   parser = new XDRReader( fileName );
00055   if ( parser->open() )
00056     {
00057       SauvReader* reader = new SauvReader;
00058       reader->_fileReader = parser;
00059       parser->incrRef();
00060       return reader;
00061     }
00062 
00063   // try to open as ASCII
00064   parser = new ASCIIReader( fileName );
00065   if ( parser->open() )
00066     {
00067       SauvReader* reader = new SauvReader;
00068       reader->_fileReader = parser;
00069       parser->incrRef();
00070       return reader;
00071     }
00072 
00073   THROW_IK_EXCEPTION("Unable to open file |"<< fileName << "|");
00074 }
00075 //================================================================================
00079 //================================================================================
00080 
00081 SauvReader::~SauvReader()
00082 {
00083   _fileReader->decrRef();
00084 }
00085 
00086 //================================================================================
00090 //================================================================================
00091 
00092 std::string SauvReader::lineNb() const
00093 {
00094   if ( isASCII() )
00095     return string(" (line #") + SauvUtilities::toString
00096       ( static_cast<SauvUtilities::ASCIIReader*>( _fileReader )->lineNb() ) + ")";
00097 
00098   return "";
00099 }
00100 
00101 //================================================================================
00105 //================================================================================
00106 
00107 ParaMEDMEM::MEDFileData * SauvReader::loadInMEDFileDS() throw(INTERP_KERNEL::Exception)
00108 {
00109   SauvUtilities::IntermediateMED iMed; // intermadiate DS
00110   _iMed = &iMed;
00111 
00112   char* line; // a current line
00113   const char* enregistrement_type=" ENREGISTREMENT DE TYPE";
00114 
00115   while ( getNextLine(line, /*raiseOEF=*/false)) // external loop looking for "ENREGISTREMENT DE TYPE"
00116     {
00117       if ( isASCII() && !GIBI_EQUAL( line, enregistrement_type ))
00118         continue; // "ENREGISTREMENT DE TYPE" not found -> read the next line
00119 
00120       // read the number of a record
00121       int recordNumber;
00122       if ( isASCII() )
00123         recordNumber = atoi( line + strlen(enregistrement_type) + 1 );
00124       else
00125         recordNumber = getInt();
00126 
00127       // read the record
00128       if ( recordNumber == 2 )
00129         readRecord2();
00130       else if (recordNumber == 4 )
00131         readRecord4();
00132       else if (recordNumber == 7 )
00133         readRecord7();
00134       else if (recordNumber == 5 )
00135         break; // stop reading
00136       else
00137         if ( !isASCII() )
00138           THROW_IK_EXCEPTION("XDR : ENREGISTREMENT DE TYPE " << recordNumber << " not implemented!!!");
00139     }
00140 
00141   ParaMEDMEM::MEDFileData* medFileData = iMed.convertInMEDFileDS();
00142 
00143   return medFileData;
00144 }
00145 
00146 //================================================================================
00150 //================================================================================
00151 
00152 void SauvReader::readRecord4()
00153 {
00154   if ( !isASCII() )
00155     {
00156       getInt(); // skip NIVEAU
00157       getInt(); // skip ERREUR
00158       _iMed->_spaceDim = getInt();
00159       getFloat(); // skip DENSITE
00160     }
00161   else
00162     {
00163       char* line;
00164       getNextLine(line);
00165       const char* s = " NIVEAU  15 NIVEAU ERREUR   0 DIMENSION";
00166       _iMed->_spaceDim = atoi( line + strlen( s ) + 1 );
00167       if ( !GIBI_EQUAL( line, " NIVEAU" ))
00168         THROW_IK_EXCEPTION( "Could not read space dimension" << lineNb() );
00169       }
00170   if ( _iMed->_spaceDim < 1 )
00171     THROW_IK_EXCEPTION( "Invalid space dimension:" << _iMed->_spaceDim );
00172 }
00173 
00174 //================================================================================
00178 //================================================================================
00179 
00180 void SauvReader::readRecord7()
00181 {
00182   if ( !isASCII() )
00183     {
00184       getInt(); // skip NOMBRE INFO CASTEM2000
00185       getInt(); // skip IFOUR
00186       getInt(); // skip NIFOUR
00187       getInt(); // skip IFOMOD
00188       getInt(); // skip IECHO
00189       getInt(); // skip IIMPI
00190       getInt(); // skip IOSPI
00191       getInt(); // skip ISOTYP
00192       getInt(); // skip NSDPGE
00193     }
00194   else
00195     {
00196       // skip 3 lines:
00197       // NOMBRE INFO CASTEM2000   8
00198       // IFOUR   2 NIFOUR   0 IFOMOD   2 IECHO   1 IIMPI   0 IOSPI   0 ISOTYP   1
00199       // NSDPGE     0
00200       char* line;
00201       getNextLine(line);
00202       getNextLine(line);
00203       getNextLine(line);
00204     }
00205 }
00206 
00207 //================================================================================
00211 //================================================================================
00212 
00213 int SauvReader::readPileNumber(int& nbNamedObjects, int& nbObjects)
00214 {
00215   // FORMAT(' PILE NUMERO',I4,'NBRE ObjectS NOMMES',I8,'NBRE ObjectS',I8)
00216   int pileNumber;
00217   if ( !isASCII() )
00218     {
00219       initIntReading(3);
00220       pileNumber     = getInt(); next();
00221       nbNamedObjects = getInt(); next();
00222       nbObjects      = getInt(); next();
00223     }
00224   else
00225     {
00226       char* line;
00227       getNextLine(line);
00228       const char *s1 = " PILE NUMERO", *s2 = "NBRE ObjectS NOMMES", *s3 = "NBRE ObjectS";
00229       if ( ! GIBI_EQUAL( line, s1 ) )
00230         THROW_IK_EXCEPTION("Could not read the pile number " << lineNb() );
00231       line           = line + strlen(s1);
00232       pileNumber     = atoi( line );
00233       line           = line + 4 + strlen(s2);
00234       nbNamedObjects = atoi( line );
00235       line           = line + 8 + strlen(s3);
00236       nbObjects      = atoi( line );
00237     }
00238   if ( nbNamedObjects<0 )
00239     THROW_IK_EXCEPTION("Invalid nb of named objects: " << nbNamedObjects  << lineNb() );
00240   if ( nbObjects<0)
00241     THROW_IK_EXCEPTION("Invalid nb of objects: " << nbObjects  << lineNb() );
00242   // It appears to be a valid case
00243   // if ( nbObjects<nbNamedObjects)
00244   //   THROW_IK_EXCEPTION("In PILE " << pileNumber <<
00245   //                      " nb of objects is less than nb of named objects"  << lineNb() );
00246   return pileNumber;
00247 }
00248 
00249 //================================================================================
00253 //================================================================================
00254 
00255 void SauvReader::readRecord2()
00256 {
00257   if ( _iMed->_spaceDim == 0 )
00258     THROW_IK_EXCEPTION("Missing ENREGISTREMENT DE TYPE   4");
00259 
00260   // read a pile number
00261   int pileNumber, nbNamedObjects, nbObjects;
00262   pileNumber = readPileNumber(nbNamedObjects, nbObjects);
00263 
00264   if ( !_encounteredPiles.insert( pileNumber ).second && // piles may repeat
00265        isASCII())
00266     return;
00267 
00268   // read object names and their indices
00269   vector<string> objectNames(nbNamedObjects);
00270   for ( initNameReading( nbNamedObjects ); more(); next() )
00271     objectNames[ index() ] = getName();
00272 
00273   vector<int> nameIndices(nbNamedObjects);
00274   for ( initIntReading( nbNamedObjects ); more(); next() )
00275     nameIndices[ index() ] = getInt();
00276 
00277   switch ( pileNumber )
00278     {
00279     case PILE_SOUS_MAILLAGE:
00280       read_PILE_SOUS_MAILLAGE(nbObjects, objectNames, nameIndices);
00281       break;
00282     case PILE_NODES_FIELD:
00283       read_PILE_NODES_FIELD(nbObjects, objectNames, nameIndices);
00284       break;
00285     case PILE_TABLES:
00286       read_PILE_TABLES(nbObjects, objectNames, nameIndices);
00287       break;
00288     case PILE_LREEL:
00289       read_PILE_LREEL(nbObjects, objectNames, nameIndices);
00290       break;
00291     case PILE_LOGIQUES:
00292       read_PILE_LOGIQUES(nbObjects, objectNames, nameIndices);
00293       break;
00294     case PILE_FLOATS:
00295       read_PILE_FLOATS(nbObjects, objectNames, nameIndices);
00296       break;
00297     case PILE_INTEGERS:
00298       read_PILE_INTEGERS(nbObjects, objectNames, nameIndices);
00299       break;
00300     case PILE_STRINGS:
00301       read_PILE_STRINGS(nbObjects, objectNames, nameIndices);
00302       break;
00303     case PILE_LMOTS:
00304       read_PILE_LMOTS(nbObjects, objectNames, nameIndices);
00305       break;
00306     case PILE_NOEUDS:
00307       read_PILE_NOEUDS(nbObjects, objectNames, nameIndices);
00308       break;
00309     case PILE_COORDONNEES:
00310       read_PILE_COORDONNEES(nbObjects, objectNames, nameIndices);
00311       break;
00312     case PILE_MODL:
00313       read_PILE_MODL(nbObjects, objectNames, nameIndices);
00314       break;
00315     case PILE_FIELD:
00316       read_PILE_FIELD(nbObjects, objectNames, nameIndices);
00317       break;
00318     default:
00319       if ( !isASCII() )
00320         THROW_IK_EXCEPTION("XDR : reading PILE " << pileNumber << " not implemented !!!");
00321     }
00322 }
00323 
00324 //================================================================================
00328 //================================================================================
00329 
00330 void SauvReader::read_PILE_SOUS_MAILLAGE(const int                 nbObjects,
00331                                          std::vector<std::string>& objectNames,
00332                                          std::vector<int>&         nameIndices)
00333 {
00334   _iMed->_groups.reserve(nbObjects*2); // fields may add some groups
00335 
00336   char* line;
00337   map<int,int> strangeGroupType;
00338   int i;
00339 
00340   for (int object=0; object!=nbObjects; ++object) // loop on sub-groups
00341     {
00342       initIntReading( 5 );
00343       int castemCellType = getIntNext();
00344       int nbSubGroups    = getIntNext();
00345       int nbReferences   = getIntNext();
00346       int nbNodesPerElem = getIntNext();
00347       int nbElements     = getIntNext();
00348 
00349       _iMed->_groups.push_back(Group());
00350       SauvUtilities::Group & group = _iMed->_groups.back();
00351 
00352       // Issue 0021311. Allocate places for names of referring groups
00353       // that will be possibly filled after reading long names from
00354       // PILE_TABLES and PILE_STRINGS
00355       group._refNames.resize( nbReferences );
00356 
00357       // castemCellType=0 corresponds to a sub-mesh composed of other sub-meshes
00358       if (castemCellType==0 && nbSubGroups>0)
00359         {
00360           group._groups.resize( nbSubGroups );
00361           for ( initIntReading( nbSubGroups ); more(); next() )
00362             group._groups[ index() ] = & _iMed->_groups[ getInt() - 1 ];
00363           //std::sort( group._groups.begin(), group._groups.end() ); // for _groups comparison in getFieldSupport()
00364         }
00365       // skip references
00366       if ( isASCII() )
00367         for ( i = 0; i < nbReferences; i += 10 ) // FORMAT(10I8)
00368           getNextLine(line);
00369       else
00370         for (initIntReading(nbReferences); more(); next());
00371 
00372       // skip colors
00373       if ( isASCII() )
00374         for ( i = 0; i < nbElements; i += 10 )
00375           getNextLine(line);
00376       else
00377         for (initIntReading(nbElements); more(); next());
00378 
00379       // not a composit group
00380       if (castemCellType>0 && nbSubGroups==0)
00381         {
00382           group._cellType = SauvUtilities::gibi2medGeom(castemCellType);
00383 
00384           initIntReading( nbElements * nbNodesPerElem );
00385           if ( group._cellType == INTERP_KERNEL::NORM_ERROR ) // look for group end
00386             {
00387               for ( ; more();  next());
00388               strangeGroupType.insert( make_pair( object, castemCellType ));
00389             }
00390           else
00391             {
00392               // if ( group._cellType == MED_POINT1 ) group._cellType = NORM_ERROR; // issue 21199
00393 
00394               // read connectivity of elements of a group
00395               SauvUtilities::Cell ma( nbNodesPerElem );
00396               SauvUtilities::Node* pNode;
00397               group._cells.resize( nbElements );
00398               for ( i = 0; i < nbElements; ++i )
00399                 {
00400                   ma.init();
00401                   for ( int n = 0; n < nbNodesPerElem; ++n )
00402                     {
00403                       int nodeID = getIntNext();
00404                       pNode = _iMed->getNode( nodeID );
00405                       ma._nodes[n] = pNode;
00406                       _iMed->_nbNodes += ( !pNode->isUsed() );
00407                       pNode->_number = nodeID;
00408                     }
00409                   ma._number = _iMed->getNbCellsOfType( group._cellType ) + 1;
00410                   group._cells[i] = _iMed->insert( group._cellType, ma );
00411                 }
00412             }
00413         }
00414     } // loop on groups
00415 
00416   // set group names
00417   for (i=0; i!=(int)objectNames.size(); ++i)
00418     {
00419       int grpID = nameIndices[i];
00420       SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ];
00421       if ( !grp._name.empty() ) // a group has several names
00422         { // create a group with subgroup grp and named grp.name
00423           _iMed->_groups.push_back(Group());
00424           _iMed->_groups.back()._groups.push_back( &_iMed->_groups[ grpID-1 ]);
00425           _iMed->_groups.back()._name = grp._name;
00426         }
00427       grp._name=objectNames[i];
00428 #ifdef _DEBUG
00429       map<int,int>::iterator it = strangeGroupType.find( grpID - 1 );
00430       if ( it != strangeGroupType.end() )
00431         cout << "Skip " << grp._name << " of not supported CASTEM type: " << it->second << endl;
00432 #endif
00433     }
00434 } // read_PILE_SOUS_MAILLAGE()
00435 
00436 //================================================================================
00440 //================================================================================
00441 
00442 void SauvReader::read_PILE_LREEL (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
00443 {
00444   if ( isXRD() )
00445     {
00446       for (int object=0; object!=nbObjects; ++object) // pour chaque Group
00447         {
00448           initIntReading(1);
00449           int nb_vals = getIntNext();
00450           initDoubleReading(nb_vals);
00451           for(int i=0; i<nb_vals; i++) next();
00452         }
00453     }
00454 }
00455 
00456 //================================================================================
00460 //================================================================================
00461 
00462 void SauvReader::read_PILE_LOGIQUES (const int, std::vector<std::string>&, std::vector<int>&)
00463 {
00464   if ( isXRD() )
00465     {
00466       initIntReading(1);
00467       int nb_vals = getIntNext();
00468       initIntReading(nb_vals);
00469       for(int i=0; i<nb_vals; i++) next();
00470     }
00471 }
00472 
00473 //================================================================================
00477 //================================================================================
00478 
00479 void SauvReader::read_PILE_FLOATS (const int, std::vector<std::string>&, std::vector<int>&)
00480 {
00481   if ( isXRD() )
00482     {
00483       initIntReading(1);
00484       int nb_vals = getIntNext();
00485       initDoubleReading(nb_vals);
00486       for(int i=0; i<nb_vals; i++) next();
00487     }
00488 }
00489 
00490 //================================================================================
00494 //================================================================================
00495 
00496 void SauvReader::read_PILE_INTEGERS (const int, std::vector<std::string>&, std::vector<int>&)
00497 {
00498   if ( isXRD() )
00499     {
00500       initIntReading(1);
00501       int nb_vals = getIntNext();
00502       initIntReading(nb_vals);
00503       for(int i=0; i<nb_vals; i++) next();
00504     }
00505 }
00506 
00507 //================================================================================
00511 //================================================================================
00512 
00513 void SauvReader::read_PILE_LMOTS (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
00514 {
00515   if ( isXRD() )
00516     {
00517       for (int object=0; object!=nbObjects; ++object) // pour chaque Group
00518         {
00519           initIntReading(2);
00520           int len = getIntNext();
00521           int nb_vals = getIntNext();
00522           int nb_char = len*nb_vals;
00523           int nb_char_tmp = 0;
00524           int fixed_length = 71;
00525           while (nb_char_tmp < nb_char)
00526             {
00527               int remain_len = nb_char - nb_char_tmp;
00528               int width;
00529               if ( remain_len > fixed_length )
00530                 {
00531                   width = fixed_length;
00532                 }
00533               else
00534                 {
00535                   width = remain_len;
00536                 }
00537               initNameReading(1, width);
00538               next();
00539               nb_char_tmp += width;
00540             }
00541         }
00542     }
00543 }
00544 
00545 //================================================================================
00549 //================================================================================
00550 
00551 void SauvReader::read_PILE_MODL (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
00552 {
00553   if ( isXRD() )
00554     {
00555       for (int object=0; object!=nbObjects; ++object) // pour chaque Group
00556         {
00557           // see wrmodl.eso
00558           initIntReading(10);
00559           int n1  = getIntNext();
00560           int nm2 = getIntNext();
00561           int nm3 = getIntNext();
00562           int nm4 = getIntNext();
00563           int nm5 = getIntNext();
00564           int n45 = getIntNext();
00565           /*int nm6 =*/ getIntNext();
00566           /*int nm7 =*/ getIntNext();
00567           next();
00568           next();
00569           int nm1 = n1 * n45;
00570           int nm9 = n1 * 16;
00571           for (initIntReading(nm1); more(); next());
00572           for (initIntReading(nm9); more(); next());
00573           for (initNameReading(nm5, 8); more(); next());
00574           for (initNameReading(nm2, 8); more(); next());
00575           for (initNameReading(nm3, 8); more(); next());
00576           for (initIntReading(nm4); more(); next());
00577         }
00578     }
00579 } // Fin case pile 38
00580 
00581 //================================================================================
00585 //================================================================================
00586 
00587 void SauvReader::read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
00588 {
00589   initIntReading(1);
00590   int nb_indices = getIntNext();
00591 
00592   if (nb_indices != nbObjects)
00593     THROW_IK_EXCEPTION("Error of reading PILE NUMERO  " << PILE_NOEUDS << lineNb() );
00594 
00595   for ( initIntReading( nbObjects ); more(); next() )
00596     {
00597       int coordID = getInt();
00598       _iMed->getNode( index()+1 )->_coordID = coordID;
00599     }
00600 }
00601 
00602 //================================================================================
00606 //================================================================================
00607 
00608 void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>&, std::vector<int>&)
00609 {
00610   initIntReading(1);
00611   int nbReals = getIntNext();
00612 
00613   if ( nbReals < (int)(_iMed->_nbNodes*(_iMed->_spaceDim+1)) )
00614     THROW_IK_EXCEPTION("Error of reading PILE NUMERO  " << PILE_COORDONNEES << lineNb() );
00615 
00616   // there are coordinates + density for each node
00617   _iMed->_coords.resize( nbReals - nbReals/(_iMed->_spaceDim+1));
00618   double* coordPtr = &_iMed->_coords[0];
00619 
00620   initDoubleReading( nbReals );
00621   while ( more() )
00622     {
00623       for (unsigned j = 0; j < _iMed->_spaceDim; ++j, next())
00624         *coordPtr++ = getDouble();
00625       // skip density
00626       getDouble();
00627       next();
00628     }
00629 }
00630 
00631 //================================================================================
00635 //================================================================================
00636 
00637 SauvUtilities::Group* SauvReader::getFieldSupport(const vector<SauvUtilities::Group*>& supports)
00638 {
00639   SauvUtilities::Group* group = NULL;
00640   set<SauvUtilities::Group*> sup_set( supports.begin(), supports.end() );
00641   if (sup_set.size() == 1 ) // one or equal supports
00642     {
00643       group = supports[0];
00644     }
00645   else
00646     {
00647       // try to find an existing composite group with the same sub-groups
00648       for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i )
00649         {
00650           Group & grp = _iMed->_groups[i];
00651           if (sup_set.size() == grp._groups.size())
00652             {
00653               bool sameOrder = true;
00654               for ( size_t j = 0; j < supports.size() && sameOrder; ++j )
00655                 sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]);
00656               if ( sameOrder )
00657                 group = & _iMed->_groups[i];
00658             }
00659         }
00660       if ( !group ) // no such a group, add a new one
00661         {
00662           vector<SauvUtilities::Group*> newGroups( supports.begin(),
00663                                                    supports.begin() + sup_set.size() );
00664           // check if supports includes newGroups in the same order
00665           bool sameOrder = true;
00666           for ( size_t j = newGroups.size(); j < supports.size() && sameOrder; ++j )
00667             sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]);
00668           if ( sameOrder )
00669             {
00670               _iMed->_groups.push_back( SauvUtilities::Group() );
00671               group = & _iMed->_groups.back();
00672               group->_groups.swap( newGroups );
00673             }
00674         }
00675     }
00676   if ( group )
00677     group->_isProfile = true;
00678   return group;
00679 }
00680 
00681 //================================================================================
00685 //================================================================================
00686 
00687 void SauvReader::setFieldNames(const vector<SauvUtilities::DoubleField* >& fields,
00688                                const vector<string>&                       objets_nommes,
00689                                const vector<int>&                          indices_objets_nommes)
00690 {
00691   unsigned i;
00692   for ( i = 0; i < indices_objets_nommes.size(); ++i )
00693     {
00694       int fieldIndex = indices_objets_nommes[ i ];
00695       if ( fields[ fieldIndex - 1 ] )
00696         fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ];
00697     }
00698 }
00699 
00700 //================================================================================
00704 //================================================================================
00705 
00706 void SauvReader::read_PILE_NODES_FIELD (const int                 nbObjects,
00707                                         std::vector<std::string>& objectNames,
00708                                         std::vector<int>&         nameIndices)
00709 {
00710   _iMed->_nodeFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 );
00711   for (int object=0; object!=nbObjects; ++object) // loop on fields
00712     {
00713       // EXAMPLE ( with no values )
00714 
00715       // (1)       4       7       2       1
00716       // (2)     -88       0       3     -89       0       1     -90       0       2     -91
00717       // (2)       0       1
00718       // (3) FX   FY   FZ   FZ   FX   FY   FLX
00719       // (4)       0       0       0       0       0       0       0
00720       // (5)           cree  par  muc pri
00721       // (6)
00722       // (7)       2
00723 
00724       // (1): nb subcomponents, nb components(total), IFOUR, nb attributes
00725       int nb_sub, total_nb_comp, nb_attr;
00726       int i_sub, i_comp;
00727       initIntReading( 4 );
00728       nb_sub        = getIntNext();
00729       total_nb_comp = getIntNext();
00730       next(); // ignore IFOUR
00731       nb_attr       = getIntNext();
00732       if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 )
00733         THROW_IK_EXCEPTION("Error of field reading " << lineNb());
00734 
00735       // (2) loop on subcomponents of a field, for each read
00736       // (a) support, (b) number of values and (c) number of components
00737       vector<Group*> supports( nb_sub );
00738       vector<int> nb_values  ( nb_sub );
00739       vector<int> nb_comps   ( nb_sub );
00740       int total_nb_values = 0;
00741       initIntReading( nb_sub * 3 );
00742       for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00743         {
00744           int supId = -getIntNext(); // (a) reference to support
00745           if ( supId < 1 || supId > (int)_iMed->_groups.size() )
00746             THROW_IK_EXCEPTION("Wrong mesh reference: "<< supId << lineNb() );
00747           supports[ i_sub ] = &_iMed->_groups[ supId-1 ]; // (a) reference to support
00748 
00749           nb_values[ i_sub ] = getIntNext();    // (b) nb points
00750           total_nb_values += nb_values[ i_sub ];
00751           if ( nb_values[ i_sub ] < 0 )
00752             THROW_IK_EXCEPTION(" Wrong nb of points: " << nb_values[ i_sub ]  << lineNb() );
00753           nb_comps[ i_sub ] = getInt(); next();     // (c) nb of components in i_sub
00754         }
00755 
00756       // create a field if there are values
00757       SauvUtilities::DoubleField* fdouble = 0;
00758       if ( total_nb_values > 0 )
00759         fdouble = new DoubleField( nb_sub, total_nb_comp );
00760       _iMed->_nodeFields[ object ] = fdouble;
00761 
00762       // (3) component names
00763       initNameReading( total_nb_comp, 4 );
00764       for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00765         {
00766           // store support id and nb components of a sub
00767           if ( fdouble )
00768             fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], supports[ i_sub ] );
00769           for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() )
00770             {
00771               // store component name
00772               string compName = getName();
00773               if ( fdouble )
00774                 fdouble->_sub[ i_sub ].compName( i_comp ) = compName;
00775             }
00776         }
00777       // (4) nb harmonics ( ignored )
00778       for ( initIntReading( total_nb_comp ); more(); next() );
00779       // (5) TYPE ( ignored )
00780       for (initNameReading(1, /*length=*/71); more(); next());
00781       // (6) TITRE ( ignored )
00782       for (initNameReading(1, /*length=*/71); more(); next());
00783       // (7) attributes ( ignored )
00784       for ( initIntReading( nb_attr ); more(); next() );
00785 
00786       for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00787         {
00788           // loop on components: read values
00789           initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] );
00790           for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp )
00791             {
00792               if ( fdouble )
00793                 {
00794                   vector<double>& vals = fdouble->addComponent( nb_values[ i_sub ] );
00795                   for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i )
00796                     vals[ i ] = getDouble();
00797                 }
00798               else
00799                 {
00800                   for ( int i = 0; i < nb_values[ i_sub ]; next(), ++i );
00801                 }
00802             }
00803         } // loop on subcomponents of a field
00804 
00805       // set a supporting group including all subs supports but only
00806       // if all subs have the same components
00807       if ( fdouble && fdouble->hasSameComponentsBySupport() )
00808         fdouble->_group = getFieldSupport( supports );
00809       else
00810         for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00811           fdouble->_sub[ i_sub ]._support->_isProfile;
00812 
00813     } // end loop on field objects
00814 
00815   // set field names
00816   setFieldNames( _iMed->_nodeFields, objectNames, nameIndices );
00817 
00818 }  // read_PILE_NODES_FIELD()
00819 
00820 //================================================================================
00824 //================================================================================
00825 
00826 void SauvReader::read_PILE_FIELD (const int                 nbObjects,
00827                                   std::vector<std::string>& objectNames,
00828                                   std::vector<int>&         nameIndices)
00829 {
00830   // REAL EXAMPLE
00831 
00832   // (1)        1       2       6      16
00833   // (2)                                                         CARACTERISTIQUES
00834   // (3)      -15  317773       4       0       0       0      -2       0       3
00835   // (4)             317581
00836   // (5)  0
00837   // (6)   317767  317761  317755  317815
00838   // (7)  YOUN     NU       H        SIGY
00839   // (8)  REAL*8            REAL*8            REAL*8            REAL*8
00840   // (9)        1       1       0       0
00841   // (10)  2.00000000000000E+05
00842   // (11)       1       1       0       0
00843   // (12)  3.30000000000000E-01
00844   // (13)       1       1       0       0
00845   // (14)  1.00000000000000E+04
00846   // (15)       6     706       0       0
00847   // (16)  1.00000000000000E+02  1.00000000000000E+02  1.00000000000000E+02
00848   // (17)  1.00000000000000E+02  1.00000000000000E+02  1.00000000000000E+02
00849   // (18)  ...
00850 
00851   _iMed->_cellFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 );
00852   for (int object=0; object!=nbObjects; ++object) // pour chaque field
00853     {
00854       initIntReading( 4 );
00855       int i_sub, nb_sub = getIntNext(); // (1) <nb_sub> 2 6 <title length>
00856       next(); // skip "2"
00857       next(); // skip "6"
00858       int title_length = getIntNext(); // <title length>
00859       if ( nb_sub < 1 )
00860         THROW_IK_EXCEPTION("Error of field reading: wrong nb of subcomponents " << nb_sub << lineNb() );
00861 
00862       string description;
00863       if ( title_length )
00864         {
00865           if ( isXRD() )
00866             {
00867               initNameReading(1, title_length);
00868               description = getName();
00869               next();
00870             }
00871           else
00872             {
00873               char* line;
00874               getNextLine( line ); // (2) title
00875               const int len = 72; // line length
00876               description = string(line + len - title_length, title_length); // title is right justified
00877             }
00878         }
00879       // look for a line starting with '-' : <reference to support>
00880       if ( isXRD() )
00881         {
00882           initIntReading( nb_sub * 9 );
00883         }
00884       else
00885         {
00886           do {
00887             initIntReading( nb_sub * 9 );
00888           } while ( getInt() >= 0 );
00889         }
00890       int total_nb_comp = 0;
00891       vector<Group*> supports( nb_sub );
00892       vector<int>     nb_comp( nb_sub );
00893       for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00894         {                                    // (3)
00895           int supportId     = -getIntNext(); // <reference to support>
00896           next();                            // ignore <address>
00897           nb_comp [ i_sub ] =  getIntNext(); // <nb of components in the sub>
00898           for ( int i = 0; i < 6; ++i ) next();  // ignore 6 ints, in example "0 0 0 -2 0 3"
00899 
00900           if ( supportId < 1 || supportId > (int)_iMed->_groups.size() )
00901             THROW_IK_EXCEPTION("Error of field reading: wrong mesh reference "<< supportId << lineNb() );
00902           if ( nb_comp[ i_sub ] < 0 )
00903             THROW_IK_EXCEPTION("Error of field reading: wrong nb of components " <<nb_comp[ i_sub ] << lineNb() );
00904 
00905           supports[ i_sub ] = &_iMed->_groups[ supportId-1 ];
00906           total_nb_comp += nb_comp[ i_sub ];
00907         }
00908       // (4) dummy strings
00909       for ( initNameReading( nb_sub, 17 ); more(); next() );
00910       // (5) dummy strings
00911       for ( initNameReading( nb_sub ); more(); next() );
00912 
00913       // loop on subcomponents of a field, each of which refers to
00914       // a certain support and has its own number of components;
00915       // read component values
00916       SauvUtilities::DoubleField* fdouble = 0;
00917       for ( i_sub = 0; i_sub < nb_sub; ++ i_sub )
00918         {
00919           vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]);
00920           // (6) nb_comp addresses of MELVAL structure
00921           for ( initIntReading( nb_comp[ i_sub ] ); more(); next() );
00922           // (7) component names
00923           for ( initNameReading( nb_comp[ i_sub ] ); more(); next() )
00924             comp_names[ index() ] = getName();
00925           // (8) component type
00926           for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) // 17 is name width
00927             {
00928               comp_type[ index() ] = getName();
00929               // component types must be the same
00930               if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] )
00931                 THROW_IK_EXCEPTION( "Error of field reading: diff component types <"
00932                                     << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ]
00933                                     << ">" << lineNb() );
00934             }
00935           // now type is known, create a field, one for all subs
00936           bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true;
00937           if ( !fdouble && total_nb_comp )
00938             {
00939               if ( !isReal )
00940                 cout << "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << lineNb() << endl;
00941               _iMed->_cellFields[ object ] = fdouble = new SauvUtilities::DoubleField( nb_sub, total_nb_comp );
00942               fdouble->_description = description;
00943             }
00944           // store support id and nb components of a sub
00945           if ( fdouble )
00946             fdouble->_sub[ i_sub ].setData( nb_comp[ i_sub ], supports[ i_sub ]);
00947           // loop on components: read values
00948           for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp )
00949             {
00950               // (9) nb of values
00951               initIntReading( 4 );
00952               int nb_val_by_elem = getIntNext();
00953               int nb_values      = getIntNext();
00954               next();
00955               next();
00956               fdouble->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem;
00957 
00958               // (10) values
00959               nb_values *= nb_val_by_elem;
00960               if ( fdouble )
00961                 {
00962                   vector<double> & vals = fdouble->addComponent( nb_values );
00963                   for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next())
00964                     vals[ index() ] = getDouble();
00965                   // store component name
00966                   fdouble->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ];
00967                 }
00968               else
00969                 {
00970                   for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next() ) ;
00971                 }
00972             }
00973         } // loop on subcomponents of a field
00974 
00975       // set id of a group including all sub supports but only
00976       // if all subs have the same nb of components
00977       if ( fdouble && fdouble->hasSameComponentsBySupport() )
00978         fdouble->_group = getFieldSupport( supports );
00979       else
00980         for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
00981           fdouble->_sub[ i_sub ]._support->_isProfile = true;
00982 
00983     } // end loop on field objects
00984 
00985   // set field names
00986   setFieldNames( _iMed->_cellFields, objectNames, nameIndices );
00987 
00988 } // read_PILE_FIELD()
00989 
00990 //================================================================================
00994 //================================================================================
00995 
00996 void SauvReader::read_PILE_TABLES (const int                 nbObjects,
00997                                    std::vector<std::string>& objectNames,
00998                                    std::vector<int>&         nameIndices)
00999 {
01000   // IMP 0020434: mapping GIBI names to MED names
01001 
01002   string table_med_mail = "MED_MAIL";
01003   string table_med_cham = "MED_CHAM";
01004   string table_med_comp = "MED_COMP";
01005   int table_med_mail_id = -1;
01006   int table_med_cham_id = -1;
01007   int table_med_comp_id = -1;
01008   for (size_t iname = 0; iname < objectNames.size(); iname++)
01009     if      (objectNames[iname] == table_med_mail) table_med_mail_id = nameIndices[iname];
01010     else if (objectNames[iname] == table_med_cham) table_med_cham_id = nameIndices[iname];
01011     else if (objectNames[iname] == table_med_comp) table_med_comp_id = nameIndices[iname];
01012 
01013   if ( isASCII() )
01014     if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0)
01015       return;
01016 
01017   for (int itable = 1; itable <= nbObjects; itable++)
01018     {
01019       // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence
01020       // between GIBI names (8 symbols if any) and MED names (possibly longer)
01021       initIntReading(1);
01022       int nb_table_vals = getIntNext();
01023       if (nb_table_vals < 0)
01024         THROW_IK_EXCEPTION("Error of reading PILE NUMERO  10" << lineNb() );
01025 
01026       int name_i_med_pile;
01027       initIntReading(nb_table_vals);
01028       for (int i = 0; i < nb_table_vals/4; i++)
01029         {
01030           if (itable == table_med_mail_id ||
01031               itable == table_med_cham_id ||
01032               itable == table_med_comp_id)
01033             {
01034               nameGIBItoMED name_i;
01035               name_i_med_pile  = getIntNext();
01036               name_i.med_id    = getIntNext();
01037               name_i.gibi_pile = getIntNext();
01038               name_i.gibi_id   = getIntNext();
01039 
01040               if (name_i_med_pile != PILE_STRINGS)
01041                 {
01042                   // error: med(long) names are always kept in PILE_STRINGS
01043                 }
01044               if (itable == table_med_mail_id)
01045                 {
01046                   if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) {
01047                     // error: must be PILE_SOUS_MAILLAGE
01048                   }
01049                   _iMed->_listGIBItoMED_mail.push_back(name_i);
01050                 }
01051               else if (itable == table_med_cham_id)
01052                 {
01053                   if (name_i.gibi_pile != PILE_FIELD &&
01054                       name_i.gibi_pile != PILE_NODES_FIELD)
01055                     {
01056                       // error: must be PILE_FIELD or PILE_NODES_FIELD
01057                     }
01058                   _iMed->_listGIBItoMED_cham.push_back(name_i);
01059                 }
01060               else if (itable == table_med_comp_id)
01061                 {
01062                   if (name_i.gibi_pile != PILE_STRINGS)
01063                     {
01064                       // error: gibi(short) names of components are kept in PILE_STRINGS
01065                     }
01066                   _iMed->_listGIBItoMED_comp.push_back(name_i);
01067                 }
01068             }
01069           else
01070             {
01071               // pass table
01072               for ( int ii = 0; ii < 4; ++ii ) next();
01073             }
01074         }
01075     } // for (int itable = 0; itable < nbObjects; itable++)
01076 }
01077 
01078 //================================================================================
01082 //================================================================================
01083 
01084 void SauvReader::read_PILE_STRINGS (const int                 nbObjects,
01085                                     std::vector<std::string>& objectNames,
01086                                     std::vector<int>&         nameIndices)
01087 {
01088   // IMP 0020434: mapping GIBI names to MED names
01089   initIntReading(2);
01090   int stringLen    = getIntNext();
01091   int nbSubStrings = getIntNext();
01092   if (nbSubStrings != nbObjects)
01093     THROW_IK_EXCEPTION("Error of reading PILE NUMERO  27" << lineNb() );
01094 
01095   string aWholeString;
01096   if ( isXRD() )
01097     {
01098       const int fixedLength = 71;
01099       while ((int)aWholeString.length() < stringLen)
01100         {
01101           int remainLen = stringLen - aWholeString.length();
01102           int len;
01103           if ( remainLen > fixedLength )
01104             {
01105               len = fixedLength;
01106             }
01107           else
01108             {
01109               len = remainLen;
01110             }
01111           initNameReading(1, len);
01112           aWholeString += getName();
01113           next();
01114         }
01115     }
01116   else
01117     {
01118       char* line;
01119       const int fixedLength = 71;
01120       while ((int)aWholeString.length() < stringLen)
01121         {
01122           getNextLine( line );
01123           int remainLen = stringLen - aWholeString.length();
01124           if ( remainLen > fixedLength )
01125             {
01126               aWholeString += line + 1;
01127             }
01128           else
01129             {
01130               aWholeString += line + ( 72 - remainLen );
01131             }
01132         }
01133     }
01134   int prevOffset = 0;
01135   int currOffset = 0;
01136   initIntReading(nbSubStrings);
01137   for (int istr = 1; istr <= nbSubStrings; istr++, next())
01138     {
01139       currOffset = getInt();
01140       // fill mapStrings
01141       _iMed->_mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset);
01142       prevOffset = currOffset;
01143     }
01144 }