// 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 "Increment_vrml.h" #include #include #include "CharUtil.h" #include // CONSTRUCTEURS : // par defaut Increment_vrml::Increment_vrml () : OrdreVisu(".........................choix numeros d'increment" // de 15 à 65=50 caracteres ,"definition d'un numero d'increment ou d'une liste de numero","cni") ,lis_inc(NULL),lis_sor() { // par défaut on active cet ordre avec l'incrément initial qui normalement existe lis_sor.push_back(0); // cout << "\n liste actuelle: debug "; // list ::iterator ikk,ikkfin=lis_sor.end(); // for (ikk=lis_sor.begin();ikk!=ikkfin;ikk++) cout << *ikk << " "; // cout << "\n fin *** liste actuelle: debug "; OrdreVisu::ChoixOrdre(); }; // constructeur de copie Increment_vrml::Increment_vrml (const Increment_vrml& ord) : OrdreVisu(ord),lis_inc(ord.lis_inc),lis_sor(ord.lis_sor) { }; // DESTRUCTEUR : Increment_vrml::~Increment_vrml () {}; // METHODES PUBLIQUES : // choix de l'ordre void Increment_vrml::ChoixOrdre() { // demande de précision bool choix_valide = false; list::iterator ik,ikfin=lis_inc->end(); // on traite tout d'abord le cas où il n'y a pas d'incrément à visualiser // dans ce dernier cas on arrête le traitement interactif if(lis_inc->begin() == ikfin) { cout << "\n *** pas d'increment disponible en dehors de l'increment 0 mis par defaut !! "; return; } // puis cas où il existe des incréments non nul while (!choix_valide) {try { cout << "\n liste actuelle: "; list ::iterator ikk,ikkfin=lis_sor.end(); for (ikk=lis_sor.begin();ikk!=ikkfin;ikk++) cout << *ikk << " "; cout << "\n liste des increments disponibles (en plus de l'increment 0 mis par defaut): "; for (ik=lis_inc->begin();ik!=ikfin;ik++) cout << *ik << " "; cout << "\n parametre par defaut ? le dernier increment (rep 'o') pour accepter " << "\n (rep 'ac') pour laisser en l'etat" << "\n (sinon autre) \n"; string rep; rep = lect_return_defaut(false,"o"); if (rep == "ac") { // on laisse en l'etat cout << "\n aucun changement "; choix_valide = true; } else if (rep != "o") { // On regarde tout d'abord si l'on veut des incréments en plus ou si l'on ne veut que // les incréments que l'on va indiquer cout << "\n voulez-vous effacer la liste actuelle qui est : "; list ::iterator ik,ikfin=lis_sor.end(); for (ik=lis_sor.begin();ik!=ikfin;ik++) cout << *ik << " "; cout << "\n rep 'o' pour effacer sinon autre (defaut)? "; rep = lect_return_defaut(false,"n"); if (rep == "o") lis_sor.erase(lis_sor.begin(),lis_sor.end()); // définition des incréments cout << "\n differentes options : " << "\n un increment rep : 1 " << "\n un interval d'increments par pas de 1 rep : 2 " << "\n un interval d'increments avec choix du pas " << "\n entre deux increment choisit rep : 3 " << "\n une liste d'increments rep : 4 " << "\n tous les increments rep : 5 " << "\n tous les increments sans l'increment 0 rep : 6 " << "\n le dernier increment (defaut) rep : 7 "; rep = lect_return_defaut(false,"7"); if (rep != "7") cout << "\n un premier chiffre negatif indique que c'est un increment a retirer (si possible)" << "\n par contre s'il est positif c'est un increment a ajouter (s'il n'existe pas deja)" << "\n les increments sont systematiquement ordonne en fin de traitement "; if (rep== "1") { cout << "\n numero d'increment : "; int irep; irep=(int)lect_double(); // on vérifie que l'incrément demandé est possible ik = find(lis_inc->begin(),lis_inc->end(),abs(irep)); if (ik != lis_inc->end()) // cas ou l'incrément existe {if (irep <= 0) lis_sor.remove(abs(irep)); // suppression s'il existe else lis_sor.push_back(irep); choix_valide = true; } } else if (rep== "2") { cout << "\n increment de depart et increment de fin (deux entiers) : "; int irep1,irep2; cin >> irep1 >> irep2; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin // on repère les deux bornes dans la liste list::iterator idep,ifin; idep = find(lis_inc->begin(),lis_inc->end(),abs(irep1)); ifin = find(lis_inc->begin(),lis_inc->end(),abs(irep2)); if (!((idep!= lis_inc->end())&&(ifin!= lis_inc->end()))) { cout << "erreur de borne (inexistantes ou pas dans le bon ordre ?) "; choix_valide = false; } else { // on met à jour ifin++; for (ik=idep;ik!=ifin;ik++) {if (irep1 >= 0) lis_sor.push_back(*ik); else lis_sor.remove(*ik); // suppression s'il existe } choix_valide = true; } } else if (rep== "3") { cout << "\n increment de depart et increment de fin (deux entiers) : "; int irep1,irep2; cin >> irep1 >> irep2; std::cin.ignore( std::numeric_limits::max(), '\n' );// purge de cin cout << "\n pas entre deux increments consecutifs (un entier) : "; int pas_inc; pas_inc=(int)lect_double(); pas_inc = abs(pas_inc); // on repère les deux bornes dans la liste list::iterator idep,ifin; idep = find(lis_inc->begin(),lis_inc->end(),abs(irep1)); ifin = find(lis_inc->begin(),lis_inc->end(),abs(irep2)); if (!((idep!= lis_inc->end())&&(ifin!= lis_inc->end()))) { cout << "erreur de borne (inexistantes ou pas dans le bon ordre ?) "; choix_valide = false; } else { // on positionne la fin suivant le standard stl ifin++; // init de ik ik = idep; // traitement while(ik!=ifin) { // enregistrement ou effacement if (irep1 >= 0) lis_sor.push_back(*ik); else lis_sor.remove(*ik); // suppression s'il existe // incrémentation du pointeur d'incrément for (int i=1;i<= pas_inc;i++) {if (ik != ifin) ik++;} // on a atteind la borne sup arrêt d'incrémentation } choix_valide = true; } } else if (rep == "4") { cout << "\nl'entree d'une liste d'increment s'effectue numero par numero "; int irep = -1; float x_ent; do { cout << "\n un numero ? (un nombre flottant (ex 1.2)pour finir) : "; x_ent=(float)lect_double(); irep = (int) Abs(x_ent); // vérification si le numéro est acceptable list::iterator idep; idep = find(lis_inc->begin(),lis_inc->end(),abs(irep)); if ((idep== lis_inc->end())) { cout << "\n numero non acceptable cf la liste : "; for (ik=lis_inc->begin();ik!=ikfin;ik++) cout << *ik << " "; cout << "\n recommencez "; irep = -20; } else { if (irep >= 0) lis_sor.push_back(irep); else lis_sor.remove(abs(irep)); // suppression s'il existe choix_valide = true; } } while (x_ent == (float) irep); } else if (rep == "5") { list::iterator idepfin = lis_sor.end(); list::iterator idepdebut = lis_sor.begin(); // on commence par effacer la liste actuelle lis_sor.erase(idepdebut,idepdebut); // on rempli la liste finale lis_sor=(*lis_inc); choix_valide = true; } else if (rep == "6") { list::iterator idepfin = lis_sor.end(); list::iterator idepdebut = lis_sor.begin(); // on commence par effacer la liste actuelle lis_sor.erase(idepdebut,idepfin); // on rempli la liste finale lis_sor=(*lis_inc); // on supprime le premier idepdebut = lis_sor.begin(); lis_sor.erase(idepdebut); choix_valide = true; } else if (rep == "7") { // on commence par effacer la liste actuelle lis_sor.erase(lis_sor.begin(),lis_sor.end()); // on ajoute l'incrément finale list::const_iterator idepdernier = lis_inc->end();idepdernier--; lis_sor.push_back(*idepdernier); choix_valide = true; } else { cout << "\n choix non valide"; choix_valide = false; } } else { // cas ou l'on retiend l'incrément par défaut c'est-à-dire le dernier // on regarde s'il est déjà enregistré sinon on l'ajoute à la liste de sortie list ::iterator ider = ikfin; ider--; int derIncr= *ider; list::iterator ipos = find(lis_sor.begin(),lis_sor.end(),derIncr); if (ipos == lis_sor.end()) lis_sor.push_back(derIncr); choix_valide = true; } } //-- 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 increments, recommencer"; choix_valide = false; } } // -- fin du while // on ordonne la liste puis on supprime les doublons enfin on l'afficher Propre_liste(lis_sor); // appel de la méthode de la classe mère OrdreVisu::ChoixOrdre(); }; // initialisation de la liste à l'incrément 0 et au dernier increment // s'il est différent void Increment_vrml::Init_list_inc_DebuEtFin() { // on efface la liste actuelle lis_sor.erase(lis_sor.begin(),lis_sor.end()); lis_sor.push_back(0); if (lis_inc != NULL) { list ::iterator ilifin=lis_inc->end(); if (*ilifin != 0) lis_sor.push_back(*ilifin); }; }; // lecture des paramètres de l'ordre dans un flux void Increment_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_list_increment")!=NULL) {// sauvegarde de la liste actuelle list liste_sauve = lis_sor; // essaie de lecture try { string nom; (*entreePrinc.entCVisu) >> nom ; if (nom != "debut_list_increment") { cout << "\n Erreur en lecture des increments a partir d'un fichier .CVisu," << " le premier enregistrement doit etre le mot clef: debut_list_increment " << " on ne tiens pas compte de la liste fournie !! "; } else {// appel de l'ordre de la classe mère OrdreVisu::Lect_para_OrdreVisu_general(entreePrinc); // on efface la liste actuelle lis_sor.erase(lis_sor.begin(),lis_sor.end()); // maintenant on n'intervient que s'il y a une liste d'incrément disponible if (lis_inc != NULL) {// lecture de la liste demandée if (strstr(entreePrinc.tablcarCVisu,"tous_les_increments_moins_zero")!=NULL) { // cas où on veut tous les incréments lis_sor = (*lis_inc); if ((lis_sor.size() != 0) && (*(lis_sor.begin()) == 0)) lis_sor.erase(lis_sor.begin()); } else if (strstr(entreePrinc.tablcarCVisu,"tous_les_increments")!=NULL) { // cas où on veut tous les incréments disponibles lis_sor = (*lis_inc); } else if (strstr(entreePrinc.tablcarCVisu,"dernier_increment")!=NULL) { // cas où on veut le dernier incrément list ::iterator iincre = lis_inc->end(); if (lis_inc->size() != 0) { iincre--; lis_sor.push_back(*iincre); }; } else { // cas de la lecture d'une liste différentes de tous les incréments int compteur=0; // pour éviter une boucle infinie int nb_lue_sur_ligne = 0; while (compteur < 1000000) { (*entreePrinc.entCVisu) >> nom; compteur++;nb_lue_sur_ligne++; if (nom != "fin_list_increment") { // on vérifie que l'incrément demandé est possible int inc=ChangeEntier(nom); list ::iterator ik = find(lis_inc->begin(),lis_inc->end(),inc); if (ik != lis_inc->end()) // cas ou l'incrément existe { lis_sor.push_back(inc);} else { cout << "\n Erreur en lecture de l'increments "<< nom <<" il n'appartient pas a la liste" << " d'increment possible ON N'EN TIENT PAS COMPTE !! ";} if (nb_lue_sur_ligne > 50) { nb_lue_sur_ligne=0;entreePrinc.NouvelleDonneeCVisu();} } else break; } }//-- fin de la lecture d'une liste différentes de tous les incréments } else // sinon on met l'incrément 0 par défaut {lis_sor.push_back(0); }; }; } 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 increments a partir d'un fichier .CVisu," << " on ne tiens pas compte de la liste fournie !! "; lis_sor=liste_sauve; // récup de la liste sauvée if (ParaGlob::NiveauImpression() >= 4) cout << "\n Increment_vrml::Lecture_parametres_OrdreVisu(.."; } // on passe à un nouvel enregistrement entreePrinc.NouvelleDonneeCVisu(); } }; // écriture des paramètres de l'ordre dans un flux void Increment_vrml::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc) { // récup du flot ostream & sort = (*(entreePrinc.Sort_CommandeVisu())); // on commente le fonctionnement sort << "\n # ----------------------------- definition de la liste des increments a balayer: ---------------- " << "\n debut_list_increment # un mot cle de debut de liste "; // appel de l'ordre de la classe mère OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc); // puis la liste des incréments sort << "\n # une liste d'entier separee par des blancs, ou le mot cle (tous_les_increments) " << "\n # un mot cle de fin de liste ( fin_list_increment)" << "\n"; bool cas_simple=false; if ( lis_sor == (*lis_inc)) { sort << " tous_les_increments "; cas_simple=true; } // on regarde si c'est tous-les-incréments sans le premier incrément // on crée une liste intermédiaire de travail list lis_sor_inter = lis_sor; lis_sor_inter.push_front(*(lis_inc->begin()));// on rajoute le premier à la liste inter if ( lis_sor_inter == (*lis_inc)) { sort << " tous_les_increments_moins_zero "; cas_simple=true; } // on regarde si ce n'est pas uniquement le dernier incrément if (lis_sor.size() > 0) // on ne regarde que si la liste n'est pas vide { list ::iterator iincre = lis_sor.end();iincre--; if ((lis_sor.size() == 1) && (*(lis_sor.begin())== *iincre)) {sort << " dernier_increment "; cas_simple=true; } }; if(!cas_simple) { // cas ou la liste est différente de la liste complète // on sort la liste des incréments à balayer, par paquet de 100 maxi sur chaque ligne list::const_iterator ili,ilifin=lis_sor.end(); int compteur=0; for (ili=lis_sor.begin();ili!=ilifin;ili++,compteur++) { sort << " " << (*ili); if (compteur > 50) {compteur = 0; sort << "\n";}} } sort << " fin_list_increment \n"; };