// 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) . // // 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 . // // For more information, please consult: . #include "Isovaleurs_vrml.h" #include #include #include "CharUtil.h" #include "Coordonnee2.h" #include "ConstMath.h" #include "MathUtil.h" #include "Banniere.h" #include // CONSTRUCTEURS : // par defaut Isovaleurs_vrml::Isovaleurs_vrml () : OrdreVisu("........................................isovaleurs" ,"visualisation des isovaleurs","iso") ,choix_peau(true),choix_legende(true),choix_min_max(1) ,pour_legende_min(0),pour_legende_max(100) ,valMini(0.),valMaxi(0.) ,tabnoeud_type_ddl(),type_ddl_retenu(),choix_var_ddl() ,tabelement_type_ddl() ,spectre_coul(),nb_iso_val() ,couleurs_noeud(),val_noeud(),num_mail_incr() ,absolue(true) {// par défaut le nombre d'isovaleur vaut le nombre de couleur du spectre nb_iso_val=spectre_coul.NbCouleurBaseSpectre(); }; // constructeur de copie Isovaleurs_vrml::Isovaleurs_vrml (const Isovaleurs_vrml& ord) : OrdreVisu(ord) ,choix_peau(ord.choix_peau),choix_legende(ord.choix_legende) ,choix_min_max(ord.choix_min_max) ,pour_legende_min(ord.pour_legende_min),pour_legende_max(ord.pour_legende_max) ,valMini(ord.valMini),valMaxi(ord.valMaxi) ,tabnoeud_type_ddl(ord.tabnoeud_type_ddl) ,type_ddl_retenu(ord.type_ddl_retenu),choix_var_ddl(ord.choix_var_ddl) ,tabelement_type_ddl(ord.tabelement_type_ddl) ,spectre_coul(ord.spectre_coul),nb_iso_val(ord.nb_iso_val) ,couleurs_noeud(ord.couleurs_noeud),val_noeud(ord.val_noeud) ,num_mail_incr(ord.num_mail_incr) ,absolue(ord.absolue) { }; // DESTRUCTEUR : Isovaleurs_vrml::~Isovaleurs_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 Isovaleurs_vrml::ExeOrdre(ParaGlob * ,const Tableau & 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 >& ,const List_io < TypeQuelconque >& listeVecGlob) {// visualisation du maillage pointé si actif if (actif) {// on boucle sur les maillages int nbmail = tab_mail.Taille(); for (int im=1;im<=nbmail;im++) { int numMail=tab_mail(im); // dans le cas où il n'y a aucun type de ddl retenu on arrête tout de suite if (type_ddl_retenu.Taille() == 0) { cout << "\n *** aucun type de ddl n'est defini en sortie, on ne fait rien \n"; } else // cas où il y a des ddl défini {// en fait on se contente de définir les couleurs aux noeuds par rapport à l'échelle // actuelle des couleurs // actualisation du conteneur du résultat if (type_incre==PREMIER_INCRE) { // au premier increment on commence par ré-initialiser les conteneurs couleurs_noeud.erase(couleurs_noeud.begin(),couleurs_noeud.end()); num_mail_incr.erase(num_mail_incr.begin(),num_mail_incr.end()); val_noeud.erase(val_noeud.begin(),val_noeud.end()); // dans le cas d'un calcul de mini max automatique on initialise if ((choix_min_max == 1)||(choix_min_max==3)) // cas d'un seul min max { valMini=0.;valMaxi=0.;}; }; // on définit deux variables intermédiaires // qui serviront ensuite à complèter les deux listes int nbmaxinoeud = lesMail->Nombre_noeud(numMail); Tableau < double > v_noeuds(nbmaxinoeud); Deuxentiers deuxi; deuxi.mail = numMail; deuxi.incr=incre; // on balaie tous les noeuds du maillage list listcoor; // une liste intermédiaire for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) { // recup du noeud Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud); // recup de la valeur du ddl double val_ddl = noe.Valeur_tdt(type_ddl_retenu(numMail).Enum()); if (!choix_var_ddl(numMail)) val_ddl -= noe.Valeur_0(type_ddl_retenu(numMail).Enum()); // enregistrement de la valeur v_noeuds(numNoeud)=val_ddl; // dans le cas on l'on utilise un mini max global automatique // on le met à jour if ((choix_min_max == 1)||(choix_min_max==3)) // cas d'un seul min max { if (val_ddl > valMaxi) valMaxi = val_ddl; if (val_ddl < valMini) valMini = val_ddl; }; }; // on sauvegarde les grandeurs intermédiaires num_mail_incr.push_back(deuxi); val_noeud.push_back(v_noeuds); // 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) )) { // dans le cas du dernier incrément on met les valeurs à la bonne échelle // si c'est une échelle automatique if ((choix_min_max == 1) || (choix_min_max==3)) { //on regarde si l'échelle n'est pas nulle si oui on la met à une valeur arbitraire de 1 if ( Dabs(valMaxi - valMini) <= ConstMath::petit) { cout << "\n *** attention la valeur mini "<< valMini <<" et maxi " << valMaxi << " sont trop rapprochees pour le calcul de la plage d'isovaleur" << "\n le mini et le maxi sont mis arbitrairement a 0 et 1"; valMaxi = 1.; valMini= 0.; } if (choix_min_max == 1) // cas d'un min max normal automatique {spectre_coul.Change_min_max(valMini,valMaxi) ;} else if (choix_min_max == 3) // cas d'un min max automatique en % {// on applique les % double leg_min=valMini + (valMaxi-valMini) * pour_legende_min/100.; double leg_max=valMini + (valMaxi-valMini) * pour_legende_max/100.; spectre_coul.Change_min_max(leg_min,leg_max) ; } } // maintenant on défini les couleurs // on passe en revue toutes les valeurs enregistrées list < Tableau < double > >::iterator it,itfin=val_noeud.end(); for (it=val_noeud.begin();it!= itfin;it++) { int taimax=(*it).Taille(); Tableau < Rgb > coul_noeuds(taimax); Tableau < double > & tab = (*it); // par facilité // dans le cas ou le min max varie à chaque incrément il faut d'abord le calculer if (choix_min_max==2) { valMini = 0.; valMaxi = 0.; // init double val_ddl; for (int j=1;j<=taimax;j++) { val_ddl=tab(j); if (val_ddl > valMaxi) valMaxi = val_ddl; if (val_ddl < valMini) valMini = val_ddl; } //on regarde si l'échelle n'est pas nulle si oui on la met à une valeur arbitraire de 1 if ( Dabs(valMaxi - valMini) <= ConstMath::petit) { cout << "\n *** attention (2) la valeur mini "<< valMini <<" et maxi " << valMaxi << " sont trop rapprochees pour le calcul de la plage d'isovaleur" << "\n le mini et le maxi sont mis arbitrairement a 0 et 1"; valMaxi = 1.; valMini= 0.; } // maintenant on applique les % double leg_min=valMini + (valMaxi-valMini) * pour_legende_min/100.; double leg_max=valMini + (valMaxi-valMini) * pour_legende_max/100.; spectre_coul.Change_min_max(leg_min,leg_max) ; }; // maintenant on calcul les couleurs for (int i=1;i<=taimax;i++) coul_noeuds(i)=spectre_coul.CouleurVal(tab(i)); couleurs_noeud.push_back(coul_noeuds); } // on dessine la légende au dernier passage // car c'est seulement à la fin que l'on connait exactement l'échelle (dans le cas d'un // calcul automatique de l'échelle) // dans les autres cas la légende ne concerne que le dernier cas Sortie_dessin_legende(entreePrinc); if (choix_min_max==2) { cout << "\n *** attention ici la legende ne concerne que le dernier increment !!";}; } }; //-- fin du choix où il y a ou pas des ddl actifs definis }; //-- fin de la boucle sur les maillages };//-- fin du choix actf 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 Isovaleurs_vrml::ChoixOrdre() { bool choix_valide = false; cout << "\n ---- isovaleurs ---- "; string rep; while (!choix_valide) { try { cout << "\n (0 ou f ou fin) fin modif" << "\n (1) definition des parametres generaux " << "\n (2) choix de l'isovaleur " << "\n (3) transferts aux noeuds de grandeurs existantes aux points d'integration"; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"f"); if (rep == "fin_prog") Sortie(1); // sinon int num = ChangeEntier(rep); if ((rep == "0")||(rep == "f")||(rep == "fin")) { choix_valide=true; } else if ((num >= 1)&&(num<=3)) { choix_valide=false; switch (num) { case 1: //"definition des parametres generaux" { ParametresGeneraux(); break;} case 2: // "choix de l'isovaleur" {ChoixIsovaleur(); break;} case 3: // "transferts aux noeuds de grandeurs existantes aux points d'integration" { TransfertGrandeursPtIntegAuNoeud(); break;} } } else { cout << "\n Erreur on attendait un entier entre 0 et 3 !!, " << "\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 // appel de la méthode de la classe mère OrdreVisu::ChoixOrdre(); }; // initialisation : permet d'initialiser les différents paramètres de l'ordre // lors d'un premier passage des différents incréments // en virtuelle, a priori est défini si nécessaire dans les classes dérivées void Isovaleurs_vrml::Initialisation(ParaGlob * paraGlob,LesMaillages * lesmail,LesReferences* lesRef ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage,Charge* charge ,LesCondLim* lesCondLim,LesContacts* lesContacts ,Resultats* resultats,EnumTypeIncre type_incre,int incre ,const map < string, const double * , std::less >& listeVarGlob ,const List_io < TypeQuelconque >& listeVecGlob ,bool fil_calcul) { // initialisation de la liste des différentes isovaleurs possibles // uniquement lors du premier et du dernier passage pour économiser if ((type_incre == OrdreVisu::DERNIER_INCRE) || (type_incre == OrdreVisu::PREMIER_INCRE)) {Init_liste_isovaleur(lesmail,lesContacts);} //appel de l'ordre d'initialisation de la classe mère OrdreVisu::Initialisation(paraGlob,lesmail,lesRef,lesLoisDeComp,diversStockage,charge ,lesCondLim,lesContacts,resultats,type_incre,incre ,listeVarGlob,listeVecGlob,fil_calcul); choix_var_ddl.Change_taille(lesmail->NbMaillage()); }; // initialisation de la liste des différentes isovaleurs possibles void Isovaleurs_vrml::Init_liste_isovaleur(LesMaillages * lesMail,LesContacts* lesContacts) { // récupération des ddl présents dans les maillages aux noeuds tabnoeud_type_ddl = lesMail->Les_type_de_ddl_par_noeud(absolue); tabelement_type_ddl = lesMail->Les_type_de_ddl_par_element(absolue); }; // lecture des paramètres de l'ordre dans un flux void Isovaleurs_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_isovaleur_vrml")!=NULL) {// sauvegarde des parametres actuels bool choix_peau_s=choix_peau; bool choix_legende_s=choix_legende; int choix_min_max_s=choix_min_max; double valMini_s=valMini; double valMaxi_s=valMaxi; int nb_iso_val_s=nb_iso_val; Tableau < Ddl_enum_etendu> type_ddl_retenu_s(type_ddl_retenu); // essaie de lecture try { string nom,nom1; (*entreePrinc.entCVisu) >> nom ; if (nom != "debut_isovaleur_vrml") { cout << "\n Erreur en lecture des parametres pour les isovaleurs a partir d'un fichier .CVisu," << " le premier enregistrement doit etre le mot clef: debut_isovaleur_vrml " << " on ne tiens pas compte des parametres fournis !! "; } else { // appel de l'ordre de la classe mère OrdreVisu::Lect_para_OrdreVisu_general(entreePrinc); // puis lecture des parametres propres // lecture du type de sortie des tenseurs if (strstr(entreePrinc.tablcarCVisu,"tenseur_en_absolue_")!=NULL) {(*entreePrinc.entCVisu) >> nom >> absolue; if (nom != "tenseur_en_absolue_") { cout << "\n lecture de l'indicateur de type de tensue, on a lue ( "<< nom << " ) et on attendait tenseur_en_absolue_" << " la suite de la lecture du .CVisu risque d'etre completement fausse, on arrete !!" ; cout << "\n Isovaleurs_Gmsh::Lecture_parametres_OrdreVisu(... "; UtilLecture::ErrNouvelEnregCVisu sortie(-1) ; throw (sortie); } else // sinon c'est ok {entreePrinc.NouvelleDonneeCVisu();}; // on passe un enregistrement }; int nb_maillage = tabnoeud_type_ddl.Taille(); while (strstr(entreePrinc.tablcarCVisu,"fin_isovaleur_vrml")==NULL) { (*entreePrinc.entCVisu) >> nom; // lecture du numero de maillage if (nom == "choix_peau") (*entreePrinc.entCVisu) >> choix_peau; if (nom == "choix_legende") (*entreePrinc.entCVisu) >> choix_legende; if (nom == "choix_min_max") (*entreePrinc.entCVisu) >> choix_min_max; if (nom == "valMini") (*entreePrinc.entCVisu) >> valMini; if (nom == "valMaxi") (*entreePrinc.entCVisu) >> valMaxi; if (nom == "pour_legende_min") (*entreePrinc.entCVisu) >> pour_legende_min; if (nom == "pour_legende_max") (*entreePrinc.entCVisu) >> pour_legende_max; if (nom == "nb_iso_val") (*entreePrinc.entCVisu) >> nb_iso_val; if (nom == "debut_tableau_ddl") { (*entreePrinc.entCVisu) >> nom1; if (nom1 != "fin_tableau_ddl") { type_ddl_retenu.Change_taille(nb_maillage); choix_var_ddl.Change_taille(nb_maillage); type_ddl_retenu(1) = Ddl_enum_etendu(nom1); for (int i=2;i<= nb_maillage; i++) { (*entreePrinc.entCVisu) >> type_ddl_retenu(i); (*entreePrinc.entCVisu) >> choix_var_ddl(i); } } } entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement } entreePrinc.NouvelleDonneeCVisu(); // on passe un enregistrement } // -- fin du if then else sur "debut_isovaleur_vrml" } // -- fin du try 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 pour les isovaleurs a partir d'un fichier .CVisu," << " on ne tiens pas compte des parametres fournis !! "; // récup des parametres sauvées choix_peau=choix_peau_s; choix_legende=choix_legende_s; choix_min_max=choix_min_max_s; valMini=valMini_s; valMaxi=valMaxi_s; nb_iso_val=nb_iso_val_s; type_ddl_retenu = type_ddl_retenu_s; if (ParaGlob::NiveauImpression() >= 4) cout << "\n Isovaleurs_vrml::Lecture_parametres_OrdreVisu(.."; } } }; // écriture des paramètres de l'ordre dans un flux void Isovaleurs_vrml::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc) { // récup du flot ostream & sort = (*(entreePrinc.Sort_CommandeVisu())); // on commente le fonctionnement sort << "\n # ----------------------------- definition des parametres pour les isovaleurs : ---------------- "; // mot clé de démarrage sort << "\n debut_isovaleur_vrml # mot cle de debut des parametres pour les isovaleurs"; // appel de l'ordre de la classe mère OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc); // le type de sortie des tenseurs sort << "\n# un parametre indiquant si les tenseurs sont en absolue (rep 1) ou suivant un repere ad hoc" << "\n# (tangent pour les coques, suivant la fibre moyenne pour les element 1D ) "; sort << "\n tenseur_en_absolue_ " << absolue; // puis les paramètres sort << "\n choix_peau " << choix_peau << " # <0 ou 1> si 1 visualisation uniquement de la peau"; sort << "\n choix_legende " << choix_legende << " # <0 ou 1> si 1 affichage de la legende"; sort << "\n choix_min_max " << choix_min_max << " # <0 ou 1 ou 2> si 1 min max calcule automatiquement, 2 auto en % par incre"; sort << "\n valMini " << valMini << " # mini utilises si choix_min_max = 0"; sort << "\n valMaxi " << valMaxi << " # maxi utilises si choix_min_max = 0"; sort << "\n pour_legende_min " << pour_legende_min << " # mini utilises si choix_min_max = 2"; sort << "\n pour_legende_max " << pour_legende_max << " # maxi utilises si choix_min_max = 2"; sort << "\n nb_iso_val " << nb_iso_val << " # nombre d'isovaleurs dans la legende"; // ---- les ddl a visualiser sort << "\n # tableau de ddl a visualiser, un par maillage"; int nb_mail = type_ddl_retenu.Taille(); sort << "\n debut_tableau_ddl " ; for (int i=1;i<= nb_mail;i++) { sort << type_ddl_retenu(i) << " " << choix_var_ddl(i) << " ";}; sort << " fin_tableau_ddl " ; // mot clé de fin sort << "\n fin_isovaleur_vrml # mot cle de fin des parametres pour les isovaleurs \n"; }; // ======================================== méthodes privées ===================================== // sortie du dessin de la légende void Isovaleurs_vrml::Sortie_dessin_legende(UtilLecture & entreePrinc) {ostream &sort = entreePrinc.Sort_legende_vrml(); // écriture de l'entête sort << "#VRML V2.0 utf8\n"; // le titre sort << "WorldInfo {\n" << "title \" Légende pour isovaleurs du calcul éléments finis : Herezh++ V" << ParaGlob::NbVersion() << " \" \n" // << "info [ \"Copyright (c) 1997-2003, Gérard Rio (gerard.rio@univ-ubs.fr) http://www-lg2m.univ-ubs.fr\" ]\n" << "info [ \" " << Banniere::CopiPirate << " \" ]\n" << "}\n"; sort << "NavigationInfo {\n" << "type [ \"EXAMINE\", \"ANY\" ] \n" << "headlight TRUE \n" << "}\n"; // on définit un rectangle pour chaque niveau d'isovaleur // globalement on définit le rectangle global par les points extrèmes Coordonnee2 ptdeb(0.,0.); Coordonnee2 ptfin(10.,200.); // on définit le deltax et le delta y Coordonnee2 deltax(10.,0.);Coordonnee2 deltay(0.,200./(nb_iso_val-1.)); // définition des points de vue avec l'angle adoc // l'objectif est de positionner les viewpoints relativement à la legende // pour l'instant pb avec maclookat donc on simplifie /* Vecteur diag = ptfin - ptdeb; double lmax = diag.Norme(); Vecteur centre = (ptfin + ptdeb)/2.; // si la dimension est différente de 3 on force à 3 // d'où les autres coordonnées sont nulles centre.Change_taille(3); // def de la distance d'observation grande pour minimiser la déformation double dist = 5.*lmax; // calcul de l'angle du cone de vue double angle = 1.25*atan(lmax/dist); int i1= std::abs( centre(1)); int i2= std::abs( centre(2)); int i3= std::abs( centre(3)+ dist); sort << "\n Viewpoint {" << "\n position " << i1 <<" "<< i2 <<" "<< i3 << "\n fieldOfView " << angle << "\n description \"suivant Z \"" << "\n }"; */ sort << "\n Viewpoint {" << "\n position " << " 5 100 1000 " << "\n fieldOfView " << 0.25 << "\n description \"suivant Z \"" << "\n }"; // definition du tableau des points de la legende Tableau tab_pt(2*nb_iso_val,ptdeb); for (int i=1;i<= nb_iso_val;i++) { tab_pt(i) += (i-1) * deltay; tab_pt(i+nb_iso_val) = tab_pt(i) + deltax; } // on ecrit 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 << "Coordonnees" << 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 [ \n"; int deux_nb_iso_val = 2*nb_iso_val; for (int i=1;i<= deux_nb_iso_val;i++) { sort <<"\n " << setw (4); tab_pt(i).Affiche(sort,16); sort << setw (16) << 0 <<" "; // pour etre en 3D } // fermeture du groupe point, coordinate, de la géométrie et de la forme sort << "\n ] } } }"; // maintenant les facettes: 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 Coordonnees" ; // def des facettes sort << "\n coordIndex ["; for (int i=0;i< nb_iso_val-1;i++) { // on definit deux triangle pour chaque facette, sort << "\n "; //début de la face 1 sort << i << ", " << i+nb_iso_val << ", " << i+1 << ", -1,"; sort << "\n "; //début de la face 2 sort << i+nb_iso_val << ", " << i+nb_iso_val+1 << ", " << i+1 << ", -1,"; } // fin pour les faces sort << "\n ]"; // definition des couleurs aux noeuds // on sauvegarde puis modifie les min max pour les adapter au tracé de la légende double legende_min = spectre_coul.Valeur_mini(); double legende_max = spectre_coul.Valeur_maxi(); spectre_coul.Change_min_max(ptdeb(2),ptfin(2)) ; sort << "\n color Color {" << "\n color ["; for (int i=1;i<= nb_iso_val;i++) { // récup de la couleur Rgb rgb = spectre_coul.CouleurVal(tab_pt(i)(2)); sort << "\n " << rgb << ", "; } for (int i=1;i<= nb_iso_val;i++) { // récup de la couleur Rgb rgb = spectre_coul.CouleurVal(tab_pt(i+nb_iso_val)(2)); sort << "\n " << rgb << " , "; } sort << "\n ]" << "\n }"; // remise normale du min max du spectre spectre_coul.Change_min_max(legende_min,legende_max) ; // on signal que l'on utilise une couleur par noeud (vertex) sort << "\n colorPerVertex TRUE"; // on signal que l'on peut voir des deux cotés des facettes sort << "\n solid FALSE"; sort << "\n }"; // fin: on ferme l'entité forme sort << "\n }"; // maintenant on définit les valeurs de la légende // def d'un décalage suivant x de la légende couleur double decax = (ptfin(1) - ptdeb(1))/ 5.; // on boucle sur les isovals double delta_val_y=(legende_max-legende_min)/(nb_iso_val-1); double val_iso=legende_min; for (int i=1;i<= nb_iso_val;i++) { // creation de la chaine de caractère qui contient la valeur de l'isovaleur ostrstream tab_out; #ifndef ENLINUX_STREAM tab_out.setf(ios_base::scientific); #else tab_out.setf(ios::scientific); #endif tab_out << setprecision(6) << val_iso << ends; // on définit une entité déplacé qui permet de ce positionner // aux coordonnées que l'on veut sort << "\n Transform { # X Y Z "; sort <<"\n translation " << setw (16) << (tab_pt(i+nb_iso_val)(1) + decax) << " " << setw (16) << tab_pt(i+nb_iso_val)(2) << " " << setw (16) << 0 << " "; // écrit la valeur sort << "\n children ["; // def de l'entité forme sort << "\n Shape { " << "\n appearance Appearance {" << "\n material Material { }" << "\n }" << "\n geometry Text {" << "\n string \"" << tab_out.str() <<"\"" << "\n fontStyle FontStyle {size 10} " << "\n }} ] }"; val_iso += delta_val_y; } // définition du titre du travail sort << "\n Transform { # X Y Z "; sort <<"\n translation " << setw (16) << -10 << " " << setw (16) << -10<< " " << setw (16) << 0 << " "; // écrit le texte sort << "\n children ["; // def de l'entité forme sort << "\n Shape { " << "\n appearance Appearance {" << "\n material Material { }" << "\n }" << "\n geometry Text {" << "\n string \"" << "Herezh++ V" << ParaGlob::NbVersion()<<" \"" << "\n fontStyle FontStyle {size 10} " << "\n }} ] }"; // définition du nom del'isovaleur sort << "\n Transform { # X Y Z "; sort <<"\n translation " << setw (16) << -28 << " " << setw (16) << -18<< " " << setw (16) << 0 << " "; // écrit le texte sort << "\n children ["; // def de l'entité forme sort << "\n Shape { " << "\n appearance Appearance {" << "\n material Material { }" << "\n }" << "\n geometry Text {" << "\n string \"" << "isovaleur de " ; if (type_ddl_retenu.Taille() != 0) sort << type_ddl_retenu(1); //.Nom(); sort << " \"" << "\n fontStyle FontStyle {size 10} " << "\n }} ] }"; // et on vide le buffer de sortie sort << endl; }; // définition interactives des paramètres généraux des isovaleurs void Isovaleurs_vrml::ParametresGeneraux() { bool choix_valide = false; cout << "\n ----> preparation de la visualisation des isovaleurs" << "\n parametre par defaut ? : affichage de la peau par facettes triangulaires," << "\n ajout de la legende avec min_max automatique," << "\n spectre standart, " << " (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) plus visualisation interne (2) calcul NON automatique des min max de la legende " << "\n (3) visualisation que des peaux (4) calcul auto global des min max de la legende" << "\n (5) autres spectres (6) % auto sur l'incr des min max de la legende" << "\n (7) spectre standart (8) % auto sur tous les incr des min max de la legende" << "\n (9) nombre isovaleurs " << "\n (10) sortie des tenseurs dans le repere absolu (par defaut) " << "\n (11) sortie des tenseurs dans un repere ad hoc, qui depend du type d'element "; cout << "\n \n reponse ? "; rep = lect_return_defaut(false,"0"); if (rep == "fin_prog") Sortie(1); // if ((rep == "0")||(rep == "f")||(rep == "fin")) return; // sinon int num = ChangeEntier(rep); if (num == 0) choix_valide=true; else if ((num >= 1)&&(num<=11)) { choix_valide=false; switch (num) { case 1: //"visualisation interne") { choix_peau = true; break;} case 2: // "calcul NON automatique des min max de la légende") {bool choixvalideLoc = false; while (!choixvalideLoc) {// on récupère les mini et maxi de la légende cout << "\n actuellement les mini/maxi sont: " << " mini= " << spectre_coul.Valeur_mini() << " maxi= " << spectre_coul.Valeur_maxi(); cout << "\n differentes methodes pour modifier les extremes: " << "\n donnez les valeurs explicitements des extremes (rep 1)" << "\n donnez en % de la plage actuelle des mini et maxi (rep 2)" << "\n (dans ce dernier cas, modif a chaque increment) " << "\n laisser tel quel (rep f ou 0 ou fin)"; cout << "\n \n reponse ? "; string reploc; reploc = lect_return_defaut(false,"f"); if (reploc == "1") {cout << "\n donner le mini et le maxi de la legende (2 reels) "; double legende_min,legende_max; // min max de la légende cin >> legende_min >> legende_max; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ( legende_max < legende_min) {cout << "\n donnees non valides, le maxi doit etre superieur au mini !! "; choixvalideLoc=false; } else {choix_min_max = 0; spectre_coul.Change_min_max(legende_min,legende_max) ; choixvalideLoc = true; }; } else if (reploc == "2") {cout << "\n donner le mini et le maxi en % de la plage (2 reels) "; double pr_legende_min,pr_legende_max; // min max de la légende cin >> pr_legende_min >> pr_legende_max; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ( pr_legende_max < pr_legende_min) {cout << "\n donnees non valides, le maxi doit etre superieur au mini !! "; choixvalideLoc=false; } else {choix_min_max = 0; double leg_min=spectre_coul.Valeur_mini() + (spectre_coul.Valeur_maxi()-spectre_coul.Valeur_mini()) * pr_legende_min/100.; double leg_max=spectre_coul.Valeur_mini() + (spectre_coul.Valeur_maxi()-spectre_coul.Valeur_mini()) * pr_legende_max/100.; spectre_coul.Change_min_max(leg_min,leg_max) ; cout << "\n nouvelles valeurs: mini= " < & tab_spectre = Spectre::Description_spectres_disponibles(); int nb_spectre= tab_spectre.Taille(); bool choix_val = false; cout << "\n donner un choix de spectre"; while (!choix_val) { try { cout << "\n (0) fin modif spectre"; for (int i=1;i<=nb_spectre;i++) cout << "\n ("<= 1)&&(nim<=nb_spectre)) { choix_val=false; spectre_coul.Change_spectre_courant(Spectre::EnumType_spectre(nim)); } else { cout << "\n ERREUR *** choix non valide :on attendait un nombre entre 0 et "<< nb_spectre << "\n redonnez une bonne valeur ****** \n \n "; choix_val=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 en lecture { cout << "\n Erreur on attendait un des mots cles proposes !!, " << "\n redonnez une bonne valeur" << "\n ou taper fin_prog pour arreter le programme"; choix_val=false; } } //-- fin du while break;} case 6: // "calcul automatique en % pour chaque incre des min max de la légende") { cout << "\n donner le mini et le maxi en % de la plage de l'increment (2 reels) "; double pr_legende_min,pr_legende_max; // min max de la légende cin >> pr_legende_min >> pr_legende_max; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ( pr_legende_max < pr_legende_min) {cout << "\n donnees non valides, le maxi doit etre superieur au mini !! ";} else {choix_min_max = 2; pour_legende_min=pr_legende_min;pour_legende_max=pr_legende_max; cout << "\n %lu (util pour chaque incr): mini= " <> pr_legende_min >> pr_legende_max; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ( pr_legende_max < pr_legende_min) {cout << "\n donnees non valides, le maxi doit etre superieur au mini !! ";} else {choix_min_max = 3; pour_legende_min=pr_legende_min;pour_legende_max=pr_legende_max; cout << "\n %lu (util pour tous les incr): mini= " < 100)) cout << "\n le nombre d'isovaleur doit etre strictement superieur a 2 et" << "inferieur ou egal a 100"; else {nb_iso_val = inter_int;choix_val = true;} } 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 en lecture { cout << "\n Erreur on attendait soit 0 pour garder la valeur precedente" << " ou un nombre entre 2 et 100 !!, " << "\n redonnez une bonne valeur"; choix_val=false; } } //-- fin du while break;} case 10: { absolue = true; break;} case 11: { absolue = false; break;} } } else { cout << "\n Erreur on attendait un entier entre 0 et 9 !!, " << "\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 } }; // choix de l'isovaleur à visualiser void Isovaleurs_vrml::ChoixIsovaleur() { bool choix_valide = false; string rep; cout << "\n choix de l'isovaleur a visualiser, on choisit une isovaleur maxi par maillage"; int nbmail = tabnoeud_type_ddl.Taille(); // update du tableau de ddl à visualiser si nécessaire if (type_ddl_retenu.Taille() != nbmail) type_ddl_retenu.Change_taille(nbmail); for (int imail = 1;imail<=nbmail;imail++) {choix_valide=false; while (!choix_valide) // premier while { try { cout << "\n (0 ou f ou fin) fin choix ddl "; cout << "\n listes de type de ddl a visualiser "; cout << "\n Maillage nb: " << imail << " liste des types de ddl disponibles " << "\n" << tabnoeud_type_ddl(imail); cout << "\n donner le ddl a visulaliser " << "\n reponse ? "; rep = lect_return_defaut(false,"f"); if (rep == "fin_prog") Sortie(1); // sinon if ((rep == "0") || (rep == "f") || (rep == "fin")) choix_valide=true; else if (ExisteEnum_ddl(rep.c_str())) // test pour savoir si c'est vraiment un ddl { Enum_ddl enum_d = Id_nom_ddl(rep.c_str()); Ddl_enum_etendu ddl_enu_etendue(enum_d); // on vérifie si le ddl existe dans la liste proposée if (Ddl_enum_etendu::Existe_dans_la_liste(tabnoeud_type_ddl(imail),ddl_enu_etendue)) {type_ddl_retenu(imail) = ddl_enu_etendue;} else {cout << "\n ddl inexistant dans la liste proposee, recommencez"; 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 en lecture { cout << "\n Erreur dans la lecture de ddl !!, " << "\n redonnez une bonne valeur" << "\n ou taper fin_prog pour arreter le programme"; choix_valide=false; } } //-- fin du premier while choix_valide=false; while (!choix_valide) { try { cout << "\n valeur du ddl ou variation entre t=0 et t (rep 1 ou 0 ) ? \n" << "\n reponse ? "; rep = lect_1_0(false); if (rep == "1") {choix_var_ddl(imail)=true;choix_valide=true;} else if (rep == "0") {choix_var_ddl(imail)=false;choix_valide=true;} else {cout << "\n mauvais choix, recommencez";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 en lecture { cout << "\n Erreur dans le choix de la variation ou non des ddl !!, " << "\n redonnez une bonne valeur"; choix_valide=false; } } //-- fin du second while }//-- fin de la boucle sur les maillages }; // choix de grandeur existantes aux points d'intégrations et à ramener aux noeuds // pour préparer une visualisation d'isovaleurs void Isovaleurs_vrml::TransfertGrandeursPtIntegAuNoeud() { /*bool choix_valide = false; string rep; while (!choix_valide) {try { cout << "\n (0 ou f ou fin) fin modif" << "\n (1) definition des parametres generaux " << "\n (2) choix de l'isovaleur " << "\n (3) transferts aux noeuds de grandeurs existantes aux points d'integration"; cout << "\n \n reponse ? "; cin >> rep; if (rep == "fin_prog") Sortie(1); // sinon int num = ChangeEntier(rep); if ((rep == "0")||(rep == "f")||(rep == "fin")) { choix_valide=true; } else if ((num >= 1)&&(num<=3)) { choix_valide=false; switch (num) { case 1: //"definition des parametres generaux" { ParametresGeneraux(); break;} case 2: // "choix de l'isovaleur" {ChoixIsovaleur(); break;} case 3: // "transferts aux noeuds de grandeurs existantes aux points d'integration" { choix_peau = false; break;} case 4: // "calcul automatique des min max de la légende") { TransfertGrandeursPtIntegAuNoeud(); break;} } } else { cout << "\n Erreur on attendait un entier entre 0 et 3 !!, " << "\n redonnez une bonne valeur" << "\n ou taper fin_prog pour arreter le programme"; choix_valide=false; } } 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*/ };