Herezh_dev/Resultats/VRML/Increment_vrml.cc
2023-05-03 17:23:49 +02:00

422 lines
19 KiB
C++

// 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 "Increment_vrml.h"
#include <iomanip>
#include <algorithm>
#include "CharUtil.h"
#include <limits>
// 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 <int>::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<int>::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 <int>::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 <int>::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<std::streamsize>::max(), '\n' );// purge de cin
// on repère les deux bornes dans la liste
list<int>::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<std::streamsize>::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<int>::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<int>::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<int>::iterator idepfin = lis_sor.end();
list<int>::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<int>::iterator idepfin = lis_sor.end();
list<int>::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<int>::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 <int>::iterator ider = ikfin; ider--; int derIncr= *ider;
list<int>::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 <int>::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 <int> 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 <int>::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 <int>::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 <int> 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 <int>::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<int>::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";
};