
// 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 "Deformees_vrml.h"
#include "CharUtil.h"

#include <iomanip>
#include <limits>

    // CONSTRUCTEURS :
// par defaut
Deformees_vrml::Deformees_vrml () :
   OrdreVisu("..........................................deformee"
             ,"visualisation des deformee","de")
   ,filaire(true),surface(true),numero(false)
   ,Rcoull(0.0),Gcoull(1.0),Bcoull(1.0)
   ,Rcoulf(1.0),Gcoulf(1.0),Bcoulf(0.0)
   ,Rcouln(1.0),Gcouln(0.0),Bcouln(0.0)
   ,amplification(1.)
   ,isovaleurs_vrml(NULL)
   ,tab_facette(),tab_arrete(),num_mail_incr()
   ,noms_matiere(),choix_mail(NULL)
   ,noms_couleurs()
     {}; 
     
     // constructeur de copie 
Deformees_vrml::Deformees_vrml (const Deformees_vrml& ord) :
    OrdreVisu(ord),filaire(ord.filaire) 
   ,surface(ord.surface),numero(ord.numero)
   ,Rcoull(ord.Rcoull),Gcoull(ord.Gcoull),Bcoull(ord.Bcoull)
   ,Rcoulf(ord.Rcoulf),Gcoulf(ord.Gcoulf),Bcoulf(ord.Bcoulf)
   ,Rcouln(ord.Rcouln),Gcouln(ord.Gcouln),Bcouln(ord.Bcouln)
   ,amplification(ord.amplification)
   ,isovaleurs_vrml(ord.isovaleurs_vrml)
   ,tab_facette(ord.tab_facette),tab_arrete(ord.tab_arrete)
   ,num_mail_incr(ord.num_mail_incr)
   ,noms_matiere(),choix_mail(ord.choix_mail)
   ,noms_couleurs(ord.noms_couleurs)
      {};
               
    // DESTRUCTEUR :
Deformees_vrml::~Deformees_vrml () 
     {};  
    
    // METHODES PUBLIQUES :
// execution de l'ordre
// tab_mail : donne les numéros de maillage concerné
// incre : numéro d'incrément qui en cours
// type_incre : indique si c'est le premier le dernier ou l'incrément courant a visualiser ou pas
// animation : indique si l'on est en animation ou pas
// unseul_incre : indique si oui ou non il y a un seul increment à visualiser
void Deformees_vrml::ExeOrdre(ParaGlob * paraGlob,const Tableau <int>& tab_mail,LesMaillages * lesMail,bool,LesReferences*
                      ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*
                      ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre type_incre,int incre
                      ,bool animation,const map < string, const double * , std::less <string> >&
                      ,const List_io < TypeQuelconque >& listeVecGlob)
 {// visualisation du maillage pointé si actif
  if (actif)
  {ostream &sort = entreePrinc.Sort_princ_vrml();
   // on boucle sur les maillages
   int nbmail = tab_mail.Taille();
   for (int im=1;im<=nbmail;im++)
    { int numMail=tab_mail(im);
      static string nom_premier_coordinate; // pour le passage d'info au dernier incrément
      // dans le cas du premier incrément on initialise les conteneurs de grandeurs transitoire
      // les facettes ne seront dessinées qu'aux derniers passages dans le cas des isovaleurs
      // sinon on dessine à mesure
      if (type_incre==PREMIER_INCRE)
         { // au premier increment on commence par ré-initialiser les conteneurs
           tab_facette.erase(tab_facette.begin(),tab_facette.end());
           tab_arrete.erase(tab_arrete.begin(),tab_arrete.end());
           num_mail_incr.erase(num_mail_incr.begin(),num_mail_incr.end());
           nom_premier_coordinate = "";
          }
      // on commence par définir la liste des points 
      // def de l'entité forme
      sort << "\n Shape { "
      << "\n  appearance Appearance {}";
      // création des points
      // tout d'abord le nom
      ostrstream tab_out;
      tab_out << "Coordinates" << incre << numMail << ends;
      string nom_coordinate = tab_out.str() ;  // le nom
      // on utilise une géométrie de face indexée bien qu'aucune face soit définit 
      sort << "\n  geometry IndexedFaceSet {"
           << "\n     coord DEF " << nom_coordinate <<  " Coordinate {"
           << "\n                   point [ ";
           
      // on balaie tous les noeuds du maillage
      int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
      list <Coordonnee > listcoor; // une liste intermédiaire
      for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
               { // recup du noeud
                 Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
                 // deux cas : si l'incrément est 0 et les autres
                 if (incre == 0)
                  { //pas d'amplification
                    sort <<"\n                        "
                      << setw (16);  noe.Coord0().Affiche(sort,16);
                    // sauvegarde des coordonnées dans la liste
                    listcoor.push_back(noe.Coord0());
                   }
                 else // calcul d'un déplacement amplifié  
                  { // calcul du déplacement amplifié
                    Coordonnee dep(paraGlob->Dimension()); // init à zero par defaut
                    if (noe.ExisteCoord1()) {dep = (noe.Coord1() - noe.Coord0() ) * amplification;};
                    // ecriture des coordonnee avec le déplacement amplifié
                    Coordonnee posifin = (noe.Coord0() + dep);
                    sort <<"\n                        "
                      << setw (16);  posifin.Affiche(sort,16);
                    // sauvegarde des coordonnées dans la liste
                    listcoor.push_back(posifin);
                    }   
                 // si l'on n'est pas en dimension 3 on complete avec des zeros
                 if (paraGlob->Dimension () == 2)
                   { sort << setw (16) << 0 <<" ";
                    }
                 else if (paraGlob->Dimension () == 1)
                    { sort << setw (16) << 0  <<" " << setw (16) << 0  <<" ";
                    }
                 sort <<  " , ";
                 }
      // fermeture du groupe point, coordinate, de la géométrie et de la forme
      sort << "\n                     ] } } }";
      // on ajoute le nom des coordonnées créés dans la liste de gestion
      list_nom_coordinate.push_back(nom_coordinate); 
      list_coordinate.push_back(listcoor);  
      
      //---------------------------------------------------------------------------------
      // dans le cas où il n'y a pas d'isovaleur on ecrit tout de suite le fichier vrml
      //---------------------------------------------------------------------------------
     if ( !(isovaleurs_vrml->Actif()) )
      {if(surface && ((animation && (type_incre==PREMIER_INCRE))||(!animation)))
        // cas d'une visualisation par face
       { 
         // def de l'entité forme 
         sort << "\n Shape { "
           << "\n   appearance Appearance {}";
         // def de la géométrie
         sort << "\n     geometry IndexedFaceSet {"
         // utilisation des points déjà défini
              << "\n     coord USE Coordinates" << incre << numMail;
          // définition de la couleur
          sort << "\n                 color Color {"
               << "\n                     color ["
               << "\n                       " 
               << Rcoulf << " " << Gcoulf << " " << Bcoulf<< " ,"
               << "\n                     ]"
               << "\n                 }";
          // def des facettes
          sort << "\n                 coordIndex [";
          // un compteur qui globalise le nombre de facette dessinée
          int nbfacette=0;     
             // on balaie tous les éléments du maillage
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // ses noeuds
             // connection des noeuds des faces par rapport a ceux de l'element
             // en fait on utilise une décomposition triangulaire linéaire de chaque facette
             // on récupère donc tout d'abord ces informations
                // le tableau des triangles linéaire
             const Tableau<Tableau<Tableau<int> > >&  
                        tabtria = elem.ElementGeometrique().Trian_lin();
             // le nombre de face à visualiser           
             int nb_FA = tabtria.Taille();
             for (int k=1;k<= nb_FA;k++)
              { sort << "\n                    "; //début de la face
                // nombre de triangle de la face
                int nbtriangle = tabtria(k).Taille();
                for (int ikt=1;ikt<=nbtriangle;ikt++,nbfacette++)
                 { //const Tableau<int> * tabn = &(tabtria(k)(ikt)); // pour simplifier
                   #ifdef MISE_AU_POINT
                   // vérification du nombre de noeud du triangle
                    if (tabtria(k)(ikt).Taille() != 3)
                      { cout << "\n erreur, les facettes n'ont pas 3 noeuds,"
                             << " nbnoeud = " << tabtria(k)(ikt).Taille()
                             << " \n Deformees_vrml::ExeOrdre(... " ;
                        Sortie(1);     
                       }
                   #endif
                   for (int no = 1; no<=3; no++)
                       sort << (tab_noeud(tabtria(k)(ikt)(no))->Num_noeud() - 1) << ", "; 
                   sort << "-1, "; 
                  }
                }
              }
          // fin pour les faces et activation de la couleur
          sort << "\n                ]";
          sort << "\n               colorIndex [ ";
          // le tableau des couleurs ici identique
          int ic; // un compteur inter pour qu'il y ait plusieurs numéros sur la même ligne
          int icmax = 10; int nf;
          for (nf=1,ic=1; nf< nbfacette;nf++,ic++) 
             { sort << " 0,"; 
               if (ic >= icmax) { ic = 1; sort << "\n";} // pour limiter la ligne
               }
          sort << " 0 ]"; // la dernière couleur
          // on signale que l'on veut voir que l'extérieur
          sort << "\n                solid TRUE";
          // ON signal que l'on tourne dans le sens positif géométrique
          sort << "\n                ccw TRUE";
          // et que les faces sont convexes
          sort << "\n                convex TRUE";
          // que l'on utilise une couleur par face
          sort << "\n       colorPerVertex FALSE";
          sort << "\n            }";
          // fin: on ferme l'entité forme
          sort << "\n         }";
         } //--- fin du cas ou c'est le premier incrément sans isovaleur pour des facettes
         
      if (filaire && ((animation && (type_incre==PREMIER_INCRE))||(!animation)))
       { 
         // def de l'entité forme
         sort << "\n Shape { "
           << "\n   appearance Appearance {}";
         // définition de la géométrie
         sort << "\n    geometry IndexedLineSet {"
         // utilisation des points déjà défini
              << "\n    coord USE " <<nom_coordinate;
          // définition de la couleur
          sort << "\n                 color Color {"
               << "\n                     color ["
               << "\n                       " 
               << Rcoull << " " << Gcoull << " " << Bcoull<< " ,"
               << "\n                     ]"
               << "\n                 }";
          // def des arrêtes
          sort << "\n                 coordIndex [";
          // def d'un compteur du nombre d'arrete dessiné
          int nbarr = 0;
             // on balaie tous les éléments du maillage
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // ses noeuds
             // connection des noeuds des arêtes par rapport a ceux de l'element
             Tableau<Tableau<int> > const & nomS =  elem.ElementGeometrique().NonS();
             int nb_ar = nomS.Taille(); // nombre d'arrêtes
             for (int k=1;k<= nb_ar;k++,nbarr++)
              { sort << "\n                    "; //début de l'arrête 
                Tableau<int>const & tabn = nomS(k); 
                int nb_no = tabn.Taille(); // le nb de noeud de l'arrête
                for (int no = 1; no<=nb_no; no++)
                  sort << (tab_noeud(tabn(no))->Num_noeud() - 1) << ", "; 
                sort << " -1,"; 
                }
              }
          // fin pour les arrêtes et activation de la couleur
          sort << "\n                ]";
          sort << "\n               colorIndex [ ";
           // le tableau des couleurs ici identique
          int ic; // un compteur inter pour qu'il y ait plusieurs numéros sur la même ligne
          int na; int icmax = 10;
          for (na=1,ic=1; na< nbarr;na++,ic++) 
             { sort << " 0,"; 
               if (ic >= icmax) { ic = 1; sort << "\n";} // pour limiter la ligne
               }
          sort << " 0 ]"; // la dernière couleur
          sort << "\n                colorPerVertex FALSE";
          sort << "\n            }";
          // fin: on ferme l'entité forme
          sort << "\n         }";
         }                         
      if (numero && ((animation && (type_incre==PREMIER_INCRE))||(!animation))) // cas d'une des numéros
       { 
         // on balaie tous les noeuds du maillage
         int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
         for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
               { // recup du noeud
                 Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
                 // définition de l'entité billboard qui permet que les numéros restent faces
                 // à l'utilisateur
     //            sort << "\n Billboard { axisOfRotation 0.0 0.0 0.0       children [ ";
                 // on définit un ensemble de déplacement qui permet de ce positionner
                 // aux coordonnées des noeuds 
                 sort << "\n        Transform {  #           X   Y   Z ";
                 // calcul du déplacement amplifié
                 Coordonnee dep(paraGlob->Dimension()); // init à zero par defaut
                 if (noe.ExisteCoord1()) {dep = (noe.Coord1() - noe.Coord0() ) * amplification;};
                 // ecriture des coordonnee avec le déplacement amplifié
                 sort <<"\n              translation "
                      << setw (16);  (noe.Coord0() + dep).Affiche(sort,16);
                 // si l'on n'est pas en dimension 3 on complete avec des zeros
                 if (paraGlob->Dimension () == 2)
                   { sort << setw (16) << 0 <<" ";
                    }
                 else if (paraGlob->Dimension () == 1)
                    { sort << setw (16) << 0  <<" " << setw (16) << 0  <<" ";
                    }
                 // on définit le numéro
                  sort   << "\n                children [";
                 // def de l'entité forme
                 sort << "\n          Shape { "
                   << "\n                appearance Appearance {"
                   << "\n                  material Material { }"
                   << "\n                             }";
                 // le numéro 
                 sort << "\n             geometry Text {"
                      << "\n             string \"" << numNoeud <<"\""
                      << "\n               fontStyle FontStyle {size 0.2} "
                      << "\n                 }} ] }";
                 // on ferme le billboard  et la forme générale       
        //         sort << "\n             ]}";        
                 }
         }
       }
      //---------------------------------------------------------------------------------
      // dans le cas où on a des isovaleurs on sauvegarde les informations pour ne les 
      // traiter qu'au dernier incrément
      //---------------------------------------------------------------------------------
      else
       {if (type_incre==PREMIER_INCRE)
           // sauvegarde pour une utilisation au dernier incrément
           nom_premier_coordinate=nom_coordinate;
        if(surface && ((animation && (type_incre==PREMIER_INCRE))||(!animation)))
          // cas d'une visualisation par face
         {// on balaie tous les éléments du maillage       
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          Tableau <int> tab3(3); // tableau de travail
          for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // ses noeuds
             // connection des noeuds des faces par rapport a ceux de l'element
             // en fait on utilise une décomposition triangulaire linéaire de chaque facette
             // on récupère donc tout d'abord ces informations
                // le tableau des triangles linéaire
             const Tableau<Tableau<Tableau<int> > >&  
                        tabtria = elem.ElementGeometrique().Trian_lin();
             // le nombre de face à visualiser           
             int nb_FA = tabtria.Taille();
             for (int k=1;k<= nb_FA;k++)
              { // nombre de triangle de la face
                int nbtriangle = tabtria(k).Taille();
                for (int ikt=1;ikt<=nbtriangle;ikt++)
                 { //const Tableau<int> * tabn = &(tabtria(k)(ikt)); // pour simplifier
                   #ifdef MISE_AU_POINT
                   // vérification du nombre de noeud du triangle
                    if (tabtria(k)(ikt).Taille() != 3)
                      { cout << "\n erreur, les facettes n'ont pas 3 noeuds,"
                             << " nbnoeud = " << tabtria(k)(ikt).Taille()
                             << " \n Deformees_vrml::ExeOrdre(... " ;
                        Sortie(1);     
                       }
                   #endif
                   for (int no = 1; no<=3; no++)
                       tab3(no) = (tab_noeud(tabtria(k)(ikt)(no))->Num_noeud() - 1) ; 
                   tab_facette.push_back(tab3);    
                  }
                }
              }
         } //--- fin du cas pour l'enregistrement des  facettes avec isovaleurs
         
      if (filaire && (  (animation && (type_incre==PREMIER_INCRE))  ||  (!animation)))
       {  // on balaie tous les éléments du maillage
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          Tableau <int> tab2(3); // tableau de travail
          for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // ses noeuds
             // connection des noeuds des arêtes par rapport a ceux de l'element
             Tableau<Tableau<int> > const & nomS =  elem.ElementGeometrique().NonS();
             int nb_ar = nomS.Taille(); // nombre d'arrêtes
             for (int k=1;k<= nb_ar;k++)
              { Tableau<int>const & tabn = nomS(k); 
                int nb_no = tabn.Taille(); // le nb de noeud de l'arrête
                for (int no = 1; no<=nb_no; no++)
                  tab2(no) = (tab_noeud(tabn(no))->Num_noeud() - 1) ; 
                tab_arrete.push_back(tab2);
                }
              }
         } //--- fin du cas pour l'enregistrement des  arretes avec isovaleurs                         
       
       }
   
      //---------------------------------------------------------------------------------
      // cas du dernier incrément 
      
      // définir les noms des matières :noms_matiere
      
      //---------------------------------------------------------------------------------
      // cas du dernier incrément ou du premier sans animation, se qui signifie que c'est également le dernier
      if ((type_incre==DERNIER_INCRE)||( (type_incre==PREMIER_INCRE) && (!animation) ))
       {// cas des isovaleurs actives
        if (isovaleurs_vrml->Actif())
         {// récup du nombre de maillage qui sont visualisé
          const list <int> & lis_mail_choisit = choix_mail->List_choisit();
          int nb_maillage= lis_mail_choisit.size();
          // récup du nombre de pas 
          int nb_step = (int) (list_nom_coordinate.size()/nb_maillage);
          // variables de travail
          list <string>::iterator inom=list_nom_coordinate.begin();
          //on boucle sur tous les incréments et sur les maillages choisit
          for (int ist=1; ist<= nb_step; ist++) for (int im=1;im<=nb_maillage;im++,inom++)
          {// def du nom de la matière
           ostrstream tab_mat;
           tab_mat << "matiere" << ist << im << ends;
           string nom_matiere = tab_mat.str() ;  // le nom
           noms_matiere.push_back(nom_matiere);
           // def du nom des couleurs
           ostrstream tab_co;
           tab_co << "couleur" << ist << im << ends;
           string nom_des_couleurs = tab_co.str() ;  // le nom
           noms_couleurs.push_back(nom_des_couleurs);
           if(surface)  // cas d'une visualisation par face
           {  // def de l'entité forme 
              sort << "\n Shape { "
                   << "\n   appearance Appearance {"
                   << "\n          material DEF "<<nom_matiere<<" Material {"
                   << "\n                                     transparency  ";
              if (ist==1) sort << 0.; else sort << 1.;
              sort << "\n                                           }"
                   << "\n                          } "; 
              // def de la géométrie
              sort << "\n     geometry IndexedFaceSet {"
              // utilisation des points déjà défini
                   << "\n     coord USE " << (*inom);
             // def des facettes
             sort << "\n                 coordIndex [";
             list < Tableau < int > >::iterator it,itfin=tab_facette.end();
             // on balaie tous les éléments de la liste
             for (it=tab_facette.begin();it!=itfin;it++)
              { for(int j=1;j<=3;j++)
                   sort << (*it)(j) << ", "; 
                 sort << "-1, ";
               }
             sort << "\n                 ] # fin de coordIndex pour les faces ";
             // fin pour les faces 
             // définition de la couleur
             // récupération des couleurs initiales
             const list < Tableau < Rgb > > & list_couleur=isovaleurs_vrml->List_couleur();
             list < Tableau < Rgb > >::const_iterator icoul_deb=list_couleur.begin();
             const Tableau < Rgb > & tab_coul = (*icoul_deb);
             int taille_tab_coul= tab_coul.Taille();
             // NB: nom_base_couleur est définie dans OrdreVisu (classe mere)
             sort << "\n                 color DEF " << nom_des_couleurs << " Color {"
                  << "\n                     color [";
             for (int i=1;i<= taille_tab_coul;i++)
                sort << "\n                       " 
                     <<tab_coul(i) << " ,";
             sort << "\n                     ]"
                  << "\n                 }";
             // on signale que l'on veut voir que l'extérieur
             sort << "\n                solid TRUE";
             // ON signal que l'on tourne dans le sens positif géométrique
             sort << "\n                ccw TRUE";
             // et que les faces sont convexes
             sort << "\n                convex TRUE";
             // que l'on utilise une couleur par noeud (vertex)
             sort << "\n       colorPerVertex TRUE";
             sort << "\n            }";
             // fin: on ferme l'entité forme
             sort << "\n         }";
            } //--- fin cas  des facettes
         
          if (filaire) // cas des arrêtes 
            {// def de l'entité forme
              sort << "\n Shape { "
                   << "\n   appearance Appearance {";
              if (surface)     
                 sort  << "\n          material USE "<<nom_matiere ;
              else
                {sort  << "\n          material DEF "<<nom_matiere<<" Material {"
                       << "\n                                     transparency  ";
                 if (ist==1) sort << 0.; else sort << 1.;
                 sort << "\n                                           }";
                 }
             sort << "\n                          } "; 
             // définition de la géométrie
             sort << "\n    geometry IndexedLineSet {"
             // utilisation des points déjà défini
                  << "\n    coord USE " << (*inom);
             // def des arrêtes
             sort << "\n                 coordIndex [";
             list < Tableau < int > >::iterator it,itfin=tab_arrete.end();
             // on balaie tous les éléments de la liste
             for (it=tab_arrete.begin();it!=itfin;it++)
              { for(int j=1;j<=2;j++)
                    sort << (*it)(j) << ", "; 
                 sort << "-1, ";
               }
             sort << "\n                 ] # fin de coordIndex pour les arretes ";
             // fin pour les arretes 
             // définition de la couleur
             // récupération des couleurs initiales
             const list < Tableau < Rgb > > & list_couleur=isovaleurs_vrml->List_couleur();
             list < Tableau < Rgb > >::const_iterator icoul_deb=list_couleur.begin();
             const Tableau < Rgb > & tab_coul = (*icoul_deb);
             int taille_tab_coul= tab_coul.Taille();
             // si les facettes sont déjà défini on réutilise leur couleurs sinon on la recré


                if (surface)
              { sort << "\n                 color USE " << nom_des_couleurs << " ";
               }
             else  
              { sort << "\n                 color DEF " << nom_des_couleurs << " Color {"
                     << "\n                     color [";
                for (int i=1;i<= taille_tab_coul;i++)
                  sort << "\n                       " 
                       <<tab_coul(i) << " ,";
                sort << "\n                     ]"
                     << "\n                 } # fin de la definition des couleurs";
               }      
             sort << "\n                colorPerVertex TRUE";
             sort << "\n            }";
             // fin: on ferme l'entité forme
             sort << "\n         }";
           } // -- fin cas des arretes
          } // -- fin boucle sur les incréments                         
         } //-- fin cas isovaleurs actives avec le dernier incrément
       } // -- fin cas du dernier incrément
    }; //-- fin de la boucle sur les maillages
    // et on vide le buffer de sortie
    sort << endl; 
  }; // fin du cas actif ou pas

 };

// choix de l'ordre, cet méthode peut entraîner la demande d'informations
// supplémentaires si nécessaire. qui sont ensuite gérer par la classe elle même
void Deformees_vrml::ChoixOrdre()
   { // demande de précision
     bool choix_valide = false;
     cout << "\n ----> preparation de la visualisation des deformees"
          << "\n  parametre par defaut ? : affichage en filaire, couleur cyan,"
          << "\n                           affichage des facettes, couleur jaune,"
          << "\n                          pas d'affichage de numeros, "
          << "\n                          amplification du deplacement = 1. "
          << "   (rep 'o') pour accepter ces parametres sinon autre ";
     string rep;
     cout << "\n reponse ? "; rep = lect_return_defaut(true,"o");
   if (rep != "o") 
    {// cas d'un choix autre que standart
     while (!choix_valide)
      {
       try 
        { 
          cout 
          << "\n (0) fin modif"
          << "\n (1) en fillaire?                       (2) affichage des facettes ?  "
          << "\n (3) affichage des numeros ?            (4) couleur pour le filaire "
          << "\n (5) couleur pour les facettes          (6) facteur d'amplification";
          cout << "\n \n reponse ? ";
          rep = lect_return_defaut(false,"0");
          if (rep == "fin_prog") Sortie(1);
          // sinon
          int num = ChangeEntier(rep);
          if (num == 0) choix_valide=true;
          else if ((num >= 1)&&(num<=6)) 
           { choix_valide=false;
             switch (num)
              { case 1:  //"en filaire")
                { cout << "\n en fillaire (par defaut rep 'o') "
                       << "ou pas de filaire (rep autre) ? "; 
                  rep = lect_return_defaut(true,"o");
                  if (rep!= "o") filaire = false;
                  else           filaire = true;
                  break;}
                case 2:  // "affichage des facettes ?")
                { cout << "\n affichage des facettes (par defaut rep 'o') "
                       << "ou pas de facette (rep autre) ? ";
                  rep = lect_return_defaut(true,"o");
                  if (rep!= "o")  surface = false;
                  else            surface = true;
                  break;}
                case 3:  // "affichage des numéros ?")
                { cout << "\n affichage des numeros (non par defaut  rep 'o') "
                       << "ou on veut l'affichage des numéros (rep autre) ? "; 
                  rep = lect_return_defaut(true,"o");
                  if (rep!= "o")  numero = true;
                  else            numero = false;
                  break;}
                case 4:  // "couleur pour le filaire?")
                { cout << "\n couleur pour le filaire au standard RGB : par defaut cyan (rep 'o') ";
                  rep = lect_return_defaut(false,"0");
                  if (rep != "o")
                   { cout << "\n couleur au standard RGB (trois réels entre 0 et 1) ?  ";
                     double Rco,Gco,Bco;
                     cin >> Rco >> Gco >> Bco;
                     std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
                     if ((Rco <= 1.)&& (Rco >= 0) && (Gco <= 1.)&& (Gco >= 0)
                          &&(Bco <= 1.)&& (Bco >= 0))
                       { Rcoull = Rco; Gcoull = Gco; Bcoull = Bco;
                        }
                     else
                       { cout << " \n *****choix non valide de couleur**** ";
                        }
                    }
                  else
                    { Rcoull = 0; Gcoull = 1; Bcoull = 1;
                      }    
                  break;}
                case 5:  // "couleur pour les facettes")
                { cout << "\n couleur au standard RGB pour les facettes : par defaut cyan (rep 'o') ";
                  rep = lect_return_defaut(false,"o");
                  if (rep != "o")
                   { cout << "\n couleur au standard RGB (trois réels entre 0 et 1) ?  ";
                     double Rco,Gco,Bco;
                     cin >> Rco >> Gco >> Bco;
                     std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
                     if ((Rco <= 1.)&& (Rco >= 0) && (Gco <= 1.)&& (Gco >= 0)
                          &&(Bco <= 1.)&& (Bco >= 0))
                       { Rcoulf = Rco; Gcoulf = Gco; Bcoulf = Bco;
                        }
                     else
                       { cout << " \n *****choix non valide de couleur**** ";
                        }
                    }
                  else
                    { Rcoulf = 0; Gcoulf = 1; Bcoulf = 1;
                      }    
                  break;}
                case 6:  // "facteur d'amplification")
                { cout << "\n facteur d'amplification : par defaut 1. (rep 'o') ";
                  rep = lect_return_defaut(false,"o");
                 if (rep != "o")
                  { cout << "\n nouvelle valeur du facteur  (un reels ) ?  ";
                    amplification=lect_double();
                   }
                 else
                   amplification = 1.;
                  break;}
              }
             } 
          else { cout << "\n Erreur on attendait un entier entre 0 et 6 !!, "
                      << "\n redonnez une bonne valeur"
                      << "\n ou taper fin_prog pour arreter le programme"; 
              choix_valide=false;
             }
         }    
       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 on attendait un des mots cles proposés !!, "
                      << "\n redonnez une bonne valeur"
                      << "\n ou taper fin_prog pour arreter le programme"; 
              choix_valide=false;
        }
       } //-- fin du while
      } //-- fin du if (rep != "o") du départ c'est-à-dire du cas non standart 
      // appel de la méthode de la classe mère
      OrdreVisu::ChoixOrdre();    
     };                 
    
// lecture des paramètres de l'ordre dans un flux
void Deformees_vrml::Lecture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // si dans le flot il existe l'identificateur adoc on lit sinon on passe
   if (strstr(entreePrinc.tablcarCVisu,"debut_deformee")!=NULL)
     {// sauvegarde des paramètres  actuelles
      bool filaire_s=filaire; bool surface_s=surface; bool numero_s = numero;
      double Rcoull_s = Rcoull; double Gcoull_s=Gcoull; double Bcoull_s=Bcoull;
      double Rcoulf_s = Rcoulf; double Gcoulf_s=Gcoulf; double Bcoulf_s=Bcoulf;
      double Rcouln_s = Rcouln; double Gcouln_s=Gcouln; double Bcouln_s=Bcouln;
      double amplification_s=amplification;
      // essaie de lecture
      try 
        { string nom; 
          (*entreePrinc.entCVisu) >> nom ;
          if (nom != "debut_deformee")
            { cout << "\n Erreur en lecture des parametres de deformee a partir d'un fichier .CVisu,"
                   << " le premier enregistrement doit etre le mot clef: debut_deformee "
                   << " on ne tiens pas compte  des parametres fournies !! ";
              }
          else
           { // appel de l'ordre de la classe mère
             OrdreVisu::Lect_para_OrdreVisu_general(entreePrinc);
              while (nom != "fin_deformee")
               { (*entreePrinc.entCVisu) >> nom;
                 if (nom == "en_filaire") (*entreePrinc.entCVisu) >> filaire;
                 if (nom == "surface")  (*entreePrinc.entCVisu) >> surface;
                 if (nom == "les_numeros") (*entreePrinc.entCVisu) >> numero;
                 if (nom == "couleurs_filaires_RGB")  
                    (*entreePrinc.entCVisu) >> Rcoull >> Gcoull >> Bcoull;
                 if (nom == "couleurs_surfaces_RGB")  
                    (*entreePrinc.entCVisu) >> Rcoulf >> Gcoulf >> Bcoulf;
                 if (nom == "couleurs_numeros_RGB")  
                    (*entreePrinc.entCVisu) >> Rcouln >> Gcouln >> Bcouln;
                 if (nom == "amplification") (*entreePrinc.entCVisu) >> amplification;
                 entreePrinc.NouvelleDonneeCVisu();
                }
            }       
         }    
      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 des parametres de deformee a partir d'un fichier .CVisu,"
               << " on ne tiens pas compte  des parametres fournies !! ";
          // récup des infos  sauvées
          filaire=filaire_s; surface=surface_s; numero = numero_s;
          Rcoull = Rcoull_s; Gcoull=Gcoull_s; Bcoull=Bcoull_s;
          Rcoulf = Rcoulf_s; Gcoulf=Gcoulf_s; Bcoulf=Bcoulf_s;
          Rcouln = Rcouln_s; Gcouln=Gcouln_s; Bcouln=Bcouln_s;
          amplification=amplification_s;
          if (ParaGlob::NiveauImpression() >= 4)     
             cout  << "\n Deformees_vrml::Lecture_parametres_OrdreVisu(..";
        }
      } 
  };

// écriture des paramètres de l'ordre dans un flux
void Deformees_vrml::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // récup du flot  
   ostream & sort = (*(entreePrinc.Sort_CommandeVisu()));
   // on commente le fonctionnement
   sort << "\n #  ----------------------------- definition des parametres de deformee: ---------------- "
        << "\n debut_deformee  #  un mot cle de debut de liste";
   // appel de l'ordre de la classe mère
   OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc);
   // on sort l'entête des paramètres
   sort << "\n # les parametres avec des valeurs: (sur une meme ligne) ";   
   // puis la liste des paramètres
   sort << "\n en_filaire " << filaire << " # en_filaire  <0 ou 1> (indique si l'on veut le dessin en filaire)"
        << "\n surface " << surface << " # surface  <0 ou 1> (indique si l'on veut le dessin des faces ou surfaces)"
        << "\n les_numeros " << numero << " # numero  <0 ou 1> (indique si l'on veut le dessin des numeros)"
        << "\n # couleurs_filaires_RGB  <3 réels> (indique la couleur en RGB du trace filaire)"
        << "\n couleurs_filaires_RGB " << Rcoull << " " << Gcoull << " " << Bcoull
        << "\n # couleurs_surfaces_RGB  <3 réels> (indique la couleur en RGB du trace des surfaces)"
        << "\n couleurs_surfaces_RGB " << Rcoulf << " " << Gcoulf << " " << Bcoulf
        << "\n # couleurs_numeros_RGB  <3 réels> (indique la couleur en RGB du trace des numeros)"
        << "\n couleurs_numeros_RGB " << Rcouln << " " << Gcouln << " " << Bcouln
        << "\n amplification " << amplification << " # amplification  <1 réel> (indique le facteur d'amplification de la deformee par rapport au calcul)";
   // fin      
   sort << "\n fin_deformee " << " #   un mot cle de fin  \n";    
  };
    
                            
                            
