
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

#include "Visualisation_Gmsh.h"
#include <stdlib.h>
#include <iomanip>
// les ordres possibles
#include "Mail_initiale_Gmsh.h"
#include "Deformees_Gmsh.h"
#include "Fin_Gmsh.h"
#include "Visuali_Gmsh.h"
#include "Increment_vrml.h"
#include "ChoixDesMaillages_vrml.h"
#include "Isovaleurs_Gmsh.h"
#include "Banniere.h"

// ---------- variables statiques ---------
Tableau < Tableau < int > > Visualisation_Gmsh::t_HerGmsh; 
Tableau < Tableau < int > > Visualisation_Gmsh::t_GmshHer; 
// ---------- fin variables statiques ------

    // CONSTRUCTEURS :
Visualisation_Gmsh::Visualisation_Gmsh ()   // par defaut
  {  cout << "\n  ce constructeur ne doit pas etre utilise !! \n" ;
     cout << " Visualisation_Gmsh::Visualisation_Gmsh () // par defaut " << endl;
  }; 
    
// le bon constructeur
Visualisation_Gmsh::Visualisation_Gmsh (UtilLecture* ent) :
 lesValVecPropres(),ordre_possible(),entreePrinc(ent)
 ,fin_o(NULL),visuali(NULL),choix_inc(NULL)
 ,list_incre(),list_balaie(NULL)
 ,animation(false)
 ,activ_sort_Gmsh(false),list_tousLesNomsASortir()
  { // définition des ordres possibles
    list <OrdreVisu>::iterator it;
    OrdreVisu* ptordre;
    // maillage initial
    ptordre = new Mail_initiale_Gmsh(); ordre_possible.push_back(ptordre);
    mailInit = ptordre; // récup de l'ordre
    // Choix de la visualisation des isovaleurs
    //NB: il faut que l'isovaleur soit avant la déformée !! pour que la déformée puisse
    // utiliser les couleurs définis dans isovaleurs 
    ptordre = new Isovaleurs_Gmsh(); ordre_possible.push_back(ptordre);
    choix_isovaleur = ptordre; // récup de l'ordre
    // déformée
    ptordre = new Deformees_Gmsh(); ordre_possible.push_back(ptordre);
    ptdeformee = ptordre; // récup de l'ordre
    // Choix du ou des incréments à visualiser. 
    ptordre = new Increment_vrml(); ordre_possible.push_back(ptordre);
    choix_inc = ptordre; // récup de l'ordre 
    // Choix du ou des maillages à visualiser. 
    ptordre = new ChoixDesMaillages_vrml(); ordre_possible.push_back(ptordre);
    choix_mail = ptordre; // récup de l'ordre 
    // transmission de la position à la déformée 
    ((Deformees_Gmsh*) ptdeformee)->Jonction_isovaleur((Isovaleurs_Gmsh*)choix_isovaleur);
    ((Deformees_Gmsh*) ptdeformee)->Jonction_ChoixDesMaillages((ChoixDesMaillages_vrml*)choix_mail);
    // transmission du maillage initiale aux isovaleurs et à la déformée
    ((Isovaleurs_Gmsh*) choix_isovaleur)->Jonction_MaillageInitiale((Mail_initiale_Gmsh*)mailInit);
    ((Deformees_Gmsh*) ptdeformee)->Jonction_MaillageInitiale((Mail_initiale_Gmsh*)mailInit);
    // ordre de visualisation
    ptordre = new Visuali_Gmsh(); ordre_possible.push_back(ptordre);
    visuali = ptordre; // récup de l'ordre 
    // fin de la visualisation
    ptordre = new Fin_Gmsh(); ordre_possible.push_back(ptordre);
    fin_o = ptordre; // récup de l'ordre fin
    
/*   [1,2], #  1: ' POUT BIE1 ' ,   	      
     [1,2,3], # 2:  ' TRIANGLE LINEAIRE ' ,
     [1,2,3,4], #  3: ' QUADRANGLE LINEAIRE ' ,   
     [1,2,3,4], #  4:  ' TETRAEDRE LINEAIRE ' ,    
     [1,2,3,4,5,6,7,8], #  5: ' HEXAEDRE LINEAIRE ' ,     
     [1,2,3,4,5,6], #  6: ' PENTAEDRE LINEAIRE ' ,    
     [1,2,3,4,5], #  7: ' PYRAMIDE LINEAIRE ' ,     
     [1,3,2], #  8: ' POUT QUADRATIQUE ' ,      
     [1,2,3,4,5,6], #  9: ' TRIANGLE QUADRACOMPL ' ,  
     [1,2,3,4,5,6,7,8,9], # 10: ' QUADRANGLE QUADRACOMPL ' , 
     [1,2,3,4,5,6,7,8,10,9], # 11: ' TETRAEDRE QUADRATIQUE '  , 
     [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27], # 12: ' HEXAEDRE QUADRACOMPL '  ,  
     [1,2,3,4,5,6,7,10,8,9, 11,12,13,15,14,16,18,17], #  13:' PENTAEDRE QUADRACOMPL ' ,  
     [1,2,3,4,5,6,7,8,9,10,11,12,13,14], #  14:' PYRAMIDE QUADRACOMPL ' ,   
     [1], #  15: ' POINT LINEAIRE ' ,	       
     [1,2,3,4,5,6,7,8], #  16: ' QUADRANGLE QUADRATIQUE ' , 
     [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], # 17: ' HEXAEDRE QUADRATIQUE ' ,   
     [1,2,3,4,5,6,7,10,8,9, 11,12,13,15,14], #  18:' PENTAEDRE QUADRATIQUE ' ,  
     [1,2,3,4,5,6,7,8,9,10,11,12,13], # 19:  ' PYRAMIDE QUADRATIQUE '      
*/

    // définition des tableaux t_HerGmsh et t_GmshHer
    t_HerGmsh.Change_taille(19);t_GmshHer.Change_taille(19);
    //' POUT BIE1 '
    t_HerGmsh(1).Change_taille(2);t_GmshHer(1).Change_taille(2);
    t_HerGmsh(1)(1)=1;t_HerGmsh(1)(2)=2;t_HerGmsh(1)(1)=1;t_HerGmsh(1)(2)=2;

    t_GmshHer(1)(1)=1;t_GmshHer(1)(2)=2;t_GmshHer(1)(1)=1;t_GmshHer(1)(2)=2;
    // ' TRIANGLE LINEAIRE ' 
    t_HerGmsh(2).Change_taille(3);t_GmshHer(2).Change_taille(3);
    t_HerGmsh(2)(1)=1;t_HerGmsh(2)(2)=2;t_HerGmsh(2)(3)=3;
    t_HerGmsh(2)(1)=1;t_HerGmsh(2)(2)=2;t_HerGmsh(2)(3)=3;

    t_GmshHer(2)(1)=1;t_GmshHer(2)(2)=2;t_GmshHer(2)(3)=3;
    t_GmshHer(2)(1)=1;t_GmshHer(2)(2)=2;t_GmshHer(2)(3)=3;
    // ' QUADRANGLE LINEAIRE ' 
    t_HerGmsh(3).Change_taille(4);t_GmshHer(3).Change_taille(4);
    t_HerGmsh(3)(1)=1;t_HerGmsh(3)(2)=2;t_HerGmsh(3)(3)=3;t_HerGmsh(3)(4)=4;
    t_HerGmsh(3)(1)=1;t_HerGmsh(3)(2)=2;t_HerGmsh(3)(3)=3;t_HerGmsh(3)(4)=4;

    t_GmshHer(3)(1)=1;t_GmshHer(3)(2)=2;t_GmshHer(3)(3)=3;t_GmshHer(3)(4)=4;
    t_GmshHer(3)(1)=1;t_GmshHer(3)(2)=2;t_GmshHer(3)(3)=3;t_GmshHer(3)(4)=4;
    // ' TETRAEDRE LINEAIRE '
    t_HerGmsh(4).Change_taille(4);t_GmshHer(4).Change_taille(4);
    for (int i=1;i<=4;i++) {t_HerGmsh(4)(i)=i;t_GmshHer(4)(i)=i;};
    // ' HEXAEDRE LINEAIRE '
    t_HerGmsh(5).Change_taille(8);t_GmshHer(5).Change_taille(8);
    for (int i=1;i<=8;i++) {t_HerGmsh(5)(i)=i;t_GmshHer(5)(i)=i;}
    // ' PENTAEDRE LINEAIRE '
    t_HerGmsh(6).Change_taille(6);t_GmshHer(6).Change_taille(6);
    for (int i=1;i<=6;i++) {t_HerGmsh(6)(i)=i;t_GmshHer(6)(i)=i;}
    // ' PYRAMIDE LINEAIRE '
    t_HerGmsh(7).Change_taille(5);t_GmshHer(7).Change_taille(5);
    for (int i=1;i<=5;i++) {t_HerGmsh(7)(i)=i;t_GmshHer(7)(i)=i;};
    // ' POUT QUADRATIQUE '
    t_HerGmsh(8).Change_taille(3);t_GmshHer(8).Change_taille(3);
    t_HerGmsh(8)(1)=1;t_HerGmsh(8)(2)=3;t_HerGmsh(8)(3)=2;
    t_GmshHer(8)(1)=1;t_GmshHer(8)(2)=3;t_GmshHer(8)(3)=2;
    // ' TRIANGLE QUADRACOMPL '
    t_HerGmsh(9).Change_taille(6);t_GmshHer(9).Change_taille(6);
    for (int i=1;i<=6;i++) {t_HerGmsh(9)(i)=i;t_GmshHer(9)(i)=i;};
    // ' QUADRANGLE QUADRACOMPL '
    t_HerGmsh(10).Change_taille(9);t_GmshHer(10).Change_taille(9);
    for (int i=1;i<=9;i++) {t_HerGmsh(10)(i)=i;t_GmshHer(10)(i)=i;};
    // ' TETRAEDRE QUADRATIQUE '
    t_HerGmsh(11).Change_taille(10);t_GmshHer(11).Change_taille(10);
    for (int i=1;i<9;i++) {t_HerGmsh(11)(i)=i;t_GmshHer(11)(i)=i;};
    t_HerGmsh(11)(9)=10;  t_HerGmsh(11)(10)=9;
	 t_GmshHer(11)(9)=10;  t_GmshHer(11)(10)=9;
    // ' HEXAEDRE QUADRACOMPL '
    t_HerGmsh(12).Change_taille(27);t_GmshHer(12).Change_taille(27);
    for (int i=1;i<=8;i++) {t_HerGmsh(12)(i)=i;t_GmshHer(12)(i)=i;};

    t_HerGmsh(12)(9)=9;  t_HerGmsh(12)(10)=12; t_HerGmsh(12)(11)=14;
    t_HerGmsh(12)(12)=10;t_HerGmsh(12)(13)=11;t_HerGmsh(12)(14)=13;
    t_HerGmsh(12)(15)=15;t_HerGmsh(12)(16)=16;t_HerGmsh(12)(17)=17;
    t_HerGmsh(12)(18)=19;t_HerGmsh(12)(19)=20;t_HerGmsh(12)(20)=18;
    t_HerGmsh(12)(21)=21;t_HerGmsh(12)(22)=22;t_HerGmsh(12)(23)=24;
    t_HerGmsh(12)(24)=25;t_HerGmsh(12)(25)=23;t_HerGmsh(12)(26)=26;
    t_HerGmsh(12)(27)=27;
    
    t_GmshHer(12)(9)=9;  t_GmshHer(12)(10)=12; t_GmshHer(12)(11)=13;
    t_GmshHer(12)(12)=10;t_GmshHer(12)(13)=14;t_GmshHer(12)(14)=11;
    t_GmshHer(12)(15)=15;t_GmshHer(12)(16)=16;t_GmshHer(12)(17)=17;
    t_GmshHer(12)(18)=20;t_GmshHer(12)(19)=18;t_GmshHer(12)(20)=19;
    t_GmshHer(12)(21)=21;t_GmshHer(12)(22)=22;t_GmshHer(12)(23)=25;
    t_GmshHer(12)(24)=23;t_GmshHer(12)(25)=24;t_GmshHer(12)(26)=26;
    t_GmshHer(12)(27)=27;
    
    // ' PENTAEDRE QUADRACOMPL '
    t_HerGmsh(13).Change_taille(18);t_GmshHer(13).Change_taille(18);
    for (int i=1;i<=7;i++) {t_HerGmsh(13)(i)=i;t_GmshHer(13)(i)=i;};
    t_HerGmsh(13)(8)=10;t_HerGmsh(13)(9)=8;
    t_HerGmsh(13)(10)=9;t_HerGmsh(13)(11)=11;t_HerGmsh(13)(12)=12;
    t_HerGmsh(13)(13)=13;t_HerGmsh(13)(14)=15;t_HerGmsh(13)(15)=14;
    t_HerGmsh(13)(16)=16;t_HerGmsh(13)(17)=18;t_HerGmsh(13)(18)=17;
    
    t_GmshHer(13)(7)=7;t_GmshHer(13)(8)=9;t_GmshHer(13)(9)=10;
    t_GmshHer(13)(10)=8;t_GmshHer(13)(11)=11;t_GmshHer(13)(12)=12;
    t_GmshHer(13)(13)=13;t_GmshHer(13)(14)=15;t_GmshHer(13)(15)=14;
    t_GmshHer(13)(16)=16;t_GmshHer(13)(17)=18;t_GmshHer(13)(18)=17;
    // ' PYRAMIDE QUADRACOMPL '
    t_HerGmsh(14).Change_taille(14);t_GmshHer(14).Change_taille(14);
    for (int i=1;i<=14;i++) {t_HerGmsh(14)(i)=i;t_GmshHer(14)(i)=i;};
    // ' POINT LINEAIRE '
    t_HerGmsh(15).Change_taille(1);t_GmshHer(15).Change_taille(1);
    t_HerGmsh(15)(1)=1;t_GmshHer(15)(1)=1;
    // ' QUADRANGLE QUADRATIQUE '
    t_HerGmsh(16).Change_taille(8);t_GmshHer(16).Change_taille(8);
    for (int i=1;i<=8;i++) {t_HerGmsh(16)(i)=i;t_GmshHer(16)(i)=i;};
    // ' HEXAEDRE QUADRATIQUE '
    t_HerGmsh(17).Change_taille(20);t_GmshHer(17).Change_taille(20);
    for (int i=1;i<=8;i++) {t_HerGmsh(17)(i)=i;t_GmshHer(17)(i)=i;};

    t_HerGmsh(17)(9)=9;  t_HerGmsh(17)(10)=12; t_HerGmsh(17)(11)=14;
    t_HerGmsh(17)(12)=10;t_HerGmsh(17)(13)=11;t_HerGmsh(17)(14)=13;
    t_HerGmsh(17)(15)=15;t_HerGmsh(17)(16)=16;t_HerGmsh(17)(17)=17;
    t_HerGmsh(17)(18)=19;t_HerGmsh(17)(19)=20;t_HerGmsh(17)(20)=18;
    
    t_GmshHer(17)(9)=9;  t_GmshHer(17)(10)=12; t_GmshHer(17)(11)=13;
    t_GmshHer(17)(12)=10;t_GmshHer(17)(13)=14;t_GmshHer(17)(14)=11;
    t_GmshHer(17)(15)=15;t_GmshHer(17)(16)=16;t_GmshHer(17)(17)=17;
    t_GmshHer(17)(18)=20;t_GmshHer(17)(19)=18;t_GmshHer(17)(20)=19;

    // ' PENTAEDRE QUADRATIQUE '
    t_HerGmsh(18).Change_taille(15);t_GmshHer(18).Change_taille(15);
    for (int i=1;i<=7;i++) {t_HerGmsh(18)(i)=i;t_GmshHer(18)(i)=i;};
    t_HerGmsh(18)(8)=10;t_HerGmsh(18)(9)=8;t_HerGmsh(18)(10)=9;
    t_HerGmsh(18)(11)=11;t_HerGmsh(18)(12)=12;
    t_HerGmsh(18)(13)=13;t_HerGmsh(18)(14)=15;t_HerGmsh(18)(15)=14;

    t_GmshHer(18)(8)=9;t_GmshHer(18)(9)=10;
    t_GmshHer(18)(10)=8;t_GmshHer(18)(11)=11;t_GmshHer(18)(12)=12;
    t_GmshHer(18)(13)=13;t_GmshHer(18)(14)=15;t_GmshHer(18)(15)=14;
    // ' PYRAMIDE QUADRATIQUE '
    t_HerGmsh(19).Change_taille(13);t_GmshHer(19).Change_taille(13);
    for (int i=1;i<=13;i++) {t_HerGmsh(19)(i)=i;t_GmshHer(19)(i)=i;}; 

   /* string ordre,comment;
    comment = "évolution force/déplacement : "; ordre = "evolFD";
    commentaires_ordres.push_back(comment); ordre_possible.push_back(ordre);*/
   };
    
    // DESTRUCTEUR :
Visualisation_Gmsh::~Visualisation_Gmsh ()
  { // destruction de la liste d'ordre
    list <OrdreVisu*>::iterator il,ifin;
    ifin = ordre_possible.end();
    for (il=ordre_possible.begin();il!=ifin;il++)
      delete (*il);
    };

    // METHODES PUBLIQUES :
    
// affichage des différentes possibilités (ordres possibles)
// ramène un numéro qui renseigne le programme appelant
// =-1  : signifie que l'on veut stopper la visualisation
// = 0  : signifie que l'on demande la visualisation effective
int Visualisation_Gmsh::OrdresPossible()
{    // si l'on passe ici cela signifie que la visualisation Gmsh est active
     activ_sort_Gmsh= true;
     string reponse; // réponse utilisateur
     // on commence par inactiver les ordres de visualisation et de fin
     fin_o->Inactive_ordre(); visuali->Inactive_ordre();
     // on boucle
     while ( !(fin_o->Actif()) && !(visuali->Actif()))
      { 
        while ((reponse.length () == 0) || (Existe(reponse)==NULL))
        { // affichage des options possibles
          Affiche_options();
          // lecture de la commande voulu
          reponse = lect_chaine();
          OrdreVisu* ord = Existe(reponse);
          if (ord == NULL)
           { // dans le cas d'un ordre non connu
             cout << "\n ordre non connu !!, verifiez votre demande \n";
            }
          else
           // demande d'activation de l'ordre 
            ord->ChoixOrdre();
          }
       // on vide la réponse pour une autre boucle éventuelle 
       reponse ="";    
       };
     // récup de la liste actuelle de noms d'iso, qui a pu changé et mise à jour de "list_tousLesNomsASortir"
     const list <string >& nom_iso = ((Isovaleurs_Gmsh*) choix_isovaleur)->NomsGrandeurSortie();
     list <string >::const_iterator il,ilfin=nom_iso.end();
     for (il=nom_iso.begin();il != ilfin; il++)
       { // on ajoute quand le nom n'est pas déjà existant
         if (find(list_tousLesNomsASortir.begin(),list_tousLesNomsASortir.end(),(*il)) == list_tousLesNomsASortir.end())
           list_tousLesNomsASortir.push_back(*il);
       };
     // récupération de la liste des incréments à visualiser
     list_balaie = &((Increment_vrml*)choix_inc)->List_choisit();
     // def du retour
     if (fin_o->Actif())
       return -1;
     else
       return 0;
   };
   
// information de l'instance de la liste d'incrément disponible pour la visualisation
void Visualisation_Gmsh::List_increment_disponible(list <int> & list_incr) 
  { list_incre = list_incr; // stockage interne
    // puis passage à l'instance d'ordre qui gère les incréments
    ((Increment_vrml*)choix_inc)->Init_list_inc(list_incre);
    } ;

// indique le choix de la liste d'incrément à utiliser pour l'initialisation
// des fonctions d'initialisation
const list<int> &  Visualisation_Gmsh::List_balaie_init()
 {  // choix entre tous les incréments : option par défaut 
    // ou une liste plus restreinte d'incrément, utile lorsqu'il y a vraiment 
    // beaucoup d'incrément    
    bool choix_valide = false;
    string rep;
    while (!choix_valide)
      { 
        cout << "\n === choix des increments utilises pour l'initialisation de la visualisation ===="
             << "\n option par defaut : tous les increments             (rep 1)"
             << "\n choix d'un nombre plus petit d'increment             (rep 2)";
        cout << "\n reponse ? "; rep = lect_return_defaut(true,"1");cout << "\n";
        if ((rep == "1") || (rep == "2"))
          // cas d'un choix valide
          choix_valide = true;
        else
          cout << "\n la reponse : " << rep << " n'est pas utilisable, recommencez !";         
       }
    // exécution   
    if (rep == "1")
      // cas de tous les incréments
      return list_incre;
    else if (rep == "2")
      // cas d'un choix d'incrément, appel du choix d'incrément
      { ((Increment_vrml*)choix_inc)->ChoixOrdre();
        return (((Increment_vrml*)choix_inc)->List_choisit());                    
       }
    // pour éviter un warning, car normalement on ne passe jamais ici
    return list_incre;
  }; 

// impose une liste d'incrément à utiliser 
void  Visualisation_Gmsh::List_balaie_init(const list<int> & )
//void  Visualisation_Gmsh::List_balaie_init(const list<int> & list_init)
  {  ((Increment_vrml*)choix_inc)->Impos_list(list_incre);
     // récupération de la liste des incréments à visualiser
     list_balaie = &((Increment_vrml*)choix_inc)->List_choisit();     
   };  

// information de l'instance du nombre de maillages disponibles pour la visualisation
// par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
void Visualisation_Gmsh::List_maillage_disponible(int nombre_maillage_dispo) 
   { nb_maillage_dispo = nombre_maillage_dispo;
     // on défini la liste de tous les maillages par défaut
     ((ChoixDesMaillages_vrml*)choix_mail)->Init_nb_maill(nb_maillage_dispo);
    };
    
// initialisation des ordres disponibles 
// par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles et les extrémas
void Visualisation_Gmsh::Initialisation(ParaGlob * paraGlob,LesMaillages * lesMaillages
                       ,LesReferences* lesReferences
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats,OrdreVisu::EnumTypeIncre type_incre,int incre
                       ,const map < string, const double * , std::less <string> >& listeVarGlob
                       ,const List_io < TypeQuelconque >& listeVecGlob
                       ,bool fil_calcul)
{      
   // on passe en revue l'ensemble des ordres possibles
   list <OrdreVisu*>::iterator s_or,s_or_fin;
   s_or_fin = ordre_possible.end();
   for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
        (*s_or)->Initialisation(paraGlob,lesMaillages,lesReferences
                      ,lesLoisDeComp ,diversStockage
                      ,charge,lesCondLim,lesContacts,resultats,type_incre,incre
                      ,listeVarGlob,listeVecGlob
                      ,fil_calcul);
   if (!fil_calcul)
    {
     // construction de la liste de tous les noms de grandeurs à sortir
     //   les noms des isovaleurs
     list_tousLesNomsASortir = ((Isovaleurs_Gmsh*) choix_isovaleur)->NomsGrandeurSortie();
     //    le nom du déplacement
     list_tousLesNomsASortir.push_back(((Deformees_Gmsh*) ptdeformee)->Nom_deplace());
     // cas de la vitesse éventuelle et accélération
     const string * nom_vitesse = (((Deformees_Gmsh*) ptdeformee)->Nom_Vitesse());
     if (nom_vitesse != NULL) list_tousLesNomsASortir.push_back(*nom_vitesse);
     const string * nom_acceleration = (((Deformees_Gmsh*) ptdeformee)->Nom_Acceleration());
     if (nom_acceleration != NULL) list_tousLesNomsASortir.push_back(*nom_acceleration);
     
     //  éventuellement les noms des références
     // dans le cas où le tableau récupéré est vide cela signifie que les ref seront dans le fichier principal
     const Tableau <string>* tabref = ((Mail_initiale_Gmsh*) mailInit)->NomsGrandeurSortie();
     if (tabref != NULL)
      {int taill = tabref->Taille();
       for (int i=1;i<=taill;i++)
         list_tousLesNomsASortir.push_back((*tabref)(i));
      };
    };
 
};

// méthode principale pour activer la visualisation
void Visualisation_Gmsh::Visu(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats,OrdreVisu::EnumTypeIncre type_incre,int incre
                       ,const map < string, const double * , std::less <string> >& listeVarGlob
                       ,const List_io < TypeQuelconque >& listeVecGlob)
   
{  // récup de la liste de maillage
   const list <int>& li_mail =  ((ChoixDesMaillages_vrml*)choix_mail)->List_choisit(); 
   list <int>::const_iterator ik,ikfin;
   ikfin = li_mail.end();
   // on définit un tableau des maillages à sortir, plus pratique pour les itérations
   // dans les routines internes (et plus rapide)
   Tableau <int> tab_mail(li_mail.size()); int iidd = 1;
   for (ik= li_mail.begin();ik!=ikfin;ik++,iidd++) tab_mail(iidd)=*ik;
   
   // initialisation de l'animation : ce paramètre n'est pas utilisé pour la sortie Gmsh
   //  on le met par défaut à false
   animation = false;
   
   // ici on passe en revue l'ensemble des ordres possibles
   list <OrdreVisu*>::iterator s_or,s_or_fin;
   s_or_fin = ordre_possible.end();
   // s'il n'y a qu'un seul incrément à visualisé on le signale
   bool unseul_incre = true; if (list_balaie->size() > 1) unseul_incre = false;
   for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
       { (*s_or)->ExeOrdre(paraGlob,tab_mail,lesMaillages,unseul_incre,lesReferences
                      ,lesLoisDeComp ,diversStockage
                      ,charge,lesCondLim,lesContacts,resultats,*entreePrinc
                      ,type_incre,incre,animation,listeVarGlob,listeVecGlob);
         };
   // on vide le buffer
   entreePrinc->Sort_initial_Gmsh() << endl;
   entreePrinc->Sort_initial_Gmsh() << flush;
   // idem pour les sorties de résultats
   const list <string>& list_nom = entreePrinc->Noms_base_fichiers_gmsh();
   list <string>::const_iterator ip,ipfin = list_nom.end();
   for (ip = list_nom.begin(); ip != ipfin; ip++)
    {entreePrinc->Sort_resultat_Gmsh(*ip) << endl << flush;}
};

                       
// == définition des paramètres de visualisation 
// titre, navigation, éclairage
// et initialisation des paramètres de la classe
void Visualisation_Gmsh::Contexte_debut_visualisation()
  {// ==== tout d'abord le maillage initial
   ostream &sort = entreePrinc->Sort_initial_Gmsh();
	  bool mail_initial_use_hold_gmsh_format // récup du format
	   = ((Isovaleurs_Gmsh*) choix_isovaleur)->Use_hold_gmsh_format();
   // le l'entité format : ça doit être la première information du fichier
   sort << "$MeshFormat ";
	  if (mail_initial_use_hold_gmsh_format)
      {sort << "\n2.0 0 8 ";}  // format 2.0 , puis 0 -> ascii, puis 8 -> sizeof(double)
	  else // cas du nouveau format
      {sort << "\n2.2 0 8 ";};  // format 2.0 , puis 0 -> ascii, puis 8 -> sizeof(double)
   sort << "\n$EndMeshFormat \n ";
   // écriture de l'entête commentaire
   sort << "\n // --------------------------------------------------------"
        << "\n //     format  fichier Gmsh (maillage initial)             "
        << "\n // --------------------------------------------------------"
        << "\n // ";
   // le titre
   sort << "\n // "
        << "\n //  Visualisation elements finis : Herezh++ V" << ParaGlob::NbVersion()
        << "\n // "
        << "\n // ";
   sort << Banniere::CopiPirate() << " \n";
   
   // ==== puis pour les résultats
   //
   // récupération de la liste des noms des différentes grandeurs à sortir en résultat
   list <string>::iterator ili,ilifin = list_tousLesNomsASortir.end();
   for (ili=list_tousLesNomsASortir.begin();ili != ilifin; ili++)
   	{ ostream &sart = entreePrinc->Sort_resultat_Gmsh((*ili));
		    bool mail_initial_use_hold_gmsh_format // récup du format
	             = ((Isovaleurs_Gmsh*) choix_isovaleur)->Use_hold_gmsh_format();
		    // le l'entité format : ça doit être la première information du fichier
	     if (!mail_initial_use_hold_gmsh_format) // cas du nouveau format
          {sart << "$MeshFormat ";
		     sart << "\n2.2 0 8 ";  // format 2.0 , puis 0 -> ascii, puis 8 -> sizeof(double)
           sart << "\n$EndMeshFormat \n ";
		    };
      // écriture de l'entête
      sart << "// Gmsh Post Results File pour la version > 2.0 \n";
      sart << "\n // -------------------------------------------------"
           << "\n //     format  fichier Gmsh  (resultats)            "
           << "\n // -------------------------------------------------"
           << "\n // ";
      // le titre
      sart << "\n // "
           << "\n //  Visualisation elements finis : Herezh++ V" << ParaGlob::NbVersion()
           << "\n // "
           << "\n // grandeur visualisee: "<< (*ili)
           << "\n // ";
      sart << Banniere::CopiPirate() << " \n";
   	};
   // === puis initialisation
   animation = false; 
      
  };
    
// (points de vue) et enchainement si nécessaire
void Visualisation_Gmsh::Contexte_fin_visualisation()
  {// définition des points de vue avec l'angle adoc
   };                  
    
// lecture des paramètres de l'ordre dans un flux
void Visualisation_Gmsh::Lecture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // si dans le flot il existe l'identificateur adoc on lit sinon on passe
   if (strstr(entreePrinc.tablcarCVisu,"debut_visualisation_Gmsh")!=NULL)
     {// essaie de lecture
      try 
        { string nom; 
          (*entreePrinc.entCVisu)  >> nom ;
          if (nom != "debut_visualisation_Gmsh")
            { cout << "\n Erreur en lecture de la visualisation Gmsh a partir d'un fichier .CVisu,"
                   << " le premier enregistrement doit etre le mot clef: debut_visualisation_Gmsh "
                   << " la visualisation Gmsh n'est pas validee !! ";
              }
          else
           { // on valide la visualisation
             activ_sort_Gmsh=true;
             entreePrinc.NouvelleDonneeCVisu();
             // on passe en revue tous les ordres disponibles
             list <OrdreVisu*>::iterator s_or,s_or_fin;
             while (strstr(entreePrinc.tablcarCVisu,"fin_visualisation_Gmsh")==NULL)
               { s_or_fin = ordre_possible.end();
                 for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
                   (*s_or)->Lecture_parametres_OrdreVisu(entreePrinc);
                 }  
            }       
         }    
      catch (ErrSortieFinale)
           // cas d'une direction voulue vers la sortie
           // on relance l'interuption pour le niveau supérieur
         { ErrSortieFinale toto;
           throw (toto);
         }
      catch (...)// erreur de lecture
       {  cout << "\n Erreur en lecture de la visualisation Gmsh a partir d'un fichier .CVisu,"
               << " la visualisation Gmsh n'est pas validee !! ";
          activ_sort_Gmsh=false;
          if (ParaGlob::NiveauImpression() >= 4)     
             cout  << "\n Visualisation::Lecture_parametres_OrdreVisu(..";
        }
      // on passe à un nouvel enregistrement
      entreePrinc.NouvelleDonneeCVisu();
      }  
   // construction de la liste de tous les noms de grandeurs à sortir
   //   les noms des isovaleurs
   list_tousLesNomsASortir = ((Isovaleurs_Gmsh*) choix_isovaleur)->NomsGrandeurSortie();
   //    le nom du déplacement
   list_tousLesNomsASortir.push_back(((Deformees_Gmsh*) ptdeformee)->Nom_deplace());                   
   // cas de la vitesse éventuelle et accélération
   const string * nom_vitesse = (((Deformees_Gmsh*) ptdeformee)->Nom_Vitesse());
   if (nom_vitesse != NULL) list_tousLesNomsASortir.push_back(*nom_vitesse);
   const string * nom_acceleration = (((Deformees_Gmsh*) ptdeformee)->Nom_Acceleration());
   if (nom_acceleration != NULL) list_tousLesNomsASortir.push_back(*nom_acceleration);
   //  éventuellement les noms des références
   // dans le cas où le tableau récupéré est vide cela signifie que les ref seront dans le fichier principal
   const Tableau <string>* tabref = ((Mail_initiale_Gmsh*) mailInit)->NomsGrandeurSortie();
   if (tabref != NULL)
    {int taill = tabref->Taille();
     for (int i=1;i<=taill;i++)
       list_tousLesNomsASortir.push_back((*tabref)(i));
    };
  };

// écriture des paramètres de l'ordre dans un flux
void Visualisation_Gmsh::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // récup du flot  
   ostream & sort = (*(entreePrinc.Sort_CommandeVisu()));
   // on s'occupe des ordres spécifiques à la visualisation Gmsh
   // il n'y a écriture que si la visualisation Gmsh est active
   if(activ_sort_Gmsh) 
    {// tout d'abord l'activation du type Gmsh    
     // on commente le fonctionnement
     sort << "\n #  =================================================================================";
     sort << "\n #  ||       *****         demande d'une visualisation Gmsh:       *****            || "
          << "\n #  ================================================================================="
          << "\n #  un mot cle de debut (debut_visualisation_Gmsh)"
          << "\n #  un mot cle de fin ( fin_visualisation_Gmsh) apres tous les ordres particuliers"
          << "\n #  la seule presence du premier mots cle suffit a activer la visualisation Gmsh"
          << "\n #  la presence du second permet une meilleur lisibilite du fichier, mais n'est pas indispensable" ;
     // on sort les mots clés d'activation du type Gmsh
     sort << "\n debut_visualisation_Gmsh \n" ;
     // on passe en revue tous les ordres disponibles
     list <OrdreVisu*>::iterator s_or,s_or_fin;
     s_or_fin = ordre_possible.end();
     for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
           (*s_or)->Ecriture_parametres_OrdreVisu(entreePrinc);
     // fin de l'activation Gmsh      
     sort << "\n fin_visualisation_Gmsh"
          << "\n #  ================================================================================="
          << "\n #  ||                          fin de la  visualisation Gmsh                       || "
          << "\n #  ================================================================================= \n \n";
     }
  };
      
//============================== méthodes privées =====================

     
    // test si la réponse fait partie des ordres possibles
    // si l'on trouve un ordre ok on ramène un pointeur sur l'ordre
    // sinon on ramène un pointeur null
    OrdreVisu* Visualisation_Gmsh::Existe(string& reponse)
     { // on passe en revue la liste d'ordre
       list <OrdreVisu*>::iterator s_or,s_or_fin;
       s_or_fin = ordre_possible.end();
       for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
          if ((*s_or)->OrdreVrai(reponse))
               return (*s_or); // cas d'un ordre correcte
       return NULL; // pas d'ordre correcte trouvé
       };
     
      
    // affichage des options possibles
    void  Visualisation_Gmsh::Affiche_options()
     { // écriture d'une ligne de transition
       cout << setw(60) << setfill('-') << "\n " << setfill(' ');
       list <OrdreVisu*>::iterator s_or,s_or_fin;
       s_or_fin = ordre_possible.end();
       for (s_or = ordre_possible.begin();s_or != s_or_fin; s_or++)
           (*s_or)->Affiche_ordre();
       cout << "\n reponse ? ";      
     };

