1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
27 #include "MEDMEM_GibiMeshDriver.hxx"
30 // On windows, this file must be included first otherwise
31 // there is a conflict with the symbol GROUP when compiling the xdr support ...
35 #include "MEDMEM_DriversDef.hxx"
37 #include "MEDMEM_Family.hxx"
38 #include "MEDMEM_Field.hxx"
39 #include "MEDMEM_Group.hxx"
40 #include "MEDMEM_Coordinate.hxx"
41 #include "MEDMEM_Connectivity.hxx"
42 #include "MEDMEM_Mesh.hxx"
43 #include "MEDMEM_CellModel.hxx"
44 #include "MEDMEM_define.hxx"
45 #include "MEDMEM_DriverTools.hxx"
64 using namespace MED_EN;
65 using namespace MEDMEM;
68 // read or not non-named fields
69 //#define GIBI_READ_ONLY_NAMED_FIELD
71 // to throw an exception when try to write a name longer than 8 or non-unique encounters
72 //#define THROW_ON_BAD_NAME
74 // to see full dump of RESULTATS STRUCTURE INTERMEDIAIRES
77 // #define MESSAGE_MED(txt) std::cout << txt << endl;
79 // #define INFOS_MED(txt) std::cout << txt << endl;
82 // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor
85 //const size_t GIBI_MESH_DRIVER::nb_geometrie_gibi;
87 const medGeometryElement GIBI_MESH_DRIVER::geomGIBItoMED[nb_geometrie_gibi] =
88 { /*1 */ MED_POINT1 ,/*2 */ MED_SEG2 ,/*3 */ MED_SEG3 ,/*4 */ MED_TRIA3 ,/*5 */ MED_NONE ,
89 /*6 */ MED_TRIA6 ,/*7 */ MED_NONE ,/*8 */ MED_QUAD4 ,/*9 */ MED_NONE ,/*10*/ MED_QUAD8 ,
90 /*11*/ MED_NONE ,/*12*/ MED_NONE ,/*13*/ MED_NONE ,/*14*/ MED_HEXA8 ,/*15*/ MED_HEXA20 ,
91 /*16*/ MED_PENTA6 ,/*17*/ MED_PENTA15,/*18*/ MED_NONE ,/*19*/ MED_NONE ,/*20*/ MED_NONE ,
92 /*21*/ MED_NONE ,/*22*/ MED_NONE ,/*23*/ MED_TETRA4 ,/*24*/ MED_TETRA10,/*25*/ MED_PYRA5 ,
93 /*26*/ MED_PYRA13 ,/*27*/ MED_NONE ,/*28*/ MED_NONE ,/*29*/ MED_NONE ,/*30*/ MED_NONE ,
94 /*31*/ MED_NONE ,/*32*/ MED_NONE ,/*33*/ MED_NONE ,/*34*/ MED_NONE ,/*35*/ MED_NONE ,
95 /*36*/ MED_NONE ,/*37*/ MED_NONE ,/*38*/ MED_NONE ,/*39*/ MED_NONE ,/*40*/ MED_NONE ,
96 /*41*/ MED_NONE ,/*42*/ MED_NONE ,/*43*/ MED_NONE ,/*44*/ MED_NONE ,/*45*/ MED_NONE ,
97 /*46*/ MED_NONE ,/*47*/ MED_NONE };
101 PILE_SOUS_MAILLAGE=1,
111 PILE_COORDONNEES =33,
114 PILE_LAST_READABLE=39
117 //=======================================================================
118 //function : gibi2medGeom
120 //=======================================================================
122 medGeometryElement GIBI_MESH_DRIVER::gibi2medGeom( size_t gibiTypeNb )
124 if ( gibiTypeNb < 1 || gibiTypeNb > 47 )
127 return geomGIBItoMED[ gibiTypeNb - 1 ];
130 //=======================================================================
131 //function : med2gibiGeom
133 //=======================================================================
135 int GIBI_MESH_DRIVER::med2gibiGeom( medGeometryElement medGeomType )
137 for ( int i = 0; i < nb_geometrie_gibi; i++ )
138 if ( geomGIBItoMED[ i ] == medGeomType )
144 //=======================================================================
145 //function : getGroupId
147 //=======================================================================
149 static int getGroupId(const vector<int>& support_ids, _intermediateMED* medi)
152 vector<int>::const_iterator sb = support_ids.begin(), se = support_ids.end();
153 if (support_ids.size() == 1 || // one or equal support ids
154 *std::max_element( sb, se ) == *std::min_element( sb, se ))
156 group_id = support_ids[0] - 1;
160 // try to find an existing group with the same sub-groups
162 sup_set.insert( sb, se );
164 for ( group_id = 0; group_id < (int)medi->groupes.size(); ++group_id )
166 if (sup_set.size() == medi->groupes[ group_id ].groupes.size() &&
167 std::equal (sup_set.begin(), sup_set.end(),
168 medi->groupes[ group_id ].groupes.begin()))
171 if ( group_id == (int)medi->groupes.size() )
173 // no such a group, add a new one
174 medi->groupes.push_back( _groupe() );
175 _groupe& new_grp = medi->groupes.back();
176 new_grp.groupes.reserve( sup_set.size() );
177 for ( set<int>::iterator it = sup_set.begin(); it != sup_set.end(); it++ ) {
178 new_grp.groupes.push_back( *it );
185 //=======================================================================
186 //function : isNamedObject
188 //=======================================================================
190 //#ifdef GIBI_READ_ONLY_NAMED_FIELD
191 static inline bool isNamedObject( int obj_index, const vector<int>& indices_objets_nommes )
193 return ( std::find( indices_objets_nommes.begin(), indices_objets_nommes.end(), obj_index)
194 != indices_objets_nommes.end() );
198 //=======================================================================
199 //function : setFieldNames
200 //purpose : set field names
201 //=======================================================================
203 static void setFieldNames(const vector< _fieldBase* >& fields,
204 const vector<string>& objets_nommes,
205 const vector<int>& indices_objets_nommes)
210 for ( i = 0; i < indices_objets_nommes.size(); ++i ) {
211 int fieldIndex = indices_objets_nommes[ i ];
212 fnames.insert( objets_nommes[ i ]);
213 if ( fields[ fieldIndex - 1 ] )
214 fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ];
217 for ( i = 0; i < fields.size(); ++i ) {
218 if ( !fields[ i ] ) {
219 if ( !isNamedObject( i+1, indices_objets_nommes ))
222 else if ( fields[ i ]->_name.empty() ) {
224 fields[ i ]->_name = STRING("F_") << ++noNameIndex;
225 } while ( !fnames.insert( fields[ i ]->_name ).second );
230 //=======================================================================
233 //=======================================================================
235 #define GIBI_EQUAL(var_str, stat_str) \
236 (strncmp (var_str, stat_str, strlen(stat_str)) == 0)
237 #define DUMP_LINE_NB " on line " << _lineNb
239 bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields )
241 const char* LOC = "GIBI_MESH_RDONLY_DRIVER::readFile() : ";
244 // LECTURE DES DONNEES DS FICHIER GIBI
246 Readable_Piles readable_Piles [] = {
262 // other known piles:
263 // PILE NUMERO 26 - Integers
264 // PILE NUMERO 25 - Floats
266 char* ligne; // pour lire une ligne
267 const char* enregistrement_type=" ENREGISTREMENT DE TYPE";
268 vector<int> numero_noeuds; // tableau de travail (indices)
269 set<int> donePiles; // already read piles
270 unsigned space_dimension = 0;
272 // IMP 0020434: mapping GIBI names to MED names
273 list<nameGIBItoMED> listGIBItoMED_mail; // to be read from PILE_TABLES, from table "MED_MAIL"
274 list<nameGIBItoMED> listGIBItoMED_cham; // to be read from PILE_TABLES, from table "MED_CHAM"
275 list<nameGIBItoMED> listGIBItoMED_comp; // to be read from PILE_TABLES, from table "MED_COMP"
276 map<int,string> mapStrings; // to be read from PILE_STRINGS
277 vector<_fieldBase*> node_fields;
278 vector<_fieldBase*> cell_fields;
289 while ( getNextLine(ligne, false)) // boucle externe de recherche de "ENREGISTREMENT DE TYPE"
294 if ( !GIBI_EQUAL( ligne, enregistrement_type ))
295 continue; // "ENREGISTREMENT DE TYPE" non trouvé -> on lit la ligne suivante
297 // lecture du numéro d'enregistrement
298 int numero_enregistrement;
301 numero_enregistrement = getInt();
304 numero_enregistrement = atoi( ligne + strlen(enregistrement_type) + 1 );
306 enum { ENREG_TYPE_2=2, ENREG_TYPE_4=4}; // énumération des types d'enregistrement traités
308 enum { ENREG_TYPE_5=5, ENREG_TYPE_7=7}; // (only for xdr)
310 int numero_pile, nb_objets_nommes, nb_objets, nb_indices;
311 vector<int> indices_objets_nommes;
312 vector<string> objets_nommes;
314 if (numero_enregistrement == ENREG_TYPE_4)
319 getInt(); // skip NIVEAU
320 getInt(); // skip ERREUR
321 space_dimension = getInt();
322 getFloat(); // skip DENSITE
328 const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION";
329 space_dimension = atoi( ligne + strlen( s ) + 1 );
330 if ( !GIBI_EQUAL( ligne, " NIVEAU" ) || space_dimension < 1 ) {
331 INFOS_MED( " Could not read file: syntax error in type 4 record" << DUMP_LINE_NB );
339 else if (numero_enregistrement == ENREG_TYPE_7)
343 getInt(); // skip NOMBRE INFO CASTEM2000
344 getInt(); // skip IFOUR
345 getInt(); // skip NIFOUR
346 getInt(); // skip IFOMOD
347 getInt(); // skip IECHO
348 getInt(); // skip IIMPI
349 getInt(); // skip IOSPI
350 getInt(); // skip ISOTYP
351 getInt(); // skip NSDPGE
355 else if (numero_enregistrement == ENREG_TYPE_2 )
357 if ( space_dimension == 0 ) {
358 INFOS_MED( "Missing ENREGISTREMENT DE TYPE 4" << DUMP_LINE_NB );
361 // FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8)
367 numero_pile = getInt(); next();
368 nb_objets_nommes = getInt(); next();
369 nb_objets = getInt(); next();
374 const char *s1 = " PILE NUMERO", *s2 = "NBRE OBJETS NOMMES", *s3 = "NBRE OBJETS";
375 if ( ! GIBI_EQUAL( ligne, s1 ) ) {
376 INFOS_MED( " Could not read file: error in type 2 record. " << ligne << DUMP_LINE_NB );
379 ligne = ligne + strlen(s1);
380 numero_pile = atoi( ligne );
381 ligne = ligne + 4 + strlen(s2);
382 nb_objets_nommes = atoi( ligne );
383 ligne = ligne + 8 + strlen(s3);
384 nb_objets = atoi( ligne );
388 if ( nb_objets_nommes<0 || nb_objets<0 ) {
389 INFOS_MED(" Could not read file: " << nb_objets << " " <<nb_objets_nommes << DUMP_LINE_NB );
392 if ( !donePiles.insert( numero_pile ).second ) // piles may repeat
395 if ( numero_pile > PILE_LAST_READABLE )
396 break; // stop file reading
398 // skip not readable piles
400 while ( readable_Piles[ ++i ] != PILE_LAST_READABLE )
401 if ( readable_Piles[ i ] == numero_pile )
403 if ( readable_Piles[ i ] != numero_pile )
408 cout << "XDR : NUMERO PILE " << numero_pile << " not implemented !!!" << endl ;
409 throw MEDEXCEPTION("XDR : NUMERO PILE not implemented !!!");
417 // lecture des objets nommés et de leurs indices
418 objets_nommes.resize(nb_objets_nommes);
419 indices_objets_nommes.resize(nb_objets_nommes);
420 //indices_objets_nommes.resize(nb_objets);
421 for ( initNameReading( nb_objets_nommes ); more(); next() ) {
422 objets_nommes[ index() ] = getName();
424 for ( initIntReading( nb_objets_nommes ); more(); next() )
425 //for ( initIntReading( nb_objets ); more(); next() )
426 indices_objets_nommes[ index() ] = getInt();
428 // boucle interne : lecture de la pile
430 MESSAGE_MED(PREFIX_MED << "---- Traitement pile " << numero_pile);
432 // -----------------------------------
434 // -----------------------------------
436 if (numero_pile == PILE_SOUS_MAILLAGE ) // PILE NUMERO 1
438 map<int,int> strangeGroupType;
439 medi->groupes.reserve(nb_objets*2); // fields may add some groups
440 map< int , int > nbElemsByGeomType;
442 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
445 unsigned type_geom_castem = getInt(); next();
446 unsigned nb_sous_maillage = getInt(); next();
447 unsigned nb_reference = getInt(); next();
448 unsigned nb_noeud = getInt(); next();
449 unsigned nb_elements = getInt();
454 // le cas type_geom_castem=0 correspond aux maillages composites
455 if (type_geom_castem<0) {
456 INFOS_MED(" Error while reading file, bad geometric type:" <<
457 type_geom_castem << DUMP_LINE_NB );
461 medi->groupes.push_back(_groupe());
462 _groupe & groupe = medi->groupes.back();
464 // Issue 0021311. Allocate places for names of referring groups
465 // that will be possibly filled after reading long names from
466 // PILE_TABLES and PILE_STRINGS
467 groupe.refNames.resize( nb_reference );
469 // si le groupe se compose de sous-maillages (ie groupe composite)
470 if (type_geom_castem==0 && nb_sous_maillage>0)
472 // lecture des indices des sous-maillages, stockage.
473 // les mailles correspondant a ces sous_maillages seront inserees a la fin du case
474 groupe.groupes.resize( nb_sous_maillage );
475 for ( initIntReading( nb_sous_maillage ); more(); next() ) {
476 groupe.groupes[ index() ] = getInt();
479 std::sort( groupe.groupes.begin(), groupe.groupes.end() );
481 // lecture des references (non utilisé pour MED)
482 for ( i = 0; i < (int)nb_reference; i += 10 ) {// FORMAT(10I8)
488 for (initIntReading(nb_reference); more(); next());
491 // lecture des couleurs (non utilisé pour MED)
492 for ( i = 0; i < (int)nb_elements; i += 10 ) {
498 for (initIntReading(nb_elements); more(); next());
501 // not a composit group
502 if (type_geom_castem>0 && nb_sous_maillage==0)
504 medGeometryElement medType = gibi2medGeom(type_geom_castem);
506 initIntReading( nb_elements * nb_noeud );
507 if ( medType == MED_NONE ) { // look for group end
510 strangeGroupType.insert( make_pair( objet, type_geom_castem ));
513 if ( medType == MED_POINT1 )
514 medType = MED_NONE; // issue 21199
515 if ( nbElemsByGeomType.find( medType ) == nbElemsByGeomType.end())
516 nbElemsByGeomType[ medType ] = 0;
517 int & order = nbElemsByGeomType[ medType ];
519 pair<set<_maille>::iterator,bool> p;
520 pair<map<int,_noeud>::iterator,bool> p_no;
522 no.coord.resize(space_dimension);
523 _maille ma( medType, nb_noeud );
524 ma.sommets.resize(nb_noeud);
525 groupe.mailles.resize( nb_elements );
527 // lecture pour chaque maille des sommets et insertions
528 for ( i = 0; i < int(nb_elements); ++i )
530 for (unsigned n = 0; n < nb_noeud; ++n, next() )
533 INFOS_MED( " Error while reading elem nodes ");
536 no.number = getInt();
537 p_no=medi->points.insert(make_pair(no.number, no));
538 ma.sommets[n]=p_no.first;
540 ma.setOrdre( ++order );
541 // on stocke dans le groupe un iterateur sur la maille
542 groupe.mailles[i] = medi->insert(ma);
548 for (i=0; i!=nb_objets_nommes; ++i) {
549 int grpID = indices_objets_nommes[i];
550 _groupe & grp = medi->groupes[ grpID-1 ];
551 if ( !grp.nom.empty() ) // a group has several names
552 { // create a group with subgroup grp and named grp.nom
553 medi->groupes.push_back(_groupe());
554 medi->groupes.back().groupes.push_back( grpID );
555 medi->groupes.back().nom = grp.nom;
557 grp.nom=objets_nommes[i];
558 map<int,int>::iterator it = strangeGroupType.find( grpID - 1 );
559 if ( it != strangeGroupType.end() ) {
561 cout << "Skip " << grp.nom << " of not supported CASTEM type: " << it->second << endl;
563 //INFOS_MED( "Skip " << grp.nom << " of not supported CASTEM type: " << it->second );
567 }// Fin case PILE_SOUS_MAILLAGE
571 // ---------------------------------
572 // ---------------------------------
574 else if ( numero_pile == PILE_LREEL ) // PILE NUMERO 18
578 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
581 int nb_vals = getInt();
583 initDoubleReading(nb_vals);
584 for(i=0; i<nb_vals; i++) next();
587 } // Fin case pile 18
589 // ---------------------------------
590 // ---------------------------------
592 else if ( numero_pile == PILE_LOGIQUES ) // PILE NUMERO 24
597 int nb_vals = getInt();
599 initIntReading(nb_vals);
600 for(i=0; i<nb_vals; i++) next();
602 } // Fin case pile 24
604 // ---------------------------------
605 // ---------------------------------
607 else if ( numero_pile == PILE_FLOATS ) // PILE NUMERO 25
612 int nb_vals = getInt();
614 initDoubleReading(nb_vals);
615 for(i=0; i<nb_vals; i++) next();
617 } // Fin case pile 25
619 // ---------------------------------
620 // ---------------------------------
622 else if ( numero_pile == PILE_INTEGERS ) // PILE NUMERO 26
627 int nb_vals = getInt();
629 initIntReading(nb_vals);
630 for(i=0; i<nb_vals; i++) next();
632 } // Fin case pile 26
634 // ---------------------------------
635 // ---------------------------------
637 else if ( numero_pile == PILE_LMOTS ) // PILE NUMERO 29
641 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
646 int nb_vals = getInt();
648 int nb_char = len*nb_vals;
650 int fixed_length = 71;
651 while (nb_char_tmp < nb_char)
653 int remain_len = nb_char - nb_char_tmp;
655 if ( remain_len > fixed_length )
657 width = fixed_length;
663 initNameReading(1, width);
665 nb_char_tmp += width;
669 } // Fin case pile 29
671 // ---------------------------------
672 // ---------------------------------
674 else if ( numero_pile == PILE_MODL ) // PILE NUMERO 38
678 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque groupe
682 int n1 = getInt() ; next();
683 int nm2 = getInt() ; next();
684 int nm3 = getInt() ; next();
685 int nm4 = getInt() ; next();
686 int nm5 = getInt() ; next();
687 int n45 = getInt() ; next();
688 /*int nm6 =*/ getInt() ; next();
689 /*int nm7 =*/ getInt() ; next();
694 for (initIntReading(nm1); more(); next());
695 for (initIntReading(nm9); more(); next());
696 for (initNameReading(nm5, 8); more(); next());
697 for (initNameReading(nm2, 8); more(); next());
698 for (initNameReading(nm3, 8); more(); next());
699 for (initIntReading(nm4); more(); next());
702 } // Fin case pile 38
706 // ---------------------------------
708 // ---------------------------------
710 else if ( numero_pile == PILE_NOEUDS ) // PILE NUMERO 32
712 getNextLine( ligne );
713 std::vector<int> place_noeuds;
718 nb_indices = getInt();
723 nb_indices = atoi ( ligne );
724 if (nb_indices != nb_objets)
726 INFOS_MED("Erreur de lecture dans enregistrement de pile " <<
727 PILE_NOEUDS << DUMP_LINE_NB );
731 place_noeuds.resize(nb_objets);
732 for ( initIntReading( nb_objets ); more(); next() )
733 place_noeuds[ index() ] = getInt();
734 int max=(* std::max_element(place_noeuds.begin(),place_noeuds.end()));
736 // numero_noeuds contient pour chacun des max noeuds qu'on va lire dans le case PILE_COORDONNEES
737 // son indice dans la connectivite du maillage. Cet indice correspond egalement a la cle du map
738 // medi->points ou l'on stocke les noeuds.
739 numero_noeuds.resize(max,-1);
740 for (unsigned i=0; i!=place_noeuds.size(); ++i)
741 numero_noeuds[place_noeuds[i]-1]=i+1;
744 // ---------------------------------------
746 // ---------------------------------------
748 else if ( numero_pile == PILE_COORDONNEES )// PILE NUMERO 33
750 getNextLine( ligne );
761 nb_reels = atoi( ligne );
762 // PROVISOIRE : certains fichier gibi n`ont
763 if (nb_reels < numero_noeuds.size()*(space_dimension)) {
764 INFOS_MED("Erreur de lecture dans enregistrement de pile " <<
765 PILE_COORDONNEES << DUMP_LINE_NB );
768 initDoubleReading( nb_reels );
769 map< int, _noeud >::iterator pIt;
770 for (unsigned i=0; i!=numero_noeuds.size(); ++i)
772 // si le noeud est utilisé dans le maillage,
773 //on lit ses coordonnées et on les stocke dans la structure
774 if (( numero_noeuds[i] != -1 ) &&
775 (( pIt = medi->points.find(numero_noeuds[i])) != medi->points.end()))
777 for (unsigned j=0; j!=space_dimension; ++j, next())
778 pIt->second.coord[j] = getDouble();
780 if(_is_xdr) getDouble(); // skip density
782 next(); // on ne conserve pas la densite
784 else // sinon, on passe au noeud suivant
786 for (unsigned j=0; j!=space_dimension+1; ++j)
789 if(_is_xdr) getDouble(); // skip ...
800 for(unsigned i=0; i!=nb_reels-numero_noeuds.size()*(space_dimension+1); ++i)
808 // ---------------------------------------
810 // ---------------------------------------
812 else if ( numero_pile == PILE_NODES_FIELD && readFields ) // PILE NUMERO 2
814 //vector< _fieldBase* > fields( nb_objets );
815 node_fields.resize(nb_objets, (_fieldBase*)0);
816 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque field
818 bool ignoreField = false;
819 #ifdef GIBI_READ_ONLY_NAMED_FIELD
820 ignoreField = !isNamedObject( objet+1, indices_objets_nommes );
822 INFOS_MED("Skip non-named field " << objet+1 << DUMP_LINE_NB);
825 // EXAMPLE ( with no values )
828 // (2) -88 0 3 -89 0 1 -90 0 2 -91
830 // (3) FX FY FZ FZ FX FY FLX
832 // (5) cree par muc pri
836 // (1): nb subcomponents, nb components(total), IFOUR, nb attributes
838 int i_sub, nb_sub = getInt(); next();
839 int i_comp, total_nb_comp = getInt(); next();
840 next(); // ignore IFOUR
841 int nb_attr = getInt();
845 if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 ) {
846 INFOS_MED("Error of field reading: wrong nb of components "
847 << nb_sub << " " << total_nb_comp << DUMP_LINE_NB);
850 // (2) loop on subcomponents of a field, for each read
851 // (a) support, (b) number of values and (c) number of components
852 vector<int> support_ids( nb_sub );
853 vector<int> nb_values ( nb_sub );
854 vector<int> nb_comps ( nb_sub );
855 int total_nb_values = 0;
856 initIntReading( nb_sub * 3 );
857 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
859 support_ids[ i_sub ] = -getInt(); next(); // (a) reference to support
860 if ( support_ids[ i_sub ] < 1 || support_ids[ i_sub ] > (int)medi->groupes.size() ) {
861 INFOS_MED("Error of field reading: wrong mesh reference "<<
862 support_ids[ i_sub ] << DUMP_LINE_NB );
865 nb_values[ i_sub ] = getInt(); next(); // (b) nb points
866 total_nb_values += nb_values[ i_sub ];
867 if ( nb_values[ i_sub ] < 0 ) {
868 INFOS_MED(" Wrong nb of points: " << nb_values[ i_sub ] << DUMP_LINE_NB );
871 nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub
873 // create a field if there are values
874 _field<double>* fdouble = 0;
875 if ( total_nb_values > 0 && !ignoreField )
877 fdouble = new _field<double>( MED_REEL64, nb_sub, total_nb_comp );
878 medi->fields.push_back( node_fields[ objet ] = fdouble );
880 // (3) component names
881 initNameReading( total_nb_comp, 4 );
882 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
884 // store support id and nb components of a sub
886 fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], support_ids[ i_sub ] );
887 for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() )
889 ASSERT_MED( more() );
890 // store component name
892 fdouble->_sub[ i_sub ].compName( i_comp ) = getName();
895 // (4) nb harmonics ( ignored )
896 for ( initIntReading( total_nb_comp ); more(); next() )
898 // (5) TYPE ( ignored )
899 getNextLine( ligne );
901 if(_is_xdr) for (initNameReading(1, 71); more(); next());
903 // (6) TITRE ( ignored )
904 getNextLine( ligne );
906 if(_is_xdr) for (initNameReading(1, 71); more(); next());
908 // (7) attributes ( ignored )
909 for ( initIntReading( nb_attr ); more(); next() )
912 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
914 // loop on components: read values
915 initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] );
916 for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp )
918 vector<double>* vals = 0;
919 if ( fdouble ) vals = & fdouble->addComponent( nb_values[ i_sub ] );
920 for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i ) {
921 if ( vals ) (*vals)[ i ] = getDouble();
924 } // loop on subcomponents of a field
926 // set id of a group including all subs supports but only
927 // if all subs have the same components
928 if ( fdouble && fdouble->hasSameComponentsBySupport() )
929 fdouble->_group_id = getGroupId( support_ids, medi );
931 } // end loop on field objects
934 setFieldNames( node_fields, objets_nommes, indices_objets_nommes );
936 } // Fin numero_pile == PILE_NODES_FIELD
938 // -------------------------------------------------
940 // -------------------------------------------------
942 else if ( numero_pile == PILE_FIELD && readFields ) // PILE NUMERO 39
947 // (2) CARACTERISTIQUES
948 // (3) -15 317773 4 0 0 0 -2 0 3
951 // (6) 317767 317761 317755 317815
952 // (7) YOUN NU H SIGY
953 // (8) REAL*8 REAL*8 REAL*8 REAL*8
955 // (10) 2.00000000000000E+05
957 // (12) 3.30000000000000E-01
959 // (14) 1.00000000000000E+04
961 // (16) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02
962 // (17) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02
965 //vector< _fieldBase* > fields( nb_objets, (_fieldBase*)0 );
966 cell_fields.resize(nb_objets, (_fieldBase*)0);
967 for (int objet=0; objet!=nb_objets; ++objet) // pour chaque field
969 bool ignoreField = false;
970 #ifdef GIBI_READ_ONLY_NAMED_FIELD
971 ignoreField = !isNamedObject( objet+1, indices_objets_nommes );
973 INFOS_MED("Skip non-named field " << objet+1 << DUMP_LINE_NB);
976 int i_sub, nb_sub = getInt(); // (1) <nb_sub> 2 6 <title length>
978 INFOS_MED("Error of field reading: wrong nb of subcomponents " <<
979 nb_sub << DUMP_LINE_NB );
982 next(); next(); next(); // skip (1) <nb_sub> 2 6
983 int title_length = getInt(); // <title length>
988 if ( title_length ) {
992 initNameReading(1, title_length);
993 description = getName();
999 getNextLine( ligne ); // (2) title
1000 const int len = 72; // line length
1001 // title is right justified
1002 description = string(ligne + len - title_length, title_length);
1007 // look for a line starting with '-' : <reference to support>
1011 initIntReading( nb_sub * 9 );
1017 initIntReading( nb_sub * 9 );
1018 } while ( getInt() >= 0 );
1022 int total_nb_comp = 0;
1023 vector<int> support_ids( nb_sub ), nb_comp( nb_sub );
1024 for ( i_sub = 0; i_sub < nb_sub; ++i_sub )
1026 support_ids[ i_sub ] = -getInt(); next(); // <reference to support>
1027 next(); // ignore <address>
1028 nb_comp [ i_sub ] = getInt(); next(); // <nb of components in the sub>
1029 for ( i = 0; i < 6; ++i ) // ignore 6 ints, in example 0 0 0 -2 0 3
1031 if ( support_ids[ i_sub ] < 1 || support_ids[ i_sub ] > (int)medi->groupes.size() ) {
1032 INFOS_MED("Error of field reading: wrong mesh reference "<<
1033 support_ids[ i_sub ] << DUMP_LINE_NB );
1036 if ( nb_comp[ i_sub ] < 0 /*1*/ ) { // [SALOME platform 0019886]
1037 INFOS_MED("Error of field reading: wrong nb of components " <<
1038 nb_comp[ i_sub ] << DUMP_LINE_NB );
1041 total_nb_comp += nb_comp[ i_sub ];
1043 for ( initNameReading( nb_sub, 17 ); more(); next() )
1044 ; // (4) dummy strings
1045 for ( initNameReading( nb_sub ); more(); next() )
1046 ; // (5) dummy strings
1048 // loop on subcomponents of a field, each of which refers to
1049 // a certain support and has its own number of components;
1050 // read component values
1051 _field<double>* fdouble = 0;
1052 _field<int>* fint = 0;
1053 _fieldBase * fbase = 0;
1054 for ( i_sub = 0; i_sub < nb_sub; ++ i_sub )
1056 vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]);
1057 for ( initIntReading( nb_comp[ i_sub ] ); more(); next() )
1058 ; // (6) nb_comp addresses of MELVAL structure
1060 // (7) component names
1061 for ( initNameReading( nb_comp[ i_sub ] ); more(); next() )
1062 comp_names[ index() ] = getName();
1064 // (8) component type
1065 for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) { // 17 is name width
1066 comp_type[ index() ] = getName();
1067 // component types must be the same
1068 if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] ) {
1069 INFOS_MED( "Error of field reading: diff component types <"
1070 << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ]
1071 << ">" << DUMP_LINE_NB );
1075 // now type is known, create a field, one for all subs
1076 bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true;
1077 if ( !ignoreField && !fbase && total_nb_comp ) {
1079 fbase = fint = new _field<int>( MED_INT32, nb_sub, total_nb_comp );
1080 INFOS_MED( "Warning: read NOT REAL field, type <" << comp_type[0] << ">"
1084 fbase = fdouble = new _field<double>( MED_REEL64, nb_sub, total_nb_comp );
1085 medi->fields.push_back( cell_fields[ objet ] = fbase ); // medi->fields is a std::list
1087 // store support id and nb components of a sub
1089 fbase->_sub[ i_sub ].setData( nb_comp[ i_sub ], support_ids[ i_sub ]);
1090 fbase->_description = description;
1092 // loop on components: read values
1093 for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp )
1097 if(_is_xdr) initIntReading( 4 );
1098 else initIntReading( 2 );
1100 initIntReading( 2 );
1102 int nb_val_by_elem = getInt(); next();
1103 int nb_values = getInt();
1105 if(_is_xdr) { next(); next(); next(); }
1107 fbase->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem;
1109 nb_values *= nb_val_by_elem;
1112 vector<double> & vals = fdouble->addComponent( nb_values );
1113 for ( initDoubleReading( nb_values ); more(); next()) {
1114 vals[ index() ] = getDouble();
1118 vector<int> & vals = fint->addComponent( nb_values );
1119 for ( initIntReading( nb_values ); more(); next() ) {
1120 vals[ index() ] = getInt();
1123 // store component name
1124 fbase->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ];
1127 for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values );
1132 } // loop on subcomponents of a field
1134 // set id of a group including all sub supports but only
1135 // if all subs have the same nb of components
1136 if ( fbase && fbase->hasSameComponentsBySupport() )
1137 fbase->_group_id = getGroupId( support_ids, medi );
1139 } // end loop on field objects
1142 setFieldNames( cell_fields, objets_nommes, indices_objets_nommes );
1144 } // numero_pile == PILE_FIELD && readFields
1146 // ---------------------------------------
1148 // ---------------------------------------
1150 // IMP 0020434: mapping GIBI names to MED names
1151 else if (numero_pile == PILE_TABLES)
1153 const char * table_med_mail = "MED_MAIL";
1154 const char * table_med_cham = "MED_CHAM";
1155 const char * table_med_comp = "MED_COMP";
1157 int table_med_mail_id = -1;
1158 int table_med_cham_id = -1;
1159 int table_med_comp_id = -1;
1161 for (int iname = 0; iname < nb_objets_nommes; iname++) {
1162 if (strcmp(objets_nommes[iname].c_str(), table_med_mail) == 0) {
1163 table_med_mail_id = indices_objets_nommes[iname];
1165 else if (strcmp(objets_nommes[iname].c_str(), table_med_cham) == 0) {
1166 table_med_cham_id = indices_objets_nommes[iname];
1168 else if (strcmp(objets_nommes[iname].c_str(), table_med_comp) == 0) {
1169 table_med_comp_id = indices_objets_nommes[iname];
1174 //if (noms_med_id < 0) continue;
1175 if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0)
1181 for (int itable = 1; itable <= nb_objets; itable++) {
1182 // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence
1183 // between GIBI names (8 symbols if any) and MED names (possibly longer)
1185 int nb_table_vals = getInt(); next();
1186 if (nb_table_vals < 0) {
1187 INFOS_MED("Erreur de lecture dans enregistrement de pile " <<
1188 PILE_TABLES << DUMP_LINE_NB );
1192 int name_i_med_pile;
1193 initIntReading(nb_table_vals);
1194 for (int i = 0; i < nb_table_vals/4; i++)
1196 if (itable == table_med_mail_id ||
1197 itable == table_med_cham_id ||
1198 itable == table_med_comp_id)
1200 nameGIBItoMED name_i;
1201 name_i_med_pile = getInt(); next();
1202 name_i.med_id = getInt(); next();
1203 name_i.gibi_pile = getInt(); next();
1204 name_i.gibi_id = getInt(); next();
1206 if (name_i_med_pile != PILE_STRINGS) {
1207 // error: med(long) names are always kept in PILE_STRINGS
1210 if (itable == table_med_mail_id) {
1211 if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) {
1212 // error: must be PILE_SOUS_MAILLAGE
1214 listGIBItoMED_mail.push_back(name_i);
1216 else if (itable == table_med_cham_id) {
1217 if (name_i.gibi_pile != PILE_FIELD &&
1218 name_i.gibi_pile != PILE_NODES_FIELD) {
1219 // error: must be PILE_FIELD or PILE_NODES_FIELD
1221 listGIBItoMED_cham.push_back(name_i);
1223 else if (itable == table_med_comp_id) {
1224 if (name_i.gibi_pile != PILE_STRINGS) {
1225 // error: gibi(short) names of components are kept in PILE_STRINGS
1227 listGIBItoMED_comp.push_back(name_i);
1235 next(); next(); next(); next();
1238 } // for (int itable = 0; itable < nb_objets; itable++)
1239 } // numero_pile == PILE_TABLES
1241 // ---------------------------------------
1243 // ---------------------------------------
1245 // IMP 0020434: mapping GIBI names to MED names
1246 else if (numero_pile == PILE_STRINGS)
1249 int stringLen = getInt(); next();
1250 int nbSubStrings = getInt(); next();
1251 if (nbSubStrings != nb_objets) {
1254 string aWholeString;
1258 const int fixedLength = 71;
1259 while ((int)aWholeString.length() < stringLen) {
1260 int remainLen = stringLen - aWholeString.length();
1262 if ( remainLen > fixedLength )
1270 initNameReading(1, len);
1271 aWholeString += getName();
1279 const int fixedLength = 71;
1280 while ((int)aWholeString.length() < stringLen) {
1281 getNextLine( ligne );
1282 int remainLen = stringLen - aWholeString.length();
1283 if ( remainLen > fixedLength )
1285 aWholeString += ligne + 1;
1289 aWholeString += ligne + ( 72 - remainLen );
1297 initIntReading(nbSubStrings);
1298 for (int istr = 1; istr <= nbSubStrings; istr++, next()) {
1299 currOffset = getInt();
1301 mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset);
1302 prevOffset = currOffset;
1306 else if ( numero_pile >= PILE_LAST_READABLE )
1307 break; // stop file reading
1309 } // Fin case ENREG_TYPE_2
1311 else if (numero_enregistrement == ENREG_TYPE_5 )
1324 cout << "XDR : ENREGISTREMENT DE TYPE " << numero_enregistrement << " not implemented !!!" << endl;
1325 throw MEDEXCEPTION("XDR : ENREGISTREMENT DE TYPE not implemented !!!");
1329 } // fin de la boucle while de lecture externe
1331 // IMP 0020434: mapping GIBI names to MED names
1332 // set med names to objects (mesh, fields, support, group or other)
1333 if (listGIBItoMED_mail.size() > 0) {
1334 set<int> treatedGroups;
1335 list<nameGIBItoMED>::iterator itGIBItoMED = listGIBItoMED_mail.begin();
1336 for (; itGIBItoMED != listGIBItoMED_mail.end(); itGIBItoMED++) {
1337 if ( (int)medi->groupes.size() < itGIBItoMED->gibi_id ) continue;
1338 _groupe & grp = medi->groupes[itGIBItoMED->gibi_id - 1];
1339 // if there are several names for grp then the 1st name is the name
1340 // of grp and the rest ones are names of groups referring grp (issue 0021311)
1341 const bool isRefName = !treatedGroups.insert( itGIBItoMED->gibi_id ).second;
1343 grp.nom = mapStrings[ itGIBItoMED->med_id ];
1345 for ( unsigned i = 0; i < grp.refNames.size(); ++i )
1346 if ( grp.refNames[i].empty() )
1347 grp.refNames[i] = mapStrings[ itGIBItoMED->med_id ];
1348 } // iterate on listGIBItoMED_mail
1350 if (listGIBItoMED_cham.size() > 0) {
1351 list<nameGIBItoMED>::iterator itGIBItoMED = listGIBItoMED_cham.begin();
1352 for (; itGIBItoMED != listGIBItoMED_cham.end(); itGIBItoMED++) {
1353 if (itGIBItoMED->gibi_pile == PILE_FIELD) {
1354 cell_fields[itGIBItoMED->gibi_id - 1]->_name = mapStrings[itGIBItoMED->med_id];
1356 else if (itGIBItoMED->gibi_pile == PILE_NODES_FIELD) {
1357 node_fields[itGIBItoMED->gibi_id - 1]->_name = mapStrings[itGIBItoMED->med_id];
1361 } // iterate on listGIBItoMED_cham
1363 if (listGIBItoMED_comp.size() > 0) {
1364 list<nameGIBItoMED>::iterator itGIBItoMED = listGIBItoMED_comp.begin();
1365 for (; itGIBItoMED != listGIBItoMED_comp.end(); itGIBItoMED++)
1367 string medName = mapStrings[itGIBItoMED->med_id];
1368 string gibiName = mapStrings[itGIBItoMED->gibi_id];
1370 bool name_found = false;
1371 for ( int isNodal = 0; isNodal < 2 && !name_found; ++isNodal )
1373 vector<_fieldBase*> & fields = isNodal ? node_fields : cell_fields;
1374 for ( unsigned ifi = 0; ifi < fields.size() && !name_found; ifi++)
1376 if (medName.find( fields[ifi]->_name + "." ) == 0 ) {
1377 std::vector<_fieldBase::_sub_data>& aSubDs = fields[ifi]->_sub;
1378 int nbSub = aSubDs.size();
1379 for (int isu = 0; isu < nbSub; isu++) {
1380 for (int ico = 0; ico < aSubDs[isu].nbComponents(); ico++) {
1381 if (aSubDs[isu].compName(ico) == gibiName) {
1382 string medNameCompo = medName.substr( fields[ifi]->_name.size() + 1 );
1383 fields[ifi]->_sub[isu].compName(ico) = medNameCompo;
1390 } // iterate on listGIBItoMED_comp
1393 // check if all needed piles present
1394 if ( donePiles.find( PILE_SOUS_MAILLAGE ) != donePiles.end() )
1396 if (donePiles.find( PILE_NOEUDS ) == donePiles.end() ) {
1397 INFOS_MED( " Missing pile " << PILE_NOEUDS );
1400 if (donePiles.find( PILE_COORDONNEES ) == donePiles.end()) {
1401 INFOS_MED( " Missing pile " << PILE_COORDONNEES );
1410 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER():
1411 GENDRIVER(GIBI_DRIVER),
1412 _mesh(( GMESH *) NULL),
1415 MESSAGE_MED("GIBI_MESH_DRIVER()");
1418 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const string & fileName,
1420 MED_EN::med_mode_acces accessMode):
1421 GENDRIVER(fileName, accessMode, GIBI_DRIVER),
1424 MESSAGE_MED( "GIBI_MESH_DRIVER(" << fileName <<","<<accessMode );
1425 // mesh name construction from fileName
1426 const string ext=".sauv"; // expected extension
1427 int pos=fileName.find(ext,0);
1428 int pos1=fileName.rfind('/');
1429 if ( pos < 0 || pos >= (int)fileName.size() ) pos = fileName.size();
1431 if ( pos1 < 0 || pos1 >= (int)fileName.size() ) pos1 = fileName.rfind('\\');
1433 if ( pos1 < 0 || pos1 >= (int)fileName.size() ) pos1 = -1;
1434 _meshName = string(fileName,pos1+1,pos-pos1-1); //get rid of directory & extension
1435 SCRUTE_MED(_meshName);
1438 GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver):
1440 _mesh(driver._mesh),
1441 _meshName(driver._meshName)
1443 MESSAGE_MED("GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver)");
1446 GIBI_MESH_DRIVER::~GIBI_MESH_DRIVER()
1448 MESSAGE_MED("~GIBI_MESH_DRIVER()");
1450 void GIBI_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }
1451 string GIBI_MESH_DRIVER::getMeshName() const { return _meshName; }
1454 //---------------------------------- RDONLY PART ------------------------------------------
1456 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER():
1458 _File (-1),_start(0L),_ptr (0L),_eptr (0L)
1461 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName,MESH * ptrMesh):
1462 GIBI_MESH_DRIVER(fileName,ptrMesh,RDONLY),
1463 _File (-1),_start(0L),_ptr (0L),_eptr (0L)
1465 MESSAGE_MED("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER"
1466 "(const string & fileName, MESH * ptrMesh) has been created, "
1467 << fileName << ", " << RDONLY);
1469 GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver):
1470 GIBI_MESH_DRIVER(driver),
1471 _File (-1),_start(0L),_ptr (0L),_eptr (0L)
1475 GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER()
1477 const char* LOC = "~GIBI_MESH_RDONLY_DRIVER()";
1484 xdr_destroy((XDR*)_xdrs);
1493 MESSAGE_MED("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed");
1495 GENDRIVER * GIBI_MESH_RDONLY_DRIVER::copy(void) const
1497 return new GIBI_MESH_RDONLY_DRIVER(*this);
1500 //=======================================================================
1503 //=======================================================================
1505 const int GIBI_MaxOutputLen = 150;
1506 const int GIBI_BufferSize = 16184; // for non-stream input
1508 void GIBI_MESH_RDONLY_DRIVER::open()
1509 // throw (MEDEXCEPTION)
1511 if( _status == MED_OPENED )
1514 const char * LOC = "GIBI_MESH_RDONLY_DRIVER::open()";
1517 // MED_EN::med_mode_acces aMode = getAccessMode();
1518 // if ( aMode != MED_EN::MED_LECT && aMode != MED_EN::MED_REMP )
1519 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Bad file mode access ! " << aMode));
1522 _File = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY);
1524 _File = ::open (_fileName.c_str(), O_RDONLY);
1528 _start = new char [GIBI_BufferSize];
1531 _status = MED_OPENED;
1536 _status = MED_CLOSED;
1537 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName
1538 << " fd: " << _File));
1545 _xdrs_file = fdopen(_File, "r");
1546 _xdrs = (XDR *)malloc(sizeof(XDR));
1548 xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE);
1550 const int maxsize = 10;
1551 char icha[maxsize+1];
1553 bool_t xdr_test = xdr_string((XDR*)_xdrs, &icha2, maxsize);
1556 icha[maxsize] = '\0';
1557 if(!strcmp(icha, "CASTEM XDR"))
1565 xdr_destroy((XDR*)_xdrs);
1569 _File = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY);
1571 ::close (_File); // ? needed ?
1572 _File = ::open (_fileName.c_str(), O_RDONLY);
1580 //=======================================================================
1583 //=======================================================================
1585 void GIBI_MESH_RDONLY_DRIVER::close()
1587 const char* LOC = "GIBI_MESH_DRIVER::close() ";
1589 if ( _status == MED_OPENED) {
1594 xdr_destroy((XDR*)_xdrs);
1604 _status = MED_CLOSED;
1609 //=======================================================================
1610 //function : getLine
1612 //=======================================================================
1614 bool GIBI_MESH_RDONLY_DRIVER::getLine(char* & aLine)
1617 if (_is_xdr) return true;
1619 bool aResult = true;
1620 // Check the state of the buffer;
1621 // if there is too little left, read the next portion of data
1622 int nBytesRest = _eptr - _ptr;
1623 if (nBytesRest < GIBI_MaxOutputLen)
1625 if (nBytesRest > 0) {
1626 //memcpy (_start, _ptr, nBytesRest);
1627 char* tmpBuf = new char [nBytesRest];
1628 memcpy (tmpBuf, _ptr, nBytesRest);
1629 memcpy (_start, tmpBuf, nBytesRest);
1634 const int nBytesRead = ::read (_File,
1635 &_start [nBytesRest],
1636 GIBI_BufferSize - nBytesRest);
1637 nBytesRest += nBytesRead;
1638 _eptr = &_start [nBytesRest];
1640 // Check the buffer for the end-of-line
1644 // Check for end-of-the-buffer, the ultimate criterion for termination
1647 if (nBytesRest <= 0)
1653 // seek the line-feed character
1656 if (ptr[-1] == '\r')
1664 // Output the result
1672 //=======================================================================
1673 //function : initNameReading
1675 //=======================================================================
1677 void GIBI_MESH_RDONLY_DRIVER::initNameReading(int nbValues, int width)
1682 _xdr_kind = _xdr_kind_char;
1685 unsigned int nels = nbValues*width;
1686 _xdr_cvals = (char*)malloc((nels+1)*sizeof(char));
1687 xdr_string((XDR*)_xdrs, &_xdr_cvals, nels);
1688 _xdr_cvals[nels] = '\0';
1692 init( nbValues, 72 / ( width + 1 ), width, 1 );
1695 //=======================================================================
1696 //function : initIntReading
1698 //=======================================================================
1700 void GIBI_MESH_RDONLY_DRIVER::initIntReading(int nbValues)
1705 _xdr_kind = _xdr_kind_int;
1708 unsigned int nels = nbValues;
1709 unsigned int actual_nels;
1710 _xdr_ivals = (int*)malloc(nels*sizeof(int));
1711 xdr_array((XDR*)_xdrs, (char **)&_xdr_ivals, &actual_nels, nels, sizeof(int), (xdrproc_t)xdr_int);
1715 init( nbValues, 10, 8 );
1718 //=======================================================================
1719 //function : initDoubleReading
1721 //=======================================================================
1723 void GIBI_MESH_RDONLY_DRIVER::initDoubleReading(int nbValues)
1728 _xdr_kind = _xdr_kind_double;
1731 unsigned int nels = nbValues;
1732 unsigned int actual_nels;
1733 _xdr_dvals = (double*)malloc(nels*sizeof(double));
1734 xdr_array((XDR*)_xdrs, (char **)&_xdr_dvals, &actual_nels, nels, sizeof(double), (xdrproc_t)xdr_double);
1738 init( nbValues, 3, 22 );
1741 //=======================================================================
1744 //=======================================================================
1746 void GIBI_MESH_RDONLY_DRIVER::init( int nbToRead, int nbPosInLine, int width, int shift )
1751 if(_iRead < _nbToRead)
1753 cout << "_iRead, _nbToRead : " << _iRead << " " << _nbToRead << endl;
1754 cout << "Unfinished iteration before new one !" << endl;
1755 throw MEDEXCEPTION("Unfinished iteration before new one !");
1759 _nbToRead = nbToRead;
1760 _nbPosInLine = nbPosInLine;
1765 getNextLine( _curPos );
1766 _curPos = _curPos + _shift;
1771 if(_is_xdr && (_xdr_kind == _xdr_kind_char))
1772 _curPos = _xdr_cvals;
1776 //=======================================================================
1779 //=======================================================================
1781 bool GIBI_MESH_RDONLY_DRIVER::more() const
1783 bool result = false;
1784 if(_iRead < _nbToRead)
1786 if(_curPos) result = true;
1788 if(_is_xdr) result = true;
1794 //=======================================================================
1796 //purpose : line getting
1797 //=======================================================================
1799 void GIBI_MESH_RDONLY_DRIVER::next()
1801 if ( !more() ) throw MEDEXCEPTION(LOCALIZED("!more()"));
1804 if ( _iRead < _nbToRead ) {
1805 if ( _iPos >= _nbPosInLine ) {
1806 getNextLine( _curPos );
1807 _curPos = _curPos + _shift;
1811 _curPos = _curPos + _width + _shift;
1813 if(_is_xdr && (_xdr_kind == _xdr_kind_char))
1815 _curPos = _xdr_cvals + _iRead*_width;
1824 if(_xdr_kind == _xdr_kind_char) free(_xdr_cvals);
1825 if(_xdr_kind == _xdr_kind_int) free(_xdr_ivals);
1826 if(_xdr_kind == _xdr_kind_double) free(_xdr_dvals);
1827 _xdr_kind = _xdr_kind_null;
1834 //=======================================================================
1835 //function : getName
1836 //purpose : names reading
1837 //=======================================================================
1839 string GIBI_MESH_RDONLY_DRIVER::getName() const
1842 while (( _curPos[len-1] == ' ' || _curPos[len-1] == 0) && len > 0 )
1844 return string( _curPos, len );
1847 //=======================================================================
1849 //purpose : int reading
1850 //=======================================================================
1852 int GIBI_MESH_RDONLY_DRIVER::getInt() const
1857 if(_iRead < _nbToRead)
1859 return _xdr_ivals[_iRead];
1864 xdr_int((XDR*)_xdrs, &result);
1869 // fix for two glued ints (issue 0021009):
1870 // Line nb | File contents
1871 // ------------------------------------------------------------------------------------
1872 // 53619905 | 1 2 6 8
1873 // 53619906 | SCALAIRE
1874 // 53619907 | -63312600499 1 0 0 0 -2 0 2
1875 // where -63312600499 is actualy -633 and 12600499
1876 char hold=_curPos[_width];
1877 _curPos[_width] = '\0';
1878 int result = atoi(str());
1879 _curPos[_width] = hold;
1881 //return atoi(str());
1884 //=======================================================================
1885 //function : getFloat
1886 //purpose : float reading
1887 //=======================================================================
1889 float GIBI_MESH_RDONLY_DRIVER::getFloat() const
1895 xdr_float((XDR*)_xdrs, &result);
1902 //=======================================================================
1903 //function : getDouble
1904 //purpose : double reading
1905 //=======================================================================
1907 double GIBI_MESH_RDONLY_DRIVER::getDouble() const
1912 if(_iRead < _nbToRead)
1914 return _xdr_dvals[_iRead];
1919 xdr_double((XDR*)_xdrs, &result);
1925 //return atof(str());
1927 std::string aStr (str());
1929 // Correction 1: add missing 'E' specifier
1930 int aPosStart = aStr.find_first_not_of(" \t");
1931 if (aPosStart < (int)aStr.length()) {
1932 int aPosSign = aStr.find_first_of("+-", aPosStart + 1); // pass the leading symbol, as it can be a sign
1933 if (aPosSign < (int)aStr.length()) {
1934 if (aStr[aPosSign - 1] != 'e' && aStr[aPosSign - 1] != 'E')
1935 aStr.insert(aPosSign, "E", 1);
1939 // Correction 2: set "C" numeric locale to read numbers
1940 // with dot decimal point separator, as it is in SAUVE files
1941 //char* aCurLocale = setlocale(LC_NUMERIC, 0);
1942 std::string aCurLocale = setlocale(LC_NUMERIC, 0);
1943 setlocale(LC_NUMERIC, "C");
1944 double ret = atof(aStr.data());
1945 //setlocale(LC_NUMERIC, aCurLocale);
1946 setlocale(LC_NUMERIC, aCurLocale.data());
1951 //=======================================================================
1954 //=======================================================================
1956 void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION)
1958 const char * LOC = "_GIBI_RDONLY_DRIVER::read() : ";
1961 if (_status!=MED_OPENED)
1962 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : "
1963 << " (the file is not opened)." ));
1964 if ( ! _mesh->isEmpty() )
1965 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh object not empty : can't fill it!"));
1967 _intermediateMED medi;
1969 if ( readFile( &medi, false )) {
1970 // impression résultats
1971 MESSAGE_MED(LOC << "GIBI_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : ");
1972 MESSAGE_MED(LOC << medi );
1975 updateSupports(); // create families from groups etc.
1978 catch (MEDEXCEPTION &ex)
1980 INFOS_MED( ex.what() );
1985 //=======================================================================
1986 //function : getReverseVector
1988 //=======================================================================
1990 static void getReverseVector (const medGeometryElement type,
1991 vector<pair<int,int> > & swapVec )
1993 const char* LOC = "void getReverseVector()";
2000 swapVec[0] = make_pair( 1, 2 );
2004 swapVec[0] = make_pair( 1, 3 );
2008 swapVec[0] = make_pair( 1, 2 );
2009 swapVec[1] = make_pair( 4, 5 );
2013 swapVec[0] = make_pair( 1, 3 );
2014 swapVec[1] = make_pair( 5, 7 );
2018 swapVec[0] = make_pair( 1, 2 );
2019 swapVec[1] = make_pair( 4, 6 );
2020 swapVec[2] = make_pair( 8, 9 );
2024 swapVec[0] = make_pair( 1, 3 );
2025 swapVec[1] = make_pair( 5, 8 );
2026 swapVec[2] = make_pair( 6, 7 );
2027 swapVec[3] = make_pair( 10, 12 );
2031 swapVec[0] = make_pair( 1, 2 );
2032 swapVec[1] = make_pair( 4, 5 );
2033 swapVec[2] = make_pair( 6, 8 );
2034 swapVec[3] = make_pair( 9, 11 );
2038 swapVec[0] = make_pair( 1, 3 );
2039 swapVec[1] = make_pair( 5, 7 );
2040 swapVec[2] = make_pair( 8, 11 );
2041 swapVec[3] = make_pair( 9, 10 );
2042 swapVec[4] = make_pair( 12, 15 );
2043 swapVec[5] = make_pair( 13, 14 );
2044 swapVec[6] = make_pair( 17, 19 );
2046 // case MED_SEG3: no need to reverse edges
2047 // swapVec.resize(1);
2048 // swapVec[0] = make_pair( 1, 2 );
2052 swapVec[0] = make_pair( 1, 2 );
2053 swapVec[1] = make_pair( 3, 5 );
2057 swapVec[0] = make_pair( 1, 3 );
2058 swapVec[1] = make_pair( 4, 7 );
2059 swapVec[2] = make_pair( 5, 6 );
2066 //=======================================================================
2067 //function : reverse
2068 //purpose : inverse element orientation using vector of indices to swap
2069 //=======================================================================
2071 static void reverse(const _maille & aMaille, const vector<pair<int,int> > & swapVec )
2073 _maille* ma = (_maille*) & aMaille;
2074 for ( unsigned i = 0; i < swapVec.size(); ++i ) {
2075 std::swap( ma->sommets[ swapVec[i].first ],
2076 ma->sommets[ swapVec[i].second ]);
2078 if ( swapVec.empty() )
2081 ma->reverse = false;
2084 //=======================================================================
2085 //function : getGibi2MedConnectivity
2086 //purpose : return array of indices to transform GIBI connectivity to MED one
2087 //=======================================================================
2089 static const int * getGibi2MedConnectivity( const medGeometryElement type )
2091 static vector<const int*> conn;
2092 static int hexa20 [] = {0,6,4,2, 12,18,16,14, 7,5,3,1, 19,17,15,13, 8,11,10,9};
2093 static int penta15[] = {0,2,4, 9,11,13, 1,3,5, 10,12,14, 6,7,3};
2094 static int pyra13 [] = {0,2,4,6, 12, 1,3,5,7, 8,9,10,11};
2095 static int tetra10[] = {0,2,4, 9, 1,3,5, 6,7,8};
2096 static int quad8 [] = {0,2,4,6, 1,3,5,7};
2097 static int tria6 [] = {0,2,4, 1,3,5};
2098 static int seg3 [] = {0,2,1};
2099 if ( conn.empty() ) {
2100 conn.resize( MED_HEXA20 + 1, 0 );
2101 conn[ MED_HEXA20 ] = hexa20;
2102 conn[ MED_PENTA15] = penta15;
2103 conn[ MED_PYRA13 ] = pyra13;
2104 conn[ MED_TETRA10] = tetra10;
2105 conn[ MED_SEG3 ] = seg3;
2106 conn[ MED_TRIA6 ] = tria6;
2107 conn[ MED_QUAD8 ] = quad8;
2109 return conn[ type ];
2112 //=======================================================================
2113 //function : fixConnectivity
2114 //purpose : GIBI connectivity -> MED one
2115 //=======================================================================
2117 static inline void fixConnectivity(const _maille & aMaille )
2119 if ( const int * conn = getGibi2MedConnectivity( aMaille.geometricType )) {
2120 _maille* ma = (_maille*) & aMaille;
2121 //cout << "###### BEFORE fixConnectivity() " << *ma << endl;
2122 vector< _maille::TNoeud > newSommets( ma->sommets.size() );
2123 for ( unsigned i = 0; i < newSommets.size(); ++i )
2124 newSommets[ i ] = ma->sommets[ conn[ i ]];
2125 ma->sommets = newSommets;
2126 //cout << "###### AFTER fixConnectivity() " << *ma << endl;
2130 //=======================================================================
2131 //function : orientElements
2133 //=======================================================================
2135 static void orientElements( _intermediateMED& medi )
2137 MESSAGE_MED("orientElements()");
2139 set<_maille>::const_iterator elemIt, elemEnd;
2142 vector< pair<int,int> > swapVec;
2144 bool isQuadratic = false;
2146 if ( medi.points.begin()->second.coord.size() == 2 ) { // space dimension
2148 // fix connectivity of quadratic edges
2149 _maillageByDimIterator edgesIt( medi, /*dim=*/1);
2150 while ( const set<_maille > * edges = edgesIt.nextType() )
2152 isQuadratic = getGibi2MedConnectivity( edgesIt.type() );
2155 elemIt = edges->begin(), elemEnd = edges->end();
2156 for ( ; elemIt != elemEnd; ++elemIt )
2157 fixConnectivity( *elemIt );
2160 // --------------------------
2161 // Orient 2D faces clockwise
2162 // --------------------------
2164 _maillageByDimIterator faceMailIt( medi, /*dim=*/2 );
2165 while ( const set<_maille > * faces = faceMailIt.nextType() )
2167 isQuadratic = getGibi2MedConnectivity( faceMailIt.type() );
2168 elemIt = faces->begin(), elemEnd = faces->end();
2169 for ( ; elemIt != elemEnd; elemIt++ )
2171 // fix connectivity of quadratic faces
2173 fixConnectivity( *elemIt );
2175 // look for index of the most left node
2176 int iLeft = 0, iNode, nbNodes = elemIt->sommets.size();
2177 if ( nbNodes > 4 ) // quadratic face
2179 double minX = elemIt->sommets[0]->second.coord[0];
2180 for ( iNode = 1; iNode < nbNodes; ++iNode )
2182 if ( minX > elemIt->sommets[ iNode ]->second.coord[ 0 ]) {
2183 minX = elemIt->sommets[ iNode ]->second.coord[ 0 ];
2187 // indeces of the nodes neighboring the most left one
2188 int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1;
2189 int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1;
2190 // find components of prev-left and left-next vectors
2191 double xP = elemIt->sommets[ iPrev ]->second.coord[ 0 ];
2192 double yP = elemIt->sommets[ iPrev ]->second.coord[ 1 ];
2193 double xN = elemIt->sommets[ iNext ]->second.coord[ 0 ];
2194 double yN = elemIt->sommets[ iNext ]->second.coord[ 1 ];
2195 double xL = elemIt->sommets[ iLeft ]->second.coord[ 0 ];
2196 double yL = elemIt->sommets[ iLeft ]->second.coord[ 1 ];
2197 double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector
2198 double xLN = xN - xL, yLN = yN - yL; // components of left-next vector
2199 // normalise y of the vectors
2200 double modPL = sqrt ( xPL * xPL + yPL * yPL );
2201 double modLN = sqrt ( xLN * xLN + yLN * yLN );
2202 if ( modLN > DBL_MIN && modPL > DBL_MIN )
2206 // summury direction of neighboring links must be positive
2207 bool clockwise = ( yPL + yLN > 0 );
2209 if ( elemIt->geometricType != type ) {
2210 type = elemIt->geometricType;
2211 getReverseVector( type, swapVec );
2213 reverse( *elemIt, swapVec );
2221 // --------------------------------------
2222 // orient equally all connected 3D faces
2223 // --------------------------------------
2224 // connectivity of quadratic faces will be fixed by fixConnectivity()
2225 // in the next loop on elements
2227 // fill map of links and their faces
2228 set<const _maille*> faces;
2229 map<const _maille*, _groupe*> fgm;
2230 map<_link, list<const _maille*> > linkFacesMap;
2231 map<_link, list<const _maille*> >::iterator lfIt, lfIt2;
2233 medi.treatGroupes(); // erase groupes that wont be converted
2234 for (unsigned int i=0; i!=medi.groupes.size(); ++i)
2236 _groupe& grp = medi.groupes[i];
2237 _groupe::TMailleIter maIt=grp.mailles.begin();
2238 if ( maIt==grp.mailles.end() || (*maIt)->dimensionWithPoly() != 2 )
2240 for(; maIt!=grp.mailles.end(); ++maIt) {
2241 if ( faces.insert( &(**maIt )).second ) {
2242 for ( int j = 0; j < (int)(*maIt)->sommets.size(); ++j )
2243 linkFacesMap[ (*maIt)->link( j ) ].push_back( &(**maIt) );
2244 fgm.insert( make_pair( &(**maIt), &grp ));
2248 // dump linkFacesMap
2249 // for ( lfIt = linkFacesMap.begin(); lfIt!=linkFacesMap.end(); lfIt++) {
2250 // cout<< "LINK: " << lfIt->first.first << "-" << lfIt->first.second << endl;
2251 // list<const _maille*> & fList = lfIt->second;
2252 // list<const _maille*>::iterator fIt = fList.begin();
2253 // for ( ; fIt != fList.end(); fIt++ )
2254 // cout << "\t" << **fIt << fgm[*fIt]->nom << endl;
2257 // Each oriented link must appear in one face only, else a face is reversed.
2259 queue<const _maille*> faceQueue; // the queue contains well oriented faces
2260 // whose neighbors orientation is to be checked
2262 bool manifold = true;
2263 while ( !linkFacesMap.empty() )
2265 if ( faceQueue.empty() ) {
2266 ASSERT_MED( !linkFacesMap.begin()->second.empty() );
2267 faceQueue.push( linkFacesMap.begin()->second.front() );
2269 while ( !faceQueue.empty() )
2271 const _maille* face = faceQueue.front();
2274 // loop on links of <face>
2275 for ( int i = 0; i < (int)face->sommets.size(); ++i ) {
2276 _link link = face->link( i );
2277 // find the neighbor faces
2278 lfIt = linkFacesMap.find( link );
2279 int nbFaceByLink = 0;
2280 list< const _maille* > ml;
2281 if ( lfIt != linkFacesMap.end() )
2283 list<const _maille*> & fList = lfIt->second;
2284 list<const _maille*>::iterator fIt = fList.begin();
2285 ASSERT_MED( fIt != fList.end() );
2286 for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) {
2287 ml.push_back( *fIt );
2288 if ( *fIt != face ) // wrongly oriented neighbor face
2290 const _maille* badFace = *fIt;
2291 // reverse and remove badFace from linkFacesMap
2292 for ( int j = 0; j < (int)badFace->sommets.size(); ++j ) {
2293 _link badlink = badFace->link( j );
2294 if ( badlink == link ) continue;
2295 lfIt2 = linkFacesMap.find( badlink );
2296 if ( lfIt2 != linkFacesMap.end() ) {
2297 list<const _maille*> & ff = lfIt2->second;
2298 ff.erase( find( ff.begin(), ff.end(), badFace ));
2300 linkFacesMap.erase( lfIt2 );
2303 badFace->reverse = true; // reverse
2304 //INFOS_MED( "REVERSE " << *badFace );
2305 faceQueue.push( badFace );
2308 linkFacesMap.erase( lfIt );
2310 // add good neighbors to the queue
2311 _link revLink( link.second, link.first );
2312 lfIt = linkFacesMap.find( revLink );
2313 if ( lfIt != linkFacesMap.end() )
2315 list<const _maille*> & fList = lfIt->second;
2316 list<const _maille*>::iterator fIt = fList.begin();
2317 for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) {
2318 ml.push_back( *fIt );
2320 faceQueue.push( *fIt );
2322 linkFacesMap.erase( lfIt );
2324 if ( nbFaceByLink > 2 ) {
2326 list<const _maille*>::iterator i = ml.begin();
2327 INFOS_MED(nbFaceByLink << " faces by 1 link:");
2328 for( ; i!= ml.end(); i++ ) {
2329 INFOS_MED("in object " << fgm[ *i ]->nom);
2335 } // loop on links of the being checked face
2336 } // loop on the face queue
2337 } // while ( !linkFacesMap.empty() )
2340 INFOS_MED(" -> Non manifold mesh, faces orientation may be incorrect");
2343 // ---------------------------------------------------
2344 // fix connectivity of quadratic elements
2345 // ---------------------------------------------------
2347 for ( int dim = 1; dim <= 3; ++dim )
2349 _maillageByDimIterator mailIt( medi, dim );
2350 while ( const set<_maille > * elems = mailIt.nextType() )
2352 isQuadratic = getGibi2MedConnectivity( mailIt.type() );
2353 elemIt = elems->begin(), elemEnd = elems->end();
2354 for ( ; elemIt != elemEnd; elemIt++ )
2356 // GIBI connectivity -> MED one
2358 fixConnectivity( *elemIt );
2360 // reverse quadratic faces
2361 if ( elemIt->reverse ) {
2362 if ( elemIt->geometricType != type ) {
2363 type = elemIt->geometricType;
2364 getReverseVector( type, swapVec );
2366 reverse ( *elemIt, swapVec );
2372 // ---------------------------------------------------
2373 // Orient volumes according to MED conventions:
2374 // normal of a bottom (first) face should be downward
2375 // ---------------------------------------------------
2377 _maillageByDimIterator mailIt( medi, 3 );
2378 while ( const set<_maille > * elems = mailIt.nextType() )
2380 elemIt = elems->begin(), elemEnd = elems->end();
2381 int nbBottomNodes = 0;
2382 switch ( elemIt->geometricType ) {
2387 nbBottomNodes = 3; break;
2392 nbBottomNodes = 4; break;
2395 getReverseVector( elemIt->geometricType, swapVec );
2397 for ( ; elemIt != elemEnd; elemIt++ )
2399 // find a normal to the bottom face
2400 const _noeud* n[4] = {
2401 &elemIt->sommets[0]->second, // 3 bottom nodes
2402 &elemIt->sommets[1]->second,
2403 &elemIt->sommets[2]->second,
2404 &elemIt->sommets[nbBottomNodes]->second };// a top node
2405 double vec01 [3] = { // vector n[0]-n[1]
2406 n[1]->coord[0] - n[0]->coord[0],
2407 n[1]->coord[1] - n[0]->coord[1],
2408 n[1]->coord[2] - n[0]->coord[2], };
2409 double vec02 [3] = { // vector n[0]-n[2]
2410 n[2]->coord[0] - n[0]->coord[0],
2411 n[2]->coord[1] - n[0]->coord[1],
2412 n[2]->coord[2] - n[0]->coord[2] };
2413 double normal [3] = { // vec01 ^ vec02
2414 vec01[1] * vec02[2] - vec01[2] * vec02[1],
2415 vec01[2] * vec02[0] - vec01[0] * vec02[2],
2416 vec01[0] * vec02[1] - vec01[1] * vec02[0] };
2417 // check if the 102 angle is convex
2418 if ( nbBottomNodes > 3 ) {
2419 const _noeud* n3 = &elemIt->sommets[nbBottomNodes-1]->second;// last bottom node
2420 double vec03 [3] = { // vector n[0]-n3
2421 n3->coord[0] - n[0]->coord[0],
2422 n3->coord[1] - n[0]->coord[1],
2423 n3->coord[2] - n[0]->coord[2], };
2424 if ( fabs( normal[0]+normal[1]+normal[2] ) <= DBL_MIN ) { // vec01 || vec02
2425 normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03
2426 normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2];
2427 normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0];
2430 double vec [3] = { // normal ^ vec01
2431 normal[1] * vec01[2] - normal[2] * vec01[1],
2432 normal[2] * vec01[0] - normal[0] * vec01[2],
2433 normal[0] * vec01[1] - normal[1] * vec01[0] };
2434 double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03
2435 if ( dot2 < 0 ) { // concave -> reverse normal
2442 // direction from top to bottom
2444 tbDir[0] = n[0]->coord[0] - n[3]->coord[0];
2445 tbDir[1] = n[0]->coord[1] - n[3]->coord[1];
2446 tbDir[2] = n[0]->coord[2] - n[3]->coord[2];
2447 // compare 2 directions: normal and top-bottom
2448 double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2];
2449 if ( dot < 0. ) // need reverse
2451 reverse( *elemIt, swapVec );
2453 } // loop on volumes of one geometry
2454 } // loop on 3D geometry types
2456 } // space dimension == 3
2459 //=======================================================================
2460 //function : fillMesh
2461 //purpose : load data from medi to mesh
2462 //=======================================================================
2464 void GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi)
2466 const char* LOC = "GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi) : ";
2469 MESH* mesh = (MESH*)_mesh;
2470 mesh->_name = _meshName;
2474 if (!_maillageByDimIterator(*_ptrMedi).nextType() ||
2475 _ptrMedi->groupes.empty() ||
2476 _ptrMedi->points.empty()) {
2477 INFOS_MED(" Error while reading file: the data read are not completed " );
2480 // fix element orientation
2481 orientElements( *_ptrMedi );
2483 mesh->_spaceDimension = _ptrMedi->points.begin()->second.coord.size();
2484 mesh->_numberOfNodes = _ptrMedi->points.size();
2485 mesh->_coordinate = _ptrMedi->getCoordinate();
2487 //Construction des groupes
2488 _ptrMedi->getGroups(mesh->_groupCell,
2491 mesh->_groupNode, mesh);
2493 mesh->_connectivity = _ptrMedi->getConnectivity();
2498 //================================================================================
2500 * \brief Create families from groups etc.
2502 //================================================================================
2504 void GIBI_MESH_RDONLY_DRIVER::updateSupports()
2506 _mesh->createFamilies();
2508 // add attributes to families
2509 set<string> famNames;
2510 for (medEntityMesh entity=MED_CELL; entity<MED_ALL_ENTITIES; ++entity)
2512 int i, nb = _mesh->getNumberOfFamilies(entity);
2513 for ( i = 1; i <= nb; ++i ) {
2514 FAMILY* f = const_cast<FAMILY*>( _mesh->getFamily( entity, i ));
2515 f->setNumberOfAttributes( 1 );
2516 int* attIDs = new int[1];
2518 f->setAttributesIdentifiers( attIDs );
2519 int* attVals = new int[1];
2521 f->setAttributesValues( attVals );
2522 string* attDescr = new string[1];
2523 attDescr[0] = "med_family";
2524 f->setAttributesDescriptions( attDescr );
2526 // limit a name length
2527 if ( f->getName().length() > 31 ) {
2529 name << "FAM" << f->getIdentifier();
2530 f->setName( name.str());
2532 // check if family is on the whole mesh entity
2533 if (_mesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) ==
2534 f->getNumberOfElements( MED_ALL_ELEMENTS ))
2537 // setAll() for groups
2538 nb = _mesh->getNumberOfGroups(entity);
2539 for ( i = 1; i <= nb; ++i ) {
2540 GROUP * g = const_cast<GROUP*>( _mesh->getGroup( entity, i ));
2541 if (_mesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) ==
2542 g->getNumberOfElements( MED_ALL_ELEMENTS ))
2548 void GIBI_MESH_RDONLY_DRIVER::write( void ) const
2549 throw (MEDEXCEPTION)
2551 throw MEDEXCEPTION("GIBI_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
2555 /*--------------------- WRONLY PART -------------------------------*/
2557 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER():GIBI_MESH_DRIVER()
2560 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName,
2562 GIBI_MESH_DRIVER(fileName,ptrMesh,WRONLY)
2564 MESSAGE_MED("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
2566 GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & driver):
2567 GIBI_MESH_DRIVER(driver)
2570 GIBI_MESH_WRONLY_DRIVER::~GIBI_MESH_WRONLY_DRIVER()
2572 //MESSAGE_MED("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
2574 GENDRIVER * GIBI_MESH_WRONLY_DRIVER::copy(void) const
2576 return new GIBI_MESH_WRONLY_DRIVER(*this);
2578 void GIBI_MESH_WRONLY_DRIVER::read (void)
2579 throw (MEDEXCEPTION)
2581 throw MEDEXCEPTION("GIBI_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
2584 //=======================================================================
2587 //=======================================================================
2589 void GIBI_MESH_WRONLY_DRIVER::open()
2590 // throw (MEDEXCEPTION)
2592 if( _status == MED_OPENED )
2595 const char * LOC = "GIBI_MESH_DRIVER::open()";
2598 MED_EN::med_mode_acces aMode = getAccessMode();
2601 case MED_EN::WRONLY: // should never append !!
2602 _gibi.open(_fileName.c_str(), ios::out);
2605 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Bad file mode access ! " << aMode));
2607 //change for windows compilation
2612 !_gibi.rdbuf()->is_open()
2616 _status = MED_CLOSED;
2617 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName));
2621 _status = MED_OPENED;
2626 //=======================================================================
2629 //=======================================================================
2631 void GIBI_MESH_WRONLY_DRIVER::close()
2632 // throw (MEDEXCEPTION)
2634 const char* LOC = "GIBI_MESH_DRIVER::close() ";
2636 if ( _status == MED_OPENED)
2639 _status = MED_CLOSED;
2644 //=======================================================================
2647 //=======================================================================
2649 void GIBI_MESH_WRONLY_DRIVER::write(void) const
2650 throw (MEDEXCEPTION)
2652 const char* LOC = "void GIBI_MESH_WRONLY_DRIVER::write(void) const : ";
2655 // we are going to modify the _gibi field
2656 GIBI_MESH_WRONLY_DRIVER * me = const_cast<GIBI_MESH_WRONLY_DRIVER *>(this);
2658 // IMP 0020434: mapping GIBI names to MED names
2659 list<nameGIBItoMED> listGIBItoMED_mail;
2660 list<nameGIBItoMED> listGIBItoMED_cham;
2661 list<nameGIBItoMED> listGIBItoMED_comp;
2662 me->writeSupportsAndMesh(listGIBItoMED_mail);
2663 me->writeMEDNames(listGIBItoMED_mail, listGIBItoMED_cham, listGIBItoMED_comp);
2664 me->writeLastRecord();
2666 // catch (MEDEXCEPTION &ex)
2668 // INFOS_MED( ex.what() );
2674 //=======================================================================
2675 //function : getName
2676 //purpose : return cleaned up support name
2677 //=======================================================================
2679 static string cleanName( const string& theName )
2681 string name = theName;
2682 if ( !name.empty() ) {
2684 // find a name string end
2685 int i, len = name.length();
2686 for ( i = 0; i < len; ++i ) {
2690 // cut off trailing white spaces
2691 while ( i > 0 && name[i-1] == ' ' )
2694 name = name.substr( 0, i );
2698 // cut off leading white spaces
2699 string::size_type firstChar = name.find_first_not_of(" \t");
2700 if (firstChar < name.length())
2702 name = name.substr(firstChar);
2706 name = ""; // only whitespaces there - remove them
2708 // cut off trailing white spaces
2709 string::size_type lastChar = name.find_last_not_of(" \t");
2710 if (lastChar < name.length()) {
2711 name = name.substr(0, lastChar + 1);
2717 //=======================================================================
2718 //function : addSupport
2720 //=======================================================================
2722 bool GIBI_MESH_WRONLY_DRIVER::addSupport( const SUPPORT * support )
2726 map<const SUPPORT*,supportData>::iterator su = _supports.find( support );
2727 if ( su != _supports.end() )
2728 return ( su->second.getNumberOfTypes() > 0 );
2730 if ( support->getMesh() != _mesh )
2731 throw MEDEXCEPTION(LOCALIZED(STRING("cant write support of other mesh" )));
2733 MESH* mesh = (MESH*)_mesh;
2735 // get sub-supports and define a support type name
2737 list<const SUPPORT*> sList;
2738 const GROUP* group = dynamic_cast< const GROUP* >(support);
2741 if ( group->getNumberOfTypes() > 0 || group->isOnAllElements() )
2742 sList.push_back( group );
2744 int iFam, nbFam = group->getNumberOfFamilies();
2745 for ( iFam = 1; iFam <= nbFam; ++iFam )
2746 sList.push_back( group->getFamily( iFam ));
2752 sList.push_back( support );
2753 supType = dynamic_cast< const FAMILY* >(support) ? "family" : "support";
2756 supportData & data = _supports[ support ];
2757 data._cleanName = cleanName( support->getName() );
2759 // check if it is a writtable support, i.e.
2760 // nodal connectivity for a support entity exists
2761 medEntityMesh entity = support->getEntity();
2762 if ( entity != MED_NODE && !mesh->existConnectivity( MED_NODAL, entity )) {
2763 INFOS_MED("Do not save " << supType << " of entity " << entity
2764 << " named <" << data._cleanName << "> nodal connectivity not defined");
2769 list<const SUPPORT*>::iterator sIt = sList.begin();
2770 for ( ; sIt != sList.end(); sIt++ )
2772 bool onAll = (*sIt)->isOnAllElements();
2775 nbTypes = (*sIt)->getNumberOfTypes();
2777 nbTypes = _mesh->getNumberOfTypes( entity );
2780 const medGeometryElement* types = 0;
2782 types = (*sIt)->getTypes();
2783 else if ( entity != MED_NODE )
2784 types = _mesh->getTypes( entity );
2785 for ( int iType = 0; iType < nbTypes; ++iType )
2787 if ( types && types[ iType ] > MED_HEXA20 )
2789 medGeometryElement geomType = types ? types[ iType ] : MED_ALL_ELEMENTS;
2790 const int * ptrElemIDs = 0;
2791 int elemID1 = 0, nbElems = 0;
2793 nbElems = _mesh->getNumberOfElements( entity, geomType );
2794 elemID1 = (entity == MED_NODE) ? 1 : mesh->getGlobalNumberingIndex (entity)[ iType ];
2797 nbElems = (*sIt)->getNumberOfElements( geomType );
2798 ptrElemIDs = (*sIt)->getNumber( geomType );
2800 if ( geomType == 0 || ( entity == MED_NODE ))
2801 geomType = MED_POINT1;
2803 data.addTypeData( geomType, nbElems, ptrElemIDs, elemID1 );
2807 if ( data.getNumberOfTypes() == 0 ) {
2808 INFOS_MED("Do not save " << supType << " of entity " << entity
2809 << " named <" << data._cleanName << "> no geometric types");
2816 //=======================================================================
2817 //function : getSupportIndex
2819 //=======================================================================
2821 int GIBI_MESH_WRONLY_DRIVER::getSubMeshIdAndSize(const SUPPORT * support,
2822 list<pair<int,int> > & idsAndSizes) const
2824 idsAndSizes.clear();
2825 map<const SUPPORT*,supportData>::const_iterator su = _supports.find( support );
2826 if ( su == _supports.end() )
2829 supportData * data = const_cast<supportData *>( & su->second );
2831 if ( data->getNumberObjects() > data->getNumberOfTypes() )
2833 supportData::typeIterator tIt = data->_types.begin();
2834 for ( ; tIt != data->_types.end(); ++tIt )
2837 list< typeData >& td = tIt->second;
2838 list< typeData >::iterator tdIt = td.begin();
2839 for ( ; tdIt != td.end(); ++tdIt )
2840 size += tdIt->_nbElems;
2841 idsAndSizes.push_back( make_pair( id++, size ));
2843 return idsAndSizes.size();
2846 // ============================================================
2847 // the class writes endl to the file as soon as <limit> fields
2848 // have been written after the last endl
2849 // ============================================================
2856 TFieldCounter(fstream& f, int limit=0): _file(f), _limit(limit) { init(); }
2857 void init(int limit=0) // init, is done by stop() as well
2858 { if (limit) _limit = limit; _count = 0; }
2859 void operator++(int) // next
2860 { if ( ++_count == _limit ) { _file << endl; init(); }}
2861 void stop() // init() and write endl if there was no endl after the last written field
2862 { if ( _count ) _file << endl; init(); }
2865 //=======================================================================
2866 //function : writeElements
2867 //purpose : ptrElemIDs and elemID1 provide two alternative ways of giving
2868 // elements to write.
2869 // If elemSet != 0 then an element is
2870 // ( addElemInSet ? <written and added to elemSet> : <ignored if id is in elemSet>)
2871 //=======================================================================
2873 void GIBI_MESH_WRONLY_DRIVER::writeElements (medGeometryElement geomType,
2874 list< typeData >& typeDataList,
2875 const int * nodalConnect,
2876 const int * nodalConnectIndex)
2878 // ITYPEL : type de l'鬩ment 1=point, 2=segment ?eux noeuds...
2879 // NBSOUS : nombre de sous parties dans cet objet,
2880 // une sous partie par type d'鬩ments le composant.
2881 // NBREF : nombre de sous r馩rences. Une r馩rence est par exemple le contour
2882 // NBNOEL : nombre de noeuds par 鬩ment
2883 // NBEL : nombre d'鬩ments
2885 int castemType = GIBI_MESH_DRIVER::med2gibiGeom( geomType );
2886 const char* zeroI8 = " 0"; // FORMAT(I8)
2887 unsigned nbElemNodes = geomType % 100;
2889 // indices to transform MED connectivity to GIBI one
2890 vector< int > toGibiConn;
2891 toGibiConn.reserve( nbElemNodes );
2892 if ( const int * toMedConn = getGibi2MedConnectivity( geomType )) {
2893 toGibiConn.resize( nbElemNodes );
2894 for ( unsigned i = 0; i < nbElemNodes; ++i )
2895 toGibiConn[ toMedConn[ i ]] = i;
2898 while ( toGibiConn.size() < nbElemNodes )
2899 toGibiConn.push_back( toGibiConn.size() );
2902 // count total nb of elements
2904 list< typeData >::iterator td = typeDataList.begin();
2905 for ( ; td != typeDataList.end(); td++ )
2906 nbElements += td->_nbElems;
2908 _gibi << setw(8) << castemType << // ITYPE
2911 setw(8) << nbElemNodes << // NBNOEL
2912 setw(8) << nbElements << // NBEL
2915 MESSAGE_MED("writeElements(): geomType=" << geomType << " nbElements= " << nbElements)
2917 // L 'enregistrement donnant le num? de la couleur des 鬩ments.
2918 // * 8000 FORMAT(10I8)
2919 TFieldCounter fcount( _gibi, 10 );
2921 for ( ; iElem < nbElements; ++iElem, fcount++ )
2925 // Tableau des connectivit鳮 Description du premier 鬩ment puis du deuxi譥...
2926 // ATTENTION il ne s'agit pas de la num?tation vraie,
2927 // il faut la faire passer par le filtre du dernier tableau de la pile num? 32.
2928 //int nbSkipped = 0;
2930 for ( td = typeDataList.begin(); td != typeDataList.end(); td++ )
2932 for ( int i = 0; i < td->_nbElems; i++ )
2934 iElem = td->_ptrElemIDs ? td->_ptrElemIDs[ i ] : td->_elemID1 + i;
2935 if ( geomType == MED_POINT1 )
2937 _gibi << setw(8) << iElem;
2942 int nodeId = nodalConnectIndex[ iElem - 1 ] - 1;
2943 for ( unsigned iNode = 0; iNode < nbElemNodes; ++iNode, fcount++ ) {
2944 _gibi << setw(8) << nodalConnect[ nodeId + toGibiConn[ iNode ]];
2953 //=======================================================================
2954 //function : addName
2955 //purpose : make name uppercase and shorter than 9, add it to nameNbMap,
2956 // raise if not unique
2957 //=======================================================================
2959 void GIBI_MESH_WRONLY_DRIVER::addName(map<string,int>& nameMap,
2964 string name = cleanName( theName );
2965 if ( !name.empty() ) {
2966 int len = name.length();
2967 #ifdef THROW_ON_BAD_NAME
2969 throw MEDEXCEPTION(STRING("Can't write name longer than 8: ") << name );
2971 for ( int i = 0; i < len; ++i )
2972 name[i] = toupper( name[i] );
2973 if ( ! nameMap.insert( make_pair( name, index )).second )
2974 throw MEDEXCEPTION(STRING("Can't write not unique name: ") << name );
2976 bool ok = ( len <= 8 && len > 0 );
2978 for ( int i = 0; i < len; ++i )
2979 name[i] = toupper( name[i] );
2980 ok = nameMap.insert( make_pair( name, index )).second;
2983 char *str=new char[ prefix.size() + 13 ];
2986 sprintf( str, "%s_%d", prefix.c_str(), nameMap.size()+j );
2987 ok = nameMap.insert( make_pair( str, index )).second;
2990 INFOS_MED( "Save <" << name << "> as <" << str << ">");
2998 // Converts names like:
3000 // TEMPERATURE_FLUIDE
3001 // TEMPERATURE_SOLIDE
3016 void GIBI_MESH_WRONLY_DRIVER::addName (map<string,int>& nameMap,
3017 map<string,int>& namePrefixesMap,
3018 const string& theName,
3021 string name = cleanName(theName);
3024 if (!name.empty()) {
3025 int len = name.length();
3026 for (int i = 0; i < len; ++i)
3027 name[i] = toupper(name[i]);
3029 bool doResave = false; // only for tracing
3031 // I. Save a short name as it is
3033 INFOS_MED("Save <" << theName << "> as <" << name << ">");
3035 map<string,int>::iterator it = nameMap.find(name);
3036 if (it != nameMap.end()) {
3037 // There is already such name in the map.
3039 // a. Replace in the map the old pair by the current one
3040 int old_ind = nameMap[name];
3041 nameMap[name] = ind;
3042 // b. Rebuild the old pair (which was in the map,
3043 // it seems to be built automatically by step II)
3045 // continue with step II
3046 doResave = true; // only for tracing
3050 nameMap.insert(make_pair(name, ind));
3052 // Update loc_index for this name (if last free characters represents a number)
3053 // to avoid conflicts with long names, same in first 5 characters
3055 int new_loc_index = atoi(name.c_str() + 5);
3056 if (new_loc_index > 0) {
3059 strncpy(str, name.c_str(), 5);
3062 if (namePrefixesMap.find(str) != namePrefixesMap.end()) {
3063 int old_loc_index = namePrefixesMap[str];
3064 if (new_loc_index < old_loc_index) new_loc_index = old_loc_index;
3066 namePrefixesMap[str] = new_loc_index;
3073 // II. Cut long name and add a numeric suffix
3075 // first 5 or less characters of the name
3076 if (len > 5) len = 5;
3080 strncpy(str, name.c_str(), len);
3086 if (namePrefixesMap.find(str) != namePrefixesMap.end())
3087 loc_index = namePrefixesMap[str] + 1;
3088 namePrefixesMap[str] = loc_index;
3090 if (loc_index > 999)
3091 throw MEDEXCEPTION(STRING("Can't write not unique name: ") << name);
3093 if (loc_index < 100) {
3097 if (loc_index < 10) {
3101 sprintf(str + addr, "%d", loc_index);
3103 nameMap.insert(make_pair(str, ind));
3105 INFOS_MED("Resave previous <" << name << "> as <" << str << ">");
3108 INFOS_MED("Save <" << theName << "> as <" << str << ">");
3113 //=======================================================================
3114 //function : writeNames
3116 //=======================================================================
3118 void GIBI_MESH_WRONLY_DRIVER::writeNames( map<string,int>& nameNbMap )
3120 // La pile num? 1 est celle des objets de type maillage.
3121 // La ligne suivante donne le nom des objets maillages sauv鳮
3122 // * 8001 FORMAT(8(1X,A8))
3123 if ( !nameNbMap.empty() )
3125 TFieldCounter fcount( _gibi, 8 );
3127 map<string,int>::iterator nameNbIt = nameNbMap.begin();
3128 for ( ; nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) {
3129 _gibi << " " << setw(8) << nameNbIt->first;
3133 // La ligne suivante donne les num?s d'ordre, dans la pile,
3134 // des objets nomm?cit?pr飩demment.
3135 // * 8000 FORMAT(10I8)
3136 nameNbIt = nameNbMap.begin();
3137 for ( fcount.init(10); nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ )
3138 _gibi << setw(8) << nameNbIt->second;
3143 //=======================================================================
3144 //function : writeSupportsAndMesh
3146 //=======================================================================
3148 void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh(list<nameGIBItoMED>& listGIBItoMED_mail)
3150 const char * LOC = "void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() ";
3153 if (_status!=MED_OPENED)
3154 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "file " << _fileName<< " is not opened." ));
3156 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "can't write a NULL mesh" ));
3158 const MESH* mesh = _mesh->convertInMESH();
3159 AutoDeref meshDeref( mesh );
3161 if (!mesh->getConnectivityptr())
3162 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "can't write a mesh with NULL connectivity" ));
3164 // fill _supports with families and groups
3165 medEntityMesh entity;
3166 for (entity=MED_CELL; entity<MED_ALL_ENTITIES; ++entity)
3168 int i, nb = _mesh->getNumberOfGroups(entity);
3169 for ( i = 1; i <= nb; ++i )
3170 addSupport( _mesh->getGroup( entity, i ));
3171 // nb = _mesh->getNumberOfFamilies(entity);
3172 // for ( i = 1; i <= nb; ++i )
3173 // addSupport( _mesh->getFamily( entity, i ));
3176 // --------------------------------------------------------------------
3177 // Count total nb of objects: an object per an element type in support
3178 // plus an object per an element type not used in _supports.
3179 // Collect object names
3180 // --------------------------------------------------------------------
3182 vector<int> nbSuppElemsByType(MED_HEXA20+1,0);
3183 map<string,int> nameNbMap;
3184 map<string,int> namePrefixMap;
3185 map<const SUPPORT*,supportData>::iterator supIt = _supports.begin();
3186 int i, nb_objects = 0;
3187 for ( ; supIt != _supports.end(); supIt++ )
3189 supportData & data = supIt->second;
3190 int nbSupObj = data.getNumberObjects();
3191 if ( nbSupObj == 0 )
3193 data._id = nb_objects + 1;
3194 nb_objects += nbSupObj;
3196 //addName( nameNbMap, data._cleanName, data._id, "C" );
3197 addName(nameNbMap, namePrefixMap, data._cleanName, data._id);
3199 // IMP 0020434: mapping GIBI names to MED names
3200 nameGIBItoMED aMEDName;
3201 aMEDName.gibi_pile = PILE_SOUS_MAILLAGE;
3202 aMEDName.gibi_id = data._id;
3203 aMEDName.med_name = data._cleanName;
3204 listGIBItoMED_mail.push_back(aMEDName);
3206 MESSAGE_MED( "obj " << data._id << " " << data._cleanName);
3208 // count elements: take into account supports on all elements and families only
3209 const SUPPORT* support = supIt->first;
3210 if ( support->isOnAllElements() || dynamic_cast< const FAMILY* >( support ))
3212 supportData::typeIterator tIt = data._types.begin();
3213 for ( ; tIt != data._types.end(); ++tIt )
3214 if ( support->isOnAllElements() )
3216 nbSuppElemsByType[ tIt->first ] = INT_MAX / 100;
3220 list< typeData >& td = tIt->second;
3221 list< typeData >::iterator tdIt = td.begin();
3222 for ( ; tdIt != td.end(); ++tdIt )
3223 nbSuppElemsByType[ tIt->first] += tdIt->_nbElems;
3228 // count types of mesh elements that are not all in _supports
3230 entity = mesh->getConnectivityptr()->getEntity();
3231 for ( ; entity < MED_NODE; entity++ )
3233 nbTypes = _mesh->getNumberOfTypes( entity );
3234 if ( nbTypes == 0 || !mesh->existConnectivity( MED_NODAL, entity ))
3236 const medGeometryElement* types = _mesh->getTypes( entity );
3237 for ( iType = 0; iType < nbTypes; ++iType )
3239 int nbElemInSups = nbSuppElemsByType[ types[ iType ]];
3240 int nbElemInMesh = _mesh->getNumberOfElements(entity, types[ iType ]);
3241 if ( nbElemInSups < nbElemInMesh ) {
3243 nbSuppElemsByType[ types[ iType ]] = -1; // to keep written elements of _supports
3252 // Premier paquet dont le nombre de lignes ne varie pas.
3253 // On y trouve des indications g鮩rales.
3254 const int dim = _mesh->getSpaceDimension();
3255 _gibi << " ENREGISTREMENT DE TYPE 4" << endl;
3256 _gibi << " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION " << dim <<endl;
3257 _gibi << " DENSITE .00000E+00" << endl;
3258 _gibi << " ENREGISTREMENT DE TYPE 7" << endl;
3259 _gibi << " NOMBRE INFO CASTEM2000 8" <<endl;
3260 _gibi << " IFOUR -1 NIFOUR 0 IFOMOD -1 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1" << endl;
3261 _gibi << " NSDPGE 0" << endl;
3263 // Deuxi譥 paquet qui d馩nit toutes les piles
3264 // (une pile par type d'objet et certaines piles en plus).
3265 // Un enregistrement de type 2 pr鶩ent de l'飲iture d'une nouvelle pile,
3266 // celui de type 5 pr鶩ent de la fin.
3267 // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4)
3268 _gibi << " ENREGISTREMENT DE TYPE 2" << endl;
3269 // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8)
3270 _gibi << " PILE NUMERO 1NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() <<
3271 "NBRE OBJETS" << setw(8) << nb_objects <<endl;
3273 writeNames( nameNbMap );
3275 // Passage ?a description des objets les uns apr賠les autres.
3276 // Le premier enregistrement de chaque objet est compos頤e 5 nombres repr鳥ntant :
3277 // ITYPEL : type de l'鬩ment 1=point, 2=segment ?eux noeuds...
3278 // NBSOUS : nombre de sous parties dans cet objet,
3279 // une sous partie par type d'鬩ments le composant.
3280 // NBREF : nombre de sous r馩rences. Une r馩rence est par exemple le contour
3281 // NBNOEL : nombre de noeuds par 鬩ment
3282 // NBEL : nombre d'鬩ments
3283 // Si ITYPEL=0 alors NBSOUS diff鲥nt de z?. Dans ce cas on lira la liste des positions,
3284 // dans la pile des objets, des sous parties le composant.
3285 // Si NBSOUS=0, NBNOEL et NBEL sont diff鲥nts de z?, on trouve, au besoin,
3286 // la liste des r馩rences , les num?s des couleurs puis les connectivit鳮
3288 TFieldCounter fcount( _gibi, 10 );
3289 const char* zeroI8 = " 0"; // FORMAT(I8)
3290 for ( supIt = _supports.begin(); supIt != _supports.end(); supIt++ )
3292 supportData & data = supIt->second;
3293 int nbSupObj = data.getNumberObjects();
3294 if ( nbSupObj == 0 )
3296 MESSAGE_MED("support " << data._id << "<" << data._cleanName << ">");
3298 // write a compound object
3299 int nbTypes = data.getNumberOfTypes();
3300 if ( nbSupObj > nbTypes )
3302 _gibi << zeroI8 << setw(8) << nbTypes << zeroI8 << zeroI8 << zeroI8 << endl;
3303 for ( int i_sub = 1; i_sub <= nbTypes; ++i_sub, fcount++ )
3304 _gibi << setw(8) << ( data._id + i_sub );
3309 entity = supIt->first->getEntity();
3310 const int * nodalConnect = 0, * nodalConnectIndex = 0;
3311 if ( entity != MED_NODE ) {
3312 nodalConnect = mesh->getConnectivity (MED_NODAL,entity,MED_ALL_ELEMENTS);
3313 nodalConnectIndex = mesh->getConnectivityIndex (MED_NODAL,entity);
3315 supportData::typeIterator tIt = data._types.begin();
3316 for ( ; tIt != data._types.end(); ++tIt )
3318 writeElements (tIt->first,
3323 } // loop on _supports
3325 // Write elements that are not in _supports
3328 entity = mesh->getConnectivityptr()->getEntity();
3329 for ( ; entity < MED_NODE; entity++ )
3331 int nbTypes = _mesh->getNumberOfTypes( entity );
3332 if ( nbTypes == 0 || !mesh->existConnectivity( MED_NODAL, entity ))
3334 const medGeometryElement* types = _mesh->getTypes( entity );
3335 const int * nbIndex = mesh->getGlobalNumberingIndex (entity);
3336 const int * nodalConnect = 0, * nodalConnectIndex = 0;
3337 nodalConnect = mesh->getConnectivity (MED_NODAL,entity,MED_ALL_ELEMENTS);
3338 nodalConnectIndex = mesh->getConnectivityIndex (MED_NODAL,entity);
3340 for ( int iType = 1; iType <= nbTypes; ++iType )
3342 int nbElements = nbIndex[ iType ] - nbIndex[ iType - 1 ];
3343 medGeometryElement geomType = types[ iType - 1 ];
3344 if ( nbSuppElemsByType[ geomType ] >= nbElements )
3345 continue; // all elements are written with _supports
3347 int elemId1 = nbIndex[ iType - 1 ];
3348 data.addTypeData( geomType, nbElements, 0, elemId1 );
3350 writeElements (geomType,
3351 data._types[ geomType ],
3357 // D颵t de la pile 32 (celle des points)
3359 int nbNodes = _mesh->getNumberOfNodes();
3360 _gibi << " ENREGISTREMENT DE TYPE 2" << endl;
3361 _gibi << " PILE NUMERO 32NBRE OBJETS NOMMES 0" <<
3362 "NBRE OBJETS" << setw(8) << nbNodes << endl;
3363 // Liste des noms de points
3364 // * 8001 FORMAT(8(1X,A8))
3366 // suit le nombre de noeuds
3367 _gibi << setw(8) << nbNodes << endl;
3368 // Le tableau suivant donne le filtre pour avoir le vrai num? des noeuds
3369 // appartenant aux 鬩ments d飲its. Par exemple, si un 鬩ment, d飲it
3370 // dans la pile 1, fait r馩rence ?n num? de noeud 駡l ? il faut le
3372 // * 8000 FORMAT(10I8)
3373 for ( i = 0; i < nbNodes; ++i, fcount++ )
3374 _gibi << setw(8) << i + 1;
3377 // D颵t de pile 33 (celle des configurations (coordonn?))
3378 _gibi << " ENREGISTREMENT DE TYPE 2" << endl;
3379 _gibi << " PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1" << endl;
3380 // Suit le nombre de points dont on donne les coordonn?
3381 int nbValues = nbNodes * ( dim + 1 );
3382 _gibi << setw(8) << nbValues << endl;
3383 // Les coordonn? sont donn? par noeuds. D'abord le premier puis le deuxi譥...
3384 // Pour chaque noeuds, on donne les 2 ou 3 coordonn? plus la densit頣ourante
3385 // au moment de sa cr顴ion.
3386 // * 8003 FORMAT(1P,3E22.14)
3387 _gibi.precision(14);
3388 _gibi.setf( ios_base::scientific, ios_base::floatfield );
3389 _gibi.setf( ios_base::uppercase );
3390 const double * coords = mesh->getCoordinates(MED_FULL_INTERLACE);
3392 const double precision = 1.e-99; // PAL12077
3393 for ( fcount.init(3),i = 0; i < nbNodes; ++i, j += dim )
3395 for ( int iCoord = 0; iCoord < dim; ++iCoord, fcount++ ) {
3396 double coo = coords[ j + iCoord ];
3397 bool zero = ( -precision < coo && coo < precision );
3398 _gibi << setw(22) << ( zero ? 0.0 : coo );
3400 _gibi << setw(22) << 0.0; // densite
3408 //=======================================================================
3409 //function : writeMEDNames
3411 //=======================================================================
3412 void GIBI_MESH_WRONLY_DRIVER::writeMEDNames (const list<nameGIBItoMED>& listGIBItoMED_mail,
3413 const list<nameGIBItoMED>& listGIBItoMED_cham,
3414 const list<nameGIBItoMED>& listGIBItoMED_comp)
3416 // IMP 0020434: mapping GIBI names to MED names
3417 // Store correspondence between GIBI and MED names
3418 // as one PILE_STRINGS and one PILE_TABLES
3419 // (in three tables: MED_MAIL, MED_CHAM and MED_COMP)
3421 int nbNames_mail = listGIBItoMED_mail.size();
3422 int nbNames_cham = listGIBItoMED_cham.size();
3423 int nbNames_comp = listGIBItoMED_comp.size();
3426 if (nbNames_mail) nbTables++;
3427 if (nbNames_cham) nbTables++;
3428 if (nbNames_comp) nbTables++;
3433 // The whole string (concatenated names)
3434 string theWholeString;
3435 list<int> theOffsets;
3439 // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4)
3440 _gibi << " ENREGISTREMENT DE TYPE 2" << endl;
3441 // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8)
3442 _gibi << " PILE NUMERO 10NBRE OBJETS NOMMES" << setw(8) << nbTables <<
3443 "NBRE OBJETS" << setw(8) << nbTables << endl; // <nbTables> named tables
3446 _gibi << " MED_MAIL";
3448 _gibi << " MED_CHAM";
3450 _gibi << " MED_COMP";
3453 _gibi << setw(8) << 1;
3454 if (nbTables > 1) _gibi << setw(8) << 2;
3455 if (nbTables > 2) _gibi << setw(8) << 3;
3462 // Provide unique MED names, to exclude conflicts on reading saved files
3463 // (use case: read fra.med, save it to GIBI, read it from GIBI,
3464 // save to MED again -> this new MED file is not readable)
3465 set<string> medUniqueNames;
3467 _gibi << setw(8) << nbNames_mail*4 << endl; // Nb of table values
3469 TFieldCounter fcount1 (_gibi, 10);
3471 list<nameGIBItoMED>::const_iterator itGIBItoMED = listGIBItoMED_mail.begin();
3472 for (; itGIBItoMED != listGIBItoMED_mail.end(); itGIBItoMED++, istr++) {
3473 // PILE of i-th key(med name)
3474 _gibi << setw(8) << 27; fcount1++; // PILE_STRINGS number is 27
3475 // ID of i-th key(med name)
3476 _gibi << setw(8) << istr; fcount1++;
3478 // PILE of i-th value(gibi name)
3479 _gibi << setw(8) << itGIBItoMED->gibi_pile; fcount1++; // PILE_SOUS_MAILLAGE number is 1
3480 // ID of i-th value(gibi name)
3481 _gibi << setw(8) << itGIBItoMED->gibi_id; fcount1++;
3483 // check MED name to be unique
3484 string aMedName = itGIBItoMED->med_name;
3485 if (!medUniqueNames.insert(aMedName).second) {
3490 sprintf(strInd, "_%d", ind++);
3491 aMedNameNew = aMedName + strInd;
3492 } while (!medUniqueNames.insert(aMedNameNew).second);
3493 aMedName = aMedNameNew;
3496 // add to the string
3497 theWholeString += aMedName; // MED name
3500 currOffset += aMedName.length();
3501 theOffsets.push_back(currOffset);
3508 // Provide unique MED names, to exclude conflicts on reading saved files
3509 // (use case: read fra.med, save it to GIBI, read it from GIBI,
3510 // save to MED again -> this new MED file is not readable)
3511 set<string> medUniqueNames;
3513 _gibi << setw(8) << nbNames_cham*4 << endl; // Nb of table values
3515 TFieldCounter fcount1 (_gibi, 10);
3517 list<nameGIBItoMED>::const_iterator itGIBItoMED = listGIBItoMED_cham.begin();
3518 for (; itGIBItoMED != listGIBItoMED_cham.end(); itGIBItoMED++, istr++) {
3519 // PILE of i-th key(med name)
3520 _gibi << setw(8) << 27; fcount1++; // PILE_STRINGS number is 27
3521 // ID of i-th key(med name)
3522 _gibi << setw(8) << istr; fcount1++;
3524 // PILE of i-th value(gibi name)
3525 // PILE_NODES_FIELD number is 2, PILE_FIELD number is 39
3526 _gibi << setw(8) << itGIBItoMED->gibi_pile; fcount1++;
3527 // ID of i-th value(gibi name)
3528 _gibi << setw(8) << itGIBItoMED->gibi_id; fcount1++;
3530 // check MED name to be unique
3531 string aMedName = itGIBItoMED->med_name;
3532 if (!medUniqueNames.insert(aMedName).second) {
3537 sprintf(strInd, "_%d", ind++);
3538 aMedNameNew = aMedName + strInd;
3539 } while (!medUniqueNames.insert(aMedNameNew).second);
3540 aMedName = aMedNameNew;
3543 // add to the string
3544 theWholeString += aMedName; // MED name
3547 currOffset += aMedName.length();
3548 theOffsets.push_back(currOffset);
3555 // for components, both key and value (long and short name) is in the STRING PILE
3557 _gibi << setw(8) << nbNames_comp*4 << endl; // Nb of table values
3559 TFieldCounter fcount1 (_gibi, 10);
3561 list<nameGIBItoMED>::const_iterator itGIBItoMED = listGIBItoMED_comp.begin();
3562 for (; itGIBItoMED != listGIBItoMED_comp.end(); itGIBItoMED++, istr+=2) {
3563 // PILE of i-th key(med name)
3564 _gibi << setw(8) << 27; fcount1++; // PILE_STRINGS number is 27
3565 // ID of i-th key(med name)
3566 _gibi << setw(8) << istr; fcount1++;
3568 // PILE of i-th value(gibi name)
3569 _gibi << setw(8) << 27; fcount1++; // PILE_STRINGS number is 27
3570 // ID of i-th value(gibi name)
3571 _gibi << setw(8) << istr + 1; fcount1++;
3573 // add to the string
3574 string aMedName = itGIBItoMED->med_name;
3575 string aGibiName = itGIBItoMED->gibi_name;
3576 theWholeString += aMedName; // MED name
3577 theWholeString += aGibiName; // GIBI name
3580 currOffset += aMedName.length();
3581 theOffsets.push_back(currOffset);
3582 currOffset += aGibiName.length();
3583 theOffsets.push_back(currOffset);
3588 int nbNames = nbNames_mail + nbNames_cham + 2 * nbNames_comp; // tmp
3591 // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4)
3592 _gibi << " ENREGISTREMENT DE TYPE 2" << endl;
3593 // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8)
3594 _gibi << " PILE NUMERO 27NBRE OBJETS NOMMES" << setw(8) << 0 << // No named strings
3595 "NBRE OBJETS" << setw(8) << nbNames << endl;
3598 //TFieldCounter fcount2 (_gibi, 10);
3600 //for (int jj = 1; jj <= nbNames; jj++) {
3601 // _gibi << setw(8) << jj; fcount2++;
3606 _gibi << setw(8) << theWholeString.length()
3607 << setw(8) << nbNames << endl;
3609 // Write the whole string
3610 const int fixedLength = 71;
3612 int aLen = theWholeString.length();
3613 for (; aPos < aLen; aPos += fixedLength) {
3614 _gibi << setw(72) << theWholeString.substr(aPos, fixedLength) << endl;
3615 } while (aPos < aLen);
3617 // Write the offsets
3618 TFieldCounter fcount3 (_gibi, 10);
3620 list<int>::iterator offsetIt = theOffsets.begin();
3621 for (; offsetIt != theOffsets.end(); offsetIt++) {
3622 _gibi << setw(8) << (*offsetIt); fcount3++;
3627 //=======================================================================
3628 //function : writeLastRecord
3630 //=======================================================================
3632 void GIBI_MESH_WRONLY_DRIVER::writeLastRecord()
3634 _gibi << " ENREGISTREMENT DE TYPE 5" << endl;
3635 _gibi << "LABEL AUTOMATIQUE : 1" << endl;
3638 /*--------------------- RDWR PART -------------------------------*/
3640 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER()
3641 :GIBI_MESH_DRIVER(), GIBI_MESH_RDONLY_DRIVER(), GIBI_MESH_WRONLY_DRIVER()
3644 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh):
3645 GIBI_MESH_DRIVER(fileName,ptrMesh,RDWR),
3646 GIBI_MESH_RDONLY_DRIVER(fileName,ptrMesh),
3647 GIBI_MESH_WRONLY_DRIVER(fileName,ptrMesh)
3649 MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created");
3651 GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const GIBI_MESH_RDWR_DRIVER & driver):
3652 GIBI_MESH_DRIVER(driver),
3653 GIBI_MESH_RDONLY_DRIVER(driver),
3654 GIBI_MESH_WRONLY_DRIVER(driver)
3656 MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(driver) has been created");
3658 GIBI_MESH_RDWR_DRIVER::~GIBI_MESH_RDWR_DRIVER() {
3659 MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed");
3661 GENDRIVER * GIBI_MESH_RDWR_DRIVER::copy(void) const
3663 const char* LOC = "GIBI_MESH_RDWR_DRIVER::copy()";
3665 GENDRIVER * driver = new GIBI_MESH_RDWR_DRIVER(*this);
3669 void GIBI_MESH_RDWR_DRIVER::write(void) const
3670 throw (MEDEXCEPTION)
3672 GIBI_MESH_RDWR_DRIVER * me = const_cast<GIBI_MESH_RDWR_DRIVER *>(this);
3673 me->GIBI_MESH_WRONLY_DRIVER::open();
3674 me->GIBI_MESH_WRONLY_DRIVER::write();
3675 me->GIBI_MESH_WRONLY_DRIVER::close();
3677 void GIBI_MESH_RDWR_DRIVER::read (void)
3678 throw (MEDEXCEPTION)
3680 const char* LOC = "GIBI_MESH_RDWR_DRIVER::read()";
3682 GIBI_MESH_RDONLY_DRIVER::open();
3683 GIBI_MESH_RDONLY_DRIVER::read();
3684 GIBI_MESH_RDONLY_DRIVER::close();
3687 void GIBI_MESH_RDWR_DRIVER::open()
3688 // throw (MEDEXCEPTION)
3691 void GIBI_MESH_RDWR_DRIVER::close()
3692 // throw (MEDEXCEPTION)
3696 //============================== ====================================================
3697 //============================== FIELD Reading Driver ==============================
3698 //============================== ====================================================
3700 GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER():GIBI_MESH_RDONLY_DRIVER(),_fields(0)
3703 GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER(const string & fileName, vector<FIELD_*>& ptrFields):
3704 GIBI_MESH_RDONLY_DRIVER(fileName,NULL), _fields( &ptrFields )
3706 MESSAGE_MED("GIBI_MED_RDONLY_DRIVER(const string & fileName, vector<FIELD_*>&) has been created");
3707 _fileName = fileName;
3708 _accessMode = RDONLY;
3710 GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER(const GIBI_MED_RDONLY_DRIVER & driver):
3711 GIBI_MESH_RDONLY_DRIVER( driver ), _fields( driver._fields )
3715 GIBI_MED_RDONLY_DRIVER::~GIBI_MED_RDONLY_DRIVER()
3718 _mesh->removeReference();
3720 GENDRIVER * GIBI_MED_RDONLY_DRIVER::copy ( void ) const
3722 return new GIBI_MED_RDONLY_DRIVER(*this);
3725 //=======================================================================
3728 //=======================================================================
3730 void GIBI_MED_RDONLY_DRIVER::read ( void ) throw (MEDEXCEPTION)
3732 const char * LOC = "GIBI_MED_RDONLY_DRIVER::read() : ";
3735 if (_status!=MED_OPENED)
3736 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "file " << _fileName<<" is not opened." ));
3740 _intermediateMED medi;
3742 if ( !readFile( &medi, true ) )
3745 //MESSAGE_MED(LOC << medi );
3747 MESSAGE_MED(LOC << "GIBI_MED_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : ");
3748 MESSAGE_MED(LOC << medi );
3750 list< FIELD_* > fields;
3751 medi.getFields( fields );
3752 updateSupports(); // create families from groups etc.
3753 MESSAGE_MED( "nb fields: " << fields.size() );
3755 if ( _mesh->getName().empty() )
3756 _mesh->setName( "MESH" );
3758 list< FIELD_* >::iterator it = fields.begin();
3759 for ( ; it != fields.end(); it++ )
3762 int nbComponents = fld->getNumberOfComponents();
3763 if(nbComponents>0) {
3764 UNIT* compoUnits = new UNIT[nbComponents];
3765 string* MEDcompoUnits = new string[nbComponents];
3766 for(int l = 0; l<nbComponents; l++) {
3767 compoUnits[l] = UNIT("", "");
3768 MEDcompoUnits[l] = "";
3770 fld->setComponentsUnits(compoUnits);
3771 fld->setMEDComponentsUnits(MEDcompoUnits);
3772 delete [] compoUnits;
3773 delete [] MEDcompoUnits;
3775 // 0020466: [CEA] sauv2med : bad conversion
3776 // Provide profile names for a partial field
3777 const SUPPORT* sup = fld->getSupport();
3778 if ( sup && !sup->isOnAllElements() )
3780 vector<string> prof_names( sup->getNumberOfTypes() );
3781 for (unsigned itype=0; itype < prof_names.size(); itype++)
3782 prof_names[itype]=STRING( sup->getName())<<"_type"<<sup->getTypes()[itype];
3783 ((SUPPORT*) sup)->setProfilNames( prof_names );
3785 _fields->push_back( *it );
3788 catch (MEDEXCEPTION &ex)
3790 INFOS_MED( ex.what() );
3796 //================================================================================
3798 * \brief Return a mesh created while reading fields.
3799 * Call removeReference() after finishing using it.
3801 //================================================================================
3803 MESH* GIBI_MED_RDONLY_DRIVER::getMesh() const
3806 _mesh->addReference();
3807 return (MESH*) _mesh;
3811 //============================== ====================================================
3812 //============================== FIELD Writting Driver ==============================
3813 //============================== ====================================================
3815 GIBI_MED_WRONLY_DRIVER::GIBI_MED_WRONLY_DRIVER():GIBI_MESH_WRONLY_DRIVER()
3818 GIBI_MED_WRONLY_DRIVER::GIBI_MED_WRONLY_DRIVER(const string & fileName,
3819 const vector<const FIELD_*>& fields,
3821 :GIBI_MESH_DRIVER(fileName,ptrMesh,WRONLY),
3822 GIBI_MESH_WRONLY_DRIVER(fileName,ptrMesh),
3825 const char * LOC = "GIBI_MED_WRONLY_DRIVER( fileName, vector<FIELD_*>&, MESH *)";
3829 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Bad mesh " << _mesh ));
3830 _fileName = fileName;
3831 _accessMode = WRONLY;
3834 GIBI_MED_WRONLY_DRIVER::GIBI_MED_WRONLY_DRIVER(const GIBI_MED_WRONLY_DRIVER & driver):
3835 GIBI_MESH_WRONLY_DRIVER( driver ), _fields( driver._fields )
3838 GIBI_MED_WRONLY_DRIVER::~GIBI_MED_WRONLY_DRIVER()
3841 GENDRIVER * GIBI_MED_WRONLY_DRIVER::copy ( void ) const
3843 return new GIBI_MED_WRONLY_DRIVER(*this);
3846 //=======================================================================
3847 //function : writeDataSection
3849 //=======================================================================
3851 template< class T, class INTERLACING_TAG>
3852 static void writeDataSection (fstream& file,
3853 const FIELD<T, INTERLACING_TAG> * field,
3855 const int id2) throw (MEDEXCEPTION)
3857 const char * LOC="writeDataSection (.....) :";
3860 int nbGauss, nbComp = field->getNumberOfComponents();
3862 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,NoGauss>::Array ArrayNoGauss;
3863 typedef typename MEDMEM_ArrayInterface<T,INTERLACING_TAG,Gauss>::Array ArrayGauss;
3865 MEDMEM_Array_ * array = field->getArray();
3866 ArrayNoGauss * arrayNoGauss = 0;
3867 ArrayGauss * arrayGauss = 0;
3870 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |"<< field->getName()
3871 << "| not allocated"));
3873 if ( array->getGaussPresence() ) {
3874 arrayGauss = field->getArrayGauss();
3875 nbGauss = arrayGauss->getNbGauss( id1 );
3878 arrayNoGauss = field->getArrayNoGauss();
3882 TFieldCounter fcount( file, 3 ); // 3 values on a line
3884 #ifdef CASTEM_FULL_INTERLACE
3885 const int gauss_step = field->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ? nbComp : 1;
3887 const bool isNodal = ( field->getSupport()->getEntity() == MED_EN::MED_NODE );
3889 for ( int iComp = 1; iComp <= nbComp; ++iComp )
3892 file << setw(8) << nbGauss // nb scalar values by element
3893 << setw(8) << ( id2 - id1 ) // total nb of scalar values
3898 // * 8003 FORMAT(1P,3E22.14)
3899 if ( arrayNoGauss ) {
3900 for (int id = id1; id < id2; id++, fcount++ )
3901 file << setw(22) << arrayNoGauss->getIJ( id, iComp );
3904 #ifdef CASTEM_FULL_INTERLACE
3905 for (int id = id1; id < id2; id++ ) {
3906 const T* val = & arrayGauss->getIJK( id, iComp, 1 );
3907 const T* valEnd = val + nbGauss * gauss_step;
3908 for ( ; val < valEnd; val += gauss_step, fcount++ )
3909 file << setw(22) << *val;
3912 for ( int iGauss = 1; iGauss <= nbGauss; ++iGauss ) {
3913 for (int id = id1; id < id2; id++, fcount++ )
3914 file << setw(22) << arrayGauss->getIJK( id, iComp, iGauss );
3923 //=======================================================================
3926 //=======================================================================
3928 void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION)
3930 const char* LOC = "void GIBI_MED_WRONLY_DRIVER::write(void) const : ";
3933 // we are going to modify the _gibi field
3934 GIBI_MED_WRONLY_DRIVER * me = const_cast<GIBI_MED_WRONLY_DRIVER *>(this);
3936 // get all fields on _mesh and add their support to be written
3937 list<const FIELD_*> fields;
3938 int iField, nbFields = _fields.size();
3939 list<int> nb_sub_list, nb_comp_list;
3940 int nb_nodal_flds = 0;
3942 map<string,int> nameNbMap;
3943 map<string,int> namePrefixMap;
3944 list< string > orderedNames;
3946 list<pair<int,int> > subIdSizeList; // pair( <submesh id>, <submesh size> );
3947 list<pair<int,int> >::iterator idsize;
3949 // IMP 0020434: mapping GIBI names to MED names
3950 list<nameGIBItoMED> listGIBItoMED_mail;
3951 list<nameGIBItoMED> listGIBItoMED_cham;
3952 list<nameGIBItoMED> listGIBItoMED_comp;
3954 for ( iField = 0; iField < nbFields; ++iField )
3956 int nb_sub = 0, nb_comp = 0;
3957 const FIELD_ * f = _fields[ iField ];
3958 if ( f->getValueType() != MED_EN::MED_REEL64 )
3960 MESSAGE_MED("GIBI_MED_WRONLY_DRIVER::write( FIELD< int > ) not implemented");
3963 const SUPPORT * sup = f->getSupport();
3964 const medEntityMesh entity = sup->getEntity();
3966 if ( me->addSupport( sup ) )
3968 if ( entity == MED_NODE ) fields.push_front( f );
3969 else fields.push_back( f );
3970 nb_sub += getSubMeshIdAndSize( sup, subIdSizeList );
3971 nb_comp += nb_sub * f->getNumberOfComponents();
3975 if ( entity == MED_NODE )
3977 nb_sub_list.push_front ( nb_sub );
3978 orderedNames.push_front( f->getName() );
3979 nb_comp_list.push_front( nb_comp );
3984 nb_sub_list.push_back ( nb_sub );
3985 orderedNames.push_back( f->getName() );
3986 nb_comp_list.push_back( nb_comp );
3990 list< string >::iterator nameIt = orderedNames.begin();
3991 for ( iField = 0 ; nameIt != orderedNames.end(); ++nameIt, ++iField )
3993 const bool isNodal = iField < nb_nodal_flds;
3994 int nb_obj = isNodal ? (iField + 1) : (iField - nb_nodal_flds + 1);
3995 addName(nameNbMap, namePrefixMap, *nameIt, nb_obj);
3997 // IMP 0020434: mapping GIBI names to MED names
3998 nameGIBItoMED aMEDName;
3999 aMEDName.gibi_pile = isNodal ? PILE_NODES_FIELD : PILE_FIELD;
4000 aMEDName.gibi_id = nb_obj;
4001 aMEDName.med_name = *nameIt;
4002 listGIBItoMED_cham.push_back(aMEDName);
4007 me->writeSupportsAndMesh(listGIBItoMED_mail);
4011 if ( !fields.empty() )
4013 fstream & gibi = me->_gibi;
4015 TFieldCounter fcount( gibi, 10 );
4017 list<const FIELD_*>::const_iterator itF = fields.begin();
4018 list<int>::iterator itNbSub = nb_sub_list.begin(), itNbComp = nb_comp_list.begin();
4019 int nb_sub = 0, cur_nb_sub = 0, total_nb_comp = 0;
4020 medEntityMesh entity = MED_INVALID;
4022 for ( iField = 0; itF != fields.end(); itF++, iField++ )
4024 const FIELD_* f = *itF;
4026 unsigned iComp, nbComp = unsigned( f->getNumberOfComponents() );
4028 // IMP 0020434: mapping GIBI names to MED names
4029 map<string, string> mapMedToGibi;
4031 for (int ico = 0; ico < nbComp; ico++)
4033 string compMedName = f->getComponentName(ico + 1);
4034 compMedName = cleanName(compMedName);
4035 mapMedToGibi[compMedName] = compMedName;
4038 map<string, string>::iterator namesIt = mapMedToGibi.begin();
4039 for (; namesIt != mapMedToGibi.end(); namesIt++)
4041 string compMedName = (*namesIt).first;
4042 string compGibiName = compMedName;
4043 if (compGibiName.size() > 4) {
4044 // use new name in form "CXXX", where "XXX" is a number
4050 if (compIndex < 100) strCGN[pos++] = '0';
4051 if (compIndex < 10 ) strCGN[pos++] = '0';
4052 sprintf(strCGN + pos, "%d", compIndex++);
4053 compGibiName = strCGN;
4055 while (mapMedToGibi.count(compGibiName) > 0); // real component name could be CXXX
4057 mapMedToGibi[compMedName] = compGibiName;
4060 compMedName = f->getName() + "." + compMedName;
4061 nameGIBItoMED aMEDName;
4062 aMEDName.med_name = compMedName;
4063 aMEDName.gibi_pile = PILE_STRINGS;
4064 aMEDName.gibi_name = compGibiName;
4065 listGIBItoMED_comp.push_back(aMEDName);
4069 if ( cur_nb_sub == nb_sub && itNbSub != nb_sub_list.end() )
4071 // Start writting another field
4073 const medEntityMesh nextEntity = f->getSupport()->getEntity();
4074 if ( nextEntity != entity )
4076 if ( entity == MED_INVALID || entity == MED_NODE )
4078 int nb_obj = ( nextEntity == MED_NODE ) ? nb_nodal_flds : orderedNames.size() - nb_nodal_flds;
4079 gibi << " ENREGISTREMENT DE TYPE 2" << endl;
4080 gibi << " PILE NUMERO" << ( nextEntity == MED_NODE ? " 2" : " 39" );
4081 gibi << "NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size();
4082 gibi << "NBRE OBJETS" << setw(8) << nb_obj << endl;
4084 me->writeNames( nameNbMap );
4086 entity = f->getSupport()->getEntity();
4089 total_nb_comp = *(itNbComp++);
4090 nb_sub = *(itNbSub++);
4092 string description = (*itF)->getDescription();
4093 if ( description.size() > 72 )
4094 description = description.substr(0,72);
4096 if ( entity == MED_NODE )
4098 gibi << setw(8) << nb_sub
4099 << setw(8) << total_nb_comp
4100 << setw(8) << -1 // IFOUR
4101 << setw(8) << 0 << endl; // nb attributes
4105 gibi << setw(8) << nb_sub
4108 << setw(8) << 72 /*description.size()*/ << endl; // PAL19100
4109 if ( !description.empty() )
4110 gibi << setw(72) << description << endl;
4112 gibi << setw(72) << "Field" << endl;
4113 gibi << setw(72) << " " << endl;
4116 // Sub Components section
4118 list<const FIELD_*>::const_iterator itF2 = itF;
4121 0, 0, 0, 0, 0, 0, 0, 0, 2
4123 const int nbv = ( entity == MED_NODE ? 3 : 9 );
4124 vector< string > comp_names;
4127 while ( itF2 != fields.end() && cur_nb_sub < nb_sub )
4129 const FIELD_* f = *itF2++;
4130 vals[2] = f->getNumberOfComponents();
4131 getSubMeshIdAndSize( f->getSupport(), subIdSizeList );
4132 for ( idsize = subIdSizeList.begin(); idsize != subIdSizeList.end(); idsize++)
4136 vals[0] = -idsize->first; // support id
4137 if ( entity == MED_NODE )
4138 vals[1] = idsize->second; // nb values
4139 for ( int i = 0; i < nbv; ++i, fcount++ )
4140 gibi << setw(8) << vals[ i ];
4142 for ( int i = 0; i < f->getNumberOfComponents(); ++i )
4143 comp_names.push_back( f->getComponentName( i+1 ));
4149 if ( entity == MED_NODE )
4155 for ( iComp = 0; iComp < comp_names.size(); ++iComp, fcount++ )
4157 string compMedName = cleanName(f->getComponentName(iComp + 1));
4158 string compName = mapMedToGibi[compMedName];
4159 gibi << " " << setw(8) << compName;
4167 for ( int i = 0; i < total_nb_comp; ++i )
4168 gibi << setw(8) << 0;
4171 gibi << endl; // TYPE
4172 gibi << setw(72) << description << endl;
4173 gibi << endl; // 0 attributes
4179 for ( fcount.init(4), i_sub = 0; i_sub < nb_sub; ++i_sub, fcount++ )
4183 for ( fcount.init(8), i_sub = 0; i_sub < nb_sub; ++i_sub, fcount++ )
4187 } // end writing common field data
4190 // loop on sub-components
4192 getSubMeshIdAndSize( f->getSupport(), subIdSizeList );
4193 for ( idsize = subIdSizeList.begin(); idsize != subIdSizeList.end(); idsize++ )
4196 if ( entity != MED_NODE )
4198 // component addresses
4200 for ( iComp = 0; iComp < nbComp; ++iComp, fcount++ )
4201 gibi << setw(8) << 777; // a good number
4206 for ( iComp = 0; iComp < nbComp; ++iComp, fcount++ )
4208 string compMedName = cleanName(f->getComponentName(iComp + 1));
4209 string compName = mapMedToGibi[compMedName];
4210 gibi << " " << setw(8) << compName;
4215 for ( iComp = 0; iComp < nbComp; ++iComp, fcount++ )
4216 gibi << " " << setw(17) << "REAL*8";
4223 int id2 = id1 + idsize->second;
4225 if ( f->getInterlacingType() == MED_NO_INTERLACE )
4226 writeDataSection( gibi, static_cast<const FIELD<double,NoInterlace > * >(f),
4228 else if ( f->getInterlacingType() == MED_FULL_INTERLACE )
4229 writeDataSection( gibi, static_cast<const FIELD<double,FullInterlace> * >(f),
4232 writeDataSection( gibi, static_cast<const FIELD<double,NoInterlaceByType> * >(f),
4240 // IMP 0020434: mapping GIBI names to MED names
4241 me->writeMEDNames(listGIBItoMED_mail, listGIBItoMED_cham, listGIBItoMED_comp);
4243 me->writeLastRecord();