Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYCalculManager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
22 #include <qcursor.h>
23 #include <qmessagebox.h>
24 #include <QTemporaryFile>
25 
26 #include "Tympan/core/config.h"
27 #include "Tympan/core/chrono.h"
28 #include "Tympan/core/defines.h"
32 #include "Tympan/gui/app/os.h"
40 #include "TYCalculManager.h"
41 
42 #define TR(id) OLocalizator::getString("TYCalculManager", (id))
43 
44 using namespace tympan;
45 
47 {
48  _pCurrentCalcul = NULL;
49 }
50 
52 {
53  _pCurrentCalcul = NULL;
54 }
55 
57 {
58  _pCurrentCalcul = pCalcul;
59 }
60 
62 {
63  return launch(_pCurrentCalcul);
64 }
65 
67 {
68  if (!pCalcul)
69  {
70  return false;
71  }
72 
73  if (pCalcul->getState() == TYCalcul::Locked)
74  {
75  OMessageManager::get()->info("+++ UN RESULTAT MESURE NE PEUX FAIRE L'OBJET D'UN CALCUL +++");
76  return true; // Si le calcul est bloque, il ne peut etre execute
77  }
78  // Keep track of old objects in order to clean them at best
79  // Issue #226
80  LPTYProjet oldProjet = pCalcul->getProjet();
81  LPTYSiteNode oldSite = oldProjet->getSite();
82  LPTYCalcul oldCalcul = oldProjet->getCurrentCalcul();
83 
84  TYProjet* pProject = pCalcul->getProjet();
85 
86  // Clear "calcul" result data before computing (avoid problems when removing some elements)
87  pCalcul->clearResult();
88 
90 
91  // Is the debug option "TYMPAN_DEBUG=keep_tmp_files" enabled?
92  bool keep_tmp_files = must_keep_tmp_files();
93  // Temporary XML files to give the current acoustic problem to the python
94  // script and get the results
95  QTemporaryFile problemfile;
96  problemfile.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
97  QTemporaryFile resultfile;
98  resultfile.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
99  QTemporaryFile meshfile;
100  meshfile.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.ply"));
101  if (!init_tmp_file(problemfile, keep_tmp_files) || !init_tmp_file(resultfile, keep_tmp_files) ||
102  !init_tmp_file(meshfile, keep_tmp_files))
103  {
104  logger.error(
105  "Creation de fichier temporaire impossible. Veuillez verifier l'espace disque disponible.");
106  return false;
107  }
108  // Serialize current project
109  try
110  {
111  save_project(problemfile.fileName().toUtf8().data(), pProject);
112  }
113  catch (const tympan::invalid_data& exc)
114  {
115  ostringstream msg;
116  msg << boost::diagnostic_information(exc);
117  logger.error("Could not export current project. Computation won't be done");
118  logger.debug(msg.str().c_str());
119  return false;
120  }
121  if (keep_tmp_files)
122  {
123  logger.debug("Le calcul va s'executer en mode debug.\nLes fichiers temporaires ne seront pas "
124  "supprimes une fois le calcul termine.\nProjet courant non calcule: %s. Projet avec les "
125  "resultats du calcul: %s. Mesh de l'altimetrie au format ply: %s",
126  problemfile.fileName().toStdString().c_str(),
127  resultfile.fileName().toStdString().c_str(), meshfile.fileName().toStdString().c_str());
128  }
129 
130  // Call python script "solve_tympan_project.py" with: the name of the file
131  // containing the problem, the name of the file where to record
132  // the result and the directory containing the solver plugin to use
133  // to solve the acoustic problem
134  QStringList args;
135  QString absolute_plugins_path(QCoreApplication::applicationDirPath());
136  absolute_plugins_path.append("/");
137  absolute_plugins_path.append(PLUGINS_PATH);
138  QString absolute_pyscript_path(QCoreApplication::applicationDirPath());
139  absolute_pyscript_path.append("/");
140  absolute_pyscript_path.append(SOLVE_PYSCRIPT);
141  args << absolute_pyscript_path << problemfile.fileName() << resultfile.fileName() << meshfile.fileName()
142  << absolute_plugins_path;
143 
144  // Altimetry parameters
145  QString parameters = pCalcul->solverParams;
146  QRegExp altimetry_size_criterion_reg("(MeshElementSizeMax\\s?=\\s?)([0-9]+.[0-9]*)");
147  QRegExp altimetry_refine_mesh_reg("(RefineMesh\\s?=\\s?)(True|False)");
148  QRegExp altimetry_use_volumes_landtakes_reg("(UseVolumesLandtake\\s?=\\s?)(True|False)");
149  int pos_size = altimetry_size_criterion_reg.indexIn(parameters);
150  int pos_refi = altimetry_refine_mesh_reg.indexIn(parameters);
151  int pos_land = altimetry_use_volumes_landtakes_reg.indexIn(parameters);
152  if (pos_size > -1 && pos_refi > -1 && pos_land > -1)
153  {
154  QString altimetry_size_criterion = altimetry_size_criterion_reg.cap(2);
155  QString altimetry_refine_mesh = altimetry_refine_mesh_reg.cap(2);
156  QString altimetry_use_volumes_landtakes = altimetry_use_volumes_landtakes_reg.cap(2);
157  args << altimetry_size_criterion << altimetry_refine_mesh << altimetry_use_volumes_landtakes;
158  }
159 
160  logger.info(TR("id_msg_go_calcul"));
161 
162  if (!python_gui(args))
163  {
164  return false;
165  }
166  // Then read the result to update the internal model
167  LPTYProjet result;
168  try
169  {
170  result = load_project(resultfile.fileName().toUtf8().data());
171  }
172  catch (const tympan::invalid_data& exc)
173  {
174  ostringstream msg;
175  msg << boost::diagnostic_information(exc);
176  logger.error("Could not import computed project. No results available.");
177  logger.debug(msg.str().c_str());
178  QMessageBox msgBox;
179  msgBox.setText("Le fichier de resultats n'a pas pu etre lu.");
180  msgBox.exec();
181  return false;
182  }
183  // Update the current project with the results of the current acoustic
184  // problem
185  pProject = result.getRealPointer();
186  pCalcul = pProject->getCurrentCalcul();
187  getTYApp()->setCurProjet(result);
188  getTYMainWnd()->getProjetFrame()->setProjet(pProject);
189  // Update site altimetry with the mesh retrieved from the ply file
190  LPTYSiteNode pSite = pProject->getSite();
191  std::deque<OPoint3D> points;
192  std::deque<OTriangle> triangles;
193  std::deque<LPTYSol> materials;
194  pSite->readMesh(points, triangles, materials, meshfile.fileName());
195  pSite->getAltimetry()->plugBackTriangulation(points, triangles, materials);
196  pSite->updateAltiInfra();
197  pSite->updateAcoustique();
198  pProject->updateAltiRecepteurs();
199  // Update graphics
200  pCalcul->getParent()->updateGraphicTree();
201  pCalcul->updateGraphicTree();
202 
203  // Update modeler frames after computation
205 
206  // Clean at best old project, site and calcul by removing references on them
207  oldCalcul->setSite(NULL);
208  oldSite->setProjet(NULL);
209  oldProjet->remAllCalcul();
210  oldProjet->unsetSite();
211 
212  getTYMainWnd()->updateModelers(false, false);
214  // Update projet frame
216  // Reset ActionManager
217  // TODO Reset ActionManager for all modelers
219  // Computation achieved with success
220  logger.info(TR("id_msg_calcul_done"));
221  return true;
222 }
223 
225 {
226  bool ret = true;
227  TYCalcul* pCalcul = NULL;
228  TYProjet* pProjet = getTYApp()->getCurProjet().getRealPointer();
229  if (pProjet)
230  {
231  pCalcul = pProjet->getCurrentCalcul();
232  }
233  else
234  {
235  return true;
236  }
237 
238  if (pCalcul)
239  {
240  ret = true;
242 
243  /*// Question
244  int del = QMessageBox::Yes;
245  if (pCalcul->getIsAcousticModified())
246  {
247  del = QMessageBox::warning(getTYMainWnd(), getTYMainWnd()->windowTitle(),
248  TR("id_msg_del_resultat"), QMessageBox::Yes, QMessageBox::No);
249  }
250  if (del == QMessageBox::Yes)
251  {
252  // Ok pour effacer les resultats (uniquement si c'est un resultat calcule);
253  if (pCalcul->getState() == TYCalcul::Actif)
254  {
255  // Reset du resultat
256  pCalcul->getResultat()->purge();
257  for (unsigned int i=0 ; i<pProjet->getPointsControl().size() ; i++)
258  {
259  pProjet->getPointsControl()[i]->purge(pCalcul);
260  }
261 
262  pCalcul->setIsAcousticModified(false); // La calcul est a jour
263  }
264 
265  ret = true;
266  }
267  else
268  {
269  ret = false;
270  }*/
271  }
272 
273  return ret;
274 }
275 
277 {
278  bool ret = false;
279  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pElement);
280  if (pSite != nullptr)
281  {
282  pSite->updateAcoustique();
283  }
284  LPTYAcousticVolumeNode pAccVolNode = dynamic_cast<TYAcousticVolumeNode*>(pElement);
285  if (pAccVolNode._pObj != nullptr)
286  {
287  TYMessageManager::get()->info(TR("id_msg_go_updateacoustic"));
288 
289  TYApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
290 
291  // Calcul acoustique
292  ret = pAccVolNode->updateAcoustic();
293 
294  if (ret)
295  {
296  TYMessageManager::get()->info(TR("id_msg_updateacoustic_done"));
297  }
298  else
299  {
300  TYMessageManager::get()->info(TR("id_msg_updateacoustic_failed"));
301  }
302 
303  // MaJ graphique
304  pAccVolNode->getGraphicObject()->update(true);
305  getTYMainWnd()->updateModelers(false, false);
306 
307  TYApplication::restoreOverrideCursor();
308  }
309  else
310  {
311  LPTYAcousticLine pLine = dynamic_cast<TYAcousticLine*>(pElement);
312  if (pLine._pObj != nullptr)
313  {
314  TYMessageManager::get()->info(TR("id_msg_go_updateacoustic"));
315 
316  TYApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
317 
318  // Calcul acoustique
319  ret = pLine->updateAcoustic();
320 
321  if (ret)
322  {
323  TYMessageManager::get()->info(TR("id_msg_updateacoustic_done"));
324  }
325  else
326  {
327  TYMessageManager::get()->info(TR("id_msg_updateacoustic_failed"));
328  }
329 
330  // MaJ graphique
331  pLine->getGraphicObject()->update(true);
332  getTYMainWnd()->updateModelers(false, false);
333 
334  TYApplication::restoreOverrideCursor();
335  }
336  }
337 
338  return ret;
339 }
TYApplication * getTYApp()
Retourne le pointeur sur l'application.
TYMainWindow * getTYMainWnd()
Retourne le pointeur sur la fenetre principale.
pour l'application Tympan (fichier header)
#define TR(id)
Gestionnaire des calculs acoustiques. Il fait l'interface entre l'IHM et le gestionnaire de donnees p...
Fenetre principale de l'application Tympan (fichier header)
utilitaire pour la gestion des messages dans Tympan (fichier header)
Classe generique pour une fenetre de modeleur (fichier header)
Frame pour la gestion de projet (fichier header)
Frame pour la gestion de site (fichier header)
Classe Modeler specialisee pour l'edition des sites (fichier header)
virtual void debug(const char *message,...)
Definition: logging.cpp:151
virtual void error(const char *message,...)
Definition: logging.cpp:127
static OMessageManager * get()
Definition: logging.cpp:108
virtual void info(const char *message,...)
Definition: logging.cpp:143
T * getRealPointer()
Definition: smartptr.h:291
T * _pObj
The real pointer, must derived IRefCount.
Definition: smartptr.h:307
virtual bool updateAcoustic(const bool &force=false)
void reset()
Reinitialise l'historique.
void plugBackTriangulation(const std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const std::deque< LPTYSol > &materials)
plug back triangulation providfed by the TYTopographie
LPTYProjet getCurProjet()
Set/Get du projet courant.
void setCurProjet(LPTYProjet pProjet)
Set/Get du projet courant.
virtual ~TYCalculManager()
Destructeur.
bool launchCurrent()
Execute le calcul courant.
bool updateAcoustic(TYElement *pElement)
Appelle la methode de calcul acoustique du volume node passe.
bool askForResetResultat()
Previent l'utilisateur que le resultat va etre efface, si celui-ci est valide.
bool launch(LPTYCalcul pCalcul)
Execute un calcul.
void setCurrent(LPTYCalcul pCalcul)
Set du Calcul et Projet courant.
TYCalculManager()
Constructeur par defaut.
Calculation program.
Definition: TYCalcul.h:50
void clearResult()
Definition: TYCalcul.cpp:844
int getState()
Get calculation state.
Definition: TYCalcul.h:416
void setSite(LPTYSiteNode pSite)
Definition of the site on which the calculation will be done.
Definition: TYCalcul.cpp:867
@ Locked
Definition: TYCalcul.h:62
QString solverParams
Definition: TYCalcul.h:482
TYProjet * getProjet()
Definition: TYCalcul.cpp:68
TYElement * getParent() const
Definition: TYElement.h:699
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:915
void updateModelersAfterComputation(LPTYProjet &result)
TYProjetFrame * getProjetFrame()
Definition: TYMainWindow.h:76
void updateModelers(bool clipping=true, bool axesAndGrid=true, bool displayList=true)
TYModelerFrame * getCurrentModeler()
Definition: TYMainWindow.h:71
TYActionManager * getActionManager()
void setCalculDone(bool state)
void setProjet(LPTYProjet pProjet)
classe de definition d'un projet.
Definition: TYProjet.h:45
bool updateAltiRecepteurs()
Definition: TYProjet.cpp:599
LPTYSiteNode getSite()
Get du site.
Definition: TYProjet.h:169
void unsetSite()
Supprime la liaison avec le site.
Definition: TYProjet.cpp:522
LPTYCalcul getCurrentCalcul()
Set/Get du pointeur du Calcul courant.
Definition: TYProjet.h:426
void remAllCalcul()
Suppression de tous les elements.
Definition: TYProjet.cpp:517
void setProjet(const LPTYProjet pProjet)
Definition: TYSiteNode.cpp:478
LPTYAltimetrie getAltimetry() const
virtual void updateAcoustique(const bool &force=false)
virtual void updateAltiInfra()
Definition: TYSiteNode.cpp:715
void readMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, std::deque< LPTYSol > &materials, const QString &filename)
Definition: TYSiteNode.cpp:674
void save_project(const char *filename, const LPTYProjet &project)
save a project into an XML file
LPTYProjet load_project(const char *filename)
load an XML project file
bool python_gui(QStringList args)
Definition: os.cpp:29
Utilitaires pour les interactions entre l'interface graphique et le système (headers)
The base exception class for errors due to invalid data.
Definition: exceptions.h:60
bool must_keep_tmp_files()
bool init_tmp_file(QTemporaryFile &tmp_file, bool keep_file)
Utilitaires pour les interactions entre l'application tympan et des sous- processus python.
Utilities to load a project and a solver.