422 lines
19 KiB
C++
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-2021 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";
|
||
|
};
|
||
|
|
||
|
|