Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYSiteNode.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
16 #include <cstdlib>
17 #include <cassert>
18 #include <locale.h>
19 
20 #if TY_USE_IHM
23 #endif
24 
33 #include "Tympan/core/logging.h"
34 #include "Tympan/core/config.h"
35 #include <QDir>
36 
37 #include "TYSiteNode.h"
38 
39 #define TR(id) OLocalizator::getString("OMessageManager", (id))
40 
43 
44 bool almost_equal(double a, double b, double precision);
45 
46 #include <cstdio>
47 #include <QString>
48 
49 /*static*/ const QString& TYSiteNode::getTopoFilePath()
50 {
51  return _topoFilePath;
52 }
53 
54 /*static*/ void TYSiteNode::setTopoFilePath(const QString& path)
55 {
56  _topoFilePath = path;
57 }
58 
60 {
61  return _meshFilePath;
62 }
63 
64 void TYSiteNode::setMeshFilePath(const QString& path)
65 {
66  _meshFilePath = path;
67 }
68 
69 QString TYSiteNode::_topoFilePath = "";
70 
72  : _pProjet(NULL), _bEmpriseAsCrbNiv(false), _altiEmprise(0.0), _useTopoFile(0), _topoFileName(""),
73  _meshFilePath(""), _topoFileExtension(""), _echelle(1.0f), _nbFaceInfra(0), _root(false),
74  _SIGType(TYMPAN), _SIG_X(0.0), _SIG_Y(0.0), _SIG_OFFSET(0.0), _isTopoFileModified(false)
75 {
77 
78 #ifdef _WIN32
79  // CLM-NT35: Pb en debug avec string cast
80  QByteArray id = getStringID().toLatin1();
81  _topoFile = getTopoFilePath() + "/image_" + id.constData();
82 #else
83  _topoFile = getTopoFilePath() + "/image_" + getStringID().toLatin1().data();
84 #endif
85 
87  _pTopographie->setParent(this);
90 }
91 
93 {
94  *this = other;
95 }
96 
98 {
99  _listSiteNode.clear();
100 }
101 
103 {
104  if (this != &other)
105  {
106  TYElement::operator=(other);
107  _echelle = other._echelle;
109  _altiEmprise = other._altiEmprise;
111  _topoFile = other._topoFile;
115  _useTopoFile = other._useTopoFile;
118  _orientation = other._orientation;
119  _position = other._position;
120  _root = other._root;
122  _SIGType = other._SIGType;
123  _SIG_X = other._SIG_X;
124  _SIG_Y = other._SIG_Y;
125  _SIG_OFFSET = other._SIG_OFFSET;
126  }
127  return *this;
128 }
129 
130 bool TYSiteNode::operator==(const TYSiteNode& other) const
131 {
132  if (this != &other)
133  {
134  if (TYElement::operator!=(other))
135  {
136  return false;
137  }
138  if (_echelle != other._echelle)
139  {
140  return false;
141  }
143  {
144  return false;
145  }
146  if (_altiEmprise != other._altiEmprise)
147  {
148  return false;
149  }
150  if (_pTopographie != other._pTopographie)
151  {
152  return false;
153  }
154  if (_topoFile != other._topoFile)
155  {
156  return false;
157  }
158  if (_topoFileName != other._topoFileName)
159  {
160  return false;
161  }
162  if (_meshFilePath != other._meshFilePath)
163  {
164  return false;
165  }
167  {
168  return false;
169  }
170  if (_useTopoFile != other._useTopoFile)
171  {
172  return false;
173  }
175  {
176  return false;
177  }
178  if (_pInfrastructure != other._pInfrastructure)
179  {
180  return false;
181  }
182  if (_orientation != other._orientation)
183  {
184  return false;
185  }
186  if (_position != other._position)
187  {
188  return false;
189  }
190  if (_root != other._root)
191  {
192  return false;
193  }
194  if (!(_listSiteNode == other._listSiteNode))
195  {
196  return false;
197  }
198  if (_SIGType != other._SIGType)
199  {
200  return false;
201  }
202  if (_SIG_X != other._SIG_X)
203  {
204  return false;
205  }
206  if (_SIG_Y != other._SIG_Y)
207  {
208  return false;
209  }
210  if (_SIG_OFFSET != other._SIG_OFFSET)
211  {
212  return false;
213  }
214  }
215  return true;
216 }
217 
218 bool TYSiteNode::operator!=(const TYSiteNode& other) const
219 {
220  return !operator==(other);
221 }
222 
223 bool TYSiteNode::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
224 {
225  if (!TYElement::deepCopy(pOther, copyId))
226  {
227  return false;
228  }
229 
230  TYSiteNode* pOtherSite = (TYSiteNode*)pOther;
231 
232  _echelle = pOtherSite->_echelle;
233  _bEmpriseAsCrbNiv = pOtherSite->_bEmpriseAsCrbNiv;
234  _altiEmprise = pOtherSite->_altiEmprise;
235  _topoFile = pOtherSite->_topoFile;
236  _topoFileName = pOtherSite->_topoFileName;
237  _meshFilePath = pOtherSite->_meshFilePath;
239  _useTopoFile = pOtherSite->_useTopoFile;
241  _pTopographie->deepCopy(pOtherSite->_pTopographie, copyId);
242  _pTopographie->setParent(this);
243  _pInfrastructure->deepCopy(pOtherSite->_pInfrastructure, copyId);
245  _orientation.deepCopy(&pOtherSite->_orientation, copyId);
246  _position.deepCopy(&pOtherSite->_position, copyId);
247  _root = pOtherSite->_root;
248  _SIGType = pOtherSite->_SIGType;
249  _SIG_X = pOtherSite->_SIG_X;
250  _SIG_Y = pOtherSite->_SIG_Y;
251  _SIG_OFFSET = pOtherSite->_SIG_OFFSET;
252 
253  _listSiteNode.clear();
254  for (unsigned int i = 0; i < pOtherSite->_listSiteNode.size(); i++)
255  {
256  LPTYSiteNodeGeoNode pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
257  pSiteNodeGeoNode->deepCopy(pOtherSite->_listSiteNode[i], copyId);
258  pSiteNodeGeoNode->getElement()->setParent(this);
259  pSiteNodeGeoNode->setParent(this);
260  _listSiteNode.push_back(pSiteNodeGeoNode);
261  }
262 
263  return true;
264 }
265 
266 std::string TYSiteNode::toString() const
267 {
268  return "TYSiteNode";
269 }
270 
272 {
273  DOM_Element domNewElem = TYElement::toXML(domElement);
274 
275  TYXMLTools::addElementFloatValue(domNewElem, "echelle", _echelle);
276  TYXMLTools::addElementBoolValue(domNewElem, "useEmpriseAsCrbNiv", _bEmpriseAsCrbNiv);
277  TYXMLTools::addElementBoolValue(domNewElem, "useTopoFile", _useTopoFile);
278 
279  if (TYXMLManager::getSavedFileName() == QString(""))
280  {
281  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _topoFileName);
282  TYXMLTools::addElementStringValue(domNewElem, "meshFile", _meshFilePath);
283  }
284  else // si non, on ecrit le chemin relatif
285  {
286  QString xmlFile = TYXMLManager::getSavedFileName().replace('\\', '/');
287  QDir xmlFileDir = QDir(xmlFile.left(xmlFile.lastIndexOf('/')));
288  if (xmlFileDir.exists())
289  {
290  TYXMLTools::addElementStringValue(domNewElem, "topoFile",
291  xmlFileDir.relativeFilePath(_topoFileName));
292  TYXMLTools::addElementStringValue(domNewElem, "meshFile",
293  xmlFileDir.relativeFilePath(_meshFilePath));
294  }
295  else
296  {
297  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _topoFileName);
298  TYXMLTools::addElementStringValue(domNewElem, "topoFile", _meshFilePath);
299  }
300  }
301 
302  TYXMLTools::addElementDoubleValue(domNewElem, "altiEmprise", _altiEmprise);
303 
304  _orientation.toXML(domNewElem);
305  _position.toXML(domNewElem);
306 
307  _pTopographie->toXML(domNewElem);
308  _pInfrastructure->toXML(domNewElem);
309 
310  TYXMLTools::addElementIntValue(domNewElem, "root", _root);
311  TYXMLTools::addElementIntValue(domNewElem, "repere", _SIGType);
312  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_X", _SIG_X);
313  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_Y", _SIG_Y);
314  TYXMLTools::addElementDoubleValue(domNewElem, "SIG_OFFSET", _SIG_OFFSET);
315 
316  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
317  {
318  _listSiteNode[i]->toXML(domNewElem);
319  }
320 
321  return domNewElem;
322 }
323 
325 {
326  TYElement::fromXML(domElement);
327 
328  bool echelleOk = false;
329  QString topoFile;
330  QString meshFile;
331  bool topoFileOk = false;
332  bool meshFileOk = false;
333  bool empriseAsCrbNivOk = false;
334  bool altiEmpriseOk = false;
335  bool useTopoFileOk = false;
336  DOM_Element elemCur;
337 
338  QDomNodeList childs = domElement.childNodes();
339  unsigned int childcount = childs.length();
340  for (unsigned int i = 0; i < childcount; i++)
341  {
342  elemCur = childs.item(i).toElement();
343  OMessageManager::get()->info("Charge element de site %d/%d.", i + 1, childcount);
344 
345  TYXMLTools::getElementFloatValue(elemCur, "echelle", _echelle, echelleOk);
346  TYXMLTools::getElementBoolValue(elemCur, "useEmpriseAsCrbNiv", _bEmpriseAsCrbNiv, empriseAsCrbNivOk);
347  TYXMLTools::getElementBoolValue(elemCur, "useTopoFile", _useTopoFile, useTopoFileOk);
348  TYXMLTools::getElementStringValue(elemCur, "topoFile", topoFile, topoFileOk);
349  TYXMLTools::getElementStringValue(elemCur, "meshFile", meshFile, meshFileOk);
350  TYXMLTools::getElementDoubleValue(elemCur, "altiEmprise", _altiEmprise, altiEmpriseOk);
351 
353  _position.callFromXMLIfEqual(elemCur);
354 
357  }
358 
359  purge(); // On vide le tableau des sous-sites
360 
361  bool rootOk = false;
362  bool repereOk = false;
363  bool SIG_XOk = false;
364  bool SIG_YOk = false;
365  bool SIG_OFFSETOk = false;
366  int SIGType = 0;
367 
368  LPTYSiteNodeGeoNode pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
369  // DOM_Element elemCur;
370 
371  // QDomNodeList childs = domElement.childNodes();
372  for (unsigned int i = 0; i < childs.length(); i++)
373  {
374  elemCur = childs.item(i).toElement();
375  TYXMLTools::getElementBoolValue(elemCur, "root", _root, rootOk);
376  TYXMLTools::getElementIntValue(elemCur, "repere", SIGType, repereOk);
377  TYXMLTools::getElementDoubleValue(elemCur, "SIG_X", _SIG_X, SIG_XOk);
378  TYXMLTools::getElementDoubleValue(elemCur, "SIG_Y", _SIG_Y, SIG_YOk);
379  TYXMLTools::getElementDoubleValue(elemCur, "SIG_OFFSET", _SIG_OFFSET, SIG_OFFSETOk);
380 
381  if (pSiteNodeGeoNode->callFromXMLIfEqual(elemCur))
382  {
383  addSiteNode(pSiteNodeGeoNode);
384  pSiteNodeGeoNode = new TYSiteNodeGeoNode(NULL, this);
385  }
386  }
387 
388  _SIGType = (systemSIG)SIGType;
389 
390  if (_useTopoFile && topoFileOk)
391  {
392  _topoFileName = topoFile;
395  }
397  if (meshFileOk)
398  {
399  // 1) Normalisation et traces d’entrée
400  const QString meshFileNorm = QDir::fromNativeSeparators(meshFile);
401 
402  // 2) Récupération du dossier du XML
403  QString xmlDir;
404  const QString saved = QDir::fromNativeSeparators(TYXMLManager::getSavedFileName());
405 
406  if (!saved.isEmpty())
407  {
408  const QFileInfo sfi(saved);
409  const bool savedIsDir = sfi.isDir();
410  const QString candidate = savedIsDir ? sfi.absoluteFilePath() : sfi.absolutePath();
411  const bool candidateExists = QDir(candidate).exists();
412 
413  if (candidateExists)
414  {
415  xmlDir = candidate;
416  }
417  }
418 
419  // 3) Décision du chemin mesh : absolu VS relatif
420  const QFileInfo mfi(meshFileNorm);
421  const bool isAbs = mfi.isAbsolute();
422  if (isAbs)
423  {
424  _meshFilePath = mfi.absoluteFilePath();
425  }
426  else if (!xmlDir.isEmpty())
427  {
428  _meshFilePath = QDir(xmlDir).filePath(meshFileNorm);
429  }
430  else
431  {
432  _meshFilePath = meshFileNorm;
433  }
434 
435  // 4) Lancement de la lecture + traces tailles
436  std::deque<OPoint3D> points;
437  std::deque<OTriangle> triangles;
438  std::deque<LPTYSol> materials;
439 
440  logger->debug("[DBG][fromXML] Appel readMesh(...) avec _meshFilePath = %s",
441  qUtf8Printable(_meshFilePath));
442  if (readMesh(points, triangles, materials, _meshFilePath))
443  {
444  logger->debug("[DBG][fromXML] readMesh terminé: points=%zu, triangles=%zu, materials=%zu",
445  points.size(), triangles.size(), materials.size());
446 
447  // 5) Suite du pipeline + traces d’état
448  getAltimetry()->plugBackTriangulation(points, triangles, materials);
449  setIsGeometryModified(false);
450  getAltimetry()->setIsUpToDate(true);
451  }
452  else
453  {
454  logger->debug("[DBG][fromXML] Echec readMesh(...) avec _meshFilePath = %s",
455  qUtf8Printable(_meshFilePath));
456  _meshFilePath = QString{};
457  getAltimetry()->setIsUpToDate(false);
458  }
459  }
460  else
461  {
462  if (_root)
463  {
464  logger->info("[DBG][fromXML] meshFileOk=false -> pas de lecture");
465  _meshFilePath = QString{};
466  getAltimetry()->setIsUpToDate(false);
467  }
468  }
469 
470  return 1;
471 }
472 
473 void TYSiteNode::getChilds(LPTYElementArray& childs, bool recursif /*=true*/)
474 {
475  TYElement::getChilds(childs, recursif);
476 
477  childs.push_back(_pTopographie);
478  childs.push_back(_pInfrastructure);
479 
480  if (recursif)
481  {
482  _pTopographie->getChilds(childs, recursif);
483  _pInfrastructure->getChilds(childs, recursif);
484  }
485 
486  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
487  {
488  childs.push_back(_listSiteNode[i]);
489  childs.push_back(_listSiteNode[i]->getElement());
490  }
491 
492  if (recursif)
493  {
494  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
495  {
496  _listSiteNode[i]->getChilds(childs, recursif);
497  }
498  }
499 }
500 
502 {
504 
505  if (!_root && _pParent)
506  {
507  _pParent->setIsGeometryModified(isModified);
508  }
509 }
510 
512 {
513  bool res = _pInfrastructure->addToCalcul(); // Ajoute les elements du site lui-meme dans le calcul
514  res = res && (_pInfrastructure->addToCalcul());
515 
516  if (res && _listSiteNode.size())
517  {
518  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
519  {
520  res = res && (TYSiteNode::safeDownCast(_listSiteNode[i]->getElement()))->addToCalcul();
521  }
522  }
523 
524  return res;
525 }
526 
528 {
529  bool res = _pInfrastructure->remFromCalcul();
530  res = res && _pInfrastructure->remFromCalcul();
531  ;
532 
533  if (res && _listSiteNode.size())
534  {
535  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
536  {
537  res = res && (TYSiteNode::safeDownCast(_listSiteNode[i]->getElement()))->remFromCalcul();
538  }
539  }
540 
541  return res;
542 }
543 
544 void TYSiteNode::updateCurrentCalcul(TYListID& listID, bool recursif) //=true
545 {
546  if (recursif) // On parcours les enfants si besoin est...
547  {
548  // Collecte des childs
549  LPTYElementArray childs;
550  getChilds(childs, false);
551  for (int i = 0; i < childs.size(); i++)
552  {
553  childs[i]->updateCurrentCalcul(listID, recursif);
554  }
555  }
556 
557  TYElement::updateCurrentCalcul(listID, false);
558 }
559 
561 {
562  _pProjet = pProjet;
563  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
564  {
565  TYSiteNode::safeDownCast(_listSiteNode[i]->getElement())->setProjet(pProjet);
566  }
567 }
568 
570 {
573 
574  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
575  {
576  TYSiteNode::safeDownCast(_listSiteNode[i]->getElement())->reparent();
577  }
578 }
579 
580 void TYSiteNode::loadTopoFile(const QString& fileName)
581 {
582  _topoFileName = fileName;
583  loadTopoFile();
584 }
585 
587 {
588  QFile file(_topoFileName);
590  logger.info("Charge fichier topographique %s", qUtf8Printable(_topoFileName));
591 
592  // Open the file
593  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
594  {
595  logger.error("Erreur durant l'ouverture du fichier %s", qUtf8Printable(_topoFileName));
596  return;
597  }
598 
599  // Read all data from the file
600  QByteArray buffer = file.readAll();
601 
602  // Close the file
603  file.close();
604 
605  // Check if the file read was successful
606  if (buffer.isEmpty())
607  {
608  logger.error("Erreur durant la lecture du fichier %s", qUtf8Printable(_topoFileName));
609  return;
610  }
611 
612  // Convert QByteArray to char*
613  const char* data = buffer.constData();
614  size_t dataSize = buffer.size();
615 
616  /* the whole file is now loaded in the memory buffer. */
617 
618  // Mise a jour du flag.
619  _isTopoFileModified = true;
620 
621  // On conserve l'extension de l'image = son type
622  QFileInfo topoFileInfo(_topoFileName);
623  _topoFileExtension = topoFileInfo.suffix();
624 
625  setIsGeometryModified(true);
626 }
627 
628 /*virtual*/ bool TYSiteNode::updateAltimetrie(QString resultMeshFilePath)
629 {
630  std::ostringstream msg;
632  try
633  {
634  do_updateAltimetrie(resultMeshFilePath);
635  return true;
636  }
637  catch (const tympan::exception& exc)
638  {
639  msg << boost::diagnostic_information(exc);
640  logger.error("An error prevented to update the altimetry (set log level to debug for diagnostic)");
641  logger.debug(msg.str().c_str());
642  return false;
643  }
644 }
645 
646 /*virtual*/ void TYSiteNode::do_updateAltimetrie(QString resultMeshFilePath)
647 {
649 
650  // disables element names automatic generation (subsites fusion etc)
651  TYNameManager::get()->enable(false);
652 
653  logger.info("Mise a jour altimetrie...");
654 
655  // Is the debug option "TYMPAN_DEBUG=keep_tmp_files" enabled?
656  bool keep_tmp_files = must_keep_tmp_files();
657  // Will be used to export the current site topography/infrastructure
658  QTemporaryFile current_project;
659  current_project.setFileTemplate(QDir::tempPath() + QString("/XXXXXX.xml"));
660  // Here will go the mesh result in a PLY Polygon formatted file
661  //(see http://www.cs.virginia.edu/~gfx/Courses/2001/Advanced.spring.01/plylib/Ply.txt)
662  if (!init_tmp_file(current_project, keep_tmp_files))
663  {
664  logger.error(
665  "Creation de fichier temporaire impossible. Veuillez verifier l'espace disque disponible.");
667  }
668  try
669  {
670  tympan::save_project(current_project.fileName().toUtf8().data(), _pProjet);
671  }
672  catch (const tympan::invalid_data& exc)
673  {
674  std::ostringstream msg;
675  msg << boost::diagnostic_information(exc);
676  logger.error("Impossible d'exporter le projet courant pour calculer l'altimetrie.");
677  TYNameManager::get()->enable(true);
678  throw;
679  }
680  if (keep_tmp_files)
681  {
682  logger.debug("Le calcul va s'executer en mode debug.\nLes fichiers temporaires ne seront pas "
683  "supprimes une fois le calcul termine.\nProjet courant non calcule: %s Projet avec les "
684  "resultats du calcul: %s.",
685  current_project.fileName().toStdString().c_str());
686  }
687 
688  // Call python script "process_site_altimetry.py" with: the name of the file
689  // containing the site description, and the name of the file where to record
690  // the result
691  QStringList args;
692  QString absolute_pyscript_path(QCoreApplication::applicationDirPath());
693  absolute_pyscript_path.append("/");
694  absolute_pyscript_path.append(ALTIMETRY_PYSCRIPT);
695  args << absolute_pyscript_path << current_project.fileName() << resultMeshFilePath;
696 
697  // Altimetry parameters
698  QString parameters = _pProjet->getCurrentCalcul()->solverParams;
699  QRegularExpression altimetry_size_criterion_reg("(MeshElementSizeMax\\s?=\\s?)([0-9]+.[0-9]*)");
700  QRegularExpression altimetry_refine_mesh_reg("(RefineMesh\\s?=\\s?)(True|False)");
701  QRegularExpression altimetry_use_volumes_landtakes_reg("(UseVolumesLandtake\\s?=\\s?)(True|False)");
702  QRegularExpressionMatch match_size = altimetry_size_criterion_reg.match(parameters);
703  QRegularExpressionMatch match_refi = altimetry_refine_mesh_reg.match(parameters);
704  QRegularExpressionMatch match_land = altimetry_use_volumes_landtakes_reg.match(parameters);
705  if (match_size.hasMatch() && match_refi.hasMatch() && match_land.hasMatch())
706  {
707  QString altimetry_size_criterion = match_size.captured(2);
708  QString altimetry_refine_mesh = match_refi.captured(2);
709  QString altimetry_use_volumes_landtakes = match_land.captured(2);
710  args << altimetry_size_criterion << altimetry_refine_mesh << altimetry_use_volumes_landtakes;
711  }
712 
713  logger.info("Lancement d'un sous-processus python pour calculer l'altimetrie avec le script: %s",
714  absolute_pyscript_path.toStdString().c_str());
715  std::string error_msg;
716  if (!python(args, error_msg))
717  {
718  logger.error("Echec du calcul de l'altimetrie: %s", error_msg.c_str());
719  TYNameManager::get()->enable(true);
721  }
722  std::deque<OPoint3D> points;
723  std::deque<OTriangle> triangles;
724  std::deque<LPTYSol> materials;
725  readMesh(points, triangles, materials, resultMeshFilePath);
726  setMeshFilePath(resultMeshFilePath);
727  getAltimetry()->plugBackTriangulation(points, triangles, materials);
728  setIsGeometryModified(false); // L'altimetrie est a jour
730  OMessageManager::get()->info("Mise a jour altimetrie terminee.");
731  TYNameManager::get()->enable(true);
732 }
733 
734 bool TYSiteNode::readMesh(std::deque<OPoint3D>& points, std::deque<OTriangle>& triangles,
735  std::deque<LPTYSol>& materials, const QString& meshFilePath)
736 {
737  // CAUTION: reader uses rply C library which calls strtod (stdlib) to read float
738  // and double values. strtod is locale dependent. It means that if decimal
739  // separator is set to ',' instead of '.' in LC_NUMERIC, float values from
740  // the ply file won't be read. To make sure this doesn't happen, temporarily
741  // set the locale and then put back the original value after file reading.
742  char* saved_locale = setlocale(LC_NUMERIC, "C");
743  FILE* fp = tympan::AltimetryPLYReader::openFileForReading(meshFilePath);
745  if (!fp)
746  {
747  logger.error("Echec d'ouverture du fichier ply : %s", qUtf8Printable(meshFilePath));
748  return false;
749  }
750  logger.debug("Ouverture du fichier ply reussie : %s", qUtf8Printable(meshFilePath));
751  tympan::AltimetryPLYReader reader(fp);
752  reader.read();
753  setlocale(LC_NUMERIC, saved_locale);
754  points = reader.points();
755  triangles = reader.faces();
756  std::deque<std::string> material_ids = reader.materials();
757  uuid2tysol(material_ids, materials);
758  return true;
759 }
760 
761 void TYSiteNode::uuid2tysol(const std::deque<std::string>& material_ids, std::deque<LPTYSol>& materials)
762 {
764  TYSol* ground = nullptr;
765  for (int i = 0; i < material_ids.size(); i++)
766  {
767  ground = dynamic_cast<TYSol*>(TYElement::getInstance(OGenID(QString(material_ids[i].c_str()))));
768  if (ground != NULL)
769  {
770  materials.push_back(ground);
771  }
772  else
773  {
774  logger.debug(
775  "Unknown material retrieved from altimetry mesh: id = %s. Using default material instead",
776  material_ids[i].c_str());
777  materials.push_back(_pTopographie->getDefTerrain()->getSol());
778  }
779  }
780 }
781 
782 // TODO : Split the huge method based on the type of infrastructure
783 // See https://extranet.logilab.fr/ticket/1508248
785 {
786  TYNameManager::get()->enable(false);
787 
788  TYAltimetrie* pAlti = getAltimetry();
789  bool modified = false;
790  OPoint3D pt;
791  unsigned int i = 0, j = 0;
792 
793  bool bNoPbAlti = true;
794 
795  // If the site node isn't a root site, compute its global transform matrix
796  // to look for the altitudes at the right place
797  OMatrix globalMatrix = getGlobalMatrix();
798 
799 #if WITH_NMPB
800  // Mise a jour de l'altitude pour les points des routes
801  for (j = 0; j < _pInfrastructure->getListRoute().size(); j++)
802  {
803  // La route
804  LPTYRouteGeoNode pGeoNode = _pInfrastructure->getListRoute()[j];
805  TYRoute* pRoute = _pInfrastructure->getRoute(j);
806 
807  bNoPbAlti &= pRoute->updateAltitudes(*pAlti, pGeoNode, globalMatrix);
808  modified = true; // As long as there is a road, it will be updated anyways.
809  }
810 #endif
811  // Mise a jour de l'altitude pour les points des reseaux transport
812  for (j = 0; j < _pInfrastructure->getListResTrans().size(); j++)
813  {
815 
816  // Hauteur au sol du reseau de transport
817  double hauteur = pResTrans->getHauteurMoyenne();
818 
819  // Matrice pour la position de cette element
820  OMatrix matrix = globalMatrix * _pInfrastructure->getListResTrans()[j]->getMatrix();
821  OMatrix matrixinv = matrix.getInvert();
822 
823  for (i = 0; i < pResTrans->getTabPoint().size(); i++)
824  {
825  // Passage au repere du site
826  pt = matrix * pResTrans->getTabPoint()[i];
827 
828  // Init
829  pt._z = 0.0;
830 
831  // Recherche de l'altitude
832  bNoPbAlti &= pAlti->updateAltitude(pt);
833 
834  // Ajout de la hauteur du reseau de transport
835  pt._z += hauteur;
836 
837  // Retour au repere d'origine
838  pResTrans->getTabPoint()[i] = matrixinv * pt;
839 
840  modified = true;
841  }
842 
843  pResTrans->setIsGeometryModified(false);
844  }
845 
846  // Mise a jour de l'altitude pour les batiments
847  for (j = 0; j < _pInfrastructure->getListBatiment().size(); j++)
848  {
850  TYBatiment* pBat = TYBatiment::safeDownCast(pBatGeoNode->getElement());
851 
852  // Recuperation de l'origine de l'element
853  pt = globalMatrix * pBatGeoNode->getORepere3D()._origin;
854 
855  // Hauteur par rapport au sol
856  double hauteur = pBatGeoNode->getHauteur();
857 
858  // Init
859  pt._z = 0.0;
860 
861  // Recherche de l'altitude
862  bNoPbAlti &= pAlti->updateAltitude(pt);
863 
864  pBatGeoNode->getORepere3D()._origin._z = pt._z + hauteur;
865 
866  pBat->setIsGeometryModified(false);
867  pBat = NULL;
868  modified = true;
869  }
870 
871  // Mise a jour de l'altitude pour les machines
872  for (j = 0; j < _pInfrastructure->getListMachine().size(); j++)
873  {
874  TYMachineGeoNode* pMachineGeoNode = _pInfrastructure->getListMachine()[j];
875  TYMachine* pMachine = TYMachine::safeDownCast(pMachineGeoNode->getElement());
876 
877  // Recuperation de l'origine de l'element
878  pt = globalMatrix * pMachineGeoNode->getORepere3D()._origin;
879 
880  // Hauteur par rapport au sol
881  double hauteur = pMachineGeoNode->getHauteur();
882 
883  // Init
884  pt._z = 0.0;
885 
886  // Recherche de l'altitude
887  bNoPbAlti &= pAlti->updateAltitude(pt);
888 
889  pMachineGeoNode->getORepere3D()._origin._z = pt._z + hauteur;
890 
891  pMachine->setIsGeometryModified(false);
892  pMachine = NULL;
893  modified = true;
894  }
895 
896  // Mise a jour de l'altitude pour les sources utilisateur
897  for (j = 0; j < _pInfrastructure->getSrcs().size(); j++)
898  {
899  // La source
902 
903  // Matrice pour la position de cette element
904  OMatrix matrix = globalMatrix * _pInfrastructure->getSrcs()[j]->getMatrix();
905  OMatrix matrixinv = matrix.getInvert();
906 
907  // Passage au repere du site
908  pt = matrix * *pSrc->getPos();
909 
910  // Init
911  pt._z = 0.0;
912 
913  // Recherche de l'altitude
914  bNoPbAlti &= pAlti->updateAltitude(pt);
915 
916  // Ajout de la hauteur
917  pt._z += pSrc->getHauteur();
918 
919  // Retour au repere d'origine
920  pt = matrixinv * pt;
921  pSrc->getPos()->_z = pt._z;
922 
923  // On va modifier la route (l'altitude seulement)
924  pSrc->setIsGeometryModified(false);
925 
926  modified = true;
927  }
928 
929  // Mise a jour de l'altitude pour les points des cours d'eau
930  for (j = 0; j < _pTopographie->getListCrsEau().size(); j++)
931  {
932  TYCoursEau* pCrsEau = _pTopographie->getCrsEau(j);
933 
934  // Matrice pour la position de cette element
935  OMatrix matrix = globalMatrix * _pTopographie->getListCrsEau()[j]->getMatrix();
936  OMatrix matrixinv = matrix.getInvert();
937 
938  for (i = 0; i < pCrsEau->getTabPoint().size(); i++)
939  {
940  // Passage au repere du site
941  pt = matrix * pCrsEau->getTabPoint()[i];
942 
943  // Init
944  pt._z = 0.0;
945 
946  // Recherche de l'altitude
947  bNoPbAlti &= pAlti->updateAltitude(pt);
948 
949  // Retour au repere d'origine
950  pCrsEau->getTabPoint()[i] = matrixinv * pt;
951 
952  modified = true;
953  }
954 
955  pCrsEau->setIsGeometryModified(false);
956  }
957 
958  // Mise a jour de l'altitude pour les points des terrains
959  for (j = 0; j < _pTopographie->getListTerrain().size(); j++)
960  {
961  TYTerrain* pTerrain = _pTopographie->getTerrain(j);
962 
963  // Matrice pour la position de cette element
964  OMatrix matrix = globalMatrix * _pTopographie->getListTerrain()[j]->getMatrix();
965  OMatrix matrixinv = matrix.getInvert();
966 
967  for (i = 0; i < pTerrain->getListPoints().size(); i++)
968  {
969  // Passage au repere du site
970  pt = matrix * pTerrain->getListPoints()[i];
971 
972  // Init
973  pt._z = 0.0;
974 
975  // Recherche de l'altitude
976  bNoPbAlti &= pAlti->updateAltitude(pt);
977 
978  // Retour au repere d'origine
979  pTerrain->getListPoints()[i] = matrixinv * pt;
980 
981  modified = true;
982  }
983 
984  pTerrain->setIsGeometryModified(false);
985  }
986 
987  // Warning if an object is not correctly altimetrized
988  if (!bNoPbAlti)
989  {
990  OMessageManager::get()->info(TR("msg_pbalti"));
991  }
992 
993  if (modified)
994  {
997  setIsGeometryModified(false);
998  }
999 
1000  OMessageManager::get()->info("Mise a jour altimetrie des infrastructures terminee.");
1001 
1002  TYNameManager::get()->enable(true);
1003 }
1004 
1005 void TYSiteNode::updateAcoustique(const bool& force)
1006 {
1007  if (_pProjet)
1008  {
1009  TYCalcul* pCalcul = _pProjet->getCurrentCalcul()._pObj;
1010  assert(pCalcul);
1011  _pInfrastructure->updateAcoustic(pCalcul, force);
1012  }
1013 
1014  for (unsigned short i = 0; i < _listSiteNode.size(); i++)
1015  {
1016  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1017 
1018  if (pSite && pSite->isInCurrentCalcul())
1019  {
1020  pSite->updateAcoustique(force);
1021  }
1022  }
1023 }
1024 
1026 {
1027  if (_pProjet)
1028  {
1029  return _pProjet->getDelaunayTolerence();
1030  }
1031 
1032  double delaunay(0.0001);
1033 #if TY_USE_IHM
1034  if (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "DelaunayTolerance"))
1035  {
1036  delaunay = TYPreferenceManager::getDouble(TYDIRPREFERENCEMANAGER, "DelaunayTolerance");
1037  }
1038  else
1039  {
1040  TYPreferenceManager::setDouble(TYDIRPREFERENCEMANAGER, "DelaunayTolerance", delaunay);
1041  }
1042 #endif
1043 
1044  delaunay = delaunay <= 0.0 ? 0.0001 : delaunay;
1045  return delaunay > 0.05 ? 0.05 : delaunay;
1046 }
1047 
1048 // az++ (revoir les faces des ecrans; il vaudrait mieux en ajouter proprement):
1049 // tableau d'index des faces ecrans
1050 // According to ticket https://extranet.logilab.fr/ticket/1459658 the notion
1051 // of ecran is obsolete
1052 // TODO remove cleanly related stuff
1053 std::vector<bool> EstUnIndexDeFaceEcran;
1054 
1055 void TYSiteNode::getListFacesWithoutFloor(TYTabAcousticSurfaceGeoNode& tabFaces, unsigned int& nbFaceInfra,
1056  std::vector<bool>& EstUnIndexDeFaceEcran,
1057  std::vector<std::pair<int, int>>& indices,
1058  std::vector<int>& etages) const
1059 {
1060  std::ofstream file;
1061  file.open("logsChargement.txt", std::ios::out | std::ios::trunc);
1062  file << "Chargement de la liste des faces." << std::endl;
1063 
1064  EstUnIndexDeFaceEcran.clear();
1065 
1066  unsigned int j = 0, i = 0;
1067  int compteurFace = 0;
1068  int compteurInfra = 0;
1070 
1071  tabFaces.clear();
1072 
1073  // Batiments
1074  for (i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1075  {
1076  file << "Chargement du batiment " << i << std::endl;
1077  // Si ce batiment est actif pour le calcul
1078  LPTYBatiment pBatiment = TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1079 
1080  if (pBatiment && pBatiment->isInCurrentCalcul())
1081  {
1082  tabTmp.clear();
1083 
1084  // Matrice de changement de repere pour ce batiment
1085  OMatrix matrix = _pInfrastructure->getListBatiment()[i]->getMatrix();
1086 
1087  for (j = 0; j < pBatiment->getTabAcousticVol().size(); j++)
1088  {
1089  // Attempt to cast volume to a TYEtage
1090  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(j));
1091  OMatrix matriceEtage = pBatiment->getTabAcousticVol().at(j)->getMatrix();
1092  if (pEtage)
1093  {
1094  // Récupération des faces des murs
1095  for (unsigned int k = 0; k < pEtage->getTabMur().size(); k++)
1096  {
1097  TYMur* mur = TYMur::safeDownCast(pEtage->getTabMur().at(k)->getElement());
1098  OMatrix matriceMur = pEtage->getTabMur().at(k)->getMatrix();
1099  if (mur)
1100  {
1101  file << "Récupération d'un mur rectangulaire." << std::endl;
1103  mur->getTabAcousticSurf().at(0)->getElement());
1104  if (pRect)
1105  {
1106  // Conversion de la face du mur en AcousticSurfaceGeoNode
1107  file << "Récupération d'un rectangle." << std::endl;
1108  file << "Ajout de la face " << compteurFace << ", etage " << j
1109  << ", batiment " << i << std::endl;
1111  new TYAcousticSurfaceGeoNode(pRect, matriceEtage * matriceMur));
1112  tabTmp.push_back(newNode);
1113  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1114  etages.push_back(j);
1115  }
1116  }
1117  }
1118 
1119  // Recovery of the upper floor only
1121  LPTYAcousticSurfaceGeoNode newNode =
1122  LPTYAcousticSurfaceGeoNode(new TYAcousticSurfaceGeoNode(poly, matriceEtage));
1123  tabTmp.push_back(newNode);
1124  indices.push_back(std::pair<int, int>(compteurFace++, (int)i));
1125  etages.push_back(j);
1126  }
1127  else
1128  {
1129  // try to cast as a screen (TYEcran)
1130  LPTYEcran pEcran = TYEcran::safeDownCast(pBatiment->getAcousticVol(j));
1131 
1132  if (pEcran)
1133  {
1135  tabTmp2 = pEcran->acousticFaces();
1136  for (unsigned k = 0; k < tabTmp2.size(); k++)
1137  {
1138  tabTmp2[k]->setMatrix(matriceEtage * tabTmp2[k]->getMatrix());
1139  tabTmp.push_back(tabTmp2[k]);
1140  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1141  etages.push_back(j);
1142  }
1143  }
1144  }
1145  }
1146 
1147  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(0));
1148  bool bEtageEcran = false;
1149  if (pEtage)
1150  {
1151  bEtageEcran = !pEtage->getClosed();
1152  }
1153  if (bEtageEcran)
1154  {
1155  pEtage->setacousticFacesPourCalcul(true);
1156  }
1157 
1158  // L'ensemble des faces de ce batiment
1159  // tabTmp =
1160  // TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement())->acousticFaces();
1161 
1162  bool bEcran = false; // element de type TYEcran
1163  // Next 3 lines commented, may be invalid (a building can't be a floor)
1164  // if (_pInfrastructure->getBatiment(i)->getElement()->isA("TYEcran"))
1165  //{
1166  // bEcran = true;
1167  //}
1168 
1169  // Pour chacune de ces faces
1170  for (j = 0; j < tabTmp.size(); j++)
1171  {
1172  // On concatene les matrices
1173  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1174 
1175  // Ajout de la face
1176  tabFaces.push_back(tabTmp[j]);
1177  EstUnIndexDeFaceEcran.push_back(bEtageEcran || bEcran);
1178  }
1179  if (bEtageEcran)
1180  {
1181  pEtage->setacousticFacesPourCalcul(false);
1182  }
1183  }
1184 
1185  compteurInfra++;
1186  }
1187 
1188  // Machines
1189  for (i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1190  {
1191  // Si cette machine est active pour le calcul
1193  if (pMachine && pMachine->isInCurrentCalcul())
1194  {
1195  tabTmp.clear();
1196 
1197  // Matrice de changement de repere pour cette machine
1198  OMatrix matrix = _pInfrastructure->getListMachine()[i]->getMatrix();
1199 
1200  // L'ensemble des faces de cette machine
1201  tabTmp = TYMachine::safeDownCast(_pInfrastructure->getMachine(i)->getElement())->acousticFaces();
1202 
1203  // Pour chacune de ces faces
1204  for (j = 0; j < tabTmp.size(); j++)
1205  {
1206  // On concatene les matrices
1207  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1208 
1209  // Ajout de la face
1210  tabFaces.push_back(tabTmp[j]);
1211  indices.push_back(std::pair<int, int>(compteurFace++, compteurInfra));
1212  EstUnIndexDeFaceEcran.push_back(false);
1213  etages.push_back(0);
1214  }
1215  }
1216  compteurInfra++;
1217  }
1218 
1219  nbFaceInfra =
1220  static_cast<uint32>(tabFaces.size()); // Determination du nombre de faces de l'infrastructure;
1221 
1222  // Les faces de la topographie (altimetrie) sont transformee en faces acoustiques
1223  // avec des proprietes acoustiques nulles
1224  // EstUnIndexDeFaceEcran n'est pas a affecter, car les faces d'infrastructures sont separees de celles de
1225  // l'alti, donc sachant ou commence les faces d'alti, le test "est un ecran" n'a pas de sens pour ces
1226  // dernieres
1227 
1228  // WIP here : the materials {c/sh}ould be stored in the TYAcousticPolygon
1229  // and thus be stored or exracted from the Altimetry ?
1230  // or is this data pulling from the solver to be replaced by data
1231  // pushing from the site to the model
1232  LPTYAltimetrie pAlti = getAltimetry();
1233  TYTabLPPolygon& listFacesAlti = pAlti->getListFaces();
1234  unsigned int nbFacesAlti = static_cast<uint32>(listFacesAlti.size());
1235 
1236  for (i = 0; i < nbFacesAlti; i++)
1237  {
1238  LPTYAcousticPolygon pAccPolygon = new TYAcousticPolygon();
1239  pAccPolygon->setParent(pAlti);
1240 
1241  // Geomtrie
1242  *pAccPolygon->getPolygon() = *listFacesAlti.at(i);
1243 
1244  // Ajout
1246  tabFaces.push_back(pNode);
1247  indices.push_back(std::pair<int, int>(compteurFace++, -1));
1248  etages.push_back(-1);
1249  }
1250 
1251  file.close();
1252 }
1253 
1255 {
1256  // As there is one only altimetry for all the subsites of the root site,
1257  // retrieve the altimetry from the root site and not from the current site.
1258  TYSiteNode const* rootsite = this;
1259  while (rootsite != nullptr && !rootsite->getRoot())
1260  {
1261  rootsite = dynamic_cast<TYSiteNode*>(rootsite->getParent());
1262  }
1263  if (rootsite != nullptr)
1264  return rootsite->getTopographie()->getAltimetrie();
1265  throw tympan::invalid_data("No root site node in current TYMPAN objects hierarchy.");
1266 }
1267 
1269 {
1270  if (getRoot())
1271  {
1272  return OMatrix(); // identity matrix at the root site
1273  }
1274  TYSiteNode const* parentsite = dynamic_cast<TYSiteNode*>(getParent());
1275  if (parentsite == nullptr)
1276  {
1277  return OMatrix();
1278  // should throw an exception
1279  }
1280 
1281  for (int i = 0; i < parentsite->_listSiteNode.size(); i++)
1282  {
1283  TYSiteNode const* subsite = dynamic_cast<TYSiteNode*>(parentsite->_listSiteNode[i]->getElement());
1284  if (subsite->getID() == getID())
1285  {
1286  return parentsite->getGlobalMatrix() * parentsite->_listSiteNode[i]->getMatrix();
1287  }
1288  }
1289  return OMatrix(); // this should not happen
1290 }
1291 
1292 bool almost_equal(double a, double b, double precision)
1293 {
1294  return abs(a - b) < abs(precision);
1295 }
1296 
1297 void TYSiteNode::groundBasedFaces(const TYTabAcousticVolumeGeoNode& volumes, const OMatrix& global_matrix,
1298  std::map<TYUUID, std::deque<TYTabPoint3D>>& contours) const
1299 {
1300  // Go through all the faces of the all the input volumes
1301  for (unsigned int i = 0; i < volumes.size(); i++)
1302  {
1303  OMatrix matrix = volumes[i]->getMatrix();
1304  matrix = global_matrix * matrix;
1305  TYAcousticVolume* volume = dynamic_cast<TYAcousticVolume*>(volumes[i]->getElement());
1306  assert(volume != nullptr &&
1307  "found an object which isn't a TYAcousticVolume in a TYTabAcousticVolumeGeoNode");
1308  TYTabAcousticSurfaceGeoNode faces = volume->acousticFaces();
1309  TYTabPoint3D contour;
1310  double tol = 10e-6;
1311  for (unsigned int j = 0; j < faces.size(); j++)
1312  {
1313  // Compute global matrix for the current face (do NOT modify the object)
1314  OMatrix face_matrix = matrix * faces[j]->getMatrix();
1315  TYAcousticSurface* pFace = dynamic_cast<TYAcousticSurface*>(faces[j]->getElement());
1316 
1317  // Take the contour of the acoustic face, move the points to a global scale
1318  // and make a polygon with them
1319  contour = pFace->getOContour();
1320  TYPolygon poly;
1321  for (unsigned int k = 0; k < contour.size(); k++)
1322  {
1323  contour[k] = face_matrix * contour[k];
1324  poly.getPoints().push_back(TYPoint(contour[k]));
1325  }
1326  // Compute polygon' normal
1327  poly.updateNormal();
1328  OVector3D normal = poly.normal();
1329  // We are looking for the floor-based face of the volumes. We keep the
1330  // current face if it is parallel to the ground
1331  if (!almost_equal(abs(normal.scalar(OVector3D(0., 0., 1.))), 1., tol))
1332  continue;
1333  // only keep the face if it is on or below the ground
1334  if (contour[0]._z < tol)
1335  {
1336  contours[volume->getID()].push_back(contour);
1337  }
1338  }
1339  }
1340 }
1341 
1342 void TYSiteNode::getFacesOnGround(std::map<TYUUID, std::deque<TYTabPoint3D>>& contours) const
1343 {
1344  assert(contours.empty() &&
1345  "Output argument 'contours' is supposed to be empty when calling 'TYSiteNode::getFacesOnGround'");
1346  // Buildings
1347  for (unsigned int i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1348  {
1349  // We get the geonode information : position and height of the building
1351  // If the building is not supposed to touch the ground, there is no need to get its contour
1352  if (gBatiment->getHauteur() != 0)
1353  {
1354  continue;
1355  }
1356  // If it does touch the ground, we force z=0 for the computation only,
1357  // without modifying the model (no setPosition side effects).
1358  else
1359  {
1360  LPTYBatiment pBuilding = dynamic_cast<TYBatiment*>(gBatiment->getElement());
1361  assert(pBuilding != nullptr &&
1362  "found an object which is not a TYBatiment in _pInfrastructure->getListBatiment()");
1363  // If this building is active in the current simulation
1364  if (pBuilding->isInCurrentCalcul())
1365  {
1366  // Building transform matrix
1367  OMatrix matrix = _pInfrastructure->getBatiment(i)->getMatrix();
1368  matrix._m[2][3] = 0.0; // Force Z translation to 0 for computation only
1369 
1370  TYTabAcousticVolumeGeoNode& building_volumes = pBuilding->getTabAcousticVol();
1371  // 1 TYTabPoint3D per volume face on the ground. Indeed there may be several,
1372  // since buildings and machines are volume nodes wghich means they
1373  // are made of one or more volumes.
1374  std::deque<TYTabPoint3D> base_faces;
1375  // Get the base of the building
1376  groundBasedFaces(building_volumes, matrix, contours);
1377  }
1378  }
1379  }
1380  // Machines
1381  for (int i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1382  {
1383  // We get the geonode information : position and height of the building
1385  // If the machine is not supposed to touch the ground, there is no need to get its contour
1386  if (gMachine->getHauteur() != 0)
1387  {
1388  continue;
1389  }
1390  // If it does touch the ground, we force z=0 for the computation only,
1391  // without modifying the model (no setPosition side effects).
1392  else
1393  {
1394  // Si cette machine est active pour le calcul
1395  LPTYMachine pMachine = dynamic_cast<TYMachine*>(gMachine->getElement());
1396  assert(pMachine != nullptr &&
1397  "found an object which is not a TYMachine in _pInfrastructure->getListMachine()");
1398  if (pMachine->isInCurrentCalcul())
1399  {
1400  // Matrice de changement de repere pour cette machine
1401  OMatrix matrix = _pInfrastructure->getMachine(i)->getMatrix();
1402  matrix._m[2][3] = 0.0; // Force Z translation to 0 for computation only
1403 
1404  TYTabAcousticVolumeGeoNode machine_volumes = pMachine->getTabAcousticVol();
1405  std::deque<TYTabPoint3D> base_faces;
1406  // Get the base of the machine
1407  groundBasedFaces(machine_volumes, matrix, contours);
1408  }
1409  }
1410  }
1411 }
1412 
1413 void TYSiteNode::getListFaces(TYTabAcousticSurfaceGeoNode& tabFaces, unsigned int& nbFaceInfra,
1414  std::vector<bool>& EstUnIndexDeFaceEcran) const
1415 {
1416  EstUnIndexDeFaceEcran.clear();
1417 
1418  unsigned int j = 0, i = 0;
1420 
1421  tabFaces.clear();
1422 
1423  // Batiments
1424  for (i = 0; i < _pInfrastructure->getListBatiment().size(); i++)
1425  {
1426  // Si ce batiment est actif pour le calcul
1427  LPTYBatiment pBatiment = TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1428  if (pBatiment && pBatiment->isInCurrentCalcul())
1429  {
1430  tabTmp.clear();
1431 
1432  // Matrice de changement de repere pour ce batiment
1433  OMatrix matrix = _pInfrastructure->getListBatiment()[i]->getMatrix();
1434 
1435  // LPTYBatiment pBatiment =
1436  // TYBatiment::safeDownCast(_pInfrastructure->getBatiment(i)->getElement());
1437  LPTYEtage pEtage = TYEtage::safeDownCast(pBatiment->getAcousticVol(0));
1438 
1439  // Old Code_TYMPAN version could use a floor as a screen so, that case should be treated
1440  bool bEtageEcran = false;
1441  if (pEtage)
1442  {
1443  bEtageEcran = !pEtage->getClosed();
1444  }
1445  if (bEtageEcran)
1446  {
1447  pEtage->setacousticFacesPourCalcul(true);
1448  }
1449 
1450  // L'ensemble des faces de ce batiment
1451  tabTmp = pBatiment->acousticFaces();
1452 
1453  // Pour chacune de ces faces
1454  for (j = 0; j < tabTmp.size(); j++)
1455  {
1456  // On concatene les matrices
1457  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1458 
1459  // Ajout de la face
1460  tabFaces.push_back(tabTmp[j]);
1461  EstUnIndexDeFaceEcran.push_back(bEtageEcran);
1462  }
1463  if (bEtageEcran)
1464  {
1465  pEtage->setacousticFacesPourCalcul(false);
1466  }
1467  }
1468  }
1469 
1470  // Machines
1471  for (i = 0; i < _pInfrastructure->getListMachine().size(); i++)
1472  {
1473  // Si cette machine est active pour le calcul
1475  if (pMachine && pMachine->isInCurrentCalcul())
1476  {
1477  tabTmp.clear();
1478 
1479  // Matrice de changement de repere pour cette machine
1480  OMatrix matrix = _pInfrastructure->getListMachine()[i]->getMatrix();
1481 
1482  // L'ensemble des faces de cette machine
1483  tabTmp = TYMachine::safeDownCast(_pInfrastructure->getMachine(i)->getElement())->acousticFaces();
1484 
1485  // Pour chacune de ces faces
1486  for (j = 0; j < tabTmp.size(); j++)
1487  {
1488  // On concatene les matrices
1489  tabTmp[j]->setMatrix(matrix * tabTmp[j]->getMatrix());
1490 
1491  // Ajout de la face
1492  tabFaces.push_back(tabTmp[j]);
1493  EstUnIndexDeFaceEcran.push_back(false);
1494  }
1495  }
1496  }
1497 
1498  nbFaceInfra =
1499  static_cast<uint32>(tabFaces.size()); // Determination du nombre de faces de l'infrastructure;
1500 
1501  // Les faces de la topographie (altimetrie) sont transformee en faces acoustiques
1502  // avec des proprietes acoustiques nulles
1503  // EstUnIndexDeFaceEcran n'est pas a affecter, car les faces d'infrastructures sont separees de celles de
1504  // l'alti, donc sachant ou commence les faces d'alti, le test "est un ecran" n'a pas de sens pour ces
1505  // dernieres
1506 
1507  TYTabLPPolygon& listFacesAlti = getAltimetry()->getListFaces();
1508  unsigned int nbFacesAlti = static_cast<uint32>(listFacesAlti.size());
1509 
1510  for (i = 0; i < nbFacesAlti; i++)
1511  {
1512  LPTYAcousticPolygon pAccPolygon = new TYAcousticPolygon();
1513  pAccPolygon->setParent(getAltimetry());
1514 
1515  // Geomtrie
1516  *pAccPolygon->getPolygon() = *listFacesAlti.at(i);
1517 
1518  // Ajout
1520  tabFaces.push_back(pNode);
1521  }
1522 }
1523 
1525 {
1526  TYTabSiteNodeGeoNode& tabGeoNode = getListSiteNode();
1527  TYSiteNode* pSite = NULL;
1528 
1529  for (unsigned int i = 0; i < tabGeoNode.size(); i++)
1530  {
1531  pSite = TYSiteNode::safeDownCast(tabGeoNode[i]->getElement());
1532  pSite->setInCurrentCalcul(false, true, false);
1533  }
1534 }
1535 
1536 TYTabSiteNodeGeoNode TYSiteNode::collectSites(bool include /*=true*/) const
1537 {
1538  TYTabSiteNodeGeoNode sites;
1539 
1540  if (include)
1541  {
1542  sites.push_back(new TYSiteNodeGeoNode((TYSiteNode*)this));
1543  }
1544 
1545  for (unsigned int i = 0; i < _listSiteNode.size(); i++)
1546  {
1547  // On inclut forcement les sites sinon sans interet
1548  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1549  if (pSite && pSite->isInCurrentCalcul()) // Uniquement si le sous-site est dans le calcul
1550  {
1551  TYTabSiteNodeGeoNode tabChild = pSite->collectSites(true);
1552 
1553  // Concatenation des matrices
1554  OMatrix matrix = _listSiteNode[i]->getMatrix();
1555  for (unsigned int j = 0; j < tabChild.size(); j++)
1556  {
1557  tabChild[j]->setMatrix(matrix * tabChild[j]->getMatrix());
1558  }
1559 
1560  //...et ajoute au tableau a retourner
1561  sites.insert(sites.end(), tabChild.begin(), tabChild.end());
1562  }
1563  }
1564 
1565  return sites;
1566 }
1567 
1569 {
1570  bool ret = false;
1571 
1572  TYSourcePonctuelle* pSource = dynamic_cast<TYSourcePonctuelle*>(pElem);
1573  if (pSource != nullptr)
1574  {
1575  return true; // Pas de mise à jour nécessaire
1576  }
1577  TYAcousticLine* pLine = dynamic_cast<TYAcousticLine*>(pElem);
1578  if (pLine != nullptr) // Cas 1 : un objet de type source linéique
1579  {
1580  pLine->updateAcoustic(true);
1581  }
1582  else // Autres cas, recherche de parent et traitement approprié
1583  {
1584  TYElement* pParent = pElem; // On commencera par tester l'objet lui-meme
1585  do
1586  {
1587  TYAcousticVolumeNode* pVolNode = dynamic_cast<TYAcousticVolumeNode*>(pParent);
1588  if (pVolNode != nullptr)
1589  {
1590  ret = pVolNode->updateAcoustic(true);
1591  break; // On a trouvé, on peut sortir
1592  }
1593  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pParent);
1594  if (pSite != nullptr)
1595  {
1596  pSite->updateAcoustique();
1597  ret = true;
1598  break; // On a trouvé, on peut sortir
1599  }
1600 
1601  pParent = pParent->getParent();
1602  } while (pParent);
1603  }
1604 
1605  return ret;
1606 }
1607 
1608 void TYSiteNode::update(const bool& force) // Force = false
1609 {
1610  // Altimetrisation des infrastructures du site
1611  updateAltiInfra();
1612 
1613  // Mise a jour de l'acoustique des elements du site
1614  updateAcoustique(force);
1615 
1616  // Et celle des sites inclus
1617  for (unsigned short i = 0; i < _listSiteNode.size(); i++)
1618  {
1619  TYSiteNode* pSite = TYSiteNode::safeDownCast(_listSiteNode[i]->getElement());
1620 
1621  if (pSite && pSite->isInCurrentCalcul())
1622  {
1623  pSite->update(force);
1624  }
1625  }
1626 
1627  // Si le site est dans un projet, on altimétrise les points de controle
1628  if (_pProjet && getRoot())
1629  {
1631  }
1632 }
1633 
1635 {
1636  assert(pSiteNodeGeoNode);
1637 
1638  LPTYSiteNode pSite = TYSiteNode::safeDownCast(pSiteNodeGeoNode->getElement());
1639 
1640  assert(pSite);
1641 
1642  pSiteNodeGeoNode->setParent(this);
1643  pSite->setParent(this);
1644  pSite->setProjet(_pProjet); // Informe du projet cadre
1645 
1646  _listSiteNode.push_back(pSiteNodeGeoNode);
1647  getAltimetry()->setIsUpToDate(false); // Invalide l'altimétrie lors de l'ajout d'un sous-site
1648 
1649 #if TY_USE_IHM
1650  pSite->updateGraphicTree();
1651 #endif
1652  setIsGeometryModified(true);
1653 
1654  return true;
1655 }
1656 
1658 {
1659  return addSiteNode(new TYSiteNodeGeoNode((LPTYElement)pSiteNode));
1660 }
1661 
1662 bool TYSiteNode::remSiteNode(const LPTYSiteNodeGeoNode pSiteNodeGeoNode)
1663 {
1664  assert(pSiteNodeGeoNode);
1665  bool ret = false;
1666  TYTabSiteNodeGeoNode::iterator ite;
1667 
1668  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1669  {
1670  if ((*ite) == pSiteNodeGeoNode)
1671  {
1672  // Suppression des calcul
1673  if (_pProjet)
1674  {
1675  _pProjet->remElmtFromCalculs((*ite)->getElement());
1676  }
1677 
1678  _listSiteNode.erase(ite);
1679  ret = true;
1680  break;
1681  }
1682  }
1683 
1684  setIsGeometryModified(true);
1685 
1686  return ret;
1687 }
1688 
1690 {
1691  assert(pSiteNode);
1692  bool ret = false;
1693  TYTabSiteNodeGeoNode::iterator ite;
1694 
1695  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1696  {
1697  if (TYSiteNode::safeDownCast((*ite)->getElement()) == pSiteNode)
1698  {
1699  // Suppression des calcul
1700  if (_pProjet)
1701  {
1702  _pProjet->remElmtFromCalculs((*ite)->getElement());
1703  }
1704 
1705  _listSiteNode.erase(ite);
1706  ret = true;
1707  break;
1708  }
1709  }
1710 
1711  setIsGeometryModified(true);
1712 
1713  return ret;
1714 }
1715 
1716 bool TYSiteNode::remSiteNode(QString idSiteNode)
1717 {
1718  bool ret = false;
1719  TYTabSiteNodeGeoNode::iterator ite;
1720 
1721  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1722  {
1723  if (TYSiteNode::safeDownCast((*ite)->getElement())->getID().toString() == idSiteNode)
1724  {
1725  // Suppression des calcul
1726  if (_pProjet)
1727  {
1728  _pProjet->remElmtFromCalculs((*ite)->getElement());
1729  }
1730 
1731  _listSiteNode.erase(ite);
1732  ret = true;
1733  break;
1734  }
1735  }
1736 
1737  setIsGeometryModified(true);
1738 
1739  return ret;
1740 }
1741 
1743 {
1744  assert(pSiteNode);
1745  TYTabSiteNodeGeoNode::iterator ite;
1746 
1747  for (ite = _listSiteNode.begin(); ite != _listSiteNode.end(); ite++)
1748  {
1749  if (TYSiteNode::safeDownCast((*ite)->getElement()) == pSiteNode)
1750  {
1751  return (*ite);
1752  }
1753  }
1754 
1755  return NULL;
1756 }
1757 
1759 {
1760  LPTYSiteNode pSite = new TYSiteNode();
1761  pSite->getTopographie()
1762  ->getListTerrain()
1763  .clear(); // On vide car un terrain par defaut a ete cree dans le site cible
1764 
1765  unsigned int j = 0;
1766 
1767  // On copie les elements de ce site
1768  appendSite(this, OMatrix(), pSite);
1769  pSite->getTopographie()->setDefTerrainIdx(getTopographie()->getDefTerrainIdx());
1770  pSite->setEmprise(getTopographie()->getEmprise());
1771  pSite->getTopographie()->setDefTerrain(getTopographie()->getDefTerrainIdx());
1772 
1773  // Merge des sites enfants
1774  for (j = 0; j < _listSiteNode.size(); j++)
1775  {
1776  // Site enfant courant
1777  LPTYSiteNodeGeoNode pSiteNodeGeoNode = _listSiteNode[j];
1778 
1779  // Appel recursif
1780  TYSiteNode* pSiteChild = TYSiteNode::safeDownCast(pSiteNodeGeoNode->getElement());
1781  assert(pSiteChild);
1782  if (pSiteChild && !(pSiteChild->isInCurrentCalcul()))
1783  {
1784  continue;
1785  }
1786 
1787  LPTYSiteNode pSiteTmp = pSiteChild->merge();
1788 
1789  // On copie les elements du site enfant en prenant compte le changement de repere
1790  appendSite(pSiteTmp, pSiteNodeGeoNode->getMatrix(), pSite);
1791  }
1792 
1794  pSite->setProjet(_pProjet);
1795 
1796  return pSite;
1797 }
1798 
1799 void TYSiteNode::appendSite(LPTYSiteNode pSiteFrom, const OMatrix& matrix, LPTYSiteNode pSiteTo)
1800 {
1801  assert(pSiteFrom);
1802  assert(pSiteTo);
1803  unsigned int i = 0;
1804  OMatrix newMatrix;
1805 
1806  // Ajout des elements de topo
1807  LPTYTopographie pTopoFrom = pSiteFrom->getTopographie();
1808  LPTYTopographie pTopoTo = pSiteTo->getTopographie();
1809 
1810  // TODO BUG #0008309 : Courbe de niveau pas prise en compte dans l'altimétrie
1811  if (pSiteFrom->getUseEmpriseAsCrbNiv())
1812  {
1813  pTopoTo->addCrbNiv(new TYCourbeNiveau(pTopoFrom->getEmprise(), pSiteFrom->getAltiEmprise()));
1814  }
1815  // This scope is here to make p_ground local
1816  {
1817  // Add the 'emprise' as a Terrain with its defaultTErrain as Sol attribute.
1818  TYTerrain* p_ground = new TYTerrain();
1819  p_ground->setSol(pTopoFrom->getDefTerrain()->getSol());
1820  p_ground->setListPoints(pTopoFrom->getEmprise());
1821  pTopoTo->addTerrain(new TYTerrainGeoNode(p_ground, matrix));
1822  }
1823  for (i = 0; i < pTopoFrom->getListCrbNiv().size(); i++)
1824  {
1825  newMatrix = matrix * pTopoFrom->getListCrbNiv()[i]->getMatrix();
1826  pTopoTo->addCrbNiv(new TYCourbeNiveauGeoNode(pTopoFrom->getListCrbNiv()[i]->getElement(), newMatrix));
1827  }
1828 
1829  for (i = 0; i < pTopoFrom->getListTerrain().size(); i++)
1830  {
1831  newMatrix = matrix * pTopoFrom->getListTerrain()[i]->getMatrix();
1832  pTopoTo->addTerrain(new TYTerrainGeoNode(pTopoFrom->getListTerrain()[i]->getElement(), newMatrix));
1833  }
1834 
1835  for (i = 0; i < pTopoFrom->getListCrsEau().size(); i++)
1836  {
1837  newMatrix = matrix * pTopoFrom->getListCrsEau()[i]->getMatrix();
1838  pTopoTo->addCrsEau(new TYCoursEauGeoNode(pTopoFrom->getListCrsEau()[i]->getElement(), newMatrix));
1839  }
1840 
1841  for (i = 0; i < pTopoFrom->getListPlanEau().size(); i++)
1842  {
1843  newMatrix = matrix * pTopoFrom->getListPlanEau()[i]->getMatrix();
1844  pTopoTo->addPlanEau(new TYPlanEauGeoNode(pTopoFrom->getListPlanEau()[i]->getElement(), newMatrix));
1845  }
1846 
1847  // Ajout des elements d'infra
1848  LPTYInfrastructure pInfraFrom = pSiteFrom->getInfrastructure();
1849  LPTYInfrastructure pInfraTo = pSiteTo->getInfrastructure();
1850 
1851 #if WITH_NMPB
1852  for (i = 0; i < pInfraFrom->getListRoute().size(); i++)
1853  {
1854  newMatrix = matrix * pInfraFrom->getListRoute()[i]->getMatrix();
1855  pInfraTo->addRoute(new TYRouteGeoNode(pInfraFrom->getListRoute()[i]->getElement(), newMatrix));
1856  }
1857 #endif
1858  for (i = 0; i < pInfraFrom->getListResTrans().size(); i++)
1859  {
1860  newMatrix = matrix * pInfraFrom->getListResTrans()[i]->getMatrix();
1861  pInfraTo->addResTrans(
1862  new TYReseauTransportGeoNode(pInfraFrom->getListResTrans()[i]->getElement(), newMatrix));
1863  }
1864 
1865  for (i = 0; i < pInfraFrom->getListBatiment().size(); i++)
1866  {
1867  newMatrix = matrix * pInfraFrom->getListBatiment()[i]->getMatrix();
1868  TYBatimentGeoNode* pBatNode =
1869  new TYBatimentGeoNode(pInfraFrom->getListBatiment()[i]->getElement(), newMatrix);
1870  pBatNode->setHauteur(pInfraFrom->getListBatiment()[i]->getHauteur());
1871  pInfraTo->addBatiment(pBatNode);
1872  }
1873 
1874  for (i = 0; i < pInfraFrom->getListMachine().size(); i++)
1875  {
1876  newMatrix = matrix * pInfraFrom->getListMachine()[i]->getMatrix();
1877  TYMachineGeoNode* pMachineNode =
1878  new TYMachineGeoNode(pInfraFrom->getListMachine()[i]->getElement(), newMatrix);
1879  pMachineNode->setHauteur(pInfraFrom->getListMachine()[i]->getHauteur());
1880  pInfraTo->addMachine(pMachineNode);
1881  }
1882 
1883  for (i = 0; i < pInfraFrom->getSrcs().size(); i++)
1884  {
1885  newMatrix = matrix * pInfraFrom->getSrcs()[i]->getMatrix();
1886  pInfraTo->addSrc(new TYSourcePonctuelleGeoNode(pInfraFrom->getSrcs()[i]->getElement(), newMatrix));
1887  }
1888 }
1889 
1890 void TYSiteNode::exportCSV(std::ofstream& ofs)
1891 {
1892  // Export du nom de l'objet
1893  ofs << getName().toLatin1().data() << '\n';
1894 
1895  // Export du type de l'objet
1896  ofs << toString() << '\n';
1897  // Export des donnees acoustiques
1898  LPTYElementArray childs;
1899  getChilds(childs);
1900 
1901  for (int i = 0; i < childs.size(); i++)
1902  {
1903  TYElement* pElement = childs[i];
1904  TYSiteNode* pSite = dynamic_cast<TYSiteNode*>(pElement);
1905  if (pSite != nullptr)
1906  {
1907  // Export du nom de l'objet
1908  ofs << pElement->getName().toLatin1().data() << '\n';
1909  continue;
1910  }
1911  LPTYAcousticVolumeNode pVolNode = dynamic_cast<TYAcousticVolumeNode*>(pElement);
1912  if (pVolNode != nullptr)
1913  {
1914  pVolNode->exportCSV(ofs);
1915  continue;
1916  }
1917  LPTYAcousticLine pAcLine = dynamic_cast<TYAcousticLine*>(pElement);
1918  if (pAcLine != nullptr)
1919  {
1920  pAcLine->exportCSV(ofs);
1921  continue;
1922  }
1923  LPTYUserSourcePonctuelle pSource = dynamic_cast<TYUserSourcePonctuelle*>(pElement);
1924  if (pSource != nullptr)
1925  {
1926  pSource->exportCSV(ofs);
1927  }
1928  }
1929 
1930  ofs << '\n';
1931 }
QDomElement DOM_Element
Definition: QT2DOM.h:30
std::vector< LPTYAcousticFaceSetGeoNode > TYTabAcousticVolumeGeoNode
Collection de noeuds geometriques de type TYAcousticFaceSet.
TYGeometryNode TYAcousticSurfaceGeoNode
Noeud geometrique de type TYAcousticSurface.
std::vector< LPTYAcousticSurfaceGeoNode > TYTabAcousticSurfaceGeoNode
Collection de noeuds geometriques de type TYAcousticSurface.
SmartPtr< TYAcousticSurfaceGeoNode > LPTYAcousticSurfaceGeoNode
Smart Pointer sur TYAcousticSurfaceGeoNode.
TYGeometryNode TYBatimentGeoNode
Noeud geometrique de type TYBatiment.
Definition: TYBatiment.h:90
TYGeometryNode TYCourbeNiveauGeoNode
Noeud geometrique de type TYCourbeNiveau.
TYGeometryNode TYCoursEauGeoNode
Noeud geometrique de type TYCoursEau.
Definition: TYCoursEau.h:66
class OGenID TYUUID
Definition: TYDefines.h:59
std::deque< OPoint3D > TYTabPoint3D
Collection de OPoint3D.
Definition: TYDefines.h:403
std::vector< LPTYPolygon > TYTabLPPolygon
Collection de pointeurs de TYPolygon.
Definition: TYDefines.h:349
std::list< TYUUID > TYListID
Collection d'identifiants.
Definition: TYDefines.h:331
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:344
#define TYDIRPREFERENCEMANAGER
Definition: TYElement.h:51
TYGeometryNode TYMachineGeoNode
Noeud geometrique de type TYMachine.
Definition: TYMachine.h:164
TYGeometryNode TYPlanEauGeoNode
Noeud geometrique de type TYPlanEau.
Definition: TYPlanEau.h:198
TYGeometryNode TYReseauTransportGeoNode
Noeud geometrique de type TYReseauTransport.
TYGeometryNode TYRouteGeoNode
Geometrical node of type TYRoute.
Definition: TYRoute.h:33
Representation graphique d'un ensemble de sites (fichier header)
outil IHM pour un ensemble de sites (fichier header)
std::vector< bool > EstUnIndexDeFaceEcran
bool almost_equal(double a, double b, double precision)
TY_EXTENSION_INST(TYSiteNode)
TY_EXT_GRAPHIC_INST(TYSiteNode)
#define TR(id)
Definition: TYSiteNode.cpp:39
systemSIG
Systeme SIG.
Definition: TYSiteNode.h:29
@ TYMPAN
Definition: TYSiteNode.h:30
TYGeometryNode TYSiteNodeGeoNode
Noeud geometrique de type TYSiteNode.
Definition: TYSiteNode.h:36
std::vector< LPTYSiteNodeGeoNode > TYTabSiteNodeGeoNode
Collection de noeuds geometriques de type TYSiteNode.
Definition: TYSiteNode.h:40
TYGeometryNode TYSourcePonctuelleGeoNode
Noeud geometrique de type TYSourcePonctuelle.
TYGeometryNode TYTerrainGeoNode
Noeud geometrique de type TYTerrain.
Definition: TYTerrain.h:177
Implementation details header for altimetry_reader.cpp.
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
Definition: idgen.h:28
The 4x4 matrix class.
Definition: 3d.h:625
OMatrix getInvert(int *ok=0) const
Return the inverse matrix of this matrix.
Definition: 3d.cpp:813
double _m[4][4]
The 4x4 matrix array.
Definition: 3d.h:974
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
The 3D point class.
Definition: 3d.h:487
virtual const char * getClassName() const
Definition: TYElement.h:248
static OPrototype * safeDownCast(OPrototype *pObject)
Definition: TYElement.cpp:71
OPoint3D _origin
The origin point.
Definition: 3d.h:1331
The 3D vector class.
Definition: 3d.h:298
double scalar(const OVector3D &vector) const
Performs the scalar product between this object and another vector.
Definition: 3d.cpp:210
T * _pObj
The real pointer, must derived IRefCount.
Definition: smartptr.h:307
TYTabPoint & getTabPoint()
virtual bool updateAcoustic(const bool &force=false)
TYTabAcousticSurfaceGeoNode & getTabAcousticSurf()
virtual TYTabPoint3D getOContour(int n=-1) const
virtual TYTabAcousticSurfaceGeoNode acousticFaces()
virtual void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
virtual bool updateAcoustic(const bool &force=false)
LPTYAcousticVolume getAcousticVol(int index)
TYTabAcousticVolumeGeoNode & getTabAcousticVol()
virtual TYTabAcousticSurfaceGeoNode acousticFaces()
Assigne une altitude a chaque point de l'espace.
Definition: TYAltimetrie.h:35
bool updateAltitude(OPoint3D &pt) const
Modifie l'altitude d'un point donn�. Si le point est hors de la zone dans laquelle l'altim�trie e...
void plugBackTriangulation(const std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const std::deque< LPTYSol > &materials)
plug back triangulation providfed by the TYTopographie
void setIsUpToDate(bool isUpToDate)
TYTabLPPolygon & getListFaces()
Definition: TYAltimetrie.h:124
Calculation program.
Definition: TYCalcul.h:50
QString solverParams
Definition: TYCalcul.h:482
TYElement * getParent() const
Definition: TYElement.h:706
virtual bool isInCurrentCalcul()
Definition: TYElement.h:539
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYElement.cpp:305
static void setIsSavedOk(const bool &toSave)
Definition: TYElement.h:914
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYElement.cpp:366
QString _name
Nom courant de l'element.
Definition: TYElement.h:965
TYElement & operator=(const TYElement &other)
Definition: TYElement.cpp:263
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:542
const TYUUID & getID() const
Definition: TYElement.cpp:176
virtual QString getName() const
Definition: TYElement.h:691
TYElement * _pParent
Reference sur l'element parent.
Definition: TYElement.h:968
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYElement.cpp:458
virtual void setInCurrentCalcul(bool state, bool recurschild=true, bool recursparent=true)
Definition: TYElement.cpp:408
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYElement.h:530
void setParent(TYElement *pParent)
Definition: TYElement.h:699
virtual int fromXML(DOM_Element domElement)
Definition: TYElement.cpp:379
QString getStringID() const
Definition: TYElement.h:660
static TYElement * getInstance(TYUUID uuid)
Definition: TYElement.cpp:158
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
LPTYDalle getPlafond()
Definition: TYEtage.h:229
void setacousticFacesPourCalcul(bool bPourCalculTrajet)
Definition: TYEtage.cpp:2022
TYTabMurGeoNode & getTabMur()
Definition: TYEtage.h:143
bool getClosed()
Definition: TYEtage.h:206
const ORepere3D & getORepere3D() const
void setHauteur(const double &hauteur)
Set the heigth above the ground.
double getHauteur()
Get the height above the ground.
TYElement * getElement() const
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
OMatrix getMatrix() const
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
TYTabBatimentGeoNode & getListBatiment()
bool addToCalcul(TYGeometryNode *pNode)
LPTYUserSourcePonctuelleGeoNode getSrc(int index)
LPTYMachineGeoNode getMachine(int index)
virtual void reparent()
LPTYReseauTransport getResTrans(int index)
TYTabUserSourcePonctuelleGeoNode & getSrcs()
LPTYBatimentGeoNode getBatiment(int index)
TYTabReseauTransportGeoNode & getListResTrans()
virtual DOM_Element toXML(DOM_Element &domElement)
bool addBatiment(LPTYBatimentGeoNode pBatimentGeoNode)
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
bool addMachine(LPTYMachineGeoNode pMachineGeoNode)
bool addSrc(LPTYUserSourcePonctuelle pSrc)
bool updateAcoustic(const TYCalcul *pCalcul, const bool &force=false)
TYTabMachineGeoNode & getListMachine()
bool addResTrans(LPTYReseauTransportGeoNode pResTransGeoNode)
Definition: TYMur.h:36
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
void enable(bool enable)
Active la generation de nom.
Definition: TYNameManager.h:64
static TYNameManager * get()
Retourne l'instance singleton.
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYPoint.cpp:112
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYPoint.cpp:92
const TYTabPoint & getPoints() const
Definition: TYPolygon.h:123
virtual OVector3D normal() const
Definition: TYPolygon.cpp:243
void updateNormal()
Definition: TYPolygon.cpp:523
void remElmtFromCalculs(TYElement *pElement)
Supprime un element de tous les calculs.
Definition: TYProjet.cpp:733
bool updateAltiRecepteurs()
Definition: TYProjet.cpp:643
double getDelaunayTolerence()
Definition: TYProjet.h:490
LPTYCalcul getCurrentCalcul()
Set/Get du pointeur du Calcul courant.
Definition: TYProjet.h:426
double getHauteurMoyenne() const
virtual bool updateAltitudes(const TYAltimetrie &alti, LPTYRouteGeoNode pGeoNode, OMatrix globalMatrix)
Required the road to update its altitude after altimetry changed.
Definition: TYRoute.cpp:420
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYSegment.cpp:97
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYSegment.cpp:120
TYTabSiteNodeGeoNode collectSites(bool include=true) const
const double getAltiEmprise() const
Definition: TYSiteNode.h:141
double _SIG_Y
Definition: TYSiteNode.h:703
void setProjet(const LPTYProjet pProjet)
Definition: TYSiteNode.cpp:560
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYSiteNode.cpp:223
void purge()
Definition: TYSiteNode.h:97
LPTYAltimetrie getAltimetry() const
void appendSite(LPTYSiteNode pSiteFrom, const OMatrix &matrix, LPTYSiteNode pSiteTo)
OMatrix getGlobalMatrix() const
LPTYTopographie getTopographie()
Definition: TYSiteNode.h:149
virtual void updateCurrentCalcul(TYListID &listID, bool recursif=true)
Definition: TYSiteNode.cpp:544
virtual void setIsGeometryModified(bool isModified)
Definition: TYSiteNode.cpp:501
bool readMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, std::deque< LPTYSol > &materials, const QString &meshFilePath)
Definition: TYSiteNode.cpp:734
virtual void do_updateAltimetrie(QString resultMeshFilePath)
Definition: TYSiteNode.cpp:646
virtual bool remFromCalcul()
Definition: TYSiteNode.cpp:527
LPTYTopographie _pTopographie
Topographie.
Definition: TYSiteNode.h:664
void setEmprise(TYTabPoint points)
Definition: TYSiteNode.h:362
QString _topoFile
Nom du fichier de topographie temporaire.
Definition: TYSiteNode.h:679
virtual void setChildsNotInCurrentCalcul()
void setTopoFileName(const QString &name)
Definition: TYSiteNode.h:248
virtual void getChilds(LPTYElementArray &childs, bool recursif=true)
Definition: TYSiteNode.cpp:473
LPTYSiteNode merge()
virtual void reparent()
Definition: TYSiteNode.cpp:569
bool remSiteNode(const LPTYSiteNodeGeoNode pSiteNodeGeoNode)
LPTYInfrastructure getInfrastructure()
Definition: TYSiteNode.h:174
LPTYInfrastructure _pInfrastructure
Infrastructure.
Definition: TYSiteNode.h:667
QString _topoFileName
Nom du fichier de topographie (image de fond)
Definition: TYSiteNode.h:673
virtual ~TYSiteNode()
Definition: TYSiteNode.cpp:97
double _altiEmprise
Altitude associee a l'emprise (s'il y a lieu)
Definition: TYSiteNode.h:661
float _echelle
Echelle du site.
Definition: TYSiteNode.h:685
virtual int fromXML(DOM_Element domElement)
Definition: TYSiteNode.cpp:324
systemSIG _SIGType
Coordonnees SIG.
Definition: TYSiteNode.h:700
const QString & getMeshFilePath()
Definition: TYSiteNode.cpp:59
TYTabSiteNodeGeoNode _listSiteNode
Liste des sites.
Definition: TYSiteNode.h:707
TYPoint _position
Position.
Definition: TYSiteNode.h:689
QString _meshFilePath
Chemin vers le fichier PLY d'altimétrie.
Definition: TYSiteNode.h:676
bool _useTopoFile
Flag d'utilisation d'une image de fond.
Definition: TYSiteNode.h:670
QString _topoFileExtension
Extension du fichier de topographie.
Definition: TYSiteNode.h:682
virtual void updateAcoustique(const bool &force=false)
void setMeshFilePath(const QString &path)
Definition: TYSiteNode.cpp:64
void uuid2tysol(const std::deque< std::string > &material_ids, std::deque< LPTYSol > &materials)
Definition: TYSiteNode.cpp:761
void update(const bool &force=false)
bool _root
Test si site racine.
Definition: TYSiteNode.h:697
void getListFaces(TYTabAcousticSurfaceGeoNode &tabFaces, unsigned int &nbFaceInfra, std::vector< bool > &EstUnIndexDeFaceEcran) const
static const QString & getTopoFilePath()
Definition: TYSiteNode.cpp:49
double getDelaunay()
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYSiteNode.cpp:271
TYTabSiteNodeGeoNode & getListSiteNode()
Definition: TYSiteNode.h:346
virtual std::string toString() const
Definition: TYSiteNode.cpp:266
LPTYSiteNodeGeoNode findSiteNode(const LPTYSiteNode pSiteNode)
LPTYProjet _pProjet
Projet auquel appartient (eventuellement) le site.
Definition: TYSiteNode.h:655
TYSegment _orientation
Orientation du Nord.
Definition: TYSiteNode.h:687
bool addSiteNode(LPTYSiteNodeGeoNode pSiteNodeGeoNode)
void loadTopoFile()
Definition: TYSiteNode.cpp:586
virtual TYSiteNode & operator=(const TYSiteNode &other)
Operateur =.
Definition: TYSiteNode.cpp:102
virtual bool updateAltimetrie(QString resultMeshFilePath)
Definition: TYSiteNode.cpp:628
static void setTopoFilePath(const QString &path)
Definition: TYSiteNode.cpp:54
virtual void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
void getListFacesWithoutFloor(TYTabAcousticSurfaceGeoNode &tabFaces, unsigned int &nbFaceInfra, std::vector< bool > &EstUnIndexDeFaceEcran, std::vector< std::pair< int, int >> &indices, std::vector< int > &etages) const
bool getUseEmpriseAsCrbNiv() const
Definition: TYSiteNode.h:123
virtual void updateAltiInfra()
Definition: TYSiteNode.cpp:784
void groundBasedFaces(const TYTabAcousticVolumeGeoNode &volumes, const OMatrix &global_matrix, std::map< TYUUID, std::deque< TYTabPoint3D >> &contours) const
bool getRoot() const
Definition: TYSiteNode.h:321
double _SIG_X
Definition: TYSiteNode.h:702
virtual bool addToCalcul()
Definition: TYSiteNode.cpp:511
void getFacesOnGround(std::map< TYUUID, std::deque< TYTabPoint3D >> &contours) const
bool _bEmpriseAsCrbNiv
Utilisation de l'emprise comme courbe de niveau.
Definition: TYSiteNode.h:658
virtual bool operator!=(const TYSiteNode &other) const
Operateur !=.
Definition: TYSiteNode.cpp:218
bool _isTopoFileModified
Flag de modification de l'image de fond.
Definition: TYSiteNode.h:710
double _SIG_OFFSET
Definition: TYSiteNode.h:704
virtual bool operator==(const TYSiteNode &other) const
Operateur ==.
Definition: TYSiteNode.cpp:130
static QString _topoFilePath
Chemin du dossier image temporaire.
Definition: TYSiteNode.h:651
Definition: TYSol.h:25
virtual void setListPoints(const TYTabPoint &liste)
Definition: TYTerrain.h:145
LPTYSol getSol() const
Definition: TYTerrain.h:77
virtual TYTabPoint & getListPoints()
Definition: TYTerrain.h:131
void setSol(const LPTYSol pSol)
Definition: TYTerrain.h:89
TYTerrain * getDefTerrain()
virtual void setIsGeometryModified(bool isModified)
TYTabPlanEauGeoNode & getListPlanEau()
bool addCrsEau(LPTYCoursEauGeoNode pCoursEauGeoNode)
LPTYCoursEau getCrsEau(int index)
virtual DOM_Element toXML(DOM_Element &domElement)
virtual void reparent()
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
LPTYAltimetrie getAltimetrie()
void setDefTerrain(int defTerrainIdx)
void setDefTerrainIdx(const int &defTerrainIdx)
TYTabCoursEauGeoNode & getListCrsEau()
bool addCrbNiv(LPTYCourbeNiveauGeoNode pCrbNivGeoNode)
bool addPlanEau(LPTYPlanEauGeoNode pPlanEauGeoNode)
LPTYTerrain getTerrain(int index)
TYTabPoint & getEmprise()
TYTabCourbeNiveauGeoNode & getListCrbNiv()
bool addTerrain(LPTYTerrainGeoNode pTerGeoNode)
TYTabTerrainGeoNode & getListTerrain()
void sortTerrainsBySurface()
void exportCSV(std::ofstream &ofs)
Export au format csv sur un flux transmis.
static QString getSavedFileName()
Definition: TYXMLManager.h:140
static void addElementDoubleValue(DOM_Element &parentElem, DOMString nodeName, double nodeValue)
Definition: TYXMLTools.cpp:87
static bool getElementBoolValue(DOM_Element parentElem, DOMString nodeName, bool &nodeValue)
Definition: TYXMLTools.cpp:179
static bool getElementStringValue(DOM_Element parentElem, DOMString nodeName, QString &nodeValue)
Definition: TYXMLTools.cpp:93
static void addElementIntValue(DOM_Element &parentElem, DOMString nodeName, int nodeValue)
Definition: TYXMLTools.cpp:72
static bool getElementFloatValue(DOM_Element parentElem, DOMString nodeName, float &nodeValue)
Definition: TYXMLTools.cpp:211
static bool getElementIntValue(DOM_Element parentElem, DOMString nodeName, int &nodeValue)
Definition: TYXMLTools.cpp:129
static bool getElementDoubleValue(DOM_Element parentElem, DOMString nodeName, double &nodeValue)
Definition: TYXMLTools.cpp:243
static void addElementBoolValue(DOM_Element &parentElem, DOMString nodeName, bool nodeValue)
Definition: TYXMLTools.cpp:77
static void addElementStringValue(DOM_Element &parentElem, DOMString nodeName, DOMString nodeValue)
Definition: TYXMLTools.cpp:24
static void addElementFloatValue(DOM_Element &parentElem, DOMString nodeName, float nodeValue)
Definition: TYXMLTools.cpp:82
read an Altimetry from a PLY file.
virtual const points_array_t & points() const
virtual void read()
read the file whose name was given at reader's construction time
virtual const materials_array_t & materials() const
Getter for the faces read.
virtual const faces_array_t & faces() const
Getter for the faces read.
static FILE * openFileForReading(const QString &filename)
#define tympan_source_loc
This macro build a source_loc object to be attached to a tympan::Exception.
Definition: exceptions.h:91
unsigned int uint32
Definition: defines.h:75
void save_project(const char *filename, const LPTYProjet &project)
save a project into an XML file
The base exception class for all exceptions specific to Code_TYMPAN.
Definition: exceptions.h:63
The base exception class for errors due to invalid data.
Definition: exceptions.h:75
bool python(QStringList args, std::string &error_msg)
Launch a Python subprocess and wait for it using a non-blocking UI loop.
bool must_keep_tmp_files()
Tell whether temporary files should be preserved (debug mode).
bool init_tmp_file(QTemporaryFile &tmp_file, bool keep_file)
Create and initialize a QTemporaryFile according to the current policy.
Utilities to interact with Python subprocesses from the Tympan application.
Utilities to load a project and a solver.