// 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 "Mail_initiale_vrml.h" #include #include // CONSTRUCTEURS : // par defaut Mail_initiale_vrml::Mail_initiale_vrml () : OrdreVisu(".................................maillage initiale" ,"visualisation des maillages initiaux","mi") ,filaire(true),surface(true),numero(false) ,Rcoull(0.0),Gcoull(0.0),Bcoull(1.0) ,Rcoulf(0.0),Gcoulf(1.0),Bcoulf(0.0) ,Rcouln(1.0),Gcouln(0.0),Bcouln(0.0) ,taille_numero(0.2) {}; // constructeur de copie Mail_initiale_vrml::Mail_initiale_vrml (const Mail_initiale_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) ,taille_numero(ord.taille_numero) {}; // DESTRUCTEUR : Mail_initiale_vrml::~Mail_initiale_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 Mail_initiale_vrml::ExeOrdre(ParaGlob * paraGlob,const Tableau & tab_mail,LesMaillages * lesMail,bool ,LesReferences* ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim* // ,LesContacts*,Resultats*,ostream & sort,EnumTypeIncre type_incre,int incre ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre // ,bool animation) ,bool,const map < string, const double * , std::less >& ,const List_io < TypeQuelconque >& listeVecGlob) {ostream &sort = entreePrinc.Sort_princ_vrml(); // visualisation du maillage pointé si actif if ((actif)&&(incre==0)) { // on boucle sur les maillages int nbmail = tab_mail.Taille(); for (int im=1;im<=nbmail;im++) { int numMail=tab_mail(im); // 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-0" << 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); for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) { // recup du noeud Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud); // ecriture des coordonnee à 0 sort <<"\n " << setw (16); noe.Coord0().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 <<" "; } sort << " , "; } // fermeture du groupe point, coordinate, de la géométrie et de la forme sort << "\n ] } } }"; } if (surface) // cas d'une visualisation par face { // def de l'entité forme sort << "\n Shape { " << "\n appearance Appearance {}"; // définition de la forme géométrique sort << "\n geometry IndexedFaceSet {" // utilisation des points définis << "\n coord USE Coordinates-0" << numMail; // définition de la couleur sort << "\n color Color {" << "\n color [" << "\n " << Rcoulf << " " << Gcoulf << " " << Bcoulf<< " ," << "\n ]" << "\n }"; // def des arrêtes 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& 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 > >& 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 * 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 Mail_initiale_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 }"; } if (filaire) { // def de l'entité forme sort << "\n Shape { " << "\n appearance Appearance {}"; // définition de la forme géométrique sort << "\n geometry IndexedLineSet {" // utilisation des points définis << "\n coord USE Coordinates-0" << numMail; // 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& tab_noeud = elem.Tab_noeud (); // ses noeuds // connection des noeuds des arêtes par rapport a ceux de l'element Tableau > 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 Tableauconst & 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) // 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 "; // ecriture des coordonnee à 0 sort <<"\n translation " << setw (16); noe.Coord0().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 " << taille_numero << " } " << "\n }} ] }"; // on ferme le billboard et la forme générale // sort << "\n ]}"; } } }; //-- fin de la boucle sur les maillages // et on vide le buffer de sortie sort << endl; };//-- fin du test d'actif }; // 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 Mail_initiale_vrml::ChoixOrdre() { // demande de précision bool choix_valide = false; while (!choix_valide) { // tout d'abord on met le choix valide a priori choix_valide = true; cout << "\n ----> preparation de la visualisation du maillage initiale" << "\n parametre par defaut ? : affichage en filaire, couleur bleu," << "\n et affichage des facettes, couleur vert," << " \n pas d'affichage de numeros. " << " (rep 'o') pour accepter ces parametres sinon autre "; string rep; cout << "\n reponse ? "; rep = lect_return_defaut(true,"o"); if (rep != "o") { // cas du filaire cout << "\n en fillaire (par defaut rep 'o') " << "ou pas de filaire (rep autre) ? "; rep = lect_return_defaut(true,"o"); if (rep!= "o") { choix_valide = choix_valide && true; filaire = false; } else { choix_valide = choix_valide && true; filaire = true; } // cas des face cout << "\n affichage des facettes (par defaut rep 'o') " << "ou pas de facette (rep autre) ? "; rep = lect_return_defaut(true,"o"); if (rep!= "o") { choix_valide = choix_valide && true; surface = false; } else { choix_valide = choix_valide && true; surface = true; } // cas des numéros cout << "\n affichage des numeros (non par defaut rep 'o') " << "ou on veut l'affichage des numeros (rep autre) ? "; rep = lect_return_defaut(true,"o"); if (rep!= "o") { choix_valide = choix_valide && true; numero = true; } else { choix_valide = choix_valide && true; numero = false; } // puis choix de la taille des numéros cout << "\n taille des numeros (non par defaut 0.2 rep 'o') " << "ou autre taille (rep autre) ? "; rep = lect_return_defaut(true,"o"); if (rep!= "o") { cout << "\n nouvelle taille (un réel) ? : "; taille_numero=lect_double(); choix_valide = choix_valide && true; } else { choix_valide = choix_valide && true; taille_numero = 0.2; } // choix de la couleur (en RGB) du filaire cout << "\n couleur au standard RGB : par defaut bleu (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::max(), '\n' );// purge de cin if ((Rco <= 1.)&& (Rco >= 0) && (Gco <= 1.)&& (Gco >= 0) &&(Bco <= 1.)&& (Bco >= 0)) { Rcoull = Rco; Gcoull = Gco; Bcoull = Bco; choix_valide = choix_valide && true; } else { cout << " \n *****choix non valide de couleur**** "; choix_valide = choix_valide && false; } } else { Rcoull = 0; Gcoull = 0; Bcoull = 1; choix_valide = choix_valide && true; } // choix de la couleur (en RGB) des facettes cout << "\n couleur au standard RGB : par defaut vert (rep 'o') "; rep = lect_return_defaut(false,"o"); if (rep != "o") { cout << "\n couleur au standard RGB (trois reels entre 0 et 1) ? "; double Rco,Gco,Bco; cin >> Rco >> Gco >> Bco; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ((Rco <= 1.)&& (Rco >= 0) && (Gco <= 1.)&& (Gco >= 0) &&(Bco <= 1.)&& (Bco >= 0)) { Rcoulf = Rco; Gcoulf = Gco; Bcoulf = Bco; choix_valide = choix_valide && true; } else { cout << " \n *****choix non valide de couleur**** "; choix_valide = choix_valide && false; } } else { Rcoulf = 0; Gcoulf = 1; Bcoulf = 0; choix_valide = choix_valide && true; } // choix de la couleur (en RGB) des numéros cout << "\n couleur au standard RGB : par defaut blanc (rep 'o') "; rep = lect_return_defaut(false,"o"); if (rep != "o") { cout << "\n couleur au standard RGB (trois reels entre 0 et 1) ? "; double Rco,Gco,Bco; cin >> Rco >> Gco >> Bco; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin if ((Rco <= 1.)&& (Rco >= 0) && (Gco <= 1.)&& (Gco >= 0) &&(Bco <= 1.)&& (Bco >= 0)) { Rcouln = Rco; Gcouln = Gco; Bcouln = Bco; choix_valide = choix_valide && true; } else { cout << " \n *****choix non valide de couleur**** "; choix_valide = choix_valide && false; } } else { Rcouln = 0; Gcouln = 0; Bcouln = 0; choix_valide = choix_valide && true; } } else choix_valide = choix_valide && true; } // appel de la méthode de la classe mère OrdreVisu::ChoixOrdre(); }; // lecture des paramètres de l'ordre dans un flux void Mail_initiale_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_maillage_initial")!=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; // essaie de lecture try { string nom; (*entreePrinc.entCVisu) >> nom ; if (nom != "debut_maillage_initial") { cout << "\n Erreur en lecture des parametres du maillage initial a partir d'un fichier .CVisu," << " le premier enregistrement doit etre le mot clef: debut_maillage_initial " << " 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_maillage_initial") { (*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; 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 du maillage initial 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; if (ParaGlob::NiveauImpression() >= 4) cout << "\n Mail_initiale_vrml::Lecture_parametres_OrdreVisu(.."; } } }; // écriture des paramètres de l'ordre dans un flux void Mail_initiale_vrml::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc) { // récup du flot ostream & sort = (*(entreePrinc.Sort_CommandeVisu())); // on commente le fonctionnement sort << "\n # ----------------------------- definition des parametres du maillage initial: ---------------- " << "\n debut_maillage_initial # 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; // fin sort << "\n fin_maillage_initial " << " # le mot cle de fin \n"; };